integrate constant calculate
This commit is contained in:
parent
ba5503da68
commit
469cd23f43
|
@ -213,16 +213,16 @@ typedef enum EDealRes {
|
|||
} EDealRes;
|
||||
|
||||
typedef EDealRes (*FNodeWalker)(SNode* pNode, void* pContext);
|
||||
void nodesWalkNode(SNodeptr pNode, FNodeWalker walker, void* pContext);
|
||||
void nodesWalkList(SNodeList* pList, FNodeWalker walker, void* pContext);
|
||||
void nodesWalkNodePostOrder(SNodeptr pNode, FNodeWalker walker, void* pContext);
|
||||
void nodesWalkListPostOrder(SNodeList* pList, FNodeWalker walker, void* pContext);
|
||||
void nodesWalkExpr(SNodeptr pNode, FNodeWalker walker, void* pContext);
|
||||
void nodesWalkExprs(SNodeList* pList, FNodeWalker walker, void* pContext);
|
||||
void nodesWalkExprPostOrder(SNodeptr pNode, FNodeWalker walker, void* pContext);
|
||||
void nodesWalkExprsPostOrder(SNodeList* pList, FNodeWalker walker, void* pContext);
|
||||
|
||||
typedef EDealRes (*FNodeRewriter)(SNode** pNode, void* pContext);
|
||||
void nodesRewriteNode(SNode** pNode, FNodeRewriter rewriter, void* pContext);
|
||||
void nodesRewriteList(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
||||
void nodesRewriteNodePostOrder(SNode** pNode, FNodeRewriter rewriter, void* pContext);
|
||||
void nodesRewriteListPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
||||
void nodesRewriteExpr(SNode** pNode, FNodeRewriter rewriter, void* pContext);
|
||||
void nodesRewriteExprs(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
||||
void nodesRewriteExprPostOrder(SNode** pNode, FNodeRewriter rewriter, void* pContext);
|
||||
void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
||||
|
||||
bool nodesEqualNode(const SNodeptr a, const SNodeptr b);
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ typedef struct SValueNode {
|
|||
char* literal;
|
||||
bool isDuration;
|
||||
bool translate;
|
||||
bool genByCalc;
|
||||
union {
|
||||
bool b;
|
||||
int64_t i;
|
||||
|
|
|
@ -5801,7 +5801,7 @@ void getDBNameFromCondition(SNode* pCondition, char* dbName) {
|
|||
return;
|
||||
}
|
||||
|
||||
nodesWalkNode(pCondition, getDBNameFromConditionWalker, dbName);
|
||||
nodesWalkExpr(pCondition, getDBNameFromConditionWalker, dbName);
|
||||
}
|
||||
|
||||
static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator, bool* newgroup) {
|
||||
|
|
|
@ -113,36 +113,13 @@ static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
|
|||
}
|
||||
|
||||
static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
||||
COPY_ALL_SCALAR_FIELDS;
|
||||
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
||||
COPY_CHAR_POINT_FIELD(literal);
|
||||
COPY_SCALAR_FIELD(isDuration);
|
||||
COPY_SCALAR_FIELD(translate);
|
||||
if (!pSrc->translate) {
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
switch (pSrc->node.resType.type) {
|
||||
case TSDB_DATA_TYPE_NULL:
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
COPY_SCALAR_FIELD(datum.b);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
COPY_SCALAR_FIELD(datum.i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
COPY_SCALAR_FIELD(datum.u);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
COPY_SCALAR_FIELD(datum.d);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
|
|
|
@ -1544,6 +1544,9 @@ static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
|
|||
|
||||
int32_t code = exprNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkValueTranslate, pNode->genByCalc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code && !pNode->genByCalc) {
|
||||
code = tjsonAddStringToObject(pJson, jkValueLiteral, pNode->literal);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -1614,6 +1617,9 @@ static int32_t jsonToValueNode(const SJson* pJson, void* pObj) {
|
|||
|
||||
int32_t code = jsonToExprNode(pJson, pObj);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkValueDuration, &pNode->genByCalc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code && !pNode->genByCalc) {
|
||||
code = tjsonDupStringValue(pJson, jkValueLiteral, &pNode->literal);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -138,19 +138,19 @@ static EDealRes walkList(SNodeList* pNodeList, ETraversalOrder order, FNodeWalke
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
void nodesWalkNode(SNodeptr pNode, FNodeWalker walker, void* pContext) {
|
||||
void nodesWalkExpr(SNodeptr pNode, FNodeWalker walker, void* pContext) {
|
||||
(void)walkNode(pNode, TRAVERSAL_PREORDER, walker, pContext);
|
||||
}
|
||||
|
||||
void nodesWalkList(SNodeList* pNodeList, FNodeWalker walker, void* pContext) {
|
||||
void nodesWalkExprs(SNodeList* pNodeList, FNodeWalker walker, void* pContext) {
|
||||
(void)walkList(pNodeList, TRAVERSAL_PREORDER, walker, pContext);
|
||||
}
|
||||
|
||||
void nodesWalkNodePostOrder(SNodeptr pNode, FNodeWalker walker, void* pContext) {
|
||||
void nodesWalkExprPostOrder(SNodeptr pNode, FNodeWalker walker, void* pContext) {
|
||||
(void)walkNode(pNode, TRAVERSAL_POSTORDER, walker, pContext);
|
||||
}
|
||||
|
||||
void nodesWalkListPostOrder(SNodeList* pList, FNodeWalker walker, void* pContext) {
|
||||
void nodesWalkExprsPostOrder(SNodeList* pList, FNodeWalker walker, void* pContext) {
|
||||
(void)walkList(pList, TRAVERSAL_POSTORDER, walker, pContext);
|
||||
}
|
||||
|
||||
|
@ -267,19 +267,19 @@ static EDealRes rewriteList(SNodeList* pNodeList, ETraversalOrder order, FNodeRe
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
void nodesRewriteNode(SNode** pNode, FNodeRewriter rewriter, void* pContext) {
|
||||
void nodesRewriteExpr(SNode** pNode, FNodeRewriter rewriter, void* pContext) {
|
||||
(void)rewriteNode(pNode, TRAVERSAL_PREORDER, rewriter, pContext);
|
||||
}
|
||||
|
||||
void nodesRewriteList(SNodeList* pList, FNodeRewriter rewriter, void* pContext) {
|
||||
void nodesRewriteExprs(SNodeList* pList, FNodeRewriter rewriter, void* pContext) {
|
||||
(void)rewriteList(pList, TRAVERSAL_PREORDER, rewriter, pContext);
|
||||
}
|
||||
|
||||
void nodesRewriteNodePostOrder(SNode** pNode, FNodeRewriter rewriter, void* pContext) {
|
||||
void nodesRewriteExprPostOrder(SNode** pNode, FNodeRewriter rewriter, void* pContext) {
|
||||
(void)rewriteNode(pNode, TRAVERSAL_POSTORDER, rewriter, pContext);
|
||||
}
|
||||
|
||||
void nodesRewriteListPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext) {
|
||||
void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext) {
|
||||
(void)rewriteList(pList, TRAVERSAL_POSTORDER, rewriter, pContext);
|
||||
}
|
||||
|
||||
|
@ -290,20 +290,20 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa
|
|||
|
||||
switch (clause) {
|
||||
case SQL_CLAUSE_FROM:
|
||||
nodesWalkNode(pSelect->pFromTable, walker, pContext);
|
||||
nodesWalkNode(pSelect->pWhere, walker, pContext);
|
||||
nodesWalkExpr(pSelect->pFromTable, walker, pContext);
|
||||
nodesWalkExpr(pSelect->pWhere, walker, pContext);
|
||||
case SQL_CLAUSE_WHERE:
|
||||
nodesWalkList(pSelect->pPartitionByList, walker, pContext);
|
||||
nodesWalkExprs(pSelect->pPartitionByList, walker, pContext);
|
||||
case SQL_CLAUSE_PARTITION_BY:
|
||||
nodesWalkNode(pSelect->pWindow, walker, pContext);
|
||||
nodesWalkExpr(pSelect->pWindow, walker, pContext);
|
||||
case SQL_CLAUSE_WINDOW:
|
||||
nodesWalkList(pSelect->pGroupByList, walker, pContext);
|
||||
nodesWalkExprs(pSelect->pGroupByList, walker, pContext);
|
||||
case SQL_CLAUSE_GROUP_BY:
|
||||
nodesWalkNode(pSelect->pHaving, walker, pContext);
|
||||
nodesWalkExpr(pSelect->pHaving, walker, pContext);
|
||||
case SQL_CLAUSE_HAVING:
|
||||
nodesWalkList(pSelect->pOrderByList, walker, pContext);
|
||||
nodesWalkExprs(pSelect->pOrderByList, walker, pContext);
|
||||
case SQL_CLAUSE_ORDER_BY:
|
||||
nodesWalkList(pSelect->pProjectionList, walker, pContext);
|
||||
nodesWalkExprs(pSelect->pProjectionList, walker, pContext);
|
||||
case SQL_CLAUSE_SELECT:
|
||||
default:
|
||||
break;
|
||||
|
@ -319,20 +319,20 @@ void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewrit
|
|||
|
||||
switch (clause) {
|
||||
case SQL_CLAUSE_FROM:
|
||||
nodesRewriteNode(&(pSelect->pFromTable), rewriter, pContext);
|
||||
nodesRewriteNode(&(pSelect->pWhere), rewriter, pContext);
|
||||
nodesRewriteExpr(&(pSelect->pFromTable), rewriter, pContext);
|
||||
nodesRewriteExpr(&(pSelect->pWhere), rewriter, pContext);
|
||||
case SQL_CLAUSE_WHERE:
|
||||
nodesRewriteList(pSelect->pPartitionByList, rewriter, pContext);
|
||||
nodesRewriteExprs(pSelect->pPartitionByList, rewriter, pContext);
|
||||
case SQL_CLAUSE_PARTITION_BY:
|
||||
nodesRewriteNode(&(pSelect->pWindow), rewriter, pContext);
|
||||
nodesRewriteExpr(&(pSelect->pWindow), rewriter, pContext);
|
||||
case SQL_CLAUSE_WINDOW:
|
||||
nodesRewriteList(pSelect->pGroupByList, rewriter, pContext);
|
||||
nodesRewriteExprs(pSelect->pGroupByList, rewriter, pContext);
|
||||
case SQL_CLAUSE_GROUP_BY:
|
||||
nodesRewriteNode(&(pSelect->pHaving), rewriter, pContext);
|
||||
nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext);
|
||||
case SQL_CLAUSE_HAVING:
|
||||
nodesRewriteList(pSelect->pProjectionList, rewriter, pContext);
|
||||
nodesRewriteExprs(pSelect->pProjectionList, rewriter, pContext);
|
||||
case SQL_CLAUSE_SELECT:
|
||||
nodesRewriteList(pSelect->pOrderByList, rewriter, pContext);
|
||||
nodesRewriteExprs(pSelect->pOrderByList, rewriter, pContext);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ TEST(NodesTest, traverseTest) {
|
|||
|
||||
EXPECT_EQ(nodeType(pRoot), QUERY_NODE_OPERATOR);
|
||||
EDealRes res = DEAL_RES_CONTINUE;
|
||||
nodesRewriteNodePostOrder(&pRoot, rewriterTest, &res);
|
||||
nodesRewriteExprPostOrder(&pRoot, rewriterTest, &res);
|
||||
EXPECT_EQ(res, DEAL_RES_CONTINUE);
|
||||
EXPECT_EQ(nodeType(pRoot), QUERY_NODE_VALUE);
|
||||
EXPECT_EQ(string(((SValueNode*)pRoot)->literal), "18");
|
||||
|
|
|
@ -8,7 +8,7 @@ target_include_directories(
|
|||
|
||||
target_link_libraries(
|
||||
parser
|
||||
PRIVATE os util nodes catalog function transport qcom
|
||||
PRIVATE os util nodes catalog function scalar transport qcom
|
||||
)
|
||||
|
||||
if(${BUILD_TEST})
|
||||
|
|
|
@ -23,9 +23,10 @@ extern "C" {
|
|||
#include "parser.h"
|
||||
|
||||
int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery);
|
||||
int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery);
|
||||
int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery);
|
||||
int32_t parse(SParseContext* pParseCxt, SQuery** pQuery);
|
||||
int32_t translate(SParseContext* pParseCxt, SQuery* pQuery);
|
||||
int32_t extractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema);
|
||||
int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -243,27 +243,27 @@ static SDatabaseOptions* setDbRetentions(SAstCreateContext* pCxt, SDatabaseOptio
|
|||
return pOptions;
|
||||
}
|
||||
|
||||
char val[20] = {0};
|
||||
int32_t len = trimString(pVal->z, pVal->n, val, sizeof(val));
|
||||
char* pStart = val;
|
||||
char* pEnd = val + len;
|
||||
int32_t sepOrder = 1;
|
||||
while (1) {
|
||||
char* pPos = strchr(pStart, (0 == sepOrder % 2) ? ',' : ':');
|
||||
SToken t = { .type = TK_NK_VARIABLE, .z = pStart, .n = (NULL == pPos ? pEnd - pStart : pPos - pStart)};
|
||||
if (TSDB_CODE_SUCCESS != nodesListStrictAppend(pOptions->pRetentions, createDurationValueNode(pCxt, &t))) {
|
||||
pCxt->valid = false;
|
||||
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "Out of memory");
|
||||
return pOptions;
|
||||
if (pVal->n > 2) {
|
||||
char* pStart = pVal->z + 1;
|
||||
char* pEnd = pVal->z + pVal->n - 1;
|
||||
int32_t sepOrder = 1;
|
||||
while (1) {
|
||||
char* pPos = strchr(pStart, (0 == (sepOrder++) % 2) ? ',' : ':');
|
||||
SToken t = { .type = TK_NK_VARIABLE, .z = pStart, .n = (NULL == pPos ? pEnd - pStart : pPos - pStart)};
|
||||
if (TSDB_CODE_SUCCESS != nodesListStrictAppend(pOptions->pRetentions, createDurationValueNode(pCxt, &t))) {
|
||||
pCxt->valid = false;
|
||||
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "Out of memory");
|
||||
return pOptions;
|
||||
}
|
||||
if (NULL == pPos) {
|
||||
break;
|
||||
}
|
||||
pStart = pPos + 1;
|
||||
}
|
||||
if (NULL == pPos) {
|
||||
break;
|
||||
}
|
||||
pStart = pPos + 1;
|
||||
}
|
||||
|
||||
if (LIST_LENGTH(pOptions->pRetentions) % 2 != 0) {
|
||||
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid db option retentions: %s", val);
|
||||
if (LIST_LENGTH(pOptions->pRetentions) < 2 || LIST_LENGTH(pOptions->pRetentions) % 2 != 0) {
|
||||
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid db option retentions: %s", pVal->z);
|
||||
pCxt->valid = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ extern void Parse(void*, int, SToken, void*);
|
|||
extern void ParseFree(void*, FFree);
|
||||
extern void ParseTrace(FILE*, char*);
|
||||
|
||||
int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) {
|
||||
int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) {
|
||||
SAstCreateContext cxt;
|
||||
initAstCreateContext(pParseCxt, &cxt);
|
||||
void *pParser = ParseAlloc((FMalloc)taosMemoryMalloc);
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parInt.h"
|
||||
#include "scalar.h"
|
||||
|
||||
typedef struct SCalcConstContext {
|
||||
int32_t code;
|
||||
} SCalcConstContext;
|
||||
|
||||
static int32_t calcConstQuery(SNode* pStmt);
|
||||
|
||||
static EDealRes doCalcConst(SNode** pNode, SCalcConstContext* pCxt) {
|
||||
SNode* pNew = NULL;
|
||||
pCxt->code = scalarCalculateConstants(*pNode, &pNew);
|
||||
if (TSDB_CODE_SUCCESS != pCxt->code) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
((SValueNode*)pNew)->genByCalc = true;
|
||||
((SValueNode*)pNew)->translate = true;
|
||||
*pNode = pNew;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static EDealRes calcConstOperator(SOperatorNode** pNode, void* pContext) {
|
||||
SOperatorNode* pOp = *pNode;
|
||||
if (QUERY_NODE_VALUE == nodeType(pOp->pLeft) && (NULL == pOp->pRight || QUERY_NODE_VALUE == nodeType(pOp->pRight))) {
|
||||
return doCalcConst((SNode**)pNode, (SCalcConstContext*)pContext);
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static EDealRes calcConstFunction(SFunctionNode** pNode, void* pContext) {
|
||||
SFunctionNode* pFunc = *pNode;
|
||||
SNode* pParam = NULL;
|
||||
FOREACH(pParam, pFunc->pParameterList) {
|
||||
if (QUERY_NODE_VALUE != nodeType(pParam)) {
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
}
|
||||
return doCalcConst((SNode**)pNode, (SCalcConstContext*)pContext);
|
||||
}
|
||||
|
||||
static EDealRes calcConstLogicCond(SLogicConditionNode** pNode, void* pContext) {
|
||||
SLogicConditionNode* pCond = *pNode;
|
||||
SNode* pParam = NULL;
|
||||
FOREACH(pParam, pCond->pParameterList) {
|
||||
if (QUERY_NODE_VALUE != nodeType(pParam)) {
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
}
|
||||
return doCalcConst((SNode**)pNode, (SCalcConstContext*)pContext);
|
||||
}
|
||||
|
||||
static EDealRes calcConstSubquery(STempTableNode** pNode, void* pContext) {
|
||||
SCalcConstContext* pCxt = pContext;
|
||||
pCxt->code = calcConstQuery((*pNode)->pSubquery);
|
||||
return (TSDB_CODE_SUCCESS == pCxt->code ? DEAL_RES_CONTINUE : DEAL_RES_ERROR);
|
||||
}
|
||||
|
||||
static EDealRes calcConst(SNode** pNode, void* pContext) {
|
||||
switch (nodeType(*pNode)) {
|
||||
case QUERY_NODE_OPERATOR:
|
||||
return calcConstOperator((SOperatorNode**)pNode, pContext);
|
||||
case QUERY_NODE_FUNCTION:
|
||||
return calcConstFunction((SFunctionNode**)pNode, pContext);
|
||||
case QUERY_NODE_LOGIC_CONDITION:
|
||||
return calcConstLogicCond((SLogicConditionNode**)pNode, pContext);
|
||||
case QUERY_NODE_TEMP_TABLE:
|
||||
return calcConstSubquery((STempTableNode**)pNode, pContext);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t calcConstSelect(SSelectStmt* pSelect) {
|
||||
SCalcConstContext cxt = { .code = TSDB_CODE_SUCCESS };
|
||||
nodesRewriteExprsPostOrder(pSelect->pProjectionList, calcConst, &cxt);
|
||||
if (TSDB_CODE_SUCCESS == cxt.code) {
|
||||
nodesRewriteExprPostOrder(&pSelect->pFromTable, calcConst, &cxt);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == cxt.code) {
|
||||
nodesRewriteExprPostOrder(&pSelect->pWhere, calcConst, &cxt);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == cxt.code) {
|
||||
nodesRewriteExprsPostOrder(pSelect->pPartitionByList, calcConst, &cxt);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == cxt.code) {
|
||||
nodesRewriteExprPostOrder(&pSelect->pWindow, calcConst, &cxt);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == cxt.code) {
|
||||
nodesRewriteExprsPostOrder(pSelect->pGroupByList, calcConst, &cxt);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == cxt.code) {
|
||||
nodesRewriteExprPostOrder(&pSelect->pHaving, calcConst, &cxt);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == cxt.code) {
|
||||
nodesRewriteExprsPostOrder(pSelect->pOrderByList, calcConst, &cxt);
|
||||
}
|
||||
return cxt.code;
|
||||
}
|
||||
|
||||
static int32_t calcConstQuery(SNode* pStmt) {
|
||||
switch (nodeType(pStmt)) {
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
return calcConstSelect((SSelectStmt*)pStmt);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery) {
|
||||
return calcConstQuery(pQuery->pRoot);
|
||||
}
|
|
@ -50,14 +50,12 @@ static bool beforeHaving(ESqlClause clause) {
|
|||
return clause < SQL_CLAUSE_HAVING;
|
||||
}
|
||||
|
||||
static EDealRes generateDealNodeErrMsg(STranslateContext* pCxt, int32_t errCode, ...) {
|
||||
va_list vArgList;
|
||||
va_start(vArgList, errCode);
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, errCode, vArgList);
|
||||
va_end(vArgList);
|
||||
pCxt->errCode = errCode;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
#define generateDealNodeErrMsg(pCxt, code, ...) \
|
||||
({ \
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, code, ##__VA_ARGS__); \
|
||||
pCxt->errCode = code; \
|
||||
DEAL_RES_ERROR; \
|
||||
})
|
||||
|
||||
static int32_t addNamespace(STranslateContext* pCxt, void* pTable) {
|
||||
size_t currTotalLevel = taosArrayGetSize(pCxt->pNsLevel);
|
||||
|
@ -440,6 +438,9 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
|
||||
static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
|
||||
if (nodesIsUnaryOp(pOp)) {
|
||||
if (OP_TYPE_MINUS == pOp->opType && !IS_NUMERIC_TYPE(((SExprNode*)(pOp->pLeft))->resType.type)) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pLeft))->aliasName);
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
SDataType ldt = ((SExprNode*)(pOp->pLeft))->resType;
|
||||
|
@ -510,12 +511,12 @@ static EDealRes doTranslateExpr(SNode* pNode, void* pContext) {
|
|||
}
|
||||
|
||||
static int32_t translateExpr(STranslateContext* pCxt, SNode* pNode) {
|
||||
nodesWalkNodePostOrder(pNode, doTranslateExpr, pCxt);
|
||||
nodesWalkExprPostOrder(pNode, doTranslateExpr, pCxt);
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
static int32_t translateExprList(STranslateContext* pCxt, SNodeList* pList) {
|
||||
nodesWalkListPostOrder(pList, doTranslateExpr, pCxt);
|
||||
nodesWalkExprsPostOrder(pList, doTranslateExpr, pCxt);
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
|
@ -570,7 +571,7 @@ static EDealRes doCheckExprForGroupBy(SNode* pNode, void* pContext) {
|
|||
}
|
||||
|
||||
static int32_t checkExprForGroupBy(STranslateContext* pCxt, SNode* pNode) {
|
||||
nodesWalkNode(pNode, doCheckExprForGroupBy, pCxt);
|
||||
nodesWalkExpr(pNode, doCheckExprForGroupBy, pCxt);
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
|
@ -578,7 +579,7 @@ static int32_t checkExprListForGroupBy(STranslateContext* pCxt, SNodeList* pList
|
|||
if (NULL == getGroupByList(pCxt)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
nodesWalkList(pList, doCheckExprForGroupBy, pCxt);
|
||||
nodesWalkExprs(pList, doCheckExprForGroupBy, pCxt);
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
|
@ -605,9 +606,9 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
CheckAggColCoexistCxt cxt = { .pTranslateCxt = pCxt, .existAggFunc = false, .existCol = false };
|
||||
nodesWalkList(pSelect->pProjectionList, doCheckAggColCoexist, &cxt);
|
||||
nodesWalkExprs(pSelect->pProjectionList, doCheckAggColCoexist, &cxt);
|
||||
if (!pSelect->isDistinct) {
|
||||
nodesWalkList(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
|
||||
nodesWalkExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
|
||||
}
|
||||
if (cxt.existAggFunc && cxt.existCol) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
|
@ -2633,7 +2634,7 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
|
||||
int32_t translate(SParseContext* pParseCxt, SQuery* pQuery) {
|
||||
STranslateContext cxt = {
|
||||
.pParseCxt = pParseCxt,
|
||||
.errCode = TSDB_CODE_SUCCESS,
|
||||
|
|
|
@ -30,9 +30,12 @@ static bool isInsertSql(const char* pStr, size_t length) {
|
|||
}
|
||||
|
||||
static int32_t parseSqlIntoAst(SParseContext* pCxt, SQuery** pQuery) {
|
||||
int32_t code = doParse(pCxt, pQuery);
|
||||
int32_t code = parse(pCxt, pQuery);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = doTranslate(pCxt, *pQuery);
|
||||
code = translate(pCxt, *pQuery);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calculateConstant(pCxt, *pQuery);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ private:
|
|||
static const int max_err_len = 1024;
|
||||
|
||||
bool runImpl(int32_t parseCode, int32_t translateCode) {
|
||||
int32_t code = doParse(&cxt_, &query_);
|
||||
int32_t code = parse(&cxt_, &query_);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
parseErrStr_ = string("code:") + tstrerror(code) + string(", msg:") + errMagBuf_;
|
||||
return (terrno == parseCode);
|
||||
|
@ -63,7 +63,7 @@ private:
|
|||
return false;
|
||||
}
|
||||
parsedAstStr_ = toString(query_->pRoot);
|
||||
code = doTranslate(&cxt_, query_);
|
||||
code = translate(&cxt_, query_);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
translateErrStr_ = string("code:") + tstrerror(code) + string(", msg:") + errMagBuf_;
|
||||
return (terrno == translateCode);
|
||||
|
|
|
@ -83,7 +83,7 @@ static EDealRes doNameExpr(SNode* pNode, void* pContext) {
|
|||
}
|
||||
|
||||
static int32_t rewriteExpr(SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) {
|
||||
nodesWalkList(pExprs, doNameExpr, NULL);
|
||||
nodesWalkExprs(pExprs, doNameExpr, NULL);
|
||||
SRewriteExprCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs };
|
||||
nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt);
|
||||
return cxt.errCode;
|
||||
|
@ -384,7 +384,7 @@ static int32_t createColumnByRewriteExps(SLogicPlanContext* pCxt, SNodeList* pEx
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nodesWalkList(pExprs, doCreateColumn, &cxt);
|
||||
nodesWalkExprs(pExprs, doCreateColumn, &cxt);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyList(cxt.pList);
|
||||
return cxt.errCode;
|
||||
|
|
|
@ -264,7 +264,7 @@ static int32_t setNodeSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, i
|
|||
.pLeftHash = taosArrayGetP(pCxt->pLocationHelper, leftDataBlockId),
|
||||
.pRightHash = (rightDataBlockId < 0 ? NULL : taosArrayGetP(pCxt->pLocationHelper, rightDataBlockId))
|
||||
};
|
||||
nodesWalkNode(pRes, doSetSlotId, &cxt);
|
||||
nodesWalkExpr(pRes, doSetSlotId, &cxt);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyNode(pRes);
|
||||
return cxt.errCode;
|
||||
|
@ -285,7 +285,7 @@ static int32_t setListSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, i
|
|||
.pLeftHash = taosArrayGetP(pCxt->pLocationHelper, leftDataBlockId),
|
||||
.pRightHash = (rightDataBlockId < 0 ? NULL : taosArrayGetP(pCxt->pLocationHelper, rightDataBlockId))
|
||||
};
|
||||
nodesWalkList(pRes, doSetSlotId, &cxt);
|
||||
nodesWalkExprs(pRes, doSetSlotId, &cxt);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyList(pRes);
|
||||
return cxt.errCode;
|
||||
|
@ -606,7 +606,7 @@ static int32_t rewritePrecalcExprs(SPhysiPlanContext* pCxt, SNodeList* pList, SN
|
|||
}
|
||||
}
|
||||
SRewritePrecalcExprsCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pPrecalcExprs = *pPrecalcExprs };
|
||||
nodesRewriteList(*pRewrittenList, doRewritePrecalcExprs, &cxt);
|
||||
nodesRewriteExprs(*pRewrittenList, doRewritePrecalcExprs, &cxt);
|
||||
if (0 == LIST_LENGTH(cxt.pPrecalcExprs)) {
|
||||
nodesDestroyList(cxt.pPrecalcExprs);
|
||||
*pPrecalcExprs = NULL;
|
||||
|
|
|
@ -157,6 +157,13 @@ TEST_F(PlannerTest, simple) {
|
|||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(PlannerTest, selectConstant) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
bind("SELECT 2-1 FROM t1");
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(PlannerTest, stSimple) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
|
|
|
@ -1297,7 +1297,7 @@ EDealRes fltTreeToGroup(SNode* pNode, void* pContext) {
|
|||
resGroup = taosArrayInit(4, sizeof(SFilterGroup));
|
||||
|
||||
SFltBuildGroupCtx tctx = {.info = ctx->info, .group = newGroup};
|
||||
nodesWalkNode(cell->pNode, fltTreeToGroup, (void *)&tctx);
|
||||
nodesWalkExpr(cell->pNode, fltTreeToGroup, (void *)&tctx);
|
||||
FLT_ERR_JRET(tctx.code);
|
||||
|
||||
FLT_ERR_JRET(filterDetachCnfGroups(resGroup, preGroup, newGroup));
|
||||
|
@ -1322,7 +1322,7 @@ EDealRes fltTreeToGroup(SNode* pNode, void* pContext) {
|
|||
if (LOGIC_COND_TYPE_OR == node->condType) {
|
||||
SListCell *cell = node->pParameterList->pHead;
|
||||
for (int32_t i = 0; i < node->pParameterList->length; ++i) {
|
||||
nodesWalkNode(cell->pNode, fltTreeToGroup, (void *)pContext);
|
||||
nodesWalkExpr(cell->pNode, fltTreeToGroup, (void *)pContext);
|
||||
FLT_ERR_JRET(ctx->code);
|
||||
|
||||
cell = cell->pNext;
|
||||
|
@ -3190,7 +3190,7 @@ int32_t fltInitFromNode(SNode* tree, SFilterInfo *info, uint32_t options) {
|
|||
filterInitUnitsFields(info);
|
||||
|
||||
SFltBuildGroupCtx tctx = {.info = info, .group = group};
|
||||
nodesWalkNode(tree, fltTreeToGroup, (void *)&tctx);
|
||||
nodesWalkExpr(tree, fltTreeToGroup, (void *)&tctx);
|
||||
FLT_ERR_JRET(tctx.code);
|
||||
|
||||
filterConvertGroupFromArray(info, group);
|
||||
|
@ -3566,7 +3566,7 @@ EDealRes fltReviseRewriter(SNode** pNode, void* pContext) {
|
|||
}
|
||||
|
||||
int32_t fltReviseNodes(SFilterInfo *pInfo, SNode** pNode, SFltTreeStat *pStat) {
|
||||
nodesRewriteNodePostOrder(pNode, fltReviseRewriter, (void *)pStat);
|
||||
nodesRewriteExprPostOrder(pNode, fltReviseRewriter, (void *)pStat);
|
||||
|
||||
FLT_RET(pStat->code);
|
||||
}
|
||||
|
|
|
@ -673,7 +673,7 @@ int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) {
|
|||
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
nodesRewriteNodePostOrder(&pNode, sclConstantsRewriter, (void *)&ctx);
|
||||
nodesRewriteExprPostOrder(&pNode, sclConstantsRewriter, (void *)&ctx);
|
||||
SCL_ERR_JRET(ctx.code);
|
||||
*pRes = pNode;
|
||||
|
||||
|
@ -696,7 +696,7 @@ int32_t scalarCalculate(SNode *pNode, SArray *pBlockList, SScalarParam *pDst) {
|
|||
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
nodesWalkNodePostOrder(pNode, sclCalcWalker, (void *)&ctx);
|
||||
nodesWalkExprPostOrder(pNode, sclCalcWalker, (void *)&ctx);
|
||||
SCL_ERR_JRET(ctx.code);
|
||||
|
||||
if (pDst) {
|
||||
|
|
Loading…
Reference in New Issue