Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
6aa602e4
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看板
提交
6aa602e4
编写于
6月 28, 2022
作者:
S
Shengliang Guan
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/3.0' into fix/tsim
上级
f98d4f33
b0b9b013
变更
22
隐藏空白更改
内联
并排
Showing
22 changed file
with
415 addition
and
170 deletion
+415
-170
include/libs/nodes/plannodes.h
include/libs/nodes/plannodes.h
+1
-0
include/libs/nodes/querynodes.h
include/libs/nodes/querynodes.h
+1
-0
include/libs/planner/planner.h
include/libs/planner/planner.h
+2
-0
include/libs/qcom/query.h
include/libs/qcom/query.h
+3
-3
source/libs/function/src/builtins.c
source/libs/function/src/builtins.c
+15
-14
source/libs/nodes/src/nodesCloneFuncs.c
source/libs/nodes/src/nodesCloneFuncs.c
+1
-0
source/libs/nodes/src/nodesUtilFuncs.c
source/libs/nodes/src/nodesUtilFuncs.c
+2
-1
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+8
-93
source/libs/parser/test/parSelectTest.cpp
source/libs/parser/test/parSelectTest.cpp
+0
-2
source/libs/planner/src/planLogicCreater.c
source/libs/planner/src/planLogicCreater.c
+41
-4
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+284
-14
source/libs/planner/src/planSpliter.c
source/libs/planner/src/planSpliter.c
+1
-1
source/libs/planner/src/planner.c
source/libs/planner/src/planner.c
+5
-0
source/libs/planner/test/planBasicTest.cpp
source/libs/planner/test/planBasicTest.cpp
+14
-0
source/libs/planner/test/planOptimizeTest.cpp
source/libs/planner/test/planOptimizeTest.cpp
+5
-3
source/libs/sync/src/syncMain.c
source/libs/sync/src/syncMain.c
+0
-12
source/libs/sync/src/syncSnapshot.c
source/libs/sync/src/syncSnapshot.c
+12
-3
tests/system-test/0-others/udfTest.py
tests/system-test/0-others/udfTest.py
+6
-6
tests/system-test/0-others/udf_create.py
tests/system-test/0-others/udf_create.py
+6
-6
tests/system-test/0-others/udf_restart_taosd.py
tests/system-test/0-others/udf_restart_taosd.py
+6
-6
tests/system-test/2-query/unique.py
tests/system-test/2-query/unique.py
+1
-1
tools/taos-tools
tools/taos-tools
+1
-1
未找到文件。
include/libs/nodes/plannodes.h
浏览文件 @
6aa602e4
...
...
@@ -103,6 +103,7 @@ typedef struct SIndefRowsFuncLogicNode {
SLogicNode
node
;
SNodeList
*
pFuncs
;
bool
isTailFunc
;
bool
isUniqueFunc
;
}
SIndefRowsFuncLogicNode
;
typedef
struct
SInterpFuncLogicNode
{
...
...
include/libs/nodes/querynodes.h
浏览文件 @
6aa602e4
...
...
@@ -50,6 +50,7 @@ typedef struct SExprNode {
char
aliasName
[
TSDB_COL_NAME_LEN
];
char
userAlias
[
TSDB_COL_NAME_LEN
];
SArray
*
pAssociation
;
bool
orderAlias
;
}
SExprNode
;
typedef
enum
EColumnType
{
COLUMN_TYPE_COLUMN
=
1
,
COLUMN_TYPE_TAG
,
COLUMN_TYPE_TBNAME
}
EColumnType
;
...
...
include/libs/planner/planner.h
浏览文件 @
6aa602e4
...
...
@@ -48,6 +48,8 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo
// @pSource one execution location of this group of datasource subplans
int32_t
qSetSubplanExecutionNode
(
SSubplan
*
pSubplan
,
int32_t
groupId
,
SDownstreamSourceNode
*
pSource
);
int32_t
qClearSubplanExecutionNode
(
SSubplan
*
pSubplan
,
int32_t
groupId
);
// Convert to subplan to string for the scheduler to send to the executor
int32_t
qSubPlanToString
(
const
SSubplan
*
pSubplan
,
char
**
pStr
,
int32_t
*
pLen
);
int32_t
qStringToSubplan
(
const
char
*
pStr
,
SSubplan
**
pSubplan
);
...
...
include/libs/qcom/query.h
浏览文件 @
6aa602e4
...
...
@@ -271,19 +271,19 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
#define qDebug(...) \
do { \
if (qDebugFlag & DEBUG_DEBUG) { \
taosPrintLog("QRY ", DEBUG_DEBUG,
qDebugFlag, __VA_ARGS__);
\
taosPrintLog("QRY ", DEBUG_DEBUG,
tsLogEmbedded ? 255 : qDebugFlag, __VA_ARGS__);
\
} \
} while (0)
#define qTrace(...) \
do { \
if (qDebugFlag & DEBUG_TRACE) { \
taosPrintLog("QRY ", DEBUG_TRACE,
qDebugFlag, __VA_ARGS__);
\
taosPrintLog("QRY ", DEBUG_TRACE,
tsLogEmbedded ? 255 : qDebugFlag, __VA_ARGS__);
\
} \
} while (0)
#define qDebugL(...) \
do { \
if (qDebugFlag & DEBUG_DEBUG) { \
taosPrintLongString("QRY ", DEBUG_DEBUG,
qDebugFlag, __VA_ARGS__);
\
taosPrintLongString("QRY ", DEBUG_DEBUG,
tsLogEmbedded ? 255 : qDebugFlag, __VA_ARGS__);
\
} \
} while (0)
...
...
source/libs/function/src/builtins.c
浏览文件 @
6aa602e4
...
...
@@ -1052,7 +1052,8 @@ static int32_t translateUniqueMode(SFunctionNode* pFunc, char* pErrBuf, int32_t
SNode
*
pPara
=
nodesListGetNode
(
pFunc
->
pParameterList
,
0
);
if
(
!
nodesExprHasColumn
(
pPara
))
{
return
buildFuncErrMsg
(
pErrBuf
,
len
,
TSDB_CODE_FUNC_FUNTION_ERROR
,
"The parameters of %s must contain columns"
,
isUnique
?
"UNIQUE"
:
"MODE"
);
return
buildFuncErrMsg
(
pErrBuf
,
len
,
TSDB_CODE_FUNC_FUNTION_ERROR
,
"The parameters of %s must contain columns"
,
isUnique
?
"UNIQUE"
:
"MODE"
);
}
pFunc
->
node
.
resType
=
((
SExprNode
*
)
pPara
)
->
resType
;
...
...
@@ -1228,19 +1229,19 @@ static int32_t translateSubstr(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
static
int32_t
translateCast
(
SFunctionNode
*
pFunc
,
char
*
pErrBuf
,
int32_t
len
)
{
// The number of parameters has been limited by the syntax definition
//uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
//
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
// The function return type has been set during syntax parsing
uint8_t
para2Type
=
pFunc
->
node
.
resType
.
type
;
//if (para2Type != TSDB_DATA_TYPE_BIGINT && para2Type != TSDB_DATA_TYPE_UBIGINT &&
// para2Type != TSDB_DATA_TYPE_VARCHAR && para2Type != TSDB_DATA_TYPE_NCHAR &&
// para2Type != TSDB_DATA_TYPE_TIMESTAMP) {
// return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
//}
//if ((para2Type == TSDB_DATA_TYPE_TIMESTAMP && IS_VAR_DATA_TYPE(para1Type)) ||
// (para2Type == TSDB_DATA_TYPE_BINARY && para1Type == TSDB_DATA_TYPE_NCHAR)) {
// return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
//}
//
if (para2Type != TSDB_DATA_TYPE_BIGINT && para2Type != TSDB_DATA_TYPE_UBIGINT &&
//
para2Type != TSDB_DATA_TYPE_VARCHAR && para2Type != TSDB_DATA_TYPE_NCHAR &&
//
para2Type != TSDB_DATA_TYPE_TIMESTAMP) {
//
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
//
}
//
if ((para2Type == TSDB_DATA_TYPE_TIMESTAMP && IS_VAR_DATA_TYPE(para1Type)) ||
//
(para2Type == TSDB_DATA_TYPE_BINARY && para1Type == TSDB_DATA_TYPE_NCHAR)) {
//
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
//
}
int32_t
para2Bytes
=
pFunc
->
node
.
resType
.
bytes
;
if
(
IS_VAR_DATA_TYPE
(
para2Type
))
{
...
...
@@ -1890,7 +1891,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{
.
name
=
"first"
,
.
type
=
FUNCTION_TYPE_FIRST
,
.
classification
=
FUNC_MGT_AGG_FUNC
|
FUNC_MGT_MULTI_RES_FUNC
|
FUNC_MGT_TIMELINE_FUNC
,
.
classification
=
FUNC_MGT_AGG_FUNC
|
FUNC_MGT_
SELECT_FUNC
|
FUNC_MGT_
MULTI_RES_FUNC
|
FUNC_MGT_TIMELINE_FUNC
,
.
translateFunc
=
translateFirstLast
,
.
getEnvFunc
=
getFirstLastFuncEnv
,
.
initFunc
=
functionSetup
,
...
...
@@ -1925,7 +1926,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{
.
name
=
"last"
,
.
type
=
FUNCTION_TYPE_LAST
,
.
classification
=
FUNC_MGT_AGG_FUNC
|
FUNC_MGT_MULTI_RES_FUNC
|
FUNC_MGT_TIMELINE_FUNC
,
.
classification
=
FUNC_MGT_AGG_FUNC
|
FUNC_MGT_
SELECT_FUNC
|
FUNC_MGT_
MULTI_RES_FUNC
|
FUNC_MGT_TIMELINE_FUNC
,
.
translateFunc
=
translateFirstLast
,
.
getEnvFunc
=
getFirstLastFuncEnv
,
.
initFunc
=
functionSetup
,
...
...
@@ -2117,7 +2118,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{
.
name
=
"unique"
,
.
type
=
FUNCTION_TYPE_UNIQUE
,
.
classification
=
FUNC_MGT_
AGG_FUNC
|
FUNC_MGT_SELECT_FUNC
|
FUNC_MGT_INDEFINITE_ROWS_FUNC
|
FUNC_MGT_TIMELINE_FUNC
|
.
classification
=
FUNC_MGT_
SELECT_FUNC
|
FUNC_MGT_INDEFINITE_ROWS_FUNC
|
FUNC_MGT_TIMELINE_FUNC
|
FUNC_MGT_FORBID_STREAM_FUNC
|
FUNC_MGT_FORBID_WINDOW_FUNC
|
FUNC_MGT_FORBID_GROUP_BY_FUNC
,
.
translateFunc
=
translateUnique
,
.
getEnvFunc
=
getUniqueFuncEnv
,
...
...
source/libs/nodes/src/nodesCloneFuncs.c
浏览文件 @
6aa602e4
...
...
@@ -100,6 +100,7 @@ static int32_t exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) {
COPY_OBJECT_FIELD
(
resType
,
sizeof
(
SDataType
));
COPY_CHAR_ARRAY_FIELD
(
aliasName
);
COPY_CHAR_ARRAY_FIELD
(
userAlias
);
COPY_SCALAR_FIELD
(
orderAlias
);
return
TSDB_CODE_SUCCESS
;
}
...
...
source/libs/nodes/src/nodesUtilFuncs.c
浏览文件 @
6aa602e4
...
...
@@ -1500,7 +1500,8 @@ typedef struct SCollectFuncsCxt {
static
EDealRes
collectFuncs
(
SNode
*
pNode
,
void
*
pContext
)
{
SCollectFuncsCxt
*
pCxt
=
(
SCollectFuncsCxt
*
)
pContext
;
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
pNode
)
&&
pCxt
->
classifier
(((
SFunctionNode
*
)
pNode
)
->
funcId
))
{
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
pNode
)
&&
pCxt
->
classifier
(((
SFunctionNode
*
)
pNode
)
->
funcId
)
&&
!
(((
SExprNode
*
)
pNode
)
->
orderAlias
))
{
pCxt
->
errCode
=
nodesListStrictAppend
(
pCxt
->
pFuncs
,
nodesCloneNode
(
pNode
));
return
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
?
DEAL_RES_IGNORE_CHILD
:
DEAL_RES_ERROR
);
}
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
6aa602e4
...
...
@@ -1355,25 +1355,6 @@ static EDealRes rewriteColToSelectValFunc(STranslateContext* pCxt, SNode** pNode
return
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
?
DEAL_RES_IGNORE_CHILD
:
DEAL_RES_ERROR
;
}
static
EDealRes
rewriteExprToGroupKeyFunc
(
STranslateContext
*
pCxt
,
SNode
**
pNode
)
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pFunc
)
{
pCxt
->
errCode
=
TSDB_CODE_OUT_OF_MEMORY
;
return
DEAL_RES_ERROR
;
}
strcpy
(
pFunc
->
functionName
,
"_group_key"
);
strcpy
(
pFunc
->
node
.
aliasName
,
((
SExprNode
*
)
*
pNode
)
->
aliasName
);
pCxt
->
errCode
=
nodesListMakeAppend
(
&
pFunc
->
pParameterList
,
*
pNode
);
if
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
)
{
*
pNode
=
(
SNode
*
)
pFunc
;
pCxt
->
errCode
=
fmGetFuncInfo
(
pFunc
,
pCxt
->
msgBuf
.
buf
,
pCxt
->
msgBuf
.
len
);
}
pCxt
->
pCurrSelectStmt
->
hasAggFuncs
=
true
;
return
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
?
DEAL_RES_IGNORE_CHILD
:
DEAL_RES_ERROR
);
}
static
EDealRes
doCheckExprForGroupBy
(
SNode
**
pNode
,
void
*
pContext
)
{
SCheckExprForGroupByCxt
*
pCxt
=
(
SCheckExprForGroupByCxt
*
)
pContext
;
if
(
!
nodesIsExprNode
(
*
pNode
)
||
isAliasColumn
(
*
pNode
))
{
...
...
@@ -1393,7 +1374,13 @@ static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) {
SNode
*
pGroupNode
=
NULL
;
FOREACH
(
pGroupNode
,
getGroupByList
(
pCxt
->
pTranslateCxt
))
{
if
(
nodesEqualNode
(
getGroupByNode
(
pGroupNode
),
*
pNode
))
{
return
rewriteExprToGroupKeyFunc
(
pCxt
->
pTranslateCxt
,
pNode
);
return
DEAL_RES_IGNORE_CHILD
;
}
}
SNode
*
pPartKey
=
NULL
;
FOREACH
(
pPartKey
,
pCxt
->
pTranslateCxt
->
pCurrSelectStmt
->
pPartitionByList
)
{
if
(
nodesEqualNode
(
pPartKey
,
*
pNode
))
{
return
DEAL_RES_IGNORE_CHILD
;
}
}
if
(
isScanPseudoColumnFunc
(
*
pNode
)
||
QUERY_NODE_COLUMN
==
nodeType
(
*
pNode
))
{
...
...
@@ -1451,25 +1438,6 @@ static int32_t rewriteColsToSelectValFunc(STranslateContext* pCxt, SSelectStmt*
return
pCxt
->
errCode
;
}
static
EDealRes
rewriteExprsToGroupKeyFuncImpl
(
SNode
**
pNode
,
void
*
pContext
)
{
STranslateContext
*
pCxt
=
pContext
;
SNode
*
pPartKey
=
NULL
;
FOREACH
(
pPartKey
,
pCxt
->
pCurrSelectStmt
->
pPartitionByList
)
{
if
(
nodesEqualNode
(
pPartKey
,
*
pNode
))
{
return
rewriteExprToGroupKeyFunc
(
pCxt
,
pNode
);
}
}
return
DEAL_RES_CONTINUE
;
}
static
int32_t
rewriteExprsToGroupKeyFunc
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
nodesRewriteExprs
(
pSelect
->
pProjectionList
,
rewriteExprsToGroupKeyFuncImpl
,
pCxt
);
if
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
&&
!
pSelect
->
isDistinct
)
{
nodesRewriteExprs
(
pSelect
->
pOrderByList
,
rewriteExprsToGroupKeyFuncImpl
,
pCxt
);
}
return
pCxt
->
errCode
;
}
typedef
struct
CheckAggColCoexistCxt
{
STranslateContext
*
pTranslateCxt
;
bool
existAggFunc
;
...
...
@@ -1529,9 +1497,6 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
if
(
cxt
.
existIndefiniteRowsFunc
&&
cxt
.
existCol
)
{
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_NOT_ALLOWED_FUNC
);
}
if
(
cxt
.
existAggFunc
&&
NULL
!=
pSelect
->
pPartitionByList
)
{
return
rewriteExprsToGroupKeyFunc
(
pCxt
,
pSelect
);
}
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -2408,54 +2373,6 @@ static EDealRes rewriteSeletcValueFunc(STranslateContext* pCxt, SNode** pNode) {
return
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
?
DEAL_RES_IGNORE_CHILD
:
DEAL_RES_ERROR
;
}
static
EDealRes
rewriteUniqueFunc
(
SNode
**
pNode
,
void
*
pContext
)
{
SRwriteUniqueCxt
*
pCxt
=
pContext
;
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
*
pNode
))
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
*
pNode
;
if
(
FUNCTION_TYPE_UNIQUE
==
pFunc
->
funcType
)
{
SNode
*
pExpr
=
nodesListGetNode
(
pFunc
->
pParameterList
,
0
);
NODES_CLEAR_LIST
(
pFunc
->
pParameterList
);
strcpy
(((
SExprNode
*
)
pExpr
)
->
aliasName
,
((
SExprNode
*
)
*
pNode
)
->
aliasName
);
nodesDestroyNode
(
*
pNode
);
*
pNode
=
pExpr
;
pCxt
->
pExpr
=
pExpr
;
return
DEAL_RES_IGNORE_CHILD
;
}
else
if
(
FUNCTION_TYPE_SELECT_VALUE
==
pFunc
->
funcType
)
{
return
rewriteSeletcValueFunc
(
pCxt
->
pTranslateCxt
,
pNode
);
}
}
return
DEAL_RES_CONTINUE
;
}
static
SNode
*
createGroupingSet
(
SNode
*
pExpr
)
{
SGroupingSetNode
*
pGroupingSet
=
(
SGroupingSetNode
*
)
nodesMakeNode
(
QUERY_NODE_GROUPING_SET
);
if
(
NULL
==
pGroupingSet
)
{
return
NULL
;
}
pGroupingSet
->
groupingSetType
=
GP_TYPE_NORMAL
;
if
(
TSDB_CODE_SUCCESS
!=
nodesListMakeStrictAppend
(
&
pGroupingSet
->
pParameterList
,
nodesCloneNode
(
pExpr
)))
{
nodesDestroyNode
((
SNode
*
)
pGroupingSet
);
return
NULL
;
}
return
(
SNode
*
)
pGroupingSet
;
}
// from: select unique(expr), col1 + col2 from t where_clause partition_by_clause order_by_clause ...
// to: select expr, first(col1) + first(col2) from t where_clause partition_by_clause group by expr order_by_clause ...
static
int32_t
rewriteUniqueStmt
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
if
(
!
pSelect
->
hasUniqueFunc
)
{
return
TSDB_CODE_SUCCESS
;
}
SRwriteUniqueCxt
cxt
=
{.
pTranslateCxt
=
pCxt
,
.
pExpr
=
NULL
};
nodesRewriteExprs
(
pSelect
->
pProjectionList
,
rewriteUniqueFunc
,
&
cxt
);
if
(
TSDB_CODE_SUCCESS
==
cxt
.
pTranslateCxt
->
errCode
)
{
cxt
.
pTranslateCxt
->
errCode
=
nodesListMakeStrictAppend
(
&
pSelect
->
pGroupByList
,
createGroupingSet
(
cxt
.
pExpr
));
}
pSelect
->
hasIndefiniteRowsFunc
=
false
;
return
cxt
.
pTranslateCxt
->
errCode
;
}
typedef
struct
SReplaceOrderByAliasCxt
{
STranslateContext
*
pTranslateCxt
;
SNodeList
*
pProjectionList
;
...
...
@@ -2474,6 +2391,7 @@ static EDealRes replaceOrderByAliasImpl(SNode** pNode, void* pContext) {
pCxt
->
pTranslateCxt
->
errCode
=
TSDB_CODE_OUT_OF_MEMORY
;
return
DEAL_RES_ERROR
;
}
((
SExprNode
*
)
pNew
)
->
orderAlias
=
true
;
nodesDestroyNode
(
*
pNode
);
*
pNode
=
pNew
;
return
DEAL_RES_CONTINUE
;
...
...
@@ -2529,9 +2447,6 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateInterp
(
pCxt
,
pSelect
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
rewriteUniqueStmt
(
pCxt
,
pSelect
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
rewriteTimelineFunc
(
pCxt
,
pSelect
);
}
...
...
source/libs/parser/test/parSelectTest.cpp
浏览文件 @
6aa602e4
...
...
@@ -232,8 +232,6 @@ TEST_F(ParserSelectTest, groupBySemanticCheck) {
run
(
"SELECT COUNT(*) cnt, c1 FROM t1 WHERE c1 > 0"
,
TSDB_CODE_PAR_NOT_SINGLE_GROUP
);
run
(
"SELECT COUNT(*) cnt, c2 FROM t1 WHERE c1 > 0 GROUP BY c1"
,
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
);
run
(
"SELECT COUNT(*) cnt, c2 FROM t1 WHERE c1 > 0 PARTITION BY c2 GROUP BY c1"
,
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
);
}
TEST_F
(
ParserSelectTest
,
orderBy
)
{
...
...
source/libs/planner/src/planLogicCreater.c
浏览文件 @
6aa602e4
...
...
@@ -437,6 +437,33 @@ static SColumnNode* createColumnByExpr(const char* pStmtName, SExprNode* pExpr)
return
pCol
;
}
static
SNode
*
createGroupingSetNode
(
SNode
*
pExpr
)
{
SGroupingSetNode
*
pGroupingSet
=
(
SGroupingSetNode
*
)
nodesMakeNode
(
QUERY_NODE_GROUPING_SET
);
if
(
NULL
==
pGroupingSet
)
{
return
NULL
;
}
pGroupingSet
->
groupingSetType
=
GP_TYPE_NORMAL
;
if
(
TSDB_CODE_SUCCESS
!=
nodesListMakeStrictAppend
(
&
pGroupingSet
->
pParameterList
,
nodesCloneNode
(
pExpr
)))
{
nodesDestroyNode
((
SNode
*
)
pGroupingSet
);
return
NULL
;
}
return
(
SNode
*
)
pGroupingSet
;
}
static
int32_t
createGroupKeysFromPartKeys
(
SNodeList
*
pPartKeys
,
SNodeList
**
pOutput
)
{
SNodeList
*
pGroupKeys
=
NULL
;
SNode
*
pPartKey
=
NULL
;
FOREACH
(
pPartKey
,
pPartKeys
)
{
int32_t
code
=
nodesListMakeStrictAppend
(
&
pGroupKeys
,
createGroupingSetNode
(
pPartKey
));
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
nodesDestroyList
(
pGroupKeys
);
return
code
;
}
}
*
pOutput
=
pGroupKeys
;
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
createAggLogicNode
(
SLogicPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
SLogicNode
**
pLogicNode
)
{
if
(
!
pSelect
->
hasAggFuncs
&&
NULL
==
pSelect
->
pGroupByList
)
{
return
TSDB_CODE_SUCCESS
;
...
...
@@ -459,10 +486,18 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
code
=
rewriteExprsForSelect
(
pAgg
->
pAggFuncs
,
pSelect
,
SQL_CLAUSE_GROUP_BY
);
}
if
(
NULL
!=
pSelect
->
pPartitionByList
)
{
code
=
createGroupKeysFromPartKeys
(
pSelect
->
pPartitionByList
,
&
pAgg
->
pGroupKeys
);
}
if
(
NULL
!=
pSelect
->
pGroupByList
)
{
pAgg
->
pGroupKeys
=
nodesCloneList
(
pSelect
->
pGroupByList
);
if
(
NULL
==
pAgg
->
pGroupKeys
)
{
code
=
TSDB_CODE_OUT_OF_MEMORY
;
if
(
NULL
!=
pAgg
->
pGroupKeys
)
{
code
=
nodesListStrictAppendList
(
pAgg
->
pGroupKeys
,
nodesCloneList
(
pSelect
->
pGroupByList
));
}
else
{
pAgg
->
pGroupKeys
=
nodesCloneList
(
pSelect
->
pGroupByList
);
if
(
NULL
==
pAgg
->
pGroupKeys
)
{
code
=
TSDB_CODE_OUT_OF_MEMORY
;
}
}
}
...
...
@@ -508,6 +543,7 @@ static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt
}
pIdfRowsFunc
->
isTailFunc
=
pSelect
->
hasTailFunc
;
pIdfRowsFunc
->
isUniqueFunc
=
pSelect
->
hasUniqueFunc
;
// indefinite rows functions and _select_values functions
int32_t
code
=
nodesCollectFuncs
(
pSelect
,
SQL_CLAUSE_SELECT
,
fmIsVectorFunc
,
&
pIdfRowsFunc
->
pFuncs
);
...
...
@@ -809,7 +845,8 @@ static int32_t createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSel
}
static
int32_t
createPartitionLogicNode
(
SLogicPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
SLogicNode
**
pLogicNode
)
{
if
(
NULL
==
pSelect
->
pPartitionByList
)
{
if
(
NULL
==
pSelect
->
pPartitionByList
||
(
pSelect
->
hasAggFuncs
&&
NULL
==
pSelect
->
pWindow
)
||
NULL
!=
pSelect
->
pGroupByList
)
{
return
TSDB_CODE_SUCCESS
;
}
...
...
source/libs/planner/src/planOptimizer.c
浏览文件 @
6aa602e4
...
...
@@ -987,6 +987,7 @@ static int32_t smaIndexOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogi
code
=
smaIndexOptApplyIndex
(
pLogicSubplan
,
pScan
,
pIndex
,
pSmaCols
,
wstrartIndex
);
taosArrayDestroyEx
(
pScan
->
pSmaIndexes
,
smaIndexOptDestroySmaIndex
);
pScan
->
pSmaIndexes
=
NULL
;
pCxt
->
optimized
=
true
;
break
;
}
}
...
...
@@ -1033,12 +1034,30 @@ static SNodeList* partTagsGetPartKeys(SLogicNode* pNode) {
}
}
static
SNodeList
*
partTagsGetFuncs
(
SLogicNode
*
pNode
)
{
if
(
QUERY_NODE_LOGIC_PLAN_PARTITION
==
nodeType
(
pNode
))
{
return
NULL
;
}
else
{
return
((
SAggLogicNode
*
)
pNode
)
->
pAggFuncs
;
}
}
static
bool
partTagsOptAreSupportedFuncs
(
SNodeList
*
pFuncs
)
{
SNode
*
pFunc
=
NULL
;
FOREACH
(
pFunc
,
pFuncs
)
{
if
(
fmIsIndefiniteRowsFunc
(((
SFunctionNode
*
)
pFunc
)
->
funcId
)
&&
!
fmIsSelectFunc
(((
SFunctionNode
*
)
pFunc
)
->
funcId
))
{
return
false
;
}
}
return
true
;
}
static
bool
partTagsOptMayBeOptimized
(
SLogicNode
*
pNode
)
{
if
(
!
partTagsIsOptimizableNode
(
pNode
))
{
return
false
;
}
return
!
partTagsOptHasCol
(
partTagsGetPartKeys
(
pNode
));
return
!
partTagsOptHasCol
(
partTagsGetPartKeys
(
pNode
))
&&
partTagsOptAreSupportedFuncs
(
partTagsGetFuncs
(
pNode
))
;
}
static
EDealRes
partTagsOptRebuildTbanmeImpl
(
SNode
**
pNode
,
void
*
pContext
)
{
...
...
@@ -1064,6 +1083,59 @@ static int32_t partTagsOptRebuildTbanme(SNodeList* pPartKeys) {
return
code
;
}
static
SNode
*
partTagsCreateWrapperFunc
(
const
char
*
pFuncName
,
SNode
*
pNode
)
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pFunc
)
{
return
NULL
;
}
strcpy
(
pFunc
->
functionName
,
pFuncName
);
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pNode
))
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
pNode
;
sprintf
(
pFunc
->
node
.
aliasName
,
"%s.%s"
,
pCol
->
tableAlias
,
pCol
->
colName
);
}
else
{
strcpy
(
pFunc
->
node
.
aliasName
,
((
SExprNode
*
)
pNode
)
->
aliasName
);
}
int32_t
code
=
nodesListMakeStrictAppend
(
&
pFunc
->
pParameterList
,
nodesCloneNode
(
pNode
));
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
fmGetFuncInfo
(
pFunc
,
NULL
,
0
);
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
nodesDestroyNode
((
SNode
*
)
pFunc
);
return
NULL
;
}
return
(
SNode
*
)
pFunc
;
}
static
bool
partTagsHasIndefRowsSelectFunc
(
SNodeList
*
pFuncs
)
{
SNode
*
pFunc
=
NULL
;
FOREACH
(
pFunc
,
pFuncs
)
{
if
(
fmIsIndefiniteRowsFunc
(((
SFunctionNode
*
)
pFunc
)
->
funcId
))
{
return
true
;
}
}
return
false
;
}
static
int32_t
partTagsRewriteGroupTagsToFuncs
(
SNodeList
*
pGroupTags
,
SNodeList
*
pAggFuncs
)
{
bool
hasIndefRowsSelectFunc
=
partTagsHasIndefRowsSelectFunc
(
pAggFuncs
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
SNode
*
pNode
=
NULL
;
FOREACH
(
pNode
,
pGroupTags
)
{
if
(
hasIndefRowsSelectFunc
)
{
code
=
nodesListStrictAppend
(
pAggFuncs
,
partTagsCreateWrapperFunc
(
"_select_value"
,
pNode
));
}
else
{
code
=
nodesListStrictAppend
(
pAggFuncs
,
partTagsCreateWrapperFunc
(
"_group_key"
,
pNode
));
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
}
return
code
;
}
static
int32_t
partTagsOptimize
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
SLogicNode
*
pNode
=
optFindPossibleNode
(
pLogicSubplan
->
pNode
,
partTagsOptMayBeOptimized
);
if
(
NULL
==
pNode
)
{
...
...
@@ -1080,15 +1152,17 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
nodesDestroyNode
((
SNode
*
)
pNode
);
}
}
else
{
SNode
*
pGroupKey
=
NULL
;
FOREACH
(
pGroupKey
,
((
SAggLogicNode
*
)
pNode
)
->
pGroupKeys
)
{
SAggLogicNode
*
pAgg
=
(
SAggLogicNode
*
)
pNode
;
SNode
*
pGroupKey
=
NULL
;
FOREACH
(
pGroupKey
,
pAgg
->
pGroupKeys
)
{
code
=
nodesListMakeStrictAppend
(
&
pScan
->
pGroupTags
,
nodesCloneNode
(
nodesListGetNode
(((
SGroupingSetNode
*
)
pGroupKey
)
->
pParameterList
,
0
)));
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
}
NODES_DESTORY_LIST
(((
SAggLogicNode
*
)
pNode
)
->
pGroupKeys
);
NODES_DESTORY_LIST
(
pAgg
->
pGroupKeys
);
code
=
partTagsRewriteGroupTagsToFuncs
(
pScan
->
pGroupTags
,
pAgg
->
pAggFuncs
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
partTagsOptRebuildTbanme
(
pScan
->
pGroupTags
);
...
...
@@ -1125,7 +1199,8 @@ static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode) {
}
SProjectLogicNode
*
pProjectNode
=
(
SProjectLogicNode
*
)
pNode
;
if
(
NULL
!=
pProjectNode
->
node
.
pLimit
||
NULL
!=
pProjectNode
->
node
.
pSlimit
)
{
if
(
NULL
!=
pProjectNode
->
node
.
pLimit
||
NULL
!=
pProjectNode
->
node
.
pSlimit
||
NULL
!=
pProjectNode
->
node
.
pConditions
)
{
return
false
;
}
...
...
@@ -1163,6 +1238,7 @@ static int32_t eliminateProjOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan*
NODES_CLEAR_LIST
(
pProjectNode
->
node
.
pChildren
);
nodesDestroyNode
((
SNode
*
)
pProjectNode
);
}
pCxt
->
optimized
=
true
;
return
code
;
}
...
...
@@ -1306,6 +1382,7 @@ static int32_t rewriteTailOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pL
nodesDestroyNode
((
SNode
*
)
pSort
);
nodesDestroyNode
((
SNode
*
)
pProject
);
}
pCxt
->
optimized
=
true
;
return
code
;
}
...
...
@@ -1344,6 +1421,7 @@ static int32_t eliminateSetOpOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan*
pSetOpNode
->
pChildren
=
NULL
;
ERASE_NODE
(
pSetOpNode
->
pParent
->
pChildren
);
pCxt
->
optimized
=
true
;
return
TSDB_CODE_SUCCESS
;
}
}
...
...
@@ -1360,15 +1438,192 @@ static int32_t eliminateSetOpOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLo
return
eliminateSetOpOptimizeImpl
(
pCxt
,
pLogicSubplan
,
pSetOpNode
);
}
//===================================================================================================================
static
bool
rewriteUniqueOptMayBeOptimized
(
SLogicNode
*
pNode
)
{
return
QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC
==
nodeType
(
pNode
)
&&
((
SIndefRowsFuncLogicNode
*
)
pNode
)
->
isUniqueFunc
;
}
static
SNode
*
rewriteUniqueOptCreateGroupingSet
(
SNode
*
pExpr
)
{
SGroupingSetNode
*
pGroupingSet
=
(
SGroupingSetNode
*
)
nodesMakeNode
(
QUERY_NODE_GROUPING_SET
);
if
(
NULL
==
pGroupingSet
)
{
return
NULL
;
}
pGroupingSet
->
groupingSetType
=
GP_TYPE_NORMAL
;
SExprNode
*
pGroupExpr
=
(
SExprNode
*
)
nodesCloneNode
(
pExpr
);
if
(
TSDB_CODE_SUCCESS
!=
nodesListMakeStrictAppend
(
&
pGroupingSet
->
pParameterList
,
(
SNode
*
)
pGroupExpr
))
{
nodesDestroyNode
((
SNode
*
)
pGroupingSet
);
return
NULL
;
}
return
(
SNode
*
)
pGroupingSet
;
}
static
SNode
*
rewriteUniqueOptCreateFirstFunc
(
SFunctionNode
*
pSelectValue
,
SNode
*
pCol
)
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pFunc
)
{
return
NULL
;
}
strcpy
(
pFunc
->
functionName
,
"first"
);
if
(
NULL
!=
pSelectValue
)
{
sprintf
(
pFunc
->
node
.
aliasName
,
"%s"
,
pSelectValue
->
node
.
aliasName
);
}
else
{
sprintf
(
pFunc
->
node
.
aliasName
,
"%s.%p"
,
pFunc
->
functionName
,
pFunc
);
}
int32_t
code
=
nodesListMakeStrictAppend
(
&
pFunc
->
pParameterList
,
nodesCloneNode
(
pCol
));
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
fmGetFuncInfo
(
pFunc
,
NULL
,
0
);
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
nodesDestroyNode
((
SNode
*
)
pFunc
);
return
NULL
;
}
return
(
SNode
*
)
pFunc
;
}
static
int32_t
rewriteUniqueOptCreateAgg
(
SIndefRowsFuncLogicNode
*
pIndef
,
SLogicNode
**
pOutput
)
{
SAggLogicNode
*
pAgg
=
(
SAggLogicNode
*
)
nodesMakeNode
(
QUERY_NODE_LOGIC_PLAN_AGG
);
if
(
NULL
==
pAgg
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
TSWAP
(
pAgg
->
node
.
pChildren
,
pIndef
->
node
.
pChildren
);
pAgg
->
node
.
precision
=
pIndef
->
node
.
precision
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
bool
hasSelectPrimaryKey
=
false
;
SNode
*
pPrimaryKey
=
NULL
;
SNode
*
pNode
=
NULL
;
FOREACH
(
pNode
,
pIndef
->
pFuncs
)
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
pNode
;
SNode
*
pExpr
=
nodesListGetNode
(
pFunc
->
pParameterList
,
0
);
if
(
FUNCTION_TYPE_UNIQUE
==
pFunc
->
funcType
)
{
pPrimaryKey
=
nodesListGetNode
(
pFunc
->
pParameterList
,
1
);
code
=
nodesListMakeStrictAppend
(
&
pAgg
->
pGroupKeys
,
rewriteUniqueOptCreateGroupingSet
(
pExpr
));
}
else
if
(
PRIMARYKEY_TIMESTAMP_COL_ID
==
((
SColumnNode
*
)
pExpr
)
->
colId
)
{
// _select_value(ts) => first(ts)
hasSelectPrimaryKey
=
true
;
code
=
nodesListMakeStrictAppend
(
&
pAgg
->
pAggFuncs
,
rewriteUniqueOptCreateFirstFunc
(
pFunc
,
pExpr
));
}
else
{
// _select_value(other_col)
code
=
nodesListMakeStrictAppend
(
&
pAgg
->
pAggFuncs
,
nodesCloneNode
(
pNode
));
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
createColumnByRewriteExprs
(
pAgg
->
pGroupKeys
,
&
pAgg
->
node
.
pTargets
);
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pAgg
->
pAggFuncs
)
{
code
=
createColumnByRewriteExprs
(
pAgg
->
pAggFuncs
,
&
pAgg
->
node
.
pTargets
);
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
!
hasSelectPrimaryKey
&&
NULL
!=
pAgg
->
pAggFuncs
)
{
code
=
nodesListMakeStrictAppend
(
&
pAgg
->
pAggFuncs
,
rewriteUniqueOptCreateFirstFunc
(
NULL
,
pPrimaryKey
));
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
*
pOutput
=
(
SLogicNode
*
)
pAgg
;
}
else
{
nodesDestroyNode
((
SNode
*
)
pAgg
);
}
return
code
;
}
static
SNode
*
rewriteUniqueOptCreateProjectCol
(
SFunctionNode
*
pFunc
)
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
nodesMakeNode
(
QUERY_NODE_COLUMN
);
if
(
NULL
==
pCol
)
{
return
NULL
;
}
pCol
->
node
.
resType
=
pFunc
->
node
.
resType
;
if
(
FUNCTION_TYPE_UNIQUE
==
pFunc
->
funcType
)
{
SExprNode
*
pExpr
=
(
SExprNode
*
)
nodesListGetNode
(
pFunc
->
pParameterList
,
0
);
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pExpr
))
{
strcpy
(
pCol
->
tableAlias
,
((
SColumnNode
*
)
pExpr
)
->
tableAlias
);
strcpy
(
pCol
->
colName
,
((
SColumnNode
*
)
pExpr
)
->
colName
);
}
else
{
strcpy
(
pCol
->
colName
,
pExpr
->
aliasName
);
}
}
else
{
strcpy
(
pCol
->
colName
,
pFunc
->
node
.
aliasName
);
}
strcpy
(
pCol
->
node
.
aliasName
,
pFunc
->
node
.
aliasName
);
return
(
SNode
*
)
pCol
;
}
static
int32_t
rewriteUniqueOptCreateProject
(
SIndefRowsFuncLogicNode
*
pIndef
,
SLogicNode
**
pOutput
)
{
SProjectLogicNode
*
pProject
=
(
SProjectLogicNode
*
)
nodesMakeNode
(
QUERY_NODE_LOGIC_PLAN_PROJECT
);
if
(
NULL
==
pProject
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
TSWAP
(
pProject
->
node
.
pTargets
,
pIndef
->
node
.
pTargets
);
pProject
->
node
.
precision
=
pIndef
->
node
.
precision
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
SNode
*
pNode
=
NULL
;
FOREACH
(
pNode
,
pIndef
->
pFuncs
)
{
code
=
nodesListMakeStrictAppend
(
&
pProject
->
pProjections
,
rewriteUniqueOptCreateProjectCol
((
SFunctionNode
*
)
pNode
));
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
*
pOutput
=
(
SLogicNode
*
)
pProject
;
}
else
{
nodesDestroyNode
((
SNode
*
)
pProject
);
}
return
code
;
}
static
int32_t
rewriteUniqueOptimizeImpl
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
,
SIndefRowsFuncLogicNode
*
pIndef
)
{
SLogicNode
*
pAgg
=
NULL
;
SLogicNode
*
pProject
=
NULL
;
int32_t
code
=
rewriteUniqueOptCreateAgg
(
pIndef
,
&
pAgg
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
rewriteUniqueOptCreateProject
(
pIndef
,
&
pProject
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesListMakeAppend
(
&
pProject
->
pChildren
,
(
SNode
*
)
pAgg
);
pAgg
->
pParent
=
pProject
;
pAgg
=
NULL
;
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
replaceLogicNode
(
pLogicSubplan
,
(
SLogicNode
*
)
pIndef
,
pProject
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
nodesDestroyNode
((
SNode
*
)
pIndef
);
}
else
{
nodesDestroyNode
((
SNode
*
)
pAgg
);
nodesDestroyNode
((
SNode
*
)
pProject
);
}
pCxt
->
optimized
=
true
;
return
code
;
}
static
int32_t
rewriteUniqueOptimize
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
SIndefRowsFuncLogicNode
*
pIndef
=
(
SIndefRowsFuncLogicNode
*
)
optFindPossibleNode
(
pLogicSubplan
->
pNode
,
rewriteUniqueOptMayBeOptimized
);
if
(
NULL
==
pIndef
)
{
return
TSDB_CODE_SUCCESS
;
}
return
rewriteUniqueOptimizeImpl
(
pCxt
,
pLogicSubplan
,
pIndef
);
}
// merge projects
static
bool
mergeProjectsMayBeOptimized
(
SLogicNode
*
pNode
)
{
if
(
QUERY_NODE_LOGIC_PLAN_PROJECT
!=
nodeType
(
pNode
)
||
1
!=
LIST_LENGTH
(
pNode
->
pChildren
))
{
return
false
;
}
SLogicNode
*
pChild
=
(
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
);
SLogicNode
*
pChild
=
(
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
);
if
(
QUERY_NODE_LOGIC_PLAN_PROJECT
!=
nodeType
(
pChild
)
||
1
<
LIST_LENGTH
(
pChild
->
pChildren
)
||
NULL
!=
pChild
->
pConditions
||
NULL
!=
p
Node
->
pLimit
||
NULL
!=
pNode
->
pSlimit
)
{
NULL
!=
pChild
->
pConditions
||
NULL
!=
p
Child
->
pLimit
||
NULL
!=
pChild
->
pSlimit
)
{
return
false
;
}
return
true
;
...
...
@@ -1376,12 +1631,12 @@ static bool mergeProjectsMayBeOptimized(SLogicNode* pNode) {
typedef
struct
SMergeProjectionsContext
{
SProjectLogicNode
*
pChildProj
;
int32_t
errCode
;
int32_t
errCode
;
}
SMergeProjectionsContext
;
static
EDealRes
mergeProjectionsExpr
(
SNode
**
pNode
,
void
*
pContext
)
{
SMergeProjectionsContext
*
pCxt
=
pContext
;
SProjectLogicNode
*
pChildProj
=
pCxt
->
pChildProj
;
SProjectLogicNode
*
pChildProj
=
pCxt
->
pChildProj
;
if
(
QUERY_NODE_COLUMN
==
nodeType
(
*
pNode
))
{
SNode
*
pTarget
;
FOREACH
(
pTarget
,
((
SLogicNode
*
)
pChildProj
)
->
pTargets
)
{
...
...
@@ -1406,7 +1661,7 @@ static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) {
}
static
int32_t
mergeProjectsOptimizeImpl
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
,
SLogicNode
*
pSelfNode
)
{
SLogicNode
*
pChild
=
(
SLogicNode
*
)
nodesListGetNode
(
pSelfNode
->
pChildren
,
0
);
SLogicNode
*
pChild
=
(
SLogicNode
*
)
nodesListGetNode
(
pSelfNode
->
pChildren
,
0
);
SMergeProjectionsContext
cxt
=
{.
pChildProj
=
(
SProjectLogicNode
*
)
pChild
,
.
errCode
=
TSDB_CODE_SUCCESS
};
nodesRewriteExprs
(((
SProjectLogicNode
*
)
pSelfNode
)
->
pProjections
,
mergeProjectionsExpr
,
&
cxt
);
...
...
@@ -1425,6 +1680,7 @@ static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan*
NODES_CLEAR_LIST
(
pChild
->
pChildren
);
}
nodesDestroyNode
((
SNode
*
)
pChild
);
pCxt
->
optimized
=
true
;
return
code
;
}
...
...
@@ -1447,23 +1703,37 @@ static const SOptimizeRule optimizeRuleSet[] = {
{.
pName
=
"MergeProjects"
,
.
optimizeFunc
=
mergeProjectsOptimize
},
{.
pName
=
"EliminateProject"
,
.
optimizeFunc
=
eliminateProjOptimize
},
{.
pName
=
"EliminateSetOperator"
,
.
optimizeFunc
=
eliminateSetOpOptimize
},
{.
pName
=
"RewriteTail"
,
.
optimizeFunc
=
rewriteTailOptimize
}
{.
pName
=
"RewriteTail"
,
.
optimizeFunc
=
rewriteTailOptimize
},
{.
pName
=
"RewriteUnique"
,
.
optimizeFunc
=
rewriteUniqueOptimize
}
};
// clang-format on
static
const
int32_t
optimizeRuleNum
=
(
sizeof
(
optimizeRuleSet
)
/
sizeof
(
SOptimizeRule
));
static
void
dumpLogicSubplan
(
const
char
*
pRuleName
,
SLogicSubplan
*
pSubplan
)
{
char
*
pStr
=
NULL
;
nodesNodeToString
((
SNode
*
)
pSubplan
,
false
,
&
pStr
,
NULL
);
qDebugL
(
"apply optimize %s rule: %s"
,
pRuleName
,
pStr
);
taosMemoryFree
(
pStr
);
}
static
int32_t
applyOptimizeRule
(
SPlanContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
SOptimizeContext
cxt
=
{.
pPlanCxt
=
pCxt
,
.
optimized
=
false
};
bool
optimized
=
false
;
do
{
cxt
.
optimized
=
false
;
optimized
=
false
;
for
(
int32_t
i
=
0
;
i
<
optimizeRuleNum
;
++
i
)
{
cxt
.
optimized
=
false
;
int32_t
code
=
optimizeRuleSet
[
i
].
optimizeFunc
(
&
cxt
,
pLogicSubplan
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
code
;
}
if
(
cxt
.
optimized
)
{
optimized
=
true
;
dumpLogicSubplan
(
optimizeRuleSet
[
i
].
pName
,
pLogicSubplan
);
}
}
}
while
(
cxt
.
optimized
);
}
while
(
optimized
);
return
TSDB_CODE_SUCCESS
;
}
...
...
source/libs/planner/src/planSpliter.c
浏览文件 @
6aa602e4
...
...
@@ -1237,7 +1237,7 @@ static const int32_t splitRuleNum = (sizeof(splitRuleSet) / sizeof(SSplitRule));
static
void
dumpLogicSubplan
(
const
char
*
pRuleName
,
SLogicSubplan
*
pSubplan
)
{
char
*
pStr
=
NULL
;
nodesNodeToString
((
SNode
*
)
pSubplan
,
false
,
&
pStr
,
NULL
);
qDebugL
(
"apply %s rule: %s"
,
pRuleName
,
pStr
);
qDebugL
(
"apply
split
%s rule: %s"
,
pRuleName
,
pStr
);
taosMemoryFree
(
pStr
);
}
...
...
source/libs/planner/src/planner.c
浏览文件 @
6aa602e4
...
...
@@ -85,6 +85,11 @@ int32_t qSetSubplanExecutionNode(SSubplan* subplan, int32_t groupId, SDownstream
return
setSubplanExecutionNode
(
subplan
->
pNode
,
groupId
,
pSource
);
}
int32_t
qClearSubplanExecutionNode
(
SSubplan
*
pSubplan
,
int32_t
groupId
)
{
// todo
return
TSDB_CODE_FAILED
;
}
int32_t
qSubPlanToString
(
const
SSubplan
*
pSubplan
,
char
**
pStr
,
int32_t
*
pLen
)
{
if
(
SUBPLAN_TYPE_MODIFY
==
pSubplan
->
subplanType
&&
NULL
==
pSubplan
->
pNode
)
{
SDataInserterNode
*
insert
=
(
SDataInserterNode
*
)
pSubplan
->
pDataSink
;
...
...
source/libs/planner/test/planBasicTest.cpp
浏览文件 @
6aa602e4
...
...
@@ -56,6 +56,8 @@ TEST_F(PlanBasicTest, uniqueFunc) {
run
(
"SELECT UNIQUE(c2 + 10) FROM t1 WHERE c1 > 10"
);
run
(
"SELECT UNIQUE(c2 + 10), c2 FROM t1 WHERE c1 > 10"
);
run
(
"SELECT UNIQUE(c2 + 10), ts, c2 FROM t1 WHERE c1 > 10"
);
run
(
"SELECT UNIQUE(c1) a FROM t1 ORDER BY a"
);
...
...
@@ -75,6 +77,8 @@ TEST_F(PlanBasicTest, tailFunc) {
run
(
"SELECT TAIL(c2 + 10, 10, 80) FROM t1 WHERE c1 > 10 LIMIT 5"
);
run
(
"SELECT TAIL(c2 + 10, 10, 80) FROM t1 WHERE c1 > 10 PARTITION BY c1 LIMIT 5"
);
run
(
"SELECT TAIL(c1, 2, 1) FROM st1s1 UNION ALL SELECT c1 FROM st1s2"
);
}
TEST_F
(
PlanBasicTest
,
interpFunc
)
{
...
...
@@ -97,6 +101,16 @@ TEST_F(PlanBasicTest, lastRowFunc) {
run
(
"SELECT LAST_ROW(c1) FROM st1"
);
}
TEST_F
(
PlanBasicTest
,
sampleFunc
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT SAMPLE(c1, 10) FROM t1"
);
run
(
"SELECT SAMPLE(c1, 10) FROM st1"
);
run
(
"SELECT SAMPLE(c1, 10) FROM st1 PARTITION BY TBNAME"
);
}
TEST_F
(
PlanBasicTest
,
withoutFrom
)
{
useDb
(
"root"
,
"test"
);
...
...
source/libs/planner/test/planOptimizeTest.cpp
浏览文件 @
6aa602e4
...
...
@@ -20,7 +20,7 @@ using namespace std;
class
PlanOptimizeTest
:
public
PlannerTestBase
{};
TEST_F
(
PlanOptimizeTest
,
optimizeScanData
)
{
TEST_F
(
PlanOptimizeTest
,
scanPath
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT COUNT(*) FROM t1"
);
...
...
@@ -32,7 +32,7 @@ TEST_F(PlanOptimizeTest, optimizeScanData) {
run
(
"SELECT PERCENTILE(c1, 40), COUNT(*) FROM t1"
);
}
TEST_F
(
PlanOptimizeTest
,
ConditionPushDow
n
)
{
TEST_F
(
PlanOptimizeTest
,
pushDownConditio
n
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT ts, c1 FROM st1 WHERE tag1 > 4"
);
...
...
@@ -42,9 +42,11 @@ TEST_F(PlanOptimizeTest, ConditionPushDown) {
run
(
"SELECT ts, c1 FROM st1 WHERE tag1 > 4 AND tag2 = 'hello'"
);
run
(
"SELECT ts, c1 FROM st1 WHERE tag1 > 4 AND tag2 = 'hello' AND c1 > 10"
);
run
(
"SELECT ts, c1 FROM (SELECT * FROM st1) WHERE tag1 > 4"
);
}
TEST_F
(
PlanOptimizeTest
,
orderBy
PrimaryKey
)
{
TEST_F
(
PlanOptimizeTest
,
sort
PrimaryKey
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT c1 FROM t1 ORDER BY ts"
);
...
...
source/libs/sync/src/syncMain.c
浏览文件 @
6aa602e4
...
...
@@ -1488,18 +1488,6 @@ char* syncNode2SimpleStr(const SSyncNode* pSyncNode) {
pSyncNode
->
commitIndex
,
logBeginIndex
,
logLastIndex
,
snapshot
.
lastApplyIndex
,
pSyncNode
->
pRaftCfg
->
isStandBy
,
pSyncNode
->
replicaNum
,
pSyncNode
->
pRaftCfg
->
lastConfigIndex
,
pSyncNode
->
changing
,
pSyncNode
->
restoreFinish
);
/*
snprintf(s, len,
"syncNode: vgId:%d, term:%lu, commit:%ld, state:%d %s, standby:%d, "
"lc:%lu, "
"lc-user:%lu, "
"ems:%d, replica-num:%d, restore:%d, changing:%d",
pSyncNode->vgId, pSyncNode->pRaftStore->currentTerm, pSyncNode->commitIndex, pSyncNode->state,
syncUtilState2String(pSyncNode->state), pSyncNode->pRaftCfg->isStandBy, pSyncNode->electTimerLogicClock,
pSyncNode->electTimerLogicClockUser, pSyncNode->electTimerMS, pSyncNode->replicaNum,
pSyncNode->restoreFinish, pSyncNode->changing);
*/
return
s
;
}
...
...
source/libs/sync/src/syncSnapshot.c
浏览文件 @
6aa602e4
...
...
@@ -683,7 +683,16 @@ int32_t syncNodeOnSnapshotSendCb(SSyncNode *pSyncNode, SyncSnapshotSend *pMsg) {
needRsp
=
true
;
}
else
{
ASSERT
(
0
);
// error log
do
{
char
logBuf
[
96
];
snprintf
(
logBuf
,
sizeof
(
logBuf
),
"snapshot receiver recv error seq:%d, my ack:%d"
,
pMsg
->
seq
,
pReceiver
->
ack
);
char
*
eventLog
=
snapshotReceiver2SimpleStr
(
pReceiver
,
logBuf
);
syncNodeErrorLog
(
pSyncNode
,
eventLog
);
taosMemoryFree
(
eventLog
);
}
while
(
0
);
return
-
1
;
}
// send ack
...
...
@@ -764,8 +773,8 @@ int32_t syncNodeOnSnapshotRspCb(SSyncNode *pSyncNode, SyncSnapshotRsp *pMsg) {
}
else
{
do
{
char
logBuf
[
64
];
snprintf
(
logBuf
,
sizeof
(
logBuf
),
"
error ack, recv
ack:%d, my seq:%d"
,
pMsg
->
ack
,
pSender
->
seq
);
char
logBuf
[
96
];
snprintf
(
logBuf
,
sizeof
(
logBuf
),
"
snapshot sender recv error
ack:%d, my seq:%d"
,
pMsg
->
ack
,
pSender
->
seq
);
char
*
eventLog
=
snapshotSender2SimpleStr
(
pSender
,
logBuf
);
syncNodeErrorLog
(
pSyncNode
,
eventLog
);
taosMemoryFree
(
eventLog
);
...
...
tests/system-test/0-others/udfTest.py
浏览文件 @
6aa602e4
...
...
@@ -301,13 +301,13 @@ class TDTestCase:
tdSql
.
checkRows
(
1
)
tdSql
.
query
(
"select ceil(num1) , min(num1) from tb;"
)
tdSql
.
checkRows
(
1
)
tdSql
.
error
(
"select udf1(num1) , first(num1) from tb;"
)
tdSql
.
query
(
"select udf1(num1) , first(num1) from tb;"
)
tdSql
.
error
(
"select abs(num1) , first(num1) from tb;"
)
tdSql
.
query
(
"select abs(num1) , first(num1) from tb;"
)
tdSql
.
error
(
"select udf1(num1) , last(num1) from tb;"
)
tdSql
.
query
(
"select udf1(num1) , last(num1) from tb;"
)
tdSql
.
error
(
"select round(num1) , last(num1) from tb;"
)
tdSql
.
query
(
"select round(num1) , last(num1) from tb;"
)
tdSql
.
query
(
"select udf1(num1) , top(num1,1) from tb;"
)
tdSql
.
checkRows
(
1
)
...
...
@@ -327,9 +327,9 @@ class TDTestCase:
tdSql
.
checkRows
(
1
)
tdSql
.
query
(
"select floor(c1) , min(c1) from stb1;"
)
tdSql
.
checkRows
(
1
)
tdSql
.
error
(
"select udf1(c1) , first(c1) from stb1;"
)
tdSql
.
query
(
"select udf1(c1) , first(c1) from stb1;"
)
tdSql
.
error
(
"select udf1(c1) , last(c1) from stb1;"
)
tdSql
.
query
(
"select udf1(c1) , last(c1) from stb1;"
)
tdSql
.
query
(
"select udf1(c1) , top(c1 ,1) from stb1;"
)
tdSql
.
checkRows
(
1
)
...
...
tests/system-test/0-others/udf_create.py
浏览文件 @
6aa602e4
...
...
@@ -303,13 +303,13 @@ class TDTestCase:
tdSql
.
checkRows
(
1
)
tdSql
.
query
(
"select ceil(num1) , min(num1) from tb;"
)
tdSql
.
checkRows
(
1
)
tdSql
.
error
(
"select udf1(num1) , first(num1) from tb;"
)
tdSql
.
query
(
"select udf1(num1) , first(num1) from tb;"
)
tdSql
.
error
(
"select abs(num1) , first(num1) from tb;"
)
tdSql
.
query
(
"select abs(num1) , first(num1) from tb;"
)
tdSql
.
error
(
"select udf1(num1) , last(num1) from tb;"
)
tdSql
.
query
(
"select udf1(num1) , last(num1) from tb;"
)
tdSql
.
error
(
"select round(num1) , last(num1) from tb;"
)
tdSql
.
query
(
"select round(num1) , last(num1) from tb;"
)
tdSql
.
query
(
"select udf1(num1) , top(num1,1) from tb;"
)
tdSql
.
checkRows
(
1
)
...
...
@@ -329,9 +329,9 @@ class TDTestCase:
tdSql
.
checkRows
(
1
)
tdSql
.
query
(
"select floor(c1) , min(c1) from stb1;"
)
tdSql
.
checkRows
(
1
)
tdSql
.
error
(
"select udf1(c1) , first(c1) from stb1;"
)
tdSql
.
query
(
"select udf1(c1) , first(c1) from stb1;"
)
tdSql
.
error
(
"select udf1(c1) , last(c1) from stb1;"
)
tdSql
.
query
(
"select udf1(c1) , last(c1) from stb1;"
)
tdSql
.
query
(
"select udf1(c1) , top(c1 ,1) from stb1;"
)
tdSql
.
checkRows
(
1
)
...
...
tests/system-test/0-others/udf_restart_taosd.py
浏览文件 @
6aa602e4
...
...
@@ -300,13 +300,13 @@ class TDTestCase:
tdSql
.
checkRows
(
1
)
tdSql
.
query
(
"select ceil(num1) , min(num1) from tb;"
)
tdSql
.
checkRows
(
1
)
tdSql
.
error
(
"select udf1(num1) , first(num1) from tb;"
)
tdSql
.
query
(
"select udf1(num1) , first(num1) from tb;"
)
tdSql
.
error
(
"select abs(num1) , first(num1) from tb;"
)
tdSql
.
query
(
"select abs(num1) , first(num1) from tb;"
)
tdSql
.
error
(
"select udf1(num1) , last(num1) from tb;"
)
tdSql
.
query
(
"select udf1(num1) , last(num1) from tb;"
)
tdSql
.
error
(
"select round(num1) , last(num1) from tb;"
)
tdSql
.
query
(
"select round(num1) , last(num1) from tb;"
)
tdSql
.
query
(
"select udf1(num1) , top(num1,1) from tb;"
)
tdSql
.
checkRows
(
1
)
...
...
@@ -326,9 +326,9 @@ class TDTestCase:
tdSql
.
checkRows
(
1
)
tdSql
.
query
(
"select floor(c1) , min(c1) from stb1;"
)
tdSql
.
checkRows
(
1
)
tdSql
.
error
(
"select udf1(c1) , first(c1) from stb1;"
)
tdSql
.
query
(
"select udf1(c1) , first(c1) from stb1;"
)
tdSql
.
error
(
"select udf1(c1) , last(c1) from stb1;"
)
tdSql
.
query
(
"select udf1(c1) , last(c1) from stb1;"
)
tdSql
.
query
(
"select udf1(c1) , top(c1 ,1) from stb1;"
)
tdSql
.
checkRows
(
1
)
...
...
tests/system-test/2-query/unique.py
浏览文件 @
6aa602e4
...
...
@@ -266,7 +266,7 @@ class TDTestCase:
tdSql
.
query
(
"select unique(c1) from ct4"
)
tdSql
.
checkRows
(
10
)
tdSql
.
error
(
"select unique(c1),tbname from ct1"
)
#tdSql.error("select unique(c1),tbname from ct1") #support
#tdSql.error("select unique(c1),t1 from ct1") #support
# unique with common col
...
...
taos-tools
@
28a49b44
比较
a875a057
...
28a49b44
Subproject commit
a875a057d1225d85c6323b9edaccc2b1a9641987
Subproject commit
28a49b447f71c4f014ebbac858b7215b897d57fd
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录