From 0bca04440ff1d01f864670c9e8b82368142aabbd Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Thu, 14 Jan 2021 12:56:03 +0000 Subject: [PATCH] TD-2571 --- src/client/inc/tsclient.h | 2 ++ src/client/src/tscLocalMerge.c | 4 ++-- src/client/src/tscSQLParser.c | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 900fab53a2..26a2502106 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -223,6 +223,8 @@ typedef struct SQueryInfo { int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX int16_t resColumnId; // result column id + bool distinctTag; // distinct tag or not + } SQueryInfo; typedef struct { diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c index 4aa751574c..80dde8576f 100644 --- a/src/client/src/tscLocalMerge.c +++ b/src/client/src/tscLocalMerge.c @@ -1102,7 +1102,7 @@ static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx) * the number of output result is decided by main output */ int32_t functionId = pCtx[j].functionId; - if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAGPRJ) { + if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG) { continue; } @@ -1184,7 +1184,7 @@ bool needToMerge(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer, tFilePage int16_t functionId = pLocalReducer->pCtx[0].functionId; // todo opt performance - if ((/*functionId == TSDB_FUNC_PRJ || */functionId == TSDB_FUNC_ARITHM) || (tscIsProjectionQueryOnSTable(pQueryInfo, 0))) { // column projection query + if ((/*functionId == TSDB_FUNC_PRJ || */functionId == TSDB_FUNC_ARITHM) || (tscIsProjectionQueryOnSTable(pQueryInfo, 0) && pQueryInfo->distinctTag == false)) { // column projection query ret = 1; // disable merge procedure } else { tOrderDescriptor *pDesc = pLocalReducer->pDesc; diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index ffb2927cbd..94b01f0a65 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1476,23 +1476,39 @@ static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) { pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; } +bool isValidDistinctSql(SQueryInfo* pQueryInfo) { + if (pQueryInfo == NULL) { + return false; + } + if ((pQueryInfo->type & TSDB_QUERY_TYPE_STABLE_QUERY) != TSDB_QUERY_TYPE_STABLE_QUERY) { + return false; + } + if (tscQueryTags(pQueryInfo) && tscSqlExprNumOfExprs(pQueryInfo) == 1){ + return true; + } + return false; +} int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool intervalQuery) { assert(pSelection != NULL && pCmd != NULL); const char* msg2 = "functions can not be mixed up"; const char* msg3 = "not support query expression"; const char* msg5 = "invalid function name"; + const char* msg6 = "only support distinct one tag"; SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); if (pQueryInfo->colList == NULL) { pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); } - + bool hasDistinct = false; for (int32_t i = 0; i < pSelection->nExpr; ++i) { int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); tSqlExprItem* pItem = &pSelection->a[i]; - + + if (hasDistinct == false) { + hasDistinct = (pItem->distinct == true); + } // project on all fields int32_t optr = pItem->pNode->nSQLOptr; @@ -1526,6 +1542,13 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel } } + if (hasDistinct == true) { + if (!isValidDistinctSql(pQueryInfo)) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + } + pQueryInfo->distinctTag = true; + } + // there is only one user-defined column in the final result field, add the timestamp column. size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList); if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo)) { @@ -4605,6 +4628,12 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu setDefaultOrderInfo(pQueryInfo); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + + if (pQueryInfo->distinctTag == true) { + pQueryInfo->order.order = TSDB_ORDER_ASC; + pQueryInfo->order.orderColId = 0; + return TSDB_CODE_SUCCESS; + } if (pQuerySql->pSortOrder == NULL) { return TSDB_CODE_SUCCESS; } -- GitLab