未验证 提交 87f16127 编写于 作者: X Xiaoyu Wang 提交者: GitHub

Merge pull request #12692 from taosdata/feature/3.0_wxy

fix: some problems of parser and planner
...@@ -142,6 +142,8 @@ void fmFuncMgtDestroy(); ...@@ -142,6 +142,8 @@ void fmFuncMgtDestroy();
int32_t fmGetFuncInfo(SFmGetFuncInfoParam* pParam, SFunctionNode* pFunc); int32_t fmGetFuncInfo(SFmGetFuncInfoParam* pParam, SFunctionNode* pFunc);
bool fmIsBuiltinFunc(const char* pFunc);
bool fmIsAggFunc(int32_t funcId); bool fmIsAggFunc(int32_t funcId);
bool fmIsScalarFunc(int32_t funcId); bool fmIsScalarFunc(int32_t funcId);
bool fmIsNonstandardSQLFunc(int32_t funcId); bool fmIsNonstandardSQLFunc(int32_t funcId);
......
...@@ -78,7 +78,7 @@ typedef struct SAlterDatabaseStmt { ...@@ -78,7 +78,7 @@ typedef struct SAlterDatabaseStmt {
typedef struct STableOptions { typedef struct STableOptions {
ENodeType type; ENodeType type;
char comment[TSDB_STB_COMMENT_LEN]; char comment[TSDB_TB_COMMENT_LEN];
int32_t delay; int32_t delay;
float filesFactor; float filesFactor;
SNodeList* pRollupFuncs; SNodeList* pRollupFuncs;
...@@ -90,7 +90,7 @@ typedef struct SColumnDefNode { ...@@ -90,7 +90,7 @@ typedef struct SColumnDefNode {
ENodeType type; ENodeType type;
char colName[TSDB_COL_NAME_LEN]; char colName[TSDB_COL_NAME_LEN];
SDataType dataType; SDataType dataType;
char comments[TSDB_STB_COMMENT_LEN]; char comments[TSDB_TB_COMMENT_LEN];
bool sma; bool sma;
} SColumnDefNode; } SColumnDefNode;
......
...@@ -647,6 +647,8 @@ int32_t* taosGetErrno(); ...@@ -647,6 +647,8 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_CANNOT_DROP_PRIMARY_KEY TAOS_DEF_ERROR_CODE(0, 0x264A) #define TSDB_CODE_PAR_CANNOT_DROP_PRIMARY_KEY TAOS_DEF_ERROR_CODE(0, 0x264A)
#define TSDB_CODE_PAR_INVALID_MODIFY_COL TAOS_DEF_ERROR_CODE(0, 0x264B) #define TSDB_CODE_PAR_INVALID_MODIFY_COL TAOS_DEF_ERROR_CODE(0, 0x264B)
#define TSDB_CODE_PAR_INVALID_TBNAME TAOS_DEF_ERROR_CODE(0, 0x264C) #define TSDB_CODE_PAR_INVALID_TBNAME TAOS_DEF_ERROR_CODE(0, 0x264C)
#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)
//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)
......
...@@ -218,8 +218,8 @@ typedef enum ELogicConditionType { ...@@ -218,8 +218,8 @@ typedef enum ELogicConditionType {
#define TSDB_MAX_SQL_SHOW_LEN 1024 #define TSDB_MAX_SQL_SHOW_LEN 1024
#define TSDB_MAX_ALLOWED_SQL_LEN (1 * 1024 * 1024u) // sql length should be less than 1mb #define TSDB_MAX_ALLOWED_SQL_LEN (1 * 1024 * 1024u) // sql length should be less than 1mb
#define TSDB_APP_NAME_LEN TSDB_UNI_LEN #define TSDB_APP_NAME_LEN TSDB_UNI_LEN
#define TSDB_STB_COMMENT_LEN 1024 #define TSDB_TB_COMMENT_LEN 1025
/** /**
* In some scenarios uint16_t (0~65535) is used to store the row len. * In some scenarios uint16_t (0~65535) is used to store the row len.
......
...@@ -100,6 +100,10 @@ int32_t fmGetFuncInfo(SFmGetFuncInfoParam* pParam, SFunctionNode* pFunc) { ...@@ -100,6 +100,10 @@ int32_t fmGetFuncInfo(SFmGetFuncInfoParam* pParam, SFunctionNode* pFunc) {
return getUdfInfo(pParam, pFunc); return getUdfInfo(pParam, pFunc);
} }
bool fmIsBuiltinFunc(const char* pFunc) {
return NULL != taosHashGet(gFunMgtService.pFuncNameHashTable, pFunc, strlen(pFunc));
}
EFuncDataRequired fmFuncDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWindow) { EFuncDataRequired fmFuncDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWindow) {
if (fmIsUserDefinedFunc(pFunc->funcId) || pFunc->funcId < 0 || pFunc->funcId >= funcMgtBuiltinsNum) { if (fmIsUserDefinedFunc(pFunc->funcId) || pFunc->funcId < 0 || pFunc->funcId >= funcMgtBuiltinsNum) {
return FUNC_DATA_REQUIRED_DATA_LOAD; return FUNC_DATA_REQUIRED_DATA_LOAD;
......
...@@ -946,6 +946,23 @@ static int32_t jsonToLogicSubplan(const SJson* pJson, void* pObj) { ...@@ -946,6 +946,23 @@ static int32_t jsonToLogicSubplan(const SJson* pJson, void* pObj) {
return code; return code;
} }
static const char* jkLogicPlanSubplans = "Subplans";
static int32_t logicPlanToJson(const void* pObj, SJson* pJson) {
const SQueryLogicPlan* pNode = (const SQueryLogicPlan*)pObj;
return tjsonAddObject(pJson, jkLogicPlanSubplans, nodeToJson, nodesListGetNode(pNode->pTopSubplans, 0));
}
static int32_t jsonToLogicPlan(const SJson* pJson, void* pObj) {
SQueryLogicPlan* pNode = (SQueryLogicPlan*)pObj;
SNode* pChild = NULL;
int32_t code = jsonToNodeObject(pJson, jkLogicPlanSubplans, &pChild);
if (TSDB_CODE_SUCCESS == code) {
code = nodesListMakeStrictAppend(&pNode->pTopSubplans, pChild);
}
return code;
}
static const char* jkJoinLogicPlanJoinType = "JoinType"; static const char* jkJoinLogicPlanJoinType = "JoinType";
static const char* jkJoinLogicPlanOnConditions = "OnConditions"; static const char* jkJoinLogicPlanOnConditions = "OnConditions";
...@@ -3029,7 +3046,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { ...@@ -3029,7 +3046,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case QUERY_NODE_LOGIC_SUBPLAN: case QUERY_NODE_LOGIC_SUBPLAN:
return logicSubplanToJson(pObj, pJson); return logicSubplanToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN: case QUERY_NODE_LOGIC_PLAN:
break; return logicPlanToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
return physiTagScanNodeToJson(pObj, pJson); return physiTagScanNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
...@@ -3126,6 +3143,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { ...@@ -3126,6 +3143,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToLogicPartitionNode(pJson, pObj); return jsonToLogicPartitionNode(pJson, pObj);
case QUERY_NODE_LOGIC_SUBPLAN: case QUERY_NODE_LOGIC_SUBPLAN:
return jsonToLogicSubplan(pJson, pObj); return jsonToLogicSubplan(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN:
return jsonToLogicPlan(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
return jsonToPhysiTagScanNode(pJson, pObj); return jsonToPhysiTagScanNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
......
...@@ -196,6 +196,15 @@ static bool checkIndexName(SAstCreateContext* pCxt, SToken* pIndexName) { ...@@ -196,6 +196,15 @@ static bool checkIndexName(SAstCreateContext* pCxt, SToken* pIndexName) {
return true; return true;
} }
static bool checkComment(SAstCreateContext* pCxt, const SToken* pCommentToken, bool demand) {
if (NULL == pCommentToken) {
pCxt->errCode = demand ? TSDB_CODE_PAR_SYNTAX_ERROR : TSDB_CODE_SUCCESS;
} else if (pCommentToken->n >= (TSDB_TB_COMMENT_LEN + 2)) {
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_COMMENT_TOO_LONG);
}
return TSDB_CODE_SUCCESS == pCxt->errCode;
}
SNode* createRawExprNode(SAstCreateContext* pCxt, const SToken* pToken, SNode* pNode) { SNode* createRawExprNode(SAstCreateContext* pCxt, const SToken* pToken, SNode* pNode) {
SRawExprNode* target = (SRawExprNode*)nodesMakeNode(QUERY_NODE_RAW_EXPR); SRawExprNode* target = (SRawExprNode*)nodesMakeNode(QUERY_NODE_RAW_EXPR);
CHECK_OUT_OF_MEM(target); CHECK_OUT_OF_MEM(target);
...@@ -823,8 +832,10 @@ SNode* createAlterTableOptions(SAstCreateContext* pCxt) { ...@@ -823,8 +832,10 @@ SNode* createAlterTableOptions(SAstCreateContext* pCxt) {
SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, void* pVal) { SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, void* pVal) {
switch (type) { switch (type) {
case TABLE_OPTION_COMMENT: case TABLE_OPTION_COMMENT:
copyStringFormStringToken((SToken*)pVal, ((STableOptions*)pOptions)->comment, if (checkComment(pCxt, (SToken*)pVal, true)) {
sizeof(((STableOptions*)pOptions)->comment)); copyStringFormStringToken((SToken*)pVal, ((STableOptions*)pOptions)->comment,
sizeof(((STableOptions*)pOptions)->comment));
}
break; break;
case TABLE_OPTION_DELAY: case TABLE_OPTION_DELAY:
((STableOptions*)pOptions)->delay = taosStr2Int32(((SToken*)pVal)->z, NULL, 10); ((STableOptions*)pOptions)->delay = taosStr2Int32(((SToken*)pVal)->z, NULL, 10);
...@@ -848,7 +859,7 @@ SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType ...@@ -848,7 +859,7 @@ SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType
} }
SNode* createColumnDefNode(SAstCreateContext* pCxt, SToken* pColName, SDataType dataType, const SToken* pComment) { SNode* createColumnDefNode(SAstCreateContext* pCxt, SToken* pColName, SDataType dataType, const SToken* pComment) {
if (!checkColumnName(pCxt, pColName)) { if (!checkColumnName(pCxt, pColName) || !checkComment(pCxt, pComment, false)) {
return NULL; return NULL;
} }
SColumnDefNode* pCol = (SColumnDefNode*)nodesMakeNode(QUERY_NODE_COLUMN_DEF); SColumnDefNode* pCol = (SColumnDefNode*)nodesMakeNode(QUERY_NODE_COLUMN_DEF);
......
...@@ -272,6 +272,10 @@ static bool isTimelineFunc(const SNode* pNode) { ...@@ -272,6 +272,10 @@ static bool isTimelineFunc(const SNode* pNode) {
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsTimelineFunc(((SFunctionNode*)pNode)->funcId)); return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsTimelineFunc(((SFunctionNode*)pNode)->funcId));
} }
static bool isScanPseudoColumnFunc(const SNode* pNode) {
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsScanPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
}
static bool isDistinctOrderBy(STranslateContext* pCxt) { static bool isDistinctOrderBy(STranslateContext* pCxt) {
return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrStmt->isDistinct); return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrStmt->isDistinct);
} }
...@@ -892,7 +896,7 @@ static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) { ...@@ -892,7 +896,7 @@ static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) {
return DEAL_RES_IGNORE_CHILD; return DEAL_RES_IGNORE_CHILD;
} }
} }
if (QUERY_NODE_COLUMN == nodeType(*pNode)) { if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) {
if (pCxt->selectFuncNum > 1) { if (pCxt->selectFuncNum > 1) {
return generateDealNodeErrMsg(pCxt->pTranslateCxt, getGroupByErrorCode(pCxt->pTranslateCxt)); return generateDealNodeErrMsg(pCxt->pTranslateCxt, getGroupByErrorCode(pCxt->pTranslateCxt));
} else { } else {
...@@ -930,7 +934,7 @@ static EDealRes rewriteColsToSelectValFuncImpl(SNode** pNode, void* pContext) { ...@@ -930,7 +934,7 @@ static EDealRes rewriteColsToSelectValFuncImpl(SNode** pNode, void* pContext) {
if (isAggFunc(*pNode)) { if (isAggFunc(*pNode)) {
return DEAL_RES_IGNORE_CHILD; return DEAL_RES_IGNORE_CHILD;
} }
if (QUERY_NODE_COLUMN == nodeType(*pNode)) { if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) {
return rewriteColToSelectValFunc((STranslateContext*)pContext, NULL, pNode); return rewriteColToSelectValFunc((STranslateContext*)pContext, NULL, pNode);
} }
return DEAL_RES_CONTINUE; return DEAL_RES_CONTINUE;
...@@ -958,7 +962,7 @@ static EDealRes doCheckAggColCoexist(SNode* pNode, void* pContext) { ...@@ -958,7 +962,7 @@ static EDealRes doCheckAggColCoexist(SNode* pNode, void* pContext) {
pCxt->existAggFunc = true; pCxt->existAggFunc = true;
return DEAL_RES_IGNORE_CHILD; return DEAL_RES_IGNORE_CHILD;
} }
if (QUERY_NODE_COLUMN == nodeType(pNode)) { if (isScanPseudoColumnFunc(pNode) || QUERY_NODE_COLUMN == nodeType(pNode)) {
pCxt->existCol = true; pCxt->existCol = true;
} }
return DEAL_RES_CONTINUE; return DEAL_RES_CONTINUE;
...@@ -3261,6 +3265,9 @@ static int32_t readFromFile(char* pName, int32_t* len, char** buf) { ...@@ -3261,6 +3265,9 @@ static int32_t readFromFile(char* pName, int32_t* len, char** buf) {
} }
static int32_t translateCreateFunction(STranslateContext* pCxt, SCreateFunctionStmt* pStmt) { static int32_t translateCreateFunction(STranslateContext* pCxt, SCreateFunctionStmt* pStmt) {
if (fmIsBuiltinFunc(pStmt->funcName)) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FUNCTION_NAME);
}
SCreateFuncReq req = {0}; SCreateFuncReq req = {0};
strcpy(req.name, pStmt->funcName); strcpy(req.name, pStmt->funcName);
req.igExists = pStmt->ignoreExists; req.igExists = pStmt->ignoreExists;
......
...@@ -160,6 +160,10 @@ static char* getSyntaxErrFormat(int32_t errCode) { ...@@ -160,6 +160,10 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "Only binary/nchar column length could be modified"; return "Only binary/nchar column length could be modified";
case TSDB_CODE_PAR_INVALID_TBNAME: case TSDB_CODE_PAR_INVALID_TBNAME:
return "Invalid tbname pseudo column"; return "Invalid tbname pseudo column";
case TSDB_CODE_PAR_INVALID_FUNCTION_NAME:
return "Invalid function name";
case TSDB_CODE_PAR_COMMENT_TOO_LONG:
return "Comment too long";
case TSDB_CODE_OUT_OF_MEMORY: case TSDB_CODE_OUT_OF_MEMORY:
return "Out of memory"; return "Out of memory";
default: default:
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define SPLIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0) #define SPLIT_FLAG_TEST_MASK(val, mask) (((val) & (mask)) != 0)
typedef struct SSplitContext { typedef struct SSplitContext {
int32_t queryId;
int32_t groupId; int32_t groupId;
bool split; bool split;
} SSplitContext; } SSplitContext;
...@@ -62,6 +63,7 @@ static SLogicSubplan* splCreateScanSubplan(SSplitContext* pCxt, SScanLogicNode* ...@@ -62,6 +63,7 @@ static SLogicSubplan* splCreateScanSubplan(SSplitContext* pCxt, SScanLogicNode*
if (NULL == pSubplan) { if (NULL == pSubplan) {
return NULL; return NULL;
} }
pSubplan->id.queryId = pCxt->queryId;
pSubplan->id.groupId = pCxt->groupId; pSubplan->id.groupId = pCxt->groupId;
pSubplan->subplanType = SUBPLAN_TYPE_SCAN; pSubplan->subplanType = SUBPLAN_TYPE_SCAN;
pSubplan->pNode = (SLogicNode*)nodesCloneNode(pScan); pSubplan->pNode = (SLogicNode*)nodesCloneNode(pScan);
...@@ -242,6 +244,7 @@ static SLogicSubplan* unionCreateSubplan(SSplitContext* pCxt, SLogicNode* pNode) ...@@ -242,6 +244,7 @@ static SLogicSubplan* unionCreateSubplan(SSplitContext* pCxt, SLogicNode* pNode)
if (NULL == pSubplan) { if (NULL == pSubplan) {
return NULL; return NULL;
} }
pSubplan->id.queryId = pCxt->queryId;
pSubplan->id.groupId = pCxt->groupId; pSubplan->id.groupId = pCxt->groupId;
pSubplan->subplanType = SUBPLAN_TYPE_SCAN; pSubplan->subplanType = SUBPLAN_TYPE_SCAN;
pSubplan->pNode = pNode; pSubplan->pNode = pNode;
...@@ -406,7 +409,7 @@ static const SSplitRule splitRuleSet[] = {{.pName = "SuperTableScan", .splitFunc ...@@ -406,7 +409,7 @@ static const SSplitRule splitRuleSet[] = {{.pName = "SuperTableScan", .splitFunc
static const int32_t splitRuleNum = (sizeof(splitRuleSet) / sizeof(SSplitRule)); static const int32_t splitRuleNum = (sizeof(splitRuleSet) / sizeof(SSplitRule));
static int32_t applySplitRule(SLogicSubplan* pSubplan) { static int32_t applySplitRule(SLogicSubplan* pSubplan) {
SSplitContext cxt = {.groupId = pSubplan->id.groupId + 1, .split = false}; SSplitContext cxt = {.queryId = pSubplan->id.queryId, .groupId = pSubplan->id.groupId + 1, .split = false};
do { do {
cxt.split = false; cxt.split = false;
for (int32_t i = 0; i < splitRuleNum; ++i) { for (int32_t i = 0; i < splitRuleNum; ++i) {
......
...@@ -32,6 +32,15 @@ TEST_F(PlanSetOpTest, unionAllSubquery) { ...@@ -32,6 +32,15 @@ TEST_F(PlanSetOpTest, unionAllSubquery) {
run("SELECT * FROM (SELECT c1, c2 FROM t1 UNION ALL SELECT c1, c2 FROM t1)"); run("SELECT * FROM (SELECT c1, c2 FROM t1 UNION ALL SELECT c1, c2 FROM t1)");
} }
TEST_F(PlanSetOpTest, unionAllWithSubquery) {
useDb("root", "test");
// child table
run("SELECT ts FROM (SELECT ts FROM st1s1) UNION ALL SELECT ts FROM (SELECT ts FROM st1s2)");
// super table
run("SELECT ts FROM (SELECT ts FROM st1) UNION ALL SELECT ts FROM (SELECT ts FROM st1)");
}
TEST_F(PlanSetOpTest, union) { TEST_F(PlanSetOpTest, union) {
useDb("root", "test"); useDb("root", "test");
......
...@@ -322,6 +322,7 @@ class PlannerTestBaseImpl { ...@@ -322,6 +322,7 @@ class PlannerTestBaseImpl {
} }
void setPlanContext(SQuery* pQuery, SPlanContext* pCxt) { void setPlanContext(SQuery* pQuery, SPlanContext* pCxt) {
pCxt->queryId = 1;
if (QUERY_NODE_CREATE_TOPIC_STMT == nodeType(pQuery->pRoot)) { if (QUERY_NODE_CREATE_TOPIC_STMT == nodeType(pQuery->pRoot)) {
pCxt->pAstRoot = ((SCreateTopicStmt*)pQuery->pRoot)->pQuery; pCxt->pAstRoot = ((SCreateTopicStmt*)pQuery->pRoot)->pQuery;
pCxt->topicQuery = true; pCxt->topicQuery = true;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册