diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 7db909797a..47906e301f 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -63,7 +63,7 @@ typedef struct SExprNode { bool asParam; bool asPosition; bool joinSrc; -// bool joinConst; + //bool constValue; int32_t projIdx; int32_t relatedTo; int32_t bindExprID; @@ -714,6 +714,8 @@ int32_t mergeJoinConds(SNode** ppDst, SNode** ppSrc); void rewriteExprAliasName(SExprNode* pNode, int64_t num); bool isRelatedToOtherExpr(SExprNode* pExpr); +bool nodesContainsColumn(SNode* pNode); +int32_t nodesMergeNode(SNode** pCond, SNode** pAdditionalCond); #ifdef __cplusplus } diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 9b7d9e53bf..23f647aa16 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -3280,3 +3280,76 @@ void rewriteExprAliasName(SExprNode* pNode, int64_t num) { bool isRelatedToOtherExpr(SExprNode* pExpr) { return pExpr->relatedTo != 0; } + +typedef struct SContainsColCxt { + bool containsCol; +} SContainsColCxt; + +static EDealRes nodeContainsCol(SNode* pNode, void* pContext) { + SContainsColCxt* pCxt = pContext; + if (QUERY_NODE_COLUMN == nodeType(pNode)) { + pCxt->containsCol = true; + return DEAL_RES_END; + } + + return DEAL_RES_CONTINUE; +} + +bool nodesContainsColumn(SNode* pNode) { + if (NULL == pNode) { + return false; + } + + SContainsColCxt cxt = {0}; + nodesWalkExpr(pNode, nodeContainsCol, &cxt); + + return cxt.containsCol; +} + + + +int32_t mergeNodeToLogic(SNode** pDst, SNode** pSrc) { + SLogicConditionNode* pLogicCond = NULL; + int32_t code = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION, (SNode**)&pLogicCond); + if (NULL == pLogicCond) { + return code; + } + pLogicCond->node.resType.type = TSDB_DATA_TYPE_BOOL; + pLogicCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes; + pLogicCond->condType = LOGIC_COND_TYPE_AND; + code = nodesListMakeAppend(&pLogicCond->pParameterList, *pSrc); + if (TSDB_CODE_SUCCESS == code) { + *pSrc = NULL; + code = nodesListMakeAppend(&pLogicCond->pParameterList, *pDst); + } + if (TSDB_CODE_SUCCESS == code) { + *pDst = (SNode*)pLogicCond; + } else { + nodesDestroyNode((SNode*)pLogicCond); + } + return code; +} + + +int32_t nodesMergeNode(SNode** pCond, SNode** pAdditionalCond) { + if (NULL == *pCond) { + TSWAP(*pCond, *pAdditionalCond); + return TSDB_CODE_SUCCESS; + } + + int32_t code = TSDB_CODE_SUCCESS; + if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pCond) && + LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)*pCond)->condType) { + code = nodesListAppend(((SLogicConditionNode*)*pCond)->pParameterList, *pAdditionalCond); + if (TSDB_CODE_SUCCESS == code) { + *pAdditionalCond = NULL; + } + } else { + code = mergeNodeToLogic(pCond, pAdditionalCond); + } + + return code; +} + + + diff --git a/source/libs/parser/src/parCalcConst.c b/source/libs/parser/src/parCalcConst.c index 8295e67dee..e787ac4ba2 100644 --- a/source/libs/parser/src/parCalcConst.c +++ b/source/libs/parser/src/parCalcConst.c @@ -281,7 +281,7 @@ static int32_t calcConstProject(SCalcConstContext* pCxt, SNode* pProject, bool d SAssociationNode* pAssNode = taosArrayGet(pAssociation, i); SNode** pCol = pAssNode->pPlace; if (((SExprNode*)pAssNode->pAssociationNode)->joinSrc) { -// ((SExprNode*)pAssNode->pAssociationNode)->joinConst = true; + //((SExprNode*)pAssNode->pAssociationNode)->constValue = true; continue; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index d0d6f068ad..9d472fab80 100755 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5156,6 +5156,79 @@ int32_t mergeInnerJoinConds(SNode** ppDst, SNode** ppSrc) { return code; } +bool isColumnExpr(SNode* pNode) { + SExprNode* pExpr = (SExprNode*)pNode; + if (QUERY_NODE_COLUMN != nodeType(pNode) && QUERY_NODE_FUNCTION != nodeType(pNode)) { + return false; + } + if (QUERY_NODE_FUNCTION == nodeType(pNode)) { + SFunctionNode* pFunc = (SFunctionNode*)pNode; + if (FUNCTION_TYPE_TIMETRUNCATE != pFunc->funcType && strcasecmp(((SFunctionNode*)pNode)->functionName, "timetruncate")) { + return false; + } + if (!nodesContainsColumn(nodesListGetNode(pFunc->pParameterList, 0))) { + return false; + } + } + + return true; +} + +int32_t splitJoinColPrimaryCond(SNode** ppSrc, SNode** ppDst) { + if (NULL == *ppSrc) { + return TSDB_CODE_SUCCESS; + } + + int32_t code = 0; + switch (nodeType(*ppSrc)) { + case QUERY_NODE_OPERATOR: { + SOperatorNode* pOp = (SOperatorNode*)*ppSrc; + if (OP_TYPE_EQUAL != pOp->opType) { + break; + } + if (isColumnExpr(pOp->pLeft) && isColumnExpr(pOp->pRight)) { + TSWAP(*ppSrc, *ppDst); + } + break; + } + case QUERY_NODE_LOGIC_CONDITION: { + SLogicConditionNode* pLogic = (SLogicConditionNode*)*ppSrc; + if (LOGIC_COND_TYPE_AND != pLogic->condType) { + break; + } + SNode* pTmp = NULL; + SNode* pTmpRes = NULL; + WHERE_EACH(pTmp, pLogic->pParameterList) { + code = splitJoinColPrimaryCond(&pTmp, &pTmpRes); + if (code) { + break; + } + if (NULL == pTmp && NULL != pTmpRes) { + cell->pNode = NULL; + ERASE_NODE(pLogic->pParameterList); + code = nodesMergeNode(ppDst, &pTmpRes); + if (code) { + break; + } + + continue; + } + + WHERE_NEXT; + } + if (pLogic->pParameterList->length <= 0) { + nodesDestroyNode(*ppSrc); + *ppSrc = NULL; + } + break; + } + default: + break; + } + + return code; +} + int32_t translateTable(STranslateContext* pCxt, SNode** pTable, bool inJoin) { SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt); int32_t code = TSDB_CODE_SUCCESS; @@ -5243,12 +5316,17 @@ int32_t translateTable(STranslateContext* pCxt, SNode** pTable, bool inJoin) { code = checkJoinTable(pCxt, pJoinTable); } if (TSDB_CODE_SUCCESS == code && !inJoin && pCurrSmt->pWhere && JOIN_TYPE_INNER == pJoinTable->joinType) { - if (pJoinTable->pOnCond) { - code = mergeInnerJoinConds(&pJoinTable->pOnCond, &pCurrSmt->pWhere); - } else { - pJoinTable->pOnCond = pCurrSmt->pWhere; - pCurrSmt->pWhere = NULL; + SNode* pPrimCond = NULL; + code = splitJoinColPrimaryCond(&pCurrSmt->pWhere, &pPrimCond); + if (TSDB_CODE_SUCCESS == code && pPrimCond) { + if (pJoinTable->pOnCond) { + code = mergeInnerJoinConds(&pJoinTable->pOnCond, &pPrimCond); + } else { + pJoinTable->pOnCond = pPrimCond; + pPrimCond = NULL; + } } + nodesDestroyNode(pPrimCond); } if (TSDB_CODE_SUCCESS == code) { pJoinTable->table.precision = calcJoinTablePrecision(pJoinTable); diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index d8f6b79413..e48d4d0acb 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -503,52 +503,12 @@ static int32_t scanPathOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub return code; } -static int32_t pdcMergeCondsToLogic(SNode** pDst, SNode** pSrc) { - SLogicConditionNode* pLogicCond = NULL; - int32_t code = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION, (SNode**)&pLogicCond); - if (NULL == pLogicCond) { - return code; - } - pLogicCond->node.resType.type = TSDB_DATA_TYPE_BOOL; - pLogicCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes; - pLogicCond->condType = LOGIC_COND_TYPE_AND; - code = nodesListMakeAppend(&pLogicCond->pParameterList, *pSrc); - if (TSDB_CODE_SUCCESS == code) { - *pSrc = NULL; - code = nodesListMakeAppend(&pLogicCond->pParameterList, *pDst); - } - if (TSDB_CODE_SUCCESS == code) { - *pDst = (SNode*)pLogicCond; - } else { - nodesDestroyNode((SNode*)pLogicCond); - } - return code; -} - -static int32_t pdcMergeConds(SNode** pCond, SNode** pAdditionalCond) { - if (NULL == *pCond) { - TSWAP(*pCond, *pAdditionalCond); - return TSDB_CODE_SUCCESS; - } - - int32_t code = TSDB_CODE_SUCCESS; - if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pCond) && - LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)*pCond)->condType) { - code = nodesListAppend(((SLogicConditionNode*)*pCond)->pParameterList, *pAdditionalCond); - if (TSDB_CODE_SUCCESS == code) { - *pAdditionalCond = NULL; - } - } else { - code = pdcMergeCondsToLogic(pCond, pAdditionalCond); - } - return code; -} static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNode* pScan, SNode** pPrimaryKeyCond, SNode** pOtherCond) { int32_t code = TSDB_CODE_SUCCESS; if (pCxt->pPlanCxt->topicQuery || pCxt->pPlanCxt->streamQuery) { - code = pdcMergeConds(pOtherCond, pPrimaryKeyCond); + code = nodesMergeNode(pOtherCond, pPrimaryKeyCond); } else { bool isStrict = false; code = filterGetTimeRange(*pPrimaryKeyCond, &pScan->scanRange, &isStrict); @@ -556,7 +516,7 @@ static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNo if (isStrict) { nodesDestroyNode(*pPrimaryKeyCond); } else { - code = pdcMergeConds(pOtherCond, pPrimaryKeyCond); + code = nodesMergeNode(pOtherCond, pPrimaryKeyCond); } *pPrimaryKeyCond = NULL; } @@ -828,11 +788,11 @@ static int32_t pdcJoinSplitCond(SJoinLogicNode* pJoin, SNode** pSrcCond, SNode** } static int32_t pdcJoinPushDownOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin, SNode** pCond) { - return pdcMergeConds(&pJoin->pFullOnCond, pCond); + return nodesMergeNode(&pJoin->pFullOnCond, pCond); } static int32_t pdcPushDownCondToChild(SOptimizeContext* pCxt, SLogicNode* pChild, SNode** pCond) { - return pdcMergeConds(&pChild->pConditions, pCond); + return nodesMergeNode(&pChild->pConditions, pCond); } static bool pdcJoinIsPrim(SNode* pNode, SSHashObj* pTables, bool constAsPrim, bool* constPrimGot) { @@ -2073,7 +2033,7 @@ static int32_t partitionAggCond(SAggLogicNode* pAgg, SNode** ppAggFunCond, SNode } static int32_t pushCondToAggCond(SOptimizeContext* pCxt, SAggLogicNode* pAgg, SNode** pAggFuncCond) { - return pdcMergeConds(&pAgg->node.pConditions, pAggFuncCond); + return nodesMergeNode(&pAgg->node.pConditions, pAggFuncCond); } typedef struct SRewriteAggGroupKeyCondContext {