Merge pull request #12743 from taosdata/feature/3.0_wxy
feat: the scan subplan adds the 'dbFName' attribute for metadata refresh
This commit is contained in:
commit
c726681009
|
@ -351,9 +351,6 @@ bool nodesIsComparisonOp(const SOperatorNode* pOp);
|
||||||
bool nodesIsJsonOp(const SOperatorNode* pOp);
|
bool nodesIsJsonOp(const SOperatorNode* pOp);
|
||||||
bool nodesIsRegularOp(const SOperatorNode* pOp);
|
bool nodesIsRegularOp(const SOperatorNode* pOp);
|
||||||
|
|
||||||
bool nodesIsTimeorderQuery(const SNode* pQuery);
|
|
||||||
bool nodesIsTimelineQuery(const SNode* pQuery);
|
|
||||||
|
|
||||||
void* nodesGetValueFromNode(SValueNode* pNode);
|
void* nodesGetValueFromNode(SValueNode* pNode);
|
||||||
int32_t nodesSetValueNodeValue(SValueNode* pNode, void* value);
|
int32_t nodesSetValueNodeValue(SValueNode* pNode, void* value);
|
||||||
char* nodesGetStrValueFromNode(SValueNode* pNode);
|
char* nodesGetStrValueFromNode(SValueNode* pNode);
|
||||||
|
|
|
@ -650,6 +650,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_PAR_INVALID_FUNCTION_NAME TAOS_DEF_ERROR_CODE(0, 0x264D)
|
#define TSDB_CODE_PAR_INVALID_FUNCTION_NAME TAOS_DEF_ERROR_CODE(0, 0x264D)
|
||||||
#define TSDB_CODE_PAR_COMMENT_TOO_LONG TAOS_DEF_ERROR_CODE(0, 0x264E)
|
#define TSDB_CODE_PAR_COMMENT_TOO_LONG TAOS_DEF_ERROR_CODE(0, 0x264E)
|
||||||
#define TSDB_CODE_PAR_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x264F)
|
#define TSDB_CODE_PAR_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x264F)
|
||||||
|
#define TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY TAOS_DEF_ERROR_CODE(0, 0x2650)
|
||||||
|
|
||||||
//planner
|
//planner
|
||||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||||
|
|
|
@ -1771,6 +1771,7 @@ static const char* jkSubplanId = "Id";
|
||||||
static const char* jkSubplanType = "SubplanType";
|
static const char* jkSubplanType = "SubplanType";
|
||||||
static const char* jkSubplanMsgType = "MsgType";
|
static const char* jkSubplanMsgType = "MsgType";
|
||||||
static const char* jkSubplanLevel = "Level";
|
static const char* jkSubplanLevel = "Level";
|
||||||
|
static const char* jkSubplanDbFName = "DbFName";
|
||||||
static const char* jkSubplanNodeAddr = "NodeAddr";
|
static const char* jkSubplanNodeAddr = "NodeAddr";
|
||||||
static const char* jkSubplanRootNode = "RootNode";
|
static const char* jkSubplanRootNode = "RootNode";
|
||||||
static const char* jkSubplanDataSink = "DataSink";
|
static const char* jkSubplanDataSink = "DataSink";
|
||||||
|
@ -1788,6 +1789,9 @@ static int32_t subplanToJson(const void* pObj, SJson* pJson) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddIntegerToObject(pJson, jkSubplanLevel, pNode->level);
|
code = tjsonAddIntegerToObject(pJson, jkSubplanLevel, pNode->level);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddStringToObject(pJson, jkSubplanDbFName, pNode->dbFName);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddObject(pJson, jkSubplanNodeAddr, queryNodeAddrToJson, &pNode->execNode);
|
code = tjsonAddObject(pJson, jkSubplanNodeAddr, queryNodeAddrToJson, &pNode->execNode);
|
||||||
}
|
}
|
||||||
|
@ -1815,6 +1819,9 @@ static int32_t jsonToSubplan(const SJson* pJson, void* pObj) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonGetIntValue(pJson, jkSubplanLevel, &pNode->level);
|
code = tjsonGetIntValue(pJson, jkSubplanLevel, &pNode->level);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetStringValue(pJson, jkSubplanDbFName, pNode->dbFName);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonToObject(pJson, jkSubplanNodeAddr, jsonToQueryNodeAddr, &pNode->execNode);
|
code = tjsonToObject(pJson, jkSubplanNodeAddr, jsonToQueryNodeAddr, &pNode->execNode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1137,10 +1137,6 @@ bool nodesIsRegularOp(const SOperatorNode* pOp) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nodesIsTimeorderQuery(const SNode* pQuery) { return false; }
|
|
||||||
|
|
||||||
bool nodesIsTimelineQuery(const SNode* pQuery) { return false; }
|
|
||||||
|
|
||||||
typedef struct SCollectColumnsCxt {
|
typedef struct SCollectColumnsCxt {
|
||||||
int32_t errCode;
|
int32_t errCode;
|
||||||
const char* pTableAlias;
|
const char* pTableAlias;
|
||||||
|
|
|
@ -382,6 +382,35 @@ static bool isInternalPrimaryKey(const SColumnNode* pCol) {
|
||||||
return PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId && 0 == strcmp(pCol->colName, PK_TS_COL_INTERNAL_NAME);
|
return PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId && 0 == strcmp(pCol->colName, PK_TS_COL_INTERNAL_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isTimeOrderQuery(SNode* pStmt) {
|
||||||
|
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||||
|
return ((SSelectStmt*)pStmt)->isTimeOrderQuery;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isPrimaryKeyImpl(STempTableNode* pTable, SNode* pExpr) {
|
||||||
|
if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
|
||||||
|
return (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId);
|
||||||
|
} else if (QUERY_NODE_FUNCTION == nodeType(pExpr)) {
|
||||||
|
SFunctionNode* pFunc = (SFunctionNode*)pExpr;
|
||||||
|
if (FUNCTION_TYPE_SELECT_VALUE == pFunc->funcType) {
|
||||||
|
return isPrimaryKeyImpl(pTable, nodesListGetNode(pFunc->pParameterList, 0));
|
||||||
|
} else if (FUNCTION_TYPE_WSTARTTS == pFunc->funcType || FUNCTION_TYPE_WENDTS == pFunc->funcType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isPrimaryKey(STempTableNode* pTable, SNode* pExpr) {
|
||||||
|
if (!isTimeOrderQuery(pTable->pSubquery)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isPrimaryKeyImpl(pTable, pExpr);
|
||||||
|
}
|
||||||
|
|
||||||
static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) {
|
static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
||||||
|
@ -404,8 +433,7 @@ static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) {
|
||||||
FOREACH(pNode, pProjectList) {
|
FOREACH(pNode, pProjectList) {
|
||||||
SExprNode* pExpr = (SExprNode*)pNode;
|
SExprNode* pExpr = (SExprNode*)pNode;
|
||||||
if (0 == strcmp(pCol->colName, pExpr->aliasName) ||
|
if (0 == strcmp(pCol->colName, pExpr->aliasName) ||
|
||||||
((QUERY_NODE_COLUMN == nodeType(pExpr) && PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId) &&
|
(isPrimaryKey((STempTableNode*)pTable, pNode) && isInternalPrimaryKey(pCol))) {
|
||||||
isInternalPrimaryKey(pCol))) {
|
|
||||||
setColumnInfoByExpr(pTable, pExpr, pCol);
|
setColumnInfoByExpr(pTable, pExpr, pCol);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -454,6 +482,9 @@ static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNod
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
if (isInternalPk) {
|
if (isInternalPk) {
|
||||||
|
if (NULL != pCxt->pCurrStmt->pWindow) {
|
||||||
|
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY);
|
||||||
|
}
|
||||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_INTERNAL_PK);
|
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_INTERNAL_PK);
|
||||||
} else {
|
} else {
|
||||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, pCol->colName);
|
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, pCol->colName);
|
||||||
|
@ -781,7 +812,6 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pCxt->pCurrStmt->hasAggFuncs = true;
|
pCxt->pCurrStmt->hasAggFuncs = true;
|
||||||
pCxt->pCurrStmt->isTimeOrderQuery = false;
|
|
||||||
if (isCountStar(pFunc)) {
|
if (isCountStar(pFunc)) {
|
||||||
pCxt->errCode = rewriteCountStar(pCxt, pFunc);
|
pCxt->errCode = rewriteCountStar(pCxt, pFunc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,6 +167,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
||||||
case TSDB_CODE_PAR_NOT_ALLOWED_FUNC:
|
case TSDB_CODE_PAR_NOT_ALLOWED_FUNC:
|
||||||
return "Some functions are allowed only in the SELECT list of a query. "
|
return "Some functions are allowed only in the SELECT list of a query. "
|
||||||
"And, cannot be mixed with other non scalar functions or columns.";
|
"And, cannot be mixed with other non scalar functions or columns.";
|
||||||
|
case TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY:
|
||||||
|
return "Window query not supported, since the result of subquery not include valid timestamp column";
|
||||||
case TSDB_CODE_OUT_OF_MEMORY:
|
case TSDB_CODE_OUT_OF_MEMORY:
|
||||||
return "Out of memory";
|
return "Out of memory";
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -125,8 +125,6 @@ TEST_F(ParserSelectTest, nonstdFunc) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
run("SELECT DIFF(c1) FROM t1");
|
run("SELECT DIFF(c1) FROM t1");
|
||||||
|
|
||||||
// run("SELECT DIFF(c1) FROM t1 INTERVAL(10s)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserSelectTest, nonstdFuncSemanticCheck) {
|
TEST_F(ParserSelectTest, nonstdFuncSemanticCheck) {
|
||||||
|
@ -139,12 +137,13 @@ TEST_F(ParserSelectTest, nonstdFuncSemanticCheck) {
|
||||||
run("SELECT DIFF(c1), count(*) FROM t1", TSDB_CODE_PAR_NOT_ALLOWED_FUNC, PARSER_STAGE_TRANSLATE);
|
run("SELECT DIFF(c1), count(*) FROM t1", TSDB_CODE_PAR_NOT_ALLOWED_FUNC, PARSER_STAGE_TRANSLATE);
|
||||||
|
|
||||||
run("SELECT DIFF(c1), CSUM(c1) FROM t1", TSDB_CODE_PAR_NOT_ALLOWED_FUNC, PARSER_STAGE_TRANSLATE);
|
run("SELECT DIFF(c1), CSUM(c1) FROM t1", TSDB_CODE_PAR_NOT_ALLOWED_FUNC, PARSER_STAGE_TRANSLATE);
|
||||||
|
|
||||||
|
// run("SELECT DIFF(c1) FROM t1 INTERVAL(10s)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserSelectTest, clause) {
|
TEST_F(ParserSelectTest, groupBy) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
// GROUP BY clause
|
|
||||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0");
|
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0");
|
||||||
|
|
||||||
run("SELECT COUNT(*), c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2");
|
run("SELECT COUNT(*), c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2");
|
||||||
|
@ -154,13 +153,19 @@ TEST_F(ParserSelectTest, clause) {
|
||||||
run("SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2, c1");
|
run("SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2, c1");
|
||||||
|
|
||||||
run("SELECT COUNT(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c1 + 10, c2");
|
run("SELECT COUNT(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c1 + 10, c2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserSelectTest, orderBy) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
// order by clause
|
|
||||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 order by cnt");
|
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 order by cnt");
|
||||||
|
|
||||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 order by 1");
|
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 order by 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserSelectTest, distinct) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
// distinct clause
|
|
||||||
// run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by c1");
|
// run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by c1");
|
||||||
|
|
||||||
// run("SELECT distinct c1 + 10, c2 FROM t1 WHERE c1 > 0 order by c1 + 10, c2");
|
// run("SELECT distinct c1 + 10, c2 FROM t1 WHERE c1 > 0 order by c1 + 10, c2");
|
||||||
|
@ -194,6 +199,25 @@ TEST_F(ParserSelectTest, intervalSemanticCheck) {
|
||||||
PARSER_STAGE_TRANSLATE);
|
PARSER_STAGE_TRANSLATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserSelectTest, subquery) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT SUM(a) FROM (SELECT MAX(c1) a, ts FROM st1s1 INTERVAL(1m)) INTERVAL(1n)");
|
||||||
|
|
||||||
|
run("SELECT SUM(a) FROM (SELECT MAX(c1) a, _wstartts FROM st1s1 INTERVAL(1m)) INTERVAL(1n)");
|
||||||
|
|
||||||
|
run("SELECT SUM(a) FROM (SELECT MAX(c1) a, ts FROM st1s1 PARTITION BY TBNAME INTERVAL(1m)) INTERVAL(1n)");
|
||||||
|
|
||||||
|
run("SELECT SUM(a) FROM (SELECT MAX(c1) a, _wstartts FROM st1s1 PARTITION BY TBNAME INTERVAL(1m)) INTERVAL(1n)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ParserSelectTest, subquerySemanticError) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT SUM(a) FROM (SELECT MAX(c1) a FROM st1s1 INTERVAL(1m)) INTERVAL(1n)", TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY,
|
||||||
|
PARSER_STAGE_TRANSLATE);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ParserSelectTest, semanticError) {
|
TEST_F(ParserSelectTest, semanticError) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue