Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
f43bbfea
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看板
提交
f43bbfea
编写于
10月 30, 2020
作者:
F
freemine
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
adding charset-endec support
上级
7d332df5
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
780 addition
and
140 deletion
+780
-140
src/connector/odbc/src/todbc.c
src/connector/odbc/src/todbc.c
+382
-122
src/connector/odbc/src/todbc_conv.c
src/connector/odbc/src/todbc_conv.c
+301
-0
src/connector/odbc/src/todbc_conv.h
src/connector/odbc/src/todbc_conv.h
+34
-0
src/connector/odbc/src/todbc_flex.h
src/connector/odbc/src/todbc_flex.h
+15
-1
src/connector/odbc/src/todbc_scanner.l
src/connector/odbc/src/todbc_scanner.l
+48
-17
未找到文件。
src/connector/odbc/src/todbc.c
浏览文件 @
f43bbfea
...
...
@@ -28,6 +28,11 @@
#include <sqlext.h>
#define UTF8_ENC "UTF-8"
#define UTF16_ENC "UCS-2LE"
#define UNICODE_ENC "UCS-4LE"
#define GB18030_ENC "GB18030"
#define GET_REF(obj) atomic_load_64(&obj->refcount)
#define INC_REF(obj) atomic_add_fetch_64(&obj->refcount, 1)
#define DEC_REF(obj) atomic_sub_fetch_64(&obj->refcount, 1)
...
...
@@ -159,8 +164,8 @@ do { \
#define CHK_CONV(todb, statement) \
do { \
TSDB_CONV_CODE code
= (statement);
\
switch (code
) {
\
TSDB_CONV_CODE code
_0c80 = (statement);
\
switch (code
_0c80) {
\
case TSDB_CONV_OK: return SQL_SUCCESS; \
case TSDB_CONV_OOM: { \
SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, ""); \
...
...
@@ -225,6 +230,16 @@ struct conn_s {
uint64_t
refcount
;
env_t
*
env
;
char
client_enc
[
64
];
char
server_enc
[
64
];
tsdb_conv_t
*
client_to_server
;
tsdb_conv_t
*
server_to_client
;
tsdb_conv_t
*
utf8_to_client
;
tsdb_conv_t
*
utf16_to_utf8
;
tsdb_conv_t
*
utf16_to_server
;
tsdb_conv_t
*
client_to_utf8
;
TAOS
*
taos
;
taos_error_t
err
;
...
...
@@ -275,20 +290,88 @@ static iconv_t sql_get_w2c(sql_t *sql) {
return
sql
->
w2c
;
}
// typedef struct stack_buffer_s stack_buffer_t;
// struct stack_buffer_s {
// char buf[1024*16];
// size_t next;
// };
//
// static char* stack_buffer_alloc(stack_buffer_t *buffer, size_t bytes);
// static int is_owned_by_stack_buffer(stack_buffer_t *buffer, const char *ptr);
//
// static const char* tsdb_conn_conv_client_to_server(conn_t *conn, stack_buffer_t *buffer, const char *src, size_t len);
// static const char* tsdb_conn_conv_server_to_client(conn_t *conn, stack_buffer_t *buffer, const char *src, size_t len);
// static const char* tsdb_conn_conv_wchars_to_server(conn_t *conn, stack_buffer_t *buffer, const char *src, size_t len);
// static const char* tsdb_conn_conv_server_to_wchars(conn_t *conn, stack_buffer_t *buffer, const char *src, size_t len);
//
static
tsdb_conv_t
*
tsdb_conn_client_to_server
(
conn_t
*
conn
)
{
if
(
!
conn
->
client_to_server
)
{
conn
->
client_to_server
=
tsdb_conv_open
(
conn
->
client_enc
,
conn
->
server_enc
);
}
return
conn
->
client_to_server
;
}
static
tsdb_conv_t
*
tsdb_conn_server_to_client
(
conn_t
*
conn
)
{
if
(
!
conn
->
server_to_client
)
{
conn
->
server_to_client
=
tsdb_conv_open
(
conn
->
server_enc
,
conn
->
client_enc
);
}
return
conn
->
server_to_client
;
}
static
tsdb_conv_t
*
tsdb_conn_utf8_to_client
(
conn_t
*
conn
)
{
if
(
!
conn
->
utf8_to_client
)
{
conn
->
utf8_to_client
=
tsdb_conv_open
(
UTF8_ENC
,
conn
->
client_enc
);
}
return
conn
->
utf8_to_client
;
}
tsdb_conv_t
*
tsdb_conn_utf16_to_utf8
(
conn_t
*
conn
)
{
if
(
!
conn
->
utf16_to_utf8
)
{
conn
->
utf16_to_utf8
=
tsdb_conv_open
(
UTF16_ENC
,
UTF8_ENC
);
}
return
conn
->
utf16_to_utf8
;
}
tsdb_conv_t
*
tsdb_conn_utf16_to_server
(
conn_t
*
conn
)
{
if
(
!
conn
->
utf16_to_server
)
{
conn
->
utf16_to_server
=
tsdb_conv_open
(
UTF16_ENC
,
conn
->
server_enc
);
}
return
conn
->
utf16_to_server
;
}
static
tsdb_conv_t
*
tsdb_conn_client_to_utf8
(
conn_t
*
conn
)
{
if
(
!
conn
->
client_to_utf8
)
{
conn
->
client_to_utf8
=
tsdb_conv_open
(
conn
->
client_enc
,
UTF8_ENC
);
}
return
conn
->
client_to_utf8
;
}
static
void
tsdb_conn_close_convs
(
conn_t
*
conn
)
{
if
(
0
)
{
tsdb_conn_server_to_client
(
NULL
);
}
if
(
conn
->
client_to_server
)
{
tsdb_conv_close
(
conn
->
client_to_server
);
conn
->
client_to_server
=
NULL
;
}
if
(
conn
->
server_to_client
)
{
tsdb_conv_close
(
conn
->
server_to_client
);
conn
->
server_to_client
=
NULL
;
}
if
(
conn
->
utf8_to_client
)
{
tsdb_conv_close
(
conn
->
utf8_to_client
);
conn
->
utf8_to_client
=
NULL
;
}
if
(
conn
->
utf16_to_utf8
)
{
tsdb_conv_close
(
conn
->
utf16_to_utf8
);
conn
->
utf16_to_utf8
=
NULL
;
}
if
(
conn
->
utf16_to_server
)
{
tsdb_conv_close
(
conn
->
utf16_to_server
);
conn
->
utf16_to_server
=
NULL
;
}
if
(
conn
->
client_to_utf8
)
{
tsdb_conv_close
(
conn
->
client_to_utf8
);
conn
->
client_to_utf8
=
NULL
;
}
}
#define SFREE(buffer, v, src) \
do { \
const char *v_096a = (const char*)(v); \
const char *src_6a = (const char*)(src); \
if (v_096a && v_096a!=src_6a && !is_owned_by_stack_buffer((buffer), v_096a)) { \
free((char*)v_096a); \
} \
} while (0)
// static iconv_t sql_get_u2c(sql_t *sql) {
// if (sql->u2c == (iconv_t)-1) {
// sql->u2c = iconv_open("UTF-8", "UCS-4LE");
...
...
@@ -375,6 +458,9 @@ static SQLRETURN doSQLAllocConnect(SQLHENV EnvironmentHandle,
break
;
}
snprintf
(
conn
->
client_enc
,
sizeof
(
conn
->
client_enc
),
UTF8_ENC
);
snprintf
(
conn
->
server_enc
,
sizeof
(
conn
->
server_enc
),
UTF8_ENC
);
conn
->
env
=
env
;
*
ConnectionHandle
=
conn
;
...
...
@@ -416,6 +502,7 @@ static SQLRETURN doSQLFreeConnect(SQLHDBC ConnectionHandle)
conn
->
env
=
NULL
;
FREE_ERROR
(
conn
);
tsdb_conn_close_convs
(
conn
);
free
(
conn
);
}
while
(
0
);
...
...
@@ -434,6 +521,8 @@ static SQLRETURN doSQLConnect(SQLHDBC ConnectionHandle,
SQLCHAR
*
UserName
,
SQLSMALLINT
NameLength2
,
SQLCHAR
*
Authentication
,
SQLSMALLINT
NameLength3
)
{
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
conn_t
*
conn
=
(
conn_t
*
)
ConnectionHandle
;
if
(
!
conn
)
return
SQL_ERROR
;
...
...
@@ -451,12 +540,16 @@ static SQLRETURN doSQLConnect(SQLHDBC ConnectionHandle,
return
SQL_ERROR
;
}
const
char
*
serverName
=
SDUP
(
ServerName
,
NameLength1
);
const
char
*
userName
=
SDUP
(
UserName
,
NameLength2
);
const
char
*
auth
=
SDUP
(
Authentication
,
NameLength3
);
tsdb_conv_t
*
client_to_server
=
tsdb_conn_client_to_server
(
conn
);
const
char
*
serverName
=
NULL
;
const
char
*
userName
=
NULL
;
const
char
*
auth
=
NULL
;
do
{
if
((
ServerName
&&
!
serverName
)
||
(
UserName
&&
!
userName
)
||
(
Authentication
&&
!
auth
))
{
tsdb_conv
(
client_to_server
,
&
buffer
,
(
const
char
*
)
ServerName
,
(
size_t
)
NameLength1
,
&
serverName
,
NULL
);
tsdb_conv
(
client_to_server
,
&
buffer
,
(
const
char
*
)
UserName
,
(
size_t
)
NameLength2
,
&
userName
,
NULL
);
tsdb_conv
(
client_to_server
,
&
buffer
,
(
const
char
*
)
Authentication
,
(
size_t
)
NameLength3
,
&
auth
,
NULL
);
if
((
!
serverName
)
||
(
!
userName
)
||
(
!
auth
))
{
SET_ERROR
(
conn
,
"HY001"
,
TSDB_CODE_ODBC_OOM
,
""
);
break
;
}
...
...
@@ -470,9 +563,9 @@ static SQLRETURN doSQLConnect(SQLHDBC ConnectionHandle,
}
}
while
(
0
);
SFRE
(
serverName
,
ServerName
,
NameLength1
);
SFRE
(
userName
,
UserName
,
NameLength2
);
SFRE
(
auth
,
Authentication
,
NameLength3
);
tsdb_conv_free
(
client_to_server
,
serverName
,
&
buffer
,
(
const
char
*
)
ServerName
);
tsdb_conv_free
(
client_to_server
,
userName
,
&
buffer
,
(
const
char
*
)
UserName
);
tsdb_conv_free
(
client_to_server
,
auth
,
&
buffer
,
(
const
char
*
)
Authentication
);
return
conn
->
taos
?
SQL_SUCCESS
:
SQL_ERROR
;
}
...
...
@@ -659,12 +752,16 @@ SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT StatementHandle,
static
SQLRETURN
doSQLExecDirect
(
SQLHSTMT
StatementHandle
,
SQLCHAR
*
StatementText
,
SQLINTEGER
TextLength
)
{
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
sql_t
*
sql
=
(
sql_t
*
)
StatementHandle
;
if
(
!
sql
)
return
SQL_INVALID_HANDLE
;
CHK_CONN
(
sql
);
CHK_CONN_TAOS
(
sql
);
conn_t
*
conn
=
sql
->
conn
;
NORM_STR_LENGTH
(
sql
,
StatementText
,
TextLength
);
if
(
sql
->
rs
)
{
...
...
@@ -684,10 +781,12 @@ static SQLRETURN doSQLExecDirect(SQLHSTMT StatementHandle,
}
sql
->
n_params
=
0
;
const
char
*
stxt
=
SDUP
(
StatementText
,
TextLength
);
tsdb_conv_t
*
client_to_server
=
tsdb_conn_client_to_server
(
conn
);
const
char
*
stxt
=
NULL
;
SQLRETURN
r
=
SQL_ERROR
;
do
{
tsdb_conv
(
client_to_server
,
&
buffer
,
(
const
char
*
)
StatementText
,
(
size_t
)
TextLength
,
&
stxt
,
NULL
);
if
(
!
stxt
)
{
SET_ERROR
(
sql
,
"HY001"
,
TSDB_CODE_ODBC_OOM
,
""
);
break
;
...
...
@@ -696,7 +795,7 @@ static SQLRETURN doSQLExecDirect(SQLHSTMT StatementHandle,
CHK_RS
(
r
,
sql
,
"failed to execute"
);
}
while
(
0
);
SFRE
(
stxt
,
StatementText
,
TextLength
);
tsdb_conv_free
(
client_to_server
,
stxt
,
&
buffer
,
(
const
char
*
)
StatementText
);
return
r
;
}
...
...
@@ -901,6 +1000,8 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
CHK_CONN
(
sql
);
CHK_CONN_TAOS
(
sql
);
conn_t
*
conn
=
sql
->
conn
;
if
(
!
sql
->
rs
)
{
SET_ERROR
(
sql
,
"HY000"
,
TSDB_CODE_ODBC_NO_RESULT
,
""
);
return
SQL_ERROR
;
...
...
@@ -911,8 +1012,6 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
return
SQL_ERROR
;
}
DASSERT
(
TargetValue
);
int
nfields
=
taos_field_count
(
sql
->
rs
);
TAOS_FIELD
*
fields
=
taos_fetch_fields
(
sql
->
rs
);
...
...
@@ -925,14 +1024,20 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
SET_ERROR
(
sql
,
"HY009"
,
TSDB_CODE_ODBC_BAD_ARG
,
"NULL TargetValue not allowed for col [%d]"
,
ColumnNumber
);
return
SQL_ERROR
;
}
if
(
BufferLength
<
0
)
{
SET_ERROR
(
sql
,
"HY090"
,
TSDB_CODE_ODBC_BAD_ARG
,
""
);
return
SQL_ERROR
;
}
TAOS_FIELD
*
field
=
fields
+
ColumnNumber
-
1
;
void
*
row
=
sql
->
row
[
ColumnNumber
-
1
];
if
(
!
row
)
{
if
(
StrLen_or_Ind
)
{
*
StrLen_or_Ind
=
SQL_NULL_DATA
;
if
(
!
StrLen_or_Ind
)
{
SET_ERROR
(
sql
,
"22002"
,
TSDB_CODE_ODBC_BAD_ARG
,
"NULL StrLen_or_Ind not allowed for col [%d]"
,
ColumnNumber
);
return
SQL_ERROR
;
}
*
StrLen_or_Ind
=
SQL_NULL_DATA
;
return
SQL_SUCCESS
;
}
...
...
@@ -981,7 +1086,11 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
CHK_CONV
(
0
,
tsdb_int64_to_double
(
v
,
TargetValue
));
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
0
,
tsdb_int64_to_char
(
v
,
TargetValue
,
(
size_t
)
BufferLength
));
tsdb_conv_t
*
utf8_to_client
=
tsdb_conn_utf8_to_client
(
conn
);
size_t
len
=
(
size_t
)
BufferLength
;
TSDB_CONV_CODE
code
=
tsdb_conv_write_int64
(
utf8_to_client
,
v
,
(
char
*
)
TargetValue
,
&
len
);
if
(
StrLen_or_Ind
)
*
StrLen_or_Ind
=
(
SQLLEN
)
len
;
CHK_CONV
(
0
,
code
);
}
break
;
default:
{
SET_ERROR
(
sql
,
"HYC00"
,
TSDB_CODE_ODBC_NOT_SUPPORT
,
...
...
@@ -1003,7 +1112,11 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
return
SQL_SUCCESS
;
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
0
,
tsdb_double_to_char
(
v
,
TargetValue
,
(
size_t
)
BufferLength
));
tsdb_conv_t
*
utf8_to_client
=
tsdb_conn_utf8_to_client
(
conn
);
size_t
len
=
(
size_t
)
BufferLength
;
TSDB_CONV_CODE
code
=
tsdb_conv_write_double
(
utf8_to_client
,
v
,
(
char
*
)
TargetValue
,
&
len
);
if
(
StrLen_or_Ind
)
*
StrLen_or_Ind
=
(
SQLLEN
)
len
;
CHK_CONV
(
0
,
code
);
}
break
;
default:
{
SET_ERROR
(
sql
,
"HYC00"
,
TSDB_CODE_ODBC_NOT_SUPPORT
,
...
...
@@ -1021,7 +1134,11 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
return
SQL_SUCCESS
;
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
0
,
tsdb_double_to_char
(
v
,
TargetValue
,
(
size_t
)
BufferLength
));
tsdb_conv_t
*
utf8_to_client
=
tsdb_conn_utf8_to_client
(
conn
);
size_t
len
=
(
size_t
)
BufferLength
;
TSDB_CONV_CODE
code
=
tsdb_conv_write_double
(
utf8_to_client
,
v
,
(
char
*
)
TargetValue
,
&
len
);
if
(
StrLen_or_Ind
)
*
StrLen_or_Ind
=
(
SQLLEN
)
len
;
CHK_CONV
(
0
,
code
);
}
break
;
default:
{
SET_ERROR
(
sql
,
"HYC00"
,
TSDB_CODE_ODBC_NOT_SUPPORT
,
...
...
@@ -1050,7 +1167,11 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
return
SQL_SUCCESS
;
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
0
,
tsdb_timestamp_to_char
(
ts
,
TargetValue
,
(
size_t
)
BufferLength
));
tsdb_conv_t
*
utf8_to_client
=
tsdb_conn_utf8_to_client
(
conn
);
size_t
len
=
(
size_t
)
BufferLength
;
TSDB_CONV_CODE
code
=
tsdb_conv_write_timestamp
(
utf8_to_client
,
ts
,
(
char
*
)
TargetValue
,
&
len
);
if
(
StrLen_or_Ind
)
*
StrLen_or_Ind
=
(
SQLLEN
)
len
;
CHK_CONV
(
0
,
code
);
}
break
;
case
SQL_C_TYPE_TIMESTAMP
:
case
SQL_C_TIMESTAMP
:
{
...
...
@@ -1070,7 +1191,14 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
field_bytes
-=
VARSTR_HEADER_SIZE
;
switch
(
target
.
ct
)
{
case
SQL_C_CHAR
:
{
CHK_CONV
(
0
,
tsdb_chars_to_char
((
const
char
*
)
row
,
field_bytes
,
TargetValue
,
(
size_t
)
BufferLength
));
tsdb_conv_t
*
server_to_client
=
tsdb_conn_server_to_client
(
conn
);
size_t
slen
=
strnlen
((
const
char
*
)
row
,
field_bytes
);
size_t
len
=
(
size_t
)
BufferLength
;
TSDB_CONV_CODE
code
=
tsdb_conv_write
(
server_to_client
,
(
const
char
*
)
row
,
&
slen
,
(
char
*
)
TargetValue
,
&
len
);
if
(
StrLen_or_Ind
)
*
StrLen_or_Ind
=
(
SQLLEN
)((
size_t
)
BufferLength
-
len
);
CHK_CONV
(
0
,
code
);
}
break
;
default:
{
SET_ERROR
(
sql
,
"HYC00"
,
TSDB_CODE_ODBC_NOT_SUPPORT
,
...
...
@@ -1085,7 +1213,14 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
field_bytes
-=
VARSTR_HEADER_SIZE
;
switch
(
target
.
ct
)
{
case
SQL_C_CHAR
:
{
CHK_CONV
(
0
,
tsdb_chars_to_char
((
const
char
*
)
row
,
field_bytes
,
TargetValue
,
(
size_t
)
BufferLength
));
tsdb_conv_t
*
server_to_client
=
tsdb_conn_server_to_client
(
conn
);
size_t
slen
=
strnlen
((
const
char
*
)
row
,
field_bytes
);
size_t
len
=
(
size_t
)
BufferLength
;
TSDB_CONV_CODE
code
=
tsdb_conv_write
(
server_to_client
,
(
const
char
*
)
row
,
&
slen
,
(
char
*
)
TargetValue
,
&
len
);
if
(
StrLen_or_Ind
)
*
StrLen_or_Ind
=
(
SQLLEN
)((
size_t
)
BufferLength
-
len
);
CHK_CONV
(
0
,
code
);
}
break
;
default:
{
SET_ERROR
(
sql
,
"HYC00"
,
TSDB_CODE_ODBC_NOT_SUPPORT
,
...
...
@@ -1144,12 +1279,16 @@ SQLRETURN SQL_API SQLFetch(SQLHSTMT StatementHandle)
static
SQLRETURN
doSQLPrepare
(
SQLHSTMT
StatementHandle
,
SQLCHAR
*
StatementText
,
SQLINTEGER
TextLength
)
{
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
sql_t
*
sql
=
(
sql_t
*
)
StatementHandle
;
if
(
!
sql
)
return
SQL_INVALID_HANDLE
;
CHK_CONN
(
sql
);
CHK_CONN_TAOS
(
sql
);
conn_t
*
conn
=
sql
->
conn
;
NORM_STR_LENGTH
(
sql
,
StatementText
,
TextLength
);
if
(
sql
->
rs
)
{
...
...
@@ -1177,9 +1316,17 @@ static SQLRETURN doSQLPrepare(SQLHSTMT StatementHandle,
break
;
}
tsdb_conv_t
*
client_to_server
=
tsdb_conn_client_to_server
(
conn
);
const
char
*
stxt
=
NULL
;
int
ok
=
0
;
do
{
int
r
=
taos_stmt_prepare
(
sql
->
stmt
,
(
const
char
*
)
StatementText
,
(
unsigned
long
)
TextLength
);
tsdb_conv
(
client_to_server
,
&
buffer
,
(
const
char
*
)
StatementText
,
(
size_t
)
TextLength
,
&
stxt
,
NULL
);
if
((
!
stxt
))
{
SET_ERROR
(
sql
,
"HY001"
,
TSDB_CODE_ODBC_OOM
,
""
);
break
;
}
int
r
=
taos_stmt_prepare
(
sql
->
stmt
,
stxt
,
(
unsigned
long
)
strlen
(
stxt
));
if
(
r
)
{
SET_ERROR
(
sql
,
"HY000"
,
r
,
"failed to prepare a TAOS statement"
);
break
;
...
...
@@ -1216,6 +1363,8 @@ static SQLRETURN doSQLPrepare(SQLHSTMT StatementHandle,
ok
=
1
;
}
while
(
0
);
tsdb_conv_free
(
client_to_server
,
stxt
,
&
buffer
,
(
const
char
*
)
StatementText
);
if
(
!
ok
)
{
taos_stmt_close
(
sql
->
stmt
);
sql
->
stmt
=
NULL
;
...
...
@@ -1245,6 +1394,16 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
SET_ERROR
(
sql
,
"HY000"
,
TSDB_CODE_ODBC_NOT_SUPPORT
,
"parameter [@%d] not bound yet"
,
idx
+
1
);
return
SQL_ERROR
;
}
if
(
param
->
ParameterValue
==
NULL
)
{
SET_ERROR
(
sql
,
"HY009"
,
TSDB_CODE_ODBC_BAD_ARG
,
"ParameterValue [@%p] not allowed"
,
param
->
ParameterValue
);
return
SQL_ERROR
;
}
if
(
param
->
StrLen_or_Ind
==
NULL
)
{
SET_ERROR
(
sql
,
"HY009"
,
TSDB_CODE_ODBC_BAD_ARG
,
"StrLen_or_Ind [@%p] not allowed"
,
param
->
StrLen_or_Ind
);
return
SQL_ERROR
;
}
conn_t
*
conn
=
sql
->
conn
;
unsigned
char
*
paramValue
=
param
->
ParameterValue
;
SQLSMALLINT
valueType
=
param
->
ValueType
;
...
...
@@ -1252,11 +1411,11 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
size_t
offset
=
((
size_t
)
idx_row
)
*
sql
->
rowlen
+
sql
->
ptr_offset
;
if
(
paramValue
)
paramValue
+=
offset
;
if
(
soi
)
soi
=
(
SQLLEN
*
)((
char
*
)
soi
+
offset
);
paramValue
+=
offset
;
soi
=
(
SQLLEN
*
)((
char
*
)
soi
+
offset
);
if
(
soi
&&
*
soi
==
SQL_NULL_DATA
)
{
if
(
*
soi
==
SQL_NULL_DATA
)
{
bind
->
is_null
=
(
int
*
)
&
yes
;
return
SQL_SUCCESS
;
}
...
...
@@ -1271,6 +1430,7 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
}
}
else
{
switch
(
valueType
)
{
case
SQL_C_SLONG
:
case
SQL_C_LONG
:
{
type
=
TSDB_DATA_TYPE_INT
;
}
break
;
...
...
@@ -1282,7 +1442,6 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
case
SQL_C_SHORT
:
case
SQL_C_SSHORT
:
case
SQL_C_USHORT
:
case
SQL_C_SLONG
:
case
SQL_C_ULONG
:
case
SQL_C_FLOAT
:
case
SQL_C_DOUBLE
:
...
...
@@ -1344,7 +1503,12 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
CHK_CONV
(
1
,
tsdb_double_to_bit
(
*
(
double
*
)
paramValue
,
&
bind
->
u
.
b
));
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
1
,
tsdb_chars_to_bit
((
const
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
b
));
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
client_to_utf8
=
tsdb_conn_client_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_bit
(
client_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
b
));
// CHK_CONV(1, tsdb_chars_to_bit((const char *)paramValue, (size_t)*soi, &bind->u.b));
}
break
;
case
SQL_C_WCHAR
:
{
CHK_CONV
(
1
,
tsdb_wchars_to_bit
(
sql_get_w2c
(
sql
),
(
const
unsigned
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
b
));
...
...
@@ -1396,7 +1560,12 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
CHK_CONV
(
1
,
tsdb_int64_to_tinyint
(
*
(
int64_t
*
)
paramValue
,
&
bind
->
u
.
v1
));
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
1
,
tsdb_chars_to_tinyint
((
const
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
v1
));
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
client_to_utf8
=
tsdb_conn_client_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_tinyint
(
client_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
v1
));
// CHK_CONV(1, tsdb_chars_to_tinyint((const char *)paramValue, (size_t)*soi, &bind->u.v1));
}
break
;
case
SQL_C_WCHAR
:
{
CHK_CONV
(
1
,
tsdb_wchars_to_tinyint
(
sql_get_w2c
(
sql
),
(
const
unsigned
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
v1
));
...
...
@@ -1450,7 +1619,12 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
CHK_CONV
(
1
,
tsdb_int64_to_smallint
(
*
(
int64_t
*
)
paramValue
,
&
bind
->
u
.
v2
));
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
1
,
tsdb_chars_to_smallint
((
const
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
v2
));
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
client_to_utf8
=
tsdb_conn_client_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_smallint
(
client_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
v2
));
// CHK_CONV(1, tsdb_chars_to_smallint((const char*)paramValue, (size_t)*soi, &bind->u.v2));
}
break
;
case
SQL_C_WCHAR
:
{
CHK_CONV
(
1
,
tsdb_wchars_to_smallint
(
sql_get_w2c
(
sql
),
(
const
unsigned
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
v2
));
...
...
@@ -1504,7 +1678,12 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
CHK_CONV
(
1
,
tsdb_int64_to_int
(
*
(
int64_t
*
)
paramValue
,
&
bind
->
u
.
v4
));
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
1
,
tsdb_chars_to_int
((
const
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
v4
));
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
client_to_utf8
=
tsdb_conn_client_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_int
(
client_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
v4
));
// CHK_CONV(1, tsdb_chars_to_int((const char*)paramValue, (size_t)*soi, &bind->u.v4));
}
break
;
case
SQL_C_WCHAR
:
{
CHK_CONV
(
1
,
tsdb_wchars_to_int
(
sql_get_w2c
(
sql
),
(
const
unsigned
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
v4
));
...
...
@@ -1558,7 +1737,12 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
CHK_CONV
(
1
,
tsdb_int64_to_bigint
(
*
(
int64_t
*
)
paramValue
,
&
bind
->
u
.
v8
));
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
1
,
tsdb_chars_to_bigint
((
const
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
v8
));
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
client_to_utf8
=
tsdb_conn_client_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_bigint
(
client_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
v8
));
// CHK_CONV(1, tsdb_chars_to_bigint((const char*)paramValue, (size_t)*soi, &bind->u.v8));
}
break
;
case
SQL_C_WCHAR
:
{
CHK_CONV
(
1
,
tsdb_wchars_to_bigint
(
sql_get_w2c
(
sql
),
(
const
unsigned
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
v8
));
...
...
@@ -1618,10 +1802,20 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
bind
->
u
.
f4
=
(
float
)
*
(
double
*
)
paramValue
;
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
1
,
tsdb_chars_to_float
((
const
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
f4
));
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
client_to_utf8
=
tsdb_conn_client_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_float
(
client_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
f4
));
// CHK_CONV(1, tsdb_chars_to_float((const char*)paramValue, (size_t)*soi, &bind->u.f4));
}
break
;
case
SQL_C_WCHAR
:
{
CHK_CONV
(
1
,
tsdb_wchars_to_float
(
sql_get_w2c
(
sql
),
(
const
unsigned
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
f4
));
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
utf16_to_utf8
=
tsdb_conn_utf16_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
DASSERT
(
slen
!=
SQL_NTS
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_float
(
utf16_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
f4
));
// CHK_CONV(1, tsdb_wchars_to_float(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.f4));
}
break
;
case
SQL_C_USHORT
:
case
SQL_C_ULONG
:
...
...
@@ -1676,10 +1870,20 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
bind
->
u
.
f8
=
*
(
double
*
)
paramValue
;
}
break
;
case
SQL_C_CHAR
:
{
CHK_CONV
(
1
,
tsdb_chars_to_double
((
const
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
f8
));
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
client_to_utf8
=
tsdb_conn_client_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_double
(
client_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
f8
));
// CHK_CONV(1, tsdb_chars_to_double((const char*)paramValue, (size_t)*soi, &bind->u.f8));
}
break
;
case
SQL_C_WCHAR
:
{
CHK_CONV
(
1
,
tsdb_wchars_to_double
(
sql_get_w2c
(
sql
),
(
const
unsigned
char
*
)
paramValue
,
(
size_t
)
*
soi
,
&
bind
->
u
.
f8
));
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
utf16_to_utf8
=
tsdb_conn_utf16_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
DASSERT
(
slen
!=
SQL_NTS
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_double
(
utf16_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
f8
));
// CHK_CONV(1, tsdb_wchars_to_double(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.f8));
}
break
;
case
SQL_C_USHORT
:
case
SQL_C_ULONG
:
...
...
@@ -1703,30 +1907,30 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
}
break
;
}
}
break
;
case
TSDB_DATA_TYPE_
BINARY
:
{
case
TSDB_DATA_TYPE_
TIMESTAMP
:
{
bind
->
buffer_type
=
type
;
bind
->
buffer_length
=
sizeof
(
bind
->
u
.
v8
);
bind
->
buffer
=
&
bind
->
u
.
v8
;
bind
->
length
=
&
bind
->
buffer_length
;
switch
(
valueType
)
{
case
SQL_C_CHAR
:
{
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
client_to_utf8
=
tsdb_conn_client_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
DASSERT
(
slen
!=
SQL_NTS
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_timestamp_ts
(
client_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
v8
));
}
break
;
case
SQL_C_WCHAR
:
{
DASSERT
(
soi
);
DASSERT
(
*
soi
!=
SQL_NTS
);
size_t
bytes
=
0
;
SQLCHAR
*
utf8
=
wchars_to_chars
((
const
SQLWCHAR
*
)
paramValue
,
(
size_t
)
*
soi
/
2
,
&
bytes
);
bind
->
allocated
=
1
;
bind
->
u
.
bin
=
utf8
;
bind
->
buffer_length
=
bytes
;
bind
->
buffer
=
bind
->
u
.
bin
;
}
break
;
case
SQL_C_BINARY
:
{
bind
->
u
.
bin
=
(
unsigned
char
*
)
paramValue
;
if
(
*
soi
==
SQL_NTS
)
{
bind
->
buffer_length
=
strlen
((
const
char
*
)
paramValue
);
}
else
{
bind
->
buffer_length
=
(
uintptr_t
)
*
soi
;
}
bind
->
buffer
=
bind
->
u
.
bin
;
stack_buffer_t
buffer
;
buffer
.
next
=
0
;
tsdb_conv_t
*
utf16_to_utf8
=
tsdb_conn_utf16_to_utf8
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
DASSERT
(
slen
!=
SQL_NTS
);
CHK_CONV
(
1
,
tsdb_conv_chars_to_timestamp_ts
(
utf16_to_utf8
,
&
buffer
,
(
const
char
*
)
paramValue
,
slen
,
&
bind
->
u
.
v8
));
}
break
;
case
SQL_C_SBIGINT
:
{
int64_t
t
=
*
(
int64_t
*
)
paramValue
;
bind
->
u
.
v8
=
t
;
}
break
;
case
SQL_C_CHAR
:
case
SQL_C_SHORT
:
case
SQL_C_SSHORT
:
case
SQL_C_USHORT
:
...
...
@@ -1735,12 +1939,12 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
case
SQL_C_ULONG
:
case
SQL_C_FLOAT
:
case
SQL_C_DOUBLE
:
case
SQL_C_BIT
:
case
SQL_C_TINYINT
:
case
SQL_C_STINYINT
:
case
SQL_C_UTINYINT
:
case
SQL_C_SBIGINT
:
case
SQL_C_UBIGINT
:
case
SQL_C_BI
T
:
case
SQL_C_BI
NARY
:
case
SQL_C_DATE
:
case
SQL_C_TIME
:
case
SQL_C_TIMESTAMP
:
...
...
@@ -1758,34 +1962,50 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
}
break
;
}
}
break
;
case
TSDB_DATA_TYPE_
TIMESTAMP
:
{
case
TSDB_DATA_TYPE_
BINARY
:
{
bind
->
buffer_type
=
type
;
bind
->
buffer_length
=
sizeof
(
bind
->
u
.
v8
);
bind
->
buffer
=
&
bind
->
u
.
v8
;
bind
->
length
=
&
bind
->
buffer_length
;
switch
(
valueType
)
{
case
SQL_C_WCHAR
:
{
DASSERT
(
soi
);
DASSERT
(
*
soi
!=
SQL_NTS
);
size_t
bytes
=
0
;
int
r
=
0
;
int64_t
t
=
0
;
SQLCHAR
*
utf8
=
wchars_to_chars
((
const
SQLWCHAR
*
)
paramValue
,
(
size_t
)
*
soi
/
2
,
&
bytes
);
// why cast utf8 to 'char*' ?
r
=
taosParseTime
((
char
*
)
utf8
,
&
t
,
(
int
)
strlen
((
const
char
*
)
utf8
),
TSDB_TIME_PRECISION_MILLI
,
0
);
bind
->
u
.
v8
=
t
;
free
(
utf8
);
if
(
r
)
{
SET_ERROR
(
sql
,
"22007"
,
TSDB_CODE_ODBC_OUT_OF_RANGE
,
"convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d] failed"
,
sql_c_type
(
valueType
),
valueType
,
valueType
,
taos_data_type
(
type
),
type
,
type
,
idx
+
1
);
return
SQL_ERROR
;
tsdb_conv_t
*
utf16_to_server
=
tsdb_conn_utf16_to_server
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
DASSERT
(
slen
!=
SQL_NTS
);
const
char
*
buf
=
NULL
;
size_t
blen
=
0
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
utf16_to_server
,
NULL
,
(
const
char
*
)
paramValue
,
slen
,
&
buf
,
&
blen
);
if
(
code
==
TSDB_CONV_OK
)
{
if
(
buf
!=
(
const
char
*
)
paramValue
)
{
bind
->
allocated
=
1
;
}
bind
->
u
.
bin
=
(
unsigned
char
*
)
buf
;
bind
->
buffer_length
=
blen
;
bind
->
buffer
=
bind
->
u
.
bin
;
}
CHK_CONV
(
1
,
code
);
}
break
;
case
SQL_C_SBIGINT
:
{
int64_t
t
=
*
(
int64_t
*
)
paramValue
;
bind
->
u
.
v8
=
t
;
case
SQL_C_CHAR
:
{
tsdb_conv_t
*
client_to_server
=
tsdb_conn_client_to_server
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
const
char
*
buf
=
NULL
;
size_t
blen
=
0
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
client_to_server
,
NULL
,
(
const
char
*
)
paramValue
,
slen
,
&
buf
,
&
blen
);
if
(
code
==
TSDB_CONV_OK
)
{
if
(
buf
!=
(
const
char
*
)
paramValue
)
{
bind
->
allocated
=
1
;
}
bind
->
u
.
bin
=
(
unsigned
char
*
)
buf
;
bind
->
buffer_length
=
blen
;
bind
->
buffer
=
bind
->
u
.
bin
;
}
CHK_CONV
(
1
,
code
);
// bind->u.bin = (unsigned char*)paramValue;
// if (*soi == SQL_NTS) {
// bind->buffer_length = strlen((const char*)paramValue);
// } else {
// bind->buffer_length = (uintptr_t)*soi;
// }
// bind->buffer = bind->u.bin;
}
break
;
case
SQL_C_SHORT
:
case
SQL_C_SSHORT
:
...
...
@@ -1795,11 +2015,12 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
case
SQL_C_ULONG
:
case
SQL_C_FLOAT
:
case
SQL_C_DOUBLE
:
case
SQL_C_BIT
:
case
SQL_C_TINYINT
:
case
SQL_C_STINYINT
:
case
SQL_C_UTINYINT
:
case
SQL_C_SBIGINT
:
case
SQL_C_UBIGINT
:
case
SQL_C_BIT
:
case
SQL_C_BINARY
:
case
SQL_C_DATE
:
case
SQL_C_TIME
:
...
...
@@ -1823,23 +2044,45 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
bind
->
length
=
&
bind
->
buffer_length
;
switch
(
valueType
)
{
case
SQL_C_WCHAR
:
{
DASSERT
(
soi
);
DASSERT
(
*
soi
!=
SQL_NTS
);
size_t
bytes
=
0
;
SQLCHAR
*
utf8
=
wchars_to_chars
((
const
SQLWCHAR
*
)
paramValue
,
(
size_t
)(
*
soi
/
2
),
&
bytes
);
bind
->
allocated
=
1
;
bind
->
u
.
nchar
=
(
char
*
)
utf8
;
bind
->
buffer_length
=
bytes
;
bind
->
buffer
=
bind
->
u
.
nchar
;
tsdb_conv_t
*
utf16_to_server
=
tsdb_conn_utf16_to_server
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
const
char
*
buf
=
NULL
;
size_t
blen
=
0
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
utf16_to_server
,
NULL
,
(
const
char
*
)
paramValue
,
slen
,
&
buf
,
&
blen
);
if
(
code
==
TSDB_CONV_OK
)
{
if
(
buf
!=
(
const
char
*
)
paramValue
)
{
bind
->
allocated
=
1
;
}
bind
->
u
.
nchar
=
(
char
*
)
buf
;
bind
->
buffer_length
=
blen
;
bind
->
buffer
=
bind
->
u
.
nchar
;
}
CHK_CONV
(
1
,
code
);
}
break
;
case
SQL_C_CHAR
:
{
bind
->
u
.
nchar
=
(
char
*
)
paramValue
;
if
(
*
soi
==
SQL_NTS
)
{
bind
->
buffer_length
=
strlen
((
const
char
*
)
paramValue
);
}
else
{
bind
->
buffer_length
=
(
uintptr_t
)
*
soi
;
tsdb_conv_t
*
client_to_server
=
tsdb_conn_client_to_server
(
conn
);
size_t
slen
=
(
size_t
)
*
soi
;
if
(
slen
==
SQL_NTS
)
slen
=
strlen
((
const
char
*
)
paramValue
);
const
char
*
buf
=
NULL
;
size_t
blen
=
0
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
client_to_server
,
NULL
,
(
const
char
*
)
paramValue
,
slen
,
&
buf
,
&
blen
);
if
(
code
==
TSDB_CONV_OK
)
{
if
(
buf
!=
(
const
char
*
)
paramValue
)
{
bind
->
allocated
=
1
;
}
bind
->
u
.
bin
=
(
unsigned
char
*
)
buf
;
bind
->
buffer_length
=
blen
;
bind
->
buffer
=
bind
->
u
.
bin
;
}
bind
->
buffer
=
bind
->
u
.
nchar
;
CHK_CONV
(
1
,
code
);
// bind->u.nchar = (char*)paramValue;
// if (*soi == SQL_NTS) {
// bind->buffer_length = strlen((const char*)paramValue);
// } else {
// bind->buffer_length = (uintptr_t)*soi;
// }
// bind->buffer = bind->u.nchar;
}
break
;
case
SQL_C_SHORT
:
case
SQL_C_SSHORT
:
...
...
@@ -2110,6 +2353,16 @@ static SQLRETURN doSQLBindParameter(
return
SQL_ERROR
;
}
if
(
ParameterValue
==
NULL
)
{
SET_ERROR
(
sql
,
"HY009"
,
TSDB_CODE_ODBC_BAD_ARG
,
"ParameterValue [@%p] not allowed"
,
ParameterValue
);
return
SQL_ERROR
;
}
if
(
StrLen_or_Ind
==
NULL
)
{
SET_ERROR
(
sql
,
"HY009"
,
TSDB_CODE_ODBC_BAD_ARG
,
"StrLen_or_Ind [@%p] not allowed"
,
StrLen_or_Ind
);
return
SQL_ERROR
;
}
param_bind_t
*
pb
=
sql
->
params
+
ParameterNumber
-
1
;
pb
->
ParameterNumber
=
ParameterNumber
;
...
...
@@ -2171,12 +2424,7 @@ static SQLRETURN doSQLDriverConnect(
const
char
*
connStr
=
SDUP
(
szConnStrIn
,
cbConnStrIn
);
char
*
serverName
=
NULL
;
char
*
userName
=
NULL
;
char
*
auth
=
NULL
;
char
*
host
=
NULL
;
char
*
ip
=
NULL
;
int
port
=
0
;
conn_val_t
val
=
{
0
};
do
{
if
(
szConnStrIn
&&
!
connStr
)
{
...
...
@@ -2184,22 +2432,37 @@ static SQLRETURN doSQLDriverConnect(
break
;
}
int
n
=
todbc_parse_conn_string
((
const
char
*
)
connStr
,
&
serverName
,
&
userName
,
&
auth
,
&
host
);
int
n
=
todbc_parse_conn_string
((
const
char
*
)
connStr
,
&
val
);
if
(
n
)
{
SET_ERROR
(
conn
,
"HY000"
,
TSDB_CODE_ODBC_BAD_CONNSTR
,
"unrecognized connection string: [%s]"
,
(
const
char
*
)
szConnStrIn
);
break
;
}
if
(
host
)
{
char
*
p
=
strchr
(
host
,
':'
);
char
*
ip
=
NULL
;
int
port
=
0
;
if
(
val
.
host
)
{
char
*
p
=
strchr
(
val
.
host
,
':'
);
if
(
p
)
{
ip
=
strndup
(
host
,
(
size_t
)(
p
-
host
));
ip
=
strndup
(
val
.
host
,
(
size_t
)(
p
-
val
.
host
));
port
=
atoi
(
p
+
1
);
}
}
if
((
val
.
cli_enc
&&
strcmp
(
val
.
cli_enc
,
conn
->
client_enc
))
||
(
val
.
svr_enc
&&
strcmp
(
val
.
svr_enc
,
conn
->
server_enc
))
)
{
tsdb_conn_close_convs
(
conn
);
if
(
val
.
cli_enc
)
{
snprintf
(
conn
->
client_enc
,
sizeof
(
conn
->
client_enc
),
"%s"
,
val
.
cli_enc
);
}
if
(
val
.
svr_enc
)
{
snprintf
(
conn
->
server_enc
,
sizeof
(
conn
->
server_enc
),
"%s"
,
val
.
svr_enc
);
}
}
// TODO: data-race
// TODO: shall receive ip/port from odbc.ini
conn
->
taos
=
taos_connect
(
ip
?
ip
:
"localhost"
,
userName
,
auth
,
NULL
,
(
uint16_t
)
port
);
// shall we support non-ansi uid/pwd/db etc?
conn
->
taos
=
taos_connect
(
ip
?
ip
:
"localhost"
,
val
.
uid
,
val
.
pwd
,
val
.
db
,
(
uint16_t
)
port
);
free
(
ip
);
ip
=
NULL
;
if
(
!
conn
->
taos
)
{
SET_ERROR
(
conn
,
"HY000"
,
terrno
,
"failed to connect to data source"
);
...
...
@@ -2212,12 +2475,9 @@ static SQLRETURN doSQLDriverConnect(
if
(
pcbConnStrOut
)
{
*
pcbConnStrOut
=
cbConnStrIn
;
}
}
while
(
0
);
if
(
serverName
)
free
(
serverName
);
if
(
userName
)
free
(
userName
);
if
(
auth
)
free
(
auth
);
conn_val_reset
(
&
val
);
SFRE
(
connStr
,
szConnStrIn
,
cbConnStrIn
);
...
...
src/connector/odbc/src/todbc_conv.c
浏览文件 @
f43bbfea
...
...
@@ -15,6 +15,8 @@
#include "todbc_conv.h"
#include "todbc_log.h"
#include <errno.h>
#include <limits.h>
#include <stdio.h>
...
...
@@ -53,11 +55,13 @@ static void buf_clean(buf_t *buf) {
const
char
*
tsdb_conv_code_str
(
TSDB_CONV_CODE
code
)
{
switch
(
code
)
{
case
TSDB_CONV_OK
:
return
"TSDB_CONV_OK"
;
case
TSDB_CONV_NOT_AVAIL
:
return
"TSDB_CONV_NOT_AVAIL"
;
case
TSDB_CONV_OOM
:
return
"TSDB_CONV_OOM"
;
case
TSDB_CONV_OOR
:
return
"TSDB_CONV_OOR"
;
case
TSDB_CONV_TRUNC_FRACTION
:
return
"TSDB_CONV_TRUNC_FRACTION"
;
case
TSDB_CONV_TRUNC
:
return
"TSDB_CONV_TRUNC"
;
case
TSDB_CONV_CHAR_NOT_NUM
:
return
"TSDB_CONV_CHAR_NOT_NUM"
;
case
TSDB_CONV_CHAR_NOT_TS
:
return
"TSDB_CONV_CHAR_NOT_TS"
;
case
TSDB_CONV_GENERAL
:
return
"TSDB_CONV_GENERAL"
;
case
TSDB_CONV_BAD_CHAR
:
return
"TSDB_CONV_BAD_CHAR"
;
default:
return
"UNKNOWN"
;
...
...
@@ -154,6 +158,7 @@ TSDB_CONV_CODE tsdb_int64_to_double(int64_t src, double *dst) {
TSDB_CONV_CODE
tsdb_int64_to_char
(
int64_t
src
,
char
*
dst
,
size_t
dlen
)
{
int
n
=
snprintf
(
dst
,
dlen
,
"%"
PRId64
""
,
src
);
DASSERT
(
n
>=
0
);
if
(
n
<
dlen
)
return
TSDB_CONV_OK
;
...
...
@@ -238,6 +243,7 @@ TSDB_CONV_CODE tsdb_double_to_ts(double src, int64_t *dst) {
TSDB_CONV_CODE
tsdb_double_to_char
(
double
src
,
char
*
dst
,
size_t
dlen
)
{
int
n
=
snprintf
(
dst
,
dlen
,
"%lg"
,
src
);
DASSERT
(
n
>=
0
);
if
(
n
<
dlen
)
return
TSDB_CONV_OK
;
...
...
@@ -250,6 +256,7 @@ TSDB_CONV_CODE tsdb_timestamp_to_char(SQL_TIMESTAMP_STRUCT src, char *dst, size_
src
.
year
,
src
.
month
,
src
.
day
,
src
.
hour
,
src
.
minute
,
src
.
second
,
src
.
fraction
/
1000000
);
DASSERT
(
n
>=
0
);
if
(
n
<
dlen
)
return
TSDB_CONV_OK
;
if
(
strlen
(
dst
)
>=
19
)
return
TSDB_CONV_TRUNC_FRACTION
;
...
...
@@ -374,8 +381,43 @@ TSDB_CONV_CODE tsdb_chars_to_double(const char *src, size_t smax, double *dst) {
return
TSDB_CONV_CHAR_NOT_NUM
;
}
TSDB_CONV_CODE
tsdb_chars_to_timestamp
(
const
char
*
src
,
size_t
smax
,
SQL_TIMESTAMP_STRUCT
*
dst
)
{
int64_t
v
=
0
;
// why cast to 'char*' ?
int
r
=
taosParseTime
((
char
*
)
src
,
&
v
,
(
int32_t
)
smax
,
TSDB_TIME_PRECISION_MILLI
,
0
);
if
(
r
)
{
return
TSDB_CONV_CHAR_NOT_TS
;
}
time_t
t
=
v
/
1000
;
struct
tm
vtm
=
{
0
};
localtime_r
(
&
t
,
&
vtm
);
dst
->
year
=
(
SQLSMALLINT
)(
vtm
.
tm_year
+
1900
);
dst
->
month
=
(
SQLUSMALLINT
)(
vtm
.
tm_mon
+
1
);
dst
->
day
=
(
SQLUSMALLINT
)(
vtm
.
tm_mday
);
dst
->
hour
=
(
SQLUSMALLINT
)(
vtm
.
tm_hour
);
dst
->
minute
=
(
SQLUSMALLINT
)(
vtm
.
tm_min
);
dst
->
second
=
(
SQLUSMALLINT
)(
vtm
.
tm_sec
);
dst
->
fraction
=
(
SQLUINTEGER
)(
v
%
1000
*
1000000
);
return
TSDB_CONV_OK
;
}
TSDB_CONV_CODE
tsdb_chars_to_timestamp_ts
(
const
char
*
src
,
size_t
smax
,
int64_t
*
dst
)
{
// why cast to 'char*' ?
int
r
=
taosParseTime
((
char
*
)
src
,
dst
,
(
int32_t
)
smax
,
TSDB_TIME_PRECISION_MILLI
,
0
);
if
(
r
)
{
return
TSDB_CONV_CHAR_NOT_TS
;
}
return
TSDB_CONV_OK
;
}
TSDB_CONV_CODE
tsdb_chars_to_char
(
const
char
*
src
,
size_t
smax
,
char
*
dst
,
size_t
dmax
)
{
int
n
=
snprintf
(
dst
,
dmax
,
"%s"
,
src
);
DASSERT
(
n
>=
0
);
if
(
n
<
dmax
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_TRUNC
;
...
...
@@ -524,5 +566,264 @@ TSDB_CONV_CODE tsdb_wchars_to_char(iconv_t cnv, const unsigned char *src, size_t
return
tsdb_iconv_conv
(
cnv
,
src
,
&
smax
,
(
unsigned
char
*
)
dst
,
&
dmax
);
}
char
*
stack_buffer_alloc
(
stack_buffer_t
*
buffer
,
size_t
bytes
)
{
if
(
!
buffer
)
return
NULL
;
// align-by-size_of-size_t-bytes
if
(
bytes
==
0
)
bytes
=
sizeof
(
size_t
);
bytes
=
(
bytes
+
sizeof
(
size_t
)
-
1
)
/
sizeof
(
size_t
)
*
sizeof
(
size_t
);
size_t
next
=
buffer
->
next
+
bytes
;
if
(
next
>
sizeof
(
buffer
->
buf
))
return
NULL
;
char
*
p
=
buffer
->
buf
+
buffer
->
next
;
buffer
->
next
=
next
;
return
p
;
}
int
is_owned_by_stack_buffer
(
stack_buffer_t
*
buffer
,
const
char
*
ptr
)
{
if
(
!
buffer
)
return
0
;
if
(
ptr
>=
buffer
->
buf
&&
ptr
<
buffer
->
buf
+
buffer
->
next
)
return
1
;
return
0
;
}
struct
tsdb_conv_s
{
iconv_t
cnv
;
unsigned
int
direct
:
1
;
};
tsdb_conv_t
*
tsdb_conv_open
(
const
char
*
from_enc
,
const
char
*
to_enc
)
{
tsdb_conv_t
*
cnv
=
(
tsdb_conv_t
*
)
calloc
(
1
,
sizeof
(
*
cnv
));
if
(
!
cnv
)
return
NULL
;
if
(
strcmp
(
from_enc
,
to_enc
)
==
0
)
{
cnv
->
cnv
=
(
iconv_t
)
-
1
;
cnv
->
direct
=
1
;
return
cnv
;
}
cnv
->
cnv
=
iconv_open
(
to_enc
,
from_enc
);
if
(
cnv
->
cnv
==
(
iconv_t
)
-
1
)
{
free
(
cnv
);
return
NULL
;
}
cnv
->
direct
=
0
;
return
cnv
;
}
void
tsdb_conv_close
(
tsdb_conv_t
*
cnv
)
{
if
(
!
cnv
)
return
;
if
(
!
cnv
->
direct
)
{
if
(
cnv
->
cnv
!=
(
iconv_t
)
-
1
)
{
iconv_close
(
cnv
->
cnv
);
}
}
cnv
->
cnv
=
(
iconv_t
)
-
1
;
cnv
->
direct
=
0
;
free
(
cnv
);
}
TSDB_CONV_CODE
tsdb_conv_write
(
tsdb_conv_t
*
cnv
,
const
char
*
src
,
size_t
*
slen
,
char
*
dst
,
size_t
*
dlen
)
{
if
(
!
cnv
)
return
TSDB_CONV_NOT_AVAIL
;
if
(
cnv
->
direct
)
{
size_t
n
=
(
*
slen
>
*
dlen
)
?
*
dlen
:
*
slen
;
memcpy
(
dst
,
src
,
n
);
*
slen
-=
n
;
*
dlen
-=
n
;
if
(
*
dlen
)
dst
[
n
]
=
'\0'
;
return
TSDB_CONV_OK
;
}
if
(
!
cnv
->
cnv
)
return
TSDB_CONV_NOT_AVAIL
;
size_t
r
=
iconv
(
cnv
->
cnv
,
(
char
**
)
&
src
,
slen
,
&
dst
,
dlen
);
if
(
r
==
(
size_t
)
-
1
)
return
TSDB_CONV_BAD_CHAR
;
if
(
*
slen
)
return
TSDB_CONV_TRUNC
;
if
(
*
dlen
)
*
dst
=
'\0'
;
return
TSDB_CONV_OK
;
}
TSDB_CONV_CODE
tsdb_conv_write_int64
(
tsdb_conv_t
*
cnv
,
int64_t
val
,
char
*
dst
,
size_t
*
dlen
)
{
char
utf8
[
64
];
int
n
=
snprintf
(
utf8
,
sizeof
(
utf8
),
"%"
PRId64
""
,
val
);
DASSERT
(
n
>=
0
);
DASSERT
(
n
<
sizeof
(
utf8
));
size_t
len
=
(
size_t
)
n
;
TSDB_CONV_CODE
code
=
tsdb_conv_write
(
cnv
,
utf8
,
&
len
,
dst
,
dlen
);
*
dlen
=
(
size_t
)
n
+
1
;
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_write_double
(
tsdb_conv_t
*
cnv
,
double
val
,
char
*
dst
,
size_t
*
dlen
)
{
char
utf8
[
256
];
int
n
=
snprintf
(
utf8
,
sizeof
(
utf8
),
"%g"
,
val
);
DASSERT
(
n
>=
0
);
DASSERT
(
n
<
sizeof
(
utf8
));
size_t
len
=
(
size_t
)
n
;
TSDB_CONV_CODE
code
=
tsdb_conv_write
(
cnv
,
utf8
,
&
len
,
dst
,
dlen
);
*
dlen
=
(
size_t
)
n
+
1
;
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_write_timestamp
(
tsdb_conv_t
*
cnv
,
SQL_TIMESTAMP_STRUCT
val
,
char
*
dst
,
size_t
*
dlen
)
{
char
utf8
[
256
];
int
n
=
snprintf
(
utf8
,
sizeof
(
utf8
),
"%04d-%02d-%02d %02d:%02d:%02d.%03d"
,
val
.
year
,
val
.
month
,
val
.
day
,
val
.
hour
,
val
.
minute
,
val
.
second
,
val
.
fraction
/
1000000
);
DASSERT
(
n
>=
0
);
DASSERT
(
n
<
sizeof
(
utf8
));
size_t
len
=
(
size_t
)
n
;
TSDB_CONV_CODE
code
=
tsdb_conv_write
(
cnv
,
utf8
,
&
len
,
dst
,
dlen
);
*
dlen
=
(
size_t
)
n
+
1
;
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_bit
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int8_t
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_bit
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_tinyint
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int8_t
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_tinyint
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_smallint
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int16_t
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_smallint
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_int
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int32_t
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_int
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_bigint
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int64_t
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_bigint
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_ts
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int64_t
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_ts
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_float
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
float
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_float
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_double
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
double
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_double
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_timestamp
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
SQL_TIMESTAMP_STRUCT
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_timestamp
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv_chars_to_timestamp_ts
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int64_t
*
dst
)
{
const
char
*
utf8
=
NULL
;
TSDB_CONV_CODE
code
=
tsdb_conv
(
cnv
,
buffer
,
src
,
slen
,
&
utf8
,
NULL
);
if
(
code
)
return
code
;
code
=
tsdb_chars_to_timestamp_ts
(
utf8
,
sizeof
(
utf8
),
dst
);
tsdb_conv_free
(
cnv
,
utf8
,
buffer
,
src
);
return
code
;
}
TSDB_CONV_CODE
tsdb_conv
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
const
char
**
dst
,
size_t
*
dlen
)
{
if
(
!
cnv
)
return
TSDB_CONV_NOT_AVAIL
;
char
*
buf
;
size_t
blen
;
if
(
cnv
->
direct
)
{
if
(
src
[
slen
]
==
'\0'
)
{
// access violation?
*
dst
=
src
;
if
(
dlen
)
*
dlen
=
slen
;
return
TSDB_CONV_OK
;
}
blen
=
slen
+
1
;
}
else
{
blen
=
(
slen
+
1
)
*
4
;
}
buf
=
stack_buffer_alloc
(
buffer
,
blen
);
if
(
!
buf
)
{
buf
=
(
char
*
)
malloc
(
blen
);
if
(
!
buf
)
return
TSDB_CONV_OOM
;
}
if
(
cnv
->
direct
)
{
size_t
n
=
slen
;
DASSERT
(
blen
>
n
);
memcpy
(
buf
,
src
,
n
);
buf
[
n
]
=
'\0'
;
*
dst
=
buf
;
if
(
dlen
)
*
dlen
=
n
;
return
TSDB_CONV_OK
;
}
const
char
*
orig_s
=
src
;
char
*
orig_d
=
buf
;
size_t
orig_blen
=
blen
;
TSDB_CONV_CODE
code
;
size_t
r
=
iconv
(
cnv
->
cnv
,
(
char
**
)
&
src
,
&
slen
,
&
buf
,
&
blen
);
do
{
if
(
r
==
(
size_t
)
-
1
)
{
code
=
TSDB_CONV_BAD_CHAR
;
break
;
}
if
(
slen
)
{
code
=
TSDB_CONV_TRUNC
;
break
;
}
DASSERT
(
blen
);
*
buf
=
'\0'
;
*
dst
=
orig_d
;
if
(
dlen
)
*
dlen
=
orig_blen
-
blen
;
return
TSDB_CONV_OK
;
}
while
(
0
);
if
(
orig_d
!=
(
char
*
)
orig_s
&&
!
is_owned_by_stack_buffer
(
buffer
,
orig_d
))
free
(
orig_d
);
return
code
;
}
void
tsdb_conv_free
(
tsdb_conv_t
*
cnv
,
const
char
*
ptr
,
stack_buffer_t
*
buffer
,
const
char
*
src
)
{
if
(
ptr
!=
src
&&
!
is_owned_by_stack_buffer
(
buffer
,
ptr
))
free
((
char
*
)
ptr
);
}
src/connector/odbc/src/todbc_conv.h
浏览文件 @
f43bbfea
...
...
@@ -23,17 +23,50 @@
typedef
enum
{
TSDB_CONV_OK
=
0
,
TSDB_CONV_NOT_AVAIL
,
TSDB_CONV_OOM
,
TSDB_CONV_OOR
,
TSDB_CONV_TRUNC_FRACTION
,
TSDB_CONV_TRUNC
,
TSDB_CONV_CHAR_NOT_NUM
,
TSDB_CONV_CHAR_NOT_TS
,
TSDB_CONV_GENERAL
,
TSDB_CONV_BAD_CHAR
,
}
TSDB_CONV_CODE
;
const
char
*
tsdb_conv_code_str
(
TSDB_CONV_CODE
code
);
typedef
struct
stack_buffer_s
stack_buffer_t
;
struct
stack_buffer_s
{
char
buf
[
1024
*
16
];
size_t
next
;
};
char
*
stack_buffer_alloc
(
stack_buffer_t
*
buffer
,
size_t
bytes
);
int
is_owned_by_stack_buffer
(
stack_buffer_t
*
buffer
,
const
char
*
ptr
);
typedef
struct
tsdb_conv_s
tsdb_conv_t
;
tsdb_conv_t
*
tsdb_conv_open
(
const
char
*
from_enc
,
const
char
*
to_enc
);
void
tsdb_conv_close
(
tsdb_conv_t
*
cnv
);
TSDB_CONV_CODE
tsdb_conv_write
(
tsdb_conv_t
*
cnv
,
const
char
*
src
,
size_t
*
slen
,
char
*
dst
,
size_t
*
dlen
);
TSDB_CONV_CODE
tsdb_conv_write_int64
(
tsdb_conv_t
*
cnv
,
int64_t
val
,
char
*
dst
,
size_t
*
dlen
);
TSDB_CONV_CODE
tsdb_conv_write_double
(
tsdb_conv_t
*
cnv
,
double
val
,
char
*
dst
,
size_t
*
dlen
);
TSDB_CONV_CODE
tsdb_conv_write_timestamp
(
tsdb_conv_t
*
cnv
,
SQL_TIMESTAMP_STRUCT
val
,
char
*
dst
,
size_t
*
dlen
);
TSDB_CONV_CODE
tsdb_conv_chars_to_bit
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_conv_chars_to_tinyint
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_conv_chars_to_smallint
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int16_t
*
dst
);
TSDB_CONV_CODE
tsdb_conv_chars_to_int
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int32_t
*
dst
);
TSDB_CONV_CODE
tsdb_conv_chars_to_bigint
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_conv_chars_to_ts
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_conv_chars_to_float
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
float
*
dst
);
TSDB_CONV_CODE
tsdb_conv_chars_to_double
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
double
*
dst
);
TSDB_CONV_CODE
tsdb_conv_chars_to_timestamp
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
SQL_TIMESTAMP_STRUCT
*
dst
);
TSDB_CONV_CODE
tsdb_conv_chars_to_timestamp_ts
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_conv
(
tsdb_conv_t
*
cnv
,
stack_buffer_t
*
buffer
,
const
char
*
src
,
size_t
slen
,
const
char
**
dst
,
size_t
*
dlen
);
void
tsdb_conv_free
(
tsdb_conv_t
*
cnv
,
const
char
*
ptr
,
stack_buffer_t
*
buffer
,
const
char
*
src
);
TSDB_CONV_CODE
tsdb_iconv_conv
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
*
slen
,
unsigned
char
*
dst
,
size_t
*
dlen
);
...
...
@@ -66,6 +99,7 @@ TSDB_CONV_CODE tsdb_chars_to_bigint(const char *src, size_t smax, int64_t *dst);
TSDB_CONV_CODE
tsdb_chars_to_ts
(
const
char
*
src
,
size_t
smax
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_float
(
const
char
*
src
,
size_t
smax
,
float
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_double
(
const
char
*
src
,
size_t
smax
,
double
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_timestamp
(
const
char
*
src
,
size_t
smax
,
SQL_TIMESTAMP_STRUCT
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_char
(
const
char
*
src
,
size_t
smax
,
char
*
dst
,
size_t
dmax
);
TSDB_CONV_CODE
tsdb_wchars_to_bit
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int8_t
*
dst
);
...
...
src/connector/odbc/src/todbc_flex.h
浏览文件 @
f43bbfea
...
...
@@ -16,7 +16,21 @@
#ifndef _TODBC_FLEX_H_
#define _TODBC_FLEX_H_
int
todbc_parse_conn_string
(
const
char
*
conn
,
char
**
dsn
,
char
**
uid
,
char
**
pwd
,
char
**
host
);
typedef
struct
conn_val_s
conn_val_t
;
struct
conn_val_s
{
char
*
key
;
char
*
dsn
;
char
*
uid
;
char
*
pwd
;
char
*
db
;
char
*
host
;
char
*
svr_enc
;
char
*
cli_enc
;
};
void
conn_val_reset
(
conn_val_t
*
val
);
int
todbc_parse_conn_string
(
const
char
*
conn
,
conn_val_t
*
val
);
#endif // _TODBC_FLEX_H_
src/connector/odbc/src/todbc_scanner.l
浏览文件 @
f43bbfea
...
...
@@ -7,15 +7,6 @@
#define strcasecmp _stricmp
#endif
typedef struct params_s params_t;
struct params_s {
char *key;
char *dsn;
char *uid;
char *pwd;
char *host;
};
#define PUSH_STATE(state) yy_push_state(state, yyscanner)
#define POP_STATE() yy_pop_state(yyscanner)
...
...
@@ -61,17 +52,32 @@ do { \
yyextra->pwd = strdup(yytext); \
break; \
} \
if (strcasecmp(yyextra->key, "DB")==0) { \
free(yyextra->db); \
yyextra->pwd = strdup(yytext); \
break; \
} \
if (strcasecmp(yyextra->key, "HOST")==0) { \
free(yyextra->host); \
yyextra->host = strdup(yytext); \
break; \
} \
if (strcasecmp(yyextra->key, "SERVER_ENC")==0) { \
free(yyextra->svr_enc); \
yyextra->host = strdup(yytext); \
break; \
} \
if (strcasecmp(yyextra->key, "CLIENT_ENC")==0) { \
free(yyextra->cli_enc); \
yyextra->host = strdup(yytext); \
break; \
} \
} while (0)
%}
%option prefix="todbc_yy"
%option extra-type="
struct params_s
*"
%option extra-type="
conn_val_t
*"
%option nounistd
%option never-interactive
%option reentrant
...
...
@@ -115,20 +121,45 @@ do { \
<VAL>.|\n { return -1; }
%%
int todbc_parse_conn_string(const char *conn, c
har **dsn, char **uid, char **pwd, char **host
) {
int todbc_parse_conn_string(const char *conn, c
onn_val_t *val
) {
yyscan_t arg = {0};
params_t params = {0};
yylex_init(&arg);
yyset_debug(0, arg);
yyset_extra(
¶ms
, arg);
yyset_extra(
val
, arg);
yy_scan_string(conn, arg);
int ret =yylex(arg);
yylex_destroy(arg);
*dsn = params.dsn
;
*uid = params.uid;
*pwd = params.pwd
;
*host = params.host;
if (val->key) free(val->key); val->key = NULL
;
if (ret) {
conn_val_reset(val)
;
}
return ret ? -1 : 0;
}
void conn_val_reset(conn_val_t *val) {
if (val->key) {
free(val->key); val->key = NULL;
}
if (val->dsn) {
free(val->dsn); val->dsn = NULL;
}
if (val->uid) {
free(val->uid); val->uid = NULL;
}
if (val->pwd) {
free(val->pwd); val->pwd = NULL;
}
if (val->db) {
free(val->db); val->db = NULL;
}
if (val->host) {
free(val->host); val->host = NULL;
}
if (val->svr_enc) {
free(val->svr_enc); val->svr_enc = NULL;
}
if (val->cli_enc) {
free(val->cli_enc); val->cli_enc = NULL;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录