Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
eba73278
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看板
提交
eba73278
编写于
10月 11, 2021
作者:
H
Haojun Liao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[td-10564] add more code for query module.
上级
04c53c29
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
639 addition
and
214 deletion
+639
-214
include/common/tvariant.h
include/common/tvariant.h
+2
-0
source/common/CMakeLists.txt
source/common/CMakeLists.txt
+3
-1
source/common/src/tmsgtype.c
source/common/src/tmsgtype.c
+0
-0
source/common/src/tvariant.c
source/common/src/tvariant.c
+55
-20
source/common/test/CMakeLists.txt
source/common/test/CMakeLists.txt
+18
-0
source/common/test/commonTests.cpp
source/common/test/commonTests.cpp
+96
-0
source/libs/parser/inc/astGenerator.h
source/libs/parser/inc/astGenerator.h
+1
-0
source/libs/parser/inc/parserInt.h
source/libs/parser/inc/parserInt.h
+10
-0
source/libs/parser/inc/parserUtil.h
source/libs/parser/inc/parserUtil.h
+2
-1
source/libs/parser/src/astGenerator.c
source/libs/parser/src/astGenerator.c
+102
-154
source/libs/parser/src/astValidate.c
source/libs/parser/src/astValidate.c
+101
-32
source/libs/parser/src/parser.c
source/libs/parser/src/parser.c
+213
-2
source/libs/parser/src/parserUtil.c
source/libs/parser/src/parserUtil.c
+6
-1
source/libs/parser/src/ttokenizer.c
source/libs/parser/src/ttokenizer.c
+2
-1
source/libs/parser/test/tokenizerTest.cpp
source/libs/parser/test/tokenizerTest.cpp
+28
-2
未找到文件。
include/common/tvariant.h
浏览文件 @
eba73278
...
...
@@ -36,6 +36,8 @@ typedef struct SVariant {
};
}
SVariant
;
int32_t
toInteger
(
const
char
*
z
,
int32_t
n
,
int32_t
base
,
int64_t
*
value
,
bool
*
issigned
);
bool
taosVariantIsValid
(
SVariant
*
pVar
);
void
taosVariantCreate
(
SVariant
*
pVar
,
char
*
z
,
int32_t
n
,
int32_t
type
);
...
...
source/common/CMakeLists.txt
浏览文件 @
eba73278
...
...
@@ -10,4 +10,6 @@ target_link_libraries(
PUBLIC os
PUBLIC util
INTERFACE api
)
\ No newline at end of file
)
ADD_SUBDIRECTORY
(
test
)
source/common/src/
sqlcmdstr
.c
→
source/common/src/
tmsgtype
.c
浏览文件 @
eba73278
文件已移动
source/common/src/tvariant.c
浏览文件 @
eba73278
...
...
@@ -15,8 +15,8 @@
#include "os.h"
#include "taos.h"
#include "thash.h"
#include "taosdef.h"
#include "thash.h"
#include "ttime.h"
#include "ttokendef.h"
#include "ttypes.h"
...
...
@@ -39,6 +39,42 @@
assert(0); \
} while (0)
int32_t
toInteger
(
const
char
*
z
,
int32_t
n
,
int32_t
base
,
int64_t
*
value
,
bool
*
isSigned
)
{
errno
=
0
;
char
*
endPtr
=
NULL
;
int32_t
index
=
0
;
bool
specifiedSign
=
(
z
[
0
]
==
'+'
||
z
[
0
]
==
'-'
);
if
(
specifiedSign
)
{
*
isSigned
=
true
;
index
=
1
;
}
uint64_t
val
=
strtoull
(
&
z
[
index
],
&
endPtr
,
base
);
if
(
errno
==
ERANGE
||
errno
==
EINVAL
)
{
errno
=
0
;
return
-
1
;
}
if
(
specifiedSign
&&
val
>
INT64_MAX
)
{
return
-
1
;
}
if
(
endPtr
-
&
z
[
index
]
!=
n
-
index
)
{
return
-
1
;
}
*
isSigned
=
specifiedSign
||
(
val
<=
INT64_MAX
);
if
(
*
isSigned
)
{
*
value
=
(
z
[
0
]
==
'-'
)
?
-
val
:
val
;
}
else
{
*
(
uint64_t
*
)
value
=
val
;
}
return
0
;
}
void
taosVariantCreate
(
SVariant
*
pVar
,
char
*
z
,
int32_t
n
,
int32_t
type
)
{
int32_t
ret
=
0
;
memset
(
pVar
,
0
,
sizeof
(
SVariant
));
...
...
@@ -52,7 +88,6 @@ void taosVariantCreate(SVariant *pVar, char* z, int32_t n, int32_t type) {
}
else
{
return
;
}
break
;
}
...
...
@@ -60,38 +95,38 @@ void taosVariantCreate(SVariant *pVar, char* z, int32_t n, int32_t type) {
case
TSDB_DATA_TYPE_SMALLINT
:
case
TSDB_DATA_TYPE_BIGINT
:
case
TSDB_DATA_TYPE_INT
:{
// ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, true);
// if (ret != 0) {
// SToken t = {0};
// tGetToken(token->z, &t.type);
// if (t.type == TK_MINUS) { // it is a signed number which is greater than INT64_MAX or less than INT64_MIN
// pVar->nType = -1; // -1 means error type
// return;
// }
//
// // data overflow, try unsigned parse the input number
// ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, false);
// if (ret != 0) {
// pVar->nType = -1; // -1 means error type
// return;
// }
// }
bool
sign
=
true
;
int32_t
base
=
10
;
if
(
type
==
TK_HEX
)
{
base
=
16
;
}
else
if
(
type
==
TK_OCT
)
{
base
=
8
;
}
else
if
(
type
==
TK_BIN
)
{
base
=
2
;
}
ret
=
toInteger
(
z
,
n
,
base
,
&
pVar
->
i64
,
&
sign
);
if
(
ret
!=
0
)
{
pVar
->
nType
=
-
1
;
// -1 means error type
return
;
}
pVar
->
nType
=
(
sign
)
?
TSDB_DATA_TYPE_BIGINT
:
TSDB_DATA_TYPE_UBIGINT
;
break
;
}
case
TSDB_DATA_TYPE_DOUBLE
:
case
TSDB_DATA_TYPE_FLOAT
:
{
pVar
->
d
=
strtod
(
z
,
NULL
);
break
;
}
case
TSDB_DATA_TYPE_BINARY
:
{
pVar
->
pz
=
strndup
(
z
,
n
);
pVar
->
nLen
=
strRmquote
(
pVar
->
pz
,
n
);
break
;
}
case
TSDB_DATA_TYPE_TIMESTAMP
:
{
assert
(
0
);
pVar
->
i64
=
taosGetTimestamp
(
TSDB_TIME_PRECISION_NANO
);
break
;
}
...
...
source/common/test/CMakeLists.txt
0 → 100644
浏览文件 @
eba73278
MESSAGE
(
STATUS
"build parser unit test"
)
# GoogleTest requires at least C++11
SET
(
CMAKE_CXX_STANDARD 11
)
AUX_SOURCE_DIRECTORY
(
${
CMAKE_CURRENT_SOURCE_DIR
}
SOURCE_LIST
)
ADD_EXECUTABLE
(
commonTest
${
SOURCE_LIST
}
)
TARGET_LINK_LIBRARIES
(
commonTest
PUBLIC os util common gtest
)
TARGET_INCLUDE_DIRECTORIES
(
commonTest
PUBLIC
"
${
CMAKE_SOURCE_DIR
}
/include/libs/common/"
PRIVATE
"
${
CMAKE_SOURCE_DIR
}
/source/libs/common/inc"
)
source/common/test/commonTests.cpp
浏览文件 @
eba73278
#include <gtest/gtest.h>
#include <iostream>
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
#include "os.h"
#include "taos.h"
#include "tvariant.h"
#include "tdef.h"
namespace
{
//
}
// namespace
int
main
(
int
argc
,
char
**
argv
)
{
testing
::
InitGoogleTest
(
&
argc
,
argv
);
return
RUN_ALL_TESTS
();
}
TEST
(
testCase
,
toInteger_test
)
{
char
*
s
=
"123"
;
uint32_t
type
=
0
;
int64_t
val
=
0
;
bool
sign
=
true
;
int32_t
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
123
);
ASSERT_EQ
(
sign
,
true
);
s
=
"9223372036854775807"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
9223372036854775807
);
ASSERT_EQ
(
sign
,
true
);
s
=
"9323372036854775807"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
9323372036854775807u
);
ASSERT_EQ
(
sign
,
false
);
s
=
"-9323372036854775807"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
-
1
);
s
=
"-1"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
-
1
);
ASSERT_EQ
(
sign
,
true
);
s
=
"-9223372036854775807"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
-
9223372036854775807
);
ASSERT_EQ
(
sign
,
true
);
s
=
"1000u"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
-
1
);
s
=
"0x10"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
16
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
16
);
ASSERT_EQ
(
sign
,
true
);
s
=
"110"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
2
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
6
);
ASSERT_EQ
(
sign
,
true
);
s
=
"110"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
8
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
72
);
ASSERT_EQ
(
sign
,
true
);
//18446744073709551615 UINT64_MAX
s
=
"18446744073709551615"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
18446744073709551615u
);
ASSERT_EQ
(
sign
,
false
);
s
=
"18446744073709551616"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ASSERT_EQ
(
ret
,
-
1
);
}
source/libs/parser/inc/astGenerator.h
浏览文件 @
eba73278
...
...
@@ -277,6 +277,7 @@ bool tSqlExprIsParentOfLeaf(tSqlExpr *pExpr);
void
tSqlExprDestroy
(
tSqlExpr
*
pExpr
);
SArray
*
tSqlExprListAppend
(
SArray
*
pList
,
tSqlExpr
*
pNode
,
SToken
*
pDistinct
,
SToken
*
pToken
);
void
tSqlExprListDestroy
(
SArray
*
pList
);
void
tSqlExprEvaluate
(
tSqlExpr
*
pExpr
);
SSqlNode
*
tSetQuerySqlNode
(
SToken
*
pSelectToken
,
SArray
*
pSelNodeList
,
SRelationInfo
*
pFrom
,
tSqlExpr
*
pWhere
,
SArray
*
pGroupby
,
SArray
*
pSortOrder
,
SIntervalVal
*
pInterval
,
SSessionWindowVal
*
ps
,
...
...
source/libs/parser/inc/parserInt.h
浏览文件 @
eba73278
...
...
@@ -46,6 +46,16 @@ typedef struct SInsertStmtInfo {
*/
int32_t
qParserValidateSqlNode
(
struct
SCatalog
*
pCatalog
,
SSqlInfo
*
pSqlInfo
,
SQueryStmtInfo
*
pQueryInfo
,
int64_t
id
,
char
*
msg
,
int32_t
msgLen
);
/**
*
* @param pNode
* @param tsPrecision
* @param msg
* @param msgBufLen
* @return
*/
int32_t
evaluateSqlNode
(
SSqlNode
*
pNode
,
int32_t
tsPrecision
,
char
*
msg
,
int32_t
msgBufLen
);
/**
*
* @param pSqlNode
...
...
source/libs/parser/inc/parserUtil.h
浏览文件 @
eba73278
...
...
@@ -23,7 +23,8 @@ extern "C" {
#include "os.h"
#include "ttoken.h"
int32_t
parserValidateNameToken
(
SToken
*
pToken
);
int32_t
parserValidateIdToken
(
SToken
*
pToken
);
int32_t
parserSetInvalidOperatorMsg
(
char
*
dst
,
int32_t
dstBufLen
,
const
char
*
msg
);
#ifdef __cplusplus
}
...
...
source/libs/parser/src/astGenerator.c
浏览文件 @
eba73278
...
...
@@ -18,52 +18,6 @@
#include "astGenerator.h"
#include "tmsgtype.h"
int32_t
tStrToInteger
(
const
char
*
z
,
int16_t
type
,
int32_t
n
,
int64_t
*
value
,
bool
issigned
)
{
errno
=
0
;
int32_t
ret
=
0
;
char
*
endPtr
=
NULL
;
if
(
type
==
TK_FLOAT
)
{
double
v
=
strtod
(
z
,
&
endPtr
);
if
((
errno
==
ERANGE
&&
v
==
HUGE_VALF
)
||
isinf
(
v
)
||
isnan
(
v
))
{
ret
=
-
1
;
}
else
if
((
issigned
&&
(
v
<
INT64_MIN
||
v
>
INT64_MAX
))
||
((
!
issigned
)
&&
(
v
<
0
||
v
>
UINT64_MAX
)))
{
ret
=
-
1
;
}
else
{
*
value
=
(
int64_t
)
round
(
v
);
}
errno
=
0
;
return
ret
;
}
int32_t
radix
=
10
;
if
(
type
==
TK_HEX
)
{
radix
=
16
;
}
else
if
(
type
==
TK_BIN
)
{
radix
=
2
;
}
// the string may be overflow according to errno
if
(
!
issigned
)
{
const
char
*
p
=
z
;
while
(
*
p
!=
0
&&
*
p
==
' '
)
p
++
;
if
(
*
p
!=
0
&&
*
p
==
'-'
)
{
return
-
1
;}
*
value
=
strtoull
(
z
,
&
endPtr
,
radix
);
}
else
{
*
value
=
strtoll
(
z
,
&
endPtr
,
radix
);
}
// not a valid integer number, return error
if
(
endPtr
-
z
!=
n
||
errno
==
ERANGE
)
{
ret
=
-
1
;
}
errno
=
0
;
return
ret
;
}
SArray
*
tListItemAppend
(
SArray
*
pList
,
SVariant
*
pVar
,
uint8_t
sortOrder
)
{
if
(
pList
==
NULL
)
{
pList
=
taosArrayInit
(
4
,
sizeof
(
SListItem
));
...
...
@@ -173,7 +127,6 @@ SRelationInfo *addSubquery(SRelationInfo *pRelationInfo, SArray *pSub, SToken *p
}
// sql expr leaf node
// todo Evalute the value during the validation process of AST.
tSqlExpr
*
tSqlExprCreateIdValue
(
SToken
*
pToken
,
int32_t
optrType
)
{
tSqlExpr
*
pSqlExpr
=
calloc
(
1
,
sizeof
(
tSqlExpr
));
...
...
@@ -189,34 +142,10 @@ tSqlExpr *tSqlExprCreateIdValue(SToken *pToken, int32_t optrType) {
pSqlExpr
->
tokenId
=
optrType
;
pSqlExpr
->
type
=
SQL_NODE_VALUE
;
}
else
if
(
optrType
==
TK_INTEGER
||
optrType
==
TK_STRING
||
optrType
==
TK_FLOAT
||
optrType
==
TK_BOOL
)
{
// if (pToken) {
// toTSDBType(pToken->type);
// tVariantCreate(&pSqlExpr->value, pToken);
// }
pSqlExpr
->
tokenId
=
optrType
;
pSqlExpr
->
type
=
SQL_NODE_VALUE
;
}
else
if
(
optrType
==
TK_NOW
)
{
// use nanosecond by default TODO set value after getting database precision
// pSqlExpr->value.i64 = taosGetTimestamp(TSDB_TIME_PRECISION_NANO);
// pSqlExpr->value.nType = TSDB_DATA_TYPE_BIGINT;
pSqlExpr
->
tokenId
=
TK_TIMESTAMP
;
// TK_TIMESTAMP used to denote the time value is in microsecond
pSqlExpr
->
type
=
SQL_NODE_VALUE
;
// pSqlExpr->flags |= 1 << EXPR_FLAG_NS_TIMESTAMP;
}
else
if
(
optrType
==
TK_VARIABLE
)
{
// use nanosecond by default
// TODO set value after getting database precision
// if (pToken) {
// char unit = 0;
// int32_t ret = parseAbsoluteDuration(pToken->z, pToken->n, &pSqlExpr->value.i64, &unit, TSDB_TIME_PRECISION_NANO);
// if (ret != TSDB_CODE_SUCCESS) {
// terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
// }
// }
// pSqlExpr->flags |= 1 << EXPR_FLAG_NS_TIMESTAMP;
// pSqlExpr->flags |= 1 << EXPR_FLAG_TIMESTAMP_VAR;
// pSqlExpr->value.nType = TSDB_DATA_TYPE_BIGINT;
pSqlExpr
->
tokenId
=
TK_TIMESTAMP
;
}
else
if
(
optrType
==
TK_NOW
||
optrType
==
TK_VARIABLE
)
{
pSqlExpr
->
tokenId
=
optrType
;
// TK_TIMESTAMP used to denote this is a timestamp value
pSqlExpr
->
type
=
SQL_NODE_VALUE
;
}
else
{
// Here it must be the column name (tk_id) if it is not a number or string.
...
...
@@ -269,87 +198,7 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) {
pExpr
->
exprToken
.
type
=
pLeft
->
exprToken
.
type
;
}
if
((
pLeft
!=
NULL
&&
pRight
!=
NULL
)
&&
(
optrType
==
TK_PLUS
||
optrType
==
TK_MINUS
||
optrType
==
TK_STAR
||
optrType
==
TK_DIVIDE
||
optrType
==
TK_REM
))
{
/*
* if a exprToken is noted as the TK_TIMESTAMP, the time precision is microsecond
* Otherwise, the time precision is adaptive, determined by the time precision from databases.
*/
if
((
pLeft
->
tokenId
==
TK_INTEGER
&&
pRight
->
tokenId
==
TK_INTEGER
)
||
(
pLeft
->
tokenId
==
TK_TIMESTAMP
&&
pRight
->
tokenId
==
TK_TIMESTAMP
))
{
pExpr
->
value
.
nType
=
TSDB_DATA_TYPE_BIGINT
;
pExpr
->
tokenId
=
pLeft
->
tokenId
;
pExpr
->
type
=
SQL_NODE_VALUE
;
switch
(
optrType
)
{
case
TK_PLUS
:
{
pExpr
->
value
.
i64
=
pLeft
->
value
.
i64
+
pRight
->
value
.
i64
;
break
;
}
case
TK_MINUS
:
{
pExpr
->
value
.
i64
=
pLeft
->
value
.
i64
-
pRight
->
value
.
i64
;
break
;
}
case
TK_STAR
:
{
pExpr
->
value
.
i64
=
pLeft
->
value
.
i64
*
pRight
->
value
.
i64
;
break
;
}
case
TK_DIVIDE
:
{
pExpr
->
tokenId
=
TK_FLOAT
;
pExpr
->
value
.
nType
=
TSDB_DATA_TYPE_DOUBLE
;
pExpr
->
value
.
d
=
(
double
)
pLeft
->
value
.
i64
/
pRight
->
value
.
i64
;
break
;
}
case
TK_REM
:
{
pExpr
->
value
.
i64
=
pLeft
->
value
.
i64
%
pRight
->
value
.
i64
;
break
;
}
}
tSqlExprDestroy
(
pLeft
);
tSqlExprDestroy
(
pRight
);
}
else
if
((
pLeft
->
tokenId
==
TK_FLOAT
&&
pRight
->
tokenId
==
TK_INTEGER
)
||
(
pLeft
->
tokenId
==
TK_INTEGER
&&
pRight
->
tokenId
==
TK_FLOAT
)
||
(
pLeft
->
tokenId
==
TK_FLOAT
&&
pRight
->
tokenId
==
TK_FLOAT
))
{
pExpr
->
value
.
nType
=
TSDB_DATA_TYPE_DOUBLE
;
pExpr
->
tokenId
=
TK_FLOAT
;
pExpr
->
type
=
SQL_NODE_VALUE
;
double
left
=
(
pLeft
->
value
.
nType
==
TSDB_DATA_TYPE_DOUBLE
)
?
pLeft
->
value
.
d
:
pLeft
->
value
.
i64
;
double
right
=
(
pRight
->
value
.
nType
==
TSDB_DATA_TYPE_DOUBLE
)
?
pRight
->
value
.
d
:
pRight
->
value
.
i64
;
switch
(
optrType
)
{
case
TK_PLUS
:
{
pExpr
->
value
.
d
=
left
+
right
;
break
;
}
case
TK_MINUS
:
{
pExpr
->
value
.
d
=
left
-
right
;
break
;
}
case
TK_STAR
:
{
pExpr
->
value
.
d
=
left
*
right
;
break
;
}
case
TK_DIVIDE
:
{
pExpr
->
value
.
d
=
left
/
right
;
break
;
}
case
TK_REM
:
{
pExpr
->
value
.
d
=
left
-
((
int64_t
)(
left
/
right
))
*
right
;
break
;
}
}
tSqlExprDestroy
(
pLeft
);
tSqlExprDestroy
(
pRight
);
}
else
{
pExpr
->
tokenId
=
optrType
;
pExpr
->
pLeft
=
pLeft
;
pExpr
->
pRight
=
pRight
;
}
}
else
if
(
optrType
==
TK_IN
)
{
if
(
optrType
==
TK_IN
)
{
pExpr
->
tokenId
=
optrType
;
pExpr
->
pLeft
=
pLeft
;
...
...
@@ -501,6 +350,105 @@ void tSqlExprListDestroy(SArray *pList) {
taosArrayDestroyEx
(
pList
,
freeExprElem
);
}
void
tSqlExprEvaluate
(
tSqlExpr
*
pExpr
)
{
tSqlExpr
*
pLeft
=
pExpr
->
pLeft
;
tSqlExpr
*
pRight
=
pExpr
->
pRight
;
if
(
pLeft
==
NULL
||
pRight
==
NULL
)
{
return
;
}
int32_t
optrType
=
pExpr
->
tokenId
;
if
((
optrType
==
TK_PLUS
||
optrType
==
TK_MINUS
||
optrType
==
TK_STAR
||
optrType
==
TK_DIVIDE
||
optrType
==
TK_REM
))
{
/*
* if a exprToken is noted as the TK_TIMESTAMP, the time precision is microsecond
* Otherwise, the time precision is adaptive, determined by the time precision from databases.
*/
int32_t
ltoken
=
pLeft
->
tokenId
;
int32_t
rtoken
=
pRight
->
tokenId
;
if
((
ltoken
==
TK_INTEGER
&&
rtoken
==
TK_INTEGER
)
||
(
ltoken
==
TK_TIMESTAMP
&&
rtoken
==
TK_TIMESTAMP
))
{
pExpr
->
value
.
nType
=
TSDB_DATA_TYPE_BIGINT
;
pExpr
->
tokenId
=
ltoken
;
pExpr
->
type
=
SQL_NODE_VALUE
;
switch
(
optrType
)
{
case
TK_PLUS
:
{
pExpr
->
value
.
i64
=
pLeft
->
value
.
i64
+
pRight
->
value
.
i64
;
break
;
}
case
TK_MINUS
:
{
pExpr
->
value
.
i64
=
pLeft
->
value
.
i64
-
pRight
->
value
.
i64
;
break
;
}
case
TK_STAR
:
{
pExpr
->
value
.
i64
=
pLeft
->
value
.
i64
*
pRight
->
value
.
i64
;
break
;
}
case
TK_DIVIDE
:
{
pExpr
->
tokenId
=
TK_FLOAT
;
pExpr
->
value
.
nType
=
TSDB_DATA_TYPE_DOUBLE
;
pExpr
->
value
.
d
=
(
double
)
pLeft
->
value
.
i64
/
pRight
->
value
.
i64
;
break
;
}
case
TK_REM
:
{
pExpr
->
value
.
i64
=
pLeft
->
value
.
i64
%
pRight
->
value
.
i64
;
break
;
}
default:
assert
(
0
);
}
tSqlExprDestroy
(
pLeft
);
tSqlExprDestroy
(
pRight
);
pExpr
->
pLeft
=
NULL
;
pExpr
->
pRight
=
NULL
;
}
else
if
((
ltoken
==
TK_FLOAT
&&
rtoken
==
TK_INTEGER
)
||
(
ltoken
==
TK_INTEGER
&&
rtoken
==
TK_FLOAT
)
||
(
ltoken
==
TK_FLOAT
&&
rtoken
==
TK_FLOAT
))
{
pExpr
->
value
.
nType
=
TSDB_DATA_TYPE_DOUBLE
;
pExpr
->
tokenId
=
TK_FLOAT
;
pExpr
->
type
=
SQL_NODE_VALUE
;
double
left
=
(
pLeft
->
value
.
nType
==
TSDB_DATA_TYPE_DOUBLE
)
?
pLeft
->
value
.
d
:
pLeft
->
value
.
i64
;
double
right
=
(
pRight
->
value
.
nType
==
TSDB_DATA_TYPE_DOUBLE
)
?
pRight
->
value
.
d
:
pRight
->
value
.
i64
;
switch
(
optrType
)
{
case
TK_PLUS
:
{
pExpr
->
value
.
d
=
left
+
right
;
break
;
}
case
TK_MINUS
:
{
pExpr
->
value
.
d
=
left
-
right
;
break
;
}
case
TK_STAR
:
{
pExpr
->
value
.
d
=
left
*
right
;
break
;
}
case
TK_DIVIDE
:
{
pExpr
->
value
.
d
=
left
/
right
;
break
;
}
case
TK_REM
:
{
pExpr
->
value
.
d
=
left
-
((
int64_t
)(
left
/
right
))
*
right
;
break
;
}
default:
assert
(
0
);
}
tSqlExprDestroy
(
pLeft
);
tSqlExprDestroy
(
pRight
);
pExpr
->
pLeft
=
NULL
;
pExpr
->
pRight
=
NULL
;
}
}
}
SSqlNode
*
tSetQuerySqlNode
(
SToken
*
pSelectToken
,
SArray
*
pSelNodeList
,
SRelationInfo
*
pFrom
,
tSqlExpr
*
pWhere
,
SArray
*
pGroupby
,
SArray
*
pSortOrder
,
SIntervalVal
*
pInterval
,
SSessionWindowVal
*
pSession
,
SWindowStateVal
*
pWindowStateVal
,
SToken
*
pSliding
,
SArray
*
pFill
,
SLimit
*
pLimit
,
...
...
source/libs/parser/src/astValidate.c
浏览文件 @
eba73278
...
...
@@ -13,13 +13,82 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ttime.h"
#include "parserInt.h"
#include "parserUtil.h"
#include "tmsgtype.h"
static
int32_t
setInvalidOperatorErrMsg
(
char
*
dst
,
int32_t
dstBufLen
,
const
char
*
msg
)
{
strncpy
(
dst
,
msg
,
dstBufLen
);
return
TSDB_CODE_TSC_INVALID_OPERATION
;
static
int32_t
evaluateImpl
(
tSqlExpr
*
pExpr
,
int32_t
tsPrecision
)
{
int32_t
code
=
0
;
if
(
pExpr
->
type
==
SQL_NODE_EXPR
)
{
code
=
evaluateImpl
(
pExpr
->
pLeft
,
tsPrecision
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
code
=
evaluateImpl
(
pExpr
->
pRight
,
tsPrecision
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
if
(
pExpr
->
pLeft
->
type
==
SQL_NODE_VALUE
&&
pExpr
->
pRight
->
type
==
SQL_NODE_VALUE
)
{
tSqlExpr
*
pLeft
=
pExpr
->
pLeft
;
tSqlExpr
*
pRight
=
pExpr
->
pRight
;
if
((
pLeft
->
tokenId
==
TK_TIMESTAMP
&&
(
pRight
->
tokenId
==
TK_INTEGER
||
pRight
->
tokenId
==
TK_FLOAT
))
||
((
pRight
->
tokenId
==
TK_TIMESTAMP
&&
(
pLeft
->
tokenId
==
TK_INTEGER
||
pLeft
->
tokenId
==
TK_FLOAT
))))
{
return
TSDB_CODE_TSC_SQL_SYNTAX_ERROR
;
}
else
if
(
pLeft
->
tokenId
==
TK_TIMESTAMP
&&
pRight
->
tokenId
==
TK_TIMESTAMP
)
{
tSqlExprEvaluate
(
pExpr
);
}
else
{
tSqlExprEvaluate
(
pExpr
);
}
}
else
{
// Other types of expressions are not evaluated, they will be handled during the validation of the abstract syntax tree.
}
}
else
if
(
pExpr
->
type
==
SQL_NODE_VALUE
)
{
if
(
pExpr
->
tokenId
==
TK_NOW
)
{
pExpr
->
value
.
i64
=
taosGetTimestamp
(
tsPrecision
);
pExpr
->
value
.
nType
=
TSDB_DATA_TYPE_BIGINT
;
pExpr
->
tokenId
=
TK_TIMESTAMP
;
}
else
if
(
pExpr
->
tokenId
==
TK_VARIABLE
)
{
char
unit
=
0
;
SToken
*
pToken
=
&
pExpr
->
exprToken
;
int32_t
ret
=
parseAbsoluteDuration
(
pToken
->
z
,
pToken
->
n
,
&
pExpr
->
value
.
i64
,
&
unit
,
tsPrecision
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_SQL_SYNTAX_ERROR
;
}
pExpr
->
value
.
nType
=
TSDB_DATA_TYPE_BIGINT
;
pExpr
->
tokenId
=
TK_TIMESTAMP
;
}
else
if
(
pExpr
->
tokenId
==
TK_NULL
)
{
pExpr
->
value
.
nType
=
TSDB_DATA_TYPE_NULL
;
}
else
if
(
pExpr
->
tokenId
==
TK_INTEGER
||
pExpr
->
tokenId
==
TK_STRING
||
pExpr
->
tokenId
==
TK_FLOAT
||
pExpr
->
tokenId
==
TK_BOOL
)
{
SToken
*
pToken
=
&
pExpr
->
exprToken
;
int32_t
tokenType
=
pToken
->
type
;
toTSDBType
(
tokenType
);
taosVariantCreate
(
&
pExpr
->
value
,
pToken
->
z
,
pToken
->
n
,
tokenType
);
}
return
TSDB_CODE_SUCCESS
;
// other types of data are handled in the parent level.
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
evaluateSqlNode
(
SSqlNode
*
pNode
,
int32_t
tsPrecision
,
char
*
msg
,
int32_t
msgBufLen
)
{
assert
(
pNode
!=
NULL
&&
msg
!=
NULL
&&
msgBufLen
>
0
);
if
(
pNode
->
pWhere
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
}
int32_t
code
=
evaluateImpl
(
pNode
->
pWhere
,
tsPrecision
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
strncpy
(
msg
,
"invalid time expression in sql"
,
msgBufLen
);
return
code
;
}
return
code
;
}
int32_t
qParserValidateSqlNode
(
struct
SCatalog
*
pCatalog
,
SSqlInfo
*
pInfo
,
SQueryStmtInfo
*
pQueryInfo
,
int64_t
id
,
char
*
msgBuf
,
int32_t
msgBufLen
)
{
...
...
@@ -37,15 +106,15 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
const char* msg2 = "invalid name";
SToken* pzName = taosArrayGet(pInfo->pMiscInfo->a, 0);
if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (parserValidate
Name
Token(pzName) != TSDB_CODE_SUCCESS)) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg2);
if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (parserValidate
Id
Token(pzName) != TSDB_CODE_SUCCESS)) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2);
}
if (pInfo->type == TSDB_SQL_DROP_DB) {
assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1);
code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName);
if (code != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg2);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2);
}
} else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
...
...
@@ -62,7 +131,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
strncpy(pCmd->payload, pzName->z, pzName->n);
} else { // drop user/account
if (pzName->n >= TSDB_USER_LEN) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg3);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg3);
}
strncpy(pCmd->payload, pzName->z, pzName->n);
...
...
@@ -76,12 +145,12 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg);
}
int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken);
if (ret != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg);
}
break;
...
...
@@ -116,19 +185,19 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SCreateDbInfo* pCreateDB = &(pInfo->pMiscInfo->dbOpt);
if (pCreateDB->dbname.n >= TSDB_DB_NAME_LEN) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg2);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2);
}
char buf[TSDB_DB_NAME_LEN] = {0};
SToken token = taosTokenDup(&pCreateDB->dbname, buf, tListLen(buf));
if (tscValidateName(&token) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg1);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1);
}
int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), &token);
if (ret != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg2);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2);
}
if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
...
...
@@ -142,7 +211,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
const char* msg = "invalid host name (ip address)";
if (taosArrayGetSize(pInfo->pMiscInfo->a) > 1) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg);
}
SToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0);
...
...
@@ -166,11 +235,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
}
if (pName->n >= TSDB_USER_LEN) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg3);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg3);
}
if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg2);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2);
}
SCreateAcctInfo* pAcctOpt = &pInfo->pMiscInfo->acctOpt;
...
...
@@ -180,7 +249,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
} else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) {
} else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) {
} else {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg1);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1);
}
}
...
...
@@ -192,7 +261,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg1);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1);
}
// additional msg has been attached already
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
...
...
@@ -208,7 +277,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg1);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1);
}
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
...
...
@@ -223,11 +292,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg1);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1);
}
if (pToken->n > TSDB_DB_NAME_LEN) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg1);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1);
}
return tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken);
}
...
...
@@ -240,7 +309,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
/* validate the parameter names and options */
if (validateDNodeConfig(pMiscInfo) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg2);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2);
}
char* pMsg = pCmd->payload;
...
...
@@ -254,7 +323,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
strncpy(pCfg->ep, t0->z, t0->n);
if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg3);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg3);
}
strncpy(pCfg->config, t1->z, t1->n);
...
...
@@ -283,11 +352,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pPwd = &pUser->passwd;
if (pName->n >= TSDB_USER_LEN) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg3);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg3);
}
if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg2);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2);
}
if (pCmd->command == TSDB_SQL_CREATE_USER) {
...
...
@@ -311,10 +380,10 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
} else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) {
pCmd->count = 3;
} else {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg5);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg5);
}
} else {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg7);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg7);
}
}
...
...
@@ -327,7 +396,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
// validate the parameter names and options
if (validateLocalConfig(pMiscInfo) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg);
}
int32_t numOfToken = (int32_t) taosArrayGetSize(pMiscInfo->a);
...
...
@@ -382,7 +451,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
tscTrace("0x%"PRIx64" start to parse the %dth subclause, total:%"PRIzu, pSql->self, i, size);
if (size > 1 && pSqlNode->from && pSqlNode->from->type == SQL_NODE_FROM_SUBQUERY) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg1);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1);
}
// normalizeSqlNode(pSqlNode); // normalize the column name in each function
...
...
@@ -448,19 +517,19 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1);
code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName);
if (code != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg1);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1);
}
break;
}
case TSDB_SQL_COMPACT_VNODE:{
const char* msg = "invalid compact";
if (setCompactVnodeInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, msg);
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg);
}
break;
}
default:
return setInvalidOperator
Err
Msg(msgBuf, msgBufLen, "not support sql expression");
return setInvalidOperatorMsg(msgBuf, msgBufLen, "not support sql expression");
}
#endif
...
...
source/libs/parser/src/parser.c
浏览文件 @
eba73278
...
...
@@ -16,6 +16,7 @@
#include "parserInt.h"
#include "ttoken.h"
#include "astGenerator.h"
#include "parserUtil.h"
bool
qIsInsertSql
(
const
char
*
pStr
,
size_t
length
)
{
return
false
;
...
...
@@ -50,6 +51,216 @@ int32_t qParserConvertSql(const char* pStr, size_t length, char** pConvertSql) {
return
0
;
}
int32_t
qParserExtractRequestedMetaInfo
(
const
SArray
*
pSqlNodeList
,
SMetaReq
*
pMetaInfo
)
{
return
0
;
static
int32_t
getTableNameFromSubquery
(
SSqlNode
*
pSqlNode
,
SArray
*
tableNameList
,
char
*
msgBuf
)
{
int32_t
numOfSub
=
(
int32_t
)
taosArrayGetSize
(
pSqlNode
->
from
->
list
);
for
(
int32_t
j
=
0
;
j
<
numOfSub
;
++
j
)
{
SRelElementPair
*
sub
=
taosArrayGet
(
pSqlNode
->
from
->
list
,
j
);
int32_t
num
=
(
int32_t
)
taosArrayGetSize
(
sub
->
pSubquery
);
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
SSqlNode
*
p
=
taosArrayGetP
(
sub
->
pSubquery
,
i
);
if
(
p
->
from
->
type
==
SQL_NODE_FROM_TABLELIST
)
{
int32_t
code
=
getTableNameFromSqlNode
(
p
,
tableNameList
,
msgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
{
getTableNameFromSubquery
(
p
,
tableNameList
,
msgBuf
);
}
}
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
getTableNameFromSqlNode
(
SSqlNode
*
pSqlNode
,
SArray
*
tableNameList
,
char
*
msg
,
int32_t
msgBufLen
)
{
const
char
*
msg1
=
"invalid table name"
;
int32_t
numOfTables
=
(
int32_t
)
taosArrayGetSize
(
pSqlNode
->
from
->
list
);
assert
(
pSqlNode
->
from
->
type
==
SQL_NODE_FROM_TABLELIST
);
for
(
int32_t
j
=
0
;
j
<
numOfTables
;
++
j
)
{
SRelElementPair
*
item
=
taosArrayGet
(
pSqlNode
->
from
->
list
,
j
);
SToken
*
t
=
&
item
->
tableName
;
if
(
t
->
type
==
TK_INTEGER
||
t
->
type
==
TK_FLOAT
)
{
return
parserSetInvalidOperatorMsg
(
msg
,
msgBufLen
,
msg1
);
}
tscDequoteAndTrimToken
(
t
);
if
(
parserValidateIdToken
(
t
)
!=
TSDB_CODE_SUCCESS
)
{
return
parserSetInvalidOperatorMsg
(
msg
,
msgBufLen
,
msg1
);
}
SName
name
=
{
0
};
int32_t
code
=
tscSetTableFullName
(
&
name
,
t
,
pSql
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
taosArrayPush
(
tableNameList
,
&
name
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
qParserExtractRequestedMetaInfo
(
const
SArray
*
pSqlNodeList
,
SMetaReq
*
pMetaInfo
,
char
*
msg
,
int32_t
msgBufLen
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
SArray
*
tableNameList
=
NULL
;
SArray
*
pVgroupList
=
NULL
;
SArray
*
plist
=
NULL
;
STableMeta
*
pTableMeta
=
NULL
;
// size_t tableMetaCapacity = 0;
// SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
// pCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
tableNameList
=
taosArrayInit
(
4
,
sizeof
(
SName
));
size_t
size
=
taosArrayGetSize
(
pSqlNodeList
);
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
SSqlNode
*
pSqlNode
=
taosArrayGetP
(
pSqlNodeList
,
i
);
if
(
pSqlNode
->
from
==
NULL
)
{
goto
_end
;
}
// load the table meta in the from clause
if
(
pSqlNode
->
from
->
type
==
SQL_NODE_FROM_TABLELIST
)
{
code
=
getTableNameFromSqlNode
(
pSqlNode
,
tableNameList
,
msg
,
msgBufLen
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_end
;
}
}
else
{
code
=
getTableNameFromSubquery
(
pSqlNode
,
tableNameList
,
msg
,
msgBufLen
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_end
;
}
}
}
char
name
[
TSDB_TABLE_FNAME_LEN
]
=
{
0
};
plist
=
taosArrayInit
(
4
,
POINTER_BYTES
);
pVgroupList
=
taosArrayInit
(
4
,
POINTER_BYTES
);
taosArraySort
(
tableNameList
,
tnameComparFn
);
taosArrayRemoveDuplicate
(
tableNameList
,
tnameComparFn
,
NULL
);
STableMeta
*
pSTMeta
=
(
STableMeta
*
)(
pSql
->
pBuf
);
size_t
numOfTables
=
taosArrayGetSize
(
tableNameList
);
for
(
int32_t
i
=
0
;
i
<
numOfTables
;
++
i
)
{
SName
*
pname
=
taosArrayGet
(
tableNameList
,
i
);
tNameExtractFullName
(
pname
,
name
);
size_t
len
=
strlen
(
name
);
if
(
NULL
==
taosHashGetCloneExt
(
tscTableMetaMap
,
name
,
len
,
NULL
,
(
void
**
)
&
pTableMeta
,
&
tableMetaCapacity
))
{
// not found
tfree
(
pTableMeta
);
}
if
(
pTableMeta
&&
pTableMeta
->
id
.
uid
>
0
)
{
tscDebug
(
"0x%"
PRIx64
" retrieve table meta %s from local buf"
,
pSql
->
self
,
name
);
// avoid mem leak, may should update pTableMeta
void
*
pVgroupIdList
=
NULL
;
if
(
pTableMeta
->
tableType
==
TSDB_CHILD_TABLE
)
{
code
=
tscCreateTableMetaFromSTableMeta
((
STableMeta
**
)(
&
pTableMeta
),
name
,
&
tableMetaCapacity
,
(
STableMeta
**
)(
&
pSTMeta
));
pSql
->
pBuf
=
(
void
*
)
pSTMeta
;
// create the child table meta from super table failed, try load it from mnode
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
char
*
t
=
strdup
(
name
);
taosArrayPush
(
plist
,
&
t
);
continue
;
}
}
else
if
(
pTableMeta
->
tableType
==
TSDB_SUPER_TABLE
)
{
// the vgroup list of super table is not kept in local buffer, so here need retrieve it from the mnode each time
tscDebug
(
"0x%"
PRIx64
" try to acquire cached super table %s vgroup id list"
,
pSql
->
self
,
name
);
void
*
pv
=
taosCacheAcquireByKey
(
tscVgroupListBuf
,
name
,
len
);
if
(
pv
==
NULL
)
{
char
*
t
=
strdup
(
name
);
taosArrayPush
(
pVgroupList
,
&
t
);
tscDebug
(
"0x%"
PRIx64
" failed to retrieve stable %s vgroup id list in cache, try fetch from mnode"
,
pSql
->
self
,
name
);
}
else
{
tFilePage
*
pdata
=
(
tFilePage
*
)
pv
;
pVgroupIdList
=
taosArrayInit
((
size_t
)
pdata
->
num
,
sizeof
(
int32_t
));
if
(
pVgroupIdList
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
taosArrayAddBatch
(
pVgroupIdList
,
pdata
->
data
,
(
int32_t
)
pdata
->
num
);
taosCacheRelease
(
tscVgroupListBuf
,
&
pv
,
false
);
}
}
if
(
taosHashGet
(
pCmd
->
pTableMetaMap
,
name
,
len
)
==
NULL
)
{
STableMeta
*
pMeta
=
tscTableMetaDup
(
pTableMeta
);
STableMetaVgroupInfo
tvi
=
{
.
pTableMeta
=
pMeta
,
.
vgroupIdList
=
pVgroupIdList
};
taosHashPut
(
pCmd
->
pTableMetaMap
,
name
,
len
,
&
tvi
,
sizeof
(
STableMetaVgroupInfo
));
}
}
else
{
// Add to the retrieve table meta array list.
// If the tableMeta is missing, the cached vgroup list for the corresponding super table will be ignored.
tscDebug
(
"0x%"
PRIx64
" failed to retrieve table meta %s from local buf"
,
pSql
->
self
,
name
);
char
*
t
=
strdup
(
name
);
taosArrayPush
(
plist
,
&
t
);
}
}
size_t
funcSize
=
0
;
if
(
pInfo
->
funcs
)
{
funcSize
=
taosArrayGetSize
(
pInfo
->
funcs
);
}
if
(
funcSize
>
0
)
{
for
(
size_t
i
=
0
;
i
<
funcSize
;
++
i
)
{
SToken
*
t
=
taosArrayGet
(
pInfo
->
funcs
,
i
);
if
(
NULL
==
t
)
{
continue
;
}
if
(
t
->
n
>=
TSDB_FUNC_NAME_LEN
)
{
code
=
tscSQLSyntaxErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
"too long function name"
,
t
->
z
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_end
;
}
}
int32_t
functionId
=
isValidFunction
(
t
->
z
,
t
->
n
);
if
(
functionId
<
0
)
{
struct
SUdfInfo
info
=
{
0
};
info
.
name
=
strndup
(
t
->
z
,
t
->
n
);
if
(
pQueryInfo
->
pUdfInfo
==
NULL
)
{
pQueryInfo
->
pUdfInfo
=
taosArrayInit
(
4
,
sizeof
(
struct
SUdfInfo
));
}
info
.
functionId
=
(
int32_t
)
taosArrayGetSize
(
pQueryInfo
->
pUdfInfo
)
*
(
-
1
)
-
1
;;
taosArrayPush
(
pQueryInfo
->
pUdfInfo
,
&
info
);
}
}
}
// load the table meta for a given table name list
if
(
taosArrayGetSize
(
plist
)
>
0
||
taosArrayGetSize
(
pVgroupList
)
>
0
||
(
pQueryInfo
->
pUdfInfo
&&
taosArrayGetSize
(
pQueryInfo
->
pUdfInfo
)
>
0
))
{
code
=
getMultiTableMetaFromMnode
(
pSql
,
plist
,
pVgroupList
,
pQueryInfo
->
pUdfInfo
,
tscTableMetaCallBack
,
true
);
}
_end:
if
(
plist
!=
NULL
)
{
taosArrayDestroyEx
(
plist
,
freeElem
);
}
if
(
pVgroupList
!=
NULL
)
{
taosArrayDestroyEx
(
pVgroupList
,
freeElem
);
}
if
(
tableNameList
!=
NULL
)
{
taosArrayDestroy
(
tableNameList
);
}
tfree
(
pTableMeta
);
return
code
;
}
\ No newline at end of file
source/libs/parser/src/parserUtil.c
浏览文件 @
eba73278
...
...
@@ -2,7 +2,7 @@
#include "taoserror.h"
#include "tutil.h"
int32_t
parserValidate
Name
Token
(
SToken
*
pToken
)
{
int32_t
parserValidate
Id
Token
(
SToken
*
pToken
)
{
if
(
pToken
==
NULL
||
pToken
->
z
==
NULL
||
pToken
->
type
!=
TK_ID
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
...
...
@@ -57,4 +57,9 @@ int32_t parserValidateNameToken(SToken* pToken) {
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
parserSetInvalidOperatorMsg
(
char
*
dst
,
int32_t
dstBufLen
,
const
char
*
msg
)
{
strncpy
(
dst
,
msg
,
dstBufLen
);
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
\ No newline at end of file
source/libs/parser/src/ttokenizer.c
浏览文件 @
eba73278
...
...
@@ -411,6 +411,7 @@ uint32_t tGetToken(char* z, uint32_t* tokenId) {
*
tokenId
=
TK_QUESTION
;
return
1
;
}
case
'`'
:
case
'\''
:
case
'"'
:
{
int
delim
=
z
[
0
];
...
...
@@ -434,7 +435,7 @@ uint32_t tGetToken(char* z, uint32_t* tokenId) {
if
(
z
[
i
])
i
++
;
if
(
strEnd
)
{
*
tokenId
=
TK_STRING
;
*
tokenId
=
(
delim
==
'`'
)
?
TK_ID
:
TK_STRING
;
return
i
;
}
...
...
source/libs/parser/test/tokenizerTest.cpp
浏览文件 @
eba73278
...
...
@@ -14,6 +14,7 @@
#include "ttoken.h"
#include "astGenerator.h"
#include "parserUtil.h"
#include "parserInt.h"
namespace
{
int32_t
testValidateName
(
char
*
name
)
{
...
...
@@ -23,7 +24,7 @@ int32_t testValidateName(char* name) {
token
.
type
=
0
;
tGetToken
(
name
,
&
token
.
type
);
return
parserValidate
Name
Token
(
&
token
);
return
parserValidate
Id
Token
(
&
token
);
}
SToken
createToken
(
char
*
s
)
{
...
...
@@ -667,4 +668,29 @@ TEST(testCase, isValidNumber_test) {
TEST
(
testCase
,
generateAST_test
)
{
SSqlInfo
info
=
doGenerateAST
(
"select * from t1 where ts < now"
);
ASSERT_EQ
(
info
.
valid
,
true
);
}
\ No newline at end of file
SSqlInfo
info1
=
doGenerateAST
(
"select * from `t.1abc` where ts<now+2h and col < 20+99"
);
ASSERT_EQ
(
info1
.
valid
,
true
);
char
msg
[
128
]
=
{
0
};
SSqlNode
*
pNode
=
(
SSqlNode
*
)
taosArrayGetP
(((
SArray
*
)
info1
.
list
),
0
);
int32_t
code
=
evaluateSqlNode
(
pNode
,
TSDB_TIME_PRECISION_NANO
,
msg
,
sizeof
(
msg
));
ASSERT_EQ
(
code
,
0
);
SSqlInfo
info2
=
doGenerateAST
(
"select * from abc where ts<now+2"
);
SSqlNode
*
pNode2
=
(
SSqlNode
*
)
taosArrayGetP
(((
SArray
*
)
info2
.
list
),
0
);
code
=
evaluateSqlNode
(
pNode2
,
TSDB_TIME_PRECISION_MILLI
,
msg
,
sizeof
(
msg
));
ASSERT_NE
(
code
,
0
);
}
TEST
(
testCase
,
evaluateAST_test
)
{
SSqlInfo
info1
=
doGenerateAST
(
"select a, b+22 from `t.1abc` where ts<now+2h and col < 20 + 99"
);
ASSERT_EQ
(
info1
.
valid
,
true
);
char
msg
[
128
]
=
{
0
};
SSqlNode
*
pNode
=
(
SSqlNode
*
)
taosArrayGetP
(((
SArray
*
)
info1
.
list
),
0
);
int32_t
code
=
evaluateSqlNode
(
pNode
,
TSDB_TIME_PRECISION_NANO
,
msg
,
sizeof
(
msg
));
ASSERT_EQ
(
code
,
0
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录