diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 6b6d11c2fe..f052c9daa7 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -238,6 +238,7 @@ typedef struct SSelectStmt { SNode* pSlimit; char stmtName[TSDB_TABLE_NAME_LEN]; uint8_t precision; + bool isEmptyResult; } SSelectStmt; typedef enum ESetOperatorType { diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index f10185c44f..fef624288a 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -44,8 +44,15 @@ typedef struct SCmdMsgInfo { void* pExtension; // todo remove it soon } SCmdMsgInfo; +typedef enum EQueryExecMode { + QUERY_EXEC_MODE_LOCAL = 1, + QUERY_EXEC_MODE_RPC, + QUERY_EXEC_MODE_SCHEDULE, + QUERY_EXEC_MODE_EMPTY_RESULT +} EQueryExecMode; + typedef struct SQuery { - bool directRpc; + EQueryExecMode execMode; bool haveResultSet; SNode* pRoot; int32_t numOfResCols; @@ -55,7 +62,6 @@ typedef struct SQuery { SArray* pDbList; SArray* pTableList; bool showRewrite; - bool localCmd; } SQuery; int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery); diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index c3a17b6073..9938a2e1b9 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -281,22 +281,35 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList SRequestObj* execQueryImpl(STscObj* pTscObj, const char* sql, int sqlLen) { SRequestObj* pRequest = NULL; SQuery* pQuery = NULL; - int32_t code = 0; SArray* pNodeList = taosArrayInit(4, sizeof(struct SQueryNodeAddr)); - CHECK_CODE_GOTO(buildRequest(pTscObj, sql, sqlLen, &pRequest), _return); - CHECK_CODE_GOTO(parseSql(pRequest, false, &pQuery), _return); - - if (pQuery->localCmd) { - CHECK_CODE_GOTO(execLocalCmd(pRequest, pQuery), _return); - } else if (pQuery->directRpc) { - CHECK_CODE_GOTO(execDdlQuery(pRequest, pQuery), _return); - } else { - CHECK_CODE_GOTO(getPlan(pRequest, pQuery, &pRequest->body.pDag, pNodeList), _return); - CHECK_CODE_GOTO(scheduleQuery(pRequest, pRequest->body.pDag, pNodeList), _return); + int32_t code = buildRequest(pTscObj, sql, sqlLen, &pRequest); + if (TSDB_CODE_SUCCESS == code) { + code = parseSql(pRequest, false, &pQuery); + } + + if (TSDB_CODE_SUCCESS == code) { + switch (pQuery->execMode) { + case QUERY_EXEC_MODE_LOCAL: + code = execLocalCmd(pRequest, pQuery); + break; + case QUERY_EXEC_MODE_RPC: + code = execDdlQuery(pRequest, pQuery); + break; + case QUERY_EXEC_MODE_SCHEDULE: + code = getPlan(pRequest, pQuery, &pRequest->body.pDag, pNodeList); + if (TSDB_CODE_SUCCESS == code) { + code = scheduleQuery(pRequest, pRequest->body.pDag, pNodeList); + } + break; + case QUERY_EXEC_MODE_EMPTY_RESULT: + pRequest->type = TSDB_SQL_RETRIEVE_EMPTY_RESULT; + break; + default: + break; + } } -_return: taosArrayDestroy(pNodeList); qDestroyQuery(pQuery); if (NULL != pRequest && TSDB_CODE_SUCCESS != code) { diff --git a/source/libs/parser/src/parCalcConst.c b/source/libs/parser/src/parCalcConst.c index 0b4f79d3ff..048830b80b 100644 --- a/source/libs/parser/src/parCalcConst.c +++ b/source/libs/parser/src/parCalcConst.c @@ -149,22 +149,37 @@ static int32_t rewriteConditionForFromTable(SCalcConstContext* pCxt, SNode* pTab return pCxt->code; } +static void rewriteConstCondition(SSelectStmt* pSelect, SNode** pCond) { + if (QUERY_NODE_VALUE != nodeType(*pCond)) { + return; + } + if (((SValueNode*)*pCond)->datum.b) { + nodesDestroyNode(*pCond); + *pCond = NULL; + } else { + pSelect->isEmptyResult = true; + } +} + static int32_t calcConstFromTable(SCalcConstContext* pCxt, SSelectStmt* pSelect) { - nodesRewriteExprPostOrder(&pSelect->pFromTable, calcConst, pCxt); + pCxt->code = rewriteConditionForFromTable(pCxt, pSelect->pFromTable); if (TSDB_CODE_SUCCESS == pCxt->code) { - pCxt->code = rewriteConditionForFromTable(pCxt, pSelect->pFromTable); + nodesRewriteExprPostOrder(&pSelect->pFromTable, calcConst, pCxt); } return pCxt->code; } -static int32_t calcConstCondition(SCalcConstContext* pCxt, SNode** pCond) { +static int32_t calcConstCondition(SCalcConstContext* pCxt, SSelectStmt* pSelect, SNode** pCond) { if (NULL == *pCond) { return TSDB_CODE_SUCCESS; } - nodesRewriteExprPostOrder(pCond, calcConst, pCxt); + pCxt->code = rewriteCondition(pCxt, pCond); if (TSDB_CODE_SUCCESS == pCxt->code) { - pCxt->code = rewriteCondition(pCxt, pCond); + nodesRewriteExprPostOrder(pCond, calcConst, pCxt); + } + if (TSDB_CODE_SUCCESS == pCxt->code) { + rewriteConstCondition(pSelect, pCond); } return pCxt->code; } @@ -176,7 +191,7 @@ static int32_t calcConstSelect(SSelectStmt* pSelect) { cxt.code = calcConstFromTable(&cxt, pSelect); } if (TSDB_CODE_SUCCESS == cxt.code) { - cxt.code = calcConstCondition(&cxt, &pSelect->pWhere); + cxt.code = calcConstCondition(&cxt, pSelect, &pSelect->pWhere); } if (TSDB_CODE_SUCCESS == cxt.code) { nodesRewriteExprsPostOrder(pSelect->pPartitionByList, calcConst, &cxt); @@ -188,7 +203,7 @@ static int32_t calcConstSelect(SSelectStmt* pSelect) { nodesRewriteExprsPostOrder(pSelect->pGroupByList, calcConst, &cxt); } if (TSDB_CODE_SUCCESS == cxt.code) { - cxt.code = calcConstCondition(&cxt, &pSelect->pHaving); + cxt.code = calcConstCondition(&cxt, pSelect, &pSelect->pHaving); } if (TSDB_CODE_SUCCESS == cxt.code) { nodesRewriteExprsPostOrder(pSelect->pOrderByList, calcConst, &cxt); @@ -208,6 +223,22 @@ static int32_t calcConstQuery(SNode* pStmt) { return TSDB_CODE_SUCCESS; } -int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery) { - return calcConstQuery(pQuery->pRoot); +static bool isEmptyResultQuery(SNode* pStmt) { + switch (nodeType(pStmt)) { + case QUERY_NODE_SELECT_STMT: + return ((SSelectStmt*)pStmt)->isEmptyResult; + case QUERY_NODE_EXPLAIN_STMT: + return isEmptyResultQuery(((SExplainStmt*)pStmt)->pQuery); + default: + break; + } + return false; +} + +int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery) { + int32_t code = calcConstQuery(pQuery->pRoot); + if (TSDB_CODE_SUCCESS == code) { + pQuery->execMode = isEmptyResultQuery(pQuery->pRoot) ? QUERY_EXEC_MODE_EMPTY_RESULT : pQuery->execMode; + } + return code; } diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index d9cf0b39b5..9d945039b8 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -1084,7 +1084,7 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) { if (NULL == *pQuery) { return TSDB_CODE_OUT_OF_MEMORY; } - (*pQuery)->directRpc = false; + (*pQuery)->execMode = QUERY_EXEC_MODE_SCHEDULE; (*pQuery)->haveResultSet = false; (*pQuery)->msgType = TDMT_VND_SUBMIT; (*pQuery)->pRoot = (SNode*)context.pOutput; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index ebe5b639c4..a286918ce5 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -2923,21 +2923,23 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) { switch (nodeType(pQuery->pRoot)) { case QUERY_NODE_SELECT_STMT: case QUERY_NODE_EXPLAIN_STMT: + pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE; pQuery->haveResultSet = true; pQuery->msgType = TDMT_VND_QUERY; break; case QUERY_NODE_VNODE_MODIF_STMT: + pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE; pQuery->msgType = TDMT_VND_CREATE_TABLE; break; case QUERY_NODE_DESCRIBE_STMT: - pQuery->localCmd = true; + pQuery->execMode = QUERY_EXEC_MODE_LOCAL; pQuery->haveResultSet = true; break; case QUERY_NODE_RESET_QUERY_CACHE_STMT: - pQuery->localCmd = true; + pQuery->execMode = QUERY_EXEC_MODE_LOCAL; break; default: - pQuery->directRpc = true; + pQuery->execMode = QUERY_EXEC_MODE_RPC; if (NULL != pCxt->pCmdMsg) { TSWAP(pQuery->pCmdMsg, pCxt->pCmdMsg, SCmdMsgInfo*); pQuery->msgType = pQuery->pCmdMsg->msgType;