fix: some problems of parser
This commit is contained in:
parent
287cbbf2c0
commit
6a845b746c
|
@ -148,7 +148,8 @@ STscObj* taos_connect_internal(const char* ip, const char* user, const char* pas
|
|||
return taosConnectImpl(user, &secretEncrypt[0], localDb, NULL, NULL, *pInst, connType);
|
||||
}
|
||||
|
||||
int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param, bool validateSql, SRequestObj** pRequest) {
|
||||
int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param, bool validateSql,
|
||||
SRequestObj** pRequest) {
|
||||
*pRequest = createRequest(connId, TSDB_SQL_SELECT);
|
||||
if (*pRequest == NULL) {
|
||||
tscError("failed to malloc sqlObj, %s", sql);
|
||||
|
@ -351,7 +352,8 @@ int32_t updateQnodeList(SAppInstInfo* pInfo, SArray* pNodeList) {
|
|||
if (pNodeList) {
|
||||
pInfo->pQnodeList = taosArrayDup(pNodeList);
|
||||
taosArraySort(pInfo->pQnodeList, compareQueryNodeLoad);
|
||||
tscDebug("QnodeList updated in cluster 0x%" PRIx64 ", num:%d", pInfo->clusterId, taosArrayGetSize(pInfo->pQnodeList));
|
||||
tscDebug("QnodeList updated in cluster 0x%" PRIx64 ", num:%d", pInfo->clusterId,
|
||||
taosArrayGetSize(pInfo->pQnodeList));
|
||||
}
|
||||
taosThreadMutexUnlock(&pInfo->qnodeMutex);
|
||||
|
||||
|
@ -993,6 +995,7 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultM
|
|||
pRequest->body.queryFp(pRequest->body.param, pRequest, 0);
|
||||
break;
|
||||
default:
|
||||
pRequest->body.queryFp(pRequest->body.param, pRequest, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,8 +48,8 @@ static int32_t validateTimeUnitParam(uint8_t dbPrec, const SValueNode* pVal) {
|
|||
return TIME_UNIT_INVALID;
|
||||
}
|
||||
|
||||
if (TSDB_TIME_PRECISION_MILLI == dbPrec && (0 == strcasecmp(pVal->literal, "1u") ||
|
||||
0 == strcasecmp(pVal->literal, "1b"))) {
|
||||
if (TSDB_TIME_PRECISION_MILLI == dbPrec &&
|
||||
(0 == strcasecmp(pVal->literal, "1u") || 0 == strcasecmp(pVal->literal, "1b"))) {
|
||||
return TIME_UNIT_TOO_SMALL;
|
||||
}
|
||||
|
||||
|
@ -57,10 +57,9 @@ static int32_t validateTimeUnitParam(uint8_t dbPrec, const SValueNode* pVal) {
|
|||
return TIME_UNIT_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (pVal->literal[0] != '1' || (pVal->literal[1] != 'u' && pVal->literal[1] != 'a' &&
|
||||
pVal->literal[1] != 's' && pVal->literal[1] != 'm' &&
|
||||
pVal->literal[1] != 'h' && pVal->literal[1] != 'd' &&
|
||||
pVal->literal[1] != 'w' && pVal->literal[1] != 'b')) {
|
||||
if (pVal->literal[0] != '1' ||
|
||||
(pVal->literal[1] != 'u' && pVal->literal[1] != 'a' && pVal->literal[1] != 's' && pVal->literal[1] != 'm' &&
|
||||
pVal->literal[1] != 'h' && pVal->literal[1] != 'd' && pVal->literal[1] != 'w' && pVal->literal[1] != 'b')) {
|
||||
return TIME_UNIT_INVALID;
|
||||
}
|
||||
|
||||
|
@ -678,9 +677,10 @@ static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
if (TSDB_DATA_TYPE_TIMESTAMP != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
SNode* pPara1 = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (QUERY_NODE_COLUMN != nodeType(pPara1) || PRIMARYKEY_TIMESTAMP_COL_ID != ((SColumnNode*)pPara1)->colId) {
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"The first parameter of the ELAPSED function can only be the timestamp primary key");
|
||||
}
|
||||
|
||||
// param1
|
||||
|
@ -694,8 +694,7 @@ static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
if (!IS_INTEGER_TYPE(pValue->node.resType.type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -706,7 +705,8 @@ static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len
|
|||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"ELAPSED function time unit parameter should be greater than db precision");
|
||||
} else if (ret == TIME_UNIT_INVALID) {
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
return buildFuncErrMsg(
|
||||
pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"ELAPSED function time unit parameter should be one of the following: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]");
|
||||
}
|
||||
}
|
||||
|
@ -1229,7 +1229,8 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
"STATEDURATION function time unit parameter should be greater than db precision");
|
||||
} else if (ret == TIME_UNIT_INVALID) {
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"STATEDURATION function time unit parameter should be one of the following: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]");
|
||||
"STATEDURATION function time unit parameter should be one of the following: [1b, 1u, 1a, "
|
||||
"1s, 1m, 1h, 1d, 1w]");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1740,7 +1741,8 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"TIMETRUNCATE function time unit parameter should be greater than db precision");
|
||||
} else if (ret == TIME_UNIT_INVALID) {
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
return buildFuncErrMsg(
|
||||
pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"TIMETRUNCATE function time unit parameter should be one of the following: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]");
|
||||
}
|
||||
|
||||
|
@ -1779,7 +1781,8 @@ static int32_t translateTimeDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"TIMEDIFF function time unit parameter should be greater than db precision");
|
||||
} else if (ret == TIME_UNIT_INVALID) {
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
return buildFuncErrMsg(
|
||||
pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"TIMEDIFF function time unit parameter should be one of the following: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1793,7 +1793,7 @@ static EDealRes classifyConditionImpl(SNode* pNode, void* pContext) {
|
|||
} else if (pCol->hasIndex) {
|
||||
pCxt->hasTagIndexCol = true;
|
||||
pCxt->hasTagCol = true;
|
||||
} else if (COLUMN_TYPE_TAG == pCol->colType) {
|
||||
} else if (COLUMN_TYPE_TAG == pCol->colType || COLUMN_TYPE_TBNAME == pCol->colType) {
|
||||
pCxt->hasTagCol = true;
|
||||
} else {
|
||||
pCxt->hasOtherCol = true;
|
||||
|
|
|
@ -339,6 +339,10 @@ SNode* createDefaultDatabaseCondValue(SAstCreateContext* pCxt) {
|
|||
|
||||
SNode* createPlaceholderValueNode(SAstCreateContext* pCxt, const SToken* pLiteral) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
if (NULL == pCxt->pQueryCxt->pStmtCb) {
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, pLiteral->z);
|
||||
return NULL;
|
||||
}
|
||||
SValueNode* val = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
CHECK_OUT_OF_MEM(val);
|
||||
val->literal = strndup(pLiteral->z, pLiteral->n);
|
||||
|
|
|
@ -41,7 +41,7 @@ bool qIsInsertValuesSql(const char* pStr, size_t length) {
|
|||
} else if (TK_SELECT == t.type) {
|
||||
return false;
|
||||
}
|
||||
if (0 == t.type) {
|
||||
if (0 == t.type || 0 == t.n) {
|
||||
break;
|
||||
}
|
||||
} while (pStr - pSql < length);
|
||||
|
|
|
@ -337,70 +337,69 @@ TEST_F(ParserSelectTest, semanticCheck) {
|
|||
useDb("root", "test");
|
||||
|
||||
// TSDB_CODE_PAR_INVALID_COLUMN
|
||||
run("SELECT c1, cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c1, cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN);
|
||||
|
||||
run("SELECT t1.c1, t1.cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT t1.c1, t1.cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN);
|
||||
|
||||
// TSDB_CODE_PAR_TABLE_NOT_EXIST
|
||||
run("SELECT * FROM t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT * FROM t10", TSDB_CODE_PAR_TABLE_NOT_EXIST);
|
||||
|
||||
run("SELECT * FROM test.t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT * FROM test.t10", TSDB_CODE_PAR_TABLE_NOT_EXIST);
|
||||
|
||||
run("SELECT t2.c1 FROM t1", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT t2.c1 FROM t1", TSDB_CODE_PAR_TABLE_NOT_EXIST);
|
||||
|
||||
// TSDB_CODE_PAR_AMBIGUOUS_COLUMN
|
||||
run("SELECT c2 FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN);
|
||||
|
||||
run("SELECT c2 FROM (SELECT c1 c2, c2 FROM t1)", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM (SELECT c1 c2, c2 FROM t1)", TSDB_CODE_PAR_AMBIGUOUS_COLUMN);
|
||||
|
||||
// TSDB_CODE_PAR_WRONG_VALUE_TYPE
|
||||
run("SELECT timestamp '2010a' FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT timestamp '2010a' FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE);
|
||||
|
||||
run("SELECT LAST(*) + SUM(c1) FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT LAST(*) + SUM(c1) FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE);
|
||||
|
||||
run("SELECT CEIL(LAST(ts, c1)) FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT CEIL(LAST(ts, c1)) FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE);
|
||||
|
||||
// TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
|
||||
run("SELECT c2 FROM t1 tt1 join t1 tt2 on COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 tt1 join t1 tt2 on COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION);
|
||||
|
||||
run("SELECT c2 FROM t1 WHERE COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 WHERE COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION);
|
||||
|
||||
run("SELECT c2 FROM t1 GROUP BY COUNT(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 GROUP BY COUNT(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION);
|
||||
|
||||
// TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
|
||||
run("SELECT c2 FROM t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
|
||||
|
||||
run("SELECT c2 FROM t1 order by 2", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 order by 2", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
|
||||
|
||||
// TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
|
||||
run("SELECT COUNT(*) cnt FROM t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT COUNT(*) cnt FROM t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
|
||||
|
||||
run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
|
||||
|
||||
run("SELECT COUNT(*), c1 cnt FROM t1 GROUP BY c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT COUNT(*), c1 cnt FROM t1 GROUP BY c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
|
||||
|
||||
run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
|
||||
|
||||
// TSDB_CODE_PAR_NOT_SINGLE_GROUP
|
||||
run("SELECT COUNT(*), c1 FROM t1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT COUNT(*), c1 FROM t1", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
|
||||
run("SELECT COUNT(*) FROM t1 order by c1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT COUNT(*) FROM t1 order by c1", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
|
||||
run("SELECT c1 FROM t1 order by COUNT(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c1 FROM t1 order by COUNT(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
|
||||
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
|
||||
run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION);
|
||||
|
||||
run("SELECT distinct c1 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT distinct c1 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION);
|
||||
|
||||
run("SELECT distinct c2 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT distinct c2 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION);
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, syntaxError) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT CAST(? AS BINARY(10)) FROM t1", TSDB_CODE_PAR_SYNTAX_ERROR, PARSER_STAGE_PARSE);
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, setOperator) {
|
||||
|
|
|
@ -80,6 +80,23 @@ static void optResetParent(SLogicNode* pNode) {
|
|||
FOREACH(pChild, pNode->pChildren) { ((SLogicNode*)pChild)->pParent = pNode; }
|
||||
}
|
||||
|
||||
static EDealRes optRebuildTbanme(SNode** pNode, void* pContext) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(*pNode) && COLUMN_TYPE_TBNAME == ((SColumnNode*)*pNode)->colType) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||
if (NULL == pFunc) {
|
||||
*(int32_t*)pContext = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
strcpy(pFunc->functionName, "tbname");
|
||||
pFunc->funcType = FUNCTION_TYPE_TBNAME;
|
||||
pFunc->node.resType = ((SColumnNode*)*pNode)->node.resType;
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = (SNode*)pFunc;
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
EDealRes scanPathOptHaveNormalColImpl(SNode* pNode, void* pContext) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
// *((bool*)pContext) = (COLUMN_TYPE_TAG != ((SColumnNode*)pNode)->colType);
|
||||
|
@ -312,6 +329,12 @@ static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNo
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t pushDownCondOptRebuildTbanme(SNode** pTagCond) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
nodesRewriteExpr(pTagCond, optRebuildTbanme, &code);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t pushDownCondOptDealScan(SOptimizeContext* pCxt, SScanLogicNode* pScan) {
|
||||
if (NULL == pScan->node.pConditions ||
|
||||
OPTIMIZE_FLAG_TEST_MASK(pScan->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE) ||
|
||||
|
@ -323,6 +346,9 @@ static int32_t pushDownCondOptDealScan(SOptimizeContext* pCxt, SScanLogicNode* p
|
|||
SNode* pOtherCond = NULL;
|
||||
int32_t code = nodesPartitionCond(&pScan->node.pConditions, &pPrimaryKeyCond, &pScan->pTagIndexCond, &pScan->pTagCond,
|
||||
&pOtherCond);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pScan->pTagCond) {
|
||||
code = pushDownCondOptRebuildTbanme(&pScan->pTagCond);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pPrimaryKeyCond) {
|
||||
code = pushDownCondOptCalcTimeRange(pCxt, pScan, &pPrimaryKeyCond, &pOtherCond);
|
||||
}
|
||||
|
@ -1386,26 +1412,9 @@ static bool partTagsOptMayBeOptimized(SLogicNode* pNode) {
|
|||
return !partTagsOptHasCol(partTagsGetPartKeys(pNode)) && partTagsOptAreSupportedFuncs(partTagsGetFuncs(pNode));
|
||||
}
|
||||
|
||||
static EDealRes partTagsOptRebuildTbanmeImpl(SNode** pNode, void* pContext) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(*pNode) && COLUMN_TYPE_TBNAME == ((SColumnNode*)*pNode)->colType) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||
if (NULL == pFunc) {
|
||||
*(int32_t*)pContext = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
strcpy(pFunc->functionName, "tbname");
|
||||
pFunc->funcType = FUNCTION_TYPE_TBNAME;
|
||||
pFunc->node.resType = ((SColumnNode*)*pNode)->node.resType;
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = (SNode*)pFunc;
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t partTagsOptRebuildTbanme(SNodeList* pPartKeys) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
nodesRewriteExprs(pPartKeys, partTagsOptRebuildTbanmeImpl, &code);
|
||||
nodesRewriteExprs(pPartKeys, optRebuildTbanme, &code);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ TEST_F(PlanOptimizeTest, pushDownCondition) {
|
|||
|
||||
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4");
|
||||
|
||||
run("SELECT ts, c1 FROM st1 WHERE TBNAME = 'st1s1'");
|
||||
|
||||
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 or tag1 < 2");
|
||||
|
||||
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 AND tag2 = 'hello'");
|
||||
|
|
Loading…
Reference in New Issue