Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
3b477f6c
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
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看板
提交
3b477f6c
编写于
7月 15, 2021
作者:
G
glzhao89
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[TD-5208]<feature> add timestamp parsing and child table name processing
上级
54ca0946
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
399 addition
and
278 deletion
+399
-278
src/client/src/tscParseLineProtocol.c
src/client/src/tscParseLineProtocol.c
+399
-278
未找到文件。
src/client/src/tscParseLineProtocol.c
浏览文件 @
3b477f6c
...
@@ -17,6 +17,11 @@
...
@@ -17,6 +17,11 @@
#include "tscLog.h"
#include "tscLog.h"
#include "taos.h"
#include "taos.h"
#define SECONDS_TO_MILLI(TS) TS * 1000
#define SECONDS_TO_MICRO(TS) TS * 1000000
#define SECONDS_TO_NANO(TS) TS * 1000000000
typedef
struct
{
typedef
struct
{
char
sTableName
[
TSDB_TABLE_NAME_LEN
];
char
sTableName
[
TSDB_TABLE_NAME_LEN
];
SHashObj
*
tagHash
;
SHashObj
*
tagHash
;
...
@@ -51,6 +56,14 @@ typedef struct {
...
@@ -51,6 +56,14 @@ typedef struct {
SSmlSTableSchema
*
schema
;
SSmlSTableSchema
*
schema
;
}
TAOS_SML_DATA_POINT
;
}
TAOS_SML_DATA_POINT
;
typedef
enum
{
SML_TIME_STAMP_NOW
,
SML_TIME_STAMP_SECONDS
,
SML_TIME_STAMP_MILLI_SECONDS
,
SML_TIME_STAMP_MICRO_SECONDS
,
SML_TIME_STAMP_NANO_SECONDS
}
SMLTimeStampType
;
//=================================================================================================
//=================================================================================================
int
compareSmlColKv
(
const
void
*
p1
,
const
void
*
p2
)
{
int
compareSmlColKv
(
const
void
*
p1
,
const
void
*
p2
)
{
...
@@ -825,94 +838,126 @@ clean_up:
...
@@ -825,94 +838,126 @@ clean_up:
//=========================================================================
//=========================================================================
bool
is_timestamp
(
char
*
pVal
,
uint16_t
len
)
{
/* Field Escape charaters
if
((
len
==
1
)
&&
pVal
[
0
]
==
'0'
)
{
1: measurement Comma,Space
printf
(
"Type is timestamp(%s)
\n
"
,
pVal
);
2: tag_key, tag_value, field_key Comma,Equal Sign,Space
return
true
;
3: field_value Double quote,Backslash
}
*/
if
(
len
<
2
)
{
void
escape_special_char
(
uint8_t
field
,
const
char
**
pos
)
{
return
false
;
const
char
*
cur
=
*
pos
;
if
(
*
cur
!=
'\\'
)
{
return
;
}
}
if
(
pVal
[
len
-
1
]
==
's'
)
{
switch
(
field
)
{
switch
(
pVal
[
len
-
2
])
{
case
1
:
case
'm'
:
switch
(
*
(
cur
+
1
))
{
case
'u'
:
case
','
:
case
'n'
:
case
' '
:
break
;
cur
++
;
default:
if
(
isdigit
(
pVal
[
len
-
2
]))
{
break
;
break
;
}
else
{
default:
return
false
;
break
;
}
}
}
break
;
printf
(
"Type is timestamp
\n
"
);
case
2
:
return
true
;
switch
(
*
(
cur
+
1
))
{
}
case
','
:
return
false
;
case
' '
:
}
case
'='
:
cur
++
;
bool
is_bool
(
char
*
pVal
,
uint16_t
len
,
bool
*
b_val
)
{
break
;
if
((
len
==
1
)
&&
default:
(
pVal
[
len
-
1
]
==
't'
||
break
;
pVal
[
len
-
1
]
==
'T'
))
{
}
printf
(
"Type is bool(%c)
\n
"
,
pVal
[
len
-
1
]);
break
;
*
b_val
=
true
;
case
3
:
return
true
;
switch
(
*
(
cur
+
1
))
{
}
case
'"'
:
case
'\\'
:
if
((
len
==
1
)
&&
cur
++
;
(
pVal
[
len
-
1
]
==
'f'
||
break
;
pVal
[
len
-
1
]
==
'F'
))
{
default:
printf
(
"Type is bool(%c)
\n
"
,
pVal
[
len
-
1
]);
break
;
*
b_val
=
false
;
}
return
true
;
break
;
}
default:
break
;
if
((
len
==
4
)
&&
(
!
strcmp
(
&
pVal
[
len
-
4
],
"true"
)
||
!
strcmp
(
&
pVal
[
len
-
4
],
"True"
)
||
!
strcmp
(
&
pVal
[
len
-
4
],
"TRUE"
)))
{
printf
(
"Type is bool(%s)
\n
"
,
&
pVal
[
len
-
4
]);
*
b_val
=
true
;
return
true
;
}
if
((
len
==
5
)
&&
(
!
strcmp
(
&
pVal
[
len
-
5
],
"false"
)
||
!
strcmp
(
&
pVal
[
len
-
5
],
"False"
)
||
!
strcmp
(
&
pVal
[
len
-
5
],
"FALSE"
)))
{
printf
(
"Type is bool(%s)
\n
"
,
&
pVal
[
len
-
5
]);
*
b_val
=
false
;
return
true
;
}
}
return
false
;
*
pos
=
cur
;
}
}
bool
is_
binary
(
char
*
pVal
,
uint16_t
len
)
{
bool
is_
valid_integer
(
char
*
str
)
{
//binary: "abc"
char
*
c
=
str
;
if
(
len
<
2
)
{
if
(
*
c
!=
'+'
&&
*
c
!=
'-'
&&
!
isdigit
(
*
c
)
)
{
return
false
;
return
false
;
}
}
//binary
c
++
;
if
(
pVal
[
0
]
==
'"'
&&
pVal
[
len
-
1
]
==
'"'
)
{
while
(
*
c
!=
'\0'
)
{
printf
(
"Type is binary(%s)
\n
"
,
pVal
);
if
(
!
isdigit
(
*
c
))
{
return
true
;
return
false
;
}
c
++
;
}
}
return
fals
e
;
return
tru
e
;
}
}
bool
is_nchar
(
char
*
pVal
,
uint16_t
len
)
{
bool
is_valid_float
(
char
*
str
)
{
//nchar: L"abc"
char
*
c
=
str
;
if
(
len
<
3
)
{
uint8_t
has_dot
,
has_exp
,
has_sign
;
has_dot
=
0
;
has_exp
=
0
;
has_sign
=
0
;
if
(
*
c
!=
'+'
&&
*
c
!=
'-'
&&
*
c
!=
'.'
&&
!
isdigit
(
*
c
))
{
return
false
;
return
false
;
}
}
if
(
pVal
[
0
]
==
'L'
&&
pVal
[
1
]
==
'"'
&&
pVal
[
len
-
1
]
==
'"'
)
{
if
(
*
c
==
'.'
&&
isdigit
(
*
(
c
+
1
)))
{
printf
(
"Type is nchar(%s)
\n
"
,
pVal
);
has_dot
=
1
;
return
true
;
}
}
return
false
;
c
++
;
while
(
*
c
!=
'\0'
)
{
if
(
!
isdigit
(
*
c
))
{
switch
(
*
c
)
{
case
'.'
:
{
if
(
!
has_dot
&&
!
has_exp
&&
isdigit
(
*
(
c
+
1
)))
{
has_dot
=
1
;
}
else
{
return
false
;
}
break
;
}
case
'e'
:
case
'E'
:
{
if
(
!
has_exp
&&
isdigit
(
*
(
c
-
1
))
&&
(
isdigit
(
*
(
c
+
1
))
||
*
(
c
+
1
)
==
'+'
||
*
(
c
+
1
)
==
'-'
))
{
has_exp
=
1
;
}
else
{
return
false
;
}
break
;
}
case
'+'
:
case
'-'
:
{
if
(
!
has_sign
&&
has_exp
&&
isdigit
(
*
(
c
+
1
)))
{
has_sign
=
1
;
}
else
{
return
false
;
}
break
;
}
default:
{
return
false
;
}
}
}
c
++
;
}
//while
return
true
;
}
}
bool
is_tiny_int
(
char
*
pVal
,
uint16_t
len
)
{
bool
is_tiny_int
(
char
*
pVal
,
uint16_t
len
)
{
if
(
len
<=
2
)
{
if
(
len
<=
2
)
{
return
false
;
return
false
;
...
@@ -1035,89 +1080,111 @@ bool is_double(char *pVal, uint16_t len) {
...
@@ -1035,89 +1080,111 @@ bool is_double(char *pVal, uint16_t len) {
return
false
;
return
false
;
}
}
bool
is_valid_integer
(
char
*
str
)
{
bool
is_bool
(
char
*
pVal
,
uint16_t
len
,
bool
*
b_val
)
{
char
*
c
=
str
;
if
((
len
==
1
)
&&
if
(
*
c
!=
'+'
&&
*
c
!=
'-'
&&
!
isdigit
(
*
c
))
{
(
pVal
[
len
-
1
]
==
't'
||
return
false
;
pVal
[
len
-
1
]
==
'T'
))
{
printf
(
"Type is bool(%c)
\n
"
,
pVal
[
len
-
1
]);
*
b_val
=
true
;
return
true
;
}
}
c
++
;
while
(
*
c
!=
'\0'
)
{
if
((
len
==
1
)
&&
if
(
!
isdigit
(
*
c
))
{
(
pVal
[
len
-
1
]
==
'f'
||
return
false
;
pVal
[
len
-
1
]
==
'F'
))
{
}
printf
(
"Type is bool(%c)
\n
"
,
pVal
[
len
-
1
]);
c
++
;
*
b_val
=
false
;
return
true
;
}
}
return
true
;
if
((
len
==
4
)
&&
(
!
strcmp
(
&
pVal
[
len
-
4
],
"true"
)
||
!
strcmp
(
&
pVal
[
len
-
4
],
"True"
)
||
!
strcmp
(
&
pVal
[
len
-
4
],
"TRUE"
)))
{
printf
(
"Type is bool(%s)
\n
"
,
&
pVal
[
len
-
4
]);
*
b_val
=
true
;
return
true
;
}
if
((
len
==
5
)
&&
(
!
strcmp
(
&
pVal
[
len
-
5
],
"false"
)
||
!
strcmp
(
&
pVal
[
len
-
5
],
"False"
)
||
!
strcmp
(
&
pVal
[
len
-
5
],
"FALSE"
)))
{
printf
(
"Type is bool(%s)
\n
"
,
&
pVal
[
len
-
5
]);
*
b_val
=
false
;
return
true
;
}
return
false
;
}
}
bool
is_valid_float
(
char
*
str
)
{
bool
is_binary
(
char
*
pVal
,
uint16_t
len
)
{
char
*
c
=
str
;
//binary: "abc"
uint8_t
has_dot
,
has_exp
,
has_sign
;
if
(
len
<
2
)
{
has_dot
=
0
;
return
false
;
has_exp
=
0
;
}
has_sign
=
0
;
//binary
if
(
pVal
[
0
]
==
'"'
&&
pVal
[
len
-
1
]
==
'"'
)
{
printf
(
"Type is binary(%s)
\n
"
,
pVal
);
return
true
;
}
return
false
;
}
if
(
*
c
!=
'+'
&&
*
c
!=
'-'
&&
*
c
!=
'.'
&&
!
isdigit
(
*
c
))
{
bool
is_nchar
(
char
*
pVal
,
uint16_t
len
)
{
//nchar: L"abc"
if
(
len
<
3
)
{
return
false
;
return
false
;
}
}
if
(
*
c
==
'.'
&&
isdigit
(
*
(
c
+
1
)))
{
if
(
pVal
[
0
]
==
'L'
&&
pVal
[
1
]
==
'"'
&&
pVal
[
len
-
1
]
==
'"'
)
{
has_dot
=
1
;
printf
(
"Type is nchar(%s)
\n
"
,
pVal
);
return
true
;
}
}
c
++
;
return
false
;
while
(
*
c
!=
'\0'
)
{
}
if
(
!
isdigit
(
*
c
))
{
switch
(
*
c
)
{
bool
is_timestamp
(
char
*
pVal
,
uint16_t
len
,
SMLTimeStampType
*
tsType
)
{
case
'.'
:
{
if
(
len
==
0
)
{
if
(
!
has_dot
&&
!
has_exp
&&
isdigit
(
*
(
c
+
1
)))
{
return
true
;
has_dot
=
1
;
}
}
else
{
if
((
len
==
1
)
&&
pVal
[
0
]
==
'0'
)
{
return
false
;
*
tsType
=
SML_TIME_STAMP_NOW
;
}
printf
(
"Type is timestamp(%s)
\n
"
,
pVal
);
break
;
return
true
;
}
}
case
'e'
:
if
(
len
<
2
)
{
case
'E'
:
{
return
false
;
if
(
!
has_exp
&&
isdigit
(
*
(
c
-
1
))
&&
}
(
isdigit
(
*
(
c
+
1
))
||
//No appendix use usec as default
*
(
c
+
1
)
==
'+'
||
if
(
isdigit
(
pVal
[
len
-
1
])
&&
isdigit
(
pVal
[
len
-
2
]))
{
*
(
c
+
1
)
==
'-'
))
{
*
tsType
=
SML_TIME_STAMP_MICRO_SECONDS
;
has_exp
=
1
;
printf
(
"Type is timestamp(%s)
\n
"
,
pVal
);
}
else
{
return
true
;
return
false
;
}
}
if
(
pVal
[
len
-
1
]
==
's'
)
{
break
;
switch
(
pVal
[
len
-
2
])
{
}
case
'm'
:
case
'+'
:
*
tsType
=
SML_TIME_STAMP_MILLI_SECONDS
;
case
'-'
:
{
break
;
if
(
!
has_sign
&&
has_exp
&&
isdigit
(
*
(
c
+
1
)))
{
case
'u'
:
has_sign
=
1
;
*
tsType
=
SML_TIME_STAMP_MICRO_SECONDS
;
}
else
{
break
;
return
false
;
case
'n'
:
}
*
tsType
=
SML_TIME_STAMP_NANO_SECONDS
;
break
;
default:
if
(
isdigit
(
pVal
[
len
-
2
]))
{
*
tsType
=
SML_TIME_STAMP_SECONDS
;
break
;
break
;
}
}
else
{
default:
{
return
false
;
return
false
;
}
}
}
}
}
c
++
;
printf
(
"Type is timestamp(%s)
\n
"
,
pVal
);
}
//while
return
true
;
}
bool
taos_sml_timestamp_convert
(
TAOS_SML_KV
*
pVal
,
char
*
value
,
uint16_t
len
)
{
if
(
is_timestamp
(
value
,
len
))
{
pVal
->
type
=
TSDB_DATA_TYPE_TIMESTAMP
;
pVal
->
length
=
(
int16_t
)
tDataTypes
[
pVal
->
type
].
bytes
;
pVal
->
value
=
calloc
(
pVal
->
length
,
1
);
int64_t
val
=
(
int64_t
)
strtoll
(
value
,
NULL
,
10
);
memcpy
(
pVal
->
value
,
&
val
,
pVal
->
length
);
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
//len does not include '\0' from value.
//len does not include '\0' from value.
bool
taos_sml_type_convert
(
TAOS_SML_KV
*
pVal
,
char
*
value
,
bool
taos_sml_type_convert
(
TAOS_SML_KV
*
pVal
,
char
*
value
,
uint16_t
len
)
{
uint16_t
len
)
{
...
@@ -1278,97 +1345,113 @@ bool taos_sml_type_convert(TAOS_SML_KV *pVal, char *value,
...
@@ -1278,97 +1345,113 @@ bool taos_sml_type_convert(TAOS_SML_KV *pVal, char *value,
return
false
;
return
false
;
}
}
/* Field Escape charaters
int32_t
tscGetTimeStampValue
(
char
*
value
,
uint16_t
len
,
SMLTimeStampType
type
,
int64_t
*
ts
)
{
1: measurement Comma,Space
2: tag_key, tag_value, field_key Comma,Equal Sign,Space
if
(
len
>=
2
)
{
3: field_value Double quote,Backslash
for
(
int
i
=
0
;
i
<
len
-
2
;
++
i
)
{
*/
if
(
!
isdigit
(
value
[
i
]))
{
void
escape_special_char
(
uint8_t
field
,
const
char
**
pos
)
{
return
TSDB_CODE_TSC_LINE_SYNTAX_ERROR
;
const
char
*
cur
=
*
pos
;
if
(
*
cur
!=
'\\'
)
{
return
;
}
switch
(
field
)
{
case
1
:
switch
(
*
(
cur
+
1
))
{
case
','
:
case
' '
:
cur
++
;
break
;
default:
break
;
}
}
}
}
//No appendix or no timestamp given (len = 0)
if
(
len
>=
1
&&
isdigit
(
value
[
len
-
1
])
&&
type
!=
SML_TIME_STAMP_NOW
)
{
type
=
SML_TIME_STAMP_MICRO_SECONDS
;
}
if
(
len
!=
0
)
{
*
ts
=
(
int64_t
)
strtoll
(
value
,
NULL
,
10
);
}
else
{
type
=
SML_TIME_STAMP_NOW
;
}
switch
(
type
)
{
case
SML_TIME_STAMP_NOW
:
{
time_t
now
=
time
(
NULL
);
*
ts
=
SECONDS_TO_MICRO
((
int64_t
)
now
);
break
;
break
;
case
2
:
}
switch
(
*
(
cur
+
1
))
{
case
SML_TIME_STAMP_SECONDS
:
{
case
','
:
case
' '
:
case
'='
:
cur
++
;
break
;
default:
break
;
}
break
;
break
;
case
3
:
}
switch
(
*
(
cur
+
1
))
{
case
SML_TIME_STAMP_MILLI_SECONDS
:
{
case
'"'
:
*
ts
=
SECONDS_TO_MILLI
(
*
ts
);
case
'\\'
:
cur
++
;
break
;
default:
break
;
}
break
;
break
;
default:
}
case
SML_TIME_STAMP_MICRO_SECONDS
:
{
*
ts
=
SECONDS_TO_MICRO
(
*
ts
);
break
;
break
;
}
case
SML_TIME_STAMP_NANO_SECONDS
:
{
*
ts
=
SECONDS_TO_NANO
(
*
ts
);
break
;
}
default:
{
return
TSDB_CODE_TSC_LINE_SYNTAX_ERROR
;
}
}
}
*
pos
=
cur
;
return
TSDB_CODE_SUCCESS
;
}
}
bool
taos_sml_parse_measurement
(
TAOS_SML_DATA_POINT
*
pSml
,
const
char
**
index
,
uint8_t
*
has_tags
)
{
int32_t
taos_sml_timestamp_convert
(
TAOS_SML_KV
*
pVal
,
char
*
value
,
uint16_t
len
)
{
const
char
*
cur
=
*
index
;
int32_t
ret
;
uint16_t
len
=
0
;
SMLTimeStampType
type
;
int64_t
tsVal
;
pSml
->
stableName
=
calloc
(
TSDB_TABLE_NAME_LEN
,
1
);
if
(
*
cur
==
'_'
)
{
if
(
!
is_timestamp
(
value
,
len
,
&
type
))
{
printf
(
"Measurement field cannnot start with
\'
_
\'\n
"
);
return
TSDB_CODE_TSC_LINE_SYNTAX_ERROR
;
return
false
;
}
}
while
(
*
cur
!=
'\0'
)
{
ret
=
tscGetTimeStampValue
(
value
,
len
,
type
,
&
tsVal
);
if
(
len
>
TSDB_TABLE_NAME_LEN
)
{
if
(
ret
)
{
printf
(
"Measurement field cannot exceeds 193 characters"
);
return
ret
;
return
false
;
}
}
printf
(
"Timestamp after conversion:%lld
\n
"
,
tsVal
);
//first unescaped comma or space identifies measurement
//if space detected first, meaning no tag in the input
pVal
->
type
=
TSDB_DATA_TYPE_TIMESTAMP
;
if
(
*
cur
==
','
&&
*
(
cur
-
1
)
!=
'\\'
)
{
pVal
->
length
=
(
int16_t
)
tDataTypes
[
pVal
->
type
].
bytes
;
*
has_tags
=
1
;
pVal
->
value
=
calloc
(
pVal
->
length
,
1
);
printf
(
"measurement:found comma
\n
"
);
memcpy
(
pVal
->
value
,
&
tsVal
,
pVal
->
length
);
break
;
return
TSDB_CODE_SUCCESS
;
}
}
if
(
*
cur
==
' '
&&
*
(
cur
-
1
)
!=
'\\'
)
{
printf
(
"measurement:found space
\n
"
);
bool
taos_sml_parse_value
(
TAOS_SML_KV
*
pKV
,
const
char
**
index
,
bool
*
is_last_kv
)
{
const
char
*
start
,
*
cur
;
char
*
value
=
NULL
;
uint16_t
len
=
0
;
start
=
cur
=
*
index
;
while
(
1
)
{
// unescaped ',' or ' ' or '\0' identifies a value
if
((
*
cur
==
','
||
*
cur
==
' '
||
*
cur
==
'\0'
)
&&
*
(
cur
-
1
)
!=
'\\'
)
{
value
=
calloc
(
len
+
1
,
1
);
memcpy
(
value
,
start
,
len
);
value
[
len
]
=
'\0'
;
if
(
!
taos_sml_type_convert
(
pKV
,
value
,
len
))
{
free
(
value
);
return
TSDB_CODE_TSC_LINE_SYNTAX_ERROR
;
}
//unescaped ' ' or '\0' indicates end of value
*
is_last_kv
=
(
*
cur
==
' '
||
*
cur
==
'\0'
)
?
true
:
false
;
break
;
break
;
}
}
//
Comma, Space, Backslash needs to be escaped if any
//
Escape special character
if
(
*
cur
==
'\\'
)
{
if
(
*
cur
==
'\\'
)
{
escape_special_char
(
1
,
&
cur
);
escape_special_char
(
2
,
&
cur
);
}
}
pSml
->
stableName
[
len
]
=
*
cur
;
cur
++
;
cur
++
;
len
++
;
len
++
;
}
}
pSml
->
stableName
[
len
]
=
'\0'
;
*
index
=
cur
+
1
;
printf
(
"stable name:%s|len:%d
\n
"
,
pSml
->
stableName
,
len
);
return
true
;
if
(
value
)
{
}
free
(
value
);
}
*
index
=
(
*
cur
==
'\0'
)
?
cur
:
cur
+
1
;
return
TSDB_CODE_SUCCESS
;
}
bool
taos_sml_parse_key
(
TAOS_SML_KV
*
pKV
,
const
char
**
index
)
{
int32_t
taos_sml_parse_key
(
TAOS_SML_KV
*
pKV
,
const
char
**
index
)
{
const
char
*
cur
=
*
index
;
const
char
*
cur
=
*
index
;
char
key
[
TSDB_COL_NAME_LEN
];
char
key
[
TSDB_COL_NAME_LEN
];
uint16_t
len
=
0
;
uint16_t
len
=
0
;
...
@@ -1376,14 +1459,12 @@ bool taos_sml_parse_key(TAOS_SML_KV *pKV, const char **index) {
...
@@ -1376,14 +1459,12 @@ bool taos_sml_parse_key(TAOS_SML_KV *pKV, const char **index) {
//key field cannot start with '_'
//key field cannot start with '_'
if
(
*
cur
==
'_'
)
{
if
(
*
cur
==
'_'
)
{
printf
(
"Tag key cannnot start with
\'
_
\'\n
"
);
printf
(
"Tag key cannnot start with
\'
_
\'\n
"
);
return
false
;
return
TSDB_CODE_TSC_LINE_SYNTAX_ERROR
;
}
}
//TODO: If tag key has ID field, use corresponding
//tag value as child table name
while
(
*
cur
!=
'\0'
)
{
while
(
*
cur
!=
'\0'
)
{
if
(
len
>
TSDB_COL_NAME_LEN
)
{
if
(
len
>
TSDB_COL_NAME_LEN
)
{
printf
(
"Key field cannot exceeds 65 characters"
);
printf
(
"Key field cannot exceeds 65 characters"
);
return
false
;
return
TSDB_CODE_TSC_LINE_SYNTAX_ERROR
;
}
}
//unescaped '=' identifies a tag key
//unescaped '=' identifies a tag key
if
(
*
cur
==
'='
&&
*
(
cur
-
1
)
!=
'\\'
)
{
if
(
*
cur
==
'='
&&
*
(
cur
-
1
)
!=
'\\'
)
{
...
@@ -1404,48 +1485,46 @@ bool taos_sml_parse_key(TAOS_SML_KV *pKV, const char **index) {
...
@@ -1404,48 +1485,46 @@ bool taos_sml_parse_key(TAOS_SML_KV *pKV, const char **index) {
memcpy
(
pKV
->
key
,
key
,
len
+
1
);
memcpy
(
pKV
->
key
,
key
,
len
+
1
);
printf
(
"key:%s|len:%d
\n
"
,
pKV
->
key
,
len
);
printf
(
"key:%s|len:%d
\n
"
,
pKV
->
key
,
len
);
*
index
=
cur
+
1
;
*
index
=
cur
+
1
;
return
true
;
return
TSDB_CODE_SUCCESS
;
}
}
bool
taos_sml_parse_value
(
TAOS_SML_KV
*
pKV
,
const
char
**
index
,
bool
*
is_last_kv
)
{
int32_t
taos_sml_parse_timestamp
(
TAOS_SML_KV
**
pTS
,
const
char
**
index
)
{
const
char
*
start
,
*
cur
;
const
char
*
start
,
*
cur
;
int32_t
ret
=
TSDB_CODE_SUCCESS
;
int
len
=
0
;
char
key
[]
=
"_ts"
;
char
*
value
=
NULL
;
char
*
value
=
NULL
;
uint16_t
len
=
0
;
start
=
cur
=
*
index
;
start
=
cur
=
*
index
;
*
pTS
=
calloc
(
1
,
sizeof
(
TAOS_SML_KV
));
while
(
1
)
{
while
(
*
cur
!=
'\0'
)
{
// unescaped ',' or ' ' or '\0' identifies a value
if
((
*
cur
==
','
||
*
cur
==
' '
||
*
cur
==
'\0'
)
&&
*
(
cur
-
1
)
!=
'\\'
)
{
value
=
calloc
(
len
+
1
,
1
);
memcpy
(
value
,
start
,
len
);
value
[
len
]
=
'\0'
;
if
(
!
taos_sml_type_convert
(
pKV
,
value
,
len
))
{
free
(
value
);
return
false
;
}
//unescaped ' ' or '\0' indicates end of value
*
is_last_kv
=
(
*
cur
==
' '
||
*
cur
==
'\0'
)
?
true
:
false
;
break
;
}
//Escape special character
if
(
*
cur
==
'\\'
)
{
escape_special_char
(
2
,
&
cur
);
}
cur
++
;
cur
++
;
len
++
;
len
++
;
}
}
if
(
value
)
{
if
(
len
>
0
)
{
value
=
calloc
(
len
,
1
);
memcpy
(
value
,
start
,
len
);
}
ret
=
taos_sml_timestamp_convert
(
*
pTS
,
value
,
len
);
if
(
ret
)
{
free
(
value
);
free
(
value
);
free
(
*
pTS
);
return
ret
;
}
}
free
(
value
);
*
index
=
(
*
cur
==
'\0'
)
?
cur
:
cur
+
1
;
(
*
pTS
)
->
key
=
calloc
(
sizeof
(
key
),
1
);
return
true
;
memcpy
((
*
pTS
)
->
key
,
key
,
sizeof
(
key
));
return
ret
;
}
}
bool
taos_sml_parse_kv_pairs
(
TAOS_SML_KV
**
pKVs
,
int
*
num_kvs
,
const
char
**
index
,
bool
isField
)
{
int32_t
taos_sml_parse_kv_pairs
(
TAOS_SML_KV
**
pKVs
,
int
*
num_kvs
,
const
char
**
index
,
bool
isField
)
{
const
char
*
cur
=
*
index
;
const
char
*
cur
=
*
index
;
int32_t
ret
=
TSDB_CODE_SUCCESS
;
TAOS_SML_KV
*
pkv
;
TAOS_SML_KV
*
pkv
;
bool
is_last_kv
=
false
;
bool
is_last_kv
=
false
;
...
@@ -1461,17 +1540,19 @@ bool taos_sml_parse_kv_pairs(TAOS_SML_KV **pKVs, int *num_kvs, const char **inde
...
@@ -1461,17 +1540,19 @@ bool taos_sml_parse_kv_pairs(TAOS_SML_KV **pKVs, int *num_kvs, const char **inde
}
}
while
(
*
cur
!=
'\0'
)
{
while
(
*
cur
!=
'\0'
)
{
if
(
!
taos_sml_parse_key
(
pkv
,
&
cur
))
{
ret
=
taos_sml_parse_key
(
pkv
,
&
cur
);
if
(
ret
)
{
printf
(
"Unable to parse key field
\n
"
);
printf
(
"Unable to parse key field
\n
"
);
goto
error
;
goto
error
;
}
}
if
(
!
taos_sml_parse_value
(
pkv
,
&
cur
,
&
is_last_kv
))
{
ret
=
taos_sml_parse_value
(
pkv
,
&
cur
,
&
is_last_kv
);
if
(
ret
)
{
printf
(
"Unable to parse value field
\n
"
);
printf
(
"Unable to parse value field
\n
"
);
goto
error
;
goto
error
;
}
}
*
num_kvs
+=
1
;
*
num_kvs
+=
1
;
if
(
is_last_kv
)
{
if
(
is_last_kv
)
{
printf
(
"last key value field detected
\n
"
);
printf
(
"last key value field detected
\n
"
);
goto
done
;
goto
done
;
}
}
...
@@ -1498,82 +1579,122 @@ bool taos_sml_parse_kv_pairs(TAOS_SML_KV **pKVs, int *num_kvs, const char **inde
...
@@ -1498,82 +1579,122 @@ bool taos_sml_parse_kv_pairs(TAOS_SML_KV **pKVs, int *num_kvs, const char **inde
error:
error:
free
(
*
pKVs
);
free
(
*
pKVs
);
return
false
;
return
ret
;
done:
done:
*
index
=
cur
;
*
index
=
cur
;
return
true
;
return
ret
;
}
}
bool
taos_sml_parse_timestamp
(
TAOS_SML_KV
**
pTS
,
const
char
**
index
)
{
int32_t
taos_sml_parse_measurement
(
TAOS_SML_DATA_POINT
*
pSml
,
const
char
**
index
,
uint8_t
*
has_tags
)
{
const
char
*
start
,
*
cur
;
const
char
*
cur
=
*
index
;
int
len
=
0
;
uint16_t
len
=
0
;
char
key
[]
=
"_ts"
;
char
*
value
=
NULL
;
start
=
cur
=
*
index
;
*
pTS
=
calloc
(
1
,
sizeof
(
TAOS_SML_KV
));
if
(
*
cur
==
'\0'
)
{
pSml
->
stableName
=
calloc
(
TSDB_TABLE_NAME_LEN
,
1
);
//no timestamp given, use current system time
if
(
*
cur
==
'_'
)
{
return
true
;
printf
(
"Measurement field cannnot start with
\'
_
\'\n
"
);
return
TSDB_CODE_TSC_LINE_SYNTAX_ERROR
;
}
}
while
(
*
cur
!=
'\0'
)
{
while
(
*
cur
!=
'\0'
)
{
if
(
len
>
TSDB_TABLE_NAME_LEN
)
{
printf
(
"Measurement field cannot exceeds 193 characters"
);
return
TSDB_CODE_TSC_LINE_SYNTAX_ERROR
;
}
//first unescaped comma or space identifies measurement
//if space detected first, meaning no tag in the input
if
(
*
cur
==
','
&&
*
(
cur
-
1
)
!=
'\\'
)
{
*
has_tags
=
1
;
printf
(
"measurement:found comma
\n
"
);
break
;
}
if
(
*
cur
==
' '
&&
*
(
cur
-
1
)
!=
'\\'
)
{
printf
(
"measurement:found space
\n
"
);
break
;
}
//Comma, Space, Backslash needs to be escaped if any
if
(
*
cur
==
'\\'
)
{
escape_special_char
(
1
,
&
cur
);
}
pSml
->
stableName
[
len
]
=
*
cur
;
cur
++
;
cur
++
;
len
++
;
len
++
;
}
}
value
=
calloc
(
len
,
1
);
pSml
->
stableName
[
len
]
=
'\0'
;
memcpy
(
value
,
start
,
len
);
*
index
=
cur
+
1
;
if
(
!
taos_sml_timestamp_convert
(
*
pTS
,
value
,
len
))
{
printf
(
"stable name:%s|len:%d
\n
"
,
pSml
->
stableName
,
len
);
free
(
*
pTS
);
return
false
;
return
TSDB_CODE_SUCCESS
;
}
}
free
(
value
);
(
*
pTS
)
->
key
=
calloc
(
sizeof
(
key
),
1
);
bool
tscGetChildTableName
(
TAOS_SML_DATA_POINT
*
pData
)
{
memcpy
((
*
pTS
)
->
key
,
key
,
sizeof
(
key
));
TAOS_SML_KV
*
pTags
=
pData
->
tags
;
return
true
;
int
tagNum
=
pData
->
tagNum
;
char
*
childTableName
=
pData
->
childTableName
;
for
(
int
i
=
0
;
i
<
tagNum
;
++
i
)
{
//use tag value as child table name if key is "ID"
//tag value has to be binary for now
if
(
!
strcmp
(
pTags
->
key
,
"ID"
)
&&
pTags
->
type
==
TSDB_DATA_TYPE_BINARY
)
{
memcpy
(
childTableName
,
pTags
->
value
,
pTags
->
length
);
return
true
;
}
pTags
++
;
}
return
false
;
}
}
bool
tscParseLine
(
const
char
*
sql
,
TAOS_SML_DATA_POINT
*
sml_data
)
{
int32_t
tscParseLine
(
const
char
*
sql
,
TAOS_SML_DATA_POINT
*
sml_data
)
{
const
char
*
index
=
sql
;
const
char
*
index
=
sql
;
int32_t
ret
=
TSDB_CODE_SUCCESS
;
uint8_t
has_tags
=
0
;
uint8_t
has_tags
=
0
;
TAOS_SML_KV
*
timestamp
=
NULL
;
TAOS_SML_KV
*
timestamp
=
NULL
;
if
(
!
taos_sml_parse_measurement
(
sml_data
,
&
index
,
&
has_tags
))
{
ret
=
taos_sml_parse_measurement
(
sml_data
,
&
index
,
&
has_tags
);
if
(
ret
)
{
printf
(
"Unable to parse measurement
\n
"
);
printf
(
"Unable to parse measurement
\n
"
);
free
(
sml_data
->
stableName
);
free
(
sml_data
->
stableName
);
free
(
sml_data
);
free
(
sml_data
);
return
false
;
return
ret
;
}
}
printf
(
"============Parse measurement finished, has_tags:%d===============
\n
"
,
has_tags
);
printf
(
"============Parse measurement finished, has_tags:%d===============
\n
"
,
has_tags
);
//Parse Tags
//Parse Tags
if
(
has_tags
)
{
if
(
has_tags
)
{
if
(
!
taos_sml_parse_kv_pairs
(
&
sml_data
->
tags
,
&
sml_data
->
tagNum
,
&
index
,
false
))
{
ret
=
taos_sml_parse_kv_pairs
(
&
sml_data
->
tags
,
&
sml_data
->
tagNum
,
&
index
,
false
);
if
(
ret
)
{
printf
(
"Unable to parse tag
\n
"
);
printf
(
"Unable to parse tag
\n
"
);
//TODO free allocated fileds inside TAOS_SML_DATA_POINT first
//TODO free allocated fileds inside TAOS_SML_DATA_POINT first
return
false
;
return
ret
;
}
sml_data
->
childTableName
=
calloc
(
TSDB_TABLE_NAME_LEN
,
1
);
if
(
!
tscGetChildTableName
(
sml_data
))
{
free
(
sml_data
->
childTableName
);
}
}
printf
(
"Child table name:%02x:%02x:%02x:%02x
\n
"
,
sml_data
->
childTableName
[
0
],
sml_data
->
childTableName
[
1
],
sml_data
->
childTableName
[
2
],
sml_data
->
childTableName
[
3
]);
}
else
{
}
else
{
//no tags given
//no tags given
}
}
printf
(
"============Parse tags finished, num_tags:%d===============
\n
"
,
sml_data
->
tagNum
);
printf
(
"============Parse tags finished, num_tags:%d===============
\n
"
,
sml_data
->
tagNum
);
//Parse fields
//Parse fields
if
(
!
taos_sml_parse_kv_pairs
(
&
sml_data
->
fields
,
&
sml_data
->
fieldNum
,
&
index
,
true
))
{
ret
=
taos_sml_parse_kv_pairs
(
&
sml_data
->
fields
,
&
sml_data
->
fieldNum
,
&
index
,
true
);
if
(
ret
)
{
printf
(
"Unable to parse field
\n
"
);
printf
(
"Unable to parse field
\n
"
);
//TODO free allocated fileds inside TAOS_SML_DATA_POINT first
//TODO free allocated fileds inside TAOS_SML_DATA_POINT first
return
false
;
return
ret
;
}
}
printf
(
"============Parse fields finished, num_fields:%d===============
\n
"
,
sml_data
->
fieldNum
);
printf
(
"============Parse fields finished, num_fields:%d===============
\n
"
,
sml_data
->
fieldNum
);
//Parse timestamp
//Parse timestamp
if
(
!
taos_sml_parse_timestamp
(
&
timestamp
,
&
index
))
{
ret
=
taos_sml_parse_timestamp
(
&
timestamp
,
&
index
);
if
(
ret
)
{
printf
(
"Unable to parse timestamp
\n
"
);
printf
(
"Unable to parse timestamp
\n
"
);
return
ret
;
return
false
;
}
}
sml_data
->
fieldNum
=
sml_data
->
fieldNum
+
1
;
sml_data
->
fieldNum
=
sml_data
->
fieldNum
+
1
;
...
@@ -1593,7 +1714,7 @@ bool tscParseLine(const char* sql, TAOS_SML_DATA_POINT* sml_data) {
...
@@ -1593,7 +1714,7 @@ bool tscParseLine(const char* sql, TAOS_SML_DATA_POINT* sml_data) {
return
true
;
return
true
;
}
}
//=========================================================================
int32_t
tscParseLines
(
char
*
lines
[],
int
numLines
,
SArray
*
points
,
SArray
*
failedLines
)
{
int32_t
tscParseLines
(
char
*
lines
[],
int
numLines
,
SArray
*
points
,
SArray
*
failedLines
)
{
for
(
int32_t
i
=
0
;
i
<
numLines
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
numLines
;
++
i
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录