From 3e5ab6b54cecbb658f0028fcb11af85969183e8a Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 31 May 2022 11:29:10 +0800 Subject: [PATCH 01/26] feat: add physical plannode of indefinite rows func --- include/libs/nodes/nodes.h | 2 + include/libs/nodes/plannodes.h | 11 ++ source/libs/function/src/builtins.c | 109 ++----------------- source/libs/nodes/src/nodesCloneFuncs.c | 8 ++ source/libs/nodes/src/nodesCodeFuncs.c | 67 ++++++++++++ source/libs/nodes/src/nodesTraverseFuncs.c | 2 + source/libs/nodes/src/nodesUtilFuncs.c | 4 + source/libs/planner/src/planLogicCreater.c | 34 ++++++ source/libs/planner/src/planPhysiCreater.c | 42 ++++++- source/libs/planner/test/planProjectTest.cpp | 34 ++++++ 10 files changed, 214 insertions(+), 99 deletions(-) create mode 100644 source/libs/planner/test/planProjectTest.cpp diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 3860266725..639a1173cd 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -194,6 +194,7 @@ typedef enum ENodeType { QUERY_NODE_LOGIC_PLAN_FILL, QUERY_NODE_LOGIC_PLAN_SORT, QUERY_NODE_LOGIC_PLAN_PARTITION, + QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC, QUERY_NODE_LOGIC_SUBPLAN, QUERY_NODE_LOGIC_PLAN, @@ -217,6 +218,7 @@ typedef enum ENodeType { QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION_WINDOW, QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW, QUERY_NODE_PHYSICAL_PLAN_PARTITION, + QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC, QUERY_NODE_PHYSICAL_PLAN_DISPATCH, QUERY_NODE_PHYSICAL_PLAN_INSERT, QUERY_NODE_PHYSICAL_SUBPLAN, diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 2648a468dd..56a1343dcb 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -84,6 +84,11 @@ typedef struct SProjectLogicNode { int64_t soffset; } SProjectLogicNode; +typedef struct SIndefRowsFuncLogicNode { + SLogicNode node; + SNodeList* pVectorFuncs; +} SIndefRowsFuncLogicNode; + typedef struct SVnodeModifLogicNode { SLogicNode node; int32_t msgType; @@ -236,6 +241,12 @@ typedef struct SProjectPhysiNode { int64_t soffset; } SProjectPhysiNode; +typedef struct SIndefRowsFuncPhysiNode { + SPhysiNode node; + SNodeList* pExprs; + SNodeList* pVectorFuncs; +} SIndefRowsFuncPhysiNode; + typedef struct SJoinPhysiNode { SPhysiNode node; EJoinType joinType; diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index c9d556c86b..831af33add 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -156,14 +156,7 @@ static int32_t translatePercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - //param0 - SNode* pParamNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (nodeType(pParamNode0) != QUERY_NODE_COLUMN) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The first parameter of PERCENTILE function can only be column"); - } - - //param1 + // param1 SValueNode* pValue = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1); if (pValue->datum.i < 0 || pValue->datum.i > 100) { @@ -178,7 +171,7 @@ static int32_t translatePercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } - //set result type + // set result type pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE}; return TSDB_CODE_SUCCESS; } @@ -197,14 +190,7 @@ static int32_t translateApercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - //param0 - SNode* pParamNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (nodeType(pParamNode0) != QUERY_NODE_COLUMN) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The first parameter of APERCENTILE function can only be column"); - } - - //param1 + // param1 SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1); if (nodeType(pParamNode1) != QUERY_NODE_VALUE) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); @@ -223,7 +209,7 @@ static int32_t translateApercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } - //param2 + // param2 if (3 == numOfParams) { uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type; if (!IS_VAR_DATA_TYPE(para3Type)) { @@ -263,14 +249,7 @@ static int32_t translateTop(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } - //param0 - SNode* pParamNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (nodeType(pParamNode0) != QUERY_NODE_COLUMN) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The first parameter of TOP/BOTTOM function can only be column"); - } - - //param1 + // param1 SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1); if (nodeType(pParamNode1) != QUERY_NODE_VALUE) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); @@ -287,7 +266,7 @@ static int32_t translateTop(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { pValue->notReserved = true; - //set result type + // set result type SDataType* pType = &((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType; pFunc->node.resType = (SDataType){.bytes = pType->bytes, .type = pType->type}; return TSDB_CODE_SUCCESS; @@ -317,13 +296,6 @@ static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - // param0 - SNode* pParaNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (QUERY_NODE_COLUMN != nodeType(pParaNode0)) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The first parameter of ELAPSED function can only be column"); - } - uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; if (TSDB_DATA_TYPE_TIMESTAMP != paraType) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); @@ -389,13 +361,6 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - // param0 - SNode* pParaNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (QUERY_NODE_COLUMN != nodeType(pParaNode0)) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The first parameter of HISTOGRAM function can only be column"); - } - uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; if (!IS_NUMERIC_TYPE(colType)) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); @@ -428,12 +393,6 @@ static int32_t translateHLL(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0); - if (QUERY_NODE_COLUMN != nodeType(pPara)) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The input parameter of HYPERLOGLOG function can only be column"); - } - pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_UBIGINT].bytes, .type = TSDB_DATA_TYPE_UBIGINT}; return TSDB_CODE_SUCCESS; } @@ -444,12 +403,6 @@ static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - // param0 - SNode* pParaNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (QUERY_NODE_COLUMN != nodeType(pParaNode0)) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The input parameter of STATECOUNT function can only be column"); - } uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; if (!IS_NUMERIC_TYPE(colType)) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); @@ -484,12 +437,6 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32 return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - // param0 - SNode* pParaNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (QUERY_NODE_COLUMN != nodeType(pParaNode0)) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The input parameter of STATEDURATION function can only be column"); - } uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; if (!IS_NUMERIC_TYPE(colType)) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); @@ -528,12 +475,6 @@ static int32_t translateCsum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0); - if (QUERY_NODE_COLUMN != nodeType(pPara)) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The input parameter of CSUM function can only be column"); - } - uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; uint8_t resType; if (!IS_NUMERIC_TYPE(colType)) { @@ -559,13 +500,6 @@ static int32_t translateMavg(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - // param0 - SNode* pParaNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (QUERY_NODE_COLUMN != nodeType(pParaNode0)) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The first parameter of MAVG function can only be column"); - } - uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; // param1 @@ -595,13 +529,6 @@ static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len) return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - // param0 - SNode* pParamNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (QUERY_NODE_COLUMN != nodeType(pParamNode0)) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The first parameter of SAMPLE function can only be column"); - } - SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0); uint8_t colType = pCol->resType.type; @@ -639,12 +566,6 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - // param0 - SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0); - if (QUERY_NODE_COLUMN != nodeType(pPara)) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The first parameter of TAIL function can only be column"); - } SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0); uint8_t colType = pCol->resType.type; @@ -659,8 +580,8 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { if (pValue->datum.i < ((i > 1) ? 0 : 1) || pValue->datum.i > 100) { return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "TAIL function second parameter should be in range [1, 100], " - "third parameter should be in range [0, 100]"); + "TAIL function second parameter should be in range [1, 100], " + "third parameter should be in range [0, 100]"); } pValue->notReserved = true; @@ -721,20 +642,12 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - //param0 - SNode* pParamNode0 = nodesListGetNode(pFunc->pParameterList, 0); - if (nodeType(pParamNode0) != QUERY_NODE_COLUMN) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "The first parameter of DIFF function can only be column"); - } - uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; - if (!IS_SIGNED_NUMERIC_TYPE(colType) && !IS_FLOAT_TYPE(colType) && - TSDB_DATA_TYPE_BOOL != colType) { + if (!IS_SIGNED_NUMERIC_TYPE(colType) && !IS_FLOAT_TYPE(colType) && TSDB_DATA_TYPE_BOOL != colType) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } - //param1 + // param1 if (numOfParams == 2) { uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type; if (!IS_INTEGER_TYPE(paraType)) { @@ -852,7 +765,7 @@ static int32_t translateSubstr(SFunctionNode* pFunc, char* pErrBuf, int32_t len) if (3 == numOfParams) { SExprNode* p2 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 2); - uint8_t para2Type = p2->resType.type; + uint8_t para2Type = p2->resType.type; if (!IS_INTEGER_TYPE(para2Type)) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 68d3741b48..40c9e68620 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -408,6 +408,12 @@ static SNode* logicPartitionCopy(const SPartitionLogicNode* pSrc, SPartitionLogi return (SNode*)pDst; } +static SNode* logicIndefRowsFuncCopy(const SIndefRowsFuncLogicNode* pSrc, SIndefRowsFuncLogicNode* pDst) { + COPY_BASE_OBJECT_FIELD(node, logicNodeCopy); + CLONE_NODE_LIST_FIELD(pVectorFuncs); + return (SNode*)pDst; +} + static SNode* logicSubplanCopy(const SLogicSubplan* pSrc, SLogicSubplan* pDst) { COPY_OBJECT_FIELD(id, sizeof(SSubplanId)); CLONE_NODE_FIELD(pNode); @@ -537,6 +543,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) { return logicSortCopy((const SSortLogicNode*)pNode, (SSortLogicNode*)pDst); case QUERY_NODE_LOGIC_PLAN_PARTITION: return logicPartitionCopy((const SPartitionLogicNode*)pNode, (SPartitionLogicNode*)pDst); + case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC: + return logicIndefRowsFuncCopy((const SIndefRowsFuncLogicNode*)pNode, (SIndefRowsFuncLogicNode*)pDst); case QUERY_NODE_LOGIC_SUBPLAN: return logicSubplanCopy((const SLogicSubplan*)pNode, (SLogicSubplan*)pDst); default: diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 78710569cb..e47913a91b 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -198,6 +198,8 @@ const char* nodesNodeName(ENodeType type) { return "LogicSort"; case QUERY_NODE_LOGIC_PLAN_PARTITION: return "LogicPartition"; + case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC: + return "LogicIndefRowsFunc"; case QUERY_NODE_LOGIC_SUBPLAN: return "LogicSubplan"; case QUERY_NODE_LOGIC_PLAN: @@ -236,6 +238,8 @@ const char* nodesNodeName(ENodeType type) { return "PhysiStateWindow"; case QUERY_NODE_PHYSICAL_PLAN_PARTITION: return "PhysiPartition"; + case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC: + return "PhysiIndefRowsFunc"; case QUERY_NODE_PHYSICAL_PLAN_DISPATCH: return "PhysiDispatch"; case QUERY_NODE_PHYSICAL_PLAN_INSERT: @@ -727,6 +731,30 @@ static int32_t jsonToLogicPartitionNode(const SJson* pJson, void* pObj) { return code; } +static const char* jkIndefRowsFuncLogicPlanVectorFuncs = "VectorFuncs"; + +static int32_t logicIndefRowsFuncNodeToJson(const void* pObj, SJson* pJson) { + const SIndefRowsFuncLogicNode* pNode = (const SIndefRowsFuncLogicNode*)pObj; + + int32_t code = logicPlanNodeToJson(pObj, pJson); + if (TSDB_CODE_SUCCESS == code) { + code = nodeListToJson(pJson, jkIndefRowsFuncLogicPlanVectorFuncs, pNode->pVectorFuncs); + } + + return code; +} + +static int32_t jsonToLogicIndefRowsFuncNode(const SJson* pJson, void* pObj) { + SIndefRowsFuncLogicNode* pNode = (SIndefRowsFuncLogicNode*)pObj; + + int32_t code = jsonToLogicPlanNode(pJson, pObj); + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeList(pJson, jkIndefRowsFuncLogicPlanVectorFuncs, &pNode->pVectorFuncs); + } + + return code; +} + static const char* jkSubplanIdQueryId = "QueryId"; static const char* jkSubplanIdGroupId = "GroupId"; static const char* jkSubplanIdSubplanId = "SubplanId"; @@ -1744,6 +1772,37 @@ static int32_t jsonToPhysiPartitionNode(const SJson* pJson, void* pObj) { return code; } +static const char* jkIndefRowsFuncPhysiPlanExprs = "Exprs"; +static const char* jkIndefRowsFuncPhysiPlanVectorFuncs = "VectorFuncs"; + +static int32_t physiIndefRowsFuncNodeToJson(const void* pObj, SJson* pJson) { + const SIndefRowsFuncPhysiNode* pNode = (const SIndefRowsFuncPhysiNode*)pObj; + + int32_t code = physicPlanNodeToJson(pObj, pJson); + if (TSDB_CODE_SUCCESS == code) { + code = nodeListToJson(pJson, jkIndefRowsFuncPhysiPlanExprs, pNode->pExprs); + } + if (TSDB_CODE_SUCCESS == code) { + code = nodeListToJson(pJson, jkIndefRowsFuncPhysiPlanVectorFuncs, pNode->pVectorFuncs); + } + + return code; +} + +static int32_t jsonToPhysiIndefRowsFuncNode(const SJson* pJson, void* pObj) { + SIndefRowsFuncPhysiNode* pNode = (SIndefRowsFuncPhysiNode*)pObj; + + int32_t code = jsonToPhysicPlanNode(pJson, pObj); + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeList(pJson, jkIndefRowsFuncPhysiPlanExprs, &pNode->pExprs); + } + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeList(pJson, jkIndefRowsFuncPhysiPlanVectorFuncs, &pNode->pVectorFuncs); + } + + return code; +} + static const char* jkDataSinkInputDataBlockDesc = "InputDataBlockDesc"; static int32_t physicDataSinkNodeToJson(const void* pObj, SJson* pJson) { @@ -3394,6 +3453,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { return logicSortNodeToJson(pObj, pJson); case QUERY_NODE_LOGIC_PLAN_PARTITION: return logicPartitionNodeToJson(pObj, pJson); + case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC: + return logicIndefRowsFuncNodeToJson(pObj, pJson); case QUERY_NODE_LOGIC_SUBPLAN: return logicSubplanToJson(pObj, pJson); case QUERY_NODE_LOGIC_PLAN: @@ -3428,6 +3489,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { return physiStateWindowNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_PARTITION: return physiPartitionNodeToJson(pObj, pJson); + case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC: + return physiIndefRowsFuncNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_DISPATCH: return physiDispatchNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_INSERT: @@ -3505,6 +3568,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { return jsonToLogicSortNode(pJson, pObj); case QUERY_NODE_LOGIC_PLAN_PARTITION: return jsonToLogicPartitionNode(pJson, pObj); + case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC: + return jsonToLogicIndefRowsFuncNode(pJson, pObj); case QUERY_NODE_LOGIC_SUBPLAN: return jsonToLogicSubplan(pJson, pObj); case QUERY_NODE_LOGIC_PLAN: @@ -3539,6 +3604,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { return jsonToPhysiStateWindowNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_PARTITION: return jsonToPhysiPartitionNode(pJson, pObj); + case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC: + return jsonToPhysiIndefRowsFuncNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_DISPATCH: return jsonToPhysiDispatchNode(pJson, pObj); case QUERY_NODE_PHYSICAL_SUBPLAN: diff --git a/source/libs/nodes/src/nodesTraverseFuncs.c b/source/libs/nodes/src/nodesTraverseFuncs.c index ae1ff5744b..9c433aa678 100644 --- a/source/libs/nodes/src/nodesTraverseFuncs.c +++ b/source/libs/nodes/src/nodesTraverseFuncs.c @@ -350,6 +350,7 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa case SQL_CLAUSE_GROUP_BY: nodesWalkExpr(pSelect->pHaving, walker, pContext); case SQL_CLAUSE_HAVING: + case SQL_CLAUSE_SELECT: case SQL_CLAUSE_DISTINCT: nodesWalkExprs(pSelect->pOrderByList, walker, pContext); case SQL_CLAUSE_ORDER_BY: @@ -382,6 +383,7 @@ void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewrit case SQL_CLAUSE_GROUP_BY: nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext); case SQL_CLAUSE_HAVING: + case SQL_CLAUSE_SELECT: case SQL_CLAUSE_DISTINCT: nodesRewriteExprs(pSelect->pOrderByList, rewriter, pContext); case SQL_CLAUSE_ORDER_BY: diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index e28844f2e1..5232c96140 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -230,6 +230,8 @@ SNodeptr nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SSortLogicNode)); case QUERY_NODE_LOGIC_PLAN_PARTITION: return makeNode(type, sizeof(SPartitionLogicNode)); + case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC: + return makeNode(type, sizeof(SIndefRowsFuncLogicNode)); case QUERY_NODE_LOGIC_SUBPLAN: return makeNode(type, sizeof(SLogicSubplan)); case QUERY_NODE_LOGIC_PLAN: @@ -268,6 +270,8 @@ SNodeptr nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SStateWinodwPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_PARTITION: return makeNode(type, sizeof(SPartitionPhysiNode)); + case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC: + return makeNode(type, sizeof(SIndefRowsFuncPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_DISPATCH: return makeNode(type, sizeof(SDataDispatcherNode)); case QUERY_NODE_PHYSICAL_PLAN_INSERT: diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 467b26b7c4..273f46ac17 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -476,6 +476,37 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, return code; } +static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) { + // top/bottom are both an aggregate function and a indefinite rows function + if (!pSelect->hasIndefiniteRowsFunc || pSelect->hasAggFuncs) { + return TSDB_CODE_SUCCESS; + } + + SIndefRowsFuncLogicNode* pIdfRowsFunc = + (SIndefRowsFuncLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC); + if (NULL == pIdfRowsFunc) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsVectorFunc, &pIdfRowsFunc->pVectorFuncs); + if (TSDB_CODE_SUCCESS == code) { + code = rewriteExprForSelect(pIdfRowsFunc->pVectorFuncs, pSelect, SQL_CLAUSE_SELECT); + } + + // set the output + if (TSDB_CODE_SUCCESS == code) { + code = createColumnByRewriteExps(pCxt, pIdfRowsFunc->pVectorFuncs, &pIdfRowsFunc->node.pTargets); + } + + if (TSDB_CODE_SUCCESS == code) { + *pLogicNode = (SLogicNode*)pIdfRowsFunc; + } else { + nodesDestroyNode(pIdfRowsFunc); + } + + return code; +} + static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow, SLogicNode** pLogicNode) { int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_WINDOW, fmIsWindowClauseFunc, &pWindow->pFuncs); @@ -787,6 +818,9 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele if (TSDB_CODE_SUCCESS == code) { code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot); } + if (TSDB_CODE_SUCCESS == code) { + code = createChildLogicNode(pCxt, pSelect, createIndefRowsFuncLogicNode, &pRoot); + } if (TSDB_CODE_SUCCESS == code) { code = createChildLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot); } diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index a45eabefb9..69fa5499c4 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -800,6 +800,43 @@ static int32_t createAggPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, return code; } +static int32_t createIndefRowsFuncPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, + SIndefRowsFuncLogicNode* pFuncLogicNode, SPhysiNode** pPhyNode) { + SIndefRowsFuncPhysiNode* pIdfRowsFunc = (SIndefRowsFuncPhysiNode*)makePhysiNode( + pCxt, getPrecision(pChildren), (SLogicNode*)pFuncLogicNode, QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC); + if (NULL == pIdfRowsFunc) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + SNodeList* pPrecalcExprs = NULL; + SNodeList* pVectorFuncs = NULL; + int32_t code = rewritePrecalcExprs(pCxt, pFuncLogicNode->pVectorFuncs, &pPrecalcExprs, &pVectorFuncs); + + SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc); + // push down expression to pOutputDataBlockDesc of child node + if (TSDB_CODE_SUCCESS == code && NULL != pPrecalcExprs) { + code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pPrecalcExprs, &pIdfRowsFunc->pExprs); + if (TSDB_CODE_SUCCESS == code) { + code = pushdownDataBlockSlots(pCxt, pIdfRowsFunc->pExprs, pChildTupe); + } + } + + if (TSDB_CODE_SUCCESS == code && NULL != pVectorFuncs) { + code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pVectorFuncs, &pIdfRowsFunc->pVectorFuncs); + if (TSDB_CODE_SUCCESS == code) { + code = addDataBlockSlots(pCxt, pIdfRowsFunc->pVectorFuncs, pIdfRowsFunc->node.pOutputDataBlockDesc); + } + } + + if (TSDB_CODE_SUCCESS == code) { + *pPhyNode = (SPhysiNode*)pIdfRowsFunc; + } else { + nodesDestroyNode(pIdfRowsFunc); + } + + return code; +} + static int32_t createProjectPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SProjectLogicNode* pProjectLogicNode, SPhysiNode** pPhyNode) { SProjectPhysiNode* pProject = (SProjectPhysiNode*)makePhysiNode( @@ -949,7 +986,8 @@ static int32_t createSessionWindowPhysiNode(SPhysiPlanContext* pCxt, SNodeList* SWindowLogicNode* pWindowLogicNode, SPhysiNode** pPhyNode) { SSessionWinodwPhysiNode* pSession = (SSessionWinodwPhysiNode*)makePhysiNode( pCxt, getPrecision(pChildren), (SLogicNode*)pWindowLogicNode, - (pCxt->pPlanCxt->streamQuery ? QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION_WINDOW : QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW)); + (pCxt->pPlanCxt->streamQuery ? QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION_WINDOW + : QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW)); if (NULL == pSession) { return TSDB_CODE_OUT_OF_MEMORY; } @@ -1153,6 +1191,8 @@ static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode return createPartitionPhysiNode(pCxt, pChildren, (SPartitionLogicNode*)pLogicNode, pPhyNode); case QUERY_NODE_LOGIC_PLAN_FILL: return createFillPhysiNode(pCxt, pChildren, (SFillLogicNode*)pLogicNode, pPhyNode); + case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC: + return createIndefRowsFuncPhysiNode(pCxt, pChildren, (SIndefRowsFuncLogicNode*)pLogicNode, pPhyNode); default: break; } diff --git a/source/libs/planner/test/planProjectTest.cpp b/source/libs/planner/test/planProjectTest.cpp new file mode 100644 index 0000000000..3ef0038ae0 --- /dev/null +++ b/source/libs/planner/test/planProjectTest.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "planTestUtil.h" + +using namespace std; + +class PlanProjectTest : public PlannerTestBase {}; + +TEST_F(PlanProjectTest, basic) { + useDb("root", "test"); + + run("SELECT CEIL(c1) FROM t1"); +} + +TEST_F(PlanProjectTest, indefiniteRowsFunc) { + useDb("root", "test"); + + run("SELECT MAVG(c1, 10) FROM t1"); + + run("SELECT MAVG(CEIL(c1), 20) + 2 FROM t1"); +} From 0244c4ff9435217bdfb2f6c9090dba3acb23c6ba Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 4 Jun 2022 19:19:49 +0800 Subject: [PATCH 02/26] enh(query): add a new operator. --- source/libs/executor/inc/executorimpl.h | 21 ++- source/libs/executor/src/executorimpl.c | 174 +++++++++++++++++++++--- 2 files changed, 171 insertions(+), 24 deletions(-) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index cb45fa9730..16d758c0e3 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -493,11 +493,11 @@ typedef struct SAggOperatorInfo { typedef struct SProjectOperatorInfo { // SOptrBasicInfo should be first, SAggSupporter should be second for stream encode - SOptrBasicInfo binfo; - SAggSupporter aggSup; + SOptrBasicInfo binfo; // todo remove it + SAggSupporter aggSup; // todo remove it - SSDataBlock* existDataBlock; - SArray* pPseudoColInfo; + SSDataBlock* existDataBlock; // todo remove it + SArray* pPseudoColInfo; // todo remove it SLimit limit; SLimit slimit; @@ -509,6 +509,17 @@ typedef struct SProjectOperatorInfo { int64_t curOutput; } SProjectOperatorInfo; +typedef struct SIndefOperatorInfo { + SOptrBasicInfo binfo; + SAggSupporter aggSup; + SArray* pPseudoColInfo; + + SExprInfo* pScalarExpr; + int32_t numOfScalarExpr; + SqlFunctionCtx* pScalarCtx; + int32_t* rowCellInfoOffset; +} SIndefOperatorInfo; + typedef struct SFillOperatorInfo { struct SFillInfo* pFillInfo; SSDataBlock* pRes; @@ -731,6 +742,8 @@ SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo); SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num, SSDataBlock* pResBlock, SLimit* pLimit, SLimit* pSlimit, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhysiNode *pNode, SExecTaskInfo* pTaskInfo); + SOperatorInfo *createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pResBlock, SArray* pSortInfo, SExprInfo* pExprInfo, int32_t numOfCols, SArray* pIndexMap, SExecTaskInfo* pTaskInfo); diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index e7de886b03..acc38735f8 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -3750,18 +3750,6 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) { break; } -#if 0 - // Return result of the previous group in the firstly. - if (false) { - if (pRes->info.rows > 0) { - pProjectInfo->existDataBlock = pBlock; - break; - } else { // init output buffer for a new group data - initCtxOutputBuffer(pInfo->pCtx, pOperator->numOfExprs); - } - } -#endif - // the pDataBlock are always the same one, no need to call this again int32_t code = getTableScanInfo(pOperator->pDownstream[0], &order, &scanFlag); if (code != TSDB_CODE_SUCCESS) { @@ -3917,6 +3905,17 @@ static int32_t getNumOfScanTimes(STaskAttr* pQueryAttr) { return 1; } +static void destroyExprInfo(SExprInfo* pExpr, int32_t numOfExprs) { + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExprInfo = &pExpr[i]; + if (pExprInfo->pExpr->nodeType == QUERY_NODE_COLUMN) { + taosMemoryFree(pExprInfo->base.pParam[0].pCol); + } + taosMemoryFree(pExprInfo->base.pParam); + taosMemoryFree(pExprInfo->pExpr); + } +} + static void destroyOperatorInfo(SOperatorInfo* pOperator) { if (pOperator == NULL) { return; @@ -3936,14 +3935,7 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) { } if (pOperator->pExpr != NULL) { - for (int32_t i = 0; i < pOperator->numOfExprs; ++i) { - SExprInfo* pExprInfo = &pOperator->pExpr[i]; - if (pExprInfo->pExpr->nodeType == QUERY_NODE_COLUMN) { - taosMemoryFree(pExprInfo->base.pParam[0].pCol); - } - taosMemoryFree(pExprInfo->base.pParam); - taosMemoryFree(pExprInfo->pExpr); - } + destroyExprInfo(pOperator->pExpr, pOperator->numOfExprs); } taosMemoryFreeClear(pOperator->pExpr); @@ -4132,6 +4124,19 @@ static void destroyProjectOperatorInfo(void* param, int32_t numOfOutput) { taosArrayDestroy(pInfo->pPseudoColInfo); } +static void destroyIndefinitOperatorInfo(void* param, int32_t numOfOutput) { + SIndefOperatorInfo* pInfo = (SIndefOperatorInfo*) param; + doDestroyBasicInfo(&pInfo->binfo, numOfOutput); + + taosArrayDestroy(pInfo->pPseudoColInfo); + cleanupAggSup(&pInfo->aggSup); + + destroySqlFunctionCtx(pInfo->pScalarCtx, numOfOutput); + destroyExprInfo(pInfo->pScalarExpr, pInfo->numOfScalarExpr); + + taosMemoryFree(pInfo->rowCellInfoOffset); +} + void destroyExchangeOperatorInfo(void* param, int32_t numOfOutput) { SExchangeInfo* pExInfo = (SExchangeInfo*)param; taosArrayDestroy(pExInfo->pSources); @@ -4209,6 +4214,133 @@ _error: return NULL; } +static SSDataBlock* doApplyIndefinitFunction(SOperatorInfo* pOperator) { + SIndefOperatorInfo* pIndefInfo = pOperator->info; + SOptrBasicInfo* pInfo = &pIndefInfo->binfo; + + SSDataBlock* pRes = pInfo->pRes; + blockDataCleanup(pRes); + + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + int64_t st = 0; + int32_t order = 0; + int32_t scanFlag = 0; + + if (pOperator->cost.openCost == 0) { + st = taosGetTimestampUs(); + } + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + + while (1) { + // The downstream exec may change the value of the newgroup, so use a local variable instead. + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + doSetOperatorCompleted(pOperator); + break; + } + + // the pDataBlock are always the same one, no need to call this again + int32_t code = getTableScanInfo(pOperator->pDownstream[0], &order, &scanFlag); + if (code != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, code); + } + + // there is an scalar expression that needs to be calculated before apply the group aggregation. + if (pIndefInfo->pScalarExpr != NULL) { + code = projectApplyFunctions(pIndefInfo->pScalarExpr, pBlock, pBlock, pIndefInfo->pScalarCtx, + pIndefInfo->numOfScalarExpr, pIndefInfo->pPseudoColInfo); + if (code != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, code); + } + } + + setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, false); + blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows); + + code = projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs, pIndefInfo->pPseudoColInfo); + if (code != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, code); + } + } + + size_t rows = pInfo->pRes->info.rows; + pOperator->resultInfo.totalRows += rows; + + if (pOperator->cost.openCost == 0) { + pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0; + } + + return (rows > 0) ? pInfo->pRes : NULL; +} + +SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhysiNode *pNode, SExecTaskInfo* pTaskInfo) { + SIndefOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SIndefOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + + SIndefRowsFuncPhysiNode* pPhyNode = (SIndefRowsFuncPhysiNode*)pNode; + + int32_t numOfExpr = 0; + SExprInfo* pExprInfo = createExprInfo(pPhyNode->pVectorFuncs, NULL, &numOfExpr); + + int32_t numOfScalarExpr = 0; + if (pPhyNode->pExprs != NULL) { + pInfo->pScalarExpr = createExprInfo(pPhyNode->pExprs, NULL, &numOfScalarExpr); + pInfo->pScalarCtx = createSqlFunctionCtx(pInfo->pScalarExpr, numOfScalarExpr, &pInfo->rowCellInfoOffset); + } + + SSDataBlock* pResBlock = createResDataBlock(pPhyNode->node.pOutputDataBlockDesc);; + + int32_t numOfRows = 4096; + size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; + + // Make sure the size of SSDataBlock will never exceed the size of 2MB. + int32_t TWOMB = 2 * 1024 * 1024; + if (numOfRows * pResBlock->info.rowSize > TWOMB) { + numOfRows = TWOMB / pResBlock->info.rowSize; + } + initResultSizeInfo(pOperator, numOfRows); + + initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfExpr, pResBlock, keyBufSize, pTaskInfo->id.str); + setFunctionResultOutput(&pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, numOfExpr, pTaskInfo); + + pInfo->binfo.pRes = pResBlock; + pInfo->numOfScalarExpr = numOfScalarExpr; + pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pInfo->binfo.pCtx, numOfExpr); + + pOperator->name = "IndefinitOperator"; + pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT; + pOperator->blocking = false; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; + pOperator->pExpr = pExprInfo; + pOperator->numOfExprs = numOfExpr; + pOperator->pTaskInfo = pTaskInfo; + + pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doApplyIndefinitFunction, NULL, NULL, + destroyIndefinitOperatorInfo, NULL, NULL, NULL); + + int32_t code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + return pOperator; + + _error: + taosMemoryFree(pInfo); + taosMemoryFree(pOperator); + pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY; + return NULL; +} + static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t numOfCols, SNodeListNode* pValNode, STimeWindow win, int32_t capacity, const char* id, SInterval* pInterval, int32_t fillType) { SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, pValNode); @@ -4710,6 +4842,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo SInterval* pInterval = &((SIntervalAggOperatorInfo*)ops[0]->info)->interval; pOptr = createFillOperatorInfo(ops[0], pExprInfo, num, pInterval, &pFillNode->timeRange, pResBlock, pFillNode->mode, (SNodeListNode*)pFillNode->pValues, false, pTaskInfo); + } else if (QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC == type) { + pOptr = createIndefinitOutputOperatorInfo(ops[0], pPhyNode, pTaskInfo); } else { ASSERT(0); } From 90cb7966bcca982ae8310006e94722c172070cd8 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 6 Jun 2022 10:35:19 +0800 Subject: [PATCH 03/26] refactor: do some internal refactor. --- source/client/inc/clientInt.h | 4 +- source/client/src/clientEnv.c | 4 +- source/client/src/clientImpl.c | 43 +++++++---- source/client/src/clientMain.c | 76 ++++++++++++-------- source/client/src/clientMsgHandler.c | 26 +++---- source/client/src/clientSml.c | 2 +- source/client/test/clientTests.cpp | 2 +- source/client/test/smlTest.cpp | 30 ++++---- tests/script/tsim/testsuit.sim | 102 +++++++++++++-------------- tools/shell/src/shellEngine.c | 2 +- 10 files changed, 162 insertions(+), 129 deletions(-) diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index eaf18884c6..85d07d2ef7 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -45,7 +45,7 @@ extern "C" { #define ERROR_MSG_BUF_DEFAULT_SIZE 512 #define HEARTBEAT_INTERVAL 1500 // ms -#define SYNC_ON_TOP_OF_ASYNC 0 +#define SYNC_ON_TOP_OF_ASYNC 1 enum { RES_TYPE__QUERY = 1, @@ -274,7 +274,7 @@ int32_t releaseTscObj(int64_t rid); uint64_t generateRequestId(); -void* createRequest(STscObj* pObj, void* param, int32_t type); +void* createRequest(STscObj* pObj, int32_t type); void destroyRequest(SRequestObj* pRequest); SRequestObj* acquireRequest(int64_t rid); int32_t releaseRequest(int64_t rid); diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index be0a41ba40..c210a7ed39 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -177,7 +177,7 @@ STscObj *acquireTscObj(int64_t rid) { return (STscObj *)taosAcquireRef(clientCon int32_t releaseTscObj(int64_t rid) { return taosReleaseRef(clientConnRefPool, rid); } -void *createRequest(STscObj *pObj, void *param, int32_t type) { +void *createRequest(STscObj *pObj, int32_t type) { assert(pObj != NULL); SRequestObj *pRequest = (SRequestObj *)taosMemoryCalloc(1, sizeof(SRequestObj)); @@ -191,8 +191,6 @@ void *createRequest(STscObj *pObj, void *param, int32_t type) { pRequest->requestId = generateRequestId(); pRequest->metric.start = taosGetTimestampUs(); - pRequest->body.param = param; - pRequest->type = type; pRequest->pTscObj = pObj; pRequest->msgBuf = taosMemoryCalloc(1, ERROR_MSG_BUF_DEFAULT_SIZE); diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 916017543d..102d1a309d 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -133,7 +133,7 @@ TAOS* taos_connect_internal(const char* ip, const char* user, const char* pass, } int32_t buildRequest(STscObj* pTscObj, const char* sql, int sqlLen, SRequestObj** pRequest) { - *pRequest = createRequest(pTscObj, NULL, TSDB_SQL_SELECT); + *pRequest = createRequest(pTscObj, TSDB_SQL_SELECT); if (*pRequest == NULL) { tscError("failed to malloc sqlObj"); return TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -207,6 +207,7 @@ int32_t execLocalCmd(SRequestObj* pRequest, SQuery* pQuery) { if (TSDB_CODE_SUCCESS == code && NULL != pRsp) { code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, false, false); } + return code; } @@ -235,6 +236,30 @@ static SAppInstInfo* getAppInfo(SRequestObj* pRequest) { return pRequest->pTscObj->pAppInfo; } +void asyncExecLocalCmd(SRequestObj* pRequest, SQuery* pQuery) { + SRetrieveTableRsp* pRsp = NULL; + + int32_t code = qExecCommand(pQuery->pRoot, &pRsp); + if (TSDB_CODE_SUCCESS == code && NULL != pRsp) { + code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, false, false); + } + + SReqResultInfo* pResultInfo = &pRequest->body.resInfo; + + if (pRequest->code != TSDB_CODE_SUCCESS) { + pResultInfo->numOfRows = 0; + pRequest->code = code; + tscError("0x%" PRIx64 " fetch results failed, code:%s, reqId:0x%" PRIx64, pRequest->self, tstrerror(code), + pRequest->requestId); + } else { + tscDebug("0x%" PRIx64 " fetch results, numOfRows:%d total Rows:%" PRId64 ", complete:%d, reqId:0x%" PRIx64, + pRequest->self, pResultInfo->numOfRows, pResultInfo->totalRows, pResultInfo->completed, + pRequest->requestId); + } + + pRequest->body.fetchFp(pRequest->body.param, pRequest, pResultInfo->numOfRows); +} + int32_t asyncExecDdlQuery(SRequestObj* pRequest, SQuery* pQuery) { // drop table if exists not_exists_table if (NULL == pQuery->pCmdMsg) { @@ -617,13 +642,12 @@ SRequestObj* launchQuery(STscObj* pTscObj, const char* sql, int sqlLen) { } void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery) { - void* pRes = NULL; - int32_t code = 0; + switch (pQuery->execMode) { case QUERY_EXEC_MODE_LOCAL: - code = execLocalCmd(pRequest, pQuery); - break; + asyncExecLocalCmd(pRequest, pQuery); + return; case QUERY_EXEC_MODE_RPC: code = asyncExecDdlQuery(pRequest, pQuery); break; @@ -654,6 +678,7 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery) { // } } + //todo not to be released here taosArrayDestroy(pNodeList); break; } @@ -671,12 +696,6 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery) { if (NULL != pRequest && TSDB_CODE_SUCCESS != code) { pRequest->code = terrno; } - - // if (res) { - // *res = pRes; - // } else { -// freeRequestRes(pRequest, pRes); -// pRes = NULL; } int32_t refreshMeta(STscObj* pTscObj, SRequestObj* pRequest) { @@ -808,7 +827,7 @@ STscObj* taosConnectImpl(const char* user, const char* auth, const char* db, __t return pTscObj; } - SRequestObj* pRequest = createRequest(pTscObj, param, TDMT_MND_CONNECT); + SRequestObj* pRequest = createRequest(pTscObj, TDMT_MND_CONNECT); if (pRequest == NULL) { destroyTscObj(pTscObj); terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index bddc32ea20..c1f90197ac 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -30,6 +30,7 @@ #define TSC_VAR_RELEASED 0 static int32_t sentinel = TSC_VAR_NOT_RELEASE; +static int32_t createParseContext(const SRequestObj *pRequest, SParseContext** pCxt); int taos_options(TSDB_OPTION option, const void *arg, ...) { static int32_t lock = 0; @@ -626,6 +627,7 @@ void retrieveMetaCallback(SMetaData* pResultMeta, void* param, int32_t code) { TSWAP(pRequest->tableList, (pQuery)->pTableList); taosMemoryFree(pWrapper); + launchAsyncQuery(pRequest, pQuery); return; @@ -637,7 +639,6 @@ void retrieveMetaCallback(SMetaData* pResultMeta, void* param, int32_t code) { pRequest->body.queryFp(pRequest->body.param, pRequest, code); } -// todo add retry before return user's callback void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) { ASSERT(fp != NULL); @@ -657,7 +658,6 @@ void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param } SRequestObj *pRequest = NULL; - int32_t retryNum = 0; int32_t code = 0; // while (retryNum++ < REQUEST_MAX_TRY_TIMES) { @@ -671,30 +671,21 @@ void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param pRequest->body.queryFp = fp; pRequest->body.param = param; + SParseContext* pCxt = NULL; + code = createParseContext(pRequest, &pCxt); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + STscObj *pTscObj = pRequest->pTscObj; - - SParseContext* pCxt = taosMemoryCalloc(1, sizeof(SParseContext)); - *pCxt = (SParseContext){.requestId = pRequest->requestId, - .acctId = pTscObj->acctId, - .db = pRequest->pDb, - .topicQuery = false, - .pSql = pRequest->sqlstr, - .sqlLen = pRequest->sqlLen, - .pMsg = pRequest->msgBuf, - .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE, - .pTransporter = pTscObj->pAppInfo->pTransporter, - .pStmtCb = NULL, - .pUser = pTscObj->user, - .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)), - .async = true,}; - pCxt->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp); code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCxt->pCatalog); if (code != TSDB_CODE_SUCCESS) { goto _error; } - SQuery * pQuery = NULL; + SQuery *pQuery = NULL; + SCatalogReq catalogReq = {0}; code = qParseSqlSyntax(pCxt, &pQuery, &catalogReq); if (code != TSDB_CODE_SUCCESS) { @@ -702,6 +693,11 @@ void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param } SqlParseWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SqlParseWrapper)); + if (pWrapper == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _error; + } + pWrapper->pCtx = pCxt; pWrapper->pQuery = pQuery; pWrapper->pRequest = pRequest; @@ -716,19 +712,36 @@ void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param return; - // todo handle the retry process - - // if (TSDB_CODE_SUCCESS == code || NEED_CLIENT_HANDLE_ERROR(code)) { - // TSWAP(pRequest->dbList, (pQuery)->pDbList); - // TSWAP(pRequest->tableList, (pQuery)->pTableList); - // } - _error: terrno = code; pRequest->code = code; fp(param, pRequest, code); } +int32_t createParseContext(const SRequestObj *pRequest, SParseContext** pCxt) { + const STscObj *pTscObj = pRequest->pTscObj; + + *pCxt = taosMemoryCalloc(1, sizeof(SParseContext)); + if (*pCxt == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + **pCxt = (SParseContext){.requestId = pRequest->requestId, + .acctId = pTscObj->acctId, + .db = pRequest->pDb, + .topicQuery = false, + .pSql = pRequest->sqlstr, + .sqlLen = pRequest->sqlLen, + .pMsg = pRequest->msgBuf, + .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE, + .pTransporter = pTscObj->pAppInfo->pTransporter, + .pStmtCb = NULL, + .pUser = pTscObj->user, + .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)), + .async = true,}; + return TSDB_CODE_SUCCESS; +} + static void fetchCallback(void* pResult, void* param, int32_t code) { SRequestObj* pRequest = (SRequestObj*) param; @@ -751,14 +764,15 @@ static void fetchCallback(void* pResult, void* param, int32_t code) { pRequest->code = setQueryResultFromRsp(&pRequest->body.resInfo, (SRetrieveTableRsp*)pResultInfo->pData, true, false); if (pRequest->code != TSDB_CODE_SUCCESS) { pResultInfo->numOfRows = 0; - pRequest->code = code; - pRequest->body.fetchFp(pRequest->body.param, pRequest, 0); + tscError("0x%" PRIx64 " fetch results failed, code:%s, reqId:0x%" PRIx64, pRequest->self, tstrerror(code), + pRequest->requestId); + } else { + tscDebug("0x%" PRIx64 " fetch results, numOfRows:%d total Rows:%" PRId64 ", complete:%d, reqId:0x%" PRIx64, + pRequest->self, pResultInfo->numOfRows, pResultInfo->totalRows, pResultInfo->completed, + pRequest->requestId); } - tscDebug("0x%" PRIx64 " fetch results, numOfRows:%d total Rows:%" PRId64 ", complete:%d, reqId:0x%" PRIx64, - pRequest->self, pResultInfo->numOfRows, pResultInfo->totalRows, pResultInfo->completed, pRequest->requestId); - pRequest->body.fetchFp(pRequest->body.param, pRequest, pResultInfo->numOfRows); } diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index 2d5199f181..29fd1c74f9 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -251,20 +251,22 @@ int32_t processAlterStbRsp(void* param, const SDataBuf* pMsg, int32_t code) { SRequestObj* pRequest = param; if (code != TSDB_CODE_SUCCESS) { setErrno(pRequest, code); - tsem_post(&pRequest->body.rspSem); - return code; + } else { + SMAlterStbRsp alterRsp = {0}; + SDecoder coder = {0}; + tDecoderInit(&coder, pMsg->pData, pMsg->len); + tDecodeSMAlterStbRsp(&coder, &alterRsp); + tDecoderClear(&coder); + + pRequest->body.resInfo.execRes.msgType = TDMT_MND_ALTER_STB; + pRequest->body.resInfo.execRes.res = alterRsp.pMeta; } - SMAlterStbRsp alterRsp = {0}; - SDecoder coder = {0}; - tDecoderInit(&coder, pMsg->pData, pMsg->len); - tDecodeSMAlterStbRsp(&coder, &alterRsp); - tDecoderClear(&coder); - - pRequest->body.resInfo.execRes.msgType = TDMT_MND_ALTER_STB; - pRequest->body.resInfo.execRes.res = alterRsp.pMeta; - - tsem_post(&pRequest->body.rspSem); + if (pRequest->body.queryFp != NULL) { + pRequest->body.queryFp(pRequest->body.param, pRequest, code); + } else { + tsem_post(&pRequest->body.rspSem); + } return code; } diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index 5643af746d..4cef67b34d 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -2364,7 +2364,7 @@ static int32_t isSchemalessDb(SSmlHandle* info){ */ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int protocol, int precision) { - SRequestObj* request = (SRequestObj*)createRequest((STscObj *)taos, NULL, TSDB_SQL_INSERT); + SRequestObj* request = (SRequestObj*)createRequest((STscObj *)taos, TSDB_SQL_INSERT); if(!request){ uError("SML:taos_schemaless_insert error request is null"); return NULL; diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index a0f33627c4..54caccdc8e 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -778,7 +778,7 @@ TEST(testCase, async_api_test) { TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT_NE(pConn, nullptr); - taos_query_a(pConn, "drop table test.tm0", queryCallback, pConn); + taos_query_a(pConn, "desc abc1.tu", queryCallback, pConn); getchar(); taos_close(pConn); } diff --git a/source/client/test/smlTest.cpp b/source/client/test/smlTest.cpp index 1358d45f30..3bfd26bb43 100644 --- a/source/client/test/smlTest.cpp +++ b/source/client/test/smlTest.cpp @@ -486,7 +486,7 @@ TEST(testCase, smlProcess_influx_Test) { pRes = taos_query(taos, "use inflx_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -607,7 +607,7 @@ TEST(testCase, smlParseLine_error_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -656,7 +656,7 @@ TEST(testCase, smlProcess_telnet_Test) { pRes = taos_query(taos, "use telnet_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -710,7 +710,7 @@ TEST(testCase, smlProcess_json1_Test) { pRes = taos_query(taos, "use json_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -779,7 +779,7 @@ TEST(testCase, smlProcess_json2_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -823,7 +823,7 @@ TEST(testCase, smlProcess_json3_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -895,7 +895,7 @@ TEST(testCase, smlProcess_json4_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -957,7 +957,7 @@ TEST(testCase, smlParseTelnetLine_error_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -1006,7 +1006,7 @@ TEST(testCase, smlParseTelnetLine_diff_type_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -1033,7 +1033,7 @@ TEST(testCase, smlParseTelnetLine_json_error_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -1101,7 +1101,7 @@ TEST(testCase, smlParseTelnetLine_diff_json_type1_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -1146,7 +1146,7 @@ TEST(testCase, smlParseTelnetLine_diff_json_type2_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -1191,7 +1191,7 @@ TEST(testCase, sml_TD15662_Test) { pRes = taos_query(taos, "use db_15662"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj *)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_MILLI_SECONDS); @@ -1218,7 +1218,7 @@ TEST(testCase, sml_TD15735_Test) { pRes = taos_query(taos, "use sml_db"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS); @@ -1244,7 +1244,7 @@ TEST(testCase, sml_TD15742_Test) { pRes = taos_query(taos, "use TD15742"); taos_free_result(pRes); - SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, NULL, TSDB_SQL_INSERT); + SRequestObj *request = (SRequestObj *)createRequest((STscObj*)taos, TSDB_SQL_INSERT); ASSERT_NE(request, nullptr); SSmlHandle *info = smlBuildSmlInfo(taos, request, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_MILLI_SECONDS); diff --git a/tests/script/tsim/testsuit.sim b/tests/script/tsim/testsuit.sim index c73efde9d5..527d28a336 100644 --- a/tests/script/tsim/testsuit.sim +++ b/tests/script/tsim/testsuit.sim @@ -7,57 +7,57 @@ #run tsim/table/basic1.sim #run tsim/trans/lossdata1.sim #run tsim/trans/create_db.sim -##run tsim/stable/alter_metrics.sim -##run tsim/stable/tag_modify.sim -##run tsim/stable/alter_comment.sim -##run tsim/stable/column_drop.sim -##run tsim/stable/column_modify.sim -##run tsim/stable/tag_rename.sim -#run tsim/stable/vnode3.sim -#run tsim/stable/metrics.sim -##run tsim/stable/alter_insert2.sim -#run tsim/stable/show.sim -#run tsim/stable/alter_import.sim -##run tsim/stable/tag_add.sim -#run tsim/stable/tag_drop.sim -#run tsim/stable/column_add.sim -#run tsim/stable/alter_count.sim -#run tsim/stable/values.sim -#run tsim/stable/dnode3.sim -#run tsim/stable/alter_insert1.sim -#run tsim/stable/refcount.sim -#run tsim/stable/disk.sim -#run tsim/db/basic1.sim -#run tsim/db/basic3.sim -##run tsim/db/basic7.sim -#run tsim/db/basic6.sim -#run tsim/db/create_all_options.sim -#run tsim/db/basic2.sim -#run tsim/db/error1.sim -#run tsim/db/taosdlog.sim -#run tsim/db/alter_option.sim -#run tsim/mnode/basic1.sim -#run tsim/mnode/basic3.sim -#run tsim/mnode/basic2.sim -#run tsim/parser/fourArithmetic-basic.sim -#run tsim/parser/groupby-basic.sim -#run tsim/snode/basic1.sim -#run tsim/query/time_process.sim -#run tsim/query/stddev.sim -#run tsim/query/interval-offset.sim -#run tsim/query/charScalarFunction.sim -#run tsim/query/complex_select.sim -#run tsim/query/explain.sim -#run tsim/query/crash_sql.sim -#run tsim/query/diff.sim -#run tsim/query/complex_limit.sim -#run tsim/query/complex_having.sim -#run tsim/query/udf.sim -#run tsim/query/complex_group.sim -#run tsim/query/interval.sim -#run tsim/query/session.sim -#run tsim/query/scalarFunction.sim -##run tsim/query/scalarNull.sim +#run tsim/stable/alter_metrics.sim +#run tsim/stable/tag_modify.sim +run tsim/stable/alter_comment.sim +run tsim/stable/column_drop.sim +run tsim/stable/column_modify.sim +run tsim/stable/tag_rename.sim +run tsim/stable/vnode3.sim +run tsim/stable/metrics.sim +run tsim/stable/alter_insert2.sim +run tsim/stable/show.sim +run tsim/stable/alter_import.sim +run tsim/stable/tag_add.sim +run tsim/stable/tag_drop.sim +run tsim/stable/column_add.sim +run tsim/stable/alter_count.sim +run tsim/stable/values.sim +run tsim/stable/dnode3.sim +run tsim/stable/alter_insert1.sim +run tsim/stable/refcount.sim +run tsim/stable/disk.sim +run tsim/db/basic1.sim +run tsim/db/basic3.sim +#run tsim/db/basic7.sim +run tsim/db/basic6.sim +run tsim/db/create_all_options.sim +run tsim/db/basic2.sim +run tsim/db/error1.sim +run tsim/db/taosdlog.sim +run tsim/db/alter_option.sim +run tsim/mnode/basic1.sim +run tsim/mnode/basic3.sim +run tsim/mnode/basic2.sim +run tsim/parser/fourArithmetic-basic.sim +run tsim/parser/groupby-basic.sim +run tsim/snode/basic1.sim +run tsim/query/time_process.sim +run tsim/query/stddev.sim +run tsim/query/interval-offset.sim +run tsim/query/charScalarFunction.sim +run tsim/query/complex_select.sim +run tsim/query/explain.sim +run tsim/query/crash_sql.sim +run tsim/query/diff.sim +run tsim/query/complex_limit.sim +run tsim/query/complex_having.sim +run tsim/query/udf.sim +run tsim/query/complex_group.sim +run tsim/query/interval.sim +run tsim/query/session.sim +run tsim/query/scalarFunction.sim +#run tsim/query/scalarNull.sim run tsim/query/complex_where.sim run tsim/tmq/basic1.sim run tsim/tmq/basic4.sim diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index 851d9a2070..329842aeb3 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -1003,7 +1003,7 @@ int32_t shellExecute() { taosSetSignal(SIGINT, shellSigintHandler); - shellGetGrantInfo(shell.conn); + shellGetGrantInfo(); while (1) { taosThreadCreate(&shell.pid, NULL, shellThreadLoop, shell.conn); From 570d464129c4f2cf071cf87552d5e9e80e15a327 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 6 Jun 2022 10:36:32 +0800 Subject: [PATCH 04/26] refactor: do some internal refactor. --- source/client/test/clientTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index 54caccdc8e..0dbef311fe 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -778,7 +778,7 @@ TEST(testCase, async_api_test) { TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT_NE(pConn, nullptr); - taos_query_a(pConn, "desc abc1.tu", queryCallback, pConn); + taos_query_a(pConn, "desc abc1.tm0", queryCallback, pConn); getchar(); taos_close(pConn); } From 79d8361a085ccc5cdcd67b710dbbe60ca305b275 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 6 Jun 2022 10:36:48 +0800 Subject: [PATCH 05/26] refactor: do some internal refactor. --- source/client/test/clientTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index 0dbef311fe..514bcc95cc 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -778,7 +778,7 @@ TEST(testCase, async_api_test) { TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT_NE(pConn, nullptr); - taos_query_a(pConn, "desc abc1.tm0", queryCallback, pConn); + taos_query_a(pConn, "desc test.tm0", queryCallback, pConn); getchar(); taos_close(pConn); } From 8e8f5fbab2701e9a713753c7574a99c1078b1a45 Mon Sep 17 00:00:00 2001 From: "wenzhouwww@live.cn" Date: Mon, 6 Jun 2022 11:30:11 +0800 Subject: [PATCH 06/26] update csum case --- tests/system-test/2-query/csum.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/system-test/2-query/csum.py b/tests/system-test/2-query/csum.py index a331311fd2..5c2de5ea14 100644 --- a/tests/system-test/2-query/csum.py +++ b/tests/system-test/2-query/csum.py @@ -240,7 +240,7 @@ class TDTestCase: tdSql.error("select csum(c1) t1") # no from tdSql.error("select csum( c1 ) from ") # no table_expr # tdSql.error(self.csum_query_form(col="st1")) # tag col - tdSql.error(self.csum_query_form(col=1)) # col is a value + # tdSql.error(self.csum_query_form(col=1)) # col is a value tdSql.error(self.csum_query_form(col="'c1'")) # col is a string tdSql.error(self.csum_query_form(col=None)) # col is NULL 1 tdSql.error(self.csum_query_form(col="NULL")) # col is NULL 2 @@ -407,6 +407,14 @@ class TDTestCase: tdDnodes.start(index) self.csum_current_query() self.csum_error_query() + tdSql.query("select csum(1) from t1 ") + tdSql.checkRows(7) + tdSql.checkData(0,0,1) + tdSql.checkData(1,0,2) + tdSql.checkData(2,0,3) + tdSql.checkData(3,0,4) + tdSql.query("select csum(abs(c1))+2 from t1 ") + tdSql.checkRows(4) def run(self): import traceback From 7fc1e3a40fd9fe61707afcd5e926f650ccea1d35 Mon Sep 17 00:00:00 2001 From: "wenzhouwww@live.cn" Date: Mon, 6 Jun 2022 11:35:28 +0800 Subject: [PATCH 07/26] update case for mavg --- tests/system-test/2-query/mavg.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/system-test/2-query/mavg.py b/tests/system-test/2-query/mavg.py index 1d92964615..13d2b4d420 100644 --- a/tests/system-test/2-query/mavg.py +++ b/tests/system-test/2-query/mavg.py @@ -417,8 +417,8 @@ class TDTestCase: # err9 = {"col": "st1"} # self.checkmavg(**err9) # col: tag - err10 = {"col": 1} - self.checkmavg(**err10) # col: value + # err10 = {"col": 1} + # self.checkmavg(**err10) # col: value err11 = {"col": "NULL"} self.checkmavg(**err11) # col: NULL err12 = {"col": "%_"} @@ -660,6 +660,14 @@ class TDTestCase: tdDnodes.start(index) self.mavg_current_query() self.mavg_error_query() + tdSql.query("select mavg(1,1) from t1") + tdSql.checkRows(7) + tdSql.checkData(0,0,1.000000000) + tdSql.checkData(1,0,1.000000000) + tdSql.checkData(5,0,1.000000000) + + tdSql.query("select mavg(abs(c1),1) from t1") + tdSql.checkRows(4) def run(self): import traceback From 5033cf0c8419bd7493ad15b687e27f9155214841 Mon Sep 17 00:00:00 2001 From: "wenzhouwww@live.cn" Date: Mon, 6 Jun 2022 14:04:51 +0800 Subject: [PATCH 08/26] update case for sample --- tests/system-test/2-query/sample.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/system-test/2-query/sample.py b/tests/system-test/2-query/sample.py index 94e06347d2..4b651b56e7 100644 --- a/tests/system-test/2-query/sample.py +++ b/tests/system-test/2-query/sample.py @@ -427,10 +427,10 @@ class TDTestCase: # err9 = {"col": "st1"} # self.checksample(**err9) # col: tag tdSql.query(" select sample(st1 ,1) from t1 ") - err10 = {"col": 1} - self.checksample(**err10) # col: value - err11 = {"col": "NULL"} - self.checksample(**err11) # col: NULL + # err10 = {"col": 1} + # self.checksample(**err10) # col: value + # err11 = {"col": "NULL"} + # self.checksample(**err11) # col: NULL err12 = {"col": "%_"} self.checksample(**err12) # col: %_ err13 = {"col": "c3"} @@ -445,12 +445,12 @@ class TDTestCase: self.checksample(**err17) # nchar col err18 = {"col": "c6"} self.checksample(**err18) # bool col - err19 = {"col": "'c1'"} - self.checksample(**err19) # col: string + # err19 = {"col": "'c1'"} + # self.checksample(**err19) # col: string err20 = {"col": None} self.checksample(**err20) # col: None - err21 = {"col": "''"} - self.checksample(**err21) # col: '' + # err21 = {"col": "''"} + # self.checksample(**err21) # col: '' err22 = {"col": "tt1.c1"} self.checksample(**err22) # not table_expr col err23 = {"col": "t1"} @@ -459,10 +459,10 @@ class TDTestCase: self.checksample(**err24) # stbname err25 = {"col": "db"} self.checksample(**err25) # datbasename - err26 = {"col": "True"} - self.checksample(**err26) # col: BOOL 1 - err27 = {"col": True} - self.checksample(**err27) # col: BOOL 2 + # err26 = {"col": "True"} + # self.checksample(**err26) # col: BOOL 1 + # err27 = {"col": True} + # self.checksample(**err27) # col: BOOL 2 err28 = {"col": "*"} self.checksample(**err28) # col: all col err29 = {"func": "sample[", "r_comm": "]"} @@ -678,7 +678,7 @@ class TDTestCase: tdSql.error(" select sample(c1,tbname) from t1 ") tdSql.error(" select sample(c1,ts) from t1 ") tdSql.error(" select sample(c1,false) from t1 ") - tdSql.error(" select sample(123,1) from t1 ") + tdSql.query(" select sample(123,1) from t1 ") tdSql.query(" select sample(c1,2) from t1 ") tdSql.checkRows(2) From d8e89196a60c9ba89bd261861d2f464a0ca446bb Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Mon, 6 Jun 2022 14:12:57 +0800 Subject: [PATCH 09/26] fix: a problem of parser async --- source/libs/parser/src/parAstParser.c | 13 +++++++++++++ source/libs/parser/test/mockCatalog.cpp | 9 +++++++++ source/libs/parser/test/parInitialDTest.cpp | 12 ++++++++++-- source/libs/parser/test/parTestUtil.h | 10 ++++++---- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index 6c44ce4c3c..c79820a950 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -258,6 +258,17 @@ static int32_t collectMetaKeyFromExplain(SCollectMetaKeyCxt* pCxt, SExplainStmt* return collectMetaKeyFromQuery(pCxt, pStmt->pQuery); } +static int32_t collectMetaKeyFromDescribe(SCollectMetaKeyCxt* pCxt, SDescribeStmt* pStmt) { + SName name = {.type = TSDB_TABLE_NAME_T, .acctId = pCxt->pParseCxt->acctId}; + strcpy(name.dbname, pStmt->dbName); + strcpy(name.tname, pStmt->tableName); + int32_t code = catalogRemoveTableMeta(pCxt->pParseCxt->pCatalog, &name); + if (TSDB_CODE_SUCCESS == code) { + code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache); + } + return code; +} + static int32_t collectMetaKeyFromCreateStream(SCollectMetaKeyCxt* pCxt, SCreateStreamStmt* pStmt) { return collectMetaKeyFromQuery(pCxt, pStmt->pQuery); } @@ -381,6 +392,8 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) { return collectMetaKeyFromCreateTopic(pCxt, (SCreateTopicStmt*)pStmt); case QUERY_NODE_EXPLAIN_STMT: return collectMetaKeyFromExplain(pCxt, (SExplainStmt*)pStmt); + case QUERY_NODE_DESCRIBE_STMT: + return collectMetaKeyFromDescribe(pCxt, (SDescribeStmt*)pStmt); case QUERY_NODE_CREATE_STREAM_STMT: return collectMetaKeyFromCreateStream(pCxt, (SCreateStreamStmt*)pStmt); case QUERY_NODE_SHOW_DNODES_STMT: diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index 8fb28ce395..c7f0990132 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -207,6 +207,13 @@ int32_t __catalogGetUdfInfo(SCatalog* pCtg, void* pTrans, const SEpSet* pMgmtEps return g_mockCatalogService->catalogGetUdfInfo(funcName, pInfo); } +int32_t __catalogRefreshGetTableMeta(SCatalog* pCatalog, void* pTransporter, const SEpSet* pMgmtEps, + const SName* pTableName, STableMeta** pTableMeta, int32_t isSTable) { + return g_mockCatalogService->catalogGetTableMeta(pTableName, pTableMeta); +} + +int32_t __catalogRemoveTableMeta(SCatalog* pCtg, SName* pTableName) { return 0; } + void initMetaDataEnv() { g_mockCatalogService.reset(new MockCatalogService()); @@ -221,6 +228,8 @@ void initMetaDataEnv() { stub.set(catalogGetDBCfg, __catalogGetDBCfg); stub.set(catalogChkAuth, __catalogChkAuth); stub.set(catalogGetUdfInfo, __catalogGetUdfInfo); + stub.set(catalogRefreshGetTableMeta, __catalogRefreshGetTableMeta); + stub.set(catalogRemoveTableMeta, __catalogRemoveTableMeta); // { // AddrAny any("libcatalog.so"); // std::map result; diff --git a/source/libs/parser/test/parInitialDTest.cpp b/source/libs/parser/test/parInitialDTest.cpp index d4f9a540ae..ee74dbe4a4 100644 --- a/source/libs/parser/test/parInitialDTest.cpp +++ b/source/libs/parser/test/parInitialDTest.cpp @@ -21,7 +21,7 @@ namespace ParserTest { class ParserInitialDTest : public ParserDdlTest {}; -// DELETE FROM tb_name [WHERE condition] +// DELETE FROM table_name [WHERE condition] TEST_F(ParserInitialDTest, delete) { useDb("root", "test"); @@ -40,7 +40,15 @@ TEST_F(ParserInitialDTest, deleteSemanticCheck) { run("DELETE FROM t1 WHERE c1 > 10", TSDB_CODE_PAR_INVALID_DELETE_WHERE, PARSER_STAGE_TRANSLATE); } -// todo desc +// DESC table_name +TEST_F(ParserInitialDTest, describe) { + useDb("root", "test"); + + run("DESC t1"); + + run("DESCRIBE st1"); +} + // todo describe // todo DROP account diff --git a/source/libs/parser/test/parTestUtil.h b/source/libs/parser/test/parTestUtil.h index 44be7a2474..07f3d3cece 100644 --- a/source/libs/parser/test/parTestUtil.h +++ b/source/libs/parser/test/parTestUtil.h @@ -50,11 +50,13 @@ class ParserDdlTest : public ParserTestBase { virtual void checkDdl(const SQuery* pQuery, ParserStage stage) { ASSERT_NE(pQuery, nullptr); - ASSERT_EQ(pQuery->haveResultSet, false); ASSERT_NE(pQuery->pRoot, nullptr); - ASSERT_EQ(pQuery->numOfResCols, 0); - ASSERT_EQ(pQuery->pResSchema, nullptr); - ASSERT_EQ(pQuery->precision, 0); + if (QUERY_EXEC_MODE_RPC == pQuery->execMode) { + ASSERT_EQ(pQuery->haveResultSet, false); + ASSERT_EQ(pQuery->numOfResCols, 0); + ASSERT_EQ(pQuery->pResSchema, nullptr); + ASSERT_EQ(pQuery->precision, 0); + } if (nullptr != checkDdl_) { checkDdl_(pQuery, stage); } From bd3e0a76fb3c23cf3d1ce955b7d4cd78598341ce Mon Sep 17 00:00:00 2001 From: "wenzhouwww@live.cn" Date: Mon, 6 Jun 2022 14:13:56 +0800 Subject: [PATCH 10/26] update case for statedurcation --- tests/system-test/2-query/function_stateduration.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/system-test/2-query/function_stateduration.py b/tests/system-test/2-query/function_stateduration.py index b25a658469..9aa6fdaefa 100644 --- a/tests/system-test/2-query/function_stateduration.py +++ b/tests/system-test/2-query/function_stateduration.py @@ -85,8 +85,8 @@ class TDTestCase: "select stateduration(c1 ,'GT','*',1s) from t1", "select stateduration(c1 ,'GT',ts,1s) from t1", "select stateduration(c1 ,'GT',max(c1),1s) from t1", - "select stateduration(abs(c1) ,'GT',1,1s) from t1", - "select stateduration(c1+2 ,'GT',1,1s) from t1", + # "select stateduration(abs(c1) ,'GT',1,1s) from t1", + # "select stateduration(c1+2 ,'GT',1,1s) from t1", "select stateduration(c1 ,'GT',1,1u) from t1", "select stateduration(c1 ,'GT',1,now) from t1", "select stateduration(c1 ,'GT','1',1s) from t1", @@ -323,6 +323,11 @@ class TDTestCase: tdSql.checkData(0, 0, None) tdSql.checkData(1, 0, 0.000000000) tdSql.checkData(3, 0, -86404.000000000) + + tdSql.query("select stateduration(abs(c1) ,'GT',1,1s) from t1") + tdSql.checkRows(12) + tdSql.query("select stateduration(c1+2 ,'GT',1,1s) from t1") + tdSql.checkRows(12) # bug for stable From 4f33ecbf23129cf576d67e93e80dd36dbff06fdb Mon Sep 17 00:00:00 2001 From: "wenzhouwww@live.cn" Date: Mon, 6 Jun 2022 14:15:20 +0800 Subject: [PATCH 11/26] update case --- tests/system-test/2-query/statecount.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system-test/2-query/statecount.py b/tests/system-test/2-query/statecount.py index 2634d9a9ab..ccda55f7ba 100644 --- a/tests/system-test/2-query/statecount.py +++ b/tests/system-test/2-query/statecount.py @@ -85,8 +85,8 @@ class TDTestCase: "select statecount(c1 ,'GT','*') from t1", "select statecount(c1 ,'GT',ts) from t1", "select statecount(c1 ,'GT',max(c1)) from t1", - "select statecount(abs(c1) ,'GT',1) from t1", - "select statecount(c1+2 ,'GT',1) from t1", + # "select statecount(abs(c1) ,'GT',1) from t1", + # "select statecount(c1+2 ,'GT',1) from t1", "select statecount(c1 ,'GT',1,1u) from t1", "select statecount(c1 ,'GT',1,now) from t1", "select statecount(c1 ,'GT','1') from t1", From 37b7f06b4a663b4b1864671c400e410527d028f4 Mon Sep 17 00:00:00 2001 From: "wenzhouwww@live.cn" Date: Mon, 6 Jun 2022 14:18:36 +0800 Subject: [PATCH 12/26] update case for elapsed function --- tests/system-test/2-query/elapsed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/2-query/elapsed.py b/tests/system-test/2-query/elapsed.py index 017090128d..1553e06914 100644 --- a/tests/system-test/2-query/elapsed.py +++ b/tests/system-test/2-query/elapsed.py @@ -141,7 +141,7 @@ class TDTestCase: tablenames = ["sub_table1_1","sub_table1_2","sub_table1_3","sub_table2_1","sub_table2_2","sub_table2_3","regular_table_1","regular_table_2","regular_table_3"] abnormal_list = ["()","(NULL)","(*)","(abc)","( , )","(NULL,*)","( ,NULL)","(%)","(+)","(*,)","(*, /)","(ts,*)" "(ts,tbname*10)","(ts,tagname)", - "(ts,2d+3m-2s,NULL)","(ts+1d,10s)","(ts+10d,NULL)" ,"(ts,now -1m%1d)","(ts+10d)","(ts+10d,_c0)","(ts+10d,)","(ts,%)","(ts, , m)","(ts,abc)","(ts,/)","(ts,*)","(ts,1s,100)", + "(ts,2d+3m-2s,NULL)","(ts+10d,NULL)" ,"(ts,now -1m%1d)","(ts+10d,_c0)","(ts+10d,)","(ts,%)","(ts, , m)","(ts,abc)","(ts,/)","(ts,*)","(ts,1s,100)", "(ts,1s,abc)","(ts,1s,_c0)","(ts,1s,*)","(ts,1s,NULL)","(ts,,_c0)","(ts,tbname,ts)","(ts,0,tbname)","('2021-11-18 00:00:10')","('2021-11-18 00:00:10', 1s)", "('2021-11-18T00:00:10+0800', '1s')","('2021-11-18T00:00:10Z', '1s')","('2021-11-18T00:00:10+0800', 10000000d,)","('ts', ,2021-11-18T00:00:10+0800, )"] From c0ec997ddab174932512cc57ae08def9cd2b5927 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 6 Jun 2022 14:56:54 +0800 Subject: [PATCH 13/26] enh: support more json filter case --- source/libs/index/inc/indexInt.h | 12 ++++++------ source/libs/index/src/indexFilter.c | 8 +++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/libs/index/inc/indexInt.h b/source/libs/index/inc/indexInt.h index 24a4e99970..2cba6a347e 100644 --- a/source/libs/index/inc/indexInt.h +++ b/source/libs/index/inc/indexInt.h @@ -35,12 +35,12 @@ extern "C" { #endif // clang-format off -#define indexFatal(...) do { if (idxDebugFlag & DEBUG_FATAL) { taosPrintLog("INDEX FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} while (0) -#define indexError(...) do { if (idxDebugFlag & DEBUG_ERROR) { taosPrintLog("INDEX ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} while (0) -#define indexWarn(...) do { if (idxDebugFlag & DEBUG_WARN) { taosPrintLog("INDEX WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} while (0) -#define indexInfo(...) do { if (idxDebugFlag & DEBUG_INFO) { taosPrintLog("INDEX ", DEBUG_INFO, 255, __VA_ARGS__); } } while (0) -#define indexDebug(...) do { if (idxDebugFlag & DEBUG_DEBUG) { taosPrintLog("INDEX ", DEBUG_DEBUG, sDebugFlag, __VA_ARGS__);} } while (0) -#define indexTrace(...) do { if (idxDebugFlag & DEBUG_TRACE) { taosPrintLog("INDEX ", DEBUG_TRACE, sDebugFlag, __VA_ARGS__);} } while (0) +#define indexFatal(...) do { if (idxDebugFlag & DEBUG_FATAL) { taosPrintLog("IDX FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} while (0) +#define indexError(...) do { if (idxDebugFlag & DEBUG_ERROR) { taosPrintLog("IDX ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} while (0) +#define indexWarn(...) do { if (idxDebugFlag & DEBUG_WARN) { taosPrintLog("IDX WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} while (0) +#define indexInfo(...) do { if (idxDebugFlag & DEBUG_INFO) { taosPrintLog("IDX ", DEBUG_INFO, 255, __VA_ARGS__); } } while (0) +#define indexDebug(...) do { if (idxDebugFlag & DEBUG_DEBUG) { taosPrintLog("IDX ", DEBUG_DEBUG, idxDebugFlag, __VA_ARGS__);} } while (0) +#define indexTrace(...) do { if (idxDebugFlag & DEBUG_TRACE) { taosPrintLog("IDX", DEBUG_TRACE, idxDebugFlag, __VA_ARGS__);} } while (0) // clang-format on typedef enum { LT, LE, GT, GE } RangeType; diff --git a/source/libs/index/src/indexFilter.c b/source/libs/index/src/indexFilter.c index 2e30ca704a..3e29530d3e 100644 --- a/source/libs/index/src/indexFilter.c +++ b/source/libs/index/src/indexFilter.c @@ -499,7 +499,9 @@ static int32_t sifExecOper(SOperatorNode *node, SIFCtx *ctx, SIFParam *output) { int32_t code = 0; int32_t nParam = sifGetOperParamNum(node->opType); if (nParam <= 1) { - SIF_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + output->status = SFLT_NOT_INDEX; + return code; + // SIF_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } if (node->opType == OP_TYPE_JSON_GET_VALUE || node->opType == OP_TYPE_JSON_CONTAINS) { return code; @@ -615,11 +617,11 @@ EDealRes sifCalcWalker(SNode *node, void *context) { } if (QUERY_NODE_OPERATOR == nodeType(node)) { - indexInfo("node type for index filter, type: %d", nodeType(node)); + // indexInfo("node type for index filter, type: %d", nodeType(node)); return sifWalkOper(node, ctx); } - indexError("invalid node type for index filter calculating, type:%d", nodeType(node)); + // indexError("invalid node type for index filter calculating, type:%d", nodeType(node)); ctx->code = TSDB_CODE_QRY_INVALID_INPUT; return DEAL_RES_ERROR; } From 62caafa35687466d0554a630ff283eb55f1f30d3 Mon Sep 17 00:00:00 2001 From: "wenzhouwww@live.cn" Date: Mon, 6 Jun 2022 15:08:43 +0800 Subject: [PATCH 14/26] update case for hyperlog function --- tests/system-test/2-query/hyperloglog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/2-query/hyperloglog.py b/tests/system-test/2-query/hyperloglog.py index 35703e441d..b20ec35f07 100644 --- a/tests/system-test/2-query/hyperloglog.py +++ b/tests/system-test/2-query/hyperloglog.py @@ -223,7 +223,7 @@ class TDTestCase: tdLog.printNoPrefix("===step 0: err case, must return err") tdSql.error( "select hyperloglog() from ct1" ) tdSql.error( "select hyperloglog(c1, c2) from ct2" ) - tdSql.error( "select hyperloglog(1) from ct2" ) + # tdSql.error( "select hyperloglog(1) from ct2" ) tdSql.error( f"select hyperloglog({NUM_COL[0]}, {NUM_COL[1]}) from ct4" ) tdSql.error( ''' select hyperloglog(['c1 + c1', 'c1 + c2', 'c1 + c3', 'c1 + c4', 'c1 + c5', 'c1 + c6', 'c1 + c7', 'c1 + c8', 'c1 + c9', 'c1 + c10']) from ct1 From 475a399c3134d2a6b0f967a3a48cea7b4a91f023 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 6 Jun 2022 17:29:43 +0800 Subject: [PATCH 15/26] refactor: do some internal refactor. --- include/libs/qcom/query.h | 2 +- source/client/inc/clientInt.h | 6 + source/client/src/clientImpl.c | 21 ++- source/client/src/clientMain.c | 161 ++++++++++++----------- source/client/src/clientMsgHandler.c | 15 +++ source/client/test/clientTests.cpp | 30 ++++- source/libs/catalog/src/ctgAsync.c | 10 +- source/libs/catalog/src/ctgRemote.c | 4 +- source/libs/scheduler/src/schJob.c | 2 +- tests/script/tsim/stable/column_drop.sim | 1 + tests/script/tsim/testsuit.sim | 34 ++--- 11 files changed, 179 insertions(+), 107 deletions(-) diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index a17be44846..a717a6b333 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -224,7 +224,7 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t #define NEED_SCHEDULER_RETRY_ERROR(_code) \ ((_code) == TSDB_CODE_RPC_REDIRECT || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || (_code) == TSDB_CODE_SCH_TIMEOUT_ERROR) -#define REQUEST_MAX_TRY_TIMES 1 +#define REQUEST_TOTAL_EXEC_TIMES 2 #define qFatal(...) \ do { \ diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 85d07d2ef7..9a029b0fea 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -212,6 +212,9 @@ typedef struct SRequestObj { SArray* tableList; SQueryExecMetric metric; SRequestSendRecvBody body; + + uint32_t prevCode; //previous error code: todo refactor, add update flag for catalog + uint32_t retry; } SRequestObj; typedef struct SSyncQueryParam { @@ -325,6 +328,9 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNod void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery); int32_t refreshMeta(STscObj* pTscObj, SRequestObj* pRequest); int32_t updateQnodeList(SAppInstInfo* pInfo, SArray* pNodeList); +void doAsyncQuery(SRequestObj* pRequest, bool forceUpdateMeta); +int32_t removeMeta(STscObj* pTscObj, SArray* tbList);// todo move to clientImpl.c and become a static function +int32_t handleAlterTbExecRes(void* res, struct SCatalog* pCatalog);// todo move to xxx #ifdef __cplusplus } diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 102d1a309d..85f6e85190 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -257,7 +257,8 @@ void asyncExecLocalCmd(SRequestObj* pRequest, SQuery* pQuery) { pRequest->requestId); } - pRequest->body.fetchFp(pRequest->body.param, pRequest, pResultInfo->numOfRows); + pRequest->body.queryFp(pRequest->body.param, pRequest, 0); +// pRequest->body.fetchFp(pRequest->body.param, pRequest, pResultInfo->numOfRows); } int32_t asyncExecDdlQuery(SRequestObj* pRequest, SQuery* pQuery) { @@ -573,6 +574,20 @@ int32_t handleExecRes(SRequestObj* pRequest) { void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) { SRequestObj* pRequest = (SRequestObj*) param; + pRequest->code = code; + + STscObj* pTscObj = pRequest->pTscObj; + if (code != TSDB_CODE_SUCCESS && NEED_CLIENT_HANDLE_ERROR(code)) { + // todo do nothing in clear value in request + tscDebug("0x%"PRIx64" client retry to handle the error, code:%s, reqId:0x%"PRIx64, pRequest->self, tstrerror(code), pRequest->requestId); + pRequest->prevCode = code; + doAsyncQuery(pRequest, true); + return; + } + + if (NEED_CLIENT_RM_TBLMETA_REQ(pRequest->type)) { + removeMeta(pTscObj, pRequest->tableList); + } // return to client pRequest->body.queryFp(pRequest->body.param, pRequest, code); @@ -769,7 +784,7 @@ SRequestObj* execQuery(STscObj* pTscObj, const char* sql, int sqlLen) { pRequest->code = code; break; } - } while (retryNum++ < REQUEST_MAX_TRY_TIMES); + } while (retryNum++ < REQUEST_TOTAL_EXEC_TIMES); if (NEED_CLIENT_RM_TBLMETA_REQ(pRequest->type)) { removeMeta(pTscObj, pRequest->tableList); @@ -1448,7 +1463,7 @@ TSDB_SERVER_STATUS taos_check_server_status(const char* fqdn, int port, char* de } code = statusRsp.statusCode; - if (details != NULL && statusRsp.details != NULL) { + if (details != NULL) { tstrncpy(details, statusRsp.details, maxlen); } diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index c1f90197ac..a15f9f17f7 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -193,7 +193,7 @@ TAOS_RES *taos_query(TAOS *taos, const char *sql) { STscObj* pTscObj = (STscObj*)taos; #if SYNC_ON_TOP_OF_ASYNC - SSyncQueryParam* param = taosMemoryCalloc(1, sizeof(struct SSyncQueryParam)); + SSyncQueryParam* param = taosMemoryCalloc(1, sizeof(SSyncQueryParam)); tsem_init(¶m->sem, 0, 0); taos_query_a(pTscObj, sql, syncQueryFn, param); @@ -609,34 +609,36 @@ void retrieveMetaCallback(SMetaData* pResultMeta, void* param, int32_t code) { SQuery* pQuery = pWrapper->pQuery; SRequestObj* pRequest = pWrapper->pRequest; - if (code != TSDB_CODE_SUCCESS) { - goto _error; + if (code == TSDB_CODE_SUCCESS) { + code = qAnalyseSqlSemantic(pWrapper->pCtx, &pWrapper->catalogReq, pResultMeta, pQuery); } - code = qAnalyseSqlSemantic(pWrapper->pCtx, &pWrapper->catalogReq, pResultMeta, pQuery); - if (code != TSDB_CODE_SUCCESS) { - goto _error; + if (code == TSDB_CODE_SUCCESS) { + if (pQuery->haveResultSet) { + setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols); + setResPrecision(&pRequest->body.resInfo, pQuery->precision); + } + + TSWAP(pRequest->dbList, (pQuery)->pDbList); + TSWAP(pRequest->tableList, (pQuery)->pTableList); + + taosMemoryFree(pWrapper); + launchAsyncQuery(pRequest, pQuery); + } else { + if (NEED_CLIENT_HANDLE_ERROR(code)) { + tscDebug("0x%"PRIx64" client retry to handle the error, code:%s, reqId:0x%"PRIx64, pRequest->self, tstrerror(code), pRequest->requestId); + pRequest->prevCode = code; + doAsyncQuery(pRequest, true); + return; + } + + // return to app directly + taosMemoryFree(pWrapper); + tscError("0x%" PRIx64 " error occurs, code:%s, return to user app, reqId:%" PRIx64, pRequest->self, tstrerror(code), + pRequest->requestId); + pRequest->code = code; + pRequest->body.queryFp(pRequest->body.param, pRequest, code); } - - if (pQuery->haveResultSet) { - setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, (pQuery)->numOfResCols); - setResPrecision(&pRequest->body.resInfo, (pQuery)->precision); - } - - TSWAP(pRequest->dbList, (pQuery)->pDbList); - TSWAP(pRequest->tableList, (pQuery)->pTableList); - - taosMemoryFree(pWrapper); - - launchAsyncQuery(pRequest, pQuery); - return; - - _error: - taosMemoryFree(pWrapper); - tscError("0x%" PRIx64 " error occurs, code:%s, return to user app, reqId:%" PRIx64, pRequest->self, tstrerror(code), - pRequest->requestId); - pRequest->code = code; - pRequest->body.queryFp(pRequest->body.param, pRequest, code); } void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) { @@ -658,64 +660,16 @@ void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param } SRequestObj *pRequest = NULL; - int32_t code = 0; - - // while (retryNum++ < REQUEST_MAX_TRY_TIMES) { - code = buildRequest(taos, sql, sqlLen, &pRequest); + int32_t code = buildRequest(taos, sql, sqlLen, &pRequest); if (code != TSDB_CODE_SUCCESS) { terrno = code; - fp(param, NULL, code); + fp(param, NULL, terrno); return; } pRequest->body.queryFp = fp; pRequest->body.param = param; - - SParseContext* pCxt = NULL; - code = createParseContext(pRequest, &pCxt); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - STscObj *pTscObj = pRequest->pTscObj; - pCxt->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp); - code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCxt->pCatalog); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - SQuery *pQuery = NULL; - - SCatalogReq catalogReq = {0}; - code = qParseSqlSyntax(pCxt, &pQuery, &catalogReq); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - SqlParseWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SqlParseWrapper)); - if (pWrapper == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - goto _error; - } - - pWrapper->pCtx = pCxt; - pWrapper->pQuery = pQuery; - pWrapper->pRequest = pRequest; - pWrapper->catalogReq = catalogReq; - - code = catalogAsyncGetAllMeta(pCxt->pCatalog, pCxt->pTransporter, &pCxt->mgmtEpSet, pRequest->requestId, - &catalogReq, retrieveMetaCallback, pWrapper, &pRequest->body.queryJob); - - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - return; - - _error: - terrno = code; - pRequest->code = code; - fp(param, pRequest, code); + doAsyncQuery(pRequest, false); } int32_t createParseContext(const SRequestObj *pRequest, SParseContext** pCxt) { @@ -742,6 +696,59 @@ int32_t createParseContext(const SRequestObj *pRequest, SParseContext** pCxt) { return TSDB_CODE_SUCCESS; } +void doAsyncQuery(SRequestObj* pRequest, bool updateMetaForce) { + SParseContext* pCxt = NULL; + STscObj *pTscObj = pRequest->pTscObj; + + if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) { + pRequest->code = pRequest->prevCode; + goto _error; + } + + int32_t code = createParseContext(pRequest, &pCxt); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + pCxt->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp); + code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCxt->pCatalog); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + SQuery *pQuery = NULL; + + SCatalogReq catalogReq = {.forceUpdate = updateMetaForce}; + code = qParseSqlSyntax(pCxt, &pQuery, &catalogReq); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + SqlParseWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SqlParseWrapper)); + if (pWrapper == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _error; + } + + pWrapper->pCtx = pCxt; + pWrapper->pQuery = pQuery; + pWrapper->pRequest = pRequest; + pWrapper->catalogReq = catalogReq; + + code = catalogAsyncGetAllMeta(pCxt->pCatalog, pCxt->pTransporter, &pCxt->mgmtEpSet, pRequest->requestId, + &catalogReq, retrieveMetaCallback, pWrapper, &pRequest->body.queryJob); + if (code == TSDB_CODE_SUCCESS) { + return; + } + + _error: + tscError("0x%"PRIx64" error happens, code:%s, reqId:0x%"PRIx64, pRequest->self, tstrerror(code), pRequest->requestId); + terrno = code; + pRequest->code = code; + pRequest->body.queryFp(pRequest->body.param, pRequest, code); +} + + static void fetchCallback(void* pResult, void* param, int32_t code) { SRequestObj* pRequest = (SRequestObj*) param; diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index 29fd1c74f9..cdac217084 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -219,6 +219,7 @@ int32_t processCreateTableRsp(void* param, const SDataBuf* pMsg, int32_t code) { } if (pRequest->body.queryFp != NULL) { + removeMeta(pRequest->pTscObj, pRequest->tableList); pRequest->body.queryFp(pRequest->body.param, pRequest, code); } else { tsem_post(&pRequest->body.rspSem); @@ -263,6 +264,20 @@ int32_t processAlterStbRsp(void* param, const SDataBuf* pMsg, int32_t code) { } if (pRequest->body.queryFp != NULL) { + SQueryExecRes* pRes = &pRequest->body.resInfo.execRes; + + if (code == TSDB_CODE_SUCCESS) { + SCatalog* pCatalog = NULL; + int32_t ret = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog); + if (pRes->res != NULL) { + ret = handleAlterTbExecRes(pRes->res, pCatalog); + } + + if (ret != TSDB_CODE_SUCCESS) { + code = ret; + } + } + pRequest->body.queryFp(pRequest->body.param, pRequest, code); } else { tsem_post(&pRequest->body.rspSem); diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index 514bcc95cc..f16baba0e7 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -778,7 +778,35 @@ TEST(testCase, async_api_test) { TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT_NE(pConn, nullptr); - taos_query_a(pConn, "desc test.tm0", queryCallback, pConn); + taos_query(pConn, "use test"); + + TAOS_RES* pRes = taos_query(pConn, "select * from t1"); + + taos_query(pConn, "alter table t1 add column b int"); + pRes = taos_query(pConn, "insert into t1 values(now, 1, 2)"); + if (taos_errno(pRes) != 0) { + printf("failed, reason:%s\n", taos_errstr(pRes)); + } + +// int32_t n = 0; +// TAOS_ROW pRow = NULL; +// TAOS_FIELD* pFields = taos_fetch_fields(pRes); +// int32_t numOfFields = taos_num_fields(pRes); +// +// char str[512] = {0}; +// while ((pRow = taos_fetch_row(pRes)) != NULL) { +// int32_t* length = taos_fetch_lengths(pRes); +// for(int32_t i = 0; i < numOfFields; ++i) { +// printf("(%d):%d " , i, length[i]); +// } +// printf("\n"); +// +// int32_t code = taos_print_row(str, pRow, pFields, numOfFields); +// printf("%s\n", str); +// memset(str, 0, sizeof(str)); +// } + + taos_query_a(pConn, "alter table test.m1 comment 'abcde' ", queryCallback, pConn); getchar(); taos_close(pConn); } diff --git a/source/libs/catalog/src/ctgAsync.c b/source/libs/catalog/src/ctgAsync.c index 6998d8c778..5eaccab004 100644 --- a/source/libs/catalog/src/ctgAsync.c +++ b/source/libs/catalog/src/ctgAsync.c @@ -67,7 +67,7 @@ int32_t ctgInitGetDbVgTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:%" PRIx64 " task %d type %d initialized, dbFName:%s", pJob->queryId, taskIdx, task.type, dbFName); + qDebug("QID:0x%" PRIx64 " task %d type %d initialized, dbFName:%s", pJob->queryId, taskIdx, task.type, dbFName); return TSDB_CODE_SUCCESS; } @@ -90,7 +90,7 @@ int32_t ctgInitGetDbCfgTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:%" PRIx64 " task %d type %d initialized, dbFName:%s", pJob->queryId, taskIdx, task.type, dbFName); + qDebug("QID:0x%" PRIx64 " task %d type %d initialized, dbFName:%s", pJob->queryId, taskIdx, task.type, dbFName); return TSDB_CODE_SUCCESS; } @@ -113,7 +113,7 @@ int32_t ctgInitGetDbInfoTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:%" PRIx64 " task %d type %d initialized, dbFName:%s", pJob->queryId, taskIdx, task.type, dbFName); + qDebug("QID:0x%" PRIx64 " task %d type %d initialized, dbFName:%s", pJob->queryId, taskIdx, task.type, dbFName); return TSDB_CODE_SUCCESS; } @@ -342,7 +342,7 @@ int32_t ctgInitJob(CTG_PARAMS, SCtgJob** job, uint64_t reqId, const SCatalogReq* taosAcquireRef(gCtgMgmt.jobPool, pJob->refId); - qDebug("QID:%" PRIx64 ", job %" PRIx64 " initialized, task num %d", pJob->queryId, pJob->refId, *taskNum); + qDebug("QID:0x%" PRIx64 ", jobId: 0x%" PRIx64 " initialized, task num %d", pJob->queryId, pJob->refId, *taskNum); return TSDB_CODE_SUCCESS; @@ -1108,7 +1108,7 @@ int32_t ctgLaunchJob(SCtgJob *pJob) { for (int32_t i = 0; i < taskNum; ++i) { SCtgTask *pTask = taosArrayGet(pJob->pTasks, i); - qDebug("QID:%" PRIx64 " start to launch task %d", pJob->queryId, pTask->taskId); + qDebug("QID:0x%" PRIx64 " start to launch task %d", pJob->queryId, pTask->taskId); CTG_ERR_RET((*gCtgAsyncFps[pTask->type].launchFp)(pTask)); } diff --git a/source/libs/catalog/src/ctgRemote.c b/source/libs/catalog/src/ctgRemote.c index b16a082f75..8f3d498440 100644 --- a/source/libs/catalog/src/ctgRemote.c +++ b/source/libs/catalog/src/ctgRemote.c @@ -177,7 +177,7 @@ int32_t ctgHandleMsgCallback(void *param, const SDataBuf *pMsg, int32_t rspCode) SCtgTask *pTask = taosArrayGet(pJob->pTasks, cbParam->taskId); - qDebug("QID:%" PRIx64 " task %d start to handle rsp %s", pJob->queryId, pTask->taskId, TMSG_INFO(cbParam->reqType + 1)); + qDebug("QID:0x%" PRIx64 " task %d start to handle rsp %s", pJob->queryId, pTask->taskId, TMSG_INFO(cbParam->reqType + 1)); CTG_ERR_JRET((*gCtgAsyncFps[pTask->type].handleRspFp)(pTask, cbParam->reqType, pMsg, rspCode)); @@ -244,7 +244,7 @@ int32_t ctgAsyncSendMsg(CTG_PARAMS, SCtgTask* pTask, int32_t msgType, void *msg, CTG_ERR_JRET(code); } - ctgDebug("req msg sent, reqId:%" PRIx64 ", msg type:%d, %s", pTask->pJob->queryId, msgType, TMSG_INFO(msgType)); + ctgDebug("req msg sent, reqId:0x%" PRIx64 ", msg type:%d, %s", pTask->pJob->queryId, msgType, TMSG_INFO(msgType)); return TSDB_CODE_SUCCESS; _return: diff --git a/source/libs/scheduler/src/schJob.c b/source/libs/scheduler/src/schJob.c index ca90d2fe34..7a0272a4d0 100644 --- a/source/libs/scheduler/src/schJob.c +++ b/source/libs/scheduler/src/schJob.c @@ -108,7 +108,7 @@ int32_t schInitJob(SSchJob **pSchJob, SQueryPlan *pDag, void *pTrans, SArray *pN pJob->refId = refId; - SCH_JOB_DLOG("job refId:%" PRIx64, pJob->refId); + SCH_JOB_DLOG("job refId:0x%" PRIx64" created", pJob->refId); pJob->status = JOB_TASK_STATUS_NOT_START; diff --git a/tests/script/tsim/stable/column_drop.sim b/tests/script/tsim/stable/column_drop.sim index 3401465103..63ac44eccd 100644 --- a/tests/script/tsim/stable/column_drop.sim +++ b/tests/script/tsim/stable/column_drop.sim @@ -118,6 +118,7 @@ if $data[0][5] != 5 then return -1 endi if $data[0][6] != 101 then + print expect 101, actual: $data06 return -1 endi diff --git a/tests/script/tsim/testsuit.sim b/tests/script/tsim/testsuit.sim index 527d28a336..1f258028cc 100644 --- a/tests/script/tsim/testsuit.sim +++ b/tests/script/tsim/testsuit.sim @@ -9,24 +9,24 @@ #run tsim/trans/create_db.sim #run tsim/stable/alter_metrics.sim #run tsim/stable/tag_modify.sim -run tsim/stable/alter_comment.sim -run tsim/stable/column_drop.sim -run tsim/stable/column_modify.sim -run tsim/stable/tag_rename.sim -run tsim/stable/vnode3.sim -run tsim/stable/metrics.sim -run tsim/stable/alter_insert2.sim -run tsim/stable/show.sim -run tsim/stable/alter_import.sim -run tsim/stable/tag_add.sim -run tsim/stable/tag_drop.sim -run tsim/stable/column_add.sim -run tsim/stable/alter_count.sim -run tsim/stable/values.sim +#run tsim/stable/alter_comment.sim +#run tsim/stable/column_drop.sim +#run tsim/stable/column_modify.sim +#run tsim/stable/tag_rename.sim +#run tsim/stable/vnode3.sim +#run tsim/stable/metrics.sim +#run tsim/stable/alter_insert2.sim +#run tsim/stable/show.sim +#run tsim/stable/alter_import.sim +#run tsim/stable/tag_add.sim +#run tsim/stable/tag_drop.sim +#run tsim/stable/column_add.sim +#run tsim/stable/alter_count.sim +#run tsim/stable/values.sim run tsim/stable/dnode3.sim -run tsim/stable/alter_insert1.sim -run tsim/stable/refcount.sim -run tsim/stable/disk.sim +#run tsim/stable/alter_insert1.sim +#run tsim/stable/refcount.sim +#run tsim/stable/disk.sim run tsim/db/basic1.sim run tsim/db/basic3.sim #run tsim/db/basic7.sim From aa143beda43a9e96204558a362c8259f132bef93 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 6 Jun 2022 19:27:51 +0800 Subject: [PATCH 16/26] fix(query): fix invalid free. --- source/client/inc/clientInt.h | 3 ++- source/client/src/clientEnv.c | 1 - source/client/src/clientImpl.c | 24 ++++++++++++------ source/client/src/clientMain.c | 1 - source/client/src/clientMsgHandler.c | 35 ++++++++++++++------------ source/libs/parser/src/parTranslater.c | 1 - 6 files changed, 37 insertions(+), 28 deletions(-) diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 9a029b0fea..ba552cc7cb 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -266,7 +266,8 @@ extern SAppInfo appInfo; extern int32_t clientReqRefPool; extern int32_t clientConnRefPool; -extern int (*handleRequestRspFp[TDMT_MAX])(void*, const SDataBuf* pMsg, int32_t code); +__async_send_cb_fn_t getMsgRspHandle(int32_t msgType); + int genericRspCallback(void* param, const SDataBuf* pMsg, int32_t code); SMsgSendInfo* buildMsgInfoImpl(SRequestObj* pReqObj); diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index c210a7ed39..75e1884360 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -278,7 +278,6 @@ void taos_init_imp(void) { return; } - initMsgHandleFp(); initQueryModuleMsgHandle(); rpcInit(); diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 85f6e85190..2ddeb7f9d4 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -535,19 +535,20 @@ int32_t handleAlterTbExecRes(void* res, SCatalog* pCatalog) { return catalogUpdateTableMeta(pCatalog, (STableMetaRsp*)res); } -int32_t handleExecRes(SRequestObj* pRequest) { +int32_t handleQueryExecRsp(SRequestObj* pRequest) { if (NULL == pRequest->body.resInfo.execRes.res) { return TSDB_CODE_SUCCESS; } - int32_t code = 0; SCatalog* pCatalog = NULL; - code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog); + SAppInstInfo* pAppInfo = getAppInfo(pRequest); + + int32_t code = catalogGetHandle(pAppInfo->clusterId, &pCatalog); if (code) { return code; } - SEpSet epset = getEpSet_s(&pRequest->pTscObj->pAppInfo->mgmtEp); + SEpSet epset = getEpSet_s(&pAppInfo->mgmtEp); SQueryExecRes* pRes = &pRequest->body.resInfo.execRes; switch (pRes->msgType) { @@ -565,8 +566,9 @@ int32_t handleExecRes(SRequestObj* pRequest) { break; } default: - tscError("invalid exec result for request type %d", pRequest->type); - return TSDB_CODE_APP_ERROR; + tscError("0x%"PRIx64", invalid exec result for request type %d, reqId:0x%"PRIx64, pRequest->self, + pRequest->type, pRequest->requestId); + code = TSDB_CODE_APP_ERROR; } return code; @@ -585,6 +587,12 @@ void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) { return; } + if (code == TSDB_CODE_SUCCESS) { + code = handleQueryExecRsp(pRequest); + ASSERT(pRequest->code == TSDB_CODE_SUCCESS); + pRequest->code = code; + } + if (NEED_CLIENT_RM_TBLMETA_REQ(pRequest->type)) { removeMeta(pTscObj, pRequest->tableList); } @@ -623,7 +631,7 @@ SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQue qDestroyQuery(pQuery); } - handleExecRes(pRequest); + handleQueryExecRsp(pRequest); if (NULL != pRequest && TSDB_CODE_SUCCESS != code) { pRequest->code = terrno; @@ -884,7 +892,7 @@ static SMsgSendInfo* buildConnectMsg(SRequestObj* pRequest) { pMsgSendInfo->requestObjRefId = pRequest->self; pMsgSendInfo->requestId = pRequest->requestId; - pMsgSendInfo->fp = handleRequestRspFp[TMSG_INDEX(pMsgSendInfo->msgType)]; + pMsgSendInfo->fp = getMsgRspHandle(pMsgSendInfo->msgType); pMsgSendInfo->param = pRequest; SConnectReq connectReq = {0}; diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index a15f9f17f7..960cda394a 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -748,7 +748,6 @@ void doAsyncQuery(SRequestObj* pRequest, bool updateMetaForce) { pRequest->body.queryFp(pRequest->body.param, pRequest, code); } - static void fetchCallback(void* pResult, void* param, int32_t code) { SRequestObj* pRequest = (SRequestObj*) param; diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index cdac217084..14e2798d3b 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -21,8 +21,6 @@ #include "tdef.h" #include "tname.h" -int32_t (*handleRequestRspFp[TDMT_MAX])(void*, const SDataBuf* pMsg, int32_t code); - static void setErrno(SRequestObj* pRequest, int32_t code) { pRequest->code = code; terrno = code; @@ -107,10 +105,7 @@ SMsgSendInfo* buildMsgInfoImpl(SRequestObj* pRequest) { assert(pRequest != NULL); pMsgSendInfo->msgInfo = pRequest->body.requestMsg; - - pMsgSendInfo->fp = (handleRequestRspFp[TMSG_INDEX(pRequest->type)] == NULL) - ? genericRspCallback - : handleRequestRspFp[TMSG_INDEX(pRequest->type)]; + pMsgSendInfo->fp = getMsgRspHandle(pRequest->type); return pMsgSendInfo; } @@ -209,7 +204,7 @@ int32_t processUseDbRsp(void* param, const SDataBuf* pMsg, int32_t code) { return 0; } -int32_t processCreateTableRsp(void* param, const SDataBuf* pMsg, int32_t code) { +int32_t processCreateSTableRsp(void* param, const SDataBuf* pMsg, int32_t code) { assert(pMsg != NULL && param != NULL); SRequestObj* pRequest = param; @@ -285,13 +280,21 @@ int32_t processAlterStbRsp(void* param, const SDataBuf* pMsg, int32_t code) { return code; } - -// todo refactor: this arraylist is too large -void initMsgHandleFp() { - handleRequestRspFp[TMSG_INDEX(TDMT_MND_CONNECT)] = processConnectRsp; - handleRequestRspFp[TMSG_INDEX(TDMT_MND_CREATE_DB)] = processCreateDbRsp; - handleRequestRspFp[TMSG_INDEX(TDMT_MND_USE_DB)] = processUseDbRsp; - handleRequestRspFp[TMSG_INDEX(TDMT_MND_CREATE_STB)] = processCreateTableRsp; - handleRequestRspFp[TMSG_INDEX(TDMT_MND_DROP_DB)] = processDropDbRsp; - handleRequestRspFp[TMSG_INDEX(TDMT_MND_ALTER_STB)] = processAlterStbRsp; +__async_send_cb_fn_t getMsgRspHandle(int32_t msgType) { + switch (msgType) { + case TDMT_MND_CONNECT: + return processConnectRsp; + case TDMT_MND_CREATE_DB: + return processCreateDbRsp; + case TDMT_MND_USE_DB: + return processUseDbRsp; + case TDMT_MND_CREATE_STB: + return processCreateSTableRsp; + case TDMT_MND_DROP_DB: + return processDropDbRsp; + case TDMT_MND_ALTER_STB: + return processAlterStbRsp; + default: + return genericRspCallback; + } } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index f1892d0040..6334d079c8 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -2903,7 +2903,6 @@ static int32_t buildRollupAst(STranslateContext* pCxt, SCreateTableStmt* pStmt, } } - taosArrayDestroy(dbCfg.pRetensions); return code; } From 98a9789c7e40456aef8f549d06022d7a9032e97e Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Mon, 6 Jun 2022 19:55:28 +0800 Subject: [PATCH 17/26] fix: top function with order by clause --- source/libs/planner/src/planLogicCreater.c | 2 +- source/libs/planner/test/planIntervalTest.cpp | 2 ++ source/libs/planner/test/planTestUtil.cpp | 6 +++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index cda2ace5ba..329712bc28 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -458,7 +458,7 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) { // top/bottom are both an aggregate function and a indefinite rows function - if (!pSelect->hasIndefiniteRowsFunc || pSelect->hasAggFuncs) { + if (!pSelect->hasIndefiniteRowsFunc || pSelect->hasAggFuncs || NULL != pSelect->pWindow) { return TSDB_CODE_SUCCESS; } diff --git a/source/libs/planner/test/planIntervalTest.cpp b/source/libs/planner/test/planIntervalTest.cpp index a04f47741e..edd735922b 100644 --- a/source/libs/planner/test/planIntervalTest.cpp +++ b/source/libs/planner/test/planIntervalTest.cpp @@ -50,6 +50,8 @@ TEST_F(PlanIntervalTest, selectFunc) { run("SELECT MAX(c1), MIN(c1) FROM t1 INTERVAL(10s)"); // select function along with the columns of select row, and with INTERVAL clause run("SELECT MAX(c1), c2 FROM t1 INTERVAL(10s)"); + + run("SELECT TOP(c1, 1) FROM t1 INTERVAL(10s) ORDER BY c1"); } TEST_F(PlanIntervalTest, stable) { diff --git a/source/libs/planner/test/planTestUtil.cpp b/source/libs/planner/test/planTestUtil.cpp index e2082d4936..84c46cb9bb 100644 --- a/source/libs/planner/test/planTestUtil.cpp +++ b/source/libs/planner/test/planTestUtil.cpp @@ -81,6 +81,8 @@ int32_t getLogLevel() { return g_logLevel; } class PlannerTestBaseImpl { public: + PlannerTestBaseImpl() : sqlNo_(0) {} + void useDb(const string& acctId, const string& db) { caseEnv_.acctId_ = acctId; caseEnv_.db_ = db; @@ -88,6 +90,7 @@ class PlannerTestBaseImpl { } void run(const string& sql) { + ++sqlNo_; if (caseEnv_.nsql_ > 0) { --(caseEnv_.nsql_); return; @@ -229,7 +232,7 @@ class PlannerTestBaseImpl { return; } - cout << "==========================================sql : [" << stmtEnv_.sql_ << "]" << endl; + cout << "========================================== " << sqlNo_ << " sql : [" << stmtEnv_.sql_ << "]" << endl; if (DUMP_MODULE_ALL == module || DUMP_MODULE_PARSER == module) { if (res_.prepareAst_.empty()) { @@ -382,6 +385,7 @@ class PlannerTestBaseImpl { caseEnv caseEnv_; stmtEnv stmtEnv_; stmtRes res_; + int32_t sqlNo_; }; PlannerTestBase::PlannerTestBase() : impl_(new PlannerTestBaseImpl()) {} From 2bd16c4978ea24a626a972c37971b75542e6a9e6 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 6 Jun 2022 19:58:14 +0800 Subject: [PATCH 18/26] refactor: update output of log. --- source/client/src/clientImpl.c | 4 ---- source/client/src/clientMain.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 2ddeb7f9d4..c71c7d3487 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -580,7 +580,6 @@ void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) { STscObj* pTscObj = pRequest->pTscObj; if (code != TSDB_CODE_SUCCESS && NEED_CLIENT_HANDLE_ERROR(code)) { - // todo do nothing in clear value in request tscDebug("0x%"PRIx64" client retry to handle the error, code:%s, reqId:0x%"PRIx64, pRequest->self, tstrerror(code), pRequest->requestId); pRequest->prevCode = code; doAsyncQuery(pRequest, true); @@ -696,9 +695,6 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery) { if (TSDB_CODE_SUCCESS == code) { schedulerAsyncExecJob(pAppInfo->pTransporter, pNodeList, pRequest->body.pDag, &pRequest->body.queryJob, pRequest->sqlstr, pRequest->metric.start, schedulerExecCb, pRequest); - // if (NULL != pRes) { - // code = validateSversion(pRequest, pRes); - // } } //todo not to be released here diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 960cda394a..d192b65bf0 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -634,7 +634,7 @@ void retrieveMetaCallback(SMetaData* pResultMeta, void* param, int32_t code) { // return to app directly taosMemoryFree(pWrapper); - tscError("0x%" PRIx64 " error occurs, code:%s, return to user app, reqId:%" PRIx64, pRequest->self, tstrerror(code), + tscError("0x%" PRIx64 " error occurs, code:%s, return to user app, reqId:0x%" PRIx64, pRequest->self, tstrerror(code), pRequest->requestId); pRequest->code = code; pRequest->body.queryFp(pRequest->body.param, pRequest, code); From b650daa33413418c2fcc283d2efc064f6b61e1f5 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 6 Jun 2022 20:00:11 +0800 Subject: [PATCH 19/26] refactor: do some internal refactor. --- source/client/inc/clientInt.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index ba552cc7cb..0630704d93 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -45,7 +45,7 @@ extern "C" { #define ERROR_MSG_BUF_DEFAULT_SIZE 512 #define HEARTBEAT_INTERVAL 1500 // ms -#define SYNC_ON_TOP_OF_ASYNC 1 +#define SYNC_ON_TOP_OF_ASYNC 0 enum { RES_TYPE__QUERY = 1, @@ -268,7 +268,6 @@ extern int32_t clientConnRefPool; __async_send_cb_fn_t getMsgRspHandle(int32_t msgType); -int genericRspCallback(void* param, const SDataBuf* pMsg, int32_t code); SMsgSendInfo* buildMsgInfoImpl(SRequestObj* pReqObj); void* createTscObj(const char* user, const char* auth, const char* db, int32_t connType, SAppInstInfo* pAppInfo); @@ -294,8 +293,6 @@ void* openTransporter(const char* user, const char* auth, int32_t numOfThreads); bool persistConnForSpecificMsg(void* parenct, tmsg_t msgType); void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet); -void initMsgHandleFp(); - TAOS* taos_connect_internal(const char* ip, const char* user, const char* pass, const char* auth, const char* db, uint16_t port, int connType); From 2677a3c8d93ca57babf45ddd308221bfa6b1c190 Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Mon, 6 Jun 2022 16:34:12 +0800 Subject: [PATCH 20/26] refactor(stream) --- include/common/tcommon.h | 22 +- include/libs/stream/tstream.h | 171 +++-- source/dnode/mnode/impl/src/mndScheduler.c | 10 +- source/dnode/vnode/src/inc/tq.h | 10 +- source/dnode/vnode/src/tq/tq.c | 67 +- source/dnode/vnode/src/tq/tqExec.c | 4 +- source/dnode/vnode/src/tq/tqMeta.c | 11 +- source/dnode/vnode/src/tq/tqPush.c | 10 +- source/dnode/vnode/src/tq/tqRead.c | 4 +- .../stream/inc/{tstreamInc.h => streamInc.h} | 12 +- source/libs/stream/src/stream.c | 112 ++++ source/libs/stream/src/streamData.c | 85 +++ source/libs/stream/src/streamExec.c | 123 ++++ source/libs/stream/src/streamMsg.c | 150 +++++ source/libs/stream/src/streamQueue.c | 43 ++ source/libs/stream/src/streamSink.c | 157 +++++ source/libs/stream/src/streamTask.c | 138 ++++ .../src/{tstreamUpdate.c => streamUpdate.c} | 0 source/libs/stream/src/tstream.c | 594 ------------------ source/util/src/tqueue.c | 18 +- 20 files changed, 1006 insertions(+), 735 deletions(-) rename source/libs/stream/inc/{tstreamInc.h => streamInc.h} (74%) create mode 100644 source/libs/stream/src/stream.c create mode 100644 source/libs/stream/src/streamData.c create mode 100644 source/libs/stream/src/streamExec.c create mode 100644 source/libs/stream/src/streamMsg.c create mode 100644 source/libs/stream/src/streamQueue.c create mode 100644 source/libs/stream/src/streamSink.c create mode 100644 source/libs/stream/src/streamTask.c rename source/libs/stream/src/{tstreamUpdate.c => streamUpdate.c} (100%) delete mode 100644 source/libs/stream/src/tstream.c diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 88fa0e728f..3d9228f05c 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -77,7 +77,9 @@ typedef struct SDataBlockInfo { int16_t numOfCols; int16_t hasVarCol; int32_t capacity; - EStreamType type; + // TODO: optimize and remove following + int32_t childId; // used for stream, do not serialize + EStreamType type; // used for stream, do not serialize } SDataBlockInfo; typedef struct SSDataBlock { @@ -105,14 +107,14 @@ typedef struct SColumnInfoData { } SColumnInfoData; typedef struct SQueryTableDataCond { - //STimeWindow twindow; + // STimeWindow twindow; int32_t order; // desc|asc order to iterate the data block int32_t numOfCols; - SColumnInfo *colList; + SColumnInfo* colList; bool loadExternalRows; // load external rows or not int32_t type; // data block load type: int32_t numOfTWindows; - STimeWindow *twindows; + STimeWindow* twindows; } SQueryTableDataCond; void* blockDataDestroy(SSDataBlock* pBlock); @@ -202,17 +204,17 @@ typedef struct SExprInfo { } SExprInfo; typedef struct { - const char* key; - int32_t keyLen; - uint8_t type; - union{ + const char* key; + int32_t keyLen; + uint8_t type; + union { const char* value; int64_t i; uint64_t u; double d; float f; }; - int32_t length; + int32_t length; } SSmlKv; #define QUERY_ASC_FORWARD_STEP 1 @@ -220,7 +222,7 @@ typedef struct { #define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP) -#define SORT_QSORT_T 0x1 +#define SORT_QSORT_T 0x1 #define SORT_SPILLED_MERGE_SORT_T 0x2 typedef struct SSortExecInfo { int32_t sortMethod; diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index f7ad7b4ed8..bb0b6dc0a0 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -24,8 +24,8 @@ extern "C" { #endif -#ifndef _TSTREAM_H_ -#define _TSTREAM_H_ +#ifndef _STREAM_H_ +#define _STREAM_H_ typedef struct SStreamTask SStreamTask; @@ -39,6 +39,7 @@ enum { TASK_INPUT_STATUS__NORMAL = 1, TASK_INPUT_STATUS__BLOCKED, TASK_INPUT_STATUS__RECOVER, + TASK_INPUT_STATUS__PROCESSING, TASK_INPUT_STATUS__STOP, TASK_INPUT_STATUS__FAILED, }; @@ -60,6 +61,10 @@ enum { STREAM_INPUT__CHECKPOINT, }; +typedef struct { + int8_t type; +} SStreamQueueItem; + typedef struct { int8_t type; int64_t ver; @@ -80,55 +85,51 @@ typedef struct { int8_t type; } SStreamCheckpoint; +enum { + STREAM_QUEUE__SUCESS = 1, + STREAM_QUEUE__FAILED, + STREAM_QUEUE__PROCESSING, +}; + typedef struct { STaosQueue* queue; STaosQall* qall; void* qItem; - int8_t failed; -} SStreamQ; + int8_t status; +} SStreamQueue; -static FORCE_INLINE void* streamQCurItem(SStreamQ* queue) { - // - return queue->qItem; +SStreamQueue* streamQueueOpen(); +void streamQueueClose(SStreamQueue* queue); + +static FORCE_INLINE void streamQueueProcessSuccess(SStreamQueue* queue) { + ASSERT(atomic_load_8(&queue->status) == STREAM_QUEUE__PROCESSING); + queue->qItem = NULL; + atomic_store_8(&queue->status, STREAM_QUEUE__SUCESS); } -static FORCE_INLINE void* streamQNextItem(SStreamQ* queue) { - int8_t failed = atomic_load_8(&queue->failed); - if (failed) { +static FORCE_INLINE void streamQueueProcessFail(SStreamQueue* queue) { + ASSERT(atomic_load_8(&queue->status) == STREAM_QUEUE__PROCESSING); + atomic_store_8(&queue->status, STREAM_QUEUE__FAILED); +} + +static FORCE_INLINE void* streamQueueCurItem(SStreamQueue* queue) { return queue->qItem; } + +static FORCE_INLINE void* streamQueueNextItem(SStreamQueue* queue) { + int8_t dequeueFlag = atomic_exchange_8(&queue->status, STREAM_QUEUE__PROCESSING); + if (dequeueFlag == STREAM_QUEUE__FAILED) { ASSERT(queue->qItem != NULL); - return streamQCurItem(queue); + return streamQueueCurItem(queue); } else { taosGetQitem(queue->qall, &queue->qItem); if (queue->qItem == NULL) { taosReadAllQitems(queue->queue, queue->qall); taosGetQitem(queue->qall, &queue->qItem); } - return streamQCurItem(queue); + return streamQueueCurItem(queue); } } -static FORCE_INLINE void streamQSetFail(SStreamQ* queue) { atomic_store_8(&queue->failed, 1); } - -static FORCE_INLINE void streamQSetSuccess(SStreamQ* queue) { atomic_store_8(&queue->failed, 0); } - -static FORCE_INLINE SStreamDataSubmit* streamDataSubmitNew(SSubmitReq* pReq) { - SStreamDataSubmit* pDataSubmit = (SStreamDataSubmit*)taosAllocateQitem(sizeof(SStreamDataSubmit), DEF_QITEM); - if (pDataSubmit == NULL) return NULL; - pDataSubmit->dataRef = (int32_t*)taosMemoryMalloc(sizeof(int32_t)); - if (pDataSubmit->dataRef == NULL) goto FAIL; - pDataSubmit->data = pReq; - *pDataSubmit->dataRef = 1; - pDataSubmit->type = STREAM_INPUT__DATA_SUBMIT; - return pDataSubmit; -FAIL: - taosFreeQitem(pDataSubmit); - return NULL; -} - -static FORCE_INLINE void streamDataSubmitRefInc(SStreamDataSubmit* pDataSubmit) { - // - atomic_add_fetch_32(pDataSubmit->dataRef, 1); -} +SStreamDataSubmit* streamDataSubmitNew(SSubmitReq* pReq); static FORCE_INLINE void streamDataSubmitRefDec(SStreamDataSubmit* pDataSubmit) { int32_t ref = atomic_sub_fetch_32(pDataSubmit->dataRef, 1); @@ -141,9 +142,31 @@ static FORCE_INLINE void streamDataSubmitRefDec(SStreamDataSubmit* pDataSubmit) SStreamDataSubmit* streamSubmitRefClone(SStreamDataSubmit* pSubmit); +#if 0 int32_t streamDataBlockEncode(void** buf, const SStreamDataBlock* pOutput); void* streamDataBlockDecode(const void* buf, SStreamDataBlock* pInput); +static FORCE_INLINE int32_t streamEnqueue1(SStreamQueue* queue, SStreamQueueItem* pItem) { + int8_t inputStatus = atomic_load_8(&queue->enqueueStatus); + if (inputStatus == TASK_INPUT_STATUS__NORMAL) { + if (pItem->type == STREAM_INPUT__DATA_SUBMIT) { + SStreamDataSubmit* pSubmitClone = streamSubmitRefClone((SStreamDataSubmit*)pItem); + if (pSubmitClone == NULL) { + atomic_store_8(&queue->enqueueStatus, TASK_INPUT_STATUS__FAILED); + return -1; + } + taosWriteQitem(queue->queue, pSubmitClone); + } else if (pItem->type == STREAM_INPUT__DATA_BLOCK) { + taosWriteQitem(queue->queue, pItem); + } else if (pItem->type == STREAM_INPUT__CHECKPOINT) { + taosWriteQitem(queue->queue, pItem); + } + return 0; + } + return 0; +} +#endif + typedef struct { int8_t parallelizable; char* qmsg; @@ -236,13 +259,17 @@ struct SStreamTask { int8_t dispatchType; int16_t dispatchMsgType; + // node info + int32_t childId; int32_t nodeId; SEpSet epSet; // exec STaskExec exec; - // local sink + // TODO: merge sink and dispatch + + // local sink union { STaskSinkTb tbSink; STaskSinkSma smaSink; @@ -258,25 +285,61 @@ struct SStreamTask { int8_t inputStatus; int8_t outputStatus; - +#if 0 STaosQueue* inputQ; STaosQall* inputQAll; STaosQueue* outputQ; STaosQall* outputQAll; +#endif + + SStreamQueue* inputQueue; + SStreamQueue* outputQueue; // application storage void* ahandle; }; -SStreamTask* tNewSStreamTask(int64_t streamId); +SStreamTask* tNewSStreamTask(int64_t streamId, int32_t childId); int32_t tEncodeSStreamTask(SEncoder* pEncoder, const SStreamTask* pTask); int32_t tDecodeSStreamTask(SDecoder* pDecoder, SStreamTask* pTask); void tFreeSStreamTask(SStreamTask* pTask); -typedef struct { - // SMsgHead head; - SStreamTask* task; -} SStreamTaskDeployReq; +static FORCE_INLINE int32_t streamTaskInput(SStreamTask* pTask, SStreamQueueItem* pItem) { + while (1) { + int8_t inputStatus = + atomic_val_compare_exchange_8(&pTask->inputStatus, TASK_INPUT_STATUS__NORMAL, TASK_INPUT_STATUS__PROCESSING); + if (inputStatus == TASK_INPUT_STATUS__NORMAL) { + break; + } + ASSERT(0); + } + + if (pItem->type == STREAM_INPUT__DATA_SUBMIT) { + SStreamDataSubmit* pSubmitClone = streamSubmitRefClone((SStreamDataSubmit*)pItem); + if (pSubmitClone == NULL) { + atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__FAILED); + return -1; + } + taosWriteQitem(pTask->inputQueue->queue, pSubmitClone); + } else if (pItem->type == STREAM_INPUT__DATA_BLOCK) { + taosWriteQitem(pTask->inputQueue->queue, pItem); + } else if (pItem->type == STREAM_INPUT__CHECKPOINT) { + taosWriteQitem(pTask->inputQueue->queue, pItem); + } + + // TODO: back pressure + atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__NORMAL); + return 0; +} + +static FORCE_INLINE void streamTaskInputFail(SStreamTask* pTask) { + atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__FAILED); +} + +static FORCE_INLINE int32_t streamTaskOutput(SStreamTask* pTask, SStreamDataBlock* pBlock) { + taosWriteQitem(pTask->outputQueue->queue, pBlock); + return 0; +} typedef struct { int32_t reserved; @@ -289,6 +352,11 @@ typedef struct { SArray* data; // SArray } SStreamTaskExecReq; +typedef struct { + // SMsgHead head; + SStreamTask* task; +} SStreamTaskDeployReq; + int32_t tEncodeSStreamTaskExecReq(void** buf, const SStreamTaskExecReq* pReq); void* tDecodeSStreamTaskExecReq(const void* buf, SStreamTaskExecReq* pReq); void tFreeSStreamTaskExecReq(SStreamTaskExecReq* pReq); @@ -297,6 +365,12 @@ typedef struct { int32_t reserved; } SStreamTaskExecRsp; +typedef struct { + SMsgHead head; + int64_t streamId; + int32_t taskId; +} SStreamTaskRunReq; + typedef struct { // SMsgHead head; int64_t streamId; @@ -304,21 +378,18 @@ typedef struct { SArray* res; // SArray } SStreamSinkReq; -typedef struct { - SMsgHead head; - int64_t streamId; - int32_t taskId; -} SStreamTaskRunReq; - typedef struct { int64_t streamId; int32_t taskId; int32_t sourceTaskId; int32_t sourceVg; + int32_t sourceChildId; #if 0 int64_t sourceVer; #endif - SArray* data; // SArray + int32_t blockNum; + SArray* dataLen; // SArray + SArray* data; // SArray } SStreamDispatchReq; typedef struct { @@ -340,6 +411,8 @@ typedef struct { int8_t inputStatus; } SStreamTaskRecoverRsp; +int32_t streamTriggerByWrite(SStreamTask* pTask, int32_t vgId, SMsgCb* pMsgCb); + int32_t streamEnqueueDataSubmit(SStreamTask* pTask, SStreamDataSubmit* input); int32_t streamEnqueueDataBlk(SStreamTask* pTask, SStreamDataBlock* input); int32_t streamDequeueOutput(SStreamTask* pTask, void** output); @@ -356,4 +429,4 @@ int32_t streamProcessRecoverRsp(SStreamTask* pTask, SStreamTaskRecoverRsp* pRsp) } #endif -#endif /* ifndef _TSTREAM_H_ */ +#endif /* ifndef _STREAM_H_ */ diff --git a/source/dnode/mnode/impl/src/mndScheduler.c b/source/dnode/mnode/impl/src/mndScheduler.c index b390a7fe4a..8497a57edd 100644 --- a/source/dnode/mnode/impl/src/mndScheduler.c +++ b/source/dnode/mnode/impl/src/mndScheduler.c @@ -190,7 +190,7 @@ int32_t mndAddShuffledSinkToStream(SMnode* pMnode, STrans* pTrans, SStreamObj* p sdbRelease(pSdb, pVgroup); continue; } - SStreamTask* pTask = tNewSStreamTask(pStream->uid); + SStreamTask* pTask = tNewSStreamTask(pStream->uid, 0); if (pTask == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; @@ -230,7 +230,7 @@ int32_t mndAddShuffledSinkToStream(SMnode* pMnode, STrans* pTrans, SStreamObj* p int32_t mndAddFixedSinkToStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream) { ASSERT(pStream->fixedSinkVgId != 0); SArray* tasks = taosArrayGetP(pStream->tasks, 0); - SStreamTask* pTask = tNewSStreamTask(pStream->uid); + SStreamTask* pTask = tNewSStreamTask(pStream->uid, 0); if (pTask == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; @@ -322,7 +322,7 @@ int32_t mndScheduleStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream) { sdbRelease(pSdb, pVgroup); continue; } - SStreamTask* pTask = tNewSStreamTask(pStream->uid); + SStreamTask* pTask = tNewSStreamTask(pStream->uid, 0); // source part pTask->sourceType = TASK_SOURCE__SCAN; pTask->inputType = TASK_INPUT_TYPE__SUMBIT_BLOCK; @@ -387,7 +387,7 @@ int32_t mndScheduleStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream) { // else, assign to vnode ASSERT(plan->subplanType == SUBPLAN_TYPE_MERGE); - SStreamTask* pTask = tNewSStreamTask(pStream->uid); + SStreamTask* pTask = tNewSStreamTask(pStream->uid, 0); // source part, currently only support multi source pTask->sourceType = TASK_SOURCE__PIPE; @@ -477,7 +477,7 @@ int32_t mndScheduleStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream) { sdbRelease(pSdb, pVgroup); continue; } - SStreamTask* pTask = tNewSStreamTask(pStream->uid); + SStreamTask* pTask = tNewSStreamTask(pStream->uid, 0); // source part pTask->sourceType = TASK_SOURCE__MERGE; diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index 7cd82b0ac3..e7a744748b 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -78,10 +78,10 @@ typedef struct { tmr_h timerId; int8_t tmrStopped; // exec - int8_t inputStatus; - int8_t execStatus; - SStreamQ inputQ; - SRWLatch lock; + int8_t inputStatus; + int8_t execStatus; + SStreamQueue inputQ; + SRWLatch lock; } STqPushHandle; // tqExec @@ -107,7 +107,7 @@ typedef struct { STqExecCol execCol; STqExecTb execTb; STqExecDb execDb; - } exec; + }; } STqExecHandle; typedef struct { diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 310b59b2e8..38482ccad5 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -266,7 +266,7 @@ int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen) { pHandle->execHandle.pExecReader[i] = tqInitSubmitMsgScanner(pTq->pVnode->pMeta); } if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) { - pHandle->execHandle.exec.execCol.qmsg = req.qmsg; + pHandle->execHandle.execCol.qmsg = req.qmsg; req.qmsg = NULL; for (int32_t i = 0; i < 5; i++) { SReadHandle handle = { @@ -274,15 +274,14 @@ int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen) { .meta = pTq->pVnode->pMeta, .pMsgCb = &pTq->pVnode->msgCb, }; - pHandle->execHandle.exec.execCol.task[i] = - qCreateStreamExecTaskInfo(pHandle->execHandle.exec.execCol.qmsg, &handle); - ASSERT(pHandle->execHandle.exec.execCol.task[i]); + pHandle->execHandle.execCol.task[i] = qCreateStreamExecTaskInfo(pHandle->execHandle.execCol.qmsg, &handle); + ASSERT(pHandle->execHandle.execCol.task[i]); } } else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__DB) { - pHandle->execHandle.exec.execDb.pFilterOutTbUid = + pHandle->execHandle.execDb.pFilterOutTbUid = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); } else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__TABLE) { - pHandle->execHandle.exec.execTb.suid = req.suid; + pHandle->execHandle.execTb.suid = req.suid; SArray* tbUidList = taosArrayInit(0, sizeof(int64_t)); tsdbGetCtbIdList(pTq->pVnode->pMeta, req.suid, tbUidList); tqDebug("vg %d, tq try get suid: %ld", pTq->pVnode->config.vgId, req.suid); @@ -296,17 +295,20 @@ int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen) { taosArrayDestroy(tbUidList); } taosHashPut(pTq->handles, req.subKey, strlen(req.subKey), pHandle, sizeof(STqHandle)); + if (tqMetaSaveHandle(pTq, req.subKey, pHandle) < 0) { + // TODO + } } else { /*ASSERT(pExec->consumerId == req.oldConsumerId);*/ // TODO handle qmsg and exec modification atomic_store_32(&pHandle->epoch, -1); atomic_store_64(&pHandle->consumerId, req.newConsumerId); atomic_add_fetch_32(&pHandle->epoch, 1); + if (tqMetaSaveHandle(pTq, req.subKey, pHandle) < 0) { + // TODO + } } - if (tqMetaSaveHandle(pTq, req.subKey, pHandle) < 0) { - // TODO - } return 0; } @@ -323,16 +325,13 @@ int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) { tDecoderClear(&decoder); pTask->status = TASK_STATUS__IDLE; + + pTask->inputQueue = streamQueueOpen(); + pTask->outputQueue = streamQueueOpen(); pTask->inputStatus = TASK_INPUT_STATUS__NORMAL; pTask->outputStatus = TASK_OUTPUT_STATUS__NORMAL; - pTask->inputQ = taosOpenQueue(); - pTask->outputQ = taosOpenQueue(); - pTask->inputQAll = taosAllocateQall(); - pTask->outputQAll = taosAllocateQall(); - - if (pTask->inputQ == NULL || pTask->outputQ == NULL || pTask->inputQAll == NULL || pTask->outputQAll == NULL) - goto FAIL; + if (pTask->inputQueue == NULL || pTask->outputQueue == NULL) goto FAIL; // exec if (pTask->execType != TASK_EXEC__NONE) { @@ -369,10 +368,8 @@ int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) { return 0; FAIL: - if (pTask->inputQ) taosCloseQueue(pTask->inputQ); - if (pTask->outputQ) taosCloseQueue(pTask->outputQ); - if (pTask->inputQAll) taosFreeQall(pTask->inputQAll); - if (pTask->outputQAll) taosFreeQall(pTask->outputQAll); + if (pTask->inputQueue) streamQueueClose(pTask->inputQueue); + if (pTask->outputQueue) streamQueueClose(pTask->outputQueue); if (pTask) taosMemoryFree(pTask); return -1; } @@ -393,38 +390,16 @@ int32_t tqProcessStreamTrigger(STQ* pTq, SSubmitReq* pReq) { SStreamTask* pTask = (SStreamTask*)pIter; if (pTask->inputType != STREAM_INPUT__DATA_SUBMIT) continue; - int8_t inputStatus = atomic_load_8(&pTask->inputStatus); - if (inputStatus == TASK_INPUT_STATUS__NORMAL) { - if (failed) { - atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__FAILED); + if (!failed) { + if (streamTaskInput(pTask, (SStreamQueueItem*)pSubmit) < 0) { continue; } - SStreamDataSubmit* pSubmitClone = streamSubmitRefClone(pSubmit); - if (pSubmitClone == NULL) { - atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__FAILED); + if (streamTriggerByWrite(pTask, pTq->pVnode->config.vgId, &pTq->pVnode->msgCb) < 0) { continue; } - taosWriteQitem(pTask->inputQ, pSubmitClone); - - int8_t execStatus = atomic_load_8(&pTask->status); - if (execStatus == TASK_STATUS__IDLE || execStatus == TASK_STATUS__CLOSING) { - SStreamTaskRunReq* pRunReq = taosMemoryMalloc(sizeof(SStreamTaskRunReq)); - if (pRunReq == NULL) continue; - // TODO: do we need htonl? - pRunReq->head.vgId = pTq->pVnode->config.vgId; - pRunReq->streamId = pTask->streamId; - pRunReq->taskId = pTask->taskId; - SRpcMsg msg = { - .msgType = TDMT_VND_TASK_RUN, - .pCont = pRunReq, - .contLen = sizeof(SStreamTaskRunReq), - }; - tmsgPutToQueue(&pTq->pVnode->msgCb, FETCH_QUEUE, &msg); - } - } else { - // blocked or stopped, do nothing + streamTaskInputFail(pTask); } } diff --git a/source/dnode/vnode/src/tq/tqExec.c b/source/dnode/vnode/src/tq/tqExec.c index b8fec34b57..31acc60006 100644 --- a/source/dnode/vnode/src/tq/tqExec.c +++ b/source/dnode/vnode/src/tq/tqExec.c @@ -59,7 +59,7 @@ static int32_t tqAddTbNameToRsp(const STQ* pTq, const STqExecHandle* pExec, SMqD int32_t tqDataExec(STQ* pTq, STqExecHandle* pExec, SSubmitReq* pReq, SMqDataBlkRsp* pRsp, int32_t workerId) { if (pExec->subType == TOPIC_SUB_TYPE__COLUMN) { - qTaskInfo_t task = pExec->exec.execCol.task[workerId]; + qTaskInfo_t task = pExec->execCol.task[workerId]; ASSERT(task); qSetStreamInput(task, pReq, STREAM_DATA_TYPE_SUBMIT_BLOCK, false); while (1) { @@ -101,7 +101,7 @@ int32_t tqDataExec(STQ* pTq, STqExecHandle* pExec, SSubmitReq* pReq, SMqDataBlkR pRsp->withSchema = 1; STqReadHandle* pReader = pExec->pExecReader[workerId]; tqReadHandleSetMsg(pReader, pReq, 0); - while (tqNextDataBlockFilterOut(pReader, pExec->exec.execDb.pFilterOutTbUid)) { + while (tqNextDataBlockFilterOut(pReader, pExec->execDb.pFilterOutTbUid)) { SSDataBlock block = {0}; if (tqRetrieveDataBlock(&block.pDataBlock, pReader, &block.info.groupId, &block.info.uid, &block.info.rows, &block.info.numOfCols) < 0) { diff --git a/source/dnode/vnode/src/tq/tqMeta.c b/source/dnode/vnode/src/tq/tqMeta.c index 9447c4007b..398a09ecbc 100644 --- a/source/dnode/vnode/src/tq/tqMeta.c +++ b/source/dnode/vnode/src/tq/tqMeta.c @@ -22,7 +22,7 @@ static int32_t tEncodeSTqHandle(SEncoder* pEncoder, const STqHandle* pHandle) { if (tEncodeI32(pEncoder, pHandle->epoch) < 0) return -1; if (tEncodeI8(pEncoder, pHandle->execHandle.subType) < 0) return -1; if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) { - if (tEncodeCStr(pEncoder, pHandle->execHandle.exec.execCol.qmsg) < 0) return -1; + if (tEncodeCStr(pEncoder, pHandle->execHandle.execCol.qmsg) < 0) return -1; } tEndEncode(pEncoder); return pEncoder->pos; @@ -35,7 +35,7 @@ static int32_t tDecodeSTqHandle(SDecoder* pDecoder, STqHandle* pHandle) { if (tDecodeI32(pDecoder, &pHandle->epoch) < 0) return -1; if (tDecodeI8(pDecoder, &pHandle->execHandle.subType) < 0) return -1; if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) { - if (tDecodeCStrAlloc(pDecoder, &pHandle->execHandle.exec.execCol.qmsg) < 0) return -1; + if (tDecodeCStrAlloc(pDecoder, &pHandle->execHandle.execCol.qmsg) < 0) return -1; } tEndDecode(pDecoder); return 0; @@ -88,12 +88,11 @@ int32_t tqMetaOpen(STQ* pTq) { .meta = pTq->pVnode->pMeta, .pMsgCb = &pTq->pVnode->msgCb, }; - handle.execHandle.exec.execCol.task[i] = - qCreateStreamExecTaskInfo(handle.execHandle.exec.execCol.qmsg, &reader); - ASSERT(handle.execHandle.exec.execCol.task[i]); + handle.execHandle.execCol.task[i] = qCreateStreamExecTaskInfo(handle.execHandle.execCol.qmsg, &reader); + ASSERT(handle.execHandle.execCol.task[i]); } } else { - handle.execHandle.exec.execDb.pFilterOutTbUid = + handle.execHandle.execDb.pFilterOutTbUid = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); } taosHashPut(pTq->handles, pKey, kLen, &handle, sizeof(STqHandle)); diff --git a/source/dnode/vnode/src/tq/tqPush.c b/source/dnode/vnode/src/tq/tqPush.c index d94c3e387a..9be94eb5b6 100644 --- a/source/dnode/vnode/src/tq/tqPush.c +++ b/source/dnode/vnode/src/tq/tqPush.c @@ -29,13 +29,13 @@ static int32_t tqLoopExecFromQueue(STQ* pTq, STqHandle* pHandle, SStreamDataSubm } // update processed atomic_store_64(&pHandle->pushHandle.processedVer, pSubmit->ver); - streamQSetSuccess(&pHandle->pushHandle.inputQ); + streamQueueProcessSuccess(&pHandle->pushHandle.inputQ); streamDataSubmitRefDec(pSubmit); if (pRsp->blockNum > 0) { *ppSubmit = pSubmit; return 0; } else { - pSubmit = streamQNextItem(&pHandle->pushHandle.inputQ); + pSubmit = streamQueueNextItem(&pHandle->pushHandle.inputQ); } } *ppSubmit = pSubmit; @@ -52,14 +52,14 @@ int32_t tqExecFromInputQ(STQ* pTq, STqHandle* pHandle) { // 2. check processedVer // 2.1. if not missed, get msg from queue // 2.2. if missed, scan wal - pSubmit = streamQNextItem(&pHandle->pushHandle.inputQ); + pSubmit = streamQueueNextItem(&pHandle->pushHandle.inputQ); while (pHandle->pushHandle.processedVer <= pSubmit->ver) { // read from wal } while (pHandle->pushHandle.processedVer > pSubmit->ver + 1) { - streamQSetSuccess(&pHandle->pushHandle.inputQ); + streamQueueProcessSuccess(&pHandle->pushHandle.inputQ); streamDataSubmitRefDec(pSubmit); - pSubmit = streamQNextItem(&pHandle->pushHandle.inputQ); + pSubmit = streamQueueNextItem(&pHandle->pushHandle.inputQ); if (pSubmit == NULL) break; } // 3. exec, after each success, update processed ver diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 8909a00c72..43f49b4cc2 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -307,7 +307,7 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) { STqHandle* pExec = (STqHandle*)pIter; if (pExec->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) { for (int32_t i = 0; i < 5; i++) { - int32_t code = qUpdateQualifiedTableId(pExec->execHandle.exec.execCol.task[i], tbUidList, isAdd); + int32_t code = qUpdateQualifiedTableId(pExec->execHandle.execCol.task[i], tbUidList, isAdd); ASSERT(code == 0); } } else if (pExec->execHandle.subType == TOPIC_SUB_TYPE__DB) { @@ -315,7 +315,7 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) { int32_t sz = taosArrayGetSize(tbUidList); for (int32_t i = 0; i < sz; i++) { int64_t tbUid = *(int64_t*)taosArrayGet(tbUidList, i); - taosHashPut(pExec->execHandle.exec.execDb.pFilterOutTbUid, &tbUid, sizeof(int64_t), NULL, 0); + taosHashPut(pExec->execHandle.execDb.pFilterOutTbUid, &tbUid, sizeof(int64_t), NULL, 0); } } } else { diff --git a/source/libs/stream/inc/tstreamInc.h b/source/libs/stream/inc/streamInc.h similarity index 74% rename from source/libs/stream/inc/tstreamInc.h rename to source/libs/stream/inc/streamInc.h index c96901e567..604539f16a 100644 --- a/source/libs/stream/inc/tstreamInc.h +++ b/source/libs/stream/inc/streamInc.h @@ -13,15 +13,21 @@ * along with this program. If not, see . */ +#ifndef _STREAM_INC_H_ +#define _STREAM_INC_H_ + +#include "executor.h" +#include "tstream.h" + #ifdef __cplusplus extern "C" { #endif -#ifndef _TSTREAM_H_ -#define _TSTREAM_H_ +int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb); +int32_t streamSink1(SStreamTask* pTask, SMsgCb* pMsgCb); #ifdef __cplusplus } #endif -#endif /* ifndef _TSTREAM_H_ */ +#endif /* ifndef _STREAM_INC_H_ */ diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c new file mode 100644 index 0000000000..d89f2ed57d --- /dev/null +++ b/source/libs/stream/src/stream.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "streamInc.h" + +int32_t streamTriggerByWrite(SStreamTask* pTask, int32_t vgId, SMsgCb* pMsgCb) { + int8_t execStatus = atomic_load_8(&pTask->status); + if (execStatus == TASK_STATUS__IDLE || execStatus == TASK_STATUS__CLOSING) { + SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq)); + if (pRunReq == NULL) return -1; + + // TODO: do we need htonl? + pRunReq->head.vgId = vgId; + pRunReq->streamId = pTask->streamId; + pRunReq->taskId = pTask->taskId; + SRpcMsg msg = { + .msgType = TDMT_VND_TASK_RUN, + .pCont = pRunReq, + .contLen = sizeof(SStreamTaskRunReq), + }; + tmsgPutToQueue(pMsgCb, FETCH_QUEUE, &msg); + } + return 0; +} + +#if 1 +int32_t streamTaskEnqueue(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp) { + SStreamDataBlock* pBlock = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM); + int8_t status; + + // enqueue + if (pBlock != NULL) { + pBlock->type = STREAM_DATA_TYPE_SSDATA_BLOCK; + pBlock->sourceVg = pReq->sourceVg; + pBlock->blocks = pReq->data; + /*pBlock->sourceVer = pReq->sourceVer;*/ + if (streamTaskInput(pTask, (SStreamQueueItem*)pBlock) == 0) { + status = TASK_INPUT_STATUS__NORMAL; + } else { + status = TASK_INPUT_STATUS__FAILED; + } + } else { + streamTaskInputFail(pTask); + status = TASK_INPUT_STATUS__FAILED; + } + + // rsp by input status + SStreamDispatchRsp* pCont = rpcMallocCont(sizeof(SStreamDispatchRsp)); + pCont->inputStatus = status; + pCont->streamId = pReq->streamId; + pCont->taskId = pReq->sourceTaskId; + pRsp->pCont = pCont; + pRsp->contLen = sizeof(SStreamDispatchRsp); + tmsgSendRsp(pRsp); + return status == TASK_INPUT_STATUS__NORMAL ? 0 : -1; +} +#endif + +int32_t streamProcessDispatchReq(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchReq* pReq, SRpcMsg* pRsp) { + // 1. handle input + streamTaskEnqueue(pTask, pReq, pRsp); + + // 2. try exec + // 2.1. idle: exec + // 2.2. executing: return + // 2.3. closing: keep trying + streamExec(pTask, pMsgCb); + + // 3. handle output + // 3.1 check and set status + // 3.2 dispatch / sink + streamSink1(pTask, pMsgCb); + + return 0; +} + +int32_t streamProcessDispatchRsp(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchRsp* pRsp) { + if (pRsp->inputStatus == TASK_INPUT_STATUS__BLOCKED) { + // TODO: init recover timer + } + // continue dispatch + streamSink1(pTask, pMsgCb); + return 0; +} + +int32_t streamTaskProcessRunReq(SStreamTask* pTask, SMsgCb* pMsgCb) { + streamExec(pTask, pMsgCb); + streamSink1(pTask, pMsgCb); + return 0; +} + +int32_t streamProcessRecoverReq(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamTaskRecoverReq* pReq, SRpcMsg* pMsg) { + // + return 0; +} + +int32_t streamProcessRecoverRsp(SStreamTask* pTask, SStreamTaskRecoverRsp* pRsp) { + // + return 0; +} diff --git a/source/libs/stream/src/streamData.c b/source/libs/stream/src/streamData.c new file mode 100644 index 0000000000..95c0290058 --- /dev/null +++ b/source/libs/stream/src/streamData.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "tstream.h" + +#if 0 +int32_t streamDataBlockEncode(void** buf, const SStreamDataBlock* pOutput) { + int32_t tlen = 0; + tlen += taosEncodeFixedI8(buf, pOutput->type); + tlen += taosEncodeFixedI32(buf, pOutput->sourceVg); + tlen += taosEncodeFixedI64(buf, pOutput->sourceVer); + ASSERT(pOutput->type == STREAM_INPUT__DATA_BLOCK); + tlen += tEncodeDataBlocks(buf, pOutput->blocks); + return tlen; +} + +void* streamDataBlockDecode(const void* buf, SStreamDataBlock* pInput) { + buf = taosDecodeFixedI8(buf, &pInput->type); + buf = taosDecodeFixedI32(buf, &pInput->sourceVg); + buf = taosDecodeFixedI64(buf, &pInput->sourceVer); + ASSERT(pInput->type == STREAM_INPUT__DATA_BLOCK); + buf = tDecodeDataBlocks(buf, &pInput->blocks); + return (void*)buf; +} +#endif + +SStreamDataSubmit* streamDataSubmitNew(SSubmitReq* pReq) { + SStreamDataSubmit* pDataSubmit = (SStreamDataSubmit*)taosAllocateQitem(sizeof(SStreamDataSubmit), DEF_QITEM); + if (pDataSubmit == NULL) return NULL; + pDataSubmit->dataRef = (int32_t*)taosMemoryMalloc(sizeof(int32_t)); + if (pDataSubmit->dataRef == NULL) goto FAIL; + pDataSubmit->data = pReq; + *pDataSubmit->dataRef = 1; + pDataSubmit->type = STREAM_INPUT__DATA_SUBMIT; + return pDataSubmit; +FAIL: + taosFreeQitem(pDataSubmit); + return NULL; +} + +static FORCE_INLINE void streamDataSubmitRefInc(SStreamDataSubmit* pDataSubmit) { + // + atomic_add_fetch_32(pDataSubmit->dataRef, 1); +} + +SStreamDataSubmit* streamSubmitRefClone(SStreamDataSubmit* pSubmit) { + SStreamDataSubmit* pSubmitClone = taosAllocateQitem(sizeof(SStreamDataSubmit), DEF_QITEM); + if (pSubmitClone == NULL) { + return NULL; + } + streamDataSubmitRefInc(pSubmit); + memcpy(pSubmitClone, pSubmit, sizeof(SStreamDataSubmit)); + return pSubmitClone; +} + +#if 0 +int32_t tEncodeSStreamTaskExecReq(void** buf, const SStreamTaskExecReq* pReq) { + int32_t tlen = 0; + tlen += taosEncodeFixedI64(buf, pReq->streamId); + tlen += taosEncodeFixedI32(buf, pReq->taskId); + tlen += tEncodeDataBlocks(buf, pReq->data); + return tlen; +} + +void* tDecodeSStreamTaskExecReq(const void* buf, SStreamTaskExecReq* pReq) { + buf = taosDecodeFixedI64(buf, &pReq->streamId); + buf = taosDecodeFixedI32(buf, &pReq->taskId); + buf = tDecodeDataBlocks(buf, &pReq->data); + return (void*)buf; +} + +void tFreeSStreamTaskExecReq(SStreamTaskExecReq* pReq) { taosArrayDestroy(pReq->data); } +#endif diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c new file mode 100644 index 0000000000..4b88cf503e --- /dev/null +++ b/source/libs/stream/src/streamExec.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "executor.h" +#include "tstream.h" + +static int32_t streamTaskExecImpl(SStreamTask* pTask, void* data, SArray* pRes) { + void* exec = pTask->exec.executor; + + // set input + if (pTask->inputType == STREAM_INPUT__DATA_SUBMIT) { + SStreamDataSubmit* pSubmit = (SStreamDataSubmit*)data; + ASSERT(pSubmit->type == STREAM_INPUT__DATA_SUBMIT); + + qSetStreamInput(exec, pSubmit->data, STREAM_DATA_TYPE_SUBMIT_BLOCK, false); + } else if (pTask->inputType == STREAM_INPUT__DATA_BLOCK) { + SStreamDataBlock* pBlock = (SStreamDataBlock*)data; + ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK); + + SArray* blocks = pBlock->blocks; + qSetMultiStreamInput(exec, blocks->pData, blocks->size, STREAM_DATA_TYPE_SSDATA_BLOCK, false); + } + + // exec + while (1) { + SSDataBlock* output = NULL; + uint64_t ts = 0; + if (qExecTask(exec, &output, &ts) < 0) { + ASSERT(false); + } + if (output == NULL) break; + // TODO: do we need free memory? + SSDataBlock* outputCopy = createOneDataBlock(output, true); + taosArrayPush(pRes, outputCopy); + } + return 0; +} + +static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { + while (1) { + void* data = streamQueueNextItem(pTask->inputQueue); + if (data == NULL) break; + + streamTaskExecImpl(pTask, data, pRes); + + if (taosArrayGetSize(pRes) != 0) { + SStreamDataBlock* qRes = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM); + if (qRes == NULL) { + streamQueueProcessFail(pTask->inputQueue); + taosArrayDestroy(pRes); + return NULL; + } + qRes->type = STREAM_INPUT__DATA_BLOCK; + qRes->blocks = pRes; + if (streamTaskOutput(pTask, qRes) < 0) { + streamQueueProcessFail(pTask->inputQueue); + taosArrayDestroy(pRes); + taosFreeQitem(qRes); + return NULL; + } + + if (pTask->inputType == STREAM_INPUT__DATA_SUBMIT) { + streamDataSubmitRefDec((SStreamDataSubmit*)data); + taosFreeQitem(data); + } else { + taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)tDeleteSSDataBlock); + taosFreeQitem(data); + } + streamQueueProcessSuccess(pTask->inputQueue); + return taosArrayInit(0, sizeof(SSDataBlock)); + } + } + return pRes; +} + +// TODO: handle version +int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb) { + SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock)); + if (pRes == NULL) return -1; + while (1) { + int8_t execStatus = atomic_val_compare_exchange_8(&pTask->status, TASK_STATUS__IDLE, TASK_STATUS__EXECUTING); + if (execStatus == TASK_STATUS__IDLE) { + // first run + pRes = streamExecForQall(pTask, pRes); + if (pRes == NULL) goto FAIL; + + // set status closing + atomic_store_8(&pTask->status, TASK_STATUS__CLOSING); + + // second run, make sure inputQ and qall are cleared + pRes = streamExecForQall(pTask, pRes); + if (pRes == NULL) goto FAIL; + + break; + } else if (execStatus == TASK_STATUS__CLOSING) { + continue; + } else if (execStatus == TASK_STATUS__EXECUTING) { + break; + } else { + ASSERT(0); + } + } + if (pRes) taosArrayDestroy(pRes); + atomic_store_8(&pTask->status, TASK_STATUS__IDLE); + return 0; +FAIL: + if (pRes) taosArrayDestroy(pRes); + atomic_store_8(&pTask->status, TASK_STATUS__IDLE); + return -1; +} + diff --git a/source/libs/stream/src/streamMsg.c b/source/libs/stream/src/streamMsg.c new file mode 100644 index 0000000000..81f18fea8d --- /dev/null +++ b/source/libs/stream/src/streamMsg.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "tstream.h" + +int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatchReq* pReq) { + if (tStartEncode(pEncoder) < 0) return -1; + if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1; + if (tEncodeI32(pEncoder, pReq->taskId) < 0) return -1; + if (tEncodeI32(pEncoder, pReq->sourceTaskId) < 0) return -1; + if (tEncodeI32(pEncoder, pReq->sourceVg) < 0) return -1; + if (tEncodeI32(pEncoder, pReq->sourceChildId) < 0) return -1; + if (tEncodeI32(pEncoder, pReq->blockNum) < 0) return -1; + ASSERT(taosArrayGetSize(pReq->data) == pReq->blockNum); + ASSERT(taosArrayGetSize(pReq->dataLen) == pReq->blockNum); + for (int32_t i = 0; i < pReq->blockNum; i++) { + int32_t len = *(int32_t*)taosArrayGet(pReq->dataLen, i); + void* data = taosArrayGetP(pReq->data, i); + if (tEncodeI32(pEncoder, len) < 0) return -1; + if (tEncodeBinary(pEncoder, data, len) < 0) return -1; + } + tEndEncode(pEncoder); + return 0; +} + +int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { + if (tStartDecode(pDecoder) < 0) return -1; + if (tDecodeI64(pDecoder, &pReq->streamId) < 0) return -1; + if (tDecodeI32(pDecoder, &pReq->taskId) < 0) return -1; + if (tDecodeI32(pDecoder, &pReq->sourceTaskId) < 0) return -1; + if (tDecodeI32(pDecoder, &pReq->sourceVg) < 0) return -1; + if (tDecodeI32(pDecoder, &pReq->sourceChildId) < 0) return -1; + if (tDecodeI32(pDecoder, &pReq->blockNum) < 0) return -1; + ASSERT(pReq->blockNum > 0); + pReq->data = taosArrayInit(pReq->blockNum, sizeof(void*)); + pReq->dataLen = taosArrayInit(pReq->blockNum, sizeof(int32_t)); + for (int32_t i = 0; i < pReq->blockNum; i++) { + int32_t len1; + uint64_t len2; + void* data; + if (tDecodeI32(pDecoder, &len1) < 0) return -1; + if (tDecodeBinaryAlloc(pDecoder, &data, &len2) < 0) return -1; + ASSERT(len1 == len2); + taosArrayPush(pReq->dataLen, &len1); + taosArrayPush(pReq->data, &data); + } + tEndDecode(pDecoder); + return 0; +} + +int32_t streamBuildDispatchMsg(SStreamTask* pTask, SArray* data, SRpcMsg* pMsg, SEpSet** ppEpSet) { + SStreamDispatchReq req = { + .streamId = pTask->streamId, + .data = data, + }; + return 0; +} + +static int32_t streamBuildExecMsg(SStreamTask* pTask, SArray* data, SRpcMsg* pMsg, SEpSet** ppEpSet) { + SStreamTaskExecReq req = { + .streamId = pTask->streamId, + .data = data, + }; + + int32_t tlen = sizeof(SMsgHead) + tEncodeSStreamTaskExecReq(NULL, &req); + void* buf = rpcMallocCont(tlen); + + if (buf == NULL) { + return -1; + } + + if (pTask->dispatchType == TASK_DISPATCH__INPLACE) { + ((SMsgHead*)buf)->vgId = 0; + req.taskId = pTask->inplaceDispatcher.taskId; + + } else if (pTask->dispatchType == TASK_DISPATCH__FIXED) { + ((SMsgHead*)buf)->vgId = htonl(pTask->fixedEpDispatcher.nodeId); + *ppEpSet = &pTask->fixedEpDispatcher.epSet; + req.taskId = pTask->fixedEpDispatcher.taskId; + + } else if (pTask->dispatchType == TASK_DISPATCH__SHUFFLE) { + // TODO use general name rule of schemaless + char ctbName[TSDB_TABLE_FNAME_LEN + 22] = {0}; + // all groupId must be the same in an array + SSDataBlock* pBlock = taosArrayGet(data, 0); + sprintf(ctbName, "%s:%ld", pTask->shuffleDispatcher.stbFullName, pBlock->info.groupId); + + // TODO: get hash function by hashMethod + + // get groupId, compute hash value + uint32_t hashValue = MurmurHash3_32(ctbName, strlen(ctbName)); + + // get node + // TODO: optimize search process + SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; + int32_t sz = taosArrayGetSize(vgInfo); + int32_t nodeId = 0; + for (int32_t i = 0; i < sz; i++) { + SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); + if (hashValue >= pVgInfo->hashBegin && hashValue <= pVgInfo->hashEnd) { + nodeId = pVgInfo->vgId; + req.taskId = pVgInfo->taskId; + *ppEpSet = &pVgInfo->epSet; + break; + } + } + ASSERT(nodeId != 0); + ((SMsgHead*)buf)->vgId = htonl(nodeId); + } + + void* abuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); + tEncodeSStreamTaskExecReq(&abuf, &req); + + pMsg->pCont = buf; + pMsg->contLen = tlen; + pMsg->code = 0; + pMsg->msgType = pTask->dispatchMsgType; + pMsg->info.noResp = 1; + + return 0; +} + +static int32_t streamShuffleDispatch(SStreamTask* pTask, SMsgCb* pMsgCb, SHashObj* data) { + void* pIter = NULL; + while (1) { + pIter = taosHashIterate(data, pIter); + if (pIter == NULL) return 0; + SArray* pData = *(SArray**)pIter; + SRpcMsg dispatchMsg = {0}; + SEpSet* pEpSet; + if (streamBuildExecMsg(pTask, pData, &dispatchMsg, &pEpSet) < 0) { + ASSERT(0); + return -1; + } + tmsgSendReq(pEpSet, &dispatchMsg); + } + return 0; +} diff --git a/source/libs/stream/src/streamQueue.c b/source/libs/stream/src/streamQueue.c new file mode 100644 index 0000000000..f82ef1b42f --- /dev/null +++ b/source/libs/stream/src/streamQueue.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "tstream.h" + +SStreamQueue* streamQueueOpen() { + SStreamQueue* pQueue = taosMemoryCalloc(1, sizeof(SStreamQueue)); + if (pQueue == NULL) return NULL; + pQueue->queue = taosOpenQueue(); + pQueue->qall = taosAllocateQall(); + if (pQueue->queue == NULL || pQueue->qall == NULL) { + goto FAIL; + } + pQueue->status = STREAM_QUEUE__SUCESS; + return pQueue; +FAIL: + if (pQueue->queue) taosCloseQueue(pQueue->queue); + if (pQueue->qall) taosFreeQall(pQueue->qall); + taosMemoryFree(pQueue); + return NULL; +} + +void streamQueueClose(SStreamQueue* queue) { + while (1) { + void* qItem = streamQueueNextItem(queue); + if (qItem) + taosFreeQitem(qItem); + else + return; + } +} diff --git a/source/libs/stream/src/streamSink.c b/source/libs/stream/src/streamSink.c new file mode 100644 index 0000000000..6acdd1064c --- /dev/null +++ b/source/libs/stream/src/streamSink.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "executor.h" +#include "tstream.h" + +int32_t streamSink1(SStreamTask* pTask, SMsgCb* pMsgCb) { + SStreamQueue* queue; + if (pTask->execType == TASK_EXEC__NONE) { + queue = pTask->inputQueue; + } else { + queue = pTask->outputQueue; + } + /*if (streamDequeueBegin(queue) == true) {*/ + /*return -1;*/ + /*}*/ + + if (pTask->sinkType == TASK_SINK__TABLE || pTask->sinkType == TASK_SINK__SMA) { + ASSERT(pTask->dispatchType == TASK_DISPATCH__NONE); + while (1) { + SStreamDataBlock* pBlock = streamQueueNextItem(queue); + if (pBlock == NULL) break; + ASSERT(pBlock->type == STREAM_DATA_TYPE_SSDATA_BLOCK); + + // local sink + if (pTask->sinkType == TASK_SINK__TABLE) { + pTask->tbSink.tbSinkFunc(pTask, pTask->tbSink.vnode, 0, pBlock->blocks); + } else if (pTask->sinkType == TASK_SINK__SMA) { + pTask->smaSink.smaSink(pTask->ahandle, pTask->smaSink.smaId, pBlock->blocks); + } + + if (pTask->dispatchType == TASK_DISPATCH__INPLACE) { + ASSERT(queue == pTask->outputQueue); + } else if (pTask->dispatchType == TASK_DISPATCH__SHUFFLE) { + ASSERT(queue == pTask->outputQueue); + } else if (pTask->dispatchType == TASK_DISPATCH__FIXED) { + ASSERT(queue == pTask->outputQueue); + } + + streamQueueProcessSuccess(queue); + } + } + + return 0; +} + +#if 0 +int32_t streamSink(SStreamTask* pTask, SMsgCb* pMsgCb) { + bool firstRun = 1; + while (1) { + SStreamDataBlock* pBlock = NULL; + if (!firstRun) { + taosReadAllQitems(pTask->outputQ, pTask->outputQAll); + } + taosGetQitem(pTask->outputQAll, (void**)&pBlock); + if (pBlock == NULL) { + if (firstRun) { + firstRun = 0; + continue; + } else { + break; + } + } + + SArray* pRes = pBlock->blocks; + + // sink + if (pTask->sinkType == TASK_SINK__TABLE) { + // blockDebugShowData(pRes); + pTask->tbSink.tbSinkFunc(pTask, pTask->tbSink.vnode, 0, pRes); + } else if (pTask->sinkType == TASK_SINK__SMA) { + pTask->smaSink.smaSink(pTask->ahandle, pTask->smaSink.smaId, pRes); + // + } else if (pTask->sinkType == TASK_SINK__FETCH) { + // + } else { + ASSERT(pTask->sinkType == TASK_SINK__NONE); + } + + // dispatch + // TODO dispatch guard + int8_t outputStatus = atomic_load_8(&pTask->outputStatus); + if (outputStatus == TASK_OUTPUT_STATUS__NORMAL) { + if (pTask->dispatchType == TASK_DISPATCH__INPLACE) { + SRpcMsg dispatchMsg = {0}; + if (streamBuildExecMsg(pTask, pRes, &dispatchMsg, NULL) < 0) { + ASSERT(0); + return -1; + } + + int32_t qType; + if (pTask->dispatchMsgType == TDMT_VND_TASK_DISPATCH || pTask->dispatchMsgType == TDMT_SND_TASK_DISPATCH) { + qType = FETCH_QUEUE; + /*} else if (pTask->dispatchMsgType == TDMT_VND_TASK_MERGE_EXEC ||*/ + /*pTask->dispatchMsgType == TDMT_SND_TASK_MERGE_EXEC) {*/ + /*qType = MERGE_QUEUE;*/ + /*} else if (pTask->dispatchMsgType == TDMT_VND_TASK_WRITE_EXEC) {*/ + /*qType = WRITE_QUEUE;*/ + } else { + ASSERT(0); + } + tmsgPutToQueue(pMsgCb, qType, &dispatchMsg); + + } else if (pTask->dispatchType == TASK_DISPATCH__FIXED) { + SRpcMsg dispatchMsg = {0}; + SEpSet* pEpSet = NULL; + if (streamBuildExecMsg(pTask, pRes, &dispatchMsg, &pEpSet) < 0) { + ASSERT(0); + return -1; + } + + tmsgSendReq(pEpSet, &dispatchMsg); + + } else if (pTask->dispatchType == TASK_DISPATCH__SHUFFLE) { + SHashObj* pShuffleRes = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK); + if (pShuffleRes == NULL) { + return -1; + } + + int32_t sz = taosArrayGetSize(pRes); + for (int32_t i = 0; i < sz; i++) { + SSDataBlock* pDataBlock = taosArrayGet(pRes, i); + SArray* pArray = taosHashGet(pShuffleRes, &pDataBlock->info.groupId, sizeof(int64_t)); + if (pArray == NULL) { + pArray = taosArrayInit(0, sizeof(SSDataBlock)); + if (pArray == NULL) { + return -1; + } + taosHashPut(pShuffleRes, &pDataBlock->info.groupId, sizeof(int64_t), &pArray, sizeof(void*)); + } + taosArrayPush(pArray, pDataBlock); + } + + if (streamShuffleDispatch(pTask, pMsgCb, pShuffleRes) < 0) { + return -1; + } + + } else { + ASSERT(pTask->dispatchType == TASK_DISPATCH__NONE); + } + } + } + return 0; +} +#endif diff --git a/source/libs/stream/src/streamTask.c b/source/libs/stream/src/streamTask.c new file mode 100644 index 0000000000..890ae1f3b5 --- /dev/null +++ b/source/libs/stream/src/streamTask.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "executor.h" +#include "tstream.h" + +SStreamTask* tNewSStreamTask(int64_t streamId, int32_t childId) { + SStreamTask* pTask = (SStreamTask*)taosMemoryCalloc(1, sizeof(SStreamTask)); + if (pTask == NULL) { + return NULL; + } + pTask->taskId = tGenIdPI32(); + pTask->streamId = streamId; + pTask->childId = childId; + pTask->status = TASK_STATUS__IDLE; + pTask->inputStatus = TASK_INPUT_STATUS__NORMAL; + pTask->outputStatus = TASK_OUTPUT_STATUS__NORMAL; + + return pTask; +} + +int32_t tEncodeSStreamTask(SEncoder* pEncoder, const SStreamTask* pTask) { + /*if (tStartEncode(pEncoder) < 0) return -1;*/ + if (tEncodeI64(pEncoder, pTask->streamId) < 0) return -1; + if (tEncodeI32(pEncoder, pTask->taskId) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->inputType) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->status) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->sourceType) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->execType) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->sinkType) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->dispatchType) < 0) return -1; + if (tEncodeI16(pEncoder, pTask->dispatchMsgType) < 0) return -1; + + if (tEncodeI32(pEncoder, pTask->childId) < 0) return -1; + if (tEncodeI32(pEncoder, pTask->nodeId) < 0) return -1; + if (tEncodeSEpSet(pEncoder, &pTask->epSet) < 0) return -1; + + if (pTask->execType != TASK_EXEC__NONE) { + if (tEncodeI8(pEncoder, pTask->exec.parallelizable) < 0) return -1; + if (tEncodeCStr(pEncoder, pTask->exec.qmsg) < 0) return -1; + } + + if (pTask->sinkType == TASK_SINK__TABLE) { + if (tEncodeI64(pEncoder, pTask->tbSink.stbUid) < 0) return -1; + if (tEncodeCStr(pEncoder, pTask->tbSink.stbFullName) < 0) return -1; + if (tEncodeSSchemaWrapper(pEncoder, pTask->tbSink.pSchemaWrapper) < 0) return -1; + } else if (pTask->sinkType == TASK_SINK__SMA) { + if (tEncodeI64(pEncoder, pTask->smaSink.smaId) < 0) return -1; + } else if (pTask->sinkType == TASK_SINK__FETCH) { + if (tEncodeI8(pEncoder, pTask->fetchSink.reserved) < 0) return -1; + } else { + ASSERT(pTask->sinkType == TASK_SINK__NONE); + } + + if (pTask->dispatchType == TASK_DISPATCH__INPLACE) { + if (tEncodeI32(pEncoder, pTask->inplaceDispatcher.taskId) < 0) return -1; + } else if (pTask->dispatchType == TASK_DISPATCH__FIXED) { + if (tEncodeI32(pEncoder, pTask->fixedEpDispatcher.taskId) < 0) return -1; + if (tEncodeI32(pEncoder, pTask->fixedEpDispatcher.nodeId) < 0) return -1; + if (tEncodeSEpSet(pEncoder, &pTask->fixedEpDispatcher.epSet) < 0) return -1; + } else if (pTask->dispatchType == TASK_DISPATCH__SHUFFLE) { + if (tSerializeSUseDbRspImp(pEncoder, &pTask->shuffleDispatcher.dbInfo) < 0) return -1; + /*if (tEncodeI8(pEncoder, pTask->shuffleDispatcher.hashMethod) < 0) return -1;*/ + } + + /*tEndEncode(pEncoder);*/ + return pEncoder->pos; +} + +int32_t tDecodeSStreamTask(SDecoder* pDecoder, SStreamTask* pTask) { + /*if (tStartDecode(pDecoder) < 0) return -1;*/ + if (tDecodeI64(pDecoder, &pTask->streamId) < 0) return -1; + if (tDecodeI32(pDecoder, &pTask->taskId) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->inputType) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->status) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->sourceType) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->execType) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->sinkType) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->dispatchType) < 0) return -1; + if (tDecodeI16(pDecoder, &pTask->dispatchMsgType) < 0) return -1; + + if (tDecodeI32(pDecoder, &pTask->childId) < 0) return -1; + if (tDecodeI32(pDecoder, &pTask->nodeId) < 0) return -1; + if (tDecodeSEpSet(pDecoder, &pTask->epSet) < 0) return -1; + + if (pTask->execType != TASK_EXEC__NONE) { + if (tDecodeI8(pDecoder, &pTask->exec.parallelizable) < 0) return -1; + if (tDecodeCStrAlloc(pDecoder, &pTask->exec.qmsg) < 0) return -1; + } + + if (pTask->sinkType == TASK_SINK__TABLE) { + if (tDecodeI64(pDecoder, &pTask->tbSink.stbUid) < 0) return -1; + if (tDecodeCStrTo(pDecoder, pTask->tbSink.stbFullName) < 0) return -1; + pTask->tbSink.pSchemaWrapper = taosMemoryCalloc(1, sizeof(SSchemaWrapper)); + if (pTask->tbSink.pSchemaWrapper == NULL) return -1; + if (tDecodeSSchemaWrapper(pDecoder, pTask->tbSink.pSchemaWrapper) < 0) return -1; + } else if (pTask->sinkType == TASK_SINK__SMA) { + if (tDecodeI64(pDecoder, &pTask->smaSink.smaId) < 0) return -1; + } else if (pTask->sinkType == TASK_SINK__FETCH) { + if (tDecodeI8(pDecoder, &pTask->fetchSink.reserved) < 0) return -1; + } else { + ASSERT(pTask->sinkType == TASK_SINK__NONE); + } + + if (pTask->dispatchType == TASK_DISPATCH__INPLACE) { + if (tDecodeI32(pDecoder, &pTask->inplaceDispatcher.taskId) < 0) return -1; + } else if (pTask->dispatchType == TASK_DISPATCH__FIXED) { + if (tDecodeI32(pDecoder, &pTask->fixedEpDispatcher.taskId) < 0) return -1; + if (tDecodeI32(pDecoder, &pTask->fixedEpDispatcher.nodeId) < 0) return -1; + if (tDecodeSEpSet(pDecoder, &pTask->fixedEpDispatcher.epSet) < 0) return -1; + } else if (pTask->dispatchType == TASK_DISPATCH__SHUFFLE) { + /*if (tDecodeI8(pDecoder, &pTask->shuffleDispatcher.hashMethod) < 0) return -1;*/ + if (tDeserializeSUseDbRspImp(pDecoder, &pTask->shuffleDispatcher.dbInfo) < 0) return -1; + } + + /*tEndDecode(pDecoder);*/ + return 0; +} + +void tFreeSStreamTask(SStreamTask* pTask) { + streamQueueClose(pTask->inputQueue); + streamQueueClose(pTask->outputQueue); + if (pTask->exec.qmsg) taosMemoryFree(pTask->exec.qmsg); + qDestroyTask(pTask->exec.executor); + taosMemoryFree(pTask); +} diff --git a/source/libs/stream/src/tstreamUpdate.c b/source/libs/stream/src/streamUpdate.c similarity index 100% rename from source/libs/stream/src/tstreamUpdate.c rename to source/libs/stream/src/streamUpdate.c diff --git a/source/libs/stream/src/tstream.c b/source/libs/stream/src/tstream.c deleted file mode 100644 index 7d406a7144..0000000000 --- a/source/libs/stream/src/tstream.c +++ /dev/null @@ -1,594 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include "tstream.h" -#include "executor.h" - -int32_t streamDataBlockEncode(void** buf, const SStreamDataBlock* pOutput) { - int32_t tlen = 0; - tlen += taosEncodeFixedI8(buf, pOutput->type); - tlen += taosEncodeFixedI32(buf, pOutput->sourceVg); - tlen += taosEncodeFixedI64(buf, pOutput->sourceVer); - ASSERT(pOutput->type == STREAM_INPUT__DATA_BLOCK); - tlen += tEncodeDataBlocks(buf, pOutput->blocks); - return tlen; -} - -void* streamDataBlockDecode(const void* buf, SStreamDataBlock* pInput) { - buf = taosDecodeFixedI8(buf, &pInput->type); - buf = taosDecodeFixedI32(buf, &pInput->sourceVg); - buf = taosDecodeFixedI64(buf, &pInput->sourceVer); - ASSERT(pInput->type == STREAM_INPUT__DATA_BLOCK); - buf = tDecodeDataBlocks(buf, &pInput->blocks); - return (void*)buf; -} - -SStreamDataSubmit* streamSubmitRefClone(SStreamDataSubmit* pSubmit) { - SStreamDataSubmit* pSubmitClone = taosAllocateQitem(sizeof(SStreamDataSubmit), DEF_QITEM); - if (pSubmitClone == NULL) { - return NULL; - } - streamDataSubmitRefInc(pSubmit); - memcpy(pSubmitClone, pSubmit, sizeof(SStreamDataSubmit)); - return pSubmitClone; -} - -static int32_t streamBuildDispatchMsg(SStreamTask* pTask, SArray* data, SRpcMsg* pMsg, SEpSet** ppEpSet) { - SStreamDispatchReq req = { - .streamId = pTask->streamId, - .data = data, - }; - return 0; -} - -static int32_t streamBuildExecMsg(SStreamTask* pTask, SArray* data, SRpcMsg* pMsg, SEpSet** ppEpSet) { - SStreamTaskExecReq req = { - .streamId = pTask->streamId, - .data = data, - }; - - int32_t tlen = sizeof(SMsgHead) + tEncodeSStreamTaskExecReq(NULL, &req); - void* buf = rpcMallocCont(tlen); - - if (buf == NULL) { - return -1; - } - - if (pTask->dispatchType == TASK_DISPATCH__INPLACE) { - ((SMsgHead*)buf)->vgId = 0; - req.taskId = pTask->inplaceDispatcher.taskId; - - } else if (pTask->dispatchType == TASK_DISPATCH__FIXED) { - ((SMsgHead*)buf)->vgId = htonl(pTask->fixedEpDispatcher.nodeId); - *ppEpSet = &pTask->fixedEpDispatcher.epSet; - req.taskId = pTask->fixedEpDispatcher.taskId; - - } else if (pTask->dispatchType == TASK_DISPATCH__SHUFFLE) { - // TODO use general name rule of schemaless - char ctbName[TSDB_TABLE_FNAME_LEN + 22] = {0}; - // all groupId must be the same in an array - SSDataBlock* pBlock = taosArrayGet(data, 0); - sprintf(ctbName, "%s:%ld", pTask->shuffleDispatcher.stbFullName, pBlock->info.groupId); - - // TODO: get hash function by hashMethod - - // get groupId, compute hash value - uint32_t hashValue = MurmurHash3_32(ctbName, strlen(ctbName)); - - // get node - // TODO: optimize search process - SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; - int32_t sz = taosArrayGetSize(vgInfo); - int32_t nodeId = 0; - for (int32_t i = 0; i < sz; i++) { - SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); - if (hashValue >= pVgInfo->hashBegin && hashValue <= pVgInfo->hashEnd) { - nodeId = pVgInfo->vgId; - req.taskId = pVgInfo->taskId; - *ppEpSet = &pVgInfo->epSet; - break; - } - } - ASSERT(nodeId != 0); - ((SMsgHead*)buf)->vgId = htonl(nodeId); - } - - void* abuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); - tEncodeSStreamTaskExecReq(&abuf, &req); - - pMsg->pCont = buf; - pMsg->contLen = tlen; - pMsg->code = 0; - pMsg->msgType = pTask->dispatchMsgType; - pMsg->info.noResp = 1; - - return 0; -} - -static int32_t streamShuffleDispatch(SStreamTask* pTask, SMsgCb* pMsgCb, SHashObj* data) { - void* pIter = NULL; - while (1) { - pIter = taosHashIterate(data, pIter); - if (pIter == NULL) return 0; - SArray* pData = *(SArray**)pIter; - SRpcMsg dispatchMsg = {0}; - SEpSet* pEpSet; - if (streamBuildExecMsg(pTask, pData, &dispatchMsg, &pEpSet) < 0) { - ASSERT(0); - return -1; - } - tmsgSendReq(pEpSet, &dispatchMsg); - } - return 0; -} - -int32_t streamEnqueueDataSubmit(SStreamTask* pTask, SStreamDataSubmit* input) { - ASSERT(pTask->inputType == TASK_INPUT_TYPE__SUMBIT_BLOCK); - int8_t inputStatus = atomic_load_8(&pTask->inputStatus); - if (inputStatus == TASK_INPUT_STATUS__NORMAL) { - streamDataSubmitRefInc(input); - taosWriteQitem(pTask->inputQ, input); - } - return inputStatus; -} - -int32_t streamEnqueueDataBlk(SStreamTask* pTask, SStreamDataBlock* input) { - ASSERT(pTask->inputType == TASK_INPUT_TYPE__DATA_BLOCK); - taosWriteQitem(pTask->inputQ, input); - int8_t inputStatus = atomic_load_8(&pTask->inputStatus); - return inputStatus; -} - -static int32_t streamTaskExecImpl(SStreamTask* pTask, void* data, SArray* pRes) { - void* exec = pTask->exec.executor; - - // set input - if (pTask->inputType == STREAM_INPUT__DATA_SUBMIT) { - SStreamDataSubmit* pSubmit = (SStreamDataSubmit*)data; - ASSERT(pSubmit->type == STREAM_INPUT__DATA_SUBMIT); - - qSetStreamInput(exec, pSubmit->data, STREAM_DATA_TYPE_SUBMIT_BLOCK, false); - } else if (pTask->inputType == STREAM_INPUT__DATA_BLOCK) { - SStreamDataBlock* pBlock = (SStreamDataBlock*)data; - ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK); - - SArray* blocks = pBlock->blocks; - qSetMultiStreamInput(exec, blocks->pData, blocks->size, STREAM_DATA_TYPE_SSDATA_BLOCK, false); - } - - // exec - while (1) { - SSDataBlock* output = NULL; - uint64_t ts = 0; - if (qExecTask(exec, &output, &ts) < 0) { - ASSERT(false); - } - if (output == NULL) break; - // TODO: do we need free memory? - SSDataBlock* outputCopy = createOneDataBlock(output, true); - taosArrayPush(pRes, outputCopy); - } - - // destroy - if (pTask->inputType == STREAM_INPUT__DATA_SUBMIT) { - streamDataSubmitRefDec((SStreamDataSubmit*)data); - taosFreeQitem(data); - } else { - taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)tDeleteSSDataBlock); - taosFreeQitem(data); - } - return 0; -} - -static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { - while (1) { - void* data = NULL; - taosGetQitem(pTask->inputQAll, &data); - if (data == NULL) break; - - streamTaskExecImpl(pTask, data, pRes); - - if (taosArrayGetSize(pRes) != 0) { - SStreamDataBlock* qRes = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM); - qRes->type = STREAM_INPUT__DATA_BLOCK; - qRes->blocks = pRes; - taosWriteQitem(pTask->outputQ, qRes); - return taosArrayInit(0, sizeof(SSDataBlock)); - } - } - return pRes; -} - -// TODO: handle version -int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb) { - SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock)); - if (pRes == NULL) return -1; - while (1) { - int8_t execStatus = atomic_val_compare_exchange_8(&pTask->status, TASK_STATUS__IDLE, TASK_STATUS__EXECUTING); - if (execStatus == TASK_STATUS__IDLE) { - // first run, from qall, handle failure from last exec - pRes = streamExecForQall(pTask, pRes); - if (pRes == NULL) goto FAIL; - - // second run, from inputQ - taosReadAllQitems(pTask->inputQ, pTask->inputQAll); - pRes = streamExecForQall(pTask, pRes); - if (pRes == NULL) goto FAIL; - - // set status closing - atomic_store_8(&pTask->status, TASK_STATUS__CLOSING); - - // third run, make sure inputQ and qall are cleared - taosReadAllQitems(pTask->inputQ, pTask->inputQAll); - pRes = streamExecForQall(pTask, pRes); - if (pRes == NULL) goto FAIL; - - atomic_store_8(&pTask->status, TASK_STATUS__IDLE); - break; - } else if (execStatus == TASK_STATUS__CLOSING) { - continue; - } else if (execStatus == TASK_STATUS__EXECUTING) { - break; - } else { - ASSERT(0); - } - } - return 0; -FAIL: - atomic_store_8(&pTask->status, TASK_STATUS__IDLE); - return -1; -} - -int32_t streamSink(SStreamTask* pTask, SMsgCb* pMsgCb) { - bool firstRun = 1; - while (1) { - SStreamDataBlock* pBlock = NULL; - if (!firstRun) { - taosReadAllQitems(pTask->outputQ, pTask->outputQAll); - } - taosGetQitem(pTask->outputQAll, (void**)&pBlock); - if (pBlock == NULL) { - if (firstRun) { - firstRun = 0; - continue; - } else { - break; - } - } - - SArray* pRes = pBlock->blocks; - - // sink - if (pTask->sinkType == TASK_SINK__TABLE) { - // blockDebugShowData(pRes); - pTask->tbSink.tbSinkFunc(pTask, pTask->tbSink.vnode, 0, pRes); - } else if (pTask->sinkType == TASK_SINK__SMA) { - pTask->smaSink.smaSink(pTask->ahandle, pTask->smaSink.smaId, pRes); - // - } else if (pTask->sinkType == TASK_SINK__FETCH) { - // - } else { - ASSERT(pTask->sinkType == TASK_SINK__NONE); - } - - // dispatch - // TODO dispatch guard - int8_t outputStatus = atomic_load_8(&pTask->outputStatus); - if (outputStatus == TASK_OUTPUT_STATUS__NORMAL) { - if (pTask->dispatchType == TASK_DISPATCH__INPLACE) { - SRpcMsg dispatchMsg = {0}; - if (streamBuildExecMsg(pTask, pRes, &dispatchMsg, NULL) < 0) { - ASSERT(0); - return -1; - } - - int32_t qType; - if (pTask->dispatchMsgType == TDMT_VND_TASK_DISPATCH || pTask->dispatchMsgType == TDMT_SND_TASK_DISPATCH) { - qType = FETCH_QUEUE; - /*} else if (pTask->dispatchMsgType == TDMT_VND_TASK_MERGE_EXEC ||*/ - /*pTask->dispatchMsgType == TDMT_SND_TASK_MERGE_EXEC) {*/ - /*qType = MERGE_QUEUE;*/ - /*} else if (pTask->dispatchMsgType == TDMT_VND_TASK_WRITE_EXEC) {*/ - /*qType = WRITE_QUEUE;*/ - } else { - ASSERT(0); - } - tmsgPutToQueue(pMsgCb, qType, &dispatchMsg); - - } else if (pTask->dispatchType == TASK_DISPATCH__FIXED) { - SRpcMsg dispatchMsg = {0}; - SEpSet* pEpSet = NULL; - if (streamBuildExecMsg(pTask, pRes, &dispatchMsg, &pEpSet) < 0) { - ASSERT(0); - return -1; - } - - tmsgSendReq(pEpSet, &dispatchMsg); - - } else if (pTask->dispatchType == TASK_DISPATCH__SHUFFLE) { - SHashObj* pShuffleRes = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK); - if (pShuffleRes == NULL) { - return -1; - } - - int32_t sz = taosArrayGetSize(pRes); - for (int32_t i = 0; i < sz; i++) { - SSDataBlock* pDataBlock = taosArrayGet(pRes, i); - SArray* pArray = taosHashGet(pShuffleRes, &pDataBlock->info.groupId, sizeof(int64_t)); - if (pArray == NULL) { - pArray = taosArrayInit(0, sizeof(SSDataBlock)); - if (pArray == NULL) { - return -1; - } - taosHashPut(pShuffleRes, &pDataBlock->info.groupId, sizeof(int64_t), &pArray, sizeof(void*)); - } - taosArrayPush(pArray, pDataBlock); - } - - if (streamShuffleDispatch(pTask, pMsgCb, pShuffleRes) < 0) { - return -1; - } - - } else { - ASSERT(pTask->dispatchType == TASK_DISPATCH__NONE); - } - } - } - return 0; -} - -int32_t streamTaskEnqueue(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp) { - SStreamDataBlock* pBlock = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM); - int8_t status; - - // 1.1 update status - // TODO cal backpressure - if (pBlock == NULL) { - atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__FAILED); - status = TASK_INPUT_STATUS__FAILED; - } else { - status = atomic_load_8(&pTask->inputStatus); - } - - // 1.2 enqueue - pBlock->type = STREAM_DATA_TYPE_SSDATA_BLOCK; - pBlock->sourceVg = pReq->sourceVg; - /*pBlock->sourceVer = pReq->sourceVer;*/ - taosWriteQitem(pTask->inputQ, pBlock); - - // 1.3 rsp by input status - SStreamDispatchRsp* pCont = rpcMallocCont(sizeof(SStreamDispatchRsp)); - pCont->inputStatus = status; - pCont->streamId = pReq->streamId; - pCont->taskId = pReq->sourceTaskId; - pRsp->pCont = pCont; - pRsp->contLen = sizeof(SStreamDispatchRsp); - tmsgSendRsp(pRsp); - - return 0; -} - -int32_t streamProcessDispatchReq(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchReq* pReq, SRpcMsg* pRsp) { - // 1. handle input - streamTaskEnqueue(pTask, pReq, pRsp); - - // 2. try exec - // 2.1. idle: exec - // 2.2. executing: return - // 2.3. closing: keep trying - streamExec(pTask, pMsgCb); - - // 3. handle output - // 3.1 check and set status - // 3.2 dispatch / sink - streamSink(pTask, pMsgCb); - - return 0; -} - -int32_t streamProcessDispatchRsp(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchRsp* pRsp) { - atomic_store_8(&pTask->inputStatus, pRsp->inputStatus); - if (pRsp->inputStatus == TASK_INPUT_STATUS__BLOCKED) { - // TODO: init recover timer - } - // continue dispatch - streamSink(pTask, pMsgCb); - return 0; -} - -int32_t streamTaskProcessRunReq(SStreamTask* pTask, SMsgCb* pMsgCb) { - streamExec(pTask, pMsgCb); - streamSink(pTask, pMsgCb); - return 0; -} - -int32_t streamProcessRecoverReq(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamTaskRecoverReq* pReq, SRpcMsg* pMsg) { - // - return 0; -} - -int32_t streamProcessRecoverRsp(SStreamTask* pTask, SStreamTaskRecoverRsp* pRsp) { - // - return 0; -} - -int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatchReq* pReq) { - if (tStartEncode(pEncoder) < 0) return -1; - if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1; - if (tEncodeI32(pEncoder, pReq->taskId) < 0) return -1; - if (tEncodeI32(pEncoder, pReq->sourceTaskId) < 0) return -1; - if (tEncodeI32(pEncoder, pReq->sourceVg) < 0) return -1; - tEndEncode(pEncoder); - return 0; -} - -int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { - if (tStartDecode(pDecoder) < 0) return -1; - if (tDecodeI64(pDecoder, &pReq->streamId) < 0) return -1; - if (tDecodeI32(pDecoder, &pReq->taskId) < 0) return -1; - if (tDecodeI32(pDecoder, &pReq->sourceTaskId) < 0) return -1; - if (tDecodeI32(pDecoder, &pReq->sourceVg) < 0) return -1; - tEndDecode(pDecoder); - return 0; -} - -int32_t tEncodeSStreamTaskExecReq(void** buf, const SStreamTaskExecReq* pReq) { - int32_t tlen = 0; - tlen += taosEncodeFixedI64(buf, pReq->streamId); - tlen += taosEncodeFixedI32(buf, pReq->taskId); - tlen += tEncodeDataBlocks(buf, pReq->data); - return tlen; -} - -void* tDecodeSStreamTaskExecReq(const void* buf, SStreamTaskExecReq* pReq) { - buf = taosDecodeFixedI64(buf, &pReq->streamId); - buf = taosDecodeFixedI32(buf, &pReq->taskId); - buf = tDecodeDataBlocks(buf, &pReq->data); - return (void*)buf; -} - -void tFreeSStreamTaskExecReq(SStreamTaskExecReq* pReq) { taosArrayDestroy(pReq->data); } - -SStreamTask* tNewSStreamTask(int64_t streamId) { - SStreamTask* pTask = (SStreamTask*)taosMemoryCalloc(1, sizeof(SStreamTask)); - if (pTask == NULL) { - return NULL; - } - pTask->taskId = tGenIdPI32(); - pTask->streamId = streamId; - pTask->status = TASK_STATUS__IDLE; - - return pTask; -} - -int32_t tEncodeSStreamTask(SEncoder* pEncoder, const SStreamTask* pTask) { - /*if (tStartEncode(pEncoder) < 0) return -1;*/ - if (tEncodeI64(pEncoder, pTask->streamId) < 0) return -1; - if (tEncodeI32(pEncoder, pTask->taskId) < 0) return -1; - if (tEncodeI8(pEncoder, pTask->inputType) < 0) return -1; - if (tEncodeI8(pEncoder, pTask->status) < 0) return -1; - if (tEncodeI8(pEncoder, pTask->sourceType) < 0) return -1; - if (tEncodeI8(pEncoder, pTask->execType) < 0) return -1; - if (tEncodeI8(pEncoder, pTask->sinkType) < 0) return -1; - if (tEncodeI8(pEncoder, pTask->dispatchType) < 0) return -1; - if (tEncodeI16(pEncoder, pTask->dispatchMsgType) < 0) return -1; - - if (tEncodeI32(pEncoder, pTask->nodeId) < 0) return -1; - if (tEncodeSEpSet(pEncoder, &pTask->epSet) < 0) return -1; - - if (pTask->execType != TASK_EXEC__NONE) { - if (tEncodeI8(pEncoder, pTask->exec.parallelizable) < 0) return -1; - if (tEncodeCStr(pEncoder, pTask->exec.qmsg) < 0) return -1; - } - - if (pTask->sinkType == TASK_SINK__TABLE) { - if (tEncodeI64(pEncoder, pTask->tbSink.stbUid) < 0) return -1; - if (tEncodeCStr(pEncoder, pTask->tbSink.stbFullName) < 0) return -1; - if (tEncodeSSchemaWrapper(pEncoder, pTask->tbSink.pSchemaWrapper) < 0) return -1; - } else if (pTask->sinkType == TASK_SINK__SMA) { - if (tEncodeI64(pEncoder, pTask->smaSink.smaId) < 0) return -1; - } else if (pTask->sinkType == TASK_SINK__FETCH) { - if (tEncodeI8(pEncoder, pTask->fetchSink.reserved) < 0) return -1; - } else { - ASSERT(pTask->sinkType == TASK_SINK__NONE); - } - - if (pTask->dispatchType == TASK_DISPATCH__INPLACE) { - if (tEncodeI32(pEncoder, pTask->inplaceDispatcher.taskId) < 0) return -1; - } else if (pTask->dispatchType == TASK_DISPATCH__FIXED) { - if (tEncodeI32(pEncoder, pTask->fixedEpDispatcher.taskId) < 0) return -1; - if (tEncodeI32(pEncoder, pTask->fixedEpDispatcher.nodeId) < 0) return -1; - if (tEncodeSEpSet(pEncoder, &pTask->fixedEpDispatcher.epSet) < 0) return -1; - } else if (pTask->dispatchType == TASK_DISPATCH__SHUFFLE) { - if (tSerializeSUseDbRspImp(pEncoder, &pTask->shuffleDispatcher.dbInfo) < 0) return -1; - /*if (tEncodeI8(pEncoder, pTask->shuffleDispatcher.hashMethod) < 0) return -1;*/ - } - - /*tEndEncode(pEncoder);*/ - return pEncoder->pos; -} - -int32_t tDecodeSStreamTask(SDecoder* pDecoder, SStreamTask* pTask) { - /*if (tStartDecode(pDecoder) < 0) return -1;*/ - if (tDecodeI64(pDecoder, &pTask->streamId) < 0) return -1; - if (tDecodeI32(pDecoder, &pTask->taskId) < 0) return -1; - if (tDecodeI8(pDecoder, &pTask->inputType) < 0) return -1; - if (tDecodeI8(pDecoder, &pTask->status) < 0) return -1; - if (tDecodeI8(pDecoder, &pTask->sourceType) < 0) return -1; - if (tDecodeI8(pDecoder, &pTask->execType) < 0) return -1; - if (tDecodeI8(pDecoder, &pTask->sinkType) < 0) return -1; - if (tDecodeI8(pDecoder, &pTask->dispatchType) < 0) return -1; - if (tDecodeI16(pDecoder, &pTask->dispatchMsgType) < 0) return -1; - - if (tDecodeI32(pDecoder, &pTask->nodeId) < 0) return -1; - if (tDecodeSEpSet(pDecoder, &pTask->epSet) < 0) return -1; - - if (pTask->execType != TASK_EXEC__NONE) { - if (tDecodeI8(pDecoder, &pTask->exec.parallelizable) < 0) return -1; - if (tDecodeCStrAlloc(pDecoder, &pTask->exec.qmsg) < 0) return -1; - } - - if (pTask->sinkType == TASK_SINK__TABLE) { - if (tDecodeI64(pDecoder, &pTask->tbSink.stbUid) < 0) return -1; - if (tDecodeCStrTo(pDecoder, pTask->tbSink.stbFullName) < 0) return -1; - pTask->tbSink.pSchemaWrapper = taosMemoryCalloc(1, sizeof(SSchemaWrapper)); - if (pTask->tbSink.pSchemaWrapper == NULL) return -1; - if (tDecodeSSchemaWrapper(pDecoder, pTask->tbSink.pSchemaWrapper) < 0) return -1; - } else if (pTask->sinkType == TASK_SINK__SMA) { - if (tDecodeI64(pDecoder, &pTask->smaSink.smaId) < 0) return -1; - } else if (pTask->sinkType == TASK_SINK__FETCH) { - if (tDecodeI8(pDecoder, &pTask->fetchSink.reserved) < 0) return -1; - } else { - ASSERT(pTask->sinkType == TASK_SINK__NONE); - } - - if (pTask->dispatchType == TASK_DISPATCH__INPLACE) { - if (tDecodeI32(pDecoder, &pTask->inplaceDispatcher.taskId) < 0) return -1; - } else if (pTask->dispatchType == TASK_DISPATCH__FIXED) { - if (tDecodeI32(pDecoder, &pTask->fixedEpDispatcher.taskId) < 0) return -1; - if (tDecodeI32(pDecoder, &pTask->fixedEpDispatcher.nodeId) < 0) return -1; - if (tDecodeSEpSet(pDecoder, &pTask->fixedEpDispatcher.epSet) < 0) return -1; - } else if (pTask->dispatchType == TASK_DISPATCH__SHUFFLE) { - /*if (tDecodeI8(pDecoder, &pTask->shuffleDispatcher.hashMethod) < 0) return -1;*/ - if (tDeserializeSUseDbRspImp(pDecoder, &pTask->shuffleDispatcher.dbInfo) < 0) return -1; - } - - /*tEndDecode(pDecoder);*/ - return 0; -} - -void tFreeSStreamTask(SStreamTask* pTask) { - taosCloseQueue(pTask->inputQ); - taosCloseQueue(pTask->outputQ); - // TODO - if (pTask->exec.qmsg) taosMemoryFree(pTask->exec.qmsg); - qDestroyTask(pTask->exec.executor); - taosMemoryFree(pTask); -} - -#if 0 -int32_t tEncodeSStreamTaskExecReq(SCoder* pEncoder, const SStreamTaskExecReq* pReq) { - if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1; - if (tEncodeI32(pEncoder, pReq->taskId) < 0) return -1; - /*if (tEncodeDataBlocks(buf, pReq->streamId) < 0) return -1;*/ - return pEncoder->size; -} -int32_t tDecodeSStreamTaskExecReq(SCoder* pDecoder, SStreamTaskExecReq* pReq) { - return pEncoder->size; -} -void tFreeSStreamTaskExecReq(SStreamTaskExecReq* pReq) { - taosArrayDestroyEx(pReq->data, tDeleteSSDataBlock); -} -#endif diff --git a/source/util/src/tqueue.c b/source/util/src/tqueue.c index 37935087fa..94311bc435 100644 --- a/source/util/src/tqueue.c +++ b/source/util/src/tqueue.c @@ -34,11 +34,11 @@ typedef struct STaosQnode { } STaosQnode; typedef struct STaosQueue { - STaosQnode * head; - STaosQnode * tail; - STaosQueue * next; // for queue set - STaosQset * qset; // for queue set - void * ahandle; // for queue set + STaosQnode *head; + STaosQnode *tail; + STaosQueue *next; // for queue set + STaosQset *qset; // for queue set + void *ahandle; // for queue set FItem itemFp; FItems itemsFp; TdThreadMutex mutex; @@ -47,8 +47,8 @@ typedef struct STaosQueue { } STaosQueue; typedef struct STaosQset { - STaosQueue * head; - STaosQueue * current; + STaosQueue *head; + STaosQueue *current; TdThreadMutex mutex; tsem_t sem; int32_t numOfQueues; @@ -86,7 +86,7 @@ void taosSetQueueFp(STaosQueue *queue, FItem itemFp, FItems itemsFp) { void taosCloseQueue(STaosQueue *queue) { if (queue == NULL) return; STaosQnode *pTemp; - STaosQset * qset; + STaosQset *qset; taosThreadMutexLock(&queue->mutex); STaosQnode *pNode = queue->head; @@ -282,6 +282,8 @@ int32_t taosGetQitem(STaosQall *qall, void **ppItem) { *ppItem = pNode->item; num = 1; uTrace("item:%p is fetched", *ppItem); + } else { + *ppItem = NULL; } return num; From 26d2c9e63d105334d4bb4acc435cb3b770a17731 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Mon, 6 Jun 2022 20:19:04 +0800 Subject: [PATCH 21/26] fix: top function with order by clause --- source/libs/planner/test/planTestUtil.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/libs/planner/test/planTestUtil.cpp b/source/libs/planner/test/planTestUtil.cpp index 84c46cb9bb..f5c8b58e43 100644 --- a/source/libs/planner/test/planTestUtil.cpp +++ b/source/libs/planner/test/planTestUtil.cpp @@ -190,6 +190,8 @@ class PlannerTestBaseImpl { string acctId_; string db_; int32_t nsql_; + + caseEnv() : nsql_(0) {} }; struct stmtEnv { @@ -197,6 +199,7 @@ class PlannerTestBaseImpl { array msgBuf_; SQuery* pQuery_; + stmtEnv() : pQuery_(nullptr) {} ~stmtEnv() { qDestroyQuery(pQuery_); } }; From a59f40dde248c215c7b28a591e8387a70ca7aca9 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 6 Jun 2022 20:48:16 +0800 Subject: [PATCH 22/26] fix(query): check array length before generating the retention string . --- source/dnode/mnode/impl/src/mndDb.c | 30 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index 1ce1a2590a..245089ddb7 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -1497,20 +1497,26 @@ char *buildRetension(SArray *pRetension) { int64_t v1 = getValOfDiffPrecision(p->freqUnit, p->freq); int64_t v2 = getValOfDiffPrecision(p->keepUnit, p->keep); - len += sprintf(p1 + len, "%" PRId64 "%c:%" PRId64 "%c,", v1, p->freqUnit, v2, p->keepUnit); - - p = taosArrayGet(pRetension, 1); - - v1 = getValOfDiffPrecision(p->freqUnit, p->freq); - v2 = getValOfDiffPrecision(p->keepUnit, p->keep); - len += sprintf(p1 + len, "%" PRId64 "%c:%" PRId64 "%c,", v1, p->freqUnit, v2, p->keepUnit); - - p = taosArrayGet(pRetension, 2); - - v1 = getValOfDiffPrecision(p->freqUnit, p->freq); - v2 = getValOfDiffPrecision(p->keepUnit, p->keep); len += sprintf(p1 + len, "%" PRId64 "%c:%" PRId64 "%c", v1, p->freqUnit, v2, p->keepUnit); + if (size > 1) { + len += sprintf(p1 + len, ","); + p = taosArrayGet(pRetension, 1); + + v1 = getValOfDiffPrecision(p->freqUnit, p->freq); + v2 = getValOfDiffPrecision(p->keepUnit, p->keep); + len += sprintf(p1 + len, "%" PRId64 "%c:%" PRId64 "%c", v1, p->freqUnit, v2, p->keepUnit); + } + + if (size > 2) { + len += sprintf(p1 + len, ","); + p = taosArrayGet(pRetension, 2); + + v1 = getValOfDiffPrecision(p->freqUnit, p->freq); + v2 = getValOfDiffPrecision(p->keepUnit, p->keep); + len += sprintf(p1 + len, "%" PRId64 "%c:%" PRId64 "%c", v1, p->freqUnit, v2, p->keepUnit); + } + varDataSetLen(p1, len); return p1; } From 6c719eef5eb689f813367581e347ce3889b42d87 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Mon, 6 Jun 2022 20:56:40 +0800 Subject: [PATCH 23/26] fix vnode get table meta issue --- source/libs/catalog/inc/catalogInt.h | 1 + source/libs/catalog/src/ctgAsync.c | 115 +++++++++++++++++++++++---- source/libs/catalog/src/ctgRemote.c | 2 +- source/libs/catalog/src/ctgUtil.c | 28 +++++++ source/libs/qcom/src/querymsg.c | 4 + 5 files changed, 133 insertions(+), 17 deletions(-) diff --git a/source/libs/catalog/inc/catalogInt.h b/source/libs/catalog/inc/catalogInt.h index 9219a382e4..1eec92f47e 100644 --- a/source/libs/catalog/inc/catalogInt.h +++ b/source/libs/catalog/inc/catalogInt.h @@ -518,6 +518,7 @@ int32_t ctgStbVersionSearchCompare(const void* key1, const void* key2); int32_t ctgDbVgVersionSearchCompare(const void* key1, const void* key2); void ctgFreeSTableMetaOutput(STableMetaOutput* pOutput); int32_t ctgUpdateMsgCtx(SCtgMsgCtx* pCtx, int32_t reqType, void* out, char* target); +char *ctgTaskTypeStr(CTG_TASK_TYPE type); extern SCatalogMgmt gCtgMgmt; diff --git a/source/libs/catalog/src/ctgAsync.c b/source/libs/catalog/src/ctgAsync.c index 5eaccab004..f43e559244 100644 --- a/source/libs/catalog/src/ctgAsync.c +++ b/source/libs/catalog/src/ctgAsync.c @@ -44,7 +44,7 @@ int32_t ctgInitGetTbMetaTask(SCtgJob *pJob, int32_t taskIdx, SName *name) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " task %d type %d initialized, tableName:%s", pJob->queryId, taskIdx, task.type, name->tname); + qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, tableName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name->tname); return TSDB_CODE_SUCCESS; } @@ -67,7 +67,7 @@ int32_t ctgInitGetDbVgTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " task %d type %d initialized, dbFName:%s", pJob->queryId, taskIdx, task.type, dbFName); + qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, dbFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), dbFName); return TSDB_CODE_SUCCESS; } @@ -90,7 +90,7 @@ int32_t ctgInitGetDbCfgTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " task %d type %d initialized, dbFName:%s", pJob->queryId, taskIdx, task.type, dbFName); + qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, dbFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), dbFName); return TSDB_CODE_SUCCESS; } @@ -113,7 +113,7 @@ int32_t ctgInitGetDbInfoTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " task %d type %d initialized, dbFName:%s", pJob->queryId, taskIdx, task.type, dbFName); + qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, dbFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), dbFName); return TSDB_CODE_SUCCESS; } @@ -143,7 +143,7 @@ int32_t ctgInitGetTbHashTask(SCtgJob *pJob, int32_t taskIdx, SName *name) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " task %d type %d initialized, tableName:%s", pJob->queryId, taskIdx, task.type, name->tname); + qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, tableName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name->tname); return TSDB_CODE_SUCCESS; } @@ -158,7 +158,7 @@ int32_t ctgInitGetQnodeTask(SCtgJob *pJob, int32_t taskIdx) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:%" PRIx64 " task %d type %d initialized", pJob->queryId, taskIdx, task.type); + qDebug("QID:%" PRIx64 " the %d task type %s initialized", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type)); return TSDB_CODE_SUCCESS; } @@ -181,7 +181,7 @@ int32_t ctgInitGetIndexTask(SCtgJob *pJob, int32_t taskIdx, char *name) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:%" PRIx64 " task %d type %d initialized, indexFName:%s", pJob->queryId, taskIdx, task.type, name); + qDebug("QID:%" PRIx64 " the %d task type %s initialized, indexFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name); return TSDB_CODE_SUCCESS; } @@ -204,7 +204,7 @@ int32_t ctgInitGetUdfTask(SCtgJob *pJob, int32_t taskIdx, char *name) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:%" PRIx64 " task %d type %d initialized, udfName:%s", pJob->queryId, taskIdx, task.type, name); + qDebug("QID:%" PRIx64 " the %d task type %s initialized, udfName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name); return TSDB_CODE_SUCCESS; } @@ -227,11 +227,96 @@ int32_t ctgInitGetUserTask(SCtgJob *pJob, int32_t taskIdx, SUserAuthInfo *user) taosArrayPush(pJob->pTasks, &task); - qDebug("QID:%" PRIx64 " task %d type %d initialized, user:%s", pJob->queryId, taskIdx, task.type, user->user); + qDebug("QID:%" PRIx64 " the %d task type %s initialized, user:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), user->user); return TSDB_CODE_SUCCESS; } +int32_t ctgHandleForceUpdate(SCatalog* pCtg, SCtgJob *pJob, const SCatalogReq* pReq) { + int32_t dbNum = pJob->dbCfgNum + pJob->dbVgNum + pJob->dbInfoNum; + if (dbNum > 0) { + if (dbNum > pJob->dbCfgNum && dbNum > pJob->dbVgNum && dbNum > pJob->dbInfoNum) { + SHashObj* pDb = taosHashInit(dbNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); + if (NULL == pDb) { + CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY); + } + + for (int32_t i = 0; i < pJob->dbVgNum; ++i) { + char* dbFName = taosArrayGet(pReq->pDbVgroup, i); + taosHashPut(pDb, dbFName, strlen(dbFName), dbFName, TSDB_DB_FNAME_LEN); + } + + for (int32_t i = 0; i < pJob->dbCfgNum; ++i) { + char* dbFName = taosArrayGet(pReq->pDbCfg, i); + taosHashPut(pDb, dbFName, strlen(dbFName), dbFName, TSDB_DB_FNAME_LEN); + } + + for (int32_t i = 0; i < pJob->dbInfoNum; ++i) { + char* dbFName = taosArrayGet(pReq->pDbInfo, i); + taosHashPut(pDb, dbFName, strlen(dbFName), dbFName, TSDB_DB_FNAME_LEN); + } + + char* dbFName = taosHashIterate(pDb, NULL); + while (dbFName) { + ctgDropDbVgroupEnqueue(pCtg, dbFName, true); + dbFName = taosHashIterate(pDb, dbFName); + } + + taosHashCleanup(pDb); + } else { + for (int32_t i = 0; i < pJob->dbVgNum; ++i) { + char* dbFName = taosArrayGet(pReq->pDbVgroup, i); + CTG_ERR_RET(ctgDropDbVgroupEnqueue(pCtg, dbFName, true)); + } + + for (int32_t i = 0; i < pJob->dbCfgNum; ++i) { + char* dbFName = taosArrayGet(pReq->pDbCfg, i); + CTG_ERR_RET(ctgDropDbVgroupEnqueue(pCtg, dbFName, true)); + } + + for (int32_t i = 0; i < pJob->dbInfoNum; ++i) { + char* dbFName = taosArrayGet(pReq->pDbInfo, i); + CTG_ERR_RET(ctgDropDbVgroupEnqueue(pCtg, dbFName, true)); + } + } + } + + int32_t tbNum = pJob->tbMetaNum + pJob->tbHashNum; + if (tbNum > 0) { + if (tbNum > pJob->tbMetaNum && tbNum > pJob->tbHashNum) { + SHashObj* pTb = taosHashInit(tbNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); + for (int32_t i = 0; i < pJob->tbMetaNum; ++i) { + SName* name = taosArrayGet(pReq->pTableMeta, i); + taosHashPut(pTb, name, sizeof(SName), name, sizeof(SName)); + } + + for (int32_t i = 0; i < pJob->tbHashNum; ++i) { + SName* name = taosArrayGet(pReq->pTableHash, i); + taosHashPut(pTb, name, sizeof(SName), name, sizeof(SName)); + } + + SName* name = taosHashIterate(pTb, NULL); + while (name) { + catalogRemoveTableMeta(pCtg, name); + name = taosHashIterate(pTb, name); + } + + taosHashCleanup(pTb); + } else { + for (int32_t i = 0; i < pJob->tbMetaNum; ++i) { + SName* name = taosArrayGet(pReq->pTableMeta, i); + catalogRemoveTableMeta(pCtg, name); + } + + for (int32_t i = 0; i < pJob->tbHashNum; ++i) { + SName* name = taosArrayGet(pReq->pTableHash, i); + catalogRemoveTableMeta(pCtg, name); + } + } + } + + return TSDB_CODE_SUCCESS; +} int32_t ctgInitJob(CTG_PARAMS, SCtgJob** job, uint64_t reqId, const SCatalogReq* pReq, catalogCallback fp, void* param, int32_t* taskNum) { int32_t code = 0; @@ -283,12 +368,13 @@ int32_t ctgInitJob(CTG_PARAMS, SCtgJob** job, uint64_t reqId, const SCatalogReq* CTG_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY); } + if (pReq->forceUpdate) { + CTG_ERR_JRET(ctgHandleForceUpdate(pCtg, pJob, pReq)); + } + int32_t taskIdx = 0; for (int32_t i = 0; i < dbVgNum; ++i) { char* dbFName = taosArrayGet(pReq->pDbVgroup, i); - if (pReq->forceUpdate) { - ctgDropDbVgroupEnqueue(pCtg, dbFName, true); - } CTG_ERR_JRET(ctgInitGetDbVgTask(pJob, taskIdx++, dbFName)); } @@ -304,9 +390,6 @@ int32_t ctgInitJob(CTG_PARAMS, SCtgJob** job, uint64_t reqId, const SCatalogReq* for (int32_t i = 0; i < tbMetaNum; ++i) { SName* name = taosArrayGet(pReq->pTableMeta, i); - if (pReq->forceUpdate) { - catalogRemoveTableMeta(pCtg, name); - } CTG_ERR_JRET(ctgInitGetTbMetaTask(pJob, taskIdx++, name)); } @@ -342,7 +425,7 @@ int32_t ctgInitJob(CTG_PARAMS, SCtgJob** job, uint64_t reqId, const SCatalogReq* taosAcquireRef(gCtgMgmt.jobPool, pJob->refId); - qDebug("QID:0x%" PRIx64 ", jobId: 0x%" PRIx64 " initialized, task num %d", pJob->queryId, pJob->refId, *taskNum); + qDebug("QID:0x%" PRIx64 ", jobId: 0x%" PRIx64 " initialized, task num %d, forceUpdate %d", pJob->queryId, pJob->refId, *taskNum, pReq->forceUpdate); return TSDB_CODE_SUCCESS; diff --git a/source/libs/catalog/src/ctgRemote.c b/source/libs/catalog/src/ctgRemote.c index 8f3d498440..188f5b44c0 100644 --- a/source/libs/catalog/src/ctgRemote.c +++ b/source/libs/catalog/src/ctgRemote.c @@ -565,7 +565,7 @@ int32_t ctgGetTbMetaFromVnode(CTG_PARAMS, const SName* pTableName, SVgroupInfo * } CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, pOut, tbFName)); - CTG_RET(ctgAsyncSendMsg(CTG_PARAMS_LIST(), pTask, reqType, msg, msgLen)); + CTG_RET(ctgAsyncSendMsg(pCtg, pTrans, &vgroupInfo->epSet, pTask, reqType, msg, msgLen)); } SRpcMsg rpcMsg = { diff --git a/source/libs/catalog/src/ctgUtil.c b/source/libs/catalog/src/ctgUtil.c index 4625203dd8..962edf9af1 100644 --- a/source/libs/catalog/src/ctgUtil.c +++ b/source/libs/catalog/src/ctgUtil.c @@ -19,6 +19,31 @@ #include "catalogInt.h" #include "systable.h" +char *ctgTaskTypeStr(CTG_TASK_TYPE type) { + switch (type) { + case CTG_TASK_GET_QNODE: + return "[get qnode list]"; + case CTG_TASK_GET_DB_VGROUP: + return "[get db vgroup]"; + case CTG_TASK_GET_DB_CFG: + return "[get db cfg]"; + case CTG_TASK_GET_DB_INFO: + return "[get db info]"; + case CTG_TASK_GET_TB_META: + return "[get table meta]"; + case CTG_TASK_GET_TB_HASH: + return "[get table hash]"; + case CTG_TASK_GET_INDEX: + return "[get index]"; + case CTG_TASK_GET_UDF: + return "[get udf]"; + case CTG_TASK_GET_USER: + return "[get user]"; + default: + return "unknown"; + } +} + void ctgFreeSMetaData(SMetaData* pData) { taosArrayDestroy(pData->pTableMeta); pData->pTableMeta = NULL; @@ -477,6 +502,9 @@ int32_t ctgGetVgInfoFromHashValue(SCatalog *pCtg, SDBVgInfo *dbInfo, const SName *pVgroup = *vgInfo; + ctgDebug("Got tb %s hash vgroup, vgId %d, epNum %d, current %s port %d", tbFullName, vgInfo->vgId, vgInfo->epSet.numOfEps, + vgInfo->epSet.eps[vgInfo->epSet.inUse].fqdn, vgInfo->epSet.eps[vgInfo->epSet.inUse].port); + CTG_RET(code); } diff --git a/source/libs/qcom/src/querymsg.c b/source/libs/qcom/src/querymsg.c index e77f2b0ca4..949a58c2fa 100644 --- a/source/libs/qcom/src/querymsg.c +++ b/source/libs/qcom/src/querymsg.c @@ -37,6 +37,8 @@ int32_t queryBuildUseDbOutput(SUseDbOutput *pOut, SUseDbRsp *usedbRsp) { pOut->dbVgroup->vgVersion = usedbRsp->vgVersion; pOut->dbVgroup->hashMethod = usedbRsp->hashMethod; + qDebug("Got %d vgroup for db %s", usedbRsp->vgNum, usedbRsp->db); + if (usedbRsp->vgNum <= 0) { return TSDB_CODE_SUCCESS; } @@ -50,6 +52,8 @@ int32_t queryBuildUseDbOutput(SUseDbOutput *pOut, SUseDbRsp *usedbRsp) { for (int32_t i = 0; i < usedbRsp->vgNum; ++i) { SVgroupInfo *pVgInfo = taosArrayGet(usedbRsp->pVgroupInfos, i); pOut->dbVgroup->numOfTable += pVgInfo->numOfTable; + qDebug("the %dth vgroup, id %d, epNum %d, current %s port %d", i, pVgInfo->vgId, pVgInfo->epSet.numOfEps, + pVgInfo->epSet.eps[pVgInfo->epSet.inUse].fqdn, pVgInfo->epSet.eps[pVgInfo->epSet.inUse].port); if (0 != taosHashPut(pOut->dbVgroup->vgHash, &pVgInfo->vgId, sizeof(int32_t), pVgInfo, sizeof(SVgroupInfo))) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } From 97f954c61f33330e087c43871210f225699e497e Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Mon, 6 Jun 2022 21:00:37 +0800 Subject: [PATCH 24/26] feat: balance vgroup --- include/util/taoserror.h | 1 + source/dnode/mnode/impl/src/mndVgroup.c | 158 +++++++++++++++++++++++- source/util/src/terror.c | 4 +- 3 files changed, 161 insertions(+), 2 deletions(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 17851bc4a8..842c8a44e1 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -219,6 +219,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_MND_VGROUP_NOT_IN_DNODE TAOS_DEF_ERROR_CODE(0, 0x0391) #define TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE TAOS_DEF_ERROR_CODE(0, 0x0392) #define TSDB_CODE_MND_VGROUP_UN_CHANGED TAOS_DEF_ERROR_CODE(0, 0x0393) +#define TSDB_CODE_MND_HAS_OFFLINE_DNODE TAOS_DEF_ERROR_CODE(0, 0x0394) // mnode-stable #define TSDB_CODE_MND_STB_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x03A0) diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index d8f2dae234..5244bc657b 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -38,6 +38,7 @@ static void mndCancelGetNextVnode(SMnode *pMnode, void *pIter); static int32_t mndProcessRedistributeVgroupMsg(SRpcMsg *pReq); static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq); +static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq); int32_t mndInitVgroup(SMnode *pMnode) { SSdbTable table = { @@ -1165,4 +1166,159 @@ _OVER: return code; } -static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) { return 0; } \ No newline at end of file +static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) { return 0; } + +static int32_t mndSetBalanceVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, + SDnodeObj *pSrc, SDnodeObj *pDst) { + SVgObj newVg = {0}; + memcpy(&newVg, pVgroup, sizeof(SVgObj)); + mInfo("vgId:%d, vgroup info before balance, replica:%d", newVg.vgId, newVg.replica); + for (int32_t i = 0; i < newVg.replica; ++i) { + mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId); + } + + if (mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pDst->id) != 0) return -1; + if (mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pSrc->id) != 0) return -1; + + SSdbRaw *pRaw = mndVgroupActionEncode(&newVg); + if (pRaw == NULL || mndTransAppendCommitlog(pTrans, pRaw) != 0) { + sdbFreeRaw(pRaw); + return -1; + } + sdbSetRawStatus(pRaw, SDB_STATUS_READY); + + mInfo("vgId:%d, vgroup info after balance, replica:%d", newVg.vgId, newVg.replica); + for (int32_t i = 0; i < newVg.replica; ++i) { + mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId); + } + return 0; +} + +static int32_t mndBalanceVgroupBetweenDnode(SMnode *pMnode, STrans *pTrans, SDnodeObj *pSrc, SDnodeObj *pDst) { + void *pIter = NULL; + int32_t code = -1; + + while (1) { + SVgObj *pVgroup = NULL; + pIter = sdbFetch(pMnode->pSdb, SDB_VGROUP, pIter, (void **)&pVgroup); + if (pIter == NULL) break; + + bool existInSrc = false; + bool existInDst = false; + for (int32_t i = 0; i < pVgroup->replica; ++i) { + SVnodeGid *pGid = &pVgroup->vnodeGid[i]; + if (pGid->dnodeId == pSrc->id) existInSrc = true; + if (pGid->dnodeId == pDst->id) existInDst = true; + } + + if (!existInSrc || existInDst) { + sdbRelease(pMnode->pSdb, pVgroup); + } + + SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName); + code = mndSetBalanceVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, pSrc, pDst); + mndReleaseDb(pMnode, pDb); + sdbRelease(pMnode->pSdb, pVgroup); + break; + } + + return code; +} + +static int32_t mndBalanceVgroup(SMnode *pMnode, SRpcMsg *pReq, SArray *pArray) { + int32_t code = -1; + int32_t numOfVgroups = 0; + STrans *pTrans = NULL; + + pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq); + if (pTrans == NULL) goto _OVER; + mndTransSetSerial(pTrans); + mDebug("trans:%d, used to balance vgroup", pTrans->id); + + while (1) { + taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes); + SDnodeObj *pSrc = taosArrayGet(pArray, 0); + SDnodeObj *pDst = taosArrayGet(pArray, taosArrayGetSize(pArray) - 1); + + float srcScore = (float)(pSrc->numOfVnodes - 1) / pSrc->numOfSupportVnodes; + float dstScore = (float)(pDst->numOfVnodes + 1) / pDst->numOfSupportVnodes; + if (srcScore + 0.0001 < dstScore) { + mDebug("trans:%d, balance vgroup from dnode:%d to dnode:%d", pTrans->id, pSrc->id, pDst->id); + code = mndBalanceVgroupBetweenDnode(pMnode, pTrans, pSrc, pDst); + if (code == 0) { + numOfVgroups++; + continue; + } else { + mError("trans:%d, failed to balance vgroup from dnode:%d to dnode:%d", pTrans->id, pSrc->id, pDst->id); + return -1; + } + } else { + mDebug("trans:%d, no vgroup need to balance vgroup any more", pTrans->id); + break; + } + } + + if (numOfVgroups <= 0) { + mDebug("no need to balance vgroup"); + code = 0; + } else { + mDebug("start to balance vgroup, numOfVgroups:%d", numOfVgroups); + if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; + code = TSDB_CODE_ACTION_IN_PROGRESS; + } + +_OVER: + mndTransDrop(pTrans); + return code; +} + +static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq) { + SMnode *pMnode = pReq->info.node; + int32_t code = -1; + SUserObj *pUser = NULL; + SArray *pArray = NULL; + void *pIter = NULL; + int64_t curMs = taosGetTimestampMs(); + + mDebug("start to balance vgroup"); + pUser = mndAcquireUser(pMnode, pReq->conn.user); + if (pUser == NULL) { + terrno = TSDB_CODE_MND_NO_USER_FROM_CONN; + goto _OVER; + } + + if (mndCheckNodeAuth(pUser) != 0) goto _OVER; + + while (1) { + SDnodeObj *pDnode = NULL; + pIter = sdbFetch(pMnode->pSdb, SDB_DNODE, pIter, (void **)&pDnode); + if (pIter == NULL) break; + if (!mndIsDnodeOnline(pDnode, curMs)) { + terrno = TSDB_CODE_MND_HAS_OFFLINE_DNODE; + mError("failed to balance vgroup since %s, dnode:%d", terrstr(), pDnode->id); + sdbRelease(pMnode->pSdb, pDnode); + goto _OVER; + } + + sdbRelease(pMnode->pSdb, pDnode); + } + + pArray = mndBuildDnodesArray(pMnode, 0); + if (pArray == NULL) goto _OVER; + + if (taosArrayGetSize(pArray) < 2) { + mDebug("no need to balance vgroup since dnode num less than 2"); + code = 0; + } else { + code = mndBalanceVgroup(pMnode, pReq, pArray); + } + +_OVER: + if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) { + mError("failed to balance vgroup since %s", terrstr()); + } + + mndReleaseUser(pMnode, pUser); + taosArrayDestroy(pArray); + return code; +} \ No newline at end of file diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 8d7bc0851b..c14c279d81 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -222,7 +222,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_INDEX_NOT_EXIST, "Index not exist") // mnode-vgroup TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE, "Vgroup already in dnode") TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_IN_DNODE, "Vgroup not in dnode") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_EXIST, "VGroup does not exist") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_EXIST, "Vgroup does not exist") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_UN_CHANGED, "Vgroup distribution has not changed") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_HAS_OFFLINE_DNODE, "Offline dnode exists") // mnode-stable TAOS_DEFINE_ERROR(TSDB_CODE_MND_STB_ALREADY_EXIST, "STable already exists") From 414d0f2e7596cf6a8c00ffecf73dc91a9c06f6f9 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 6 Jun 2022 22:12:57 +0800 Subject: [PATCH 25/26] fix: failed to update json idx --- source/libs/index/inc/indexInt.h | 2 +- source/libs/index/src/indexCache.c | 7 +++++-- source/libs/index/src/indexComm.c | 11 +++++++++-- source/libs/index/src/indexFilter.c | 11 +++++++---- source/libs/index/src/indexTfile.c | 7 +------ source/libs/parser/src/parTokenizer.c | 1 + 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/source/libs/index/inc/indexInt.h b/source/libs/index/inc/indexInt.h index 2cba6a347e..e3f9cb89ec 100644 --- a/source/libs/index/inc/indexInt.h +++ b/source/libs/index/inc/indexInt.h @@ -43,7 +43,7 @@ extern "C" { #define indexTrace(...) do { if (idxDebugFlag & DEBUG_TRACE) { taosPrintLog("IDX", DEBUG_TRACE, idxDebugFlag, __VA_ARGS__);} } while (0) // clang-format on -typedef enum { LT, LE, GT, GE } RangeType; +typedef enum { LT, LE, GT, GE, CONTAINS } RangeType; typedef enum { kTypeValue, kTypeDeletion } STermValueType; typedef struct SIndexStat { diff --git a/source/libs/index/src/indexCache.c b/source/libs/index/src/indexCache.c index 4e7be245ef..c1fb086fa0 100644 --- a/source/libs/index/src/indexCache.c +++ b/source/libs/index/src/indexCache.c @@ -90,7 +90,7 @@ static int32_t cacheSearchTerm(void* cache, SIndexTerm* term, SIdxTRslt* tr, STe break; } CacheTerm* c = (CacheTerm*)SL_GET_NODE_DATA(node); - if (0 == strcmp(c->colVal, pCt->colVal)) { + if (0 == strcmp(c->colVal, pCt->colVal) && strlen(pCt->colVal) == strlen(c->colVal)) { if (c->operaType == ADD_VALUE) { INDEX_MERGE_ADD_DEL(tr->del, tr->add, c->uid) // taosArrayPush(result, &c->uid); @@ -222,7 +222,7 @@ static int32_t cacheSearchTerm_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr return TSDB_CODE_SUCCESS; } static int32_t cacheSearchPrefix_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) { - return TSDB_CODE_SUCCESS; + return cacheSearchCompareFunc_JSON(cache, term, tr, s, CONTAINS); } static int32_t cacheSearchSuffix_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) { return TSDB_CODE_SUCCESS; @@ -242,6 +242,9 @@ static int32_t cacheSearchGreaterThan_JSON(void* cache, SIndexTerm* term, SIdxTR static int32_t cacheSearchGreaterEqual_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) { return cacheSearchCompareFunc_JSON(cache, term, tr, s, GE); } +static int32_t cacheSearchContain_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) { + return cacheSearchCompareFunc_JSON(cache, term, tr, s, CONTAINS); +} static int32_t cacheSearchRange_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) { return TSDB_CODE_SUCCESS; } diff --git a/source/libs/index/src/indexComm.c b/source/libs/index/src/indexComm.c index 74b1773e87..d30147d70f 100644 --- a/source/libs/index/src/indexComm.c +++ b/source/libs/index/src/indexComm.c @@ -97,6 +97,11 @@ static TExeCond tCompareGreaterEqual(void* a, void* b, int8_t type) { __compar_fn_t func = indexGetCompar(type); return tCompare(func, QUERY_GREATER_EQUAL, a, b, type); } + +static TExeCond tCompareContains(void* a, void* b, int8_t type) { + __compar_fn_t func = indexGetCompar(type); + return tCompare(func, QUERY_TERM, a, b, type); +} TExeCond tCompare(__compar_fn_t func, int8_t cmptype, void* a, void* b, int8_t dtype) { if (dtype == TSDB_DATA_TYPE_BINARY || dtype == TSDB_DATA_TYPE_NCHAR || dtype == TSDB_DATA_TYPE_VARBINARY) { return tDoCompare(func, cmptype, a, b); @@ -185,12 +190,14 @@ TExeCond tDoCompare(__compar_fn_t func, int8_t comparType, void* a, void* b) { case QUERY_TERM: { if (ret == 0) return MATCH; } + default: + return BREAK; } return CONTINUE; } -static TExeCond (*rangeCompare[])(void* a, void* b, int8_t type) = {tCompareLessThan, tCompareLessEqual, - tCompareGreaterThan, tCompareGreaterEqual}; +static TExeCond (*rangeCompare[])(void* a, void* b, int8_t type) = { + tCompareLessThan, tCompareLessEqual, tCompareGreaterThan, tCompareGreaterEqual, tCompareContains}; _cache_range_compare indexGetCompare(RangeType ty) { return rangeCompare[ty]; } diff --git a/source/libs/index/src/indexFilter.c b/source/libs/index/src/indexFilter.c index 3e29530d3e..02c1c7923f 100644 --- a/source/libs/index/src/indexFilter.c +++ b/source/libs/index/src/indexFilter.c @@ -64,6 +64,8 @@ static int32_t sifGetFuncFromSql(EOperatorType src, EIndexQueryType *dst) { *dst = QUERY_TERM; } else if (src == OP_TYPE_LIKE || src == OP_TYPE_MATCH || src == OP_TYPE_NMATCH) { *dst = QUERY_REGEX; + } else if (src == OP_TYPE_JSON_CONTAINS) { + *dst = QUERY_PREFIX; } else { return TSDB_CODE_QRY_INVALID_INPUT; } @@ -184,6 +186,7 @@ static int32_t sifInitParam(SNode *node, SIFParam *param, SIFCtx *ctx) { SIF_ERR_RET(sifGetValueFromNode(node, ¶m->condValue)); param->colId = -1; param->colValType = (uint8_t)(vn->node.resType.type); + memcpy(param->colName, vn->literal, strlen(vn->literal)); break; } case QUERY_NODE_COLUMN: { @@ -235,7 +238,7 @@ static int32_t sifInitOperParams(SIFParam **params, SOperatorNode *node, SIFCtx indexError("invalid operation node, left: %p, rigth: %p", node->pLeft, node->pRight); SIF_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - if (node->opType == OP_TYPE_JSON_GET_VALUE || node->opType == OP_TYPE_JSON_CONTAINS) { + if (node->opType == OP_TYPE_JSON_GET_VALUE) { return code; } SIFParam *paramList = taosMemoryCalloc(nParam, sizeof(SIFParam)); @@ -418,8 +421,8 @@ static int32_t sifNotMatchFunc(SIFParam *left, SIFParam *right, SIFParam *output return sifDoIndex(left, right, id, output); } static int32_t sifJsonContains(SIFParam *left, SIFParam *right, SIFParam *output) { - // return 0 - return 0; + int id = OP_TYPE_JSON_CONTAINS; + return sifDoIndex(left, right, id, output); } static int32_t sifJsonGetValue(SIFParam *left, SIFParam *rigth, SIFParam *output) { // return 0 @@ -503,7 +506,7 @@ static int32_t sifExecOper(SOperatorNode *node, SIFCtx *ctx, SIFParam *output) { return code; // SIF_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - if (node->opType == OP_TYPE_JSON_GET_VALUE || node->opType == OP_TYPE_JSON_CONTAINS) { + if (node->opType == OP_TYPE_JSON_GET_VALUE) { return code; } SIFParam *params = NULL; diff --git a/source/libs/index/src/indexTfile.c b/source/libs/index/src/indexTfile.c index 53dd2923ac..0145df4676 100644 --- a/source/libs/index/src/indexTfile.c +++ b/source/libs/index/src/indexTfile.c @@ -425,8 +425,7 @@ static int32_t tfSearchTerm_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr) { return TSDB_CODE_SUCCESS; } static int32_t tfSearchPrefix_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr) { - // impl later - return TSDB_CODE_SUCCESS; + return tfSearchCompareFunc_JSON(reader, tem, tr, CONTAINS); } static int32_t tfSearchSuffix_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr) { // impl later @@ -466,10 +465,6 @@ static int32_t tfSearchCompareFunc_JSON(void* reader, SIndexTerm* tem, SIdxTRslt AutomationCtx* ctx = automCtxCreate((void*)p, AUTOMATION_PREFIX); FstStreamBuilder* sb = fstSearch(((TFileReader*)reader)->fst, ctx); - // FstSlice h = fstSliceCreate((uint8_t*)p, skip); - // fstStreamBuilderSetRange(sb, &h, ctype); - // fstSliceDestroy(&h); - StreamWithState* st = streamBuilderIntoStream(sb); StreamWithStateResult* rt = NULL; while ((rt = streamWithStateNextWith(st, NULL)) != NULL) { diff --git a/source/libs/parser/src/parTokenizer.c b/source/libs/parser/src/parTokenizer.c index 685c299c01..d13f17f895 100644 --- a/source/libs/parser/src/parTokenizer.c +++ b/source/libs/parser/src/parTokenizer.c @@ -64,6 +64,7 @@ static SKeyword keywordTable[] = { {"CONSUMER", TK_CONSUMER}, {"COUNT", TK_COUNT}, {"CREATE", TK_CREATE}, + {"CONTAINS", TK_CONTAINS}, {"DATABASE", TK_DATABASE}, {"DATABASES", TK_DATABASES}, {"DAYS", TK_DAYS}, From d8b4240bb33351bc347b1435127d484ecfaecb2a Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Tue, 7 Jun 2022 00:23:23 +0800 Subject: [PATCH 26/26] fix(os): add win32 monitor case --- tests/system-test/0-others/taosdMonitor.py | 372 +++++++++++---------- tests/system-test/fulltest.bat | 4 +- tests/system-test/test.py | 1 + 3 files changed, 190 insertions(+), 187 deletions(-) diff --git a/tests/system-test/0-others/taosdMonitor.py b/tests/system-test/0-others/taosdMonitor.py index a219c54e59..4c5a434f0c 100644 --- a/tests/system-test/0-others/taosdMonitor.py +++ b/tests/system-test/0-others/taosdMonitor.py @@ -8,6 +8,7 @@ import http.server import gzip import threading import json +import pickle from util.log import * from util.sql import * @@ -15,206 +16,203 @@ from util.cases import * from util.dnodes import * telemetryPort = '6043' +serverPort = '7080' +hostname = socket.gethostname() +class RequestHandlerImpl(http.server.BaseHTTPRequestHandler): + hostPort = hostname + ":" + serverPort -def telemetryInfoCheck(infoDict=''): + def telemetryInfoCheck(self, infoDict=''): + if "ts" not in infoDict or len(infoDict["ts"]) == 0: + tdLog.exit("ts is null!") - hostname = socket.gethostname() - serverPort = 7080 + if "dnode_id" not in infoDict or infoDict["dnode_id"] != 1: + tdLog.exit("dnode_id is null!") - if "ts" not in infoDict or len(infoDict["ts"]) == 0: - tdLog.exit("ts is null!") + if "dnode_ep" not in infoDict: + tdLog.exit("dnode_ep is null!") - if "dnode_id" not in infoDict or infoDict["dnode_id"] != 1: - tdLog.exit("dnode_id is null!") + if "cluster_id" not in infoDict: + tdLog.exit("cluster_id is null!") - if "dnode_ep" not in infoDict: - tdLog.exit("dnode_ep is null!") + if "protocol" not in infoDict or infoDict["protocol"] != 1: + tdLog.exit("protocol is null!") - if "cluster_id" not in infoDict: - tdLog.exit("cluster_id is null!") + if "cluster_info" not in infoDict : + tdLog.exit("cluster_info is null!") - if "protocol" not in infoDict or infoDict["protocol"] != 1: - tdLog.exit("protocol is null!") + # cluster_info ==================================== - if "cluster_info" not in infoDict : - tdLog.exit("cluster_info is null!") + if "first_ep" not in infoDict["cluster_info"] or infoDict["cluster_info"]["first_ep"] == None: + tdLog.exit("first_ep is null!") - # cluster_info ==================================== + if "first_ep_dnode_id" not in infoDict["cluster_info"] or infoDict["cluster_info"]["first_ep_dnode_id"] != 1: + tdLog.exit("first_ep_dnode_id is null!") - if "first_ep" not in infoDict["cluster_info"] or infoDict["cluster_info"]["first_ep"] == None: - tdLog.exit("first_ep is null!") - - if "first_ep_dnode_id" not in infoDict["cluster_info"] or infoDict["cluster_info"]["first_ep_dnode_id"] != 1: - tdLog.exit("first_ep_dnode_id is null!") - - if "version" not in infoDict["cluster_info"] or infoDict["cluster_info"]["version"] == None: - tdLog.exit("first_ep_dnode_id is null!") - - if "master_uptime" not in infoDict["cluster_info"] or infoDict["cluster_info"]["master_uptime"] == None: - tdLog.exit("master_uptime is null!") - - if "monitor_interval" not in infoDict["cluster_info"] or infoDict["cluster_info"]["monitor_interval"] !=5: - tdLog.exit("monitor_interval is null!") - - if "vgroups_total" not in infoDict["cluster_info"] or infoDict["cluster_info"]["vgroups_total"] < 0: - tdLog.exit("vgroups_total is null!") - - if "vgroups_alive" not in infoDict["cluster_info"] or infoDict["cluster_info"]["vgroups_alive"] < 0: - tdLog.exit("vgroups_alive is null!") - - if "connections_total" not in infoDict["cluster_info"] or infoDict["cluster_info"]["connections_total"] < 0 : - tdLog.exit("connections_total is null!") - - if "dnodes" not in infoDict["cluster_info"] or infoDict["cluster_info"]["dnodes"] == None : - tdLog.exit("dnodes is null!") - - dnodes_info = { "dnode_id": 1,"dnode_ep": f"{hostname}:{serverPort}","status":"ready"} - - for k ,v in dnodes_info.items(): - if k not in infoDict["cluster_info"]["dnodes"][0] or v != infoDict["cluster_info"]["dnodes"][0][k] : - tdLog.exit("dnodes info is null!") - - mnodes_info = { "mnode_id":1, "mnode_ep":f"{hostname}:{serverPort}","role": "leader" } - - for k ,v in mnodes_info.items(): - if k not in infoDict["cluster_info"]["mnodes"][0] or v != infoDict["cluster_info"]["mnodes"][0][k] : - tdLog.exit("mnodes info is null!") - - # vgroup_infos ==================================== - - if "vgroup_infos" not in infoDict or infoDict["vgroup_infos"]== None: - tdLog.exit("vgroup_infos is null!") - - vgroup_infos_nums = len(infoDict["vgroup_infos"]) - - for index in range(vgroup_infos_nums): - if "vgroup_id" not in infoDict["vgroup_infos"][index] or infoDict["vgroup_infos"][index]["vgroup_id"]<0: - tdLog.exit("vgroup_id is null!") - if "database_name" not in infoDict["vgroup_infos"][index] or len(infoDict["vgroup_infos"][index]["database_name"]) < 0: - tdLog.exit("database_name is null!") - if "tables_num" not in infoDict["vgroup_infos"][index] or infoDict["vgroup_infos"][index]["tables_num"]!= 0: - tdLog.exit("tables_num is null!") - if "status" not in infoDict["vgroup_infos"][index] or len(infoDict["vgroup_infos"][index]["status"]) < 0 : - tdLog.exit("status is null!") - if "vnodes" not in infoDict["vgroup_infos"][index] or infoDict["vgroup_infos"][index]["vnodes"] ==None : - tdLog.exit("vnodes is null!") - if "dnode_id" not in infoDict["vgroup_infos"][index]["vnodes"][0] or infoDict["vgroup_infos"][index]["vnodes"][0]["dnode_id"] < 0 : - tdLog.exit("vnodes is null!") - - # grant_info ==================================== - - if "grant_info" not in infoDict or infoDict["grant_info"]== None: - tdLog.exit("grant_info is null!") - - if "expire_time" not in infoDict["grant_info"] or not infoDict["grant_info"]["expire_time"] > 0: - tdLog.exit("expire_time is null!") - - if "timeseries_used" not in infoDict["grant_info"] or not infoDict["grant_info"]["timeseries_used"] > 0: - tdLog.exit("timeseries_used is null!") - - if "timeseries_total" not in infoDict["grant_info"] or not infoDict["grant_info"]["timeseries_total"] > 0: - tdLog.exit("timeseries_total is null!") + if "version" not in infoDict["cluster_info"] or infoDict["cluster_info"]["version"] == None: + tdLog.exit("first_ep_dnode_id is null!") - # dnode_info ==================================== + if "master_uptime" not in infoDict["cluster_info"] or infoDict["cluster_info"]["master_uptime"] == None: + tdLog.exit("master_uptime is null!") - if "dnode_info" not in infoDict or infoDict["dnode_info"]== None: - tdLog.exit("dnode_info is null!") + if "monitor_interval" not in infoDict["cluster_info"] or infoDict["cluster_info"]["monitor_interval"] !=5: + tdLog.exit("monitor_interval is null!") - dnode_infos = ['uptime', 'cpu_engine', 'cpu_system', 'cpu_cores', 'mem_engine', 'mem_system', 'mem_total', 'disk_engine', - 'disk_used', 'disk_total', 'net_in', 'net_out', 'io_read', 'io_write', 'io_read_disk', 'io_write_disk', 'req_select', - 'req_select_rate', 'req_insert', 'req_insert_success', 'req_insert_rate', 'req_insert_batch', 'req_insert_batch_success', - 'req_insert_batch_rate', 'errors', 'vnodes_num', 'masters', 'has_mnode', 'has_qnode', 'has_snode', 'has_bnode'] - for elem in dnode_infos: - if elem not in infoDict["dnode_info"] or infoDict["dnode_info"][elem] < 0: - tdLog.exit(f"{elem} is null!") + if "vgroups_total" not in infoDict["cluster_info"] or infoDict["cluster_info"]["vgroups_total"] < 0: + tdLog.exit("vgroups_total is null!") - # dnode_info ==================================== + if "vgroups_alive" not in infoDict["cluster_info"] or infoDict["cluster_info"]["vgroups_alive"] < 0: + tdLog.exit("vgroups_alive is null!") - if "disk_infos" not in infoDict or infoDict["disk_infos"]== None: - tdLog.exit("disk_infos is null!") - - # bug for data_dir - if "datadir" not in infoDict["disk_infos"] or len(infoDict["disk_infos"]["datadir"]) <=0 : - tdLog.exit("datadir is null!") + if "connections_total" not in infoDict["cluster_info"] or infoDict["cluster_info"]["connections_total"] < 0 : + tdLog.exit("connections_total is null!") - if "name" not in infoDict["disk_infos"]["datadir"][0] or len(infoDict["disk_infos"]["datadir"][0]["name"]) <= 0: - tdLog.exit("name is null!") + if "dnodes" not in infoDict["cluster_info"] or infoDict["cluster_info"]["dnodes"] == None : + tdLog.exit("dnodes is null!") + + dnodes_info = { "dnode_id": 1,"dnode_ep": self.hostPort,"status":"ready"} + + for k ,v in dnodes_info.items(): + if k not in infoDict["cluster_info"]["dnodes"][0] or v != infoDict["cluster_info"]["dnodes"][0][k] : + tdLog.exit("dnodes info is null!") + + mnodes_info = { "mnode_id":1, "mnode_ep": self.hostPort,"role": "leader" } - if "level" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["level"] < 0: - tdLog.exit("level is null!") + for k ,v in mnodes_info.items(): + if k not in infoDict["cluster_info"]["mnodes"][0] or v != infoDict["cluster_info"]["mnodes"][0][k] : + tdLog.exit("mnodes info is null!") - if "avail" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["avail"] <= 0: - tdLog.exit("avail is null!") + # vgroup_infos ==================================== - if "used" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["used"] <= 0: - tdLog.exit("used is null!") + if "vgroup_infos" not in infoDict or infoDict["vgroup_infos"]== None: + tdLog.exit("vgroup_infos is null!") + + vgroup_infos_nums = len(infoDict["vgroup_infos"]) - if "total" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["total"] <= 0: - tdLog.exit("total is null!") + for index in range(vgroup_infos_nums): + if "vgroup_id" not in infoDict["vgroup_infos"][index] or infoDict["vgroup_infos"][index]["vgroup_id"]<0: + tdLog.exit("vgroup_id is null!") + if "database_name" not in infoDict["vgroup_infos"][index] or len(infoDict["vgroup_infos"][index]["database_name"]) < 0: + tdLog.exit("database_name is null!") + if "tables_num" not in infoDict["vgroup_infos"][index] or infoDict["vgroup_infos"][index]["tables_num"]!= 0: + tdLog.exit("tables_num is null!") + if "status" not in infoDict["vgroup_infos"][index] or len(infoDict["vgroup_infos"][index]["status"]) < 0 : + tdLog.exit("status is null!") + if "vnodes" not in infoDict["vgroup_infos"][index] or infoDict["vgroup_infos"][index]["vnodes"] ==None : + tdLog.exit("vnodes is null!") + if "dnode_id" not in infoDict["vgroup_infos"][index]["vnodes"][0] or infoDict["vgroup_infos"][index]["vnodes"][0]["dnode_id"] < 0 : + tdLog.exit("vnodes is null!") + + # grant_info ==================================== + + if "grant_info" not in infoDict or infoDict["grant_info"]== None: + tdLog.exit("grant_info is null!") + + if "expire_time" not in infoDict["grant_info"] or not infoDict["grant_info"]["expire_time"] > 0: + tdLog.exit("expire_time is null!") + + if "timeseries_used" not in infoDict["grant_info"] or not infoDict["grant_info"]["timeseries_used"] > 0: + tdLog.exit("timeseries_used is null!") + + if "timeseries_total" not in infoDict["grant_info"] or not infoDict["grant_info"]["timeseries_total"] > 0: + tdLog.exit("timeseries_total is null!") + + # dnode_info ==================================== + + if "dnode_info" not in infoDict or infoDict["dnode_info"]== None: + tdLog.exit("dnode_info is null!") + + dnode_infos = ['uptime', 'cpu_engine', 'cpu_system', 'cpu_cores', 'mem_engine', 'mem_system', 'mem_total', 'disk_engine', + 'disk_used', 'disk_total', 'net_in', 'net_out', 'io_read', 'io_write', 'io_read_disk', 'io_write_disk', 'req_select', + 'req_select_rate', 'req_insert', 'req_insert_success', 'req_insert_rate', 'req_insert_batch', 'req_insert_batch_success', + 'req_insert_batch_rate', 'errors', 'vnodes_num', 'masters', 'has_mnode', 'has_qnode', 'has_snode', 'has_bnode'] + for elem in dnode_infos: + if elem not in infoDict["dnode_info"] or infoDict["dnode_info"][elem] < 0: + tdLog.exit(f"{elem} is null!") + + # dnode_info ==================================== + + if "disk_infos" not in infoDict or infoDict["disk_infos"]== None: + tdLog.exit("disk_infos is null!") + + # bug for data_dir + if "datadir" not in infoDict["disk_infos"] or len(infoDict["disk_infos"]["datadir"]) <=0 : + tdLog.exit("datadir is null!") + + if "name" not in infoDict["disk_infos"]["datadir"][0] or len(infoDict["disk_infos"]["datadir"][0]["name"]) <= 0: + tdLog.exit("name is null!") + + if "level" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["level"] < 0: + tdLog.exit("level is null!") + + if "avail" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["avail"] <= 0: + tdLog.exit("avail is null!") + + if "used" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["used"] <= 0: + tdLog.exit("used is null!") + + if "total" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["total"] <= 0: + tdLog.exit("total is null!") - if "logdir" not in infoDict["disk_infos"] or infoDict["disk_infos"]["logdir"]== None: - tdLog.exit("logdir is null!") + if "logdir" not in infoDict["disk_infos"] or infoDict["disk_infos"]["logdir"]== None: + tdLog.exit("logdir is null!") - if "name" not in infoDict["disk_infos"]["logdir"] or len(infoDict["disk_infos"]["logdir"]["name"]) <= 0: - tdLog.exit("name is null!") + if "name" not in infoDict["disk_infos"]["logdir"] or len(infoDict["disk_infos"]["logdir"]["name"]) <= 0: + tdLog.exit("name is null!") - if "avail" not in infoDict["disk_infos"]["logdir"] or infoDict["disk_infos"]["logdir"]["avail"] <= 0: - tdLog.exit("avail is null!") + if "avail" not in infoDict["disk_infos"]["logdir"] or infoDict["disk_infos"]["logdir"]["avail"] <= 0: + tdLog.exit("avail is null!") - if "used" not in infoDict["disk_infos"]["logdir"] or infoDict["disk_infos"]["logdir"]["used"] <= 0: - tdLog.exit("used is null!") + if "used" not in infoDict["disk_infos"]["logdir"] or infoDict["disk_infos"]["logdir"]["used"] <= 0: + tdLog.exit("used is null!") - if "total" not in infoDict["disk_infos"]["logdir"] or infoDict["disk_infos"]["logdir"]["total"] <= 0: - tdLog.exit("total is null!") + if "total" not in infoDict["disk_infos"]["logdir"] or infoDict["disk_infos"]["logdir"]["total"] <= 0: + tdLog.exit("total is null!") + if "tempdir" not in infoDict["disk_infos"] or infoDict["disk_infos"]["tempdir"]== None: + tdLog.exit("tempdir is null!") + + if "name" not in infoDict["disk_infos"]["tempdir"] or len(infoDict["disk_infos"]["tempdir"]["name"]) <= 0: + tdLog.exit("name is null!") + + if "avail" not in infoDict["disk_infos"]["tempdir"] or infoDict["disk_infos"]["tempdir"]["avail"] <= 0: + tdLog.exit("avail is null!") + + if "used" not in infoDict["disk_infos"]["tempdir"] or infoDict["disk_infos"]["tempdir"]["used"] <= 0: + tdLog.exit("used is null!") + + if "total" not in infoDict["disk_infos"]["tempdir"] or infoDict["disk_infos"]["tempdir"]["total"] <= 0: + tdLog.exit("total is null!") + + + # log_infos ==================================== + + if "log_infos" not in infoDict or infoDict["log_infos"]== None: + tdLog.exit("log_infos is null!") + + if "logs" not in infoDict["log_infos"] or len(infoDict["log_infos"]["logs"])!= 10: + tdLog.exit("logs is null!") + + if "ts" not in infoDict["log_infos"]["logs"][0] or len(infoDict["log_infos"]["logs"][0]["ts"]) <= 10: + tdLog.exit("ts is null!") + + if "level" not in infoDict["log_infos"]["logs"][0] or infoDict["log_infos"]["logs"][0]["level"] not in ["error" ,"info" , "debug" ,"trace"]: + tdLog.exit("level is null!") + + if "content" not in infoDict["log_infos"]["logs"][0] or len(infoDict["log_infos"]["logs"][0]["ts"]) <= 1: + tdLog.exit("content is null!") + + if "summary" not in infoDict["log_infos"] or len(infoDict["log_infos"]["summary"])!= 4: + tdLog.exit("summary is null!") + + + if "total" not in infoDict["log_infos"]["summary"][0] or infoDict["log_infos"]["summary"][0]["total"] < 0 : + tdLog.exit("total is null!") + + if "level" not in infoDict["log_infos"]["summary"][0] or infoDict["log_infos"]["summary"][0]["level"] not in ["error" ,"info" , "debug" ,"trace"]: + tdLog.exit("level is null!") - - if "tempdir" not in infoDict["disk_infos"] or infoDict["disk_infos"]["tempdir"]== None: - tdLog.exit("tempdir is null!") - - if "name" not in infoDict["disk_infos"]["tempdir"] or len(infoDict["disk_infos"]["tempdir"]["name"]) <= 0: - tdLog.exit("name is null!") - - if "avail" not in infoDict["disk_infos"]["tempdir"] or infoDict["disk_infos"]["tempdir"]["avail"] <= 0: - tdLog.exit("avail is null!") - - if "used" not in infoDict["disk_infos"]["tempdir"] or infoDict["disk_infos"]["tempdir"]["used"] <= 0: - tdLog.exit("used is null!") - - if "total" not in infoDict["disk_infos"]["tempdir"] or infoDict["disk_infos"]["tempdir"]["total"] <= 0: - tdLog.exit("total is null!") - - - # log_infos ==================================== - - if "log_infos" not in infoDict or infoDict["log_infos"]== None: - tdLog.exit("log_infos is null!") - - if "logs" not in infoDict["log_infos"] or len(infoDict["log_infos"]["logs"])!= 10: - tdLog.exit("logs is null!") - - if "ts" not in infoDict["log_infos"]["logs"][0] or len(infoDict["log_infos"]["logs"][0]["ts"]) <= 10: - tdLog.exit("ts is null!") - - if "level" not in infoDict["log_infos"]["logs"][0] or infoDict["log_infos"]["logs"][0]["level"] not in ["error" ,"info" , "debug" ,"trace"]: - tdLog.exit("level is null!") - - if "content" not in infoDict["log_infos"]["logs"][0] or len(infoDict["log_infos"]["logs"][0]["ts"]) <= 1: - tdLog.exit("content is null!") - - if "summary" not in infoDict["log_infos"] or len(infoDict["log_infos"]["summary"])!= 4: - tdLog.exit("summary is null!") - - - if "total" not in infoDict["log_infos"]["summary"][0] or infoDict["log_infos"]["summary"][0]["total"] < 0 : - tdLog.exit("total is null!") - - if "level" not in infoDict["log_infos"]["summary"][0] or infoDict["log_infos"]["summary"][0]["level"] not in ["error" ,"info" , "debug" ,"trace"]: - tdLog.exit("level is null!") - -class RequestHandlerImpl(http.server.BaseHTTPRequestHandler): def do_GET(self): """ process GET request @@ -245,17 +243,23 @@ class RequestHandlerImpl(http.server.BaseHTTPRequestHandler): infoDict = json.loads(plainText) #print("================") # print(infoDict) - telemetryInfoCheck(infoDict) + self.telemetryInfoCheck(infoDict) # 4. shutdown the server and exit case - assassin = threading.Thread(target=httpServer.shutdown) + assassin = threading.Thread(target=self.server.shutdown) assassin.daemon = True assassin.start() print ("==== shutdown http server ====") class TDTestCase: - hostname = socket.gethostname() - serverPort = '7080' + global hostname + global serverPort + if (platform.system().lower() == 'windows' and not tdDnodes.dnodes[0].remoteIP == ""): + try: + config = eval(tdDnodes.dnodes[0].remoteIP ) + hostname = config["host"] + except Exception: + hostname = tdDnodes.dnodes[0].remoteIP rpcDebugFlagVal = '143' clientCfgDict = {'serverPort': '', 'firstEp': '', 'secondEp':'', 'rpcDebugFlag':'135', 'fqdn':''} clientCfgDict["serverPort"] = serverPort @@ -291,21 +295,19 @@ class TDTestCase: sql = "create database db3 vgroups " + vgroups tdSql.query(sql) - # loop to wait request - httpServer.serve_forever() + # create http server: bing ip/port , and request processor + if (platform.system().lower() == 'windows' and not tdDnodes.dnodes[0].remoteIP == ""): + RequestHandlerImplStr = base64.b64encode(pickle.dumps(RequestHandlerImpl)).decode() + cmdStr = "import pickle\nimport http\nRequestHandlerImpl=pickle.loads(base64.b64decode(\"%s\".encode()))\nclass NewRequestHandlerImpl(RequestHandlerImpl):\n hostPort = \'%s\'\nhttp.server.HTTPServer((\"\", %s), NewRequestHandlerImpl).serve_forever()"%(RequestHandlerImplStr,hostname+":"+serverPort,telemetryPort) + tdDnodes.dnodes[0].remoteExec({}, cmdStr) + else: + serverAddress = ("", int(telemetryPort)) + http.server.HTTPServer(serverAddress, RequestHandlerImpl).serve_forever() def stop(self): tdSql.close() tdLog.success(f"{__file__} successfully executed") -# create http server: bing ip/port , and request processor -serverAddress = ("", int(telemetryPort)) -httpServer = http.server.HTTPServer(serverAddress, RequestHandlerImpl) - tdCases.addLinux(__file__, TDTestCase()) tdCases.addWindows(__file__, TDTestCase()) - - - - diff --git a/tests/system-test/fulltest.bat b/tests/system-test/fulltest.bat index c4eaeed2ad..6ef66c58c2 100644 --- a/tests/system-test/fulltest.bat +++ b/tests/system-test/fulltest.bat @@ -1,9 +1,9 @@ -@REM python3 .\test.py -f 0-others\taosShell.py +python3 .\test.py -f 0-others\taosShell.py python3 .\test.py -f 0-others\taosShellError.py python3 .\test.py -f 0-others\taosShellNetChk.py python3 .\test.py -f 0-others\telemetry.py -@REM python3 .\test.py -f 0-others\taosdMonitor.py +python3 .\test.py -f 0-others\taosdMonitor.py python3 .\test.py -f 0-others\udfTest.py python3 .\test.py -f 0-others\udf_create.py python3 .\test.py -f 0-others\udf_restart_taosd.py diff --git a/tests/system-test/test.py b/tests/system-test/test.py index a11085708c..d9ae792901 100644 --- a/tests/system-test/test.py +++ b/tests/system-test/test.py @@ -114,6 +114,7 @@ if __name__ == "__main__": if not execCmd == "": tdDnodes.init(deployPath) + print(execCmd) exec(execCmd) quit()