From 40c7562470fba96443fe24e88592cfd91c6940cd Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 15 Nov 2022 16:38:51 +0800 Subject: [PATCH 01/33] enh: optimize statement for querying the number of sub tables of the super table --- include/libs/function/functionMgt.h | 1 + include/libs/nodes/nodes.h | 1 + include/libs/nodes/plannodes.h | 4 +- source/libs/function/src/builtins.c | 25 ++++- source/libs/nodes/src/nodesCodeFuncs.c | 8 +- source/libs/nodes/src/nodesMsgFuncs.c | 2 + source/libs/nodes/src/nodesUtilFuncs.c | 3 + source/libs/parser/src/parTranslater.c | 111 +++++++++++++++++++++ source/libs/parser/test/mockCatalog.cpp | 7 +- source/libs/planner/src/planLogicCreater.c | 16 +-- source/libs/planner/src/planPhysiCreater.c | 3 + source/libs/planner/src/planSpliter.c | 17 +++- source/libs/planner/test/planSysTbTest.cpp | 6 ++ 13 files changed, 186 insertions(+), 18 deletions(-) diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 81f63537e5..9ca6a7a9fa 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -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, diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 00e896f586..b4f256e304 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -227,6 +227,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, diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index f942713f5d..aa0962a40b 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -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 { @@ -314,6 +315,7 @@ typedef struct SScanPhysiNode { typedef SScanPhysiNode STagScanPhysiNode; typedef SScanPhysiNode SBlockDistScanPhysiNode; +typedef SScanPhysiNode STableCountScanPhysiNode; typedef struct SLastRowScanPhysiNode { SScanPhysiNode scan; diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index d3f03e8e9c..155a184074 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -475,7 +475,7 @@ static int32_t translateNowToday(SFunctionNode* pFunc, char* pErrBuf, int32_t le // add database precision as param uint8_t dbPrec = pFunc->node.resType.precision; - int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); + int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -1506,7 +1506,7 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len) // add database precision as param uint8_t dbPrec = pFunc->node.resType.precision; - int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); + int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -1519,7 +1519,7 @@ static int32_t translateInterp(SFunctionNode* pFunc, char* pErrBuf, int32_t len) int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList); uint8_t dbPrec = pFunc->node.resType.precision; - //if (1 != numOfParams && 3 != numOfParams && 4 != numOfParams) { + // if (1 != numOfParams && 3 != numOfParams && 4 != numOfParams) { if (1 != numOfParams) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } @@ -1835,7 +1835,7 @@ static int32_t translateCast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { // add database precision as param uint8_t dbPrec = pFunc->node.resType.precision; - int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); + int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -1894,7 +1894,7 @@ static int32_t translateToUnixtimestamp(SFunctionNode* pFunc, char* pErrBuf, int // add database precision as param uint8_t dbPrec = pFunc->node.resType.precision; - int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); + int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -2060,6 +2060,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_INT].bytes, .type = TSDB_DATA_TYPE_INT}; + return TSDB_CODE_SUCCESS; +} + // clang-format off const SBuiltinFuncDefinition funcMgtBuiltins[] = { { @@ -3218,6 +3223,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 diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 172c769433..c60f08c6a8 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -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 "PhysiTableMergeScan"; + case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: + return "PhysiTableCountScan"; case QUERY_NODE_PHYSICAL_PLAN_PROJECT: return "PhysiProject"; case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: @@ -4630,6 +4632,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { return logicPlanToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: return physiScanNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: return physiLastRowScanNodeToJson(pObj, pJson); @@ -4786,6 +4789,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); diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index 2879d55167..c263e276da 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -3630,6 +3630,7 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { break; case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: code = physiScanNodeToMsg(pObj, pEncoder); break; case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: @@ -3768,6 +3769,7 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) { break; case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: code = msgToPhysiScanNode(pDecoder, pObj); break; case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 39d17153d0..ea02c887cf 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -493,6 +493,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: @@ -1118,6 +1120,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: { diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 0e5cb14208..0bd04781bb 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -7464,6 +7464,112 @@ static int32_t rewriteFlushDatabase(STranslateContext* pCxt, SQuery* pQuery) { return code; } +static bool isTableCountProject(SNodeList* pProjectionList) { + if (1 != LIST_LENGTH(pProjectionList)) { + return false; + } + SNode* pProj = nodesListGetNode(pProjectionList, 0); + return QUERY_NODE_FUNCTION == nodeType(pProj) && 0 == strcmp(((SFunctionNode*)pProj)->functionName, "count"); +} + +static bool isTableCountFrom(SNode* pTable) { + if (NULL == pTable || QUERY_NODE_REAL_TABLE != nodeType(pTable)) { + return false; + } + SRealTableNode* pRtable = (SRealTableNode*)pTable; + return 0 == strcmp(pRtable->table.dbName, TSDB_INFORMATION_SCHEMA_DB) && + 0 == strcmp(pRtable->table.tableName, TSDB_INS_TABLE_TABLES); +} + +static bool isTableCountCond(SNode* pCond, const char* pCol) { + if (QUERY_NODE_OPERATOR != nodeType(pCond) || OP_TYPE_EQUAL != ((SOperatorNode*)pCond)->opType) { + return false; + } + SNode* pLeft = ((SOperatorNode*)pCond)->pLeft; + SNode* pRight = ((SOperatorNode*)pCond)->pRight; + if (QUERY_NODE_COLUMN == nodeType(pLeft) && QUERY_NODE_VALUE == nodeType(pRight)) { + return 0 == strcmp(((SColumnNode*)pLeft)->colName, pCol); + } + if (QUERY_NODE_COLUMN == nodeType(pRight) && QUERY_NODE_VALUE == nodeType(pLeft)) { + return 0 == strcmp(((SColumnNode*)pRight)->colName, pCol); + } + return false; +} + +static bool isTableCountWhere(SNode* pWhere) { + if (NULL == pWhere || QUERY_NODE_LOGIC_CONDITION != nodeType(pWhere)) { + return false; + } + SLogicConditionNode* pLogicCond = (SLogicConditionNode*)pWhere; + if (LOGIC_COND_TYPE_AND != pLogicCond->condType || 2 != LIST_LENGTH(pLogicCond->pParameterList)) { + return false; + } + SNode* pCond1 = nodesListGetNode(pLogicCond->pParameterList, 0); + SNode* pCond2 = nodesListGetNode(pLogicCond->pParameterList, 1); + return (isTableCountCond(pCond1, "db_name") && isTableCountCond(pCond2, "stable_name")) || + (isTableCountCond(pCond1, "stable_name") && isTableCountCond(pCond2, "db_name")); +} + +static bool isTableCountQuery(const SSelectStmt* pSelect) { + if (!isTableCountProject(pSelect->pProjectionList) || !isTableCountFrom(pSelect->pFromTable) || + !isTableCountWhere(pSelect->pWhere) || NULL != pSelect->pPartitionByList || NULL != pSelect->pWindow || + NULL != pSelect->pGroupByList || NULL != pSelect->pHaving || NULL != pSelect->pRange || NULL != pSelect->pEvery || + NULL != pSelect->pFill) { + return false; + } + return true; +} + +static SNode* createTableCountPseudoColumn() { + SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); + if (NULL == pFunc) { + return NULL; + } + snprintf(pFunc->functionName, sizeof(pFunc->functionName), "%s", "_table_count"); + return (SNode*)pFunc; +} + +static int32_t rewriteCountFuncForTableCount(SSelectStmt* pSelect) { + SFunctionNode* pFunc = (SFunctionNode*)nodesListGetNode(pSelect->pProjectionList, 0); + NODES_DESTORY_LIST(pFunc->pParameterList); + snprintf(pFunc->functionName, sizeof(pFunc->functionName), "%s", "sum"); + return nodesListMakeStrictAppend(&pFunc->pParameterList, createTableCountPseudoColumn()); +} + +static const char* getNameFromCond(SLogicConditionNode* pLogicCond, const char* pCol) { + SOperatorNode* pCond1 = (SOperatorNode*)nodesListGetNode(pLogicCond->pParameterList, 0); + SOperatorNode* pCond2 = (SOperatorNode*)nodesListGetNode(pLogicCond->pParameterList, 1); + if (QUERY_NODE_COLUMN == nodeType(pCond1->pLeft) && 0 == strcmp(((SColumnNode*)pCond1->pLeft)->colName, pCol)) { + return ((SValueNode*)pCond1->pRight)->literal; + } + if (QUERY_NODE_COLUMN == nodeType(pCond1->pRight) && 0 == strcmp(((SColumnNode*)pCond1->pRight)->colName, pCol)) { + return ((SValueNode*)pCond1->pLeft)->literal; + } + if (QUERY_NODE_COLUMN == nodeType(pCond2->pLeft) && 0 == strcmp(((SColumnNode*)pCond2->pLeft)->colName, pCol)) { + return ((SValueNode*)pCond2->pRight)->literal; + } + return ((SValueNode*)pCond2->pLeft)->literal; +} + +static int32_t rewriteRealTableForTableCount(SSelectStmt* pSelect) { + STableNode* pTable = (STableNode*)pSelect->pFromTable; + snprintf(pTable->dbName, sizeof(pTable->dbName), "%s", + getNameFromCond((SLogicConditionNode*)pSelect->pWhere, "db_name")); + snprintf(pTable->tableName, sizeof(pTable->tableName), "%s", + getNameFromCond((SLogicConditionNode*)pSelect->pWhere, "stable_name")); + nodesDestroyNode(pSelect->pWhere); + pSelect->pWhere = NULL; + return TSDB_CODE_SUCCESS; +} + +static int32_t rewriteTableCountQuery(SSelectStmt* pSelect) { + int32_t code = rewriteCountFuncForTableCount(pSelect); + if (TSDB_CODE_SUCCESS == code) { + code = rewriteRealTableForTableCount(pSelect); + } + return code; +} + static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { int32_t code = TSDB_CODE_SUCCESS; switch (nodeType(pQuery->pRoot)) { @@ -7524,6 +7630,11 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { case QUERY_NODE_FLUSH_DATABASE_STMT: code = rewriteFlushDatabase(pCxt, pQuery); break; + case QUERY_NODE_SELECT_STMT: + if (isTableCountQuery((SSelectStmt*)pQuery->pRoot)) { + code = rewriteTableCountQuery((SSelectStmt*)pQuery->pRoot); + } + break; default: break; } diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index 8f051c67a0..564594a558 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -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) + mcs->createTableBuilder(TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_TABLES, TSDB_SYSTEM_TABLE, 3) .addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN) .addColumn("table_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_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) @@ -248,8 +249,8 @@ int32_t __catalogGetTableDistVgInfo(SCatalog* pCtg, SRequestConnInfo* pConn, con return g_mockCatalogService->catalogGetTableDistVgInfo(pTableName, pVgList); } -int32_t __catalogGetDBVgVersion(SCatalog* pCtg, const char* dbFName, int32_t* version, int64_t* dbId, - int32_t* tableNum, int64_t* stateTs) { +int32_t __catalogGetDBVgVersion(SCatalog* pCtg, const char* dbFName, int32_t* version, int64_t* dbId, int32_t* tableNum, + int64_t* stateTs) { return 0; } diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 89e8a85895..89635909ee 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -203,11 +203,13 @@ 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; + } + int32_t funcType = ((SFunctionNode*)nodesListGetNode(pScanPseudoCols, 0))->funcType; + return FUNCTION_TYPE_BLOCK_DIST_INFO == funcType + ? SCAN_TYPE_BLOCK_INFO + : (FUNCTION_TYPE_TABLE_COUNT == funcType ? SCAN_TYPE_TABLE_COUNT : SCAN_TYPE_TABLE); } return SCAN_TYPE_TABLE; @@ -286,6 +288,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; @@ -320,7 +324,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); } diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 72f3d995bc..a19835be0b 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -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; } @@ -623,6 +625,7 @@ static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, switch (pScanLogicNode->scanType) { case SCAN_TYPE_TAG: case SCAN_TYPE_BLOCK_INFO: + case SCAN_TYPE_TABLE_COUNT: return createSimpleScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); case SCAN_TYPE_LAST_ROW: return createLastRowScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 249ba1815d..783dce9483 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -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 bool stbSplNeedSplit(bool streamQuery, SLogicNode* pNode) { switch (nodeType(pNode)) { case QUERY_NODE_LOGIC_PLAN_SCAN: @@ -301,7 +315,8 @@ static bool stbSplNeedSplit(bool streamQuery, SLogicNode* pNode) { case QUERY_NODE_LOGIC_PLAN_PARTITION: return streamQuery ? false : stbSplIsMultiTbScanChild(streamQuery, pNode); case QUERY_NODE_LOGIC_PLAN_AGG: - return !stbSplHasGatherExecFunc(((SAggLogicNode*)pNode)->pAggFuncs) && stbSplHasMultiTbScan(streamQuery, pNode); + return !stbSplHasGatherExecFunc(((SAggLogicNode*)pNode)->pAggFuncs) && stbSplHasMultiTbScan(streamQuery, pNode) && + !stbSplIsTableCountQuery(pNode); case QUERY_NODE_LOGIC_PLAN_WINDOW: return stbSplNeedSplitWindow(streamQuery, pNode); case QUERY_NODE_LOGIC_PLAN_SORT: diff --git a/source/libs/planner/test/planSysTbTest.cpp b/source/libs/planner/test/planSysTbTest.cpp index 6b40e381cc..2603b3183f 100644 --- a/source/libs/planner/test/planSysTbTest.cpp +++ b/source/libs/planner/test/planSysTbTest.cpp @@ -38,3 +38,9 @@ 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 WHERE db_name = 'test' AND stable_name = 'st1'"); +} From 2ead89e3d6530857f41baba4d9171aa9debc0e46 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Fri, 18 Nov 2022 11:53:33 +0800 Subject: [PATCH 02/33] feat: table merge scan save work --- include/libs/function/function.h | 1 + source/dnode/vnode/inc/vnode.h | 6 ++ source/dnode/vnode/src/inc/vnodeInt.h | 6 -- source/libs/executor/inc/executorimpl.h | 11 ++++ source/libs/executor/src/executil.c | 1 + source/libs/executor/src/executorimpl.c | 5 ++ source/libs/executor/src/scanoperator.c | 80 +++++++++++++++++++++++++ 7 files changed, 104 insertions(+), 6 deletions(-) diff --git a/include/libs/function/function.h b/include/libs/function/function.h index 6f2a675466..d6e584cc10 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -163,6 +163,7 @@ typedef struct tExprNode { int32_t functionId; int32_t num; struct SFunctionNode *pFunctNode; + int32_t functionType; } _function; struct { diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 370103c222..fcbe5e476b 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -109,6 +109,12 @@ int metaGetTableUidByName(void *meta, char *tbName, int64_t *uid); int metaGetTableTypeByName(void *meta, char *tbName, ETableType *tbType); bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid); +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; int16_t cid; diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h index ac9fabf052..1ca80c7570 100644 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ b/source/dnode/vnode/src/inc/vnodeInt.h @@ -144,12 +144,6 @@ typedef struct SMetaInfo { } SMetaInfo; int32_t metaGetInfo(SMeta* pMeta, int64_t uid, SMetaInfo* pInfo); -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); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index b0da277cfb..6aa2a1e5d5 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -549,6 +549,17 @@ typedef struct SSysTableScanInfo { SLoadRemoteDataInfo loadInfo; } SSysTableScanInfo; +typedef struct STableCountScanInfo { + SReadHandle readHandle; + SSDataBlock* pRes; + SExprSupp pseudoSup; + SNode* pCondition; + SName name; + uint64_t suid; + uint64_t uid; + int8_t tableType; +} STableCountScanInfo; + typedef struct SBlockDistInfo { SSDataBlock* pResBlock; STsdbReader* pHandle; diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index d1046ff02c..d9b7682e45 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1283,6 +1283,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)); diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 39e876800f..b1fe016d13 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -2612,6 +2612,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); @@ -2802,6 +2804,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; diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 77d2aeba28..c42089eee5 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -4839,3 +4839,83 @@ _error: taosMemoryFree(pOperator); return NULL; } + +// ==================================================================================================================== +// TableCountScanOperator +static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator); +static void destoryTableCountScanOperator(void* param); + +SOperatorInfo* createTableCountScanOperatorInfo(SReadHandle* readHandle, STableCountScanPhysiNode* pScanNode, + SExecTaskInfo* pTaskInfo) { + int32_t code = TSDB_CODE_SUCCESS; + + STableCountScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableCountScanInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + + if (!pInfo || !pOperator) { + goto _error; + } + + pInfo->readHandle = *readHandle; + + if (pScanNode->pScanPseudoCols != NULL) { + SExprSupp* pSup = &pInfo->pseudoSup; + pSup->pExprInfo = createExprInfo(pScanNode->pScanPseudoCols, NULL, &pSup->numOfExprs); + pSup->pCtx = createSqlFunctionCtx(pSup->pExprInfo, pSup->numOfExprs, &pSup->rowEntryInfoOffset); + } + + SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc; + initResultSizeInfo(&pOperator->resultInfo, 1); + pInfo->pRes = createResDataBlock(pDescNode); + blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity); + + tNameAssign(&pInfo->name, &pScanNode->tableName); + + pInfo->suid = pScanNode->suid; // 0 for super table, super table uid for child table + pInfo->uid = pScanNode->uid; // super table uid, or child table uid + pInfo->tableType = pScanNode->tableType; + + 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; +} + +static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + STableCountScanInfo* pInfo = pOperator->info; + + SExprSupp* pSup = &pInfo->pseudoSup; + if (pSup->numOfExprs != 1 || pSup->pExprInfo[0].pExpr->nodeType != QUERY_NODE_FUNCTION || + pSup->pExprInfo[0].pExpr->_function.functionType != FUNCTION_TYPE_TABLE_COUNT ) { + qError("%s table count scan operator invalid pseduo columns", GET_TASKID(pTaskInfo)); + } + SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 0); + if (pInfo->uid != 0) { + SMetaStbStats stats = {0}; + metaGetStbStats(pInfo->readHandle.meta, pInfo->uid, &stats); + int64_t ctbNum = stats.ctbNum; + //TODO: wxy about the return type bigint or int? + colDataAppend(pColInfoData, 0, (char*)&ctbNum, false); + pInfo->pRes->info.rows = 1; + } else { + //TODO: get table count in this vnode? + } + return NULL; +} + +static void destoryTableCountScanOperator(void* param) { + STableCountScanInfo* pTableCountScanInfo = param; + blockDataDestroy(pTableCountScanInfo->pRes); + + cleanupExprSupp(&pTableCountScanInfo->pseudoSup); + taosMemoryFreeClear(param); +} From 469fcd314e0a6c5b1451c7aad137b9591250ee2f Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Mon, 21 Nov 2022 18:44:04 +0800 Subject: [PATCH 03/33] enh: ins_tables optimize --- include/libs/nodes/nodes.h | 6 + source/libs/parser/inc/parUtil.h | 2 +- source/libs/parser/src/parAstParser.c | 2 +- source/libs/parser/src/parTranslater.c | 201 +++++------------- source/libs/parser/src/parUtil.c | 2 +- source/libs/parser/test/mockCatalog.cpp | 12 +- .../libs/parser/test/mockCatalogService.cpp | 136 +++++++----- source/libs/planner/src/planLogicCreater.c | 5 +- source/libs/planner/src/planOptimizer.c | 200 ++++++++++++++++- source/libs/planner/src/planPhysiCreater.c | 1 - source/libs/planner/test/planSysTbTest.cpp | 15 +- 11 files changed, 353 insertions(+), 229 deletions(-) diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index b4f256e304..3b0fcab5fc 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -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)); \ diff --git a/source/libs/parser/inc/parUtil.h b/source/libs/parser/inc/parUtil.h index c53d3f9320..ce5a63f5d0 100644 --- a/source/libs/parser/inc/parUtil.h +++ b/source/libs/parser/inc/parUtil.h @@ -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 getInsTagsTableTargetName(int32_t acctId, SNode* pWhere, SName* pName); +int32_t getVnodeSysTableTargetName(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); diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index 5aa87d780d..8c5806ebe1 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -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 = getInsTagsTableTargetName(pCxt->pParseCxt->acctId, pSelect->pWhere, &name); + int32_t code = getVnodeSysTableTargetName(pCxt->pParseCxt->acctId, pSelect->pWhere, &name); if (TSDB_CODE_SUCCESS == code) { code = collectMetaKeyFromInsTagsImpl(pCxt, &name); } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 9c3ff6c26d..fba40889f8 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -2203,22 +2203,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 getTagsTableVgroupListImpl(STranslateContext* pCxt, SName* pTargetName, SName* pName, - SArray** pVgroupList) { +static int32_t getVnodeSysTableVgroupListImpl(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) { + // system table query should not report errors code = TSDB_CODE_SUCCESS; } return code; @@ -2235,50 +2241,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 getTagsTableVgroupList(STranslateContext* pCxt, SName* pName, SArray** pVgroupList) { +static int32_t getVnodeSysTableVgroupList(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 = getInsTagsTableTargetName(pCxt->pParseCxt->acctId, pSelect->pWhere, &targetName); + int32_t code = getVnodeSysTableTargetName(pCxt->pParseCxt->acctId, pSelect->pWhere, &targetName); if (TSDB_CODE_SUCCESS == code) { - code = getTagsTableVgroupListImpl(pCxt, &targetName, pName, pVgroupList); + code = getVnodeSysTableVgroupListImpl(pCxt, &targetName, pName, pVgs); } + *pHasUserDbCond = (0 != targetName.type); 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; } @@ -2303,30 +2303,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) { @@ -2360,7 +2369,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); @@ -7467,112 +7475,6 @@ static int32_t rewriteFlushDatabase(STranslateContext* pCxt, SQuery* pQuery) { return code; } -static bool isTableCountProject(SNodeList* pProjectionList) { - if (1 != LIST_LENGTH(pProjectionList)) { - return false; - } - SNode* pProj = nodesListGetNode(pProjectionList, 0); - return QUERY_NODE_FUNCTION == nodeType(pProj) && 0 == strcmp(((SFunctionNode*)pProj)->functionName, "count"); -} - -static bool isTableCountFrom(SNode* pTable) { - if (NULL == pTable || QUERY_NODE_REAL_TABLE != nodeType(pTable)) { - return false; - } - SRealTableNode* pRtable = (SRealTableNode*)pTable; - return 0 == strcmp(pRtable->table.dbName, TSDB_INFORMATION_SCHEMA_DB) && - 0 == strcmp(pRtable->table.tableName, TSDB_INS_TABLE_TABLES); -} - -static bool isTableCountCond(SNode* pCond, const char* pCol) { - if (QUERY_NODE_OPERATOR != nodeType(pCond) || OP_TYPE_EQUAL != ((SOperatorNode*)pCond)->opType) { - return false; - } - SNode* pLeft = ((SOperatorNode*)pCond)->pLeft; - SNode* pRight = ((SOperatorNode*)pCond)->pRight; - if (QUERY_NODE_COLUMN == nodeType(pLeft) && QUERY_NODE_VALUE == nodeType(pRight)) { - return 0 == strcmp(((SColumnNode*)pLeft)->colName, pCol); - } - if (QUERY_NODE_COLUMN == nodeType(pRight) && QUERY_NODE_VALUE == nodeType(pLeft)) { - return 0 == strcmp(((SColumnNode*)pRight)->colName, pCol); - } - return false; -} - -static bool isTableCountWhere(SNode* pWhere) { - if (NULL == pWhere || QUERY_NODE_LOGIC_CONDITION != nodeType(pWhere)) { - return false; - } - SLogicConditionNode* pLogicCond = (SLogicConditionNode*)pWhere; - if (LOGIC_COND_TYPE_AND != pLogicCond->condType || 2 != LIST_LENGTH(pLogicCond->pParameterList)) { - return false; - } - SNode* pCond1 = nodesListGetNode(pLogicCond->pParameterList, 0); - SNode* pCond2 = nodesListGetNode(pLogicCond->pParameterList, 1); - return (isTableCountCond(pCond1, "db_name") && isTableCountCond(pCond2, "stable_name")) || - (isTableCountCond(pCond1, "stable_name") && isTableCountCond(pCond2, "db_name")); -} - -static bool isTableCountQuery(const SSelectStmt* pSelect) { - if (!isTableCountProject(pSelect->pProjectionList) || !isTableCountFrom(pSelect->pFromTable) || - !isTableCountWhere(pSelect->pWhere) || NULL != pSelect->pPartitionByList || NULL != pSelect->pWindow || - NULL != pSelect->pGroupByList || NULL != pSelect->pHaving || NULL != pSelect->pRange || NULL != pSelect->pEvery || - NULL != pSelect->pFill) { - return false; - } - return true; -} - -static SNode* createTableCountPseudoColumn() { - SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); - if (NULL == pFunc) { - return NULL; - } - snprintf(pFunc->functionName, sizeof(pFunc->functionName), "%s", "_table_count"); - return (SNode*)pFunc; -} - -static int32_t rewriteCountFuncForTableCount(SSelectStmt* pSelect) { - SFunctionNode* pFunc = (SFunctionNode*)nodesListGetNode(pSelect->pProjectionList, 0); - NODES_DESTORY_LIST(pFunc->pParameterList); - snprintf(pFunc->functionName, sizeof(pFunc->functionName), "%s", "sum"); - return nodesListMakeStrictAppend(&pFunc->pParameterList, createTableCountPseudoColumn()); -} - -static const char* getNameFromCond(SLogicConditionNode* pLogicCond, const char* pCol) { - SOperatorNode* pCond1 = (SOperatorNode*)nodesListGetNode(pLogicCond->pParameterList, 0); - SOperatorNode* pCond2 = (SOperatorNode*)nodesListGetNode(pLogicCond->pParameterList, 1); - if (QUERY_NODE_COLUMN == nodeType(pCond1->pLeft) && 0 == strcmp(((SColumnNode*)pCond1->pLeft)->colName, pCol)) { - return ((SValueNode*)pCond1->pRight)->literal; - } - if (QUERY_NODE_COLUMN == nodeType(pCond1->pRight) && 0 == strcmp(((SColumnNode*)pCond1->pRight)->colName, pCol)) { - return ((SValueNode*)pCond1->pLeft)->literal; - } - if (QUERY_NODE_COLUMN == nodeType(pCond2->pLeft) && 0 == strcmp(((SColumnNode*)pCond2->pLeft)->colName, pCol)) { - return ((SValueNode*)pCond2->pRight)->literal; - } - return ((SValueNode*)pCond2->pLeft)->literal; -} - -static int32_t rewriteRealTableForTableCount(SSelectStmt* pSelect) { - STableNode* pTable = (STableNode*)pSelect->pFromTable; - snprintf(pTable->dbName, sizeof(pTable->dbName), "%s", - getNameFromCond((SLogicConditionNode*)pSelect->pWhere, "db_name")); - snprintf(pTable->tableName, sizeof(pTable->tableName), "%s", - getNameFromCond((SLogicConditionNode*)pSelect->pWhere, "stable_name")); - nodesDestroyNode(pSelect->pWhere); - pSelect->pWhere = NULL; - return TSDB_CODE_SUCCESS; -} - -static int32_t rewriteTableCountQuery(SSelectStmt* pSelect) { - int32_t code = rewriteCountFuncForTableCount(pSelect); - if (TSDB_CODE_SUCCESS == code) { - code = rewriteRealTableForTableCount(pSelect); - } - return code; -} - static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { int32_t code = TSDB_CODE_SUCCESS; switch (nodeType(pQuery->pRoot)) { @@ -7633,11 +7535,6 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { case QUERY_NODE_FLUSH_DATABASE_STMT: code = rewriteFlushDatabase(pCxt, pQuery); break; - case QUERY_NODE_SELECT_STMT: - if (isTableCountQuery((SSelectStmt*)pQuery->pRoot)) { - code = rewriteTableCountQuery((SSelectStmt*)pQuery->pRoot); - } - break; default: break; } diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index e8c3f2fa8d..ed9b1f6582 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -474,7 +474,7 @@ static int32_t getInsTagsTableTargetNameFromCond(int32_t acctId, SLogicCondition return TSDB_CODE_SUCCESS; } -int32_t getInsTagsTableTargetName(int32_t acctId, SNode* pWhere, SName* pName) { +int32_t getVnodeSysTableTargetName(int32_t acctId, SNode* pWhere, SName* pName) { if (NULL == pWhere) { return TSDB_CODE_SUCCESS; } diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index 564594a558..935ef77b93 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -137,7 +137,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) @@ -179,9 +179,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) @@ -191,8 +191,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); } } diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp index 95f7af435d..b3e92525e2 100644 --- a/source/libs/parser/test/mockCatalogService.cpp +++ b/source/libs/parser/test/mockCatalogService.cpp @@ -20,15 +20,18 @@ #include #include +#include "systable.h" #include "tdatablock.h" #include "tname.h" #include "ttypes.h" +using std::string; + std::unique_ptr g_mockCatalogService; class TableBuilder : public ITableBuilder { public: - virtual TableBuilder& addColumn(const std::string& 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 +145,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; + 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); } - std::set 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; + return catalogGetDBVgListImpl(dbName, pVgList); } int32_t catalogGetDBCfg(const char* pDbFName, SDbCfgInfo* pDbCfg) const { - std::string dbFName(pDbFName); - DbCfgCache::const_iterator it = dbCfg_.find(dbFName.substr(std::string(pDbFName).find_last_of('.') + 1)); + string 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 +163,7 @@ class MockCatalogServiceImpl { return TSDB_CODE_SUCCESS; } - int32_t catalogGetUdfInfo(const std::string& 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 +228,15 @@ class MockCatalogServiceImpl { return code; } - TableBuilder& createTableBuilder(const std::string& db, const std::string& tbname, int8_t tableType, - int32_t numOfColumns, int32_t numOfTags) { + TableBuilder& createTableBuilder(const string& 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 std::string& db, const std::string& stbname, const std::string& tbname, int16_t vgid) { + void createSubTable(const string& db, const string& stbname, const string& tbname, int16_t vgid) { std::unique_ptr table; if (TSDB_CODE_SUCCESS != copyTableSchemaMeta(db, stbname, &table)) { throw std::runtime_error("copyTableSchemaMeta failed"); @@ -274,13 +266,13 @@ class MockCatalogServiceImpl { // string field length #define SFL 20 // string field header -#define SH(h) CA(SFL, std::string(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, std::string(i)) +#define IH(i) CA(IFL, string(i)) // integer field #define IF(i) CA(IFL, std::to_string(i)) // split line @@ -308,7 +300,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(std::string(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 +308,7 @@ class MockCatalogServiceImpl { } } - void createFunction(const std::string& 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 info(new SFuncInfo); strcpy(info->name, func.c_str()); info->funcType = funcType; @@ -342,19 +334,19 @@ class MockCatalogServiceImpl { info.expr = strdup(pReq->expr); auto it = index_.find(pReq->stb); if (index_.end() == it) { - index_.insert(std::make_pair(std::string(pReq->stb), std::vector{info})); + index_.insert(std::make_pair(string(pReq->stb), std::vector{info})); } else { it->second.push_back(info); } } - void createDnode(int32_t dnodeId, const std::string& 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 std::string& 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 +356,12 @@ class MockCatalogServiceImpl { } private: - typedef std::map> TableMetaCache; - typedef std::map DbMetaCache; - typedef std::map> UdfMetaCache; - typedef std::map> IndexMetaCache; - typedef std::map DnodeCache; - typedef std::map DbCfgCache; + typedef std::map> TableMetaCache; + typedef std::map DbMetaCache; + typedef std::map> UdfMetaCache; + typedef std::map> IndexMetaCache; + typedef std::map DnodeCache; + typedef std::map DbCfgCache; uint64_t getNextId() { return id_++; } @@ -386,15 +378,15 @@ class MockCatalogServiceImpl { return pDst; } - std::string toDbname(const std::string& dbFullName) const { - std::string::size_type n = dbFullName.find("."); - if (n == std::string::npos) { + string toDbname(const string& dbFullName) const { + string::size_type n = dbFullName.find("."); + if (n == string::npos) { return dbFullName; } return dbFullName.substr(n + 1); } - std::string ttToString(int8_t tableType) const { + string ttToString(int8_t tableType) const { switch (tableType) { case TSDB_SUPER_TABLE: return "super table"; @@ -407,7 +399,7 @@ class MockCatalogServiceImpl { } } - std::string pToString(uint8_t precision) const { + string pToString(uint8_t precision) const { switch (precision) { case TSDB_TIME_PRECISION_MILLI: return "millisecond"; @@ -420,19 +412,18 @@ class MockCatalogServiceImpl { } } - std::string dtToString(int8_t type) const { return tDataTypes[type].name; } + string dtToString(int8_t type) const { return tDataTypes[type].name; } - std::string 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 std::string& db, const std::string& tbname) const { + STableMeta* getTableSchemaMeta(const string& db, const string& tbname) const { std::shared_ptr table = getTableMeta(db, tbname); return table ? table->schema : nullptr; } - int32_t copyTableSchemaMeta(const std::string& db, const std::string& tbname, - std::unique_ptr* dst) const { + int32_t copyTableSchemaMeta(const string& db, const string& tbname, std::unique_ptr* dst) const { STableMeta* src = getTableSchemaMeta(db, tbname); if (nullptr == src) { return TSDB_CODE_TSC_INVALID_TABLE_NAME; @@ -446,7 +437,7 @@ class MockCatalogServiceImpl { return TSDB_CODE_SUCCESS; } - int32_t copyTableVgroup(const std::string& db, const std::string& tbname, SVgroupInfo* vg) const { + int32_t copyTableVgroup(const string& db, const string& tbname, SVgroupInfo* vg) const { std::shared_ptr table = getTableMeta(db, tbname); if (table->vgs.empty()) { return TSDB_CODE_SUCCESS; @@ -455,7 +446,7 @@ class MockCatalogServiceImpl { return TSDB_CODE_SUCCESS; } - int32_t copyTableVgroup(const std::string& db, const std::string& tbname, SArray** vgList) const { + int32_t copyTableVgroup(const string& db, const string& tbname, SArray** vgList) const { std::shared_ptr table = getTableMeta(db, tbname); if (table->vgs.empty()) { return TSDB_CODE_SUCCESS; @@ -467,7 +458,7 @@ class MockCatalogServiceImpl { return TSDB_CODE_SUCCESS; } - std::shared_ptr getTableMeta(const std::string& db, const std::string& tbname) const { + std::shared_ptr getTableMeta(const string& db, const string& tbname) const { DbMetaCache::const_iterator it = meta_.find(db); if (meta_.end() == it) { return std::shared_ptr(); @@ -527,6 +518,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 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 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 +659,29 @@ MockCatalogService::MockCatalogService() : impl_(new MockCatalogServiceImpl()) { MockCatalogService::~MockCatalogService() {} -ITableBuilder& MockCatalogService::createTableBuilder(const std::string& db, const std::string& tbname, - int8_t tableType, int32_t numOfColumns, int32_t numOfTags) { +ITableBuilder& MockCatalogService::createTableBuilder(const string& db, const string& tbname, int8_t tableType, + 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 std::string& 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 std::string& 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 std::string& db, bool rollup, int8_t cacheLast) { +void MockCatalogService::createDatabase(const string& db, bool rollup, int8_t cacheLast) { impl_->createDatabase(db, rollup, cacheLast); } @@ -683,7 +707,7 @@ int32_t MockCatalogService::catalogGetDBCfg(const char* pDbFName, SDbCfgInfo* pD return impl_->catalogGetDBCfg(pDbFName, pDbCfg); } -int32_t MockCatalogService::catalogGetUdfInfo(const std::string& funcName, SFuncInfo* pInfo) const { +int32_t MockCatalogService::catalogGetUdfInfo(const string& funcName, SFuncInfo* pInfo) const { return impl_->catalogGetUdfInfo(funcName, pInfo); } diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 89635909ee..3d1c939152 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -206,10 +206,9 @@ static EScanType getScanType(SLogicPlanContext* pCxt, SNodeList* pScanPseudoCols if (NULL == pScanPseudoCols) { return SCAN_TYPE_TABLE; } - int32_t funcType = ((SFunctionNode*)nodesListGetNode(pScanPseudoCols, 0))->funcType; - return FUNCTION_TYPE_BLOCK_DIST_INFO == funcType + return FUNCTION_TYPE_BLOCK_DIST_INFO == ((SFunctionNode*)nodesListGetNode(pScanPseudoCols, 0))->funcType ? SCAN_TYPE_BLOCK_INFO - : (FUNCTION_TYPE_TABLE_COUNT == funcType ? SCAN_TYPE_TABLE_COUNT : SCAN_TYPE_TABLE); + : SCAN_TYPE_TABLE; } return SCAN_TYPE_TABLE; diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 45fa67faef..ad0aac977d 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -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; } @@ -2440,6 +2455,188 @@ static int32_t pushDownLimitOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLog return TSDB_CODE_SUCCESS; } +typedef struct STbCntScanOptInfo { + SAggLogicNode* pAgg; + SScanLogicNode* pScan; + SName table; +} STbCntScanOptInfo; + +static bool tbCntScanOptIsEligibleAgg(SAggLogicNode* pAgg) { + if (1 != LIST_LENGTH(pAgg->pAggFuncs) || NULL != pAgg->pGroupKeys) { + return false; + } + SFunctionNode* pFunc = (SFunctionNode*)nodesListGetNode(pAgg->pAggFuncs, 0); + if (FUNCTION_TYPE_COUNT != pFunc->funcType) { + return false; + } + return true; +} + +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; + } + 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, SScanLogicNode* pScan) { + pScan->scanType = SCAN_TYPE_TABLE_COUNT; + strcpy(pScan->tableName.dbname, pInfo->table.dbname); + strcpy(pScan->tableName.tname, pInfo->table.tname); + NODES_DESTORY_LIST(pScan->node.pTargets); + NODES_DESTORY_NODE(pScan->node.pConditions); + NODES_DESTORY_LIST(pScan->pScanCols); + NODES_DESTORY_LIST(pScan->pScanPseudoCols); + int32_t code = nodesListMakeStrictAppend(&pScan->pScanPseudoCols, tbCntScanOptCreateTableCountFunc()); + if (TSDB_CODE_SUCCESS == code) { + code = createColumnByRewriteExpr(nodesListGetNode(pScan->pScanPseudoCols, 0), &pScan->node.pTargets); + } + 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 = nodesListMakeStrictAppend(&pFunc->pParameterList, nodesCloneNode(pParam)); + 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) { + SNode* pSum = NULL; + int32_t code = tbCntScanOptCreateSumFunc( + (SFunctionNode*)nodesListGetNode(pAgg->pAggFuncs, 0), + nodesListGetNode(((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))->pTargets, 0), &pSum); + if (TSDB_CODE_SUCCESS == code) { + NODES_DESTORY_LIST(pAgg->pAggFuncs); + code = nodesListMakeStrictAppend(&pAgg->pAggFuncs, pSum); + } + 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, info.pScan); + if (TSDB_CODE_SUCCESS == code) { + code = tbCntScanOptRewriteAgg(info.pAgg); + } + return code; +} + // clang-format off static const SOptimizeRule optimizeRuleSet[] = { {.pName = "ScanPath", .optimizeFunc = scanPathOptimize}, @@ -2454,7 +2651,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 diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index a19835be0b..f1c0812612 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -591,7 +591,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 { diff --git a/source/libs/planner/test/planSysTbTest.cpp b/source/libs/planner/test/planSysTbTest.cpp index 2603b3183f..fc00285a6d 100644 --- a/source/libs/planner/test/planSysTbTest.cpp +++ b/source/libs/planner/test/planSysTbTest.cpp @@ -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"); @@ -42,5 +35,13 @@ TEST_F(PlanSysTableTest, withAgg) { 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"); } From bc180e39c997895ce1af952f0d2ca7876631a3c9 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 22 Nov 2022 16:39:30 +0800 Subject: [PATCH 04/33] enh: ins_tables optimize --- include/libs/nodes/plannodes.h | 3 +- source/libs/nodes/src/nodesCodeFuncs.c | 2 +- source/libs/planner/src/planOptimizer.c | 75 +++++++++++++++++----- source/libs/planner/src/planPhysiCreater.c | 21 +++++- 4 files changed, 82 insertions(+), 19 deletions(-) diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index aa0962a40b..74daef4047 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -315,7 +315,6 @@ typedef struct SScanPhysiNode { typedef SScanPhysiNode STagScanPhysiNode; typedef SScanPhysiNode SBlockDistScanPhysiNode; -typedef SScanPhysiNode STableCountScanPhysiNode; typedef struct SLastRowScanPhysiNode { SScanPhysiNode scan; @@ -324,6 +323,8 @@ typedef struct SLastRowScanPhysiNode { bool ignoreNull; } SLastRowScanPhysiNode; +typedef SLastRowScanPhysiNode STableCountScanPhysiNode; + typedef struct SSystemTableScanPhysiNode { SScanPhysiNode scan; SEpSet mgmtEpSet; diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index c60f08c6a8..e1482c8720 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -4632,9 +4632,9 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { return logicPlanToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: - case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_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: diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index ad0aac977d..6355f23285 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2461,17 +2461,51 @@ typedef struct STbCntScanOptInfo { SName table; } STbCntScanOptInfo; -static bool tbCntScanOptIsEligibleAgg(SAggLogicNode* pAgg) { - if (1 != LIST_LENGTH(pAgg->pAggFuncs) || NULL != pAgg->pGroupKeys) { +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; } - SFunctionNode* pFunc = (SFunctionNode*)nodesListGetNode(pAgg->pAggFuncs, 0); - if (FUNCTION_TYPE_COUNT != pFunc->funcType) { - 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; @@ -2578,17 +2612,25 @@ static SNode* tbCntScanOptCreateTableCountFunc() { return (SNode*)pFunc; } -static int32_t tbCntScanOptRewriteScan(STbCntScanOptInfo* pInfo, SScanLogicNode* pScan) { - pScan->scanType = SCAN_TYPE_TABLE_COUNT; - strcpy(pScan->tableName.dbname, pInfo->table.dbname); - strcpy(pScan->tableName.tname, pInfo->table.tname); - NODES_DESTORY_LIST(pScan->node.pTargets); - NODES_DESTORY_NODE(pScan->node.pConditions); - NODES_DESTORY_LIST(pScan->pScanCols); - NODES_DESTORY_LIST(pScan->pScanPseudoCols); - int32_t code = nodesListMakeStrictAppend(&pScan->pScanPseudoCols, tbCntScanOptCreateTableCountFunc()); +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_NODE(pInfo->pScan->node.pConditions); + NODES_DESTORY_LIST(pInfo->pScan->pScanCols); + NODES_DESTORY_LIST(pInfo->pScan->pScanPseudoCols); + int32_t code = nodesListMakeStrictAppend(&pInfo->pScan->pScanPseudoCols, tbCntScanOptCreateTableCountFunc()); if (TSDB_CODE_SUCCESS == code) { - code = createColumnByRewriteExpr(nodesListGetNode(pScan->pScanPseudoCols, 0), &pScan->node.pTargets); + code = createColumnByRewriteExpr(nodesListGetNode(pInfo->pScan->pScanPseudoCols, 0), &pInfo->pScan->node.pTargets); + } + SNode* pGroupKey = NULL; + FOREACH(pGroupKey, pInfo->pAgg->pGroupKeys) { + code = nodesListMakeStrictAppend( + &pInfo->pScan->pGroupTags, nodesCloneNode(nodesListGetNode(((SGroupingSetNode*)pGroupKey)->pParameterList, 0))); + if (TSDB_CODE_SUCCESS != code) { + break; + } } return code; } @@ -2621,6 +2663,7 @@ static int32_t tbCntScanOptRewriteAgg(SAggLogicNode* pAgg) { NODES_DESTORY_LIST(pAgg->pAggFuncs); code = nodesListMakeStrictAppend(&pAgg->pAggFuncs, pSum); } + NODES_DESTORY_LIST(pAgg->pGroupKeys); return code; } @@ -2630,7 +2673,7 @@ static int32_t tableCountScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLo return TSDB_CODE_SUCCESS; } - int32_t code = tbCntScanOptRewriteScan(&info, info.pScan); + int32_t code = tbCntScanOptRewriteScan(&info); if (TSDB_CODE_SUCCESS == code) { code = tbCntScanOptRewriteAgg(info.pAgg); } diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index f1c0812612..1a20a80f54 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -526,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); @@ -624,8 +642,9 @@ static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, switch (pScanLogicNode->scanType) { case SCAN_TYPE_TAG: case SCAN_TYPE_BLOCK_INFO: - case SCAN_TYPE_TABLE_COUNT: 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: From 7f6ff3964875ae508bb96a904260bdec48b33e16 Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Fri, 18 Nov 2022 11:53:33 +0800 Subject: [PATCH 05/33] feat: table merge scan save work --- include/libs/function/function.h | 1 + source/dnode/vnode/inc/vnode.h | 6 ++ source/dnode/vnode/src/inc/vnodeInt.h | 6 -- source/libs/executor/inc/executorimpl.h | 11 ++++ source/libs/executor/src/executil.c | 1 + source/libs/executor/src/executorimpl.c | 5 ++ source/libs/executor/src/scanoperator.c | 80 +++++++++++++++++++++++++ 7 files changed, 104 insertions(+), 6 deletions(-) diff --git a/include/libs/function/function.h b/include/libs/function/function.h index 6f2a675466..d6e584cc10 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -163,6 +163,7 @@ typedef struct tExprNode { int32_t functionId; int32_t num; struct SFunctionNode *pFunctNode; + int32_t functionType; } _function; struct { diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 27084700b0..52a8a7f5a3 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -109,6 +109,12 @@ int metaGetTableUidByName(void *meta, char *tbName, int64_t *uid); int metaGetTableTypeByName(void *meta, char *tbName, ETableType *tbType); bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid); +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; int16_t cid; diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h index ac9fabf052..1ca80c7570 100644 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ b/source/dnode/vnode/src/inc/vnodeInt.h @@ -144,12 +144,6 @@ typedef struct SMetaInfo { } SMetaInfo; int32_t metaGetInfo(SMeta* pMeta, int64_t uid, SMetaInfo* pInfo); -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); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index f179c7bd41..1785553c39 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -530,6 +530,17 @@ typedef struct SSysTableScanInfo { SLoadRemoteDataInfo loadInfo; } SSysTableScanInfo; +typedef struct STableCountScanInfo { + SReadHandle readHandle; + SSDataBlock* pRes; + SExprSupp pseudoSup; + SNode* pCondition; + SName name; + uint64_t suid; + uint64_t uid; + int8_t tableType; +} STableCountScanInfo; + typedef struct SBlockDistInfo { SSDataBlock* pResBlock; STsdbReader* pHandle; diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index d1046ff02c..d9b7682e45 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1283,6 +1283,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)); diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 0dd5765aa4..24c9244bda 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -2543,6 +2543,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); @@ -2733,6 +2735,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; diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 916b6df969..a7298df58d 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -4788,3 +4788,83 @@ _error: taosMemoryFree(pOperator); return NULL; } + +// ==================================================================================================================== +// TableCountScanOperator +static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator); +static void destoryTableCountScanOperator(void* param); + +SOperatorInfo* createTableCountScanOperatorInfo(SReadHandle* readHandle, STableCountScanPhysiNode* pScanNode, + SExecTaskInfo* pTaskInfo) { + int32_t code = TSDB_CODE_SUCCESS; + + STableCountScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableCountScanInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + + if (!pInfo || !pOperator) { + goto _error; + } + + pInfo->readHandle = *readHandle; + + if (pScanNode->pScanPseudoCols != NULL) { + SExprSupp* pSup = &pInfo->pseudoSup; + pSup->pExprInfo = createExprInfo(pScanNode->pScanPseudoCols, NULL, &pSup->numOfExprs); + pSup->pCtx = createSqlFunctionCtx(pSup->pExprInfo, pSup->numOfExprs, &pSup->rowEntryInfoOffset); + } + + SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc; + initResultSizeInfo(&pOperator->resultInfo, 1); + pInfo->pRes = createResDataBlock(pDescNode); + blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity); + + tNameAssign(&pInfo->name, &pScanNode->tableName); + + pInfo->suid = pScanNode->suid; // 0 for super table, super table uid for child table + pInfo->uid = pScanNode->uid; // super table uid, or child table uid + pInfo->tableType = pScanNode->tableType; + + 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; +} + +static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + STableCountScanInfo* pInfo = pOperator->info; + + SExprSupp* pSup = &pInfo->pseudoSup; + if (pSup->numOfExprs != 1 || pSup->pExprInfo[0].pExpr->nodeType != QUERY_NODE_FUNCTION || + pSup->pExprInfo[0].pExpr->_function.functionType != FUNCTION_TYPE_TABLE_COUNT ) { + qError("%s table count scan operator invalid pseduo columns", GET_TASKID(pTaskInfo)); + } + SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 0); + if (pInfo->uid != 0) { + SMetaStbStats stats = {0}; + metaGetStbStats(pInfo->readHandle.meta, pInfo->uid, &stats); + int64_t ctbNum = stats.ctbNum; + //TODO: wxy about the return type bigint or int? + colDataAppend(pColInfoData, 0, (char*)&ctbNum, false); + pInfo->pRes->info.rows = 1; + } else { + //TODO: get table count in this vnode? + } + return NULL; +} + +static void destoryTableCountScanOperator(void* param) { + STableCountScanInfo* pTableCountScanInfo = param; + blockDataDestroy(pTableCountScanInfo->pRes); + + cleanupExprSupp(&pTableCountScanInfo->pseudoSup); + taosMemoryFreeClear(param); +} From 8d77b0cfb71e39c75134e79cae0293f8661fa141 Mon Sep 17 00:00:00 2001 From: slzhou Date: Wed, 23 Nov 2022 20:42:00 +0800 Subject: [PATCH 06/33] fix: save work --- source/libs/executor/src/scanoperator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index a7298df58d..941f7e7098 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -4794,10 +4794,11 @@ _error: static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator); static void destoryTableCountScanOperator(void* param); -SOperatorInfo* createTableCountScanOperatorInfo(SReadHandle* readHandle, STableCountScanPhysiNode* pScanNode, +SOperatorInfo* createTableCountScanOperatorInfo(SReadHandle* readHandle, STableCountScanPhysiNode* pTblCountScanNode, SExecTaskInfo* pTaskInfo) { int32_t code = TSDB_CODE_SUCCESS; + SScanPhysiNode* pScanNode = &pTblCountScanNode->scan; STableCountScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableCountScanInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); From c2a7404b425e655bf01e54e159f79b96e430b047 Mon Sep 17 00:00:00 2001 From: slzhou Date: Fri, 25 Nov 2022 23:00:14 +0800 Subject: [PATCH 07/33] save work in case it losts --- source/dnode/vnode/inc/vnode.h | 2 + source/dnode/vnode/src/inc/vnodeInt.h | 2 - source/libs/executor/inc/executorimpl.h | 36 ++-- source/libs/executor/src/scanoperator.c | 227 ++++++++++++++++++++---- 4 files changed, 216 insertions(+), 51 deletions(-) diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 52a8a7f5a3..791e7e88b0 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -108,6 +108,8 @@ int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName); int metaGetTableUidByName(void *meta, char *tbName, int64_t *uid); int metaGetTableTypeByName(void *meta, char *tbName, ETableType *tbType); bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid); +tb_uid_t metaGetTableEntryUidByName(SMeta* pMeta, const char* name); +int64_t metaGetTbNum(SMeta* pMeta); typedef struct { int64_t uid; diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h index 1ca80c7570..1b15e55c0d 100644 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ b/source/dnode/vnode/src/inc/vnodeInt.h @@ -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); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 1785553c39..a14c9bb51e 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -530,16 +530,32 @@ typedef struct SSysTableScanInfo { SLoadRemoteDataInfo loadInfo; } SSysTableScanInfo; -typedef struct STableCountScanInfo { - SReadHandle readHandle; - SSDataBlock* pRes; - SExprSupp pseudoSup; - SNode* pCondition; - SName name; - uint64_t suid; - uint64_t uid; - int8_t tableType; -} STableCountScanInfo; +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; +} STableCountScanOperatorInfo; typedef struct SBlockDistInfo { SSDataBlock* pResBlock; diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 941f7e7098..c8ff156cd3 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -31,7 +31,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)) @@ -233,8 +232,8 @@ static SResultRow* getTableGroupOutputBuf(SOperatorInfo* pOperator, uint64_t gro STableScanInfo* pTableScanInfo = pOperator->info; - SResultRowPosition* p1 = (SResultRowPosition*)tSimpleHashGet(pTableScanInfo->base.pdInfo.pAggSup->pResultRowHashTable, buf, - GET_RES_WINDOW_KEY_LEN(sizeof(groupId))); + SResultRowPosition* p1 = (SResultRowPosition*)tSimpleHashGet(pTableScanInfo->base.pdInfo.pAggSup->pResultRowHashTable, + buf, GET_RES_WINDOW_KEY_LEN(sizeof(groupId))); if (p1 == NULL) { return NULL; @@ -376,7 +375,7 @@ void applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableScanInfo, SSDataBlock* pBlock, uint32_t* status) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SFileBlockLoadRecorder* pCost = &pTableScanInfo->readRecorder; pCost->totalBlocks += 1; @@ -4428,7 +4427,7 @@ static SSDataBlock* getTableDataBlockImpl(void* param) { uint32_t status = 0; loadDataBlock(pOperator, &pTableScanInfo->base, pBlock, &status); -// code = loadDataBlockFromOneTable(pOperator, pTableScanInfo, pBlock, &status); + // code = loadDataBlockFromOneTable(pOperator, pTableScanInfo, pBlock, &status); if (code != TSDB_CODE_SUCCESS) { T_LONG_JMP(pTaskInfo->env, code); } @@ -4758,7 +4757,6 @@ SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanN goto _error; } - initResultSizeInfo(&pOperator->resultInfo, 1024); pInfo->pResBlock = createResDataBlock(pDescNode); blockDataEnsureCapacity(pInfo->pResBlock, pOperator->resultInfo.capacity); @@ -4792,15 +4790,106 @@ _error: // ==================================================================================================================== // TableCountScanOperator static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator); -static void destoryTableCountScanOperator(void* param); +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; - STableCountScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableCountScanInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + SScanPhysiNode* pScanNode = &pTblCountScanNode->scan; + STableCountScanOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableCountScanSupp)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); if (!pInfo || !pOperator) { goto _error; @@ -4808,26 +4897,19 @@ SOperatorInfo* createTableCountScanOperatorInfo(SReadHandle* readHandle, STableC pInfo->readHandle = *readHandle; - if (pScanNode->pScanPseudoCols != NULL) { - SExprSupp* pSup = &pInfo->pseudoSup; - pSup->pExprInfo = createExprInfo(pScanNode->pScanPseudoCols, NULL, &pSup->numOfExprs); - pSup->pCtx = createSqlFunctionCtx(pSup->pExprInfo, pSup->numOfExprs, &pSup->rowEntryInfoOffset); - } - SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc; initResultSizeInfo(&pOperator->resultInfo, 1); pInfo->pRes = createResDataBlock(pDescNode); blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity); - tNameAssign(&pInfo->name, &pScanNode->tableName); - - pInfo->suid = pScanNode->suid; // 0 for super table, super table uid for child table - pInfo->uid = pScanNode->uid; // super table uid, or child table uid - pInfo->tableType = pScanNode->tableType; + 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); + pOperator->fpSet = + createOperatorFpSet(operatorDummyOpenFn, doTableCountScan, NULL, destoryTableCountScanOperator, NULL); return pOperator; _error: @@ -4840,32 +4922,99 @@ _error: } static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - STableCountScanInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + STableCountScanOperatorInfo* pInfo = pOperator->info; + STableCountScanSupp* pSupp = &pInfo->supp; + SSDataBlock* pRes = pInfo->pRes; + // compute group id must, but output is according to scancols. output group by group + // grouptags high priority(groupid<=>grouptag), then tablename(dbname,tableName). + // scanCols, (grouptags cols) + { + // mnode, query table count of information_schema and performance_schema + if (pInfo->readHandle.mnd != NULL) { + if (pSupp->groupByDbName) { + if (pInfo->currGrpIdx == 0) { + uint64_t groupId = calcGroupId(TSDB_INFORMATION_SCHEMA_DB, strlen(TSDB_INFORMATION_SCHEMA_DB)); + size_t infodbTableNum; + getInfosDbMeta(NULL, &infodbTableNum); + pRes->info.groupId = groupId; + if (pSupp->dbNameSlotId != -1) { + SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->dbNameSlotId); + //colDataAppend(colInfoData, 0, ) + } + return NULL; + } else if (pInfo->currGrpIdx == 1) { + uint64_t groupId = calcGroupId(TSDB_PERFORMANCE_SCHEMA_DB, strlen(TSDB_PERFORMANCE_SCHEMA_DB)); + size_t perfdbTableNum; + getPerfDbMeta(NULL, &perfdbTableNum); + } else if (pInfo->currGrpIdx >= 2) { + return NULL; + } + uint64_t groupId = calcGroupId(TSDB_INFORMATION_SCHEMA_DB, strlen(TSDB_INFORMATION_SCHEMA_DB)); + size_t infodbTableNum; + getInfosDbMeta(NULL, &infodbTableNum); + size_t perfdbTableNum; + getPerfDbMeta(NULL, &perfdbTableNum); + // grouptags, db name + } else { + } + } + return NULL; + } + const char* db = NULL; + int32_t vgId = 0; + { + // get dbname + vnodeGetInfo(pInfo->readHandle.vnode, &db, &vgId); + SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 0); + SName sn = {0}; + char varDbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; + tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB); - SExprSupp* pSup = &pInfo->pseudoSup; - if (pSup->numOfExprs != 1 || pSup->pExprInfo[0].pExpr->nodeType != QUERY_NODE_FUNCTION || - pSup->pExprInfo[0].pExpr->_function.functionType != FUNCTION_TYPE_TABLE_COUNT ) { - qError("%s table count scan operator invalid pseduo columns", GET_TASKID(pTaskInfo)); + tNameGetDbName(&sn, varDataVal(varDbName)); + varDataSetLen(varDbName, strlen(varDataVal(varDbName))); } - SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 0); - if (pInfo->uid != 0) { + const char* tableName = tNameGetTableName(&pInfo->tableName); + + { + // grouptags only have column db_name or (no grouptags and tablename is null) + // if (tableName == NULL | strlen(tableName) == 0) + metaGetTbNum(pInfo->readHandle.meta); + } + {// no grouptags and TableName is not null, return child table count + {tb_uid_t uid = metaGetTableEntryUidByName(pInfo->readHandle.meta, tableName); + SMetaStbStats stats = {0}; + metaGetStbStats(pInfo->readHandle.meta, uid, &stats); + int64_t ctbNum = stats.ctbNum; +} +} +{ + // grouptags have column stable_name. return (stable name, child table count) + SArray* stbUidList = taosArrayInit(16, sizeof(tb_uid_t)); + vnodeGetStbIdList(pInfo->readHandle.vnode, 0, stbUidList); + if (vnodeGetStbIdList(pInfo->readHandle.vnode, 0, stbUidList) < 0) { + qError("vgId:%d, failed to get stb id list error: %s", vgId, terrstr()); + taosArrayDestroy(stbUidList); + // return failure + } + for (int i = 0; i < taosArrayGetSize(stbUidList); ++i) { + tb_uid_t stbUid = *(tb_uid_t*)taosArrayGet(stbUidList, i); SMetaStbStats stats = {0}; - metaGetStbStats(pInfo->readHandle.meta, pInfo->uid, &stats); + metaGetStbStats(pInfo->readHandle.meta, stbUid, &stats); int64_t ctbNum = stats.ctbNum; - //TODO: wxy about the return type bigint or int? - colDataAppend(pColInfoData, 0, (char*)&ctbNum, false); - pInfo->pRes->info.rows = 1; - } else { - //TODO: get table count in this vnode? + + char varStbName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; + metaGetTableNameByUid(pInfo->readHandle.meta, stbUid, varStbName); } - return NULL; + taosArrayDestroy(stbUidList); +} +return NULL; } static void destoryTableCountScanOperator(void* param) { - STableCountScanInfo* pTableCountScanInfo = param; + STableCountScanOperatorInfo* pTableCountScanInfo = param; blockDataDestroy(pTableCountScanInfo->pRes); - cleanupExprSupp(&pTableCountScanInfo->pseudoSup); + nodesDestroyList(pTableCountScanInfo->groupTags); taosMemoryFreeClear(param); } From 2cccfe2be44b695309b188502bec944503f888ae Mon Sep 17 00:00:00 2001 From: slzhou Date: Sat, 26 Nov 2022 23:03:12 +0800 Subject: [PATCH 08/33] feature: save work --- source/libs/executor/src/scanoperator.c | 122 +++++++++++++++++------- 1 file changed, 86 insertions(+), 36 deletions(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index c8ff156cd3..51d317ea0f 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -4921,68 +4921,118 @@ _error: 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_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; + strncpy(varDataVal(varDbName), dbName, strlen(dbName)); + varDataSetLen(varDbName, strlen(dbName)); + colDataAppend(colInfoData, 0, varDbName, false); + } + + if (pSupp->stbNameSlotId != -1) { + ASSERT(strlen(stbName)); + SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->stbNameSlotId); + char varStbName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; + strncpy(varDataVal(varStbName), stbName, strlen(stbName)); + varDataSetLen(varStbName, strlen(stbName)); + colDataAppend(colInfoData, 0, varStbName, false); + } + + if (pSupp->tbCountSlotId != -1) { + SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->stbNameSlotId); + colDataAppend(colInfoData, 0, (char*)&count, false); + } + pRes->info.rows = 1; +} + +static SSDataBlock* buildSysDbTableCount(STableCountScanOperatorInfo* pInfo) { + STableCountScanSupp* pSupp = &pInfo->supp; + SSDataBlock* pRes = pInfo->pRes; + + int64_t infodbTableNum; + getInfosDbMeta(NULL, &infodbTableNum); + int64_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.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.groupId = groupId; + fillTableCountScanDataBlock(pSupp, TSDB_PERFORMANCE_SCHEMA_DB, "", perfdbTableNum, pRes); + } + 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); + } + 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); // compute group id must, but output is according to scancols. output group by group // grouptags high priority(groupid<=>grouptag), then tablename(dbname,tableName). // scanCols, (grouptags cols) - { - // mnode, query table count of information_schema and performance_schema - if (pInfo->readHandle.mnd != NULL) { - if (pSupp->groupByDbName) { - if (pInfo->currGrpIdx == 0) { - uint64_t groupId = calcGroupId(TSDB_INFORMATION_SCHEMA_DB, strlen(TSDB_INFORMATION_SCHEMA_DB)); - size_t infodbTableNum; - getInfosDbMeta(NULL, &infodbTableNum); - pRes->info.groupId = groupId; - if (pSupp->dbNameSlotId != -1) { - SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->dbNameSlotId); - //colDataAppend(colInfoData, 0, ) - } - return NULL; - } else if (pInfo->currGrpIdx == 1) { - uint64_t groupId = calcGroupId(TSDB_PERFORMANCE_SCHEMA_DB, strlen(TSDB_PERFORMANCE_SCHEMA_DB)); - size_t perfdbTableNum; - getPerfDbMeta(NULL, &perfdbTableNum); - } else if (pInfo->currGrpIdx >= 2) { - return NULL; - } - uint64_t groupId = calcGroupId(TSDB_INFORMATION_SCHEMA_DB, strlen(TSDB_INFORMATION_SCHEMA_DB)); - size_t infodbTableNum; - getInfosDbMeta(NULL, &infodbTableNum); - size_t perfdbTableNum; - getPerfDbMeta(NULL, &perfdbTableNum); - // grouptags, db name - } else { - } - } - return NULL; + // mnode, query table count of information_schema and performance_schema + if (pInfo->readHandle.mnd != NULL) { + return buildSysDbTableCount(pInfo); } + const char* db = NULL; int32_t vgId = 0; + char dbName[TSDB_DB_FNAME_LEN] = {0}; + { // get dbname vnodeGetInfo(pInfo->readHandle.vnode, &db, &vgId); SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 0); SName sn = {0}; - char varDbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB); - tNameGetDbName(&sn, varDataVal(varDbName)); - varDataSetLen(varDbName, strlen(varDataVal(varDbName))); + tNameGetDbName(&sn, dbName); } - const char* tableName = tNameGetTableName(&pInfo->tableName); + if (pSupp->groupByDbName) { + if (pSupp->groupByStbName) { + } else { + uint64_t groupId = calcGroupId(dbName, strlen(dbName)); + pRes->info.groupId = groupId; + int64_t dbTableCount = metaGetTbNum(pInfo->readHandle.meta); + fillTableCountScanDataBlock(pSupp, dbName, "", dbTableCount, pRes); + } + } else { + if (strlen(pSupp->dbName) != 0) { + if (strlen(pSupp->stbName) != 0) { + + } else { + + } + } + } { // grouptags only have column db_name or (no grouptags and tablename is null) // if (tableName == NULL | strlen(tableName) == 0) metaGetTbNum(pInfo->readHandle.meta); } {// no grouptags and TableName is not null, return child table count - {tb_uid_t uid = metaGetTableEntryUidByName(pInfo->readHandle.meta, tableName); + {tb_uid_t uid = metaGetTableEntryUidByName(pInfo->readHandle.meta, pSupp->stbName); SMetaStbStats stats = {0}; metaGetStbStats(pInfo->readHandle.meta, uid, &stats); int64_t ctbNum = stats.ctbNum; From b5b6fff68b2b77d80f6deaec7594de5a5c44f046 Mon Sep 17 00:00:00 2001 From: slzhou Date: Sun, 27 Nov 2022 13:50:36 +0800 Subject: [PATCH 09/33] feature: save work --- source/dnode/vnode/inc/vnode.h | 1 + source/dnode/vnode/src/meta/metaQuery.c | 16 +++++ source/libs/executor/inc/executorimpl.h | 1 + source/libs/executor/src/scanoperator.c | 79 +++++++++++++------------ 4 files changed, 58 insertions(+), 39 deletions(-) diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 791e7e88b0..3fcd9fbc2b 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -105,6 +105,7 @@ 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 metaGetTableSzNameByUid(void *meta, uint64_t uid, char *tbName); int metaGetTableUidByName(void *meta, char *tbName, int64_t *uid); int metaGetTableTypeByName(void *meta, char *tbName, ETableType *tbType); bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid); diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index 620022c06d..7f8353049a 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -211,6 +211,22 @@ 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, int64_t *uid) { int code = 0; SMetaReader mr = {0}; diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index a14c9bb51e..3f1b7605ea 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -555,6 +555,7 @@ typedef struct STableCountScanOperatorInfo { STableCountScanSupp supp; int32_t currGrpIdx; + SArray* stbUidList; // when group by db_name and stable_name } STableCountScanOperatorInfo; typedef struct SBlockDistInfo { diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 51d317ea0f..78a8f9e706 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -4926,7 +4926,7 @@ void fillTableCountScanDataBlock(STableCountScanSupp* pSupp, char* dbName, char* if (pSupp->dbNameSlotId != -1) { ASSERT(strlen(dbName)); SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->dbNameSlotId); - char varDbName[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; + 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); @@ -4935,7 +4935,7 @@ void fillTableCountScanDataBlock(STableCountScanSupp* pSupp, char* dbName, char* if (pSupp->stbNameSlotId != -1) { ASSERT(strlen(stbName)); SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->stbNameSlotId); - char varStbName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {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); @@ -4997,7 +4997,7 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { const char* db = NULL; int32_t vgId = 0; - char dbName[TSDB_DB_FNAME_LEN] = {0}; + char dbName[TSDB_DB_NAME_LEN] = {0}; { // get dbname @@ -5005,13 +5005,40 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 0); SName sn = {0}; tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB); - tNameGetDbName(&sn, dbName); } if (pSupp->groupByDbName) { if (pSupp->groupByStbName) { + // group by db_name and stable_name + 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); + SMetaStbStats stats = {0}; + metaGetStbStats(pInfo->readHandle.meta, stbUid, &stats); + int64_t ctbNum = stats.ctbNum; + + char stbName[TSDB_TABLE_NAME_LEN] = {0}; + metaGetTableSzNameByUid(pInfo->readHandle.meta, stbUid, stbName); + + char fullStbName[TSDB_TABLE_FNAME_LEN] = {0}; + strcpy(fullStbName, dbName); + strcat(fullStbName, "."); + strcat(fullStbName, stbName); + uint64_t groupId = calcGroupId(fullStbName, strlen(fullStbName)); + pRes->info.groupId = groupId; + + pInfo->currGrpIdx++; + + fillTableCountScanDataBlock(pSupp, dbName, stbName, ctbNum, pRes); + } } else { + // group by only db_name uint64_t groupId = calcGroupId(dbName, strlen(dbName)); pRes->info.groupId = groupId; int64_t dbTableCount = metaGetTbNum(pInfo->readHandle.meta); @@ -5020,45 +5047,18 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* 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, pSupp->dbName, "", tbNumVnode, pRes); } } } - { - // grouptags only have column db_name or (no grouptags and tablename is null) - // if (tableName == NULL | strlen(tableName) == 0) - metaGetTbNum(pInfo->readHandle.meta); - } - {// no grouptags and TableName is not null, return child table count - {tb_uid_t uid = metaGetTableEntryUidByName(pInfo->readHandle.meta, pSupp->stbName); - SMetaStbStats stats = {0}; - metaGetStbStats(pInfo->readHandle.meta, uid, &stats); - int64_t ctbNum = stats.ctbNum; -} -} -{ - // grouptags have column stable_name. return (stable name, child table count) - SArray* stbUidList = taosArrayInit(16, sizeof(tb_uid_t)); - vnodeGetStbIdList(pInfo->readHandle.vnode, 0, stbUidList); - if (vnodeGetStbIdList(pInfo->readHandle.vnode, 0, stbUidList) < 0) { - qError("vgId:%d, failed to get stb id list error: %s", vgId, terrstr()); - taosArrayDestroy(stbUidList); - // return failure - } - for (int i = 0; i < taosArrayGetSize(stbUidList); ++i) { - tb_uid_t stbUid = *(tb_uid_t*)taosArrayGet(stbUidList, i); - SMetaStbStats stats = {0}; - metaGetStbStats(pInfo->readHandle.meta, stbUid, &stats); - int64_t ctbNum = stats.ctbNum; - - char varStbName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; - metaGetTableNameByUid(pInfo->readHandle.meta, stbUid, varStbName); - } - taosArrayDestroy(stbUidList); -} -return NULL; + return pRes->info.rows > 0 ? pRes : pRes; } static void destoryTableCountScanOperator(void* param) { @@ -5066,5 +5066,6 @@ static void destoryTableCountScanOperator(void* param) { blockDataDestroy(pTableCountScanInfo->pRes); nodesDestroyList(pTableCountScanInfo->groupTags); + taosArrayDestroy(pTableCountScanInfo->stbUidList); taosMemoryFreeClear(param); } From b289adce9b7349a1a160f94dfd1f850e3ced7ef8 Mon Sep 17 00:00:00 2001 From: slzhou Date: Mon, 28 Nov 2022 11:12:06 +0800 Subject: [PATCH 10/33] fix: save work --- source/libs/executor/src/scanoperator.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 78a8f9e706..743b5d8a84 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -5002,7 +5002,6 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { { // get dbname vnodeGetInfo(pInfo->readHandle.vnode, &db, &vgId); - SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 0); SName sn = {0}; tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB); tNameGetDbName(&sn, dbName); @@ -5019,23 +5018,21 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { if (pInfo->currGrpIdx < taosArrayGetSize(pInfo->stbUidList)) { tb_uid_t stbUid = *(tb_uid_t*)taosArrayGet(pInfo->stbUidList, pInfo->currGrpIdx); - SMetaStbStats stats = {0}; - metaGetStbStats(pInfo->readHandle.meta, stbUid, &stats); - int64_t ctbNum = stats.ctbNum; - char stbName[TSDB_TABLE_NAME_LEN] = {0}; metaGetTableSzNameByUid(pInfo->readHandle.meta, stbUid, stbName); char fullStbName[TSDB_TABLE_FNAME_LEN] = {0}; - strcpy(fullStbName, dbName); - strcat(fullStbName, "."); - strcat(fullStbName, stbName); + snprintf(fullStbName, TSDB_TABLE_FNAME_LEN, "%s.%s", dbName, stbName); uint64_t groupId = calcGroupId(fullStbName, strlen(fullStbName)); pRes->info.groupId = groupId; - pInfo->currGrpIdx++; + SMetaStbStats stats = {0}; + metaGetStbStats(pInfo->readHandle.meta, stbUid, &stats); + int64_t ctbNum = stats.ctbNum; fillTableCountScanDataBlock(pSupp, dbName, stbName, ctbNum, pRes); + + pInfo->currGrpIdx++; } } else { // group by only db_name From 37b65c16c8e32cabb991ff1a8637399a62aa3f23 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 29 Nov 2022 14:59:48 +0800 Subject: [PATCH 11/33] enh: ins_tables count optimize --- source/libs/function/src/builtins.c | 2 +- source/libs/planner/src/planOptimizer.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 3e2bc2a4ac..a2a827e7e5 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -2081,7 +2081,7 @@ static int32_t translateTagsPseudoColumn(SFunctionNode* pFunc, char* pErrBuf, in } static int32_t translateTableCountPseudoColumn(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { - pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes, .type = TSDB_DATA_TYPE_INT}; + pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT}; return TSDB_CODE_SUCCESS; } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 515d594e45..4f288f97d3 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2630,9 +2630,11 @@ 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); + if (NULL == pInfo->pAgg->pGroupKeys) { + 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->pScanCols); NODES_DESTORY_LIST(pInfo->pScan->pScanPseudoCols); int32_t code = nodesListMakeStrictAppend(&pInfo->pScan->pScanPseudoCols, tbCntScanOptCreateTableCountFunc()); if (TSDB_CODE_SUCCESS == code) { @@ -2672,7 +2674,7 @@ static int32_t tbCntScanOptRewriteAgg(SAggLogicNode* pAgg) { SNode* pSum = NULL; int32_t code = tbCntScanOptCreateSumFunc( (SFunctionNode*)nodesListGetNode(pAgg->pAggFuncs, 0), - nodesListGetNode(((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))->pTargets, 0), &pSum); + nodesListGetNode(((SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))->pScanPseudoCols, 0), &pSum); if (TSDB_CODE_SUCCESS == code) { NODES_DESTORY_LIST(pAgg->pAggFuncs); code = nodesListMakeStrictAppend(&pAgg->pAggFuncs, pSum); From 8ee170bef1c5b5a64c6d415d0e8317c74e31034e Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Tue, 29 Nov 2022 16:17:05 +0800 Subject: [PATCH 12/33] enh: add retry for vnode closed case --- include/libs/executor/executor.h | 2 +- include/util/taoserror.h | 1 + source/libs/executor/inc/executorimpl.h | 2 +- source/libs/executor/src/executor.c | 4 ++-- source/libs/executor/src/executorimpl.c | 15 ++------------- source/libs/qworker/inc/qwInt.h | 2 +- source/libs/qworker/src/qwUtil.c | 4 ++-- source/libs/qworker/src/qworker.c | 18 ++++++++++-------- source/libs/qworker/test/qworkerTests.cpp | 2 +- source/util/src/terror.c | 1 + 10 files changed, 22 insertions(+), 29 deletions(-) diff --git a/include/libs/executor/executor.h b/include/libs/executor/executor.h index 0bca254e14..1413b41756 100644 --- a/include/libs/executor/executor.h +++ b/include/libs/executor/executor.h @@ -152,7 +152,7 @@ void qCleanExecTaskBlockBuf(qTaskInfo_t tinfo); * @param tinfo qhandle * @return */ -int32_t qAsyncKillTask(qTaskInfo_t tinfo); +int32_t qAsyncKillTask(qTaskInfo_t tinfo, int32_t rspCode); /** * destroy query info structure diff --git a/include/util/taoserror.h b/include/util/taoserror.h index e5d0bcb249..ba7c72e0f3 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -323,6 +323,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_VND_COL_NOT_EXISTS TAOS_DEF_ERROR_CODE(0, 0x0526) #define TSDB_CODE_VND_COL_SUBSCRIBED TAOS_DEF_ERROR_CODE(0, 0x0527) #define TSDB_CODE_VND_NO_AVAIL_BUFPOOL TAOS_DEF_ERROR_CODE(0, 0x0528) +#define TSDB_CODE_VND_STOPPED TAOS_DEF_ERROR_CODE(0, 0x0529) // tsdb #define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 8163217039..e18a6916dd 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -796,7 +796,7 @@ void setInputDataBlock(SExprSupp* pExprSupp, SSDataBlock* pBlock, int32_t order, int32_t checkForQueryBuf(size_t numOfTables); bool isTaskKilled(SExecTaskInfo* pTaskInfo); -void setTaskKilled(SExecTaskInfo* pTaskInfo); +void setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode); void doDestroyTask(SExecTaskInfo* pTaskInfo); void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status); diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index 34bd9cf8ca..fd4dd3bd12 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -688,7 +688,7 @@ void qStopTaskOperators(SExecTaskInfo* pTaskInfo) { taosWUnLockLatch(&pTaskInfo->stopInfo.lock); } -int32_t qAsyncKillTask(qTaskInfo_t qinfo) { +int32_t qAsyncKillTask(qTaskInfo_t qinfo, int32_t rspCode) { SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)qinfo; if (pTaskInfo == NULL) { @@ -697,7 +697,7 @@ int32_t qAsyncKillTask(qTaskInfo_t qinfo) { qDebug("%s execTask async killed", GET_TASKID(pTaskInfo)); - setTaskKilled(pTaskInfo); + setTaskKilled(pTaskInfo, rspCode); qStopTaskOperators(pTaskInfo); diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 300ba52934..2766b48744 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -611,21 +611,10 @@ void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pB } bool isTaskKilled(SExecTaskInfo* pTaskInfo) { - // query has been executed more than tsShellActivityTimer, and the retrieve has not arrived - // abort current query execution. - if (pTaskInfo->owner != 0 && - ((taosGetTimestampSec() - pTaskInfo->cost.start / 1000) > 10 * getMaximumIdleDurationSec()) - /*(!needBuildResAfterQueryComplete(pTaskInfo))*/) { - assert(pTaskInfo->cost.start != 0); - // qDebug("QInfo:%" PRIu64 " retrieve not arrive beyond %d ms, abort current query execution, start:%" PRId64 - // ", current:%d", pQInfo->qId, 1, pQInfo->startExecTs, taosGetTimestampSec()); - // return true; - } - - return false; + return (0 != pTaskInfo->code) ? true : false; } -void setTaskKilled(SExecTaskInfo* pTaskInfo) { pTaskInfo->code = TSDB_CODE_TSC_QUERY_CANCELLED; } +void setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode) { pTaskInfo->code = rspCode; } ///////////////////////////////////////////////////////////////////////////////////////////// STimeWindow getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key) { diff --git a/source/libs/qworker/inc/qwInt.h b/source/libs/qworker/inc/qwInt.h index a0e04b6a19..af361323a7 100644 --- a/source/libs/qworker/inc/qwInt.h +++ b/source/libs/qworker/inc/qwInt.h @@ -363,7 +363,7 @@ int32_t qwAcquireTaskCtx(QW_FPARAMS_DEF, SQWTaskCtx **ctx); int32_t qwGetTaskCtx(QW_FPARAMS_DEF, SQWTaskCtx **ctx); int32_t qwAddAcquireTaskCtx(QW_FPARAMS_DEF, SQWTaskCtx **ctx); void qwReleaseTaskCtx(SQWorker *mgmt, void *ctx); -int32_t qwKillTaskHandle(SQWTaskCtx *ctx); +int32_t qwKillTaskHandle(SQWTaskCtx *ctx, int32_t rspCode); int32_t qwUpdateTaskStatus(QW_FPARAMS_DEF, int8_t status); int32_t qwDropTask(QW_FPARAMS_DEF); void qwSaveTbVersionInfo(qTaskInfo_t pTaskInfo, SQWTaskCtx *ctx); diff --git a/source/libs/qworker/src/qwUtil.c b/source/libs/qworker/src/qwUtil.c index 2c0a4072ae..86fd1d533c 100644 --- a/source/libs/qworker/src/qwUtil.c +++ b/source/libs/qworker/src/qwUtil.c @@ -279,14 +279,14 @@ void qwFreeTaskHandle(qTaskInfo_t *taskHandle) { } } -int32_t qwKillTaskHandle(SQWTaskCtx *ctx) { +int32_t qwKillTaskHandle(SQWTaskCtx *ctx, int32_t rspCode) { int32_t code = 0; // Note: free/kill may in RC qTaskInfo_t taskHandle = atomic_load_ptr(&ctx->taskHandle); if (taskHandle && atomic_val_compare_exchange_ptr(&ctx->taskHandle, taskHandle, NULL)) { qDebug("start to kill task"); - code = qAsyncKillTask(taskHandle); + code = qAsyncKillTask(taskHandle, rspCode); atomic_store_ptr(&ctx->taskHandle, taskHandle); } diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c index 0890d10b65..9a318df324 100644 --- a/source/libs/qworker/src/qworker.c +++ b/source/libs/qworker/src/qworker.c @@ -411,7 +411,7 @@ int32_t qwHandlePrePhaseEvents(QW_FPARAMS_DEF, int8_t phase, SQWPhaseInput *inpu // qwBuildAndSendDropRsp(&ctx->ctrlConnInfo, code); // QW_TASK_DLOG("drop rsp send, handle:%p, code:%x - %s", ctx->ctrlConnInfo.handle, code, tstrerror(code)); - QW_ERR_JRET(TSDB_CODE_QRY_TASK_DROPPED); + QW_ERR_JRET(ctx->rspCode); } QW_ERR_JRET(qwUpdateTaskStatus(QW_FPARAMS(), JOB_TASK_STATUS_EXEC)); @@ -420,7 +420,7 @@ int32_t qwHandlePrePhaseEvents(QW_FPARAMS_DEF, int8_t phase, SQWPhaseInput *inpu case QW_PHASE_PRE_FETCH: { if (QW_EVENT_PROCESSED(ctx, QW_EVENT_DROP) || QW_EVENT_RECEIVED(ctx, QW_EVENT_DROP)) { QW_TASK_WLOG("task dropping or already dropped, phase:%s", qwPhaseStr(phase)); - QW_ERR_JRET(TSDB_CODE_QRY_TASK_DROPPED); + QW_ERR_JRET(ctx->rspCode); } if (QW_EVENT_RECEIVED(ctx, QW_EVENT_FETCH)) { @@ -442,7 +442,7 @@ int32_t qwHandlePrePhaseEvents(QW_FPARAMS_DEF, int8_t phase, SQWPhaseInput *inpu case QW_PHASE_PRE_CQUERY: { if (QW_EVENT_PROCESSED(ctx, QW_EVENT_DROP)) { QW_TASK_WLOG("task already dropped, phase:%s", qwPhaseStr(phase)); - QW_ERR_JRET(TSDB_CODE_QRY_TASK_DROPPED); + QW_ERR_JRET(ctx->rspCode); } if (ctx->rspCode) { @@ -456,7 +456,7 @@ int32_t qwHandlePrePhaseEvents(QW_FPARAMS_DEF, int8_t phase, SQWPhaseInput *inpu // qwBuildAndSendDropRsp(&ctx->ctrlConnInfo, code); // QW_TASK_DLOG("drop rsp send, handle:%p, code:%x - %s", ctx->ctrlConnInfo.handle, code, tstrerror(code)); - QW_ERR_JRET(TSDB_CODE_QRY_TASK_DROPPED); + QW_ERR_JRET(ctx->rspCode); } break; @@ -502,7 +502,7 @@ int32_t qwHandlePostPhaseEvents(QW_FPARAMS_DEF, int8_t phase, SQWPhaseInput *inp if (QW_EVENT_PROCESSED(ctx, QW_EVENT_DROP)) { QW_TASK_WLOG("task already dropped, phase:%s", qwPhaseStr(phase)); - QW_ERR_JRET(TSDB_CODE_QRY_TASK_DROPPED); + QW_ERR_JRET(ctx->rspCode); } if (QW_EVENT_RECEIVED(ctx, QW_EVENT_DROP)) { @@ -515,7 +515,7 @@ int32_t qwHandlePostPhaseEvents(QW_FPARAMS_DEF, int8_t phase, SQWPhaseInput *inp // QW_TASK_DLOG("drop rsp send, handle:%p, code:%x - %s", ctx->ctrlConnInfo.handle, code, tstrerror(code)); QW_ERR_JRET(qwDropTask(QW_FPARAMS())); - QW_ERR_JRET(TSDB_CODE_QRY_TASK_DROPPED); + QW_ERR_JRET(ctx->rspCode); } if (ctx->rspCode) { @@ -861,7 +861,7 @@ int32_t qwProcessDrop(QW_FPARAMS_DEF, SQWMsg *qwMsg) { } if (QW_QUERY_RUNNING(ctx)) { - QW_ERR_JRET(qwKillTaskHandle(ctx)); + QW_ERR_JRET(qwKillTaskHandle(ctx, TSDB_CODE_TSC_QUERY_CANCELLED)); qwUpdateTaskStatus(QW_FPARAMS(), JOB_TASK_STATUS_DROP); } else { QW_ERR_JRET(qwDropTask(QW_FPARAMS())); @@ -869,6 +869,7 @@ int32_t qwProcessDrop(QW_FPARAMS_DEF, SQWMsg *qwMsg) { } if (!dropped) { + QW_UPDATE_RSP_CODE(ctx, TSDB_CODE_TSC_QUERY_CANCELLED); QW_SET_EVENT_RECEIVED(ctx, QW_EVENT_DROP); } @@ -1195,8 +1196,9 @@ void qWorkerStopAllTasks(void *qWorkerMgmt) { } if (QW_QUERY_RUNNING(ctx)) { - qwKillTaskHandle(ctx); + qwKillTaskHandle(ctx, TSDB_CODE_VND_STOPPED); } else if (!QW_EVENT_PROCESSED(ctx, QW_EVENT_DROP)) { + QW_UPDATE_RSP_CODE(ctx, TSDB_CODE_VND_STOPPED); QW_SET_EVENT_RECEIVED(ctx, QW_EVENT_DROP); } diff --git a/source/libs/qworker/test/qworkerTests.cpp b/source/libs/qworker/test/qworkerTests.cpp index 8a48977c77..02b341e28c 100644 --- a/source/libs/qworker/test/qworkerTests.cpp +++ b/source/libs/qworker/test/qworkerTests.cpp @@ -302,7 +302,7 @@ int32_t qwtExecTask(qTaskInfo_t tinfo, SSDataBlock **pRes, uint64_t *useconds) { return 0; } -int32_t qwtKillTask(qTaskInfo_t qinfo) { return 0; } +int32_t qwtKillTask(qTaskInfo_t qinfo, int32_t rspCode) { return 0; } void qwtDestroyTask(qTaskInfo_t qHandle) {} diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 4d889843e8..35f59c4881 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -315,6 +315,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_COL_ALREADY_EXISTS, "Table column already TAOS_DEFINE_ERROR(TSDB_CODE_VND_COL_NOT_EXISTS, "Table column not exists") TAOS_DEFINE_ERROR(TSDB_CODE_VND_COL_SUBSCRIBED, "Table column is subscribed") TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_AVAIL_BUFPOOL, "No availabe buffer pool") +TAOS_DEFINE_ERROR(TSDB_CODE_VND_STOPPED, "Vnode stopped") // tsdb TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INVALID_TABLE_ID, "Invalid table ID") From 9465d100a2708b303f31f5420f07752fb6c973db Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Wed, 30 Nov 2022 15:31:01 +0800 Subject: [PATCH 13/33] enh: ins_table count optimize --- source/libs/parser/src/parAstParser.c | 3 ++- source/libs/planner/src/planOptimizer.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index 8c5806ebe1..d4e486db6b 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -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); } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 4f288f97d3..6627dfbae8 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2658,7 +2658,7 @@ static int32_t tbCntScanOptCreateSumFunc(SFunctionNode* pCntFunc, SNode* pParam, } strcpy(pFunc->functionName, "sum"); strcpy(pFunc->node.aliasName, pCntFunc->node.aliasName); - int32_t code = nodesListMakeStrictAppend(&pFunc->pParameterList, nodesCloneNode(pParam)); + int32_t code = createColumnByRewriteExpr(pParam, &pFunc->pParameterList); if (TSDB_CODE_SUCCESS == code) { code = fmGetFuncInfo(pFunc, NULL, 0); } From 259b893f0a9e31671b1c803ab5c005f223de00c2 Mon Sep 17 00:00:00 2001 From: slzhou Date: Wed, 30 Nov 2022 15:42:45 +0800 Subject: [PATCH 14/33] fix: integration test of table count scan --- source/libs/executor/src/scanoperator.c | 31 ++++++++++++++++++------- source/libs/nodes/src/nodesMsgFuncs.c | 4 ++-- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index fcdd4dd86b..f01781fd2b 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -3028,7 +3028,7 @@ SOperatorInfo* createTableCountScanOperatorInfo(SReadHandle* readHandle, STableC int32_t code = TSDB_CODE_SUCCESS; SScanPhysiNode* pScanNode = &pTblCountScanNode->scan; - STableCountScanOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableCountScanSupp)); + STableCountScanOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableCountScanOperatorInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); if (!pInfo || !pOperator) { @@ -3082,19 +3082,19 @@ void fillTableCountScanDataBlock(STableCountScanSupp* pSupp, char* dbName, char* } if (pSupp->tbCountSlotId != -1) { - SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->stbNameSlotId); + SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->tbCountSlotId); colDataAppend(colInfoData, 0, (char*)&count, false); } pRes->info.rows = 1; } -static SSDataBlock* buildSysDbTableCount(STableCountScanOperatorInfo* pInfo) { +static SSDataBlock* buildSysDbTableCount(SOperatorInfo* pOperator, STableCountScanOperatorInfo* pInfo) { STableCountScanSupp* pSupp = &pInfo->supp; SSDataBlock* pRes = pInfo->pRes; - int64_t infodbTableNum; + size_t infodbTableNum; getInfosDbMeta(NULL, &infodbTableNum); - int64_t perfdbTableNum; + size_t perfdbTableNum; getPerfDbMeta(NULL, &perfdbTableNum); if (pSupp->groupByDbName) { @@ -3106,6 +3106,9 @@ static SSDataBlock* buildSysDbTableCount(STableCountScanOperatorInfo* pInfo) { 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; @@ -3117,6 +3120,7 @@ static SSDataBlock* buildSysDbTableCount(STableCountScanOperatorInfo* pInfo) { } else if (strlen(pSupp->dbName) == 0) { fillTableCountScanDataBlock(pSupp, "", "", infodbTableNum + perfdbTableNum, pRes); } + setOperatorCompleted(pOperator); return (pRes->info.rows > 0) ? pRes : NULL; } } @@ -3131,8 +3135,11 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { // grouptags high priority(groupid<=>grouptag), then tablename(dbname,tableName). // scanCols, (grouptags cols) // mnode, query table count of information_schema and performance_schema + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } if (pInfo->readHandle.mnd != NULL) { - return buildSysDbTableCount(pInfo); + return buildSysDbTableCount(pOperator, pInfo); } const char* db = NULL; @@ -3173,6 +3180,9 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { fillTableCountScanDataBlock(pSupp, dbName, stbName, ctbNum, pRes); pInfo->currGrpIdx++; + } else { + setOperatorCompleted(pOperator); + return NULL; } } else { // group by only db_name @@ -3180,6 +3190,7 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { 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) { @@ -3191,11 +3202,15 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { fillTableCountScanDataBlock(pSupp, dbName, pSupp->stbName, ctbNum, pRes); } else { int64_t tbNumVnode = metaGetTbNum(pInfo->readHandle.meta); - fillTableCountScanDataBlock(pSupp, pSupp->dbName, "", tbNumVnode, pRes); + 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 : pRes; + return pRes->info.rows > 0 ? pRes : NULL; } static void destoryTableCountScanOperator(void* param) { diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index d054cda745..bf6cd33af7 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -3637,10 +3637,10 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { break; case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: - case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: 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: @@ -3776,10 +3776,10 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) { break; case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: - case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: 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: From 45ecc2ba529c7c4fc5a4e276f98c0b2220502843 Mon Sep 17 00:00:00 2001 From: slzhou Date: Wed, 30 Nov 2022 19:52:29 +0800 Subject: [PATCH 15/33] fix: no result for table cout scan group by dbname,stable_name for systable --- source/libs/executor/src/scanoperator.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 98b8d46aae..7bcc2e6a0e 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -3099,6 +3099,10 @@ static SSDataBlock* buildSysDbTableCount(SOperatorInfo* pOperator, STableCountSc getPerfDbMeta(NULL, &perfdbTableNum); if (pSupp->groupByDbName) { + if (pSupp->groupByStbName) { + setOperatorCompleted(pOperator); + return NULL; + } if (pInfo->currGrpIdx == 0) { uint64_t groupId = calcGroupId(TSDB_INFORMATION_SCHEMA_DB, strlen(TSDB_INFORMATION_SCHEMA_DB)); pRes->info.id.groupId = groupId; From 89be771b6172bb04e19b72e8193889daa523bcee Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Thu, 1 Dec 2022 09:53:41 +0800 Subject: [PATCH 16/33] enh: add retry for vnode stopped case --- include/libs/qcom/query.h | 2 +- source/dnode/mgmt/node_mgmt/src/dmTransport.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index f51aa88485..ef543470aa 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -260,7 +260,7 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t (NEED_CLIENT_RM_TBLMETA_ERROR(_code) || NEED_CLIENT_REFRESH_VG_ERROR(_code) || \ NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code)) -#define SYNC_UNKNOWN_LEADER_REDIRECT_ERROR(_code) ((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR) +#define SYNC_UNKNOWN_LEADER_REDIRECT_ERROR(_code) ((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR || (_code) == TSDB_CODE_VND_STOPPED) #define SYNC_SELF_LEADER_REDIRECT_ERROR(_code) ((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR) #define SYNC_OTHER_LEADER_REDIRECT_ERROR(_code) (false) // used later diff --git a/source/dnode/mgmt/node_mgmt/src/dmTransport.c b/source/dnode/mgmt/node_mgmt/src/dmTransport.c index 95656fd76c..b9b7477952 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmTransport.c +++ b/source/dnode/mgmt/node_mgmt/src/dmTransport.c @@ -234,7 +234,8 @@ static inline void dmReleaseHandle(SRpcHandleInfo *pHandle, int8_t type) { rpcRe static bool rpcRfp(int32_t code, tmsg_t msgType) { if (code == TSDB_CODE_RPC_REDIRECT || code == TSDB_CODE_RPC_NETWORK_UNAVAIL || code == TSDB_CODE_NODE_NOT_DEPLOYED || - code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_APP_NOT_READY || code == TSDB_CODE_RPC_BROKEN_LINK) { + code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_APP_NOT_READY || code == TSDB_CODE_RPC_BROKEN_LINK || + code == TSDB_CODE_VND_STOPPED) { if (msgType == TDMT_SCH_QUERY || msgType == TDMT_SCH_MERGE_QUERY || msgType == TDMT_SCH_FETCH || msgType == TDMT_SCH_MERGE_FETCH) { return false; From eea8d7bebbcb642c028b03bebb85ec114a71088d Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 1 Dec 2022 10:48:36 +0800 Subject: [PATCH 17/33] enh: ins_table count optimize --- source/libs/parser/test/mockCatalog.cpp | 2 +- source/libs/planner/src/planOptimizer.c | 27 ++++++++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index 935ef77b93..bc12861dc7 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -66,8 +66,8 @@ void generateInformationSchema(MockCatalogService* mcs) { .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, 3) - .addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN) .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) diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 6627dfbae8..2af09f8f8b 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2630,10 +2630,8 @@ 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); - if (NULL == pInfo->pAgg->pGroupKeys) { - NODES_DESTORY_LIST(pInfo->pScan->node.pTargets); - NODES_DESTORY_LIST(pInfo->pScan->pScanCols); - } + 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()); @@ -2642,8 +2640,14 @@ static int32_t tbCntScanOptRewriteScan(STbCntScanOptInfo* pInfo) { } SNode* pGroupKey = NULL; FOREACH(pGroupKey, pInfo->pAgg->pGroupKeys) { - code = nodesListMakeStrictAppend( - &pInfo->pScan->pGroupTags, nodesCloneNode(nodesListGetNode(((SGroupingSetNode*)pGroupKey)->pParameterList, 0))); + 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; } @@ -2671,14 +2675,17 @@ static int32_t tbCntScanOptCreateSumFunc(SFunctionNode* pCntFunc, SNode* pParam, } static int32_t tbCntScanOptRewriteAgg(SAggLogicNode* pAgg) { - SNode* pSum = NULL; - int32_t code = tbCntScanOptCreateSumFunc( - (SFunctionNode*)nodesListGetNode(pAgg->pAggFuncs, 0), - nodesListGetNode(((SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))->pScanPseudoCols, 0), &pSum); + 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; } From 58c75dde6ff082a1cbb9070b76a619d8bd3265dc Mon Sep 17 00:00:00 2001 From: slzhou Date: Thu, 1 Dec 2022 11:38:34 +0800 Subject: [PATCH 18/33] fix: add seperate group for normal table when group by db_name/stbable_name --- source/dnode/vnode/inc/vnode.h | 26 +++++++++--------- source/dnode/vnode/src/meta/metaQuery.c | 4 +++ source/libs/executor/src/scanoperator.c | 35 ++++++++++++++----------- 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index fe2892a76b..756e23deeb 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -107,23 +107,23 @@ 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 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); - +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); +int32_t metaGetStbStats(SMeta *pMeta, int64_t uid, SMetaStbStats *pInfo); typedef struct SMetaFltParam { tb_uid_t suid; diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index 8fb93f2c2e..cfdb4ab8d1 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -756,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; diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index db508b43f9..437e3e1393 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -3050,7 +3050,7 @@ _error: void fillTableCountScanDataBlock(STableCountScanSupp* pSupp, char* dbName, char* stbName, int64_t count, SSDataBlock* pRes) { if (pSupp->dbNameSlotId != -1) { - ASSERT(strlen(dbName)); + ASSERT(strlen(pSupp->dbName)); SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->dbNameSlotId); char varDbName[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0}; strncpy(varDataVal(varDbName), dbName, strlen(dbName)); @@ -3059,12 +3059,15 @@ void fillTableCountScanDataBlock(STableCountScanSupp* pSupp, char* dbName, char* } if (pSupp->stbNameSlotId != -1) { - ASSERT(strlen(stbName)); SColumnInfoData* colInfoData = taosArrayGet(pRes->pDataBlock, pSupp->stbNameSlotId); - 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); + 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) { @@ -3084,10 +3087,6 @@ static SSDataBlock* buildSysDbTableCount(SOperatorInfo* pOperator, STableCountSc getPerfDbMeta(NULL, &perfdbTableNum); if (pSupp->groupByDbName) { - if (pSupp->groupByStbName) { - setOperatorCompleted(pOperator); - return NULL; - } if (pInfo->currGrpIdx == 0) { uint64_t groupId = calcGroupId(TSDB_INFORMATION_SCHEMA_DB, strlen(TSDB_INFORMATION_SCHEMA_DB)); pRes->info.id.groupId = groupId; @@ -3121,10 +3120,7 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { STableCountScanSupp* pSupp = &pInfo->supp; SSDataBlock* pRes = pInfo->pRes; blockDataCleanup(pRes); - // compute group id must, but output is according to scancols. output group by group - // grouptags high priority(groupid<=>grouptag), then tablename(dbname,tableName). - // scanCols, (grouptags cols) - // mnode, query table count of information_schema and performance_schema + if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -3145,7 +3141,6 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { } if (pSupp->groupByDbName) { if (pSupp->groupByStbName) { - // group by db_name and stable_name if (pInfo->stbUidList == NULL) { pInfo->stbUidList = taosArrayInit(16, sizeof(tb_uid_t)); if (vnodeGetStbIdList(pInfo->readHandle.vnode, 0, pInfo->stbUidList) < 0) { @@ -3169,13 +3164,21 @@ static SSDataBlock* doTableCountScan(SOperatorInfo* pOperator) { 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 { - // group by only db_name uint64_t groupId = calcGroupId(dbName, strlen(dbName)); pRes->info.id.groupId = groupId; int64_t dbTableCount = metaGetTbNum(pInfo->readHandle.meta); From 6e73c89e504038577d273880637689a14343f500 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Thu, 1 Dec 2022 12:22:03 +0800 Subject: [PATCH 19/33] fix: executor returns kill task error code --- source/libs/executor/src/exchangeoperator.c | 6 +++--- source/libs/executor/src/scanoperator.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/libs/executor/src/exchangeoperator.c b/source/libs/executor/src/exchangeoperator.c index 963a273290..53660d88e1 100644 --- a/source/libs/executor/src/exchangeoperator.c +++ b/source/libs/executor/src/exchangeoperator.c @@ -70,7 +70,7 @@ static void concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeIn tsem_wait(&pExchangeInfo->ready); if (isTaskKilled(pTaskInfo)) { - longjmp(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED); + longjmp(pTaskInfo->env, pTaskInfo->code); } for (int32_t i = 0; i < totalSources; ++i) { @@ -573,7 +573,7 @@ int32_t prepareConcurrentlyLoad(SOperatorInfo* pOperator) { tsem_wait(&pExchangeInfo->ready); if (isTaskKilled(pTaskInfo)) { - longjmp(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED); + longjmp(pTaskInfo->env, pTaskInfo->code); } tsem_post(&pExchangeInfo->ready); @@ -621,7 +621,7 @@ int32_t seqLoadRemoteData(SOperatorInfo* pOperator) { doSendFetchDataRequest(pExchangeInfo, pTaskInfo, pExchangeInfo->current); tsem_wait(&pExchangeInfo->ready); if (isTaskKilled(pTaskInfo)) { - longjmp(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED); + longjmp(pTaskInfo->env, pTaskInfo->code); } SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, pExchangeInfo->current); diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index b6353061fb..3c4ed00000 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -629,7 +629,7 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) { while (tsdbNextDataBlock(pTableScanInfo->base.dataReader)) { if (isTaskKilled(pTaskInfo)) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED); + T_LONG_JMP(pTaskInfo->env, pTaskInfo->code); } // process this data block based on the probabilities @@ -2032,7 +2032,7 @@ static SSDataBlock* doRawScan(SOperatorInfo* pOperator) { if (pInfo->dataReader && tsdbNextDataBlock(pInfo->dataReader)) { if (isTaskKilled(pTaskInfo)) { - longjmp(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED); + longjmp(pTaskInfo->env, pTaskInfo->code); } int32_t rows = 0; @@ -2529,7 +2529,7 @@ static SSDataBlock* getTableDataBlockImpl(void* param) { STsdbReader* reader = pInfo->base.dataReader; while (tsdbNextDataBlock(reader)) { if (isTaskKilled(pTaskInfo)) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED); + T_LONG_JMP(pTaskInfo->env, pTaskInfo->code); } // process this data block based on the probabilities From 98726f17fa13b21fe88fd41f2536396528833f16 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Thu, 1 Dec 2022 14:54:58 +0800 Subject: [PATCH 20/33] fix: redirect handler issue --- source/libs/scheduler/src/schTask.c | 10 +++++----- source/libs/transport/src/transCli.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/libs/scheduler/src/schTask.c b/source/libs/scheduler/src/schTask.c index 9a7f3332b3..289fb35032 100644 --- a/source/libs/scheduler/src/schTask.c +++ b/source/libs/scheduler/src/schTask.c @@ -430,15 +430,15 @@ int32_t schDoTaskRedirect(SSchJob *pJob, SSchTask *pTask, SDataBuf *pData, int32 if (SCH_IS_DATA_BIND_TASK(pTask)) { if (pData && pData->pEpSet) { SCH_ERR_JRET(schUpdateTaskCandidateAddr(pJob, pTask, pData->pEpSet)); - } else if (SYNC_UNKNOWN_LEADER_REDIRECT_ERROR(rspCode)) { - SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); - SCH_SWITCH_EPSET(addr); - SCH_TASK_DLOG("switch task target node %d epset to %d/%d", addr->nodeId, addr->epSet.inUse, addr->epSet.numOfEps); - } else { + } else if (SYNC_SELF_LEADER_REDIRECT_ERROR(rspCode)) { SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); SEp *pEp = &addr->epSet.eps[addr->epSet.inUse]; SCH_TASK_DLOG("task retry node %d current ep, idx:%d/%d,%s:%d", addr->nodeId, addr->epSet.inUse, addr->epSet.numOfEps, pEp->fqdn, pEp->port); + } else { + SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); + SCH_SWITCH_EPSET(addr); + SCH_TASK_DLOG("switch task target node %d epset to %d/%d", addr->nodeId, addr->epSet.inUse, addr->epSet.numOfEps); } if (SCH_TASK_NEED_FLOW_CTRL(pJob, pTask)) { diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c index fbcc1fb525..4003a74ec7 100644 --- a/source/libs/transport/src/transCli.c +++ b/source/libs/transport/src/transCli.c @@ -1512,7 +1512,7 @@ bool cliGenRetryRule(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) { transFreeMsg(pResp->pCont); transUnrefCliHandle(pConn); } else if (code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_SYN_INTERNAL_ERROR || - code == TSDB_CODE_SYN_PROPOSE_NOT_READY || code == TSDB_CODE_RPC_REDIRECT) { + code == TSDB_CODE_SYN_PROPOSE_NOT_READY || code == TSDB_CODE_RPC_REDIRECT || TSDB_CODE_VND_STOPPED) { tDebug("code str %s, contlen:%d 1", tstrerror(code), pResp->contLen); noDelay = cliResetEpset(pCtx, pResp, true); transFreeMsg(pResp->pCont); From b8ed0459a605094a5ab2d29c1b0429bc6b582c7a Mon Sep 17 00:00:00 2001 From: slzhou Date: Thu, 1 Dec 2022 16:50:23 +0800 Subject: [PATCH 21/33] fix: change the paramter instead of table name --- source/libs/executor/src/scanoperator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 437e3e1393..3dd027ad04 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -3050,7 +3050,7 @@ _error: void fillTableCountScanDataBlock(STableCountScanSupp* pSupp, char* dbName, char* stbName, int64_t count, SSDataBlock* pRes) { if (pSupp->dbNameSlotId != -1) { - ASSERT(strlen(pSupp->dbName)); + 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)); From a2de81e9085b9abf2d0137a8bfda18ae5e40648a Mon Sep 17 00:00:00 2001 From: slzhou Date: Thu, 1 Dec 2022 16:58:47 +0800 Subject: [PATCH 22/33] fix: fill scan type for select count(*) from ins_tables --- source/libs/executor/src/executorimpl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 60749aa552..b539d63037 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -1381,7 +1381,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; From 233377444c990a5d21920bb777ce98f51d9f67fa Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 1 Dec 2022 17:57:53 +0800 Subject: [PATCH 23/33] enh: ins_table count optimize --- source/libs/command/inc/commandInt.h | 1 + source/libs/command/src/explain.c | 48 +++++++++++++++++++++++++ source/libs/parser/src/parTranslater.c | 2 +- source/libs/planner/src/planOptimizer.c | 3 ++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/source/libs/command/inc/commandInt.h b/source/libs/command/inc/commandInt.h index 4d0c5389e1..6acf19218d 100644 --- a/source/libs/command/inc/commandInt.h +++ b/source/libs/command/inc/commandInt.h @@ -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" diff --git a/source/libs/command/src/explain.c b/source/libs/command/src/explain.c index 410e62a18b..03c7249294 100644 --- a/source/libs/command/src/explain.c +++ b/source/libs/command/src/explain.c @@ -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); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 4c361b91d3..becf58b401 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -2257,7 +2257,7 @@ static int32_t getVnodeSysTableVgroupList(STranslateContext* pCxt, SName* pName, if (TSDB_CODE_SUCCESS == code) { code = getVnodeSysTableVgroupListImpl(pCxt, &targetName, pName, pVgs); } - *pHasUserDbCond = (0 != targetName.type); + *pHasUserDbCond = (0 != targetName.type && taosArrayGetSize(*pVgs) > 0); return code; } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 2af09f8f8b..c370e2c84b 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2598,6 +2598,9 @@ static bool tbCntScanOptIsEligibleScan(STbCntScanOptInfo* pInfo) { 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); } From 7ad0226e32968d5c467091bec6e9d167826197ff Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Thu, 1 Dec 2022 18:04:13 +0800 Subject: [PATCH 24/33] fix: add debug code info --- source/libs/scheduler/src/schTask.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/libs/scheduler/src/schTask.c b/source/libs/scheduler/src/schTask.c index 289fb35032..c8b8db367f 100644 --- a/source/libs/scheduler/src/schTask.c +++ b/source/libs/scheduler/src/schTask.c @@ -391,6 +391,8 @@ int32_t schChkUpdateRedirectCtx(SSchJob *pJob, SSchTask *pTask, SEpSet *pEpSet) int64_t leftTime = tsMaxRetryWaitTime - lastTime; pTask->delayExecMs = leftTime < pCtx->periodMs ? leftTime : pCtx->periodMs; + pCtx->roundTimes = 0; + goto _return; } @@ -407,7 +409,7 @@ _return: int32_t schDoTaskRedirect(SSchJob *pJob, SSchTask *pTask, SDataBuf *pData, int32_t rspCode) { int32_t code = 0; - SCH_TASK_DLOG("task will be redirected now, status:%s", SCH_GET_TASK_STATUS_STR(pTask)); + SCH_TASK_DLOG("task will be redirected now, status:%s, code:%s", SCH_GET_TASK_STATUS_STR(pTask), tstrerror(rspCode)); if (NULL == pData) { pTask->retryTimes = 0; @@ -433,8 +435,8 @@ int32_t schDoTaskRedirect(SSchJob *pJob, SSchTask *pTask, SDataBuf *pData, int32 } else if (SYNC_SELF_LEADER_REDIRECT_ERROR(rspCode)) { SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); SEp *pEp = &addr->epSet.eps[addr->epSet.inUse]; - SCH_TASK_DLOG("task retry node %d current ep, idx:%d/%d,%s:%d", addr->nodeId, addr->epSet.inUse, - addr->epSet.numOfEps, pEp->fqdn, pEp->port); + SCH_TASK_DLOG("task retry node %d current ep, idx:%d/%d,%s:%d, code:%s", addr->nodeId, addr->epSet.inUse, + addr->epSet.numOfEps, pEp->fqdn, pEp->port, tstrerror(rspCode)); } else { SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); SCH_SWITCH_EPSET(addr); From 67d6ea93b06006cbb0b9af9f0a44e4c3448a0da6 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Fri, 2 Dec 2022 10:02:22 +0800 Subject: [PATCH 25/33] enh: ins_table count optimize --- source/libs/parser/src/parTranslater.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index becf58b401..307eefe2bd 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -47,6 +47,7 @@ typedef struct STranslateContext { SParseMetaCache* pMetaCache; bool createStream; bool stableQuery; + bool showRewrite; } STranslateContext; typedef struct SFullDatabaseName { @@ -2222,8 +2223,8 @@ static int32_t getVnodeSysTableVgroupListImpl(STranslateContext* pCxt, SName* pT 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; } @@ -6294,6 +6295,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; @@ -6347,6 +6349,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); @@ -6377,6 +6380,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; @@ -6396,6 +6400,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; @@ -6437,6 +6442,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; From 64a2bd481cb259825e3bd993102ee679f1e9fd50 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Fri, 2 Dec 2022 10:30:23 +0800 Subject: [PATCH 26/33] fix: check subquery time series error --- source/libs/parser/src/parTranslater.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index d2d97f7b90..15682a2cfe 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -750,8 +750,8 @@ static bool isPrimaryKeyImpl(SNode* pExpr) { return (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId); } else if (QUERY_NODE_FUNCTION == nodeType(pExpr)) { SFunctionNode* pFunc = (SFunctionNode*)pExpr; - if (FUNCTION_TYPE_SELECT_VALUE == pFunc->funcType || FUNCTION_TYPE_FIRST == pFunc->funcType || - FUNCTION_TYPE_LAST == pFunc->funcType) { + if (FUNCTION_TYPE_SELECT_VALUE == pFunc->funcType || FUNCTION_TYPE_GROUP_KEY == pFunc->funcType || + FUNCTION_TYPE_FIRST == pFunc->funcType || FUNCTION_TYPE_LAST == pFunc->funcType) { return isPrimaryKeyImpl(nodesListGetNode(pFunc->pParameterList, 0)); } else if (FUNCTION_TYPE_WSTART == pFunc->funcType || FUNCTION_TYPE_WEND == pFunc->funcType) { return true; From 1fcd99176bc71614842f0de54f47828de8178dc8 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Fri, 2 Dec 2022 10:59:52 +0800 Subject: [PATCH 27/33] fix: filter memory leak cause of same const strings --- source/libs/scalar/inc/filterInt.h | 11 +++-- source/libs/scalar/src/filter.c | 65 ++++++++++++++++-------------- 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/source/libs/scalar/inc/filterInt.h b/source/libs/scalar/inc/filterInt.h index e26bc59d47..2023d38777 100644 --- a/source/libs/scalar/inc/filterInt.h +++ b/source/libs/scalar/inc/filterInt.h @@ -101,6 +101,11 @@ typedef int32_t (*filter_desc_compare_func)(const void *, const void *); typedef bool (*filter_exec_func)(void *, int32_t, SColumnInfoData *, SColumnDataAgg *, int16_t, int32_t *); typedef int32_t (*filer_get_col_from_name)(void *, int32_t, char *, void **); +typedef struct SFilterDataInfo { + int32_t idx; + void* addr; +} SFilterDataInfo; + typedef struct SFilterRangeCompare { int64_t s; int64_t e; @@ -294,9 +299,9 @@ struct SFilterInfo { #define CHK_OR_OPTR(ctx) ((ctx)->isnull == true && (ctx)->notnull == true) #define CHK_AND_OPTR(ctx) ((ctx)->isnull == true && (((ctx)->notnull == true) || ((ctx)->isrange == true))) -#define FILTER_GET_FLAG(st, f) (st & f) -#define FILTER_SET_FLAG(st, f) st |= (f) -#define FILTER_CLR_FLAG(st, f) st &= (~f) +#define FILTER_GET_FLAG(st, f) ((st) & (f)) +#define FILTER_SET_FLAG(st, f) (st) |= (f) +#define FILTER_CLR_FLAG(st, f) (st) &= (~f) #define SIMPLE_COPY_VALUES(dst, src) *((int64_t *)dst) = *((int64_t *)src) #define FLT_PACKAGE_UNIT_HASH_KEY(v, op1, op2, lidx, ridx, ridx2) \ diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index 45931c209c..ef92377410 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -963,16 +963,17 @@ int32_t filterGetFiledByDesc(SFilterFields *fields, int32_t type, void *v) { return -1; } -int32_t filterGetFiledByData(SFilterInfo *info, int32_t type, void *v, int32_t dataLen) { +int32_t filterGetFiledByData(SFilterInfo *info, int32_t type, void *v, int32_t dataLen, bool *sameBuf) { if (type == FLD_TYPE_VALUE) { if (info->pctx.valHash == false) { qError("value hash is empty"); return -1; } - void *hv = taosHashGet(info->pctx.valHash, v, dataLen); - if (hv) { - return *(int32_t *)hv; + SFilterDataInfo *dInfo = taosHashGet(info->pctx.valHash, v, dataLen); + if (dInfo) { + *sameBuf = (dInfo->addr == v); + return dInfo->idx; } } @@ -982,9 +983,10 @@ int32_t filterGetFiledByData(SFilterInfo *info, int32_t type, void *v, int32_t d // In the params, we should use void *data instead of void **data, there is no need to use taosMemoryFreeClear(*data) to // set *data = 0 Besides, fields data value is a pointer, so dataLen should be POINTER_BYTES for better. int32_t filterAddField(SFilterInfo *info, void *desc, void **data, int32_t type, SFilterFieldId *fid, int32_t dataLen, - bool freeIfExists) { + bool freeIfExists, int16_t *srcFlag) { int32_t idx = -1; uint32_t *num; + bool sameBuf = false; num = &info->fields[type].num; @@ -992,7 +994,7 @@ int32_t filterAddField(SFilterInfo *info, void *desc, void **data, int32_t type, if (type == FLD_TYPE_COLUMN) { idx = filterGetFiledByDesc(&info->fields[type], type, desc); } else if (data && (*data) && dataLen > 0 && FILTER_GET_FLAG(info->options, FLT_OPTION_NEED_UNIQE)) { - idx = filterGetFiledByData(info, type, *data, dataLen); + idx = filterGetFiledByData(info, type, *data, dataLen, &sameBuf); } } @@ -1020,11 +1022,14 @@ int32_t filterAddField(SFilterInfo *info, void *desc, void **data, int32_t type, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, false); } - taosHashPut(info->pctx.valHash, *data, dataLen, &idx, sizeof(idx)); + SFilterDataInfo dInfo = {idx, *data}; + taosHashPut(info->pctx.valHash, *data, dataLen, &dInfo, sizeof(dInfo)); } - } else { - if (data && freeIfExists) { + } else if (data) { + if (freeIfExists) { taosMemoryFreeClear(*data); + } else if (sameBuf) { + FILTER_SET_FLAG(*srcFlag, FLD_DATA_NO_FREE); } } @@ -1035,7 +1040,7 @@ int32_t filterAddField(SFilterInfo *info, void *desc, void **data, int32_t type, } static FORCE_INLINE int32_t filterAddColFieldFromField(SFilterInfo *info, SFilterField *field, SFilterFieldId *fid) { - filterAddField(info, field->desc, &field->data, FILTER_GET_TYPE(field->flag), fid, 0, false); + filterAddField(info, field->desc, &field->data, FILTER_GET_TYPE(field->flag), fid, 0, false, NULL); FILTER_SET_FLAG(field->flag, FLD_DATA_NO_FREE); @@ -1064,7 +1069,7 @@ int32_t filterAddFieldFromNode(SFilterInfo *info, SNode *node, SFilterFieldId *f v = node; } - filterAddField(info, v, NULL, type, fid, 0, true); + filterAddField(info, v, NULL, type, fid, 0, true, NULL); return TSDB_CODE_SUCCESS; } @@ -1195,7 +1200,7 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) { len = tDataTypes[type].bytes; - filterAddField(info, NULL, (void **)&out.columnData->pData, FLD_TYPE_VALUE, &right, len, true); + filterAddField(info, NULL, (void **)&out.columnData->pData, FLD_TYPE_VALUE, &right, len, true, NULL); out.columnData->pData = NULL; } else { void *data = taosMemoryCalloc(1, tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes); // reserved space for simple_copy @@ -1203,7 +1208,7 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) { FLT_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } memcpy(data, nodesGetValueFromNode(valueNode), tDataTypes[type].bytes); - filterAddField(info, NULL, (void **)&data, FLD_TYPE_VALUE, &right, len, true); + filterAddField(info, NULL, (void **)&data, FLD_TYPE_VALUE, &right, len, true, NULL); } filterAddUnit(info, OP_TYPE_EQUAL, &left, &right, &uidx); @@ -1234,28 +1239,26 @@ int32_t filterAddUnitFromUnit(SFilterInfo *dst, SFilterInfo *src, SFilterUnit *u uint8_t type = FILTER_UNIT_DATA_TYPE(u); uint16_t flag = 0; - filterAddField(dst, FILTER_UNIT_COL_DESC(src, u), NULL, FLD_TYPE_COLUMN, &left, 0, false); + filterAddField(dst, FILTER_UNIT_COL_DESC(src, u), NULL, FLD_TYPE_COLUMN, &left, 0, false, NULL); SFilterField *t = FILTER_UNIT_LEFT_FIELD(src, u); if (u->right.type == FLD_TYPE_VALUE) { void *data = FILTER_UNIT_VAL_DATA(src, u); + SFilterField *rField = FILTER_UNIT_RIGHT_FIELD(src, u); + if (IS_VAR_DATA_TYPE(type)) { if (FILTER_UNIT_OPTR(u) == OP_TYPE_IN) { filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, POINTER_BYTES, - false); // POINTER_BYTES should be sizeof(SHashObj), but POINTER_BYTES is also right. + false, &rField->flag); // POINTER_BYTES should be sizeof(SHashObj), but POINTER_BYTES is also right. t = FILTER_GET_FIELD(dst, right); FILTER_SET_FLAG(t->flag, FLD_DATA_IS_HASH); } else { - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, varDataTLen(data), false); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, varDataTLen(data), false, &rField->flag); } } else { - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, false); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, false, &rField->flag); } - - flag = FLD_DATA_NO_FREE; - t = FILTER_UNIT_RIGHT_FIELD(src, u); - FILTER_SET_FLAG(t->flag, flag); } else { pright = NULL; } @@ -1313,17 +1316,17 @@ int32_t filterAddGroupUnitFromCtx(SFilterInfo *dst, SFilterInfo *src, SFilterRan if (func(&ra->s, &ra->e) == 0) { void *data = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data, &ra->s); - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true, NULL); filterAddUnit(dst, OP_TYPE_EQUAL, &left, &right, &uidx); filterAddUnitToGroup(g, uidx); return TSDB_CODE_SUCCESS; } else { void *data = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data, &ra->s); - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true, NULL); void *data2 = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data2, &ra->e); - filterAddField(dst, NULL, &data2, FLD_TYPE_VALUE, &right2, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data2, FLD_TYPE_VALUE, &right2, tDataTypes[type].bytes, true, NULL); filterAddUnitImpl( dst, FILTER_GET_FLAG(ra->sflag, RANGE_FLG_EXCLUDE) ? OP_TYPE_GREATER_THAN : OP_TYPE_GREATER_EQUAL, &left, @@ -1337,7 +1340,7 @@ int32_t filterAddGroupUnitFromCtx(SFilterInfo *dst, SFilterInfo *src, SFilterRan if (!FILTER_GET_FLAG(ra->sflag, RANGE_FLG_NULL)) { void *data = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data, &ra->s); - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true, NULL); filterAddUnit(dst, FILTER_GET_FLAG(ra->sflag, RANGE_FLG_EXCLUDE) ? OP_TYPE_GREATER_THAN : OP_TYPE_GREATER_EQUAL, &left, &right, &uidx); filterAddUnitToGroup(g, uidx); @@ -1346,7 +1349,7 @@ int32_t filterAddGroupUnitFromCtx(SFilterInfo *dst, SFilterInfo *src, SFilterRan if (!FILTER_GET_FLAG(ra->eflag, RANGE_FLG_NULL)) { void *data = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data, &ra->e); - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true, NULL); filterAddUnit(dst, FILTER_GET_FLAG(ra->eflag, RANGE_FLG_EXCLUDE) ? OP_TYPE_LOWER_THAN : OP_TYPE_LOWER_EQUAL, &left, &right, &uidx); filterAddUnitToGroup(g, uidx); @@ -1393,16 +1396,16 @@ int32_t filterAddGroupUnitFromCtx(SFilterInfo *dst, SFilterInfo *src, SFilterRan if (func(&r->ra.s, &r->ra.e) == 0) { void *data = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data, &r->ra.s); - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true, NULL); filterAddUnit(dst, OP_TYPE_EQUAL, &left, &right, &uidx); filterAddUnitToGroup(g, uidx); } else { void *data = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data, &r->ra.s); - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true, NULL); void *data2 = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data2, &r->ra.e); - filterAddField(dst, NULL, &data2, FLD_TYPE_VALUE, &right2, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data2, FLD_TYPE_VALUE, &right2, tDataTypes[type].bytes, true, NULL); filterAddUnitImpl( dst, FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_EXCLUDE) ? OP_TYPE_GREATER_THAN : OP_TYPE_GREATER_EQUAL, &left, @@ -1421,7 +1424,7 @@ int32_t filterAddGroupUnitFromCtx(SFilterInfo *dst, SFilterInfo *src, SFilterRan if (!FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_NULL)) { void *data = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data, &r->ra.s); - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true, NULL); filterAddUnit(dst, FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_EXCLUDE) ? OP_TYPE_GREATER_THAN : OP_TYPE_GREATER_EQUAL, &left, &right, &uidx); filterAddUnitToGroup(g, uidx); @@ -1430,7 +1433,7 @@ int32_t filterAddGroupUnitFromCtx(SFilterInfo *dst, SFilterInfo *src, SFilterRan if (!FILTER_GET_FLAG(r->ra.eflag, RANGE_FLG_NULL)) { void *data = taosMemoryMalloc(sizeof(int64_t)); SIMPLE_COPY_VALUES(data, &r->ra.e); - filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true); + filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true, NULL); filterAddUnit(dst, FILTER_GET_FLAG(r->ra.eflag, RANGE_FLG_EXCLUDE) ? OP_TYPE_LOWER_THAN : OP_TYPE_LOWER_EQUAL, &left, &right, &uidx); filterAddUnitToGroup(g, uidx); From dafc1ac826da01b26f51b6d1b4e5549b7365c3df Mon Sep 17 00:00:00 2001 From: sunpeng Date: Fri, 2 Dec 2022 12:03:01 +0800 Subject: [PATCH 28/33] doc: update grafana version in English doc and modifythe way grafana plugin installed in application doc (#18635) --- docs/en/20-third-party/01-grafana.mdx | 2 +- docs/en/25-application/01-telegraf.md | 10 ++-------- docs/en/25-application/02-collectd.md | 10 ++-------- docs/zh/25-application/01-telegraf.md | 10 ++-------- docs/zh/25-application/02-collectd.md | 10 ++-------- 5 files changed, 9 insertions(+), 33 deletions(-) diff --git a/docs/en/20-third-party/01-grafana.mdx b/docs/en/20-third-party/01-grafana.mdx index e0fbefd5a8..ca32ce8afc 100644 --- a/docs/en/20-third-party/01-grafana.mdx +++ b/docs/en/20-third-party/01-grafana.mdx @@ -76,7 +76,7 @@ sudo -u grafana grafana-cli plugins install tdengine-datasource You can also download zip files from [GitHub](https://github.com/taosdata/grafanaplugin/releases/tag/latest) or [Grafana](https://grafana.com/grafana/plugins/tdengine-datasource/?tab=installation) and install manually. The commands are as follows: ```bash -GF_VERSION=3.2.2 +GF_VERSION=3.2.7 # from GitHub wget https://github.com/taosdata/grafanaplugin/releases/download/v$GF_VERSION/tdengine-datasource-$GF_VERSION.zip # from Grafana diff --git a/docs/en/25-application/01-telegraf.md b/docs/en/25-application/01-telegraf.md index f700326449..65fb08ee67 100644 --- a/docs/en/25-application/01-telegraf.md +++ b/docs/en/25-application/01-telegraf.md @@ -38,15 +38,9 @@ Download the latest TDengine-server from the [Downloads](http://tdengine.com/en/ ## Data Connection Setup -### Download TDengine plug-in to grafana plug-in directory +### Install Grafana Plugin and Configure Data Source -```bash -1. wget -c https://github.com/taosdata/grafanaplugin/releases/download/v3.1.3/tdengine-datasource-3.1.3.zip -2. sudo unzip tdengine-datasource-3.1.3.zip -d /var/lib/grafana/plugins/ -3. sudo chown grafana:grafana -R /var/lib/grafana/plugins/tdengine -4. echo -e "[plugins]\nallow_loading_unsigned_plugins = tdengine-datasource\n" | sudo tee -a /etc/grafana/grafana.ini -5. sudo systemctl restart grafana-server.service -``` +Please refer to [Install Grafana Plugin and Configure Data Source](/third-party/grafana/#install-grafana-plugin-and-configure-data-source) ### Modify /etc/telegraf/telegraf.conf diff --git a/docs/en/25-application/02-collectd.md b/docs/en/25-application/02-collectd.md index 692cd8d929..97412b2309 100644 --- a/docs/en/25-application/02-collectd.md +++ b/docs/en/25-application/02-collectd.md @@ -41,15 +41,9 @@ Download the latest TDengine-server from the [Downloads](http://tdengine.com/en/ ## Data Connection Setup -### Copy the TDengine plugin to the grafana plugin directory +### Install Grafana Plugin and Configure Data Source -```bash -1. wget -c https://github.com/taosdata/grafanaplugin/releases/download/v3.1.3/tdengine-datasource-3.1.3.zip -2. sudo unzip tdengine-datasource-3.1.3.zip -d /var/lib/grafana/plugins/ -3. sudo chown grafana:grafana -R /var/lib/grafana/plugins/tdengine -4. echo -e "[plugins]\nallow_loading_unsigned_plugins = tdengine-datasource\n" | sudo tee -a /etc/grafana/grafana.ini -5. sudo systemctl restart grafana-server.service -``` +Please refer to [Install Grafana Plugin and Configure Data Source](/third-party/grafana/#install-grafana-plugin-and-configure-data-source) ### Configure collectd diff --git a/docs/zh/25-application/01-telegraf.md b/docs/zh/25-application/01-telegraf.md index 6338264d17..ec263d7792 100644 --- a/docs/zh/25-application/01-telegraf.md +++ b/docs/zh/25-application/01-telegraf.md @@ -39,15 +39,9 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ## 数据链路设置 -### 下载 TDengine 插件到 Grafana 插件目录 +### 安装 Grafana Plugin 并配置数据源 -```bash -1. wget -c https://github.com/taosdata/grafanaplugin/releases/download/v3.1.3/tdengine-datasource-3.1.3.zip -2. sudo unzip tdengine-datasource-3.1.3.zip -d /var/lib/grafana/plugins/ -3. sudo chown grafana:grafana -R /var/lib/grafana/plugins/tdengine -4. echo -e "[plugins]\nallow_loading_unsigned_plugins = tdengine-datasource\n" | sudo tee -a /etc/grafana/grafana.ini -5. sudo systemctl restart grafana-server.service -``` +请参考[安装 Grafana Plugin 并配置数据源](/third-party/grafana/#%E5%AE%89%E8%A3%85-grafana-plugin-%E5%B9%B6%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E6%BA%90)。 ### 修改 /etc/telegraf/telegraf.conf diff --git a/docs/zh/25-application/02-collectd.md b/docs/zh/25-application/02-collectd.md index c6230f48ab..8b39a6431d 100644 --- a/docs/zh/25-application/02-collectd.md +++ b/docs/zh/25-application/02-collectd.md @@ -41,15 +41,9 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ## 数据链路设置 -### 复制 TDengine 插件到 grafana 插件目录 +### 安装 Grafana Plugin 并配置数据源 -```bash -1. wget -c https://github.com/taosdata/grafanaplugin/releases/download/v3.1.3/tdengine-datasource-3.1.3.zip -2. sudo unzip tdengine-datasource-3.1.3.zip -d /var/lib/grafana/plugins/ -3. sudo chown grafana:grafana -R /var/lib/grafana/plugins/tdengine -4. echo -e "[plugins]\nallow_loading_unsigned_plugins = tdengine-datasource\n" | sudo tee -a /etc/grafana/grafana.ini -5. sudo systemctl restart grafana-server.service -``` +请参考[安装 Grafana Plugin 并配置数据源](/third-party/grafana/#%E5%AE%89%E8%A3%85-grafana-plugin-%E5%B9%B6%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E6%BA%90)。 ### 配置 collectd From 37299a53f8cb6eb42c504a2884c06959f4916b88 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Fri, 2 Dec 2022 12:14:56 +0800 Subject: [PATCH 29/33] feat: sql command 'show user privileges' --- source/dnode/mnode/impl/inc/mndUser.h | 2 +- source/dnode/mnode/impl/src/mndShow.c | 2 ++ source/dnode/mnode/impl/src/mndUser.c | 34 +++++++++++++++++++++------ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/source/dnode/mnode/impl/inc/mndUser.h b/source/dnode/mnode/impl/inc/mndUser.h index 970d1db7db..8cd1950daf 100644 --- a/source/dnode/mnode/impl/inc/mndUser.h +++ b/source/dnode/mnode/impl/inc/mndUser.h @@ -30,7 +30,7 @@ void mndReleaseUser(SMnode *pMnode, SUserObj *pUser); // for trans test SSdbRaw *mndUserActionEncode(SUserObj *pUser); -SHashObj *mndDupDbHash(SHashObj *pOld); +SHashObj *mndDupObjHash(SHashObj *pOld, int32_t dataLen); int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp, int32_t *pRspLen); diff --git a/source/dnode/mnode/impl/src/mndShow.c b/source/dnode/mnode/impl/src/mndShow.c index 20c2ebb0a4..ec2e844ba5 100644 --- a/source/dnode/mnode/impl/src/mndShow.c +++ b/source/dnode/mnode/impl/src/mndShow.c @@ -108,6 +108,8 @@ static int32_t convertToRetrieveType(char *name, int32_t len) { type = TSDB_MGMT_TABLE_APPS; } else if (strncasecmp(name, TSDB_INS_TABLE_STREAM_TASKS, len) == 0) { type = TSDB_MGMT_TABLE_STREAM_TASKS; + } else if (strncasecmp(name, TSDB_INS_TABLE_USER_PRIVILEGES, len) == 0) { + type = TSDB_MGMT_TABLE_PRIVILEGES; } else { // ASSERT(0); } diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 5f34adce77..1666fe2f09 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -161,7 +161,7 @@ SSdbRaw *mndUserActionEncode(SUserObj *pUser) { char *topic = taosHashIterate(pUser->topics, NULL); while (topic != NULL) { SDB_SET_BINARY(pRaw, dataPos, topic, TSDB_TOPIC_FNAME_LEN, _OVER); - db = taosHashIterate(pUser->topics, topic); + topic = taosHashIterate(pUser->topics, topic); } SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER) @@ -446,7 +446,7 @@ static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpc return 0; } -SHashObj *mndDupDbHash(SHashObj *pOld) { +SHashObj *mndDupObjHash(SHashObj *pOld, int32_t dataLen) { SHashObj *pNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); if (pNew == NULL) { @@ -457,7 +457,7 @@ SHashObj *mndDupDbHash(SHashObj *pOld) { char *db = taosHashIterate(pOld, NULL); while (db != NULL) { int32_t len = strlen(db) + 1; - if (taosHashPut(pNew, db, len, db, TSDB_DB_FNAME_LEN) != 0) { + if (taosHashPut(pNew, db, len, db, dataLen) != 0) { taosHashCancelIterate(pOld, db); taosHashCleanup(pNew); terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -517,9 +517,9 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) { newUser.updateTime = taosGetTimestampMs(); taosRLockLatch(&pUser->lock); - newUser.readDbs = mndDupDbHash(pUser->readDbs); - newUser.writeDbs = mndDupDbHash(pUser->writeDbs); - newUser.topics = mndDupDbHash(pUser->topics); + newUser.readDbs = mndDupObjHash(pUser->readDbs, TSDB_DB_FNAME_LEN); + newUser.writeDbs = mndDupObjHash(pUser->writeDbs, TSDB_DB_FNAME_LEN); + newUser.topics = mndDupObjHash(pUser->topics, TSDB_TOPIC_FNAME_LEN); taosRUnLockLatch(&pUser->lock); if (newUser.readDbs == NULL || newUser.writeDbs == NULL || newUser.topics == NULL) { @@ -832,6 +832,26 @@ static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock int32_t numOfTopics = taosHashGetSize(pUser->topics); if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics >= rows) break; + if (pUser->superUser) { + cols = 0; + SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + char userName[TSDB_USER_LEN + VARSTR_HEADER_SIZE] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(userName, pUser->user, pShow->pMeta->pSchemas[cols].bytes); + colDataAppend(pColInfo, numOfRows, (const char *)userName, false); + + char privilege[20] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(privilege, "all", pShow->pMeta->pSchemas[cols].bytes); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataAppend(pColInfo, numOfRows, (const char *)privilege, false); + + char objName[20] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(objName, "all", pShow->pMeta->pSchemas[cols].bytes); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataAppend(pColInfo, numOfRows, (const char *)objName, false); + + numOfRows++; + } + char *db = taosHashIterate(pUser->readDbs, NULL); while (db != NULL) { cols = 0; @@ -902,7 +922,7 @@ static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock colDataAppend(pColInfo, numOfRows, (const char *)topicName, false); numOfRows++; - db = taosHashIterate(pUser->topics, topic); + topic = taosHashIterate(pUser->topics, topic); } sdbRelease(pSdb, pUser); From 4f8c04cf79aca8bbe14a9ebb953717e27e9dd9c8 Mon Sep 17 00:00:00 2001 From: sunpeng Date: Fri, 2 Dec 2022 12:47:19 +0800 Subject: [PATCH 30/33] doc: writting from kafka (#18626) * doc: writting from kafka * rename file * docs: typo fix Co-authored-by: Shuduo Sang --- .../03-insert-data/20-kafka-writting.mdx | 46 +++++ ...influxdb-line.mdx => 30-influxdb-line.mdx} | 0 ...tsdb-telnet.mdx => 40-opentsdb-telnet.mdx} | 0 ...opentsdb-json.mdx => 50-opentsdb-json.mdx} | 0 .../{05-high-volume.md => 60-high-volume.md} | 0 .../07-develop/03-insert-data/_py_kafka.mdx | 60 ++++++ docs/examples/python/kafka_example.py | 192 ++++++++++++++++++ .../03-insert-data/20-kafka-writting.mdx | 47 +++++ ...influxdb-line.mdx => 30-influxdb-line.mdx} | 0 ...tsdb-telnet.mdx => 40-opentsdb-telnet.mdx} | 0 ...opentsdb-json.mdx => 50-opentsdb-json.mdx} | 0 .../{05-high-volume.md => 60-high-volume.md} | 0 .../07-develop/03-insert-data/_py_kafka.mdx | 60 ++++++ 13 files changed, 405 insertions(+) create mode 100644 docs/en/07-develop/03-insert-data/20-kafka-writting.mdx rename docs/en/07-develop/03-insert-data/{02-influxdb-line.mdx => 30-influxdb-line.mdx} (100%) rename docs/en/07-develop/03-insert-data/{03-opentsdb-telnet.mdx => 40-opentsdb-telnet.mdx} (100%) rename docs/en/07-develop/03-insert-data/{04-opentsdb-json.mdx => 50-opentsdb-json.mdx} (100%) rename docs/en/07-develop/03-insert-data/{05-high-volume.md => 60-high-volume.md} (100%) create mode 100644 docs/en/07-develop/03-insert-data/_py_kafka.mdx create mode 100644 docs/examples/python/kafka_example.py create mode 100644 docs/zh/07-develop/03-insert-data/20-kafka-writting.mdx rename docs/zh/07-develop/03-insert-data/{02-influxdb-line.mdx => 30-influxdb-line.mdx} (100%) rename docs/zh/07-develop/03-insert-data/{03-opentsdb-telnet.mdx => 40-opentsdb-telnet.mdx} (100%) rename docs/zh/07-develop/03-insert-data/{04-opentsdb-json.mdx => 50-opentsdb-json.mdx} (100%) rename docs/zh/07-develop/03-insert-data/{05-high-volume.md => 60-high-volume.md} (100%) create mode 100644 docs/zh/07-develop/03-insert-data/_py_kafka.mdx diff --git a/docs/en/07-develop/03-insert-data/20-kafka-writting.mdx b/docs/en/07-develop/03-insert-data/20-kafka-writting.mdx new file mode 100644 index 0000000000..ffb969a8a6 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/20-kafka-writting.mdx @@ -0,0 +1,46 @@ +--- +title: Write from Kafka +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; +import PyKafka from "./_py_kafka.mdx"; + +## About Kafka + +Apache Kafka is an open-source distributed event streaming platform, used by thousands of companies for high-performance data pipelines, streaming analytics, data integration, and mission-critical applications. For the key concepts of kafka, please refer to [kafka documentation](https://kafka.apache.org/documentation/#gettingStarted). + +### kafka topic + +Messages in Kafka are organized by topics. A topic may have one or more partitions. We can manage kafka topics through `kafka-topics`. + +create a topic named `kafka-events`: + +``` +bin/kafka-topics.sh --create --topic kafka-events --bootstrap-server localhost:9092 +``` + +Alter `kafka-events` topic to set partitions to 3: + +``` +bin/kafka-topics.sh --alter --topic kafka-events --partitions 3 --bootstrap-server=localhost:9092 +``` + +Show all topics and partitions in Kafka: + +``` +bin/kafka-topics.sh --bootstrap-server=localhost:9092 --describe +``` + +## Insert into TDengine + +We can write data into TDengine via SQL or Schemaless. For more information, please refer to [Insert Using SQL](/develop/insert-data/sql-writing/) or [High Performance Writing](/develop/insert-data/high-volume/) or [Schemaless Writing](/reference/schemaless/). + +## Examples + + + + + + + diff --git a/docs/en/07-develop/03-insert-data/02-influxdb-line.mdx b/docs/en/07-develop/03-insert-data/30-influxdb-line.mdx similarity index 100% rename from docs/en/07-develop/03-insert-data/02-influxdb-line.mdx rename to docs/en/07-develop/03-insert-data/30-influxdb-line.mdx diff --git a/docs/en/07-develop/03-insert-data/03-opentsdb-telnet.mdx b/docs/en/07-develop/03-insert-data/40-opentsdb-telnet.mdx similarity index 100% rename from docs/en/07-develop/03-insert-data/03-opentsdb-telnet.mdx rename to docs/en/07-develop/03-insert-data/40-opentsdb-telnet.mdx diff --git a/docs/en/07-develop/03-insert-data/04-opentsdb-json.mdx b/docs/en/07-develop/03-insert-data/50-opentsdb-json.mdx similarity index 100% rename from docs/en/07-develop/03-insert-data/04-opentsdb-json.mdx rename to docs/en/07-develop/03-insert-data/50-opentsdb-json.mdx diff --git a/docs/en/07-develop/03-insert-data/05-high-volume.md b/docs/en/07-develop/03-insert-data/60-high-volume.md similarity index 100% rename from docs/en/07-develop/03-insert-data/05-high-volume.md rename to docs/en/07-develop/03-insert-data/60-high-volume.md diff --git a/docs/en/07-develop/03-insert-data/_py_kafka.mdx b/docs/en/07-develop/03-insert-data/_py_kafka.mdx new file mode 100644 index 0000000000..dc43a0d415 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_py_kafka.mdx @@ -0,0 +1,60 @@ +### python Kafka 客户端 + +For python kafka client, please refer to [kafka client](https://cwiki.apache.org/confluence/display/KAFKA/Clients#Clients-Python). In this document, we use [kafka-python](http://github.com/dpkp/kafka-python). + +### consume from Kafka + +The simple way to consume messages from Kafka is to read messages one by one. The demo is as follows: + +``` +from kafka import KafkaConsumer +consumer = KafkaConsumer('my_favorite_topic') +for msg in consumer: + print (msg) +``` + +For higher performance, we can consume message from kafka in batch. The demo is as follows: + +``` +from kafka import KafkaConsumer +consumer = KafkaConsumer('my_favorite_topic') +while True: + msgs = consumer.poll(timeout_ms=500, max_records=1000) + if msgs: + print (msgs) +``` + +### multi-threading + +For more higher performance we can process data from kafka in multi-thread. We can use python's ThreadPoolExecutor to achieve multithreading. The demo is as follows: + +``` +from concurrent.futures import ThreadPoolExecutor, Future +pool = ThreadPoolExecutor(max_workers=10) +pool.submit(...) +``` + +### multi-process + +For more higher performance, sometimes we use multiprocessing. In this case, the number of Kafka Consumers should not be greater than the number of Kafka Topic Partitions. The demo is as follows: + +``` +from multiprocessing import Process + +ps = [] +for i in range(5): + p = Process(target=Consumer().consume()) + p.start() + ps.append(p) + +for p in ps: + p.join() +``` + +In addition to python's built-in multithreading and multiprocessing library, we can also use the third-party library gunicorn. + +### Examples + +```py +{{#include docs/examples/python/kafka_example.py}} +``` diff --git a/docs/examples/python/kafka_example.py b/docs/examples/python/kafka_example.py new file mode 100644 index 0000000000..735059eec0 --- /dev/null +++ b/docs/examples/python/kafka_example.py @@ -0,0 +1,192 @@ +#! encoding = utf-8 +import json +import time +from json import JSONDecodeError +from typing import Callable +import logging +from concurrent.futures import ThreadPoolExecutor, Future + +import taos +from kafka import KafkaConsumer +from kafka.consumer.fetcher import ConsumerRecord + + +class Consumer(object): + DEFAULT_CONFIGS = { + 'kafka_brokers': 'localhost:9092', + 'kafka_topic': 'python_kafka', + 'kafka_group_id': 'taos', + 'taos_host': 'localhost', + 'taos_user': 'root', + 'taos_password': 'taosdata', + 'taos_database': 'power', + 'taos_port': 6030, + 'timezone': None, + 'clean_after_testing': False, + 'bath_consume': True, + 'batch_size': 1000, + 'async_model': True, + 'workers': 10 + } + + LOCATIONS = ['California.SanFrancisco', 'California.LosAngles', 'California.SanDiego', 'California.SanJose', + 'California.PaloAlto', 'California.Campbell', 'California.MountainView', 'California.Sunnyvale', + 'California.SantaClara', 'California.Cupertino'] + + CREATE_DATABASE_SQL = 'create database if not exists {} keep 365 duration 10 buffer 16 wal_level 1' + USE_DATABASE_SQL = 'use {}' + DROP_TABLE_SQL = 'drop table if exists meters' + DROP_DATABASE_SQL = 'drop database if exists {}' + CREATE_STABLE_SQL = 'create stable meters (ts timestamp, current float, voltage int, phase float) ' \ + 'tags (location binary(64), groupId int)' + CREATE_TABLE_SQL = 'create table if not exists {} using meters tags (\'{}\', {})' + INSERT_SQL_HEADER = "insert into " + INSERT_PART_SQL = 'power.{} values (\'{}\', {}, {}, {})' + + def __init__(self, **configs): + self.config: dict = self.DEFAULT_CONFIGS + self.config.update(configs) + self.consumer = KafkaConsumer( + self.config.get('kafka_topic'), # topic + bootstrap_servers=self.config.get('kafka_brokers'), + group_id=self.config.get('kafka_group_id'), + ) + self.taos = taos.connect( + host=self.config.get('taos_host'), + user=self.config.get('taos_user'), + password=self.config.get('taos_password'), + port=self.config.get('taos_port'), + timezone=self.config.get('timezone'), + ) + if self.config.get('async_model'): + self.pool = ThreadPoolExecutor(max_workers=self.config.get('workers')) + self.tasks: list[Future] = [] + # tags and table mapping # key: {location}_{groupId} value: + self.tag_table_mapping = {} + i = 0 + for location in self.LOCATIONS: + for j in range(1, 11): + table_name = 'd{}'.format(i) + self._cache_table(location=location, group_id=j, table_name=table_name) + i += 1 + + def init_env(self): + # create database and table + self.taos.execute(self.DROP_DATABASE_SQL.format(self.config.get('taos_database'))) + self.taos.execute(self.CREATE_DATABASE_SQL.format(self.config.get('taos_database'))) + self.taos.execute(self.USE_DATABASE_SQL.format(self.config.get('taos_database'))) + self.taos.execute(self.DROP_TABLE_SQL) + self.taos.execute(self.CREATE_STABLE_SQL) + for tags, table_name in self.tag_table_mapping.items(): + location, group_id = _get_location_and_group(tags) + self.taos.execute(self.CREATE_TABLE_SQL.format(table_name, location, group_id)) + + def consume(self): + logging.warning('## start consumer topic-[%s]', self.config.get('kafka_topic')) + try: + if self.config.get('bath_consume'): + self._run_batch(self._to_taos_batch) + else: + self._run(self._to_taos) + except KeyboardInterrupt: + logging.warning("## caught keyboard interrupt, stopping") + finally: + self.stop() + + def stop(self): + # close consumer + if self.consumer is not None: + self.consumer.commit() + self.consumer.close() + + # multi thread + if self.config.get('async_model'): + for task in self.tasks: + while not task.done(): + pass + if self.pool is not None: + self.pool.shutdown() + + # clean data + if self.config.get('clean_after_testing'): + self.taos.execute(self.DROP_TABLE_SQL) + self.taos.execute(self.DROP_DATABASE_SQL.format(self.config.get('taos_database'))) + # close taos + if self.taos is not None: + self.taos.close() + + def _run(self, f: Callable[[ConsumerRecord], bool]): + for message in self.consumer: + if self.config.get('async_model'): + self.pool.submit(f(message)) + else: + f(message) + + def _run_batch(self, f: Callable[[list[list[ConsumerRecord]]], None]): + while True: + messages = self.consumer.poll(timeout_ms=500, max_records=self.config.get('batch_size')) + if messages: + if self.config.get('async_model'): + self.pool.submit(f, messages.values()) + else: + f(list(messages.values())) + if not messages: + time.sleep(0.1) + + def _to_taos(self, message: ConsumerRecord) -> bool: + sql = self.INSERT_SQL_HEADER + self._build_sql(message.value) + if len(sql) == 0: # decode error, skip + return True + logging.info('## insert sql %s', sql) + return self.taos.execute(sql=sql) == 1 + + def _to_taos_batch(self, messages: list[list[ConsumerRecord]]): + sql = self._build_sql_batch(messages=messages) + if len(sql) == 0: # decode error, skip + return + self.taos.execute(sql=sql) + + def _build_sql(self, msg_value: str) -> str: + try: + data = json.loads(msg_value) + except JSONDecodeError as e: + logging.error('## decode message [%s] error ', msg_value, e) + return '' + location = data.get('location') + group_id = data.get('groupId') + ts = data.get('ts') + current = data.get('current') + voltage = data.get('voltage') + phase = data.get('phase') + + table_name = self._get_table_name(location=location, group_id=group_id) + return self.INSERT_PART_SQL.format(table_name, ts, current, voltage, phase) + + def _build_sql_batch(self, messages: list[list[ConsumerRecord]]) -> str: + sql_list = [] + for partition_messages in messages: + for message in partition_messages: + sql_list.append(self._build_sql(message.value)) + + return self.INSERT_SQL_HEADER + ' '.join(sql_list) + + def _cache_table(self, location: str, group_id: int, table_name: str): + self.tag_table_mapping[_tag_table_mapping_key(location=location, group_id=group_id)] = table_name + + def _get_table_name(self, location: str, group_id: int) -> str: + return self.tag_table_mapping.get(_tag_table_mapping_key(location=location, group_id=group_id)) + + +def _tag_table_mapping_key(location: str, group_id: int): + return '{}_{}'.format(location, group_id) + + +def _get_location_and_group(key: str) -> (str, int): + fields = key.split('_') + return fields[0], fields[1] + + +if __name__ == '__main__': + consumer = Consumer(async_model=True) + consumer.init_env() + consumer.consume() \ No newline at end of file diff --git a/docs/zh/07-develop/03-insert-data/20-kafka-writting.mdx b/docs/zh/07-develop/03-insert-data/20-kafka-writting.mdx new file mode 100644 index 0000000000..32d3c2e5cb --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/20-kafka-writting.mdx @@ -0,0 +1,47 @@ +--- +title: 从 Kafka 写入 +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; +import PyKafka from "./_py_kafka.mdx"; + +## Kafka 介绍 + +Apache Kafka 是开源的分布式消息分发平台,被广泛应用于高性能数据管道、流式数据分析、数据集成和事件驱动类型的应用程序。Kafka 包含 Producer、Consumer 和 Topic,其中 Producer 是向 Kafka 发送消息的进程,Consumer 是从 Kafka 消费消息的进程。Kafka 相关概念可以参考[官方文档](https://kafka.apache.org/documentation/#gettingStarted)。 + + +### kafka topic + +Kafka 的消息按 topic 组织,每个 topic 会有一到多个 partition。可以通过 kafka 的 `kafka-topics` 管理 topic。 + +创建名为 `kafka-events` 的topic: + +``` +bin/kafka-topics.sh --create --topic kafka-events --bootstrap-server localhost:9092 +``` + +修改 `kafka-events` 的 partition 数量为 3: + +``` +bin/kafka-topics.sh --alter --topic kafka-events --partitions 3 --bootstrap-server=localhost:9092 +``` + +展示所有的 topic 和 partition: + +``` +bin/kafka-topics.sh --bootstrap-server=localhost:9092 --describe +``` + +## 写入 TDengine + +TDengine 支持 Sql 方式和 Schemaless 方式的数据写入,Sql 方式数据写入可以参考 [TDengine SQL 写入](/develop/insert-data/sql-writing/) 和 [TDengine 高效写入](/develop/insert-data/high-volume/)。Schemaless 方式数据写入可以参考 [TDengine Schemaless 写入](/reference/schemaless/) 文档。 + +## 示例代码 + + + + + + + diff --git a/docs/zh/07-develop/03-insert-data/02-influxdb-line.mdx b/docs/zh/07-develop/03-insert-data/30-influxdb-line.mdx similarity index 100% rename from docs/zh/07-develop/03-insert-data/02-influxdb-line.mdx rename to docs/zh/07-develop/03-insert-data/30-influxdb-line.mdx diff --git a/docs/zh/07-develop/03-insert-data/03-opentsdb-telnet.mdx b/docs/zh/07-develop/03-insert-data/40-opentsdb-telnet.mdx similarity index 100% rename from docs/zh/07-develop/03-insert-data/03-opentsdb-telnet.mdx rename to docs/zh/07-develop/03-insert-data/40-opentsdb-telnet.mdx diff --git a/docs/zh/07-develop/03-insert-data/04-opentsdb-json.mdx b/docs/zh/07-develop/03-insert-data/50-opentsdb-json.mdx similarity index 100% rename from docs/zh/07-develop/03-insert-data/04-opentsdb-json.mdx rename to docs/zh/07-develop/03-insert-data/50-opentsdb-json.mdx diff --git a/docs/zh/07-develop/03-insert-data/05-high-volume.md b/docs/zh/07-develop/03-insert-data/60-high-volume.md similarity index 100% rename from docs/zh/07-develop/03-insert-data/05-high-volume.md rename to docs/zh/07-develop/03-insert-data/60-high-volume.md diff --git a/docs/zh/07-develop/03-insert-data/_py_kafka.mdx b/docs/zh/07-develop/03-insert-data/_py_kafka.mdx new file mode 100644 index 0000000000..cd7edf557d --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_py_kafka.mdx @@ -0,0 +1,60 @@ +### python Kafka 客户端 + +Kafka 的 python 客户端可以参考文档 [kafka client](https://cwiki.apache.org/confluence/display/KAFKA/Clients#Clients-Python)。推荐使用 [confluent-kafka-python](https://github.com/confluentinc/confluent-kafka-python) 和 [kafka-python](http://github.com/dpkp/kafka-python)。以下示例以 [kafka-python](http://github.com/dpkp/kafka-python) 为例。 + +### 从 Kafka 消费数据 + +Kafka 客户端采用 pull 的方式从 Kafka 消费数据,可以采用单条消费的方式或批量消费的方式读取数据。使用 [kafka-python](http://github.com/dpkp/kafka-python) 客户端单条消费数据的示例如下: + +``` +from kafka import KafkaConsumer +consumer = KafkaConsumer('my_favorite_topic') +for msg in consumer: + print (msg) +``` + +单条消费的方式在数据流量大的情况下往往存在性能瓶颈,导致 Kafka 消息积压,更推荐使用批量消费的方式消费数据。使用 [kafka-python](http://github.com/dpkp/kafka-python) 客户端批量消费数据的示例如下: + +``` +from kafka import KafkaConsumer +consumer = KafkaConsumer('my_favorite_topic') +while True: + msgs = consumer.poll(timeout_ms=500, max_records=1000) + if msgs: + print (msgs) +``` + +### Python 多线程 + +为了提高数据写入效率,通常采用多线程的方式写入数据,可以使用 python 线程池 ThreadPoolExecutor 实现多线程。示例代码如下: + +``` +from concurrent.futures import ThreadPoolExecutor, Future +pool = ThreadPoolExecutor(max_workers=10) +pool.submit(...) +``` + +### Python 多进程 + +单个python进程不能充分发挥多核 CPU 的性能,有时候我们会选择多进程的方式。在多进程的情况下,需要注意,Kafka Consumer 的数量应该小于等于 Kafka Topic Partition 数量。Python 多进程示例代码如下: + +``` +from multiprocessing import Process + +ps = [] +for i in range(5): + p = Process(target=Consumer().consume()) + p.start() + ps.append(p) + +for p in ps: + p.join() +``` + +除了 Python 内置的多线程和多进程方式,还可以通过第三方库 gunicorn 实现并发。 + +### 完整示例 + +```py +{{#include docs/examples/python/kafka_example.py}} +``` From 83d33ceae27b93d78008159a9e2b865dfa81f5c7 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Fri, 2 Dec 2022 13:12:41 +0800 Subject: [PATCH 31/33] feat: sql command 'show user privileges' --- source/dnode/mnode/impl/inc/mndUser.h | 2 +- source/dnode/mnode/impl/src/mndUser.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/dnode/mnode/impl/inc/mndUser.h b/source/dnode/mnode/impl/inc/mndUser.h index 8cd1950daf..ff43d69d2f 100644 --- a/source/dnode/mnode/impl/inc/mndUser.h +++ b/source/dnode/mnode/impl/inc/mndUser.h @@ -30,7 +30,7 @@ void mndReleaseUser(SMnode *pMnode, SUserObj *pUser); // for trans test SSdbRaw *mndUserActionEncode(SUserObj *pUser); -SHashObj *mndDupObjHash(SHashObj *pOld, int32_t dataLen); +SHashObj *mndDupDbHash(SHashObj *pOld, int32_t dataLen); int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp, int32_t *pRspLen); diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 1666fe2f09..291b83c80e 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -446,7 +446,7 @@ static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpc return 0; } -SHashObj *mndDupObjHash(SHashObj *pOld, int32_t dataLen) { +SHashObj *mndDupDbHash(SHashObj *pOld, int32_t dataLen) { SHashObj *pNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); if (pNew == NULL) { @@ -517,9 +517,9 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) { newUser.updateTime = taosGetTimestampMs(); taosRLockLatch(&pUser->lock); - newUser.readDbs = mndDupObjHash(pUser->readDbs, TSDB_DB_FNAME_LEN); - newUser.writeDbs = mndDupObjHash(pUser->writeDbs, TSDB_DB_FNAME_LEN); - newUser.topics = mndDupObjHash(pUser->topics, TSDB_TOPIC_FNAME_LEN); + newUser.readDbs = mndDupDbHash(pUser->readDbs, TSDB_DB_FNAME_LEN); + newUser.writeDbs = mndDupDbHash(pUser->writeDbs, TSDB_DB_FNAME_LEN); + newUser.topics = mndDupDbHash(pUser->topics, TSDB_TOPIC_FNAME_LEN); taosRUnLockLatch(&pUser->lock); if (newUser.readDbs == NULL || newUser.writeDbs == NULL || newUser.topics == NULL) { From 71140f565e928855bb7c18d53cd810273c283096 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Fri, 2 Dec 2022 13:43:48 +0800 Subject: [PATCH 32/33] feat: sql command 'show user privileges' --- source/dnode/mnode/impl/inc/mndUser.h | 3 ++- source/dnode/mnode/impl/src/mndUser.c | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/source/dnode/mnode/impl/inc/mndUser.h b/source/dnode/mnode/impl/inc/mndUser.h index ff43d69d2f..cf7deba397 100644 --- a/source/dnode/mnode/impl/inc/mndUser.h +++ b/source/dnode/mnode/impl/inc/mndUser.h @@ -30,7 +30,8 @@ void mndReleaseUser(SMnode *pMnode, SUserObj *pUser); // for trans test SSdbRaw *mndUserActionEncode(SUserObj *pUser); -SHashObj *mndDupDbHash(SHashObj *pOld, int32_t dataLen); +SHashObj *mndDupDbHash(SHashObj *pOld); +SHashObj *mndDupTopicHash(SHashObj *pOld); int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp, int32_t *pRspLen); diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 291b83c80e..806ba0c98e 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -446,7 +446,7 @@ static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpc return 0; } -SHashObj *mndDupDbHash(SHashObj *pOld, int32_t dataLen) { +SHashObj *mndDupObjHash(SHashObj *pOld, int32_t dataLen) { SHashObj *pNew = taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); if (pNew == NULL) { @@ -469,6 +469,10 @@ SHashObj *mndDupDbHash(SHashObj *pOld, int32_t dataLen) { return pNew; } +SHashObj *mndDupDbHash(SHashObj *pOld) { return mndDupObjHash(pOld, TSDB_DB_FNAME_LEN); } + +SHashObj *mndDupTopicHash(SHashObj *pOld) { return mndDupObjHash(pOld, TSDB_TOPIC_FNAME_LEN); } + static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) { SMnode *pMnode = pReq->info.node; SSdb *pSdb = pMnode->pSdb; @@ -517,9 +521,9 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) { newUser.updateTime = taosGetTimestampMs(); taosRLockLatch(&pUser->lock); - newUser.readDbs = mndDupDbHash(pUser->readDbs, TSDB_DB_FNAME_LEN); - newUser.writeDbs = mndDupDbHash(pUser->writeDbs, TSDB_DB_FNAME_LEN); - newUser.topics = mndDupDbHash(pUser->topics, TSDB_TOPIC_FNAME_LEN); + newUser.readDbs = mndDupDbHash(pUser->readDbs); + newUser.writeDbs = mndDupDbHash(pUser->writeDbs); + newUser.topics = mndDupTopicHash(pUser->topics); taosRUnLockLatch(&pUser->lock); if (newUser.readDbs == NULL || newUser.writeDbs == NULL || newUser.topics == NULL) { From 7bb30150a9ef13f3f5c66d9b06fbf9e9f73d88a4 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Fri, 2 Dec 2022 14:23:36 +0800 Subject: [PATCH 33/33] fix: fix memory leak --- source/libs/qworker/src/qwMsg.c | 2 +- source/libs/scalar/src/filter.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source/libs/qworker/src/qwMsg.c b/source/libs/qworker/src/qwMsg.c index d9a7cea411..7dc13ce5f3 100644 --- a/source/libs/qworker/src/qwMsg.c +++ b/source/libs/qworker/src/qwMsg.c @@ -336,7 +336,7 @@ int32_t qwRegisterHbBrokenLinkArg(SQWorker *mgmt, uint64_t sId, SRpcHandleInfo * } if (tSerializeSSchedulerHbReq(msg, msgSize, &req) < 0) { QW_SCH_ELOG("tSerializeSSchedulerHbReq hbReq failed, size:%d", msgSize); - taosMemoryFree(msg); + rpcFreeCont(msg); QW_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index ef92377410..1cf4bd9923 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -1024,8 +1024,11 @@ int32_t filterAddField(SFilterInfo *info, void *desc, void **data, int32_t type, SFilterDataInfo dInfo = {idx, *data}; taosHashPut(info->pctx.valHash, *data, dataLen, &dInfo, sizeof(dInfo)); + if (srcFlag) { + FILTER_SET_FLAG(*srcFlag, FLD_DATA_NO_FREE); + } } - } else if (data) { + } else if (type != FLD_TYPE_COLUMN && data) { if (freeIfExists) { taosMemoryFreeClear(*data); } else if (sameBuf) {