Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
988cffcc
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1187
Star
22018
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看板
提交
988cffcc
编写于
7月 02, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: some problems of parser and planner
上级
5c060565
变更
14
展开全部
隐藏空白更改
内联
并排
Showing
14 changed file
with
970 addition
and
803 deletion
+970
-803
include/libs/nodes/nodes.h
include/libs/nodes/nodes.h
+3
-2
include/libs/scalar/scalar.h
include/libs/scalar/scalar.h
+2
-0
include/util/taoserror.h
include/util/taoserror.h
+1
-0
source/libs/parser/inc/parAst.h
source/libs/parser/inc/parAst.h
+1
-0
source/libs/parser/inc/parUtil.h
source/libs/parser/inc/parUtil.h
+1
-0
source/libs/parser/inc/sql.y
source/libs/parser/inc/sql.y
+2
-2
source/libs/parser/src/parAstCreater.c
source/libs/parser/src/parAstCreater.c
+5
-0
source/libs/parser/src/parInsert.c
source/libs/parser/src/parInsert.c
+66
-24
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+170
-106
source/libs/parser/src/parUtil.c
source/libs/parser/src/parUtil.c
+9
-1
source/libs/parser/src/sql.c
source/libs/parser/src/sql.c
+695
-667
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+2
-0
source/libs/planner/src/planSpliter.c
source/libs/planner/src/planSpliter.c
+4
-0
source/libs/planner/test/planSetOpTest.cpp
source/libs/planner/test/planSetOpTest.cpp
+9
-1
未找到文件。
include/libs/nodes/nodes.h
浏览文件 @
988cffcc
...
...
@@ -22,8 +22,8 @@ extern "C" {
#include "tdef.h"
#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type)
#define setNodeType(nodeptr,
type) (((SNode*)(nodeptr))->type = (
type))
#define nodeType(nodeptr)
(((const SNode*)(nodeptr))->type)
#define setNodeType(nodeptr,
nodetype) (((SNode*)(nodeptr))->type = (node
type))
#define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0)
...
...
@@ -118,6 +118,7 @@ typedef enum ENodeType {
QUERY_NODE_DROP_TABLE_STMT
,
QUERY_NODE_DROP_SUPER_TABLE_STMT
,
QUERY_NODE_ALTER_TABLE_STMT
,
QUERY_NODE_ALTER_SUPER_TABLE_STMT
,
QUERY_NODE_CREATE_USER_STMT
,
QUERY_NODE_ALTER_USER_STMT
,
QUERY_NODE_DROP_USER_STMT
,
...
...
include/libs/scalar/scalar.h
浏览文件 @
988cffcc
...
...
@@ -25,6 +25,8 @@ extern "C" {
typedef
struct
SFilterInfo
SFilterInfo
;
int32_t
scalarGetOperatorResultType
(
SDataType
left
,
SDataType
right
,
EOperatorType
op
,
SDataType
*
pRes
);
/*
pNode will be freed in API;
*pRes need to freed in caller
...
...
include/util/taoserror.h
浏览文件 @
988cffcc
...
...
@@ -578,6 +578,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_INVALID_TABLE_OPTION TAOS_DEF_ERROR_CODE(0, 0x265C)
#define TSDB_CODE_PAR_INVALID_INTERP_CLAUSE TAOS_DEF_ERROR_CODE(0, 0x265D)
#define TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN TAOS_DEF_ERROR_CODE(0, 0x265E)
#define TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE TAOS_DEF_ERROR_CODE(0, 0x265F)
//planner
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
...
...
source/libs/parser/inc/parAst.h
浏览文件 @
988cffcc
...
...
@@ -154,6 +154,7 @@ SNode* createAlterTableDropCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_
SNode
*
createAlterTableRenameCol
(
SAstCreateContext
*
pCxt
,
SNode
*
pRealTable
,
int8_t
alterType
,
SToken
*
pOldColName
,
SToken
*
pNewColName
);
SNode
*
createAlterTableSetTag
(
SAstCreateContext
*
pCxt
,
SNode
*
pRealTable
,
SToken
*
pTagName
,
SNode
*
pVal
);
SNode
*
setAlterSuperTableType
(
SNode
*
pStmt
);
SNode
*
createUseDatabaseStmt
(
SAstCreateContext
*
pCxt
,
SToken
*
pDbName
);
SNode
*
createShowStmt
(
SAstCreateContext
*
pCxt
,
ENodeType
type
);
SNode
*
createShowStmtWithCond
(
SAstCreateContext
*
pCxt
,
ENodeType
type
,
SNode
*
pDbName
,
SNode
*
pTbName
,
...
...
source/libs/parser/inc/parUtil.h
浏览文件 @
988cffcc
...
...
@@ -53,6 +53,7 @@ typedef struct SParseMetaCache {
}
SParseMetaCache
;
int32_t
generateSyntaxErrMsg
(
SMsgBuf
*
pBuf
,
int32_t
errCode
,
...);
int32_t
generateSyntaxErrMsgExt
(
SMsgBuf
*
pBuf
,
int32_t
errCode
,
const
char
*
pFormat
,
...);
int32_t
buildInvalidOperationMsg
(
SMsgBuf
*
pMsgBuf
,
const
char
*
msg
);
int32_t
buildSyntaxErrMsg
(
SMsgBuf
*
pBuf
,
const
char
*
additionalInfo
,
const
char
*
sourceStr
);
...
...
source/libs/parser/inc/sql.y
浏览文件 @
988cffcc
...
...
@@ -232,7 +232,7 @@ cmd ::= DROP TABLE multi_drop_clause(A).
cmd ::= DROP STABLE exists_opt(A) full_table_name(B). { pCxt->pRootNode = createDropSuperTableStmt(pCxt, A, B); }
cmd ::= ALTER TABLE alter_table_clause(A). { pCxt->pRootNode = A; }
cmd ::= ALTER STABLE alter_table_clause(A). { pCxt->pRootNode =
A
; }
cmd ::= ALTER STABLE alter_table_clause(A). { pCxt->pRootNode =
setAlterSuperTableType(A)
; }
alter_table_clause(A) ::= full_table_name(B) alter_table_options(C). { A = createAlterTableModifyOptions(pCxt, B, C); }
alter_table_clause(A) ::=
...
...
@@ -259,7 +259,7 @@ multi_create_clause(A) ::= multi_create_clause(B) create_subtable_clause(C).
create_subtable_clause(A) ::=
not_exists_opt(B) full_table_name(C) USING full_table_name(D)
specific_tags_opt(E) TAGS NK_LP
literal_list(F) NK_RP table_options(G).
{ A = createCreateSubTableClause(pCxt, B, C, D, E, F, G); }
specific_tags_opt(E) TAGS NK_LP
expression_list(F) NK_RP table_options(G).
{ A = createCreateSubTableClause(pCxt, B, C, D, E, F, G); }
%type multi_drop_clause { SNodeList* }
%destructor multi_drop_clause { nodesDestroyList($$); }
...
...
source/libs/parser/src/parAstCreater.c
浏览文件 @
988cffcc
...
...
@@ -1127,6 +1127,11 @@ SNode* createAlterTableSetTag(SAstCreateContext* pCxt, SNode* pRealTable, SToken
return
createAlterTableStmtFinalize
(
pRealTable
,
pStmt
);
}
SNode
*
setAlterSuperTableType
(
SNode
*
pStmt
)
{
setNodeType
(
pStmt
,
QUERY_NODE_ALTER_SUPER_TABLE_STMT
);
return
pStmt
;
}
SNode
*
createUseDatabaseStmt
(
SAstCreateContext
*
pCxt
,
SToken
*
pDbName
)
{
CHECK_PARSER_STATUS
(
pCxt
);
if
(
!
checkDbName
(
pCxt
,
pDbName
,
false
))
{
...
...
source/libs/parser/src/parInsert.c
浏览文件 @
988cffcc
...
...
@@ -48,6 +48,12 @@
pSql += sToken.n; \
} while (TK_NK_SPACE == sToken.type)
typedef
struct
SInsertParseBaseContext
{
SParseContext
*
pComCxt
;
char
*
pSql
;
SMsgBuf
msg
;
}
SInsertParseBaseContext
;
typedef
struct
SInsertParseContext
{
SParseContext
*
pComCxt
;
// input
char
*
pSql
;
// input
...
...
@@ -1105,6 +1111,32 @@ static int32_t storeTableMeta(SInsertParseContext* pCxt, SHashObj* pHash, SName*
return
taosHashPut
(
pHash
,
pName
,
len
,
&
pBackup
,
POINTER_BYTES
);
}
static
int32_t
skipParentheses
(
SInsertParseSyntaxCxt
*
pCxt
)
{
SToken
sToken
;
int32_t
expectRightParenthesis
=
1
;
while
(
1
)
{
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
if
(
TK_NK_LP
==
sToken
.
type
)
{
++
expectRightParenthesis
;
}
else
if
(
TK_NK_RP
==
sToken
.
type
&&
0
==
--
expectRightParenthesis
)
{
break
;
}
if
(
0
==
sToken
.
n
)
{
return
buildSyntaxErrMsg
(
&
pCxt
->
msg
,
") expected"
,
NULL
);
}
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
skipBoundColumns
(
SInsertParseSyntaxCxt
*
pCxt
)
{
return
skipParentheses
(
pCxt
);
}
static
int32_t
ignoreBoundColumns
(
SInsertParseContext
*
pCxt
)
{
SInsertParseSyntaxCxt
cxt
=
{.
pComCxt
=
pCxt
->
pComCxt
,
.
pSql
=
pCxt
->
pSql
,
.
msg
=
pCxt
->
msg
,
.
pMetaCache
=
NULL
};
int32_t
code
=
skipBoundColumns
(
&
cxt
);
pCxt
->
pSql
=
cxt
.
pSql
;
return
code
;
}
static
int32_t
skipUsingClause
(
SInsertParseSyntaxCxt
*
pCxt
);
// pSql -> stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)
...
...
@@ -1453,8 +1485,25 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
tNameGetFullDbName
(
&
name
,
dbFName
);
CHECK_CODE
(
taosHashPut
(
pCxt
->
pDbFNameHashObj
,
dbFName
,
strlen
(
dbFName
),
dbFName
,
sizeof
(
dbFName
)));
bool
existedUsing
=
false
;
// USING clause
if
(
TK_USING
==
sToken
.
type
)
{
existedUsing
=
true
;
CHECK_CODE
(
parseUsingClause
(
pCxt
,
&
name
,
tbFName
));
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
autoCreateTbl
=
true
;
}
char
*
pBoundColsStart
=
NULL
;
if
(
TK_NK_LP
==
sToken
.
type
)
{
// pSql -> field1_name, ...)
pBoundColsStart
=
pCxt
->
pSql
;
CHECK_CODE
(
ignoreBoundColumns
(
pCxt
));
// CHECK_CODE(parseBoundColumns(pCxt, &dataBuf->boundColumnInfo, getTableColumnSchema(pCxt->pTableMeta)));
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
}
if
(
TK_USING
==
sToken
.
type
&&
!
existedUsing
)
{
CHECK_CODE
(
parseUsingClause
(
pCxt
,
&
name
,
tbFName
));
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
autoCreateTbl
=
true
;
...
...
@@ -1467,10 +1516,11 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
sizeof
(
SSubmitBlk
),
getTableInfo
(
pCxt
->
pTableMeta
).
rowSize
,
pCxt
->
pTableMeta
,
&
dataBuf
,
NULL
,
&
pCxt
->
createTblReq
));
if
(
TK_NK_LP
==
sToken
.
type
)
{
// pSql -> field1_name, ...)
if
(
NULL
!=
pBoundColsStart
)
{
char
*
pCurrPos
=
pCxt
->
pSql
;
pCxt
->
pSql
=
pBoundColsStart
;
CHECK_CODE
(
parseBoundColumns
(
pCxt
,
&
dataBuf
->
boundColumnInfo
,
getTableColumnSchema
(
pCxt
->
pTableMeta
)));
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
)
;
pCxt
->
pSql
=
pCurrPos
;
}
if
(
TK_VALUES
==
sToken
.
type
)
{
...
...
@@ -1610,25 +1660,6 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery, SParseMetaCache
return
code
;
}
static
int32_t
skipParentheses
(
SInsertParseSyntaxCxt
*
pCxt
)
{
SToken
sToken
;
int32_t
expectRightParenthesis
=
1
;
while
(
1
)
{
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
if
(
TK_NK_LP
==
sToken
.
type
)
{
++
expectRightParenthesis
;
}
else
if
(
TK_NK_RP
==
sToken
.
type
&&
0
==
--
expectRightParenthesis
)
{
break
;
}
if
(
0
==
sToken
.
n
)
{
return
buildSyntaxErrMsg
(
&
pCxt
->
msg
,
") expected"
,
NULL
);
}
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
skipBoundColumns
(
SInsertParseSyntaxCxt
*
pCxt
)
{
return
skipParentheses
(
pCxt
);
}
// pSql -> (field1_value, ...) [(field1_value2, ...) ...]
static
int32_t
skipValuesClause
(
SInsertParseSyntaxCxt
*
pCxt
)
{
int32_t
numOfRows
=
0
;
...
...
@@ -1717,15 +1748,15 @@ static int32_t parseInsertBodySyntax(SInsertParseSyntaxCxt* pCxt) {
SToken
tbnameToken
=
sToken
;
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
bool
existedUsing
=
false
;
// USING clause
if
(
TK_USING
==
sToken
.
type
)
{
existedUsing
=
true
;
CHECK_CODE
(
collectAutoCreateTableMetaKey
(
pCxt
,
&
tbnameToken
));
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
CHECK_CODE
(
collectTableMetaKey
(
pCxt
,
&
sToken
));
CHECK_CODE
(
skipUsingClause
(
pCxt
));
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
}
else
{
CHECK_CODE
(
collectTableMetaKey
(
pCxt
,
&
tbnameToken
));
}
if
(
TK_NK_LP
==
sToken
.
type
)
{
...
...
@@ -1734,6 +1765,17 @@ static int32_t parseInsertBodySyntax(SInsertParseSyntaxCxt* pCxt) {
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
}
if
(
TK_USING
==
sToken
.
type
&&
!
existedUsing
)
{
existedUsing
=
true
;
CHECK_CODE
(
collectAutoCreateTableMetaKey
(
pCxt
,
&
tbnameToken
));
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
CHECK_CODE
(
collectTableMetaKey
(
pCxt
,
&
sToken
));
CHECK_CODE
(
skipUsingClause
(
pCxt
));
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
}
else
{
CHECK_CODE
(
collectTableMetaKey
(
pCxt
,
&
tbnameToken
));
}
if
(
TK_VALUES
==
sToken
.
type
)
{
// pSql -> (field1_value, ...) [(field1_value2, ...) ...]
CHECK_CODE
(
skipValuesClause
(
pCxt
));
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
988cffcc
...
...
@@ -1248,6 +1248,22 @@ static int32_t translateForbidGroupByFunc(STranslateContext* pCxt, SFunctionNode
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
translateRepeatScanFunc
(
STranslateContext
*
pCxt
,
SFunctionNode
*
pFunc
)
{
if
(
!
fmIsRepeatScanFunc
(
pFunc
->
funcId
))
{
return
TSDB_CODE_SUCCESS
;
}
if
(
isSelectStmt
(
pCxt
->
pCurrStmt
)
&&
NULL
!=
((
SSelectStmt
*
)
pCxt
->
pCurrStmt
)
->
pFromTable
)
{
SNode
*
pTable
=
((
SSelectStmt
*
)
pCxt
->
pCurrStmt
)
->
pFromTable
;
if
(
QUERY_NODE_REAL_TABLE
==
nodeType
(
pTable
)
&&
(
TSDB_CHILD_TABLE
==
((
SRealTableNode
*
)
pTable
)
->
pMeta
->
tableType
||
TSDB_NORMAL_TABLE
==
((
SRealTableNode
*
)
pTable
)
->
pMeta
->
tableType
))
{
return
TSDB_CODE_SUCCESS
;
}
}
return
generateSyntaxErrMsgExt
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE
,
"%s is only supported in single table query"
,
pFunc
->
functionName
);
}
static
void
setFuncClassification
(
SNode
*
pCurrStmt
,
SFunctionNode
*
pFunc
)
{
if
(
NULL
!=
pCurrStmt
&&
QUERY_NODE_SELECT_STMT
==
nodeType
(
pCurrStmt
))
{
SSelectStmt
*
pSelect
=
(
SSelectStmt
*
)
pCurrStmt
;
...
...
@@ -1370,6 +1386,9 @@ static int32_t translateNoramlFunction(STranslateContext* pCxt, SFunctionNode* p
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateForbidGroupByFunc
(
pCxt
,
pFunc
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateRepeatScanFunc
(
pCxt
,
pFunc
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
setFuncClassification
(
pCxt
->
pCurrStmt
,
pFunc
);
}
...
...
@@ -3743,12 +3762,24 @@ static int32_t buildAlterSuperTableReq(STranslateContext* pCxt, SAlterTableStmt*
return
TSDB_CODE_SUCCESS
;
}
static
SSchema
*
getColSchema
(
STableMeta
*
pTableMeta
,
const
char
*
p
Tag
Name
)
{
static
SSchema
*
getColSchema
(
STableMeta
*
pTableMeta
,
const
char
*
p
Col
Name
)
{
int32_t
numOfFields
=
getNumOfTags
(
pTableMeta
)
+
getNumOfColumns
(
pTableMeta
);
for
(
int32_t
i
=
0
;
i
<
numOfFields
;
++
i
)
{
SSchema
*
pTagSchema
=
pTableMeta
->
schema
+
i
;
if
(
0
==
strcmp
(
pTagName
,
pTagSchema
->
name
))
{
return
pTagSchema
;
SSchema
*
pSchema
=
pTableMeta
->
schema
+
i
;
if
(
0
==
strcmp
(
pColName
,
pSchema
->
name
))
{
return
pSchema
;
}
}
return
NULL
;
}
static
SSchema
*
getTagSchema
(
STableMeta
*
pTableMeta
,
const
char
*
pTagName
)
{
int32_t
numOfTags
=
getNumOfTags
(
pTableMeta
);
SSchema
*
pTagsSchema
=
getTableTagSchema
(
pTableMeta
);
for
(
int32_t
i
=
0
;
i
<
numOfTags
;
++
i
)
{
SSchema
*
pSchema
=
pTagsSchema
+
i
;
if
(
0
==
strcmp
(
pTagName
,
pSchema
->
name
))
{
return
pSchema
;
}
}
return
NULL
;
...
...
@@ -3756,19 +3787,24 @@ static SSchema* getColSchema(STableMeta* pTableMeta, const char* pTagName) {
static
int32_t
checkAlterSuperTable
(
STranslateContext
*
pCxt
,
SAlterTableStmt
*
pStmt
)
{
if
(
TSDB_ALTER_TABLE_UPDATE_TAG_VAL
==
pStmt
->
alterType
||
TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME
==
pStmt
->
alterType
)
{
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_ALTER_TABLE
);
return
generateSyntaxErrMsgExt
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_ALTER_TABLE
,
"Set tag value only available for child table"
);
}
if
(
TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES
==
pStmt
->
alterType
||
TSDB_ALTER_TABLE_UPDATE_TAG_BYTES
==
pStmt
->
alterType
)
{
STableMeta
*
pTableMeta
=
NULL
;
int32_t
code
=
getTableMeta
(
pCxt
,
pStmt
->
dbName
,
pStmt
->
tableName
,
&
pTableMeta
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
TSDB_SUPER_TABLE
!=
pTableMeta
->
tableType
)
{
return
generateSyntaxErrMsgExt
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_ALTER_TABLE
,
"Table is not super table"
);
}
SSchema
*
pSchema
=
getColSchema
(
pTableMeta
,
pStmt
->
colName
);
if
(
NULL
==
pSchema
)
{
code
=
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_COLUMN
,
pStmt
->
colName
);
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_COLUMN
,
pStmt
->
colName
);
}
else
if
(
!
IS_VAR_DATA_TYPE
(
pSchema
->
type
)
||
pSchema
->
type
!=
pStmt
->
dataType
.
type
||
pSchema
->
bytes
>=
calcTypeBytes
(
pStmt
->
dataType
))
{
code
=
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_MODIFY_COL
);
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_MODIFY_COL
);
}
}
return
code
;
...
...
@@ -4455,6 +4491,7 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
code
=
translateDropSuperTable
(
pCxt
,
(
SDropSuperTableStmt
*
)
pNode
);
break
;
case
QUERY_NODE_ALTER_TABLE_STMT
:
case
QUERY_NODE_ALTER_SUPER_TABLE_STMT
:
code
=
translateAlterSuperTable
(
pCxt
,
(
SAlterTableStmt
*
)
pNode
);
break
;
case
QUERY_NODE_CREATE_USER_STMT
:
...
...
@@ -5222,31 +5259,81 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, S
}
}
static
int32_t
createValueFromFunction
(
STranslateContext
*
pCxt
,
SFunctionNode
*
pFunc
,
SValueNode
**
pVal
)
{
int32_t
code
=
getFuncInfo
(
pCxt
,
pFunc
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
scalarCalculateConstants
((
SNode
*
)
pFunc
,
(
SNode
**
)
pVal
);
}
return
code
;
}
//
static int32_t createValueFromFunction(STranslateContext* pCxt, SFunctionNode* pFunc, SValueNode** pVal) {
//
int32_t code = getFuncInfo(pCxt, pFunc);
//
if (TSDB_CODE_SUCCESS == code) {
//
code = scalarCalculateConstants((SNode*)pFunc, (SNode**)pVal);
//
}
//
return code;
//
}
static
SDataType
schemaToDataType
(
uint8_t
precision
,
SSchema
*
pSchema
)
{
SDataType
dt
=
{.
type
=
pSchema
->
type
,
.
bytes
=
pSchema
->
bytes
,
.
precision
=
precision
,
.
scale
=
0
};
return
dt
;
}
static
int32_t
translateTagVal
(
STranslateContext
*
pCxt
,
uint8_t
precision
,
SSchema
*
pSchema
,
SNode
*
pNode
,
SValueNode
**
pVal
)
{
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
pNode
))
{
return
createValueFromFunction
(
pCxt
,
(
SFunctionNode
*
)
pNode
,
pVal
);
}
else
if
(
QUERY_NODE_VALUE
==
nodeType
(
pNode
))
{
return
(
DEAL_RES_ERROR
==
translateValueImpl
(
pCxt
,
(
SValueNode
*
)
pNode
,
schemaToDataType
(
precision
,
pSchema
))
?
pCxt
->
errCode
:
TSDB_CODE_SUCCESS
);
// static int32_t createValueFromExpr(STranslateContext* pCxt, SNode* pNode, SValueNode** pVal) {
// SNode* pExpr = nodesCloneNode(pNode);
// if (NULL == pExpr) {
// return TSDB_CODE_OUT_OF_MEMORY;
// }
// SNode* pNew = NULL;
// int32_t code = translateExpr(pCxt, &pExpr);
// if (TSDB_CODE_SUCCESS == code) {
// code = scalarCalculateConstants(pExpr, &pNew);
// }
// if (TSDB_CODE_SUCCESS == code) {
// pExpr = pNew;
// if (QUERY_NODE_VALUE != nodeType(pExpr)) {
// code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pExpr)->aliasName);
// }
// }
// if (TSDB_CODE_SUCCESS == code) {
// *pVal = pExpr;
// } else {
// nodesDestroyNode(pExpr);
// }
// return code;
// }
static
int32_t
createCastFuncForTag
(
STranslateContext
*
pCxt
,
SNode
*
pNode
,
SDataType
dt
,
SNode
**
pCast
)
{
SNode
*
pExpr
=
nodesCloneNode
(
pNode
);
if
(
NULL
==
pExpr
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
int32_t
code
=
createCastFunc
(
pCxt
,
pExpr
,
dt
,
pCast
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
nodesDestroyNode
(
pExpr
);
}
return
code
;
}
static
int32_t
createTagVal
(
STranslateContext
*
pCxt
,
uint8_t
precision
,
SSchema
*
pSchema
,
SNode
*
pNode
,
SValueNode
**
pVal
)
{
SNode
*
pCast
=
NULL
;
int32_t
code
=
createCastFuncForTag
(
pCxt
,
pNode
,
schemaToDataType
(
precision
,
pSchema
),
&
pCast
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateExpr
(
pCxt
,
&
pCast
);
}
SNode
*
pNew
=
NULL
;
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
scalarCalculateConstants
(
pCast
,
&
pNew
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
pCast
=
pNew
;
if
(
QUERY_NODE_VALUE
!=
nodeType
(
pCast
))
{
code
=
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
((
SExprNode
*
)
pNode
)
->
aliasName
);
}
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
*
pVal
=
(
SValueNode
*
)
pCast
;
}
else
{
// return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pNode)->aliasName);
return
TSDB_CODE_FAILED
;
nodesDestroyNode
(
pCast
);
}
return
code
;
}
static
int32_t
buildJsonTagVal
(
STranslateContext
*
pCxt
,
SSchema
*
pTagSchema
,
SValueNode
*
pVal
,
SArray
*
pTagArray
,
...
...
@@ -5285,56 +5372,45 @@ static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableCla
if
(
NULL
==
pTagArray
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
int32_t
code
=
TSDB_CODE_SUCCESS
;
SSchema
*
pTagSchema
=
getTableTagSchema
(
pSuperTableMeta
);
SNode
*
pTag
=
NULL
,
*
pNode
=
NULL
;
bool
isJson
=
false
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
bool
isJson
=
false
;
SNodeList
*
pVals
=
NULL
;
SNode
*
pTag
=
NULL
,
*
pNode
=
NULL
;
FORBOTH
(
pTag
,
pStmt
->
pSpecificTags
,
pNode
,
pStmt
->
pValsOfTags
)
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
pTag
;
SSchema
*
pSchema
=
NULL
;
for
(
int32_t
i
=
0
;
i
<
numOfTags
;
++
i
)
{
if
(
0
==
strcmp
(
pCol
->
colName
,
pTagSchema
[
i
].
name
))
{
pSchema
=
pTagSchema
+
i
;
break
;
}
}
SSchema
*
pSchema
=
getTagSchema
(
pSuperTableMeta
,
pCol
->
colName
);
if
(
NULL
==
pSchema
)
{
code
=
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_TAG_NAME
,
pCol
->
colName
);
goto
end
;
}
SValueNode
*
pVal
=
NULL
;
code
=
translateTagVal
(
pCxt
,
pSuperTableMeta
->
tableInfo
.
precision
,
pSchema
,
pNode
,
&
pVal
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
goto
end
;
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
createTagVal
(
pCxt
,
pSuperTableMeta
->
tableInfo
.
precision
,
pSchema
,
pNode
,
&
pVal
);
}
if
(
NULL
==
pVal
)
{
pVal
=
(
SValueNode
*
)
pNode
;
}
else
{
REPLACE_LIST2_NODE
(
pVal
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
pSchema
->
type
==
TSDB_DATA_TYPE_JSON
)
{
isJson
=
true
;
code
=
buildJsonTagVal
(
pCxt
,
pSchema
,
pVal
,
pTagArray
,
ppTag
);
}
else
if
(
pVal
->
node
.
resType
.
type
!=
TSDB_DATA_TYPE_NULL
)
{
code
=
buildNormalTagVal
(
pCxt
,
pSchema
,
pVal
,
pTagArray
);
}
}
if
(
pSchema
->
type
==
TSDB_DATA_TYPE_JSON
)
{
isJson
=
true
;
code
=
buildJsonTagVal
(
pCxt
,
pSchema
,
pVal
,
pTagArray
,
ppTag
);
}
else
if
(
pVal
->
node
.
resType
.
type
!=
TSDB_DATA_TYPE_NULL
)
{
code
=
buildNormalTagVal
(
pCxt
,
pSchema
,
pVal
,
pTagArray
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesListMakeAppend
(
&
pVals
,
(
SNode
*
)
pVal
);
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
}
if
(
!
isJson
)
code
=
tTagNew
(
pTagArray
,
1
,
false
,
ppTag
);
end:
if
(
isJson
)
{
for
(
int
i
=
0
;
i
<
taosArrayGetSize
(
pTagArray
);
++
i
)
{
STagVal
*
p
=
(
STagVal
*
)
taosArrayGet
(
pTagArray
,
i
);
if
(
IS_VAR_DATA_TYPE
(
p
->
type
))
{
taosMemoryFree
(
p
->
pData
);
}
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
!
isJson
)
{
code
=
tTagNew
(
pTagArray
,
1
,
false
,
ppTag
);
}
nodesDestroyList
(
pVals
);
taosArrayDestroy
(
pTagArray
);
return
TSDB_CODE_SUCCESS
;
return
code
;
}
static
int32_t
buildKVRowForAllTags
(
STranslateContext
*
pCxt
,
SCreateSubTableClause
*
pStmt
,
STableMeta
*
pSuperTableMeta
,
...
...
@@ -5343,64 +5419,52 @@ static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClau
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_TAGS_NOT_MATCHED
);
}
SSchema
*
pTagSchemas
=
getTableTagSchema
(
pSuperTableMeta
);
SNode
*
pNode
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
index
=
0
;
SArray
*
pTagArray
=
taosArrayInit
(
LIST_LENGTH
(
pStmt
->
pValsOfTags
),
sizeof
(
STagVal
));
if
(
!
pTagArray
)
{
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_TSC_OUT_OF_MEMORY
);
SArray
*
pTagArray
=
taosArrayInit
(
LIST_LENGTH
(
pStmt
->
pValsOfTags
),
sizeof
(
STagVal
));
if
(
NULL
==
pTagArray
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
bool
isJson
=
false
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
bool
isJson
=
false
;
int32_t
index
=
0
;
SSchema
*
pTagSchemas
=
getTableTagSchema
(
pSuperTableMeta
);
SNodeList
*
pVals
=
NULL
;
SNode
*
pNode
;
FOREACH
(
pNode
,
pStmt
->
pValsOfTags
)
{
SValueNode
*
pVal
=
NULL
;
SSchema
*
pTagSchema
=
pTagSchemas
+
index
;
code
=
translateTagVal
(
pCxt
,
pSuperTableMeta
->
tableInfo
.
precision
,
pTagSchema
,
pNode
,
&
pVal
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
goto
end
;
code
=
createTagVal
(
pCxt
,
pSuperTableMeta
->
tableInfo
.
precision
,
pTagSchema
,
pNode
,
&
pVal
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
pTagSchema
->
type
==
TSDB_DATA_TYPE_JSON
)
{
isJson
=
true
;
code
=
buildJsonTagVal
(
pCxt
,
pTagSchema
,
pVal
,
pTagArray
,
ppTag
);
}
else
if
(
pVal
->
node
.
resType
.
type
!=
TSDB_DATA_TYPE_NULL
&&
!
pVal
->
isNull
)
{
char
*
tmpVal
=
nodesGetValueFromNode
(
pVal
);
STagVal
val
=
{.
cid
=
pTagSchema
->
colId
,
.
type
=
pTagSchema
->
type
};
if
(
IS_VAR_DATA_TYPE
(
pTagSchema
->
type
))
{
val
.
pData
=
varDataVal
(
tmpVal
);
val
.
nData
=
varDataLen
(
tmpVal
);
}
else
{
memcpy
(
&
val
.
i64
,
tmpVal
,
pTagSchema
->
bytes
);
}
taosArrayPush
(
pTagArray
,
&
val
);
}
}
if
(
NULL
==
pVal
)
{
pVal
=
(
SValueNode
*
)
pNode
;
}
else
{
REPLACE_NODE
(
pVal
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesListMakeAppend
(
&
pVals
,
(
SNode
*
)
pVal
);
}
if
(
pTagSchema
->
type
==
TSDB_DATA_TYPE_JSON
)
{
if
(
pVal
->
literal
&&
strlen
(
pVal
->
literal
)
>
(
TSDB_MAX_JSON_TAG_LEN
-
VARSTR_HEADER_SIZE
)
/
TSDB_NCHAR_SIZE
)
{
code
=
buildSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
"json string too long than 4095"
,
pVal
->
literal
);
goto
end
;
}
isJson
=
true
;
code
=
parseJsontoTagData
(
pVal
->
literal
,
pTagArray
,
ppTag
,
&
pCxt
->
msgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
end
;
}
}
else
if
(
pVal
->
node
.
resType
.
type
!=
TSDB_DATA_TYPE_NULL
&&
!
pVal
->
isNull
)
{
char
*
tmpVal
=
nodesGetValueFromNode
(
pVal
);
STagVal
val
=
{.
cid
=
pTagSchema
->
colId
,
.
type
=
pTagSchema
->
type
};
if
(
IS_VAR_DATA_TYPE
(
pTagSchema
->
type
))
{
val
.
pData
=
varDataVal
(
tmpVal
);
val
.
nData
=
varDataLen
(
tmpVal
);
}
else
{
memcpy
(
&
val
.
i64
,
tmpVal
,
pTagSchema
->
bytes
);
}
taosArrayPush
(
pTagArray
,
&
val
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
++
index
;
}
if
(
!
isJson
)
code
=
tTagNew
(
pTagArray
,
1
,
false
,
ppTag
);
end:
if
(
isJson
)
{
for
(
int
i
=
0
;
i
<
taosArrayGetSize
(
pTagArray
);
++
i
)
{
STagVal
*
p
=
(
STagVal
*
)
taosArrayGet
(
pTagArray
,
i
);
if
(
IS_VAR_DATA_TYPE
(
p
->
type
))
{
taosMemoryFree
(
p
->
pData
);
}
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
!
isJson
)
{
code
=
tTagNew
(
pTagArray
,
1
,
false
,
ppTag
);
}
nodesDestroyList
(
pVals
);
taosArrayDestroy
(
pTagArray
);
return
code
;
}
...
...
source/libs/parser/src/parUtil.c
浏览文件 @
988cffcc
...
...
@@ -215,13 +215,21 @@ int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...) {
return
errCode
;
}
int32_t
generateSyntaxErrMsgExt
(
SMsgBuf
*
pBuf
,
int32_t
errCode
,
const
char
*
pFormat
,
...)
{
va_list
vArgList
;
va_start
(
vArgList
,
pFormat
);
vsnprintf
(
pBuf
->
buf
,
pBuf
->
len
,
pFormat
,
vArgList
);
va_end
(
vArgList
);
return
errCode
;
}
int32_t
buildInvalidOperationMsg
(
SMsgBuf
*
pBuf
,
const
char
*
msg
)
{
strncpy
(
pBuf
->
buf
,
msg
,
pBuf
->
len
);
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
int32_t
buildSyntaxErrMsg
(
SMsgBuf
*
pBuf
,
const
char
*
additionalInfo
,
const
char
*
sourceStr
)
{
if
(
pBuf
==
NULL
)
return
TSDB_CODE_TSC_SQL_SYNTAX_ERROR
;
if
(
pBuf
==
NULL
)
return
TSDB_CODE_TSC_SQL_SYNTAX_ERROR
;
const
char
*
msgFormat1
=
"syntax error near
\'
%s
\'
"
;
const
char
*
msgFormat2
=
"syntax error near
\'
%s
\'
(%s)"
;
const
char
*
msgFormat3
=
"%s"
;
...
...
source/libs/parser/src/sql.c
浏览文件 @
988cffcc
此差异已折叠。
点击以展开。
source/libs/planner/src/planOptimizer.c
浏览文件 @
988cffcc
...
...
@@ -1868,6 +1868,8 @@ static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) {
pCxt
->
errCode
=
terrno
;
return
DEAL_RES_ERROR
;
}
snprintf
(((
SExprNode
*
)
pExpr
)
->
aliasName
,
sizeof
(((
SExprNode
*
)
pExpr
)
->
aliasName
),
"%s"
,
((
SExprNode
*
)
*
pNode
)
->
aliasName
);
nodesDestroyNode
(
*
pNode
);
*
pNode
=
pExpr
;
}
...
...
source/libs/planner/src/planSpliter.c
浏览文件 @
988cffcc
...
...
@@ -986,6 +986,10 @@ static bool unionIsChildSubplan(SLogicNode* pLogicNode, int32_t groupId) {
return
((
SExchangeLogicNode
*
)
pLogicNode
)
->
srcGroupId
==
groupId
;
}
if
(
QUERY_NODE_LOGIC_PLAN_MERGE
==
nodeType
(
pLogicNode
))
{
return
((
SMergeLogicNode
*
)
pLogicNode
)
->
srcGroupId
==
groupId
;
}
SNode
*
pChild
;
FOREACH
(
pChild
,
pLogicNode
->
pChildren
)
{
bool
isChild
=
unionIsChildSubplan
((
SLogicNode
*
)
pChild
,
groupId
);
...
...
source/libs/planner/test/planSetOpTest.cpp
浏览文件 @
988cffcc
...
...
@@ -97,7 +97,15 @@ TEST_F(PlanSetOpTest, unionSubquery) {
run
(
"SELECT * FROM (SELECT c1, c2 FROM t1 UNION SELECT c1, c2 FROM t1)"
);
}
TEST_F
(
PlanSetOpTest
,
bug001
)
{
TEST_F
(
PlanSetOpTest
,
unionWithSubquery
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT c1 FROM (SELECT c1 FROM st1) UNION SELECT c2 FROM (SELECT c1 AS c2 FROM st2)"
);
run
(
"SELECT c1 FROM (SELECT c1 FROM st1 ORDER BY c2) UNION SELECT c1 FROM (SELECT c1 FROM st2)"
);
}
TEST_F
(
PlanSetOpTest
,
unionDataTypeConversion
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT c2 FROM t1 WHERE c1 IS NOT NULL GROUP BY c2 "
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录