diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 4dc6ee6e72..c7a5d2de65 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -166,6 +166,10 @@ typedef enum EFunctionType { FUNCTION_TYPE_IRATE_MERGE, FUNCTION_TYPE_AVG_STATE, FUNCTION_TYPE_AVG_STATE_MERGE, + FUNCTION_TYPE_FIRST_STATE, + FUNCTION_TYPE_FIRST_STATE_MERGE, + FUNCTION_TYPE_LAST_STATE, + FUNCTION_TYPE_LAST_STATE_MERGE, // geometry functions FUNCTION_TYPE_GEOM_FROM_TEXT = 4250, diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 1766de6c9d..ea6a37f642 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -827,6 +827,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSMA_INVALID_TB TAOS_DEF_ERROR_CODE(0, 0x3106) #define TSDB_CODE_TSMA_INVALID_INTERVAL TAOS_DEF_ERROR_CODE(0, 0x3107) #define TSDB_CODE_TSMA_INVALID_FUNC_PARAM TAOS_DEF_ERROR_CODE(0, 0x3108) +#define TSDB_CODE_TSMA_UNSUPPORTED_FUNC TAOS_DEF_ERROR_CODE(0, 0x3109) //rsma #define TSDB_CODE_RSMA_INVALID_ENV TAOS_DEF_ERROR_CODE(0, 0x3150) diff --git a/source/libs/function/inc/functionMgtInt.h b/source/libs/function/inc/functionMgtInt.h index abbd2fa27a..9c01d9320a 100644 --- a/source/libs/function/inc/functionMgtInt.h +++ b/source/libs/function/inc/functionMgtInt.h @@ -55,6 +55,7 @@ extern "C" { #define FUNC_MGT_SKIP_SCAN_CHECK_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(26) #define FUNC_MGT_IGNORE_NULL_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(27) #define FUNC_MGT_PRIMARY_KEY_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(28) +#define FUNC_MGT_TSMA_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(29) #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 9fcc4dd16d..de8d674d20 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -2418,7 +2418,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { { .name = "count", .type = FUNCTION_TYPE_COUNT, - .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_IGNORE_NULL_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_TSMA_FUNC, .translateFunc = translateCount, .dataRequiredFunc = countDataRequired, .getEnvFunc = getCountFuncEnv, @@ -2431,12 +2431,13 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { #endif .combineFunc = combineFunction, .pPartialFunc = "count", + .pStateFunc = "count", .pMergeFunc = "sum" }, { .name = "sum", .type = FUNCTION_TYPE_SUM, - .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_IGNORE_NULL_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_TSMA_FUNC, .translateFunc = translateSum, .dataRequiredFunc = statisDataRequired, .getEnvFunc = getSumFuncEnv, @@ -2449,12 +2450,13 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { #endif .combineFunc = sumCombine, .pPartialFunc = "sum", + .pStateFunc = "sum", .pMergeFunc = "sum" }, { .name = "min", .type = FUNCTION_TYPE_MIN, - .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_SELECT_FUNC | FUNC_MGT_IGNORE_NULL_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_SELECT_FUNC | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_TSMA_FUNC, .translateFunc = translateInOutNum, .dataRequiredFunc = statisDataRequired, .getEnvFunc = getMinmaxFuncEnv, @@ -2464,12 +2466,13 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .finalizeFunc = minmaxFunctionFinalize, .combineFunc = minCombine, .pPartialFunc = "min", + .pStateFunc = "min", .pMergeFunc = "min" }, { .name = "max", .type = FUNCTION_TYPE_MAX, - .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_SELECT_FUNC | FUNC_MGT_IGNORE_NULL_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_SELECT_FUNC | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_TSMA_FUNC, .translateFunc = translateInOutNum, .dataRequiredFunc = statisDataRequired, .getEnvFunc = getMinmaxFuncEnv, @@ -2479,6 +2482,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .finalizeFunc = minmaxFunctionFinalize, .combineFunc = maxCombine, .pPartialFunc = "max", + .pStateFunc = "max", .pMergeFunc = "max" }, { @@ -2544,7 +2548,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { { .name = "avg", .type = FUNCTION_TYPE_AVG, - .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_IGNORE_NULL_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_TSMA_FUNC, .translateFunc = translateInNumOutDou, .dataRequiredFunc = statisDataRequired, .getEnvFunc = getAvgFuncEnv, @@ -2906,7 +2910,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .name = "first", .type = FUNCTION_TYPE_FIRST, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | - FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC, + FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC | FUNC_MGT_TSMA_FUNC, .translateFunc = translateFirstLast, .dynDataRequiredFunc = firstDynDataReq, .getEnvFunc = getFirstLastFuncEnv, @@ -3850,7 +3854,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { //TODO for outer use not only internal .name = "_avg_state", .type = FUNCTION_TYPE_AVG_STATE, - .classification = FUNC_MGT_AGG_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC, .translateFunc = translateAvgState, //.dataRequiredFunc = statisDataRequired, .getEnvFunc = getAvgFuncEnv, @@ -3864,13 +3868,26 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { { .name = "_avg_state_merge", .type = FUNCTION_TYPE_AVG_STATE_MERGE, - .classification = FUNC_MGT_AGG_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC, .translateFunc = translateAvgStateMerge, .getEnvFunc = getAvgFuncEnv, .initFunc = avgFunctionSetup, .processFunc = avgFunctionMerge, .finalizeFunc = avgPartialFinalize, }, + { + .name = "_first_state", + .type = FUNCTION_TYPE_FIRST_STATE, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | + FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_TSMA_FUNC, + .translateFunc = translateAvgState, + .getEnvFunc = getFirstLastFuncEnv, + .initFunc = functionSetup, + .processFunc = firstFunction, + .finalizeFunc = firstLastPartialFinalize, + .pPartialFunc = "_first_partial", + .pMergeFunc = "_avg_state_merge" + }, }; // clang-format on diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 6bcbd1c3a7..3f3c4a1c99 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -714,6 +714,7 @@ int32_t avgFunctionMerge(SqlFunctionCtx* pCtx) { int32_t start = pInput->startRowIndex; for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + if(colDataIsNull_s(pCol, i)) continue; char* data = colDataGetData(pCol, i); SAvgRes* pInputInfo = (SAvgRes*)varDataVal(data); avgTransferInfo(pInputInfo, pInfo); diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index b14aada9d1..8d5342620f 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -539,7 +539,8 @@ static int32_t fmCreateStateFunc(const SFunctionNode* pFunc, SFunctionNode** pSt } bool fmIsTSMASupportedFunc(func_id_t funcId) { - return fmIsAggFunc(funcId) && !fmIsForbidStreamFunc(funcId); + return isSpecificClassifyFunc(funcId, FUNC_MGT_TSMA_FUNC) && + !isSpecificClassifyFunc(funcId, FUNC_MGT_FORBID_STREAM_FUNC); } int32_t fmCreateStateFuncs(SNodeList* pFuncs) { diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index e2d4708dc6..98c1d740dc 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -3592,7 +3592,7 @@ static int32_t setNormalTableVgroupList(STranslateContext* pCxt, SName* pName, S } static int32_t setTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) { - if (pCxt->pParseCxt->topicQuery) { + if (0 && pCxt->pParseCxt->topicQuery) { return TSDB_CODE_SUCCESS; } @@ -10581,7 +10581,7 @@ static int32_t buildTSMAAstMakeConcatFuncNode(SCreateTSMAStmt* pStmt, SMCreateSm code = nodesListMakeStrictAppend(&pSubstrFunc->pParameterList, nodesMakeNode(QUERY_NODE_VALUE)); if (TSDB_CODE_SUCCESS == code) { SValueNode* pV = (SValueNode*)pSubstrFunc->pParameterList->pTail->pNode; - pV->literal = strdup("34"); + pV->literal = strdup("34"); // TODO define this magic number if (!pV->literal) code = TSDB_CODE_OUT_OF_MEMORY; pV->isDuration = false; pV->translate = false; @@ -10663,6 +10663,8 @@ static int32_t createColumnBySchema(const SSchema* pSchema, SColumnNode** ppCol) if (!*ppCol) return TSDB_CODE_OUT_OF_MEMORY; (*ppCol)->colId = pSchema->colId; + (*ppCol)->node.resType.type = pSchema->type; + (*ppCol)->node.resType.bytes = pSchema->bytes; strcpy((*ppCol)->colName, pSchema->name); return TSDB_CODE_SUCCESS; } @@ -10674,22 +10676,21 @@ static int32_t rewriteTSMAFuncs(STranslateContext* pCxt, SCreateTSMAStmt* pStmt, SFunctionNode* pFunc = NULL; SColumnNode* pCol = NULL; if (pStmt->pOptions->recursiveTsma) { + int32_t i = 0; + FOREACH(pNode, pStmt->pOptions->pFuncs) { + // rewrite all func parameters with tsma dest tb cols + pFunc = (SFunctionNode*)pNode; + const SSchema* pSchema = pCols + i; + code = createColumnBySchema(pSchema, &pCol); + if (code) break; + nodesListErase(pFunc->pParameterList, pFunc->pParameterList->pHead); + nodesListPushFront(pFunc->pParameterList, (SNode*)pCol); + snprintf(pFunc->node.userAlias, TSDB_COL_NAME_LEN, "%s", pSchema->name); + ++i; + } // recursive tsma, create func list from base tsma - code = fmCreateStateMergeFuncs(pStmt->pOptions->pFuncs); if (TSDB_CODE_SUCCESS == code) { - int32_t i = 0; - FOREACH(pNode, pStmt->pOptions->pFuncs) { - // rewrite all func parameters with tsma dest tb cols - pFunc = (SFunctionNode*)pNode; - const SSchema* pSchema = pCols + i; - code = createColumnBySchema(pSchema, &pCol); - if (code) break; - nodesListErase(pFunc->pParameterList, pFunc->pParameterList->pHead); - nodesListPushFront(pFunc->pParameterList, (SNode*)pCol); - //TODO what if exceeds the max size - snprintf(pFunc->node.userAlias, TSDB_COL_NAME_LEN, "%s", pSchema->name); - ++i; - } + code = fmCreateStateMergeFuncs(pStmt->pOptions->pFuncs); } } else { FOREACH(pNode, pStmt->pOptions->pFuncs) { @@ -10699,7 +10700,13 @@ static int32_t rewriteTSMAFuncs(STranslateContext* pCxt, SCreateTSMAStmt* pStmt, code = TSDB_CODE_TSMA_INVALID_FUNC_PARAM; break; } - // TODO test func params with exprs + code = fmGetFuncInfo(pFunc, NULL, 0); + if (TSDB_CODE_SUCCESS != code) break; + if (!fmIsTSMASupportedFunc(pFunc->funcId)) { + code = TSDB_CODE_TSMA_UNSUPPORTED_FUNC; + break; + } + pCol = (SColumnNode*)pFunc->pParameterList->pHead->pNode; snprintf(pFunc->node.userAlias, TSDB_COL_NAME_LEN, "%s(%s)", pFunc->functionName, pCol->colName); } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 2844a979bc..4882c8517c 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -5902,7 +5902,7 @@ static bool tsmaOptCheckValidFuncs(const SArray* pTsmaFuncs, const SNodeList* pQ } int32_t queryColId = ((SColumnNode*)pQueryFunc->pParameterList->pHead->pNode)->colId; found = false; - int32_t notMyStateFuncId = 0; + int32_t notMyStateFuncId = -1; // iterate funcs // TODO if func is count, skip checking cols, test count(*) for (int32_t i = 0; i < pTsmaFuncs->size; i++) { diff --git a/source/util/src/terror.c b/source/util/src/terror.c index a2568fc034..d7ce6becf5 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -691,6 +691,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_PARA, "Invalid tsma parame TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_TB, "Invalid table to create tsma, only stable or normal table allowed") TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_INTERVAL, "Invalid tsma interval, 1ms ~ 1h is allowed") TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_FUNC_PARAM, "Invalid tsma func param, only one column allowed") +TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_UNSUPPORTED_FUNC, "Tsma func not supported") //rsma TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_ENV, "Invalid rsma env") diff --git a/tests/system-test/2-query/tsma.py b/tests/system-test/2-query/tsma.py index b638190f3e..e9933ea3a1 100644 --- a/tests/system-test/2-query/tsma.py +++ b/tests/system-test/2-query/tsma.py @@ -225,7 +225,8 @@ class TSMATester: sql, str(no_tsma_res), str(tsma_res))) if skip_order: try: - no_tsma_res.sort(key=lambda x: [v is None for v in x] + list(x)) + no_tsma_res.sort( + key=lambda x: [v is None for v in x] + list(x)) tsma_res.sort(key=lambda x: [v is None for v in x] + list(x)) except Exception as e: tdLog.exit("comparing tsma res for: %s got different data: \nno tsma res: %s \n tsma res: %s err: %s" % ( @@ -239,7 +240,6 @@ class TSMATester: (sql, str(tsma_res), str(no_tsma_res))) def check_sql(self, sql: str, expect: TSMAQueryContext): - return tdLog.debug(f"start to check sql: {sql}") actual_ctx = self.check_explain(sql, expect=expect) tdLog.debug(f"ctx: {actual_ctx}") @@ -399,7 +399,7 @@ class TSMATestSQLGenerator: opt = random.choice(opts) return f'{column_name} = "{opt}"' - ## TODO support it + # TODO support it def generate_str_in_operator(self, column_name: str, opts: List) -> str: opt = random.choice(opts) IN = f'"{",".join(opts)}"' @@ -603,9 +603,8 @@ class TDTestCase: def create_ctable(self, tsql=None, dbName='dbx', stbName='stb', ctbPrefix='ctb', ctbNum=1, ctbStartIdx=0): for i in range(ctbNum): - sqlString = "create table %s.%s%d using %s.%s tags(%d, 'tb%d', 'tb%d', %d, %d, %d)" % \ - (dbName, ctbPrefix, i+ctbStartIdx, dbName, stbName, (i+ctbStartIdx) % 5, i+ctbStartIdx + - random.randint(1, 100), i+ctbStartIdx + random.randint(1, 100), i+ctbStartIdx + random.randint(1, 100), i+ctbStartIdx + random.randint(1, 100), i+ctbStartIdx + random.randint(1, 100)) + sqlString = "create table %s.%s%d using %s.%s tags(%d, 'tb%d', 'tb%d', %d, %d, %d)" % (dbName, ctbPrefix, i+ctbStartIdx, dbName, stbName, (i+ctbStartIdx) % 5, i+ctbStartIdx + random.randint( + 1, 100), i+ctbStartIdx + random.randint(1, 100), i+ctbStartIdx + random.randint(1, 100), i+ctbStartIdx + random.randint(1, 100), i+ctbStartIdx + random.randint(1, 100)) tsql.execute(sqlString) tdLog.debug("complete to create %d child tables by %s.%s" % @@ -613,13 +612,13 @@ class TDTestCase: return def init_normal_tb(self, tsql, db_name: str, tb_name: str, rows: int, start_ts: int, ts_step: int): - sql = 'CREATE TABLE %s.%s (ts timestamp, c1 INT, c2 INT, c3 INT, c4 VARCHAR(255))' % ( + sql = 'CREATE TABLE %s.%s (ts timestamp, c1 INT, c2 INT, c3 INT, c4 double, c5 VARCHAR(255))' % ( db_name, tb_name) tsql.execute(sql) sql = 'INSERT INTO %s.%s values' % (db_name, tb_name) for j in range(rows): - sql += '(%d, %d,%d,%d,"varchar_%d"),' % (start_ts + j * ts_step + randrange(500), j % 10 + randrange(200), j % 10, j % 10, - j % 10 + randrange(100)) + sql += f'(%d, %d,%d,%d,{random.random()},"varchar_%d"),' % (start_ts + j * ts_step + randrange(500), j % + 10 + randrange(200), j % 10, j % 10, j % 10 + randrange(100)) tsql.execute(sql) def insert_data(self, tsql, dbName, ctbPrefix, ctbNum, rowsPerTbl, batchNum, startTs, tsStep): @@ -772,23 +771,25 @@ class TDTestCase: def test_recursive_tsma(self): tdSql.execute('drop tsma tsma2') - func_list: List[str] = ['avg(c2)', 'avg(c3)'] - self.create_tsma('tsma3', 'test', 'meters', func_list, '5m') + tsma_func_list = ['avg(c2)', 'avg(c3)', 'min(c4)', 'max(c3)', 'sum(c2)', 'count(ts)', 'count(c2)'] + select_func_list: List[str] = tsma_func_list.copy() + select_func_list.append('count(*)') + self.create_tsma('tsma3', 'test', 'meters', tsma_func_list, '5m') self.create_recursive_tsma( - 'tsma3', 'tsma4', 'test', '20m', 'meters', func_list) + 'tsma3', 'tsma4', 'test', '20m', 'meters', tsma_func_list) # now we have 5m, 10m, 30m, 1h 4 tsmas sql = 'select avg(c2), "recursive tsma4" from meters' ctx = TSMAQCBuilder().with_sql(sql).should_query_with_tsma( 'tsma4', UsedTsma.TS_MIN, UsedTsma.TS_MAX).get_qc() self.tsma_tester.check_sql(sql, ctx) - self.check(self.test_query_tsma_all(['avg(c2)', 'avg(c3)'])) + self.check(self.test_query_tsma_all(select_func_list)) self.create_recursive_tsma( - 'tsma4', 'tsma6', 'test', '1h', 'meters', func_list) + 'tsma4', 'tsma6', 'test', '1h', 'meters', tsma_func_list) ctx = TSMAQCBuilder().with_sql(sql).should_query_with_tsma( 'tsma6', UsedTsma.TS_MIN, UsedTsma.TS_MAX).get_qc() self.tsma_tester.check_sql(sql, ctx) - self.check(self.test_query_tsma_all(['avg(c2)', 'avg(c3)'])) + self.check(self.test_query_tsma_all(select_func_list)) tdSql.error('drop tsma tsma3', -2147482491) tdSql.error('drop tsma tsma4', -2147482491) @@ -1000,7 +1001,7 @@ class TDTestCase: # time.sleep(999999) self.test_ddl() self.test_query_with_tsma() - time.sleep(999999) + # time.sleep(999999) def test_create_tsma(self): function_name = sys._getframe().f_code.co_name @@ -1087,13 +1088,24 @@ class TDTestCase: 'create tsma tsma2 on meters function(avg(c1), avg(c2)) interval(999999b)', -2147471097) tdSql.error( 'create tsma tsma2 on meters function(avg(c1), avg(c2)) interval(999u)', -2147471097) - tdSql.error('create tsma tsma2 on meters function(avg(c1, c2), avg(c2)) interval(10m)', -2147471096) ## invalid tsma func param - tdSql.error('create tsma tsma2 on meters function(avg(ts), avg(c2)) interval(10m)', -2147473406)## invalid param data type - tdSql.error('create tsma tsma2 on meters function(avg(c3), avg(c2)) interval(10m)', -2147473406) - tdSql.error('create tsma tsma2 on meters function(avg(c1+1), avg(c2)) interval(10m)', -2147471096) ## invalid tsma func param - tdSql.error('create tsma tsma2 on meters function(avg(c1*c2), avg(c2)) interval(10m)', -2147471096) ## invalid tsma func param + # invalid tsma func param + tdSql.error( + 'create tsma tsma2 on meters function(avg(c1, c2), avg(c2)) interval(10m)', -2147471096) + # invalid param data type + tdSql.error( + 'create tsma tsma2 on meters function(avg(ts), avg(c2)) interval(10m)', -2147473406) + tdSql.error( + 'create tsma tsma2 on meters function(avg(c3), avg(c2)) interval(10m)', -2147473406) + # invalid tsma func param + tdSql.error( + 'create tsma tsma2 on meters function(avg(c1+1), avg(c2)) interval(10m)', -2147471096) + # invalid tsma func param + tdSql.error( + 'create tsma tsma2 on meters function(avg(c1*c2), avg(c2)) interval(10m)', -2147471096) - tdSql.error('create tsma tsma1 on meters function(avg(c1), avg(c2)) interval(10m)', -2147482496) ## sma already exists + # sma already exists + tdSql.error( + 'create tsma tsma1 on meters function(avg(c1), avg(c2)) interval(10m)', -2147482496) tdSql.execute('drop tsma tsma1', queryTimes=1) tdSql.execute('use test', queryTimes=1)