diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 427431d3c00549da4008bb6a9879288b4685b92d..2c4d711520471cb3c1cc6acc308479593a24c0f6 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -138,6 +138,7 @@ bool isSimpleAggregateRv(SQueryInfo* pQueryInfo); bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex); bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex); +bool tscIsDiffDerivQuery(SQueryInfo* pQueryInfo); bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex); bool tscIsProjectionQuery(SQueryInfo* pQueryInfo); diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 57e1ee93bce111680f153c3518bc0959c0e33123..15c816d3d47ce13c08ebcd58b29d307c21a73aa5 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -6306,7 +6306,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { int16_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS || - functionId == TSDB_FUNC_ARITHM) { + functionId == TSDB_FUNC_ARITHM || functionId == TSDB_FUNC_TS_DUMMY) { continue; } @@ -6412,9 +6412,14 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo size_t size = tscNumOfExprs(pQueryInfo); if (TSDB_COL_IS_TAG(pColIndex->flag)) { + + int32_t f = TSDB_FUNC_TAG; + if (tscIsDiffDerivQuery(pQueryInfo)) { + f = TSDB_FUNC_TAGPRJ; + } + SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; - SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, s->type, s->bytes, - getNewResColId(pCmd), s->bytes, true); + SExprInfo* pExpr = tscExprAppend(pQueryInfo, f, &index, s->type, s->bytes, getNewResColId(pCmd), s->bytes, true); memset(pExpr->base.aliasName, 0, sizeof(pExpr->base.aliasName)); tstrncpy(pExpr->base.aliasName, s->name, sizeof(pExpr->base.aliasName)); @@ -6550,7 +6555,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* } // projection query on super table does not compatible with "group by" syntax - if (tscIsProjectionQuery(pQueryInfo)) { + if (tscIsProjectionQuery(pQueryInfo) && !(tscIsDiffDerivQuery(pQueryInfo))) { return invalidOperationMsg(msg, msg3); } @@ -7758,7 +7763,8 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf const char* msg2 = "too many tables in from clause"; const char* msg3 = "start(end) time of query range required or time range too large"; const char* msg4 = "interval query not supported, since the result of sub query not include valid timestamp column"; - const char* msg9 = "only tag query not compatible with normal column filter"; + const char* msg5 = "only tag query not compatible with normal column filter"; + const char* msg6 = "not support stddev/percentile in outer query yet"; int32_t code = TSDB_CODE_SUCCESS; @@ -7799,6 +7805,15 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf return TSDB_CODE_TSC_INVALID_OPERATION; } + // todo NOT support yet + for(int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) { + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); + int32_t f = pExpr->base.functionId; + if (f == TSDB_FUNC_STDDEV || f == TSDB_FUNC_PERCT) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); + } + } + // validate the query filter condition info if (pSqlNode->pWhere != NULL) { if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { @@ -7912,7 +7927,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf for (int32_t i = 0; i < numOfCols; ++i) { SColumn* pCols = taosArrayGetP(pQueryInfo->colList, i); if (pCols->info.flist.numOfFilters > 0) { - return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } } } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 60919c98b5ae1d1ebc4d229b2023d679c87c1118..c17cd21c42c92aeeb09c21f5ed040ed8a8bee32d 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -255,10 +255,14 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) { size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId; + int32_t f = tscExprGet(pQueryInfo, i)->base.functionId; + if (f == TSDB_FUNC_TS_DUMMY) { + continue; + } - if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ && functionId != TSDB_FUNC_TAG && - functionId != TSDB_FUNC_TS && functionId != TSDB_FUNC_ARITHM) { + if (f != TSDB_FUNC_PRJ && f != TSDB_FUNC_TAGPRJ && f != TSDB_FUNC_TAG && + f != TSDB_FUNC_TS && f != TSDB_FUNC_ARITHM && f != TSDB_FUNC_DIFF && + f != TSDB_FUNC_DERIVATIVE) { return false; } } @@ -266,6 +270,24 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) { return true; } +bool tscIsDiffDerivQuery(SQueryInfo* pQueryInfo) { + size_t size = tscNumOfExprs(pQueryInfo); + + for (int32_t i = 0; i < size; ++i) { + int32_t f = tscExprGet(pQueryInfo, i)->base.functionId; + if (f == TSDB_FUNC_TS_DUMMY) { + continue; + } + + if (f == TSDB_FUNC_DIFF || f == TSDB_FUNC_DERIVATIVE) { + return true; + } + } + + return false; +} + + bool tscHasColumnFilter(SQueryInfo* pQueryInfo) { // filter on primary timestamp column if (pQueryInfo->window.skey != INT64_MIN || pQueryInfo->window.ekey != INT64_MAX) { diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 2fc6f332df3c4f0cbb26339c7ea1ac85b61870ba..5dea37ee0b36c1b7495446bb42f84ce482b14e3e 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -5394,7 +5394,7 @@ SAggFunctionInfo aAggs[] = {{ "diff", TSDB_FUNC_DIFF, TSDB_FUNC_INVALID_ID, - TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SELECTIVITY, diff_function_setup, diff_function, diff_function_f, @@ -5498,7 +5498,7 @@ SAggFunctionInfo aAggs[] = {{ "derivative", // return table id and the corresponding tags for join match and subscribe TSDB_FUNC_DERIVATIVE, TSDB_FUNC_INVALID_ID, - TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SELECTIVITY, deriv_function_setup, deriv_function, noop2, diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 9e78354c19befd0d01b5c06f44f2e3d6afc837c2..8af6251568b462325b8e0588d52e09aa07c4af3c 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1687,8 +1687,6 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; pRuntimeEnv->prevGroupId = INT32_MIN; - pRuntimeEnv->enableGroupData = false; - pRuntimeEnv->pQueryAttr = pQueryAttr; pRuntimeEnv->pResultRowHashTable = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); @@ -4123,6 +4121,7 @@ int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr pQueryAttr->interBufSize = getOutputInterResultBufSize(pQueryAttr); pRuntimeEnv->groupResInfo.totalGroup = (int32_t) (pQueryAttr->stableQuery? GET_NUM_OF_TABLEGROUP(pRuntimeEnv):0); + pRuntimeEnv->enableGroupData = false; pRuntimeEnv->pQueryAttr = pQueryAttr; pRuntimeEnv->pTsBuf = pTsBuf; diff --git a/tests/script/general/parser/nestquery.sim b/tests/script/general/parser/nestquery.sim index 16d190d3fe174e2c19960999584baa7352f555aa..98c0918c0f51683d69f00546b76a2e553b548fdc 100644 --- a/tests/script/general/parser/nestquery.sim +++ b/tests/script/general/parser/nestquery.sim @@ -147,8 +147,57 @@ if $data02 != @nest_tb0@ then endi print ===================> nest query interval +sql_error select ts, avg(c1) from (select ts, c1 from nest_tb0); +sql select avg(c1) from (select * from nest_tb0) interval(3d) +if $rows != 3 then + return -1 +endi + +if $data00 != @20-09-14 00:00:00.000@ then + return -1 +endi + +if $data01 != 49.222222222 then + return -1 +endi + +if $data10 != @20-09-17 00:00:00.000@ then + print expect 20-09-17 00:00:00.000, actual: $data10 + return -1 +endi + +if $data11 != 49.685185185 then + return -1 +endi + +if $data20 != @20-09-20 00:00:00.000@ then + return -1 +endi + +if $data21 != 49.500000000 then + return -1 +endi + +#define TSDB_FUNC_APERCT 7 +#define TSDB_FUNC_LAST_ROW 10 +#define TSDB_FUNC_TWA 14 +#define TSDB_FUNC_LEASTSQR 15 +#define TSDB_FUNC_ARITHM 23 +#define TSDB_FUNC_DIFF 24 +#define TSDB_FUNC_INTERP 28 +#define TSDB_FUNC_RATE 29 +#define TSDB_FUNC_IRATE 30 +#define TSDB_FUNC_DERIVATIVE 32 + +sql_error select stddev(c1) from (select c1 from nest_tb0); +sql_error select percentile(c1, 20) from (select * from nest_tb0); + +sql select avg(c1),sum(c2), max(c3), min(c4), count(*), first(c7), last(c7),spread(c6) from (select * from nest_tb0) interval(1d); + +sql select top(x, 20) from (select c1 x from nest_tb0); +sql select bottom(x, 20) from (select c1 x from nest_tb0) print ===================> complex query