Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
93d37963
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
93d37963
编写于
4月 12, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
enh(query):optimize scanning through SQL functions
上级
983e4aa0
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
275 addition
and
58 deletion
+275
-58
include/libs/function/functionMgt.h
include/libs/function/functionMgt.h
+10
-1
include/libs/nodes/nodes.h
include/libs/nodes/nodes.h
+1
-0
include/libs/nodes/plannodes.h
include/libs/nodes/plannodes.h
+5
-9
source/libs/function/inc/builtins.h
source/libs/function/inc/builtins.h
+2
-0
source/libs/function/inc/builtinsimpl.h
source/libs/function/inc/builtinsimpl.h
+2
-0
source/libs/function/src/builtins.c
source/libs/function/src/builtins.c
+2
-1
source/libs/function/src/builtinsimpl.c
source/libs/function/src/builtinsimpl.c
+8
-0
source/libs/function/src/functionMgt.c
source/libs/function/src/functionMgt.c
+17
-0
source/libs/nodes/src/nodesCodeFuncs.c
source/libs/nodes/src/nodesCodeFuncs.c
+22
-0
source/libs/nodes/src/nodesUtilFuncs.c
source/libs/nodes/src/nodesUtilFuncs.c
+11
-0
source/libs/planner/src/planLogicCreater.c
source/libs/planner/src/planLogicCreater.c
+1
-0
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+153
-1
source/libs/planner/src/planPhysiCreater.c
source/libs/planner/src/planPhysiCreater.c
+6
-0
source/libs/planner/src/planSpliter.c
source/libs/planner/src/planSpliter.c
+29
-40
source/libs/planner/test/plannerTest.cpp
source/libs/planner/test/plannerTest.cpp
+6
-6
未找到文件。
include/libs/function/functionMgt.h
浏览文件 @
93d37963
...
...
@@ -135,8 +135,17 @@ bool fmIsTimeorderFunc(int32_t funcId);
bool
fmIsPseudoColumnFunc
(
int32_t
funcId
);
bool
fmIsWindowPseudoColumnFunc
(
int32_t
funcId
);
bool
fmIsWindowClauseFunc
(
int32_t
funcId
);
bool
fmIsSpecialDataRequiredFunc
(
int32_t
funcId
);
bool
fmIsDynamicScanOptimizedFunc
(
int32_t
funcId
);
int32_t
fmFuncScanType
(
int32_t
funcId
);
typedef
enum
EFuncDataRequired
{
FUNC_DATA_REQUIRED_ALL_NEEDED
=
1
,
FUNC_DATA_REQUIRED_STATIS_NEEDED
,
FUNC_DATA_REQUIRED_NO_NEEDED
,
FUNC_DATA_REQUIRED_DISCARD
}
EFuncDataRequired
;
EFuncDataRequired
fmFuncDataRequired
(
SFunctionNode
*
pFunc
,
STimeWindow
*
pTimeWindow
);
int32_t
fmGetFuncExecFuncs
(
int32_t
funcId
,
SFuncExecFuncs
*
pFpSet
);
int32_t
fmGetScalarFuncExecFuncs
(
int32_t
funcId
,
SScalarFuncExecFuncs
*
pFpSet
);
...
...
include/libs/nodes/nodes.h
浏览文件 @
93d37963
...
...
@@ -216,6 +216,7 @@ SNodeList* nodesMakeList();
int32_t
nodesListAppend
(
SNodeList
*
pList
,
SNodeptr
pNode
);
int32_t
nodesListStrictAppend
(
SNodeList
*
pList
,
SNodeptr
pNode
);
int32_t
nodesListMakeAppend
(
SNodeList
**
pList
,
SNodeptr
pNode
);
int32_t
nodesListMakeStrictAppend
(
SNodeList
**
pList
,
SNodeptr
pNode
);
int32_t
nodesListAppendList
(
SNodeList
*
pTarget
,
SNodeList
*
pSrc
);
int32_t
nodesListStrictAppendList
(
SNodeList
*
pTarget
,
SNodeList
*
pSrc
);
int32_t
nodesListPushFront
(
SNodeList
*
pList
,
SNodeptr
pNode
);
...
...
include/libs/nodes/plannodes.h
浏览文件 @
93d37963
...
...
@@ -30,6 +30,7 @@ typedef struct SLogicNode {
SNode
*
pConditions
;
SNodeList
*
pChildren
;
struct
SLogicNode
*
pParent
;
int32_t
optimizedFlag
;
}
SLogicNode
;
typedef
enum
EScanType
{
...
...
@@ -50,6 +51,8 @@ typedef struct SScanLogicNode {
SName
tableName
;
bool
showRewrite
;
double
ratio
;
SNodeList
*
pDynamicScanFuncs
;
int32_t
dataRequired
;
}
SScanLogicNode
;
typedef
struct
SJoinLogicNode
{
...
...
@@ -196,20 +199,13 @@ typedef struct SSystemTableScanPhysiNode {
int32_t
accountId
;
}
SSystemTableScanPhysiNode
;
typedef
enum
EScanRequired
{
SCAN_REQUIRED_DATA_NO_NEEDED
=
1
,
SCAN_REQUIRED_DATA_STATIS_NEEDED
,
SCAN_REQUIRED_DATA_ALL_NEEDED
,
SCAN_REQUIRED_DATA_DISCARD
,
}
EScanRequired
;
typedef
struct
STableScanPhysiNode
{
SScanPhysiNode
scan
;
uint8_t
scanFlag
;
// denotes reversed scan of data or not
STimeWindow
scanRange
;
double
ratio
;
EScanRequired
scan
Required
;
SNodeList
*
p
ScanRefer
Funcs
;
int32_t
data
Required
;
SNodeList
*
p
DynamicScan
Funcs
;
}
STableScanPhysiNode
;
typedef
STableScanPhysiNode
STableSeqScanPhysiNode
;
...
...
source/libs/function/inc/builtins.h
浏览文件 @
93d37963
...
...
@@ -41,12 +41,14 @@ extern "C" {
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
typedef
int32_t
(
*
FCheckAndGetResultType
)(
SFunctionNode
*
pFunc
);
typedef
EFuncDataRequired
(
*
FFuncDataRequired
)(
SFunctionNode
*
pFunc
,
STimeWindow
*
pTimeWindow
);
typedef
struct
SBuiltinFuncDefinition
{
char
name
[
FUNCTION_NAME_MAX_LENGTH
];
EFunctionType
type
;
uint64_t
classification
;
FCheckAndGetResultType
checkFunc
;
FFuncDataRequired
dataRequiredFunc
;
FExecGetEnv
getEnvFunc
;
FExecInit
initFunc
;
FExecProcess
processFunc
;
...
...
source/libs/function/inc/builtinsimpl.h
浏览文件 @
93d37963
...
...
@@ -21,10 +21,12 @@ extern "C" {
#endif
#include "function.h"
#include "functionMgt.h"
bool
functionSetup
(
SqlFunctionCtx
*
pCtx
,
SResultRowEntryInfo
*
pResultInfo
);
void
functionFinalize
(
SqlFunctionCtx
*
pCtx
);
EFuncDataRequired
countDataRequired
(
SFunctionNode
*
pFunc
,
STimeWindow
*
pTimeWindow
);
bool
getCountFuncEnv
(
struct
SFunctionNode
*
pFunc
,
SFuncExecEnv
*
pEnv
);
int32_t
countFunction
(
SqlFunctionCtx
*
pCtx
);
...
...
source/libs/function/src/builtins.c
浏览文件 @
93d37963
...
...
@@ -25,8 +25,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{
.
name
=
"count"
,
.
type
=
FUNCTION_TYPE_COUNT
,
.
classification
=
FUNC_MGT_AGG_FUNC
,
.
classification
=
FUNC_MGT_AGG_FUNC
|
FUNC_MGT_SPECIAL_DATA_REQUIRED
,
.
checkFunc
=
checkAndGetResultType
,
.
dataRequiredFunc
=
countDataRequired
,
.
getEnvFunc
=
getCountFuncEnv
,
.
initFunc
=
functionSetup
,
.
processFunc
=
countFunction
,
...
...
source/libs/function/src/builtinsimpl.c
浏览文件 @
93d37963
...
...
@@ -55,6 +55,14 @@ void functionFinalize(SqlFunctionCtx *pCtx) {
pResInfo
->
isNullRes
=
(
pResInfo
->
numOfRes
==
0
)
?
1
:
0
;
}
EFuncDataRequired
countDataRequired
(
SFunctionNode
*
pFunc
,
STimeWindow
*
pTimeWindow
)
{
SNode
*
pParam
=
nodesListGetNode
(
pFunc
->
pParameterList
,
0
);
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pParam
)
&&
PRIMARYKEY_TIMESTAMP_COL_ID
==
((
SColumnNode
*
)
pParam
)
->
colId
)
{
return
FUNC_DATA_REQUIRED_NO_NEEDED
;
}
return
FUNC_DATA_REQUIRED_STATIS_NEEDED
;
}
bool
getCountFuncEnv
(
SFunctionNode
*
UNUSED_PARAM
(
pFunc
),
SFuncExecEnv
*
pEnv
)
{
pEnv
->
calcMemSize
=
sizeof
(
int64_t
);
return
true
;
...
...
source/libs/function/src/functionMgt.c
浏览文件 @
93d37963
...
...
@@ -76,6 +76,16 @@ int32_t fmGetFuncResultType(SFunctionNode* pFunc) {
return
funcMgtBuiltins
[
pFunc
->
funcId
].
checkFunc
(
pFunc
);
}
EFuncDataRequired
fmFuncDataRequired
(
SFunctionNode
*
pFunc
,
STimeWindow
*
pTimeWindow
)
{
if
(
pFunc
->
funcId
<
0
||
pFunc
->
funcId
>=
funcMgtBuiltinsNum
)
{
return
FUNC_DATA_REQUIRED_ALL_NEEDED
;
}
if
(
NULL
==
funcMgtBuiltins
[
pFunc
->
funcId
].
dataRequiredFunc
)
{
return
FUNC_DATA_REQUIRED_ALL_NEEDED
;
}
return
funcMgtBuiltins
[
pFunc
->
funcId
].
dataRequiredFunc
(
pFunc
,
pTimeWindow
);
}
int32_t
fmGetFuncExecFuncs
(
int32_t
funcId
,
SFuncExecFuncs
*
pFpSet
)
{
if
(
funcId
<
0
||
funcId
>=
funcMgtBuiltinsNum
)
{
return
TSDB_CODE_FAILED
;
...
...
@@ -120,6 +130,13 @@ bool fmIsNonstandardSQLFunc(int32_t funcId) {
return
isSpecificClassifyFunc
(
funcId
,
FUNC_MGT_NONSTANDARD_SQL_FUNC
);
}
bool
fmIsSpecialDataRequiredFunc
(
int32_t
funcId
)
{
return
isSpecificClassifyFunc
(
funcId
,
FUNC_MGT_SPECIAL_DATA_REQUIRED
);
}
bool
fmIsDynamicScanOptimizedFunc
(
int32_t
funcId
)
{
return
isSpecificClassifyFunc
(
funcId
,
FUNC_MGT_DYNAMIC_SCAN_OPTIMIZED
);
}
void
fmFuncMgtDestroy
()
{
void
*
m
=
gFunMgtService
.
pFuncNameHashTable
;
...
...
source/libs/nodes/src/nodesCodeFuncs.c
浏览文件 @
93d37963
...
...
@@ -723,6 +723,9 @@ static int32_t jsonToPhysiTagScanNode(const SJson* pJson, void* pObj) {
static
const
char
*
jkTableScanPhysiPlanScanFlag
=
"ScanFlag"
;
static
const
char
*
jkTableScanPhysiPlanStartKey
=
"StartKey"
;
static
const
char
*
jkTableScanPhysiPlanEndKey
=
"EndKey"
;
static
const
char
*
jkTableScanPhysiPlanRatio
=
"Ratio"
;
static
const
char
*
jkTableScanPhysiPlanDataRequired
=
"DataRequired"
;
static
const
char
*
jkTableScanPhysiPlanDynamicScanFuncs
=
"DynamicScanFuncs"
;
static
int32_t
physiTableScanNodeToJson
(
const
void
*
pObj
,
SJson
*
pJson
)
{
const
STableScanPhysiNode
*
pNode
=
(
const
STableScanPhysiNode
*
)
pObj
;
...
...
@@ -737,6 +740,15 @@ static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddIntegerToObject
(
pJson
,
jkTableScanPhysiPlanEndKey
,
pNode
->
scanRange
.
ekey
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddDoubleToObject
(
pJson
,
jkTableScanPhysiPlanRatio
,
pNode
->
ratio
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddIntegerToObject
(
pJson
,
jkTableScanPhysiPlanDataRequired
,
pNode
->
dataRequired
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodeListToJson
(
pJson
,
jkTableScanPhysiPlanDynamicScanFuncs
,
pNode
->
pDynamicScanFuncs
);
}
return
code
;
}
...
...
@@ -754,6 +766,15 @@ static int32_t jsonToPhysiTableScanNode(const SJson* pJson, void* pObj) {
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetBigIntValue
(
pJson
,
jkTableScanPhysiPlanEndKey
,
&
pNode
->
scanRange
.
ekey
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetDoubleValue
(
pJson
,
jkTableScanPhysiPlanRatio
,
&
pNode
->
ratio
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetNumberValue
(
pJson
,
jkTableScanPhysiPlanDataRequired
,
pNode
->
dataRequired
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
jsonToNodeList
(
pJson
,
jkTableScanPhysiPlanDynamicScanFuncs
,
&
pNode
->
pDynamicScanFuncs
);
}
return
code
;
}
...
...
@@ -2767,6 +2788,7 @@ int32_t nodesStringToList(const char* pStr, SNodeList** pList) {
return
TSDB_CODE_FAILED
;
}
int32_t
code
=
jsonToNodeListImpl
(
pJson
,
pList
);
tjsonDelete
(
pJson
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
nodesDestroyList
(
*
pList
);
terrno
=
code
;
...
...
source/libs/nodes/src/nodesUtilFuncs.c
浏览文件 @
93d37963
...
...
@@ -694,6 +694,17 @@ int32_t nodesListMakeAppend(SNodeList** pList, SNodeptr pNode) {
return
nodesListAppend
(
*
pList
,
pNode
);
}
int32_t
nodesListMakeStrictAppend
(
SNodeList
**
pList
,
SNodeptr
pNode
)
{
if
(
NULL
==
*
pList
)
{
*
pList
=
nodesMakeList
();
if
(
NULL
==
*
pList
)
{
terrno
=
TSDB_CODE_OUT_OF_MEMORY
;
return
TSDB_CODE_OUT_OF_MEMORY
;
}
}
return
nodesListStrictAppend
(
*
pList
,
pNode
);
}
int32_t
nodesListAppendList
(
SNodeList
*
pTarget
,
SNodeList
*
pSrc
)
{
if
(
NULL
==
pTarget
||
NULL
==
pSrc
)
{
return
TSDB_CODE_FAILED
;
...
...
source/libs/planner/src/planLogicCreater.c
浏览文件 @
93d37963
...
...
@@ -200,6 +200,7 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
strcpy
(
pScan
->
tableName
.
tname
,
pRealTable
->
table
.
tableName
);
pScan
->
showRewrite
=
pCxt
->
pPlanCxt
->
showRewrite
;
pScan
->
ratio
=
pRealTable
->
ratio
;
pScan
->
dataRequired
=
FUNC_DATA_REQUIRED_ALL_NEEDED
;
// set columns to scan
SNodeList
*
pCols
=
NULL
;
...
...
source/libs/planner/src/planOptimizer.c
浏览文件 @
93d37963
...
...
@@ -14,7 +14,159 @@
*/
#include "planInt.h"
#include "functionMgt.h"
int32_t
optimizeLogicPlan
(
SPlanContext
*
pCxt
,
SLogicNode
*
pLogicNode
)
{
#define OPTIMIZE_FLAG_MASK(n) (1 << n)
#define OPTIMIZE_FLAG_OSD OPTIMIZE_FLAG_MASK(0)
#define OPTIMIZE_FLAG_SET_MASK(val, mask) (val) |= (mask)
#define OPTIMIZE_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
typedef
struct
SOptimizeContext
{
bool
optimized
;
}
SOptimizeContext
;
typedef
int32_t
(
*
FMatch
)(
SOptimizeContext
*
pCxt
,
SLogicNode
*
pLogicNode
);
typedef
int32_t
(
*
FOptimize
)(
SOptimizeContext
*
pCxt
,
SLogicNode
*
pLogicNode
);
typedef
struct
SOptimizeRule
{
char
*
pName
;
FOptimize
optimizeFunc
;
}
SOptimizeRule
;
typedef
struct
SOsdInfo
{
SScanLogicNode
*
pScan
;
SNodeList
*
pSdrFuncs
;
SNodeList
*
pDsoFuncs
;
}
SOsdInfo
;
static
bool
osdMayBeOptimized
(
SLogicNode
*
pNode
)
{
if
(
OPTIMIZE_FLAG_TEST_MASK
(
pNode
->
optimizedFlag
,
OPTIMIZE_FLAG_OSD
))
{
return
false
;
}
if
(
QUERY_NODE_LOGIC_PLAN_SCAN
!=
nodeType
(
pNode
))
{
return
false
;
}
if
(
NULL
==
pNode
->
pParent
||
(
QUERY_NODE_LOGIC_PLAN_WINDOW
!=
nodeType
(
pNode
->
pParent
)
&&
QUERY_NODE_LOGIC_PLAN_AGG
==
nodeType
(
pNode
->
pParent
)))
{
return
false
;
}
return
true
;
}
static
SLogicNode
*
osdFindPossibleScanNode
(
SLogicNode
*
pNode
)
{
if
(
osdMayBeOptimized
(
pNode
))
{
return
pNode
;
}
SNode
*
pChild
;
FOREACH
(
pChild
,
pNode
->
pChildren
)
{
SLogicNode
*
pScanNode
=
osdFindPossibleScanNode
((
SLogicNode
*
)
pChild
);
if
(
NULL
!=
pScanNode
)
{
return
pScanNode
;
}
}
return
NULL
;
}
static
SNodeList
*
osdGetAllFuncs
(
SLogicNode
*
pNode
)
{
switch
(
nodeType
(
pNode
))
{
case
QUERY_NODE_LOGIC_PLAN_WINDOW
:
return
((
SWindowLogicNode
*
)
pNode
)
->
pFuncs
;
case
QUERY_NODE_LOGIC_PLAN_AGG
:
return
((
SAggLogicNode
*
)
pNode
)
->
pAggFuncs
;
default:
break
;
}
return
NULL
;
}
static
int32_t
osdGetRelatedFuncs
(
SScanLogicNode
*
pScan
,
SNodeList
**
pSdrFuncs
,
SNodeList
**
pDsoFuncs
)
{
SNodeList
*
pAllFuncs
=
osdGetAllFuncs
(
pScan
->
node
.
pParent
);
SNode
*
pFunc
=
NULL
;
FOREACH
(
pFunc
,
pAllFuncs
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
fmIsSpecialDataRequiredFunc
(((
SFunctionNode
*
)
pFunc
)
->
funcId
))
{
code
=
nodesListMakeStrictAppend
(
pSdrFuncs
,
nodesCloneNode
(
pFunc
));
}
else
if
(
fmIsDynamicScanOptimizedFunc
(((
SFunctionNode
*
)
pFunc
)
->
funcId
))
{
code
=
nodesListMakeStrictAppend
(
pDsoFuncs
,
nodesCloneNode
(
pFunc
));
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
nodesDestroyList
(
*
pSdrFuncs
);
nodesDestroyList
(
*
pDsoFuncs
);
return
code
;
}
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
osdMatch
(
SOptimizeContext
*
pCxt
,
SLogicNode
*
pLogicNode
,
SOsdInfo
*
pInfo
)
{
pInfo
->
pScan
=
(
SScanLogicNode
*
)
osdFindPossibleScanNode
(
pLogicNode
);
if
(
NULL
==
pInfo
->
pScan
)
{
return
TSDB_CODE_SUCCESS
;
}
return
osdGetRelatedFuncs
(
pInfo
->
pScan
,
&
pInfo
->
pSdrFuncs
,
&
pInfo
->
pDsoFuncs
);
}
static
EFuncDataRequired
osdPromoteDataRequired
(
EFuncDataRequired
l
,
EFuncDataRequired
r
)
{
switch
(
l
)
{
case
FUNC_DATA_REQUIRED_ALL_NEEDED
:
return
l
;
case
FUNC_DATA_REQUIRED_STATIS_NEEDED
:
return
FUNC_DATA_REQUIRED_ALL_NEEDED
==
r
?
r
:
l
;
case
FUNC_DATA_REQUIRED_NO_NEEDED
:
return
FUNC_DATA_REQUIRED_DISCARD
==
r
?
l
:
r
;
default:
break
;
}
return
r
;
}
static
int32_t
osdGetDataRequired
(
SNodeList
*
pFuncs
)
{
if
(
NULL
==
pFuncs
)
{
return
FUNC_DATA_REQUIRED_ALL_NEEDED
;
}
EFuncDataRequired
dataRequired
=
FUNC_DATA_REQUIRED_DISCARD
;
SNode
*
pFunc
=
NULL
;
FOREACH
(
pFunc
,
pFuncs
)
{
dataRequired
=
osdPromoteDataRequired
(
dataRequired
,
fmFuncDataRequired
((
SFunctionNode
*
)
pFunc
,
NULL
));
}
return
dataRequired
;
}
static
int32_t
osdOptimize
(
SOptimizeContext
*
pCxt
,
SLogicNode
*
pLogicNode
)
{
SOsdInfo
info
=
{
0
};
int32_t
code
=
osdMatch
(
pCxt
,
pLogicNode
,
&
info
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
(
NULL
!=
info
.
pDsoFuncs
||
NULL
!=
info
.
pSdrFuncs
))
{
info
.
pScan
->
dataRequired
=
osdGetDataRequired
(
info
.
pSdrFuncs
);
info
.
pScan
->
pDynamicScanFuncs
=
info
.
pDsoFuncs
;
OPTIMIZE_FLAG_SET_MASK
(
info
.
pScan
->
node
.
optimizedFlag
,
OPTIMIZE_FLAG_OSD
);
pCxt
->
optimized
=
true
;
}
nodesDestroyList
(
info
.
pSdrFuncs
);
return
code
;
}
static
const
SOptimizeRule
optimizeRuleSet
[]
=
{
{
.
pName
=
"OptimizeScanData"
,
.
optimizeFunc
=
osdOptimize
}
};
static
const
int32_t
optimizeRuleNum
=
(
sizeof
(
optimizeRuleSet
)
/
sizeof
(
SOptimizeRule
));
static
int32_t
applyOptimizeRule
(
SLogicNode
*
pLogicNode
)
{
SOptimizeContext
cxt
=
{
.
optimized
=
false
};
do
{
cxt
.
optimized
=
false
;
for
(
int32_t
i
=
0
;
i
<
optimizeRuleNum
;
++
i
)
{
int32_t
code
=
optimizeRuleSet
[
i
].
optimizeFunc
(
&
cxt
,
pLogicNode
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
code
;
}
}
}
while
(
cxt
.
optimized
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
optimizeLogicPlan
(
SPlanContext
*
pCxt
,
SLogicNode
*
pLogicNode
)
{
return
applyOptimizeRule
(
pLogicNode
);
}
source/libs/planner/src/planPhysiCreater.c
浏览文件 @
93d37963
...
...
@@ -437,6 +437,12 @@ static int32_t createTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubp
taosArrayPush
(
pCxt
->
pExecNodeList
,
&
pSubplan
->
execNode
);
pSubplan
->
execNodeStat
.
tableNum
=
pScanLogicNode
->
pVgroupList
->
vgroups
[
0
].
numOfTable
;
tNameGetFullDbName
(
&
pScanLogicNode
->
tableName
,
pSubplan
->
dbFName
);
pTableScan
->
dataRequired
=
pScanLogicNode
->
dataRequired
;
pTableScan
->
pDynamicScanFuncs
=
nodesCloneList
(
pScanLogicNode
->
pDynamicScanFuncs
);
if
(
NULL
!=
pScanLogicNode
->
pDynamicScanFuncs
&&
NULL
==
pTableScan
->
pDynamicScanFuncs
)
{
nodesDestroyNode
(
pTableScan
);
return
TSDB_CODE_OUT_OF_MEMORY
;
}
return
createScanPhysiNodeFinalize
(
pCxt
,
pScanLogicNode
,
(
SScanPhysiNode
*
)
pTableScan
,
pPhyNode
);
}
...
...
source/libs/planner/src/planSpliter.c
浏览文件 @
93d37963
...
...
@@ -23,18 +23,14 @@
#define SPLIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
typedef
struct
SSplitContext
{
int32_t
errCode
;
int32_t
groupId
;
bool
match
;
void
*
pInfo
;
bool
split
;
}
SSplitContext
;
typedef
int32_t
(
*
FMatch
)(
SSplitContext
*
pCxt
,
SLogicSubplan
*
pSubplan
);
typedef
int32_t
(
*
FSplit
)(
SSplitContext
*
pCxt
);
typedef
int32_t
(
*
FSplit
)(
SSplitContext
*
pCxt
,
SLogicSubplan
*
pSubplan
);
typedef
struct
SSplitRule
{
char
*
pName
;
FMatch
matchFunc
;
FSplit
splitFunc
;
}
SSplitRule
;
...
...
@@ -58,30 +54,25 @@ static SLogicNode* stsMatchByNode(SLogicNode* pNode) {
return
NULL
;
}
static
int32_t
stsMatch
(
SSplitContext
*
pCxt
,
SLogicSubplan
*
pSubplan
)
{
if
(
SPLIT_FLAG_TEST_MASK
(
pSubplan
->
splitFlag
,
SPLIT_FLAG_STS
))
{
return
TSDB_CODE_SUCCESS
;
}
static
void
stsFindSplitNode
(
SLogicSubplan
*
pSubplan
,
SStsInfo
*
pInfo
)
{
SLogicNode
*
pSplitNode
=
stsMatchByNode
(
pSubplan
->
pNode
);
if
(
NULL
!=
pSplitNode
)
{
SStsInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
SStsInfo
));
if
(
NULL
==
pInfo
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
pInfo
->
pScan
=
(
SScanLogicNode
*
)
pSplitNode
;
pInfo
->
pSubplan
=
pSubplan
;
pCxt
->
pInfo
=
pInfo
;
pCxt
->
match
=
true
;
return
TSDB_CODE_SUCCESS
;
}
}
static
void
stsMatch
(
SSplitContext
*
pCxt
,
SLogicSubplan
*
pSubplan
,
SStsInfo
*
pInfo
)
{
if
(
!
SPLIT_FLAG_TEST_MASK
(
pSubplan
->
splitFlag
,
SPLIT_FLAG_STS
))
{
stsFindSplitNode
(
pSubplan
,
pInfo
);
}
SNode
*
pChild
;
FOREACH
(
pChild
,
pSubplan
->
pChildren
)
{
int32_t
code
=
stsMatch
(
pCxt
,
(
SLogicSubplan
*
)
pChild
);
if
(
TSDB_CODE_SUCCESS
!=
code
||
pCxt
->
match
)
{
return
code
;
stsMatch
(
pCxt
,
(
SLogicSubplan
*
)
pChild
,
pInfo
);
if
(
NULL
!=
pInfo
->
pScan
)
{
break
;
}
}
return
TSDB_CODE_SUCCESS
;
return
;
}
static
SLogicSubplan
*
stsCreateScanSubplan
(
SSplitContext
*
pCxt
,
SScanLogicNode
*
pScan
)
{
...
...
@@ -128,46 +119,44 @@ static int32_t stsCreateExchangeNode(SSplitContext* pCxt, SLogicSubplan* pSubpla
return
TSDB_CODE_FAILED
;
}
static
int32_t
stsSplit
(
SSplitContext
*
pCxt
)
{
SStsInfo
*
pInfo
=
pCxt
->
pInfo
;
if
(
NULL
==
pInfo
->
pSubplan
->
pChildren
)
{
pInfo
->
pSubplan
->
pChildren
=
nodesMakeList
();
if
(
NULL
==
pInfo
->
pSubplan
->
pChildren
)
{
static
int32_t
stsSplit
(
SSplitContext
*
pCxt
,
SLogicSubplan
*
pSubplan
)
{
SStsInfo
info
=
{
0
};
stsMatch
(
pCxt
,
pSubplan
,
&
info
);
if
(
NULL
==
info
.
pScan
)
{
return
TSDB_CODE_SUCCESS
;
}
if
(
NULL
==
info
.
pSubplan
->
pChildren
)
{
info
.
pSubplan
->
pChildren
=
nodesMakeList
();
if
(
NULL
==
info
.
pSubplan
->
pChildren
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
}
int32_t
code
=
nodesListStrictAppend
(
pInfo
->
pSubplan
->
pChildren
,
stsCreateScanSubplan
(
pCxt
,
pInfo
->
pScan
));
int32_t
code
=
nodesListStrictAppend
(
info
.
pSubplan
->
pChildren
,
stsCreateScanSubplan
(
pCxt
,
info
.
pScan
));
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
stsCreateExchangeNode
(
pCxt
,
pInfo
->
pSubplan
,
pInfo
->
pScan
);
code
=
stsCreateExchangeNode
(
pCxt
,
info
.
pSubplan
,
info
.
pScan
);
}
++
(
pCxt
->
groupId
);
taosMemoryFreeClear
(
pCxt
->
pInfo
)
;
pCxt
->
split
=
true
;
return
code
;
}
static
const
SSplitRule
splitRuleSet
[]
=
{
{
.
pName
=
"SuperTableScan"
,
.
matchFunc
=
stsMatch
,
.
splitFunc
=
stsSplit
}
{
.
pName
=
"SuperTableScan"
,
.
splitFunc
=
stsSplit
}
};
static
const
int32_t
splitRuleNum
=
(
sizeof
(
splitRuleSet
)
/
sizeof
(
SSplitRule
));
static
int32_t
applySplitRule
(
SLogicSubplan
*
pSubplan
)
{
SSplitContext
cxt
=
{
.
errCode
=
TSDB_CODE_SUCCESS
,
.
groupId
=
pSubplan
->
id
.
groupId
+
1
,
.
match
=
false
,
.
pInfo
=
NULL
};
bool
split
=
false
;
SSplitContext
cxt
=
{
.
groupId
=
pSubplan
->
id
.
groupId
+
1
,
.
split
=
false
};
do
{
split
=
false
;
cxt
.
split
=
false
;
for
(
int32_t
i
=
0
;
i
<
splitRuleNum
;
++
i
)
{
cxt
.
match
=
false
;
int32_t
code
=
splitRuleSet
[
i
].
matchFunc
(
&
cxt
,
pSubplan
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
cxt
.
match
)
{
code
=
splitRuleSet
[
i
].
splitFunc
(
&
cxt
);
split
=
true
;
}
int32_t
code
=
splitRuleSet
[
i
].
splitFunc
(
&
cxt
,
pSubplan
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
code
;
}
}
}
while
(
split
);
}
while
(
cxt
.
split
);
return
TSDB_CODE_SUCCESS
;
}
...
...
source/libs/planner/test/plannerTest.cpp
浏览文件 @
93d37963
...
...
@@ -177,14 +177,14 @@ TEST_F(PlannerTest, groupBy) {
bind
(
"SELECT count(*) FROM t1"
);
ASSERT_TRUE
(
run
());
bind
(
"SELECT c1, max(c3), min(c2), count(*) FROM t1 GROUP BY c1"
);
ASSERT_TRUE
(
run
());
//
bind("SELECT c1, max(c3), min(c2), count(*) FROM t1 GROUP BY c1");
//
ASSERT_TRUE(run());
bind
(
"SELECT c1 + c3, c1 + count(*) FROM t1 where c2 = 'abc' GROUP BY c1, c3"
);
ASSERT_TRUE
(
run
());
//
bind("SELECT c1 + c3, c1 + count(*) FROM t1 where c2 = 'abc' GROUP BY c1, c3");
//
ASSERT_TRUE(run());
bind
(
"SELECT c1 + c3, sum(c4 * c5) FROM t1 where concat(c2, 'wwww') = 'abcwww' GROUP BY c1 + c3"
);
ASSERT_TRUE
(
run
());
//
bind("SELECT c1 + c3, sum(c4 * c5) FROM t1 where concat(c2, 'wwww') = 'abcwww' GROUP BY c1 + c3");
//
ASSERT_TRUE(run());
}
TEST_F
(
PlannerTest
,
subquery
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录