From 7c6bc107605bccadda20a3d3f1bf4ec42b43ad82 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 27 Apr 2022 17:52:39 +0800 Subject: [PATCH 1/3] fix(query): enable the limitation on the number of query results within each group. --- source/client/src/clientImpl.c | 12 ++++++++++-- source/libs/executor/src/executorimpl.c | 11 +++++------ source/libs/parser/src/parInsert.c | 1 - 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 7c873acadb..c41400f439 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -358,8 +358,16 @@ SRequestObj* launchQuery(STscObj* pTscObj, const char* sql, int sqlLen) { SQuery* pQuery = NULL; int32_t code = buildRequest(pTscObj, sql, sqlLen, &pRequest); - if (TSDB_CODE_SUCCESS == code) { - code = parseSql(pRequest, false, &pQuery, NULL); + if (code != TSDB_CODE_SUCCESS) { + terrno = code; + return NULL; + } + + code = parseSql(pRequest, false, &pQuery, NULL); + if (code != TSDB_CODE_SUCCESS) { + destroyRequest(pRequest); + terrno = code; + return NULL; } return launchQueryImpl(pRequest, pQuery, code, false); diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index f6b1839f68..85dfa4c866 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -4994,13 +4994,12 @@ static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock) pProjectInfo->curOffset = 0; } + // check for the limitation in each group + if (pProjectInfo->limit.limit > 0 && pProjectInfo->curOutput + pRes->info.rows >= pProjectInfo->limit.limit) { + pRes->info.rows = (int32_t)(pProjectInfo->limit.limit - pProjectInfo->curOutput); + } + if (pRes->info.rows >= pOperator->resultInfo.threshold) { - - // check for the limitation in each group - if (pProjectInfo->limit.limit > 0 && pProjectInfo->curOutput + pRes->info.rows >= pProjectInfo->limit.limit) { - pRes->info.rows = (int32_t)(pProjectInfo->limit.limit - pProjectInfo->curOutput); - } - return PROJECT_RETRIEVE_DONE; } else { // not full enough, continue to accumulate the output data in the buffer. return PROJECT_RETRIEVE_CONTINUE; diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index dfeb2df911..609413d61b 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -1069,7 +1069,6 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) { if (TSDB_QUERY_HAS_TYPE(pCxt->pOutput->insertType, TSDB_QUERY_TYPE_STMT_INSERT) && tbNum > 0) { return buildInvalidOperationMsg(&pCxt->msg, "single table allowed in one stmt"); - ; } destroyInsertParseContextForTable(pCxt); From 1c08688da20f62594ee145ae0643607b3d6935f2 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 27 Apr 2022 18:12:26 +0800 Subject: [PATCH 2/3] fix(query): return object instead of free it when error happens. --- source/client/src/clientImpl.c | 7 +++---- source/libs/executor/src/executorimpl.c | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index c41400f439..c3868ee6d5 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -365,9 +365,8 @@ SRequestObj* launchQuery(STscObj* pTscObj, const char* sql, int sqlLen) { code = parseSql(pRequest, false, &pQuery, NULL); if (code != TSDB_CODE_SUCCESS) { - destroyRequest(pRequest); - terrno = code; - return NULL; + pRequest->code = code; + return pRequest; } return launchQueryImpl(pRequest, pQuery, code, false); @@ -418,7 +417,7 @@ SRequestObj* execQuery(STscObj* pTscObj, const char* sql, int sqlLen) { while (retryNum++ < REQUEST_MAX_TRY_TIMES) { pRequest = launchQuery(pTscObj, sql, sqlLen); - if (TSDB_CODE_SUCCESS == pRequest->code || !NEED_CLIENT_HANDLE_ERROR(pRequest->code)) { + if (pRequest == NULL || TSDB_CODE_SUCCESS == pRequest->code || !NEED_CLIENT_HANDLE_ERROR(pRequest->code)) { break; } diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 85dfa4c866..76d06accf4 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -4997,6 +4997,7 @@ static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock) // check for the limitation in each group if (pProjectInfo->limit.limit > 0 && pProjectInfo->curOutput + pRes->info.rows >= pProjectInfo->limit.limit) { pRes->info.rows = (int32_t)(pProjectInfo->limit.limit - pProjectInfo->curOutput); + return PROJECT_RETRIEVE_DONE; } if (pRes->info.rows >= pOperator->resultInfo.threshold) { From d41a9e8bf0c82578329798eeaa3c1227c965db4a Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 27 Apr 2022 18:43:46 +0800 Subject: [PATCH 3/3] fix(query): enable the limitation on each group by using limit/offset. --- source/libs/executor/src/executorimpl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 76d06accf4..1da0409fb8 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -4997,10 +4997,17 @@ static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock) // check for the limitation in each group if (pProjectInfo->limit.limit > 0 && pProjectInfo->curOutput + pRes->info.rows >= pProjectInfo->limit.limit) { pRes->info.rows = (int32_t)(pProjectInfo->limit.limit - pProjectInfo->curOutput); + + if (pProjectInfo->slimit.limit == -1 || pProjectInfo->slimit.limit <= pProjectInfo->curGroupOutput) { + pOperator->status = OP_EXEC_DONE; + } + return PROJECT_RETRIEVE_DONE; } - if (pRes->info.rows >= pOperator->resultInfo.threshold) { + // If there are slimit/soffset value exists, multi-round result can not be packed into one group, since the + // they may not belong to the same group the limit/offset value is not valid in this case. + if (pRes->info.rows >= pOperator->resultInfo.threshold || pProjectInfo->slimit.offset != -1 || pProjectInfo->slimit.limit != -1) { return PROJECT_RETRIEVE_DONE; } else { // not full enough, continue to accumulate the output data in the buffer. return PROJECT_RETRIEVE_CONTINUE;