diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index c8e803c811e04a31c848f9bc14b32a84a7fa679c..8888f6ca8e91e53f11781b2d35252940c4ee57d5 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -121,7 +121,7 @@ typedef enum EFunctionType { // internal function FUNCTION_TYPE_SELECT_VALUE, - FUNCTION_TYPE_BLOCK_DIST, // block distribution aggregate function + FUNCTION_TYPE_BLOCK_DIST, // block distribution aggregate function // distributed splitting functions FUNCTION_TYPE_APERCENTILE_PARTIAL, @@ -170,6 +170,7 @@ bool fmIsMultiResFunc(int32_t funcId); bool fmIsRepeatScanFunc(int32_t funcId); bool fmIsUserDefinedFunc(int32_t funcId); bool fmIsDistExecFunc(int32_t funcId); +bool fmIsForbidFillFunc(int32_t funcId); int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc); diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index c267c8938479c7b9410aead8bfd39cdbed9aa090..25369f2342f6d5cd928f2f1c2782a9cb9186dc60 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -47,7 +47,7 @@ typedef struct SDatabaseOptions { int32_t maxRowsPerBlock; int32_t minRowsPerBlock; SNodeList* pKeep; - int32_t keep[3]; + int64_t keep[3]; int32_t pages; int32_t pagesize; char precisionStr[3]; diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 1a53988621bf7ad6a10d1c2b4f0af4d25f7f575c..03308e395f9d785229c06eb83e86eadd08666701 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -652,6 +652,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2654) #define TSDB_CODE_PAR_INVALID_DELETE_WHERE TAOS_DEF_ERROR_CODE(0, 0x2655) #define TSDB_CODE_PAR_INVALID_REDISTRIBUTE_VG TAOS_DEF_ERROR_CODE(0, 0x2656) +#define TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x2657) //planner #define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700) diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index e6c93a9bfdf8540b8ffcc3f3b1233cd31dd4ee5f..c20459829ece38be56beb6d6fcf9b27f1684577a 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -1424,10 +1424,10 @@ static void dumpDbInfoData(SSDataBlock *pBlock, SDbObj *pDb, SShowObj *pShow, in char tmp[128] = {0}; int32_t len = 0; if (pDb->cfg.daysToKeep0 > pDb->cfg.daysToKeep1 || pDb->cfg.daysToKeep0 > pDb->cfg.daysToKeep2) { - len = sprintf(&tmp[VARSTR_HEADER_SIZE], "%d,%d,%d", pDb->cfg.daysToKeep1, pDb->cfg.daysToKeep2, + len = sprintf(&tmp[VARSTR_HEADER_SIZE], "%dm,%dm,%dm", pDb->cfg.daysToKeep1, pDb->cfg.daysToKeep2, pDb->cfg.daysToKeep0); } else { - len = sprintf(&tmp[VARSTR_HEADER_SIZE], "%d,%d,%d", pDb->cfg.daysToKeep0, pDb->cfg.daysToKeep1, + len = sprintf(&tmp[VARSTR_HEADER_SIZE], "%dm,%dm,%dm", pDb->cfg.daysToKeep0, pDb->cfg.daysToKeep1, pDb->cfg.daysToKeep2); } @@ -1592,4 +1592,3 @@ static void mndCancelGetNextDb(SMnode *pMnode, void *pIter) { SSdb *pSdb = pMnode->pSdb; sdbCancelFetch(pSdb, pIter); } - diff --git a/source/libs/function/inc/functionMgtInt.h b/source/libs/function/inc/functionMgtInt.h index 29dd0bcd90d6297ca539bad8a5c5cd78ff151d1d..d1af6b605187e0e761c59293e4090408a0ca19a4 100644 --- a/source/libs/function/inc/functionMgtInt.h +++ b/source/libs/function/inc/functionMgtInt.h @@ -41,6 +41,7 @@ extern "C" { #define FUNC_MGT_SCAN_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(12) #define FUNC_MGT_SELECT_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(13) #define FUNC_MGT_REPEAT_SCAN_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(14) +#define FUNC_MGT_FORBID_FILL_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(15) #define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index ca586a79c9fe0be63e5ac9d5d5fd97c44dc9d249..a1aa1a775c2a43075960cba8d5ee29e0a8e88107 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -294,7 +294,8 @@ static int32_t translateApercentileImpl(SFunctionNode* pFunc, char* pErrBuf, int pValue->notReserved = true; } - pFunc->node.resType = (SDataType){.bytes = getApercentileMaxSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; + pFunc->node.resType = + (SDataType){.bytes = getApercentileMaxSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; } else { if (1 != numOfParams) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); @@ -479,7 +480,8 @@ static int32_t translateElapsedImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t } } - pFunc->node.resType = (SDataType){.bytes = getElapsedInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; + pFunc->node.resType = + (SDataType){.bytes = getElapsedInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; } else { if (1 != numOfParams) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); @@ -593,7 +595,8 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32 return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } - pFunc->node.resType = (SDataType){.bytes = getHistogramInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; + pFunc->node.resType = + (SDataType){.bytes = getHistogramInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; } else { if (1 != numOfParams) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); @@ -631,7 +634,8 @@ static int32_t translateHLLImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len } if (isPartial) { - pFunc->node.resType = (SDataType){.bytes = getHistogramInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; + pFunc->node.resType = + (SDataType){.bytes = getHistogramInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; } else { pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT}; } @@ -1127,7 +1131,7 @@ static bool validateTimezoneFormat(const SValueNode* pVal) { char* tz = varDataVal(pVal->datum.p); int32_t len = varDataLen(pVal->datum.p); - char buf[3] = {0}; + char buf[3] = {0}; int8_t hour = -1, minute = -1; if (len == 0) { return false; @@ -1320,7 +1324,7 @@ static int32_t translateSelectValue(SFunctionNode* pFunc, char* pErrBuf, int32_t } static int32_t translateBlockDistFunc(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { - pFunc->node.resType = (SDataType) {.bytes = 128, .type = TSDB_DATA_TYPE_VARCHAR}; + pFunc->node.resType = (SDataType){.bytes = 128, .type = TSDB_DATA_TYPE_VARCHAR}; return TSDB_CODE_SUCCESS; } @@ -1329,7 +1333,6 @@ static bool getBlockDistFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv return true; } - // clang-format off const SBuiltinFuncDefinition funcMgtBuiltins[] = { { @@ -1625,7 +1628,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { { .name = "histogram", .type = FUNCTION_TYPE_HISTOGRAM, - .classification = FUNC_MGT_AGG_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_FORBID_FILL_FUNC, .translateFunc = translateHistogram, .getEnvFunc = getHistogramFuncEnv, .initFunc = histogramFunctionSetup, diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index f2514f54f1ce83e71c78e2c418f9b58439d824a5..df09d3e5294141cfa97448051644b1d2140fea34 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -159,6 +159,8 @@ bool fmIsRepeatScanFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, bool fmIsUserDefinedFunc(int32_t funcId) { return funcId > FUNC_UDF_ID_START; } +bool fmIsForbidFillFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_FORBID_FILL_FUNC); } + void fmFuncMgtDestroy() { void* m = gFunMgtService.pFuncNameHashTable; if (m != NULL && atomic_val_compare_exchange_ptr((void**)&gFunMgtService.pFuncNameHashTable, m, 0) == m) { diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index 613a2d867da148efb25ef3dfc96d3ea521882b8e..054912d540dac2bac00011ec5d2caffbb5ca4a6a 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -346,25 +346,30 @@ SNode* createPlaceholderValueNode(SAstCreateContext* pCxt, const SToken* pLitera return (SNode*)val; } +static int32_t addParamToLogicConditionNode(SLogicConditionNode* pCond, SNode* pParam) { + if (QUERY_NODE_LOGIC_CONDITION == nodeType(pParam) && pCond->condType == ((SLogicConditionNode*)pParam)->condType) { + int32_t code = nodesListAppendList(pCond->pParameterList, ((SLogicConditionNode*)pParam)->pParameterList); + ((SLogicConditionNode*)pParam)->pParameterList = NULL; + nodesDestroyNode(pParam); + return code; + } else { + return nodesListAppend(pCond->pParameterList, pParam); + } +} + SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType type, SNode* pParam1, SNode* pParam2) { CHECK_PARSER_STATUS(pCxt); SLogicConditionNode* cond = (SLogicConditionNode*)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION); CHECK_OUT_OF_MEM(cond); cond->condType = type; cond->pParameterList = nodesMakeList(); - if (QUERY_NODE_LOGIC_CONDITION == nodeType(pParam1) && type == ((SLogicConditionNode*)pParam1)->condType) { - nodesListAppendList(cond->pParameterList, ((SLogicConditionNode*)pParam1)->pParameterList); - ((SLogicConditionNode*)pParam1)->pParameterList = NULL; - nodesDestroyNode(pParam1); - } else { - nodesListAppend(cond->pParameterList, pParam1); + int32_t code = addParamToLogicConditionNode(cond, pParam1); + if (TSDB_CODE_SUCCESS == code && NULL != pParam2) { + code = addParamToLogicConditionNode(cond, pParam2); } - if (QUERY_NODE_LOGIC_CONDITION == nodeType(pParam2) && type == ((SLogicConditionNode*)pParam2)->condType) { - nodesListAppendList(cond->pParameterList, ((SLogicConditionNode*)pParam2)->pParameterList); - ((SLogicConditionNode*)pParam2)->pParameterList = NULL; - nodesDestroyNode(pParam2); - } else { - nodesListAppend(cond->pParameterList, pParam2); + if (TSDB_CODE_SUCCESS != code) { + nodesDestroyNode(cond); + return NULL; } return (SNode*)cond; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 178cc2595a2b26ad87916beaa4f2f88d1d09faae..8ca6332a8d65fe04e1ad645ca7ce7fc7f61f5007 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -733,7 +733,7 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD } int32_t len = 0; - if (!taosMbsToUcs4(pVal->literal, pVal->node.resType.bytes, (TdUcs4*)varDataVal(pVal->datum.p), + if (!taosMbsToUcs4(pVal->literal, strlen(pVal->literal), (TdUcs4*)varDataVal(pVal->datum.p), targetDt.bytes - VARSTR_HEADER_SIZE, &len)) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); } @@ -974,6 +974,9 @@ static int32_t getFuncInfo(STranslateContext* pCxt, SFunctionNode* pFunc) { } static int32_t translateAggFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { + if (!fmIsAggFunc(pFunc->funcId)) { + return TSDB_CODE_SUCCESS; + } if (beforeHaving(pCxt->currClause)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION); } @@ -991,6 +994,9 @@ static int32_t translateAggFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { } static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { + if (!fmIsScanPseudoColumnFunc(pFunc->funcId)) { + return TSDB_CODE_SUCCESS; + } if (0 == LIST_LENGTH(pFunc->pParameterList)) { if (QUERY_NODE_REAL_TABLE != nodeType(pCxt->pCurrSelectStmt->pFromTable)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME); @@ -1007,6 +1013,9 @@ static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SFunctionN } static int32_t translateIndefiniteRowsFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { + if (!fmIsIndefiniteRowsFunc(pFunc->funcId)) { + return TSDB_CODE_SUCCESS; + } if (SQL_CLAUSE_SELECT != pCxt->currClause || pCxt->pCurrSelectStmt->hasIndefiniteRowsFunc || pCxt->pCurrSelectStmt->hasAggFuncs) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC); @@ -1017,6 +1026,18 @@ static int32_t translateIndefiniteRowsFunc(STranslateContext* pCxt, SFunctionNod return TSDB_CODE_SUCCESS; } +static int32_t translateForbidFillFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { + if (!fmIsForbidFillFunc(pFunc->funcId)) { + return TSDB_CODE_SUCCESS; + } + if (NULL != pCxt->pCurrSelectStmt->pWindow && + QUERY_NODE_INTERVAL_WINDOW == nodeType(pCxt->pCurrSelectStmt->pWindow) && + NULL != ((SIntervalWindowNode*)pCxt->pCurrSelectStmt->pWindow)->pFill) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC, pFunc->functionName); + } + return TSDB_CODE_SUCCESS; +} + static void setFuncClassification(SSelectStmt* pSelect, SFunctionNode* pFunc) { if (NULL != pSelect) { pSelect->hasAggFuncs = pSelect->hasAggFuncs ? true : fmIsAggFunc(pFunc->funcId); @@ -1034,15 +1055,18 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) } pCxt->errCode = getFuncInfo(pCxt, pFunc); - if (TSDB_CODE_SUCCESS == pCxt->errCode && fmIsAggFunc(pFunc->funcId)) { + if (TSDB_CODE_SUCCESS == pCxt->errCode) { pCxt->errCode = translateAggFunc(pCxt, pFunc); } - if (TSDB_CODE_SUCCESS == pCxt->errCode && fmIsScanPseudoColumnFunc(pFunc->funcId)) { + if (TSDB_CODE_SUCCESS == pCxt->errCode) { pCxt->errCode = translateScanPseudoColumnFunc(pCxt, pFunc); } - if (TSDB_CODE_SUCCESS == pCxt->errCode && fmIsIndefiniteRowsFunc(pFunc->funcId)) { + if (TSDB_CODE_SUCCESS == pCxt->errCode) { pCxt->errCode = translateIndefiniteRowsFunc(pCxt, pFunc); } + if (TSDB_CODE_SUCCESS == pCxt->errCode) { + pCxt->errCode = translateForbidFillFunc(pCxt, pFunc); + } if (TSDB_CODE_SUCCESS == pCxt->errCode) { setFuncClassification(pCxt->pCurrSelectStmt, pFunc); } @@ -2365,7 +2389,9 @@ static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRete return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION); } - SNode* pRetention = NULL; + SValueNode* pPrevFreq = NULL; + SValueNode* pPrevKeep = NULL; + SNode* pRetention = NULL; FOREACH(pRetention, pRetentions) { SNode* pNode = NULL; FOREACH(pNode, ((SNodeListNode*)pRetention)->pNodeList) { @@ -2374,6 +2400,16 @@ static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRete return pCxt->errCode; } } + + SValueNode* pFreq = (SValueNode*)nodesListGetNode(((SNodeListNode*)pRetention)->pNodeList, 0); + SValueNode* pKeep = (SValueNode*)nodesListGetNode(((SNodeListNode*)pRetention)->pNodeList, 1); + if (pFreq->datum.i <= 0 || 'n' == pFreq->unit || 'y' == pFreq->unit || pFreq->datum.i >= pKeep->datum.i || + (NULL != pPrevFreq && pPrevFreq->datum.i >= pFreq->datum.i) || + (NULL != pPrevKeep && pPrevKeep->datum.i > pKeep->datum.i)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION); + } + pPrevFreq = pFreq; + pPrevKeep = pKeep; } return TSDB_CODE_SUCCESS; @@ -2593,12 +2629,23 @@ static int32_t checkTableSmaOption(STranslateContext* pCxt, SCreateTableStmt* pS return TSDB_CODE_SUCCESS; } +static bool validRollupFunc(const char* pFunc) { + static const char* rollupFuncs[] = {"avg", "sum", "min", "max", "last", "first"}; + static const int32_t numOfRollupFuncs = (sizeof(rollupFuncs) / sizeof(char*)); + for (int i = 0; i < numOfRollupFuncs; ++i) { + if (0 == strcmp(rollupFuncs[i], pFunc)) { + return true; + } + } + return false; +} + static int32_t checkTableRollupOption(STranslateContext* pCxt, SNodeList* pFuncs) { if (NULL == pFuncs) { return TSDB_CODE_SUCCESS; } - if (1 != LIST_LENGTH(pFuncs)) { + if (1 != LIST_LENGTH(pFuncs) || !validRollupFunc(((SFunctionNode*)nodesListGetNode(pFuncs, 0))->functionName)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROLLUP_OPTION); } return TSDB_CODE_SUCCESS; @@ -3083,15 +3130,14 @@ static int32_t translateAlterTable(STranslateContext* pCxt, SAlterTableStmt* pSt SName tableName; tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &tableName), alterReq.name); alterReq.alterType = pStmt->alterType; - if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == pStmt->alterType) { - return TSDB_CODE_FAILED; - } else { - if (TSDB_CODE_SUCCESS != setAlterTableField(pStmt, &alterReq)) { - return TSDB_CODE_OUT_OF_MEMORY; - } + if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == pStmt->alterType || TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME == pStmt->alterType) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE); } - - return buildCmdMsg(pCxt, TDMT_MND_ALTER_STB, (FSerializeFunc)tSerializeSMAlterStbReq, &alterReq); + int32_t code = setAlterTableField(pStmt, &alterReq); + if (TSDB_CODE_SUCCESS == code) { + code = buildCmdMsg(pCxt, TDMT_MND_ALTER_STB, (FSerializeFunc)tSerializeSMAlterStbReq, &alterReq); + } + return code; } static int32_t translateUseDatabase(STranslateContext* pCxt, SUseDatabaseStmt* pStmt) { @@ -3171,7 +3217,7 @@ static int32_t nodeTypeToShowType(ENodeType nt) { case QUERY_NODE_SHOW_QUERIES_STMT: return TSDB_MGMT_TABLE_QUERIES; case QUERY_NODE_SHOW_VARIABLE_STMT: - return 0; // todo + return TSDB_MGMT_TABLE_CONFIGS; default: break; } @@ -3778,6 +3824,7 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) { case QUERY_NODE_SHOW_CONNECTIONS_STMT: case QUERY_NODE_SHOW_QUERIES_STMT: case QUERY_NODE_SHOW_TOPICS_STMT: + case QUERY_NODE_SHOW_VARIABLE_STMT: code = translateShow(pCxt, (SShowStmt*)pNode); break; case QUERY_NODE_CREATE_INDEX_STMT: @@ -4932,7 +4979,11 @@ static int32_t buildAlterTbReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, case TSDB_ALTER_TABLE_UPDATE_OPTIONS: return buildUpdateOptionsReq(pCxt, pStmt, pReq); case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: - return buildRenameColReq(pCxt, pStmt, pTableMeta, pReq); + if (TSDB_CHILD_TABLE == pTableMeta->tableType) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE); + } else { + return buildRenameColReq(pCxt, pStmt, pTableMeta, pReq); + } default: break; } diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 1e5a6681eece01b77181da2f1ce06812a24135c4..716b120af53b7e11fa2236fe2fc2b2f9016ebf6d 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -76,7 +76,7 @@ static char* getSyntaxErrFormat(int32_t errCode) { case TSDB_CODE_PAR_INVALID_KEEP_ORDER: return "Invalid keep value, should be keep0 <= keep1 <= keep2"; case TSDB_CODE_PAR_INVALID_KEEP_VALUE: - return "Invalid option keep: %d, %d, %d valid range: [%d, %d]"; + return "Invalid option keep: %" PRId64 ", %" PRId64 ", %" PRId64 " valid range: [%dm, %dm]"; case TSDB_CODE_PAR_INVALID_COMMENT_OPTION: return "Invalid option comment, length cannot exceed %d"; case TSDB_CODE_PAR_INVALID_F_RANGE_OPTION: @@ -182,6 +182,8 @@ static char* getSyntaxErrFormat(int32_t errCode) { return "The DELETE statement must have a definite time window range"; case TSDB_CODE_PAR_INVALID_REDISTRIBUTE_VG: return "The REDISTRIBUTE VGROUP statement only support 1 to 3 dnodes"; + case TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC: + return "%s function not allowed in fill query"; case TSDB_CODE_OUT_OF_MEMORY: return "Out of memory"; default: diff --git a/source/libs/parser/test/parInitialATest.cpp b/source/libs/parser/test/parInitialATest.cpp index 22b244145bc0fe01759381a3a5bf8499d77d026d..f554651b90e6ef343ffb0f72bc2508f6c91a5246 100644 --- a/source/libs/parser/test/parInitialATest.cpp +++ b/source/libs/parser/test/parInitialATest.cpp @@ -24,7 +24,7 @@ class ParserInitialATest : public ParserDdlTest {}; TEST_F(ParserInitialATest, alterAccount) { useDb("root", "test"); - run("ALTER ACCOUNT ac_wxy PASS '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT); + run("ALTER ACCOUNT ac_wxy PASS '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT, PARSER_STAGE_PARSE); } TEST_F(ParserInitialATest, alterDnode) { @@ -157,8 +157,8 @@ TEST_F(ParserInitialATest, alterSTable) { 20 + VARSTR_HEADER_SIZE); run("ALTER TABLE st1 MODIFY COLUMN c1 VARCHAR(20)"); - setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, 2, "c1", 0, 0, "cc1"); - run("ALTER TABLE st1 RENAME COLUMN c1 cc1"); + // setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, 2, "c1", 0, 0, "cc1"); + // run("ALTER TABLE st1 RENAME COLUMN c1 cc1"); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_ADD_TAG, 1, "tag11", TSDB_DATA_TYPE_BIGINT); run("ALTER TABLE st1 ADD TAG tag11 BIGINT"); @@ -177,6 +177,12 @@ TEST_F(ParserInitialATest, alterSTable) { // ADD {FULLTEXT | SMA} INDEX index_name (col_name [, col_name] ...) [index_option] } +TEST_F(ParserInitialATest, alterSTableSemanticCheck) { + useDb("root", "test"); + + run("ALTER TABLE st1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE); +} + TEST_F(ParserInitialATest, alterTable) { useDb("root", "test"); @@ -299,6 +305,12 @@ TEST_F(ParserInitialATest, alterTable) { // ADD {FULLTEXT | SMA} INDEX index_name (col_name [, col_name] ...) [index_option] } +TEST_F(ParserInitialATest, alterTableSemanticCheck) { + useDb("root", "test"); + + run("ALTER TABLE st1s1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE); +} + TEST_F(ParserInitialATest, alterUser) { useDb("root", "test"); @@ -323,7 +335,7 @@ TEST_F(ParserInitialATest, balanceVgroup) { TEST_F(ParserInitialATest, bug001) { useDb("root", "test"); - run("ALTER DATABASE db WAL 0 # td-14436", TSDB_CODE_PAR_SYNTAX_ERROR); + run("ALTER DATABASE db WAL 0 # td-14436", TSDB_CODE_PAR_SYNTAX_ERROR, PARSER_STAGE_PARSE); } } // namespace ParserTest \ No newline at end of file diff --git a/source/libs/parser/test/parInitialCTest.cpp b/source/libs/parser/test/parInitialCTest.cpp index d996ca196a11bf902f50199eed1a852ca3b00e6b..f306947f76604e4e52d6764edae6c685e0e49e20 100644 --- a/source/libs/parser/test/parInitialCTest.cpp +++ b/source/libs/parser/test/parInitialCTest.cpp @@ -27,7 +27,7 @@ class ParserInitialCTest : public ParserDdlTest {}; TEST_F(ParserInitialCTest, createAccount) { useDb("root", "test"); - run("CREATE ACCOUNT ac_wxy PASS '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT); + run("CREATE ACCOUNT ac_wxy PASS '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT, PARSER_STAGE_PARSE); } TEST_F(ParserInitialCTest, createBnode) { @@ -186,7 +186,7 @@ TEST_F(ParserInitialCTest, createDatabase) { setDbReplicaFunc(3); addDbRetentionFunc(15 * MILLISECOND_PER_SECOND, 7 * MILLISECOND_PER_DAY, TIME_UNIT_SECOND, TIME_UNIT_DAY); addDbRetentionFunc(1 * MILLISECOND_PER_MINUTE, 21 * MILLISECOND_PER_DAY, TIME_UNIT_MINUTE, TIME_UNIT_DAY); - addDbRetentionFunc(15 * MILLISECOND_PER_MINUTE, 5, TIME_UNIT_MINUTE, TIME_UNIT_YEAR); + addDbRetentionFunc(15 * MILLISECOND_PER_MINUTE, 500 * MILLISECOND_PER_DAY, TIME_UNIT_MINUTE, TIME_UNIT_DAY); setDbStrictaFunc(1); setDbWalLevelFunc(2); setDbVgroupsFunc(100); @@ -205,7 +205,7 @@ TEST_F(ParserInitialCTest, createDatabase) { "PAGESIZE 8 " "PRECISION 'ns' " "REPLICA 3 " - "RETENTIONS 15s:7d,1m:21d,15m:5y " + "RETENTIONS 15s:7d,1m:21d,15m:500d " "STRICT 1 " "WAL 2 " "VGROUPS 100 " @@ -220,6 +220,17 @@ TEST_F(ParserInitialCTest, createDatabase) { "KEEP 1440m,300h,400d "); } +TEST_F(ParserInitialCTest, createDatabaseSemanticCheck) { + useDb("root", "test"); + + run("create database db2 retentions 0s:1d", TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION); + run("create database db2 retentions 10s:0d", TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION); + run("create database db2 retentions 1w:1d", TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION); + run("create database db2 retentions 1w:1n", TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION); + run("create database db2 retentions 15s:7d,15m:21d,10m:500d", TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION); + run("create database db2 retentions 15s:7d,5m:21d,10m:10d", TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION); +} + TEST_F(ParserInitialCTest, createDnode) { useDb("root", "test"); @@ -434,6 +445,13 @@ TEST_F(ParserInitialCTest, createStable) { "TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (MIN) FILE_FACTOR 0.1"); } +TEST_F(ParserInitialCTest, createStableSemanticCheck) { + useDb("root", "test"); + + run("CREATE STABLE stb2 (ts TIMESTAMP, c1 INT) TAGS (tag1 INT) ROLLUP(CEIL) FILE_FACTOR 0.1", + TSDB_CODE_PAR_INVALID_ROLLUP_OPTION, PARSER_STAGE_TRANSLATE); +} + TEST_F(ParserInitialCTest, createStream) { useDb("root", "test"); diff --git a/source/libs/parser/test/parSelectTest.cpp b/source/libs/parser/test/parSelectTest.cpp index 154e28a02c7fa88d5ba0f527463f7508af9e023c..51d302fe12281a646f2d3259656036575084a9d7 100644 --- a/source/libs/parser/test/parSelectTest.cpp +++ b/source/libs/parser/test/parSelectTest.cpp @@ -65,6 +65,8 @@ TEST_F(ParserSelectTest, condition) { run("SELECT c1 FROM t1 WHERE ts in (true, false)"); + run("SELECT c1 FROM t1 WHERE NOT ts in (true, false)"); + run("SELECT * FROM t1 WHERE c1 > 10 and c1 is not null"); } @@ -212,9 +214,11 @@ TEST_F(ParserSelectTest, interval) { TEST_F(ParserSelectTest, intervalSemanticCheck) { useDb("root", "test"); - run("SELECT c1 FROM t1 INTERVAL(10s)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE); - run("SELECT DISTINCT c1, c2 FROM t1 WHERE c1 > 3 INTERVAL(1d) FILL(NEXT)", TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE, - PARSER_STAGE_TRANSLATE); + run("SELECT c1 FROM t1 INTERVAL(10s)", TSDB_CODE_PAR_NOT_SINGLE_GROUP); + run("SELECT DISTINCT c1, c2 FROM t1 WHERE c1 > 3 INTERVAL(1d) FILL(NEXT)", TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE); + run("SELECT HISTOGRAM(c1, 'log_bin', '{\"start\": -33,\"factor\": 55,\"count\": 5,\"infinity\": false}', 1) FROM t1 " + "WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' INTERVAL(10s) FILL(NULL)", + TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC); } TEST_F(ParserSelectTest, subquery) { diff --git a/source/libs/parser/test/parTestUtil.h b/source/libs/parser/test/parTestUtil.h index 07f3d3cece104da51ed9baf3715f6063b5d870fc..ad21252c2b768fde82fd8577acc18d502ba4a9e3 100644 --- a/source/libs/parser/test/parTestUtil.h +++ b/source/libs/parser/test/parTestUtil.h @@ -36,7 +36,7 @@ class ParserTestBase : public testing::Test { void login(const std::string& user); void useDb(const std::string& acctId, const std::string& db); - void run(const std::string& sql, int32_t expect = TSDB_CODE_SUCCESS, ParserStage checkStage = PARSER_STAGE_ALL); + void run(const std::string& sql, int32_t expect = TSDB_CODE_SUCCESS, ParserStage checkStage = PARSER_STAGE_TRANSLATE); virtual void checkDdl(const SQuery* pQuery, ParserStage stage); diff --git a/tests/script/tsim/db/alter_option.sim b/tests/script/tsim/db/alter_option.sim index 744451150429ce110f2caf69af5e059765325f26..12babea097da4002cb829d29bb5aae3830d60340 100644 --- a/tests/script/tsim/db/alter_option.sim +++ b/tests/script/tsim/db/alter_option.sim @@ -95,7 +95,7 @@ endi if $data6_db != 345600 then # days return -1 endi -if $data7_db != 1440000,1440000,1440000 then # keep +if $data7_db != 1440000m,1440000m,1440000m then # keep return -1 endi if $data8_db != 96 then # buffer @@ -232,7 +232,7 @@ print ============== modify keep sql alter database db keep 2400 sql show databases print keep $data7_db -if $data7_db != 3456000,3456000,3456000 then +if $data7_db != 3456000m,3456000m,3456000m then return -1 endi diff --git a/tests/script/tsim/db/basic6.sim b/tests/script/tsim/db/basic6.sim index 9075ebb2e83c76fa2f762b0ef8bebd48968f2ce9..142460f214a372c6f9084409a700c01a23238b36 100644 --- a/tests/script/tsim/db/basic6.sim +++ b/tests/script/tsim/db/basic6.sim @@ -37,7 +37,7 @@ endi if $data26 != 2880 then return -1 endi -if $data27 != 14400,14400,14400 then +if $data27 != 14400m,14400m,14400m then return -1 endi #if $data28 != 32 then diff --git a/tests/script/tsim/db/create_all_options.sim b/tests/script/tsim/db/create_all_options.sim index 88f0378d618229ee6edd4ccf7879793453305746..fac385a9a672fa46028ac4c6b0d1e997a525e2b1 100644 --- a/tests/script/tsim/db/create_all_options.sim +++ b/tests/script/tsim/db/create_all_options.sim @@ -116,7 +116,7 @@ endi if $data6_db != 14400 then # days return -1 endi -if $data7_db != 5256000,5256000,5256000 then # keep +if $data7_db != 5256000m,5256000m,5256000m then # keep return -1 endi if $data8_db != 96 then # buffer