add tsma funcs

This commit is contained in:
wangjiaming0909 2024-03-08 10:26:38 +00:00
parent 98ca847eb8
commit cc9550f45e
10 changed files with 94 additions and 49 deletions

View File

@ -166,6 +166,10 @@ typedef enum EFunctionType {
FUNCTION_TYPE_IRATE_MERGE, FUNCTION_TYPE_IRATE_MERGE,
FUNCTION_TYPE_AVG_STATE, FUNCTION_TYPE_AVG_STATE,
FUNCTION_TYPE_AVG_STATE_MERGE, 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 // geometry functions
FUNCTION_TYPE_GEOM_FROM_TEXT = 4250, FUNCTION_TYPE_GEOM_FROM_TEXT = 4250,

View File

@ -827,6 +827,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_TSMA_INVALID_TB TAOS_DEF_ERROR_CODE(0, 0x3106) #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_INTERVAL TAOS_DEF_ERROR_CODE(0, 0x3107)
#define TSDB_CODE_TSMA_INVALID_FUNC_PARAM TAOS_DEF_ERROR_CODE(0, 0x3108) #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 //rsma
#define TSDB_CODE_RSMA_INVALID_ENV TAOS_DEF_ERROR_CODE(0, 0x3150) #define TSDB_CODE_RSMA_INVALID_ENV TAOS_DEF_ERROR_CODE(0, 0x3150)

View File

@ -55,6 +55,7 @@ extern "C" {
#define FUNC_MGT_SKIP_SCAN_CHECK_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(26) #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_IGNORE_NULL_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(27)
#define FUNC_MGT_PRIMARY_KEY_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(28) #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) #define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)

View File

@ -2418,7 +2418,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{ {
.name = "count", .name = "count",
.type = FUNCTION_TYPE_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, .translateFunc = translateCount,
.dataRequiredFunc = countDataRequired, .dataRequiredFunc = countDataRequired,
.getEnvFunc = getCountFuncEnv, .getEnvFunc = getCountFuncEnv,
@ -2431,12 +2431,13 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
#endif #endif
.combineFunc = combineFunction, .combineFunc = combineFunction,
.pPartialFunc = "count", .pPartialFunc = "count",
.pStateFunc = "count",
.pMergeFunc = "sum" .pMergeFunc = "sum"
}, },
{ {
.name = "sum", .name = "sum",
.type = FUNCTION_TYPE_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, .translateFunc = translateSum,
.dataRequiredFunc = statisDataRequired, .dataRequiredFunc = statisDataRequired,
.getEnvFunc = getSumFuncEnv, .getEnvFunc = getSumFuncEnv,
@ -2449,12 +2450,13 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
#endif #endif
.combineFunc = sumCombine, .combineFunc = sumCombine,
.pPartialFunc = "sum", .pPartialFunc = "sum",
.pStateFunc = "sum",
.pMergeFunc = "sum" .pMergeFunc = "sum"
}, },
{ {
.name = "min", .name = "min",
.type = FUNCTION_TYPE_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, .translateFunc = translateInOutNum,
.dataRequiredFunc = statisDataRequired, .dataRequiredFunc = statisDataRequired,
.getEnvFunc = getMinmaxFuncEnv, .getEnvFunc = getMinmaxFuncEnv,
@ -2464,12 +2466,13 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.finalizeFunc = minmaxFunctionFinalize, .finalizeFunc = minmaxFunctionFinalize,
.combineFunc = minCombine, .combineFunc = minCombine,
.pPartialFunc = "min", .pPartialFunc = "min",
.pStateFunc = "min",
.pMergeFunc = "min" .pMergeFunc = "min"
}, },
{ {
.name = "max", .name = "max",
.type = FUNCTION_TYPE_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, .translateFunc = translateInOutNum,
.dataRequiredFunc = statisDataRequired, .dataRequiredFunc = statisDataRequired,
.getEnvFunc = getMinmaxFuncEnv, .getEnvFunc = getMinmaxFuncEnv,
@ -2479,6 +2482,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.finalizeFunc = minmaxFunctionFinalize, .finalizeFunc = minmaxFunctionFinalize,
.combineFunc = maxCombine, .combineFunc = maxCombine,
.pPartialFunc = "max", .pPartialFunc = "max",
.pStateFunc = "max",
.pMergeFunc = "max" .pMergeFunc = "max"
}, },
{ {
@ -2544,7 +2548,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{ {
.name = "avg", .name = "avg",
.type = FUNCTION_TYPE_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, .translateFunc = translateInNumOutDou,
.dataRequiredFunc = statisDataRequired, .dataRequiredFunc = statisDataRequired,
.getEnvFunc = getAvgFuncEnv, .getEnvFunc = getAvgFuncEnv,
@ -2906,7 +2910,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.name = "first", .name = "first",
.type = FUNCTION_TYPE_FIRST, .type = FUNCTION_TYPE_FIRST,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | .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, .translateFunc = translateFirstLast,
.dynDataRequiredFunc = firstDynDataReq, .dynDataRequiredFunc = firstDynDataReq,
.getEnvFunc = getFirstLastFuncEnv, .getEnvFunc = getFirstLastFuncEnv,
@ -3850,7 +3854,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
//TODO for outer use not only internal //TODO for outer use not only internal
.name = "_avg_state", .name = "_avg_state",
.type = FUNCTION_TYPE_AVG_STATE, .type = FUNCTION_TYPE_AVG_STATE,
.classification = FUNC_MGT_AGG_FUNC, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC,
.translateFunc = translateAvgState, .translateFunc = translateAvgState,
//.dataRequiredFunc = statisDataRequired, //.dataRequiredFunc = statisDataRequired,
.getEnvFunc = getAvgFuncEnv, .getEnvFunc = getAvgFuncEnv,
@ -3864,13 +3868,26 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{ {
.name = "_avg_state_merge", .name = "_avg_state_merge",
.type = FUNCTION_TYPE_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, .translateFunc = translateAvgStateMerge,
.getEnvFunc = getAvgFuncEnv, .getEnvFunc = getAvgFuncEnv,
.initFunc = avgFunctionSetup, .initFunc = avgFunctionSetup,
.processFunc = avgFunctionMerge, .processFunc = avgFunctionMerge,
.finalizeFunc = avgPartialFinalize, .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 // clang-format on

View File

@ -714,6 +714,7 @@ int32_t avgFunctionMerge(SqlFunctionCtx* pCtx) {
int32_t start = pInput->startRowIndex; int32_t start = pInput->startRowIndex;
for (int32_t i = start; i < start + pInput->numOfRows; ++i) { for (int32_t i = start; i < start + pInput->numOfRows; ++i) {
if(colDataIsNull_s(pCol, i)) continue;
char* data = colDataGetData(pCol, i); char* data = colDataGetData(pCol, i);
SAvgRes* pInputInfo = (SAvgRes*)varDataVal(data); SAvgRes* pInputInfo = (SAvgRes*)varDataVal(data);
avgTransferInfo(pInputInfo, pInfo); avgTransferInfo(pInputInfo, pInfo);

View File

@ -539,7 +539,8 @@ static int32_t fmCreateStateFunc(const SFunctionNode* pFunc, SFunctionNode** pSt
} }
bool fmIsTSMASupportedFunc(func_id_t funcId) { 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) { int32_t fmCreateStateFuncs(SNodeList* pFuncs) {

View File

@ -3592,7 +3592,7 @@ static int32_t setNormalTableVgroupList(STranslateContext* pCxt, SName* pName, S
} }
static int32_t setTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) { static int32_t setTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) {
if (pCxt->pParseCxt->topicQuery) { if (0 && pCxt->pParseCxt->topicQuery) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -10581,7 +10581,7 @@ static int32_t buildTSMAAstMakeConcatFuncNode(SCreateTSMAStmt* pStmt, SMCreateSm
code = nodesListMakeStrictAppend(&pSubstrFunc->pParameterList, nodesMakeNode(QUERY_NODE_VALUE)); code = nodesListMakeStrictAppend(&pSubstrFunc->pParameterList, nodesMakeNode(QUERY_NODE_VALUE));
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
SValueNode* pV = (SValueNode*)pSubstrFunc->pParameterList->pTail->pNode; 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; if (!pV->literal) code = TSDB_CODE_OUT_OF_MEMORY;
pV->isDuration = false; pV->isDuration = false;
pV->translate = 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; if (!*ppCol) return TSDB_CODE_OUT_OF_MEMORY;
(*ppCol)->colId = pSchema->colId; (*ppCol)->colId = pSchema->colId;
(*ppCol)->node.resType.type = pSchema->type;
(*ppCol)->node.resType.bytes = pSchema->bytes;
strcpy((*ppCol)->colName, pSchema->name); strcpy((*ppCol)->colName, pSchema->name);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -10674,9 +10676,6 @@ static int32_t rewriteTSMAFuncs(STranslateContext* pCxt, SCreateTSMAStmt* pStmt,
SFunctionNode* pFunc = NULL; SFunctionNode* pFunc = NULL;
SColumnNode* pCol = NULL; SColumnNode* pCol = NULL;
if (pStmt->pOptions->recursiveTsma) { if (pStmt->pOptions->recursiveTsma) {
// recursive tsma, create func list from base tsma
code = fmCreateStateMergeFuncs(pStmt->pOptions->pFuncs);
if (TSDB_CODE_SUCCESS == code) {
int32_t i = 0; int32_t i = 0;
FOREACH(pNode, pStmt->pOptions->pFuncs) { FOREACH(pNode, pStmt->pOptions->pFuncs) {
// rewrite all func parameters with tsma dest tb cols // rewrite all func parameters with tsma dest tb cols
@ -10686,10 +10685,12 @@ static int32_t rewriteTSMAFuncs(STranslateContext* pCxt, SCreateTSMAStmt* pStmt,
if (code) break; if (code) break;
nodesListErase(pFunc->pParameterList, pFunc->pParameterList->pHead); nodesListErase(pFunc->pParameterList, pFunc->pParameterList->pHead);
nodesListPushFront(pFunc->pParameterList, (SNode*)pCol); nodesListPushFront(pFunc->pParameterList, (SNode*)pCol);
//TODO what if exceeds the max size
snprintf(pFunc->node.userAlias, TSDB_COL_NAME_LEN, "%s", pSchema->name); snprintf(pFunc->node.userAlias, TSDB_COL_NAME_LEN, "%s", pSchema->name);
++i; ++i;
} }
// recursive tsma, create func list from base tsma
if (TSDB_CODE_SUCCESS == code) {
code = fmCreateStateMergeFuncs(pStmt->pOptions->pFuncs);
} }
} else { } else {
FOREACH(pNode, pStmt->pOptions->pFuncs) { FOREACH(pNode, pStmt->pOptions->pFuncs) {
@ -10699,7 +10700,13 @@ static int32_t rewriteTSMAFuncs(STranslateContext* pCxt, SCreateTSMAStmt* pStmt,
code = TSDB_CODE_TSMA_INVALID_FUNC_PARAM; code = TSDB_CODE_TSMA_INVALID_FUNC_PARAM;
break; 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; pCol = (SColumnNode*)pFunc->pParameterList->pHead->pNode;
snprintf(pFunc->node.userAlias, TSDB_COL_NAME_LEN, "%s(%s)", pFunc->functionName, pCol->colName); snprintf(pFunc->node.userAlias, TSDB_COL_NAME_LEN, "%s(%s)", pFunc->functionName, pCol->colName);
} }

View File

@ -5902,7 +5902,7 @@ static bool tsmaOptCheckValidFuncs(const SArray* pTsmaFuncs, const SNodeList* pQ
} }
int32_t queryColId = ((SColumnNode*)pQueryFunc->pParameterList->pHead->pNode)->colId; int32_t queryColId = ((SColumnNode*)pQueryFunc->pParameterList->pHead->pNode)->colId;
found = false; found = false;
int32_t notMyStateFuncId = 0; int32_t notMyStateFuncId = -1;
// iterate funcs // iterate funcs
// TODO if func is count, skip checking cols, test count(*) // TODO if func is count, skip checking cols, test count(*)
for (int32_t i = 0; i < pTsmaFuncs->size; i++) { for (int32_t i = 0; i < pTsmaFuncs->size; i++) {

View File

@ -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_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_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_INVALID_FUNC_PARAM, "Invalid tsma func param, only one column allowed")
TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_UNSUPPORTED_FUNC, "Tsma func not supported")
//rsma //rsma
TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_ENV, "Invalid rsma env") TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_ENV, "Invalid rsma env")

View File

@ -225,7 +225,8 @@ class TSMATester:
sql, str(no_tsma_res), str(tsma_res))) sql, str(no_tsma_res), str(tsma_res)))
if skip_order: if skip_order:
try: 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)) tsma_res.sort(key=lambda x: [v is None for v in x] + list(x))
except Exception as e: except Exception as e:
tdLog.exit("comparing tsma res for: %s got different data: \nno tsma res: %s \n tsma res: %s err: %s" % ( 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))) (sql, str(tsma_res), str(no_tsma_res)))
def check_sql(self, sql: str, expect: TSMAQueryContext): def check_sql(self, sql: str, expect: TSMAQueryContext):
return
tdLog.debug(f"start to check sql: {sql}") tdLog.debug(f"start to check sql: {sql}")
actual_ctx = self.check_explain(sql, expect=expect) actual_ctx = self.check_explain(sql, expect=expect)
tdLog.debug(f"ctx: {actual_ctx}") tdLog.debug(f"ctx: {actual_ctx}")
@ -399,7 +399,7 @@ class TSMATestSQLGenerator:
opt = random.choice(opts) opt = random.choice(opts)
return f'{column_name} = "{opt}"' return f'{column_name} = "{opt}"'
## TODO support it # TODO support it
def generate_str_in_operator(self, column_name: str, opts: List) -> str: def generate_str_in_operator(self, column_name: str, opts: List) -> str:
opt = random.choice(opts) opt = random.choice(opts)
IN = f'"{",".join(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): def create_ctable(self, tsql=None, dbName='dbx', stbName='stb', ctbPrefix='ctb', ctbNum=1, ctbStartIdx=0):
for i in range(ctbNum): for i in range(ctbNum):
sqlString = "create table %s.%s%d using %s.%s tags(%d, 'tb%d', 'tb%d', %d, %d, %d)" % \ 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(
(dbName, ctbPrefix, i+ctbStartIdx, dbName, stbName, (i+ctbStartIdx) % 5, i+ctbStartIdx + 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))
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) tsql.execute(sqlString)
tdLog.debug("complete to create %d child tables by %s.%s" % tdLog.debug("complete to create %d child tables by %s.%s" %
@ -613,13 +612,13 @@ class TDTestCase:
return return
def init_normal_tb(self, tsql, db_name: str, tb_name: str, rows: int, start_ts: int, ts_step: int): 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) db_name, tb_name)
tsql.execute(sql) tsql.execute(sql)
sql = 'INSERT INTO %s.%s values' % (db_name, tb_name) sql = 'INSERT INTO %s.%s values' % (db_name, tb_name)
for j in range(rows): 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, sql += f'(%d, %d,%d,%d,{random.random()},"varchar_%d"),' % (start_ts + j * ts_step + randrange(500), j %
j % 10 + randrange(100)) 10 + randrange(200), j % 10, j % 10, j % 10 + randrange(100))
tsql.execute(sql) tsql.execute(sql)
def insert_data(self, tsql, dbName, ctbPrefix, ctbNum, rowsPerTbl, batchNum, startTs, tsStep): def insert_data(self, tsql, dbName, ctbPrefix, ctbNum, rowsPerTbl, batchNum, startTs, tsStep):
@ -772,23 +771,25 @@ class TDTestCase:
def test_recursive_tsma(self): def test_recursive_tsma(self):
tdSql.execute('drop tsma tsma2') tdSql.execute('drop tsma tsma2')
func_list: List[str] = ['avg(c2)', 'avg(c3)'] tsma_func_list = ['avg(c2)', 'avg(c3)', 'min(c4)', 'max(c3)', 'sum(c2)', 'count(ts)', 'count(c2)']
self.create_tsma('tsma3', 'test', 'meters', func_list, '5m') 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( 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 # now we have 5m, 10m, 30m, 1h 4 tsmas
sql = 'select avg(c2), "recursive tsma4" from meters' sql = 'select avg(c2), "recursive tsma4" from meters'
ctx = TSMAQCBuilder().with_sql(sql).should_query_with_tsma( ctx = TSMAQCBuilder().with_sql(sql).should_query_with_tsma(
'tsma4', UsedTsma.TS_MIN, UsedTsma.TS_MAX).get_qc() 'tsma4', UsedTsma.TS_MIN, UsedTsma.TS_MAX).get_qc()
self.tsma_tester.check_sql(sql, ctx) 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( 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( ctx = TSMAQCBuilder().with_sql(sql).should_query_with_tsma(
'tsma6', UsedTsma.TS_MIN, UsedTsma.TS_MAX).get_qc() 'tsma6', UsedTsma.TS_MIN, UsedTsma.TS_MAX).get_qc()
self.tsma_tester.check_sql(sql, ctx) 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 tsma3', -2147482491)
tdSql.error('drop tsma tsma4', -2147482491) tdSql.error('drop tsma tsma4', -2147482491)
@ -1000,7 +1001,7 @@ class TDTestCase:
# time.sleep(999999) # time.sleep(999999)
self.test_ddl() self.test_ddl()
self.test_query_with_tsma() self.test_query_with_tsma()
time.sleep(999999) # time.sleep(999999)
def test_create_tsma(self): def test_create_tsma(self):
function_name = sys._getframe().f_code.co_name 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) 'create tsma tsma2 on meters function(avg(c1), avg(c2)) interval(999999b)', -2147471097)
tdSql.error( tdSql.error(
'create tsma tsma2 on meters function(avg(c1), avg(c2)) interval(999u)', -2147471097) '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 # 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(
tdSql.error('create tsma tsma2 on meters function(avg(c3), avg(c2)) interval(10m)', -2147473406) 'create tsma tsma2 on meters function(avg(c1, c2), avg(c2)) interval(10m)', -2147471096)
tdSql.error('create tsma tsma2 on meters function(avg(c1+1), avg(c2)) interval(10m)', -2147471096) ## invalid tsma func param # invalid param data type
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)
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('drop tsma tsma1', queryTimes=1)
tdSql.execute('use test', queryTimes=1) tdSql.execute('use test', queryTimes=1)