Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
30e124a5
T
TDengine
项目概览
taosdata
/
TDengine
12 个月 前同步成功
通知
1180
Star
22014
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看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
30e124a5
编写于
12月 02, 2022
作者:
S
Shengliang Guan
提交者:
GitHub
12月 02, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #18618 from taosdata/enh/3.0_planner_optimize
enh: ins_table count optimize
上级
a3f57b9d
85ea8bbb
变更
28
隐藏空白更改
内联
并排
Showing
28 changed file
with
932 addition
and
149 deletion
+932
-149
include/libs/function/function.h
include/libs/function/function.h
+1
-0
include/libs/function/functionMgt.h
include/libs/function/functionMgt.h
+1
-0
include/libs/nodes/nodes.h
include/libs/nodes/nodes.h
+7
-0
include/libs/nodes/plannodes.h
include/libs/nodes/plannodes.h
+4
-1
source/dnode/vnode/inc/vnode.h
source/dnode/vnode/inc/vnode.h
+18
-8
source/dnode/vnode/src/inc/vnodeInt.h
source/dnode/vnode/src/inc/vnodeInt.h
+0
-8
source/dnode/vnode/src/meta/metaQuery.c
source/dnode/vnode/src/meta/metaQuery.c
+21
-0
source/libs/command/inc/commandInt.h
source/libs/command/inc/commandInt.h
+1
-0
source/libs/command/src/explain.c
source/libs/command/src/explain.c
+48
-0
source/libs/executor/inc/executorimpl.h
source/libs/executor/inc/executorimpl.h
+28
-0
source/libs/executor/src/executil.c
source/libs/executor/src/executil.c
+1
-0
source/libs/executor/src/executorimpl.c
source/libs/executor/src/executorimpl.c
+7
-1
source/libs/executor/src/scanoperator.c
source/libs/executor/src/scanoperator.c
+302
-1
source/libs/function/src/builtins.c
source/libs/function/src/builtins.c
+15
-0
source/libs/nodes/src/nodesCodeFuncs.c
source/libs/nodes/src/nodesCodeFuncs.c
+6
-2
source/libs/nodes/src/nodesMsgFuncs.c
source/libs/nodes/src/nodesMsgFuncs.c
+2
-0
source/libs/nodes/src/nodesUtilFuncs.c
source/libs/nodes/src/nodesUtilFuncs.c
+3
-0
source/libs/parser/inc/parUtil.h
source/libs/parser/inc/parUtil.h
+1
-1
source/libs/parser/src/parAstParser.c
source/libs/parser/src/parAstParser.c
+3
-2
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+57
-43
source/libs/parser/src/parUtil.c
source/libs/parser/src/parUtil.c
+1
-1
source/libs/parser/test/mockCatalog.cpp
source/libs/parser/test/mockCatalog.cpp
+9
-8
source/libs/parser/test/mockCatalogService.cpp
source/libs/parser/test/mockCatalogService.cpp
+82
-57
source/libs/planner/src/planLogicCreater.c
source/libs/planner/src/planLogicCreater.c
+9
-6
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+254
-1
source/libs/planner/src/planPhysiCreater.c
source/libs/planner/src/planPhysiCreater.c
+22
-1
source/libs/planner/src/planSpliter.c
source/libs/planner/src/planSpliter.c
+15
-1
source/libs/planner/test/planSysTbTest.cpp
source/libs/planner/test/planSysTbTest.cpp
+14
-7
未找到文件。
include/libs/function/function.h
浏览文件 @
30e124a5
...
...
@@ -163,6 +163,7 @@ typedef struct tExprNode {
int32_t
functionId
;
int32_t
num
;
struct
SFunctionNode
*
pFunctNode
;
int32_t
functionType
;
}
_function
;
struct
{
...
...
include/libs/function/functionMgt.h
浏览文件 @
30e124a5
...
...
@@ -130,6 +130,7 @@ typedef enum EFunctionType {
FUNCTION_TYPE_GROUP_KEY
,
FUNCTION_TYPE_CACHE_LAST_ROW
,
FUNCTION_TYPE_CACHE_LAST
,
FUNCTION_TYPE_TABLE_COUNT
,
// distributed splitting functions
FUNCTION_TYPE_APERCENTILE_PARTIAL
=
4000
,
...
...
include/libs/nodes/nodes.h
浏览文件 @
30e124a5
...
...
@@ -60,6 +60,12 @@ extern "C" {
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \
(NULL != cell ? (node = &(cell->pNode), true) : (node = NULL, false)); cell = cell->pNext)
#define NODES_DESTORY_NODE(node) \
do { \
nodesDestroyNode((node)); \
(node) = NULL; \
} while (0)
#define NODES_DESTORY_LIST(list) \
do { \
nodesDestroyList((list)); \
...
...
@@ -228,6 +234,7 @@ typedef enum ENodeType {
QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN
,
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
,
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
,
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
,
QUERY_NODE_PHYSICAL_PLAN_PROJECT
,
QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN
,
QUERY_NODE_PHYSICAL_PLAN_HASH_AGG
,
...
...
include/libs/nodes/plannodes.h
浏览文件 @
30e124a5
...
...
@@ -62,7 +62,8 @@ typedef enum EScanType {
SCAN_TYPE_STREAM
,
SCAN_TYPE_TABLE_MERGE
,
SCAN_TYPE_BLOCK_INFO
,
SCAN_TYPE_LAST_ROW
SCAN_TYPE_LAST_ROW
,
SCAN_TYPE_TABLE_COUNT
}
EScanType
;
typedef
struct
SScanLogicNode
{
...
...
@@ -323,6 +324,8 @@ typedef struct SLastRowScanPhysiNode {
bool
ignoreNull
;
}
SLastRowScanPhysiNode
;
typedef
SLastRowScanPhysiNode
STableCountScanPhysiNode
;
typedef
struct
SSystemTableScanPhysiNode
{
SScanPhysiNode
scan
;
SEpSet
mgmtEpSet
;
...
...
source/dnode/vnode/inc/vnode.h
浏览文件 @
30e124a5
...
...
@@ -106,14 +106,24 @@ int32_t metaGetTableTagsByUids(SMeta *pMeta, int64_t suid, SArray *uidList,
int32_t
metaReadNext
(
SMetaReader
*
pReader
);
const
void
*
metaGetTableTagVal
(
void
*
tag
,
int16_t
type
,
STagVal
*
tagVal
);
int
metaGetTableNameByUid
(
void
*
meta
,
uint64_t
uid
,
char
*
tbName
);
int
metaGetTableUidByName
(
void
*
meta
,
char
*
tbName
,
uint64_t
*
uid
);
int
metaGetTableTypeByName
(
void
*
meta
,
char
*
tbName
,
ETableType
*
tbType
);
bool
metaIsTableExist
(
SMeta
*
pMeta
,
tb_uid_t
uid
);
int32_t
metaGetCachedTableUidList
(
SMeta
*
pMeta
,
tb_uid_t
suid
,
const
uint8_t
*
key
,
int32_t
keyLen
,
SArray
*
pList
,
bool
*
acquired
);
int32_t
metaUidFilterCachePut
(
SMeta
*
pMeta
,
uint64_t
suid
,
const
void
*
pKey
,
int32_t
keyLen
,
void
*
pPayload
,
int32_t
payloadLen
,
double
selectivityRatio
);
int32_t
metaUidCacheClear
(
SMeta
*
pMeta
,
uint64_t
suid
);
int
metaGetTableSzNameByUid
(
void
*
meta
,
uint64_t
uid
,
char
*
tbName
);
int
metaGetTableUidByName
(
void
*
meta
,
char
*
tbName
,
uint64_t
*
uid
);
int
metaGetTableTypeByName
(
void
*
meta
,
char
*
tbName
,
ETableType
*
tbType
);
bool
metaIsTableExist
(
SMeta
*
pMeta
,
tb_uid_t
uid
);
int32_t
metaGetCachedTableUidList
(
SMeta
*
pMeta
,
tb_uid_t
suid
,
const
uint8_t
*
key
,
int32_t
keyLen
,
SArray
*
pList
,
bool
*
acquired
);
int32_t
metaUidFilterCachePut
(
SMeta
*
pMeta
,
uint64_t
suid
,
const
void
*
pKey
,
int32_t
keyLen
,
void
*
pPayload
,
int32_t
payloadLen
,
double
selectivityRatio
);
int32_t
metaUidCacheClear
(
SMeta
*
pMeta
,
uint64_t
suid
);
tb_uid_t
metaGetTableEntryUidByName
(
SMeta
*
pMeta
,
const
char
*
name
);
int64_t
metaGetTbNum
(
SMeta
*
pMeta
);
int64_t
metaGetNtbNum
(
SMeta
*
pMeta
);
typedef
struct
{
int64_t
uid
;
int64_t
ctbNum
;
}
SMetaStbStats
;
int32_t
metaGetStbStats
(
SMeta
*
pMeta
,
int64_t
uid
,
SMetaStbStats
*
pInfo
);
typedef
struct
SMetaFltParam
{
tb_uid_t
suid
;
...
...
source/dnode/vnode/src/inc/vnodeInt.h
浏览文件 @
30e124a5
...
...
@@ -116,8 +116,6 @@ int32_t metaGetTbTSchemaEx(SMeta* pMeta, tb_uid_t suid, tb_uid_t uid, in
int
metaGetTableEntryByName
(
SMetaReader
*
pReader
,
const
char
*
name
);
int
metaAlterCache
(
SMeta
*
pMeta
,
int32_t
nPage
);
tb_uid_t
metaGetTableEntryUidByName
(
SMeta
*
pMeta
,
const
char
*
name
);
int64_t
metaGetTbNum
(
SMeta
*
pMeta
);
int64_t
metaGetTimeSeriesNum
(
SMeta
*
pMeta
);
SMCtbCursor
*
metaOpenCtbCursor
(
SMeta
*
pMeta
,
tb_uid_t
uid
,
int
lock
);
void
metaCloseCtbCursor
(
SMCtbCursor
*
pCtbCur
,
int
lock
);
...
...
@@ -144,12 +142,6 @@ typedef struct SMetaInfo {
}
SMetaInfo
;
int32_t
metaGetInfo
(
SMeta
*
pMeta
,
int64_t
uid
,
SMetaInfo
*
pInfo
,
SMetaReader
*
pReader
);
typedef
struct
{
int64_t
uid
;
int64_t
ctbNum
;
}
SMetaStbStats
;
int32_t
metaGetStbStats
(
SMeta
*
pMeta
,
int64_t
uid
,
SMetaStbStats
*
pInfo
);
// tsdb
int
tsdbOpen
(
SVnode
*
pVnode
,
STsdb
**
ppTsdb
,
const
char
*
dir
,
STsdbKeepCfg
*
pKeepCfg
,
int8_t
rollback
);
int
tsdbClose
(
STsdb
**
pTsdb
);
...
...
source/dnode/vnode/src/meta/metaQuery.c
浏览文件 @
30e124a5
...
...
@@ -223,6 +223,23 @@ int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName) {
return
0
;
}
int
metaGetTableSzNameByUid
(
void
*
meta
,
uint64_t
uid
,
char
*
tbName
)
{
int
code
=
0
;
SMetaReader
mr
=
{
0
};
metaReaderInit
(
&
mr
,
(
SMeta
*
)
meta
,
0
);
code
=
metaGetTableEntryByUid
(
&
mr
,
uid
);
if
(
code
<
0
)
{
metaReaderClear
(
&
mr
);
return
-
1
;
}
strncpy
(
tbName
,
mr
.
me
.
name
,
TSDB_TABLE_NAME_LEN
);
metaReaderClear
(
&
mr
);
return
0
;
}
int
metaGetTableUidByName
(
void
*
meta
,
char
*
tbName
,
uint64_t
*
uid
)
{
int
code
=
0
;
SMetaReader
mr
=
{
0
};
...
...
@@ -739,6 +756,10 @@ int64_t metaGetTimeSeriesNum(SMeta *pMeta) {
return
pMeta
->
pVnode
->
config
.
vndStats
.
numOfTimeSeries
+
pMeta
->
pVnode
->
config
.
vndStats
.
numOfNTimeSeries
;
}
int64_t
metaGetNtbNum
(
SMeta
*
pMeta
)
{
return
pMeta
->
pVnode
->
config
.
vndStats
.
numOfNTables
;
}
typedef
struct
{
SMeta
*
pMeta
;
TBC
*
pCur
;
...
...
source/libs/command/inc/commandInt.h
浏览文件 @
30e124a5
...
...
@@ -34,6 +34,7 @@ extern "C" {
#define EXPLAIN_SYSTBL_SCAN_FORMAT "System Table Scan on %s"
#define EXPLAIN_DISTBLK_SCAN_FORMAT "Block Dist Scan on %s"
#define EXPLAIN_LASTROW_SCAN_FORMAT "Last Row Scan on %s"
#define EXPLAIN_TABLE_COUNT_SCAN_FORMAT "Table Count Row Scan on %s"
#define EXPLAIN_PROJECTION_FORMAT "Projection"
#define EXPLAIN_JOIN_FORMAT "%s"
#define EXPLAIN_AGG_FORMAT "Aggragate"
...
...
source/libs/command/src/explain.c
浏览文件 @
30e124a5
...
...
@@ -19,6 +19,7 @@
#include "query.h"
#include "tcommon.h"
#include "tdatablock.h"
#include "systable.h"
int32_t
qExplainGenerateResNode
(
SPhysiNode
*
pNode
,
SExplainGroup
*
group
,
SExplainResNode
**
pRes
);
int32_t
qExplainAppendGroupResRows
(
void
*
pCtx
,
int32_t
groupId
,
int32_t
level
,
bool
singleChannel
);
...
...
@@ -212,6 +213,11 @@ int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNo
pPhysiChildren
=
lastRowPhysiNode
->
scan
.
node
.
pChildren
;
break
;
}
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
:
{
STableCountScanPhysiNode
*
tableCountPhysiNode
=
(
STableCountScanPhysiNode
*
)
pNode
;
pPhysiChildren
=
tableCountPhysiNode
->
scan
.
node
.
pChildren
;
break
;
}
case
QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT
:
{
SGroupSortPhysiNode
*
groupSortPhysiNode
=
(
SGroupSortPhysiNode
*
)
pNode
;
pPhysiChildren
=
groupSortPhysiNode
->
node
.
pChildren
;
...
...
@@ -1355,6 +1361,48 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
}
break
;
}
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
:
{
STableCountScanPhysiNode
*
pLastRowNode
=
(
STableCountScanPhysiNode
*
)
pNode
;
EXPLAIN_ROW_NEW
(
level
,
EXPLAIN_TABLE_COUNT_SCAN_FORMAT
,
(
'\0'
!=
pLastRowNode
->
scan
.
tableName
.
tname
[
0
]
?
pLastRowNode
->
scan
.
tableName
.
tname
:
TSDB_INS_TABLE_TABLES
));
EXPLAIN_ROW_APPEND
(
EXPLAIN_LEFT_PARENTHESIS_FORMAT
);
if
(
pResNode
->
pExecInfo
)
{
QRY_ERR_RET
(
qExplainBufAppendExecInfo
(
pResNode
->
pExecInfo
,
tbuf
,
&
tlen
));
EXPLAIN_ROW_APPEND
(
EXPLAIN_BLANK_FORMAT
);
}
EXPLAIN_ROW_APPEND
(
EXPLAIN_COLUMNS_FORMAT
,
LIST_LENGTH
(
pLastRowNode
->
scan
.
pScanCols
));
EXPLAIN_ROW_APPEND
(
EXPLAIN_BLANK_FORMAT
);
if
(
pLastRowNode
->
scan
.
pScanPseudoCols
)
{
EXPLAIN_ROW_APPEND
(
EXPLAIN_PSEUDO_COLUMNS_FORMAT
,
pLastRowNode
->
scan
.
pScanPseudoCols
->
length
);
EXPLAIN_ROW_APPEND
(
EXPLAIN_BLANK_FORMAT
);
}
EXPLAIN_ROW_APPEND
(
EXPLAIN_WIDTH_FORMAT
,
pLastRowNode
->
scan
.
node
.
pOutputDataBlockDesc
->
totalRowSize
);
EXPLAIN_ROW_APPEND
(
EXPLAIN_BLANK_FORMAT
);
EXPLAIN_ROW_APPEND
(
EXPLAIN_RIGHT_PARENTHESIS_FORMAT
);
EXPLAIN_ROW_END
();
QRY_ERR_RET
(
qExplainResAppendRow
(
ctx
,
tbuf
,
tlen
,
level
));
if
(
verbose
)
{
EXPLAIN_ROW_NEW
(
level
+
1
,
EXPLAIN_OUTPUT_FORMAT
);
EXPLAIN_ROW_APPEND
(
EXPLAIN_COLUMNS_FORMAT
,
nodesGetOutputNumFromSlotList
(
pLastRowNode
->
scan
.
node
.
pOutputDataBlockDesc
->
pSlots
));
EXPLAIN_ROW_APPEND
(
EXPLAIN_BLANK_FORMAT
);
EXPLAIN_ROW_APPEND
(
EXPLAIN_WIDTH_FORMAT
,
pLastRowNode
->
scan
.
node
.
pOutputDataBlockDesc
->
outputRowSize
);
EXPLAIN_ROW_APPEND_LIMIT
(
pLastRowNode
->
scan
.
node
.
pLimit
);
EXPLAIN_ROW_APPEND_SLIMIT
(
pLastRowNode
->
scan
.
node
.
pSlimit
);
EXPLAIN_ROW_END
();
QRY_ERR_RET
(
qExplainResAppendRow
(
ctx
,
tbuf
,
tlen
,
level
+
1
));
if
(
pLastRowNode
->
scan
.
node
.
pConditions
)
{
EXPLAIN_ROW_NEW
(
level
+
1
,
EXPLAIN_FILTER_FORMAT
);
QRY_ERR_RET
(
nodesNodeToSQL
(
pLastRowNode
->
scan
.
node
.
pConditions
,
tbuf
+
VARSTR_HEADER_SIZE
,
TSDB_EXPLAIN_RESULT_ROW_SIZE
,
&
tlen
));
EXPLAIN_ROW_END
();
QRY_ERR_RET
(
qExplainResAppendRow
(
ctx
,
tbuf
,
tlen
,
level
+
1
));
}
}
break
;
}
case
QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT
:
{
SGroupSortPhysiNode
*
pSortNode
=
(
SGroupSortPhysiNode
*
)
pNode
;
EXPLAIN_ROW_NEW
(
level
,
EXPLAIN_GROUP_SORT_FORMAT
);
...
...
source/libs/executor/inc/executorimpl.h
浏览文件 @
30e124a5
...
...
@@ -482,6 +482,34 @@ typedef struct {
SSnapContext
*
sContext
;
}
SStreamRawScanInfo
;
typedef
struct
STableCountScanSupp
{
int16_t
dbNameSlotId
;
int16_t
stbNameSlotId
;
int16_t
tbCountSlotId
;
bool
groupByDbName
;
bool
groupByStbName
;
char
dbName
[
TSDB_DB_NAME_LEN
];
char
stbName
[
TSDB_TABLE_NAME_LEN
];
}
STableCountScanSupp
;
typedef
struct
STableCountScanOperatorInfo
{
SReadHandle
readHandle
;
SSDataBlock
*
pRes
;
SName
tableName
;
SNodeList
*
groupTags
;
SNodeList
*
scanCols
;
SNodeList
*
pseudoCols
;
STableCountScanSupp
supp
;
int32_t
currGrpIdx
;
SArray
*
stbUidList
;
// when group by db_name and stable_name
}
STableCountScanOperatorInfo
;
typedef
struct
SOptrBasicInfo
{
SResultRowInfo
resultRowInfo
;
SSDataBlock
*
pRes
;
...
...
source/libs/executor/src/executil.c
浏览文件 @
30e124a5
...
...
@@ -1348,6 +1348,7 @@ void createExprFromOneNode(SExprInfo* pExp, SNode* pNode, int16_t slotId) {
pExprNode
->
_function
.
functionId
=
pFuncNode
->
funcId
;
pExprNode
->
_function
.
pFunctNode
=
pFuncNode
;
pExprNode
->
_function
.
functionType
=
pFuncNode
->
funcType
;
tstrncpy
(
pExprNode
->
_function
.
functionName
,
pFuncNode
->
functionName
,
tListLen
(
pExprNode
->
_function
.
functionName
));
...
...
source/libs/executor/src/executorimpl.c
浏览文件 @
30e124a5
...
...
@@ -1370,7 +1370,8 @@ int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scan
int32_t
type
=
pOperator
->
operatorType
;
if
(
type
==
QUERY_NODE_PHYSICAL_PLAN_EXCHANGE
||
type
==
QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN
||
type
==
QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN
||
type
==
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN
||
type
==
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
||
type
==
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
)
{
type
==
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
||
type
==
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
||
type
==
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
)
{
*
order
=
TSDB_ORDER_ASC
;
*
scanFlag
=
MAIN_SCAN
;
return
TSDB_CODE_SUCCESS
;
...
...
@@ -1872,6 +1873,8 @@ static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPT
SSchemaWrapper
*
extractQueriedColumnSchema
(
SScanPhysiNode
*
pScanNode
);
SOperatorInfo
*
createTableCountScanOperatorInfo
(
SReadHandle
*
handle
,
STableCountScanPhysiNode
*
pNode
,
SExecTaskInfo
*
pTaskInfo
);
int32_t
extractTableSchemaInfo
(
SReadHandle
*
pHandle
,
SScanPhysiNode
*
pScanNode
,
SExecTaskInfo
*
pTaskInfo
)
{
SMetaReader
mr
=
{
0
};
metaReaderInit
(
&
mr
,
pHandle
->
meta
,
0
);
...
...
@@ -2062,6 +2065,9 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN
==
type
)
{
SSystemTableScanPhysiNode
*
pSysScanPhyNode
=
(
SSystemTableScanPhysiNode
*
)
pPhyNode
;
pOperator
=
createSysTableScanOperatorInfo
(
pHandle
,
pSysScanPhyNode
,
pUser
,
pTaskInfo
);
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
==
type
)
{
STableCountScanPhysiNode
*
pTblCountScanNode
=
(
STableCountScanPhysiNode
*
)
pPhyNode
;
pOperator
=
createTableCountScanOperatorInfo
(
pHandle
,
pTblCountScanNode
,
pTaskInfo
);
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN
==
type
)
{
STagScanPhysiNode
*
pScanPhyNode
=
(
STagScanPhysiNode
*
)
pPhyNode
;
...
...
source/libs/executor/src/scanoperator.c
浏览文件 @
30e124a5
...
...
@@ -30,7 +30,6 @@
#include "tcompare.h"
#include "thash.h"
#include "ttypes.h"
#include "vnode.h"
#define SET_REVERSE_SCAN_FLAG(_info) ((_info)->scanFlag = REVERSE_SCAN)
#define SWITCH_ORDER(n) (((n) = ((n) == TSDB_ORDER_ASC) ? TSDB_ORDER_DESC : TSDB_ORDER_ASC))
...
...
@@ -2913,3 +2912,305 @@ _error:
taosMemoryFree
(
pOperator
);
return
NULL
;
}
// ====================================================================================================================
// TableCountScanOperator
static
SSDataBlock
*
doTableCountScan
(
SOperatorInfo
*
pOperator
);
static
void
destoryTableCountScanOperator
(
void
*
param
);
static
const
char
*
GROUP_TAG_DB_NAME
=
"db_name"
;
static
const
char
*
GROUP_TAG_STABLE_NAME
=
"stable_name"
;
int32_t
tblCountScanGetGroupTagsSlotId
(
const
SNodeList
*
scanCols
,
STableCountScanSupp
*
supp
)
{
if
(
scanCols
!=
NULL
)
{
SNode
*
pNode
=
NULL
;
FOREACH
(
pNode
,
scanCols
)
{
if
(
nodeType
(
pNode
)
!=
QUERY_NODE_TARGET
)
{
return
TSDB_CODE_QRY_SYS_ERROR
;
}
STargetNode
*
targetNode
=
(
STargetNode
*
)
pNode
;
if
(
nodeType
(
targetNode
->
pExpr
)
!=
QUERY_NODE_COLUMN
)
{
return
TSDB_CODE_QRY_SYS_ERROR
;
}
SColumnNode
*
colNode
=
(
SColumnNode
*
)(
targetNode
->
pExpr
);
if
(
strcmp
(
colNode
->
colName
,
GROUP_TAG_DB_NAME
)
==
0
)
{
supp
->
dbNameSlotId
=
targetNode
->
slotId
;
}
else
if
(
strcmp
(
colNode
->
colName
,
GROUP_TAG_STABLE_NAME
)
==
0
)
{
supp
->
stbNameSlotId
=
targetNode
->
slotId
;
}
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
tblCountScanGetCountSlotId
(
const
SNodeList
*
pseudoCols
,
STableCountScanSupp
*
supp
)
{
if
(
pseudoCols
!=
NULL
)
{
SNode
*
pNode
=
NULL
;
FOREACH
(
pNode
,
pseudoCols
)
{
if
(
nodeType
(
pNode
)
!=
QUERY_NODE_TARGET
)
{
return
TSDB_CODE_QRY_SYS_ERROR
;
}
STargetNode
*
targetNode
=
(
STargetNode
*
)
pNode
;
if
(
nodeType
(
targetNode
->
pExpr
)
!=
QUERY_NODE_FUNCTION
)
{
return
TSDB_CODE_QRY_SYS_ERROR
;
}
SFunctionNode
*
funcNode
=
(
SFunctionNode
*
)(
targetNode
->
pExpr
);
if
(
funcNode
->
funcType
==
FUNCTION_TYPE_TABLE_COUNT
)
{
supp
->
tbCountSlotId
=
targetNode
->
slotId
;
}
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
tblCountScanGetInputs
(
SNodeList
*
groupTags
,
SName
*
tableName
,
STableCountScanSupp
*
supp
)
{
if
(
groupTags
!=
NULL
)
{
SNode
*
pNode
=
NULL
;
FOREACH
(
pNode
,
groupTags
)
{
if
(
nodeType
(
pNode
)
!=
QUERY_NODE_COLUMN
)
{
return
TSDB_CODE_QRY_SYS_ERROR
;
}
SColumnNode
*
colNode
=
(
SColumnNode
*
)
pNode
;
if
(
strcmp
(
colNode
->
colName
,
GROUP_TAG_DB_NAME
)
==
0
)
{
supp
->
groupByDbName
=
true
;
}
if
(
strcmp
(
colNode
->
colName
,
GROUP_TAG_STABLE_NAME
)
==
0
)
{
supp
->
groupByStbName
=
true
;
}
}
}
else
{
strncpy
(
supp
->
dbName
,
tNameGetDbNameP
(
tableName
),
TSDB_DB_NAME_LEN
);
strncpy
(
supp
->
stbName
,
tNameGetTableName
(
tableName
),
TSDB_TABLE_NAME_LEN
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
getTableCountScanSupp
(
SNodeList
*
groupTags
,
SName
*
tableName
,
SNodeList
*
scanCols
,
SNodeList
*
pseudoCols
,
STableCountScanSupp
*
supp
,
SExecTaskInfo
*
taskInfo
)
{
int32_t
code
=
0
;
code
=
tblCountScanGetInputs
(
groupTags
,
tableName
,
supp
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
qError
(
"%s get table count scan supp. get inputs error"
,
GET_TASKID
(
taskInfo
));
return
code
;
}
supp
->
dbNameSlotId
=
-
1
;
supp
->
stbNameSlotId
=
-
1
;
supp
->
tbCountSlotId
=
-
1
;
code
=
tblCountScanGetGroupTagsSlotId
(
scanCols
,
supp
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
qError
(
"%s get table count scan supp. get group tags slot id error"
,
GET_TASKID
(
taskInfo
));
return
code
;
}
code
=
tblCountScanGetCountSlotId
(
pseudoCols
,
supp
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
qError
(
"%s get table count scan supp. get count error"
,
GET_TASKID
(
taskInfo
));
return
code
;
}
return
code
;
}
SOperatorInfo
*
createTableCountScanOperatorInfo
(
SReadHandle
*
readHandle
,
STableCountScanPhysiNode
*
pTblCountScanNode
,
SExecTaskInfo
*
pTaskInfo
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
SScanPhysiNode
*
pScanNode
=
&
pTblCountScanNode
->
scan
;
STableCountScanOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
STableCountScanOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
!
pInfo
||
!
pOperator
)
{
goto
_error
;
}
pInfo
->
readHandle
=
*
readHandle
;
SDataBlockDescNode
*
pDescNode
=
pScanNode
->
node
.
pOutputDataBlockDesc
;
initResultSizeInfo
(
&
pOperator
->
resultInfo
,
1
);
pInfo
->
pRes
=
createDataBlockFromDescNode
(
pDescNode
);
blockDataEnsureCapacity
(
pInfo
->
pRes
,
pOperator
->
resultInfo
.
capacity
);
getTableCountScanSupp
(
pTblCountScanNode
->
pGroupTags
,
&
pTblCountScanNode
->
scan
.
tableName
,
pTblCountScanNode
->
scan
.
pScanCols
,
pTblCountScanNode
->
scan
.
pScanPseudoCols
,
&
pInfo
->
supp
,
pTaskInfo
);
setOperatorInfo
(
pOperator
,
"TableCountScanOperator"
,
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
,
false
,
OP_NOT_OPENED
,
pInfo
,
pTaskInfo
);
pOperator
->
fpSet
=
createOperatorFpSet
(
operatorDummyOpenFn
,
doTableCountScan
,
NULL
,
destoryTableCountScanOperator
,
NULL
);
return
pOperator
;
_error:
if
(
pInfo
!=
NULL
)
{
destoryTableCountScanOperator
(
pInfo
);
}
taosMemoryFreeClear
(
pOperator
);
pTaskInfo
->
code
=
code
;
return
NULL
;
}
void
fillTableCountScanDataBlock
(
STableCountScanSupp
*
pSupp
,
char
*
dbName
,
char
*
stbName
,
int64_t
count
,
SSDataBlock
*
pRes
)
{
if
(
pSupp
->
dbNameSlotId
!=
-
1
)
{
ASSERT
(
strlen
(
dbName
));
SColumnInfoData
*
colInfoData
=
taosArrayGet
(
pRes
->
pDataBlock
,
pSupp
->
dbNameSlotId
);
char
varDbName
[
TSDB_DB_NAME_LEN
+
VARSTR_HEADER_SIZE
]
=
{
0
};
strncpy
(
varDataVal
(
varDbName
),
dbName
,
strlen
(
dbName
));
varDataSetLen
(
varDbName
,
strlen
(
dbName
));
colDataAppend
(
colInfoData
,
0
,
varDbName
,
false
);
}
if
(
pSupp
->
stbNameSlotId
!=
-
1
)
{
SColumnInfoData
*
colInfoData
=
taosArrayGet
(
pRes
->
pDataBlock
,
pSupp
->
stbNameSlotId
);
if
(
strlen
(
stbName
)
!=
0
)
{
char
varStbName
[
TSDB_TABLE_NAME_LEN
+
VARSTR_HEADER_SIZE
]
=
{
0
};
strncpy
(
varDataVal
(
varStbName
),
stbName
,
strlen
(
stbName
));
varDataSetLen
(
varStbName
,
strlen
(
stbName
));
colDataAppend
(
colInfoData
,
0
,
varStbName
,
false
);
}
else
{
colDataAppendNULL
(
colInfoData
,
0
);
}
}
if
(
pSupp
->
tbCountSlotId
!=
-
1
)
{
SColumnInfoData
*
colInfoData
=
taosArrayGet
(
pRes
->
pDataBlock
,
pSupp
->
tbCountSlotId
);
colDataAppend
(
colInfoData
,
0
,
(
char
*
)
&
count
,
false
);
}
pRes
->
info
.
rows
=
1
;
}
static
SSDataBlock
*
buildSysDbTableCount
(
SOperatorInfo
*
pOperator
,
STableCountScanOperatorInfo
*
pInfo
)
{
STableCountScanSupp
*
pSupp
=
&
pInfo
->
supp
;
SSDataBlock
*
pRes
=
pInfo
->
pRes
;
size_t
infodbTableNum
;
getInfosDbMeta
(
NULL
,
&
infodbTableNum
);
size_t
perfdbTableNum
;
getPerfDbMeta
(
NULL
,
&
perfdbTableNum
);
if
(
pSupp
->
groupByDbName
)
{
if
(
pInfo
->
currGrpIdx
==
0
)
{
uint64_t
groupId
=
calcGroupId
(
TSDB_INFORMATION_SCHEMA_DB
,
strlen
(
TSDB_INFORMATION_SCHEMA_DB
));
pRes
->
info
.
id
.
groupId
=
groupId
;
fillTableCountScanDataBlock
(
pSupp
,
TSDB_INFORMATION_SCHEMA_DB
,
""
,
infodbTableNum
,
pRes
);
}
else
if
(
pInfo
->
currGrpIdx
==
1
)
{
uint64_t
groupId
=
calcGroupId
(
TSDB_PERFORMANCE_SCHEMA_DB
,
strlen
(
TSDB_PERFORMANCE_SCHEMA_DB
));
pRes
->
info
.
id
.
groupId
=
groupId
;
fillTableCountScanDataBlock
(
pSupp
,
TSDB_PERFORMANCE_SCHEMA_DB
,
""
,
perfdbTableNum
,
pRes
);
}
else
{
setOperatorCompleted
(
pOperator
);
return
NULL
;
}
pInfo
->
currGrpIdx
++
;
return
(
pRes
->
info
.
rows
>
0
)
?
pRes
:
NULL
;
}
else
{
if
(
strcmp
(
pSupp
->
dbName
,
TSDB_INFORMATION_SCHEMA_DB
)
==
0
)
{
fillTableCountScanDataBlock
(
pSupp
,
TSDB_INFORMATION_SCHEMA_DB
,
""
,
infodbTableNum
,
pRes
);
}
else
if
(
strcmp
(
pSupp
->
dbName
,
TSDB_PERFORMANCE_SCHEMA_DB
)
==
0
)
{
fillTableCountScanDataBlock
(
pSupp
,
TSDB_PERFORMANCE_SCHEMA_DB
,
""
,
perfdbTableNum
,
pRes
);
}
else
if
(
strlen
(
pSupp
->
dbName
)
==
0
)
{
fillTableCountScanDataBlock
(
pSupp
,
""
,
""
,
infodbTableNum
+
perfdbTableNum
,
pRes
);
}
setOperatorCompleted
(
pOperator
);
return
(
pRes
->
info
.
rows
>
0
)
?
pRes
:
NULL
;
}
}
static
SSDataBlock
*
doTableCountScan
(
SOperatorInfo
*
pOperator
)
{
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
STableCountScanOperatorInfo
*
pInfo
=
pOperator
->
info
;
STableCountScanSupp
*
pSupp
=
&
pInfo
->
supp
;
SSDataBlock
*
pRes
=
pInfo
->
pRes
;
blockDataCleanup
(
pRes
);
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
if
(
pInfo
->
readHandle
.
mnd
!=
NULL
)
{
return
buildSysDbTableCount
(
pOperator
,
pInfo
);
}
const
char
*
db
=
NULL
;
int32_t
vgId
=
0
;
char
dbName
[
TSDB_DB_NAME_LEN
]
=
{
0
};
{
// get dbname
vnodeGetInfo
(
pInfo
->
readHandle
.
vnode
,
&
db
,
&
vgId
);
SName
sn
=
{
0
};
tNameFromString
(
&
sn
,
db
,
T_NAME_ACCT
|
T_NAME_DB
);
tNameGetDbName
(
&
sn
,
dbName
);
}
if
(
pSupp
->
groupByDbName
)
{
if
(
pSupp
->
groupByStbName
)
{
if
(
pInfo
->
stbUidList
==
NULL
)
{
pInfo
->
stbUidList
=
taosArrayInit
(
16
,
sizeof
(
tb_uid_t
));
if
(
vnodeGetStbIdList
(
pInfo
->
readHandle
.
vnode
,
0
,
pInfo
->
stbUidList
)
<
0
)
{
qError
(
"vgId:%d, failed to get stb id list error: %s"
,
vgId
,
terrstr
());
}
}
if
(
pInfo
->
currGrpIdx
<
taosArrayGetSize
(
pInfo
->
stbUidList
))
{
tb_uid_t
stbUid
=
*
(
tb_uid_t
*
)
taosArrayGet
(
pInfo
->
stbUidList
,
pInfo
->
currGrpIdx
);
char
stbName
[
TSDB_TABLE_NAME_LEN
]
=
{
0
};
metaGetTableSzNameByUid
(
pInfo
->
readHandle
.
meta
,
stbUid
,
stbName
);
char
fullStbName
[
TSDB_TABLE_FNAME_LEN
]
=
{
0
};
snprintf
(
fullStbName
,
TSDB_TABLE_FNAME_LEN
,
"%s.%s"
,
dbName
,
stbName
);
uint64_t
groupId
=
calcGroupId
(
fullStbName
,
strlen
(
fullStbName
));
pRes
->
info
.
id
.
groupId
=
groupId
;
SMetaStbStats
stats
=
{
0
};
metaGetStbStats
(
pInfo
->
readHandle
.
meta
,
stbUid
,
&
stats
);
int64_t
ctbNum
=
stats
.
ctbNum
;
fillTableCountScanDataBlock
(
pSupp
,
dbName
,
stbName
,
ctbNum
,
pRes
);
pInfo
->
currGrpIdx
++
;
}
else
if
(
pInfo
->
currGrpIdx
==
taosArrayGetSize
(
pInfo
->
stbUidList
))
{
char
fullStbName
[
TSDB_TABLE_FNAME_LEN
]
=
{
0
};
snprintf
(
fullStbName
,
TSDB_TABLE_FNAME_LEN
,
"%s.%s"
,
dbName
,
""
);
uint64_t
groupId
=
calcGroupId
(
fullStbName
,
strlen
(
fullStbName
));
pRes
->
info
.
id
.
groupId
=
groupId
;
int64_t
ntbNum
=
metaGetNtbNum
(
pInfo
->
readHandle
.
meta
);
fillTableCountScanDataBlock
(
pSupp
,
dbName
,
""
,
ntbNum
,
pRes
);
pInfo
->
currGrpIdx
++
;
}
else
{
setOperatorCompleted
(
pOperator
);
return
NULL
;
}
}
else
{
uint64_t
groupId
=
calcGroupId
(
dbName
,
strlen
(
dbName
));
pRes
->
info
.
id
.
groupId
=
groupId
;
int64_t
dbTableCount
=
metaGetTbNum
(
pInfo
->
readHandle
.
meta
);
fillTableCountScanDataBlock
(
pSupp
,
dbName
,
""
,
dbTableCount
,
pRes
);
setOperatorCompleted
(
pOperator
);
}
}
else
{
if
(
strlen
(
pSupp
->
dbName
)
!=
0
)
{
if
(
strlen
(
pSupp
->
stbName
)
!=
0
)
{
tb_uid_t
uid
=
metaGetTableEntryUidByName
(
pInfo
->
readHandle
.
meta
,
pSupp
->
stbName
);
SMetaStbStats
stats
=
{
0
};
metaGetStbStats
(
pInfo
->
readHandle
.
meta
,
uid
,
&
stats
);
int64_t
ctbNum
=
stats
.
ctbNum
;
fillTableCountScanDataBlock
(
pSupp
,
dbName
,
pSupp
->
stbName
,
ctbNum
,
pRes
);
}
else
{
int64_t
tbNumVnode
=
metaGetTbNum
(
pInfo
->
readHandle
.
meta
);
fillTableCountScanDataBlock
(
pSupp
,
dbName
,
""
,
tbNumVnode
,
pRes
);
}
}
else
{
int64_t
tbNumVnode
=
metaGetTbNum
(
pInfo
->
readHandle
.
meta
);
fillTableCountScanDataBlock
(
pSupp
,
dbName
,
""
,
tbNumVnode
,
pRes
);
}
setOperatorCompleted
(
pOperator
);
}
return
pRes
->
info
.
rows
>
0
?
pRes
:
NULL
;
}
static
void
destoryTableCountScanOperator
(
void
*
param
)
{
STableCountScanOperatorInfo
*
pTableCountScanInfo
=
param
;
blockDataDestroy
(
pTableCountScanInfo
->
pRes
);
nodesDestroyList
(
pTableCountScanInfo
->
groupTags
);
taosArrayDestroy
(
pTableCountScanInfo
->
stbUidList
);
taosMemoryFreeClear
(
param
);
}
source/libs/function/src/builtins.c
浏览文件 @
30e124a5
...
...
@@ -2080,6 +2080,11 @@ static int32_t translateTagsPseudoColumn(SFunctionNode* pFunc, char* pErrBuf, in
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
translateTableCountPseudoColumn
(
SFunctionNode
*
pFunc
,
char
*
pErrBuf
,
int32_t
len
)
{
pFunc
->
node
.
resType
=
(
SDataType
){.
bytes
=
tDataTypes
[
TSDB_DATA_TYPE_BIGINT
].
bytes
,
.
type
=
TSDB_DATA_TYPE_BIGINT
};
return
TSDB_CODE_SUCCESS
;
}
// clang-format off
const
SBuiltinFuncDefinition
funcMgtBuiltins
[]
=
{
{
...
...
@@ -3241,6 +3246,16 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.
sprocessFunc
=
NULL
,
.
finalizeFunc
=
NULL
},
{
.
name
=
"_table_count"
,
.
type
=
FUNCTION_TYPE_TABLE_COUNT
,
.
classification
=
FUNC_MGT_PSEUDO_COLUMN_FUNC
|
FUNC_MGT_SCAN_PC_FUNC
,
.
translateFunc
=
translateTableCountPseudoColumn
,
.
getEnvFunc
=
NULL
,
.
initFunc
=
NULL
,
.
sprocessFunc
=
NULL
,
.
finalizeFunc
=
NULL
},
};
// clang-format on
...
...
source/libs/nodes/src/nodesCodeFuncs.c
浏览文件 @
30e124a5
...
...
@@ -221,6 +221,8 @@ const char* nodesNodeName(ENodeType type) {
return
"PhysiTableScan"
;
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN
:
return
"PhysiTableSeqScan"
;
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN
:
return
"PhysiTableMergeScan"
;
case
QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN
:
return
"PhysiSreamScan"
;
case
QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN
:
...
...
@@ -229,8 +231,8 @@ const char* nodesNodeName(ENodeType type) {
return
"PhysiBlockDistScan"
;
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
return
"PhysiLastRowScan"
;
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_
MERGE
_SCAN
:
return
"PhysiTable
Merge
Scan"
;
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_
COUNT
_SCAN
:
return
"PhysiTable
Count
Scan"
;
case
QUERY_NODE_PHYSICAL_PLAN_PROJECT
:
return
"PhysiProject"
;
case
QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN
:
...
...
@@ -4646,6 +4648,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
:
return
physiScanNodeToJson
(
pObj
,
pJson
);
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
:
return
physiLastRowScanNodeToJson
(
pObj
,
pJson
);
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN
:
...
...
@@ -4800,6 +4803,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return
jsonToLogicPlan
(
pJson
,
pObj
);
case
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
:
return
jsonToPhysiScanNode
(
pJson
,
pObj
);
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
return
jsonToPhysiLastRowScanNode
(
pJson
,
pObj
);
...
...
source/libs/nodes/src/nodesMsgFuncs.c
浏览文件 @
30e124a5
...
...
@@ -3640,6 +3640,7 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
code
=
physiScanNodeToMsg
(
pObj
,
pEncoder
);
break
;
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
:
code
=
physiLastRowScanNodeToMsg
(
pObj
,
pEncoder
);
break
;
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN
:
...
...
@@ -3778,6 +3779,7 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) {
code
=
msgToPhysiScanNode
(
pDecoder
,
pObj
);
break
;
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
:
code
=
msgToPhysiLastRowScanNode
(
pDecoder
,
pObj
);
break
;
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN
:
...
...
source/libs/nodes/src/nodesUtilFuncs.c
浏览文件 @
30e124a5
...
...
@@ -494,6 +494,8 @@ SNode* nodesMakeNode(ENodeType type) {
return
makeNode
(
type
,
sizeof
(
SBlockDistScanPhysiNode
));
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
return
makeNode
(
type
,
sizeof
(
SLastRowScanPhysiNode
));
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
:
return
makeNode
(
type
,
sizeof
(
STableCountScanPhysiNode
));
case
QUERY_NODE_PHYSICAL_PLAN_PROJECT
:
return
makeNode
(
type
,
sizeof
(
SProjectPhysiNode
));
case
QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN
:
...
...
@@ -1120,6 +1122,7 @@ void nodesDestroyNode(SNode* pNode) {
case
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
:
destroyScanPhysiNode
((
SScanPhysiNode
*
)
pNode
);
break
;
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
{
...
...
source/libs/parser/inc/parUtil.h
浏览文件 @
30e124a5
...
...
@@ -86,7 +86,7 @@ STableComInfo getTableInfo(const STableMeta* pTableMeta);
STableMeta
*
tableMetaDup
(
const
STableMeta
*
pTableMeta
);
int32_t
trimString
(
const
char
*
src
,
int32_t
len
,
char
*
dst
,
int32_t
dlen
);
int32_t
get
InsTag
sTableTargetName
(
int32_t
acctId
,
SNode
*
pWhere
,
SName
*
pName
);
int32_t
get
VnodeSy
sTableTargetName
(
int32_t
acctId
,
SNode
*
pWhere
,
SName
*
pName
);
int32_t
buildCatalogReq
(
const
SParseMetaCache
*
pMetaCache
,
SCatalogReq
*
pCatalogReq
);
int32_t
putMetaDataToCache
(
const
SCatalogReq
*
pCatalogReq
,
const
SMetaData
*
pMetaData
,
SParseMetaCache
*
pMetaCache
);
...
...
source/libs/parser/src/parAstParser.c
浏览文件 @
30e124a5
...
...
@@ -140,7 +140,7 @@ static int32_t collectMetaKeyFromInsTagsImpl(SCollectMetaKeyCxt* pCxt, SName* pN
static
int32_t
collectMetaKeyFromInsTags
(
SCollectMetaKeyCxt
*
pCxt
)
{
SSelectStmt
*
pSelect
=
(
SSelectStmt
*
)
pCxt
->
pStmt
;
SName
name
=
{
0
};
int32_t
code
=
get
InsTag
sTableTargetName
(
pCxt
->
pParseCxt
->
acctId
,
pSelect
->
pWhere
,
&
name
);
int32_t
code
=
get
VnodeSy
sTableTargetName
(
pCxt
->
pParseCxt
->
acctId
,
pSelect
->
pWhere
,
&
name
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
collectMetaKeyFromInsTagsImpl
(
pCxt
,
&
name
);
}
...
...
@@ -165,7 +165,8 @@ static int32_t collectMetaKeyFromRealTableImpl(SCollectMetaKeyCxt* pCxt, const c
if
(
TSDB_CODE_SUCCESS
==
code
&&
(
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_DNODE_VARIABLES
)))
{
code
=
reserveDnodeRequiredInCache
(
pCxt
->
pMetaCache
);
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
(
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_TAGS
))
&&
if
(
TSDB_CODE_SUCCESS
==
code
&&
(
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_TAGS
)
||
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_TABLES
))
&&
QUERY_NODE_SELECT_STMT
==
nodeType
(
pCxt
->
pStmt
))
{
code
=
collectMetaKeyFromInsTags
(
pCxt
);
}
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
30e124a5
...
...
@@ -47,6 +47,7 @@ typedef struct STranslateContext {
SParseMetaCache
*
pMetaCache
;
bool
createStream
;
bool
stableQuery
;
bool
showRewrite
;
}
STranslateContext
;
typedef
struct
SFullDatabaseName
{
...
...
@@ -2209,22 +2210,28 @@ static int32_t dnodeToVgroupsInfo(SArray* pDnodes, SVgroupsInfo** pVgsInfo) {
}
static
bool
sysTableFromVnode
(
const
char
*
pTable
)
{
return
(
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_TABLES
))
||
(
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_TABLE_DISTRIBUTED
)
||
(
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_TAGS
)));
return
((
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_TABLES
))
||
(
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_TAGS
)));
}
static
bool
sysTableFromDnode
(
const
char
*
pTable
)
{
return
0
==
strcmp
(
pTable
,
TSDB_INS_TABLE_DNODE_VARIABLES
);
}
static
int32_t
get
Tag
sTableVgroupListImpl
(
STranslateContext
*
pCxt
,
SName
*
pTargetName
,
SName
*
pName
,
SArray
**
pVgroupList
)
{
static
int32_t
get
VnodeSy
sTableVgroupListImpl
(
STranslateContext
*
pCxt
,
SName
*
pTargetName
,
SName
*
pName
,
SArray
**
pVgroupList
)
{
if
(
0
==
pTargetName
->
type
)
{
return
getDBVgInfoImpl
(
pCxt
,
pName
,
pVgroupList
);
}
if
(
0
==
strcmp
(
pTargetName
->
dbname
,
TSDB_INFORMATION_SCHEMA_DB
)
||
0
==
strcmp
(
pTargetName
->
dbname
,
TSDB_PERFORMANCE_SCHEMA_DB
))
{
pTargetName
->
type
=
0
;
return
TSDB_CODE_SUCCESS
;
}
if
(
TSDB_DB_NAME_T
==
pTargetName
->
type
)
{
int32_t
code
=
getDBVgInfoImpl
(
pCxt
,
pTargetName
,
pVgroupList
);
if
(
TSDB_CODE_MND_DB_NOT_EXIST
==
code
||
TSDB_CODE_MND_DB_IN_CREATING
==
code
||
TSDB_CODE_MND_DB_IN_DROPPING
==
code
)
{
if
(
!
pCxt
->
showRewrite
&&
(
TSDB_CODE_MND_DB_NOT_EXIST
==
code
||
TSDB_CODE_MND_DB_IN_CREATING
==
code
||
TSDB_CODE_MND_DB_IN_DROPPING
==
code
))
{
// system table query should not report errors
code
=
TSDB_CODE_SUCCESS
;
}
return
code
;
...
...
@@ -2241,50 +2248,44 @@ static int32_t getTagsTableVgroupListImpl(STranslateContext* pCxt, SName* pTarge
}
}
else
if
(
TSDB_CODE_MND_DB_NOT_EXIST
==
code
||
TSDB_CODE_MND_DB_IN_CREATING
==
code
||
TSDB_CODE_MND_DB_IN_DROPPING
==
code
)
{
// system table query should not report errors
code
=
TSDB_CODE_SUCCESS
;
}
return
code
;
}
static
int32_t
get
TagsTableVgroupList
(
STranslateContext
*
pCxt
,
SName
*
pName
,
SArray
**
pVgroupList
)
{
static
int32_t
get
VnodeSysTableVgroupList
(
STranslateContext
*
pCxt
,
SName
*
pName
,
SArray
**
pVgs
,
bool
*
pHasUserDbCond
)
{
if
(
!
isSelectStmt
(
pCxt
->
pCurrStmt
))
{
return
TSDB_CODE_SUCCESS
;
}
SSelectStmt
*
pSelect
=
(
SSelectStmt
*
)
pCxt
->
pCurrStmt
;
SName
targetName
=
{
0
};
int32_t
code
=
get
InsTag
sTableTargetName
(
pCxt
->
pParseCxt
->
acctId
,
pSelect
->
pWhere
,
&
targetName
);
int32_t
code
=
get
VnodeSy
sTableTargetName
(
pCxt
->
pParseCxt
->
acctId
,
pSelect
->
pWhere
,
&
targetName
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
get
TagsTableVgroupListImpl
(
pCxt
,
&
targetName
,
pName
,
pVgroupList
);
code
=
get
VnodeSysTableVgroupListImpl
(
pCxt
,
&
targetName
,
pName
,
pVgs
);
}
*
pHasUserDbCond
=
(
0
!=
targetName
.
type
&&
taosArrayGetSize
(
*
pVgs
)
>
0
);
return
code
;
}
static
int32_t
setVnodeSysTableVgroupList
(
STranslateContext
*
pCxt
,
SName
*
pName
,
SRealTableNode
*
pRealTable
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
SArray
*
vgroupList
=
NULL
;
if
(
0
==
strcmp
(
pRealTable
->
table
.
tableName
,
TSDB_INS_TABLE_TAGS
))
{
code
=
getTagsTableVgroupList
(
pCxt
,
pName
,
&
vgroupList
);
}
else
if
(
'\0'
!=
pRealTable
->
qualDbName
[
0
])
{
if
(
0
!=
strcmp
(
pRealTable
->
qualDbName
,
TSDB_INFORMATION_SCHEMA_DB
))
{
code
=
getDBVgInfo
(
pCxt
,
pRealTable
->
qualDbName
,
&
vgroupList
);
}
}
else
{
code
=
getDBVgInfoImpl
(
pCxt
,
pName
,
&
vgroupList
);
}
bool
hasUserDbCond
=
false
;
SArray
*
pVgs
=
NULL
;
int32_t
code
=
getVnodeSysTableVgroupList
(
pCxt
,
pName
,
&
pVgs
,
&
hasUserDbCond
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
0
==
strcmp
(
pRealTable
->
table
.
tableName
,
TSDB_INS_TABLE_TAGS
)
&&
isSelectStmt
(
pCxt
->
pCurrStmt
)
&&
0
==
taosArrayGetSize
(
vgroupList
))
{
isSelectStmt
(
pCxt
->
pCurrStmt
)
&&
0
==
taosArrayGetSize
(
pVgs
))
{
((
SSelectStmt
*
)
pCxt
->
pCurrStmt
)
->
isEmptyResult
=
true
;
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
0
==
strcmp
(
pRealTable
->
table
.
tableName
,
TSDB_INS_TABLE_TABLES
))
{
code
=
addMnodeToVgroupList
(
&
pCxt
->
pParseCxt
->
mgmtEpSet
,
&
vgroupList
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
0
==
strcmp
(
pRealTable
->
table
.
tableName
,
TSDB_INS_TABLE_TABLES
)
&&
!
hasUserDbCond
)
{
code
=
addMnodeToVgroupList
(
&
pCxt
->
pParseCxt
->
mgmtEpSet
,
&
pVgs
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
toVgroupsInfo
(
vgroupList
,
&
pRealTable
->
pVgroupList
);
code
=
toVgroupsInfo
(
pVgs
,
&
pRealTable
->
pVgroupList
);
}
taosArrayDestroy
(
vgroupList
);
taosArrayDestroy
(
pVgs
);
return
code
;
}
...
...
@@ -2309,30 +2310,39 @@ static int32_t setSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRea
}
}
static
int32_t
setSuperTableVgroupList
(
STranslateContext
*
pCxt
,
SName
*
pName
,
SRealTableNode
*
pRealTable
)
{
SArray
*
vgroupList
=
NULL
;
int32_t
code
=
getDBVgInfoImpl
(
pCxt
,
pName
,
&
vgroupList
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
toVgroupsInfo
(
vgroupList
,
&
pRealTable
->
pVgroupList
);
}
taosArrayDestroy
(
vgroupList
);
return
code
;
}
static
int32_t
setNormalTableVgroupList
(
STranslateContext
*
pCxt
,
SName
*
pName
,
SRealTableNode
*
pRealTable
)
{
pRealTable
->
pVgroupList
=
taosMemoryCalloc
(
1
,
sizeof
(
SVgroupsInfo
)
+
sizeof
(
SVgroupInfo
));
if
(
NULL
==
pRealTable
->
pVgroupList
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
pRealTable
->
pVgroupList
->
numOfVgroups
=
1
;
return
getTableHashVgroupImpl
(
pCxt
,
pName
,
pRealTable
->
pVgroupList
->
vgroups
);
}
static
int32_t
setTableVgroupList
(
STranslateContext
*
pCxt
,
SName
*
pName
,
SRealTableNode
*
pRealTable
)
{
if
(
pCxt
->
pParseCxt
->
topicQuery
)
{
return
TSDB_CODE_SUCCESS
;
}
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
TSDB_SUPER_TABLE
==
pRealTable
->
pMeta
->
tableType
)
{
SArray
*
vgroupList
=
NULL
;
code
=
getDBVgInfoImpl
(
pCxt
,
pName
,
&
vgroupList
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
toVgroupsInfo
(
vgroupList
,
&
pRealTable
->
pVgroupList
);
}
taosArrayDestroy
(
vgroupList
);
}
else
if
(
TSDB_SYSTEM_TABLE
==
pRealTable
->
pMeta
->
tableType
)
{
code
=
setSysTableVgroupList
(
pCxt
,
pName
,
pRealTable
);
}
else
{
pRealTable
->
pVgroupList
=
taosMemoryCalloc
(
1
,
sizeof
(
SVgroupsInfo
)
+
sizeof
(
SVgroupInfo
));
if
(
NULL
==
pRealTable
->
pVgroupList
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
pRealTable
->
pVgroupList
->
numOfVgroups
=
1
;
code
=
getTableHashVgroupImpl
(
pCxt
,
pName
,
pRealTable
->
pVgroupList
->
vgroups
);
return
setSuperTableVgroupList
(
pCxt
,
pName
,
pRealTable
);
}
return
code
;
if
(
TSDB_SYSTEM_TABLE
==
pRealTable
->
pMeta
->
tableType
)
{
return
setSysTableVgroupList
(
pCxt
,
pName
,
pRealTable
);
}
return
setNormalTableVgroupList
(
pCxt
,
pName
,
pRealTable
);
}
static
uint8_t
getStmtPrecision
(
SNode
*
pStmt
)
{
...
...
@@ -2366,7 +2376,6 @@ static bool isSingleTable(SRealTableNode* pRealTable) {
int8_t
tableType
=
pRealTable
->
pMeta
->
tableType
;
if
(
TSDB_SYSTEM_TABLE
==
tableType
)
{
return
0
!=
strcmp
(
pRealTable
->
table
.
tableName
,
TSDB_INS_TABLE_TABLES
)
&&
0
!=
strcmp
(
pRealTable
->
table
.
tableName
,
TSDB_INS_TABLE_TABLE_DISTRIBUTED
)
&&
0
!=
strcmp
(
pRealTable
->
table
.
tableName
,
TSDB_INS_TABLE_TAGS
);
}
return
(
TSDB_CHILD_TABLE
==
tableType
||
TSDB_NORMAL_TABLE
==
tableType
);
...
...
@@ -6296,6 +6305,7 @@ static int32_t rewriteShow(STranslateContext* pCxt, SQuery* pQuery) {
code
=
createShowCondition
((
SShowStmt
*
)
pQuery
->
pRoot
,
pStmt
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
pCxt
->
showRewrite
=
true
;
pQuery
->
showRewrite
=
true
;
nodesDestroyNode
(
pQuery
->
pRoot
);
pQuery
->
pRoot
=
(
SNode
*
)
pStmt
;
...
...
@@ -6349,6 +6359,7 @@ static int32_t rewriteShowStableTags(STranslateContext* pCxt, SQuery* pQuery) {
code
=
createShowTableTagsProjections
(
&
pSelect
->
pProjectionList
,
&
pShow
->
pTags
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
pCxt
->
showRewrite
=
true
;
pQuery
->
showRewrite
=
true
;
pSelect
->
tagScan
=
true
;
nodesDestroyNode
(
pQuery
->
pRoot
);
...
...
@@ -6379,6 +6390,7 @@ static int32_t rewriteShowDnodeVariables(STranslateContext* pCxt, SQuery* pQuery
}
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
pCxt
->
showRewrite
=
true
;
pQuery
->
showRewrite
=
true
;
nodesDestroyNode
(
pQuery
->
pRoot
);
pQuery
->
pRoot
=
(
SNode
*
)
pSelect
;
...
...
@@ -6398,6 +6410,7 @@ static int32_t rewriteShowVnodes(STranslateContext* pCxt, SQuery* pQuery) {
}
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
pCxt
->
showRewrite
=
true
;
pQuery
->
showRewrite
=
true
;
nodesDestroyNode
(
pQuery
->
pRoot
);
pQuery
->
pRoot
=
(
SNode
*
)
pStmt
;
...
...
@@ -6439,6 +6452,7 @@ static int32_t rewriteShowTableDist(STranslateContext* pCxt, SQuery* pQuery) {
code
=
nodesListMakeStrictAppend
(
&
pStmt
->
pProjectionList
,
createBlockDistFunc
());
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
pCxt
->
showRewrite
=
true
;
pQuery
->
showRewrite
=
true
;
nodesDestroyNode
(
pQuery
->
pRoot
);
pQuery
->
pRoot
=
(
SNode
*
)
pStmt
;
...
...
source/libs/parser/src/parUtil.c
浏览文件 @
30e124a5
...
...
@@ -474,7 +474,7 @@ static int32_t getInsTagsTableTargetNameFromCond(int32_t acctId, SLogicCondition
return
TSDB_CODE_SUCCESS
;
}
int32_t
get
InsTag
sTableTargetName
(
int32_t
acctId
,
SNode
*
pWhere
,
SName
*
pName
)
{
int32_t
get
VnodeSy
sTableTargetName
(
int32_t
acctId
,
SNode
*
pWhere
,
SName
*
pName
)
{
if
(
NULL
==
pWhere
)
{
return
TSDB_CODE_SUCCESS
;
}
...
...
source/libs/parser/test/mockCatalog.cpp
浏览文件 @
30e124a5
...
...
@@ -65,9 +65,10 @@ void generateInformationSchema(MockCatalogService* mcs) {
.
addColumn
(
"db_name"
,
TSDB_DATA_TYPE_BINARY
,
TSDB_DB_NAME_LEN
)
.
addColumn
(
"stable_name"
,
TSDB_DATA_TYPE_BINARY
,
TSDB_TABLE_NAME_LEN
)
.
done
();
mcs
->
createTableBuilder
(
TSDB_INFORMATION_SCHEMA_DB
,
TSDB_INS_TABLE_TABLES
,
TSDB_SYSTEM_TABLE
,
2
)
.
addColumn
(
"db_name"
,
TSDB_DATA_TYPE_BINARY
,
TSDB_DB_NAME_LEN
)
mcs
->
createTableBuilder
(
TSDB_INFORMATION_SCHEMA_DB
,
TSDB_INS_TABLE_TABLES
,
TSDB_SYSTEM_TABLE
,
3
)
.
addColumn
(
"table_name"
,
TSDB_DATA_TYPE_BINARY
,
TSDB_TABLE_NAME_LEN
)
.
addColumn
(
"db_name"
,
TSDB_DATA_TYPE_BINARY
,
TSDB_DB_NAME_LEN
)
.
addColumn
(
"stable_name"
,
TSDB_DATA_TYPE_BINARY
,
TSDB_TABLE_NAME_LEN
)
.
done
();
mcs
->
createTableBuilder
(
TSDB_INFORMATION_SCHEMA_DB
,
TSDB_INS_TABLE_TABLE_DISTRIBUTED
,
TSDB_SYSTEM_TABLE
,
2
)
.
addColumn
(
"db_name"
,
TSDB_DATA_TYPE_BINARY
,
TSDB_DB_NAME_LEN
)
...
...
@@ -140,7 +141,7 @@ void generatePerformanceSchema(MockCatalogService* mcs) {
void
generateTestTables
(
MockCatalogService
*
mcs
,
const
std
::
string
&
db
)
{
mcs
->
createTableBuilder
(
db
,
"t1"
,
TSDB_NORMAL_TABLE
,
6
)
.
setPrecision
(
TSDB_TIME_PRECISION_MILLI
)
.
setVgid
(
1
)
.
setVgid
(
2
)
.
addColumn
(
"ts"
,
TSDB_DATA_TYPE_TIMESTAMP
)
.
addColumn
(
"c1"
,
TSDB_DATA_TYPE_INT
)
.
addColumn
(
"c2"
,
TSDB_DATA_TYPE_BINARY
,
20
)
...
...
@@ -182,9 +183,9 @@ void generateTestStables(MockCatalogService* mcs, const std::string& db) {
.
addTag
(
"tag2"
,
TSDB_DATA_TYPE_BINARY
,
20
)
.
addTag
(
"tag3"
,
TSDB_DATA_TYPE_TIMESTAMP
);
builder
.
done
();
mcs
->
createSubTable
(
db
,
"st1"
,
"st1s1"
,
1
);
mcs
->
createSubTable
(
db
,
"st1"
,
"st1s2"
,
2
);
mcs
->
createSubTable
(
db
,
"st1"
,
"st1s3"
,
1
);
mcs
->
createSubTable
(
db
,
"st1"
,
"st1s1"
,
2
);
mcs
->
createSubTable
(
db
,
"st1"
,
"st1s2"
,
3
);
mcs
->
createSubTable
(
db
,
"st1"
,
"st1s3"
,
2
);
}
{
ITableBuilder
&
builder
=
mcs
->
createTableBuilder
(
db
,
"st2"
,
TSDB_SUPER_TABLE
,
3
,
1
)
...
...
@@ -194,8 +195,8 @@ void generateTestStables(MockCatalogService* mcs, const std::string& db) {
.
addColumn
(
"c2"
,
TSDB_DATA_TYPE_BINARY
,
20
)
.
addTag
(
"jtag"
,
TSDB_DATA_TYPE_JSON
);
builder
.
done
();
mcs
->
createSubTable
(
db
,
"st2"
,
"st2s1"
,
1
);
mcs
->
createSubTable
(
db
,
"st2"
,
"st2s2"
,
2
);
mcs
->
createSubTable
(
db
,
"st2"
,
"st2s1"
,
2
);
mcs
->
createSubTable
(
db
,
"st2"
,
"st2s2"
,
3
);
}
}
...
...
source/libs/parser/test/mockCatalogService.cpp
浏览文件 @
30e124a5
...
...
@@ -20,15 +20,19 @@
#include <map>
#include <set>
#include "systable.h"
#include "tdatablock.h"
#include "tmisce.h"
#include "tname.h"
#include "ttypes.h"
#include "tmisce.h"
using
std
::
string
;
std
::
unique_ptr
<
MockCatalogService
>
g_mockCatalogService
;
class
TableBuilder
:
public
ITableBuilder
{
public:
virtual
TableBuilder
&
addColumn
(
const
st
d
::
st
ring
&
name
,
int8_t
type
,
int32_t
bytes
)
{
virtual
TableBuilder
&
addColumn
(
const
string
&
name
,
int8_t
type
,
int32_t
bytes
)
{
assert
(
colId_
<=
schema
()
->
tableInfo
.
numOfTags
+
schema
()
->
tableInfo
.
numOfColumns
);
SSchema
*
col
=
schema
()
->
schema
+
(
colId_
-
1
);
col
->
type
=
type
;
...
...
@@ -142,27 +146,16 @@ class MockCatalogServiceImpl {
}
int32_t
catalogGetDBVgList
(
const
char
*
pDbFName
,
SArray
**
pVgList
)
const
{
std
::
string
dbFName
(
pDbFName
);
DbMetaCache
::
const_iterator
it
=
meta_
.
find
(
dbFName
.
substr
(
std
::
string
(
pDbFName
).
find_last_of
(
'.'
)
+
1
));
if
(
meta_
.
end
()
==
it
)
{
return
TSDB_CODE_FAILED
;
}
std
::
set
<
int32_t
>
vgSet
;
*
pVgList
=
taosArrayInit
(
it
->
second
.
size
(),
sizeof
(
SVgroupInfo
));
for
(
const
auto
&
vgs
:
it
->
second
)
{
for
(
const
auto
&
vg
:
vgs
.
second
->
vgs
)
{
if
(
0
==
vgSet
.
count
(
vg
.
vgId
))
{
taosArrayPush
(
*
pVgList
,
&
vg
);
vgSet
.
insert
(
vg
.
vgId
);
}
}
string
dbName
(
string
(
pDbFName
).
substr
(
string
(
pDbFName
).
find_last_of
(
'.'
)
+
1
));
if
(
0
==
dbName
.
compare
(
TSDB_INFORMATION_SCHEMA_DB
)
||
0
==
dbName
.
compare
(
TSDB_PERFORMANCE_SCHEMA_DB
))
{
return
catalogGetAllDBVgList
(
pVgList
);
}
return
TSDB_CODE_SUCCESS
;
return
catalogGetDBVgListImpl
(
dbName
,
pVgList
)
;
}
int32_t
catalogGetDBCfg
(
const
char
*
pDbFName
,
SDbCfgInfo
*
pDbCfg
)
const
{
st
d
::
string
dbFName
(
pDbFName
);
DbCfgCache
::
const_iterator
it
=
dbCfg_
.
find
(
dbFName
.
substr
(
st
d
::
st
ring
(
pDbFName
).
find_last_of
(
'.'
)
+
1
));
st
ring
dbFName
(
pDbFName
);
DbCfgCache
::
const_iterator
it
=
dbCfg_
.
find
(
dbFName
.
substr
(
string
(
pDbFName
).
find_last_of
(
'.'
)
+
1
));
if
(
dbCfg_
.
end
()
==
it
)
{
return
TSDB_CODE_FAILED
;
}
...
...
@@ -171,7 +164,7 @@ class MockCatalogServiceImpl {
return
TSDB_CODE_SUCCESS
;
}
int32_t
catalogGetUdfInfo
(
const
st
d
::
st
ring
&
funcName
,
SFuncInfo
*
pInfo
)
const
{
int32_t
catalogGetUdfInfo
(
const
string
&
funcName
,
SFuncInfo
*
pInfo
)
const
{
auto
it
=
udf_
.
find
(
funcName
);
if
(
udf_
.
end
()
==
it
)
{
return
TSDB_CODE_FAILED
;
...
...
@@ -236,15 +229,15 @@ class MockCatalogServiceImpl {
return
code
;
}
TableBuilder
&
createTableBuilder
(
const
st
d
::
string
&
db
,
const
std
::
string
&
tbname
,
int8_t
tableType
,
int32_t
numOf
Columns
,
int32_t
numOf
Tags
)
{
TableBuilder
&
createTableBuilder
(
const
st
ring
&
db
,
const
string
&
tbname
,
int8_t
tableType
,
int32_t
numOfColumns
,
int32_t
numOfTags
)
{
builder_
=
TableBuilder
::
createTableBuilder
(
tableType
,
numOfColumns
,
numOfTags
);
meta_
[
db
][
tbname
]
=
builder_
->
table
();
meta_
[
db
][
tbname
]
->
schema
->
uid
=
getNextId
();
return
*
(
builder_
.
get
());
}
void
createSubTable
(
const
st
d
::
string
&
db
,
const
std
::
string
&
stbname
,
const
std
::
string
&
tbname
,
int16_t
vgid
)
{
void
createSubTable
(
const
st
ring
&
db
,
const
string
&
stbname
,
const
string
&
tbname
,
int16_t
vgid
)
{
std
::
unique_ptr
<
STableMeta
>
table
;
if
(
TSDB_CODE_SUCCESS
!=
copyTableSchemaMeta
(
db
,
stbname
,
&
table
))
{
throw
std
::
runtime_error
(
"copyTableSchemaMeta failed"
);
...
...
@@ -274,13 +267,13 @@ class MockCatalogServiceImpl {
// string field length
#define SFL 20
// string field header
#define SH(h) CA(SFL, st
d::st
ring(h))
#define SH(h) CA(SFL, string(h))
// string field
#define SF(n) CA(SFL, n)
// integer field length
#define IFL 10
// integer field header
#define IH(i) CA(IFL, st
d::st
ring(i))
#define IH(i) CA(IFL, string(i))
// integer field
#define IF(i) CA(IFL, std::to_string(i))
// split line
...
...
@@ -308,7 +301,7 @@ class MockCatalogServiceImpl {
int16_t
numOfFields
=
numOfColumns
+
schema
->
tableInfo
.
numOfTags
;
for
(
int16_t
i
=
0
;
i
<
numOfFields
;
++
i
)
{
const
SSchema
*
col
=
schema
->
schema
+
i
;
std
::
cout
<<
SF
(
st
d
::
st
ring
(
col
->
name
))
<<
SH
(
ftToString
(
i
,
numOfColumns
))
<<
SH
(
dtToString
(
col
->
type
))
std
::
cout
<<
SF
(
string
(
col
->
name
))
<<
SH
(
ftToString
(
i
,
numOfColumns
))
<<
SH
(
dtToString
(
col
->
type
))
<<
IF
(
col
->
bytes
)
<<
std
::
endl
;
}
std
::
cout
<<
std
::
endl
;
...
...
@@ -316,7 +309,7 @@ class MockCatalogServiceImpl {
}
}
void
createFunction
(
const
st
d
::
st
ring
&
func
,
int8_t
funcType
,
int8_t
outputType
,
int32_t
outputLen
,
int32_t
bufSize
)
{
void
createFunction
(
const
string
&
func
,
int8_t
funcType
,
int8_t
outputType
,
int32_t
outputLen
,
int32_t
bufSize
)
{
std
::
shared_ptr
<
SFuncInfo
>
info
(
new
SFuncInfo
);
strcpy
(
info
->
name
,
func
.
c_str
());
info
->
funcType
=
funcType
;
...
...
@@ -342,19 +335,19 @@ class MockCatalogServiceImpl {
info
.
expr
=
strdup
(
pReq
->
expr
);
auto
it
=
index_
.
find
(
pReq
->
stb
);
if
(
index_
.
end
()
==
it
)
{
index_
.
insert
(
std
::
make_pair
(
st
d
::
st
ring
(
pReq
->
stb
),
std
::
vector
<
STableIndexInfo
>
{
info
}));
index_
.
insert
(
std
::
make_pair
(
string
(
pReq
->
stb
),
std
::
vector
<
STableIndexInfo
>
{
info
}));
}
else
{
it
->
second
.
push_back
(
info
);
}
}
void
createDnode
(
int32_t
dnodeId
,
const
st
d
::
st
ring
&
host
,
int16_t
port
)
{
void
createDnode
(
int32_t
dnodeId
,
const
string
&
host
,
int16_t
port
)
{
SEpSet
epSet
=
{
0
};
addEpIntoEpSet
(
&
epSet
,
host
.
c_str
(),
port
);
dnode_
.
insert
(
std
::
make_pair
(
dnodeId
,
epSet
));
}
void
createDatabase
(
const
st
d
::
st
ring
&
db
,
bool
rollup
,
int8_t
cacheLast
)
{
void
createDatabase
(
const
string
&
db
,
bool
rollup
,
int8_t
cacheLast
)
{
SDbCfgInfo
cfg
=
{
0
};
if
(
rollup
)
{
cfg
.
pRetensions
=
taosArrayInit
(
TARRAY_MIN_SIZE
,
sizeof
(
SRetention
));
...
...
@@ -364,12 +357,12 @@ class MockCatalogServiceImpl {
}
private:
typedef
std
::
map
<
st
d
::
st
ring
,
std
::
shared_ptr
<
MockTableMeta
>>
TableMetaCache
;
typedef
std
::
map
<
st
d
::
st
ring
,
TableMetaCache
>
DbMetaCache
;
typedef
std
::
map
<
st
d
::
st
ring
,
std
::
shared_ptr
<
SFuncInfo
>>
UdfMetaCache
;
typedef
std
::
map
<
st
d
::
st
ring
,
std
::
vector
<
STableIndexInfo
>>
IndexMetaCache
;
typedef
std
::
map
<
int32_t
,
SEpSet
>
DnodeCache
;
typedef
std
::
map
<
st
d
::
st
ring
,
SDbCfgInfo
>
DbCfgCache
;
typedef
std
::
map
<
string
,
std
::
shared_ptr
<
MockTableMeta
>>
TableMetaCache
;
typedef
std
::
map
<
string
,
TableMetaCache
>
DbMetaCache
;
typedef
std
::
map
<
string
,
std
::
shared_ptr
<
SFuncInfo
>>
UdfMetaCache
;
typedef
std
::
map
<
string
,
std
::
vector
<
STableIndexInfo
>>
IndexMetaCache
;
typedef
std
::
map
<
int32_t
,
SEpSet
>
DnodeCache
;
typedef
std
::
map
<
string
,
SDbCfgInfo
>
DbCfgCache
;
uint64_t
getNextId
()
{
return
id_
++
;
}
...
...
@@ -386,15 +379,15 @@ class MockCatalogServiceImpl {
return
pDst
;
}
st
d
::
string
toDbname
(
const
std
::
string
&
dbFullName
)
const
{
st
d
::
st
ring
::
size_type
n
=
dbFullName
.
find
(
"."
);
if
(
n
==
st
d
::
st
ring
::
npos
)
{
st
ring
toDbname
(
const
string
&
dbFullName
)
const
{
string
::
size_type
n
=
dbFullName
.
find
(
"."
);
if
(
n
==
string
::
npos
)
{
return
dbFullName
;
}
return
dbFullName
.
substr
(
n
+
1
);
}
st
d
::
st
ring
ttToString
(
int8_t
tableType
)
const
{
string
ttToString
(
int8_t
tableType
)
const
{
switch
(
tableType
)
{
case
TSDB_SUPER_TABLE
:
return
"super table"
;
...
...
@@ -407,7 +400,7 @@ class MockCatalogServiceImpl {
}
}
st
d
::
st
ring
pToString
(
uint8_t
precision
)
const
{
string
pToString
(
uint8_t
precision
)
const
{
switch
(
precision
)
{
case
TSDB_TIME_PRECISION_MILLI
:
return
"millisecond"
;
...
...
@@ -420,19 +413,18 @@ class MockCatalogServiceImpl {
}
}
st
d
::
st
ring
dtToString
(
int8_t
type
)
const
{
return
tDataTypes
[
type
].
name
;
}
string
dtToString
(
int8_t
type
)
const
{
return
tDataTypes
[
type
].
name
;
}
st
d
::
st
ring
ftToString
(
int16_t
colid
,
int16_t
numOfColumns
)
const
{
string
ftToString
(
int16_t
colid
,
int16_t
numOfColumns
)
const
{
return
(
0
==
colid
?
"column"
:
(
colid
<
numOfColumns
?
"column"
:
"tag"
));
}
STableMeta
*
getTableSchemaMeta
(
const
st
d
::
string
&
db
,
const
std
::
string
&
tbname
)
const
{
STableMeta
*
getTableSchemaMeta
(
const
st
ring
&
db
,
const
string
&
tbname
)
const
{
std
::
shared_ptr
<
MockTableMeta
>
table
=
getTableMeta
(
db
,
tbname
);
return
table
?
table
->
schema
:
nullptr
;
}
int32_t
copyTableSchemaMeta
(
const
std
::
string
&
db
,
const
std
::
string
&
tbname
,
std
::
unique_ptr
<
STableMeta
>*
dst
)
const
{
int32_t
copyTableSchemaMeta
(
const
string
&
db
,
const
string
&
tbname
,
std
::
unique_ptr
<
STableMeta
>*
dst
)
const
{
STableMeta
*
src
=
getTableSchemaMeta
(
db
,
tbname
);
if
(
nullptr
==
src
)
{
return
TSDB_CODE_TSC_INVALID_TABLE_NAME
;
...
...
@@ -446,7 +438,7 @@ class MockCatalogServiceImpl {
return
TSDB_CODE_SUCCESS
;
}
int32_t
copyTableVgroup
(
const
st
d
::
string
&
db
,
const
std
::
string
&
tbname
,
SVgroupInfo
*
vg
)
const
{
int32_t
copyTableVgroup
(
const
st
ring
&
db
,
const
string
&
tbname
,
SVgroupInfo
*
vg
)
const
{
std
::
shared_ptr
<
MockTableMeta
>
table
=
getTableMeta
(
db
,
tbname
);
if
(
table
->
vgs
.
empty
())
{
return
TSDB_CODE_SUCCESS
;
...
...
@@ -455,7 +447,7 @@ class MockCatalogServiceImpl {
return
TSDB_CODE_SUCCESS
;
}
int32_t
copyTableVgroup
(
const
st
d
::
string
&
db
,
const
std
::
string
&
tbname
,
SArray
**
vgList
)
const
{
int32_t
copyTableVgroup
(
const
st
ring
&
db
,
const
string
&
tbname
,
SArray
**
vgList
)
const
{
std
::
shared_ptr
<
MockTableMeta
>
table
=
getTableMeta
(
db
,
tbname
);
if
(
table
->
vgs
.
empty
())
{
return
TSDB_CODE_SUCCESS
;
...
...
@@ -467,7 +459,7 @@ class MockCatalogServiceImpl {
return
TSDB_CODE_SUCCESS
;
}
std
::
shared_ptr
<
MockTableMeta
>
getTableMeta
(
const
st
d
::
string
&
db
,
const
std
::
string
&
tbname
)
const
{
std
::
shared_ptr
<
MockTableMeta
>
getTableMeta
(
const
st
ring
&
db
,
const
string
&
tbname
)
const
{
DbMetaCache
::
const_iterator
it
=
meta_
.
find
(
db
);
if
(
meta_
.
end
()
==
it
)
{
return
std
::
shared_ptr
<
MockTableMeta
>
();
...
...
@@ -527,6 +519,40 @@ class MockCatalogServiceImpl {
return
code
;
}
int32_t
catalogGetDBVgListImpl
(
const
string
&
dbName
,
SArray
**
pVgList
)
const
{
DbMetaCache
::
const_iterator
it
=
meta_
.
find
(
dbName
);
if
(
meta_
.
end
()
==
it
)
{
return
TSDB_CODE_FAILED
;
}
std
::
set
<
int32_t
>
vgSet
;
*
pVgList
=
taosArrayInit
(
it
->
second
.
size
(),
sizeof
(
SVgroupInfo
));
for
(
const
auto
&
vgs
:
it
->
second
)
{
for
(
const
auto
&
vg
:
vgs
.
second
->
vgs
)
{
if
(
0
==
vgSet
.
count
(
vg
.
vgId
))
{
taosArrayPush
(
*
pVgList
,
&
vg
);
vgSet
.
insert
(
vg
.
vgId
);
}
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
catalogGetAllDBVgList
(
SArray
**
pVgList
)
const
{
std
::
set
<
int32_t
>
vgSet
;
*
pVgList
=
taosArrayInit
(
TARRAY_MIN_SIZE
,
sizeof
(
SVgroupInfo
));
for
(
const
auto
&
db
:
meta_
)
{
for
(
const
auto
&
vgs
:
db
.
second
)
{
for
(
const
auto
&
vg
:
vgs
.
second
->
vgs
)
{
if
(
0
==
vgSet
.
count
(
vg
.
vgId
))
{
taosArrayPush
(
*
pVgList
,
&
vg
);
vgSet
.
insert
(
vg
.
vgId
);
}
}
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
getAllDbCfg
(
SArray
*
pDbCfgReq
,
SArray
**
pDbCfgData
)
const
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
NULL
!=
pDbCfgReq
)
{
...
...
@@ -634,30 +660,29 @@ MockCatalogService::MockCatalogService() : impl_(new MockCatalogServiceImpl()) {
MockCatalogService
::~
MockCatalogService
()
{}
ITableBuilder
&
MockCatalogService
::
createTableBuilder
(
const
st
d
::
string
&
db
,
const
std
::
string
&
tbnam
e
,
int
8_t
tableType
,
int
32_t
numOfColumns
,
int32_t
numOfTags
)
{
ITableBuilder
&
MockCatalogService
::
createTableBuilder
(
const
st
ring
&
db
,
const
string
&
tbname
,
int8_t
tableTyp
e
,
int32_t
numOfColumns
,
int32_t
numOfTags
)
{
return
impl_
->
createTableBuilder
(
db
,
tbname
,
tableType
,
numOfColumns
,
numOfTags
);
}
void
MockCatalogService
::
createSubTable
(
const
std
::
string
&
db
,
const
std
::
string
&
stbname
,
const
std
::
string
&
tbname
,
int16_t
vgid
)
{
void
MockCatalogService
::
createSubTable
(
const
string
&
db
,
const
string
&
stbname
,
const
string
&
tbname
,
int16_t
vgid
)
{
impl_
->
createSubTable
(
db
,
stbname
,
tbname
,
vgid
);
}
void
MockCatalogService
::
showTables
()
const
{
impl_
->
showTables
();
}
void
MockCatalogService
::
createFunction
(
const
st
d
::
st
ring
&
func
,
int8_t
funcType
,
int8_t
outputType
,
int32_t
outputLen
,
void
MockCatalogService
::
createFunction
(
const
string
&
func
,
int8_t
funcType
,
int8_t
outputType
,
int32_t
outputLen
,
int32_t
bufSize
)
{
impl_
->
createFunction
(
func
,
funcType
,
outputType
,
outputLen
,
bufSize
);
}
void
MockCatalogService
::
createSmaIndex
(
const
SMCreateSmaReq
*
pReq
)
{
impl_
->
createSmaIndex
(
pReq
);
}
void
MockCatalogService
::
createDnode
(
int32_t
dnodeId
,
const
st
d
::
st
ring
&
host
,
int16_t
port
)
{
void
MockCatalogService
::
createDnode
(
int32_t
dnodeId
,
const
string
&
host
,
int16_t
port
)
{
impl_
->
createDnode
(
dnodeId
,
host
,
port
);
}
void
MockCatalogService
::
createDatabase
(
const
st
d
::
st
ring
&
db
,
bool
rollup
,
int8_t
cacheLast
)
{
void
MockCatalogService
::
createDatabase
(
const
string
&
db
,
bool
rollup
,
int8_t
cacheLast
)
{
impl_
->
createDatabase
(
db
,
rollup
,
cacheLast
);
}
...
...
@@ -683,7 +708,7 @@ int32_t MockCatalogService::catalogGetDBCfg(const char* pDbFName, SDbCfgInfo* pD
return
impl_
->
catalogGetDBCfg
(
pDbFName
,
pDbCfg
);
}
int32_t
MockCatalogService
::
catalogGetUdfInfo
(
const
st
d
::
st
ring
&
funcName
,
SFuncInfo
*
pInfo
)
const
{
int32_t
MockCatalogService
::
catalogGetUdfInfo
(
const
string
&
funcName
,
SFuncInfo
*
pInfo
)
const
{
return
impl_
->
catalogGetUdfInfo
(
funcName
,
pInfo
);
}
...
...
source/libs/planner/src/planLogicCreater.c
浏览文件 @
30e124a5
...
...
@@ -250,11 +250,12 @@ static EScanType getScanType(SLogicPlanContext* pCxt, SNodeList* pScanPseudoCols
}
if
(
NULL
==
pScanCols
)
{
return
NULL
==
pScanPseudoCols
?
SCAN_TYPE_TABLE
:
((
FUNCTION_TYPE_BLOCK_DIST_INFO
==
((
SFunctionNode
*
)
nodesListGetNode
(
pScanPseudoCols
,
0
))
->
funcType
)
?
SCAN_TYPE_BLOCK_INFO
:
SCAN_TYPE_TABLE
);
if
(
NULL
==
pScanPseudoCols
)
{
return
SCAN_TYPE_TABLE
;
}
return
FUNCTION_TYPE_BLOCK_DIST_INFO
==
((
SFunctionNode
*
)
nodesListGetNode
(
pScanPseudoCols
,
0
))
->
funcType
?
SCAN_TYPE_BLOCK_INFO
:
SCAN_TYPE_TABLE
;
}
return
SCAN_TYPE_TABLE
;
...
...
@@ -333,6 +334,8 @@ static int32_t makeScanLogicNode(SLogicPlanContext* pCxt, SRealTableNode* pRealT
return
TSDB_CODE_SUCCESS
;
}
static
bool
needScanDefaultCol
(
EScanType
scanType
)
{
return
SCAN_TYPE_TABLE_COUNT
!=
scanType
;
}
static
int32_t
createScanLogicNode
(
SLogicPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
SRealTableNode
*
pRealTable
,
SLogicNode
**
pLogicNode
)
{
SScanLogicNode
*
pScan
=
NULL
;
...
...
@@ -367,7 +370,7 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
pScan
->
hasNormalCols
=
true
;
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
TSDB_CODE_SUCCESS
==
code
&&
needScanDefaultCol
(
pScan
->
scanType
)
)
{
code
=
addDefaultScanCol
(
pRealTable
->
pMeta
,
&
pScan
->
pScanCols
);
}
...
...
source/libs/planner/src/planOptimizer.c
浏览文件 @
30e124a5
...
...
@@ -16,6 +16,7 @@
#include "filter.h"
#include "functionMgt.h"
#include "planInt.h"
#include "systable.h"
#include "tglobal.h"
#include "ttime.h"
...
...
@@ -64,6 +65,7 @@ typedef enum ECondAction {
}
ECondAction
;
typedef
bool
(
*
FMayBeOptimized
)(
SLogicNode
*
pNode
);
typedef
bool
(
*
FShouldBeOptimized
)(
SLogicNode
*
pNode
,
void
*
pInfo
);
static
SLogicNode
*
optFindPossibleNode
(
SLogicNode
*
pNode
,
FMayBeOptimized
func
)
{
if
(
func
(
pNode
))
{
...
...
@@ -79,6 +81,19 @@ static SLogicNode* optFindPossibleNode(SLogicNode* pNode, FMayBeOptimized func)
return
NULL
;
}
static
bool
optFindEligibleNode
(
SLogicNode
*
pNode
,
FShouldBeOptimized
func
,
void
*
pInfo
)
{
if
(
func
(
pNode
,
pInfo
))
{
return
true
;
}
SNode
*
pChild
;
FOREACH
(
pChild
,
pNode
->
pChildren
)
{
if
(
optFindEligibleNode
((
SLogicNode
*
)
pChild
,
func
,
pInfo
))
{
return
true
;
}
}
return
false
;
}
static
void
optResetParent
(
SLogicNode
*
pNode
)
{
SNode
*
pChild
=
NULL
;
FOREACH
(
pChild
,
pNode
->
pChildren
)
{
((
SLogicNode
*
)
pChild
)
->
pParent
=
pNode
;
}
...
...
@@ -2454,6 +2469,243 @@ static int32_t pushDownLimitOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLog
return
TSDB_CODE_SUCCESS
;
}
typedef
struct
STbCntScanOptInfo
{
SAggLogicNode
*
pAgg
;
SScanLogicNode
*
pScan
;
SName
table
;
}
STbCntScanOptInfo
;
static
bool
tbCntScanOptIsEligibleGroupKeys
(
SNodeList
*
pGroupKeys
)
{
if
(
NULL
==
pGroupKeys
)
{
return
true
;
}
SNode
*
pGroupKey
=
NULL
;
FOREACH
(
pGroupKey
,
pGroupKeys
)
{
SNode
*
pKey
=
nodesListGetNode
(((
SGroupingSetNode
*
)
pGroupKey
)
->
pParameterList
,
0
);
if
(
QUERY_NODE_COLUMN
!=
nodeType
(
pKey
))
{
return
false
;
}
SColumnNode
*
pCol
=
(
SColumnNode
*
)
pKey
;
if
(
0
!=
strcmp
(
pCol
->
colName
,
"db_name"
)
&&
0
!=
strcmp
(
pCol
->
colName
,
"stable_name"
))
{
return
false
;
}
}
return
true
;
}
static
bool
tbCntScanOptNotNullableExpr
(
SNode
*
pNode
)
{
if
(
QUERY_NODE_COLUMN
!=
nodeType
(
pNode
))
{
return
false
;
}
const
char
*
pColName
=
((
SColumnNode
*
)
pNode
)
->
colName
;
return
0
==
strcmp
(
pColName
,
"*"
)
||
0
==
strcmp
(
pColName
,
"db_name"
)
||
0
==
strcmp
(
pColName
,
"stable_name"
)
||
0
==
strcmp
(
pColName
,
"table_name"
);
}
static
bool
tbCntScanOptIsEligibleAggFuncs
(
SNodeList
*
pAggFuncs
)
{
SNode
*
pNode
=
NULL
;
FOREACH
(
pNode
,
pAggFuncs
)
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
nodesListGetNode
(
pAggFuncs
,
0
);
if
(
FUNCTION_TYPE_COUNT
!=
pFunc
->
funcType
||
!
tbCntScanOptNotNullableExpr
(
nodesListGetNode
(
pFunc
->
pParameterList
,
0
)))
{
return
false
;
}
}
return
true
;
}
static
bool
tbCntScanOptIsEligibleAgg
(
SAggLogicNode
*
pAgg
)
{
return
tbCntScanOptIsEligibleGroupKeys
(
pAgg
->
pGroupKeys
)
&&
tbCntScanOptIsEligibleAggFuncs
(
pAgg
->
pAggFuncs
);
}
static
bool
tbCntScanOptGetColValFromCond
(
SOperatorNode
*
pOper
,
SColumnNode
**
pCol
,
SValueNode
**
pVal
)
{
if
(
OP_TYPE_EQUAL
!=
pOper
->
opType
)
{
return
false
;
}
*
pCol
=
NULL
;
*
pVal
=
NULL
;
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pOper
->
pLeft
))
{
*
pCol
=
(
SColumnNode
*
)
pOper
->
pLeft
;
}
else
if
(
QUERY_NODE_VALUE
==
nodeType
(
pOper
->
pLeft
))
{
*
pVal
=
(
SValueNode
*
)
pOper
->
pLeft
;
}
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pOper
->
pRight
))
{
*
pCol
=
(
SColumnNode
*
)
pOper
->
pRight
;
}
else
if
(
QUERY_NODE_VALUE
==
nodeType
(
pOper
->
pRight
))
{
*
pVal
=
(
SValueNode
*
)
pOper
->
pRight
;
}
return
NULL
!=
*
pCol
&&
NULL
!=
*
pVal
;
}
static
bool
tbCntScanOptIsEligibleLogicCond
(
STbCntScanOptInfo
*
pInfo
,
SLogicConditionNode
*
pCond
)
{
if
(
LOGIC_COND_TYPE_AND
!=
pCond
->
condType
)
{
return
false
;
}
bool
hasDbCond
=
false
;
bool
hasStbCond
=
false
;
SColumnNode
*
pCol
=
NULL
;
SValueNode
*
pVal
=
NULL
;
SNode
*
pNode
=
NULL
;
FOREACH
(
pNode
,
pCond
->
pParameterList
)
{
if
(
QUERY_NODE_OPERATOR
!=
nodeType
(
pNode
)
||
!
tbCntScanOptGetColValFromCond
((
SOperatorNode
*
)
pNode
,
&
pCol
,
&
pVal
))
{
return
false
;
}
if
(
!
hasDbCond
&&
0
==
strcmp
(
pCol
->
colName
,
"db_name"
))
{
hasDbCond
=
true
;
strcpy
(
pInfo
->
table
.
dbname
,
pVal
->
literal
);
}
else
if
(
!
hasStbCond
&&
0
==
strcmp
(
pCol
->
colName
,
"stable_name"
))
{
hasStbCond
=
true
;
strcpy
(
pInfo
->
table
.
tname
,
pVal
->
literal
);
}
else
{
return
false
;
}
}
return
hasDbCond
;
}
static
bool
tbCntScanOptIsEligibleOpCond
(
SOperatorNode
*
pCond
)
{
SColumnNode
*
pCol
=
NULL
;
SValueNode
*
pVal
=
NULL
;
if
(
!
tbCntScanOptGetColValFromCond
(
pCond
,
&
pCol
,
&
pVal
))
{
return
false
;
}
return
0
==
strcmp
(
pCol
->
colName
,
"db_name"
);
}
static
bool
tbCntScanOptIsEligibleConds
(
STbCntScanOptInfo
*
pInfo
,
SNode
*
pConditions
)
{
if
(
NULL
==
pConditions
)
{
return
true
;
}
if
(
QUERY_NODE_LOGIC_CONDITION
==
nodeType
(
pConditions
))
{
return
tbCntScanOptIsEligibleLogicCond
(
pInfo
,
(
SLogicConditionNode
*
)
pConditions
);
}
if
(
QUERY_NODE_OPERATOR
==
nodeType
(
pConditions
))
{
return
tbCntScanOptIsEligibleOpCond
((
SOperatorNode
*
)
pConditions
);
}
return
false
;
}
static
bool
tbCntScanOptIsEligibleScan
(
STbCntScanOptInfo
*
pInfo
)
{
if
(
0
!=
strcmp
(
pInfo
->
pScan
->
tableName
.
dbname
,
TSDB_INFORMATION_SCHEMA_DB
)
||
0
!=
strcmp
(
pInfo
->
pScan
->
tableName
.
tname
,
TSDB_INS_TABLE_TABLES
)
||
NULL
!=
pInfo
->
pScan
->
pGroupTags
)
{
return
false
;
}
if
(
1
==
pInfo
->
pScan
->
pVgroupList
->
numOfVgroups
&&
MNODE_HANDLE
==
pInfo
->
pScan
->
pVgroupList
->
vgroups
[
0
].
vgId
)
{
return
false
;
}
return
tbCntScanOptIsEligibleConds
(
pInfo
,
pInfo
->
pScan
->
node
.
pConditions
);
}
static
bool
tbCntScanOptShouldBeOptimized
(
SLogicNode
*
pNode
,
STbCntScanOptInfo
*
pInfo
)
{
if
(
QUERY_NODE_LOGIC_PLAN_AGG
!=
nodeType
(
pNode
)
||
1
!=
LIST_LENGTH
(
pNode
->
pChildren
)
||
QUERY_NODE_LOGIC_PLAN_SCAN
!=
nodeType
(
nodesListGetNode
(
pNode
->
pChildren
,
0
)))
{
return
false
;
}
pInfo
->
pAgg
=
(
SAggLogicNode
*
)
pNode
;
pInfo
->
pScan
=
(
SScanLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
);
return
tbCntScanOptIsEligibleAgg
(
pInfo
->
pAgg
)
&&
tbCntScanOptIsEligibleScan
(
pInfo
);
}
static
SNode
*
tbCntScanOptCreateTableCountFunc
()
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pFunc
)
{
return
NULL
;
}
strcpy
(
pFunc
->
functionName
,
"_table_count"
);
strcpy
(
pFunc
->
node
.
aliasName
,
"_table_count"
);
if
(
TSDB_CODE_SUCCESS
!=
fmGetFuncInfo
(
pFunc
,
NULL
,
0
))
{
nodesDestroyNode
((
SNode
*
)
pFunc
);
return
NULL
;
}
return
(
SNode
*
)
pFunc
;
}
static
int32_t
tbCntScanOptRewriteScan
(
STbCntScanOptInfo
*
pInfo
)
{
pInfo
->
pScan
->
scanType
=
SCAN_TYPE_TABLE_COUNT
;
strcpy
(
pInfo
->
pScan
->
tableName
.
dbname
,
pInfo
->
table
.
dbname
);
strcpy
(
pInfo
->
pScan
->
tableName
.
tname
,
pInfo
->
table
.
tname
);
NODES_DESTORY_LIST
(
pInfo
->
pScan
->
node
.
pTargets
);
NODES_DESTORY_LIST
(
pInfo
->
pScan
->
pScanCols
);
NODES_DESTORY_NODE
(
pInfo
->
pScan
->
node
.
pConditions
);
NODES_DESTORY_LIST
(
pInfo
->
pScan
->
pScanPseudoCols
);
int32_t
code
=
nodesListMakeStrictAppend
(
&
pInfo
->
pScan
->
pScanPseudoCols
,
tbCntScanOptCreateTableCountFunc
());
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
createColumnByRewriteExpr
(
nodesListGetNode
(
pInfo
->
pScan
->
pScanPseudoCols
,
0
),
&
pInfo
->
pScan
->
node
.
pTargets
);
}
SNode
*
pGroupKey
=
NULL
;
FOREACH
(
pGroupKey
,
pInfo
->
pAgg
->
pGroupKeys
)
{
SNode
*
pGroupCol
=
nodesListGetNode
(((
SGroupingSetNode
*
)
pGroupKey
)
->
pParameterList
,
0
);
code
=
nodesListMakeStrictAppend
(
&
pInfo
->
pScan
->
pGroupTags
,
nodesCloneNode
(
pGroupCol
));
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesListMakeStrictAppend
(
&
pInfo
->
pScan
->
pScanCols
,
nodesCloneNode
(
pGroupCol
));
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesListMakeStrictAppend
(
&
pInfo
->
pScan
->
node
.
pTargets
,
nodesCloneNode
(
pGroupCol
));
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
}
return
code
;
}
static
int32_t
tbCntScanOptCreateSumFunc
(
SFunctionNode
*
pCntFunc
,
SNode
*
pParam
,
SNode
**
pOutput
)
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pFunc
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
strcpy
(
pFunc
->
functionName
,
"sum"
);
strcpy
(
pFunc
->
node
.
aliasName
,
pCntFunc
->
node
.
aliasName
);
int32_t
code
=
createColumnByRewriteExpr
(
pParam
,
&
pFunc
->
pParameterList
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
fmGetFuncInfo
(
pFunc
,
NULL
,
0
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
*
pOutput
=
(
SNode
*
)
pFunc
;
}
else
{
nodesDestroyNode
((
SNode
*
)
pFunc
);
}
return
code
;
}
static
int32_t
tbCntScanOptRewriteAgg
(
SAggLogicNode
*
pAgg
)
{
SScanLogicNode
*
pScan
=
(
SScanLogicNode
*
)
nodesListGetNode
(
pAgg
->
node
.
pChildren
,
0
);
SNode
*
pSum
=
NULL
;
int32_t
code
=
tbCntScanOptCreateSumFunc
((
SFunctionNode
*
)
nodesListGetNode
(
pAgg
->
pAggFuncs
,
0
),
nodesListGetNode
(
pScan
->
pScanPseudoCols
,
0
),
&
pSum
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
NODES_DESTORY_LIST
(
pAgg
->
pAggFuncs
);
code
=
nodesListMakeStrictAppend
(
&
pAgg
->
pAggFuncs
,
pSum
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
partTagsRewriteGroupTagsToFuncs
(
pScan
->
pGroupTags
,
0
,
pAgg
);
}
NODES_DESTORY_LIST
(
pAgg
->
pGroupKeys
);
return
code
;
}
static
int32_t
tableCountScanOptimize
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
STbCntScanOptInfo
info
=
{
0
};
if
(
!
optFindEligibleNode
(
pLogicSubplan
->
pNode
,
(
FShouldBeOptimized
)
tbCntScanOptShouldBeOptimized
,
&
info
))
{
return
TSDB_CODE_SUCCESS
;
}
int32_t
code
=
tbCntScanOptRewriteScan
(
&
info
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tbCntScanOptRewriteAgg
(
info
.
pAgg
);
}
return
code
;
}
// clang-format off
static
const
SOptimizeRule
optimizeRuleSet
[]
=
{
{.
pName
=
"ScanPath"
,
.
optimizeFunc
=
scanPathOptimize
},
...
...
@@ -2468,7 +2720,8 @@ static const SOptimizeRule optimizeRuleSet[] = {
{.
pName
=
"RewriteUnique"
,
.
optimizeFunc
=
rewriteUniqueOptimize
},
{.
pName
=
"LastRowScan"
,
.
optimizeFunc
=
lastRowScanOptimize
},
{.
pName
=
"TagScan"
,
.
optimizeFunc
=
tagScanOptimize
},
{.
pName
=
"PushDownLimit"
,
.
optimizeFunc
=
pushDownLimitOptimize
}
{.
pName
=
"PushDownLimit"
,
.
optimizeFunc
=
pushDownLimitOptimize
},
{.
pName
=
"TableCountScan"
,
.
optimizeFunc
=
tableCountScanOptimize
},
};
// clang-format on
...
...
source/libs/planner/src/planPhysiCreater.c
浏览文件 @
30e124a5
...
...
@@ -489,6 +489,8 @@ static ENodeType getScanOperatorType(EScanType scanType) {
return
QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN
;
case
SCAN_TYPE_BLOCK_INFO
:
return
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
;
case
SCAN_TYPE_TABLE_COUNT
:
return
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
;
default:
break
;
}
...
...
@@ -524,6 +526,24 @@ static int32_t createLastRowScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSu
pScan
->
ignoreNull
=
pScanLogicNode
->
igLastNull
;
vgroupInfoToNodeAddr
(
pScanLogicNode
->
pVgroupList
->
vgroups
,
&
pSubplan
->
execNode
);
return
createScanPhysiNodeFinalize
(
pCxt
,
pSubplan
,
pScanLogicNode
,
(
SScanPhysiNode
*
)
pScan
,
pPhyNode
);
}
static
int32_t
createTableCountScanPhysiNode
(
SPhysiPlanContext
*
pCxt
,
SSubplan
*
pSubplan
,
SScanLogicNode
*
pScanLogicNode
,
SPhysiNode
**
pPhyNode
)
{
STableCountScanPhysiNode
*
pScan
=
(
STableCountScanPhysiNode
*
)
makePhysiNode
(
pCxt
,
(
SLogicNode
*
)
pScanLogicNode
,
QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN
);
if
(
NULL
==
pScan
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
pScan
->
pGroupTags
=
nodesCloneList
(
pScanLogicNode
->
pGroupTags
);
if
(
NULL
!=
pScanLogicNode
->
pGroupTags
&&
NULL
==
pScan
->
pGroupTags
)
{
nodesDestroyNode
((
SNode
*
)
pScan
);
return
TSDB_CODE_OUT_OF_MEMORY
;
}
pScan
->
groupSort
=
pScanLogicNode
->
groupSort
;
vgroupInfoToNodeAddr
(
pScanLogicNode
->
pVgroupList
->
vgroups
,
&
pSubplan
->
execNode
);
return
createScanPhysiNodeFinalize
(
pCxt
,
pSubplan
,
pScanLogicNode
,
(
SScanPhysiNode
*
)
pScan
,
pPhyNode
);
...
...
@@ -589,7 +609,6 @@ static int32_t createSystemTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan*
pScan
->
accountId
=
pCxt
->
pPlanCxt
->
acctId
;
pScan
->
sysInfo
=
pCxt
->
pPlanCxt
->
sysInfo
;
if
(
0
==
strcmp
(
pScanLogicNode
->
tableName
.
tname
,
TSDB_INS_TABLE_TABLES
)
||
0
==
strcmp
(
pScanLogicNode
->
tableName
.
tname
,
TSDB_INS_TABLE_TABLE_DISTRIBUTED
)
||
0
==
strcmp
(
pScanLogicNode
->
tableName
.
tname
,
TSDB_INS_TABLE_TAGS
))
{
vgroupInfoToNodeAddr
(
pScanLogicNode
->
pVgroupList
->
vgroups
,
&
pSubplan
->
execNode
);
}
else
{
...
...
@@ -624,6 +643,8 @@ static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan,
case
SCAN_TYPE_TAG
:
case
SCAN_TYPE_BLOCK_INFO
:
return
createSimpleScanPhysiNode
(
pCxt
,
pSubplan
,
pScanLogicNode
,
pPhyNode
);
case
SCAN_TYPE_TABLE_COUNT
:
return
createTableCountScanPhysiNode
(
pCxt
,
pSubplan
,
pScanLogicNode
,
pPhyNode
);
case
SCAN_TYPE_LAST_ROW
:
return
createLastRowScanPhysiNode
(
pCxt
,
pSubplan
,
pScanLogicNode
,
pPhyNode
);
case
SCAN_TYPE_TABLE
:
...
...
source/libs/planner/src/planSpliter.c
浏览文件 @
30e124a5
...
...
@@ -292,6 +292,20 @@ static bool stbSplNeedSplitJoin(bool streamQuery, SJoinLogicNode* pJoin) {
return
true
;
}
static
bool
stbSplIsTableCountQuery
(
SLogicNode
*
pNode
)
{
if
(
1
!=
LIST_LENGTH
(
pNode
->
pChildren
))
{
return
false
;
}
SNode
*
pChild
=
nodesListGetNode
(
pNode
->
pChildren
,
0
);
if
(
QUERY_NODE_LOGIC_PLAN_PARTITION
==
nodeType
(
pChild
))
{
if
(
1
!=
LIST_LENGTH
(((
SLogicNode
*
)
pChild
)
->
pChildren
))
{
return
false
;
}
pChild
=
nodesListGetNode
(((
SLogicNode
*
)
pChild
)
->
pChildren
,
0
);
}
return
QUERY_NODE_LOGIC_PLAN_SCAN
==
nodeType
(
pChild
)
&&
SCAN_TYPE_TABLE_COUNT
==
((
SScanLogicNode
*
)
pChild
)
->
scanType
;
}
static
SNodeList
*
stbSplGetPartKeys
(
SLogicNode
*
pNode
)
{
if
(
QUERY_NODE_LOGIC_PLAN_SCAN
==
nodeType
(
pNode
))
{
return
((
SScanLogicNode
*
)
pNode
)
->
pGroupTags
;
...
...
@@ -340,7 +354,7 @@ static bool stbSplNeedSplit(bool streamQuery, SLogicNode* pNode) {
case
QUERY_NODE_LOGIC_PLAN_AGG
:
return
(
!
stbSplHasGatherExecFunc
(((
SAggLogicNode
*
)
pNode
)
->
pAggFuncs
)
||
stbSplIsPartTableAgg
((
SAggLogicNode
*
)
pNode
))
&&
stbSplHasMultiTbScan
(
streamQuery
,
pNode
);
stbSplHasMultiTbScan
(
streamQuery
,
pNode
)
&&
!
stbSplIsTableCountQuery
(
pNode
)
;
case
QUERY_NODE_LOGIC_PLAN_WINDOW
:
return
stbSplNeedSplitWindow
(
streamQuery
,
pNode
);
case
QUERY_NODE_LOGIC_PLAN_SORT
:
...
...
source/libs/planner/test/planSysTbTest.cpp
浏览文件 @
30e124a5
...
...
@@ -20,13 +20,6 @@ using namespace std;
class
PlanSysTableTest
:
public
PlannerTestBase
{};
TEST_F
(
PlanSysTableTest
,
show
)
{
useDb
(
"root"
,
"test"
);
run
(
"show tables"
);
run
(
"show stables"
);
}
TEST_F
(
PlanSysTableTest
,
informationSchema
)
{
useDb
(
"root"
,
"information_schema"
);
...
...
@@ -38,3 +31,17 @@ TEST_F(PlanSysTableTest, withAgg) {
run
(
"SELECT COUNT(1) FROM ins_users"
);
}
TEST_F
(
PlanSysTableTest
,
tableCount
)
{
useDb
(
"root"
,
"information_schema"
);
run
(
"SELECT COUNT(*) FROM ins_tables"
);
run
(
"SELECT COUNT(*) FROM ins_tables WHERE db_name = 'test'"
);
run
(
"SELECT COUNT(*) FROM ins_tables WHERE db_name = 'test' AND stable_name = 'st1'"
);
run
(
"SELECT db_name, COUNT(*) FROM ins_tables GROUP BY db_name"
);
run
(
"SELECT db_name, stable_name, COUNT(*) FROM ins_tables GROUP BY db_name, stable_name"
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录