From 4224d55b391f7949cb2918da37d3c5e7673a2e53 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Tue, 25 Feb 2025 19:26:52 +0800 Subject: [PATCH] feat: support const ts as primary cond --- include/libs/nodes/plannodes.h | 4 + include/libs/scalar/scalar.h | 1 + include/util/taoserror.h | 4 +- source/libs/nodes/src/nodesCloneFuncs.c | 7 ++ source/libs/parser/src/parTranslater.c | 25 +++-- source/libs/planner/src/planLogicCreater.c | 1 + source/libs/planner/src/planOptimizer.c | 106 +++++++++++++++++---- source/libs/planner/src/planPhysiCreater.c | 26 ++++- source/libs/scalar/src/scalar.c | 51 +++++----- source/util/src/terror.c | 5 +- 10 files changed, 171 insertions(+), 59 deletions(-) diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 9ed565090e..ae1b68f90a 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -155,6 +155,10 @@ typedef struct SJoinLogicNode { bool grpJoin; bool hashJoinHint; bool batchScanHint; + + // FOR CONST JOIN + bool noPrimKeyEqCond; + bool constPrimGot; // FOR HASH JOIN int32_t timeRangeTarget; // table onCond filter diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index 67fd954ad7..ae2e76b18d 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -33,6 +33,7 @@ pNode will be freed in API; */ int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes); int32_t scalarCalculateConstantsFromDual(SNode *pNode, SNode **pRes); +int32_t scalarConvertOpValueNodeTs(SOperatorNode *node); /* pDst need to freed in caller diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 29e95251e9..b3bd774df4 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -913,8 +913,8 @@ int32_t taosGetErrSize(); #define TSDB_CODE_PAR_TRUE_FOR_UNIT TAOS_DEF_ERROR_CODE(0, 0x2688) #define TSDB_CODE_PAR_INVALID_COLS_FUNCTION TAOS_DEF_ERROR_CODE(0, 0x2689) #define TSDB_CODE_PAR_INVALID_COLS_SELECTFUNC TAOS_DEF_ERROR_CODE(0, 0x268A) -#define TSDB_CODE_INVALID_MULITI_COLS_FUNC TAOS_DEF_ERROR_CODE(0, 0x268B) -#define TSDB_CODE_INVALID_COLS_ALIAS TAOS_DEF_ERROR_CODE(0, 0x268C) +#define TSDB_CODE_PAR_INVALID_COLS_ALIAS TAOS_DEF_ERROR_CODE(0, 0x268B) +#define TSDB_CODE_PAR_VALID_TS_SERIOUS_REQUIRED TAOS_DEF_ERROR_CODE(0, 0x268C) #define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF) //planner diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index fcb39c4284..ff796df0f6 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -321,6 +321,8 @@ static int32_t joinTableNodeCopy(const SJoinTableNode* pSrc, SJoinTableNode* pDs CLONE_NODE_FIELD(addPrimCond); COPY_SCALAR_FIELD(hasSubQuery); COPY_SCALAR_FIELD(isLowLevelJoin); + COPY_SCALAR_FIELD(leftNoOrderQuery); + COPY_SCALAR_FIELD(rightNoOrderQuery); CLONE_NODE_FIELD(pLeft); CLONE_NODE_FIELD(pRight); CLONE_NODE_FIELD(pOnCond); @@ -542,6 +544,11 @@ static int32_t logicJoinCopy(const SJoinLogicNode* pSrc, SJoinLogicNode* pDst) { COPY_SCALAR_FIELD(grpJoin); COPY_SCALAR_FIELD(hashJoinHint); COPY_SCALAR_FIELD(batchScanHint); + COPY_SCALAR_FIELD(leftNoOrderQuery); + COPY_SCALAR_FIELD(rightNoOrderQuery); + COPY_SCALAR_FIELD(noPrimKeyEqCond); + CLONE_NODE_FIELD(pLeftConstPrim); + CLONE_NODE_FIELD(pRightConstPrim); CLONE_NODE_FIELD(pLeftOnCond); CLONE_NODE_FIELD(pRightOnCond); COPY_SCALAR_FIELD(timeRangeTarget); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 2fdba9bad9..9d8b255d35 100755 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -4753,14 +4753,23 @@ static int32_t checkJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTabl } } - if ((QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pLeft) && - !isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pLeft)->pSubquery)) || - (QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pRight) && - !isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pRight)->pSubquery))) { - return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN, - "Join requires valid time series input"); + if (QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pLeft) && + !isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pLeft)->pSubquery)) { + if (IS_ASOF_JOIN(pJoinTable->subType) || IS_WINDOW_JOIN(pJoinTable->subType)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN, + "Join requires valid time series input"); + } } + if (QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pRight) && + !isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pRight)->pSubquery)) { + if (IS_ASOF_JOIN(pJoinTable->subType) || IS_WINDOW_JOIN(pJoinTable->subType)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN, + "Join requires valid time series input"); + } + } + + return TSDB_CODE_SUCCESS; } @@ -7555,7 +7564,7 @@ static EDealRes rewriteSingleColsFunc(SNode** pNode, void* pContext) { } if (pFunc->node.asAlias) { if (((SExprNode*)pExpr)->asAlias) { - pCxt->status = TSDB_CODE_INVALID_COLS_ALIAS; + pCxt->status = TSDB_CODE_PAR_INVALID_COLS_ALIAS; parserError("%s Invalid using alias for cols function", __func__); return DEAL_RES_ERROR; } else { @@ -7664,7 +7673,7 @@ static int32_t rewriteColsFunction(STranslateContext* pCxt, SNodeList** nodeList if (isMultiColsFuncNode(pTmpNode)) { SFunctionNode* pFunc = (SFunctionNode*)pTmpNode; if(pFunc->node.asAlias) { - code = TSDB_CODE_INVALID_COLS_ALIAS; + code = TSDB_CODE_PAR_INVALID_COLS_ALIAS; parserError("%s Invalid using alias for cols function", __func__); goto _end; } diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 98b2ef341e..273fd9abfc 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -600,6 +600,7 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect pJoin->node.requireDataOrder = pJoin->hashJoinHint ? DATA_ORDER_LEVEL_NONE : DATA_ORDER_LEVEL_GLOBAL; pJoin->node.resultDataOrder = DATA_ORDER_LEVEL_NONE; pJoin->isLowLevelJoin = pJoinTable->isLowLevelJoin; + code = nodesCloneNode(pJoinTable->pWindowOffset, &pJoin->pWindowOffset); if (TSDB_CODE_SUCCESS == code) { code = nodesCloneNode(pJoinTable->pJLimit, &pJoin->pJLimit); diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 367d0f4b4f..be1632d740 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -20,6 +20,7 @@ #include "systable.h" #include "tglobal.h" #include "ttime.h" +#include "scalar.h" #define OPTIMIZE_FLAG_MASK(n) (1 << n) @@ -826,8 +827,18 @@ static int32_t pdcPushDownCondToChild(SOptimizeContext* pCxt, SLogicNode* pChild return pdcMergeConds(&pChild->pConditions, pCond); } -static bool pdcJoinIsPrim(SNode* pNode, SSHashObj* pTables) { - if (QUERY_NODE_COLUMN != nodeType(pNode) && QUERY_NODE_FUNCTION != nodeType(pNode)) { +static bool pdcJoinIsPrim(SNode* pNode, SSHashObj* pTables, bool constAsPrim, bool* constPrimGot) { + if (QUERY_NODE_COLUMN != nodeType(pNode) && QUERY_NODE_FUNCTION != nodeType(pNode) && (!constAsPrim || QUERY_NODE_VALUE != nodeType(pNode))) { + return false; + } + + if (QUERY_NODE_VALUE == nodeType(pNode)) { + SValueNode* pVal = (SValueNode*)pNode; + if (TSDB_DATA_TYPE_NULL != pVal->node.resType.type && !pVal->isNull) { + *constPrimGot = true; + return true; + } + return false; } @@ -850,7 +861,7 @@ static bool pdcJoinIsPrim(SNode* pNode, SSHashObj* pTables) { return pdcJoinColInTableList(pNode, pTables); } -static bool pdcJoinIsPrimEqualCond(SJoinLogicNode* pJoin, SNode* pCond) { +static bool pdcJoinIsPrimEqualCond(SJoinLogicNode* pJoin, SNode* pCond, bool constAsPrim) { if (QUERY_NODE_OPERATOR != nodeType(pCond)) { return false; } @@ -878,11 +889,18 @@ static bool pdcJoinIsPrimEqualCond(SJoinLogicNode* pJoin, SNode* pCond) { return code; } - bool res = false; - if (pdcJoinIsPrim(pOper->pLeft, pLeftTables)) { - res = pdcJoinIsPrim(pOper->pRight, pRightTables); - } else if (pdcJoinIsPrim(pOper->pLeft, pRightTables)) { - res = pdcJoinIsPrim(pOper->pRight, pLeftTables); + bool res = false, constGot = false; + if (pdcJoinIsPrim(pOper->pLeft, pLeftTables, constAsPrim, &constGot)) { + res = pdcJoinIsPrim(pOper->pRight, pRightTables, constAsPrim, &constGot); + if (constGot) { + pJoin->constPrimGot = true; + } + } else if (pdcJoinIsPrim(pOper->pLeft, pRightTables, constAsPrim, &constGot)) { + res = pdcJoinIsPrim(pOper->pRight, pLeftTables, constAsPrim, &constGot); + if (constGot) { + pJoin->constPrimGot = true; + TSWAP(pOper->pLeft, pOper->pRight); + } } tSimpleHashCleanup(pLeftTables); @@ -910,12 +928,12 @@ static bool pdcJoinHasPrimEqualCond(SJoinLogicNode* pJoin, SNode* pCond, bool* e } return hasPrimaryKeyEqualCond; } else { - return pdcJoinIsPrimEqualCond(pJoin, pCond); + return pdcJoinIsPrimEqualCond(pJoin, pCond, false); } } -static int32_t pdcJoinSplitPrimInLogicCond(SJoinLogicNode* pJoin, SNode** ppPrimEqCond, SNode** ppOnCond) { - SLogicConditionNode* pLogicCond = (SLogicConditionNode*)(pJoin->pFullOnCond); +static int32_t pdcJoinSplitPrimInLogicCond(SJoinLogicNode* pJoin, SNode** ppInput, SNode** ppPrimEqCond, SNode** ppOnCond, bool constAsPrim) { + SLogicConditionNode* pLogicCond = (SLogicConditionNode*)(*ppInput); int32_t code = TSDB_CODE_SUCCESS; SNodeList* pOnConds = NULL; @@ -924,7 +942,7 @@ static int32_t pdcJoinSplitPrimInLogicCond(SJoinLogicNode* pJoin, SNode** ppPrim SNode* pNew = NULL; code = nodesCloneNode(pCond, &pNew); if (TSDB_CODE_SUCCESS != code) break; - if (pdcJoinIsPrimEqualCond(pJoin, pCond) && (NULL == *ppPrimEqCond)) { + if (pdcJoinIsPrimEqualCond(pJoin, pCond, constAsPrim) && (NULL == *ppPrimEqCond)) { *ppPrimEqCond = pNew; ERASE_NODE(pLogicCond->pParameterList); } else { @@ -942,8 +960,8 @@ static int32_t pdcJoinSplitPrimInLogicCond(SJoinLogicNode* pJoin, SNode** ppPrim if (TSDB_CODE_SUCCESS == code) { if (NULL != *ppPrimEqCond) { *ppOnCond = pTempOnCond; - nodesDestroyNode(pJoin->pFullOnCond); - pJoin->pFullOnCond = NULL; + nodesDestroyNode(*ppInput); + *ppInput = NULL; return TSDB_CODE_SUCCESS; } planError("no primary key equal cond found, condListNum:%d", pLogicCond->pParameterList->length); @@ -962,8 +980,8 @@ static int32_t pdcJoinSplitPrimEqCond(SOptimizeContext* pCxt, SJoinLogicNode* pJ if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pFullOnCond) && LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)(pJoin->pFullOnCond))->condType) { - code = pdcJoinSplitPrimInLogicCond(pJoin, &pPrimKeyEqCond, &pJoinOnCond); - } else if (pdcJoinIsPrimEqualCond(pJoin, pJoin->pFullOnCond)) { + code = pdcJoinSplitPrimInLogicCond(pJoin, &pJoin->pFullOnCond, &pPrimKeyEqCond, &pJoinOnCond, false); + } else if (pdcJoinIsPrimEqualCond(pJoin, pJoin->pFullOnCond, false)) { pPrimKeyEqCond = pJoin->pFullOnCond; pJoinOnCond = NULL; } else { @@ -1412,6 +1430,37 @@ static int32_t pdcJoinAddFilterColsToTarget(SOptimizeContext* pCxt, SJoinLogicNo return code; } +static int32_t pdcJoinSplitConstPrimEqCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin, SNode** ppCond) { + int32_t code = TSDB_CODE_SUCCESS; + SNode* pPrimKeyEqCond = NULL; + SNode* pJoinOnCond = NULL; + + if (QUERY_NODE_LOGIC_CONDITION == nodeType(*ppCond) && + LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)*ppCond)->condType) { + code = pdcJoinSplitPrimInLogicCond(pJoin, ppCond, &pPrimKeyEqCond, &pJoinOnCond, true); + } else if (pdcJoinIsPrimEqualCond(pJoin, *ppCond, true)) { + pPrimKeyEqCond = *ppCond; + pJoinOnCond = NULL; + } else { + return TSDB_CODE_SUCCESS; + } + + if (TSDB_CODE_SUCCESS == code) { + pJoin->pPrimKeyEqCond = pPrimKeyEqCond; + *ppCond = pJoinOnCond; + if (pJoin->constPrimGot) { + code = scalarConvertOpValueNodeTs((SOperatorNode*)pJoin->pPrimKeyEqCond); + } + } else { + nodesDestroyNode(pPrimKeyEqCond); + nodesDestroyNode(pJoinOnCond); + } + + return code; +} + + + static int32_t pdcJoinCheckAllCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) { if (NULL == pJoin->pFullOnCond) { if (IS_WINDOW_JOIN(pJoin->subType) || IS_ASOF_JOIN(pJoin->subType)) { @@ -1427,9 +1476,9 @@ static int32_t pdcJoinCheckAllCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin } } - SNode* pCond = pJoin->pFullOnCond ? pJoin->pFullOnCond : pJoin->node.pConditions; + SNode** ppCond = pJoin->pFullOnCond ? &pJoin->pFullOnCond : &pJoin->node.pConditions; bool errCond = false; - if (!pdcJoinHasPrimEqualCond(pJoin, pCond, &errCond)) { + if (!pdcJoinHasPrimEqualCond(pJoin, *ppCond, &errCond)) { if (errCond && !(IS_INNER_NONE_JOIN(pJoin->joinType, pJoin->subType) && NULL != pJoin->pFullOnCond && NULL != pJoin->node.pConditions)) { return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND); @@ -1449,6 +1498,20 @@ static int32_t pdcJoinCheckAllCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin return TSDB_CODE_SUCCESS; } + pJoin->noPrimKeyEqCond = true; + int32_t code = pdcJoinSplitConstPrimEqCond(pCxt, pJoin, ppCond); + if (code || pJoin->pPrimKeyEqCond) { + return code; + } + + if (IS_INNER_NONE_JOIN(pJoin->joinType, pJoin->subType) && NULL != pJoin->pFullOnCond && + NULL != pJoin->node.pConditions) { + code = pdcJoinSplitConstPrimEqCond(pCxt, pJoin, &pJoin->node.pConditions); + if (code || pJoin->pPrimKeyEqCond) { + return code; + } + } + return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_EXPECTED_TS_EQUAL); } @@ -1813,6 +1876,7 @@ static int32_t pdcRewriteTypeBasedOnJoinRes(SOptimizeContext* pCxt, SJoinLogicNo return TSDB_CODE_SUCCESS; } + static int32_t pdcDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) { if (OPTIMIZE_FLAG_TEST_MASK(pJoin->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) { return TSDB_CODE_SUCCESS; @@ -1870,7 +1934,7 @@ static int32_t pdcDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) { } if (TSDB_CODE_SUCCESS == code && NULL != pJoin->pFullOnCond && !IS_WINDOW_JOIN(pJoin->subType) && - NULL == pJoin->addPrimEqCond) { + NULL == pJoin->addPrimEqCond && NULL == pJoin->pPrimKeyEqCond) { code = pdcJoinSplitPrimEqCond(pCxt, pJoin); } @@ -2616,6 +2680,10 @@ static int32_t sortForJoinOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pL bool res = false; SOperatorNode* pOp = (SOperatorNode*)pJoin->pPrimKeyEqCond; + if (QUERY_NODE_VALUE != nodeType(pOp->pLeft) || QUERY_NODE_VALUE != nodeType(pOp->pRight)) { + return TSDB_CODE_SUCCESS; + } + if (QUERY_NODE_COLUMN != nodeType(pOp->pLeft) || QUERY_NODE_COLUMN != nodeType(pOp->pRight)) { return TSDB_CODE_PLAN_INTERNAL_ERROR; } diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index e12ec77bff..108379725c 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -924,7 +924,7 @@ static int32_t setColEqList(SNode* pEqCond, int16_t leftBlkId, int16_t rightBlkI } static int32_t setMergeJoinPrimColEqCond(SNode* pEqCond, int32_t subType, int16_t leftBlkId, int16_t rightBlkId, - SSortMergeJoinPhysiNode* pJoin) { + SSortMergeJoinPhysiNode* pJoin, SJoinLogicNode* pJoinLogicNode) { int32_t code = 0; if (QUERY_NODE_OPERATOR == nodeType(pEqCond)) { SOperatorNode* pOp = (SOperatorNode*)pEqCond; @@ -947,6 +947,16 @@ static int32_t setMergeJoinPrimColEqCond(SNode* pEqCond, int32_t subType, int16_ } break; } + case QUERY_NODE_VALUE: { + if (pJoinLogicNode && pJoinLogicNode->constPrimGot) { + pJoin->leftPrimExpr = NULL; + code = nodesCloneNode(pOp->pLeft, &pJoin->leftPrimExpr); + break; + } + + planError("value node got in prim eq left cond"); + return TSDB_CODE_PLAN_INTERNAL_ERROR; + } case QUERY_NODE_FUNCTION: { SFunctionNode* pFunc = (SFunctionNode*)pOp->pLeft; if (FUNCTION_TYPE_TIMETRUNCATE != pFunc->funcType) { @@ -995,6 +1005,16 @@ static int32_t setMergeJoinPrimColEqCond(SNode* pEqCond, int32_t subType, int16_ } break; } + case QUERY_NODE_VALUE: { + if (pJoinLogicNode && pJoinLogicNode->constPrimGot) { + pJoin->rightPrimExpr = NULL; + code = nodesCloneNode(pOp->pRight, &pJoin->rightPrimExpr); + break; + } + + planError("value node got in prim eq right cond"); + return TSDB_CODE_PLAN_INTERNAL_ERROR; + } case QUERY_NODE_FUNCTION: { SFunctionNode* pFunc = (SFunctionNode*)pOp->pRight; if (FUNCTION_TYPE_TIMETRUNCATE != pFunc->funcType) { @@ -1068,7 +1088,7 @@ static int32_t createMergeJoinPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi &pJoin->pPrimKeyCond); if (TSDB_CODE_SUCCESS == code) { code = setMergeJoinPrimColEqCond(pJoin->pPrimKeyCond, pJoin->subType, pLeftDesc->dataBlockId, - pRightDesc->dataBlockId, pJoin); + pRightDesc->dataBlockId, pJoin, pJoinLogicNode); } if (TSDB_CODE_SUCCESS == code && NULL != pJoin->leftPrimExpr) { code = addDataBlockSlot(pCxt, &pJoin->leftPrimExpr, pLeftDesc); @@ -1084,7 +1104,7 @@ static int32_t createMergeJoinPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi &pPrimKeyCond); if (TSDB_CODE_SUCCESS == code) { code = setMergeJoinPrimColEqCond(pPrimKeyCond, pJoin->subType, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, - pJoin); + pJoin, NULL); } if (TSDB_CODE_SUCCESS == code && NULL != pJoin->leftPrimExpr) { code = addDataBlockSlot(pCxt, &pJoin->leftPrimExpr, pLeftDesc); diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index 9bab697772..7dd3a8e9e3 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -1133,29 +1133,7 @@ static uint8_t sclGetOpValueNodeTsPrecision(SNode *pLeft, SNode *pRight) { return 0; } -int32_t sclConvertOpValueNodeTs(SOperatorNode *node) { - if (node->pLeft && SCL_IS_VAR_VALUE_NODE(node->pLeft)) { - if (node->pRight && (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pRight)->resType.type)) { - SCL_ERR_RET( - sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, node->pRight), (SValueNode *)node->pLeft)); - } - } else if (node->pRight && SCL_IS_NOTNULL_CONST_NODE(node->pRight)) { - if (node->pLeft && (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pLeft)->resType.type)) { - if (SCL_IS_VAR_VALUE_NODE(node->pRight)) { - SCL_ERR_RET(sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, node->pRight), - (SValueNode *)node->pRight)); - } else if (QUERY_NODE_NODE_LIST == node->pRight->type) { - SNode *pNode; - FOREACH(pNode, ((SNodeListNode *)node->pRight)->pNodeList) { - if (SCL_IS_VAR_VALUE_NODE(pNode)) { - SCL_ERR_RET(sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, pNode), (SValueNode *)pNode)); - } - } - } - } - } - return TSDB_CODE_SUCCESS; -} + int32_t sclConvertCaseWhenValueNodeTs(SCaseWhenNode *node) { if (NULL == node->pCase) { @@ -1344,7 +1322,7 @@ EDealRes sclRewriteLogic(SNode **pNode, SScalarCtx *ctx) { EDealRes sclRewriteOperator(SNode **pNode, SScalarCtx *ctx) { SOperatorNode *node = (SOperatorNode *)*pNode; - ctx->code = sclConvertOpValueNodeTs(node); + ctx->code = scalarConvertOpValueNodeTs(node); if (ctx->code) { return DEAL_RES_ERROR; } @@ -1807,6 +1785,31 @@ static int32_t sclGetBitwiseOperatorResType(SOperatorNode *pOp) { return TSDB_CODE_SUCCESS; } +int32_t scalarConvertOpValueNodeTs(SOperatorNode *node) { + if (node->pLeft && SCL_IS_VAR_VALUE_NODE(node->pLeft)) { + if (node->pRight && (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pRight)->resType.type)) { + SCL_ERR_RET( + sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, node->pRight), (SValueNode *)node->pLeft)); + } + } else if (node->pRight && SCL_IS_NOTNULL_CONST_NODE(node->pRight)) { + if (node->pLeft && (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode *)node->pLeft)->resType.type)) { + if (SCL_IS_VAR_VALUE_NODE(node->pRight)) { + SCL_ERR_RET(sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, node->pRight), + (SValueNode *)node->pRight)); + } else if (QUERY_NODE_NODE_LIST == node->pRight->type) { + SNode *pNode; + FOREACH(pNode, ((SNodeListNode *)node->pRight)->pNodeList) { + if (SCL_IS_VAR_VALUE_NODE(pNode)) { + SCL_ERR_RET(sclConvertToTsValueNode(sclGetOpValueNodeTsPrecision(node->pLeft, pNode), (SValueNode *)pNode)); + } + } + } + } + } + return TSDB_CODE_SUCCESS; +} + + int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { return sclCalcConstants(pNode, false, pRes); } int32_t scalarCalculateConstantsFromDual(SNode *pNode, SNode **pRes) { return sclCalcConstants(pNode, true, pRes); } diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 98396d7016..94a6c92a38 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -757,9 +757,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_TRUE_FOR_NEGATIVE, "True_for duration c TAOS_DEFINE_ERROR(TSDB_CODE_PAR_TRUE_FOR_UNIT, "Cannot use 'year' or 'month' as true_for duration") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_COLS_FUNCTION, "Invalid cols function") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_COLS_SELECTFUNC, "cols function's first param must be a select function that output a single row") -TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_MULITI_COLS_FUNC, "Improper use of cols function with multiple output columns") -TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_COLS_ALIAS, "Invalid using alias for cols function") - +TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_COLS_ALIAS, "Invalid using alias for cols function") +TAOS_DEFINE_ERROR(TSDB_CODE_PAR_VALID_TS_SERIOUS_REQUIRED, "Valid time series required as input") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INTERNAL_ERROR, "Parser internal error") //planner