Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
f8b8569b
T
TDengine
项目概览
taosdata
/
TDengine
接近 2 年 前同步成功
通知
1191
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看板
提交
f8b8569b
编写于
12月 14, 2021
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
TD-12034 Organize planner module interface.
上级
d143ca45
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
192 addition
and
137 deletion
+192
-137
include/libs/planner/planner.h
include/libs/planner/planner.h
+16
-68
include/libs/scheduler/scheduler.h
include/libs/scheduler/scheduler.h
+36
-1
source/libs/parser/test/plannerTest.cpp
source/libs/parser/test/plannerTest.cpp
+5
-4
source/libs/planner/inc/plannerInt.h
source/libs/planner/inc/plannerInt.h
+91
-52
source/libs/planner/src/physicalPlan.c
source/libs/planner/src/physicalPlan.c
+36
-0
source/libs/planner/src/planner.c
source/libs/planner/src/planner.c
+8
-12
未找到文件。
include/libs/planner/planner.h
浏览文件 @
f8b8569b
...
@@ -22,6 +22,7 @@ extern "C" {
...
@@ -22,6 +22,7 @@ extern "C" {
#define QUERY_TYPE_MERGE 1
#define QUERY_TYPE_MERGE 1
#define QUERY_TYPE_PARTIAL 2
#define QUERY_TYPE_PARTIAL 2
#define QUERY_TYPE_SCAN 3
enum
OPERATOR_TYPE_E
{
enum
OPERATOR_TYPE_E
{
OP_TableScan
=
1
,
OP_TableScan
=
1
,
...
@@ -54,90 +55,37 @@ enum OPERATOR_TYPE_E {
...
@@ -54,90 +55,37 @@ enum OPERATOR_TYPE_E {
struct
SEpSet
;
struct
SEpSet
;
struct
SQueryPlanNode
;
struct
SQueryPlanNode
;
struct
S
QueryPhyPlan
Node
;
struct
S
Phy
Node
;
struct
SQueryStmtInfo
;
struct
SQueryStmtInfo
;
typedef
struct
SSubquery
{
typedef
struct
SSubplan
{
int64_t
queryId
;
// the subquery id created by qnode
int32_t
type
;
// QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL|QUERY_TYPE_SCAN
int32_t
type
;
// QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL
SArray
*
pDatasource
;
// the datasource subplan,from which to fetch the result
int32_t
level
;
// the execution level of current subquery, starting from 0.
struct
SPhyNode
*
pNode
;
// physical plan of current subplan
SArray
*
pUpstream
;
// the upstream,from which to fetch the result
}
SSubplan
;
struct
SQueryPhyPlanNode
*
pNode
;
// physical plan of current subquery
}
SSubquery
;
typedef
struct
SQueryJob
{
typedef
struct
SQueryDag
{
SArray
**
pSubqueries
;
SArray
**
pSubplans
;
int32_t
numOfLevels
;
}
SQueryDag
;
int32_t
currentLevel
;
}
SQueryJob
;
/**
* Optimize the query execution plan, currently not implement yet.
* @param pQueryNode
* @return
*/
int32_t
qOptimizeQueryPlan
(
struct
SQueryPlanNode
*
pQueryNode
);
/**
* Create the query plan according to the bound AST, which is in the form of pQueryInfo
* @param pQueryInfo
* @param pQueryNode
* @return
*/
int32_t
qCreateQueryPlan
(
const
struct
SQueryStmtInfo
*
pQueryInfo
,
struct
SQueryPlanNode
**
pQueryNode
);
/**
* Convert the query plan to string, in order to display it in the shell.
* @param pQueryNode
* @return
*/
int32_t
qQueryPlanToString
(
struct
SQueryPlanNode
*
pQueryNode
,
char
**
str
);
/**
/**
* Restore the SQL statement according to the logic query plan.
* Create the physical plan for the query, according to the AST.
* @param pQueryNode
* @param sql
* @return
*/
*/
int32_t
q
QueryPlanToSql
(
struct
SQueryPlanNode
*
pQueryNode
,
char
**
sql
);
int32_t
q
CreateQueryDag
(
const
struct
SQueryStmtInfo
*
pQueryInfo
,
struct
SEpSet
*
pQnode
,
struct
SQueryDag
**
pDag
);
/**
int32_t
qExplainQuery
(
const
struct
SQueryStmtInfo
*
pQueryInfo
,
struct
SEpSet
*
pQnode
,
char
**
str
);
* Create the physical plan for the query, according to the logic plan.
* @param pQueryNode
* @param pPhyNode
* @return
*/
int32_t
qCreatePhysicalPlan
(
struct
SQueryPlanNode
*
pQueryNode
,
struct
SEpSet
*
pQnode
,
struct
SQueryPhyPlanNode
*
pPhyNode
);
/**
/**
* Convert to physical plan to string to enable to print it out in the shell.
* Convert to subplan to string for the scheduler to send to the executor
* @param pPhyNode
* @param str
* @return
*/
*/
int32_t
qPhyPlanToString
(
struct
SQueryPhyPlanNode
*
pPhyNode
,
char
**
str
);
int32_t
qSubPlanToString
(
struct
SSubplan
*
pPhyNode
,
char
**
str
);
/**
* Destroy the query plan object.
* @return
*/
void
*
qDestroyQueryPlan
(
struct
SQueryPlanNode
*
pQueryNode
);
/**
/**
* Destroy the physical plan.
* Destroy the physical plan.
* @param pQueryPhyNode
* @param pQueryPhyNode
* @return
* @return
*/
*/
void
*
qDestroyQueryPhyPlan
(
struct
SQueryPhyPlanNode
*
pQueryPhyNode
);
void
*
qDestroyQueryDag
(
struct
SQueryDag
*
pDag
);
/**
* Create the query job from the physical execution plan
* @param pPhyNode
* @param pJob
* @return
*/
int32_t
qCreateQueryJob
(
const
struct
SQueryPhyPlanNode
*
pPhyNode
,
struct
SQueryJob
**
pJob
);
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
...
include/libs/scheduler/scheduler.h
浏览文件 @
f8b8569b
...
@@ -20,7 +20,42 @@
...
@@ -20,7 +20,42 @@
extern
"C"
{
extern
"C"
{
#endif
#endif
struct
SQueryJob
;
typedef
struct
SQueryProfileSummary
{
int64_t
startTs
;
// Object created and added into the message queue
int64_t
endTs
;
// the timestamp when the task is completed
int64_t
cputime
;
// total cpu cost, not execute elapsed time
int64_t
loadRemoteDataDuration
;
// remote io time
int64_t
loadNativeDataDuration
;
// native disk io time
uint64_t
loadNativeData
;
// blocks + SMA + header files
uint64_t
loadRemoteData
;
// remote data acquired by exchange operator.
uint64_t
waitDuration
;
// the time to waiting to be scheduled in queue does matter, so we need to record it
int64_t
addQTs
;
// the time to be added into the message queue, used to calculate the waiting duration in queue.
uint64_t
totalRows
;
uint64_t
loadRows
;
uint32_t
totalBlocks
;
uint32_t
loadBlocks
;
uint32_t
loadBlockAgg
;
uint32_t
skipBlocks
;
uint64_t
resultSize
;
// generated result size in Kb.
}
SQueryProfileSummary
;
typedef
struct
SQueryTask
{
uint64_t
queryId
;
// query id
uint64_t
taskId
;
// task id
char
*
pSubplan
;
// operator tree
uint64_t
status
;
// task status
SQueryProfileSummary
summary
;
// task execution summary
void
*
pOutputHandle
;
// result buffer handle, to temporarily keep the output result for next stage
}
SQueryTask
;
typedef
struct
SQueryJob
{
SArray
**
pSubtasks
;
// todo
}
SQueryJob
;
/**
/**
* Process the query job, generated according to the query physical plan.
* Process the query job, generated according to the query physical plan.
...
...
source/libs/parser/test/plannerTest.cpp
浏览文件 @
f8b8569b
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include "tdef.h"
#include "tdef.h"
#include "tvariant.h"
#include "tvariant.h"
#include "planner.h"
#include "planner.h"
#include "../../planner/inc/plannerInt.h"
namespace
{
namespace
{
void
setSchema
(
SSchema
*
p
,
int32_t
type
,
int32_t
bytes
,
const
char
*
name
,
int32_t
colId
)
{
void
setSchema
(
SSchema
*
p
,
int32_t
type
,
int32_t
bytes
,
const
char
*
name
,
int32_t
colId
)
{
...
@@ -92,10 +93,10 @@ void generateLogicplan(const char* sql) {
...
@@ -92,10 +93,10 @@ void generateLogicplan(const char* sql) {
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
ret
,
0
);
struct
SQueryPlanNode
*
n
=
nullptr
;
struct
SQueryPlanNode
*
n
=
nullptr
;
code
=
qC
reateQueryPlan
(
pQueryInfo
,
&
n
);
code
=
c
reateQueryPlan
(
pQueryInfo
,
&
n
);
char
*
str
=
NULL
;
char
*
str
=
NULL
;
q
Q
ueryPlanToString
(
n
,
&
str
);
queryPlanToString
(
n
,
&
str
);
printf
(
"--------SQL:%s
\n
"
,
sql
);
printf
(
"--------SQL:%s
\n
"
,
sql
);
printf
(
"%s
\n
"
,
str
);
printf
(
"%s
\n
"
,
str
);
...
@@ -155,10 +156,10 @@ TEST(testCase, planner_test) {
...
@@ -155,10 +156,10 @@ TEST(testCase, planner_test) {
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
2
);
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
2
);
struct
SQueryPlanNode
*
n
=
nullptr
;
struct
SQueryPlanNode
*
n
=
nullptr
;
code
=
qC
reateQueryPlan
(
pQueryInfo
,
&
n
);
code
=
c
reateQueryPlan
(
pQueryInfo
,
&
n
);
char
*
str
=
NULL
;
char
*
str
=
NULL
;
q
Q
ueryPlanToString
(
n
,
&
str
);
queryPlanToString
(
n
,
&
str
);
printf
(
"%s
\n
"
,
str
);
printf
(
"%s
\n
"
,
str
);
destroyQueryInfo
(
pQueryInfo
);
destroyQueryInfo
(
pQueryInfo
);
...
...
source/libs/planner/inc/plannerInt.h
浏览文件 @
f8b8569b
...
@@ -25,6 +25,19 @@ extern "C" {
...
@@ -25,6 +25,19 @@ extern "C" {
#include "planner.h"
#include "planner.h"
#include "taosmsg.h"
#include "taosmsg.h"
enum
LOGIC_PLAN_E
{
LP_SCAN
=
1
,
LP_SESSION
=
2
,
LP_STATE
=
3
,
LP_INTERVAL
=
4
,
LP_FILL
=
5
,
LP_AGG
=
6
,
LP_JOIN
=
7
,
LP_PROJECT
=
8
,
LP_DISTINCT
=
9
,
LP_ORDER
=
10
};
typedef
struct
SQueryNodeBasicInfo
{
typedef
struct
SQueryNodeBasicInfo
{
int32_t
type
;
// operator type
int32_t
type
;
// operator type
char
*
name
;
// operator name
char
*
name
;
// operator name
...
@@ -57,68 +70,94 @@ typedef struct SQueryPlanNode {
...
@@ -57,68 +70,94 @@ typedef struct SQueryPlanNode {
struct
SQueryPlanNode
*
nextNode
;
struct
SQueryPlanNode
*
nextNode
;
}
SQueryPlanNode
;
}
SQueryPlanNode
;
typedef
SSchema
SSlotSchema
;
typedef
struct
SDataBlockSchema
{
typedef
struct
SDataBlockSchema
{
int32_t
index
;
int32_t
index
;
SS
chema
*
pSchema
;
// the schema of the SSDatablock
SS
lotSchema
*
pSchema
;
int32_t
numOfCols
;
// number of columns
int32_t
numOfCols
;
// number of columns
}
SDataBlockSchema
;
}
SDataBlockSchema
;
typedef
struct
S
QueryPhyPlan
Node
{
typedef
struct
S
Phy
Node
{
SQueryNodeBasicInfo
info
;
SQueryNodeBasicInfo
info
;
SArray
*
pTarget
;
// target list to be comput
ed at this node
SArray
*
pTarget
s
;
// target list to be computed or scann
ed at this node
SArray
*
qual
;
// implicitly-ANDed qual conditions
SArray
*
pConditions
;
// implicitly-ANDed qual conditions
SDataBlockSchema
targetSchema
;
SDataBlockSchema
targetSchema
;
// children plan to generated result for current node to process
// children plan to generated result for current node to process
// in case of join, multiple plan nodes exist.
// in case of join, multiple plan nodes exist.
SArray
*
pChildren
;
SArray
*
pChildren
;
}
SQueryPhyPlanNode
;
}
SPhyNode
;
typedef
struct
SQueryScanPhyNode
{
typedef
struct
SScanPhyNode
{
SQueryPhyPlanNode
node
;
SPhyNode
node
;
uint64_t
uid
;
uint64_t
uid
;
// unique id of the table
}
SQueryScanPhyNode
;
}
SScanPhyNode
;
typedef
struct
SQueryProjectPhyNode
{
typedef
SScanPhyNode
STagScanPhyNode
;
SQueryPhyPlanNode
node
;
}
SQueryProjectPhyNode
;
typedef
SScanPhyNode
SSystemTableScanPhyNode
;
typedef
struct
SQueryAggPhyNode
{
typedef
struct
SMultiTableScanPhyNode
{
SQueryPhyPlanNode
node
;
SScanPhyNode
scan
;
SArray
*
pGroup
;
SArray
*
pTagsConditions
;
// implicitly-ANDed tag qual conditions
// SInterval
}
SMultiTableScanPhyNode
;
}
SQueryAggPhyNode
;
typedef
SMultiTableScanPhyNode
SMultiTableSeqScanPhyNode
;
typedef
struct
SQueryProfileSummary
{
int64_t
startTs
;
// Object created and added into the message queue
typedef
struct
SProjectPhyNode
{
int64_t
endTs
;
// the timestamp when the task is completed
SPhyNode
node
;
int64_t
cputime
;
// total cpu cost, not execute elapsed time
}
SProjectPhyNode
;
int64_t
loadRemoteDataDuration
;
// remote io time
/**
int64_t
loadNativeDataDuration
;
// native disk io time
* Optimize the query execution plan, currently not implement yet.
* @param pQueryNode
uint64_t
loadNativeData
;
// blocks + SMA + header files
* @return
uint64_t
loadRemoteData
;
// remote data acquired by exchange operator.
*/
int32_t
optimizeQueryPlan
(
struct
SQueryPlanNode
*
pQueryNode
);
uint64_t
waitDuration
;
// the time to waiting to be scheduled in queue does matter, so we need to record it
int64_t
addQTs
;
// the time to be added into the message queue, used to calculate the waiting duration in queue.
/**
* Create the query plan according to the bound AST, which is in the form of pQueryInfo
uint64_t
totalRows
;
* @param pQueryInfo
uint64_t
loadRows
;
* @param pQueryNode
uint32_t
totalBlocks
;
* @return
uint32_t
loadBlocks
;
*/
uint32_t
loadBlockAgg
;
int32_t
createQueryPlan
(
const
struct
SQueryStmtInfo
*
pQueryInfo
,
struct
SQueryPlanNode
**
pQueryNode
);
uint32_t
skipBlocks
;
uint64_t
resultSize
;
// generated result size in Kb.
/**
}
SQueryProfileSummary
;
* Convert the query plan to string, in order to display it in the shell.
* @param pQueryNode
typedef
struct
SQueryTask
{
* @return
uint64_t
queryId
;
// query id
*/
uint64_t
taskId
;
// task id
int32_t
queryPlanToString
(
struct
SQueryPlanNode
*
pQueryNode
,
char
**
str
);
SQueryPhyPlanNode
*
pNode
;
// operator tree
uint64_t
status
;
// task status
/**
SQueryProfileSummary
summary
;
// task execution summary
* Restore the SQL statement according to the logic query plan.
void
*
pOutputHandle
;
// result buffer handle, to temporarily keep the output result for next stage
* @param pQueryNode
}
SQueryTask
;
* @param sql
* @return
*/
int32_t
queryPlanToSql
(
struct
SQueryPlanNode
*
pQueryNode
,
char
**
sql
);
/**
* Convert to physical plan to string to enable to print it out in the shell.
* @param pPhyNode
* @param str
* @return
*/
int32_t
phyPlanToString
(
struct
SPhyNode
*
pPhyNode
,
char
**
str
);
/**
* Destroy the query plan object.
* @return
*/
void
*
destroyQueryPlan
(
struct
SQueryPlanNode
*
pQueryNode
);
/**
* Destroy the physical plan.
* @param pQueryPhyNode
* @return
*/
void
*
destroyQueryPhyPlan
(
struct
SPhyNode
*
pQueryPhyNode
);
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
...
source/libs/planner/src/physicalPlan.c
0 → 100644
浏览文件 @
f8b8569b
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "plannerInt.h"
SPhyNode
*
createScanNode
(
SQueryPlanNode
*
pPlanNode
)
{
return
NULL
;
}
SPhyNode
*
createPhyNode
(
SQueryPlanNode
*
node
)
{
switch
(
node
->
info
.
type
)
{
case
LP_SCAN
:
return
createScanNode
(
node
);
}
return
NULL
;
}
SPhyNode
*
createSubplan
(
SQueryPlanNode
*
pSubquery
)
{
return
NULL
;
}
int32_t
createDag
(
struct
SQueryPlanNode
*
pQueryNode
,
struct
SEpSet
*
pQnode
,
struct
SQueryDag
**
pDag
)
{
return
0
;
}
source/libs/planner/src/planner.c
浏览文件 @
f8b8569b
...
@@ -48,11 +48,11 @@ static SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo);
...
@@ -48,11 +48,11 @@ static SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo);
static
void
doDestroyQueryNode
(
SQueryPlanNode
*
pQueryNode
);
static
void
doDestroyQueryNode
(
SQueryPlanNode
*
pQueryNode
);
int32_t
printExprInfo
(
const
char
*
buf
,
const
SQueryPlanNode
*
pQueryNode
,
int32_t
len
);
int32_t
printExprInfo
(
const
char
*
buf
,
const
SQueryPlanNode
*
pQueryNode
,
int32_t
len
);
int32_t
qO
ptimizeQueryPlan
(
struct
SQueryPlanNode
*
pQueryNode
)
{
int32_t
o
ptimizeQueryPlan
(
struct
SQueryPlanNode
*
pQueryNode
)
{
return
0
;
return
0
;
}
}
int32_t
qC
reateQueryPlan
(
const
struct
SQueryStmtInfo
*
pQueryInfo
,
struct
SQueryPlanNode
**
pQueryNode
)
{
int32_t
c
reateQueryPlan
(
const
struct
SQueryStmtInfo
*
pQueryInfo
,
struct
SQueryPlanNode
**
pQueryNode
)
{
SArray
*
upstream
=
createQueryPlanImpl
((
struct
SQueryStmtInfo
*
)
pQueryInfo
);
SArray
*
upstream
=
createQueryPlanImpl
((
struct
SQueryStmtInfo
*
)
pQueryInfo
);
assert
(
taosArrayGetSize
(
upstream
)
==
1
);
assert
(
taosArrayGetSize
(
upstream
)
==
1
);
...
@@ -62,20 +62,20 @@ int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryP
...
@@ -62,20 +62,20 @@ int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryP
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
int32_t
q
Q
ueryPlanToSql
(
struct
SQueryPlanNode
*
pQueryNode
,
char
**
sql
)
{
int32_t
queryPlanToSql
(
struct
SQueryPlanNode
*
pQueryNode
,
char
**
sql
)
{
return
0
;
return
0
;
}
}
int32_t
qCreatePhysicalPlan
(
struct
SQueryPlanNode
*
pQueryNode
,
struct
SEpSet
*
pQnode
,
struct
SQuery
PhyPlanNode
*
pPhyNode
)
{
int32_t
qCreatePhysicalPlan
(
struct
SQueryPlanNode
*
pQueryNode
,
struct
SEpSet
*
pQnode
,
struct
SQuery
Dag
**
pDag
)
{
return
0
;
return
0
;
}
}
int32_t
qPhyPlanToString
(
struct
SQueryPhyPlan
Node
*
pPhyNode
,
char
**
str
)
{
int32_t
phyPlanToString
(
struct
SPhy
Node
*
pPhyNode
,
char
**
str
)
{
return
0
;
return
0
;
}
}
void
*
qD
estroyQueryPlan
(
SQueryPlanNode
*
pQueryNode
)
{
void
*
d
estroyQueryPlan
(
SQueryPlanNode
*
pQueryNode
)
{
if
(
pQueryNode
==
NULL
)
{
if
(
pQueryNode
==
NULL
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -84,14 +84,10 @@ void* qDestroyQueryPlan(SQueryPlanNode* pQueryNode) {
...
@@ -84,14 +84,10 @@ void* qDestroyQueryPlan(SQueryPlanNode* pQueryNode) {
return
NULL
;
return
NULL
;
}
}
void
*
qDestroyQueryPhyPlan
(
struct
SQueryPhyPlan
Node
*
pQueryPhyNode
)
{
void
*
destroyQueryPhyPlan
(
struct
SPhy
Node
*
pQueryPhyNode
)
{
return
NULL
;
return
NULL
;
}
}
int32_t
qCreateQueryJob
(
const
struct
SQueryPhyPlanNode
*
pPhyNode
,
struct
SQueryJob
**
pJob
)
{
return
0
;
}
//======================================================================================================================
//======================================================================================================================
static
SQueryPlanNode
*
createQueryNode
(
int32_t
type
,
const
char
*
name
,
SQueryPlanNode
**
prev
,
int32_t
numOfPrev
,
static
SQueryPlanNode
*
createQueryNode
(
int32_t
type
,
const
char
*
name
,
SQueryPlanNode
**
prev
,
int32_t
numOfPrev
,
...
@@ -620,7 +616,7 @@ int32_t queryPlanToStringImpl(char* buf, SQueryPlanNode* pQueryNode, int32_t lev
...
@@ -620,7 +616,7 @@ int32_t queryPlanToStringImpl(char* buf, SQueryPlanNode* pQueryNode, int32_t lev
return
len
;
return
len
;
}
}
int32_t
q
Q
ueryPlanToString
(
struct
SQueryPlanNode
*
pQueryNode
,
char
**
str
)
{
int32_t
queryPlanToString
(
struct
SQueryPlanNode
*
pQueryNode
,
char
**
str
)
{
assert
(
pQueryNode
);
assert
(
pQueryNode
);
*
str
=
calloc
(
1
,
4096
);
*
str
=
calloc
(
1
,
4096
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录