From cae0a9e7b229b7661067d9a6274e64a62d2731eb Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 17 Aug 2021 08:44:44 +0000 Subject: [PATCH] [TD-4335] support group by multi column --- src/client/src/tscSQLParser.c | 7 +++-- src/query/src/qExecutor.c | 56 +++++++++++++++++------------------ 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 70c7310c2b..c626031171 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -3555,7 +3555,7 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd const char* msg4 = "join query does not support group by"; const char* msg5 = "not allowed column type for group by"; const char* msg6 = "tags not allowed for table query"; - //const char* msg7 = "not support group by expression"; + const char* msg7 = "not support group by primary key"; //const char* msg8 = "normal column can only locate at the end of group by clause"; // todo : handle two tables situation @@ -3638,9 +3638,12 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); } else { // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by - if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { + if (pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } + if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); + } tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index ca6ce09f88..d5cefde6c0 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -52,7 +52,6 @@ (_dst).ekey = (_src).ekey;\ } while (0) -#define GROUPBY_MULTI_COLUMN_DELIM "-" enum { TS_JOIN_TS_EQUAL = 0, @@ -1675,17 +1674,18 @@ static bool initGroupbyInfo(const SSDataBlock *pSDataBlock, const SGroupbyExpr * } } } - pInfo->totalBytes += (int32_t)strlen(GROUPBY_MULTI_COLUMN_DELIM) * pGroupbyExpr->numOfGroupCols; + pInfo->totalBytes += (int32_t)strlen(MULTI_KEY_DELIM) * pGroupbyExpr->numOfGroupCols; return true; } -static void buildGroupbyKeyBuf(const SSDataBlock *pSDataBlock, SGroupbyOperatorInfo *pInfo, int32_t rowId, char **buf, bool *isNullKey) { +static void buildGroupbyKeyBuf(const SSDataBlock *pSDataBlock, SGroupbyOperatorInfo *pInfo, int32_t rowId, char **buf) { char *p = calloc(1, pInfo->totalBytes); - if (p == NULL) { *buf = NULL; return; } - + if (p == NULL) { + *buf = NULL; + return; + } *buf = p; - *isNullKey = true; for (int32_t i = 0; i < taosArrayGetSize(pInfo->pGroupbyDataInfo); i++) { SGroupbyDataInfo *pDataInfo = taosArrayGet(pInfo->pGroupbyDataInfo, i); @@ -1703,24 +1703,27 @@ static void buildGroupbyKeyBuf(const SSDataBlock *pSDataBlock, SGroupbyOperatorI memcpy(p, val, pDataInfo->bytes); p += pDataInfo->bytes; } - memcpy(p, GROUPBY_MULTI_COLUMN_DELIM, strlen(GROUPBY_MULTI_COLUMN_DELIM)); - p += strlen(GROUPBY_MULTI_COLUMN_DELIM); - *isNullKey = false; + + memcpy(p, MULTI_KEY_DELIM, strlen(MULTI_KEY_DELIM)); + p += strlen(MULTI_KEY_DELIM); } } static bool isGroupbyKeyEqual(void *a, void *b, void *ext) { SGroupbyOperatorInfo *pInfo = (SGroupbyOperatorInfo *)ext; - + if (memcmp(a, b, pInfo->totalBytes) == 0) { + return true; + } int32_t offset = 0; for (int32_t i = 0; i < taosArrayGetSize(pInfo->pGroupbyDataInfo); i++) { SGroupbyDataInfo *pDataInfo = taosArrayGet(pInfo->pGroupbyDataInfo, i); + char *k1 = (char *)a + offset; char *k2 = (char *)b + offset; if (getComparFunc(pDataInfo->type, 0)(k1, k2) != 0) { return false; } offset += pDataInfo->bytes; - offset += (int32_t)strlen(GROUPBY_MULTI_COLUMN_DELIM); + offset += (int32_t)strlen(MULTI_KEY_DELIM); } return true; } @@ -1747,11 +1750,9 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn char *key = NULL; int16_t num = 0; int32_t type = 0; - bool isNullKey = false; for (int32_t j = 0; j < pSDataBlock->info.rows; ++j) { - buildGroupbyKeyBuf(pSDataBlock, pInfo, j, &key, &isNullKey); - if (isNullKey) { continue;} - if (key == NULL) { /* handle malloc failure*/} + buildGroupbyKeyBuf(pSDataBlock, pInfo, j, &key); + if (!key) { continue;} if (pInfo->prevData == NULL) { // first row of pInfo->prevData = key; @@ -1781,20 +1782,19 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn } if (num > 0) { - buildGroupbyKeyBuf(pSDataBlock, pInfo, pSDataBlock->info.rows - num, &key, &isNullKey); - tfree(pInfo->prevData); - pInfo->prevData = key; - - if (pQueryAttr->stableQuery && pQueryAttr->stabledev && (pRuntimeEnv->prevResult != NULL)) { - setParamForStableStddevByColData(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, pOperator->pExpr, pInfo); - } - - int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, pInfo->prevData, type, pInfo->totalBytes, item->groupIndex); - if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code - longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); + buildGroupbyKeyBuf(pSDataBlock, pInfo, pSDataBlock->info.rows - num, &key); + if (key) { + tfree(pInfo->prevData); + pInfo->prevData = key; + if (pQueryAttr->stableQuery && pQueryAttr->stabledev && (pRuntimeEnv->prevResult != NULL)) { + setParamForStableStddevByColData(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, pOperator->pExpr, pInfo); + } + int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, pInfo->prevData, type, pInfo->totalBytes, item->groupIndex); + if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code + longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); + } + doApplyFunctions(pRuntimeEnv, pInfo->binfo.pCtx, &w, pSDataBlock->info.rows - num, num, tsList, pSDataBlock->info.rows, pOperator->numOfOutput); } - - doApplyFunctions(pRuntimeEnv, pInfo->binfo.pCtx, &w, pSDataBlock->info.rows - num, num, tsList, pSDataBlock->info.rows, pOperator->numOfOutput); } tfree(pInfo->prevData); } -- GitLab