diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 2c888b8d2d3461facc963b7a22fb74f9f1d5c7ad..b250eed5a12e88b1c4829ceee52520764d4e96b6 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -143,6 +143,7 @@ bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo); bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo); bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo); bool tscGroupbyColumn(SQueryInfo* pQueryInfo); +bool tscGroupbyTag(SQueryInfo* pQueryInfo); int32_t tscGetTopBotQueryExprIndex(SQueryInfo* pQueryInfo); bool tscIsTopBotQuery(SQueryInfo* pQueryInfo); bool hasTagValOutput(SQueryInfo* pQueryInfo); diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 8dfb7f6bb7321472931aa05b0b96d4237583fcc4..2103c5c8ededaee59b22f9a024b71d57ff241703 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -8895,6 +8895,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf pQueryInfo->simpleAgg = isSimpleAggregateRv(pQueryInfo); pQueryInfo->onlyTagQuery = onlyTagPrjFunction(pQueryInfo); pQueryInfo->groupbyColumn = tscGroupbyColumn(pQueryInfo); + pQueryInfo->groupbyTag = tscGroupbyTag(pQueryInfo); pQueryInfo->arithmeticOnAgg = tsIsArithmeticQueryOnAggResult(pQueryInfo); pQueryInfo->orderProjectQuery = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0); diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index cba337cd1c7048acf76b77c614adecaa75bce0c9..af5d21c279d186d33f14768cb69af3c1e887b00a 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -3736,6 +3736,25 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { return hasData; } + +void tscSetQuerySort(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr) { + if (pQueryInfo->interval.interval <= 0) { + return; + } + + if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { + size_t size = taosArrayGetSize(pQueryInfo->pUpstream); + for(int32_t i = 0; i < size; ++i) { + SQueryInfo* pq = taosArrayGetP(pQueryInfo->pUpstream, i); + if (pq->groupbyTag && pq->interval.interval > 0) { + pQueryAttr->needSort = true; + return; + } + } + } +} + + void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pSourceOperator, char* sql, void* merger, int32_t stage, uint64_t qId) { assert(pQueryInfo != NULL); @@ -3838,6 +3857,7 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr SArray* pa = NULL; if (stage == MASTER_SCAN) { pQueryAttr->createFilterOperator = false; // no need for parent query + tscSetQuerySort(pQueryInfo, pQueryAttr); pa = createExecOperatorPlan(pQueryAttr); } else { pa = createGlobalMergePlan(pQueryAttr); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 2b16ffc011f875ba716e60de207c26bfad3fcaec..6a3ceef2c242f6f8ca7781db8694580f180d3358 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -385,6 +385,19 @@ bool tscGroupbyColumn(SQueryInfo* pQueryInfo) { return false; } +bool tscGroupbyTag(SQueryInfo* pQueryInfo) { + SGroupbyExpr* pGroupbyExpr = &pQueryInfo->groupbyExpr; + for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols; ++k) { + SColIndex* pIndex = taosArrayGet(pGroupbyExpr->columnInfo, k); + if (TSDB_COL_IS_TAG(pIndex->flag)) { // group by tag + return true; + } + } + + return false; +} + + int32_t tscGetTopBotQueryExprIndex(SQueryInfo* pQueryInfo) { size_t numOfExprs = tscNumOfExprs(pQueryInfo); @@ -1217,6 +1230,7 @@ static void createInputDataFilterInfo(SQueryInfo* px, int32_t numOfCol1, int32_t tfree(tableCols); } + void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQueryInfo* px, SSqlObj* pSql) { SSqlRes* pOutput = &pSql->res; diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index 17e027b6f65c3f9f0f088f21a78ff6bbfdeb4747..acd70b66883d59f8ace42c804307d395c0df3b4b 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -227,6 +227,7 @@ typedef struct SQueryAttr { bool stateWindow; // window State on sub/normal table bool createFilterOperator; // if filter operator is needed bool multigroupResult; // multigroup result can exist in one SSDataBlock + bool needSort; // need sort rowRes int32_t interBufSize; // intermediate buffer sizse int32_t havingNum; // having expr number diff --git a/src/query/inc/qTableMeta.h b/src/query/inc/qTableMeta.h index fce8e23d1c0f2aa4b2bf4b35f2b99a1b5344658d..5db76bce188e4386ebe3c83af82b8faf72d0ed5f 100644 --- a/src/query/inc/qTableMeta.h +++ b/src/query/inc/qTableMeta.h @@ -142,7 +142,8 @@ typedef struct SQueryInfo { struct SQueryInfo *pDownstream; int32_t havingFieldNum; bool stableQuery; - bool groupbyColumn; + bool groupbyColumn; + bool groupbyTag; bool simpleAgg; bool arithmeticOnAgg; bool projectionQuery; diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 42787f22190e3fd7685af6598b51fc9c9699d0c2..ae4db6bdb8a7887e7adc7bf15354a104f1a903fa 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -5917,6 +5917,18 @@ static SSDataBlock* doFilter(void* param, bool* newgroup) { return NULL; } +static int32_t resRowCompare(const void *r1, const void *r2) { + SResultRow *res1 = *(SResultRow **)r1; + SResultRow *res2 = *(SResultRow **)r2; + + if (res1->win.skey == res2->win.skey) { + return 0; + } else { + return res1->win.skey > res2->win.skey ? 1 : -1; + } +} + + static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { @@ -5962,6 +5974,10 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { pQueryAttr->window = win; pOperator->status = OP_RES_TO_RETURN; + if (pIntervalInfo->resultRowInfo.size > 0 && pQueryAttr->needSort) { + qsort(pIntervalInfo->resultRowInfo.pResult, pIntervalInfo->resultRowInfo.size, POINTER_BYTES, resRowCompare); + } + closeAllResultRows(&pIntervalInfo->resultRowInfo); setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); finalizeQueryResult(pOperator, pIntervalInfo->pCtx, &pIntervalInfo->resultRowInfo, pIntervalInfo->rowCellInfoOffset); diff --git a/tests/script/general/parser/nestquery.sim b/tests/script/general/parser/nestquery.sim index 3c1ba0336973b8d07c785337de2d2c66202520c4..4182b867053d5d26cdc95970c545fd0c5f20d09c 100644 --- a/tests/script/general/parser/nestquery.sim +++ b/tests/script/general/parser/nestquery.sim @@ -508,4 +508,381 @@ if $data11 != 2.000000000 then return -1 endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +sql create database test2; +sql use test2; +sql create table meters (ts TIMESTAMP,a INT,b INT) TAGS (area INT); +sql CREATE TABLE t0 USING meters TAGS (0); +sql CREATE TABLE t1 USING meters TAGS (1); +sql CREATE TABLE t2 USING meters TAGS (1); +sql CREATE TABLE t3 USING meters TAGS (0); +sql insert into t0 values ('2021-09-30 15:00:00.00',0,0); +sql insert into t0 values ('2021-09-30 15:00:01.00',1,1); +sql insert into t0 values ('2021-09-30 15:00:03.00',3,3); +sql insert into t0 values ('2021-09-30 15:00:05.00',5,5); +sql insert into t0 values ('2021-09-30 15:00:07.00',7,7); +sql insert into t0 values ('2021-09-30 15:00:09.00',9,9); + +sql insert into t1 values ('2021-09-30 15:00:00.00',0,0); +sql insert into t1 values ('2021-09-30 15:00:02.00',2,2); +sql insert into t1 values ('2021-09-30 15:00:04.00',4,4); +sql insert into t1 values ('2021-09-30 15:00:06.00',6,6); +sql insert into t1 values ('2021-09-30 15:00:08.00',8,8); +sql insert into t1 values ('2021-09-30 15:00:10.00',10,10); + +sql insert into t2 values ('2021-09-30 15:00:00.00',0,0); +sql insert into t2 values ('2021-09-30 15:00:01.00',11,11); +sql insert into t2 values ('2021-09-30 15:00:02.00',22,22); +sql insert into t2 values ('2021-09-30 15:00:03.00',33,33); +sql insert into t2 values ('2021-09-30 15:00:04.00',44,44); +sql insert into t2 values ('2021-09-30 15:00:05.00',55,55); + +sql insert into t3 values ('2021-09-30 15:00:00.00',0,0); +sql insert into t3 values ('2021-09-30 15:00:01.00',11,11); +sql insert into t3 values ('2021-09-30 15:00:02.00',22,22); +sql insert into t3 values ('2021-09-30 15:00:03.00',33,33); +sql insert into t3 values ('2021-09-30 15:00:04.00',44,44); +sql insert into t3 values ('2021-09-30 15:00:05.00',55,55); + +sql select count(*) from meters interval(1s) group by tbname; +if $rows != 24 then + return -1 +endi + +sql select count(*) from (select count(*) from meters interval(1s) group by tbname) interval(1s); +if $rows != 11 then + return -1 +endi +if $data00 != @21-09-30 15:00:00.000@ then + return -1 +endi +if $data01 != 4 then + return -1 +endi +if $data10 != @21-09-30 15:00:01.000@ then + return -1 +endi +if $data11 != 3 then + return -1 +endi +if $data20 != @21-09-30 15:00:02.000@ then + return -1 +endi +if $data21 != 3 then + return -1 +endi +if $data30 != @21-09-30 15:00:03.000@ then + return -1 +endi +if $data31 != 3 then + return -1 +endi +if $data40 != @21-09-30 15:00:04.000@ then + return -1 +endi +if $data41 != 3 then + return -1 +endi +if $data50 != @21-09-30 15:00:05.000@ then + return -1 +endi +if $data51 != 3 then + return -1 +endi +if $data60 != @21-09-30 15:00:06.000@ then + return -1 +endi +if $data61 != 1 then + return -1 +endi +if $data70 != @21-09-30 15:00:07.000@ then + return -1 +endi +if $data71 != 1 then + return -1 +endi +if $data80 != @21-09-30 15:00:08.000@ then + return -1 +endi +if $data81 != 1 then + return -1 +endi +if $data90 != @21-09-30 15:00:09.000@ then + return -1 +endi +if $data91 != 1 then + return -1 +endi + +sql select count(*) from (select count(*) from meters interval(1s) group by area) interval(1s); +if $rows != 11 then + return -1 +endi +if $data00 != @21-09-30 15:00:00.000@ then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data10 != @21-09-30 15:00:01.000@ then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data20 != @21-09-30 15:00:02.000@ then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data30 != @21-09-30 15:00:03.000@ then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data40 != @21-09-30 15:00:04.000@ then + return -1 +endi +if $data41 != 2 then + return -1 +endi +if $data50 != @21-09-30 15:00:05.000@ then + return -1 +endi +if $data51 != 2 then + return -1 +endi +if $data60 != @21-09-30 15:00:06.000@ then + return -1 +endi +if $data61 != 1 then + return -1 +endi +if $data70 != @21-09-30 15:00:07.000@ then + return -1 +endi +if $data71 != 1 then + return -1 +endi +if $data80 != @21-09-30 15:00:08.000@ then + return -1 +endi +if $data81 != 1 then + return -1 +endi +if $data90 != @21-09-30 15:00:09.000@ then + return -1 +endi +if $data91 != 1 then + return -1 +endi + + +sql select sum(sa) from (select sum(a) as sa from meters interval(1s) group by tbname) interval(1s); +if $rows != 11 then + return -1 +endi +if $data00 != @21-09-30 15:00:00.000@ then + return -1 +endi +if $data01 != 0 then + return -1 +endi +if $data10 != @21-09-30 15:00:01.000@ then + return -1 +endi +if $data11 != 23 then + return -1 +endi +if $data20 != @21-09-30 15:00:02.000@ then + return -1 +endi +if $data21 != 46 then + return -1 +endi +if $data30 != @21-09-30 15:00:03.000@ then + return -1 +endi +if $data31 != 69 then + return -1 +endi +if $data40 != @21-09-30 15:00:04.000@ then + return -1 +endi +if $data41 != 92 then + return -1 +endi +if $data50 != @21-09-30 15:00:05.000@ then + return -1 +endi +if $data51 != 115 then + return -1 +endi +if $data60 != @21-09-30 15:00:06.000@ then + return -1 +endi +if $data61 != 6 then + return -1 +endi +if $data70 != @21-09-30 15:00:07.000@ then + return -1 +endi +if $data71 != 7 then + return -1 +endi +if $data80 != @21-09-30 15:00:08.000@ then + return -1 +endi +if $data81 != 8 then + return -1 +endi +if $data90 != @21-09-30 15:00:09.000@ then + return -1 +endi +if $data91 != 9 then + return -1 +endi + +sql select sum(sa) from (select sum(a) as sa from meters interval(1s) group by area) interval(1s); +if $rows != 11 then + return -1 +endi +if $data00 != @21-09-30 15:00:00.000@ then + return -1 +endi +if $data01 != 0 then + return -1 +endi +if $data10 != @21-09-30 15:00:01.000@ then + return -1 +endi +if $data11 != 23 then + return -1 +endi +if $data20 != @21-09-30 15:00:02.000@ then + return -1 +endi +if $data21 != 46 then + return -1 +endi +if $data30 != @21-09-30 15:00:03.000@ then + return -1 +endi +if $data31 != 69 then + return -1 +endi +if $data40 != @21-09-30 15:00:04.000@ then + return -1 +endi +if $data41 != 92 then + return -1 +endi +if $data50 != @21-09-30 15:00:05.000@ then + return -1 +endi +if $data51 != 115 then + return -1 +endi +if $data60 != @21-09-30 15:00:06.000@ then + return -1 +endi +if $data61 != 6 then + return -1 +endi +if $data70 != @21-09-30 15:00:07.000@ then + return -1 +endi +if $data71 != 7 then + return -1 +endi +if $data80 != @21-09-30 15:00:08.000@ then + return -1 +endi +if $data81 != 8 then + return -1 +endi +if $data90 != @21-09-30 15:00:09.000@ then + return -1 +endi +if $data91 != 9 then + return -1 +endi + + + +sql select count(*) from (select count(*) from meters interval(1s)) interval(1s); +if $rows != 11 then + return -1 +endi +if $data00 != @21-09-30 15:00:00.000@ then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data10 != @21-09-30 15:00:01.000@ then + return -1 +endi +if $data11 != 1 then + return -1 +endi +if $data20 != @21-09-30 15:00:02.000@ then + return -1 +endi +if $data21 != 1 then + return -1 +endi +if $data30 != @21-09-30 15:00:03.000@ then + return -1 +endi +if $data31 != 1 then + return -1 +endi +if $data40 != @21-09-30 15:00:04.000@ then + return -1 +endi +if $data41 != 1 then + return -1 +endi +if $data50 != @21-09-30 15:00:05.000@ then + return -1 +endi +if $data51 != 1 then + return -1 +endi +if $data60 != @21-09-30 15:00:06.000@ then + return -1 +endi +if $data61 != 1 then + return -1 +endi +if $data70 != @21-09-30 15:00:07.000@ then + return -1 +endi +if $data71 != 1 then + return -1 +endi +if $data80 != @21-09-30 15:00:08.000@ then + return -1 +endi +if $data81 != 1 then + return -1 +endi +if $data90 != @21-09-30 15:00:09.000@ then + return -1 +endi +if $data91 != 1 then + return -1 +endi + +sql select count(*) from (select count(*) from meters interval(1s) group by tbname); +if $rows != 1 then + return -1 +endi +if $data00 != 24 then + return -1 +endi + + +system sh/exec.sh -n dnode1 -s stop -x SIGINT