From 67991804a6ab97c170513689eabb7278c4ed215a Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sun, 23 Jul 2023 18:14:07 +0800 Subject: [PATCH 01/92] test: add build --- cmake/cmake.define | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/cmake.define b/cmake/cmake.define index cf7f450994..c72d48d7f3 100644 --- a/cmake/cmake.define +++ b/cmake/cmake.define @@ -1,5 +1,4 @@ cmake_minimum_required(VERSION 3.0) - set(CMAKE_VERBOSE_MAKEFILE ON) set(TD_BUILD_TAOSA_INTERNAL FALSE) From 41aa6a0c671e4210aff4d4a9852817df069704dc Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sun, 23 Jul 2023 18:17:18 +0800 Subject: [PATCH 02/92] test: test build taos-tools --- source/libs/wal/src/walMeta.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/libs/wal/src/walMeta.c b/source/libs/wal/src/walMeta.c index 3d457c9b5f..0fe7e3a1a0 100644 --- a/source/libs/wal/src/walMeta.c +++ b/source/libs/wal/src/walMeta.c @@ -20,6 +20,7 @@ #include "tutil.h" #include "walInt.h" + bool FORCE_INLINE walLogExist(SWal* pWal, int64_t ver) { return !walIsEmpty(pWal) && walGetFirstVer(pWal) <= ver && walGetLastVer(pWal) >= ver; } From cddf27e8b4d9183b321d83ea2df1ef5561a294bd Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 31 Jul 2023 18:48:50 +0800 Subject: [PATCH 03/92] fix:add committed & seek process logic --- source/client/test/clientTests.cpp | 3 ++- source/dnode/mnode/impl/src/mndSubscribe.c | 1 + source/dnode/vnode/src/tq/tq.c | 6 +++--- source/dnode/vnode/src/vnd/vnodeSvr.c | 5 +++++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index d88a26cbb2..6f978b0143 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -1251,7 +1251,8 @@ TEST(clientCase, td_25129) { } for(int i = 0; i < numOfAssign; i++){ - printf("assign i:%d, vgId:%d, offset:%lld, start:%lld, end:%lld\n", i, pAssign[i].vgId, pAssign[i].currentOffset, pAssign[i].begin, pAssign[i].end); + int64_t committed = tmq_committed(tmq, topicName, pAssign[i].vgId); + printf("assign i:%d, vgId:%d, committed:%lld, offset:%lld, start:%lld, end:%lld\n", i, pAssign[i].vgId, committed, pAssign[i].currentOffset, pAssign[i].begin, pAssign[i].end); } while (1) { diff --git a/source/dnode/mnode/impl/src/mndSubscribe.c b/source/dnode/mnode/impl/src/mndSubscribe.c index 6bd23c3b90..85054e5cd7 100644 --- a/source/dnode/mnode/impl/src/mndSubscribe.c +++ b/source/dnode/mnode/impl/src/mndSubscribe.c @@ -692,6 +692,7 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) { taosArrayDestroy(rebOutput.modifyConsumers); taosArrayDestroy(rebOutput.rebVgs); + taosHashCancelIterate(pReq->rebSubHash, pIter); terrno = TSDB_CODE_OUT_OF_MEMORY; mInfo("mq re-balance failed, due to out of memory"); taosHashCleanup(pReq->rebSubHash); diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 4d4383473d..2999944dd0 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -336,10 +336,10 @@ int32_t tqProcessOffsetCommitReq(STQ* pTq, int64_t sversion, char* msg, int32_t STqOffset* pOffset = &vgOffset.offset; if (pOffset->val.type == TMQ_OFFSET__SNAPSHOT_DATA || pOffset->val.type == TMQ_OFFSET__SNAPSHOT_META) { - tqInfo("receive offset commit msg to %s on vgId:%d, offset(type:snapshot) uid:%" PRId64 ", ts:%" PRId64, + tqDebug("receive offset commit msg to %s on vgId:%d, offset(type:snapshot) uid:%" PRId64 ", ts:%" PRId64, pOffset->subKey, vgId, pOffset->val.uid, pOffset->val.ts); } else if (pOffset->val.type == TMQ_OFFSET__LOG) { - tqInfo("receive offset commit msg to %s on vgId:%d, offset(type:log) version:%" PRId64, pOffset->subKey, vgId, + tqDebug("receive offset commit msg to %s on vgId:%d, offset(type:log) version:%" PRId64, pOffset->subKey, vgId, pOffset->val.version); } else { tqError("invalid commit offset type:%d", pOffset->val.type); @@ -367,12 +367,12 @@ int32_t tqProcessSeekReq(STQ* pTq, SRpcMsg* pMsg) { SRpcMsg rsp = {.info = pMsg->info}; int code = 0; - tqDebug("tmq seek: consumer:0x%" PRIx64 " vgId:%d, subkey %s", req.consumerId, vgId, req.subKey); if (tDeserializeSMqSeekReq(pMsg->pCont, pMsg->contLen, &req) < 0) { code = TSDB_CODE_OUT_OF_MEMORY; goto end; } + tqDebug("tmq seek: consumer:0x%" PRIx64 " vgId:%d, subkey %s", req.consumerId, vgId, req.subKey); STqHandle* pHandle = taosHashGet(pTq->pHandle, req.subKey, strlen(req.subKey)); if (pHandle == NULL) { tqWarn("tmq seek: consumer:0x%" PRIx64 " vgId:%d subkey %s not found", req.consumerId, vgId, req.subKey); diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index 81f87a3e22..743470aac8 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -624,6 +624,11 @@ int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) { // return tqProcessPollReq(pVnode->pTq, pMsg); case TDMT_VND_TMQ_VG_WALINFO: return tqProcessVgWalInfoReq(pVnode->pTq, pMsg); + case TDMT_VND_TMQ_VG_COMMITTEDINFO: + return tqProcessVgCommittedInfoReq(pVnode->pTq, pMsg); + case TDMT_VND_TMQ_SEEK: + return tqProcessSeekReq(pVnode->pTq, pMsg); + default: vError("unknown msg type:%d in fetch queue", pMsg->msgType); return TSDB_CODE_APP_ERROR; From 8a0e9ff0e0722e9578a1cc53933664c0dea6fb64 Mon Sep 17 00:00:00 2001 From: dmchen Date: Tue, 1 Aug 2023 14:24:28 +0800 Subject: [PATCH 04/92] fix/retry_resolve_fqdn --- include/common/tglobal.h | 1 + source/common/src/tglobal.c | 3 +++ source/libs/sync/src/syncUtil.c | 18 +++++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 8ea0a857e8..81f2af98f5 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -198,6 +198,7 @@ extern bool tsFilterScalarMode; extern int32_t tsKeepTimeOffset; extern int32_t tsMaxStreamBackendCache; extern int32_t tsPQSortMemThreshold; +extern int32_t tsResolveFQDNRetryTime; // #define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 0546ed7f47..56202899cd 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -234,6 +234,7 @@ int64_t tsStreamBufferSize = 128 * 1024 * 1024; int64_t tsCheckpointInterval = 3 * 60 * 60 * 1000; bool tsFilterScalarMode = false; int32_t tsKeepTimeOffset = 0; // latency of data migration +int tsResolveFQDNRetryTime = 100; //seconds #ifndef _STORAGE int32_t taosSetTfsCfg(SConfig *pCfg) { @@ -559,6 +560,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddInt32(pCfg, "keepTimeOffset", tsKeepTimeOffset, 0, 23, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "maxStreamBackendCache", tsMaxStreamBackendCache, 16, 1024, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "pqSortMemThreshold", tsPQSortMemThreshold, 1, 10240, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddInt32(pCfg, "resolveFQDNRetryTime", tsResolveFQDNRetryTime, 1, 10240, 0) != 0) return -1; GRANT_CFG_ADD; return 0; @@ -947,6 +949,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { tsKeepTimeOffset = cfgGetItem(pCfg, "keepTimeOffset")->i32; tsMaxStreamBackendCache = cfgGetItem(pCfg, "maxStreamBackendCache")->i32; tsPQSortMemThreshold = cfgGetItem(pCfg, "pqSortMemThreshold")->i32; + tsResolveFQDNRetryTime = cfgGetItem(pCfg, "resolveFQDNRetryTime")->i32; GRANT_CFG_GET; return 0; diff --git a/source/libs/sync/src/syncUtil.c b/source/libs/sync/src/syncUtil.c index ae1c775a18..9acc17e130 100644 --- a/source/libs/sync/src/syncUtil.c +++ b/source/libs/sync/src/syncUtil.c @@ -21,6 +21,7 @@ #include "syncRaftCfg.h" #include "syncRaftStore.h" #include "syncSnapshot.h" +#include "tglobal.h" void syncCfg2SimpleStr(const SSyncCfg* pCfg, char* buf, int32_t bufLen) { int32_t len = snprintf(buf, bufLen, "{num:%d, as:%d, [", pCfg->replicaNum, pCfg->myIndex); @@ -41,7 +42,22 @@ void syncUtilNodeInfo2EpSet(const SNodeInfo* pInfo, SEpSet* pEpSet) { } bool syncUtilNodeInfo2RaftId(const SNodeInfo* pInfo, SyncGroupId vgId, SRaftId* raftId) { - uint32_t ipv4 = taosGetIpv4FromFqdn(pInfo->nodeFqdn); + uint32_t ipv4 = 0xFFFFFFFF; + sDebug("vgId:%d, start to resolve sync addr fqdn in %d seconds, " + "dnode:%d cluster:%" PRId64 " fqdn:%s port:%u ", + vgId, tsResolveFQDNRetryTime, + pInfo->nodeId, pInfo->clusterId, pInfo->nodeFqdn, pInfo->nodePort); + for(int i = 0; i < tsResolveFQDNRetryTime; i++){ + ipv4 = taosGetIpv4FromFqdn(pInfo->nodeFqdn); + if (ipv4 == 0xFFFFFFFF || ipv4 == 1) { + sError("failed to resolve ipv4 addr, fqdn:%s, wait one second", pInfo->nodeFqdn); + taosSsleep(1); + } + else{ + break; + } + } + if (ipv4 == 0xFFFFFFFF || ipv4 == 1) { sError("failed to resolve ipv4 addr, fqdn:%s", pInfo->nodeFqdn); terrno = TSDB_CODE_TSC_INVALID_FQDN; From d0332a7789d44ddd11982ffbd514b4b4b94bedf0 Mon Sep 17 00:00:00 2001 From: liuyao <38781207+54liuyao@users.noreply.github.com> Date: Thu, 3 Aug 2023 14:20:55 +0800 Subject: [PATCH 05/92] Update 14-stream.md --- docs/zh/12-taos-sql/14-stream.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/zh/12-taos-sql/14-stream.md b/docs/zh/12-taos-sql/14-stream.md index 634f50356d..43bdc9b04a 100644 --- a/docs/zh/12-taos-sql/14-stream.md +++ b/docs/zh/12-taos-sql/14-stream.md @@ -249,3 +249,12 @@ T = 最新事件时间 - DELETE_MARK - [unique](../function/#unique) - [mode](../function/#mode) +## 暂停、恢复流计算 +1.流计算暂停计算任务 +PAUSE STREAM [IF EXISTS] stream_name; +没有指定IF EXISTS,如果该stream不存在,则报错;如果存在,则暂停流计算。指定了IF EXISTS,如果该stream不存在,则返回成功;如果存在,则暂停流计算 + +2.流计算恢复计算任务 +RESUME STREAM [IF EXISTS] [IGNORE UNTREATED] stream_name; +没有指定IF EXISTS,如果该stream不存在,则报错,如果存在,则恢复流计算;指定了IF EXISTS,如果stream不存在,则返回成功;如果存在,则恢复流计算。如果指定IGNORE UNTREATED,则恢复流计算时,忽略流计算暂停期间写入的数据。 + From 873262ec784e8fd2f318276dddcb347fe82f2ffc Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 9 Aug 2023 20:45:05 +0800 Subject: [PATCH 06/92] fix:add test cases to cases.task --- tests/parallel_test/cases.task | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index fb67ee51cd..6b9a577fd5 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -126,6 +126,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/dataFromTsdbNWal.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/dataFromTsdbNWal-multiCtb.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_taosx.py +,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_offset.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/raw_block_interface_test.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/stbTagFilter-multiCtb.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmqSubscribeStb-r3.py -N 5 From b61216d1a85598e9e4c15352799a181e72bfd87b Mon Sep 17 00:00:00 2001 From: danielclow <106956386+danielclow@users.noreply.github.com> Date: Wed, 9 Aug 2023 23:28:54 +0800 Subject: [PATCH 07/92] docs: update 06-stream.md to correct sample sql statement the existing sql statement failed due to invalid syntax on "select _wstart as start". copying the statement from the zh document instead --- docs/en/07-develop/06-stream.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/07-develop/06-stream.md b/docs/en/07-develop/06-stream.md index 125173e60b..59a6b815cf 100644 --- a/docs/en/07-develop/06-stream.md +++ b/docs/en/07-develop/06-stream.md @@ -52,7 +52,7 @@ CREATE TABLE d1004 USING meters TAGS ("California.LosAngeles", 3); ### Create a Stream ```sql -create stream current_stream into current_stream_output_stb as select _wstart as start, _wend as end, max(current) as max_current from meters where voltage <= 220 interval (5s); +create stream current_stream trigger at_once into current_stream_output_stb as select _wstart as wstart, _wend as wend, max(current) as max_current from meters where voltage <= 220 interval (5s); ``` ### Write Data From 700d9a6d68888626f234373972a864cebbb66999 Mon Sep 17 00:00:00 2001 From: kailixu Date: Thu, 10 Aug 2023 13:02:34 +0800 Subject: [PATCH 08/92] fix: sma option for show create table --- source/libs/command/src/command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index 8ddf730d5a..921ec41021 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -624,7 +624,7 @@ void appendTableOptions(char* buf, int32_t* len, SDbCfgInfo* pDbCfg, STableCfg* } } - if (nSma < pCfg->numOfColumns) { + if (nSma < pCfg->numOfColumns && nSma > 0) { bool smaOn = false; *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, " SMA("); for (int32_t i = 0; i < pCfg->numOfColumns; ++i) { From e2481599b0f71667baea3bcbade89568e56ccbd7 Mon Sep 17 00:00:00 2001 From: liuyao <54liuyao@163.com> Date: Thu, 10 Aug 2023 13:58:46 +0800 Subject: [PATCH 09/92] fix mem leak --- source/libs/executor/src/timewindowoperator.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index d2e385200d..4f793d7064 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1520,6 +1520,10 @@ void destroyStreamFinalIntervalOperatorInfo(void* param) { colDataDestroy(&pInfo->twAggSup.timeWindowData); pInfo->groupResInfo.pRows = taosArrayDestroy(pInfo->groupResInfo.pRows); cleanupExprSupp(&pInfo->scalarSupp); + tSimpleHashCleanup(pInfo->pUpdatedMap); + pInfo->pUpdatedMap = NULL; + pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated); + taosMemoryFreeClear(param); } From 8890fa578185d7605c9348847f6b34b6c7190472 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 10 Aug 2023 15:13:49 +0800 Subject: [PATCH 10/92] fix(stream): execute the stream task directly, instead of executing it in a asynchronized way. --- source/libs/stream/src/streamExec.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index c7da80fdaf..b479931cd2 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -592,14 +592,21 @@ int32_t streamTryExec(SStreamTask* pTask) { if (pTask->status.transferState) { code = streamTransferStateToStreamTask(pTask); if (code != TSDB_CODE_SUCCESS) { + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); return code; } - streamSchedExec(pTask); - } else { - atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), - pTask->status.schedStatus); + + // the schedStatus == TASK_SCHED_STATUS__ACTIVE, streamSchedExec cannot be executed, so execute once again by + // call this function (streamExecForAll) directly. + code = streamExecForAll(pTask); + if (code < 0) { + // do nothing + } } + + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, + streamGetTaskStatusStr(pTask->status.taskStatus), pTask->status.schedStatus); } else { atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), From 78fd70202c98f7133c8901e75260f0d4dd030a6f Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 10 Aug 2023 16:18:53 +0800 Subject: [PATCH 11/92] fix:offset error in tmq & add test cases --- source/client/src/clientTmq.c | 10 ++--- source/dnode/vnode/src/inc/tq.h | 2 +- source/dnode/vnode/src/tq/tq.c | 5 +-- source/dnode/vnode/src/tq/tqUtil.c | 62 +++++++++++++-------------- source/libs/wal/src/walRead.c | 6 ++- tests/system-test/7-tmq/tmq_offset.py | 6 +-- utils/test/c/tmq_offset_test.c | 10 +++++ 7 files changed, 54 insertions(+), 47 deletions(-) diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index ae82be2470..b4168046f4 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -1863,10 +1863,10 @@ static int32_t tmqHandleNoPollRsp(tmq_t* tmq, SMqRspWrapper* rspWrapper, bool* p return 0; } -static void updateVgInfo(SMqClientVg* pVg, STqOffsetVal* reqOffset, STqOffsetVal* rspOffset, int64_t sver, int64_t ever, int64_t consumerId){ +static void updateVgInfo(SMqClientVg* pVg, STqOffsetVal* reqOffset, STqOffsetVal* rspOffset, int64_t sver, int64_t ever, int64_t consumerId, bool hasData){ if (!pVg->seekUpdated) { tscDebug("consumer:0x%" PRIx64" local offset is update, since seekupdate not set", consumerId); - pVg->offsetInfo.beginOffset = *reqOffset; + if(hasData) pVg->offsetInfo.beginOffset = *reqOffset; pVg->offsetInfo.endOffset = *rspOffset; } else { tscDebug("consumer:0x%" PRIx64" local offset is NOT update, since seekupdate is set", consumerId); @@ -1929,7 +1929,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { pVg->epSet = *pollRspWrapper->pEpset; } - updateVgInfo(pVg, &pDataRsp->reqOffset, &pDataRsp->rspOffset, pDataRsp->head.walsver, pDataRsp->head.walever, tmq->consumerId); + updateVgInfo(pVg, &pDataRsp->reqOffset, &pDataRsp->rspOffset, pDataRsp->head.walsver, pDataRsp->head.walever, tmq->consumerId, pDataRsp->blockNum != 0); char buf[TSDB_OFFSET_LEN] = {0}; tFormatOffset(buf, TSDB_OFFSET_LEN, &pDataRsp->rspOffset); @@ -1979,7 +1979,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { return NULL; } - updateVgInfo(pVg, &pollRspWrapper->metaRsp.rspOffset, &pollRspWrapper->metaRsp.rspOffset, pollRspWrapper->metaRsp.head.walsver, pollRspWrapper->metaRsp.head.walever, tmq->consumerId); + updateVgInfo(pVg, &pollRspWrapper->metaRsp.rspOffset, &pollRspWrapper->metaRsp.rspOffset, pollRspWrapper->metaRsp.head.walsver, pollRspWrapper->metaRsp.head.walever, tmq->consumerId, true); // build rsp SMqMetaRspObj* pRsp = tmqBuildMetaRspFromWrapper(pollRspWrapper); taosFreeQitem(pollRspWrapper); @@ -2007,7 +2007,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { return NULL; } - updateVgInfo(pVg, &pollRspWrapper->taosxRsp.reqOffset, &pollRspWrapper->taosxRsp.rspOffset, pollRspWrapper->taosxRsp.head.walsver, pollRspWrapper->taosxRsp.head.walever, tmq->consumerId); + updateVgInfo(pVg, &pollRspWrapper->taosxRsp.reqOffset, &pollRspWrapper->taosxRsp.rspOffset, pollRspWrapper->taosxRsp.head.walsver, pollRspWrapper->taosxRsp.head.walever, tmq->consumerId, pollRspWrapper->taosxRsp.blockNum != 0); if (pollRspWrapper->taosxRsp.blockNum == 0) { tscDebug("consumer:0x%" PRIx64 " taosx empty block received, vgId:%d, vg total:%" PRId64 ", reqId:0x%" PRIx64, diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index 13b991e038..a6a84075b5 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -175,7 +175,7 @@ int32_t extractDelDataBlock(const void* pData, int32_t len, int64_t ver, SStream int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg); int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId, int32_t type, int64_t sver, int64_t ever); -int32_t tqInitDataRsp(SMqDataRsp* pRsp, const SMqPollReq* pReq); +int32_t tqInitDataRsp(SMqDataRsp* pRsp, STqOffsetVal pOffset); #ifdef __cplusplus } #endif diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 98695a9e63..65ff1539aa 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -289,9 +289,8 @@ int32_t tqPushEmptyDataRsp(STqHandle* pHandle, int32_t vgId) { } SMqDataRsp dataRsp = {0}; - tqInitDataRsp(&dataRsp, &req); + tqInitDataRsp(&dataRsp, req.reqOffset); dataRsp.blockNum = 0; - dataRsp.rspOffset = dataRsp.reqOffset; char buf[TSDB_OFFSET_LEN] = {0}; tFormatOffset(buf, TSDB_OFFSET_LEN, &dataRsp.reqOffset); tqInfo("tqPushEmptyDataRsp to consumer:0x%"PRIx64 " vgId:%d, offset:%s, reqId:0x%" PRIx64, req.consumerId, vgId, buf, req.reqId); @@ -714,7 +713,7 @@ int32_t tqProcessVgWalInfoReq(STQ* pTq, SRpcMsg* pMsg) { walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever); SMqDataRsp dataRsp = {0}; - tqInitDataRsp(&dataRsp, &req); + tqInitDataRsp(&dataRsp, req.reqOffset); if (req.useSnapshot == true) { tqError("consumer:0x%" PRIx64 " vgId:%d subkey:%s snapshot not support wal info", consumerId, vgId, req.subKey); diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index 1a0663665d..5cbca6e0f2 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -20,8 +20,9 @@ static int32_t tqSendMetaPollRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp, int32_t vgId); -int32_t tqInitDataRsp(SMqDataRsp* pRsp, const SMqPollReq* pReq) { - pRsp->reqOffset = pReq->reqOffset; +int32_t tqInitDataRsp(SMqDataRsp* pRsp, STqOffsetVal pOffset) { + pRsp->reqOffset = pOffset; + pRsp->rspOffset = pOffset; pRsp->blockData = taosArrayInit(0, sizeof(void*)); pRsp->blockDataLen = taosArrayInit(0, sizeof(int32_t)); @@ -35,8 +36,9 @@ int32_t tqInitDataRsp(SMqDataRsp* pRsp, const SMqPollReq* pReq) { return 0; } -static int32_t tqInitTaosxRsp(STaosxRsp* pRsp, const SMqPollReq* pReq) { - pRsp->reqOffset = pReq->reqOffset; +static int32_t tqInitTaosxRsp(STaosxRsp* pRsp, STqOffsetVal pOffset) { + pRsp->reqOffset = pOffset; + pRsp->rspOffset = pOffset; pRsp->withTbName = 1; pRsp->withSchema = 1; @@ -69,7 +71,6 @@ static int32_t tqInitTaosxRsp(STaosxRsp* pRsp, const SMqPollReq* pReq) { static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg, bool* pBlockReturned) { uint64_t consumerId = pRequest->consumerId; - STqOffsetVal reqOffset = pRequest->reqOffset; STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, pRequest->subKey); int32_t vgId = TD_VID(pTq->pVnode); @@ -86,7 +87,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand return 0; } else { // no poll occurs in this vnode for this topic, let's seek to the right offset value. - if (reqOffset.type == TMQ_OFFSET__RESET_EARLIEST) { + if (pRequest->reqOffset.type == TMQ_OFFSET__RESET_EARLIEST) { if (pRequest->useSnapshot) { tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey:%s, vgId:%d, (earliest) set offset to be snapshot", consumerId, pHandle->subKey, vgId); @@ -100,12 +101,12 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand walRefFirstVer(pTq->pVnode->pWal, pHandle->pRef); tqOffsetResetToLog(pOffsetVal, pHandle->pRef->refVer); } - } else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) { + } else if (pRequest->reqOffset.type == TMQ_OFFSET__RESET_LATEST) { walRefLastVer(pTq->pVnode->pWal, pHandle->pRef); SMqDataRsp dataRsp = {0}; - tqInitDataRsp(&dataRsp, pRequest); + tqOffsetResetToLog(pOffsetVal, pHandle->pRef->refVer + 1); - tqOffsetResetToLog(&dataRsp.rspOffset, pHandle->pRef->refVer + 1); + tqInitDataRsp(&dataRsp, *pOffsetVal); tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, (latest) offset reset to %" PRId64, consumerId, pHandle->subKey, vgId, dataRsp.rspOffset.version); int32_t code = tqSendDataRsp(pHandle, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); @@ -113,7 +114,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand *pBlockReturned = true; return code; - } else if (reqOffset.type == TMQ_OFFSET__RESET_NONE) { + } else if (pRequest->reqOffset.type == TMQ_OFFSET__RESET_NONE) { tqError("tmq poll: subkey:%s, no offset committed for consumer:0x%" PRIx64 " in vg %d, subkey %s, reset none failed", pHandle->subKey, consumerId, vgId, pRequest->subKey); @@ -125,11 +126,11 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand return 0; } -static void setRequestVersion(STqOffsetVal* offset, int64_t ver){ - if(offset->type == TMQ_OFFSET__LOG){ - offset->version = ver; - } -} +//static void setRequestVersion(STqOffsetVal* offset, int64_t ver){ +// if(offset->type == TMQ_OFFSET__LOG){ +// offset->version = ver; +// } +//} static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg, STqOffsetVal* pOffset) { @@ -138,8 +139,8 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle, terrno = 0; SMqDataRsp dataRsp = {0}; - tqInitDataRsp(&dataRsp, pRequest); - dataRsp.reqOffset.type = pOffset->type; // stroe origin type for getting offset in tmq_get_vgroup_offset + tqInitDataRsp(&dataRsp, *pOffset); +// dataRsp.reqOffset.type = pOffset->type; // store origin type for getting offset in tmq_get_vgroup_offset qSetTaskId(pHandle->execHandle.task, consumerId, pRequest->reqId); int code = tqScanData(pTq, pHandle, &dataRsp, pOffset); @@ -160,7 +161,7 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle, taosWUnLockLatch(&pTq->lock); } - setRequestVersion(&dataRsp.reqOffset, pOffset->version); +// setRequestVersion(&dataRsp.reqOffset, pOffset->version); code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); end : { @@ -181,8 +182,8 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, SWalCkHead* pCkHead = NULL; SMqMetaRsp metaRsp = {0}; STaosxRsp taosxRsp = {0}; - tqInitTaosxRsp(&taosxRsp, pRequest); - taosxRsp.reqOffset.type = offset->type; // store origin type for getting offset in tmq_get_vgroup_offset + tqInitTaosxRsp(&taosxRsp, *offset); +// taosxRsp.reqOffset.type = offset->type; // store origin type for getting offset in tmq_get_vgroup_offset if (offset->type != TMQ_OFFSET__LOG) { if (tqScanTaosx(pTq, pHandle, &taosxRsp, &metaRsp, offset) < 0) { @@ -235,7 +236,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if (tqFetchLog(pTq, pHandle, &fetchVer, &pCkHead, pRequest->reqId) < 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer); - setRequestVersion(&taosxRsp.reqOffset, offset->version); +// setRequestVersion(&taosxRsp.reqOffset, offset->version); code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); goto end; } @@ -248,7 +249,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if (pHead->msgType != TDMT_VND_SUBMIT) { if (totalRows > 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer); - setRequestVersion(&taosxRsp.reqOffset, offset->version); +// setRequestVersion(&taosxRsp.reqOffset, offset->version); code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); goto end; } @@ -278,7 +279,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if (totalRows >= 4096 || taosxRsp.createTableNum > 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer + 1); - setRequestVersion(&taosxRsp.reqOffset, offset->version); +// setRequestVersion(&taosxRsp.reqOffset, offset->version); code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); goto end; } else { @@ -295,15 +296,13 @@ end: } int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg) { - int32_t code = -1; - STqOffsetVal offset = {0}; STqOffsetVal reqOffset = pRequest->reqOffset; // 1. reset the offset if needed - if (IS_OFFSET_RESET_TYPE(reqOffset.type)) { + if (IS_OFFSET_RESET_TYPE(pRequest->reqOffset.type)) { // handle the reset offset cases, according to the consumer's choice. bool blockReturned = false; - code = extractResetOffsetVal(&offset, pTq, pHandle, pRequest, pMsg, &blockReturned); + int32_t code = extractResetOffsetVal(&reqOffset, pTq, pHandle, pRequest, pMsg, &blockReturned); if (code != 0) { return code; } @@ -312,20 +311,17 @@ int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequ if (blockReturned) { return 0; } - } else if(reqOffset.type != 0){ // use the consumer specified offset - // the offset value can not be monotonious increase?? - offset = reqOffset; - } else { + } else if(reqOffset.type == 0){ // use the consumer specified offset uError("req offset type is 0"); return TSDB_CODE_TMQ_INVALID_MSG; } // this is a normal subscribe requirement if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) { - return extractDataAndRspForNormalSubscribe(pTq, pHandle, pRequest, pMsg, &offset); + return extractDataAndRspForNormalSubscribe(pTq, pHandle, pRequest, pMsg, &reqOffset); } else { // todo handle the case where re-balance occurs. // for taosx - return extractDataAndRspForDbStbSubscribe(pTq, pHandle, pRequest, pMsg, &offset); + return extractDataAndRspForDbStbSubscribe(pTq, pHandle, pRequest, pMsg, &reqOffset); } } diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c index 04a76146c6..54b9576eb1 100644 --- a/source/libs/wal/src/walRead.c +++ b/source/libs/wal/src/walRead.c @@ -75,7 +75,10 @@ int32_t walNextValidMsg(SWalReader *pReader) { wDebug("vgId:%d, wal start to fetch, index:%" PRId64 ", last index:%" PRId64 " commit index:%" PRId64 ", applied index:%" PRId64, pReader->pWal->cfg.vgId, fetchVer, lastVer, committedVer, appliedVer); - + if (fetchVer > appliedVer){ + terrno = TSDB_CODE_WAL_LOG_NOT_EXIST; + return -1; + } while (fetchVer <= appliedVer) { if (walFetchHeadNew(pReader, fetchVer) < 0) { return -1; @@ -97,7 +100,6 @@ int32_t walNextValidMsg(SWalReader *pReader) { } } - terrno = TSDB_CODE_WAL_LOG_NOT_EXIST; return -1; } diff --git a/tests/system-test/7-tmq/tmq_offset.py b/tests/system-test/7-tmq/tmq_offset.py index a39365c13b..33d36eda71 100644 --- a/tests/system-test/7-tmq/tmq_offset.py +++ b/tests/system-test/7-tmq/tmq_offset.py @@ -23,16 +23,16 @@ class TDTestCase: def run(self): tdSql.prepare() buildPath = tdCom.getBuildPath() - cmdStr1 = '%s/build/bin/taosBenchmark -i 10 -B 1 -t 100000 -n 100000 -y &'%(buildPath) + cmdStr1 = '%s/build/bin/taosBenchmark -i 50 -B 1 -t 1000 -n 100000 -y &'%(buildPath) tdLog.info(cmdStr1) os.system(cmdStr1) - time.sleep(20) + time.sleep(10) cmdStr2 = '%s/build/bin/tmq_offset_test &'%(buildPath) tdLog.info(cmdStr2) os.system(cmdStr2) - time.sleep(30) + time.sleep(20) os.system("kill -9 `pgrep taosBenchmark`") result = os.system("kill -9 `pgrep tmq_offset_test`") diff --git a/utils/test/c/tmq_offset_test.c b/utils/test/c/tmq_offset_test.c index 03f710ae16..18931e2548 100644 --- a/utils/test/c/tmq_offset_test.c +++ b/utils/test/c/tmq_offset_test.c @@ -190,6 +190,16 @@ void test_offset(TAOS* pConn){ ASSERT(0); } + for(int i = 0; i < numOfAssign; i++){ + int64_t position = tmq_position(tmq, "tp", pAssign[i].vgId); + if(position == 0) continue; + + printf("position = %lld\n", position); + tmq_commit_offset_sync(tmq, "tp", pAssign[i].vgId, position); + int64_t committed = tmq_committed(tmq, "tp", pAssign[i].vgId); + ASSERT(position == committed); + } + tmq_offset_seek(tmq, "tp", pAssign[0].vgId, pAssign[0].currentOffset); tmq_offset_seek(tmq, "tp", pAssign[1].vgId, pAssign[1].currentOffset); From ab9ad7d088321d8ef47b9ba4c053b21aa06ab5e9 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 10 Aug 2023 17:13:10 +0800 Subject: [PATCH 12/92] fix:offset error in tmq & add test cases --- tests/system-test/7-tmq/tmqMaxTopic.py | 2 +- utils/test/c/tmq_offset_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system-test/7-tmq/tmqMaxTopic.py b/tests/system-test/7-tmq/tmqMaxTopic.py index 62bc9ccb4e..05b699ca00 100644 --- a/tests/system-test/7-tmq/tmqMaxTopic.py +++ b/tests/system-test/7-tmq/tmqMaxTopic.py @@ -36,7 +36,7 @@ class TDTestCase: # tdDnodes[1].cfgDir cfgFile = f"%s/taos.cfg"%(cfgDir) - shellCmd = 'echo "tmqMaxTopicNum %d" >> %s'%(tmqMaxTopicNum, cfgFile) + shellCmd = 'echo tmqMaxTopicNum %d >> %s'%(tmqMaxTopicNum, cfgFile) tdLog.info(" shell cmd: %s"%(shellCmd)) os.system(shellCmd) tdDnodes.stoptaosd(1) diff --git a/utils/test/c/tmq_offset_test.c b/utils/test/c/tmq_offset_test.c index 18931e2548..cecbd615d1 100644 --- a/utils/test/c/tmq_offset_test.c +++ b/utils/test/c/tmq_offset_test.c @@ -194,7 +194,7 @@ void test_offset(TAOS* pConn){ int64_t position = tmq_position(tmq, "tp", pAssign[i].vgId); if(position == 0) continue; - printf("position = %lld\n", position); + printf("position = %d\n", (int)position); tmq_commit_offset_sync(tmq, "tp", pAssign[i].vgId, position); int64_t committed = tmq_committed(tmq, "tp", pAssign[i].vgId); ASSERT(position == committed); From 78bc18c71762f11ac219b4d63d998d6b78c03a1c Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Thu, 10 Aug 2023 18:17:42 +0800 Subject: [PATCH 13/92] update_release_version --- cmake/cmake.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/cmake.version b/cmake/cmake.version index 86afe68188..d5ada35dc3 100644 --- a/cmake/cmake.version +++ b/cmake/cmake.version @@ -2,7 +2,7 @@ IF (DEFINED VERNUMBER) SET(TD_VER_NUMBER ${VERNUMBER}) ELSE () - SET(TD_VER_NUMBER "3.1.0.1.alpha") + SET(TD_VER_NUMBER "3.1.0.2.alpha") ENDIF () IF (DEFINED VERCOMPATIBLE) From 6155c80729211a209e3feb843b70ac15ce923716 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 10 Aug 2023 18:38:01 +0800 Subject: [PATCH 14/92] fix:offset error in tmq & add test cases --- tests/parallel_test/cases.task | 2 +- tests/system-test/7-tmq/tmqParamsTest.py | 4 ++-- tests/system-test/7-tmq/tmq_offset.py | 2 +- utils/test/c/tmq_offset_test.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 6b9a577fd5..dd28154176 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -126,7 +126,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/dataFromTsdbNWal.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/dataFromTsdbNWal-multiCtb.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_taosx.py -,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_offset.py +,,n,system-test,python3 ./test.py -f 7-tmq/tmq_offset.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/raw_block_interface_test.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/stbTagFilter-multiCtb.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmqSubscribeStb-r3.py -N 5 diff --git a/tests/system-test/7-tmq/tmqParamsTest.py b/tests/system-test/7-tmq/tmqParamsTest.py index 0fc7a6cdd9..ff7c70bcd2 100644 --- a/tests/system-test/7-tmq/tmqParamsTest.py +++ b/tests/system-test/7-tmq/tmqParamsTest.py @@ -131,7 +131,7 @@ class TDTestCase: if snapshot_value == "true": if offset_value != "earliest" and offset_value != "": if offset_value == "latest": - offset_value_list = list(map(lambda x: int(x[-2].replace("wal:", "").replace(offset_value, "0")), subscription_info)) + offset_value_list = list(map(lambda x: int(x[-2].replace("wal:", "").replace("earliest", "0").replace("latest", "0").replace(offset_value, "0")), subscription_info)) tdSql.checkEqual(sum(offset_value_list) >= 0, True) rows_value_list = list(map(lambda x: int(x[-1]), subscription_info)) tdSql.checkEqual(sum(rows_value_list), expected_res) @@ -154,7 +154,7 @@ class TDTestCase: tdSql.checkEqual(rows_value_list, [None]*len(subscription_info)) else: if offset_value != "none": - offset_value_list = list(map(lambda x: int(x[-2].replace("wal:", "").replace(offset_value, "0")), subscription_info)) + offset_value_list = list(map(lambda x: int(x[-2].replace("wal:", "").replace("earliest", "0").replace("latest", "0").replace(offset_value, "0")), subscription_info)) tdSql.checkEqual(sum(offset_value_list) >= 0, True) rows_value_list = list(map(lambda x: int(x[-1]), subscription_info)) tdSql.checkEqual(sum(rows_value_list), expected_res) diff --git a/tests/system-test/7-tmq/tmq_offset.py b/tests/system-test/7-tmq/tmq_offset.py index 33d36eda71..6453f452c6 100644 --- a/tests/system-test/7-tmq/tmq_offset.py +++ b/tests/system-test/7-tmq/tmq_offset.py @@ -26,7 +26,7 @@ class TDTestCase: cmdStr1 = '%s/build/bin/taosBenchmark -i 50 -B 1 -t 1000 -n 100000 -y &'%(buildPath) tdLog.info(cmdStr1) os.system(cmdStr1) - time.sleep(10) + time.sleep(15) cmdStr2 = '%s/build/bin/tmq_offset_test &'%(buildPath) tdLog.info(cmdStr2) diff --git a/utils/test/c/tmq_offset_test.c b/utils/test/c/tmq_offset_test.c index cecbd615d1..6be9b38979 100644 --- a/utils/test/c/tmq_offset_test.c +++ b/utils/test/c/tmq_offset_test.c @@ -266,7 +266,7 @@ void test_ts3756(TAOS* pConn){ int32_t numOfAssign = 0; while (1) { - printf("start to poll\n"); +// printf("start to poll\n"); pRes = tmq_consumer_poll(tmq, timeout); if (pRes) { From 1afbde7d2f1437ceda703d11db4b4cce60ca1309 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 11 Aug 2023 10:06:37 +0800 Subject: [PATCH 15/92] fix: add time window boundary check before interpolation --- source/libs/executor/src/timesliceoperator.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index b019985645..c9824ff2d6 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -848,6 +848,10 @@ static void doHandleTimeslice(SOperatorInfo* pOperator, SSDataBlock* pBlock) { bool ignoreNull = getIgoreNullRes(pSup); int32_t order = TSDB_ORDER_ASC; + if (checkWindowBoundReached(pSliceInfo)) { + return; + } + int32_t code = initKeeperInfo(pSliceInfo, pBlock, &pOperator->exprSupp); if (code != TSDB_CODE_SUCCESS) { T_LONG_JMP(pTaskInfo->env, code); From b6e0e076679007c2fa4343a0e58430eb00f26bda Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 11 Aug 2023 10:07:18 +0800 Subject: [PATCH 16/92] add test case --- tests/system-test/2-query/interp.py | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py index 986c63839b..c2eb7bee2e 100644 --- a/tests/system-test/2-query/interp.py +++ b/tests/system-test/2-query/interp.py @@ -20,6 +20,7 @@ class TDTestCase: tbname = "tb" tbname1 = "tb1" tbname2 = "tb2" + tbname3 = "tb3" stbname = "stb" ctbname1 = "ctb1" ctbname2 = "ctb2" @@ -5607,6 +5608,44 @@ class TDTestCase: tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname_single} partition by tbname range('2020-02-01 00:00:06') fill(linear)") tdSql.checkRows(0) + #### TS-3799 #### + + tdSql.execute( + f'''create table if not exists {dbname}.{tbname3} (ts timestamp, c0 double)''' + ) + + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:51.000000000', 4.233947800000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:52.000000000', 3.606781000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:52.500000000', 3.162353500000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:53.000000000', 3.162292500000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:53.500000000', 4.998230000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:54.400000000', 8.800414999999999)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:54.900000000', 8.853271500000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:55.900000000', 7.507751500000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:56.400000000', 7.510681000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:56.900000000', 7.841614000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:57.900000000', 8.153809000000001)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:58.500000000', 6.866455000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:59.000000000', 6.869140600000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-07 00:00:00.000000000', 0.261475000000001)") + + tdSql.query(f"select _irowts, interp(c0) from {dbname}.{tbname3} range('2023-08-06 23:59:00','2023-08-06 23:59:59') every(1m) fill(next)") + tdSql.checkRows(1); + tdSql.checkData(0, 0, '2023-08-06 23:59:00') + tdSql.checkData(0, 1, 4.233947800000000) + + tdSql.query(f"select _irowts, interp(c0) from {dbname}.{tbname3} range('2023-08-06 23:59:00','2023-08-06 23:59:59') every(1m) fill(value, 1)") + tdSql.checkRows(1); + tdSql.checkData(0, 0, '2023-08-06 23:59:00') + tdSql.checkData(0, 1, 1) + + tdSql.query(f"select _irowts, interp(c0) from {dbname}.{tbname3} range('2023-08-06 23:59:00','2023-08-06 23:59:59') every(1m) fill(null)") + tdSql.checkRows(1); + tdSql.checkData(0, 0, '2023-08-06 23:59:00') + tdSql.checkData(0, 1, None) + + + def stop(self): tdSql.close() tdLog.success(f"{__file__} successfully executed") From 847bc0da0881a625b06a1352ef80ed32a8e1927f Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Fri, 11 Aug 2023 18:10:16 +0800 Subject: [PATCH 17/92] fix: infinite tomb data sync loop --- source/dnode/vnode/src/tsdb/tsdbSnapshot.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c index bdcf4a87c1..f547119f49 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c +++ b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c @@ -392,6 +392,9 @@ static int32_t tsdbSnapReadTombData(STsdbSnapReader* reader, uint8_t** data) { code = tTombBlockPut(reader->tombBlock, record); TSDB_CHECK_CODE(code, lino, _exit); + code = tsdbIterMergerNext(reader->tombIterMerger); + TSDB_CHECK_CODE(code, lino, _exit); + if (TOMB_BLOCK_SIZE(reader->tombBlock) >= 81920) { break; } From deda4b9eed07444133f140213e702c392824b111 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 11 Aug 2023 19:26:17 +0800 Subject: [PATCH 18/92] opti:wal logic --- include/libs/wal/wal.h | 7 +- source/dnode/vnode/src/inc/tq.h | 2 +- source/dnode/vnode/src/tq/tqRead.c | 44 ++++----- source/dnode/vnode/src/tq/tqUtil.c | 12 +-- source/libs/wal/src/walRead.c | 142 ++++------------------------- 5 files changed, 39 insertions(+), 168 deletions(-) diff --git a/include/libs/wal/wal.h b/include/libs/wal/wal.h index b19a0d783d..1f7323a06a 100644 --- a/include/libs/wal/wal.h +++ b/include/libs/wal/wal.h @@ -153,7 +153,6 @@ struct SWalReader { int64_t capacity; TdThreadMutex mutex; SWalFilterCond cond; - // TODO remove it SWalCkHead *pHead; }; @@ -208,9 +207,9 @@ void walReaderVerifyOffset(SWalReader *pWalReader, STqOffsetVal* pOffset) // only for tq usage void walSetReaderCapacity(SWalReader *pRead, int32_t capacity); -int32_t walFetchHead(SWalReader *pRead, int64_t ver, SWalCkHead *pHead); -int32_t walFetchBody(SWalReader *pRead, SWalCkHead **ppHead); -int32_t walSkipFetchBody(SWalReader *pRead, const SWalCkHead *pHead); +int32_t walFetchHead(SWalReader *pRead, int64_t ver); +int32_t walFetchBody(SWalReader *pRead); +int32_t walSkipFetchBody(SWalReader *pRead); void walRefFirstVer(SWal *, SWalRef *); void walRefLastVer(SWal *, SWalRef *); diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index a6a84075b5..f08c308185 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -127,7 +127,7 @@ void tqDestroyTqHandle(void* data); // tqRead int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMetaRsp* pMetaRsp, STqOffsetVal* offset); int32_t tqScanData(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal* pOffset); -int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHead** pHeadWithCkSum, uint64_t reqId); +int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t reqId); // tqExec int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxRsp* pRsp, int32_t* totalRows); diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 9b8f1781cb..6c091fa4cb 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -184,50 +184,42 @@ end: return tbSuid == realTbSuid; } -int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHead** ppCkHead, uint64_t reqId) { - int32_t code = 0; +int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t reqId) { + int32_t code = -1; int32_t vgId = TD_VID(pTq->pVnode); - taosThreadMutexLock(&pHandle->pWalReader->mutex); int64_t offset = *fetchOffset; + int64_t lastVer = walGetLastVer(pHandle->pWalReader->pWal); + int64_t committedVer = walGetCommittedVer(pHandle->pWalReader->pWal); + int64_t appliedVer = walGetAppliedVer(pHandle->pWalReader->pWal); - while (1) { - if (walFetchHead(pHandle->pWalReader, offset, *ppCkHead) < 0) { + wDebug("vgId:%d, wal start to fetch, index:%" PRId64 ", last index:%" PRId64 " commit index:%" PRId64 ", applied index:%" PRId64, + vgId, offset, lastVer, committedVer, appliedVer); + + while (offset <= appliedVer) { + if (walFetchHead(pHandle->pWalReader, offset) < 0) { tqDebug("tmq poll: consumer:0x%" PRIx64 ", (epoch %d) vgId:%d offset %" PRId64 ", no more log to return, reqId:0x%" PRIx64, pHandle->consumerId, pHandle->epoch, vgId, offset, reqId); - *fetchOffset = offset; - code = -1; goto END; } tqDebug("vgId:%d, consumer:0x%" PRIx64 " taosx get msg ver %" PRId64 ", type: %s, reqId:0x%" PRIx64, vgId, - pHandle->consumerId, offset, TMSG_INFO((*ppCkHead)->head.msgType), reqId); + pHandle->consumerId, offset, TMSG_INFO(pHandle->pWalReader->pHead->head.msgType), reqId); - if ((*ppCkHead)->head.msgType == TDMT_VND_SUBMIT) { - code = walFetchBody(pHandle->pWalReader, ppCkHead); - - if (code < 0) { - *fetchOffset = offset; - code = -1; - goto END; - } - *fetchOffset = offset; - code = 0; + if (pHandle->pWalReader->pHead->head.msgType == TDMT_VND_SUBMIT) { + code = walFetchBody(pHandle->pWalReader); goto END; } else { if (pHandle->fetchMeta != WITH_DATA) { - SWalCont* pHead = &((*ppCkHead)->head); + SWalCont* pHead = &(pHandle->pWalReader->pHead->head); if (IS_META_MSG(pHead->msgType) && !(pHead->msgType == TDMT_VND_DELETE && pHandle->fetchMeta == ONLY_META)) { - code = walFetchBody(pHandle->pWalReader, ppCkHead); + code = walFetchBody(pHandle->pWalReader); if (code < 0) { - *fetchOffset = offset; - code = -1; goto END; } if (isValValidForTable(pHandle, pHead)) { - *fetchOffset = offset; code = 0; goto END; } else { @@ -236,10 +228,8 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHea } } } - code = walSkipFetchBody(pHandle->pWalReader, *ppCkHead); + code = walSkipFetchBody(pHandle->pWalReader); if (code < 0) { - *fetchOffset = offset; - code = -1; goto END; } offset++; @@ -247,7 +237,7 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHea } END: - taosThreadMutexUnlock(&pHandle->pWalReader->mutex); + *fetchOffset = offset; return code; } diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index 5cbca6e0f2..42aac52c63 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -179,7 +179,6 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, SRpcMsg* pMsg, STqOffsetVal* offset) { int code = 0; int32_t vgId = TD_VID(pTq->pVnode); - SWalCkHead* pCkHead = NULL; SMqMetaRsp metaRsp = {0}; STaosxRsp taosxRsp = {0}; tqInitTaosxRsp(&taosxRsp, *offset); @@ -216,12 +215,6 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if (offset->type == TMQ_OFFSET__LOG) { walReaderVerifyOffset(pHandle->pWalReader, offset); int64_t fetchVer = offset->version; - pCkHead = taosMemoryMalloc(sizeof(SWalCkHead) + 2048); - if (pCkHead == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - code = -1; - goto end; - } walSetReaderCapacity(pHandle->pWalReader, 2048); int totalRows = 0; @@ -234,14 +227,14 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, break; } - if (tqFetchLog(pTq, pHandle, &fetchVer, &pCkHead, pRequest->reqId) < 0) { + if (tqFetchLog(pTq, pHandle, &fetchVer, pRequest->reqId) < 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer); // setRequestVersion(&taosxRsp.reqOffset, offset->version); code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); goto end; } - SWalCont* pHead = &pCkHead->head; + SWalCont* pHead = &pHandle->pWalReader->pHead->head; tqDebug("tmq poll: consumer:0x%" PRIx64 " (epoch %d) iter log, vgId:%d offset %" PRId64 " msgType %d", pRequest->consumerId, pRequest->epoch, vgId, fetchVer, pHead->msgType); @@ -291,7 +284,6 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, end: tDeleteSTaosxRsp(&taosxRsp); - taosMemoryFreeClear(pCkHead); return code; } diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c index 54b9576eb1..01404494e3 100644 --- a/source/libs/wal/src/walRead.c +++ b/source/libs/wal/src/walRead.c @@ -16,10 +16,6 @@ #include "taoserror.h" #include "walInt.h" -static int32_t walFetchHeadNew(SWalReader *pRead, int64_t fetchVer); -static int32_t walFetchBodyNew(SWalReader *pRead); -static int32_t walSkipFetchBodyNew(SWalReader *pRead); - SWalReader *walOpenReader(SWal *pWal, SWalFilterCond *cond) { SWalReader *pReader = taosMemoryCalloc(1, sizeof(SWalReader)); if (pReader == NULL) { @@ -80,19 +76,19 @@ int32_t walNextValidMsg(SWalReader *pReader) { return -1; } while (fetchVer <= appliedVer) { - if (walFetchHeadNew(pReader, fetchVer) < 0) { + if (walFetchHead(pReader, fetchVer) < 0) { return -1; } int32_t type = pReader->pHead->head.msgType; if (type == TDMT_VND_SUBMIT || ((type == TDMT_VND_DELETE) && (pReader->cond.deleteMsg == 1)) || (IS_META_MSG(type) && pReader->cond.scanMeta)) { - if (walFetchBodyNew(pReader) < 0) { + if (walFetchBody(pReader) < 0) { return -1; } return 0; } else { - if (walSkipFetchBodyNew(pReader) < 0) { + if (walSkipFetchBody(pReader) < 0) { return -1; } @@ -256,102 +252,7 @@ int32_t walReaderSeekVer(SWalReader *pReader, int64_t ver) { void walSetReaderCapacity(SWalReader *pRead, int32_t capacity) { pRead->capacity = capacity; } -static int32_t walFetchHeadNew(SWalReader *pRead, int64_t fetchVer) { - int64_t contLen; - bool seeked = false; - - wDebug("vgId:%d, wal starts to fetch head, index:%" PRId64, pRead->pWal->cfg.vgId, fetchVer); - - if (pRead->curVersion != fetchVer) { - if (walReaderSeekVer(pRead, fetchVer) < 0) { - return -1; - } - seeked = true; - } - - while (1) { - contLen = taosReadFile(pRead->pLogFile, pRead->pHead, sizeof(SWalCkHead)); - if (contLen == sizeof(SWalCkHead)) { - break; - } else if (contLen == 0 && !seeked) { - if(walReadSeekVerImpl(pRead, fetchVer) < 0){ - return -1; - } - seeked = true; - continue; - } else { - if (contLen < 0) { - terrno = TAOS_SYSTEM_ERROR(errno); - } else { - terrno = TSDB_CODE_WAL_FILE_CORRUPTED; - } - return -1; - } - } -// pRead->curInvalid = 0; - return 0; -} - -static int32_t walFetchBodyNew(SWalReader *pReader) { - SWalCont *pReadHead = &pReader->pHead->head; - int64_t ver = pReadHead->version; - - wDebug("vgId:%d, wal starts to fetch body, ver:%" PRId64 " ,len:%d, total", pReader->pWal->cfg.vgId, ver, - pReadHead->bodyLen); - - if (pReader->capacity < pReadHead->bodyLen) { - SWalCkHead *ptr = (SWalCkHead *)taosMemoryRealloc(pReader->pHead, sizeof(SWalCkHead) + pReadHead->bodyLen); - if (ptr == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - pReader->pHead = ptr; - pReadHead = &pReader->pHead->head; - pReader->capacity = pReadHead->bodyLen; - } - - if (pReadHead->bodyLen != taosReadFile(pReader->pLogFile, pReadHead->body, pReadHead->bodyLen)) { - if (pReadHead->bodyLen < 0) { - terrno = TAOS_SYSTEM_ERROR(errno); - wError("vgId:%d, wal fetch body error:%" PRId64 ", read request index:%" PRId64 ", since %s", - pReader->pWal->cfg.vgId, pReader->pHead->head.version, ver, tstrerror(terrno)); - } else { - wError("vgId:%d, wal fetch body error:%" PRId64 ", read request index:%" PRId64 ", since file corrupted", - pReader->pWal->cfg.vgId, pReader->pHead->head.version, ver); - terrno = TSDB_CODE_WAL_FILE_CORRUPTED; - } - return -1; - } - - if (walValidBodyCksum(pReader->pHead) != 0) { - wError("vgId:%d, wal fetch body error:%" PRId64 ", since body checksum not passed", pReader->pWal->cfg.vgId, ver); - terrno = TSDB_CODE_WAL_FILE_CORRUPTED; - return -1; - } - - wDebug("vgId:%d, index:%" PRId64 " is fetched, type:%d, cursor advance", pReader->pWal->cfg.vgId, ver, pReader->pHead->head.msgType); - pReader->curVersion = ver + 1; - return 0; -} - -static int32_t walSkipFetchBodyNew(SWalReader *pRead) { - int64_t code; - - code = taosLSeekFile(pRead->pLogFile, pRead->pHead->head.bodyLen, SEEK_CUR); - if (code < 0) { - terrno = TAOS_SYSTEM_ERROR(errno); -// pRead->curInvalid = 1; - return -1; - } - - pRead->curVersion++; - wDebug("vgId:%d, version advance to %" PRId64 ", skip fetch", pRead->pWal->cfg.vgId, pRead->curVersion); - - return 0; -} - -int32_t walFetchHead(SWalReader *pRead, int64_t ver, SWalCkHead *pHead) { +int32_t walFetchHead(SWalReader *pRead, int64_t ver) { int64_t code; int64_t contLen; bool seeked = false; @@ -369,15 +270,13 @@ int32_t walFetchHead(SWalReader *pRead, int64_t ver, SWalCkHead *pHead) { if (pRead->curVersion != ver) { code = walReaderSeekVer(pRead, ver); if (code < 0) { -// pRead->curVersion = ver; -// pRead->curInvalid = 1; return -1; } seeked = true; } while (1) { - contLen = taosReadFile(pRead->pLogFile, pHead, sizeof(SWalCkHead)); + contLen = taosReadFile(pRead->pLogFile, pRead->pHead, sizeof(SWalCkHead)); if (contLen == sizeof(SWalCkHead)) { break; } else if (contLen == 0 && !seeked) { @@ -392,12 +291,11 @@ int32_t walFetchHead(SWalReader *pRead, int64_t ver, SWalCkHead *pHead) { } else { terrno = TSDB_CODE_WAL_FILE_CORRUPTED; } -// pRead->curInvalid = 1; return -1; } } - code = walValidHeadCksum(pHead); + code = walValidHeadCksum(pRead->pHead); if (code != 0) { wError("vgId:%d, unexpected wal log index:%" PRId64 ", since head checksum not passed", pRead->pWal->cfg.vgId, ver); @@ -405,32 +303,27 @@ int32_t walFetchHead(SWalReader *pRead, int64_t ver, SWalCkHead *pHead) { return -1; } -// pRead->curInvalid = 0; return 0; } -int32_t walSkipFetchBody(SWalReader *pRead, const SWalCkHead *pHead) { - int64_t code; - +int32_t walSkipFetchBody(SWalReader *pRead) { wDebug("vgId:%d, skip fetch body %" PRId64 ", first ver:%" PRId64 ", commit ver:%" PRId64 ", last ver:%" PRId64 ", applied ver:%" PRId64, - pRead->pWal->cfg.vgId, pHead->head.version, pRead->pWal->vers.firstVer, pRead->pWal->vers.commitVer, + pRead->pWal->cfg.vgId, pRead->pHead->head.version, pRead->pWal->vers.firstVer, pRead->pWal->vers.commitVer, pRead->pWal->vers.lastVer, pRead->pWal->vers.appliedVer); - code = taosLSeekFile(pRead->pLogFile, pHead->head.bodyLen, SEEK_CUR); + int64_t code = taosLSeekFile(pRead->pLogFile, pRead->pHead->head.bodyLen, SEEK_CUR); if (code < 0) { terrno = TAOS_SYSTEM_ERROR(errno); -// pRead->curInvalid = 1; return -1; } pRead->curVersion++; - return 0; } -int32_t walFetchBody(SWalReader *pRead, SWalCkHead **ppHead) { - SWalCont *pReadHead = &((*ppHead)->head); +int32_t walFetchBody(SWalReader *pRead) { + SWalCont *pReadHead = &pRead->pHead->head; int64_t ver = pReadHead->version; wDebug("vgId:%d, fetch body %" PRId64 ", first ver:%" PRId64 ", commit ver:%" PRId64 ", last ver:%" PRId64 @@ -439,13 +332,13 @@ int32_t walFetchBody(SWalReader *pRead, SWalCkHead **ppHead) { pRead->pWal->vers.appliedVer); if (pRead->capacity < pReadHead->bodyLen) { - SWalCkHead *ptr = (SWalCkHead *)taosMemoryRealloc(*ppHead, sizeof(SWalCkHead) + pReadHead->bodyLen); + SWalCkHead *ptr = (SWalCkHead *)taosMemoryRealloc(pRead->pHead, sizeof(SWalCkHead) + pReadHead->bodyLen); if (ptr == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - *ppHead = ptr; - pReadHead = &((*ppHead)->head); + pRead->pHead = ptr; + pReadHead = &pRead->pHead->head; pRead->capacity = pReadHead->bodyLen; } @@ -459,27 +352,24 @@ int32_t walFetchBody(SWalReader *pRead, SWalCkHead **ppHead) { pRead->pWal->cfg.vgId, pReadHead->version, ver); terrno = TSDB_CODE_WAL_FILE_CORRUPTED; } -// pRead->curInvalid = 1; return -1; } if (pReadHead->version != ver) { wError("vgId:%d, wal fetch body error, index:%" PRId64 ", read request index:%" PRId64, pRead->pWal->cfg.vgId, pReadHead->version, ver); -// pRead->curInvalid = 1; terrno = TSDB_CODE_WAL_FILE_CORRUPTED; return -1; } - if (walValidBodyCksum(*ppHead) != 0) { + if (walValidBodyCksum(pRead->pHead) != 0) { wError("vgId:%d, wal fetch body error, index:%" PRId64 ", since body checksum not passed", pRead->pWal->cfg.vgId, ver); -// pRead->curInvalid = 1; terrno = TSDB_CODE_WAL_FILE_CORRUPTED; return -1; } - pRead->curVersion = ver + 1; + pRead->curVersion++; return 0; } From dea30255ecc6be4119166373a30ff409cf0b9182 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 11 Aug 2023 23:51:52 +0800 Subject: [PATCH 19/92] fix(stream): add new datablock type. --- include/common/tcommon.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index bdfb1d32b4..705f5b675b 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -169,6 +169,7 @@ typedef enum EStreamType { STREAM_PULL_OVER, STREAM_FILL_OVER, STREAM_CREATE_CHILD_TABLE, + STREAM_TRANS_STATE, } EStreamType; #pragma pack(push, 1) From a89ce1a20b2da84a42257c01e7be000bc3ad47ed Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 01:24:07 +0800 Subject: [PATCH 20/92] fix(stream): transfer state by using data block. --- include/common/tcommon.h | 1 + include/libs/stream/tstream.h | 1 + source/libs/stream/src/streamExec.c | 60 ++++++++++++++++++++++---- source/libs/stream/src/streamRecover.c | 29 +++++++++++++ 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 705f5b675b..1dfe30af71 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -152,6 +152,7 @@ enum { STREAM_INPUT__DATA_RETRIEVE, STREAM_INPUT__GET_RES, STREAM_INPUT__CHECKPOINT, + STREAM_INPUT__TRANS_STATE, STREAM_INPUT__REF_DATA_BLOCK, STREAM_INPUT__DESTROY, }; diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index b9b24917f3..b7e323a213 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -627,6 +627,7 @@ int32_t streamSourceScanHistoryData(SStreamTask* pTask); int32_t streamDispatchScanHistoryFinishMsg(SStreamTask* pTask); int32_t streamDispatchTransferStateMsg(SStreamTask* pTask); +int32_t appendTranstateIntoInputQ(SStreamTask* pTask); // agg level int32_t streamTaskScanHistoryPrepare(SStreamTask* pTask); diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index b479931cd2..102c8805b5 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -390,6 +390,11 @@ static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { if (level == TASK_LEVEL__SOURCE) { streamTaskFillHistoryFinished(pTask); streamTaskEndScanWAL(pTask); + + code = streamDoTransferStateToStreamTask(pTask); + if (code != TSDB_CODE_SUCCESS) { // todo handle this + return code; + } } else if (level == TASK_LEVEL__AGG) { // do transfer task operator states. code = streamDoTransferStateToStreamTask(pTask); if (code != TSDB_CODE_SUCCESS) { // todo handle this @@ -460,6 +465,40 @@ static int32_t extractMsgFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInpu } } +int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock) { + const char* id = pTask->id.idStr; + int32_t code = TSDB_CODE_SUCCESS; + + int32_t level = pTask->info.taskLevel; + if (level == TASK_LEVEL__AGG || level == TASK_LEVEL__SINK) { + int32_t remain = streamAlignTransferState(pTask); + if (remain > 0) { + qDebug("s-task:%s receive upstream transfer state msg, remain:%d", id, remain); + return 0; + } + + // transfer the ownership of executor state + qDebug("s-task:%s all upstream tasks send transfer msg, open transfer state flag", id); + ASSERT(pTask->streamTaskId.taskId != 0 && pTask->info.fillHistory == 1); + + pTask->status.transferState = true; + } + + // dispatch the transtate block to downstream task immediately + if (level == TASK_LEVEL__SOURCE || level == TASK_LEVEL__AGG) { + // pBlock-> = pTask->id.taskId; + pBlock->srcVgId = pTask->pMeta->vgId; + code = taosWriteQitem(pTask->outputInfo.queue->queue, pBlock); + if (code == 0) { + streamDispatchStreamBlock(pTask); + } else { + streamFreeQitem((SStreamQueueItem*)pBlock); + } + } + + return code; +} + /** * todo: the batch of blocks should be tuned dynamic, according to the total elapsed time of each batch of blocks, the * appropriate batch of blocks should be handled in 5 to 10 sec. @@ -484,6 +523,11 @@ int32_t streamExecForAll(SStreamTask* pTask) { break; } + if (pInput->type == STREAM_INPUT__TRANS_STATE) { + streamProcessTranstateBlock(pTask, (SStreamDataBlock*)pInput); + return 0; + } + if (pTask->info.taskLevel == TASK_LEVEL__SINK) { ASSERT(pInput->type == STREAM_INPUT__DATA_BLOCK); qDebug("s-task:%s sink task start to sink %d blocks", id, batchSize); @@ -557,17 +601,15 @@ int32_t streamTaskEndScanWAL(SStreamTask* pTask) { qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, el); // 1. notify all downstream tasks to transfer executor state after handle all history blocks. - int32_t code = streamDispatchTransferStateMsg(pTask); - if (code != TSDB_CODE_SUCCESS) { - // todo handle error - } +// pTask->status.transferState = true; + appendTranstateIntoInputQ(pTask); // 2. do transfer stream task operator states. - pTask->status.transferState = true; - code = streamDoTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { // todo handle error - return code; - } + // todo remove this +// int32_t code = streamDoTransferStateToStreamTask(pTask); +// if (code != TSDB_CODE_SUCCESS) { // todo handle error +// return code; +// } return TSDB_CODE_SUCCESS; } diff --git a/source/libs/stream/src/streamRecover.c b/source/libs/stream/src/streamRecover.c index e59b3f682d..b46ded6ca7 100644 --- a/source/libs/stream/src/streamRecover.c +++ b/source/libs/stream/src/streamRecover.c @@ -415,6 +415,35 @@ static int32_t doDispatchTransferMsg(SStreamTask* pTask, const SStreamTransferRe return 0; } +int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { + SStreamDataBlock* pTranstate = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, sizeof(SSDataBlock)); + if (pTranstate == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock)); + if (pBlock == NULL) { + taosFreeQitem(pTranstate); + return TSDB_CODE_OUT_OF_MEMORY; + } + + pBlock->info.type = STREAM_TRANS_STATE; + pBlock->info.rows = 1; + pBlock->info.childId = pTask->info.selfChildId; + + pTranstate->blocks = taosArrayInit(4, sizeof(SSDataBlock));//pBlock; + taosArrayPush(pTranstate->blocks, pBlock); + + taosMemoryFree(pBlock); + if (tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pTranstate) < 0) { + taosFreeQitem(pTranstate); + return TSDB_CODE_OUT_OF_MEMORY; + } + + streamSchedExec(pTask); + return TSDB_CODE_SUCCESS; +} + int32_t streamDispatchTransferStateMsg(SStreamTask* pTask) { SStreamTransferReq req = { .streamId = pTask->id.streamId, .childId = pTask->info.selfChildId }; From ce721a0146f65e37d5708564a1b8d1a89c293bdf Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 16:32:05 +0800 Subject: [PATCH 21/92] fix(stream): fix error. --- include/libs/stream/tstream.h | 1 + source/dnode/vnode/src/tq/tqRestore.c | 8 +++++--- source/libs/stream/src/stream.c | 3 ++- source/libs/stream/src/streamExec.c | 23 ++++++++++++----------- source/libs/stream/src/streamRecover.c | 5 +++++ 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index b7e323a213..f40a6c9338 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -272,6 +272,7 @@ typedef struct SStreamStatus { int8_t schedStatus; int8_t keepTaskStatus; bool transferState; + bool appendTranstateBlock; // has append the transfer state data block already int8_t timerActive; // timer is active int8_t pauseAllowed; // allowed task status to be set to be paused } SStreamStatus; diff --git a/source/dnode/vnode/src/tq/tqRestore.c b/source/dnode/vnode/src/tq/tqRestore.c index 3d9a91899c..a217bc2966 100644 --- a/source/dnode/vnode/src/tq/tqRestore.c +++ b/source/dnode/vnode/src/tq/tqRestore.c @@ -214,9 +214,11 @@ static void checkForFillHistoryVerRange(SStreamTask* pTask, int64_t ver) { qWarn("s-task:%s fill-history scan WAL, currentVer:%" PRId64 " reach the maximum ver:%" PRId64 ", not scan wal anymore, set the transfer state flag", pTask->id.idStr, ver, pTask->dataRange.range.maxVer); - pTask->status.transferState = true; - - /*int32_t code = */streamSchedExec(pTask); + if (!pTask->status.appendTranstateBlock) { + pTask->status.appendTranstateBlock = true; + appendTranstateIntoInputQ(pTask); + /*int32_t code = */streamSchedExec(pTask); + } } } diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index f85ade591c..fa24c01418 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -385,8 +385,9 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { destroyStreamDataBlock((SStreamDataBlock*) pItem); return code; } - } else if (type == STREAM_INPUT__CHECKPOINT) { + } else if (type == STREAM_INPUT__CHECKPOINT || type == STREAM_INPUT__TRANS_STATE) { taosWriteQitem(pTask->inputQueue->queue, pItem); + qDebug("s-task:%s trans-state blockdata enqueue, total in queue:%d, size:%.2fMiB", pTask->id.idStr, total, size); } else if (type == STREAM_INPUT__GET_RES) { // use the default memory limit, refactor later. taosWriteQitem(pTask->inputQueue->queue, pItem); diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 102c8805b5..c73868123c 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -391,11 +391,11 @@ static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { streamTaskFillHistoryFinished(pTask); streamTaskEndScanWAL(pTask); - code = streamDoTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { // todo handle this - return code; - } - } else if (level == TASK_LEVEL__AGG) { // do transfer task operator states. + code = streamDoTransferStateToStreamTask(pTask); + if (code != TSDB_CODE_SUCCESS) { // todo handle this + return code; + } + } else if (level == TASK_LEVEL__AGG) { // do transfer task operator states. code = streamDoTransferStateToStreamTask(pTask); if (code != TSDB_CODE_SUCCESS) { // todo handle this return code; @@ -484,9 +484,10 @@ int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock pTask->status.transferState = true; } - // dispatch the transtate block to downstream task immediately - if (level == TASK_LEVEL__SOURCE || level == TASK_LEVEL__AGG) { - // pBlock-> = pTask->id.taskId; + // dispatch the tran-state block to downstream task immediately + int32_t type = pTask->outputInfo.type; + if ((level == TASK_LEVEL__AGG || level == TASK_LEVEL__SOURCE) && + (type == TASK_OUTPUT__FIXED_DISPATCH || type == TASK_OUTPUT__SHUFFLE_DISPATCH)) { pBlock->srcVgId = pTask->pMeta->vgId; code = taosWriteQitem(pTask->outputInfo.queue->queue, pBlock); if (code == 0) { @@ -640,10 +641,10 @@ int32_t streamTryExec(SStreamTask* pTask) { // the schedStatus == TASK_SCHED_STATUS__ACTIVE, streamSchedExec cannot be executed, so execute once again by // call this function (streamExecForAll) directly. - code = streamExecForAll(pTask); - if (code < 0) { +// code = streamExecForAll(pTask); +// if (code < 0) { // do nothing - } +// } } atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); diff --git a/source/libs/stream/src/streamRecover.c b/source/libs/stream/src/streamRecover.c index b46ded6ca7..708524bf10 100644 --- a/source/libs/stream/src/streamRecover.c +++ b/source/libs/stream/src/streamRecover.c @@ -427,6 +427,8 @@ int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { return TSDB_CODE_OUT_OF_MEMORY; } + pTranstate->type = STREAM_INPUT__TRANS_STATE; + pBlock->info.type = STREAM_TRANS_STATE; pBlock->info.rows = 1; pBlock->info.childId = pTask->info.selfChildId; @@ -440,7 +442,10 @@ int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { return TSDB_CODE_OUT_OF_MEMORY; } + qDebug("s-task:%s set sched-status:%d, prev:%d", pTask->id.idStr, TASK_SCHED_STATUS__INACTIVE, pTask->status.schedStatus); + pTask->status.schedStatus = TASK_SCHED_STATUS__INACTIVE; streamSchedExec(pTask); + return TSDB_CODE_SUCCESS; } From 0d0e30b7646afe4761dc25f932c726652e13c609 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 17:20:10 +0800 Subject: [PATCH 22/92] fix(stream): fix the error. --- include/common/tcommon.h | 1 + source/libs/stream/src/streamExec.c | 119 ++++++++++++++++++---------- 2 files changed, 79 insertions(+), 41 deletions(-) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 1dfe30af71..92e64f075f 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -152,6 +152,7 @@ enum { STREAM_INPUT__DATA_RETRIEVE, STREAM_INPUT__GET_RES, STREAM_INPUT__CHECKPOINT, + STREAM_INPUT__CHECKPOINT_TRIGGER, STREAM_INPUT__TRANS_STATE, STREAM_INPUT__REF_DATA_BLOCK, STREAM_INPUT__DESTROY, diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index c73868123c..bbfaa8cb9d 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -334,6 +334,9 @@ static int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { qDebug("s-task:%s no need to update time window for non-source task", pStreamTask->id.idStr); } + // todo check the output queue for fill-history task, and wait for it complete + + // 1. expand the query time window for stream task of WAL scanner pTimeWindow->skey = INT64_MIN; qStreamInfoResetTimewindowFilter(pStreamTask->exec.pExecutor); @@ -389,8 +392,6 @@ static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { int32_t level = pTask->info.taskLevel; if (level == TASK_LEVEL__SOURCE) { streamTaskFillHistoryFinished(pTask); - streamTaskEndScanWAL(pTask); - code = streamDoTransferStateToStreamTask(pTask); if (code != TSDB_CODE_SUCCESS) { // todo handle this return code; @@ -405,14 +406,41 @@ static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { return code; } -static int32_t extractMsgFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInput, int32_t* numOfBlocks, - const char* id) { - int32_t retryTimes = 0; - int32_t MAX_RETRY_TIMES = 5; +static int32_t extractBlocksFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInput, int32_t* numOfBlocks) { + int32_t retryTimes = 0; + int32_t MAX_RETRY_TIMES = 5; + const char* id = pTask->id.idStr; + if (pTask->info.taskLevel == TASK_LEVEL__SINK) { // extract block from inputQ, one-by-one + while (1) { + if (streamTaskShouldPause(&pTask->status) || streamTaskShouldStop(&pTask->status)) { + qDebug("s-task:%s task should pause, extract input blocks:%d", pTask->id.idStr, *numOfBlocks); + return TSDB_CODE_SUCCESS; + } + + SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue); + if (qItem == NULL) { + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE && (++retryTimes) < MAX_RETRY_TIMES) { + taosMsleep(10); + qDebug("===stream===try again batchSize:%d, retry:%d, %s", *numOfBlocks, retryTimes, id); + continue; + } + + qDebug("===stream===break batchSize:%d, %s", *numOfBlocks, id); + return TSDB_CODE_SUCCESS; + } + + qDebug("s-task:%s sink task handle result block one-by-one", id); + *numOfBlocks = 1; + *pInput = qItem; + return TSDB_CODE_SUCCESS; + } + } + + // non sink task while (1) { - if (streamTaskShouldPause(&pTask->status)) { - qDebug("s-task:%s task should pause, input blocks:%d", pTask->id.idStr, *numOfBlocks); + if (streamTaskShouldPause(&pTask->status) || streamTaskShouldStop(&pTask->status)) { + qDebug("s-task:%s task should pause, extract input blocks:%d", pTask->id.idStr, *numOfBlocks); return TSDB_CODE_SUCCESS; } @@ -420,47 +448,52 @@ static int32_t extractMsgFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInpu if (qItem == NULL) { if (pTask->info.taskLevel == TASK_LEVEL__SOURCE && (++retryTimes) < MAX_RETRY_TIMES) { taosMsleep(10); - qDebug("===stream===try again batchSize:%d, retry:%d", *numOfBlocks, retryTimes); + qDebug("===stream===try again batchSize:%d, retry:%d, %s", *numOfBlocks, retryTimes, id); continue; } - qDebug("===stream===break batchSize:%d", *numOfBlocks); + qDebug("===stream===break batchSize:%d, %s", *numOfBlocks, id); return TSDB_CODE_SUCCESS; } - // do not merge blocks for sink node - if (pTask->info.taskLevel == TASK_LEVEL__SINK) { - *numOfBlocks = 1; - *pInput = qItem; - return TSDB_CODE_SUCCESS; - } - - if (*pInput == NULL) { - ASSERT((*numOfBlocks) == 0); - *pInput = qItem; - } else { - // todo we need to sort the data block, instead of just appending into the array list. - void* newRet = streamMergeQueueItem(*pInput, qItem); - if (newRet == NULL) { - if (terrno == 0) { - qDebug("s-task:%s failed to merge blocks from inputQ, numOfBlocks:%d", id, *numOfBlocks); - } else { - qDebug("s-task:%s failed to merge blocks from inputQ, numOfBlocks:%d, code:%s", id, *numOfBlocks, - tstrerror(terrno)); - } + // do not merge blocks for sink node and check point data block + if (qItem->type == STREAM_INPUT__CHECKPOINT || qItem->type == STREAM_INPUT__CHECKPOINT_TRIGGER || + qItem->type == STREAM_INPUT__TRANS_STATE) { + if (*pInput == NULL) { + qDebug("s-task:%s checkpoint/transtate msg extracted, start to process immediately", id); + *numOfBlocks = 1; + *pInput = qItem; + return TSDB_CODE_SUCCESS; + } else { + // previous existed blocks needs to be handle, before handle the checkpoint msg block + qDebug("s-task:%s checkpoint/transtate msg extracted, handle previous block first, numOfBlocks:%d", id, + *numOfBlocks); streamQueueProcessFail(pTask->inputQueue); return TSDB_CODE_SUCCESS; } + } else { + if (*pInput == NULL) { + ASSERT((*numOfBlocks) == 0); + *pInput = qItem; + } else { + // todo we need to sort the data block, instead of just appending into the array list. + void* newRet = streamMergeQueueItem(*pInput, qItem); + if (newRet == NULL) { + qError("s-task:%s failed to merge blocks from inputQ, numOfBlocks:%d", id, *numOfBlocks); + streamQueueProcessFail(pTask->inputQueue); + return TSDB_CODE_SUCCESS; + } - *pInput = newRet; - } + *pInput = newRet; + } - *numOfBlocks += 1; - streamQueueProcessSuccess(pTask->inputQueue); + *numOfBlocks += 1; + streamQueueProcessSuccess(pTask->inputQueue); - if (*numOfBlocks >= MAX_STREAM_EXEC_BATCH_NUM) { - qDebug("s-task:%s batch size limit:%d reached, start to process blocks", id, MAX_STREAM_EXEC_BATCH_NUM); - return TSDB_CODE_SUCCESS; + if (*numOfBlocks >= MAX_STREAM_EXEC_BATCH_NUM) { + qDebug("s-task:%s batch size limit:%d reached, start to process blocks", id, MAX_STREAM_EXEC_BATCH_NUM); + return TSDB_CODE_SUCCESS; + } } } } @@ -476,14 +509,18 @@ int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock qDebug("s-task:%s receive upstream transfer state msg, remain:%d", id, remain); return 0; } + } - // transfer the ownership of executor state + // transfer the ownership of executor state + if (level == TASK_LEVEL__SOURCE) { + qDebug("s-task:%s open transfer state flag for source task", id); + } else { qDebug("s-task:%s all upstream tasks send transfer msg, open transfer state flag", id); ASSERT(pTask->streamTaskId.taskId != 0 && pTask->info.fillHistory == 1); - - pTask->status.transferState = true; } + pTask->status.transferState = true; + // dispatch the tran-state block to downstream task immediately int32_t type = pTask->outputInfo.type; if ((level == TASK_LEVEL__AGG || level == TASK_LEVEL__SOURCE) && @@ -518,7 +555,7 @@ int32_t streamExecForAll(SStreamTask* pTask) { // merge multiple input data if possible in the input queue. qDebug("s-task:%s start to extract data block from inputQ", id); - /*int32_t code = */extractMsgFromInputQ(pTask, &pInput, &batchSize, id); + /*int32_t code = */extractBlocksFromInputQ(pTask, &pInput, &batchSize); if (pInput == NULL) { ASSERT(batchSize == 0); break; From 30c2a9c61927c66a61673d2f9996455ebae3c0ac Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 18:27:51 +0800 Subject: [PATCH 23/92] refactor: do some internal refactor. --- source/libs/stream/inc/streamInt.h | 2 +- source/libs/stream/src/stream.c | 2 +- source/libs/stream/src/streamDispatch.c | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/libs/stream/inc/streamInt.h b/source/libs/stream/inc/streamInt.h index 32d6dc65d9..30c941d106 100644 --- a/source/libs/stream/inc/streamInt.h +++ b/source/libs/stream/inc/streamInt.h @@ -52,7 +52,7 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock) int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq); -int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData); +int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData); int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet); int32_t streamDoDispatchScanHistoryFinishMsg(SStreamTask* pTask, const SStreamScanHistoryFinishReq* pReq, int32_t vgId, diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index fa24c01418..39f4e7fc7a 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -268,7 +268,7 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i } else { qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", pTask->id.idStr, pRsp->downstreamTaskId, tstrerror(code), ++pTask->msgInfo.retryCount); - return streamDispatchAllBlocks(pTask, pTask->msgInfo.pData); + return doDispatchAllBlocks(pTask, pTask->msgInfo.pData); } } diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 8334ea1c88..7eef42e289 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -436,7 +436,7 @@ int32_t streamSearchAndAddBlock(SStreamTask* pTask, SStreamDispatchReq* pReqs, S return 0; } -int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { +int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { int32_t code = 0; int32_t numOfBlocks = taosArrayGetSize(pData->blocks); @@ -552,7 +552,7 @@ static void doRetryDispatchData(void* param, void* tmrId) { SStreamTask* pTask = param; ASSERT(pTask->outputInfo.status == TASK_OUTPUT_STATUS__WAIT); - int32_t code = streamDispatchAllBlocks(pTask, pTask->msgInfo.pData); + int32_t code = doDispatchAllBlocks(pTask, pTask->msgInfo.pData); if (code != TSDB_CODE_SUCCESS) { qDebug("s-task:%s reset the waitRspCnt to be 0 before launch retry dispatch", pTask->id.idStr); atomic_store_32(&pTask->shuffleDispatcher.waitingRspCnt, 0); @@ -593,12 +593,13 @@ int32_t streamDispatchStreamBlock(SStreamTask* pTask) { } pTask->msgInfo.pData = pBlock; - ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK); + ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK || pBlock->type == STREAM_INPUT__CHECKPOINT_TRIGGER || + pBlock->type == STREAM_INPUT__TRANS_STATE); int32_t retryCount = 0; while (1) { - int32_t code = streamDispatchAllBlocks(pTask, pBlock); + int32_t code = doDispatchAllBlocks(pTask, pBlock); if (code == TSDB_CODE_SUCCESS) { break; } From 8f9de93cf005197196be53d7f6b3820c721b5d47 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 18:37:36 +0800 Subject: [PATCH 24/92] refactor: do some internal refactor. --- include/libs/stream/tstream.h | 2 ++ source/libs/stream/src/stream.c | 56 ++++++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index f40a6c9338..8dc0684976 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -251,6 +251,7 @@ typedef struct SStreamChildEpInfo { int32_t nodeId; int32_t childId; int32_t taskId; + int8_t dataAllowed; SEpSet epSet; } SStreamChildEpInfo; @@ -400,6 +401,7 @@ typedef struct { typedef struct { int64_t streamId; + int32_t type; int32_t taskId; int32_t dataSrcVgId; int32_t upstreamTaskId; diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index 39f4e7fc7a..79759ff012 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -239,21 +239,61 @@ int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, S qDebug("s-task:%s receive dispatch msg from taskId:0x%x(vgId:%d), msgLen:%" PRId64, pTask->id.idStr, pReq->upstreamTaskId, pReq->upstreamNodeId, pReq->totalLen); - // todo add the input queue buffer limitation - streamTaskEnqueueBlocks(pTask, pReq, pRsp); - tDeleteStreamDispatchReq(pReq); + int32_t status = 0; - if (exec) { - if (streamTryExec(pTask) < 0) { - return -1; - } + SStreamChildEpInfo* pInfo = streamTaskGetUpstreamTaskEpInfo(pTask, pReq->upstreamTaskId); + ASSERT(pInfo != NULL); + + if (!pInfo->dataAllowed) { + qWarn("s-task:%s data from task:0x%x is denied, since inputQ is closed for it", pTask->id.idStr, pReq->upstreamTaskId); + status = TASK_INPUT_STATUS__BLOCKED; } else { - streamSchedExec(pTask); + // Current task has received the checkpoint req from the upstream task, from which the message should all be blocked + if (pReq->type == STREAM_INPUT__CHECKPOINT_TRIGGER) { + streamTaskCloseUpstreamInput(pTask, pReq->upstreamTaskId); + qDebug("s-task:%s close inputQ for upstream:0x%x", pTask->id.idStr, pReq->upstreamTaskId); + } + + status = streamTaskAppendInputBlocks(pTask, pReq); } + { + // do send response with the input status + int32_t code = buildDispatchRsp(pTask, pReq, status, &pRsp->pCont); + if (code != TSDB_CODE_SUCCESS) { + // todo handle failure + return code; + } + + pRsp->contLen = sizeof(SMsgHead) + sizeof(SStreamDispatchRsp); + tmsgSendRsp(pRsp); + } + + tDeleteStreamDispatchReq(pReq); + streamSchedExec(pTask); + return 0; } +//int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) { +// qDebug("s-task:%s receive dispatch msg from taskId:0x%x(vgId:%d), msgLen:%" PRId64, pTask->id.idStr, +// pReq->upstreamTaskId, pReq->upstreamNodeId, pReq->totalLen); +// +// // todo add the input queue buffer limitation +// streamTaskEnqueueBlocks(pTask, pReq, pRsp); +// tDeleteStreamDispatchReq(pReq); +// +// if (exec) { +// if (streamTryExec(pTask) < 0) { +// return -1; +// } +// } else { +// streamSchedExec(pTask); +// } +// +// return 0; +//} + // todo record the idle time for dispatch data int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code) { if (code != TSDB_CODE_SUCCESS) { From a0534ee715acd723063093903866a61f1a4aea03 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 18:40:09 +0800 Subject: [PATCH 25/92] refactor: do some internal refactor. --- source/libs/stream/src/stream.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index 79759ff012..9548c3c327 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -235,6 +235,24 @@ int32_t streamTaskOutputResultBlock(SStreamTask* pTask, SStreamDataBlock* pBlock return 0; } +static int32_t streamTaskAppendInputBlocks(SStreamTask* pTask, const SStreamDispatchReq* pReq) { + int8_t status = 0; + + SStreamDataBlock* pBlock = createStreamBlockFromDispatchMsg(pReq, pReq->type, pReq->srcVgId); + if (pBlock == NULL) { + streamTaskInputFail(pTask); + status = TASK_INPUT_STATUS__FAILED; + qError("vgId:%d, s-task:%s failed to receive dispatch msg, reason: out of memory", pTask->pMeta->vgId, + pTask->id.idStr); + } else { + int32_t code = tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pBlock); + // input queue is full, upstream is blocked now + status = (code == TSDB_CODE_SUCCESS) ? TASK_INPUT_STATUS__NORMAL : TASK_INPUT_STATUS__BLOCKED; + } + + return status; +} + int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) { qDebug("s-task:%s receive dispatch msg from taskId:0x%x(vgId:%d), msgLen:%" PRId64, pTask->id.idStr, pReq->upstreamTaskId, pReq->upstreamNodeId, pReq->totalLen); From 075b5e94817d4c3e8d04b0a0e832acd0219c8ebe Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 18:41:54 +0800 Subject: [PATCH 26/92] refactor: do some internal refactor. --- source/libs/stream/src/stream.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index 9548c3c327..d73bb1562e 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -253,6 +253,25 @@ static int32_t streamTaskAppendInputBlocks(SStreamTask* pTask, const SStreamDisp return status; } +static int32_t buildDispatchRsp(const SStreamTask* pTask, const SStreamDispatchReq* pReq, int32_t status, void** pBuf) { + *pBuf = rpcMallocCont(sizeof(SMsgHead) + sizeof(SStreamDispatchRsp)); + if (*pBuf == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + ((SMsgHead*)(*pBuf))->vgId = htonl(pReq->upstreamNodeId); + SStreamDispatchRsp* pDispatchRsp = POINTER_SHIFT((*pBuf), sizeof(SMsgHead)); + + pDispatchRsp->inputStatus = status; + pDispatchRsp->streamId = htobe64(pReq->streamId); + pDispatchRsp->upstreamNodeId = htonl(pReq->upstreamNodeId); + pDispatchRsp->upstreamTaskId = htonl(pReq->upstreamTaskId); + pDispatchRsp->downstreamNodeId = htonl(pTask->info.nodeId); + pDispatchRsp->downstreamTaskId = htonl(pTask->id.taskId); + + return TSDB_CODE_SUCCESS; +} + int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) { qDebug("s-task:%s receive dispatch msg from taskId:0x%x(vgId:%d), msgLen:%" PRId64, pTask->id.idStr, pReq->upstreamTaskId, pReq->upstreamNodeId, pReq->totalLen); From 75e6fb0f16627525725f1a55038cb2f4137c98fd Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 18:47:01 +0800 Subject: [PATCH 27/92] refactor: do some internal refactor. --- include/libs/stream/tstream.h | 3 ++- source/libs/stream/src/stream.c | 11 ++++++++++- source/libs/stream/src/streamDispatch.c | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index 8dc0684976..3542788b4b 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -403,7 +403,7 @@ typedef struct { int64_t streamId; int32_t type; int32_t taskId; - int32_t dataSrcVgId; + int32_t srcVgId; int32_t upstreamTaskId; int32_t upstreamChildId; int32_t upstreamNodeId; @@ -582,6 +582,7 @@ int32_t streamSetupScheduleTrigger(SStreamTask* pTask); int32_t streamProcessRunReq(SStreamTask* pTask); int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pMsg, bool exec); int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code); +void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId); int32_t streamProcessRetrieveReq(SStreamTask* pTask, SStreamRetrieveReq* pReq, SRpcMsg* pMsg); diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index d73bb1562e..caf20a499c 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -145,7 +145,7 @@ int32_t streamSchedExec(SStreamTask* pTask) { int32_t streamTaskEnqueueBlocks(SStreamTask* pTask, const SStreamDispatchReq* pReq, SRpcMsg* pRsp) { int8_t status = 0; - SStreamDataBlock* pBlock = createStreamDataFromDispatchMsg(pReq, STREAM_INPUT__DATA_BLOCK, pReq->dataSrcVgId); + SStreamDataBlock* pBlock = createStreamDataFromDispatchMsg(pReq, STREAM_INPUT__DATA_BLOCK, pReq->srcVgId); if (pBlock == NULL) { streamTaskInputFail(pTask); status = TASK_INPUT_STATUS__FAILED; @@ -235,6 +235,8 @@ int32_t streamTaskOutputResultBlock(SStreamTask* pTask, SStreamDataBlock* pBlock return 0; } + + static int32_t streamTaskAppendInputBlocks(SStreamTask* pTask, const SStreamDispatchReq* pReq) { int8_t status = 0; @@ -272,6 +274,13 @@ static int32_t buildDispatchRsp(const SStreamTask* pTask, const SStreamDispatchR return TSDB_CODE_SUCCESS; } +void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId) { + SStreamChildEpInfo* pInfo = streamTaskGetUpstreamTaskEpInfo(pTask, taskId); + if (pInfo != NULL) { + pInfo->dataAllowed = false; + } +} + int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) { qDebug("s-task:%s receive dispatch msg from taskId:0x%x(vgId:%d), msgLen:%" PRId64, pTask->id.idStr, pReq->upstreamTaskId, pReq->upstreamNodeId, pReq->totalLen); diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 7eef42e289..a162f0e770 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -36,7 +36,7 @@ static int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatc if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->taskId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->upstreamTaskId) < 0) return -1; - if (tEncodeI32(pEncoder, pReq->dataSrcVgId) < 0) return -1; + if (tEncodeI32(pEncoder, pReq->srcVgId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->upstreamChildId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->upstreamNodeId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->blockNum) < 0) return -1; From 09da6c6840aaec42a3b0b89b7ee60b8bf15a378d Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 18:51:20 +0800 Subject: [PATCH 28/92] refactor: do some internal refactor. --- include/libs/stream/tstream.h | 1 + source/libs/stream/src/stream.c | 36 +---------------------- source/libs/stream/src/streamData.c | 39 +++++++++++++++++++++++++ source/libs/stream/src/streamDispatch.c | 4 +-- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index 3542788b4b..cee2def85f 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -122,6 +122,7 @@ typedef struct { int8_t type; int32_t srcVgId; + int32_t srcTaskId; int32_t childId; int64_t sourceVer; int64_t reqId; diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index caf20a499c..0eaeafd0b3 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -142,40 +142,6 @@ int32_t streamSchedExec(SStreamTask* pTask) { return 0; } -int32_t streamTaskEnqueueBlocks(SStreamTask* pTask, const SStreamDispatchReq* pReq, SRpcMsg* pRsp) { - int8_t status = 0; - - SStreamDataBlock* pBlock = createStreamDataFromDispatchMsg(pReq, STREAM_INPUT__DATA_BLOCK, pReq->srcVgId); - if (pBlock == NULL) { - streamTaskInputFail(pTask); - status = TASK_INPUT_STATUS__FAILED; - qError("vgId:%d, s-task:%s failed to receive dispatch msg, reason: out of memory", pTask->pMeta->vgId, - pTask->id.idStr); - } else { - int32_t code = tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pBlock); - // input queue is full, upstream is blocked now - status = (code == TSDB_CODE_SUCCESS)? TASK_INPUT_STATUS__NORMAL:TASK_INPUT_STATUS__BLOCKED; - } - - // rsp by input status - void* buf = rpcMallocCont(sizeof(SMsgHead) + sizeof(SStreamDispatchRsp)); - ((SMsgHead*)buf)->vgId = htonl(pReq->upstreamNodeId); - SStreamDispatchRsp* pDispatchRsp = POINTER_SHIFT(buf, sizeof(SMsgHead)); - - pDispatchRsp->inputStatus = status; - pDispatchRsp->streamId = htobe64(pReq->streamId); - pDispatchRsp->upstreamNodeId = htonl(pReq->upstreamNodeId); - pDispatchRsp->upstreamTaskId = htonl(pReq->upstreamTaskId); - pDispatchRsp->downstreamNodeId = htonl(pTask->info.nodeId); - pDispatchRsp->downstreamTaskId = htonl(pTask->id.taskId); - - pRsp->pCont = buf; - pRsp->contLen = sizeof(SMsgHead) + sizeof(SStreamDispatchRsp); - tmsgSendRsp(pRsp); - - return status == TASK_INPUT_STATUS__NORMAL ? 0 : -1; -} - int32_t streamTaskEnqueueRetrieve(SStreamTask* pTask, SStreamRetrieveReq* pReq, SRpcMsg* pRsp) { SStreamDataBlock* pData = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, 0); int8_t status = TASK_INPUT_STATUS__NORMAL; @@ -240,7 +206,7 @@ int32_t streamTaskOutputResultBlock(SStreamTask* pTask, SStreamDataBlock* pBlock static int32_t streamTaskAppendInputBlocks(SStreamTask* pTask, const SStreamDispatchReq* pReq) { int8_t status = 0; - SStreamDataBlock* pBlock = createStreamBlockFromDispatchMsg(pReq, pReq->type, pReq->srcVgId); + SStreamDataBlock* pBlock = createStreamDataFromDispatchMsg(pReq, pReq->type, pReq->srcVgId); if (pBlock == NULL) { streamTaskInputFail(pTask); status = TASK_INPUT_STATUS__FAILED; diff --git a/source/libs/stream/src/streamData.c b/source/libs/stream/src/streamData.c index bb4b842787..fcc0195bf4 100644 --- a/source/libs/stream/src/streamData.c +++ b/source/libs/stream/src/streamData.c @@ -15,6 +15,45 @@ #include "streamInt.h" +SStreamDataBlock* createStreamBlockFromDispatchMsg(const SStreamDispatchReq* pReq, int32_t blockType, int32_t srcVg) { + SStreamDataBlock* pData = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, pReq->totalLen); + if (pData == NULL) { + return NULL; + } + + pData->type = blockType; + pData->srcVgId = srcVg; + pData->srcTaskId = pReq->upstreamTaskId; + + int32_t blockNum = pReq->blockNum; + SArray* pArray = taosArrayInit_s(sizeof(SSDataBlock), blockNum); + if (pArray == NULL) { + taosFreeQitem(pData); + return NULL; + } + + ASSERT((pReq->blockNum == taosArrayGetSize(pReq->data)) && (pReq->blockNum == taosArrayGetSize(pReq->dataLen))); + + for (int32_t i = 0; i < blockNum; i++) { + SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*) taosArrayGetP(pReq->data, i); + SSDataBlock* pDataBlock = taosArrayGet(pArray, i); + blockDecode(pDataBlock, pRetrieve->data); + + // TODO: refactor + pDataBlock->info.window.skey = be64toh(pRetrieve->skey); + pDataBlock->info.window.ekey = be64toh(pRetrieve->ekey); + pDataBlock->info.version = be64toh(pRetrieve->version); + pDataBlock->info.watermark = be64toh(pRetrieve->watermark); + memcpy(pDataBlock->info.parTbName, pRetrieve->parTbName, TSDB_TABLE_NAME_LEN); + + pDataBlock->info.type = pRetrieve->streamBlockType; + pDataBlock->info.childId = pReq->upstreamChildId; + } + + pData->blocks = pArray; + return pData; +} + SStreamDataBlock* createStreamDataFromDispatchMsg(const SStreamDispatchReq* pReq, int32_t blockType, int32_t srcVg) { SStreamDataBlock* pData = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, pReq->totalLen); if (pData == NULL) { diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index a162f0e770..fab7856cf6 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -89,7 +89,7 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { if (tDecodeI64(pDecoder, &pReq->streamId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->taskId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->upstreamTaskId) < 0) return -1; - if (tDecodeI32(pDecoder, &pReq->dataSrcVgId) < 0) return -1; + if (tDecodeI32(pDecoder, &pReq->srcVgId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->upstreamChildId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->upstreamNodeId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->blockNum) < 0) return -1; @@ -115,7 +115,7 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, int32_t numOfBlocks, int64_t dstTaskId) { pReq->streamId = pTask->id.streamId; - pReq->dataSrcVgId = vgId; + pReq->srcVgId = vgId; pReq->upstreamTaskId = pTask->id.taskId; pReq->upstreamChildId = pTask->info.selfChildId; pReq->upstreamNodeId = pTask->info.nodeId; From afe9b848a58c91b62755baf6b912161a005cdd10 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 18:54:39 +0800 Subject: [PATCH 29/92] fix(tsdb): check the --- include/libs/stream/tstream.h | 2 -- source/libs/stream/src/streamDispatch.c | 10 +++++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index cee2def85f..508392ff77 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -574,8 +574,6 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq); int32_t tDecodeStreamRetrieveReq(SDecoder* pDecoder, SStreamRetrieveReq* pReq); void tDeleteStreamRetrieveReq(SStreamRetrieveReq* pReq); -int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, int32_t numOfBlocks, - int64_t dstTaskId); void tDeleteStreamDispatchReq(SStreamDispatchReq* pReq); int32_t streamSetupScheduleTrigger(SStreamTask* pTask); diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index fab7856cf6..b6a03153d3 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -25,6 +25,9 @@ typedef struct SBlockName { char parTbName[TSDB_TABLE_NAME_LEN]; } SBlockName; +static int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, + int32_t numOfBlocks, int64_t dstTaskId, int32_t type); + static void initRpcMsg(SRpcMsg* pMsg, int32_t msgType, void* pCont, int32_t contLen) { pMsg->msgType = msgType; pMsg->pCont = pCont; @@ -112,8 +115,8 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { return 0; } -int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, int32_t numOfBlocks, - int64_t dstTaskId) { +int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, + int32_t numOfBlocks, int64_t dstTaskId, int32_t type) { pReq->streamId = pTask->id.streamId; pReq->srcVgId = vgId; pReq->upstreamTaskId = pTask->id.taskId; @@ -121,6 +124,7 @@ int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTas pReq->upstreamNodeId = pTask->info.nodeId; pReq->blockNum = numOfBlocks; pReq->taskId = dstTaskId; + pReq->type = type; pReq->data = taosArrayInit(numOfBlocks, POINTER_BYTES); pReq->dataLen = taosArrayInit(numOfBlocks, sizeof(int32_t)); @@ -446,7 +450,7 @@ int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { SStreamDispatchReq req = {0}; int32_t downstreamTaskId = pTask->fixedEpDispatcher.taskId; - code = tInitStreamDispatchReq(&req, pTask, pData->srcVgId, numOfBlocks, downstreamTaskId); + code = tInitStreamDispatchReq(&req, pTask, pData->srcVgId, numOfBlocks, downstreamTaskId, ); if (code != TSDB_CODE_SUCCESS) { return code; } From 03c26a9d6df9e429f17f0be6b7f4f743e217b791 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 19:16:20 +0800 Subject: [PATCH 30/92] refactor --- include/common/tcommon.h | 1 + source/libs/stream/inc/streamInt.h | 1 - source/libs/stream/src/streamDispatch.c | 20 +++++++++----------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 92e64f075f..8482ba8a78 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -170,6 +170,7 @@ typedef enum EStreamType { STREAM_PULL_DATA, STREAM_PULL_OVER, STREAM_FILL_OVER, + STREAM_CHECKPOINT, STREAM_CREATE_CHILD_TABLE, STREAM_TRANS_STATE, } EStreamType; diff --git a/source/libs/stream/inc/streamInt.h b/source/libs/stream/inc/streamInt.h index 30c941d106..b0fed5dde1 100644 --- a/source/libs/stream/inc/streamInt.h +++ b/source/libs/stream/inc/streamInt.h @@ -52,7 +52,6 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock) int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq); -int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData); int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet); int32_t streamDoDispatchScanHistoryFinishMsg(SStreamTask* pTask, const SStreamScanHistoryFinishReq* pReq, int32_t vgId, diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index b6a03153d3..41ed784d16 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -440,9 +440,8 @@ int32_t streamSearchAndAddBlock(SStreamTask* pTask, SStreamDispatchReq* pReqs, S return 0; } -int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { +static int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { int32_t code = 0; - int32_t numOfBlocks = taosArrayGetSize(pData->blocks); ASSERT(numOfBlocks != 0); @@ -450,7 +449,7 @@ int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { SStreamDispatchReq req = {0}; int32_t downstreamTaskId = pTask->fixedEpDispatcher.taskId; - code = tInitStreamDispatchReq(&req, pTask, pData->srcVgId, numOfBlocks, downstreamTaskId, ); + code = tInitStreamDispatchReq(&req, pTask, pData->srcVgId, numOfBlocks, downstreamTaskId, pData->type); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -491,7 +490,7 @@ int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { for (int32_t i = 0; i < vgSz; i++) { SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); - code = tInitStreamDispatchReq(&pReqs[i], pTask, pData->srcVgId, 0, pVgInfo->taskId); + code = tInitStreamDispatchReq(&pReqs[i], pTask, pData->srcVgId, 0, pVgInfo->taskId, pData->type); if (code != TSDB_CODE_SUCCESS) { goto FAIL_SHUFFLE_DISPATCH; } @@ -501,8 +500,7 @@ int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { SSDataBlock* pDataBlock = taosArrayGet(pData->blocks, i); // TODO: do not use broadcast - if (pDataBlock->info.type == STREAM_DELETE_RESULT) { - + if (pDataBlock->info.type == STREAM_DELETE_RESULT || pDataBlock->info.type == STREAM_CHECKPOINT || pDataBlock->info.type == STREAM_TRANS_STATE) { for (int32_t j = 0; j < vgSz; j++) { if (streamAddBlockIntoDispatchMsg(pDataBlock, &pReqs[j]) < 0) { goto FAIL_SHUFFLE_DISPATCH; @@ -522,14 +520,14 @@ int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { } } - qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to %d vgroups", pTask->id.idStr, pTask->info.selfChildId, - numOfBlocks, vgSz); + qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to %d vgroups", pTask->id.idStr, + pTask->info.selfChildId, numOfBlocks, vgSz); for (int32_t i = 0; i < vgSz; i++) { if (pReqs[i].blockNum > 0) { SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); - qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to vgId:%d", pTask->id.idStr, pTask->info.selfChildId, - pReqs[i].blockNum, pVgInfo->vgId); + qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to vgId:%d", pTask->id.idStr, + pTask->info.selfChildId, pReqs[i].blockNum, pVgInfo->vgId); code = doSendDispatchMsg(pTask, &pReqs[i], pVgInfo->vgId, &pVgInfo->epSet); if (code < 0) { @@ -540,7 +538,7 @@ int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { code = 0; - FAIL_SHUFFLE_DISPATCH: + FAIL_SHUFFLE_DISPATCH: for (int32_t i = 0; i < vgSz; i++) { taosArrayDestroyP(pReqs[i].data, taosMemoryFree); taosArrayDestroy(pReqs[i].dataLen); From 0e189f70a103a63e52f83aa2d2e9dd8d8ac205e5 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Aug 2023 19:44:44 +0800 Subject: [PATCH 31/92] refactor --- source/libs/stream/src/stream.c | 65 ------------------------ source/libs/stream/src/streamDispatch.c | 66 +++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 65 deletions(-) diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index 0eaeafd0b3..b9c9e40562 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -306,71 +306,6 @@ int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, S // return 0; //} -// todo record the idle time for dispatch data -int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code) { - if (code != TSDB_CODE_SUCCESS) { - // dispatch message failed: network error, or node not available. - // in case of the input queue is full, the code will be TSDB_CODE_SUCCESS, the and pRsp>inputStatus will be set - // flag. here we need to retry dispatch this message to downstream task immediately. handle the case the failure - // happened too fast. todo handle the shuffle dispatch failure - if (code == TSDB_CODE_STREAM_TASK_NOT_EXIST) { - qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, no-retry", pTask->id.idStr, - pRsp->downstreamTaskId, tstrerror(code)); - return code; - } else { - qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", pTask->id.idStr, - pRsp->downstreamTaskId, tstrerror(code), ++pTask->msgInfo.retryCount); - return doDispatchAllBlocks(pTask, pTask->msgInfo.pData); - } - } - - qDebug("s-task:%s receive dispatch rsp, output status:%d code:%d", pTask->id.idStr, pRsp->inputStatus, code); - - // there are other dispatch message not response yet - if (pTask->outputInfo.type == TASK_OUTPUT__SHUFFLE_DISPATCH) { - int32_t leftRsp = atomic_sub_fetch_32(&pTask->shuffleDispatcher.waitingRspCnt, 1); - qDebug("s-task:%s is shuffle, left waiting rsp %d", pTask->id.idStr, leftRsp); - if (leftRsp > 0) { - return 0; - } - } - - pTask->msgInfo.retryCount = 0; - ASSERT(pTask->outputInfo.status == TASK_OUTPUT_STATUS__WAIT); - - qDebug("s-task:%s output status is set to:%d", pTask->id.idStr, pTask->outputInfo.status); - - // the input queue of the (down stream) task that receive the output data is full, - // so the TASK_INPUT_STATUS_BLOCKED is rsp - // todo blocking the output status - if (pRsp->inputStatus == TASK_INPUT_STATUS__BLOCKED) { - pTask->msgInfo.blockingTs = taosGetTimestampMs(); // record the blocking start time - - int32_t waitDuration = 300; // 300 ms - qError("s-task:%s inputQ of downstream task:0x%x is full, time:%" PRId64 "wait for %dms and retry dispatch data", - pTask->id.idStr, pRsp->downstreamTaskId, pTask->msgInfo.blockingTs, waitDuration); - streamRetryDispatchStreamBlock(pTask, waitDuration); - } else { // pipeline send data in output queue - // this message has been sent successfully, let's try next one. - destroyStreamDataBlock(pTask->msgInfo.pData); - pTask->msgInfo.pData = NULL; - - if (pTask->msgInfo.blockingTs != 0) { - int64_t el = taosGetTimestampMs() - pTask->msgInfo.blockingTs; - qDebug("s-task:%s resume to normal from inputQ blocking, idle time:%"PRId64"ms", pTask->id.idStr, el); - pTask->msgInfo.blockingTs = 0; - } - - // now ready for next data output - atomic_store_8(&pTask->outputInfo.status, TASK_OUTPUT_STATUS__NORMAL); - - // otherwise, continue dispatch the first block to down stream task in pipeline - streamDispatchStreamBlock(pTask); - } - - return 0; -} - int32_t streamProcessRunReq(SStreamTask* pTask) { if (streamTryExec(pTask) < 0) { return -1; diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 41ed784d16..bcd45875fb 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -718,3 +718,69 @@ int32_t streamNotifyUpstreamContinue(SStreamTask* pTask) { num); return 0; } + +int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code) { + if (code != TSDB_CODE_SUCCESS) { + // dispatch message failed: network error, or node not available. + // in case of the input queue is full, the code will be TSDB_CODE_SUCCESS, the and pRsp>inputStatus will be set + // flag. here we need to retry dispatch this message to downstream task immediately. handle the case the failure + // happened too fast. + // todo handle the shuffle dispatch failure + qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", pTask->id.idStr, + pRsp->downstreamTaskId, tstrerror(code), ++pTask->msgInfo.retryCount); + int32_t ret = doDispatchAllBlocks(pTask, pTask->msgInfo.pData); + if (ret != TSDB_CODE_SUCCESS) { + } + + return TSDB_CODE_SUCCESS; + } + + qDebug("s-task:%s recv dispatch rsp, downstream task input status:%d code:%d", pTask->id.idStr, pRsp->inputStatus, + code); + + // there are other dispatch message not response yet + if (pTask->outputInfo.type == TASK_OUTPUT__SHUFFLE_DISPATCH) { + int32_t leftRsp = atomic_sub_fetch_32(&pTask->shuffleDispatcher.waitingRspCnt, 1); + qDebug("s-task:%s is shuffle, left waiting rsp %d", pTask->id.idStr, leftRsp); + if (leftRsp > 0) { + return 0; + } + } + + pTask->msgInfo.retryCount = 0; + ASSERT(pTask->outputInfo.status == TASK_OUTPUT_STATUS__WAIT); + + qDebug("s-task:%s output status is set to:%d", pTask->id.idStr, pTask->outputInfo.status); + + // the input queue of the (down stream) task that receive the output data is full, + // so the TASK_INPUT_STATUS_BLOCKED is rsp + if (pRsp->inputStatus == TASK_INPUT_STATUS__BLOCKED) { + pTask->inputStatus = TASK_INPUT_STATUS__BLOCKED; // block the input of current task, to push pressure to upstream + pTask->msgInfo.blockingTs = taosGetTimestampMs(); // record the blocking start time + qError("s-task:%s inputQ of downstream task:0x%x is full, time:%" PRId64 "wait for %dms and retry dispatch data", + pTask->id.idStr, pRsp->downstreamTaskId, pTask->msgInfo.blockingTs, DISPATCH_RETRY_INTERVAL_MS); + streamRetryDispatchStreamBlock(pTask, DISPATCH_RETRY_INTERVAL_MS); + } else { // pipeline send data in output queue + // this message has been sent successfully, let's try next one. + destroyStreamDataBlock(pTask->msgInfo.pData); + pTask->msgInfo.pData = NULL; + + if (pTask->msgInfo.blockingTs != 0) { + int64_t el = taosGetTimestampMs() - pTask->msgInfo.blockingTs; + qDebug("s-task:%s downstream task:0x%x resume to normal from inputQ blocking, blocking time:%" PRId64 "ms", + pTask->id.idStr, pRsp->downstreamTaskId, el); + pTask->msgInfo.blockingTs = 0; + + // put data into inputQ of current task is also allowed + pTask->inputStatus = TASK_INPUT_STATUS__NORMAL; + } + + // now ready for next data output + atomic_store_8(&pTask->outputInfo.status, TASK_OUTPUT_STATUS__NORMAL); + + // otherwise, continue dispatch the first block to down stream task in pipeline + streamDispatchStreamBlock(pTask); + } + + return 0; +} From 0d38f389abe7c229cb2ffb7d8c25582874051e6a Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sun, 13 Aug 2023 16:25:35 +0800 Subject: [PATCH 32/92] refactor: do some internal refactor. --- include/common/tmsgdef.h | 1 - include/libs/stream/tstream.h | 4 +- source/dnode/mgmt/mgmt_vnode/src/vmHandle.c | 1 - source/dnode/vnode/src/inc/vnodeInt.h | 1 - source/dnode/vnode/src/tq/tq.c | 51 ++++------------ source/dnode/vnode/src/tq/tqRestore.c | 17 ++++-- source/dnode/vnode/src/vnd/vnodeSvr.c | 2 - source/libs/stream/inc/streamInt.h | 1 + source/libs/stream/src/stream.c | 20 ++++++- source/libs/stream/src/streamDispatch.c | 41 +++++++++---- source/libs/stream/src/streamExec.c | 62 ++++++++----------- source/libs/stream/src/streamRecover.c | 66 +-------------------- 12 files changed, 100 insertions(+), 167 deletions(-) diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index 232551007d..60172bce3d 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -254,7 +254,6 @@ enum { TD_DEF_MSG_TYPE(TDMT_STREAM_RETRIEVE, "stream-retrieve", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_SCAN_HISTORY, "stream-scan-history", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_SCAN_HISTORY_FINISH, "stream-scan-history-finish", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_STREAM_TRANSFER_STATE, "stream-transfer-state", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_CHECK, "stream-task-check", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_CHECKPOINT, "stream-checkpoint", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_REPORT_CHECKPOINT, "stream-report-checkpoint", NULL, NULL) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index 508392ff77..d3b670d0ec 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -274,7 +274,7 @@ typedef struct SStreamStatus { int8_t schedStatus; int8_t keepTaskStatus; bool transferState; - bool appendTranstateBlock; // has append the transfer state data block already + bool appendTranstateBlock; // has append the transfer state data block already, todo: remove it int8_t timerActive; // timer is active int8_t pauseAllowed; // allowed task status to be set to be paused } SStreamStatus; @@ -582,6 +582,7 @@ int32_t streamProcessRunReq(SStreamTask* pTask); int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pMsg, bool exec); int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code); void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId); +void streamTaskOpenAllUpstreamInput(SStreamTask* pTask); int32_t streamProcessRetrieveReq(SStreamTask* pTask, SStreamRetrieveReq* pReq, SRpcMsg* pMsg); @@ -629,7 +630,6 @@ int32_t streamSetParamForStreamScannerStep2(SStreamTask* pTask, SVersionRange* p int32_t streamSourceScanHistoryData(SStreamTask* pTask); int32_t streamDispatchScanHistoryFinishMsg(SStreamTask* pTask); -int32_t streamDispatchTransferStateMsg(SStreamTask* pTask); int32_t appendTranstateIntoInputQ(SStreamTask* pTask); // agg level diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index bed9a67303..cf57deaa22 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -742,7 +742,6 @@ SArray *vmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_STREAM_RETRIEVE_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_SCAN_HISTORY_FINISH, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_SCAN_HISTORY_FINISH_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_TRANSFER_STATE, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECK, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECK_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TRIGGER, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h index cd7704940b..d41c58b501 100644 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ b/source/dnode/vnode/src/inc/vnodeInt.h @@ -250,7 +250,6 @@ int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskRetrieveReq(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskRetrieveRsp(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg); -int32_t tqProcessTaskTransferStateReq(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskScanHistoryFinishReq(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskScanHistoryFinishRsp(STQ* pTq, SRpcMsg* pMsg); int32_t tqCheckLogInWal(STQ* pTq, int64_t version); diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index ad1af080fd..9dfde0fed7 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -928,6 +928,8 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) { pTask->pMsgCb = &pTq->pVnode->msgCb; pTask->pMeta = pTq->pStreamMeta; + streamTaskOpenAllUpstreamInput(pTask); + // backup the initial status, and set it to be TASK_STATUS__INIT pTask->chkInfo.version = ver; pTask->chkInfo.currentVer = ver; @@ -1272,7 +1274,8 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { if (done) { pTask->tsInfo.step2Start = taosGetTimestampMs(); - streamTaskEndScanWAL(pTask); + qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, 0.0); + appendTranstateIntoInputQ(pTask); } else { STimeWindow* pWindow = &pTask->dataRange.window; tqDebug("s-task:%s level:%d verRange:%" PRId64 " - %" PRId64 " window:%" PRId64 "-%" PRId64 @@ -1337,44 +1340,6 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { return 0; } -// notify the downstream tasks to transfer executor state after handle all history blocks. -int32_t tqProcessTaskTransferStateReq(STQ* pTq, SRpcMsg* pMsg) { - char* pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); - int32_t len = pMsg->contLen - sizeof(SMsgHead); - - SStreamTransferReq req = {0}; - - SDecoder decoder; - tDecoderInit(&decoder, (uint8_t*)pReq, len); - int32_t code = tDecodeStreamScanHistoryFinishReq(&decoder, &req); - tDecoderClear(&decoder); - - tqDebug("vgId:%d start to process transfer state msg, from s-task:0x%x", pTq->pStreamMeta->vgId, req.downstreamTaskId); - - SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, req.streamId, req.downstreamTaskId); - if (pTask == NULL) { - tqError("failed to find task:0x%x, it may have been dropped already. process transfer state failed", req.downstreamTaskId); - return -1; - } - - int32_t remain = streamAlignTransferState(pTask); - if (remain > 0) { - tqDebug("s-task:%s receive upstream transfer state msg, remain:%d", pTask->id.idStr, remain); - streamMetaReleaseTask(pTq->pStreamMeta, pTask); - return 0; - } - - // transfer the ownership of executor state - tqDebug("s-task:%s all upstream tasks send transfer msg, open transfer state flag", pTask->id.idStr); - ASSERT(pTask->streamTaskId.taskId != 0 && pTask->info.fillHistory == 1); - - pTask->status.transferState = true; - - streamSchedExec(pTask); - streamMetaReleaseTask(pTq->pStreamMeta, pTask); - return 0; -} - int32_t tqProcessTaskScanHistoryFinishReq(STQ* pTq, SRpcMsg* pMsg) { char* msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); int32_t msgLen = pMsg->contLen - sizeof(SMsgHead); @@ -1706,6 +1671,8 @@ int32_t tqProcessTaskRetrieveRsp(STQ* pTq, SRpcMsg* pMsg) { int32_t vnodeEnqueueStreamMsg(SVnode* pVnode, SRpcMsg* pMsg) { STQ* pTq = pVnode->pTq; + int32_t vgId = pVnode->config.vgId; + SMsgHead* msgStr = pMsg->pCont; char* msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead)); int32_t msgLen = pMsg->contLen - sizeof(SMsgHead); @@ -1722,7 +1689,9 @@ int32_t vnodeEnqueueStreamMsg(SVnode* pVnode, SRpcMsg* pMsg) { tDecoderClear(&decoder); int32_t taskId = req.taskId; - SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, req.streamId, req.taskId); + tqDebug("vgId:%d receive dispatch msg to s-task:0x%"PRIx64"-0x%x", vgId, req.streamId, taskId); + + SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, req.streamId, taskId); if (pTask != NULL) { SRpcMsg rsp = {.info = pMsg->info, .code = 0}; streamProcessDispatchMsg(pTask, &req, &rsp, false); @@ -1739,7 +1708,7 @@ int32_t vnodeEnqueueStreamMsg(SVnode* pVnode, SRpcMsg* pMsg) { FAIL: if (pMsg->info.handle == NULL) { - tqError("s-task:0x%x vgId:%d msg handle is null, abort enqueue dispatch msg", pTq->pStreamMeta->vgId, taskId); + tqError("s-task:0x%x vgId:%d msg handle is null, abort enqueue dispatch msg", vgId, taskId); return -1; } diff --git a/source/dnode/vnode/src/tq/tqRestore.c b/source/dnode/vnode/src/tq/tqRestore.c index a217bc2966..3054179416 100644 --- a/source/dnode/vnode/src/tq/tqRestore.c +++ b/source/dnode/vnode/src/tq/tqRestore.c @@ -210,14 +210,21 @@ int32_t doSetOffsetForWalReader(SStreamTask *pTask, int32_t vgId) { } static void checkForFillHistoryVerRange(SStreamTask* pTask, int64_t ver) { + const char* id = pTask->id.idStr; + if ((pTask->info.fillHistory == 1) && ver > pTask->dataRange.range.maxVer) { - qWarn("s-task:%s fill-history scan WAL, currentVer:%" PRId64 " reach the maximum ver:%" PRId64 - ", not scan wal anymore, set the transfer state flag", - pTask->id.idStr, ver, pTask->dataRange.range.maxVer); if (!pTask->status.appendTranstateBlock) { - pTask->status.appendTranstateBlock = true; + qWarn("s-task:%s fill-history scan WAL, currentVer:%" PRId64 " reach the maximum ver:%" PRId64 + ", not scan wal anymore, add transfer-state block into inputQ", + id, ver, pTask->dataRange.range.maxVer); + + double el = (taosGetTimestampMs() - pTask->tsInfo.step2Start) / 1000.0; + qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, el); appendTranstateIntoInputQ(pTask); /*int32_t code = */streamSchedExec(pTask); + } else { + qWarn("s-task:%s fill-history scan WAL, currentVer:%" PRId64 " reach the maximum ver:%" PRId64 ", not scan wal", + id, ver, pTask->dataRange.range.maxVer); } } } @@ -264,7 +271,7 @@ int32_t createStreamTaskRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) { continue; } - if ((pTask->info.fillHistory == 1) && pTask->status.transferState) { + if ((pTask->info.fillHistory == 1) && pTask->status.appendTranstateBlock) { ASSERT(status == TASK_STATUS__NORMAL); // the maximum version of data in the WAL has reached already, the step2 is done tqDebug("s-task:%s fill-history reach the maximum ver:%" PRId64 ", not scan wal anymore", pTask->id.idStr, diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index bf1abf5795..70c3382dc5 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -660,8 +660,6 @@ int32_t vnodeProcessStreamMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) return tqProcessTaskRetrieveRsp(pVnode->pTq, pMsg); case TDMT_VND_STREAM_SCAN_HISTORY: return tqProcessTaskScanHistory(pVnode->pTq, pMsg); - case TDMT_STREAM_TRANSFER_STATE: - return tqProcessTaskTransferStateReq(pVnode->pTq, pMsg); case TDMT_STREAM_SCAN_HISTORY_FINISH: return tqProcessTaskScanHistoryFinishReq(pVnode->pTq, pMsg); case TDMT_STREAM_SCAN_HISTORY_FINISH_RSP: diff --git a/source/libs/stream/inc/streamInt.h b/source/libs/stream/inc/streamInt.h index b0fed5dde1..7a557a744a 100644 --- a/source/libs/stream/inc/streamInt.h +++ b/source/libs/stream/inc/streamInt.h @@ -62,6 +62,7 @@ SStreamQueueItem* streamMergeQueueItem(SStreamQueueItem* dst, SStreamQueueItem* int32_t streamAddEndScanHistoryMsg(SStreamTask* pTask, SRpcHandleInfo* pRpcInfo, SStreamScanHistoryFinishReq* pReq); int32_t streamNotifyUpstreamContinue(SStreamTask* pTask); int32_t streamTaskFillHistoryFinished(SStreamTask* pTask); +int32_t streamTransferStateToStreamTask(SStreamTask* pTask); extern int32_t streamBackendId; extern int32_t streamBackendCfWrapperId; diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index b9c9e40562..e9b38dfff2 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -213,6 +213,10 @@ static int32_t streamTaskAppendInputBlocks(SStreamTask* pTask, const SStreamDisp qError("vgId:%d, s-task:%s failed to receive dispatch msg, reason: out of memory", pTask->pMeta->vgId, pTask->id.idStr); } else { + if (pBlock->type == STREAM_INPUT__TRANS_STATE) { + pTask->status.appendTranstateBlock = true; + } + int32_t code = tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pBlock); // input queue is full, upstream is blocked now status = (code == TSDB_CODE_SUCCESS) ? TASK_INPUT_STATUS__NORMAL : TASK_INPUT_STATUS__BLOCKED; @@ -379,6 +383,8 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { // use the default memory limit, refactor later. taosWriteQitem(pTask->inputQueue->queue, pItem); qDebug("s-task:%s data res enqueue, current(blocks:%d, size:%.2fMiB)", pTask->id.idStr, total, size); + } else { + ASSERT(0); } if (type != STREAM_INPUT__GET_RES && type != STREAM_INPUT__CHECKPOINT && pTask->triggerParam != 0) { @@ -421,4 +427,16 @@ SStreamChildEpInfo * streamTaskGetUpstreamTaskEpInfo(SStreamTask* pTask, int32_t } return NULL; -} \ No newline at end of file +} + +void streamTaskOpenAllUpstreamInput(SStreamTask* pTask) { + int32_t num = taosArrayGetSize(pTask->pUpstreamEpInfoList); + if (num == 0) { + return; + } + + for(int32_t i = 0; i < num; ++i) { + SStreamChildEpInfo* pInfo = taosArrayGetP(pTask->pUpstreamEpInfoList, i); + pInfo->dataAllowed = true; + } +} diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index bcd45875fb..d479dd44df 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -38,6 +38,7 @@ static int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatc if (tStartEncode(pEncoder) < 0) return -1; if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->taskId) < 0) return -1; + if (tEncodeI32(pEncoder, pReq->type) < 0) return -1; if (tEncodeI32(pEncoder, pReq->upstreamTaskId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->srcVgId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->upstreamChildId) < 0) return -1; @@ -91,6 +92,7 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { if (tStartDecode(pDecoder) < 0) return -1; if (tDecodeI64(pDecoder, &pReq->streamId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->taskId) < 0) return -1; + if (tDecodeI32(pDecoder, &pReq->type) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->upstreamTaskId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->srcVgId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->upstreamChildId) < 0) return -1; @@ -115,8 +117,8 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { return 0; } -int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, - int32_t numOfBlocks, int64_t dstTaskId, int32_t type) { +int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, int32_t numOfBlocks, + int64_t dstTaskId, int32_t type) { pReq->streamId = pTask->id.streamId; pReq->srcVgId = vgId; pReq->upstreamTaskId = pTask->id.taskId; @@ -456,8 +458,8 @@ static int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* p for (int32_t i = 0; i < numOfBlocks; i++) { SSDataBlock* pDataBlock = taosArrayGet(pData->blocks, i); - code = streamAddBlockIntoDispatchMsg(pDataBlock, &req); + code = streamAddBlockIntoDispatchMsg(pDataBlock, &req); if (code != TSDB_CODE_SUCCESS) { taosArrayDestroyP(req.data, taosMemoryFree); taosArrayDestroy(req.dataLen); @@ -720,14 +722,16 @@ int32_t streamNotifyUpstreamContinue(SStreamTask* pTask) { } int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code) { + const char* id = pTask->id.idStr; + if (code != TSDB_CODE_SUCCESS) { // dispatch message failed: network error, or node not available. // in case of the input queue is full, the code will be TSDB_CODE_SUCCESS, the and pRsp>inputStatus will be set // flag. here we need to retry dispatch this message to downstream task immediately. handle the case the failure // happened too fast. // todo handle the shuffle dispatch failure - qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", pTask->id.idStr, - pRsp->downstreamTaskId, tstrerror(code), ++pTask->msgInfo.retryCount); + qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", id, pRsp->downstreamTaskId, + tstrerror(code), ++pTask->msgInfo.retryCount); int32_t ret = doDispatchAllBlocks(pTask, pTask->msgInfo.pData); if (ret != TSDB_CODE_SUCCESS) { } @@ -735,22 +739,35 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i return TSDB_CODE_SUCCESS; } - qDebug("s-task:%s recv dispatch rsp, downstream task input status:%d code:%d", pTask->id.idStr, pRsp->inputStatus, - code); + qDebug("s-task:%s recv dispatch rsp from 0x%x, downstream task input status:%d code:%d", id, pRsp->downstreamTaskId, + pRsp->inputStatus, code); // there are other dispatch message not response yet if (pTask->outputInfo.type == TASK_OUTPUT__SHUFFLE_DISPATCH) { int32_t leftRsp = atomic_sub_fetch_32(&pTask->shuffleDispatcher.waitingRspCnt, 1); - qDebug("s-task:%s is shuffle, left waiting rsp %d", pTask->id.idStr, leftRsp); + qDebug("s-task:%s is shuffle, left waiting rsp %d", id, leftRsp); if (leftRsp > 0) { return 0; } } + // transtate msg has been sent to downstream successfully. let's transfer the fill-history task state + SStreamDataBlock* p = pTask->msgInfo.pData; + if (p->type == STREAM_INPUT__TRANS_STATE) { + qDebug("s-task:%s dispatch transtate msg to downstream successfully, start to transfer state", id); + ASSERT(pTask->info.fillHistory == 1); + code = streamTransferStateToStreamTask(pTask); + + if (code != TSDB_CODE_SUCCESS) { + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + return code; + } + } + pTask->msgInfo.retryCount = 0; ASSERT(pTask->outputInfo.status == TASK_OUTPUT_STATUS__WAIT); - qDebug("s-task:%s output status is set to:%d", pTask->id.idStr, pTask->outputInfo.status); + qDebug("s-task:%s output status is set to:%d", id, pTask->outputInfo.status); // the input queue of the (down stream) task that receive the output data is full, // so the TASK_INPUT_STATUS_BLOCKED is rsp @@ -758,7 +775,7 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i pTask->inputStatus = TASK_INPUT_STATUS__BLOCKED; // block the input of current task, to push pressure to upstream pTask->msgInfo.blockingTs = taosGetTimestampMs(); // record the blocking start time qError("s-task:%s inputQ of downstream task:0x%x is full, time:%" PRId64 "wait for %dms and retry dispatch data", - pTask->id.idStr, pRsp->downstreamTaskId, pTask->msgInfo.blockingTs, DISPATCH_RETRY_INTERVAL_MS); + id, pRsp->downstreamTaskId, pTask->msgInfo.blockingTs, DISPATCH_RETRY_INTERVAL_MS); streamRetryDispatchStreamBlock(pTask, DISPATCH_RETRY_INTERVAL_MS); } else { // pipeline send data in output queue // this message has been sent successfully, let's try next one. @@ -767,8 +784,8 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i if (pTask->msgInfo.blockingTs != 0) { int64_t el = taosGetTimestampMs() - pTask->msgInfo.blockingTs; - qDebug("s-task:%s downstream task:0x%x resume to normal from inputQ blocking, blocking time:%" PRId64 "ms", - pTask->id.idStr, pRsp->downstreamTaskId, el); + qDebug("s-task:%s downstream task:0x%x resume to normal from inputQ blocking, blocking time:%" PRId64 "ms", id, + pRsp->downstreamTaskId, el); pTask->msgInfo.blockingTs = 0; // put data into inputQ of current task is also allowed diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index bbfaa8cb9d..269334f54d 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -287,7 +287,7 @@ static void waitForTaskIdle(SStreamTask* pTask, SStreamTask* pStreamTask) { } } -static int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { +int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { SStreamMeta* pMeta = pTask->pMeta; SStreamTask* pStreamTask = streamMetaAcquireTask(pMeta, pTask->streamTaskId.streamId, pTask->streamTaskId.taskId); @@ -301,7 +301,7 @@ static int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { pStreamTask->id.idStr); } - ASSERT(pStreamTask->historyTaskId.taskId == pTask->id.taskId && pTask->status.transferState == true); + ASSERT(pStreamTask->historyTaskId.taskId == pTask->id.taskId && pTask->status.appendTranstateBlock == true); STimeWindow* pTimeWindow = &pStreamTask->dataRange.window; @@ -383,11 +383,9 @@ static int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { return TSDB_CODE_SUCCESS; } -static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { +int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { int32_t code = TSDB_CODE_SUCCESS; - if (!pTask->status.transferState) { - return code; - } + ASSERT(pTask->status.appendTranstateBlock == 1); int32_t level = pTask->info.taskLevel; if (level == TASK_LEVEL__SOURCE) { @@ -513,14 +511,12 @@ int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock // transfer the ownership of executor state if (level == TASK_LEVEL__SOURCE) { - qDebug("s-task:%s open transfer state flag for source task", id); + qDebug("s-task:%s add transfer-state block into outputQ", id); } else { - qDebug("s-task:%s all upstream tasks send transfer msg, open transfer state flag", id); + qDebug("s-task:%s all upstream tasks send transfer-state block, add transfer-state block into outputQ", id); ASSERT(pTask->streamTaskId.taskId != 0 && pTask->info.fillHistory == 1); } - pTask->status.transferState = true; - // dispatch the tran-state block to downstream task immediately int32_t type = pTask->outputInfo.type; if ((level == TASK_LEVEL__AGG || level == TASK_LEVEL__SOURCE) && @@ -639,16 +635,7 @@ int32_t streamTaskEndScanWAL(SStreamTask* pTask) { qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, el); // 1. notify all downstream tasks to transfer executor state after handle all history blocks. -// pTask->status.transferState = true; appendTranstateIntoInputQ(pTask); - - // 2. do transfer stream task operator states. - // todo remove this -// int32_t code = streamDoTransferStateToStreamTask(pTask); -// if (code != TSDB_CODE_SUCCESS) { // todo handle error -// return code; -// } - return TSDB_CODE_SUCCESS; } @@ -667,35 +654,36 @@ int32_t streamTryExec(SStreamTask* pTask) { } // todo the task should be commit here - if (taosQueueEmpty(pTask->inputQueue->queue)) { +// if (taosQueueEmpty(pTask->inputQueue->queue)) { // fill-history WAL scan has completed - if (pTask->status.transferState) { - code = streamTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { - atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - return code; - } +// if (pTask->status.transferState) { +// code = streamTransferStateToStreamTask(pTask); +// if (code != TSDB_CODE_SUCCESS) { +// atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); +// return code; +// } // the schedStatus == TASK_SCHED_STATUS__ACTIVE, streamSchedExec cannot be executed, so execute once again by // call this function (streamExecForAll) directly. -// code = streamExecForAll(pTask); -// if (code < 0) { - // do nothing -// } - } + // code = streamExecForAll(pTask); + // if (code < 0) { + // do nothing + // } +// } - atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, - streamGetTaskStatusStr(pTask->status.taskStatus), pTask->status.schedStatus); - } else { +// atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); +// qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, +// streamGetTaskStatusStr(pTask->status.taskStatus), pTask->status.schedStatus); +// } else { atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), pTask->status.schedStatus); - if ((!streamTaskShouldStop(&pTask->status)) && (!streamTaskShouldPause(&pTask->status))) { + if (!(taosQueueEmpty(pTask->inputQueue->queue) || streamTaskShouldStop(&pTask->status) || + streamTaskShouldPause(&pTask->status))) { streamSchedExec(pTask); } - } +// } } else { qDebug("s-task:%s already started to exec by other thread, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), pTask->status.schedStatus); diff --git a/source/libs/stream/src/streamRecover.c b/source/libs/stream/src/streamRecover.c index 708524bf10..72dae735e1 100644 --- a/source/libs/stream/src/streamRecover.c +++ b/source/libs/stream/src/streamRecover.c @@ -372,49 +372,6 @@ int32_t streamDispatchScanHistoryFinishMsg(SStreamTask* pTask) { return 0; } -static int32_t doDispatchTransferMsg(SStreamTask* pTask, const SStreamTransferReq* pReq, int32_t vgId, SEpSet* pEpSet) { - void* buf = NULL; - int32_t code = -1; - SRpcMsg msg = {0}; - - int32_t tlen; - tEncodeSize(tEncodeStreamScanHistoryFinishReq, pReq, tlen, code); - if (code < 0) { - return -1; - } - - buf = rpcMallocCont(sizeof(SMsgHead) + tlen); - if (buf == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - ((SMsgHead*)buf)->vgId = htonl(vgId); - void* abuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); - - SEncoder encoder; - tEncoderInit(&encoder, abuf, tlen); - if ((code = tEncodeStreamScanHistoryFinishReq(&encoder, pReq)) < 0) { - if (buf) { - rpcFreeCont(buf); - } - return code; - } - - tEncoderClear(&encoder); - - msg.contLen = tlen + sizeof(SMsgHead); - msg.pCont = buf; - msg.msgType = TDMT_STREAM_TRANSFER_STATE; - msg.info.noResp = 1; - - tmsgSendReq(pEpSet, &msg); - qDebug("s-task:%s level:%d, status:%s dispatch transfer state msg to taskId:0x%x (vgId:%d)", pTask->id.idStr, - pTask->info.taskLevel, streamGetTaskStatusStr(pTask->status.taskStatus), pReq->downstreamTaskId, vgId); - - return 0; -} - int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { SStreamDataBlock* pTranstate = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, sizeof(SSDataBlock)); if (pTranstate == NULL) { @@ -442,6 +399,8 @@ int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { return TSDB_CODE_OUT_OF_MEMORY; } + pTask->status.appendTranstateBlock = true; + qDebug("s-task:%s set sched-status:%d, prev:%d", pTask->id.idStr, TASK_SCHED_STATUS__INACTIVE, pTask->status.schedStatus); pTask->status.schedStatus = TASK_SCHED_STATUS__INACTIVE; streamSchedExec(pTask); @@ -449,27 +408,6 @@ int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { return TSDB_CODE_SUCCESS; } -int32_t streamDispatchTransferStateMsg(SStreamTask* pTask) { - SStreamTransferReq req = { .streamId = pTask->id.streamId, .childId = pTask->info.selfChildId }; - - // serialize - if (pTask->outputInfo.type == TASK_OUTPUT__FIXED_DISPATCH) { - req.downstreamTaskId = pTask->fixedEpDispatcher.taskId; - doDispatchTransferMsg(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet); - } else if (pTask->outputInfo.type == TASK_OUTPUT__SHUFFLE_DISPATCH) { - SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; - - int32_t numOfVgs = taosArrayGetSize(vgInfo); - for (int32_t i = 0; i < numOfVgs; i++) { - SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); - req.downstreamTaskId = pVgInfo->taskId; - doDispatchTransferMsg(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet); - } - } - - return 0; -} - // agg int32_t streamTaskScanHistoryPrepare(SStreamTask* pTask) { pTask->numOfWaitingUpstream = taosArrayGetSize(pTask->pUpstreamEpInfoList); From a81cc9aebfead3f455e2b5c251ab59ae0934b8dd Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sun, 13 Aug 2023 17:31:09 +0800 Subject: [PATCH 33/92] fix(stream): fix the error when no agg tasks exist. --- source/libs/stream/src/streamExec.c | 40 ++++++++++++++++++----------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 269334f54d..fa3f149a43 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -509,24 +509,34 @@ int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock } } - // transfer the ownership of executor state - if (level == TASK_LEVEL__SOURCE) { - qDebug("s-task:%s add transfer-state block into outputQ", id); - } else { - qDebug("s-task:%s all upstream tasks send transfer-state block, add transfer-state block into outputQ", id); - ASSERT(pTask->streamTaskId.taskId != 0 && pTask->info.fillHistory == 1); - } - // dispatch the tran-state block to downstream task immediately int32_t type = pTask->outputInfo.type; - if ((level == TASK_LEVEL__AGG || level == TASK_LEVEL__SOURCE) && - (type == TASK_OUTPUT__FIXED_DISPATCH || type == TASK_OUTPUT__SHUFFLE_DISPATCH)) { - pBlock->srcVgId = pTask->pMeta->vgId; - code = taosWriteQitem(pTask->outputInfo.queue->queue, pBlock); - if (code == 0) { - streamDispatchStreamBlock(pTask); + + // transfer the ownership of executor state + if (type == TASK_OUTPUT__FIXED_DISPATCH || type == TASK_OUTPUT__SHUFFLE_DISPATCH) { + if (level == TASK_LEVEL__SOURCE) { + qDebug("s-task:%s add transfer-state block into outputQ", id); } else { - streamFreeQitem((SStreamQueueItem*)pBlock); + qDebug("s-task:%s all upstream tasks send transfer-state block, add transfer-state block into outputQ", id); + ASSERT(pTask->streamTaskId.taskId != 0 && pTask->info.fillHistory == 1); + } + + if (level == TASK_LEVEL__AGG || level == TASK_LEVEL__SOURCE) { + pBlock->srcVgId = pTask->pMeta->vgId; + code = taosWriteQitem(pTask->outputInfo.queue->queue, pBlock); + if (code == 0) { + streamDispatchStreamBlock(pTask); + } else { + streamFreeQitem((SStreamQueueItem*)pBlock); + } + } + } else { // non-dispatch task, do task state transfer directly + qDebug("s-task:%s non-dispatch task, start to transfer state directly", id); + ASSERT(pTask->info.fillHistory == 1); + code = streamTransferStateToStreamTask(pTask); + + if (code != TSDB_CODE_SUCCESS) { + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); } } From 72e509a46c8832ade6b2986bb8b09efd227ddad0 Mon Sep 17 00:00:00 2001 From: Alex Duan <51781608+DuanKuanJun@users.noreply.github.com> Date: Sun, 13 Aug 2023 17:39:24 +0800 Subject: [PATCH 34/92] Update 08-taos-shell.md --- docs/zh/14-reference/08-taos-shell.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/zh/14-reference/08-taos-shell.md b/docs/zh/14-reference/08-taos-shell.md index 3423cf35bb..1caa580b73 100644 --- a/docs/zh/14-reference/08-taos-shell.md +++ b/docs/zh/14-reference/08-taos-shell.md @@ -89,3 +89,11 @@ taos -h h1.taos.com -s "use db; show tables;" - 执行 `RESET QUERY CACHE` 可清除本地表 Schema 的缓存 - 批量执行 SQL 语句。可以将一系列的 TDengine CLI 命令(以英文 ; 结尾,每个 SQL 语句为一行)按行存放在文件里,在 TDengine CLI 里执行命令 `source ` 自动执行该文件里所有的 SQL 语句 - 输入 `q` 或 `quit` 或 `exit` 回车,可以退出 TDengine CLI + +## TDengine CLI 导出查询结果到文件中 + +- 可以使用符号 “>>” 导出查询结果到某个文件中,语法为: sql 查询语句 >> ‘输出文件名’; 输出文件如果不写路径的话,将输出至当前目录下。如 select * from d0 >> ‘/root/d0.csv’; 将把查询结果输出到 /root/d0.csv 中。 + +## TDengine CLI 导入文件中的数据到表中 + +- 可以使用 insert into table_name file '输入文件名',把上一步中导出的数据文件再导入到指定表中。如 insert into d0 file '/root/d0.csv'; 表示把上面导出的数据全部再导致至 d0 表中。 From 98f40325e9147fad41823ed32a2188cd707e11eb Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sun, 13 Aug 2023 20:02:15 +0800 Subject: [PATCH 35/92] fix(stream): fix memory leak. --- source/dnode/snode/src/snode.c | 2 ++ source/libs/stream/src/streamData.c | 41 +------------------------ source/libs/stream/src/streamDispatch.c | 2 +- source/libs/stream/src/streamExec.c | 3 ++ 4 files changed, 7 insertions(+), 41 deletions(-) diff --git a/source/dnode/snode/src/snode.c b/source/dnode/snode/src/snode.c index 4000e72835..635fdcf459 100644 --- a/source/dnode/snode/src/snode.c +++ b/source/dnode/snode/src/snode.c @@ -77,6 +77,8 @@ int32_t sndExpandTask(SSnode *pSnode, SStreamTask *pTask, int64_t ver) { pTask->chkInfo.version = ver; pTask->pMeta = pSnode->pMeta; + streamTaskOpenAllUpstreamInput(pTask); + pTask->pState = streamStateOpen(pSnode->path, pTask, false, -1, -1); if (pTask->pState == NULL) { return -1; diff --git a/source/libs/stream/src/streamData.c b/source/libs/stream/src/streamData.c index fcc0195bf4..fc1b788b77 100644 --- a/source/libs/stream/src/streamData.c +++ b/source/libs/stream/src/streamData.c @@ -15,45 +15,6 @@ #include "streamInt.h" -SStreamDataBlock* createStreamBlockFromDispatchMsg(const SStreamDispatchReq* pReq, int32_t blockType, int32_t srcVg) { - SStreamDataBlock* pData = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, pReq->totalLen); - if (pData == NULL) { - return NULL; - } - - pData->type = blockType; - pData->srcVgId = srcVg; - pData->srcTaskId = pReq->upstreamTaskId; - - int32_t blockNum = pReq->blockNum; - SArray* pArray = taosArrayInit_s(sizeof(SSDataBlock), blockNum); - if (pArray == NULL) { - taosFreeQitem(pData); - return NULL; - } - - ASSERT((pReq->blockNum == taosArrayGetSize(pReq->data)) && (pReq->blockNum == taosArrayGetSize(pReq->dataLen))); - - for (int32_t i = 0; i < blockNum; i++) { - SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*) taosArrayGetP(pReq->data, i); - SSDataBlock* pDataBlock = taosArrayGet(pArray, i); - blockDecode(pDataBlock, pRetrieve->data); - - // TODO: refactor - pDataBlock->info.window.skey = be64toh(pRetrieve->skey); - pDataBlock->info.window.ekey = be64toh(pRetrieve->ekey); - pDataBlock->info.version = be64toh(pRetrieve->version); - pDataBlock->info.watermark = be64toh(pRetrieve->watermark); - memcpy(pDataBlock->info.parTbName, pRetrieve->parTbName, TSDB_TABLE_NAME_LEN); - - pDataBlock->info.type = pRetrieve->streamBlockType; - pDataBlock->info.childId = pReq->upstreamChildId; - } - - pData->blocks = pArray; - return pData; -} - SStreamDataBlock* createStreamDataFromDispatchMsg(const SStreamDispatchReq* pReq, int32_t blockType, int32_t srcVg) { SStreamDataBlock* pData = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, pReq->totalLen); if (pData == NULL) { @@ -243,7 +204,7 @@ void streamFreeQitem(SStreamQueueItem* data) { if (type == STREAM_INPUT__GET_RES) { blockDataDestroy(((SStreamTrigger*)data)->pBlock); taosFreeQitem(data); - } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE) { + } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE || type == STREAM_INPUT__TRANS_STATE) { taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)blockDataFreeRes); taosFreeQitem(data); } else if (type == STREAM_INPUT__DATA_SUBMIT) { diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index d479dd44df..94e005b790 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -774,7 +774,7 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i if (pRsp->inputStatus == TASK_INPUT_STATUS__BLOCKED) { pTask->inputStatus = TASK_INPUT_STATUS__BLOCKED; // block the input of current task, to push pressure to upstream pTask->msgInfo.blockingTs = taosGetTimestampMs(); // record the blocking start time - qError("s-task:%s inputQ of downstream task:0x%x is full, time:%" PRId64 "wait for %dms and retry dispatch data", + qError("s-task:%s inputQ of downstream task:0x%x is full, time:%" PRId64 " wait for %dms and retry dispatch data", id, pRsp->downstreamTaskId, pTask->msgInfo.blockingTs, DISPATCH_RETRY_INTERVAL_MS); streamRetryDispatchStreamBlock(pTask, DISPATCH_RETRY_INTERVAL_MS); } else { // pipeline send data in output queue diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index fa3f149a43..3b954793de 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -504,6 +504,7 @@ int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock if (level == TASK_LEVEL__AGG || level == TASK_LEVEL__SINK) { int32_t remain = streamAlignTransferState(pTask); if (remain > 0) { + streamFreeQitem((SStreamQueueItem*)pBlock); qDebug("s-task:%s receive upstream transfer state msg, remain:%d", id, remain); return 0; } @@ -532,6 +533,8 @@ int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock } } else { // non-dispatch task, do task state transfer directly qDebug("s-task:%s non-dispatch task, start to transfer state directly", id); + + streamFreeQitem((SStreamQueueItem*)pBlock); ASSERT(pTask->info.fillHistory == 1); code = streamTransferStateToStreamTask(pTask); From dd0bc0e0500d758a4ac99523f5afeeda021779fb Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 14 Aug 2023 09:42:55 +0800 Subject: [PATCH 36/92] fix:heap use after free --- include/libs/wal/wal.h | 1 - source/dnode/vnode/src/tq/tqRead.c | 3 +++ source/dnode/vnode/src/tq/tqUtil.c | 1 - source/libs/wal/src/walRead.c | 1 - 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/libs/wal/wal.h b/include/libs/wal/wal.h index 1f7323a06a..cfe70a186c 100644 --- a/include/libs/wal/wal.h +++ b/include/libs/wal/wal.h @@ -206,7 +206,6 @@ void walReaderValidVersionRange(SWalReader *pReader, int64_t *sver, int64 void walReaderVerifyOffset(SWalReader *pWalReader, STqOffsetVal* pOffset); // only for tq usage -void walSetReaderCapacity(SWalReader *pRead, int32_t capacity); int32_t walFetchHead(SWalReader *pRead, int64_t ver); int32_t walFetchBody(SWalReader *pRead); int32_t walSkipFetchBody(SWalReader *pRead); diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 6c091fa4cb..252a0642fa 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -219,11 +219,13 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t goto END; } + pHead = &(pHandle->pWalReader->pHead->head); if (isValValidForTable(pHandle, pHead)) { code = 0; goto END; } else { offset++; + code = -1; continue; } } @@ -234,6 +236,7 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t } offset++; } + code = -1; } END: diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index 42aac52c63..b7fd505784 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -216,7 +216,6 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, walReaderVerifyOffset(pHandle->pWalReader, offset); int64_t fetchVer = offset->version; - walSetReaderCapacity(pHandle->pWalReader, 2048); int totalRows = 0; while (1) { int32_t savedEpoch = atomic_load_32(&pHandle->epoch); diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c index 01404494e3..d9e43e4324 100644 --- a/source/libs/wal/src/walRead.c +++ b/source/libs/wal/src/walRead.c @@ -250,7 +250,6 @@ int32_t walReaderSeekVer(SWalReader *pReader, int64_t ver) { return 0; } -void walSetReaderCapacity(SWalReader *pRead, int32_t capacity) { pRead->capacity = capacity; } int32_t walFetchHead(SWalReader *pRead, int64_t ver) { int64_t code; From 2806fe1c563b13a554147b9c6b21f219a1892fde Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Aug 2023 10:58:24 +0800 Subject: [PATCH 37/92] fix(stream): ignore the related stream task destory msg in transfer state. --- source/dnode/vnode/src/tq/tq.c | 2 +- source/libs/stream/src/streamDispatch.c | 6 ++--- source/libs/stream/src/streamExec.c | 32 ++++++++++++++----------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 9dfde0fed7..4b666ec54a 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1527,7 +1527,7 @@ int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg) { if (pTask) { streamProcessDispatchRsp(pTask, pRsp, pMsg->code); streamMetaReleaseTask(pTq->pStreamMeta, pTask); - return 0; + return TSDB_CODE_SUCCESS; } else { tqDebug("vgId:%d failed to handle the dispatch rsp, since find task:0x%x failed", vgId, taskId); return TSDB_CODE_INVALID_MSG; diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 94e005b790..06861454d1 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -758,10 +758,10 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i ASSERT(pTask->info.fillHistory == 1); code = streamTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { - atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - return code; + if (code != TSDB_CODE_SUCCESS) { // todo: do nothing if error happens +// atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); } + return TSDB_CODE_SUCCESS; } pTask->msgInfo.retryCount = 0; diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 3b954793de..a3ff752bc5 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -292,9 +292,20 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { SStreamTask* pStreamTask = streamMetaAcquireTask(pMeta, pTask->streamTaskId.streamId, pTask->streamTaskId.taskId); if (pStreamTask == NULL) { - // todo: destroy the fill-history task here - qError("s-task:%s failed to find related stream task:0x%x, it may have been destroyed or closed", pTask->id.idStr, - pTask->streamTaskId.taskId); + qError( + "s-task:%s failed to find related stream task:0x%x, it may have been destroyed or closed, destroy the related " + "fill-history task", + pTask->id.idStr, pTask->streamTaskId.taskId); + + // 1. free it and remove fill-history task from disk meta-store + streamMetaUnregisterTask(pMeta, pTask->id.streamId, pTask->id.taskId); + + // 2. save to disk + taosWLockLatch(&pMeta->lock); + if (streamMetaCommit(pMeta) < 0) { + // persist to disk + } + taosWUnLockLatch(&pMeta->lock); return TSDB_CODE_STREAM_TASK_NOT_EXIST; } else { qDebug("s-task:%s fill-history task end, update related stream task:%s info, transfer exec state", pTask->id.idStr, @@ -334,9 +345,6 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { qDebug("s-task:%s no need to update time window for non-source task", pStreamTask->id.idStr); } - // todo check the output queue for fill-history task, and wait for it complete - - // 1. expand the query time window for stream task of WAL scanner pTimeWindow->skey = INT64_MIN; qStreamInfoResetTimewindowFilter(pStreamTask->exec.pExecutor); @@ -390,15 +398,10 @@ int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { int32_t level = pTask->info.taskLevel; if (level == TASK_LEVEL__SOURCE) { streamTaskFillHistoryFinished(pTask); + } + + if (level == TASK_LEVEL__AGG || level == TASK_LEVEL__SOURCE) { // do transfer task operator states. code = streamDoTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { // todo handle this - return code; - } - } else if (level == TASK_LEVEL__AGG) { // do transfer task operator states. - code = streamDoTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { // todo handle this - return code; - } } return code; @@ -522,6 +525,7 @@ int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock ASSERT(pTask->streamTaskId.taskId != 0 && pTask->info.fillHistory == 1); } + // agg task should dispatch trans-state msg to sink task, to flush all data to sink task. if (level == TASK_LEVEL__AGG || level == TASK_LEVEL__SOURCE) { pBlock->srcVgId = pTask->pMeta->vgId; code = taosWriteQitem(pTask->outputInfo.queue->queue, pBlock); From ac446a3b959965af2c52daaa7ed5715faa787113 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:26:47 +0800 Subject: [PATCH 38/92] Update 08-taos-shell.md --- docs/en/14-reference/08-taos-shell.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/en/14-reference/08-taos-shell.md b/docs/en/14-reference/08-taos-shell.md index e66da7ec17..7e0433a8b2 100644 --- a/docs/en/14-reference/08-taos-shell.md +++ b/docs/en/14-reference/08-taos-shell.md @@ -81,6 +81,14 @@ For example: taos -h h1.taos.com -s "use db; show tables;" ``` +## Export query results to a file + +- You can use ">>" to export the query results to a file, the syntax is like `select * from table >> file`. If there is only file name without path, the file will be generated under the current working directory of TDegnine CLI. + +## Import data from CSV file + +- You can use `insert into table_name file 'fileName'` to import the data from the specified file into the specified table. For example, `insert into d0 file '/root/d0.csv';` means importing the data in file "/root/d0.csv" into table "d0". If there is only file name without path, that means the file is located under current working directory of TDengine CLI. + ## TDengine CLI tips - You can use the up and down keys to iterate the history of commands entered @@ -89,3 +97,5 @@ taos -h h1.taos.com -s "use db; show tables;" - Execute `RESET QUERY CACHE` to clear the local cache of the table schema - Execute SQL statements in batches. You can store a series of shell commands (ending with ;, one line for each SQL command) in a script file and execute the command `source ` in the TDengine CLI to execute all SQL commands in that file automatically - Enter `q` to exit TDengine CLI + + From e8c9a019a4938671fbc0a77fe4e523139c987dd8 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Aug 2023 11:41:24 +0800 Subject: [PATCH 39/92] fix(stream): remove the invalid set of scheduler status. --- include/libs/stream/tstream.h | 1 - source/libs/stream/src/streamExec.c | 10 ---------- source/libs/stream/src/streamRecover.c | 2 -- 3 files changed, 13 deletions(-) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index d3b670d0ec..02bb65b762 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -593,7 +593,6 @@ int32_t streamTaskOutputResultBlock(SStreamTask* pTask, SStreamDataBlock* pBlock bool streamTaskShouldStop(const SStreamStatus* pStatus); bool streamTaskShouldPause(const SStreamStatus* pStatus); bool streamTaskIsIdle(const SStreamTask* pTask); -int32_t streamTaskEndScanWAL(SStreamTask* pTask); SStreamChildEpInfo* streamTaskGetUpstreamTaskEpInfo(SStreamTask* pTask, int32_t taskId); int32_t streamScanExec(SStreamTask* pTask, int32_t batchSize); diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index a3ff752bc5..37c5808e02 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -646,16 +646,6 @@ bool streamTaskIsIdle(const SStreamTask* pTask) { pTask->status.taskStatus == TASK_STATUS__DROPPING); } -int32_t streamTaskEndScanWAL(SStreamTask* pTask) { - const char* id = pTask->id.idStr; - double el = (taosGetTimestampMs() - pTask->tsInfo.step2Start) / 1000.0; - qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, el); - - // 1. notify all downstream tasks to transfer executor state after handle all history blocks. - appendTranstateIntoInputQ(pTask); - return TSDB_CODE_SUCCESS; -} - int32_t streamTryExec(SStreamTask* pTask) { // this function may be executed by multi-threads, so status check is required. int8_t schedStatus = diff --git a/source/libs/stream/src/streamRecover.c b/source/libs/stream/src/streamRecover.c index 72dae735e1..42ff9b9b4e 100644 --- a/source/libs/stream/src/streamRecover.c +++ b/source/libs/stream/src/streamRecover.c @@ -400,9 +400,7 @@ int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { } pTask->status.appendTranstateBlock = true; - qDebug("s-task:%s set sched-status:%d, prev:%d", pTask->id.idStr, TASK_SCHED_STATUS__INACTIVE, pTask->status.schedStatus); - pTask->status.schedStatus = TASK_SCHED_STATUS__INACTIVE; streamSchedExec(pTask); return TSDB_CODE_SUCCESS; From 5ec6b64aab0f37930dcb9c4c45b1ece6663f664a Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Aug 2023 13:12:41 +0800 Subject: [PATCH 40/92] fix(stream): add logs. --- source/dnode/vnode/src/tq/tqRead.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 9b8f1781cb..a875febd09 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -339,8 +339,12 @@ int32_t extractMsgFromWal(SWalReader* pReader, void** pItem, int64_t maxVer, con void* pBody = POINTER_SHIFT(pReader->pHead->head.body, sizeof(SMsgHead)); int32_t len = pReader->pHead->head.bodyLen - sizeof(SMsgHead); - extractDelDataBlock(pBody, len, ver, (SStreamRefDataBlock**)pItem); - tqDebug("s-task:%s delete msg extract from WAL, len:%d, ver:%"PRId64, id, len, ver); + code = extractDelDataBlock(pBody, len, ver, (SStreamRefDataBlock**)pItem); + if (code != TSDB_CODE_SUCCESS) { + tqError("s-task:%s extract delete msg from WAL failed, code:%s", id, tstrerror(code)); + } else { + tqDebug("s-task:%s delete msg extract from WAL, len:%d, ver:%"PRId64, id, len, ver); + } } else { ASSERT(0); } From 3f90ca4b38721b4890f00798d2f694071b98b0af Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Mon, 14 Aug 2023 14:19:24 +0800 Subject: [PATCH 41/92] fix: set max_binary_display_width can not show all text --- tests/system-test/0-others/walRetention.py | 3 +-- tools/shell/src/shellEngine.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/system-test/0-others/walRetention.py b/tests/system-test/0-others/walRetention.py index 2b340b7969..5257b7644a 100644 --- a/tests/system-test/0-others/walRetention.py +++ b/tests/system-test/0-others/walRetention.py @@ -460,8 +460,7 @@ class TDTestCase: #self.test_db("db2", 5, 10*24*3600, 2*1024) # 2M size # period + size - self.test_db("db", checkTime = 5*60, wal_period = 60, wal_size_kb=10) - #self.test_db("db", checkTime = 3*60, wal_period = 0, wal_size_kb=0) + self.test_db("db", checkTime = 3*60, wal_period = 60, wal_size_kb=500) def stop(self): diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index e9dd067ac4..0148ebc3c5 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -776,7 +776,7 @@ int32_t shellCalcColWidth(TAOS_FIELD *field, int32_t precision) { if (field->bytes > shell.args.displayWidth) { return TMAX(shell.args.displayWidth, width); } else { - return TMAX(field->bytes, width); + return TMAX(field->bytes + 2, width); } case TSDB_DATA_TYPE_NCHAR: @@ -785,7 +785,7 @@ int32_t shellCalcColWidth(TAOS_FIELD *field, int32_t precision) { if (bytes > shell.args.displayWidth) { return TMAX(shell.args.displayWidth, width); } else { - return TMAX(bytes, width); + return TMAX(bytes + 2, width); } } From 91710b0c0f243e8c8f00a65b637e231d36801f33 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Aug 2023 14:56:17 +0800 Subject: [PATCH 42/92] fix(stream): --- source/dnode/vnode/src/tq/tq.c | 2 ++ source/libs/stream/src/streamRecover.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 64715122f2..ddd0c49649 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1274,6 +1274,8 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { pTask->tsInfo.step2Start = taosGetTimestampMs(); qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, 0.0); appendTranstateIntoInputQ(pTask); + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + streamSchedExec(pTask); } else { STimeWindow* pWindow = &pTask->dataRange.window; tqDebug("s-task:%s level:%d verRange:%" PRId64 " - %" PRId64 " window:%" PRId64 "-%" PRId64 diff --git a/source/libs/stream/src/streamRecover.c b/source/libs/stream/src/streamRecover.c index 42ff9b9b4e..c3d4d4c7ae 100644 --- a/source/libs/stream/src/streamRecover.c +++ b/source/libs/stream/src/streamRecover.c @@ -401,8 +401,6 @@ int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { pTask->status.appendTranstateBlock = true; qDebug("s-task:%s set sched-status:%d, prev:%d", pTask->id.idStr, TASK_SCHED_STATUS__INACTIVE, pTask->status.schedStatus); - streamSchedExec(pTask); - return TSDB_CODE_SUCCESS; } From a1e554fbf32b68496f63a5a9c9a0d5fe41d25dfd Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Aug 2023 15:05:13 +0800 Subject: [PATCH 43/92] refactor: exec directly not asynchnoized. --- source/dnode/vnode/src/tq/tq.c | 3 +-- source/libs/stream/src/streamExec.c | 36 ++++++----------------------- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index ddd0c49649..815e9647b5 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1274,8 +1274,7 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { pTask->tsInfo.step2Start = taosGetTimestampMs(); qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, 0.0); appendTranstateIntoInputQ(pTask); - atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - streamSchedExec(pTask); + streamTryExec(pTask); // exec directly } else { STimeWindow* pWindow = &pTask->dataRange.window; tqDebug("s-task:%s level:%d verRange:%" PRId64 " - %" PRId64 " window:%" PRId64 "-%" PRId64 diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 37c5808e02..ccfa331661 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -661,36 +661,14 @@ int32_t streamTryExec(SStreamTask* pTask) { } // todo the task should be commit here -// if (taosQueueEmpty(pTask->inputQueue->queue)) { - // fill-history WAL scan has completed -// if (pTask->status.transferState) { -// code = streamTransferStateToStreamTask(pTask); -// if (code != TSDB_CODE_SUCCESS) { -// atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); -// return code; -// } + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), + pTask->status.schedStatus); - // the schedStatus == TASK_SCHED_STATUS__ACTIVE, streamSchedExec cannot be executed, so execute once again by - // call this function (streamExecForAll) directly. - // code = streamExecForAll(pTask); - // if (code < 0) { - // do nothing - // } -// } - -// atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); -// qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, -// streamGetTaskStatusStr(pTask->status.taskStatus), pTask->status.schedStatus); -// } else { - atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), - pTask->status.schedStatus); - - if (!(taosQueueEmpty(pTask->inputQueue->queue) || streamTaskShouldStop(&pTask->status) || - streamTaskShouldPause(&pTask->status))) { - streamSchedExec(pTask); - } -// } + if (!(taosQueueEmpty(pTask->inputQueue->queue) || streamTaskShouldStop(&pTask->status) || + streamTaskShouldPause(&pTask->status))) { + streamSchedExec(pTask); + } } else { qDebug("s-task:%s already started to exec by other thread, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), pTask->status.schedStatus); From cf9f9ab4718c8420c72ea5767e097ba3c0b1c19c Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 14 Aug 2023 08:01:20 +0000 Subject: [PATCH 44/92] rebuild index at tag0 --- source/dnode/mnode/impl/src/mndIndex.c | 70 ++++++-- source/dnode/vnode/src/meta/metaQuery.c | 14 +- source/dnode/vnode/src/meta/metaTable.c | 9 +- source/libs/parser/src/parTranslater.c | 229 +++++++++++++----------- 4 files changed, 191 insertions(+), 131 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndIndex.c b/source/dnode/mnode/impl/src/mndIndex.c index 2157804559..b56ea320cc 100644 --- a/source/dnode/mnode/impl/src/mndIndex.c +++ b/source/dnode/mnode/impl/src/mndIndex.c @@ -79,9 +79,12 @@ int32_t mndInitIdx(SMnode *pMnode) { return sdbSetTable(pMnode->pSdb, table); } -static int32_t mndFindSuperTableTagId(const SStbObj *pStb, const char *tagName) { +static int32_t mndFindSuperTableTagId(const SStbObj *pStb, const char *tagName, int8_t *hasIdx) { for (int32_t tag = 0; tag < pStb->numOfTags; tag++) { if (strcasecmp(pStb->pTags[tag].name, tagName) == 0) { + if (IS_IDX_ON(&pStb->pTags[tag])) { + *hasIdx = 1; + } return tag; } } @@ -597,7 +600,8 @@ static int32_t mndSetUpdateIdxStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStb pNew->updateTime = taosGetTimestampMs(); pNew->lock = 0; - int32_t tag = mndFindSuperTableTagId(pOld, tagName); + int8_t hasIdx = 0; + int32_t tag = mndFindSuperTableTagId(pOld, tagName, &hasIdx); if (tag < 0) { terrno = TSDB_CODE_MND_TAG_NOT_EXIST; return -1; @@ -612,14 +616,14 @@ static int32_t mndSetUpdateIdxStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStb SSchema *pTag = pNew->pTags + tag; if (on == 1) { - if (IS_IDX_ON(pTag)) { + if (hasIdx && tag != 0) { terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; return -1; } else { SSCHMEA_SET_IDX_ON(pTag); } } else { - if (!IS_IDX_ON(pTag)) { + if (hasIdx == 0) { terrno = TSDB_CODE_MND_SMA_NOT_EXIST; } else { SSCHMEA_SET_IDX_OFF(pTag); @@ -667,7 +671,42 @@ _OVER: mndTransDrop(pTrans); return code; } +int8_t mndCheckIndexNameByTagName(SMnode *pMnode, SIdxObj *pIdxObj) { + // build index on first tag, and no index name; + int8_t exist = 0; + SDbObj *pDb = NULL; + if (strlen(pIdxObj->db) > 0) { + pDb = mndAcquireDb(pMnode, pIdxObj->db); + if (pDb == NULL) return 0; + } + SSmaAndTagIter *pIter = NULL; + SIdxObj *pIdx = NULL; + SSdb *pSdb = pMnode->pSdb; + while (1) { + pIter = sdbFetch(pSdb, SDB_IDX, pIter, (void **)&pIdx); + if (pIter == NULL) break; + + if (NULL != pDb && pIdx->dbUid != pDb->uid) { + sdbRelease(pSdb, pIdx); + continue; + } + if (pIdxObj->stbUid != pIdx->stbUid) { + sdbRelease(pSdb, pIdx); + continue; + } + if (strncmp(pIdxObj->colName, pIdx->colName, TSDB_COL_NAME_LEN) == 0) { + sdbRelease(pSdb, pIdx); + sdbCancelFetch(pSdb, pIdx); + exist = 1; + break; + } + sdbRelease(pSdb, pIdx); + } + + mndReleaseDb(pMnode, pDb); + return exist; +} static int32_t mndAddIndex(SMnode *pMnode, SRpcMsg *pReq, SCreateTagIndexReq *req, SDbObj *pDb, SStbObj *pStb) { int32_t code = -1; SIdxObj idxObj = {0}; @@ -681,11 +720,20 @@ static int32_t mndAddIndex(SMnode *pMnode, SRpcMsg *pReq, SCreateTagIndexReq *re idxObj.stbUid = pStb->uid; idxObj.dbUid = pStb->dbUid; - int32_t tag = mndFindSuperTableTagId(pStb, req->colName); + int8_t hasIdx = 0; + int32_t tag = mndFindSuperTableTagId(pStb, req->colName, &hasIdx); if (tag < 0) { terrno = TSDB_CODE_MND_TAG_NOT_EXIST; return -1; - } else if (tag == 0) { + } + int8_t exist = 0; + if (tag == 0 && hasIdx == 1) { + exist = mndCheckIndexNameByTagName(pMnode, &idxObj); + if (exist) { + terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; + return -1; + } + } else if (hasIdx == 1) { terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; return -1; } @@ -695,11 +743,11 @@ static int32_t mndAddIndex(SMnode *pMnode, SRpcMsg *pReq, SCreateTagIndexReq *re return -1; } - SSchema *pTag = pStb->pTags + tag; - if (IS_IDX_ON(pTag)) { - terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; - return -1; - } + // SSchema *pTag = pStb->pTags + tag; + // if (IS_IDX_ON(pTag)) { + // terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; + // return -1; + // } code = mndAddIndexImpl(pMnode, pReq, pDb, pStb, &idxObj); return code; diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index c26bb45c2b..389994ce1d 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -17,8 +17,8 @@ #include "osMemory.h" #include "tencode.h" -void _metaReaderInit(SMetaReader* pReader, void* pVnode, int32_t flags, SStoreMeta* pAPI) { - SMeta* pMeta = ((SVnode*)pVnode)->pMeta; +void _metaReaderInit(SMetaReader *pReader, void *pVnode, int32_t flags, SStoreMeta *pAPI) { + SMeta *pMeta = ((SVnode *)pVnode)->pMeta; metaReaderDoInit(pReader, pMeta, flags); pReader->pAPI = pAPI; } @@ -143,7 +143,7 @@ tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name) { int metaGetTableNameByUid(void *pVnode, uint64_t uid, char *tbName) { int code = 0; SMetaReader mr = {0}; - metaReaderDoInit(&mr, ((SVnode*)pVnode)->pMeta, 0); + metaReaderDoInit(&mr, ((SVnode *)pVnode)->pMeta, 0); code = metaReaderGetTableEntryByUid(&mr, uid); if (code < 0) { metaReaderClear(&mr); @@ -195,7 +195,7 @@ int metaGetTableUidByName(void *pVnode, char *tbName, uint64_t *uid) { int metaGetTableTypeByName(void *pVnode, char *tbName, ETableType *tbType) { int code = 0; SMetaReader mr = {0}; - metaReaderDoInit(&mr, ((SVnode*)pVnode)->pMeta, 0); + metaReaderDoInit(&mr, ((SVnode *)pVnode)->pMeta, 0); code = metaGetTableEntryByName(&mr, tbName); if (code == 0) *tbType = mr.me.type; @@ -244,7 +244,7 @@ SMTbCursor *metaOpenTbCursor(void *pVnode) { return NULL; } - SVnode* pVnodeObj = pVnode; + SVnode *pVnodeObj = pVnode; // tdbTbcMoveToFirst((TBC *)pTbCur->pDbc); pTbCur->pMeta = pVnodeObj->pMeta; pTbCur->paused = 1; @@ -1139,7 +1139,7 @@ int32_t metaFilterTtl(void *pVnode, SMetaFltParam *arg, SArray *pUids) { pCursor->type = param->type; metaRLock(pMeta); - //ret = tdbTbcOpen(pMeta->pTtlIdx, &pCursor->pCur, NULL); + // ret = tdbTbcOpen(pMeta->pTtlIdx, &pCursor->pCur, NULL); END: if (pCursor->pMeta) metaULock(pCursor->pMeta); @@ -1194,7 +1194,7 @@ int32_t metaFilterTableIds(void *pVnode, SMetaFltParam *arg, SArray *pUids) { ret = -1; for (int i = 0; i < oStbEntry.stbEntry.schemaTag.nCols; i++) { SSchema *schema = oStbEntry.stbEntry.schemaTag.pSchema + i; - if (schema->colId == param->cid && param->type == schema->type && (IS_IDX_ON(schema) || i == 0)) { + if (schema->colId == param->cid && param->type == schema->type && (IS_IDX_ON(schema))) { ret = 0; } } diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index 632e6dd872..f56837f759 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -450,12 +450,13 @@ int metaAddIndexToSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) { goto _err; } if (IS_IDX_ON(pNew) && !IS_IDX_ON(pOld)) { - if (diffIdx != -1) goto _err; + // if (diffIdx != -1) goto _err; diffIdx = i; + break; } } - if (diffIdx == -1 || diffIdx == 0) { + if (diffIdx == -1) { goto _err; } @@ -586,7 +587,7 @@ int metaDropIndexFromSTable(SMeta *pMeta, int64_t version, SDropIndexReq *pReq) for (int i = 0; i < oStbEntry.stbEntry.schemaTag.nCols; i++) { SSchema *schema = oStbEntry.stbEntry.schemaTag.pSchema + i; if (0 == strncmp(schema->name, pReq->colName, sizeof(pReq->colName))) { - if (i != 0 || IS_IDX_ON(schema)) { + if (IS_IDX_ON(schema)) { pCol = schema; } break; @@ -2094,7 +2095,7 @@ static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) { } else { for (int i = 0; i < pTagSchema->nCols; i++) { pTagColumn = &pTagSchema->pSchema[i]; - if (i != 0 && !IS_IDX_ON(pTagColumn)) continue; + if (!IS_IDX_ON(pTagColumn)) continue; STagVal tagVal = {.cid = pTagColumn->colId}; tTagGet((const STag *)pCtbEntry->ctbEntry.pTags, &tagVal); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 38118c03f8..d2dc1f3320 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -31,8 +31,8 @@ #define SYSTABLE_SHOW_TYPE_OFFSET QUERY_NODE_SHOW_DNODES_STMT typedef struct SRewriteTbNameContext { - int32_t errCode; - char* pTbName; + int32_t errCode; + char* pTbName; } SRewriteTbNameContext; typedef struct STranslateContext { @@ -54,7 +54,7 @@ typedef struct STranslateContext { bool stableQuery; bool showRewrite; SNode* pPrevRoot; - SNode* pPostRoot; + SNode* pPostRoot; } STranslateContext; typedef struct SBuildTopicContext { @@ -278,10 +278,11 @@ static const SSysTableShowAdapter sysTableShowAdapter[] = { static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode); static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode); static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal); -static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, SSelectStmt** pStmt); -static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta, SNode** pQuery); -static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery); -static int32_t setRefreshMate(STranslateContext* pCxt, SQuery* pQuery); +static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, + SSelectStmt** pStmt); +static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta, SNode** pQuery); +static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery); +static int32_t setRefreshMate(STranslateContext* pCxt, SQuery* pQuery); static bool afterGroupBy(ESqlClause clause) { return clause > SQL_CLAUSE_GROUP_BY; } @@ -772,7 +773,8 @@ static SNodeList* getProjectList(const SNode* pNode) { static bool isTimeLineQuery(SNode* pStmt) { if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) { - return (TIME_LINE_MULTI == ((SSelectStmt*)pStmt)->timeLineResMode) || (TIME_LINE_GLOBAL == ((SSelectStmt*)pStmt)->timeLineResMode); + return (TIME_LINE_MULTI == ((SSelectStmt*)pStmt)->timeLineResMode) || + (TIME_LINE_GLOBAL == ((SSelectStmt*)pStmt)->timeLineResMode); } else if (QUERY_NODE_SET_OPERATOR == nodeType(pStmt)) { return TIME_LINE_GLOBAL == ((SSetOperator*)pStmt)->timeLineResMode; } else { @@ -791,7 +793,7 @@ static bool isGlobalTimeLineQuery(SNode* pStmt) { } static bool isTimeLineAlignedQuery(SNode* pStmt) { - SSelectStmt *pSelect = (SSelectStmt *)pStmt; + SSelectStmt* pSelect = (SSelectStmt*)pStmt; if (isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) { return true; } @@ -801,7 +803,7 @@ static bool isTimeLineAlignedQuery(SNode* pStmt) { if (QUERY_NODE_SELECT_STMT != nodeType(((STempTableNode*)pSelect->pFromTable)->pSubquery)) { return false; } - SSelectStmt *pSub = (SSelectStmt *)((STempTableNode*)pSelect->pFromTable)->pSubquery; + SSelectStmt* pSub = (SSelectStmt*)((STempTableNode*)pSelect->pFromTable)->pSubquery; if (nodesListMatch(pSelect->pPartitionByList, pSub->pPartitionByList)) { return true; } @@ -822,18 +824,18 @@ static bool isPrimaryKeyImpl(SNode* pExpr) { return true; } } else if (QUERY_NODE_OPERATOR == nodeType(pExpr)) { - SOperatorNode* pOper = (SOperatorNode*)pExpr; - if (OP_TYPE_ADD != pOper->opType && OP_TYPE_SUB != pOper->opType) { - return false; - } - if (!isPrimaryKeyImpl(pOper->pLeft)) { - return false; - } - if (QUERY_NODE_VALUE != nodeType(pOper->pRight)) { - return false; - } - return true; + SOperatorNode* pOper = (SOperatorNode*)pExpr; + if (OP_TYPE_ADD != pOper->opType && OP_TYPE_SUB != pOper->opType) { + return false; } + if (!isPrimaryKeyImpl(pOper->pLeft)) { + return false; + } + if (QUERY_NODE_VALUE != nodeType(pOper->pRight)) { + return false; + } + return true; + } return false; } @@ -860,7 +862,7 @@ static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* p pCol->tableType = pTable->pMeta->tableType; pCol->colId = pColSchema->colId; pCol->colType = (tagFlag >= 0 ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN); - pCol->hasIndex = ((0 == tagFlag) || (pColSchema != NULL && IS_IDX_ON(pColSchema))); + pCol->hasIndex = (pColSchema != NULL && IS_IDX_ON(pColSchema)); pCol->node.resType.type = pColSchema->type; pCol->node.resType.bytes = pColSchema->bytes; if (TSDB_DATA_TYPE_TIMESTAMP == pCol->node.resType.type) { @@ -1406,7 +1408,7 @@ static bool isCountStar(SFunctionNode* pFunc) { } static int32_t rewriteCountStarAsCount1(STranslateContext* pCxt, SFunctionNode* pCount) { - int32_t code = TSDB_CODE_SUCCESS; + int32_t code = TSDB_CODE_SUCCESS; SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); if (NULL == pVal) { return TSDB_CODE_OUT_OF_MEMORY; @@ -1608,9 +1610,11 @@ static int32_t translateInterpFunc(STranslateContext* pCxt, SFunctionNode* pFunc return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC); } - if (pSelect->hasInterpFunc && (FUNC_RETURN_ROWS_INDEFINITE == pSelect->returnRows || pSelect->returnRows != fmGetFuncReturnRows(pFunc))) { + if (pSelect->hasInterpFunc && + (FUNC_RETURN_ROWS_INDEFINITE == pSelect->returnRows || pSelect->returnRows != fmGetFuncReturnRows(pFunc))) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC, - "%s ignoring null value options cannot be used when applying to multiple columns", pFunc->functionName); + "%s ignoring null value options cannot be used when applying to multiple columns", + pFunc->functionName); } if (NULL != pSelect->pWindow || NULL != pSelect->pGroupByList) { @@ -1648,7 +1652,8 @@ static int32_t translateTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFu } SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt; if (NULL != pSelect->pFromTable && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) && - !isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery) && !isTimeLineAlignedQuery(pCxt->pCurrStmt)) { + !isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery) && + !isTimeLineAlignedQuery(pCxt->pCurrStmt)) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC, "%s function requires valid time series input", pFunc->functionName); } @@ -1718,8 +1723,8 @@ static int32_t translateForbidSysTableFunc(STranslateContext* pCxt, SFunctionNod return TSDB_CODE_SUCCESS; } - SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt; - SNode* pTable = pSelect->pFromTable; + SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt; + SNode* pTable = pSelect->pFromTable; if (NULL != pTable && QUERY_NODE_REAL_TABLE == nodeType(pTable) && TSDB_SYSTEM_TABLE == ((SRealTableNode*)pTable)->pMeta->tableType) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED_FUNC, pFunc->functionName); @@ -2308,7 +2313,8 @@ static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) { } } if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) { - if (pSelect->selectFuncNum > 1 || pSelect->hasOtherVectorFunc || !pSelect->hasSelectFunc || (isDistinctOrderBy(pCxt) && pCxt->currClause == SQL_CLAUSE_ORDER_BY)) { + if (pSelect->selectFuncNum > 1 || pSelect->hasOtherVectorFunc || !pSelect->hasSelectFunc || + (isDistinctOrderBy(pCxt) && pCxt->currClause == SQL_CLAUSE_ORDER_BY)) { return generateDealNodeErrMsg(pCxt, getGroupByErrorCode(pCxt), ((SExprNode*)(*pNode))->userAlias); } else { return rewriteColToSelectValFunc(pCxt, pNode); @@ -2403,14 +2409,14 @@ static int32_t checkHavingGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) if (NULL != pSelect->pHaving) { code = checkExprForGroupBy(pCxt, &pSelect->pHaving); } -/* - if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pProjectionList) { - code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pProjectionList); - } - if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pOrderByList) { - code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pOrderByList); - } -*/ + /* + if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pProjectionList) { + code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pProjectionList); + } + if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pOrderByList) { + code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pOrderByList); + } + */ return code; } @@ -2669,10 +2675,10 @@ static int32_t setTableCacheLastMode(STranslateContext* pCxt, SSelectStmt* pSele static EDealRes doTranslateTbName(SNode** pNode, void* pContext) { switch (nodeType(*pNode)) { case QUERY_NODE_FUNCTION: { - SFunctionNode *pFunc = (SFunctionNode *)*pNode; + SFunctionNode* pFunc = (SFunctionNode*)*pNode; if (FUNCTION_TYPE_TBNAME == pFunc->funcType) { - SRewriteTbNameContext *pCxt = (SRewriteTbNameContext*)pContext; - SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); + SRewriteTbNameContext* pCxt = (SRewriteTbNameContext*)pContext; + SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); if (NULL == pVal) { pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; return DEAL_RES_ERROR; @@ -2711,11 +2717,12 @@ static int32_t replaceTbName(STranslateContext* pCxt, SSelectStmt* pSelect) { } SRealTableNode* pTable = (SRealTableNode*)pSelect->pFromTable; - if (TSDB_CHILD_TABLE != pTable->pMeta->tableType && TSDB_NORMAL_TABLE != pTable->pMeta->tableType && TSDB_SYSTEM_TABLE != pTable->pMeta->tableType) { + if (TSDB_CHILD_TABLE != pTable->pMeta->tableType && TSDB_NORMAL_TABLE != pTable->pMeta->tableType && + TSDB_SYSTEM_TABLE != pTable->pMeta->tableType) { return TSDB_CODE_SUCCESS; } - SNode** pNode = NULL; + SNode** pNode = NULL; SRewriteTbNameContext pRewriteCxt = {0}; pRewriteCxt.pTbName = pTable->table.tableName; @@ -3122,7 +3129,8 @@ static int32_t convertFillValue(STranslateContext* pCxt, SDataType dt, SNodeList code = scalarCalculateConstants(pCastFunc, &pCell->pNode); } if (TSDB_CODE_SUCCESS == code && QUERY_NODE_VALUE != nodeType(pCell->pNode)) { - code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Fill value can only accept constant"); + code = + generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Fill value can only accept constant"); } else if (TSDB_CODE_SUCCESS != code) { code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled data type mismatch"); } @@ -3588,7 +3596,6 @@ static int32_t createDefaultEveryNode(STranslateContext* pCxt, SNode** pOutput) pEvery->isDuration = true; pEvery->literal = taosStrdup("1s"); - *pOutput = (SNode*)pEvery; return TSDB_CODE_SUCCESS; } @@ -3683,15 +3690,15 @@ static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) { static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelect) { pCxt->currClause = SQL_CLAUSE_PARTITION_BY; int32_t code = TSDB_CODE_SUCCESS; - + if (pSelect->pPartitionByList) { int8_t typeType = getTableTypeFromTableNode(pSelect->pFromTable); SNode* pPar = nodesListGetNode(pSelect->pPartitionByList, 0); - if (!((TSDB_NORMAL_TABLE == typeType || TSDB_CHILD_TABLE == typeType) && - 1 == pSelect->pPartitionByList->length && (QUERY_NODE_FUNCTION == nodeType(pPar) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPar)->funcType))) { + if (!((TSDB_NORMAL_TABLE == typeType || TSDB_CHILD_TABLE == typeType) && 1 == pSelect->pPartitionByList->length && + (QUERY_NODE_FUNCTION == nodeType(pPar) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPar)->funcType))) { pSelect->timeLineResMode = TIME_LINE_MULTI; } - + code = translateExprList(pCxt, pSelect->pPartitionByList); } if (TSDB_CODE_SUCCESS == code) { @@ -3955,9 +3962,9 @@ static int32_t translateSetOperProject(STranslateContext* pCxt, SSetOperator* pS } snprintf(pRightExpr->aliasName, sizeof(pRightExpr->aliasName), "%s", pLeftExpr->aliasName); SNode* pProj = createSetOperProject(pSetOperator->stmtName, pLeft); - if (QUERY_NODE_COLUMN == nodeType(pLeft) && QUERY_NODE_COLUMN == nodeType(pRight) - && ((SColumnNode*)pLeft)->colId == PRIMARYKEY_TIMESTAMP_COL_ID - && ((SColumnNode*)pRight)->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + if (QUERY_NODE_COLUMN == nodeType(pLeft) && QUERY_NODE_COLUMN == nodeType(pRight) && + ((SColumnNode*)pLeft)->colId == PRIMARYKEY_TIMESTAMP_COL_ID && + ((SColumnNode*)pRight)->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { ((SColumnNode*)pProj)->colId = PRIMARYKEY_TIMESTAMP_COL_ID; } if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pSetOperator->pProjectionList, pProj)) { @@ -5737,7 +5744,6 @@ static int32_t translateRestoreDnode(STranslateContext* pCxt, SRestoreComponentN return buildCmdMsg(pCxt, TDMT_MND_RESTORE_DNODE, (FSerializeFunc)tSerializeSRestoreDnodeReq, &restoreReq); } - static int32_t getSmaIndexDstVgId(STranslateContext* pCxt, const char* pDbName, const char* pTableName, int32_t* pVgId) { SVgroupInfo vg = {0}; @@ -5865,7 +5871,7 @@ static int32_t checkCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pS } static int32_t translateCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) { - int32_t code = checkCreateSmaIndex(pCxt, pStmt); + int32_t code = checkCreateSmaIndex(pCxt, pStmt); pStmt->pReq = taosMemoryCalloc(1, sizeof(SMCreateSmaReq)); if (pStmt->pReq == NULL) code = TSDB_CODE_OUT_OF_MEMORY; if (TSDB_CODE_SUCCESS == code) { @@ -5879,13 +5885,15 @@ int32_t createIntervalFromCreateSmaIndexStmt(SCreateIndexStmt* pStmt, SInterval* pInterval->interval = ((SValueNode*)pStmt->pOptions->pInterval)->datum.i; pInterval->intervalUnit = ((SValueNode*)pStmt->pOptions->pInterval)->unit; pInterval->offset = NULL != pStmt->pOptions->pOffset ? ((SValueNode*)pStmt->pOptions->pOffset)->datum.i : 0; - pInterval->sliding = NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->datum.i : pInterval->interval; - pInterval->slidingUnit = NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->unit : pInterval->intervalUnit; + pInterval->sliding = + NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->datum.i : pInterval->interval; + pInterval->slidingUnit = + NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->unit : pInterval->intervalUnit; pInterval->precision = pStmt->pOptions->tsPrecision; return TSDB_CODE_SUCCESS; } -int32_t translatePostCreateSmaIndex(SParseContext* pParseCxt, SQuery* pQuery, void ** pResRow) { +int32_t translatePostCreateSmaIndex(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow) { int32_t code = TSDB_CODE_SUCCESS; SCreateIndexStmt* pStmt = (SCreateIndexStmt*)pQuery->pRoot; int64_t lastTs = 0; @@ -6053,7 +6061,7 @@ static int32_t buildCreateTopicReq(STranslateContext* pCxt, SCreateTopicStmt* pS toName(pCxt->pParseCxt->acctId, pStmt->subDbName, pStmt->subSTbName, &name); tNameGetFullDbName(&name, pReq->subDbName); tNameExtractFullName(&name, pReq->subStbName); - if(pStmt->pQuery != NULL) { + if (pStmt->pQuery != NULL) { code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL); } } else if ('\0' != pStmt->subDbName[0]) { @@ -6108,11 +6116,12 @@ static EDealRes checkColumnTagsInCond(SNode* pNode, void* pContext) { addTagList(&pCxt->pTags, nodesCloneNode(pNode)); } } - + return DEAL_RES_CONTINUE; } -static int32_t checkCollectTopicTags(STranslateContext* pCxt, SCreateTopicStmt* pStmt, STableMeta* pMeta, SNodeList** ppProjection) { +static int32_t checkCollectTopicTags(STranslateContext* pCxt, SCreateTopicStmt* pStmt, STableMeta* pMeta, + SNodeList** ppProjection) { SBuildTopicContext colCxt = {.colExists = false, .colNotFound = false, .pMeta = pMeta, .pTags = NULL}; nodesWalkExprPostOrder(pStmt->pWhere, checkColumnTagsInCond, &colCxt); if (colCxt.colNotFound) { @@ -6122,18 +6131,18 @@ static int32_t checkCollectTopicTags(STranslateContext* pCxt, SCreateTopicStmt* nodesDestroyList(colCxt.pTags); return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, "Columns are forbidden in where clause"); } - if (NULL == colCxt.pTags) { // put one column to select -// for (int32_t i = 0; i < pMeta->tableInfo.numOfColumns; ++i) { - SSchema* column = &pMeta->schema[0]; - SColumnNode* col = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); - if (NULL == col) { - return TSDB_CODE_OUT_OF_MEMORY; - } - strcpy(col->colName, column->name); - strcpy(col->node.aliasName, col->colName); - strcpy(col->node.userAlias, col->colName); - addTagList(&colCxt.pTags, (SNode*)col); -// } + if (NULL == colCxt.pTags) { // put one column to select + // for (int32_t i = 0; i < pMeta->tableInfo.numOfColumns; ++i) { + SSchema* column = &pMeta->schema[0]; + SColumnNode* col = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); + if (NULL == col) { + return TSDB_CODE_OUT_OF_MEMORY; + } + strcpy(col->colName, column->name); + strcpy(col->node.aliasName, col->colName); + strcpy(col->node.userAlias, col->colName); + addTagList(&colCxt.pTags, (SNode*)col); + // } } *ppProjection = colCxt.pTags; @@ -6141,13 +6150,13 @@ static int32_t checkCollectTopicTags(STranslateContext* pCxt, SCreateTopicStmt* } static int32_t buildQueryForTableTopic(STranslateContext* pCxt, SCreateTopicStmt* pStmt, SNode** pSelect) { - SParseContext* pParCxt = pCxt->pParseCxt; - SRequestConnInfo connInfo = {.pTrans = pParCxt->pTransporter, - .requestId = pParCxt->requestId, + SParseContext* pParCxt = pCxt->pParseCxt; + SRequestConnInfo connInfo = {.pTrans = pParCxt->pTransporter, + .requestId = pParCxt->requestId, .requestObjRefId = pParCxt->requestRid, .mgmtEps = pParCxt->mgmtEpSet}; - SName name; - STableMeta* pMeta = NULL; + SName name; + STableMeta* pMeta = NULL; int32_t code = getTableMetaImpl(pCxt, toName(pParCxt->acctId, pStmt->subDbName, pStmt->subSTbName, &name), &pMeta); if (code) { taosMemoryFree(pMeta); @@ -6156,7 +6165,7 @@ static int32_t buildQueryForTableTopic(STranslateContext* pCxt, SCreateTopicStmt if (TSDB_SUPER_TABLE != pMeta->tableType) { taosMemoryFree(pMeta); return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, "Only supertable table can be used"); - } + } SNodeList* pProjection = NULL; code = checkCollectTopicTags(pCxt, pStmt, pMeta, &pProjection); @@ -6554,7 +6563,8 @@ static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStm return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "SUBTABLE expression must be of VARCHAR type"); } - if (NULL != pSelect->pSubtable && 0 == LIST_LENGTH(pSelect->pPartitionByList) && subtableExprHasColumnOrPseudoColumn(pSelect->pSubtable)) { + if (NULL != pSelect->pSubtable && 0 == LIST_LENGTH(pSelect->pPartitionByList) && + subtableExprHasColumnOrPseudoColumn(pSelect->pSubtable)) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "SUBTABLE expression must not has column when no partition by clause"); } @@ -6910,28 +6920,28 @@ static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta if (NULL == col) { return TSDB_CODE_OUT_OF_MEMORY; } - + strcpy(col->tableAlias, pTable); strcpy(col->colName, pMeta->schema[0].name); SNodeList* pParamterList = nodesMakeList(); if (NULL == pParamterList) { - nodesDestroyNode((SNode *)col); + nodesDestroyNode((SNode*)col); return TSDB_CODE_OUT_OF_MEMORY; } - - int32_t code = nodesListStrictAppend(pParamterList, (SNode *)col); + + int32_t code = nodesListStrictAppend(pParamterList, (SNode*)col); if (code) { - nodesDestroyNode((SNode *)col); + nodesDestroyNode((SNode*)col); nodesDestroyList(pParamterList); return code; } - + SNode* pFunc = (SNode*)createFunction("last", pParamterList); if (NULL == pFunc) { nodesDestroyList(pParamterList); return TSDB_CODE_OUT_OF_MEMORY; } - + SNodeList* pProjectionList = nodesMakeList(); if (NULL == pProjectionList) { nodesDestroyList(pParamterList); @@ -6943,8 +6953,8 @@ static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta nodesDestroyList(pProjectionList); return code; } - - code = createSimpleSelectStmtFromProjList(pDb, pTable, pProjectionList, (SSelectStmt **)pQuery); + + code = createSimpleSelectStmtFromProjList(pDb, pTable, pProjectionList, (SSelectStmt**)pQuery); if (code) { nodesDestroyList(pProjectionList); return code; @@ -6982,14 +6992,14 @@ static int32_t buildCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt if (TSDB_CODE_SUCCESS == code && pStmt->pOptions->fillHistory) { SRealTableNode* pTable = (SRealTableNode*)(((SSelectStmt*)pStmt->pQuery)->pFromTable); code = createLastTsSelectStmt(pTable->table.dbName, pTable->table.tableName, pTable->pMeta, &pStmt->pPrevQuery); -/* - if (TSDB_CODE_SUCCESS == code) { - STranslateContext cxt = {0}; - int32_t code = initTranslateContext(pCxt->pParseCxt, pCxt->pMetaCache, &cxt); - code = translateQuery(&cxt, pStmt->pPrevQuery); - destroyTranslateContext(&cxt); - } -*/ + /* + if (TSDB_CODE_SUCCESS == code) { + STranslateContext cxt = {0}; + int32_t code = initTranslateContext(pCxt->pParseCxt, pCxt->pMetaCache, &cxt); + code = translateQuery(&cxt, pStmt->pPrevQuery); + destroyTranslateContext(&cxt); + } + */ } taosMemoryFree(pMeta); return code; @@ -7084,7 +7094,7 @@ static int32_t buildIntervalForCreateStream(SCreateStreamStmt* pStmt, SInterval* if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow)) { return code; } - + SIntervalWindowNode* pWindow = (SIntervalWindowNode*)pSelect->pWindow; pInterval->interval = ((SValueNode*)pWindow->pInterval)->datum.i; pInterval->intervalUnit = ((SValueNode*)pWindow->pInterval)->unit; @@ -7092,16 +7102,16 @@ static int32_t buildIntervalForCreateStream(SCreateStreamStmt* pStmt, SInterval* pInterval->sliding = (NULL != pWindow->pSliding ? ((SValueNode*)pWindow->pSliding)->datum.i : pInterval->interval); pInterval->slidingUnit = (NULL != pWindow->pSliding ? ((SValueNode*)pWindow->pSliding)->unit : pInterval->intervalUnit); - pInterval->precision = ((SColumnNode*)pWindow->pCol)->node.resType.precision; + pInterval->precision = ((SColumnNode*)pWindow->pCol)->node.resType.precision; return code; } int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow) { SCreateStreamStmt* pStmt = (SCreateStreamStmt*)pQuery->pRoot; - STranslateContext cxt = {0}; - SInterval interval = {0}; - int64_t lastTs = 0; + STranslateContext cxt = {0}; + SInterval interval = {0}; + int64_t lastTs = 0; int32_t code = initTranslateContext(pParseCxt, NULL, &cxt); if (TSDB_CODE_SUCCESS == code) { @@ -7136,7 +7146,6 @@ int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void return code; } - static int32_t translateDropStream(STranslateContext* pCxt, SDropStreamStmt* pStmt) { SMDropStreamReq dropReq = {0}; SName name; @@ -7261,7 +7270,7 @@ static int32_t translateGrantTagCond(STranslateContext* pCxt, SGrantStmt* pStmt, } } - int32_t code = createRealTableForGrantTable(pStmt, &pTable); + int32_t code = createRealTableForGrantTable(pStmt, &pTable); if (TSDB_CODE_SUCCESS == code) { SName name; code = getTableMetaImpl(pCxt, toName(pCxt->pParseCxt->acctId, pTable->table.dbName, pTable->table.tableName, &name), @@ -7821,7 +7830,8 @@ static SNodeList* createProjectCols(int32_t ncols, const char* const pCols[]) { return pProjections; } -static int32_t createSimpleSelectStmtImpl(const char* pDb, const char* pTable, SNodeList* pProjectionList, SSelectStmt** pStmt) { +static int32_t createSimpleSelectStmtImpl(const char* pDb, const char* pTable, SNodeList* pProjectionList, + SSelectStmt** pStmt) { SSelectStmt* pSelect = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT); if (NULL == pSelect) { return TSDB_CODE_OUT_OF_MEMORY; @@ -7844,9 +7854,8 @@ static int32_t createSimpleSelectStmtImpl(const char* pDb, const char* pTable, S return TSDB_CODE_SUCCESS; } - static int32_t createSimpleSelectStmtFromCols(const char* pDb, const char* pTable, int32_t numOfProjs, - const char* const pProjCol[], SSelectStmt** pStmt) { + const char* const pProjCol[], SSelectStmt** pStmt) { SNodeList* pProjectionList = NULL; if (numOfProjs >= 0) { pProjectionList = createProjectCols(numOfProjs, pProjCol); @@ -7858,13 +7867,15 @@ static int32_t createSimpleSelectStmtFromCols(const char* pDb, const char* pTabl return createSimpleSelectStmtImpl(pDb, pTable, pProjectionList, pStmt); } -static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, SSelectStmt** pStmt) { +static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, + SSelectStmt** pStmt) { return createSimpleSelectStmtImpl(pDb, pTable, pProjectionList, pStmt); } static int32_t createSelectStmtForShow(ENodeType showType, SSelectStmt** pStmt) { const SSysTableShowAdapter* pShow = &sysTableShowAdapter[showType - SYSTABLE_SHOW_TYPE_OFFSET]; - return createSimpleSelectStmtFromCols(pShow->pDbName, pShow->pTableName, pShow->numOfShowCols, pShow->pShowCols, pStmt); + return createSimpleSelectStmtFromCols(pShow->pDbName, pShow->pTableName, pShow->numOfShowCols, pShow->pShowCols, + pStmt); } static int32_t createSelectStmtForShowTableDist(SShowTableDistributedStmt* pStmt, SSelectStmt** pOutput) { @@ -8002,8 +8013,8 @@ static int32_t createShowTableTagsProjections(SNodeList** pProjections, SNodeLis static int32_t rewriteShowStableTags(STranslateContext* pCxt, SQuery* pQuery) { SShowTableTagsStmt* pShow = (SShowTableTagsStmt*)pQuery->pRoot; SSelectStmt* pSelect = NULL; - int32_t code = createSimpleSelectStmtFromCols(((SValueNode*)pShow->pDbName)->literal, ((SValueNode*)pShow->pTbName)->literal, - -1, NULL, &pSelect); + int32_t code = createSimpleSelectStmtFromCols(((SValueNode*)pShow->pDbName)->literal, + ((SValueNode*)pShow->pTbName)->literal, -1, NULL, &pSelect); if (TSDB_CODE_SUCCESS == code) { code = createShowTableTagsProjections(&pSelect->pProjectionList, &pShow->pTags); } From 2e6263b43f5102f108fd38ce3a14ab590d3580d8 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Aug 2023 17:16:11 +0800 Subject: [PATCH 45/92] fix(stream): fix memory leak. --- source/dnode/vnode/src/tq/tqRestore.c | 5 +++-- source/libs/stream/src/streamDispatch.c | 4 ++-- source/libs/stream/src/streamExec.c | 17 +++++++++++------ source/libs/stream/src/streamRecover.c | 1 - 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/source/dnode/vnode/src/tq/tqRestore.c b/source/dnode/vnode/src/tq/tqRestore.c index 3054179416..d363031db1 100644 --- a/source/dnode/vnode/src/tq/tqRestore.c +++ b/source/dnode/vnode/src/tq/tqRestore.c @@ -211,12 +211,13 @@ int32_t doSetOffsetForWalReader(SStreamTask *pTask, int32_t vgId) { static void checkForFillHistoryVerRange(SStreamTask* pTask, int64_t ver) { const char* id = pTask->id.idStr; + int64_t maxVer = pTask->dataRange.range.maxVer; if ((pTask->info.fillHistory == 1) && ver > pTask->dataRange.range.maxVer) { if (!pTask->status.appendTranstateBlock) { qWarn("s-task:%s fill-history scan WAL, currentVer:%" PRId64 " reach the maximum ver:%" PRId64 ", not scan wal anymore, add transfer-state block into inputQ", - id, ver, pTask->dataRange.range.maxVer); + id, ver, maxVer); double el = (taosGetTimestampMs() - pTask->tsInfo.step2Start) / 1000.0; qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, el); @@ -224,7 +225,7 @@ static void checkForFillHistoryVerRange(SStreamTask* pTask, int64_t ver) { /*int32_t code = */streamSchedExec(pTask); } else { qWarn("s-task:%s fill-history scan WAL, currentVer:%" PRId64 " reach the maximum ver:%" PRId64 ", not scan wal", - id, ver, pTask->dataRange.range.maxVer); + id, ver, maxVer); } } } diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 06861454d1..557b92baf9 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -757,10 +757,10 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i qDebug("s-task:%s dispatch transtate msg to downstream successfully, start to transfer state", id); ASSERT(pTask->info.fillHistory == 1); code = streamTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { // todo: do nothing if error happens -// atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); } + + streamFreeQitem(pTask->msgInfo.pData); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index ccfa331661..cebae0801d 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -534,16 +534,21 @@ int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock } else { streamFreeQitem((SStreamQueueItem*)pBlock); } + } else { // level == TASK_LEVEL__SINK + streamFreeQitem((SStreamQueueItem*)pBlock); } } else { // non-dispatch task, do task state transfer directly - qDebug("s-task:%s non-dispatch task, start to transfer state directly", id); - streamFreeQitem((SStreamQueueItem*)pBlock); - ASSERT(pTask->info.fillHistory == 1); - code = streamTransferStateToStreamTask(pTask); + if (level != TASK_LEVEL__SINK) { + qDebug("s-task:%s non-dispatch task, start to transfer state directly", id); + ASSERT(pTask->info.fillHistory == 1); + code = streamTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { - atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + if (code != TSDB_CODE_SUCCESS) { + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + } + } else { + qDebug("s-task:%d sink task does not transfer state", id); } } diff --git a/source/libs/stream/src/streamRecover.c b/source/libs/stream/src/streamRecover.c index c3d4d4c7ae..0a1a15259c 100644 --- a/source/libs/stream/src/streamRecover.c +++ b/source/libs/stream/src/streamRecover.c @@ -400,7 +400,6 @@ int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { } pTask->status.appendTranstateBlock = true; - qDebug("s-task:%s set sched-status:%d, prev:%d", pTask->id.idStr, TASK_SCHED_STATUS__INACTIVE, pTask->status.schedStatus); return TSDB_CODE_SUCCESS; } From 9d1e5a512d2da4c0431b85f9c854836d245ce3ee Mon Sep 17 00:00:00 2001 From: liuyao <54liuyao@163.com> Date: Thu, 10 Aug 2023 17:04:32 +0800 Subject: [PATCH 46/92] add stream task id --- include/common/tdatablock.h | 2 +- source/common/src/tdatablock.c | 6 +- source/dnode/vnode/src/tq/tqSink.c | 2 +- source/libs/executor/inc/executil.h | 2 +- source/libs/executor/src/executil.c | 6 +- source/libs/executor/src/filloperator.c | 12 ++-- source/libs/executor/src/groupoperator.c | 9 +-- source/libs/executor/src/scanoperator.c | 51 ++++----------- source/libs/executor/src/timewindowoperator.c | 63 ++++++++++--------- 9 files changed, 64 insertions(+), 89 deletions(-) diff --git a/include/common/tdatablock.h b/include/common/tdatablock.h index c0412d2617..dac723aa58 100644 --- a/include/common/tdatablock.h +++ b/include/common/tdatablock.h @@ -241,7 +241,7 @@ int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols); const char* blockDecode(SSDataBlock* pBlock, const char* pData); // for debug -char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf); +char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf, const char* taskIdStr); int32_t buildSubmitReqFromDataBlock(SSubmitReq2** pReq, const SSDataBlock* pDataBlocks, const STSchema* pTSchema, int64_t uid, int32_t vgId, tb_uid_t suid); diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 5188b1e27c..5ce763ab8f 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -1771,7 +1771,7 @@ static char* formatTimestamp(char* buf, int64_t val, int precision) { } // for debug -char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) { +char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf, const char* taskIdStr) { int32_t size = 2048*1024; *pDataBuf = taosMemoryCalloc(size, 1); char* dumpBuf = *pDataBuf; @@ -1780,9 +1780,9 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) int32_t rows = pDataBlock->info.rows; int32_t len = 0; len += snprintf(dumpBuf + len, size - len, - "===stream===%s|block type %d|child id %d|group id:%" PRIu64 "|uid:%" PRId64 + "%s===stream===%s|block type %d|child id %d|group id:%" PRIu64 "|uid:%" PRId64 "|rows:%" PRId64 "|version:%" PRIu64 "|cal start:%" PRIu64 "|cal end:%" PRIu64 "|tbl:%s\n", - flag, (int32_t)pDataBlock->info.type, pDataBlock->info.childId, pDataBlock->info.id.groupId, + taskIdStr, flag, (int32_t)pDataBlock->info.type, pDataBlock->info.childId, pDataBlock->info.id.groupId, pDataBlock->info.id.uid, pDataBlock->info.rows, pDataBlock->info.version, pDataBlock->info.calWin.skey, pDataBlock->info.calWin.ekey, pDataBlock->info.parTbName); if (len >= size - 1) return dumpBuf; diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c index b22650d249..cce31688bc 100644 --- a/source/dnode/vnode/src/tq/tqSink.c +++ b/source/dnode/vnode/src/tq/tqSink.c @@ -412,7 +412,7 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d if (k == 0) { SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, dataIndex); void* colData = colDataGetData(pColData, j); - tqTrace("tq sink pipe2, row %d, col %d ts %" PRId64, j, k, *(int64_t*)colData); + tqDebug("tq sink pipe2, row %d, col %d ts %" PRId64, j, k, *(int64_t*)colData); } if (IS_SET_NULL(pCol)) { SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type); diff --git a/source/libs/executor/inc/executil.h b/source/libs/executor/inc/executil.h index 33c9d845b9..485b4f01de 100644 --- a/source/libs/executor/inc/executil.h +++ b/source/libs/executor/inc/executil.h @@ -185,7 +185,7 @@ int32_t convertFillType(int32_t mode); int32_t resultrowComparAsc(const void* p1, const void* p2); int32_t isQualifiedTable(STableKeyInfo* info, SNode* pTagCond, void* metaHandle, bool* pQualified, SStorageAPI *pAPI); -void printDataBlock(SSDataBlock* pBlock, const char* flag); +void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr); void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order); void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery); diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index aa0c7945b0..54e86415f5 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -2178,12 +2178,12 @@ int32_t createScanTableListInfo(SScanPhysiNode* pScanNode, SNodeList* pGroupTags return TSDB_CODE_SUCCESS; } -void printDataBlock(SSDataBlock* pBlock, const char* flag) { +void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr) { if (!pBlock || pBlock->info.rows == 0) { - qDebug("===stream===%s: Block is Null or Empty", flag); + qDebug("%s===stream===%s: Block is Null or Empty", taskIdStr, flag); return; } char* pBuf = NULL; - qDebug("%s", dumpBlockData(pBlock, flag, &pBuf)); + qDebug("%s", dumpBlockData(pBlock, flag, &pBuf, taskIdStr)); taosMemoryFree(pBuf); } diff --git a/source/libs/executor/src/filloperator.c b/source/libs/executor/src/filloperator.c index 80c88a803e..ed00329aed 100644 --- a/source/libs/executor/src/filloperator.c +++ b/source/libs/executor/src/filloperator.c @@ -1292,14 +1292,14 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { (pInfo->pFillInfo->pos != FILL_POS_INVALID && pInfo->pFillInfo->needFill == true)) { doStreamFillRange(pInfo->pFillInfo, pInfo->pFillSup, pInfo->pRes); if (pInfo->pRes->info.rows > 0) { - printDataBlock(pInfo->pRes, "stream fill"); + printDataBlock(pInfo->pRes, "stream fill", GET_TASKID(pTaskInfo)); return pInfo->pRes; } } if (pOperator->status == OP_RES_TO_RETURN) { doDeleteFillFinalize(pOperator); if (pInfo->pRes->info.rows > 0) { - printDataBlock(pInfo->pRes, "stream fill"); + printDataBlock(pInfo->pRes, "stream fill", GET_TASKID(pTaskInfo)); return pInfo->pRes; } setOperatorCompleted(pOperator); @@ -1317,12 +1317,12 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { pOperator->status = OP_RES_TO_RETURN; pInfo->pFillInfo->preRowKey = INT64_MIN; if (pInfo->pRes->info.rows > 0) { - printDataBlock(pInfo->pRes, "stream fill"); + printDataBlock(pInfo->pRes, "stream fill", GET_TASKID(pTaskInfo)); return pInfo->pRes; } break; } - printDataBlock(pBlock, "stream fill recv"); + printDataBlock(pBlock, "stream fill recv", GET_TASKID(pTaskInfo)); if (pInfo->pFillInfo->curGroupId != pBlock->info.id.groupId) { pInfo->pFillInfo->curGroupId = pBlock->info.id.groupId; @@ -1339,7 +1339,7 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { pInfo->pFillSup->hasDelete = true; doDeleteFillResult(pOperator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "stream fill delete"); + printDataBlock(pInfo->pDelRes, "stream fill delete", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } continue; @@ -1378,7 +1378,7 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { } pOperator->resultInfo.totalRows += pInfo->pRes->info.rows; - printDataBlock(pInfo->pRes, "stream fill"); + printDataBlock(pInfo->pRes, "stream fill", GET_TASKID(pTaskInfo)); return pInfo->pRes; } diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c index 9228c923a6..4f0bedba3d 100644 --- a/source/libs/executor/src/groupoperator.c +++ b/source/libs/executor/src/groupoperator.c @@ -956,7 +956,8 @@ static bool hasRemainPartion(SStreamPartitionOperatorInfo* pInfo) { return pInfo static bool hasRemainTbName(SStreamPartitionOperatorInfo* pInfo) { return pInfo->pTbNameIte != NULL; } static SSDataBlock* buildStreamPartitionResult(SOperatorInfo* pOperator) { - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SStreamPartitionOperatorInfo* pInfo = pOperator->info; SSDataBlock* pDest = pInfo->binfo.pRes; @@ -994,7 +995,7 @@ static SSDataBlock* buildStreamPartitionResult(SOperatorInfo* pOperator) { pOperator->resultInfo.totalRows += pDest->info.rows; pInfo->parIte = taosHashIterate(pInfo->pPartitions, pInfo->parIte); ASSERT(pDest->info.rows > 0); - printDataBlock(pDest, "stream partitionby"); + printDataBlock(pDest, "stream partitionby", GET_TASKID(pTaskInfo)); return pDest; } @@ -1115,7 +1116,7 @@ static SSDataBlock* doStreamHashPartition(SOperatorInfo* pOperator) { setOperatorCompleted(pOperator); return NULL; } - printDataBlock(pBlock, "stream partitionby recv"); + printDataBlock(pBlock, "stream partitionby recv", GET_TASKID(pTaskInfo)); switch (pBlock->info.type) { case STREAM_NORMAL: case STREAM_PULL_DATA: @@ -1125,7 +1126,7 @@ static SSDataBlock* doStreamHashPartition(SOperatorInfo* pOperator) { case STREAM_DELETE_DATA: { copyDataBlock(pInfo->pDelRes, pBlock); pInfo->pDelRes->info.type = STREAM_DELETE_RESULT; - printDataBlock(pInfo->pDelRes, "stream partitionby delete"); + printDataBlock(pInfo->pDelRes, "stream partitionby delete", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } break; default: diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 9a836caa8c..85c9c39d11 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1343,7 +1343,7 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS if (rows == 0) { return TSDB_CODE_SUCCESS; } - + SExecTaskInfo* pTaskInfo = pInfo->pStreamScanOp->pTaskInfo; SColumnInfoData* pSrcStartTsCol = (SColumnInfoData*)taosArrayGet(pSrcBlock->pDataBlock, START_TS_COLUMN_INDEX); SColumnInfoData* pSrcEndTsCol = (SColumnInfoData*)taosArrayGet(pSrcBlock->pDataBlock, END_TS_COLUMN_INDEX); SColumnInfoData* pSrcUidCol = taosArrayGet(pSrcBlock->pDataBlock, UID_COLUMN_INDEX); @@ -1360,7 +1360,7 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS TSKEY startTs = srcStartTsCol[0]; TSKEY endTs = srcEndTsCol[0]; SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, srcUid, startTs, endTs, ver); - printDataBlock(pPreRes, "pre res"); + printDataBlock(pPreRes, "pre res", GET_TASKID(pTaskInfo)); blockDataCleanup(pSrcBlock); int32_t code = blockDataEnsureCapacity(pSrcBlock, pPreRes->info.rows); if (code != TSDB_CODE_SUCCESS) { @@ -1375,7 +1375,7 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS appendOneRowToStreamSpecialBlock(pSrcBlock, ((TSKEY*)pTsCol->pData) + i, ((TSKEY*)pTsCol->pData) + i, &srcUid, &groupId, NULL); } - printDataBlock(pSrcBlock, "new delete"); + printDataBlock(pSrcBlock, "new delete", GET_TASKID(pTaskInfo)); } uint64_t* srcGp = (uint64_t*)pSrcGpCol->pData; srcStartTsCol = (TSKEY*)pSrcStartTsCol->pData; @@ -1921,38 +1921,9 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { switch (pInfo->scanMode) { case STREAM_SCAN_FROM_RES: { pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE; - printDataBlock(pInfo->pRecoverRes, "scan recover"); + printDataBlock(pInfo->pRecoverRes, "scan recover", GET_TASKID(pTaskInfo)); return pInfo->pRecoverRes; } break; - // case STREAM_SCAN_FROM_UPDATERES: { - // generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes); - // prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex); - // pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE; - // printDataBlock(pInfo->pUpdateRes, "recover update"); - // return pInfo->pUpdateRes; - // } break; - // case STREAM_SCAN_FROM_DELETE_DATA: { - // generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes); - // prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex); - // pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE; - // copyDataBlock(pInfo->pDeleteDataRes, pInfo->pUpdateRes); - // pInfo->pDeleteDataRes->info.type = STREAM_DELETE_DATA; - // printDataBlock(pInfo->pDeleteDataRes, "recover delete"); - // return pInfo->pDeleteDataRes; - // } break; - // case STREAM_SCAN_FROM_DATAREADER_RANGE: { - // SSDataBlock* pSDB = doRangeScan(pInfo, pInfo->pUpdateRes, pInfo->primaryTsIndex, &pInfo->updateResIndex); - // if (pSDB) { - // STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info; - // pSDB->info.type = pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER_RANGE ? STREAM_NORMAL : STREAM_PULL_DATA; - // checkUpdateData(pInfo, true, pSDB, false); - // printDataBlock(pSDB, "scan recover update"); - // calBlockTbName(pInfo, pSDB); - // return pSDB; - // } - // blockDataCleanup(pInfo->pUpdateDataRes); - // pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE; - // } break; default: break; } @@ -1971,12 +1942,12 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { } if (pInfo->pCreateTbRes->info.rows > 0) { pInfo->scanMode = STREAM_SCAN_FROM_RES; - printDataBlock(pInfo->pCreateTbRes, "recover createTbl"); + printDataBlock(pInfo->pCreateTbRes, "recover createTbl", GET_TASKID(pTaskInfo)); return pInfo->pCreateTbRes; } qDebug("stream recover scan get block, rows %" PRId64, pInfo->pRecoverRes->info.rows); - printDataBlock(pInfo->pRecoverRes, "scan recover"); + printDataBlock(pInfo->pRecoverRes, "scan recover", GET_TASKID(pTaskInfo)); return pInfo->pRecoverRes; } pStreamInfo->recoverStep = STREAM_RECOVER_STEP__NONE; @@ -2032,7 +2003,7 @@ FETCH_NEXT_BLOCK: pAPI->stateStore.updateInfoAddCloseWindowSBF(pInfo->pUpdateInfo); } break; case STREAM_DELETE_DATA: { - printDataBlock(pBlock, "stream scan delete recv"); + printDataBlock(pBlock, "stream scan delete recv", GET_TASKID(pTaskInfo)); SSDataBlock* pDelBlock = NULL; if (pInfo->tqReader) { pDelBlock = createSpecialDataBlock(STREAM_DELETE_DATA); @@ -2043,7 +2014,7 @@ FETCH_NEXT_BLOCK: setBlockGroupIdByUid(pInfo, pDelBlock); rebuildDeleteBlockData(pDelBlock, &pStreamInfo->fillHistoryWindow, id); - printDataBlock(pDelBlock, "stream scan delete recv filtered"); + printDataBlock(pDelBlock, "stream scan delete recv filtered", GET_TASKID(pTaskInfo)); if (pDelBlock->info.rows == 0) { if (pInfo->tqReader) { blockDataDestroy(pDelBlock); @@ -2054,7 +2025,7 @@ FETCH_NEXT_BLOCK: if (!isIntervalWindow(pInfo) && !isSessionWindow(pInfo) && !isStateWindow(pInfo)) { generateDeleteResultBlock(pInfo, pDelBlock, pInfo->pDeleteDataRes); pInfo->pDeleteDataRes->info.type = STREAM_DELETE_RESULT; - printDataBlock(pDelBlock, "stream scan delete result"); + printDataBlock(pDelBlock, "stream scan delete result", GET_TASKID(pTaskInfo)); blockDataDestroy(pDelBlock); if (pInfo->pDeleteDataRes->info.rows > 0) { @@ -2069,7 +2040,7 @@ FETCH_NEXT_BLOCK: prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex); copyDataBlock(pInfo->pDeleteDataRes, pInfo->pUpdateRes); pInfo->pDeleteDataRes->info.type = STREAM_DELETE_DATA; - printDataBlock(pDelBlock, "stream scan delete data"); + printDataBlock(pDelBlock, "stream scan delete data", GET_TASKID(pTaskInfo)); if (pInfo->tqReader) { blockDataDestroy(pDelBlock); } @@ -2120,7 +2091,7 @@ FETCH_NEXT_BLOCK: STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info; pSDB->info.type = pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER_RANGE ? STREAM_NORMAL : STREAM_PULL_DATA; checkUpdateData(pInfo, true, pSDB, false); - printDataBlock(pSDB, "stream scan update"); + printDataBlock(pSDB, "stream scan update", GET_TASKID(pTaskInfo)); calBlockTbName(pInfo, pSDB); return pSDB; } diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 3abb4f44f4..992147ab10 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -2589,20 +2589,20 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); if (pInfo->pPullDataRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); return pInfo->pPullDataRes; } doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); if (pInfo->binfo.pRes->info.rows != 0) { - printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); return pInfo->binfo.pRes; } @@ -2633,7 +2633,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } } @@ -2670,7 +2670,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { break; } pInfo->numOfDatapack++; - printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "interval final recv" : "interval semi recv"); + printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "interval final recv" : "interval semi recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) { pInfo->binfo.pRes->info.type = pBlock->info.type; @@ -2694,7 +2694,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_CLEAR) { pInfo->pDelRes->info.type = STREAM_CLEAR; } else { @@ -2758,20 +2758,20 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); if (pInfo->pPullDataRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); return pInfo->pPullDataRes; } doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); if (pInfo->binfo.pRes->info.rows != 0) { - printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); return pInfo->binfo.pRes; } @@ -3660,18 +3660,19 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { SStreamSessionAggOperatorInfo* pInfo = pOperator->info; SOptrBasicInfo* pBInfo = &pInfo->binfo; SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; qDebug("===stream=== stream session agg"); if (pOperator->status == OP_EXEC_DONE) { return NULL; } else if (pOperator->status == OP_RES_TO_RETURN) { doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session"); + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session"); + printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); return pBInfo->pRes; } @@ -3692,7 +3693,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { if (pBlock == NULL) { break; } - printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "final session recv" : "single session recv"); + printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "final session recv" : "single session recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || pBlock->info.type == STREAM_CLEAR) { @@ -3770,13 +3771,13 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session"); + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session"); + printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); return pBInfo->pRes; } @@ -3950,6 +3951,7 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { TSKEY maxTs = INT64_MIN; SExprSupp* pSup = &pOperator->exprSupp; SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; qDebug("===stream=== stream session semi agg"); if (pOperator->status == OP_EXEC_DONE) { @@ -3959,13 +3961,13 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { { doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "semi session"); + printDataBlock(pBInfo->pRes, "semi session", GET_TASKID(pTaskInfo)); return pBInfo->pRes; } doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "semi session delete"); + printDataBlock(pInfo->pDelRes, "semi session delete", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } @@ -3993,7 +3995,7 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { pOperator->status = OP_RES_TO_RETURN; break; } - printDataBlock(pBlock, "semi session recv"); + printDataBlock(pBlock, "semi session recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || pBlock->info.type == STREAM_CLEAR) { @@ -4042,13 +4044,13 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "semi session"); + printDataBlock(pBInfo->pRes, "semi session", GET_TASKID(pTaskInfo)); return pBInfo->pRes; } doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "semi session delete"); + printDataBlock(pInfo->pDelRes, "semi session delete", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } @@ -4341,17 +4343,18 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { SExprSupp* pSup = &pOperator->exprSupp; SStreamStateAggOperatorInfo* pInfo = pOperator->info; SOptrBasicInfo* pBInfo = &pInfo->binfo; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; qDebug("===stream=== stream state agg"); if (pOperator->status == OP_RES_TO_RETURN) { doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single state delete"); + printDataBlock(pInfo->pDelRes, "single state delete", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "single state"); + printDataBlock(pBInfo->pRes, "single state", GET_TASKID(pTaskInfo)); return pBInfo->pRes; } @@ -4372,7 +4375,7 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { if (pBlock == NULL) { break; } - printDataBlock(pBlock, "single state recv"); + printDataBlock(pBlock, "single state recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || pBlock->info.type == STREAM_CLEAR) { @@ -4425,13 +4428,13 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single state delete"); + printDataBlock(pInfo->pDelRes, "single state delete", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "single state"); + printDataBlock(pBInfo->pRes, "single state", GET_TASKID(pTaskInfo)); return pBInfo->pRes; } setOperatorCompleted(pOperator); @@ -5211,13 +5214,13 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { if (pOperator->status == OP_RES_TO_RETURN) { doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval delete"); + printDataBlock(pInfo->pDelRes, "single interval delete", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); if (pInfo->binfo.pRes->info.rows > 0) { - printDataBlock(pInfo->binfo.pRes, "single interval"); + printDataBlock(pInfo->binfo.pRes, "single interval", GET_TASKID(pTaskInfo)); return pInfo->binfo.pRes; } @@ -5257,7 +5260,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { } pInfo->numOfDatapack++; - printDataBlock(pBlock, "single interval recv"); + printDataBlock(pBlock, "single interval recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || pBlock->info.type == STREAM_CLEAR) { @@ -5269,7 +5272,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); continue; } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - printDataBlock(pBlock, "single interval"); + printDataBlock(pBlock, "single interval", GET_TASKID(pTaskInfo)); return pBlock; } else { ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); @@ -5323,13 +5326,13 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval delete"); + printDataBlock(pInfo->pDelRes, "single interval delete", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); if (pInfo->binfo.pRes->info.rows > 0) { - printDataBlock(pInfo->binfo.pRes, "single interval"); + printDataBlock(pInfo->binfo.pRes, "single interval", GET_TASKID(pTaskInfo)); return pInfo->binfo.pRes; } From 57a020edfca72a9e105832c88fb511b911f32d0f Mon Sep 17 00:00:00 2001 From: liuyao <54liuyao@163.com> Date: Mon, 14 Aug 2023 14:24:21 +0800 Subject: [PATCH 47/92] refact stream interval --- source/libs/executor/inc/executil.h | 3 + source/libs/executor/inc/executorInt.h | 7 + .../libs/executor/src/eventwindowoperator.c | 12 +- source/libs/executor/src/executil.c | 11 + source/libs/executor/src/executorInt.c | 12 + .../executor/src/streamtimewindowoperator.c | 3232 ++++++++++++++++ source/libs/executor/src/timewindowoperator.c | 3272 +---------------- 7 files changed, 3267 insertions(+), 3282 deletions(-) create mode 100644 source/libs/executor/src/streamtimewindowoperator.c diff --git a/source/libs/executor/inc/executil.h b/source/libs/executor/inc/executil.h index 485b4f01de..3339772b1c 100644 --- a/source/libs/executor/inc/executil.h +++ b/source/libs/executor/inc/executil.h @@ -190,4 +190,7 @@ void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order); void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery); +TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols); +void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, int64_t delta); + #endif // TDENGINE_EXECUTIL_H diff --git a/source/libs/executor/inc/executorInt.h b/source/libs/executor/inc/executorInt.h index fbca5e29f9..bd5d8e76ab 100644 --- a/source/libs/executor/inc/executorInt.h +++ b/source/libs/executor/inc/executorInt.h @@ -695,6 +695,13 @@ uint64_t calcGroupId(char* pData, int32_t len); void streamOpReleaseState(struct SOperatorInfo* pOperator); void streamOpReloadState(struct SOperatorInfo* pOperator); +bool inSlidingWindow(SInterval* pInterval, STimeWindow* pWin, SDataBlockInfo* pBlockInfo); +bool inCalSlidingWindow(SInterval* pInterval, STimeWindow* pWin, TSKEY calStart, TSKEY calEnd, EStreamType blockType); +bool compareVal(const char* v, const SStateKeys* pKey); + +int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, + TSKEY* primaryKeys, int32_t prevPosition, int32_t order); + #ifdef __cplusplus } #endif diff --git a/source/libs/executor/src/eventwindowoperator.c b/source/libs/executor/src/eventwindowoperator.c index bbdc50183e..5c335c116f 100644 --- a/source/libs/executor/src/eventwindowoperator.c +++ b/source/libs/executor/src/eventwindowoperator.c @@ -58,16 +58,6 @@ static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts, uint64_t groupId) { pRowSup->groupId = groupId; } -static void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, bool includeEndpoint) { - int64_t* ts = (int64_t*)pColData->pData; - int32_t delta = includeEndpoint ? 1 : 0; - - int64_t duration = pWin->ekey - pWin->skey + delta; - ts[2] = duration; // set the duration - ts[3] = pWin->skey; // window start key - ts[4] = pWin->ekey + delta; // window end key -} - SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo) { SEventWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SEventWindowOperatorInfo)); @@ -250,7 +240,7 @@ static void doEventWindowAggImpl(SEventWindowOperatorInfo* pInfo, SExprSupp* pSu T_LONG_JMP(pTaskInfo->env, TSDB_CODE_APP_ERROR); } - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false); + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, 0); applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, startIndex, numOfRows, pBlock->info.rows, numOfOutput); } diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 54e86415f5..8e0569e0f5 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -2187,3 +2187,14 @@ void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr qDebug("%s", dumpBlockData(pBlock, flag, &pBuf, taskIdStr)); taosMemoryFree(pBuf); } + +TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols) { return tsCols == NULL ? win->skey : tsCols[0]; } + +void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, int64_t delta) { + int64_t* ts = (int64_t*)pColData->pData; + + int64_t duration = pWin->ekey - pWin->skey + delta; + ts[2] = duration; // set the duration + ts[3] = pWin->skey; // window start key + ts[4] = pWin->ekey + delta; // window end key +} diff --git a/source/libs/executor/src/executorInt.c b/source/libs/executor/src/executorInt.c index ebec9aa94e..a7f0e02815 100644 --- a/source/libs/executor/src/executorInt.c +++ b/source/libs/executor/src/executorInt.c @@ -1070,3 +1070,15 @@ void streamOpReloadState(SOperatorInfo* pOperator) { downstream->fpSet.reloadStreamStateFn(downstream); } } + +bool compareVal(const char* v, const SStateKeys* pKey) { + if (IS_VAR_DATA_TYPE(pKey->type)) { + if (varDataLen(v) != varDataLen(pKey->pData)) { + return false; + } else { + return memcmp(varDataVal(v), varDataVal(pKey->pData), varDataLen(v)) == 0; + } + } else { + return memcmp(pKey->pData, v, pKey->bytes) == 0; + } +} diff --git a/source/libs/executor/src/streamtimewindowoperator.c b/source/libs/executor/src/streamtimewindowoperator.c new file mode 100644 index 0000000000..3849104b27 --- /dev/null +++ b/source/libs/executor/src/streamtimewindowoperator.c @@ -0,0 +1,3232 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#include "executorInt.h" +#include "filter.h" +#include "function.h" +#include "functionMgt.h" +#include "operator.h" +#include "querytask.h" +#include "tcommon.h" +#include "tcompare.h" +#include "tdatablock.h" +#include "tfill.h" +#include "tglobal.h" +#include "tlog.h" +#include "ttime.h" + +#define IS_FINAL_OP(op) ((op)->isFinal) +#define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL); +#define STREAM_INTERVAL_OP_STATE_NAME "StreamIntervalHistoryState" +#define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState" +#define STREAM_STATE_OP_STATE_NAME "StreamStateHistoryState" + +typedef struct SStateWindowInfo { + SResultWindowInfo winInfo; + SStateKeys* pStateKey; +} SStateWindowInfo; + +typedef struct SPullWindowInfo { + STimeWindow window; + uint64_t groupId; + STimeWindow calWin; +} SPullWindowInfo; + +typedef int32_t (*__compare_fn_t)(void* pKey, void* data, int32_t index); + +static int32_t binarySearchCom(void* keyList, int num, void* pKey, int order, __compare_fn_t comparefn) { + int firstPos = 0, lastPos = num - 1, midPos = -1; + int numOfRows = 0; + + if (num <= 0) return -1; + if (order == TSDB_ORDER_DESC) { + // find the first position which is smaller or equal than the key + while (1) { + if (comparefn(pKey, keyList, lastPos) >= 0) return lastPos; + if (comparefn(pKey, keyList, firstPos) == 0) return firstPos; + if (comparefn(pKey, keyList, firstPos) < 0) return firstPos - 1; + + numOfRows = lastPos - firstPos + 1; + midPos = (numOfRows >> 1) + firstPos; + + if (comparefn(pKey, keyList, midPos) < 0) { + lastPos = midPos - 1; + } else if (comparefn(pKey, keyList, midPos) > 0) { + firstPos = midPos + 1; + } else { + break; + } + } + + } else { + // find the first position which is bigger or equal than the key + while (1) { + if (comparefn(pKey, keyList, firstPos) <= 0) return firstPos; + if (comparefn(pKey, keyList, lastPos) == 0) return lastPos; + + if (comparefn(pKey, keyList, lastPos) > 0) { + lastPos = lastPos + 1; + if (lastPos >= num) + return -1; + else + return lastPos; + } + + numOfRows = lastPos - firstPos + 1; + midPos = (numOfRows >> 1) + firstPos; + + if (comparefn(pKey, keyList, midPos) < 0) { + lastPos = midPos - 1; + } else if (comparefn(pKey, keyList, midPos) > 0) { + firstPos = midPos + 1; + } else { + break; + } + } + } + + return midPos; +} + +static int32_t comparePullWinKey(void* pKey, void* data, int32_t index) { + SArray* res = (SArray*)data; + SPullWindowInfo* pos = taosArrayGet(res, index); + SPullWindowInfo* pData = (SPullWindowInfo*)pKey; + if (pData->groupId > pos->groupId) { + return 1; + } else if (pData->groupId < pos->groupId) { + return -1; + } + + if (pData->window.skey > pos->window.ekey) { + return 1; + } else if (pData->window.ekey < pos->window.skey) { + return -1; + } + return 0; +} + +static int32_t savePullWindow(SPullWindowInfo* pPullInfo, SArray* pPullWins) { + int32_t size = taosArrayGetSize(pPullWins); + int32_t index = binarySearchCom(pPullWins, size, pPullInfo, TSDB_ORDER_DESC, comparePullWinKey); + if (index == -1) { + index = 0; + } else { + int32_t code = comparePullWinKey(pPullInfo, pPullWins, index); + if (code == 0) { + SPullWindowInfo* pos = taosArrayGet(pPullWins, index); + pos->window.skey = TMIN(pos->window.skey, pPullInfo->window.skey); + pos->window.ekey = TMAX(pos->window.ekey, pPullInfo->window.ekey); + pos->calWin.skey = TMIN(pos->calWin.skey, pPullInfo->calWin.skey); + pos->calWin.ekey = TMAX(pos->calWin.ekey, pPullInfo->calWin.ekey); + return TSDB_CODE_SUCCESS; + } else if (code > 0) { + index++; + } + } + if (taosArrayInsert(pPullWins, index, pPullInfo) == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + return TSDB_CODE_SUCCESS; +} + +static int32_t saveResult(SResultWindowInfo winInfo, SSHashObj* pStUpdated) { + winInfo.sessionWin.win.ekey = winInfo.sessionWin.win.skey; + return tSimpleHashPut(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); +} + +static int32_t saveWinResult(SWinKey* pKey, SRowBuffPos* pPos, SSHashObj* pUpdatedMap) { + tSimpleHashPut(pUpdatedMap, pKey, sizeof(SWinKey), &pPos, POINTER_BYTES); + return TSDB_CODE_SUCCESS; +} + +static int32_t saveWinResultInfo(TSKEY ts, uint64_t groupId, SRowBuffPos* pPos, SSHashObj* pUpdatedMap) { + SWinKey key = {.ts = ts, .groupId = groupId}; + saveWinResult(&key, pPos, pUpdatedMap); + return TSDB_CODE_SUCCESS; +} + +static void removeResults(SArray* pWins, SSHashObj* pUpdatedMap) { + int32_t size = taosArrayGetSize(pWins); + for (int32_t i = 0; i < size; i++) { + SWinKey* pW = taosArrayGet(pWins, i); + void* tmp = tSimpleHashGet(pUpdatedMap, pW, sizeof(SWinKey)); + if (tmp) { + void* value = *(void**)tmp; + taosMemoryFree(value); + tSimpleHashRemove(pUpdatedMap, pW, sizeof(SWinKey)); + } + } +} + +static int32_t compareWinKey(void* pKey, void* data, int32_t index) { + void* pDataPos = taosArrayGet((SArray*)data, index); + return winKeyCmprImpl(pKey, pDataPos); +} + +static void removeDeleteResults(SSHashObj* pUpdatedMap, SArray* pDelWins) { + taosArraySort(pDelWins, winKeyCmprImpl); + taosArrayRemoveDuplicate(pDelWins, winKeyCmprImpl, NULL); + int32_t delSize = taosArrayGetSize(pDelWins); + if (tSimpleHashGetSize(pUpdatedMap) == 0 || delSize == 0) { + return; + } + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pUpdatedMap, pIte, &iter)) != NULL) { + SWinKey* pResKey = tSimpleHashGetKey(pIte, NULL); + int32_t index = binarySearchCom(pDelWins, delSize, pResKey, TSDB_ORDER_DESC, compareWinKey); + if (index >= 0 && 0 == compareWinKey(pResKey, pDelWins, index)) { + taosArrayRemove(pDelWins, index); + delSize = taosArrayGetSize(pDelWins); + } + } +} + +bool isOverdue(TSKEY ekey, STimeWindowAggSupp* pTwSup) { + ASSERTS(pTwSup->maxTs == INT64_MIN || pTwSup->maxTs > 0, "maxts should greater than 0"); + return pTwSup->maxTs != INT64_MIN && ekey < pTwSup->maxTs - pTwSup->waterMark; +} + +bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pTwSup) { return isOverdue(pWin->ekey, pTwSup); } + +static bool doDeleteWindow(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId) { + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SWinKey key = {.ts = ts, .groupId = groupId}; + tSimpleHashRemove(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey)); + pAPI->stateStore.streamStateDel(pInfo->pState, &key); + return true; +} + +static int32_t getChildIndex(SSDataBlock* pBlock) { return pBlock->info.childId; } + +static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDataBlock* pBlock, SArray* pUpWins, + SSHashObj* pUpdatedMap) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + TSKEY* startTsCols = (TSKEY*)pStartTsCol->pData; + SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + TSKEY* endTsCols = (TSKEY*)pEndTsCol->pData; + SColumnInfoData* pCalStTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + TSKEY* calStTsCols = (TSKEY*)pCalStTsCol->pData; + SColumnInfoData* pCalEnTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + TSKEY* calEnTsCols = (TSKEY*)pCalEnTsCol->pData; + SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* pGpDatas = (uint64_t*)pGpCol->pData; + for (int32_t i = 0; i < pBlock->info.rows; i++) { + SResultRowInfo dumyInfo = {0}; + dumyInfo.cur.pageId = -1; + + STimeWindow win = {0}; + if (IS_FINAL_OP(pInfo)) { + win.skey = startTsCols[i]; + win.ekey = endTsCols[i]; + } else { + win = getActiveTimeWindow(NULL, &dumyInfo, startTsCols[i], pInterval, TSDB_ORDER_ASC); + } + + do { + if (!inCalSlidingWindow(pInterval, &win, calStTsCols[i], calEnTsCols[i], pBlock->info.type)) { + getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); + continue; + } + uint64_t winGpId = pGpDatas[i]; + SWinKey winRes = {.ts = win.skey, .groupId = winGpId}; + void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey)); + if (chIds) { + int32_t childId = getChildIndex(pBlock); + SArray* chArray = *(void**)chIds; + int32_t index = taosArraySearchIdx(chArray, &childId, compareInt32Val, TD_EQ); + if (index != -1) { + qDebug("===stream===try push delete window%" PRId64 "chId:%d ,continue", win.skey, childId); + getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); + continue; + } + } + bool res = doDeleteWindow(pOperator, win.skey, winGpId); + if (pUpWins && res) { + taosArrayPush(pUpWins, &winRes); + } + if (pUpdatedMap) { + tSimpleHashRemove(pUpdatedMap, &winRes, sizeof(SWinKey)); + } + getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); + } while (win.ekey <= endTsCols[i]); + } +} + +static int32_t getAllIntervalWindow(SSHashObj* pHashMap, SSHashObj* resWins) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { + SWinKey* pKey = tSimpleHashGetKey(pIte, NULL); + uint64_t groupId = pKey->groupId; + TSKEY ts = pKey->ts; + int32_t code = saveWinResultInfo(ts, groupId, *(SRowBuffPos**)pIte, resWins); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + return TSDB_CODE_SUCCESS; +} + +static int32_t closeStreamIntervalWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SInterval* pInterval, + SHashObj* pPullDataMap, SSHashObj* closeWins, SArray* pDelWins, + SOperatorInfo* pOperator) { + qDebug("===stream===close interval window"); + void* pIte = NULL; + int32_t iter = 0; + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + int32_t delSize = taosArrayGetSize(pDelWins); + while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { + void* key = tSimpleHashGetKey(pIte, NULL); + SWinKey* pWinKey = (SWinKey*)key; + if (delSize > 0) { + int32_t index = binarySearchCom(pDelWins, delSize, pWinKey, TSDB_ORDER_DESC, compareWinKey); + if (index >= 0 && 0 == compareWinKey(pWinKey, pDelWins, index)) { + taosArrayRemove(pDelWins, index); + delSize = taosArrayGetSize(pDelWins); + } + } + + void* chIds = taosHashGet(pPullDataMap, pWinKey, sizeof(SWinKey)); + STimeWindow win = { + .skey = pWinKey->ts, + .ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1, + }; + if (isCloseWindow(&win, pTwSup)) { + if (chIds && pPullDataMap) { + SArray* chAy = *(SArray**)chIds; + int32_t size = taosArrayGetSize(chAy); + qDebug("===stream===window %" PRId64 " wait child size:%d", pWinKey->ts, size); + for (int32_t i = 0; i < size; i++) { + qDebug("===stream===window %" PRId64 " wait child id:%d", pWinKey->ts, *(int32_t*)taosArrayGet(chAy, i)); + } + continue; + } else if (pPullDataMap) { + qDebug("===stream===close window %" PRId64, pWinKey->ts); + } + + if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + int32_t code = saveWinResult(pWinKey, *(SRowBuffPos**)pIte, closeWins); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + tSimpleHashIterateRemove(pHashMap, pWinKey, sizeof(SWinKey), &pIte, &iter); + } + } + return TSDB_CODE_SUCCESS; +} + +STimeWindow getFinalTimeWindow(int64_t ts, SInterval* pInterval) { + STimeWindow w = {.skey = ts, .ekey = INT64_MAX}; + w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1; + return w; +} + +static void doBuildDeleteResult(SStreamIntervalOperatorInfo* pInfo, SArray* pWins, int32_t* index, + SSDataBlock* pBlock) { + blockDataCleanup(pBlock); + int32_t size = taosArrayGetSize(pWins); + if (*index == size) { + *index = 0; + taosArrayClear(pWins); + return; + } + blockDataEnsureCapacity(pBlock, size - *index); + uint64_t uid = 0; + for (int32_t i = *index; i < size; i++) { + SWinKey* pWin = taosArrayGet(pWins, i); + void* tbname = NULL; + pInfo->statestore.streamStateGetParName(pInfo->pState, pWin->groupId, &tbname); + if (tbname == NULL) { + appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, NULL); + } else { + char parTbName[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN]; + STR_WITH_MAXSIZE_TO_VARSTR(parTbName, tbname, sizeof(parTbName)); + appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, parTbName); + } + pInfo->statestore.streamStateFreeVal(tbname); + (*index)++; + } +} + +void destroyStreamFinalIntervalOperatorInfo(void* param) { + SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)param; + cleanupBasicInfo(&pInfo->binfo); + cleanupAggSup(&pInfo->aggSup); + // it should be empty. + void* pIte = NULL; + while ((pIte = taosHashIterate(pInfo->pPullDataMap, pIte)) != NULL) { + taosArrayDestroy(*(void**)pIte); + } + taosHashCleanup(pInfo->pPullDataMap); + taosHashCleanup(pInfo->pFinalPullDataMap); + taosArrayDestroy(pInfo->pPullWins); + blockDataDestroy(pInfo->pPullDataRes); + taosArrayDestroy(pInfo->pDelWins); + blockDataDestroy(pInfo->pDelRes); + pInfo->statestore.streamFileStateDestroy(pInfo->pState->pFileState); + taosMemoryFreeClear(pInfo->pState); + + nodesDestroyNode((SNode*)pInfo->pPhyNode); + colDataDestroy(&pInfo->twAggSup.timeWindowData); + pInfo->groupResInfo.pRows = taosArrayDestroy(pInfo->groupResInfo.pRows); + cleanupExprSupp(&pInfo->scalarSupp); + tSimpleHashCleanup(pInfo->pUpdatedMap); + pInfo->pUpdatedMap = NULL; + pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated); + + taosMemoryFreeClear(param); +} + +static bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) { + for (int32_t i = 0; i < numOfCols; i++) { + if (fmIsUserDefinedFunc(pFCtx[i].functionId) || !fmIsInvertible(pFCtx[i].functionId)) { + return false; + } + } + return true; +} + +void initIntervalDownStream(SOperatorInfo* downstream, uint16_t type, SStreamIntervalOperatorInfo* pInfo) { + SStateStore* pAPI = &downstream->pTaskInfo->storageAPI.stateStore; + + if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { + initIntervalDownStream(downstream->pDownstream[0], type, pInfo); + return; + } + + SStreamScanInfo* pScanInfo = downstream->info; + pScanInfo->windowSup.parentType = type; + pScanInfo->windowSup.pIntervalAggSup = &pInfo->aggSup; + if (!pScanInfo->pUpdateInfo) { + pScanInfo->pUpdateInfo = pAPI->updateInfoInitP(&pInfo->interval, pInfo->twAggSup.waterMark); + } + + pScanInfo->interval = pInfo->interval; + pScanInfo->twAggSup = pInfo->twAggSup; + pScanInfo->pState = pInfo->pState; +} + +void compactFunctions(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx, int32_t numOfOutput, + SExecTaskInfo* pTaskInfo, SColumnInfoData* pTimeWindowData) { + for (int32_t k = 0; k < numOfOutput; ++k) { + if (fmIsWindowPseudoColumnFunc(pDestCtx[k].functionId)) { + if (!pTimeWindowData) { + continue; + } + + SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pDestCtx[k]); + char* p = GET_ROWCELL_INTERBUF(pEntryInfo); + SColumnInfoData idata = {0}; + idata.info.type = TSDB_DATA_TYPE_BIGINT; + idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; + idata.pData = p; + + SScalarParam out = {.columnData = &idata}; + SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData}; + pDestCtx[k].sfp.process(&tw, 1, &out); + pEntryInfo->numOfRes = 1; + } else if (functionNeedToExecute(&pDestCtx[k]) && pDestCtx[k].fpSet.combine != NULL) { + int32_t code = pDestCtx[k].fpSet.combine(&pDestCtx[k], &pSourceCtx[k]); + if (code != TSDB_CODE_SUCCESS) { + qError("%s apply combine functions error, code: %s", GET_TASKID(pTaskInfo), tstrerror(code)); + } + } else if (pDestCtx[k].fpSet.combine == NULL) { + char* funName = fmGetFuncName(pDestCtx[k].functionId); + qError("%s error, combine funcion for %s is not implemented", GET_TASKID(pTaskInfo), funName); + taosMemoryFreeClear(funName); + } + } +} + +bool hasIntervalWindow(void* pState, SWinKey* pKey, SStateStore* pStore) { return pStore->streamStateCheck(pState, pKey); } + +int32_t setIntervalOutputBuf(void* pState, STimeWindow* win, SRowBuffPos** pResult, int64_t groupId, + SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, + SAggSupporter* pAggSup, SStateStore* pStore) { + + SWinKey key = { .ts = win->skey, .groupId = groupId }; + char* value = NULL; + int32_t size = pAggSup->resultRowSize; + + if (pStore->streamStateAddIfNotExist(pState, &key, (void**)&value, &size) < 0) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + *pResult = (SRowBuffPos*)value; + SResultRow* res = (SResultRow*)((*pResult)->pRowBuff); + + // set time window for current result + res->win = (*win); + setResultRowInitCtx(res, pCtx, numOfOutput, rowEntryInfoOffset); + return TSDB_CODE_SUCCESS; +} + +bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, void* pState, STimeWindowAggSupp* pTwSup, SStateStore* pStore) { + if (pTwSup->maxTs != INT64_MIN && pWin->ekey < pTwSup->maxTs - pTwSup->deleteMark) { + SWinKey key = {.ts = pWin->skey, .groupId = groupId}; + if (!hasIntervalWindow(pState, &key, pStore)) { + return true; + } + return false; + } + return false; +} + +int32_t getNexWindowPos(SInterval* pInterval, SDataBlockInfo* pBlockInfo, TSKEY* tsCols, int32_t startPos, TSKEY eKey, + STimeWindow* pNextWin) { + int32_t forwardRows = + getNumOfRowsInTimeWindow(pBlockInfo, tsCols, startPos, eKey, binarySearchForKey, NULL, TSDB_ORDER_ASC); + int32_t prevEndPos = forwardRows - 1 + startPos; + return getNextQualifiedWindow(pInterval, pNextWin, pBlockInfo, tsCols, prevEndPos, TSDB_ORDER_ASC); +} + +void addPullWindow(SHashObj* pMap, SWinKey* pWinRes, int32_t size) { + SArray* childIds = taosArrayInit(8, sizeof(int32_t)); + for (int32_t i = 0; i < size; i++) { + taosArrayPush(childIds, &i); + } + taosHashPut(pMap, pWinRes, sizeof(SWinKey), &childIds, sizeof(void*)); +} + +static void clearStreamIntervalOperator(SStreamIntervalOperatorInfo* pInfo) { + tSimpleHashClear(pInfo->aggSup.pResultRowHashTable); + clearDiskbasedBuf(pInfo->aggSup.pResultBuf); + initResultRowInfo(&pInfo->binfo.resultRowInfo); + pInfo->aggSup.currentPageId = -1; + pInfo->statestore.streamStateClear(pInfo->pState); +} + +static void clearSpecialDataBlock(SSDataBlock* pBlock) { + if (pBlock->info.rows <= 0) { + return; + } + blockDataCleanup(pBlock); +} + +static void doBuildPullDataBlock(SArray* array, int32_t* pIndex, SSDataBlock* pBlock) { + clearSpecialDataBlock(pBlock); + int32_t size = taosArrayGetSize(array); + if (size - (*pIndex) == 0) { + return; + } + blockDataEnsureCapacity(pBlock, size - (*pIndex)); + SColumnInfoData* pStartTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + SColumnInfoData* pEndTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + SColumnInfoData* pGroupId = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + SColumnInfoData* pCalStartTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + SColumnInfoData* pCalEndTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + for (; (*pIndex) < size; (*pIndex)++) { + SPullWindowInfo* pWin = taosArrayGet(array, (*pIndex)); + colDataSetVal(pStartTs, pBlock->info.rows, (const char*)&pWin->window.skey, false); + colDataSetVal(pEndTs, pBlock->info.rows, (const char*)&pWin->window.ekey, false); + colDataSetVal(pGroupId, pBlock->info.rows, (const char*)&pWin->groupId, false); + colDataSetVal(pCalStartTs, pBlock->info.rows, (const char*)&pWin->calWin.skey, false); + colDataSetVal(pCalEndTs, pBlock->info.rows, (const char*)&pWin->calWin.ekey, false); + pBlock->info.rows++; + } + if ((*pIndex) == size) { + *pIndex = 0; + taosArrayClear(array); + } + blockDataUpdateTsWindow(pBlock, 0); +} + +void processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pFinalMap, SInterval* pInterval, SArray* pPullWins, int32_t numOfCh, SOperatorInfo* pOperator) { + SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + TSKEY* tsData = (TSKEY*)pStartCol->pData; + SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + TSKEY* tsEndData = (TSKEY*)pEndCol->pData; + SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* groupIdData = (uint64_t*)pGroupCol->pData; + int32_t chId = getChildIndex(pBlock); + for (int32_t i = 0; i < pBlock->info.rows; i++) { + TSKEY winTs = tsData[i]; + while (winTs <= tsEndData[i]) { + SWinKey winRes = {.ts = winTs, .groupId = groupIdData[i]}; + void* chIds = taosHashGet(pMap, &winRes, sizeof(SWinKey)); + if (chIds) { + SArray* chArray = *(SArray**)chIds; + int32_t index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ); + if (index != -1) { + qDebug("===stream===retrive window %" PRId64 " delete child id %d", winRes.ts, chId); + taosArrayRemove(chArray, index); + if (taosArrayGetSize(chArray) == 0) { + // pull data is over + taosArrayDestroy(chArray); + taosHashRemove(pMap, &winRes, sizeof(SWinKey)); + qDebug("===stream===retrive pull data over.window %" PRId64 , winRes.ts); + + void* pFinalCh = taosHashGet(pFinalMap, &winRes, sizeof(SWinKey)); + if (pFinalCh) { + taosHashRemove(pFinalMap, &winRes, sizeof(SWinKey)); + doDeleteWindow(pOperator, winRes.ts, winRes.groupId); + STimeWindow nextWin = getFinalTimeWindow(winRes.ts, pInterval); + SPullWindowInfo pull = {.window = nextWin, + .groupId = winRes.groupId, + .calWin.skey = nextWin.skey, + .calWin.ekey = nextWin.skey}; + // add pull data request + if (savePullWindow(&pull, pPullWins) == TSDB_CODE_SUCCESS) { + addPullWindow(pMap, &winRes, numOfCh); + qDebug("===stream===prepare final retrive for delete %" PRId64 ", size:%d", winRes.ts, numOfCh); + } + } + } + } + } + winTs = taosTimeAdd(winTs, pInterval->sliding, pInterval->slidingUnit, pInterval->precision); + } + } +} + +static void addRetriveWindow(SArray* wins, SStreamIntervalOperatorInfo* pInfo, int32_t childId) { + int32_t size = taosArrayGetSize(wins); + for (int32_t i = 0; i < size; i++) { + SWinKey* winKey = taosArrayGet(wins, i); + STimeWindow nextWin = getFinalTimeWindow(winKey->ts, &pInfo->interval); + if (isOverdue(nextWin.ekey, &pInfo->twAggSup) && pInfo->ignoreExpiredData) { + continue; + } + void* chIds = taosHashGet(pInfo->pPullDataMap, winKey, sizeof(SWinKey)); + if (!chIds) { + SPullWindowInfo pull = { + .window = nextWin, .groupId = winKey->groupId, .calWin.skey = nextWin.skey, .calWin.ekey = nextWin.skey}; + // add pull data request + if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) { + addPullWindow(pInfo->pPullDataMap, winKey, pInfo->numOfChild); + qDebug("===stream===prepare retrive for delete %" PRId64 ", size:%d", winKey->ts, pInfo->numOfChild); + } + } else { + SArray* chArray = *(void**)chIds; + int32_t index = taosArraySearchIdx(chArray, &childId, compareInt32Val, TD_EQ); + qDebug("===stream===check final retrive %" PRId64",chid:%d", winKey->ts, index); + if (index == -1) { + qDebug("===stream===add final retrive %" PRId64, winKey->ts); + taosHashPut(pInfo->pFinalPullDataMap, winKey, sizeof(SWinKey), NULL, 0); + } + } + } +} + +static void clearFunctionContext(SExprSupp* pSup) { + for (int32_t i = 0; i < pSup->numOfExprs; i++) { + pSup->pCtx[i].saveHandle.currentPage = -1; + } +} + +int32_t getOutputBuf(void* pState, SRowBuffPos* pPos, SResultRow** pResult, SStateStore* pStore) { + return pStore->streamStateGetByPos(pState, pPos, (void**)pResult); +} + +int32_t buildDataBlockFromGroupRes(SOperatorInfo* pOperator, void* pState, SSDataBlock* pBlock, SExprSupp* pSup, + SGroupResInfo* pGroupResInfo) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SExprInfo* pExprInfo = pSup->pExprInfo; + int32_t numOfExprs = pSup->numOfExprs; + int32_t* rowEntryOffset = pSup->rowEntryInfoOffset; + SqlFunctionCtx* pCtx = pSup->pCtx; + + int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); + + for (int32_t i = pGroupResInfo->index; i < numOfRows; i += 1) { + SRowBuffPos* pPos = *(SRowBuffPos**)taosArrayGet(pGroupResInfo->pRows, i); + SResultRow* pRow = NULL; + int32_t code = getOutputBuf(pState, pPos, &pRow, &pAPI->stateStore); + uint64_t groupId = ((SWinKey*)pPos->pKey)->groupId; + ASSERT(code == 0); + doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowEntryOffset); + // no results, continue to check the next one + if (pRow->numOfRows == 0) { + pGroupResInfo->index += 1; + continue; + } + if (pBlock->info.id.groupId == 0) { + pBlock->info.id.groupId = groupId; + void* tbname = NULL; + if (pAPI->stateStore.streamStateGetParName(pTaskInfo->streamInfo.pState, pBlock->info.id.groupId, &tbname) < 0) { + pBlock->info.parTbName[0] = 0; + } else { + memcpy(pBlock->info.parTbName, tbname, TSDB_TABLE_NAME_LEN); + } + pAPI->stateStore.streamStateFreeVal(tbname); + } else { + // current value belongs to different group, it can't be packed into one datablock + if (pBlock->info.id.groupId != groupId) { + break; + } + } + + if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) { + ASSERT(pBlock->info.rows > 0); + break; + } + pGroupResInfo->index += 1; + + for (int32_t j = 0; j < numOfExprs; ++j) { + int32_t slotId = pExprInfo[j].base.resSchema.slotId; + + pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowEntryOffset); + SResultRowEntryInfo* pEnryInfo = pCtx[j].resultInfo; + + if (pCtx[j].fpSet.finalize) { + int32_t code1 = pCtx[j].fpSet.finalize(&pCtx[j], pBlock); + if (TAOS_FAILED(code1)) { + qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code1)); + T_LONG_JMP(pTaskInfo->env, code1); + } + } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) { + // do nothing, todo refactor + } else { + // expand the result into multiple rows. E.g., _wstart, top(k, 20) + // the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows. + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId); + char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo); + for (int32_t k = 0; k < pRow->numOfRows; ++k) { + colDataSetVal(pColInfoData, pBlock->info.rows + k, in, pCtx[j].resultInfo->isNullRes); + } + } + } + + pBlock->info.rows += pRow->numOfRows; + } + + pBlock->info.dataLoad = 1; + blockDataUpdateTsWindow(pBlock, 0); + return TSDB_CODE_SUCCESS; +} + +void doBuildStreamIntervalResult(SOperatorInfo* pOperator, void* pState, SSDataBlock* pBlock, + SGroupResInfo* pGroupResInfo) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + // set output datablock version + pBlock->info.version = pTaskInfo->version; + + blockDataCleanup(pBlock); + if (!hasRemainResults(pGroupResInfo)) { + return; + } + + // clear the existed group id + pBlock->info.id.groupId = 0; + buildDataBlockFromGroupRes(pOperator, pState, pBlock, &pOperator->exprSupp, pGroupResInfo); +} + +static int32_t getNextQualifiedFinalWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, + TSKEY* primaryKeys, int32_t prevPosition) { + int32_t startPos = prevPosition + 1; + if (startPos == pDataBlockInfo->rows) { + startPos = -1; + } else { + *pNext = getFinalTimeWindow(primaryKeys[startPos], pInterval); + } + return startPos; +} + +static void setStreamDataVersion(SExecTaskInfo* pTaskInfo, int64_t version, int64_t ckId) { + pTaskInfo->streamInfo.dataVersion = version; + pTaskInfo->streamInfo.checkPointId = ckId; +} + +static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBlock, uint64_t groupId, + SSHashObj* pUpdatedMap) { + SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)pOperatorInfo->info; + pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); + + SResultRowInfo* pResultRowInfo = &(pInfo->binfo.resultRowInfo); + SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; + SExprSupp* pSup = &pOperatorInfo->exprSupp; + int32_t numOfOutput = pSup->numOfExprs; + int32_t step = 1; + TSKEY* tsCols = NULL; + SRowBuffPos* pResPos = NULL; + SResultRow* pResult = NULL; + int32_t forwardRows = 0; + + SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); + tsCols = (int64_t*)pColDataInfo->pData; + + int32_t startPos = 0; + TSKEY ts = getStartTsKey(&pSDataBlock->info.window, tsCols); + STimeWindow nextWin = {0}; + if (IS_FINAL_OP(pInfo)) { + nextWin = getFinalTimeWindow(ts, &pInfo->interval); + } else { + nextWin = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval, TSDB_ORDER_ASC); + } + while (1) { + bool isClosed = isCloseWindow(&nextWin, &pInfo->twAggSup); + if ((pInfo->ignoreExpiredData && isClosed && !IS_FINAL_OP(pInfo)) || !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) { + startPos = getNexWindowPos(&pInfo->interval, &pSDataBlock->info, tsCols, startPos, nextWin.ekey, &nextWin); + if (startPos < 0) { + break; + } + continue; + } + + if (IS_FINAL_OP(pInfo) && pInfo->numOfChild > 0) { + bool ignore = true; + SWinKey winRes = { + .ts = nextWin.skey, + .groupId = groupId, + }; + void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey)); + if (isDeletedStreamWindow(&nextWin, groupId, pInfo->pState, &pInfo->twAggSup, &pInfo->statestore) && isClosed && !chIds) { + SPullWindowInfo pull = { + .window = nextWin, .groupId = groupId, .calWin.skey = nextWin.skey, .calWin.ekey = nextWin.skey}; + // add pull data request + if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) { + addPullWindow(pInfo->pPullDataMap, &winRes, pInfo->numOfChild); + } + } else { + int32_t index = -1; + SArray* chArray = NULL; + int32_t chId = 0; + if (chIds) { + chArray = *(void**)chIds; + chId = getChildIndex(pSDataBlock); + index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ); + } + if (index == -1 || pSDataBlock->info.type == STREAM_PULL_DATA) { + ignore = false; + } + } + + if (ignore) { + startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, startPos); + if (startPos < 0) { + break; + } + continue; + } + } + + int32_t code = setIntervalOutputBuf(pInfo->pState, &nextWin, &pResPos, groupId, pSup->pCtx, numOfOutput, + pSup->rowEntryInfoOffset, &pInfo->aggSup, &pInfo->statestore); + pResult = (SResultRow*)pResPos->pRowBuff; + if (code != TSDB_CODE_SUCCESS || pResult == NULL) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + if (IS_FINAL_OP(pInfo)) { + forwardRows = 1; + } else { + forwardRows = getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey, + NULL, TSDB_ORDER_ASC); + } + + SWinKey key = { + .ts = pResult->win.skey, + .groupId = groupId, + }; + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdatedMap) { + saveWinResult(&key, pResPos, pUpdatedMap); + } + + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + tSimpleHashPut(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey), &pResPos, POINTER_BYTES); + } + + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, 1); + applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, + pSDataBlock->info.rows, numOfOutput); + key.ts = nextWin.skey; + + if (pInfo->delKey.ts > key.ts) { + pInfo->delKey = key; + } + int32_t prevEndPos = (forwardRows - 1) * step + startPos; + if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) { + qError("table uid %" PRIu64 " data block timestamp range may not be calculated! minKey %" PRId64 + ",maxKey %" PRId64, + pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey); + blockDataUpdateTsWindow(pSDataBlock, 0); + + // timestamp of the data is incorrect + if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) { + qError("table uid %" PRIu64 " data block timestamp is out of range! minKey %" PRId64 ",maxKey %" PRId64, + pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey); + } + } + + if (IS_FINAL_OP(pInfo)) { + startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos); + } else { + startPos = + getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, TSDB_ORDER_ASC); + } + if (startPos < 0) { + break; + } + } +} + +static inline int winPosCmprImpl(const void* pKey1, const void* pKey2) { + SRowBuffPos* pos1 = *(SRowBuffPos**)pKey1; + SRowBuffPos* pos2 = *(SRowBuffPos**)pKey2; + SWinKey* pWin1 = (SWinKey*)pos1->pKey; + SWinKey* pWin2 = (SWinKey*)pos2->pKey; + + if (pWin1->groupId > pWin2->groupId) { + return 1; + } else if (pWin1->groupId < pWin2->groupId) { + return -1; + } + + if (pWin1->ts > pWin2->ts) { + return 1; + } else if (pWin1->ts < pWin2->ts) { + return -1; + } + + return 0; +} + +static void resetUnCloseWinInfo(SSHashObj* winMap) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(winMap, pIte, &iter)) != NULL) { + SRowBuffPos* pPos = *(SRowBuffPos**)pIte; + pPos->beUsed = true; + } +} +static char* getStreamOpName(uint16_t opType) { + switch (opType) { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: + return "single interval"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: + return "interval final"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: + return "interval semi"; + default: + return ""; + } + +} + +static SSDataBlock* getResult(SOperatorInfo* pOperator){ + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + uint16_t opType = pOperator->operatorType; + doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); + if (pInfo->pPullDataRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pPullDataRes, getStreamOpName(opType), GET_TASKID(pTaskInfo)); + return pInfo->pPullDataRes; + } + + doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pDelRes, getStreamOpName(opType), GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); + if (pInfo->binfo.pRes->info.rows != 0) { + printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); + return pInfo->binfo.pRes; + } + return NULL; +} + +static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + SExprSupp* pSup = &pOperator->exprSupp; + + qDebug("interval status %d %s", pOperator->status, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } else if (pOperator->status == OP_RES_TO_RETURN) { + SSDataBlock* resBlock = getResult(pOperator); + if (resBlock != NULL) { + return resBlock; + } + + if (pInfo->recvGetAll) { + pInfo->recvGetAll = false; + resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable); + } + + setOperatorCompleted(pOperator); + if (!IS_FINAL_OP(pInfo)) { + clearFunctionContext(&pOperator->exprSupp); + // semi interval operator clear disk buffer + clearStreamIntervalOperator(pInfo); + setStreamDataVersion(pTaskInfo, pInfo->dataVersion, pInfo->pState->checkPointId); + qDebug("===stream===clear semi operator"); + } else { + if (pInfo->twAggSup.maxTs > 0 && + pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) { + pAPI->stateStore.streamStateCommit(pInfo->pState); + pAPI->stateStore.streamStateDeleteCheckPoint(pInfo->pState, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark); + pInfo->twAggSup.checkPointTs = pInfo->twAggSup.maxTs; + } + qDebug("===stream===interval final close"); + } + return NULL; + } else { + if (!IS_FINAL_OP(pInfo)) { + doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + } + } + + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(4096, POINTER_BYTES); + } + if (!pInfo->pUpdatedMap) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pUpdatedMap = tSimpleHashInit(4096, hashFn); + } + + while (1) { + if (isTaskKilled(pTaskInfo)) { + if (pInfo->pUpdated != NULL) { + pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated); + } + + if (pInfo->pUpdatedMap != NULL) { + tSimpleHashCleanup(pInfo->pUpdatedMap); + pInfo->pUpdatedMap = NULL; + } + + T_LONG_JMP(pTaskInfo->env, pTaskInfo->code); + } + + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + pOperator->status = OP_RES_TO_RETURN; + qDebug("===stream===return data:%s. recv datablock num:%" PRIu64, + IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", pInfo->numOfDatapack); + pInfo->numOfDatapack = 0; + break; + } + pInfo->numOfDatapack++; + printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "interval final recv" : "interval semi recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) { + pInfo->binfo.pRes->info.type = pBlock->info.type; + } else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + SArray* delWins = taosArrayInit(8, sizeof(SWinKey)); + doDeleteWindows(pOperator, &pInfo->interval, pBlock, delWins, pInfo->pUpdatedMap); + if (IS_FINAL_OP(pInfo)) { + int32_t chId = getChildIndex(pBlock); + addRetriveWindow(delWins, pInfo, chId); + if (pBlock->info.type != STREAM_CLEAR) { + taosArrayAddAll(pInfo->pDelWins, delWins); + } + taosArrayDestroy(delWins); + continue; + } + removeResults(delWins, pInfo->pUpdatedMap); + taosArrayAddAll(pInfo->pDelWins, delWins); + taosArrayDestroy(delWins); + + doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); + if (pBlock->info.type == STREAM_CLEAR) { + pInfo->pDelRes->info.type = STREAM_CLEAR; + } else { + pInfo->pDelRes->info.type = STREAM_DELETE_RESULT; + } + return pInfo->pDelRes; + } + + break; + } else if (pBlock->info.type == STREAM_GET_ALL && IS_FINAL_OP(pInfo)) { + pInfo->recvGetAll = true; + getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); + continue; + } else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_OP(pInfo)) { + doDeleteWindows(pOperator, &pInfo->interval, pBlock, NULL, pInfo->pUpdatedMap); + if (taosArrayGetSize(pInfo->pUpdated) > 0) { + break; + } + continue; + } else if (pBlock->info.type == STREAM_PULL_OVER && IS_FINAL_OP(pInfo)) { + processPullOver(pBlock, pInfo->pPullDataMap, pInfo->pFinalPullDataMap, &pInfo->interval, pInfo->pPullWins, pInfo->numOfChild, pOperator); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark); + pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey); + } + + removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins); + if (IS_FINAL_OP(pInfo)) { + closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, + pInfo->pPullDataMap, pInfo->pUpdatedMap, pInfo->pDelWins, pOperator); + } + pInfo->binfo.pRes->info.watermark = pInfo->twAggSup.maxTs; + + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pInfo->pUpdatedMap, pIte, &iter)) != NULL) { + taosArrayPush(pInfo->pUpdated, pIte); + } + + tSimpleHashCleanup(pInfo->pUpdatedMap); + pInfo->pUpdatedMap = NULL; + taosArraySort(pInfo->pUpdated, winPosCmprImpl); + + initMultiResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); + + return getResult(pOperator); +} + +static int64_t getDeleteMark(SIntervalPhysiNode* pIntervalPhyNode) { + if (pIntervalPhyNode->window.deleteMark <= 0) { + return DEAULT_DELETE_MARK; + } + int64_t deleteMark = TMAX(pIntervalPhyNode->window.deleteMark, pIntervalPhyNode->window.watermark); + deleteMark = TMAX(deleteMark, pIntervalPhyNode->interval); + return deleteMark; +} + +static TSKEY compareTs(void* pKey) { + SWinKey* pWinKey = (SWinKey*)pKey; + return pWinKey->ts; +} + +static int32_t getSelectivityBufSize(SqlFunctionCtx* pCtx) { + if (pCtx->subsidiaries.rowLen == 0) { + int32_t rowLen = 0; + for (int32_t j = 0; j < pCtx->subsidiaries.num; ++j) { + SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j]; + rowLen += pc->pExpr->base.resSchema.bytes; + } + + return rowLen + pCtx->subsidiaries.num * sizeof(bool); + } else { + return pCtx->subsidiaries.rowLen; + } +} + +static int32_t getMaxFunResSize(SExprSupp* pSup, int32_t numOfCols) { + int32_t size = 0; + for (int32_t i = 0; i < numOfCols; ++i) { + int32_t resSize = getSelectivityBufSize(pSup->pCtx + i); + size = TMAX(size, resSize); + } + return size; +} + +static void streamIntervalReleaseState(SOperatorInfo* pOperator) { + if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + int32_t resSize = sizeof(TSKEY); + pInfo->statestore.streamStateSaveInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, strlen(STREAM_INTERVAL_OP_STATE_NAME), &pInfo->twAggSup.maxTs, resSize); + } + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + pAPI->stateStore.streamStateCommit(pInfo->pState); + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +void streamIntervalReloadState(SOperatorInfo* pOperator) { + if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pInfo->statestore.streamStateGetInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, + strlen(STREAM_INTERVAL_OP_STATE_NAME), &pBuf, &size); + TSKEY ts = *(TSKEY*)pBuf; + taosMemoryFree(pBuf); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, ts); + pInfo->statestore.streamStateReloadInfo(pInfo->pState, ts); + } + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + +SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo, int32_t numOfChild) { + SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode; + SStreamIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamIntervalOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + + pOperator->pTaskInfo = pTaskInfo; + SStorageAPI* pAPI = &pTaskInfo->storageAPI; + + pInfo->interval = (SInterval){.interval = pIntervalPhyNode->interval, + .sliding = pIntervalPhyNode->sliding, + .intervalUnit = pIntervalPhyNode->intervalUnit, + .slidingUnit = pIntervalPhyNode->slidingUnit, + .offset = pIntervalPhyNode->offset, + .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision}; + pInfo->twAggSup = (STimeWindowAggSupp){ + .waterMark = pIntervalPhyNode->window.watermark, + .calTrigger = pIntervalPhyNode->window.triggerType, + .maxTs = INT64_MIN, + .minTs = INT64_MAX, + .deleteMark = getDeleteMark(pIntervalPhyNode), + .deleteMarkSaved = 0, + .calTriggerSaved = 0, + .checkPointTs = 0, + .checkPointInterval = + convertTimePrecision(tsCheckpointInterval, TSDB_TIME_PRECISION_MILLI, pInfo->interval.precision), + }; + ASSERTS(pInfo->twAggSup.calTrigger != STREAM_TRIGGER_MAX_DELAY, "trigger type should not be max delay"); + pInfo->primaryTsIndex = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; + size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; + initResultSizeInfo(&pOperator->resultInfo, 4096); + if (pIntervalPhyNode->window.pExprs != NULL) { + int32_t numOfScalar = 0; + SExprInfo* pScalarExprInfo = createExprInfo(pIntervalPhyNode->window.pExprs, NULL, &numOfScalar); + int32_t code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + } + + int32_t numOfCols = 0; + SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &numOfCols); + SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); + initBasicInfo(&pInfo->binfo, pResBlock); + + pInfo->pState = taosMemoryCalloc(1, sizeof(SStreamState)); + *(pInfo->pState) = *(pTaskInfo->streamInfo.pState); + + pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1); + int32_t code = initAggSup(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, + pInfo->pState, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); + initResultRowInfo(&pInfo->binfo.resultRowInfo); + + pInfo->numOfChild = numOfChild; + + pInfo->pPhyNode = (SPhysiNode*)nodesCloneNode((SNode*)pPhyNode); + + if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) { + pInfo->isFinal = true; + pOperator->name = "StreamFinalIntervalOperator"; + } else { + // semi interval operator does not catch result + pInfo->isFinal = false; + pOperator->name = "StreamSemiIntervalOperator"; + } + + if (!IS_FINAL_OP(pInfo) || numOfChild == 0) { + pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; + } + + pInfo->pPullWins = taosArrayInit(8, sizeof(SPullWindowInfo)); + pInfo->pullIndex = 0; + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pPullDataMap = taosHashInit(64, hashFn, false, HASH_NO_LOCK); + pInfo->pFinalPullDataMap = taosHashInit(64, hashFn, false, HASH_NO_LOCK); + pInfo->pPullDataRes = createSpecialDataBlock(STREAM_RETRIEVE); + pInfo->ignoreExpiredData = pIntervalPhyNode->window.igExpired; + pInfo->ignoreExpiredDataSaved = false; + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + pInfo->delIndex = 0; + pInfo->pDelWins = taosArrayInit(4, sizeof(SWinKey)); + pInfo->delKey.ts = INT64_MAX; + pInfo->delKey.groupId = 0; + pInfo->numOfDatapack = 0; + pInfo->pUpdated = NULL; + pInfo->pUpdatedMap = NULL; + int32_t funResSize= getMaxFunResSize(&pOperator->exprSupp, numOfCols); + pInfo->pState->pFileState = pAPI->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, + compareTs, pInfo->pState, pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); + pInfo->dataVersion = 0; + pInfo->statestore = pTaskInfo->storageAPI.stateStore; + pInfo->recvGetAll = false; + + pOperator->operatorType = pPhyNode->type; + pOperator->blocking = true; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; + + pOperator->fpSet = createOperatorFpSet(NULL, doStreamFinalIntervalAgg, NULL, destroyStreamFinalIntervalOperatorInfo, + optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); + if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { + initIntervalDownStream(downstream, pPhyNode->type, pInfo); + } + code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + return pOperator; + +_error: + destroyStreamFinalIntervalOperatorInfo(pInfo); + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} + +void destroyStreamAggSupporter(SStreamAggSupporter* pSup) { + tSimpleHashCleanup(pSup->pResultRows); + destroyDiskbasedBuf(pSup->pResultBuf); + blockDataDestroy(pSup->pScanBlock); + taosMemoryFreeClear(pSup->pState); + taosMemoryFreeClear(pSup->pDummyCtx); +} + +void destroyStreamSessionAggOperatorInfo(void* param) { + SStreamSessionAggOperatorInfo* pInfo = (SStreamSessionAggOperatorInfo*)param; + cleanupBasicInfo(&pInfo->binfo); + destroyStreamAggSupporter(&pInfo->streamAggSup); + + if (pInfo->pChildren != NULL) { + int32_t size = taosArrayGetSize(pInfo->pChildren); + for (int32_t i = 0; i < size; i++) { + SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i); + destroyOperator(pChild); + } + taosArrayDestroy(pInfo->pChildren); + } + + colDataDestroy(&pInfo->twAggSup.timeWindowData); + blockDataDestroy(pInfo->pDelRes); + blockDataDestroy(pInfo->pWinBlock); + blockDataDestroy(pInfo->pUpdateRes); + tSimpleHashCleanup(pInfo->pStUpdated); + tSimpleHashCleanup(pInfo->pStDeleted); + + taosArrayDestroy(pInfo->historyWins); + taosMemoryFreeClear(param); +} + +int32_t initBasicInfoEx(SOptrBasicInfo* pBasicInfo, SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfCols, + SSDataBlock* pResultBlock, SFunctionStateStore* pStore) { + initBasicInfo(pBasicInfo, pResultBlock); + int32_t code = initExprSupp(pSup, pExprInfo, numOfCols, pStore); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + for (int32_t i = 0; i < numOfCols; ++i) { + pSup->pCtx[i].saveHandle.pBuf = NULL; + } + + ASSERT(numOfCols > 0); + return TSDB_CODE_SUCCESS; +} + +void initDummyFunction(SqlFunctionCtx* pDummy, SqlFunctionCtx* pCtx, int32_t nums) { + for (int i = 0; i < nums; i++) { + pDummy[i].functionId = pCtx[i].functionId; + pDummy[i].isNotNullFunc = pCtx[i].isNotNullFunc; + pDummy[i].isPseudoFunc = pCtx[i].isPseudoFunc; + } +} + +void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, uint16_t type, int32_t tsColIndex, + STimeWindowAggSupp* pTwSup) { + if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION) { + SStreamPartitionOperatorInfo* pScanInfo = downstream->info; + pScanInfo->tsColIndex = tsColIndex; + } + + if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { + initDownStream(downstream->pDownstream[0], pAggSup, type, tsColIndex, pTwSup); + return; + } + SStreamScanInfo* pScanInfo = downstream->info; + pScanInfo->windowSup = (SWindowSupporter){.pStreamAggSup = pAggSup, .gap = pAggSup->gap, .parentType = type}; + pScanInfo->pState = pAggSup->pState; + if (!pScanInfo->pUpdateInfo) { + pScanInfo->pUpdateInfo = pAggSup->stateStore.updateInfoInit(60000, TSDB_TIME_PRECISION_MILLI, pTwSup->waterMark); + } + pScanInfo->twAggSup = *pTwSup; +} + +int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, int64_t gap, + SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore, SReadHandle* pHandle, SStorageAPI* pApi) { + pSup->resultRowSize = keySize + getResultRowSize(pCtx, numOfOutput); + pSup->pScanBlock = createSpecialDataBlock(STREAM_CLEAR); + pSup->gap = gap; + pSup->stateKeySize = keySize; + pSup->stateKeyType = keyType; + pSup->pDummyCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx)); + if (pSup->pDummyCtx == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + pSup->stateStore = *pStore; + + initDummyFunction(pSup->pDummyCtx, pCtx, numOfOutput); + pSup->pState = taosMemoryCalloc(1, sizeof(SStreamState)); + *(pSup->pState) = *pState; + pSup->stateStore.streamStateSetNumber(pSup->pState, -1); + + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pSup->pResultRows = tSimpleHashInit(32, hashFn); + + int32_t pageSize = 4096; + while (pageSize < pSup->resultRowSize * 4) { + pageSize <<= 1u; + } + // at least four pages need to be in buffer + int32_t bufSize = 4096 * 256; + if (bufSize <= pageSize) { + bufSize = pageSize * 4; + } + + if (!osTempSpaceAvailable()) { + terrno = TSDB_CODE_NO_DISKSPACE; + qError("Init stream agg supporter failed since %s, tempDir:%s", terrstr(), tsTempDir); + return terrno; + } + + int32_t code = createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, "function", tsTempDir); + for (int32_t i = 0; i < numOfOutput; ++i) { + pCtx[i].saveHandle.pBuf = pSup->pResultBuf; + } + + pSup->pSessionAPI = pApi; + + return TSDB_CODE_SUCCESS; +} + +bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap) { + if (ts + gap >= pWin->skey && ts - gap <= pWin->ekey) { + return true; + } + return false; +} + +bool isInWindow(SResultWindowInfo* pWinInfo, TSKEY ts, int64_t gap) { + return isInTimeWindow(&pWinInfo->sessionWin.win, ts, gap); +} + +void getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, + SSessionKey* pKey) { + pKey->win.skey = startTs; + pKey->win.ekey = endTs; + pKey->groupId = groupId; + int32_t code = pAggSup->stateStore.streamStateSessionGetKeyByRange(pAggSup->pState, pKey, pKey); + if (code != TSDB_CODE_SUCCESS) { + SET_SESSION_WIN_KEY_INVALID(pKey); + } +} + +bool isInvalidSessionWin(SResultWindowInfo* pWinInfo) { return pWinInfo->sessionWin.win.skey == 0; } + +bool inWinRange(STimeWindow* range, STimeWindow* cur) { + if (cur->skey >= range->skey && cur->ekey <= range->ekey) { + return true; + } + return false; +} + +void setSessionOutputBuf(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, + SResultWindowInfo* pCurWin) { + pCurWin->sessionWin.groupId = groupId; + pCurWin->sessionWin.win.skey = startTs; + pCurWin->sessionWin.win.ekey = endTs; + int32_t size = pAggSup->resultRowSize; + int32_t code = pAggSup->stateStore.streamStateSessionAddIfNotExist(pAggSup->pState, &pCurWin->sessionWin, + pAggSup->gap, &pCurWin->pOutputBuf, &size); + if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->sessionWin.win)) { + code = TSDB_CODE_FAILED; + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->pOutputBuf, &pAggSup->pSessionAPI->stateStore); + pCurWin->pOutputBuf = taosMemoryCalloc(1, size); + } + + if (code == TSDB_CODE_SUCCESS) { + pCurWin->isOutput = true; + pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &pCurWin->sessionWin); + } else { + pCurWin->sessionWin.win.skey = startTs; + pCurWin->sessionWin.win.ekey = endTs; + } +} + +int32_t getSessionWinBuf(SStreamAggSupporter* pAggSup, SStreamStateCur* pCur, SResultWindowInfo* pWinInfo) { + int32_t size = 0; + int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pWinInfo->sessionWin, &pWinInfo->pOutputBuf, &size); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + pAggSup->stateStore.streamStateCurNext(pAggSup->pState, pCur); + return TSDB_CODE_SUCCESS; +} +void saveDeleteInfo(SArray* pWins, SSessionKey key) { + // key.win.ekey = key.win.skey; + taosArrayPush(pWins, &key); +} + +void saveDeleteRes(SSHashObj* pStDelete, SSessionKey key) { + key.win.ekey = key.win.skey; + tSimpleHashPut(pStDelete, &key, sizeof(SSessionKey), NULL, 0); +} + +static void removeSessionResult(SSHashObj* pHashMap, SSHashObj* pResMap, SSessionKey key) { + key.win.ekey = key.win.skey; + tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey)); + tSimpleHashRemove(pResMap, &key, sizeof(SSessionKey)); +} + +static void getSessionHashKey(const SSessionKey* pKey, SSessionKey* pHashKey) { + *pHashKey = *pKey; + pHashKey->win.ekey = pKey->win.skey; +} + +static void removeSessionResults(SSHashObj* pHashMap, SArray* pWins) { + if (tSimpleHashGetSize(pHashMap) == 0) { + return; + } + int32_t size = taosArrayGetSize(pWins); + for (int32_t i = 0; i < size; i++) { + SSessionKey* pWin = taosArrayGet(pWins, i); + if (!pWin) continue; + SSessionKey key = {0}; + getSessionHashKey(pWin, &key); + tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey)); + } +} + +int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t groupId, + int32_t rows, int32_t start, int64_t gap, SSHashObj* pResultRows, SSHashObj* pStUpdated, + SSHashObj* pStDeleted) { + for (int32_t i = start; i < rows; ++i) { + if (!isInWindow(pWinInfo, pStartTs[i], gap) && (!pEndTs || !isInWindow(pWinInfo, pEndTs[i], gap))) { + return i - start; + } + if (pWinInfo->sessionWin.win.skey > pStartTs[i]) { + if (pStDeleted && pWinInfo->isOutput) { + saveDeleteRes(pStDeleted, pWinInfo->sessionWin); + } + removeSessionResult(pStUpdated, pResultRows, pWinInfo->sessionWin); + pWinInfo->sessionWin.win.skey = pStartTs[i]; + } + pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pStartTs[i]); + if (pEndTs) { + pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pEndTs[i]); + } + } + return rows - start; +} + +static int32_t initSessionOutputBuf(SResultWindowInfo* pWinInfo, SResultRow** pResult, SqlFunctionCtx* pCtx, + int32_t numOfOutput, int32_t* rowEntryInfoOffset) { + ASSERT(pWinInfo->sessionWin.win.skey <= pWinInfo->sessionWin.win.ekey); + *pResult = (SResultRow*)pWinInfo->pOutputBuf; + // set time window for current result + (*pResult)->win = pWinInfo->sessionWin.win; + setResultRowInitCtx(*pResult, pCtx, numOfOutput, rowEntryInfoOffset); + return TSDB_CODE_SUCCESS; +} + +static int32_t doOneWindowAggImpl(SColumnInfoData* pTimeWindowData, SResultWindowInfo* pCurWin, SResultRow** pResult, + int32_t startIndex, int32_t winRows, int32_t rows, int32_t numOutput, + SOperatorInfo* pOperator, int64_t winDelta) { + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + int32_t code = initSessionOutputBuf(pCurWin, pResult, pSup->pCtx, numOutput, pSup->rowEntryInfoOffset); + if (code != TSDB_CODE_SUCCESS || (*pResult) == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + updateTimeWindowInfo(pTimeWindowData, &pCurWin->sessionWin.win, winDelta); + applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, pTimeWindowData, startIndex, winRows, rows, numOutput); + return TSDB_CODE_SUCCESS; +} + +static bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pKey) { + pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, pKey); + SSessionKey hashKey = {0}; + getSessionHashKey(pKey, &hashKey); + tSimpleHashRemove(pAggSup->pResultRows, &hashKey, sizeof(SSessionKey)); + return true; +} + +static int32_t setSessionWinOutputInfo(SSHashObj* pStUpdated, SResultWindowInfo* pWinInfo) { + void* pVal = tSimpleHashGet(pStUpdated, &pWinInfo->sessionWin, sizeof(SSessionKey)); + if (pVal) { + SResultWindowInfo* pWin = pVal; + pWinInfo->isOutput = pWin->isOutput; + } + return TSDB_CODE_SUCCESS; +} + +SStreamStateCur* getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* pStUpdated, SResultWindowInfo* pCurWin, + SResultWindowInfo* pNextWin) { + SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pCurWin->sessionWin); + pNextWin->isOutput = true; + setSessionWinOutputInfo(pStUpdated, pNextWin); + int32_t size = 0; + pNextWin->sessionWin = pCurWin->sessionWin; + int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->sessionWin, &pNextWin->pOutputBuf, &size); + if (code != TSDB_CODE_SUCCESS) { + taosMemoryFreeClear(pNextWin->pOutputBuf); + SET_SESSION_WIN_INVALID(*pNextWin); + } + return pCur; +} + +static int32_t compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SSHashObj* pStUpdated, + SSHashObj* pStDeleted, bool addGap) { + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + int32_t winNum = 0; + + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SResultRow* pCurResult = NULL; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); + // Just look for the window behind StartIndex + while (1) { + SResultWindowInfo winInfo = {0}; + SStreamStateCur* pCur = getNextSessionWinInfo(pAggSup, pStUpdated, pCurWin, &winInfo); + if (!IS_VALID_SESSION_WIN(winInfo) || !isInWindow(pCurWin, winInfo.sessionWin.win.skey, pAggSup->gap) || + !inWinRange(&pAggSup->winRange, &winInfo.sessionWin.win)) { + taosMemoryFree(winInfo.pOutputBuf); + pAPI->stateStore.streamStateFreeCur(pCur); + break; + } + SResultRow* pWinResult = NULL; + initSessionOutputBuf(&winInfo, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); + pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, winInfo.sessionWin.win.ekey); + int64_t winDelta = 0; + if (addGap) { + winDelta = pAggSup->gap; + } + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, winDelta); + compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); + tSimpleHashRemove(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey)); + if (winInfo.isOutput && pStDeleted) { + saveDeleteRes(pStDeleted, winInfo.sessionWin); + } + removeSessionResult(pStUpdated, pAggSup->pResultRows, winInfo.sessionWin); + doDeleteSessionWindow(pAggSup, &winInfo.sessionWin); + pAPI->stateStore.streamStateFreeCur(pCur); + taosMemoryFree(winInfo.pOutputBuf); + winNum++; + } + return winNum; +} + +int32_t saveSessionOutputBuf(SStreamAggSupporter* pAggSup, SResultWindowInfo* pWinInfo) { + saveSessionDiscBuf(pAggSup->pState, &pWinInfo->sessionWin, pWinInfo->pOutputBuf, pAggSup->resultRowSize, &pAggSup->stateStore); + pWinInfo->pOutputBuf = NULL; + return TSDB_CODE_SUCCESS; +} + +static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pStUpdated, + SSHashObj* pStDeleted, bool hasEndTs, bool addGap) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + uint64_t groupId = pSDataBlock->info.id.groupId; + int64_t code = TSDB_CODE_SUCCESS; + SResultRow* pResult = NULL; + int32_t rows = pSDataBlock->info.rows; + int32_t winRows = 0; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + + pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); + pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow; + if (pAggSup->winRange.ekey <= 0) { + pAggSup->winRange.ekey = INT64_MAX; + } + + SColumnInfoData* pStartTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); + TSKEY* startTsCols = (int64_t*)pStartTsCol->pData; + SColumnInfoData* pEndTsCol = NULL; + if (hasEndTs) { + pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->endTsIndex); + } else { + pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); + } + + TSKEY* endTsCols = (int64_t*)pEndTsCol->pData; + for (int32_t i = 0; i < rows;) { + if (pInfo->ignoreExpiredData && isOverdue(endTsCols[i], &pInfo->twAggSup)) { + i++; + continue; + } + SResultWindowInfo winInfo = {0}; + setSessionOutputBuf(pAggSup, startTsCols[i], endTsCols[i], groupId, &winInfo); + setSessionWinOutputInfo(pStUpdated, &winInfo); + winRows = updateSessionWindowInfo(&winInfo, startTsCols, endTsCols, groupId, rows, i, pAggSup->gap, + pAggSup->pResultRows, pStUpdated, pStDeleted); + // coverity scan error + if (!winInfo.pOutputBuf) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + + int64_t winDelta = 0; + if (addGap) { + winDelta = pAggSup->gap; + } + code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &winInfo, &pResult, i, winRows, rows, numOfOutput, + pOperator, winDelta); + if (code != TSDB_CODE_SUCCESS || pResult == NULL) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + compactSessionWindow(pOperator, &winInfo, pStUpdated, pStDeleted, addGap); + saveSessionOutputBuf(pAggSup, &winInfo); + + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pStUpdated) { + code = saveResult(winInfo, pStUpdated); + if (code != TSDB_CODE_SUCCESS) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + } + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + SSessionKey key = {0}; + getSessionHashKey(&winInfo.sessionWin, &key); + tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); + } + + i += winRows; + } +} + +static void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SArray* result) { + SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + TSKEY* startDatas = (TSKEY*)pStartTsCol->pData; + SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + TSKEY* endDatas = (TSKEY*)pEndTsCol->pData; + SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* gpDatas = (uint64_t*)pGroupCol->pData; + for (int32_t i = 0; i < pBlock->info.rows; i++) { + while (1) { + SSessionKey curWin = {0}; + getCurSessionWindow(pAggSup, startDatas[i], endDatas[i], gpDatas[i], &curWin); + if (IS_INVALID_SESSION_WIN_KEY(curWin)) { + break; + } + doDeleteSessionWindow(pAggSup, &curWin); + if (result) { + saveDeleteInfo(result, curWin); + } + } + } +} + +static inline int32_t sessionKeyCompareAsc(const void* pKey1, const void* pKey2) { + SSessionKey* pWin1 = (SSessionKey*)pKey1; + SSessionKey* pWin2 = (SSessionKey*)pKey2; + + if (pWin1->groupId > pWin2->groupId) { + return 1; + } else if (pWin1->groupId < pWin2->groupId) { + return -1; + } + + if (pWin1->win.skey > pWin2->win.skey) { + return 1; + } else if (pWin1->win.skey < pWin2->win.skey) { + return -1; + } + + return 0; +} + +static int32_t copyUpdateResult(SSHashObj* pStUpdated, SArray* pUpdated) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pStUpdated, pIte, &iter)) != NULL) { + void* key = tSimpleHashGetKey(pIte, NULL); + taosArrayPush(pUpdated, key); + } + taosArraySort(pUpdated, sessionKeyCompareAsc); + return TSDB_CODE_SUCCESS; +} + +void doBuildDeleteDataBlock(SOperatorInfo* pOp, SSHashObj* pStDeleted, SSDataBlock* pBlock, void** Ite) { + SStorageAPI* pAPI = &pOp->pTaskInfo->storageAPI; + + blockDataCleanup(pBlock); + int32_t size = tSimpleHashGetSize(pStDeleted); + if (size == 0) { + return; + } + blockDataEnsureCapacity(pBlock, size); + int32_t iter = 0; + while (((*Ite) = tSimpleHashIterate(pStDeleted, *Ite, &iter)) != NULL) { + if (pBlock->info.rows + 1 > pBlock->info.capacity) { + break; + } + SSessionKey* res = tSimpleHashGetKey(*Ite, NULL); + SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + colDataSetVal(pStartTsCol, pBlock->info.rows, (const char*)&res->win.skey, false); + SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + colDataSetVal(pEndTsCol, pBlock->info.rows, (const char*)&res->win.skey, false); + SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX); + colDataSetNULL(pUidCol, pBlock->info.rows); + SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + colDataSetVal(pGpCol, pBlock->info.rows, (const char*)&res->groupId, false); + SColumnInfoData* pCalStCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + colDataSetNULL(pCalStCol, pBlock->info.rows); + SColumnInfoData* pCalEdCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + colDataSetNULL(pCalEdCol, pBlock->info.rows); + + SColumnInfoData* pTableCol = taosArrayGet(pBlock->pDataBlock, TABLE_NAME_COLUMN_INDEX); + + void* tbname = NULL; + pAPI->stateStore.streamStateGetParName(pOp->pTaskInfo->streamInfo.pState, res->groupId, &tbname); + if (tbname == NULL) { + colDataSetNULL(pTableCol, pBlock->info.rows); + } else { + char parTbName[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN]; + STR_WITH_MAXSIZE_TO_VARSTR(parTbName, tbname, sizeof(parTbName)); + colDataSetVal(pTableCol, pBlock->info.rows, (const char*)parTbName, false); + pAPI->stateStore.streamStateFreeVal(tbname); + } + pBlock->info.rows += 1; + } + if ((*Ite) == NULL) { + tSimpleHashClear(pStDeleted); + } +} + +static void rebuildSessionWindow(SOperatorInfo* pOperator, SArray* pWinArray, SSHashObj* pStUpdated) { + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + int32_t size = taosArrayGetSize(pWinArray); + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + int32_t numOfOutput = pSup->numOfExprs; + int32_t numOfChild = taosArrayGetSize(pInfo->pChildren); + + for (int32_t i = 0; i < size; i++) { + SSessionKey* pWinKey = taosArrayGet(pWinArray, i); + int32_t num = 0; + SResultWindowInfo parentWin = {0}; + for (int32_t j = 0; j < numOfChild; j++) { + SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, j); + SStreamSessionAggOperatorInfo* pChInfo = pChild->info; + SStreamAggSupporter* pChAggSup = &pChInfo->streamAggSup; + SSessionKey chWinKey = {0}; + getSessionHashKey(pWinKey, &chWinKey); + SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyCurrentNext(pChAggSup->pState, &chWinKey); + SResultRow* pResult = NULL; + SResultRow* pChResult = NULL; + while (1) { + SResultWindowInfo childWin = {0}; + childWin.sessionWin = *pWinKey; + int32_t code = getSessionWinBuf(pChAggSup, pCur, &childWin); + + if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &childWin.sessionWin.win)) { + continue; + } + + if (code == TSDB_CODE_SUCCESS && inWinRange(&pWinKey->win, &childWin.sessionWin.win)) { + if (num == 0) { + setSessionOutputBuf(pAggSup, pWinKey->win.skey, pWinKey->win.ekey, pWinKey->groupId, &parentWin); + code = initSessionOutputBuf(&parentWin, &pResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); + if (code != TSDB_CODE_SUCCESS || pResult == NULL) { + break; + } + } + num++; + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &parentWin.sessionWin.win, pAggSup->gap); + initSessionOutputBuf(&childWin, &pChResult, pChild->exprSupp.pCtx, numOfOutput, + pChild->exprSupp.rowEntryInfoOffset); + compactFunctions(pSup->pCtx, pChild->exprSupp.pCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); + compactSessionWindow(pOperator, &parentWin, pStUpdated, NULL, true); + saveResult(parentWin, pStUpdated); + } else { + break; + } + } + pAPI->stateStore.streamStateFreeCur(pCur); + } + if (num > 0) { + saveSessionOutputBuf(pAggSup, &parentWin); + } + } +} + +int32_t closeSessionWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SSHashObj* pClosed) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { + SResultWindowInfo* pWinInfo = pIte; + if (isCloseWindow(&pWinInfo->sessionWin.win, pTwSup)) { + if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE && pClosed) { + int32_t code = saveResult(*pWinInfo, pClosed); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + SSessionKey* pKey = tSimpleHashGetKey(pIte, NULL); + tSimpleHashIterateRemove(pHashMap, pKey, sizeof(SSessionKey), &pIte, &iter); + } + } + return TSDB_CODE_SUCCESS; +} + +static void closeChildSessionWindow(SArray* pChildren, TSKEY maxTs) { + int32_t size = taosArrayGetSize(pChildren); + for (int32_t i = 0; i < size; i++) { + SOperatorInfo* pChildOp = taosArrayGetP(pChildren, i); + SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info; + pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, maxTs); + closeSessionWindow(pChInfo->streamAggSup.pResultRows, &pChInfo->twAggSup, NULL); + } +} + +int32_t getAllSessionWindow(SSHashObj* pHashMap, SSHashObj* pStUpdated) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { + SResultWindowInfo* pWinInfo = pIte; + saveResult(*pWinInfo, pStUpdated); + } + return TSDB_CODE_SUCCESS; +} + +static void copyDeleteWindowInfo(SArray* pResWins, SSHashObj* pStDeleted) { + int32_t size = taosArrayGetSize(pResWins); + for (int32_t i = 0; i < size; i++) { + SSessionKey* pWinKey = taosArrayGet(pResWins, i); + if (!pWinKey) continue; + SSessionKey winInfo = {0}; + getSessionHashKey(pWinKey, &winInfo); + tSimpleHashPut(pStDeleted, &winInfo, sizeof(SSessionKey), NULL, 0); + } +} + +// the allocated memory comes from outer function. +void initGroupResInfoFromArrayList(SGroupResInfo* pGroupResInfo, SArray* pArrayList) { + pGroupResInfo->pRows = pArrayList; + pGroupResInfo->index = 0; + pGroupResInfo->pBuf = NULL; +} + +void doBuildSessionResult(SOperatorInfo* pOperator, void* pState, SGroupResInfo* pGroupResInfo, + SSDataBlock* pBlock) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + // set output datablock version + pBlock->info.version = pTaskInfo->version; + + blockDataCleanup(pBlock); + if (!hasRemainResults(pGroupResInfo)) { + cleanupGroupResInfo(pGroupResInfo); + return; + } + + // clear the existed group id + pBlock->info.id.groupId = 0; + buildSessionResultDataBlock(pOperator, pState, pBlock, &pOperator->exprSupp, pGroupResInfo); + if (pBlock->info.rows == 0) { + cleanupGroupResInfo(pGroupResInfo); + } +} +void getMaxTsWins(const SArray* pAllWins, SArray* pMaxWins) { + int32_t size = taosArrayGetSize(pAllWins); + if (size == 0) { + return; + } + + SSessionKey* pSeKey = taosArrayGet(pAllWins, size - 1); + taosArrayPush(pMaxWins, pSeKey); + if (pSeKey->groupId == 0) { + return; + } + uint64_t preGpId = pSeKey->groupId; + for (int32_t i = size - 2; i >= 0; i--) { + pSeKey = taosArrayGet(pAllWins, i); + if (preGpId != pSeKey->groupId) { + taosArrayPush(pMaxWins, pSeKey); + preGpId = pSeKey->groupId; + } + } +} + +static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { + SExprSupp* pSup = &pOperator->exprSupp; + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + qDebug("===stream=== stream session agg"); + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } else if (pOperator->status == OP_RES_TO_RETURN) { + doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + + setOperatorCompleted(pOperator); + return NULL; + } + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); + } + if (!pInfo->pStUpdated) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pStUpdated = tSimpleHashInit(64, hashFn); + } + while (1) { + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + break; + } + printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "final session recv" : "single session recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); + // gap must be 0 + doDeleteTimeWindows(pAggSup, pBlock, pWins); + removeSessionResults(pInfo->pStUpdated, pWins); + if (IS_FINAL_OP(pInfo)) { + int32_t childIndex = getChildIndex(pBlock); + SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex); + SStreamSessionAggOperatorInfo* pChildInfo = pChildOp->info; + // gap must be 0 + doDeleteTimeWindows(&pChildInfo->streamAggSup, pBlock, NULL); + rebuildSessionWindow(pOperator, pWins, pInfo->pStUpdated); + } + copyDeleteWindowInfo(pWins, pInfo->pStDeleted); + taosArrayDestroy(pWins); + continue; + } else if (pBlock->info.type == STREAM_GET_ALL) { + getAllSessionWindow(pAggSup->pResultRows, pInfo->pStUpdated); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, IS_FINAL_OP(pInfo), true); + if (IS_FINAL_OP(pInfo)) { + int32_t chIndex = getChildIndex(pBlock); + int32_t size = taosArrayGetSize(pInfo->pChildren); + // if chIndex + 1 - size > 0, add new child + for (int32_t i = 0; i < chIndex + 1 - size; i++) { + SOperatorInfo* pChildOp = + createStreamFinalSessionAggOperatorInfo(NULL, pInfo->pPhyNode, pOperator->pTaskInfo, 0, NULL); + if (!pChildOp) { + T_LONG_JMP(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + taosArrayPush(pInfo->pChildren, &pChildOp); + } + SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, chIndex); + setInputDataBlock(&pChildOp->exprSupp, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamSessionAggImpl(pChildOp, pBlock, NULL, NULL, true, false); + } + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark); + } + // restore the value + pOperator->status = OP_RES_TO_RETURN; + + closeSessionWindow(pAggSup->pResultRows, &pInfo->twAggSup, pInfo->pStUpdated); + closeChildSessionWindow(pInfo->pChildren, pInfo->twAggSup.maxTs); + copyUpdateResult(pInfo->pStUpdated, pInfo->pUpdated); + removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); + tSimpleHashCleanup(pInfo->pStUpdated); + pInfo->pStUpdated = NULL; + if(pInfo->isHistoryOp) { + getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); + } + initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); + +#if 0 + char* pBuf = streamStateSessionDump(pAggSup->pState); + qDebug("===stream===final session%s", pBuf); + taosMemoryFree(pBuf); +#endif + + doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + + setOperatorCompleted(pOperator); + return NULL; +} + +void streamSessionReleaseState(SOperatorInfo* pOperator) { + if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); + pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_SESSION_OP_STATE_NAME, strlen(STREAM_SESSION_OP_STATE_NAME), pInfo->historyWins->pData, resSize); + } + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +void resetWinRange(STimeWindow* winRange) { + winRange->skey = INT64_MIN; + winRange->ekey = INT64_MAX; +} + +void streamSessionReloadState(SOperatorInfo* pOperator) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + resetWinRange(&pAggSup->winRange); + + SResultWindowInfo winInfo = {0}; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_SESSION_OP_STATE_NAME, + strlen(STREAM_SESSION_OP_STATE_NAME), &pBuf, &size); + int32_t num = size / sizeof(SSessionKey); + SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; + ASSERT(size == num * sizeof(SSessionKey)); + if (!pInfo->pStUpdated && num > 0) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pStUpdated = tSimpleHashInit(64, hashFn); + } + for (int32_t i = 0; i < num; i++) { + SResultWindowInfo winInfo = {0}; + setSessionOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].win.ekey, pSeKeyBuf[i].groupId, &winInfo); + int32_t winNum = compactSessionWindow(pOperator, &winInfo, pInfo->pStUpdated, pInfo->pStDeleted, true); + if (winNum > 0) { + qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, winInfo.sessionWin.win.skey, winInfo.sessionWin.groupId); + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { + saveResult(winInfo, pInfo->pStUpdated); + } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + if (!isCloseWindow(&winInfo.sessionWin.win, &pInfo->twAggSup)) { + saveDeleteRes(pInfo->pStDeleted, winInfo.sessionWin); + } + SSessionKey key = {0}; + getSessionHashKey(&winInfo.sessionWin, &key); + tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); + } + } + saveSessionOutputBuf(pAggSup, &winInfo); + } + taosMemoryFree(pBuf); + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + +SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { + SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode; + int32_t numOfCols = 0; + int32_t code = TSDB_CODE_OUT_OF_MEMORY; + SStreamSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamSessionAggOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + + pOperator->pTaskInfo = pTaskInfo; + + initResultSizeInfo(&pOperator->resultInfo, 4096); + if (pSessionNode->window.pExprs != NULL) { + int32_t numOfScalar = 0; + SExprInfo* pScalarExprInfo = createExprInfo(pSessionNode->window.pExprs, NULL, &numOfScalar); + code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + } + SExprSupp* pSup = &pOperator->exprSupp; + + SExprInfo* pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &numOfCols); + SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); + code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, pSessionNode->gap, + pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + pInfo->twAggSup = (STimeWindowAggSupp){ + .waterMark = pSessionNode->window.watermark, + .calTrigger = pSessionNode->window.triggerType, + .maxTs = INT64_MIN, + .minTs = INT64_MAX, + }; + + initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); + + pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId; + if (pSessionNode->window.pTsEnd) { + pInfo->endTsIndex = ((SColumnNode*)pSessionNode->window.pTsEnd)->slotId; + } + pInfo->binfo.pRes = pResBlock; + pInfo->order = TSDB_ORDER_ASC; + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pStDeleted = tSimpleHashInit(64, hashFn); + pInfo->pDelIterator = NULL; + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + pInfo->pChildren = NULL; + pInfo->isFinal = false; + pInfo->pPhyNode = pPhyNode; + pInfo->ignoreExpiredData = pSessionNode->window.igExpired; + pInfo->ignoreExpiredDataSaved = false; + pInfo->pUpdated = NULL; + pInfo->pStUpdated = NULL; + pInfo->dataVersion = 0; + pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); + if (!pInfo->historyWins) { + goto _error; + } + if (pHandle) { + pInfo->isHistoryOp = pHandle->fillHistory; + } + + setOperatorInfo(pOperator, "StreamSessionWindowAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, true, + OP_NOT_OPENED, pInfo, pTaskInfo); + pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionAgg, NULL, destroyStreamSessionAggOperatorInfo, + optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); + + if (downstream) { + initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); + code = appendDownstream(pOperator, &downstream, 1); + } + return pOperator; + +_error: + if (pInfo != NULL) { + destroyStreamSessionAggOperatorInfo(pInfo); + } + + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} + +static void clearStreamSessionOperator(SStreamSessionAggOperatorInfo* pInfo) { + tSimpleHashClear(pInfo->streamAggSup.pResultRows); + pInfo->streamAggSup.stateStore.streamStateSessionClear(pInfo->streamAggSup.pState); +} + +static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + TSKEY maxTs = INT64_MIN; + SExprSupp* pSup = &pOperator->exprSupp; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + qDebug("===stream=== stream session semi agg"); + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + { + doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, "semi session", GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + + doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, "semi session delete", GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + if (pOperator->status == OP_RES_TO_RETURN) { + clearFunctionContext(&pOperator->exprSupp); + // semi interval operator clear disk buffer + clearStreamSessionOperator(pInfo); + setOperatorCompleted(pOperator); + return NULL; + } + } + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); + } + if (!pInfo->pStUpdated) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pStUpdated = tSimpleHashInit(64, hashFn); + } + while (1) { + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + clearSpecialDataBlock(pInfo->pUpdateRes); + pOperator->status = OP_RES_TO_RETURN; + break; + } + printDataBlock(pBlock, "semi session recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + // gap must be 0 + SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); + doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins); + removeSessionResults(pInfo->pStUpdated, pWins); + copyDeleteWindowInfo(pWins, pInfo->pStDeleted); + taosArrayDestroy(pWins); + break; + } else if (pBlock->info.type == STREAM_GET_ALL) { + getAllSessionWindow(pInfo->streamAggSup.pResultRows, pInfo->pStUpdated); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, NULL, false, false); + maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + } + + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs); + pBInfo->pRes->info.watermark = pInfo->twAggSup.maxTs; + + copyUpdateResult(pInfo->pStUpdated, pInfo->pUpdated); + removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); + tSimpleHashCleanup(pInfo->pStUpdated); + pInfo->pStUpdated = NULL; + initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity); + +#if 0 + char* pBuf = streamStateSessionDump(pAggSup->pState); + qDebug("===stream===semi session%s", pBuf); + taosMemoryFree(pBuf); +#endif + + doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, "semi session", GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + + doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, "semi session delete", GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + clearFunctionContext(&pOperator->exprSupp); + // semi interval operator clear disk buffer + clearStreamSessionOperator(pInfo); + setOperatorCompleted(pOperator); + return NULL; +} + +SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo, int32_t numOfChild, SReadHandle* pHandle) { + int32_t code = TSDB_CODE_OUT_OF_MEMORY; + SOperatorInfo* pOperator = createStreamSessionAggOperatorInfo(downstream, pPhyNode, pTaskInfo, pHandle); + if (pOperator == NULL) { + goto _error; + } + + SStorageAPI* pAPI = &pTaskInfo->storageAPI; + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + + pInfo->isFinal = (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION); + char* name = (pInfo->isFinal) ? "StreamSessionFinalAggOperator" : "StreamSessionSemiAggOperator"; + + if (pPhyNode->type != QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) { + pInfo->pUpdateRes = createSpecialDataBlock(STREAM_CLEAR); + blockDataEnsureCapacity(pInfo->pUpdateRes, 128); + pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionSemiAgg, NULL, + destroyStreamSessionAggOperatorInfo, optrDefaultBufFn, NULL); + } + setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); + setOperatorInfo(pOperator, name, pPhyNode->type, false, OP_NOT_OPENED, pInfo, pTaskInfo); + + pOperator->operatorType = pPhyNode->type; + if (numOfChild > 0) { + pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*)); + for (int32_t i = 0; i < numOfChild; i++) { + SOperatorInfo* pChildOp = createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0, NULL); + if (pChildOp == NULL) { + goto _error; + } + SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info; + pChInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; + pAPI->stateStore.streamStateSetNumber(pChInfo->streamAggSup.pState, i); + taosArrayPush(pInfo->pChildren, &pChildOp); + } + } + + if (!IS_FINAL_OP(pInfo) || numOfChild == 0) { + pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; + } + + return pOperator; + +_error: + if (pInfo != NULL) { + destroyStreamSessionAggOperatorInfo(pInfo); + } + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} + +void destroyStreamStateOperatorInfo(void* param) { + SStreamStateAggOperatorInfo* pInfo = (SStreamStateAggOperatorInfo*)param; + cleanupBasicInfo(&pInfo->binfo); + destroyStreamAggSupporter(&pInfo->streamAggSup); + cleanupGroupResInfo(&pInfo->groupResInfo); + if (pInfo->pChildren != NULL) { + int32_t size = taosArrayGetSize(pInfo->pChildren); + for (int32_t i = 0; i < size; i++) { + SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i); + destroyOperator(pChild); + } + taosArrayDestroy(pInfo->pChildren); + } + colDataDestroy(&pInfo->twAggSup.timeWindowData); + blockDataDestroy(pInfo->pDelRes); + taosArrayDestroy(pInfo->historyWins); + tSimpleHashCleanup(pInfo->pSeUpdated); + tSimpleHashCleanup(pInfo->pSeDeleted); + taosMemoryFreeClear(param); +} + +bool isTsInWindow(SStateWindowInfo* pWin, TSKEY ts) { + if (pWin->winInfo.sessionWin.win.skey <= ts && ts <= pWin->winInfo.sessionWin.win.ekey) { + return true; + } + return false; +} + +bool isEqualStateKey(SStateWindowInfo* pWin, char* pKeyData) { + return pKeyData && compareVal(pKeyData, pWin->pStateKey); +} + +bool compareStateKey(void* data, void* key) { + if (!data || !key) { + return true; + } + SStateKeys* stateKey = (SStateKeys*)key; + stateKey->pData = (char*)key + sizeof(SStateKeys); + return compareVal(data, stateKey); +} + +bool compareWinStateKey(SStateKeys* left, SStateKeys* right) { + if (!left || !right) { + return false; + } + return compareVal(left->pData, right); +} + +void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, char* pKeyData, + SStateWindowInfo* pCurWin, SStateWindowInfo* pNextWin) { + int32_t size = pAggSup->resultRowSize; + pCurWin->winInfo.sessionWin.groupId = groupId; + pCurWin->winInfo.sessionWin.win.skey = ts; + pCurWin->winInfo.sessionWin.win.ekey = ts; + int32_t code = + pAggSup->stateStore.streamStateStateAddIfNotExist(pAggSup->pState, &pCurWin->winInfo.sessionWin, pKeyData, pAggSup->stateKeySize, + compareStateKey, &pCurWin->winInfo.pOutputBuf, &size); + pCurWin->pStateKey = + (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); + pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); + pCurWin->pStateKey->type = pAggSup->stateKeyType; + pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); + pCurWin->pStateKey->isNull = false; + + if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->winInfo.sessionWin.win)) { + code = TSDB_CODE_FAILED; + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->winInfo.pOutputBuf, &pAggSup->pSessionAPI->stateStore); + pCurWin->winInfo.pOutputBuf = taosMemoryCalloc(1, size); + pCurWin->pStateKey = + (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); + pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); + pCurWin->pStateKey->type = pAggSup->stateKeyType; + pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); + pCurWin->pStateKey->isNull = false; + pCurWin->winInfo.sessionWin.groupId = groupId; + pCurWin->winInfo.sessionWin.win.skey = ts; + pCurWin->winInfo.sessionWin.win.ekey = ts; + qDebug("===stream===reset state win key. skey:%" PRId64 ", endkey:%" PRId64, pCurWin->winInfo.sessionWin.win.skey, pCurWin->winInfo.sessionWin.win.ekey); + } + + if (code == TSDB_CODE_SUCCESS) { + pCurWin->winInfo.isOutput = true; + pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &pCurWin->winInfo.sessionWin); + } else if (pKeyData) { + if (IS_VAR_DATA_TYPE(pAggSup->stateKeyType)) { + varDataCopy(pCurWin->pStateKey->pData, pKeyData); + } else { + memcpy(pCurWin->pStateKey->pData, pKeyData, pCurWin->pStateKey->bytes); + } + } + + pNextWin->winInfo.sessionWin = pCurWin->winInfo.sessionWin; + SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pNextWin->winInfo.sessionWin); + int32_t nextSize = pAggSup->resultRowSize; + code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->winInfo.sessionWin, &pNextWin->winInfo.pOutputBuf, &nextSize); + if (code != TSDB_CODE_SUCCESS) { + SET_SESSION_WIN_INVALID(pNextWin->winInfo); + } else { + pNextWin->pStateKey = + (SStateKeys*)((char*)pNextWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); + pNextWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); + pNextWin->pStateKey->type = pAggSup->stateKeyType; + pNextWin->pStateKey->pData = (char*)pNextWin->pStateKey + sizeof(SStateKeys); + pNextWin->pStateKey->isNull = false; + pNextWin->winInfo.isOutput = true; + } + pAggSup->stateStore.streamStateFreeCur(pCur); +} + +int32_t updateStateWindowInfo(SStateWindowInfo* pWinInfo, SStateWindowInfo* pNextWin, TSKEY* pTs, uint64_t groupId, + SColumnInfoData* pKeyCol, int32_t rows, int32_t start, bool* allEqual, + SSHashObj* pResultRows, SSHashObj* pSeUpdated, SSHashObj* pSeDeleted) { + *allEqual = true; + for (int32_t i = start; i < rows; ++i) { + char* pKeyData = colDataGetData(pKeyCol, i); + if (!isTsInWindow(pWinInfo, pTs[i])) { + if (isEqualStateKey(pWinInfo, pKeyData)) { + if (IS_VALID_SESSION_WIN(pNextWin->winInfo)) { + // ts belongs to the next window + if (pTs[i] >= pNextWin->winInfo.sessionWin.win.skey) { + return i - start; + } + } + } else { + return i - start; + } + } + + if (pWinInfo->winInfo.sessionWin.win.skey > pTs[i]) { + if (pSeDeleted && pWinInfo->winInfo.isOutput) { + saveDeleteRes(pSeDeleted, pWinInfo->winInfo.sessionWin); + } + removeSessionResult(pSeUpdated, pResultRows, pWinInfo->winInfo.sessionWin); + pWinInfo->winInfo.sessionWin.win.skey = pTs[i]; + } + pWinInfo->winInfo.sessionWin.win.ekey = TMAX(pWinInfo->winInfo.sessionWin.win.ekey, pTs[i]); + if (!isEqualStateKey(pWinInfo, pKeyData)) { + *allEqual = false; + } + } + return rows - start; +} + +static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pSeUpdated, + SSHashObj* pStDeleted) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + uint64_t groupId = pSDataBlock->info.id.groupId; + int64_t code = TSDB_CODE_SUCCESS; + TSKEY* tsCols = NULL; + SResultRow* pResult = NULL; + int32_t winRows = 0; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + + pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); + pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow; + if (pAggSup->winRange.ekey <= 0) { + pAggSup->winRange.ekey = INT64_MAX; + } + + if (pSDataBlock->pDataBlock != NULL) { + SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); + tsCols = (int64_t*)pColDataInfo->pData; + } else { + return; + } + + int32_t rows = pSDataBlock->info.rows; + blockDataEnsureCapacity(pAggSup->pScanBlock, rows); + SColumnInfoData* pKeyColInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->stateCol.slotId); + for (int32_t i = 0; i < rows; i += winRows) { + if (pInfo->ignoreExpiredData && isOverdue(tsCols[i], &pInfo->twAggSup) || colDataIsNull_s(pKeyColInfo, i)) { + i++; + continue; + } + char* pKeyData = colDataGetData(pKeyColInfo, i); + int32_t winIndex = 0; + bool allEqual = true; + SStateWindowInfo curWin = {0}; + SStateWindowInfo nextWin = {0}; + setStateOutputBuf(pAggSup, tsCols[i], groupId, pKeyData, &curWin, &nextWin); + if (IS_VALID_SESSION_WIN(nextWin.winInfo)) { + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextWin.winInfo.pOutputBuf, &pAPI->stateStore); + } + setSessionWinOutputInfo(pSeUpdated, &curWin.winInfo); + winRows = updateStateWindowInfo(&curWin, &nextWin, tsCols, groupId, pKeyColInfo, rows, i, &allEqual, + pAggSup->pResultRows, pSeUpdated, pStDeleted); + if (!allEqual) { + uint64_t uid = 0; + appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey, + &curWin.winInfo.sessionWin.win.ekey, &uid, &groupId, NULL); + tSimpleHashRemove(pSeUpdated, &curWin.winInfo.sessionWin, sizeof(SSessionKey)); + doDeleteSessionWindow(pAggSup, &curWin.winInfo.sessionWin); + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)curWin.winInfo.pOutputBuf, &pAPI->stateStore); + continue; + } + code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput, + pOperator, 0); + if (code != TSDB_CODE_SUCCESS || pResult == NULL) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + saveSessionOutputBuf(pAggSup, &curWin.winInfo); + + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { + code = saveResult(curWin.winInfo, pSeUpdated); + if (code != TSDB_CODE_SUCCESS) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + } + + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + SSessionKey key = {0}; + getSessionHashKey(&curWin.winInfo.sessionWin, &key); + tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curWin.winInfo, sizeof(SResultWindowInfo)); + } + } +} + +static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SExprSupp* pSup = &pOperator->exprSupp; + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + qDebug("===stream=== stream state agg"); + if (pOperator->status == OP_RES_TO_RETURN) { + doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, "single state delete", GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, "single state", GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + + setOperatorCompleted(pOperator); + return NULL; + } + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); + } + if (!pInfo->pSeUpdated) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pSeUpdated = tSimpleHashInit(64, hashFn); + } + while (1) { + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + break; + } + printDataBlock(pBlock, "single state recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); + doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins); + removeSessionResults(pInfo->pSeUpdated, pWins); + copyDeleteWindowInfo(pWins, pInfo->pSeDeleted); + taosArrayDestroy(pWins); + continue; + } else if (pBlock->info.type == STREAM_GET_ALL) { + getAllSessionWindow(pInfo->streamAggSup.pResultRows, pInfo->pSeUpdated); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamStateAggImpl(pOperator, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + } + // restore the value + pOperator->status = OP_RES_TO_RETURN; + + closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pInfo->pSeUpdated); + copyUpdateResult(pInfo->pSeUpdated, pInfo->pUpdated); + removeSessionResults(pInfo->pSeDeleted, pInfo->pUpdated); + tSimpleHashCleanup(pInfo->pSeUpdated); + pInfo->pSeUpdated = NULL; + + if(pInfo->isHistoryOp) { + getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); + } + + initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); + +#if 0 + char* pBuf = streamStateSessionDump(pInfo->streamAggSup.pState); + qDebug("===stream===final session%s", pBuf); + taosMemoryFree(pBuf); +#endif + + doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, "single state delete", GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, "single state", GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + setOperatorCompleted(pOperator); + return NULL; +} + +void streamStateReleaseState(SOperatorInfo* pOperator) { + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); + qDebug("===stream=== relase state. save result count:%d", (int32_t)taosArrayGetSize(pInfo->historyWins)); + pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_STATE_OP_STATE_NAME, strlen(STREAM_STATE_OP_STATE_NAME), pInfo->historyWins->pData, resSize); + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +static void compactStateWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SResultWindowInfo* pNextWin, + SSHashObj* pStUpdated, SSHashObj* pStDeleted) { + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SResultRow* pCurResult = NULL; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); + SResultRow* pWinResult = NULL; + initSessionOutputBuf(pNextWin, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); + pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, pNextWin->sessionWin.win.ekey); + + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, 1); + compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); + tSimpleHashRemove(pStUpdated, &pNextWin->sessionWin, sizeof(SSessionKey)); + if (pNextWin->isOutput && pStDeleted) { + qDebug("===stream=== save delete window info %" PRId64 ", %" PRIu64, pNextWin->sessionWin.win.skey, pNextWin->sessionWin.groupId); + saveDeleteRes(pStDeleted, pNextWin->sessionWin); + } + removeSessionResult(pStUpdated, pAggSup->pResultRows, pNextWin->sessionWin); + doDeleteSessionWindow(pAggSup, &pNextWin->sessionWin); + taosMemoryFree(pNextWin->pOutputBuf); +} + +void streamStateReloadState(SOperatorInfo* pOperator) { + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + resetWinRange(&pAggSup->winRange); + + SSessionKey seKey = {.win.skey = INT64_MIN, .win.ekey = INT64_MIN, .groupId = 0}; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_STATE_OP_STATE_NAME, + strlen(STREAM_STATE_OP_STATE_NAME), &pBuf, &size); + int32_t num = size / sizeof(SSessionKey); + qDebug("===stream=== reload state. get result count:%d", num); + SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; + ASSERT(size == num * sizeof(SSessionKey)); + if (!pInfo->pSeUpdated && num > 0) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pSeUpdated = tSimpleHashInit(64, hashFn); + } + if (!pInfo->pSeDeleted && num > 0) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pSeDeleted = tSimpleHashInit(64, hashFn); + } + for (int32_t i = 0; i < num; i++) { + SStateWindowInfo curInfo = {0}; + SStateWindowInfo nextInfo = {0}; + SStateWindowInfo dummy = {0}; + qDebug("===stream=== reload state. try process result %" PRId64 ", %" PRIu64 ", index:%d", pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, i); + setStateOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, NULL, &curInfo, &nextInfo); + bool cpRes = compareWinStateKey(curInfo.pStateKey,nextInfo.pStateKey); + qDebug("===stream=== reload state. next window info %" PRId64 ", %" PRIu64 ", compare:%d", nextInfo.winInfo.sessionWin.win.skey, nextInfo.winInfo.sessionWin.groupId, cpRes); + if (cpRes) { + compactStateWindow(pOperator, &curInfo.winInfo, &nextInfo.winInfo, pInfo->pSeUpdated, pInfo->pSeDeleted); + qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, curInfo.winInfo.sessionWin.win.skey, curInfo.winInfo.sessionWin.groupId); + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { + saveResult(curInfo.winInfo, pInfo->pSeUpdated); + } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + if (!isCloseWindow(&curInfo.winInfo.sessionWin.win, &pInfo->twAggSup)) { + saveDeleteRes(pInfo->pSeDeleted, curInfo.winInfo.sessionWin); + } + SSessionKey key = {0}; + getSessionHashKey(&curInfo.winInfo.sessionWin, &key); + tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curInfo.winInfo, sizeof(SResultWindowInfo)); + } + } else if (IS_VALID_SESSION_WIN(nextInfo.winInfo)) { + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextInfo.winInfo.pOutputBuf, &pAggSup->pSessionAPI->stateStore); + } + + if (IS_VALID_SESSION_WIN(curInfo.winInfo)) { + saveSessionOutputBuf(pAggSup, &curInfo.winInfo); + } + } + taosMemoryFree(pBuf); + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + +SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { + SStreamStateWinodwPhysiNode* pStateNode = (SStreamStateWinodwPhysiNode*)pPhyNode; + int32_t tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId; + SColumnNode* pColNode = (SColumnNode*)(pStateNode->pStateKey); + int32_t code = TSDB_CODE_SUCCESS; + + SStreamStateAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamStateAggOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _error; + } + + pInfo->stateCol = extractColumnFromColumnNode(pColNode); + initResultSizeInfo(&pOperator->resultInfo, 4096); + if (pStateNode->window.pExprs != NULL) { + int32_t numOfScalar = 0; + SExprInfo* pScalarExprInfo = createExprInfo(pStateNode->window.pExprs, NULL, &numOfScalar); + code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + } + + pInfo->twAggSup = (STimeWindowAggSupp){ + .waterMark = pStateNode->window.watermark, + .calTrigger = pStateNode->window.triggerType, + .maxTs = INT64_MIN, + .minTs = INT64_MAX, + }; + + initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); + + SExprSupp* pSup = &pOperator->exprSupp; + int32_t numOfCols = 0; + SExprInfo* pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &numOfCols); + SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); + code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + int32_t keySize = sizeof(SStateKeys) + pColNode->node.resType.bytes; + int16_t type = pColNode->node.resType.type; + code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, 0, pTaskInfo->streamInfo.pState, keySize, + type, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + pInfo->primaryTsIndex = tsSlotId; + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pSeDeleted = tSimpleHashInit(64, hashFn); + pInfo->pDelIterator = NULL; + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + pInfo->pChildren = NULL; + pInfo->ignoreExpiredData = pStateNode->window.igExpired; + pInfo->ignoreExpiredDataSaved = false; + pInfo->pUpdated = NULL; + pInfo->pSeUpdated = NULL; + pInfo->dataVersion = 0; + pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); + if (!pInfo->historyWins) { + goto _error; + } + if (pHandle) { + pInfo->isHistoryOp = pHandle->fillHistory; + } + + setOperatorInfo(pOperator, "StreamStateAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE, true, OP_NOT_OPENED, + pInfo, pTaskInfo); + pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamStateAgg, NULL, destroyStreamStateOperatorInfo, + optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamStateReleaseState, streamStateReloadState); + initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); + code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + return pOperator; + +_error: + destroyStreamStateOperatorInfo(pInfo); + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} + +static void cleanupAfterGroupResultGen(SMergeAlignedIntervalAggOperatorInfo* pMiaInfo, SSDataBlock* pRes) { + pRes->info.id.groupId = pMiaInfo->groupId; + pMiaInfo->curTs = INT64_MIN; + pMiaInfo->groupId = 0; +} + +static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type) { + for (int i = 0; i < num; i++) { + if (type == STREAM_INVERT) { + fmSetInvertFunc(pCtx[i].functionId, &(pCtx[i].fpSet)); + } else if (type == STREAM_NORMAL) { + fmSetNormalFunc(pCtx[i].functionId, &(pCtx[i].fpSet)); + } + } +} + +static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SExprSupp* pSup = &pOperator->exprSupp; + + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + if (pOperator->status == OP_RES_TO_RETURN) { + doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, "single interval delete", GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); + if (pInfo->binfo.pRes->info.rows > 0) { + printDataBlock(pInfo->binfo.pRes, "single interval", GET_TASKID(pTaskInfo)); + return pInfo->binfo.pRes; + } + + if (pInfo->recvGetAll) { + pInfo->recvGetAll = false; + resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable); + } + + setOperatorCompleted(pOperator); + if (pInfo->twAggSup.maxTs > 0 && + pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) { + pAPI->stateStore.streamStateCommit(pInfo->pState); + pAPI->stateStore.streamStateDeleteCheckPoint(pInfo->pState, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark); + setStreamDataVersion(pTaskInfo, pInfo->dataVersion, pInfo->pState->checkPointId); + pInfo->twAggSup.checkPointTs = pInfo->twAggSup.maxTs; + } + return NULL; + } + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(4096, POINTER_BYTES); + } + + if (!pInfo->pUpdatedMap) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pUpdatedMap = tSimpleHashInit(4096, hashFn); + } + + while (1) { + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + qDebug("===stream===return data:single interval. recv datablock num:%" PRIu64, pInfo->numOfDatapack); + pInfo->numOfDatapack = 0; + break; + } + + pInfo->numOfDatapack++; + printDataBlock(pBlock, "single interval recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + doDeleteWindows(pOperator, &pInfo->interval, pBlock, pInfo->pDelWins, pInfo->pUpdatedMap); + continue; + } else if (pBlock->info.type == STREAM_GET_ALL) { + qDebug("===stream===single interval recv|block type STREAM_GET_ALL"); + pInfo->recvGetAll = true; + getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + printDataBlock(pBlock, "single interval", GET_TASKID(pTaskInfo)); + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pBlock->info.type == STREAM_NORMAL && pBlock->info.version != 0) { + // set input version + pTaskInfo->version = pBlock->info.version; + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + + // The timewindow that overlaps the timestamps of the input pBlock need to be recalculated and return to the + // caller. Note that all the time window are not close till now. + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + if (pInfo->invertible) { + setInverFunction(pSup->pCtx, pOperator->exprSupp.numOfExprs, pBlock->info.type); + } + + doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey); + } + pOperator->status = OP_RES_TO_RETURN; + removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins); + closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL, + pInfo->pUpdatedMap, pInfo->pDelWins, pOperator); + + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pInfo->pUpdatedMap, pIte, &iter)) != NULL) { + taosArrayPush(pInfo->pUpdated, pIte); + } + taosArraySort(pInfo->pUpdated, winPosCmprImpl); + + initMultiResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); + tSimpleHashCleanup(pInfo->pUpdatedMap); + pInfo->pUpdatedMap = NULL; + + doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, "single interval delete", GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); + if (pInfo->binfo.pRes->info.rows > 0) { + printDataBlock(pInfo->binfo.pRes, "single interval", GET_TASKID(pTaskInfo)); + return pInfo->binfo.pRes; + } + + return NULL; +} + +SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo) { + SStreamIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamIntervalOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + SStreamIntervalPhysiNode* pIntervalPhyNode = (SStreamIntervalPhysiNode*)pPhyNode; + + int32_t code = TSDB_CODE_SUCCESS; + int32_t numOfCols = 0; + SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &numOfCols); + + SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); + pInfo->interval = (SInterval){ + .interval = pIntervalPhyNode->interval, + .sliding = pIntervalPhyNode->sliding, + .intervalUnit = pIntervalPhyNode->intervalUnit, + .slidingUnit = pIntervalPhyNode->slidingUnit, + .offset = pIntervalPhyNode->offset, + .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision, + }; + + pInfo->twAggSup = (STimeWindowAggSupp){ + .waterMark = pIntervalPhyNode->window.watermark, + .calTrigger = pIntervalPhyNode->window.triggerType, + .maxTs = INT64_MIN, + .minTs = INT64_MAX, + .deleteMark = getDeleteMark(pIntervalPhyNode), + .checkPointTs = 0, + .checkPointInterval = + convertTimePrecision(tsCheckpointInterval, TSDB_TIME_PRECISION_MILLI, pInfo->interval.precision), + }; + + ASSERTS(pInfo->twAggSup.calTrigger != STREAM_TRIGGER_MAX_DELAY, "trigger type should not be max delay"); + + pOperator->pTaskInfo = pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + pInfo->ignoreExpiredData = pIntervalPhyNode->window.igExpired; + pInfo->ignoreExpiredDataSaved = false; + pInfo->isFinal = false; + + SExprSupp* pSup = &pOperator->exprSupp; + initBasicInfo(&pInfo->binfo, pResBlock); + initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); + + pInfo->primaryTsIndex = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; + initResultSizeInfo(&pOperator->resultInfo, 4096); + + pInfo->pState = taosMemoryCalloc(1, sizeof(SStreamState)); + *(pInfo->pState) = *(pTaskInfo->streamInfo.pState); + pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1); + + size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; + code = initAggSup(pSup, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, + pInfo->pState, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + if (pIntervalPhyNode->window.pExprs != NULL) { + int32_t numOfScalar = 0; + SExprInfo* pScalarExprInfo = createExprInfo(pIntervalPhyNode->window.pExprs, NULL, &numOfScalar); + code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + } + + pInfo->invertible = false; + pInfo->pDelWins = taosArrayInit(4, sizeof(SWinKey)); + pInfo->delIndex = 0; + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + initResultRowInfo(&pInfo->binfo.resultRowInfo); + + pInfo->pPhyNode = NULL; // create new child + pInfo->pPullDataMap = NULL; + pInfo->pFinalPullDataMap = NULL; + pInfo->pPullWins = NULL; // SPullWindowInfo + pInfo->pullIndex = 0; + pInfo->pPullDataRes = NULL; + pInfo->isFinal = false; + pInfo->numOfChild = 0; + pInfo->delKey.ts = INT64_MAX; + pInfo->delKey.groupId = 0; + pInfo->numOfDatapack = 0; + pInfo->pUpdated = NULL; + pInfo->pUpdatedMap = NULL; + int32_t funResSize= getMaxFunResSize(pSup, numOfCols); + + pInfo->pState->pFileState = pTaskInfo->storageAPI.stateStore.streamFileStateInit( + tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, compareTs, pInfo->pState, + pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); + + setOperatorInfo(pOperator, "StreamIntervalOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL, true, OP_NOT_OPENED, + pInfo, pTaskInfo); + pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamIntervalAgg, NULL, + destroyStreamFinalIntervalOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); + + pInfo->statestore = pTaskInfo->storageAPI.stateStore; + pInfo->recvGetAll = false; + + initIntervalDownStream(downstream, pPhyNode->type, pInfo); + code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + return pOperator; + +_error: + destroyStreamFinalIntervalOperatorInfo(pInfo); + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 992147ab10..9e5cea2afd 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -26,17 +26,6 @@ #include "tlog.h" #include "ttime.h" -#define IS_FINAL_OP(op) ((op)->isFinal) -#define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL); -#define STREAM_INTERVAL_OP_STATE_NAME "StreamIntervalHistoryState" -#define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState" -#define STREAM_STATE_OP_STATE_NAME "StreamStateHistoryState" - -typedef struct SStateWindowInfo { - SResultWindowInfo winInfo; - SStateKeys* pStateKey; -} SStateWindowInfo; - typedef struct SSessionAggOperatorInfo { SOptrBasicInfo binfo; SAggSupporter aggSup; @@ -66,11 +55,6 @@ typedef enum SResultTsInterpType { RESULT_ROW_END_INTERP = 2, } SResultTsInterpType; -typedef struct SPullWindowInfo { - STimeWindow window; - uint64_t groupId; - STimeWindow calWin; -} SPullWindowInfo; typedef struct SOpenWindowInfo { SResultRowPosition pos; @@ -83,8 +67,6 @@ static SResultRowPosition addToOpenWindowList(SResultRowInfo* pResultRowInfo, co uint64_t groupId); static void doCloseWindow(SResultRowInfo* pResultRowInfo, const SIntervalAggOperatorInfo* pInfo, SResultRow* pResult); -static TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols) { return tsCols == NULL ? win->skey : tsCols[0]; } - static int32_t setTimeWindowOutputBuf(SResultRowInfo* pResultRowInfo, STimeWindow* win, bool masterscan, SResultRow** pResult, int64_t tableGroupId, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, SAggSupporter* pAggSup, @@ -106,15 +88,6 @@ static int32_t setTimeWindowOutputBuf(SResultRowInfo* pResultRowInfo, STimeWindo return TSDB_CODE_SUCCESS; } -static void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, int64_t delta) { - int64_t* ts = (int64_t*)pColData->pData; - - int64_t duration = pWin->ekey - pWin->skey + delta; - ts[2] = duration; // set the duration - ts[3] = pWin->skey; // window start key - ts[4] = pWin->ekey + delta; // window end key -} - static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts, uint64_t groupId) { pRowSup->win.ekey = ts; pRowSup->prevTs = ts; @@ -426,7 +399,7 @@ bool inSlidingWindow(SInterval* pInterval, STimeWindow* pWin, SDataBlockInfo* pB return inCalSlidingWindow(pInterval, pWin, pBlockInfo->calWin.skey, pBlockInfo->calWin.ekey, pBlockInfo->type); } -static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, +int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, TSKEY* primaryKeys, int32_t prevPosition, int32_t order) { bool ascQuery = (order == TSDB_ORDER_ASC); @@ -658,224 +631,6 @@ static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t num } } -typedef int32_t (*__compare_fn_t)(void* pKey, void* data, int32_t index); - -int32_t binarySearchCom(void* keyList, int num, void* pKey, int order, __compare_fn_t comparefn) { - int firstPos = 0, lastPos = num - 1, midPos = -1; - int numOfRows = 0; - - if (num <= 0) return -1; - if (order == TSDB_ORDER_DESC) { - // find the first position which is smaller or equal than the key - while (1) { - if (comparefn(pKey, keyList, lastPos) >= 0) return lastPos; - if (comparefn(pKey, keyList, firstPos) == 0) return firstPos; - if (comparefn(pKey, keyList, firstPos) < 0) return firstPos - 1; - - numOfRows = lastPos - firstPos + 1; - midPos = (numOfRows >> 1) + firstPos; - - if (comparefn(pKey, keyList, midPos) < 0) { - lastPos = midPos - 1; - } else if (comparefn(pKey, keyList, midPos) > 0) { - firstPos = midPos + 1; - } else { - break; - } - } - - } else { - // find the first position which is bigger or equal than the key - while (1) { - if (comparefn(pKey, keyList, firstPos) <= 0) return firstPos; - if (comparefn(pKey, keyList, lastPos) == 0) return lastPos; - - if (comparefn(pKey, keyList, lastPos) > 0) { - lastPos = lastPos + 1; - if (lastPos >= num) - return -1; - else - return lastPos; - } - - numOfRows = lastPos - firstPos + 1; - midPos = (numOfRows >> 1) + firstPos; - - if (comparefn(pKey, keyList, midPos) < 0) { - lastPos = midPos - 1; - } else if (comparefn(pKey, keyList, midPos) > 0) { - firstPos = midPos + 1; - } else { - break; - } - } - } - - return midPos; -} - -typedef int64_t (*__get_value_fn_t)(void* data, int32_t index); - -int32_t binarySearch(void* keyList, int num, TSKEY key, int order, __get_value_fn_t getValuefn) { - int firstPos = 0, lastPos = num - 1, midPos = -1; - int numOfRows = 0; - - if (num <= 0) return -1; - if (order == TSDB_ORDER_DESC) { - // find the first position which is smaller or equal than the key - while (1) { - if (key >= getValuefn(keyList, lastPos)) return lastPos; - if (key == getValuefn(keyList, firstPos)) return firstPos; - if (key < getValuefn(keyList, firstPos)) return firstPos - 1; - - numOfRows = lastPos - firstPos + 1; - midPos = (numOfRows >> 1) + firstPos; - - if (key < getValuefn(keyList, midPos)) { - lastPos = midPos - 1; - } else if (key > getValuefn(keyList, midPos)) { - firstPos = midPos + 1; - } else { - break; - } - } - - } else { - // find the first position which is bigger or equal than the key - while (1) { - if (key <= getValuefn(keyList, firstPos)) return firstPos; - if (key == getValuefn(keyList, lastPos)) return lastPos; - - if (key > getValuefn(keyList, lastPos)) { - lastPos = lastPos + 1; - if (lastPos >= num) - return -1; - else - return lastPos; - } - - numOfRows = lastPos - firstPos + 1; - midPos = (numOfRows >> 1) + firstPos; - - if (key < getValuefn(keyList, midPos)) { - lastPos = midPos - 1; - } else if (key > getValuefn(keyList, midPos)) { - firstPos = midPos + 1; - } else { - break; - } - } - } - - return midPos; -} - -int32_t comparePullWinKey(void* pKey, void* data, int32_t index) { - SArray* res = (SArray*)data; - SPullWindowInfo* pos = taosArrayGet(res, index); - SPullWindowInfo* pData = (SPullWindowInfo*)pKey; - if (pData->groupId > pos->groupId) { - return 1; - } else if (pData->groupId < pos->groupId) { - return -1; - } - - if (pData->window.skey > pos->window.ekey) { - return 1; - } else if (pData->window.ekey < pos->window.skey) { - return -1; - } - return 0; -} - -static int32_t savePullWindow(SPullWindowInfo* pPullInfo, SArray* pPullWins) { - int32_t size = taosArrayGetSize(pPullWins); - int32_t index = binarySearchCom(pPullWins, size, pPullInfo, TSDB_ORDER_DESC, comparePullWinKey); - if (index == -1) { - index = 0; - } else { - int32_t code = comparePullWinKey(pPullInfo, pPullWins, index); - if (code == 0) { - SPullWindowInfo* pos = taosArrayGet(pPullWins, index); - pos->window.skey = TMIN(pos->window.skey, pPullInfo->window.skey); - pos->window.ekey = TMAX(pos->window.ekey, pPullInfo->window.ekey); - pos->calWin.skey = TMIN(pos->calWin.skey, pPullInfo->calWin.skey); - pos->calWin.ekey = TMAX(pos->calWin.ekey, pPullInfo->calWin.ekey); - return TSDB_CODE_SUCCESS; - } else if (code > 0) { - index++; - } - } - if (taosArrayInsert(pPullWins, index, pPullInfo) == NULL) { - return TSDB_CODE_OUT_OF_MEMORY; - } - return TSDB_CODE_SUCCESS; -} - -static int32_t saveResult(SResultWindowInfo winInfo, SSHashObj* pStUpdated) { - winInfo.sessionWin.win.ekey = winInfo.sessionWin.win.skey; - return tSimpleHashPut(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); -} - -static int32_t saveWinResult(SWinKey* pKey, SRowBuffPos* pPos, SSHashObj* pUpdatedMap) { - tSimpleHashPut(pUpdatedMap, pKey, sizeof(SWinKey), &pPos, POINTER_BYTES); - return TSDB_CODE_SUCCESS; -} - -static int32_t saveWinResultInfo(TSKEY ts, uint64_t groupId, SRowBuffPos* pPos, SSHashObj* pUpdatedMap) { - SWinKey key = {.ts = ts, .groupId = groupId}; - saveWinResult(&key, pPos, pUpdatedMap); - return TSDB_CODE_SUCCESS; -} - -static void removeResults(SArray* pWins, SSHashObj* pUpdatedMap) { - int32_t size = taosArrayGetSize(pWins); - for (int32_t i = 0; i < size; i++) { - SWinKey* pW = taosArrayGet(pWins, i); - void* tmp = tSimpleHashGet(pUpdatedMap, pW, sizeof(SWinKey)); - if (tmp) { - void* value = *(void**)tmp; - taosMemoryFree(value); - tSimpleHashRemove(pUpdatedMap, pW, sizeof(SWinKey)); - } - } -} - -int32_t compareWinKey(void* pKey, void* data, int32_t index) { - void* pDataPos = taosArrayGet((SArray*)data, index); - return winKeyCmprImpl(pKey, pDataPos); -} - -static void removeDeleteResults(SSHashObj* pUpdatedMap, SArray* pDelWins) { - taosArraySort(pDelWins, winKeyCmprImpl); - taosArrayRemoveDuplicate(pDelWins, winKeyCmprImpl, NULL); - int32_t delSize = taosArrayGetSize(pDelWins); - if (tSimpleHashGetSize(pUpdatedMap) == 0 || delSize == 0) { - return; - } - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pUpdatedMap, pIte, &iter)) != NULL) { - SWinKey* pResKey = tSimpleHashGetKey(pIte, NULL); - int32_t index = binarySearchCom(pDelWins, delSize, pResKey, TSDB_ORDER_DESC, compareWinKey); - if (index >= 0 && 0 == compareWinKey(pResKey, pDelWins, index)) { - taosArrayRemove(pDelWins, index); - delSize = taosArrayGetSize(pDelWins); - } - } -} - -bool isOverdue(TSKEY ekey, STimeWindowAggSupp* pTwSup) { - ASSERTS(pTwSup->maxTs == INT64_MIN || pTwSup->maxTs > 0, "maxts should greater than 0"); - return pTwSup->maxTs != INT64_MIN && ekey < pTwSup->maxTs - pTwSup->waterMark; -} - -bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pTwSup) { return isOverdue(pWin->ekey, pTwSup); } - -bool needDeleteWindowBuf(STimeWindow* pWin, STimeWindowAggSupp* pTwSup) { - return pTwSup->maxTs != INT64_MIN && pWin->ekey < pTwSup->maxTs - pTwSup->deleteMark; -} - static bool tsKeyCompFn(void* l, void* r, void* param) { TSKEY* lTS = (TSKEY*)l; TSKEY* rTS = (TSKEY*)r; @@ -1127,18 +882,6 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) { return TSDB_CODE_SUCCESS; } -static bool compareVal(const char* v, const SStateKeys* pKey) { - if (IS_VAR_DATA_TYPE(pKey->type)) { - if (varDataLen(v) != varDataLen(pKey->pData)) { - return false; - } else { - return memcmp(varDataVal(v), varDataVal(pKey->pData), varDataLen(v)) == 0; - } - } else { - return memcmp(pKey->pData, v, pKey->bytes) == 0; - } -} - static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo* pInfo, SSDataBlock* pBlock) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExprSupp* pSup = &pOperator->exprSupp; @@ -1373,169 +1116,6 @@ static void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf, releaseBufPage(pResultBuf, bufPage); } -static bool doDeleteWindow(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId) { - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SWinKey key = {.ts = ts, .groupId = groupId}; - tSimpleHashRemove(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey)); - pAPI->stateStore.streamStateDel(pInfo->pState, &key); - return true; -} - -static int32_t getChildIndex(SSDataBlock* pBlock) { return pBlock->info.childId; } - -static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDataBlock* pBlock, SArray* pUpWins, - SSHashObj* pUpdatedMap) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); - TSKEY* startTsCols = (TSKEY*)pStartTsCol->pData; - SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); - TSKEY* endTsCols = (TSKEY*)pEndTsCol->pData; - SColumnInfoData* pCalStTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); - TSKEY* calStTsCols = (TSKEY*)pCalStTsCol->pData; - SColumnInfoData* pCalEnTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); - TSKEY* calEnTsCols = (TSKEY*)pCalEnTsCol->pData; - SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - uint64_t* pGpDatas = (uint64_t*)pGpCol->pData; - for (int32_t i = 0; i < pBlock->info.rows; i++) { - SResultRowInfo dumyInfo = {0}; - dumyInfo.cur.pageId = -1; - - STimeWindow win = {0}; - if (IS_FINAL_OP(pInfo)) { - win.skey = startTsCols[i]; - win.ekey = endTsCols[i]; - } else { - win = getActiveTimeWindow(NULL, &dumyInfo, startTsCols[i], pInterval, TSDB_ORDER_ASC); - } - - do { - if (!inCalSlidingWindow(pInterval, &win, calStTsCols[i], calEnTsCols[i], pBlock->info.type)) { - getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); - continue; - } - uint64_t winGpId = pGpDatas[i]; - SWinKey winRes = {.ts = win.skey, .groupId = winGpId}; - void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey)); - if (chIds) { - int32_t childId = getChildIndex(pBlock); - SArray* chArray = *(void**)chIds; - int32_t index = taosArraySearchIdx(chArray, &childId, compareInt32Val, TD_EQ); - if (index != -1) { - qDebug("===stream===try push delete window%" PRId64 "chId:%d ,continue", win.skey, childId); - getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); - continue; - } - } - bool res = doDeleteWindow(pOperator, win.skey, winGpId); - if (pUpWins && res) { - taosArrayPush(pUpWins, &winRes); - } - if (pUpdatedMap) { - tSimpleHashRemove(pUpdatedMap, &winRes, sizeof(SWinKey)); - } - getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); - } while (win.ekey <= endTsCols[i]); - } -} - -static int32_t getAllIntervalWindow(SSHashObj* pHashMap, SSHashObj* resWins) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { - SWinKey* pKey = tSimpleHashGetKey(pIte, NULL); - uint64_t groupId = pKey->groupId; - TSKEY ts = pKey->ts; - int32_t code = saveWinResultInfo(ts, groupId, *(SRowBuffPos**)pIte, resWins); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } - return TSDB_CODE_SUCCESS; -} - -static int32_t closeStreamIntervalWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SInterval* pInterval, - SHashObj* pPullDataMap, SSHashObj* closeWins, SArray* pDelWins, - SOperatorInfo* pOperator) { - qDebug("===stream===close interval window"); - void* pIte = NULL; - int32_t iter = 0; - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - int32_t delSize = taosArrayGetSize(pDelWins); - while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { - void* key = tSimpleHashGetKey(pIte, NULL); - SWinKey* pWinKey = (SWinKey*)key; - if (delSize > 0) { - int32_t index = binarySearchCom(pDelWins, delSize, pWinKey, TSDB_ORDER_DESC, compareWinKey); - if (index >= 0 && 0 == compareWinKey(pWinKey, pDelWins, index)) { - taosArrayRemove(pDelWins, index); - delSize = taosArrayGetSize(pDelWins); - } - } - - void* chIds = taosHashGet(pPullDataMap, pWinKey, sizeof(SWinKey)); - STimeWindow win = { - .skey = pWinKey->ts, - .ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1, - }; - if (isCloseWindow(&win, pTwSup)) { - if (chIds && pPullDataMap) { - SArray* chAy = *(SArray**)chIds; - int32_t size = taosArrayGetSize(chAy); - qDebug("===stream===window %" PRId64 " wait child size:%d", pWinKey->ts, size); - for (int32_t i = 0; i < size; i++) { - qDebug("===stream===window %" PRId64 " wait child id:%d", pWinKey->ts, *(int32_t*)taosArrayGet(chAy, i)); - } - continue; - } else if (pPullDataMap) { - qDebug("===stream===close window %" PRId64, pWinKey->ts); - } - - if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - int32_t code = saveWinResult(pWinKey, *(SRowBuffPos**)pIte, closeWins); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } - tSimpleHashIterateRemove(pHashMap, pWinKey, sizeof(SWinKey), &pIte, &iter); - } - } - return TSDB_CODE_SUCCESS; -} - -STimeWindow getFinalTimeWindow(int64_t ts, SInterval* pInterval) { - STimeWindow w = {.skey = ts, .ekey = INT64_MAX}; - w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1; - return w; -} - -static void doBuildDeleteResult(SStreamIntervalOperatorInfo* pInfo, SArray* pWins, int32_t* index, - SSDataBlock* pBlock) { - blockDataCleanup(pBlock); - int32_t size = taosArrayGetSize(pWins); - if (*index == size) { - *index = 0; - taosArrayClear(pWins); - return; - } - blockDataEnsureCapacity(pBlock, size - *index); - uint64_t uid = 0; - for (int32_t i = *index; i < size; i++) { - SWinKey* pWin = taosArrayGet(pWins, i); - void* tbname = NULL; - pInfo->statestore.streamStateGetParName(pInfo->pState, pWin->groupId, &tbname); - if (tbname == NULL) { - appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, NULL); - } else { - char parTbName[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN]; - STR_WITH_MAXSIZE_TO_VARSTR(parTbName, tbname, sizeof(parTbName)); - appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, parTbName); - } - pInfo->statestore.streamStateFreeVal(tbname); - (*index)++; - } -} static void destroyStateWindowOperatorInfo(void* param) { SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*)param; @@ -1573,40 +1153,6 @@ void destroyIntervalOperatorInfo(void* param) { taosMemoryFreeClear(param); } -void destroyStreamFinalIntervalOperatorInfo(void* param) { - SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)param; - cleanupBasicInfo(&pInfo->binfo); - cleanupAggSup(&pInfo->aggSup); - // it should be empty. - void* pIte = NULL; - while ((pIte = taosHashIterate(pInfo->pPullDataMap, pIte)) != NULL) { - taosArrayDestroy(*(void**)pIte); - } - taosHashCleanup(pInfo->pPullDataMap); - taosHashCleanup(pInfo->pFinalPullDataMap); - taosArrayDestroy(pInfo->pPullWins); - blockDataDestroy(pInfo->pPullDataRes); - taosArrayDestroy(pInfo->pDelWins); - blockDataDestroy(pInfo->pDelRes); - pInfo->statestore.streamFileStateDestroy(pInfo->pState->pFileState); - taosMemoryFreeClear(pInfo->pState); - - nodesDestroyNode((SNode*)pInfo->pPhyNode); - colDataDestroy(&pInfo->twAggSup.timeWindowData); - pInfo->groupResInfo.pRows = taosArrayDestroy(pInfo->groupResInfo.pRows); - cleanupExprSupp(&pInfo->scalarSupp); - - taosMemoryFreeClear(param); -} - -static bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) { - for (int32_t i = 0; i < numOfCols; i++) { - if (fmIsUserDefinedFunc(pFCtx[i].functionId) || !fmIsInvertible(pFCtx[i].functionId)) { - return false; - } - } - return true; -} static bool timeWindowinterpNeeded(SqlFunctionCtx* pCtx, int32_t numOfCols, SIntervalAggOperatorInfo* pInfo) { // the primary timestamp column @@ -1662,25 +1208,6 @@ static bool timeWindowinterpNeeded(SqlFunctionCtx* pCtx, int32_t numOfCols, SInt return needed; } -void initIntervalDownStream(SOperatorInfo* downstream, uint16_t type, SStreamIntervalOperatorInfo* pInfo) { - SStateStore* pAPI = &downstream->pTaskInfo->storageAPI.stateStore; - - if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { - initIntervalDownStream(downstream->pDownstream[0], type, pInfo); - return; - } - - SStreamScanInfo* pScanInfo = downstream->info; - pScanInfo->windowSup.parentType = type; - pScanInfo->windowSup.pIntervalAggSup = &pInfo->aggSup; - if (!pScanInfo->pUpdateInfo) { - pScanInfo->pUpdateInfo = pAPI->updateInfoInitP(&pInfo->interval, pInfo->twAggSup.waterMark); - } - - pScanInfo->interval = pInfo->interval; - pScanInfo->twAggSup = pInfo->twAggSup; - pScanInfo->pState = pInfo->pState; -} void initStreamFunciton(SqlFunctionCtx* pCtx, int32_t numOfExpr) { for (int32_t i = 0; i < numOfExpr; i++) { @@ -2088,2543 +1615,6 @@ _error: return NULL; } -void compactFunctions(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx, int32_t numOfOutput, - SExecTaskInfo* pTaskInfo, SColumnInfoData* pTimeWindowData) { - for (int32_t k = 0; k < numOfOutput; ++k) { - if (fmIsWindowPseudoColumnFunc(pDestCtx[k].functionId)) { - if (!pTimeWindowData) { - continue; - } - - SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pDestCtx[k]); - char* p = GET_ROWCELL_INTERBUF(pEntryInfo); - SColumnInfoData idata = {0}; - idata.info.type = TSDB_DATA_TYPE_BIGINT; - idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - idata.pData = p; - - SScalarParam out = {.columnData = &idata}; - SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData}; - pDestCtx[k].sfp.process(&tw, 1, &out); - pEntryInfo->numOfRes = 1; - } else if (functionNeedToExecute(&pDestCtx[k]) && pDestCtx[k].fpSet.combine != NULL) { - int32_t code = pDestCtx[k].fpSet.combine(&pDestCtx[k], &pSourceCtx[k]); - if (code != TSDB_CODE_SUCCESS) { - qError("%s apply combine functions error, code: %s", GET_TASKID(pTaskInfo), tstrerror(code)); - } - } else if (pDestCtx[k].fpSet.combine == NULL) { - char* funName = fmGetFuncName(pDestCtx[k].functionId); - qError("%s error, combine funcion for %s is not implemented", GET_TASKID(pTaskInfo), funName); - taosMemoryFreeClear(funName); - } - } -} - -bool hasIntervalWindow(void* pState, SWinKey* pKey, SStateStore* pStore) { return pStore->streamStateCheck(pState, pKey); } - -int32_t setIntervalOutputBuf(void* pState, STimeWindow* win, SRowBuffPos** pResult, int64_t groupId, - SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, - SAggSupporter* pAggSup, SStateStore* pStore) { - - SWinKey key = { .ts = win->skey, .groupId = groupId }; - char* value = NULL; - int32_t size = pAggSup->resultRowSize; - - if (pStore->streamStateAddIfNotExist(pState, &key, (void**)&value, &size) < 0) { - return TSDB_CODE_OUT_OF_MEMORY; - } - - *pResult = (SRowBuffPos*)value; - SResultRow* res = (SResultRow*)((*pResult)->pRowBuff); - - // set time window for current result - res->win = (*win); - setResultRowInitCtx(res, pCtx, numOfOutput, rowEntryInfoOffset); - return TSDB_CODE_SUCCESS; -} - -bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, void* pState, STimeWindowAggSupp* pTwSup, SStateStore* pStore) { - if (pTwSup->maxTs != INT64_MIN && pWin->ekey < pTwSup->maxTs - pTwSup->deleteMark) { - SWinKey key = {.ts = pWin->skey, .groupId = groupId}; - if (!hasIntervalWindow(pState, &key, pStore)) { - return true; - } - return false; - } - return false; -} - -int32_t getNexWindowPos(SInterval* pInterval, SDataBlockInfo* pBlockInfo, TSKEY* tsCols, int32_t startPos, TSKEY eKey, - STimeWindow* pNextWin) { - int32_t forwardRows = - getNumOfRowsInTimeWindow(pBlockInfo, tsCols, startPos, eKey, binarySearchForKey, NULL, TSDB_ORDER_ASC); - int32_t prevEndPos = forwardRows - 1 + startPos; - return getNextQualifiedWindow(pInterval, pNextWin, pBlockInfo, tsCols, prevEndPos, TSDB_ORDER_ASC); -} - -void addPullWindow(SHashObj* pMap, SWinKey* pWinRes, int32_t size) { - SArray* childIds = taosArrayInit(8, sizeof(int32_t)); - for (int32_t i = 0; i < size; i++) { - taosArrayPush(childIds, &i); - } - taosHashPut(pMap, pWinRes, sizeof(SWinKey), &childIds, sizeof(void*)); -} - -static void clearStreamIntervalOperator(SStreamIntervalOperatorInfo* pInfo) { - tSimpleHashClear(pInfo->aggSup.pResultRowHashTable); - clearDiskbasedBuf(pInfo->aggSup.pResultBuf); - initResultRowInfo(&pInfo->binfo.resultRowInfo); - pInfo->aggSup.currentPageId = -1; - pInfo->statestore.streamStateClear(pInfo->pState); -} - -static void clearSpecialDataBlock(SSDataBlock* pBlock) { - if (pBlock->info.rows <= 0) { - return; - } - blockDataCleanup(pBlock); -} - -static void doBuildPullDataBlock(SArray* array, int32_t* pIndex, SSDataBlock* pBlock) { - clearSpecialDataBlock(pBlock); - int32_t size = taosArrayGetSize(array); - if (size - (*pIndex) == 0) { - return; - } - blockDataEnsureCapacity(pBlock, size - (*pIndex)); - SColumnInfoData* pStartTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); - SColumnInfoData* pEndTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); - SColumnInfoData* pGroupId = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - SColumnInfoData* pCalStartTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); - SColumnInfoData* pCalEndTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); - for (; (*pIndex) < size; (*pIndex)++) { - SPullWindowInfo* pWin = taosArrayGet(array, (*pIndex)); - colDataSetVal(pStartTs, pBlock->info.rows, (const char*)&pWin->window.skey, false); - colDataSetVal(pEndTs, pBlock->info.rows, (const char*)&pWin->window.ekey, false); - colDataSetVal(pGroupId, pBlock->info.rows, (const char*)&pWin->groupId, false); - colDataSetVal(pCalStartTs, pBlock->info.rows, (const char*)&pWin->calWin.skey, false); - colDataSetVal(pCalEndTs, pBlock->info.rows, (const char*)&pWin->calWin.ekey, false); - pBlock->info.rows++; - } - if ((*pIndex) == size) { - *pIndex = 0; - taosArrayClear(array); - } - blockDataUpdateTsWindow(pBlock, 0); -} - -void processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pFinalMap, SInterval* pInterval, SArray* pPullWins, int32_t numOfCh, SOperatorInfo* pOperator) { - SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); - TSKEY* tsData = (TSKEY*)pStartCol->pData; - SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); - TSKEY* tsEndData = (TSKEY*)pEndCol->pData; - SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - uint64_t* groupIdData = (uint64_t*)pGroupCol->pData; - int32_t chId = getChildIndex(pBlock); - for (int32_t i = 0; i < pBlock->info.rows; i++) { - TSKEY winTs = tsData[i]; - while (winTs <= tsEndData[i]) { - SWinKey winRes = {.ts = winTs, .groupId = groupIdData[i]}; - void* chIds = taosHashGet(pMap, &winRes, sizeof(SWinKey)); - if (chIds) { - SArray* chArray = *(SArray**)chIds; - int32_t index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ); - if (index != -1) { - qDebug("===stream===retrive window %" PRId64 " delete child id %d", winRes.ts, chId); - taosArrayRemove(chArray, index); - if (taosArrayGetSize(chArray) == 0) { - // pull data is over - taosArrayDestroy(chArray); - taosHashRemove(pMap, &winRes, sizeof(SWinKey)); - qDebug("===stream===retrive pull data over.window %" PRId64 , winRes.ts); - - void* pFinalCh = taosHashGet(pFinalMap, &winRes, sizeof(SWinKey)); - if (pFinalCh) { - taosHashRemove(pFinalMap, &winRes, sizeof(SWinKey)); - doDeleteWindow(pOperator, winRes.ts, winRes.groupId); - STimeWindow nextWin = getFinalTimeWindow(winRes.ts, pInterval); - SPullWindowInfo pull = {.window = nextWin, - .groupId = winRes.groupId, - .calWin.skey = nextWin.skey, - .calWin.ekey = nextWin.skey}; - // add pull data request - if (savePullWindow(&pull, pPullWins) == TSDB_CODE_SUCCESS) { - addPullWindow(pMap, &winRes, numOfCh); - qDebug("===stream===prepare final retrive for delete %" PRId64 ", size:%d", winRes.ts, numOfCh); - } - } - } - } - } - winTs = taosTimeAdd(winTs, pInterval->sliding, pInterval->slidingUnit, pInterval->precision); - } - } -} - -static void addRetriveWindow(SArray* wins, SStreamIntervalOperatorInfo* pInfo, int32_t childId) { - int32_t size = taosArrayGetSize(wins); - for (int32_t i = 0; i < size; i++) { - SWinKey* winKey = taosArrayGet(wins, i); - STimeWindow nextWin = getFinalTimeWindow(winKey->ts, &pInfo->interval); - if (isOverdue(nextWin.ekey, &pInfo->twAggSup) && pInfo->ignoreExpiredData) { - continue; - } - void* chIds = taosHashGet(pInfo->pPullDataMap, winKey, sizeof(SWinKey)); - if (!chIds) { - SPullWindowInfo pull = { - .window = nextWin, .groupId = winKey->groupId, .calWin.skey = nextWin.skey, .calWin.ekey = nextWin.skey}; - // add pull data request - if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) { - addPullWindow(pInfo->pPullDataMap, winKey, pInfo->numOfChild); - qDebug("===stream===prepare retrive for delete %" PRId64 ", size:%d", winKey->ts, pInfo->numOfChild); - } - } else { - SArray* chArray = *(void**)chIds; - int32_t index = taosArraySearchIdx(chArray, &childId, compareInt32Val, TD_EQ); - qDebug("===stream===check final retrive %" PRId64",chid:%d", winKey->ts, index); - if (index == -1) { - qDebug("===stream===add final retrive %" PRId64, winKey->ts); - taosHashPut(pInfo->pFinalPullDataMap, winKey, sizeof(SWinKey), NULL, 0); - } - } - } -} - -static void clearFunctionContext(SExprSupp* pSup) { - for (int32_t i = 0; i < pSup->numOfExprs; i++) { - pSup->pCtx[i].saveHandle.currentPage = -1; - } -} - -int32_t getOutputBuf(void* pState, SRowBuffPos* pPos, SResultRow** pResult, SStateStore* pStore) { - return pStore->streamStateGetByPos(pState, pPos, (void**)pResult); -} - -int32_t buildDataBlockFromGroupRes(SOperatorInfo* pOperator, void* pState, SSDataBlock* pBlock, SExprSupp* pSup, - SGroupResInfo* pGroupResInfo) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SExprInfo* pExprInfo = pSup->pExprInfo; - int32_t numOfExprs = pSup->numOfExprs; - int32_t* rowEntryOffset = pSup->rowEntryInfoOffset; - SqlFunctionCtx* pCtx = pSup->pCtx; - - int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); - - for (int32_t i = pGroupResInfo->index; i < numOfRows; i += 1) { - SRowBuffPos* pPos = *(SRowBuffPos**)taosArrayGet(pGroupResInfo->pRows, i); - SResultRow* pRow = NULL; - int32_t code = getOutputBuf(pState, pPos, &pRow, &pAPI->stateStore); - uint64_t groupId = ((SWinKey*)pPos->pKey)->groupId; - ASSERT(code == 0); - doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowEntryOffset); - // no results, continue to check the next one - if (pRow->numOfRows == 0) { - pGroupResInfo->index += 1; - continue; - } - if (pBlock->info.id.groupId == 0) { - pBlock->info.id.groupId = groupId; - void* tbname = NULL; - if (pAPI->stateStore.streamStateGetParName(pTaskInfo->streamInfo.pState, pBlock->info.id.groupId, &tbname) < 0) { - pBlock->info.parTbName[0] = 0; - } else { - memcpy(pBlock->info.parTbName, tbname, TSDB_TABLE_NAME_LEN); - } - pAPI->stateStore.streamStateFreeVal(tbname); - } else { - // current value belongs to different group, it can't be packed into one datablock - if (pBlock->info.id.groupId != groupId) { - break; - } - } - - if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) { - ASSERT(pBlock->info.rows > 0); - break; - } - pGroupResInfo->index += 1; - - for (int32_t j = 0; j < numOfExprs; ++j) { - int32_t slotId = pExprInfo[j].base.resSchema.slotId; - - pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowEntryOffset); - SResultRowEntryInfo* pEnryInfo = pCtx[j].resultInfo; - - if (pCtx[j].fpSet.finalize) { - int32_t code1 = pCtx[j].fpSet.finalize(&pCtx[j], pBlock); - if (TAOS_FAILED(code1)) { - qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code1)); - T_LONG_JMP(pTaskInfo->env, code1); - } - } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) { - // do nothing, todo refactor - } else { - // expand the result into multiple rows. E.g., _wstart, top(k, 20) - // the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows. - SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId); - char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo); - for (int32_t k = 0; k < pRow->numOfRows; ++k) { - colDataSetVal(pColInfoData, pBlock->info.rows + k, in, pCtx[j].resultInfo->isNullRes); - } - } - } - - pBlock->info.rows += pRow->numOfRows; - } - - pBlock->info.dataLoad = 1; - blockDataUpdateTsWindow(pBlock, 0); - return TSDB_CODE_SUCCESS; -} - -void doBuildStreamIntervalResult(SOperatorInfo* pOperator, void* pState, SSDataBlock* pBlock, - SGroupResInfo* pGroupResInfo) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - // set output datablock version - pBlock->info.version = pTaskInfo->version; - - blockDataCleanup(pBlock); - if (!hasRemainResults(pGroupResInfo)) { - return; - } - - // clear the existed group id - pBlock->info.id.groupId = 0; - buildDataBlockFromGroupRes(pOperator, pState, pBlock, &pOperator->exprSupp, pGroupResInfo); -} - -static int32_t getNextQualifiedFinalWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, - TSKEY* primaryKeys, int32_t prevPosition) { - int32_t startPos = prevPosition + 1; - if (startPos == pDataBlockInfo->rows) { - startPos = -1; - } else { - *pNext = getFinalTimeWindow(primaryKeys[startPos], pInterval); - } - return startPos; -} - -static void setStreamDataVersion(SExecTaskInfo* pTaskInfo, int64_t version, int64_t ckId) { - pTaskInfo->streamInfo.dataVersion = version; - pTaskInfo->streamInfo.checkPointId = ckId; -} - -static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBlock, uint64_t groupId, - SSHashObj* pUpdatedMap) { - SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)pOperatorInfo->info; - pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); - - SResultRowInfo* pResultRowInfo = &(pInfo->binfo.resultRowInfo); - SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; - SExprSupp* pSup = &pOperatorInfo->exprSupp; - int32_t numOfOutput = pSup->numOfExprs; - int32_t step = 1; - TSKEY* tsCols = NULL; - SRowBuffPos* pResPos = NULL; - SResultRow* pResult = NULL; - int32_t forwardRows = 0; - - SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); - tsCols = (int64_t*)pColDataInfo->pData; - - int32_t startPos = 0; - TSKEY ts = getStartTsKey(&pSDataBlock->info.window, tsCols); - STimeWindow nextWin = {0}; - if (IS_FINAL_OP(pInfo)) { - nextWin = getFinalTimeWindow(ts, &pInfo->interval); - } else { - nextWin = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval, TSDB_ORDER_ASC); - } - while (1) { - bool isClosed = isCloseWindow(&nextWin, &pInfo->twAggSup); - if ((pInfo->ignoreExpiredData && isClosed && !IS_FINAL_OP(pInfo)) || !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) { - startPos = getNexWindowPos(&pInfo->interval, &pSDataBlock->info, tsCols, startPos, nextWin.ekey, &nextWin); - if (startPos < 0) { - break; - } - continue; - } - - if (IS_FINAL_OP(pInfo) && pInfo->numOfChild > 0) { - bool ignore = true; - SWinKey winRes = { - .ts = nextWin.skey, - .groupId = groupId, - }; - void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey)); - if (isDeletedStreamWindow(&nextWin, groupId, pInfo->pState, &pInfo->twAggSup, &pInfo->statestore) && isClosed && !chIds) { - SPullWindowInfo pull = { - .window = nextWin, .groupId = groupId, .calWin.skey = nextWin.skey, .calWin.ekey = nextWin.skey}; - // add pull data request - if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) { - addPullWindow(pInfo->pPullDataMap, &winRes, pInfo->numOfChild); - } - } else { - int32_t index = -1; - SArray* chArray = NULL; - int32_t chId = 0; - if (chIds) { - chArray = *(void**)chIds; - chId = getChildIndex(pSDataBlock); - index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ); - } - if (index == -1 || pSDataBlock->info.type == STREAM_PULL_DATA) { - ignore = false; - } - } - - if (ignore) { - startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, startPos); - if (startPos < 0) { - break; - } - continue; - } - } - - int32_t code = setIntervalOutputBuf(pInfo->pState, &nextWin, &pResPos, groupId, pSup->pCtx, numOfOutput, - pSup->rowEntryInfoOffset, &pInfo->aggSup, &pInfo->statestore); - pResult = (SResultRow*)pResPos->pRowBuff; - if (code != TSDB_CODE_SUCCESS || pResult == NULL) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - if (IS_FINAL_OP(pInfo)) { - forwardRows = 1; - } else { - forwardRows = getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey, - NULL, TSDB_ORDER_ASC); - } - - SWinKey key = { - .ts = pResult->win.skey, - .groupId = groupId, - }; - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdatedMap) { - saveWinResult(&key, pResPos, pUpdatedMap); - } - - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - tSimpleHashPut(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey), &pResPos, POINTER_BYTES); - } - - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, 1); - applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, - pSDataBlock->info.rows, numOfOutput); - key.ts = nextWin.skey; - - if (pInfo->delKey.ts > key.ts) { - pInfo->delKey = key; - } - int32_t prevEndPos = (forwardRows - 1) * step + startPos; - if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) { - qError("table uid %" PRIu64 " data block timestamp range may not be calculated! minKey %" PRId64 - ",maxKey %" PRId64, - pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey); - blockDataUpdateTsWindow(pSDataBlock, 0); - - // timestamp of the data is incorrect - if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) { - qError("table uid %" PRIu64 " data block timestamp is out of range! minKey %" PRId64 ",maxKey %" PRId64, - pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey); - } - } - - if (IS_FINAL_OP(pInfo)) { - startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos); - } else { - startPos = - getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, TSDB_ORDER_ASC); - } - if (startPos < 0) { - break; - } - } -} - -static inline int winPosCmprImpl(const void* pKey1, const void* pKey2) { - SRowBuffPos* pos1 = *(SRowBuffPos**)pKey1; - SRowBuffPos* pos2 = *(SRowBuffPos**)pKey2; - SWinKey* pWin1 = (SWinKey*)pos1->pKey; - SWinKey* pWin2 = (SWinKey*)pos2->pKey; - - if (pWin1->groupId > pWin2->groupId) { - return 1; - } else if (pWin1->groupId < pWin2->groupId) { - return -1; - } - - if (pWin1->ts > pWin2->ts) { - return 1; - } else if (pWin1->ts < pWin2->ts) { - return -1; - } - - return 0; -} - -static void resetUnCloseWinInfo(SSHashObj* winMap) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(winMap, pIte, &iter)) != NULL) { - SRowBuffPos* pPos = *(SRowBuffPos**)pIte; - pPos->beUsed = true; - } -} - -static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - SExprSupp* pSup = &pOperator->exprSupp; - - qDebug("interval status %d %s", pOperator->status, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } else if (pOperator->status == OP_RES_TO_RETURN) { - doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); - if (pInfo->pPullDataRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); - return pInfo->pPullDataRes; - } - - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows != 0) { - printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); - return pInfo->binfo.pRes; - } - - if (pInfo->recvGetAll) { - pInfo->recvGetAll = false; - resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable); - } - - setOperatorCompleted(pOperator); - if (!IS_FINAL_OP(pInfo)) { - clearFunctionContext(&pOperator->exprSupp); - // semi interval operator clear disk buffer - clearStreamIntervalOperator(pInfo); - setStreamDataVersion(pTaskInfo, pInfo->dataVersion, pInfo->pState->checkPointId); - qDebug("===stream===clear semi operator"); - } else { - if (pInfo->twAggSup.maxTs > 0 && - pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) { - pAPI->stateStore.streamStateCommit(pInfo->pState); - pAPI->stateStore.streamStateDeleteCheckPoint(pInfo->pState, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark); - pInfo->twAggSup.checkPointTs = pInfo->twAggSup.maxTs; - } - qDebug("===stream===interval final close"); - } - return NULL; - } else { - if (!IS_FINAL_OP(pInfo)) { - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - } - } - - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(4096, POINTER_BYTES); - } - if (!pInfo->pUpdatedMap) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pUpdatedMap = tSimpleHashInit(4096, hashFn); - } - - while (1) { - if (isTaskKilled(pTaskInfo)) { - if (pInfo->pUpdated != NULL) { - pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated); - } - - if (pInfo->pUpdatedMap != NULL) { - tSimpleHashCleanup(pInfo->pUpdatedMap); - pInfo->pUpdatedMap = NULL; - } - - T_LONG_JMP(pTaskInfo->env, pTaskInfo->code); - } - - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - pOperator->status = OP_RES_TO_RETURN; - qDebug("===stream===return data:%s. recv datablock num:%" PRIu64, - IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", pInfo->numOfDatapack); - pInfo->numOfDatapack = 0; - break; - } - pInfo->numOfDatapack++; - printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "interval final recv" : "interval semi recv", GET_TASKID(pTaskInfo)); - - if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) { - pInfo->binfo.pRes->info.type = pBlock->info.type; - } else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - SArray* delWins = taosArrayInit(8, sizeof(SWinKey)); - doDeleteWindows(pOperator, &pInfo->interval, pBlock, delWins, pInfo->pUpdatedMap); - if (IS_FINAL_OP(pInfo)) { - int32_t chId = getChildIndex(pBlock); - addRetriveWindow(delWins, pInfo, chId); - if (pBlock->info.type != STREAM_CLEAR) { - taosArrayAddAll(pInfo->pDelWins, delWins); - } - taosArrayDestroy(delWins); - continue; - } - removeResults(delWins, pInfo->pUpdatedMap); - taosArrayAddAll(pInfo->pDelWins, delWins); - taosArrayDestroy(delWins); - - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); - if (pBlock->info.type == STREAM_CLEAR) { - pInfo->pDelRes->info.type = STREAM_CLEAR; - } else { - pInfo->pDelRes->info.type = STREAM_DELETE_RESULT; - } - return pInfo->pDelRes; - } - - break; - } else if (pBlock->info.type == STREAM_GET_ALL && IS_FINAL_OP(pInfo)) { - pInfo->recvGetAll = true; - getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); - continue; - } else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_OP(pInfo)) { - doDeleteWindows(pOperator, &pInfo->interval, pBlock, NULL, pInfo->pUpdatedMap); - if (taosArrayGetSize(pInfo->pUpdated) > 0) { - break; - } - continue; - } else if (pBlock->info.type == STREAM_PULL_OVER && IS_FINAL_OP(pInfo)) { - processPullOver(pBlock, pInfo->pPullDataMap, pInfo->pFinalPullDataMap, &pInfo->interval, pInfo->pPullWins, pInfo->numOfChild, pOperator); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark); - pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey); - } - - removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins); - if (IS_FINAL_OP(pInfo)) { - closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, - pInfo->pPullDataMap, pInfo->pUpdatedMap, pInfo->pDelWins, pOperator); - } - pInfo->binfo.pRes->info.watermark = pInfo->twAggSup.maxTs; - - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pInfo->pUpdatedMap, pIte, &iter)) != NULL) { - taosArrayPush(pInfo->pUpdated, pIte); - } - - tSimpleHashCleanup(pInfo->pUpdatedMap); - pInfo->pUpdatedMap = NULL; - taosArraySort(pInfo->pUpdated, winPosCmprImpl); - - initMultiResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - - doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); - if (pInfo->pPullDataRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); - return pInfo->pPullDataRes; - } - - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows != 0) { - printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); - return pInfo->binfo.pRes; - } - - return NULL; -} - -int64_t getDeleteMark(SIntervalPhysiNode* pIntervalPhyNode) { - if (pIntervalPhyNode->window.deleteMark <= 0) { - return DEAULT_DELETE_MARK; - } - int64_t deleteMark = TMAX(pIntervalPhyNode->window.deleteMark, pIntervalPhyNode->window.watermark); - deleteMark = TMAX(deleteMark, pIntervalPhyNode->interval); - return deleteMark; -} - -TSKEY compareTs(void* pKey) { - SWinKey* pWinKey = (SWinKey*)pKey; - return pWinKey->ts; -} - -int32_t getSelectivityBufSize(SqlFunctionCtx* pCtx) { - if (pCtx->subsidiaries.rowLen == 0) { - int32_t rowLen = 0; - for (int32_t j = 0; j < pCtx->subsidiaries.num; ++j) { - SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j]; - rowLen += pc->pExpr->base.resSchema.bytes; - } - - return rowLen + pCtx->subsidiaries.num * sizeof(bool); - } else { - return pCtx->subsidiaries.rowLen; - } -} - -int32_t getMaxFunResSize(SExprSupp* pSup, int32_t numOfCols) { - int32_t size = 0; - for (int32_t i = 0; i < numOfCols; ++i) { - int32_t resSize = getSelectivityBufSize(pSup->pCtx + i); - size = TMAX(size, resSize); - } - return size; -} - -void streamIntervalReleaseState(SOperatorInfo* pOperator) { - if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - int32_t resSize = sizeof(TSKEY); - pInfo->statestore.streamStateSaveInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, strlen(STREAM_INTERVAL_OP_STATE_NAME), &pInfo->twAggSup.maxTs, resSize); - } - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - pAPI->stateStore.streamStateCommit(pInfo->pState); - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.releaseStreamStateFn) { - downstream->fpSet.releaseStreamStateFn(downstream); - } -} - -void streamIntervalReloadState(SOperatorInfo* pOperator) { - if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - int32_t size = 0; - void* pBuf = NULL; - int32_t code = pInfo->statestore.streamStateGetInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, - strlen(STREAM_INTERVAL_OP_STATE_NAME), &pBuf, &size); - TSKEY ts = *(TSKEY*)pBuf; - taosMemoryFree(pBuf); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, ts); - pInfo->statestore.streamStateReloadInfo(pInfo->pState, ts); - } - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.reloadStreamStateFn) { - downstream->fpSet.reloadStreamStateFn(downstream); - } -} - -SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, int32_t numOfChild) { - SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode; - SStreamIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamIntervalOperatorInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); - if (pInfo == NULL || pOperator == NULL) { - goto _error; - } - - pOperator->pTaskInfo = pTaskInfo; - SStorageAPI* pAPI = &pTaskInfo->storageAPI; - - pInfo->interval = (SInterval){.interval = pIntervalPhyNode->interval, - .sliding = pIntervalPhyNode->sliding, - .intervalUnit = pIntervalPhyNode->intervalUnit, - .slidingUnit = pIntervalPhyNode->slidingUnit, - .offset = pIntervalPhyNode->offset, - .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision}; - pInfo->twAggSup = (STimeWindowAggSupp){ - .waterMark = pIntervalPhyNode->window.watermark, - .calTrigger = pIntervalPhyNode->window.triggerType, - .maxTs = INT64_MIN, - .minTs = INT64_MAX, - .deleteMark = getDeleteMark(pIntervalPhyNode), - .deleteMarkSaved = 0, - .calTriggerSaved = 0, - .checkPointTs = 0, - .checkPointInterval = - convertTimePrecision(tsCheckpointInterval, TSDB_TIME_PRECISION_MILLI, pInfo->interval.precision), - }; - ASSERTS(pInfo->twAggSup.calTrigger != STREAM_TRIGGER_MAX_DELAY, "trigger type should not be max delay"); - pInfo->primaryTsIndex = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; - size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; - initResultSizeInfo(&pOperator->resultInfo, 4096); - if (pIntervalPhyNode->window.pExprs != NULL) { - int32_t numOfScalar = 0; - SExprInfo* pScalarExprInfo = createExprInfo(pIntervalPhyNode->window.pExprs, NULL, &numOfScalar); - int32_t code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - } - - int32_t numOfCols = 0; - SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &numOfCols); - SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); - initBasicInfo(&pInfo->binfo, pResBlock); - - pInfo->pState = taosMemoryCalloc(1, sizeof(SStreamState)); - *(pInfo->pState) = *(pTaskInfo->streamInfo.pState); - - pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1); - int32_t code = initAggSup(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, - pInfo->pState, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - initStreamFunciton(pOperator->exprSupp.pCtx, pOperator->exprSupp.numOfExprs); - initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); - initResultRowInfo(&pInfo->binfo.resultRowInfo); - - pInfo->numOfChild = numOfChild; - - pInfo->pPhyNode = (SPhysiNode*)nodesCloneNode((SNode*)pPhyNode); - - if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) { - pInfo->isFinal = true; - pOperator->name = "StreamFinalIntervalOperator"; - } else { - // semi interval operator does not catch result - pInfo->isFinal = false; - pOperator->name = "StreamSemiIntervalOperator"; - } - - if (!IS_FINAL_OP(pInfo) || numOfChild == 0) { - pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - } - - pInfo->pPullWins = taosArrayInit(8, sizeof(SPullWindowInfo)); - pInfo->pullIndex = 0; - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pPullDataMap = taosHashInit(64, hashFn, false, HASH_NO_LOCK); - pInfo->pFinalPullDataMap = taosHashInit(64, hashFn, false, HASH_NO_LOCK); - pInfo->pPullDataRes = createSpecialDataBlock(STREAM_RETRIEVE); - pInfo->ignoreExpiredData = pIntervalPhyNode->window.igExpired; - pInfo->ignoreExpiredDataSaved = false; - pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); - pInfo->delIndex = 0; - pInfo->pDelWins = taosArrayInit(4, sizeof(SWinKey)); - pInfo->delKey.ts = INT64_MAX; - pInfo->delKey.groupId = 0; - pInfo->numOfDatapack = 0; - pInfo->pUpdated = NULL; - pInfo->pUpdatedMap = NULL; - int32_t funResSize= getMaxFunResSize(&pOperator->exprSupp, numOfCols); - pInfo->pState->pFileState = pAPI->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, - compareTs, pInfo->pState, pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); - pInfo->dataVersion = 0; - pInfo->statestore = pTaskInfo->storageAPI.stateStore; - pInfo->recvGetAll = false; - - pOperator->operatorType = pPhyNode->type; - pOperator->blocking = true; - pOperator->status = OP_NOT_OPENED; - pOperator->info = pInfo; - - pOperator->fpSet = createOperatorFpSet(NULL, doStreamFinalIntervalAgg, NULL, destroyStreamFinalIntervalOperatorInfo, - optrDefaultBufFn, NULL); - setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); - if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { - initIntervalDownStream(downstream, pPhyNode->type, pInfo); - } - code = appendDownstream(pOperator, &downstream, 1); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - return pOperator; - -_error: - destroyStreamFinalIntervalOperatorInfo(pInfo); - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} - -void destroyStreamAggSupporter(SStreamAggSupporter* pSup) { - tSimpleHashCleanup(pSup->pResultRows); - destroyDiskbasedBuf(pSup->pResultBuf); - blockDataDestroy(pSup->pScanBlock); - taosMemoryFreeClear(pSup->pState); - taosMemoryFreeClear(pSup->pDummyCtx); -} - -void destroyStreamSessionAggOperatorInfo(void* param) { - SStreamSessionAggOperatorInfo* pInfo = (SStreamSessionAggOperatorInfo*)param; - cleanupBasicInfo(&pInfo->binfo); - destroyStreamAggSupporter(&pInfo->streamAggSup); - - if (pInfo->pChildren != NULL) { - int32_t size = taosArrayGetSize(pInfo->pChildren); - for (int32_t i = 0; i < size; i++) { - SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i); - destroyOperator(pChild); - } - taosArrayDestroy(pInfo->pChildren); - } - - colDataDestroy(&pInfo->twAggSup.timeWindowData); - blockDataDestroy(pInfo->pDelRes); - blockDataDestroy(pInfo->pWinBlock); - blockDataDestroy(pInfo->pUpdateRes); - tSimpleHashCleanup(pInfo->pStUpdated); - tSimpleHashCleanup(pInfo->pStDeleted); - - taosArrayDestroy(pInfo->historyWins); - taosMemoryFreeClear(param); -} - -int32_t initBasicInfoEx(SOptrBasicInfo* pBasicInfo, SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfCols, - SSDataBlock* pResultBlock, SFunctionStateStore* pStore) { - initBasicInfo(pBasicInfo, pResultBlock); - int32_t code = initExprSupp(pSup, pExprInfo, numOfCols, pStore); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - - initStreamFunciton(pSup->pCtx, pSup->numOfExprs); - for (int32_t i = 0; i < numOfCols; ++i) { - pSup->pCtx[i].saveHandle.pBuf = NULL; - } - - ASSERT(numOfCols > 0); - return TSDB_CODE_SUCCESS; -} - -void initDummyFunction(SqlFunctionCtx* pDummy, SqlFunctionCtx* pCtx, int32_t nums) { - for (int i = 0; i < nums; i++) { - pDummy[i].functionId = pCtx[i].functionId; - pDummy[i].isNotNullFunc = pCtx[i].isNotNullFunc; - pDummy[i].isPseudoFunc = pCtx[i].isPseudoFunc; - } -} - -void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, uint16_t type, int32_t tsColIndex, - STimeWindowAggSupp* pTwSup) { - if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION) { - SStreamPartitionOperatorInfo* pScanInfo = downstream->info; - pScanInfo->tsColIndex = tsColIndex; - } - - if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { - initDownStream(downstream->pDownstream[0], pAggSup, type, tsColIndex, pTwSup); - return; - } - SStreamScanInfo* pScanInfo = downstream->info; - pScanInfo->windowSup = (SWindowSupporter){.pStreamAggSup = pAggSup, .gap = pAggSup->gap, .parentType = type}; - pScanInfo->pState = pAggSup->pState; - if (!pScanInfo->pUpdateInfo) { - pScanInfo->pUpdateInfo = pAggSup->stateStore.updateInfoInit(60000, TSDB_TIME_PRECISION_MILLI, pTwSup->waterMark); - } - pScanInfo->twAggSup = *pTwSup; -} - -int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, int64_t gap, - SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore, SReadHandle* pHandle, SStorageAPI* pApi) { - pSup->resultRowSize = keySize + getResultRowSize(pCtx, numOfOutput); - pSup->pScanBlock = createSpecialDataBlock(STREAM_CLEAR); - pSup->gap = gap; - pSup->stateKeySize = keySize; - pSup->stateKeyType = keyType; - pSup->pDummyCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx)); - if (pSup->pDummyCtx == NULL) { - return TSDB_CODE_OUT_OF_MEMORY; - } - - pSup->stateStore = *pStore; - - initDummyFunction(pSup->pDummyCtx, pCtx, numOfOutput); - pSup->pState = taosMemoryCalloc(1, sizeof(SStreamState)); - *(pSup->pState) = *pState; - pSup->stateStore.streamStateSetNumber(pSup->pState, -1); - - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pSup->pResultRows = tSimpleHashInit(32, hashFn); - - int32_t pageSize = 4096; - while (pageSize < pSup->resultRowSize * 4) { - pageSize <<= 1u; - } - // at least four pages need to be in buffer - int32_t bufSize = 4096 * 256; - if (bufSize <= pageSize) { - bufSize = pageSize * 4; - } - - if (!osTempSpaceAvailable()) { - terrno = TSDB_CODE_NO_DISKSPACE; - qError("Init stream agg supporter failed since %s, tempDir:%s", terrstr(), tsTempDir); - return terrno; - } - - int32_t code = createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, "function", tsTempDir); - for (int32_t i = 0; i < numOfOutput; ++i) { - pCtx[i].saveHandle.pBuf = pSup->pResultBuf; - } - - pSup->pSessionAPI = pApi; - - return TSDB_CODE_SUCCESS; -} - -bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap) { - if (ts + gap >= pWin->skey && ts - gap <= pWin->ekey) { - return true; - } - return false; -} - -bool isInWindow(SResultWindowInfo* pWinInfo, TSKEY ts, int64_t gap) { - return isInTimeWindow(&pWinInfo->sessionWin.win, ts, gap); -} - -void getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, - SSessionKey* pKey) { - pKey->win.skey = startTs; - pKey->win.ekey = endTs; - pKey->groupId = groupId; - int32_t code = pAggSup->stateStore.streamStateSessionGetKeyByRange(pAggSup->pState, pKey, pKey); - if (code != TSDB_CODE_SUCCESS) { - SET_SESSION_WIN_KEY_INVALID(pKey); - } -} - -bool isInvalidSessionWin(SResultWindowInfo* pWinInfo) { return pWinInfo->sessionWin.win.skey == 0; } - -bool inWinRange(STimeWindow* range, STimeWindow* cur) { - if (cur->skey >= range->skey && cur->ekey <= range->ekey) { - return true; - } - return false; -} - -void setSessionOutputBuf(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, - SResultWindowInfo* pCurWin) { - pCurWin->sessionWin.groupId = groupId; - pCurWin->sessionWin.win.skey = startTs; - pCurWin->sessionWin.win.ekey = endTs; - int32_t size = pAggSup->resultRowSize; - int32_t code = pAggSup->stateStore.streamStateSessionAddIfNotExist(pAggSup->pState, &pCurWin->sessionWin, - pAggSup->gap, &pCurWin->pOutputBuf, &size); - if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->sessionWin.win)) { - code = TSDB_CODE_FAILED; - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->pOutputBuf, &pAggSup->pSessionAPI->stateStore); - pCurWin->pOutputBuf = taosMemoryCalloc(1, size); - } - - if (code == TSDB_CODE_SUCCESS) { - pCurWin->isOutput = true; - pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &pCurWin->sessionWin); - } else { - pCurWin->sessionWin.win.skey = startTs; - pCurWin->sessionWin.win.ekey = endTs; - } -} - -int32_t getSessionWinBuf(SStreamAggSupporter* pAggSup, SStreamStateCur* pCur, SResultWindowInfo* pWinInfo) { - int32_t size = 0; - int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pWinInfo->sessionWin, &pWinInfo->pOutputBuf, &size); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - - pAggSup->stateStore.streamStateCurNext(pAggSup->pState, pCur); - return TSDB_CODE_SUCCESS; -} -void saveDeleteInfo(SArray* pWins, SSessionKey key) { - // key.win.ekey = key.win.skey; - taosArrayPush(pWins, &key); -} - -void saveDeleteRes(SSHashObj* pStDelete, SSessionKey key) { - key.win.ekey = key.win.skey; - tSimpleHashPut(pStDelete, &key, sizeof(SSessionKey), NULL, 0); -} - -static void removeSessionResult(SSHashObj* pHashMap, SSHashObj* pResMap, SSessionKey key) { - key.win.ekey = key.win.skey; - tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey)); - tSimpleHashRemove(pResMap, &key, sizeof(SSessionKey)); -} - -static void getSessionHashKey(const SSessionKey* pKey, SSessionKey* pHashKey) { - *pHashKey = *pKey; - pHashKey->win.ekey = pKey->win.skey; -} - -static void removeSessionResults(SSHashObj* pHashMap, SArray* pWins) { - if (tSimpleHashGetSize(pHashMap) == 0) { - return; - } - int32_t size = taosArrayGetSize(pWins); - for (int32_t i = 0; i < size; i++) { - SSessionKey* pWin = taosArrayGet(pWins, i); - if (!pWin) continue; - SSessionKey key = {0}; - getSessionHashKey(pWin, &key); - tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey)); - } -} - -int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t groupId, - int32_t rows, int32_t start, int64_t gap, SSHashObj* pResultRows, SSHashObj* pStUpdated, - SSHashObj* pStDeleted) { - for (int32_t i = start; i < rows; ++i) { - if (!isInWindow(pWinInfo, pStartTs[i], gap) && (!pEndTs || !isInWindow(pWinInfo, pEndTs[i], gap))) { - return i - start; - } - if (pWinInfo->sessionWin.win.skey > pStartTs[i]) { - if (pStDeleted && pWinInfo->isOutput) { - saveDeleteRes(pStDeleted, pWinInfo->sessionWin); - } - removeSessionResult(pStUpdated, pResultRows, pWinInfo->sessionWin); - pWinInfo->sessionWin.win.skey = pStartTs[i]; - } - pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pStartTs[i]); - if (pEndTs) { - pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pEndTs[i]); - } - } - return rows - start; -} - -static int32_t initSessionOutputBuf(SResultWindowInfo* pWinInfo, SResultRow** pResult, SqlFunctionCtx* pCtx, - int32_t numOfOutput, int32_t* rowEntryInfoOffset) { - ASSERT(pWinInfo->sessionWin.win.skey <= pWinInfo->sessionWin.win.ekey); - *pResult = (SResultRow*)pWinInfo->pOutputBuf; - // set time window for current result - (*pResult)->win = pWinInfo->sessionWin.win; - setResultRowInitCtx(*pResult, pCtx, numOfOutput, rowEntryInfoOffset); - return TSDB_CODE_SUCCESS; -} - -static int32_t doOneWindowAggImpl(SColumnInfoData* pTimeWindowData, SResultWindowInfo* pCurWin, SResultRow** pResult, - int32_t startIndex, int32_t winRows, int32_t rows, int32_t numOutput, - SOperatorInfo* pOperator, int64_t winDelta) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - int32_t code = initSessionOutputBuf(pCurWin, pResult, pSup->pCtx, numOutput, pSup->rowEntryInfoOffset); - if (code != TSDB_CODE_SUCCESS || (*pResult) == NULL) { - return TSDB_CODE_OUT_OF_MEMORY; - } - updateTimeWindowInfo(pTimeWindowData, &pCurWin->sessionWin.win, winDelta); - applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, pTimeWindowData, startIndex, winRows, rows, numOutput); - return TSDB_CODE_SUCCESS; -} - -static bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pKey) { - pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, pKey); - SSessionKey hashKey = {0}; - getSessionHashKey(pKey, &hashKey); - tSimpleHashRemove(pAggSup->pResultRows, &hashKey, sizeof(SSessionKey)); - return true; -} - -static int32_t setSessionWinOutputInfo(SSHashObj* pStUpdated, SResultWindowInfo* pWinInfo) { - void* pVal = tSimpleHashGet(pStUpdated, &pWinInfo->sessionWin, sizeof(SSessionKey)); - if (pVal) { - SResultWindowInfo* pWin = pVal; - pWinInfo->isOutput = pWin->isOutput; - } - return TSDB_CODE_SUCCESS; -} - -SStreamStateCur* getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* pStUpdated, SResultWindowInfo* pCurWin, - SResultWindowInfo* pNextWin) { - SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pCurWin->sessionWin); - pNextWin->isOutput = true; - setSessionWinOutputInfo(pStUpdated, pNextWin); - int32_t size = 0; - pNextWin->sessionWin = pCurWin->sessionWin; - int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->sessionWin, &pNextWin->pOutputBuf, &size); - if (code != TSDB_CODE_SUCCESS) { - taosMemoryFreeClear(pNextWin->pOutputBuf); - SET_SESSION_WIN_INVALID(*pNextWin); - } - return pCur; -} - -static int32_t compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SSHashObj* pStUpdated, - SSHashObj* pStDeleted, bool addGap) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - int32_t winNum = 0; - - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SResultRow* pCurResult = NULL; - int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); - // Just look for the window behind StartIndex - while (1) { - SResultWindowInfo winInfo = {0}; - SStreamStateCur* pCur = getNextSessionWinInfo(pAggSup, pStUpdated, pCurWin, &winInfo); - if (!IS_VALID_SESSION_WIN(winInfo) || !isInWindow(pCurWin, winInfo.sessionWin.win.skey, pAggSup->gap) || - !inWinRange(&pAggSup->winRange, &winInfo.sessionWin.win)) { - taosMemoryFree(winInfo.pOutputBuf); - pAPI->stateStore.streamStateFreeCur(pCur); - break; - } - SResultRow* pWinResult = NULL; - initSessionOutputBuf(&winInfo, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); - pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, winInfo.sessionWin.win.ekey); - int64_t winDelta = 0; - if (addGap) { - winDelta = pAggSup->gap; - } - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, winDelta); - compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); - tSimpleHashRemove(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey)); - if (winInfo.isOutput && pStDeleted) { - saveDeleteRes(pStDeleted, winInfo.sessionWin); - } - removeSessionResult(pStUpdated, pAggSup->pResultRows, winInfo.sessionWin); - doDeleteSessionWindow(pAggSup, &winInfo.sessionWin); - pAPI->stateStore.streamStateFreeCur(pCur); - taosMemoryFree(winInfo.pOutputBuf); - winNum++; - } - return winNum; -} - -int32_t saveSessionOutputBuf(SStreamAggSupporter* pAggSup, SResultWindowInfo* pWinInfo) { - saveSessionDiscBuf(pAggSup->pState, &pWinInfo->sessionWin, pWinInfo->pOutputBuf, pAggSup->resultRowSize, &pAggSup->stateStore); - pWinInfo->pOutputBuf = NULL; - return TSDB_CODE_SUCCESS; -} - -static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pStUpdated, - SSHashObj* pStDeleted, bool hasEndTs, bool addGap) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - uint64_t groupId = pSDataBlock->info.id.groupId; - int64_t code = TSDB_CODE_SUCCESS; - SResultRow* pResult = NULL; - int32_t rows = pSDataBlock->info.rows; - int32_t winRows = 0; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - - pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); - pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow; - if (pAggSup->winRange.ekey <= 0) { - pAggSup->winRange.ekey = INT64_MAX; - } - - SColumnInfoData* pStartTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); - TSKEY* startTsCols = (int64_t*)pStartTsCol->pData; - SColumnInfoData* pEndTsCol = NULL; - if (hasEndTs) { - pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->endTsIndex); - } else { - pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); - } - - TSKEY* endTsCols = (int64_t*)pEndTsCol->pData; - for (int32_t i = 0; i < rows;) { - if (pInfo->ignoreExpiredData && isOverdue(endTsCols[i], &pInfo->twAggSup)) { - i++; - continue; - } - SResultWindowInfo winInfo = {0}; - setSessionOutputBuf(pAggSup, startTsCols[i], endTsCols[i], groupId, &winInfo); - setSessionWinOutputInfo(pStUpdated, &winInfo); - winRows = updateSessionWindowInfo(&winInfo, startTsCols, endTsCols, groupId, rows, i, pAggSup->gap, - pAggSup->pResultRows, pStUpdated, pStDeleted); - // coverity scan error - if (!winInfo.pOutputBuf) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - - int64_t winDelta = 0; - if (addGap) { - winDelta = pAggSup->gap; - } - code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &winInfo, &pResult, i, winRows, rows, numOfOutput, - pOperator, winDelta); - if (code != TSDB_CODE_SUCCESS || pResult == NULL) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - compactSessionWindow(pOperator, &winInfo, pStUpdated, pStDeleted, addGap); - saveSessionOutputBuf(pAggSup, &winInfo); - - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pStUpdated) { - code = saveResult(winInfo, pStUpdated); - if (code != TSDB_CODE_SUCCESS) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - } - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - SSessionKey key = {0}; - getSessionHashKey(&winInfo.sessionWin, &key); - tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); - } - - i += winRows; - } -} - -static void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SArray* result) { - SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); - TSKEY* startDatas = (TSKEY*)pStartTsCol->pData; - SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); - TSKEY* endDatas = (TSKEY*)pEndTsCol->pData; - SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - uint64_t* gpDatas = (uint64_t*)pGroupCol->pData; - for (int32_t i = 0; i < pBlock->info.rows; i++) { - while (1) { - SSessionKey curWin = {0}; - getCurSessionWindow(pAggSup, startDatas[i], endDatas[i], gpDatas[i], &curWin); - if (IS_INVALID_SESSION_WIN_KEY(curWin)) { - break; - } - doDeleteSessionWindow(pAggSup, &curWin); - if (result) { - saveDeleteInfo(result, curWin); - } - } - } -} - -static inline int32_t sessionKeyCompareAsc(const void* pKey1, const void* pKey2) { - SSessionKey* pWin1 = (SSessionKey*)pKey1; - SSessionKey* pWin2 = (SSessionKey*)pKey2; - - if (pWin1->groupId > pWin2->groupId) { - return 1; - } else if (pWin1->groupId < pWin2->groupId) { - return -1; - } - - if (pWin1->win.skey > pWin2->win.skey) { - return 1; - } else if (pWin1->win.skey < pWin2->win.skey) { - return -1; - } - - return 0; -} - -static int32_t copyUpdateResult(SSHashObj* pStUpdated, SArray* pUpdated) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pStUpdated, pIte, &iter)) != NULL) { - void* key = tSimpleHashGetKey(pIte, NULL); - taosArrayPush(pUpdated, key); - } - taosArraySort(pUpdated, sessionKeyCompareAsc); - return TSDB_CODE_SUCCESS; -} - -void doBuildDeleteDataBlock(SOperatorInfo* pOp, SSHashObj* pStDeleted, SSDataBlock* pBlock, void** Ite) { - SStorageAPI* pAPI = &pOp->pTaskInfo->storageAPI; - - blockDataCleanup(pBlock); - int32_t size = tSimpleHashGetSize(pStDeleted); - if (size == 0) { - return; - } - blockDataEnsureCapacity(pBlock, size); - int32_t iter = 0; - while (((*Ite) = tSimpleHashIterate(pStDeleted, *Ite, &iter)) != NULL) { - if (pBlock->info.rows + 1 > pBlock->info.capacity) { - break; - } - SSessionKey* res = tSimpleHashGetKey(*Ite, NULL); - SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); - colDataSetVal(pStartTsCol, pBlock->info.rows, (const char*)&res->win.skey, false); - SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); - colDataSetVal(pEndTsCol, pBlock->info.rows, (const char*)&res->win.skey, false); - SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX); - colDataSetNULL(pUidCol, pBlock->info.rows); - SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - colDataSetVal(pGpCol, pBlock->info.rows, (const char*)&res->groupId, false); - SColumnInfoData* pCalStCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); - colDataSetNULL(pCalStCol, pBlock->info.rows); - SColumnInfoData* pCalEdCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); - colDataSetNULL(pCalEdCol, pBlock->info.rows); - - SColumnInfoData* pTableCol = taosArrayGet(pBlock->pDataBlock, TABLE_NAME_COLUMN_INDEX); - - void* tbname = NULL; - pAPI->stateStore.streamStateGetParName(pOp->pTaskInfo->streamInfo.pState, res->groupId, &tbname); - if (tbname == NULL) { - colDataSetNULL(pTableCol, pBlock->info.rows); - } else { - char parTbName[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN]; - STR_WITH_MAXSIZE_TO_VARSTR(parTbName, tbname, sizeof(parTbName)); - colDataSetVal(pTableCol, pBlock->info.rows, (const char*)parTbName, false); - pAPI->stateStore.streamStateFreeVal(tbname); - } - pBlock->info.rows += 1; - } - if ((*Ite) == NULL) { - tSimpleHashClear(pStDeleted); - } -} - -static void rebuildSessionWindow(SOperatorInfo* pOperator, SArray* pWinArray, SSHashObj* pStUpdated) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - int32_t size = taosArrayGetSize(pWinArray); - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - int32_t numOfOutput = pSup->numOfExprs; - int32_t numOfChild = taosArrayGetSize(pInfo->pChildren); - - for (int32_t i = 0; i < size; i++) { - SSessionKey* pWinKey = taosArrayGet(pWinArray, i); - int32_t num = 0; - SResultWindowInfo parentWin = {0}; - for (int32_t j = 0; j < numOfChild; j++) { - SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, j); - SStreamSessionAggOperatorInfo* pChInfo = pChild->info; - SStreamAggSupporter* pChAggSup = &pChInfo->streamAggSup; - SSessionKey chWinKey = {0}; - getSessionHashKey(pWinKey, &chWinKey); - SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyCurrentNext(pChAggSup->pState, &chWinKey); - SResultRow* pResult = NULL; - SResultRow* pChResult = NULL; - while (1) { - SResultWindowInfo childWin = {0}; - childWin.sessionWin = *pWinKey; - int32_t code = getSessionWinBuf(pChAggSup, pCur, &childWin); - - if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &childWin.sessionWin.win)) { - continue; - } - - if (code == TSDB_CODE_SUCCESS && inWinRange(&pWinKey->win, &childWin.sessionWin.win)) { - if (num == 0) { - setSessionOutputBuf(pAggSup, pWinKey->win.skey, pWinKey->win.ekey, pWinKey->groupId, &parentWin); - code = initSessionOutputBuf(&parentWin, &pResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); - if (code != TSDB_CODE_SUCCESS || pResult == NULL) { - break; - } - } - num++; - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &parentWin.sessionWin.win, pAggSup->gap); - initSessionOutputBuf(&childWin, &pChResult, pChild->exprSupp.pCtx, numOfOutput, - pChild->exprSupp.rowEntryInfoOffset); - compactFunctions(pSup->pCtx, pChild->exprSupp.pCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); - compactSessionWindow(pOperator, &parentWin, pStUpdated, NULL, true); - saveResult(parentWin, pStUpdated); - } else { - break; - } - } - pAPI->stateStore.streamStateFreeCur(pCur); - } - if (num > 0) { - saveSessionOutputBuf(pAggSup, &parentWin); - } - } -} - -int32_t closeSessionWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SSHashObj* pClosed) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { - SResultWindowInfo* pWinInfo = pIte; - if (isCloseWindow(&pWinInfo->sessionWin.win, pTwSup)) { - if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE && pClosed) { - int32_t code = saveResult(*pWinInfo, pClosed); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } - SSessionKey* pKey = tSimpleHashGetKey(pIte, NULL); - tSimpleHashIterateRemove(pHashMap, pKey, sizeof(SSessionKey), &pIte, &iter); - } - } - return TSDB_CODE_SUCCESS; -} - -static void closeChildSessionWindow(SArray* pChildren, TSKEY maxTs) { - int32_t size = taosArrayGetSize(pChildren); - for (int32_t i = 0; i < size; i++) { - SOperatorInfo* pChildOp = taosArrayGetP(pChildren, i); - SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info; - pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, maxTs); - closeSessionWindow(pChInfo->streamAggSup.pResultRows, &pChInfo->twAggSup, NULL); - } -} - -int32_t getAllSessionWindow(SSHashObj* pHashMap, SSHashObj* pStUpdated) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { - SResultWindowInfo* pWinInfo = pIte; - saveResult(*pWinInfo, pStUpdated); - } - return TSDB_CODE_SUCCESS; -} - -static void copyDeleteWindowInfo(SArray* pResWins, SSHashObj* pStDeleted) { - int32_t size = taosArrayGetSize(pResWins); - for (int32_t i = 0; i < size; i++) { - SSessionKey* pWinKey = taosArrayGet(pResWins, i); - if (!pWinKey) continue; - SSessionKey winInfo = {0}; - getSessionHashKey(pWinKey, &winInfo); - tSimpleHashPut(pStDeleted, &winInfo, sizeof(SSessionKey), NULL, 0); - } -} - -// the allocated memory comes from outer function. -void initGroupResInfoFromArrayList(SGroupResInfo* pGroupResInfo, SArray* pArrayList) { - pGroupResInfo->pRows = pArrayList; - pGroupResInfo->index = 0; - pGroupResInfo->pBuf = NULL; -} - -void doBuildSessionResult(SOperatorInfo* pOperator, void* pState, SGroupResInfo* pGroupResInfo, - SSDataBlock* pBlock) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - // set output datablock version - pBlock->info.version = pTaskInfo->version; - - blockDataCleanup(pBlock); - if (!hasRemainResults(pGroupResInfo)) { - cleanupGroupResInfo(pGroupResInfo); - return; - } - - // clear the existed group id - pBlock->info.id.groupId = 0; - buildSessionResultDataBlock(pOperator, pState, pBlock, &pOperator->exprSupp, pGroupResInfo); - if (pBlock->info.rows == 0) { - cleanupGroupResInfo(pGroupResInfo); - } -} -void getMaxTsWins(const SArray* pAllWins, SArray* pMaxWins) { - int32_t size = taosArrayGetSize(pAllWins); - if (size == 0) { - return; - } - - SSessionKey* pSeKey = taosArrayGet(pAllWins, size - 1); - taosArrayPush(pMaxWins, pSeKey); - if (pSeKey->groupId == 0) { - return; - } - uint64_t preGpId = pSeKey->groupId; - for (int32_t i = size - 2; i >= 0; i--) { - pSeKey = taosArrayGet(pAllWins, i); - if (preGpId != pSeKey->groupId) { - taosArrayPush(pMaxWins, pSeKey); - preGpId = pSeKey->groupId; - } - } -} - -static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { - SExprSupp* pSup = &pOperator->exprSupp; - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SOptrBasicInfo* pBInfo = &pInfo->binfo; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - qDebug("===stream=== stream session agg"); - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } else if (pOperator->status == OP_RES_TO_RETURN) { - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; - } - - setOperatorCompleted(pOperator); - return NULL; - } - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); - } - if (!pInfo->pStUpdated) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pStUpdated = tSimpleHashInit(64, hashFn); - } - while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - break; - } - printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "final session recv" : "single session recv", GET_TASKID(pTaskInfo)); - - if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); - // gap must be 0 - doDeleteTimeWindows(pAggSup, pBlock, pWins); - removeSessionResults(pInfo->pStUpdated, pWins); - if (IS_FINAL_OP(pInfo)) { - int32_t childIndex = getChildIndex(pBlock); - SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex); - SStreamSessionAggOperatorInfo* pChildInfo = pChildOp->info; - // gap must be 0 - doDeleteTimeWindows(&pChildInfo->streamAggSup, pBlock, NULL); - rebuildSessionWindow(pOperator, pWins, pInfo->pStUpdated); - } - copyDeleteWindowInfo(pWins, pInfo->pStDeleted); - taosArrayDestroy(pWins); - continue; - } else if (pBlock->info.type == STREAM_GET_ALL) { - getAllSessionWindow(pAggSup->pResultRows, pInfo->pStUpdated); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, IS_FINAL_OP(pInfo), true); - if (IS_FINAL_OP(pInfo)) { - int32_t chIndex = getChildIndex(pBlock); - int32_t size = taosArrayGetSize(pInfo->pChildren); - // if chIndex + 1 - size > 0, add new child - for (int32_t i = 0; i < chIndex + 1 - size; i++) { - SOperatorInfo* pChildOp = - createStreamFinalSessionAggOperatorInfo(NULL, pInfo->pPhyNode, pOperator->pTaskInfo, 0, NULL); - if (!pChildOp) { - T_LONG_JMP(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - taosArrayPush(pInfo->pChildren, &pChildOp); - } - SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, chIndex); - setInputDataBlock(&pChildOp->exprSupp, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamSessionAggImpl(pChildOp, pBlock, NULL, NULL, true, false); - } - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark); - } - // restore the value - pOperator->status = OP_RES_TO_RETURN; - - closeSessionWindow(pAggSup->pResultRows, &pInfo->twAggSup, pInfo->pStUpdated); - closeChildSessionWindow(pInfo->pChildren, pInfo->twAggSup.maxTs); - copyUpdateResult(pInfo->pStUpdated, pInfo->pUpdated); - removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); - tSimpleHashCleanup(pInfo->pStUpdated); - pInfo->pStUpdated = NULL; - if(pInfo->isHistoryOp) { - getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); - } - initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - -#if 0 - char* pBuf = streamStateSessionDump(pAggSup->pState); - qDebug("===stream===final session%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; - } - - setOperatorCompleted(pOperator); - return NULL; -} - -void streamSessionReleaseState(SOperatorInfo* pOperator) { - if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION) { - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); - pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_SESSION_OP_STATE_NAME, strlen(STREAM_SESSION_OP_STATE_NAME), pInfo->historyWins->pData, resSize); - } - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.releaseStreamStateFn) { - downstream->fpSet.releaseStreamStateFn(downstream); - } -} - -void resetWinRange(STimeWindow* winRange) { - winRange->skey = INT64_MIN; - winRange->ekey = INT64_MAX; -} - -void streamSessionReloadState(SOperatorInfo* pOperator) { - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - resetWinRange(&pAggSup->winRange); - - SResultWindowInfo winInfo = {0}; - int32_t size = 0; - void* pBuf = NULL; - int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_SESSION_OP_STATE_NAME, - strlen(STREAM_SESSION_OP_STATE_NAME), &pBuf, &size); - int32_t num = size / sizeof(SSessionKey); - SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; - ASSERT(size == num * sizeof(SSessionKey)); - if (!pInfo->pStUpdated && num > 0) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pStUpdated = tSimpleHashInit(64, hashFn); - } - for (int32_t i = 0; i < num; i++) { - SResultWindowInfo winInfo = {0}; - setSessionOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].win.ekey, pSeKeyBuf[i].groupId, &winInfo); - int32_t winNum = compactSessionWindow(pOperator, &winInfo, pInfo->pStUpdated, pInfo->pStDeleted, true); - if (winNum > 0) { - qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, winInfo.sessionWin.win.skey, winInfo.sessionWin.groupId); - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { - saveResult(winInfo, pInfo->pStUpdated); - } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - if (!isCloseWindow(&winInfo.sessionWin.win, &pInfo->twAggSup)) { - saveDeleteRes(pInfo->pStDeleted, winInfo.sessionWin); - } - SSessionKey key = {0}; - getSessionHashKey(&winInfo.sessionWin, &key); - tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); - } - } - saveSessionOutputBuf(pAggSup, &winInfo); - } - taosMemoryFree(pBuf); - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.reloadStreamStateFn) { - downstream->fpSet.reloadStreamStateFn(downstream); - } -} - -SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { - SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode; - int32_t numOfCols = 0; - int32_t code = TSDB_CODE_OUT_OF_MEMORY; - SStreamSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamSessionAggOperatorInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); - if (pInfo == NULL || pOperator == NULL) { - goto _error; - } - - pOperator->pTaskInfo = pTaskInfo; - - initResultSizeInfo(&pOperator->resultInfo, 4096); - if (pSessionNode->window.pExprs != NULL) { - int32_t numOfScalar = 0; - SExprInfo* pScalarExprInfo = createExprInfo(pSessionNode->window.pExprs, NULL, &numOfScalar); - code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - } - SExprSupp* pSup = &pOperator->exprSupp; - - SExprInfo* pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &numOfCols); - SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); - code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, pSessionNode->gap, - pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - pInfo->twAggSup = (STimeWindowAggSupp){ - .waterMark = pSessionNode->window.watermark, - .calTrigger = pSessionNode->window.triggerType, - .maxTs = INT64_MIN, - .minTs = INT64_MAX, - }; - - initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); - - pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId; - if (pSessionNode->window.pTsEnd) { - pInfo->endTsIndex = ((SColumnNode*)pSessionNode->window.pTsEnd)->slotId; - } - pInfo->binfo.pRes = pResBlock; - pInfo->order = TSDB_ORDER_ASC; - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pStDeleted = tSimpleHashInit(64, hashFn); - pInfo->pDelIterator = NULL; - pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); - pInfo->pChildren = NULL; - pInfo->isFinal = false; - pInfo->pPhyNode = pPhyNode; - pInfo->ignoreExpiredData = pSessionNode->window.igExpired; - pInfo->ignoreExpiredDataSaved = false; - pInfo->pUpdated = NULL; - pInfo->pStUpdated = NULL; - pInfo->dataVersion = 0; - pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); - if (!pInfo->historyWins) { - goto _error; - } - if (pHandle) { - pInfo->isHistoryOp = pHandle->fillHistory; - } - - setOperatorInfo(pOperator, "StreamSessionWindowAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, true, - OP_NOT_OPENED, pInfo, pTaskInfo); - pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionAgg, NULL, destroyStreamSessionAggOperatorInfo, - optrDefaultBufFn, NULL); - setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); - - if (downstream) { - initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); - code = appendDownstream(pOperator, &downstream, 1); - } - return pOperator; - -_error: - if (pInfo != NULL) { - destroyStreamSessionAggOperatorInfo(pInfo); - } - - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} - -static void clearStreamSessionOperator(SStreamSessionAggOperatorInfo* pInfo) { - tSimpleHashClear(pInfo->streamAggSup.pResultRows); - pInfo->streamAggSup.stateStore.streamStateSessionClear(pInfo->streamAggSup.pState); -} - -static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SOptrBasicInfo* pBInfo = &pInfo->binfo; - TSKEY maxTs = INT64_MIN; - SExprSupp* pSup = &pOperator->exprSupp; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - - qDebug("===stream=== stream session semi agg"); - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } - - { - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "semi session", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; - } - - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "semi session delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - if (pOperator->status == OP_RES_TO_RETURN) { - clearFunctionContext(&pOperator->exprSupp); - // semi interval operator clear disk buffer - clearStreamSessionOperator(pInfo); - setOperatorCompleted(pOperator); - return NULL; - } - } - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); - } - if (!pInfo->pStUpdated) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pStUpdated = tSimpleHashInit(64, hashFn); - } - while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - clearSpecialDataBlock(pInfo->pUpdateRes); - pOperator->status = OP_RES_TO_RETURN; - break; - } - printDataBlock(pBlock, "semi session recv", GET_TASKID(pTaskInfo)); - - if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - // gap must be 0 - SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); - doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins); - removeSessionResults(pInfo->pStUpdated, pWins); - copyDeleteWindowInfo(pWins, pInfo->pStDeleted); - taosArrayDestroy(pWins); - break; - } else if (pBlock->info.type == STREAM_GET_ALL) { - getAllSessionWindow(pInfo->streamAggSup.pResultRows, pInfo->pStUpdated); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, NULL, false, false); - maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - } - - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs); - pBInfo->pRes->info.watermark = pInfo->twAggSup.maxTs; - - copyUpdateResult(pInfo->pStUpdated, pInfo->pUpdated); - removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); - tSimpleHashCleanup(pInfo->pStUpdated); - pInfo->pStUpdated = NULL; - initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity); - -#if 0 - char* pBuf = streamStateSessionDump(pAggSup->pState); - qDebug("===stream===semi session%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "semi session", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; - } - - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "semi session delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - clearFunctionContext(&pOperator->exprSupp); - // semi interval operator clear disk buffer - clearStreamSessionOperator(pInfo); - setOperatorCompleted(pOperator); - return NULL; -} - -SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, int32_t numOfChild, SReadHandle* pHandle) { - int32_t code = TSDB_CODE_OUT_OF_MEMORY; - SOperatorInfo* pOperator = createStreamSessionAggOperatorInfo(downstream, pPhyNode, pTaskInfo, pHandle); - if (pOperator == NULL) { - goto _error; - } - - SStorageAPI* pAPI = &pTaskInfo->storageAPI; - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - - pInfo->isFinal = (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION); - char* name = (pInfo->isFinal) ? "StreamSessionFinalAggOperator" : "StreamSessionSemiAggOperator"; - - if (pPhyNode->type != QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) { - pInfo->pUpdateRes = createSpecialDataBlock(STREAM_CLEAR); - blockDataEnsureCapacity(pInfo->pUpdateRes, 128); - pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionSemiAgg, NULL, - destroyStreamSessionAggOperatorInfo, optrDefaultBufFn, NULL); - } - setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); - setOperatorInfo(pOperator, name, pPhyNode->type, false, OP_NOT_OPENED, pInfo, pTaskInfo); - - pOperator->operatorType = pPhyNode->type; - if (numOfChild > 0) { - pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*)); - for (int32_t i = 0; i < numOfChild; i++) { - SOperatorInfo* pChildOp = createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0, NULL); - if (pChildOp == NULL) { - goto _error; - } - SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info; - pChInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - pAPI->stateStore.streamStateSetNumber(pChInfo->streamAggSup.pState, i); - taosArrayPush(pInfo->pChildren, &pChildOp); - } - } - - if (!IS_FINAL_OP(pInfo) || numOfChild == 0) { - pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - } - - return pOperator; - -_error: - if (pInfo != NULL) { - destroyStreamSessionAggOperatorInfo(pInfo); - } - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} - -void destroyStreamStateOperatorInfo(void* param) { - SStreamStateAggOperatorInfo* pInfo = (SStreamStateAggOperatorInfo*)param; - cleanupBasicInfo(&pInfo->binfo); - destroyStreamAggSupporter(&pInfo->streamAggSup); - cleanupGroupResInfo(&pInfo->groupResInfo); - if (pInfo->pChildren != NULL) { - int32_t size = taosArrayGetSize(pInfo->pChildren); - for (int32_t i = 0; i < size; i++) { - SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i); - destroyOperator(pChild); - } - taosArrayDestroy(pInfo->pChildren); - } - colDataDestroy(&pInfo->twAggSup.timeWindowData); - blockDataDestroy(pInfo->pDelRes); - taosArrayDestroy(pInfo->historyWins); - tSimpleHashCleanup(pInfo->pSeUpdated); - tSimpleHashCleanup(pInfo->pSeDeleted); - taosMemoryFreeClear(param); -} - -bool isTsInWindow(SStateWindowInfo* pWin, TSKEY ts) { - if (pWin->winInfo.sessionWin.win.skey <= ts && ts <= pWin->winInfo.sessionWin.win.ekey) { - return true; - } - return false; -} - -bool isEqualStateKey(SStateWindowInfo* pWin, char* pKeyData) { - return pKeyData && compareVal(pKeyData, pWin->pStateKey); -} - -bool compareStateKey(void* data, void* key) { - if (!data || !key) { - return true; - } - SStateKeys* stateKey = (SStateKeys*)key; - stateKey->pData = (char*)key + sizeof(SStateKeys); - return compareVal(data, stateKey); -} - -bool compareWinStateKey(SStateKeys* left, SStateKeys* right) { - if (!left || !right) { - return false; - } - return compareVal(left->pData, right); -} - -void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, char* pKeyData, - SStateWindowInfo* pCurWin, SStateWindowInfo* pNextWin) { - int32_t size = pAggSup->resultRowSize; - pCurWin->winInfo.sessionWin.groupId = groupId; - pCurWin->winInfo.sessionWin.win.skey = ts; - pCurWin->winInfo.sessionWin.win.ekey = ts; - int32_t code = - pAggSup->stateStore.streamStateStateAddIfNotExist(pAggSup->pState, &pCurWin->winInfo.sessionWin, pKeyData, pAggSup->stateKeySize, - compareStateKey, &pCurWin->winInfo.pOutputBuf, &size); - pCurWin->pStateKey = - (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); - pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); - pCurWin->pStateKey->type = pAggSup->stateKeyType; - pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); - pCurWin->pStateKey->isNull = false; - - if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->winInfo.sessionWin.win)) { - code = TSDB_CODE_FAILED; - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->winInfo.pOutputBuf, &pAggSup->pSessionAPI->stateStore); - pCurWin->winInfo.pOutputBuf = taosMemoryCalloc(1, size); - pCurWin->pStateKey = - (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); - pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); - pCurWin->pStateKey->type = pAggSup->stateKeyType; - pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); - pCurWin->pStateKey->isNull = false; - pCurWin->winInfo.sessionWin.groupId = groupId; - pCurWin->winInfo.sessionWin.win.skey = ts; - pCurWin->winInfo.sessionWin.win.ekey = ts; - qDebug("===stream===reset state win key. skey:%" PRId64 ", endkey:%" PRId64, pCurWin->winInfo.sessionWin.win.skey, pCurWin->winInfo.sessionWin.win.ekey); - } - - if (code == TSDB_CODE_SUCCESS) { - pCurWin->winInfo.isOutput = true; - pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &pCurWin->winInfo.sessionWin); - } else if (pKeyData) { - if (IS_VAR_DATA_TYPE(pAggSup->stateKeyType)) { - varDataCopy(pCurWin->pStateKey->pData, pKeyData); - } else { - memcpy(pCurWin->pStateKey->pData, pKeyData, pCurWin->pStateKey->bytes); - } - } - - pNextWin->winInfo.sessionWin = pCurWin->winInfo.sessionWin; - SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pNextWin->winInfo.sessionWin); - int32_t nextSize = pAggSup->resultRowSize; - code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->winInfo.sessionWin, &pNextWin->winInfo.pOutputBuf, &nextSize); - if (code != TSDB_CODE_SUCCESS) { - SET_SESSION_WIN_INVALID(pNextWin->winInfo); - } else { - pNextWin->pStateKey = - (SStateKeys*)((char*)pNextWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); - pNextWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); - pNextWin->pStateKey->type = pAggSup->stateKeyType; - pNextWin->pStateKey->pData = (char*)pNextWin->pStateKey + sizeof(SStateKeys); - pNextWin->pStateKey->isNull = false; - pNextWin->winInfo.isOutput = true; - } - pAggSup->stateStore.streamStateFreeCur(pCur); -} - -int32_t updateStateWindowInfo(SStateWindowInfo* pWinInfo, SStateWindowInfo* pNextWin, TSKEY* pTs, uint64_t groupId, - SColumnInfoData* pKeyCol, int32_t rows, int32_t start, bool* allEqual, - SSHashObj* pResultRows, SSHashObj* pSeUpdated, SSHashObj* pSeDeleted) { - *allEqual = true; - for (int32_t i = start; i < rows; ++i) { - char* pKeyData = colDataGetData(pKeyCol, i); - if (!isTsInWindow(pWinInfo, pTs[i])) { - if (isEqualStateKey(pWinInfo, pKeyData)) { - if (IS_VALID_SESSION_WIN(pNextWin->winInfo)) { - // ts belongs to the next window - if (pTs[i] >= pNextWin->winInfo.sessionWin.win.skey) { - return i - start; - } - } - } else { - return i - start; - } - } - - if (pWinInfo->winInfo.sessionWin.win.skey > pTs[i]) { - if (pSeDeleted && pWinInfo->winInfo.isOutput) { - saveDeleteRes(pSeDeleted, pWinInfo->winInfo.sessionWin); - } - removeSessionResult(pSeUpdated, pResultRows, pWinInfo->winInfo.sessionWin); - pWinInfo->winInfo.sessionWin.win.skey = pTs[i]; - } - pWinInfo->winInfo.sessionWin.win.ekey = TMAX(pWinInfo->winInfo.sessionWin.win.ekey, pTs[i]); - if (!isEqualStateKey(pWinInfo, pKeyData)) { - *allEqual = false; - } - } - return rows - start; -} - -static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pSeUpdated, - SSHashObj* pStDeleted) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - uint64_t groupId = pSDataBlock->info.id.groupId; - int64_t code = TSDB_CODE_SUCCESS; - TSKEY* tsCols = NULL; - SResultRow* pResult = NULL; - int32_t winRows = 0; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - - pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); - pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow; - if (pAggSup->winRange.ekey <= 0) { - pAggSup->winRange.ekey = INT64_MAX; - } - - if (pSDataBlock->pDataBlock != NULL) { - SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); - tsCols = (int64_t*)pColDataInfo->pData; - } else { - return; - } - - int32_t rows = pSDataBlock->info.rows; - blockDataEnsureCapacity(pAggSup->pScanBlock, rows); - SColumnInfoData* pKeyColInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->stateCol.slotId); - for (int32_t i = 0; i < rows; i += winRows) { - if (pInfo->ignoreExpiredData && isOverdue(tsCols[i], &pInfo->twAggSup) || colDataIsNull_s(pKeyColInfo, i)) { - i++; - continue; - } - char* pKeyData = colDataGetData(pKeyColInfo, i); - int32_t winIndex = 0; - bool allEqual = true; - SStateWindowInfo curWin = {0}; - SStateWindowInfo nextWin = {0}; - setStateOutputBuf(pAggSup, tsCols[i], groupId, pKeyData, &curWin, &nextWin); - if (IS_VALID_SESSION_WIN(nextWin.winInfo)) { - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextWin.winInfo.pOutputBuf, &pAPI->stateStore); - } - setSessionWinOutputInfo(pSeUpdated, &curWin.winInfo); - winRows = updateStateWindowInfo(&curWin, &nextWin, tsCols, groupId, pKeyColInfo, rows, i, &allEqual, - pAggSup->pResultRows, pSeUpdated, pStDeleted); - if (!allEqual) { - uint64_t uid = 0; - appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey, - &curWin.winInfo.sessionWin.win.ekey, &uid, &groupId, NULL); - tSimpleHashRemove(pSeUpdated, &curWin.winInfo.sessionWin, sizeof(SSessionKey)); - doDeleteSessionWindow(pAggSup, &curWin.winInfo.sessionWin); - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)curWin.winInfo.pOutputBuf, &pAPI->stateStore); - continue; - } - code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput, - pOperator, 0); - if (code != TSDB_CODE_SUCCESS || pResult == NULL) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - saveSessionOutputBuf(pAggSup, &curWin.winInfo); - - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { - code = saveResult(curWin.winInfo, pSeUpdated); - if (code != TSDB_CODE_SUCCESS) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - } - - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - SSessionKey key = {0}; - getSessionHashKey(&curWin.winInfo.sessionWin, &key); - tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curWin.winInfo, sizeof(SResultWindowInfo)); - } - } -} - -static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } - - SExprSupp* pSup = &pOperator->exprSupp; - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - SOptrBasicInfo* pBInfo = &pInfo->binfo; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - qDebug("===stream=== stream state agg"); - if (pOperator->status == OP_RES_TO_RETURN) { - doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single state delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "single state", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; - } - - setOperatorCompleted(pOperator); - return NULL; - } - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); - } - if (!pInfo->pSeUpdated) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pSeUpdated = tSimpleHashInit(64, hashFn); - } - while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - break; - } - printDataBlock(pBlock, "single state recv", GET_TASKID(pTaskInfo)); - - if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); - doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins); - removeSessionResults(pInfo->pSeUpdated, pWins); - copyDeleteWindowInfo(pWins, pInfo->pSeDeleted); - taosArrayDestroy(pWins); - continue; - } else if (pBlock->info.type == STREAM_GET_ALL) { - getAllSessionWindow(pInfo->streamAggSup.pResultRows, pInfo->pSeUpdated); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamStateAggImpl(pOperator, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - } - // restore the value - pOperator->status = OP_RES_TO_RETURN; - - closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pInfo->pSeUpdated); - copyUpdateResult(pInfo->pSeUpdated, pInfo->pUpdated); - removeSessionResults(pInfo->pSeDeleted, pInfo->pUpdated); - tSimpleHashCleanup(pInfo->pSeUpdated); - pInfo->pSeUpdated = NULL; - - if(pInfo->isHistoryOp) { - getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); - } - - initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - -#if 0 - char* pBuf = streamStateSessionDump(pInfo->streamAggSup.pState); - qDebug("===stream===final session%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single state delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "single state", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; - } - setOperatorCompleted(pOperator); - return NULL; -} - -void streamStateReleaseState(SOperatorInfo* pOperator) { - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); - qDebug("===stream=== relase state. save result count:%d", (int32_t)taosArrayGetSize(pInfo->historyWins)); - pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_STATE_OP_STATE_NAME, strlen(STREAM_STATE_OP_STATE_NAME), pInfo->historyWins->pData, resSize); - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.releaseStreamStateFn) { - downstream->fpSet.releaseStreamStateFn(downstream); - } -} - -static void compactStateWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SResultWindowInfo* pNextWin, - SSHashObj* pStUpdated, SSHashObj* pStDeleted) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - SResultRow* pCurResult = NULL; - int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); - SResultRow* pWinResult = NULL; - initSessionOutputBuf(pNextWin, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); - pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, pNextWin->sessionWin.win.ekey); - - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, 1); - compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); - tSimpleHashRemove(pStUpdated, &pNextWin->sessionWin, sizeof(SSessionKey)); - if (pNextWin->isOutput && pStDeleted) { - qDebug("===stream=== save delete window info %" PRId64 ", %" PRIu64, pNextWin->sessionWin.win.skey, pNextWin->sessionWin.groupId); - saveDeleteRes(pStDeleted, pNextWin->sessionWin); - } - removeSessionResult(pStUpdated, pAggSup->pResultRows, pNextWin->sessionWin); - doDeleteSessionWindow(pAggSup, &pNextWin->sessionWin); - taosMemoryFree(pNextWin->pOutputBuf); -} - -void streamStateReloadState(SOperatorInfo* pOperator) { - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - resetWinRange(&pAggSup->winRange); - - SSessionKey seKey = {.win.skey = INT64_MIN, .win.ekey = INT64_MIN, .groupId = 0}; - int32_t size = 0; - void* pBuf = NULL; - int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_STATE_OP_STATE_NAME, - strlen(STREAM_STATE_OP_STATE_NAME), &pBuf, &size); - int32_t num = size / sizeof(SSessionKey); - qDebug("===stream=== reload state. get result count:%d", num); - SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; - ASSERT(size == num * sizeof(SSessionKey)); - if (!pInfo->pSeUpdated && num > 0) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pSeUpdated = tSimpleHashInit(64, hashFn); - } - if (!pInfo->pSeDeleted && num > 0) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pSeDeleted = tSimpleHashInit(64, hashFn); - } - for (int32_t i = 0; i < num; i++) { - SStateWindowInfo curInfo = {0}; - SStateWindowInfo nextInfo = {0}; - SStateWindowInfo dummy = {0}; - qDebug("===stream=== reload state. try process result %" PRId64 ", %" PRIu64 ", index:%d", pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, i); - setStateOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, NULL, &curInfo, &nextInfo); - bool cpRes = compareWinStateKey(curInfo.pStateKey,nextInfo.pStateKey); - qDebug("===stream=== reload state. next window info %" PRId64 ", %" PRIu64 ", compare:%d", nextInfo.winInfo.sessionWin.win.skey, nextInfo.winInfo.sessionWin.groupId, cpRes); - if (cpRes) { - compactStateWindow(pOperator, &curInfo.winInfo, &nextInfo.winInfo, pInfo->pSeUpdated, pInfo->pSeDeleted); - qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, curInfo.winInfo.sessionWin.win.skey, curInfo.winInfo.sessionWin.groupId); - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { - saveResult(curInfo.winInfo, pInfo->pSeUpdated); - } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - if (!isCloseWindow(&curInfo.winInfo.sessionWin.win, &pInfo->twAggSup)) { - saveDeleteRes(pInfo->pSeDeleted, curInfo.winInfo.sessionWin); - } - SSessionKey key = {0}; - getSessionHashKey(&curInfo.winInfo.sessionWin, &key); - tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curInfo.winInfo, sizeof(SResultWindowInfo)); - } - } else if (IS_VALID_SESSION_WIN(nextInfo.winInfo)) { - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextInfo.winInfo.pOutputBuf, &pAggSup->pSessionAPI->stateStore); - } - - if (IS_VALID_SESSION_WIN(curInfo.winInfo)) { - saveSessionOutputBuf(pAggSup, &curInfo.winInfo); - } - } - taosMemoryFree(pBuf); - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.reloadStreamStateFn) { - downstream->fpSet.reloadStreamStateFn(downstream); - } -} - -SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { - SStreamStateWinodwPhysiNode* pStateNode = (SStreamStateWinodwPhysiNode*)pPhyNode; - int32_t tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId; - SColumnNode* pColNode = (SColumnNode*)(pStateNode->pStateKey); - int32_t code = TSDB_CODE_SUCCESS; - - SStreamStateAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamStateAggOperatorInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); - if (pInfo == NULL || pOperator == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - goto _error; - } - - pInfo->stateCol = extractColumnFromColumnNode(pColNode); - initResultSizeInfo(&pOperator->resultInfo, 4096); - if (pStateNode->window.pExprs != NULL) { - int32_t numOfScalar = 0; - SExprInfo* pScalarExprInfo = createExprInfo(pStateNode->window.pExprs, NULL, &numOfScalar); - code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - } - - pInfo->twAggSup = (STimeWindowAggSupp){ - .waterMark = pStateNode->window.watermark, - .calTrigger = pStateNode->window.triggerType, - .maxTs = INT64_MIN, - .minTs = INT64_MAX, - }; - - initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); - - SExprSupp* pSup = &pOperator->exprSupp; - int32_t numOfCols = 0; - SExprInfo* pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &numOfCols); - SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); - code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - int32_t keySize = sizeof(SStateKeys) + pColNode->node.resType.bytes; - int16_t type = pColNode->node.resType.type; - code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, 0, pTaskInfo->streamInfo.pState, keySize, - type, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - pInfo->primaryTsIndex = tsSlotId; - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pSeDeleted = tSimpleHashInit(64, hashFn); - pInfo->pDelIterator = NULL; - pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); - pInfo->pChildren = NULL; - pInfo->ignoreExpiredData = pStateNode->window.igExpired; - pInfo->ignoreExpiredDataSaved = false; - pInfo->pUpdated = NULL; - pInfo->pSeUpdated = NULL; - pInfo->dataVersion = 0; - pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); - if (!pInfo->historyWins) { - goto _error; - } - if (pHandle) { - pInfo->isHistoryOp = pHandle->fillHistory; - } - - setOperatorInfo(pOperator, "StreamStateAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE, true, OP_NOT_OPENED, - pInfo, pTaskInfo); - pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamStateAgg, NULL, destroyStreamStateOperatorInfo, - optrDefaultBufFn, NULL); - setOperatorStreamStateFn(pOperator, streamStateReleaseState, streamStateReloadState); - initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); - code = appendDownstream(pOperator, &downstream, 1); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - return pOperator; - -_error: - destroyStreamStateOperatorInfo(pInfo); - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} void destroyMAIOperatorInfo(void* param) { SMergeAlignedIntervalAggOperatorInfo* miaInfo = (SMergeAlignedIntervalAggOperatorInfo*)param; @@ -5199,263 +2189,3 @@ _error: pTaskInfo->code = code; return NULL; } - -static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SExprSupp* pSup = &pOperator->exprSupp; - - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } - - if (pOperator->status == OP_RES_TO_RETURN) { - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows > 0) { - printDataBlock(pInfo->binfo.pRes, "single interval", GET_TASKID(pTaskInfo)); - return pInfo->binfo.pRes; - } - - if (pInfo->recvGetAll) { - pInfo->recvGetAll = false; - resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable); - } - - setOperatorCompleted(pOperator); - if (pInfo->twAggSup.maxTs > 0 && - pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) { - pAPI->stateStore.streamStateCommit(pInfo->pState); - pAPI->stateStore.streamStateDeleteCheckPoint(pInfo->pState, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark); - setStreamDataVersion(pTaskInfo, pInfo->dataVersion, pInfo->pState->checkPointId); - pInfo->twAggSup.checkPointTs = pInfo->twAggSup.maxTs; - } - return NULL; - } - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(4096, POINTER_BYTES); - } - - if (!pInfo->pUpdatedMap) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pUpdatedMap = tSimpleHashInit(4096, hashFn); - } - - while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - qDebug("===stream===return data:single interval. recv datablock num:%" PRIu64, pInfo->numOfDatapack); - pInfo->numOfDatapack = 0; - break; - } - - pInfo->numOfDatapack++; - printDataBlock(pBlock, "single interval recv", GET_TASKID(pTaskInfo)); - - if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - doDeleteWindows(pOperator, &pInfo->interval, pBlock, pInfo->pDelWins, pInfo->pUpdatedMap); - continue; - } else if (pBlock->info.type == STREAM_GET_ALL) { - qDebug("===stream===single interval recv|block type STREAM_GET_ALL"); - pInfo->recvGetAll = true; - getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - printDataBlock(pBlock, "single interval", GET_TASKID(pTaskInfo)); - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pBlock->info.type == STREAM_NORMAL && pBlock->info.version != 0) { - // set input version - pTaskInfo->version = pBlock->info.version; - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - - // The timewindow that overlaps the timestamps of the input pBlock need to be recalculated and return to the - // caller. Note that all the time window are not close till now. - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - if (pInfo->invertible) { - setInverFunction(pSup->pCtx, pOperator->exprSupp.numOfExprs, pBlock->info.type); - } - - doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey); - } - pOperator->status = OP_RES_TO_RETURN; - removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins); - closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL, - pInfo->pUpdatedMap, pInfo->pDelWins, pOperator); - - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pInfo->pUpdatedMap, pIte, &iter)) != NULL) { - taosArrayPush(pInfo->pUpdated, pIte); - } - taosArraySort(pInfo->pUpdated, winPosCmprImpl); - - initMultiResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - tSimpleHashCleanup(pInfo->pUpdatedMap); - pInfo->pUpdatedMap = NULL; - -#if 0 - char* pBuf = streamStateIntervalDump(pInfo->pState); - qDebug("===stream===interval state%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows > 0) { - printDataBlock(pInfo->binfo.pRes, "single interval", GET_TASKID(pTaskInfo)); - return pInfo->binfo.pRes; - } - - return NULL; -} - -SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo) { - SStreamIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamIntervalOperatorInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); - if (pInfo == NULL || pOperator == NULL) { - goto _error; - } - SStreamIntervalPhysiNode* pIntervalPhyNode = (SStreamIntervalPhysiNode*)pPhyNode; - - int32_t code = TSDB_CODE_SUCCESS; - int32_t numOfCols = 0; - SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &numOfCols); - - SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); - pInfo->interval = (SInterval){ - .interval = pIntervalPhyNode->interval, - .sliding = pIntervalPhyNode->sliding, - .intervalUnit = pIntervalPhyNode->intervalUnit, - .slidingUnit = pIntervalPhyNode->slidingUnit, - .offset = pIntervalPhyNode->offset, - .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision, - }; - - pInfo->twAggSup = (STimeWindowAggSupp){ - .waterMark = pIntervalPhyNode->window.watermark, - .calTrigger = pIntervalPhyNode->window.triggerType, - .maxTs = INT64_MIN, - .minTs = INT64_MAX, - .deleteMark = getDeleteMark(pIntervalPhyNode), - .checkPointTs = 0, - .checkPointInterval = - convertTimePrecision(tsCheckpointInterval, TSDB_TIME_PRECISION_MILLI, pInfo->interval.precision), - }; - - ASSERTS(pInfo->twAggSup.calTrigger != STREAM_TRIGGER_MAX_DELAY, "trigger type should not be max delay"); - - pOperator->pTaskInfo = pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - pInfo->ignoreExpiredData = pIntervalPhyNode->window.igExpired; - pInfo->ignoreExpiredDataSaved = false; - pInfo->isFinal = false; - - SExprSupp* pSup = &pOperator->exprSupp; - initBasicInfo(&pInfo->binfo, pResBlock); - initStreamFunciton(pSup->pCtx, pSup->numOfExprs); - initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); - - pInfo->primaryTsIndex = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; - initResultSizeInfo(&pOperator->resultInfo, 4096); - - pInfo->pState = taosMemoryCalloc(1, sizeof(SStreamState)); - *(pInfo->pState) = *(pTaskInfo->streamInfo.pState); - pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1); - - size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; - code = initAggSup(pSup, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, - pInfo->pState, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - if (pIntervalPhyNode->window.pExprs != NULL) { - int32_t numOfScalar = 0; - SExprInfo* pScalarExprInfo = createExprInfo(pIntervalPhyNode->window.pExprs, NULL, &numOfScalar); - code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - } - - pInfo->invertible = allInvertible(pSup->pCtx, numOfCols); - pInfo->invertible = false; - pInfo->pDelWins = taosArrayInit(4, sizeof(SWinKey)); - pInfo->delIndex = 0; - pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); - initResultRowInfo(&pInfo->binfo.resultRowInfo); - - pInfo->pPhyNode = NULL; // create new child - pInfo->pPullDataMap = NULL; - pInfo->pFinalPullDataMap = NULL; - pInfo->pPullWins = NULL; // SPullWindowInfo - pInfo->pullIndex = 0; - pInfo->pPullDataRes = NULL; - pInfo->isFinal = false; - pInfo->numOfChild = 0; - pInfo->delKey.ts = INT64_MAX; - pInfo->delKey.groupId = 0; - pInfo->numOfDatapack = 0; - pInfo->pUpdated = NULL; - pInfo->pUpdatedMap = NULL; - int32_t funResSize= getMaxFunResSize(pSup, numOfCols); - - pInfo->pState->pFileState = pTaskInfo->storageAPI.stateStore.streamFileStateInit( - tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, compareTs, pInfo->pState, - pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); - - setOperatorInfo(pOperator, "StreamIntervalOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL, true, OP_NOT_OPENED, - pInfo, pTaskInfo); - pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamIntervalAgg, NULL, - destroyStreamFinalIntervalOperatorInfo, optrDefaultBufFn, NULL); - setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); - - pInfo->statestore = pTaskInfo->storageAPI.stateStore; - pInfo->recvGetAll = false; - - initIntervalDownStream(downstream, pPhyNode->type, pInfo); - code = appendDownstream(pOperator, &downstream, 1); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - return pOperator; - -_error: - destroyStreamFinalIntervalOperatorInfo(pInfo); - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} From 3043c7f09f24172e8f3cab87333ee5732fcc0027 Mon Sep 17 00:00:00 2001 From: liuyao <54liuyao@163.com> Date: Mon, 14 Aug 2023 15:10:44 +0800 Subject: [PATCH 48/92] refactor operator --- source/libs/executor/inc/executorInt.h | 2 - .../executor/src/streamtimewindowoperator.c | 106 +++++++++--------- 2 files changed, 51 insertions(+), 57 deletions(-) diff --git a/source/libs/executor/inc/executorInt.h b/source/libs/executor/inc/executorInt.h index bd5d8e76ab..b225627e34 100644 --- a/source/libs/executor/inc/executorInt.h +++ b/source/libs/executor/inc/executorInt.h @@ -456,7 +456,6 @@ typedef struct SStreamIntervalOperatorInfo { SArray* pPullWins; // SPullWindowInfo int32_t pullIndex; SSDataBlock* pPullDataRes; - bool isFinal; SArray* pChildren; int32_t numOfChild; SStreamState* pState; // void @@ -507,7 +506,6 @@ typedef struct SStreamSessionAggOperatorInfo { void* pDelIterator; SArray* pChildren; // cache for children's result; final stream operator SPhysiNode* pPhyNode; // create new child - bool isFinal; bool ignoreExpiredData; bool ignoreExpiredDataSaved; SArray* pUpdated; diff --git a/source/libs/executor/src/streamtimewindowoperator.c b/source/libs/executor/src/streamtimewindowoperator.c index 3849104b27..57f9476922 100644 --- a/source/libs/executor/src/streamtimewindowoperator.c +++ b/source/libs/executor/src/streamtimewindowoperator.c @@ -26,7 +26,8 @@ #include "tlog.h" #include "ttime.h" -#define IS_FINAL_OP(op) ((op)->isFinal) +#define IS_FINAL_INTERVAL_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) +#define IS_FINAL_SESSION_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) #define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL); #define STREAM_INTERVAL_OP_STATE_NAME "StreamIntervalHistoryState" #define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState" @@ -231,7 +232,7 @@ static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDa dumyInfo.cur.pageId = -1; STimeWindow win = {0}; - if (IS_FINAL_OP(pInfo)) { + if (IS_FINAL_INTERVAL_OP(pOperator)) { win.skey = startTsCols[i]; win.ekey = endTsCols[i]; } else { @@ -746,14 +747,14 @@ static void setStreamDataVersion(SExecTaskInfo* pTaskInfo, int64_t version, int6 pTaskInfo->streamInfo.checkPointId = ckId; } -static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBlock, uint64_t groupId, +static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, uint64_t groupId, SSHashObj* pUpdatedMap) { - SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)pOperatorInfo->info; + SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)pOperator->info; pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); SResultRowInfo* pResultRowInfo = &(pInfo->binfo.resultRowInfo); - SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; - SExprSupp* pSup = &pOperatorInfo->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SExprSupp* pSup = &pOperator->exprSupp; int32_t numOfOutput = pSup->numOfExprs; int32_t step = 1; TSKEY* tsCols = NULL; @@ -767,14 +768,14 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* p int32_t startPos = 0; TSKEY ts = getStartTsKey(&pSDataBlock->info.window, tsCols); STimeWindow nextWin = {0}; - if (IS_FINAL_OP(pInfo)) { + if (IS_FINAL_INTERVAL_OP(pOperator)) { nextWin = getFinalTimeWindow(ts, &pInfo->interval); } else { nextWin = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval, TSDB_ORDER_ASC); } while (1) { bool isClosed = isCloseWindow(&nextWin, &pInfo->twAggSup); - if ((pInfo->ignoreExpiredData && isClosed && !IS_FINAL_OP(pInfo)) || !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) { + if ((pInfo->ignoreExpiredData && isClosed && !IS_FINAL_INTERVAL_OP(pOperator)) || !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) { startPos = getNexWindowPos(&pInfo->interval, &pSDataBlock->info, tsCols, startPos, nextWin.ekey, &nextWin); if (startPos < 0) { break; @@ -782,7 +783,7 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* p continue; } - if (IS_FINAL_OP(pInfo) && pInfo->numOfChild > 0) { + if (IS_FINAL_INTERVAL_OP(pOperator) && pInfo->numOfChild > 0) { bool ignore = true; SWinKey winRes = { .ts = nextWin.skey, @@ -825,7 +826,7 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* p if (code != TSDB_CODE_SUCCESS || pResult == NULL) { T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); } - if (IS_FINAL_OP(pInfo)) { + if (IS_FINAL_INTERVAL_OP(pOperator)) { forwardRows = 1; } else { forwardRows = getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey, @@ -866,7 +867,7 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* p } } - if (IS_FINAL_OP(pInfo)) { + if (IS_FINAL_INTERVAL_OP(pOperator)) { startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos); } else { startPos = @@ -910,7 +911,7 @@ static void resetUnCloseWinInfo(SSHashObj* winMap) { static char* getStreamOpName(uint16_t opType) { switch (opType) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: - return "single interval"; + return "interval single"; case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: return "interval final"; case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: @@ -921,15 +922,17 @@ static char* getStreamOpName(uint16_t opType) { } -static SSDataBlock* getResult(SOperatorInfo* pOperator){ +static SSDataBlock* buildIntervalResult(SOperatorInfo* pOperator){ SStreamIntervalOperatorInfo* pInfo = pOperator->info; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; uint16_t opType = pOperator->operatorType; - doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); - if (pInfo->pPullDataRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pPullDataRes, getStreamOpName(opType), GET_TASKID(pTaskInfo)); - return pInfo->pPullDataRes; + if (IS_FINAL_INTERVAL_OP(pOperator)) { + doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); + if (pInfo->pPullDataRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pPullDataRes, getStreamOpName(opType), GET_TASKID(pTaskInfo)); + return pInfo->pPullDataRes; + } } doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); @@ -941,7 +944,7 @@ static SSDataBlock* getResult(SOperatorInfo* pOperator){ doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); if (pInfo->binfo.pRes->info.rows != 0) { - printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->binfo.pRes, getStreamOpName(opType), GET_TASKID(pTaskInfo)); return pInfo->binfo.pRes; } return NULL; @@ -955,12 +958,12 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { SOperatorInfo* downstream = pOperator->pDownstream[0]; SExprSupp* pSup = &pOperator->exprSupp; - qDebug("interval status %d %s", pOperator->status, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status); if (pOperator->status == OP_EXEC_DONE) { return NULL; } else if (pOperator->status == OP_RES_TO_RETURN) { - SSDataBlock* resBlock = getResult(pOperator); + SSDataBlock* resBlock = buildIntervalResult(pOperator); if (resBlock != NULL) { return resBlock; } @@ -971,12 +974,12 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { } setOperatorCompleted(pOperator); - if (!IS_FINAL_OP(pInfo)) { + if (!IS_FINAL_INTERVAL_OP(pOperator)) { clearFunctionContext(&pOperator->exprSupp); // semi interval operator clear disk buffer clearStreamIntervalOperator(pInfo); setStreamDataVersion(pTaskInfo, pInfo->dataVersion, pInfo->pState->checkPointId); - qDebug("===stream===clear semi operator"); + qDebug("stask:%s ===stream===%s clear", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType)); } else { if (pInfo->twAggSup.maxTs > 0 && pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) { @@ -984,15 +987,15 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { pAPI->stateStore.streamStateDeleteCheckPoint(pInfo->pState, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark); pInfo->twAggSup.checkPointTs = pInfo->twAggSup.maxTs; } - qDebug("===stream===interval final close"); + qDebug("stask:%s ===stream===%s close", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType)); } return NULL; } else { - if (!IS_FINAL_OP(pInfo)) { + if (!IS_FINAL_INTERVAL_OP(pOperator)) { doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } } @@ -1024,12 +1027,12 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { if (pBlock == NULL) { pOperator->status = OP_RES_TO_RETURN; qDebug("===stream===return data:%s. recv datablock num:%" PRIu64, - IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", pInfo->numOfDatapack); + IS_FINAL_INTERVAL_OP(pOperator) ? "interval final" : "interval semi", pInfo->numOfDatapack); pInfo->numOfDatapack = 0; break; } pInfo->numOfDatapack++; - printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "interval final recv" : "interval semi recv", GET_TASKID(pTaskInfo)); + printDataBlock(pBlock, IS_FINAL_INTERVAL_OP(pOperator) ? "interval final recv" : "interval semi recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) { pInfo->binfo.pRes->info.type = pBlock->info.type; @@ -1037,7 +1040,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { pBlock->info.type == STREAM_CLEAR) { SArray* delWins = taosArrayInit(8, sizeof(SWinKey)); doDeleteWindows(pOperator, &pInfo->interval, pBlock, delWins, pInfo->pUpdatedMap); - if (IS_FINAL_OP(pInfo)) { + if (IS_FINAL_INTERVAL_OP(pOperator)) { int32_t chId = getChildIndex(pBlock); addRetriveWindow(delWins, pInfo, chId); if (pBlock->info.type != STREAM_CLEAR) { @@ -1053,7 +1056,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, IS_FINAL_INTERVAL_OP(pOperator) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_CLEAR) { pInfo->pDelRes->info.type = STREAM_CLEAR; } else { @@ -1063,17 +1066,17 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { } break; - } else if (pBlock->info.type == STREAM_GET_ALL && IS_FINAL_OP(pInfo)) { + } else if (pBlock->info.type == STREAM_GET_ALL && IS_FINAL_INTERVAL_OP(pOperator)) { pInfo->recvGetAll = true; getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); continue; - } else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_OP(pInfo)) { + } else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_INTERVAL_OP(pOperator)) { doDeleteWindows(pOperator, &pInfo->interval, pBlock, NULL, pInfo->pUpdatedMap); if (taosArrayGetSize(pInfo->pUpdated) > 0) { break; } continue; - } else if (pBlock->info.type == STREAM_PULL_OVER && IS_FINAL_OP(pInfo)) { + } else if (pBlock->info.type == STREAM_PULL_OVER && IS_FINAL_INTERVAL_OP(pOperator)) { processPullOver(pBlock, pInfo->pPullDataMap, pInfo->pFinalPullDataMap, &pInfo->interval, pInfo->pPullWins, pInfo->numOfChild, pOperator); continue; } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { @@ -1094,7 +1097,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { } removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins); - if (IS_FINAL_OP(pInfo)) { + if (IS_FINAL_INTERVAL_OP(pOperator)) { closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, pInfo->pPullDataMap, pInfo->pUpdatedMap, pInfo->pDelWins, pOperator); } @@ -1114,7 +1117,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { pInfo->pUpdated = NULL; blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - return getResult(pOperator); + return buildIntervalResult(pOperator); } static int64_t getDeleteMark(SIntervalPhysiNode* pIntervalPhyNode) { @@ -1253,15 +1256,13 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, pInfo->pPhyNode = (SPhysiNode*)nodesCloneNode((SNode*)pPhyNode); if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) { - pInfo->isFinal = true; pOperator->name = "StreamFinalIntervalOperator"; } else { // semi interval operator does not catch result - pInfo->isFinal = false; pOperator->name = "StreamSemiIntervalOperator"; } - if (!IS_FINAL_OP(pInfo) || numOfChild == 0) { + if (!IS_FINAL_INTERVAL_OP(pOperator) || numOfChild == 0) { pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; } @@ -2004,12 +2005,12 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { } else if (pOperator->status == OP_RES_TO_RETURN) { doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + printDataBlock(pBInfo->pRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", GET_TASKID(pTaskInfo)); return pBInfo->pRes; } @@ -2030,7 +2031,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { if (pBlock == NULL) { break; } - printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "final session recv" : "single session recv", GET_TASKID(pTaskInfo)); + printDataBlock(pBlock, IS_FINAL_SESSION_OP(pOperator) ? "final session recv" : "single session recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || pBlock->info.type == STREAM_CLEAR) { @@ -2038,7 +2039,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { // gap must be 0 doDeleteTimeWindows(pAggSup, pBlock, pWins); removeSessionResults(pInfo->pStUpdated, pWins); - if (IS_FINAL_OP(pInfo)) { + if (IS_FINAL_SESSION_OP(pOperator)) { int32_t childIndex = getChildIndex(pBlock); SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex); SStreamSessionAggOperatorInfo* pChildInfo = pChildOp->info; @@ -2064,8 +2065,8 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { } // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, IS_FINAL_OP(pInfo), true); - if (IS_FINAL_OP(pInfo)) { + doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, IS_FINAL_SESSION_OP(pOperator), true); + if (IS_FINAL_SESSION_OP(pOperator)) { int32_t chIndex = getChildIndex(pBlock); int32_t size = taosArrayGetSize(pInfo->pChildren); // if chIndex + 1 - size > 0, add new child @@ -2108,13 +2109,13 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + printDataBlock(pBInfo->pRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", GET_TASKID(pTaskInfo)); return pBInfo->pRes; } @@ -2240,7 +2241,6 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh pInfo->pDelIterator = NULL; pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); pInfo->pChildren = NULL; - pInfo->isFinal = false; pInfo->pPhyNode = pPhyNode; pInfo->ignoreExpiredData = pSessionNode->window.igExpired; pInfo->ignoreExpiredDataSaved = false; @@ -2406,11 +2406,10 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream goto _error; } - SStorageAPI* pAPI = &pTaskInfo->storageAPI; + SStorageAPI* pAPI = &pTaskInfo->storageAPI; SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - - pInfo->isFinal = (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION); - char* name = (pInfo->isFinal) ? "StreamSessionFinalAggOperator" : "StreamSessionSemiAggOperator"; + pOperator->operatorType = pPhyNode->type; + char* name = getStreamOpName(pOperator->operatorType); if (pPhyNode->type != QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) { pInfo->pUpdateRes = createSpecialDataBlock(STREAM_CLEAR); @@ -2421,7 +2420,6 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); setOperatorInfo(pOperator, name, pPhyNode->type, false, OP_NOT_OPENED, pInfo, pTaskInfo); - pOperator->operatorType = pPhyNode->type; if (numOfChild > 0) { pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*)); for (int32_t i = 0; i < numOfChild; i++) { @@ -2436,7 +2434,7 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream } } - if (!IS_FINAL_OP(pInfo) || numOfChild == 0) { + if (!IS_FINAL_SESSION_OP(pOperator) || numOfChild == 0) { pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; } @@ -3153,7 +3151,6 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys pInfo->ignoreExpiredData = pIntervalPhyNode->window.igExpired; pInfo->ignoreExpiredDataSaved = false; - pInfo->isFinal = false; SExprSupp* pSup = &pOperator->exprSupp; initBasicInfo(&pInfo->binfo, pResBlock); @@ -3194,7 +3191,6 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys pInfo->pPullWins = NULL; // SPullWindowInfo pInfo->pullIndex = 0; pInfo->pPullDataRes = NULL; - pInfo->isFinal = false; pInfo->numOfChild = 0; pInfo->delKey.ts = INT64_MAX; pInfo->delKey.groupId = 0; From 4b435e2cbf865fe8254585bc1c81c9c4c21c2306 Mon Sep 17 00:00:00 2001 From: liuyao <54liuyao@163.com> Date: Mon, 14 Aug 2023 15:12:54 +0800 Subject: [PATCH 49/92] format code --- .../executor/src/streamtimewindowoperator.c | 262 ++++++++++-------- 1 file changed, 148 insertions(+), 114 deletions(-) diff --git a/source/libs/executor/src/streamtimewindowoperator.c b/source/libs/executor/src/streamtimewindowoperator.c index 57f9476922..2832af5d10 100644 --- a/source/libs/executor/src/streamtimewindowoperator.c +++ b/source/libs/executor/src/streamtimewindowoperator.c @@ -26,12 +26,12 @@ #include "tlog.h" #include "ttime.h" -#define IS_FINAL_INTERVAL_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) -#define IS_FINAL_SESSION_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) -#define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL); +#define IS_FINAL_INTERVAL_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) +#define IS_FINAL_SESSION_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) +#define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL); #define STREAM_INTERVAL_OP_STATE_NAME "StreamIntervalHistoryState" -#define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState" -#define STREAM_STATE_OP_STATE_NAME "StreamStateHistoryState" +#define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState" +#define STREAM_STATE_OP_STATE_NAME "StreamStateHistoryState" typedef struct SStateWindowInfo { SResultWindowInfo winInfo; @@ -456,13 +456,14 @@ void compactFunctions(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx, int3 } } -bool hasIntervalWindow(void* pState, SWinKey* pKey, SStateStore* pStore) { return pStore->streamStateCheck(pState, pKey); } +bool hasIntervalWindow(void* pState, SWinKey* pKey, SStateStore* pStore) { + return pStore->streamStateCheck(pState, pKey); +} int32_t setIntervalOutputBuf(void* pState, STimeWindow* win, SRowBuffPos** pResult, int64_t groupId, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, SAggSupporter* pAggSup, SStateStore* pStore) { - - SWinKey key = { .ts = win->skey, .groupId = groupId }; + SWinKey key = {.ts = win->skey, .groupId = groupId}; char* value = NULL; int32_t size = pAggSup->resultRowSize; @@ -479,7 +480,8 @@ int32_t setIntervalOutputBuf(void* pState, STimeWindow* win, SRowBuffPos** pResu return TSDB_CODE_SUCCESS; } -bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, void* pState, STimeWindowAggSupp* pTwSup, SStateStore* pStore) { +bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, void* pState, STimeWindowAggSupp* pTwSup, + SStateStore* pStore) { if (pTwSup->maxTs != INT64_MIN && pWin->ekey < pTwSup->maxTs - pTwSup->deleteMark) { SWinKey key = {.ts = pWin->skey, .groupId = groupId}; if (!hasIntervalWindow(pState, &key, pStore)) { @@ -549,7 +551,8 @@ static void doBuildPullDataBlock(SArray* array, int32_t* pIndex, SSDataBlock* pB blockDataUpdateTsWindow(pBlock, 0); } -void processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pFinalMap, SInterval* pInterval, SArray* pPullWins, int32_t numOfCh, SOperatorInfo* pOperator) { +void processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pFinalMap, SInterval* pInterval, SArray* pPullWins, + int32_t numOfCh, SOperatorInfo* pOperator) { SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); TSKEY* tsData = (TSKEY*)pStartCol->pData; SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); @@ -572,13 +575,13 @@ void processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pFinalMap, S // pull data is over taosArrayDestroy(chArray); taosHashRemove(pMap, &winRes, sizeof(SWinKey)); - qDebug("===stream===retrive pull data over.window %" PRId64 , winRes.ts); + qDebug("===stream===retrive pull data over.window %" PRId64, winRes.ts); void* pFinalCh = taosHashGet(pFinalMap, &winRes, sizeof(SWinKey)); if (pFinalCh) { taosHashRemove(pFinalMap, &winRes, sizeof(SWinKey)); doDeleteWindow(pOperator, winRes.ts, winRes.groupId); - STimeWindow nextWin = getFinalTimeWindow(winRes.ts, pInterval); + STimeWindow nextWin = getFinalTimeWindow(winRes.ts, pInterval); SPullWindowInfo pull = {.window = nextWin, .groupId = winRes.groupId, .calWin.skey = nextWin.skey, @@ -617,7 +620,7 @@ static void addRetriveWindow(SArray* wins, SStreamIntervalOperatorInfo* pInfo, i } else { SArray* chArray = *(void**)chIds; int32_t index = taosArraySearchIdx(chArray, &childId, compareInt32Val, TD_EQ); - qDebug("===stream===check final retrive %" PRId64",chid:%d", winKey->ts, index); + qDebug("===stream===check final retrive %" PRId64 ",chid:%d", winKey->ts, index); if (index == -1) { qDebug("===stream===add final retrive %" PRId64, winKey->ts); taosHashPut(pInfo->pFinalPullDataMap, winKey, sizeof(SWinKey), NULL, 0); @@ -638,8 +641,8 @@ int32_t getOutputBuf(void* pState, SRowBuffPos* pPos, SResultRow** pResult, SSta int32_t buildDataBlockFromGroupRes(SOperatorInfo* pOperator, void* pState, SSDataBlock* pBlock, SExprSupp* pSup, SGroupResInfo* pGroupResInfo) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; SExprInfo* pExprInfo = pSup->pExprInfo; int32_t numOfExprs = pSup->numOfExprs; @@ -775,7 +778,8 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDat } while (1) { bool isClosed = isCloseWindow(&nextWin, &pInfo->twAggSup); - if ((pInfo->ignoreExpiredData && isClosed && !IS_FINAL_INTERVAL_OP(pOperator)) || !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) { + if ((pInfo->ignoreExpiredData && isClosed && !IS_FINAL_INTERVAL_OP(pOperator)) || + !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) { startPos = getNexWindowPos(&pInfo->interval, &pSDataBlock->info, tsCols, startPos, nextWin.ekey, &nextWin); if (startPos < 0) { break; @@ -790,7 +794,8 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDat .groupId = groupId, }; void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey)); - if (isDeletedStreamWindow(&nextWin, groupId, pInfo->pState, &pInfo->twAggSup, &pInfo->statestore) && isClosed && !chIds) { + if (isDeletedStreamWindow(&nextWin, groupId, pInfo->pState, &pInfo->twAggSup, &pInfo->statestore) && isClosed && + !chIds) { SPullWindowInfo pull = { .window = nextWin, .groupId = groupId, .calWin.skey = nextWin.skey, .calWin.ekey = nextWin.skey}; // add pull data request @@ -910,19 +915,18 @@ static void resetUnCloseWinInfo(SSHashObj* winMap) { } static char* getStreamOpName(uint16_t opType) { switch (opType) { - case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: - return "interval single"; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: - return "interval final"; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: - return "interval semi"; - default: - return ""; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: + return "interval single"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: + return "interval final"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: + return "interval semi"; + default: + return ""; } - } -static SSDataBlock* buildIntervalResult(SOperatorInfo* pOperator){ +static SSDataBlock* buildIntervalResult(SOperatorInfo* pOperator) { SStreamIntervalOperatorInfo* pInfo = pOperator->info; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; uint16_t opType = pOperator->operatorType; @@ -953,10 +957,10 @@ static SSDataBlock* buildIntervalResult(SOperatorInfo* pOperator){ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { SStreamIntervalOperatorInfo* pInfo = pOperator->info; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - SOperatorInfo* downstream = pOperator->pDownstream[0]; - SExprSupp* pSup = &pOperator->exprSupp; + SOperatorInfo* downstream = pOperator->pDownstream[0]; + SExprSupp* pSup = &pOperator->exprSupp; qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status); @@ -1032,7 +1036,8 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { break; } pInfo->numOfDatapack++; - printDataBlock(pBlock, IS_FINAL_INTERVAL_OP(pOperator) ? "interval final recv" : "interval semi recv", GET_TASKID(pTaskInfo)); + printDataBlock(pBlock, IS_FINAL_INTERVAL_OP(pOperator) ? "interval final recv" : "interval semi recv", + GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) { pInfo->binfo.pRes->info.type = pBlock->info.type; @@ -1056,7 +1061,8 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_INTERVAL_OP(pOperator) ? "interval final" : "interval semi", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, IS_FINAL_INTERVAL_OP(pOperator) ? "interval final" : "interval semi", + GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_CLEAR) { pInfo->pDelRes->info.type = STREAM_CLEAR; } else { @@ -1077,7 +1083,8 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { } continue; } else if (pBlock->info.type == STREAM_PULL_OVER && IS_FINAL_INTERVAL_OP(pOperator)) { - processPullOver(pBlock, pInfo->pPullDataMap, pInfo->pFinalPullDataMap, &pInfo->interval, pInfo->pPullWins, pInfo->numOfChild, pOperator); + processPullOver(pBlock, pInfo->pPullDataMap, pInfo->pFinalPullDataMap, &pInfo->interval, pInfo->pPullWins, + pInfo->numOfChild, pOperator); continue; } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { return pBlock; @@ -1151,8 +1158,8 @@ static int32_t getSelectivityBufSize(SqlFunctionCtx* pCtx) { static int32_t getMaxFunResSize(SExprSupp* pSup, int32_t numOfCols) { int32_t size = 0; for (int32_t i = 0; i < numOfCols; ++i) { - int32_t resSize = getSelectivityBufSize(pSup->pCtx + i); - size = TMAX(size, resSize); + int32_t resSize = getSelectivityBufSize(pSup->pCtx + i); + size = TMAX(size, resSize); } return size; } @@ -1160,11 +1167,12 @@ static int32_t getMaxFunResSize(SExprSupp* pSup, int32_t numOfCols) { static void streamIntervalReleaseState(SOperatorInfo* pOperator) { if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { SStreamIntervalOperatorInfo* pInfo = pOperator->info; - int32_t resSize = sizeof(TSKEY); - pInfo->statestore.streamStateSaveInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, strlen(STREAM_INTERVAL_OP_STATE_NAME), &pInfo->twAggSup.maxTs, resSize); + int32_t resSize = sizeof(TSKEY); + pInfo->statestore.streamStateSaveInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, + strlen(STREAM_INTERVAL_OP_STATE_NAME), &pInfo->twAggSup.maxTs, resSize); } SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; pAPI->stateStore.streamStateCommit(pInfo->pState); SOperatorInfo* downstream = pOperator->pDownstream[0]; if (downstream->fpSet.releaseStreamStateFn) { @@ -1175,11 +1183,11 @@ static void streamIntervalReleaseState(SOperatorInfo* pOperator) { void streamIntervalReloadState(SOperatorInfo* pOperator) { if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { SStreamIntervalOperatorInfo* pInfo = pOperator->info; - int32_t size = 0; - void* pBuf = NULL; + int32_t size = 0; + void* pBuf = NULL; int32_t code = pInfo->statestore.streamStateGetInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, strlen(STREAM_INTERVAL_OP_STATE_NAME), &pBuf, &size); - TSKEY ts = *(TSKEY*)pBuf; + TSKEY ts = *(TSKEY*)pBuf; taosMemoryFree(pBuf); pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, ts); pInfo->statestore.streamStateReloadInfo(pInfo->pState, ts); @@ -1227,7 +1235,7 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, if (pIntervalPhyNode->window.pExprs != NULL) { int32_t numOfScalar = 0; SExprInfo* pScalarExprInfo = createExprInfo(pIntervalPhyNode->window.pExprs, NULL, &numOfScalar); - int32_t code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); + int32_t code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); if (code != TSDB_CODE_SUCCESS) { goto _error; } @@ -1282,9 +1290,10 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, pInfo->numOfDatapack = 0; pInfo->pUpdated = NULL; pInfo->pUpdatedMap = NULL; - int32_t funResSize= getMaxFunResSize(&pOperator->exprSupp, numOfCols); - pInfo->pState->pFileState = pAPI->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, - compareTs, pInfo->pState, pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); + int32_t funResSize = getMaxFunResSize(&pOperator->exprSupp, numOfCols); + pInfo->pState->pFileState = + pAPI->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, + compareTs, pInfo->pState, pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); pInfo->dataVersion = 0; pInfo->statestore = pTaskInfo->storageAPI.stateStore; pInfo->recvGetAll = false; @@ -1392,7 +1401,8 @@ void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, uin } int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, int64_t gap, - SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore, SReadHandle* pHandle, SStorageAPI* pApi) { + SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore, + SReadHandle* pHandle, SStorageAPI* pApi) { pSup->resultRowSize = keySize + getResultRowSize(pCtx, numOfOutput); pSup->pScanBlock = createSpecialDataBlock(STREAM_CLEAR); pSup->gap = gap; @@ -1495,7 +1505,8 @@ void setSessionOutputBuf(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endT int32_t getSessionWinBuf(SStreamAggSupporter* pAggSup, SStreamStateCur* pCur, SResultWindowInfo* pWinInfo) { int32_t size = 0; - int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pWinInfo->sessionWin, &pWinInfo->pOutputBuf, &size); + int32_t code = + pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pWinInfo->sessionWin, &pWinInfo->pOutputBuf, &size); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -1608,7 +1619,8 @@ SStreamStateCur* getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* setSessionWinOutputInfo(pStUpdated, pNextWin); int32_t size = 0; pNextWin->sessionWin = pCurWin->sessionWin; - int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->sessionWin, &pNextWin->pOutputBuf, &size); + int32_t code = + pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->sessionWin, &pNextWin->pOutputBuf, &size); if (code != TSDB_CODE_SUCCESS) { taosMemoryFreeClear(pNextWin->pOutputBuf); SET_SESSION_WIN_INVALID(*pNextWin); @@ -1617,7 +1629,7 @@ SStreamStateCur* getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* } static int32_t compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SSHashObj* pStUpdated, - SSHashObj* pStDeleted, bool addGap) { + SSHashObj* pStDeleted, bool addGap) { SExprSupp* pSup = &pOperator->exprSupp; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; @@ -1661,7 +1673,8 @@ static int32_t compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo* } int32_t saveSessionOutputBuf(SStreamAggSupporter* pAggSup, SResultWindowInfo* pWinInfo) { - saveSessionDiscBuf(pAggSup->pState, &pWinInfo->sessionWin, pWinInfo->pOutputBuf, pAggSup->resultRowSize, &pAggSup->stateStore); + saveSessionDiscBuf(pAggSup->pState, &pWinInfo->sessionWin, pWinInfo->pOutputBuf, pAggSup->resultRowSize, + &pAggSup->stateStore); pWinInfo->pOutputBuf = NULL; return TSDB_CODE_SUCCESS; } @@ -1693,7 +1706,7 @@ static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSData pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); } - TSKEY* endTsCols = (int64_t*)pEndTsCol->pData; + TSKEY* endTsCols = (int64_t*)pEndTsCol->pData; for (int32_t i = 0; i < rows;) { if (pInfo->ignoreExpiredData && isOverdue(endTsCols[i], &pInfo->twAggSup)) { i++; @@ -1837,9 +1850,9 @@ void doBuildDeleteDataBlock(SOperatorInfo* pOp, SSHashObj* pStDeleted, SSDataBlo } static void rebuildSessionWindow(SOperatorInfo* pOperator, SArray* pWinArray, SSHashObj* pStUpdated) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; int32_t size = taosArrayGetSize(pWinArray); SStreamSessionAggOperatorInfo* pInfo = pOperator->info; @@ -1878,7 +1891,7 @@ static void rebuildSessionWindow(SOperatorInfo* pOperator, SArray* pWinArray, SS } } num++; - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &parentWin.sessionWin.win, pAggSup->gap); + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &parentWin.sessionWin.win, pAggSup->gap); initSessionOutputBuf(&childWin, &pChResult, pChild->exprSupp.pCtx, numOfOutput, pChild->exprSupp.rowEntryInfoOffset); compactFunctions(pSup->pCtx, pChild->exprSupp.pCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); @@ -1953,8 +1966,7 @@ void initGroupResInfoFromArrayList(SGroupResInfo* pGroupResInfo, SArray* pArrayL pGroupResInfo->pBuf = NULL; } -void doBuildSessionResult(SOperatorInfo* pOperator, void* pState, SGroupResInfo* pGroupResInfo, - SSDataBlock* pBlock) { +void doBuildSessionResult(SOperatorInfo* pOperator, void* pState, SGroupResInfo* pGroupResInfo, SSDataBlock* pBlock) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; // set output datablock version pBlock->info.version = pTaskInfo->version; @@ -2005,12 +2017,14 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { } else if (pOperator->status == OP_RES_TO_RETURN) { doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", + GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + printDataBlock(pBInfo->pRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", + GET_TASKID(pTaskInfo)); return pBInfo->pRes; } @@ -2031,7 +2045,8 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { if (pBlock == NULL) { break; } - printDataBlock(pBlock, IS_FINAL_SESSION_OP(pOperator) ? "final session recv" : "single session recv", GET_TASKID(pTaskInfo)); + printDataBlock(pBlock, IS_FINAL_SESSION_OP(pOperator) ? "final session recv" : "single session recv", + GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || pBlock->info.type == STREAM_CLEAR) { @@ -2065,7 +2080,8 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { } // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, IS_FINAL_SESSION_OP(pOperator), true); + doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, IS_FINAL_SESSION_OP(pOperator), + true); if (IS_FINAL_SESSION_OP(pOperator)) { int32_t chIndex = getChildIndex(pBlock); int32_t size = taosArrayGetSize(pInfo->pChildren); @@ -2094,7 +2110,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); tSimpleHashCleanup(pInfo->pStUpdated); pInfo->pStUpdated = NULL; - if(pInfo->isHistoryOp) { + if (pInfo->isHistoryOp) { getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); } initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); @@ -2109,13 +2125,15 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", + GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", GET_TASKID(pTaskInfo)); + printDataBlock(pBInfo->pRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", + GET_TASKID(pTaskInfo)); return pBInfo->pRes; } @@ -2126,8 +2144,10 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { void streamSessionReleaseState(SOperatorInfo* pOperator) { if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION) { SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); - pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_SESSION_OP_STATE_NAME, strlen(STREAM_SESSION_OP_STATE_NAME), pInfo->historyWins->pData, resSize); + int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); + pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_SESSION_OP_STATE_NAME, + strlen(STREAM_SESSION_OP_STATE_NAME), pInfo->historyWins->pData, + resSize); } SOperatorInfo* downstream = pOperator->pDownstream[0]; if (downstream->fpSet.releaseStreamStateFn) { @@ -2142,16 +2162,16 @@ void resetWinRange(STimeWindow* winRange) { void streamSessionReloadState(SOperatorInfo* pOperator) { SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; resetWinRange(&pAggSup->winRange); SResultWindowInfo winInfo = {0}; - int32_t size = 0; - void* pBuf = NULL; - int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_SESSION_OP_STATE_NAME, - strlen(STREAM_SESSION_OP_STATE_NAME), &pBuf, &size); - int32_t num = size / sizeof(SSessionKey); - SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_SESSION_OP_STATE_NAME, + strlen(STREAM_SESSION_OP_STATE_NAME), &pBuf, &size); + int32_t num = size / sizeof(SSessionKey); + SSessionKey* pSeKeyBuf = (SSessionKey*)pBuf; ASSERT(size == num * sizeof(SSessionKey)); if (!pInfo->pStUpdated && num > 0) { _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); @@ -2162,7 +2182,8 @@ void streamSessionReloadState(SOperatorInfo* pOperator) { setSessionOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].win.ekey, pSeKeyBuf[i].groupId, &winInfo); int32_t winNum = compactSessionWindow(pOperator, &winInfo, pInfo->pStUpdated, pInfo->pStDeleted, true); if (winNum > 0) { - qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, winInfo.sessionWin.win.skey, winInfo.sessionWin.groupId); + qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, winInfo.sessionWin.win.skey, + winInfo.sessionWin.groupId); if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { saveResult(winInfo, pInfo->pStUpdated); } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { @@ -2216,7 +2237,8 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh } code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, pSessionNode->gap, - pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); + pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle, + &pTaskInfo->storageAPI); if (code != TSDB_CODE_SUCCESS) { goto _error; } @@ -2399,7 +2421,8 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { } SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, int32_t numOfChild, SReadHandle* pHandle) { + SExecTaskInfo* pTaskInfo, int32_t numOfChild, + SReadHandle* pHandle) { int32_t code = TSDB_CODE_OUT_OF_MEMORY; SOperatorInfo* pOperator = createStreamSessionAggOperatorInfo(downstream, pPhyNode, pTaskInfo, pHandle); if (pOperator == NULL) { @@ -2503,9 +2526,9 @@ void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, pCurWin->winInfo.sessionWin.groupId = groupId; pCurWin->winInfo.sessionWin.win.skey = ts; pCurWin->winInfo.sessionWin.win.ekey = ts; - int32_t code = - pAggSup->stateStore.streamStateStateAddIfNotExist(pAggSup->pState, &pCurWin->winInfo.sessionWin, pKeyData, pAggSup->stateKeySize, - compareStateKey, &pCurWin->winInfo.pOutputBuf, &size); + int32_t code = pAggSup->stateStore.streamStateStateAddIfNotExist(pAggSup->pState, &pCurWin->winInfo.sessionWin, + pKeyData, pAggSup->stateKeySize, compareStateKey, + &pCurWin->winInfo.pOutputBuf, &size); pCurWin->pStateKey = (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); @@ -2515,10 +2538,11 @@ void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->winInfo.sessionWin.win)) { code = TSDB_CODE_FAILED; - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->winInfo.pOutputBuf, &pAggSup->pSessionAPI->stateStore); + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->winInfo.pOutputBuf, + &pAggSup->pSessionAPI->stateStore); pCurWin->winInfo.pOutputBuf = taosMemoryCalloc(1, size); pCurWin->pStateKey = - (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); + (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); pCurWin->pStateKey->type = pAggSup->stateKeyType; pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); @@ -2526,7 +2550,8 @@ void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, pCurWin->winInfo.sessionWin.groupId = groupId; pCurWin->winInfo.sessionWin.win.skey = ts; pCurWin->winInfo.sessionWin.win.ekey = ts; - qDebug("===stream===reset state win key. skey:%" PRId64 ", endkey:%" PRId64, pCurWin->winInfo.sessionWin.win.skey, pCurWin->winInfo.sessionWin.win.ekey); + qDebug("===stream===reset state win key. skey:%" PRId64 ", endkey:%" PRId64, pCurWin->winInfo.sessionWin.win.skey, + pCurWin->winInfo.sessionWin.win.ekey); } if (code == TSDB_CODE_SUCCESS) { @@ -2541,14 +2566,16 @@ void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, } pNextWin->winInfo.sessionWin = pCurWin->winInfo.sessionWin; - SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pNextWin->winInfo.sessionWin); + SStreamStateCur* pCur = + pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pNextWin->winInfo.sessionWin); int32_t nextSize = pAggSup->resultRowSize; - code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->winInfo.sessionWin, &pNextWin->winInfo.pOutputBuf, &nextSize); + code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->winInfo.sessionWin, + &pNextWin->winInfo.pOutputBuf, &nextSize); if (code != TSDB_CODE_SUCCESS) { SET_SESSION_WIN_INVALID(pNextWin->winInfo); } else { pNextWin->pStateKey = - (SStateKeys*)((char*)pNextWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); + (SStateKeys*)((char*)pNextWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); pNextWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); pNextWin->pStateKey->type = pAggSup->stateKeyType; pNextWin->pStateKey->pData = (char*)pNextWin->pStateKey + sizeof(SStateKeys); @@ -2619,7 +2646,7 @@ static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl return; } - int32_t rows = pSDataBlock->info.rows; + int32_t rows = pSDataBlock->info.rows; blockDataEnsureCapacity(pAggSup->pScanBlock, rows); SColumnInfoData* pKeyColInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->stateCol.slotId); for (int32_t i = 0; i < rows; i += winRows) { @@ -2747,7 +2774,7 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { tSimpleHashCleanup(pInfo->pSeUpdated); pInfo->pSeUpdated = NULL; - if(pInfo->isHistoryOp) { + if (pInfo->isHistoryOp) { getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); } @@ -2778,9 +2805,11 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { void streamStateReleaseState(SOperatorInfo* pOperator) { SStreamStateAggOperatorInfo* pInfo = pOperator->info; - int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); + int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); qDebug("===stream=== relase state. save result count:%d", (int32_t)taosArrayGetSize(pInfo->historyWins)); - pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_STATE_OP_STATE_NAME, strlen(STREAM_STATE_OP_STATE_NAME), pInfo->historyWins->pData, resSize); + pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_STATE_OP_STATE_NAME, + strlen(STREAM_STATE_OP_STATE_NAME), pInfo->historyWins->pData, + resSize); SOperatorInfo* downstream = pOperator->pDownstream[0]; if (downstream->fpSet.releaseStreamStateFn) { downstream->fpSet.releaseStreamStateFn(downstream); @@ -2789,14 +2818,14 @@ void streamStateReleaseState(SOperatorInfo* pOperator) { static void compactStateWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SResultWindowInfo* pNextWin, SSHashObj* pStUpdated, SSHashObj* pStDeleted) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - SResultRow* pCurResult = NULL; - int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SResultRow* pCurResult = NULL; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); SResultRow* pWinResult = NULL; initSessionOutputBuf(pNextWin, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); @@ -2806,7 +2835,8 @@ static void compactStateWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCur compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); tSimpleHashRemove(pStUpdated, &pNextWin->sessionWin, sizeof(SSessionKey)); if (pNextWin->isOutput && pStDeleted) { - qDebug("===stream=== save delete window info %" PRId64 ", %" PRIu64, pNextWin->sessionWin.win.skey, pNextWin->sessionWin.groupId); + qDebug("===stream=== save delete window info %" PRId64 ", %" PRIu64, pNextWin->sessionWin.win.skey, + pNextWin->sessionWin.groupId); saveDeleteRes(pStDeleted, pNextWin->sessionWin); } removeSessionResult(pStUpdated, pAggSup->pResultRows, pNextWin->sessionWin); @@ -2816,17 +2846,17 @@ static void compactStateWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCur void streamStateReloadState(SOperatorInfo* pOperator) { SStreamStateAggOperatorInfo* pInfo = pOperator->info; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; resetWinRange(&pAggSup->winRange); SSessionKey seKey = {.win.skey = INT64_MIN, .win.ekey = INT64_MIN, .groupId = 0}; - int32_t size = 0; - void* pBuf = NULL; - int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_STATE_OP_STATE_NAME, - strlen(STREAM_STATE_OP_STATE_NAME), &pBuf, &size); - int32_t num = size / sizeof(SSessionKey); + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_STATE_OP_STATE_NAME, + strlen(STREAM_STATE_OP_STATE_NAME), &pBuf, &size); + int32_t num = size / sizeof(SSessionKey); qDebug("===stream=== reload state. get result count:%d", num); - SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; + SSessionKey* pSeKeyBuf = (SSessionKey*)pBuf; ASSERT(size == num * sizeof(SSessionKey)); if (!pInfo->pSeUpdated && num > 0) { _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); @@ -2840,13 +2870,16 @@ void streamStateReloadState(SOperatorInfo* pOperator) { SStateWindowInfo curInfo = {0}; SStateWindowInfo nextInfo = {0}; SStateWindowInfo dummy = {0}; - qDebug("===stream=== reload state. try process result %" PRId64 ", %" PRIu64 ", index:%d", pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, i); + qDebug("===stream=== reload state. try process result %" PRId64 ", %" PRIu64 ", index:%d", pSeKeyBuf[i].win.skey, + pSeKeyBuf[i].groupId, i); setStateOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, NULL, &curInfo, &nextInfo); - bool cpRes = compareWinStateKey(curInfo.pStateKey,nextInfo.pStateKey); - qDebug("===stream=== reload state. next window info %" PRId64 ", %" PRIu64 ", compare:%d", nextInfo.winInfo.sessionWin.win.skey, nextInfo.winInfo.sessionWin.groupId, cpRes); + bool cpRes = compareWinStateKey(curInfo.pStateKey, nextInfo.pStateKey); + qDebug("===stream=== reload state. next window info %" PRId64 ", %" PRIu64 ", compare:%d", + nextInfo.winInfo.sessionWin.win.skey, nextInfo.winInfo.sessionWin.groupId, cpRes); if (cpRes) { compactStateWindow(pOperator, &curInfo.winInfo, &nextInfo.winInfo, pInfo->pSeUpdated, pInfo->pSeDeleted); - qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, curInfo.winInfo.sessionWin.win.skey, curInfo.winInfo.sessionWin.groupId); + qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, curInfo.winInfo.sessionWin.win.skey, + curInfo.winInfo.sessionWin.groupId); if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { saveResult(curInfo.winInfo, pInfo->pSeUpdated); } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { @@ -2858,7 +2891,8 @@ void streamStateReloadState(SOperatorInfo* pOperator) { tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curInfo.winInfo, sizeof(SResultWindowInfo)); } } else if (IS_VALID_SESSION_WIN(nextInfo.winInfo)) { - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextInfo.winInfo.pOutputBuf, &pAggSup->pSessionAPI->stateStore); + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextInfo.winInfo.pOutputBuf, + &pAggSup->pSessionAPI->stateStore); } if (IS_VALID_SESSION_WIN(curInfo.winInfo)) { @@ -2870,7 +2904,7 @@ void streamStateReloadState(SOperatorInfo* pOperator) { SOperatorInfo* downstream = pOperator->pDownstream[0]; if (downstream->fpSet.reloadStreamStateFn) { downstream->fpSet.reloadStreamStateFn(downstream); - } + } } SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, @@ -2980,7 +3014,7 @@ static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { SStreamIntervalOperatorInfo* pInfo = pOperator->info; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; SExprSupp* pSup = &pOperator->exprSupp; @@ -3164,8 +3198,8 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1); size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; - code = initAggSup(pSup, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, - pInfo->pState, &pTaskInfo->storageAPI.functionStore); + code = initAggSup(pSup, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, pInfo->pState, + &pTaskInfo->storageAPI.functionStore); if (code != TSDB_CODE_SUCCESS) { goto _error; } @@ -3197,7 +3231,7 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys pInfo->numOfDatapack = 0; pInfo->pUpdated = NULL; pInfo->pUpdatedMap = NULL; - int32_t funResSize= getMaxFunResSize(pSup, numOfCols); + int32_t funResSize = getMaxFunResSize(pSup, numOfCols); pInfo->pState->pFileState = pTaskInfo->storageAPI.stateStore.streamFileStateInit( tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, compareTs, pInfo->pState, From d1c289823f0f42c98d78342e633c1ba132713362 Mon Sep 17 00:00:00 2001 From: liuyao <54liuyao@163.com> Date: Mon, 14 Aug 2023 17:51:20 +0800 Subject: [PATCH 50/92] refactor stream session window --- source/libs/executor/inc/executil.h | 7 +- source/libs/executor/src/executil.c | 53 ++++ source/libs/executor/src/filloperator.c | 12 +- source/libs/executor/src/groupoperator.c | 6 +- .../executor/src/streamtimewindowoperator.c | 233 +++++++----------- 5 files changed, 149 insertions(+), 162 deletions(-) diff --git a/source/libs/executor/inc/executil.h b/source/libs/executor/inc/executil.h index 3339772b1c..e92414d0a2 100644 --- a/source/libs/executor/inc/executil.h +++ b/source/libs/executor/inc/executil.h @@ -183,9 +183,10 @@ void cleanupQueryTableDataCond(SQueryTableDataCond* pCond); int32_t convertFillType(int32_t mode); int32_t resultrowComparAsc(const void* p1, const void* p2); -int32_t isQualifiedTable(STableKeyInfo* info, SNode* pTagCond, void* metaHandle, bool* pQualified, SStorageAPI *pAPI); - -void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr); +int32_t isQualifiedTable(STableKeyInfo* info, SNode* pTagCond, void* metaHandle, bool* pQualified, SStorageAPI* pAPI); +char* getStreamOpName(uint16_t opType); +void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr); +void printSpecDataBlock(SSDataBlock* pBlock, const char* flag, const char* opStr, const char* taskIdStr); void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order); void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery); diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 8e0569e0f5..9b4d0c1725 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -2178,6 +2178,45 @@ int32_t createScanTableListInfo(SScanPhysiNode* pScanNode, SNodeList* pGroupTags return TSDB_CODE_SUCCESS; } +char* getStreamOpName(uint16_t opType) { + switch (opType) { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: { + return "stream scan"; + }; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: { + return "interval single"; + }; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: { + return "interval final"; + }; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: { + return "interval semi"; + }; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: { + return "stream fill"; + } + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION: { + return "session single"; + }; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION: { + return "session semi"; + }; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION: { + return "session final"; + }; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE: { + return "state single"; + }; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION: { + return "stream partitionby"; + }; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT: { + return "stream event"; + }; + } + return ""; +} + void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr) { if (!pBlock || pBlock->info.rows == 0) { qDebug("%s===stream===%s: Block is Null or Empty", taskIdStr, flag); @@ -2188,6 +2227,20 @@ void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr taosMemoryFree(pBuf); } +void printSpecDataBlock(SSDataBlock* pBlock, const char* flag, const char* opStr, const char* taskIdStr) { + if (!pBlock || pBlock->info.rows == 0) { + qDebug("%s===stream===%s: Block is Null or Empty", taskIdStr, flag); + return; + } + if (qDebugFlag & DEBUG_DEBUG) { + char* pBuf = NULL; + char flagBuf[64]; + snprintf(flagBuf, sizeof(flagBuf), "%s %s", flag, opStr); + qDebug("%s", dumpBlockData(pBlock, flagBuf, &pBuf, taskIdStr)); + taosMemoryFree(pBuf); + } +} + TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols) { return tsCols == NULL ? win->skey : tsCols[0]; } void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, int64_t delta) { diff --git a/source/libs/executor/src/filloperator.c b/source/libs/executor/src/filloperator.c index ed00329aed..1788027bd6 100644 --- a/source/libs/executor/src/filloperator.c +++ b/source/libs/executor/src/filloperator.c @@ -1292,14 +1292,14 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { (pInfo->pFillInfo->pos != FILL_POS_INVALID && pInfo->pFillInfo->needFill == true)) { doStreamFillRange(pInfo->pFillInfo, pInfo->pFillSup, pInfo->pRes); if (pInfo->pRes->info.rows > 0) { - printDataBlock(pInfo->pRes, "stream fill", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pRes; } } if (pOperator->status == OP_RES_TO_RETURN) { doDeleteFillFinalize(pOperator); if (pInfo->pRes->info.rows > 0) { - printDataBlock(pInfo->pRes, "stream fill", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pRes; } setOperatorCompleted(pOperator); @@ -1317,12 +1317,12 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { pOperator->status = OP_RES_TO_RETURN; pInfo->pFillInfo->preRowKey = INT64_MIN; if (pInfo->pRes->info.rows > 0) { - printDataBlock(pInfo->pRes, "stream fill", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pRes; } break; } - printDataBlock(pBlock, "stream fill recv", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); if (pInfo->pFillInfo->curGroupId != pBlock->info.id.groupId) { pInfo->pFillInfo->curGroupId = pBlock->info.id.groupId; @@ -1339,7 +1339,7 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { pInfo->pFillSup->hasDelete = true; doDeleteFillResult(pOperator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "stream fill delete", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } continue; @@ -1378,7 +1378,7 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { } pOperator->resultInfo.totalRows += pInfo->pRes->info.rows; - printDataBlock(pInfo->pRes, "stream fill", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pRes; } diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c index 4f0bedba3d..d097c58835 100644 --- a/source/libs/executor/src/groupoperator.c +++ b/source/libs/executor/src/groupoperator.c @@ -995,7 +995,7 @@ static SSDataBlock* buildStreamPartitionResult(SOperatorInfo* pOperator) { pOperator->resultInfo.totalRows += pDest->info.rows; pInfo->parIte = taosHashIterate(pInfo->pPartitions, pInfo->parIte); ASSERT(pDest->info.rows > 0); - printDataBlock(pDest, "stream partitionby", GET_TASKID(pTaskInfo)); + printDataBlock(pDest, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pDest; } @@ -1116,7 +1116,7 @@ static SSDataBlock* doStreamHashPartition(SOperatorInfo* pOperator) { setOperatorCompleted(pOperator); return NULL; } - printDataBlock(pBlock, "stream partitionby recv", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); switch (pBlock->info.type) { case STREAM_NORMAL: case STREAM_PULL_DATA: @@ -1126,7 +1126,7 @@ static SSDataBlock* doStreamHashPartition(SOperatorInfo* pOperator) { case STREAM_DELETE_DATA: { copyDataBlock(pInfo->pDelRes, pBlock); pInfo->pDelRes->info.type = STREAM_DELETE_RESULT; - printDataBlock(pInfo->pDelRes, "stream partitionby delete", GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } break; default: diff --git a/source/libs/executor/src/streamtimewindowoperator.c b/source/libs/executor/src/streamtimewindowoperator.c index 2832af5d10..a718373f60 100644 --- a/source/libs/executor/src/streamtimewindowoperator.c +++ b/source/libs/executor/src/streamtimewindowoperator.c @@ -913,18 +913,7 @@ static void resetUnCloseWinInfo(SSHashObj* winMap) { pPos->beUsed = true; } } -static char* getStreamOpName(uint16_t opType) { - switch (opType) { - case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: - return "interval single"; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: - return "interval final"; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: - return "interval semi"; - default: - return ""; - } -} + static SSDataBlock* buildIntervalResult(SOperatorInfo* pOperator) { SStreamIntervalOperatorInfo* pInfo = pOperator->info; @@ -1030,14 +1019,13 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); if (pBlock == NULL) { pOperator->status = OP_RES_TO_RETURN; - qDebug("===stream===return data:%s. recv datablock num:%" PRIu64, - IS_FINAL_INTERVAL_OP(pOperator) ? "interval final" : "interval semi", pInfo->numOfDatapack); + qDebug("===stream===return data:%s. recv datablock num:%" PRIu64, getStreamOpName(pOperator->operatorType), + pInfo->numOfDatapack); pInfo->numOfDatapack = 0; break; } pInfo->numOfDatapack++; - printDataBlock(pBlock, IS_FINAL_INTERVAL_OP(pOperator) ? "interval final recv" : "interval semi recv", - GET_TASKID(pTaskInfo)); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) { pInfo->binfo.pRes->info.type = pBlock->info.type; @@ -1061,8 +1049,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows != 0) { // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_INTERVAL_OP(pOperator) ? "interval final" : "interval semi", - GET_TASKID(pTaskInfo)); + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_CLEAR) { pInfo->pDelRes->info.type = STREAM_CLEAR; } else { @@ -1260,20 +1247,8 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, initResultRowInfo(&pInfo->binfo.resultRowInfo); pInfo->numOfChild = numOfChild; - pInfo->pPhyNode = (SPhysiNode*)nodesCloneNode((SNode*)pPhyNode); - if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) { - pOperator->name = "StreamFinalIntervalOperator"; - } else { - // semi interval operator does not catch result - pOperator->name = "StreamSemiIntervalOperator"; - } - - if (!IS_FINAL_INTERVAL_OP(pOperator) || numOfChild == 0) { - pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - } - pInfo->pPullWins = taosArrayInit(8, sizeof(SPullWindowInfo)); pInfo->pullIndex = 0; _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); @@ -1299,6 +1274,10 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, pInfo->recvGetAll = false; pOperator->operatorType = pPhyNode->type; + if (!IS_FINAL_INTERVAL_OP(pOperator) || numOfChild == 0) { + pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; + } + pOperator->name = getStreamOpName(pOperator->operatorType); pOperator->blocking = true; pOperator->status = OP_NOT_OPENED; pOperator->info = pInfo; @@ -1984,6 +1963,25 @@ void doBuildSessionResult(SOperatorInfo* pOperator, void* pState, SGroupResInfo* cleanupGroupResInfo(pGroupResInfo); } } + +static SSDataBlock* buildSessionResult(SOperatorInfo* pOperator) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + return NULL; +} + void getMaxTsWins(const SArray* pAllWins, SArray* pMaxWins) { int32_t size = taosArrayGetSize(pAllWins); if (size == 0) { @@ -2011,23 +2009,14 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { SOptrBasicInfo* pBInfo = &pInfo->binfo; SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - qDebug("===stream=== stream session agg"); + qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status); if (pOperator->status == OP_EXEC_DONE) { return NULL; } else if (pOperator->status == OP_RES_TO_RETURN) { - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", - GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; + SSDataBlock* opRes = buildSessionResult(pOperator); + if (opRes) { + return opRes; } - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", - GET_TASKID(pTaskInfo)); - return pBInfo->pRes; - } - setOperatorCompleted(pOperator); return NULL; } @@ -2045,8 +2034,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { if (pBlock == NULL) { break; } - printDataBlock(pBlock, IS_FINAL_SESSION_OP(pOperator) ? "final session recv" : "single session recv", - GET_TASKID(pTaskInfo)); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || pBlock->info.type == STREAM_CLEAR) { @@ -2117,24 +2105,9 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { pInfo->pUpdated = NULL; blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); -#if 0 - char* pBuf = streamStateSessionDump(pAggSup->pState); - qDebug("===stream===final session%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", - GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_SESSION_OP(pOperator) ? "final session" : "single session", - GET_TASKID(pTaskInfo)); - return pBInfo->pRes; + SSDataBlock* opRes = buildSessionResult(pOperator); + if (opRes) { + return opRes; } setOperatorCompleted(pOperator); @@ -2276,8 +2249,8 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh if (pHandle) { pInfo->isHistoryOp = pHandle->fillHistory; } - - setOperatorInfo(pOperator, "StreamSessionWindowAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, true, + pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION; + setOperatorInfo(pOperator, getStreamOpName(pOperator->operatorType), QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, true, OP_NOT_OPENED, pInfo, pTaskInfo); pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionAgg, NULL, destroyStreamSessionAggOperatorInfo, optrDefaultBufFn, NULL); @@ -2312,22 +2285,15 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - qDebug("===stream=== stream session semi agg"); + qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status); if (pOperator->status == OP_EXEC_DONE) { return NULL; } { - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "semi session", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; - } - - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "semi session delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; + SSDataBlock* opRes = buildSessionResult(pOperator); + if (opRes) { + return opRes; } if (pOperator->status == OP_RES_TO_RETURN) { @@ -2354,7 +2320,7 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { pOperator->status = OP_RES_TO_RETURN; break; } - printDataBlock(pBlock, "semi session recv", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || pBlock->info.type == STREAM_CLEAR) { @@ -2395,22 +2361,9 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { pInfo->pUpdated = NULL; blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity); -#if 0 - char* pBuf = streamStateSessionDump(pAggSup->pState); - qDebug("===stream===semi session%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "semi session", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; - } - - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "semi session delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; + SSDataBlock* opRes = buildSessionResult(pOperator); + if (opRes) { + return opRes; } clearFunctionContext(&pOperator->exprSupp); @@ -2432,7 +2385,6 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream SStorageAPI* pAPI = &pTaskInfo->storageAPI; SStreamSessionAggOperatorInfo* pInfo = pOperator->info; pOperator->operatorType = pPhyNode->type; - char* name = getStreamOpName(pOperator->operatorType); if (pPhyNode->type != QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) { pInfo->pUpdateRes = createSpecialDataBlock(STREAM_CLEAR); @@ -2440,8 +2392,7 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionSemiAgg, NULL, destroyStreamSessionAggOperatorInfo, optrDefaultBufFn, NULL); } - setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); - setOperatorInfo(pOperator, name, pPhyNode->type, false, OP_NOT_OPENED, pInfo, pTaskInfo); + setOperatorInfo(pOperator, getStreamOpName(pOperator->operatorType), pPhyNode->type, false, OP_NOT_OPENED, pInfo, pTaskInfo); if (numOfChild > 0) { pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*)); @@ -2697,6 +2648,25 @@ static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl } } +static SSDataBlock* buildStateResult(SOperatorInfo* pOperator) { + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + return NULL; +} + static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -2708,16 +2678,9 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; qDebug("===stream=== stream state agg"); if (pOperator->status == OP_RES_TO_RETURN) { - doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single state delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "single state", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; + SSDataBlock* resBlock = buildStateResult(pOperator); + if (resBlock != NULL) { + return resBlock; } setOperatorCompleted(pOperator); @@ -2782,22 +2745,9 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { pInfo->pUpdated = NULL; blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); -#if 0 - char* pBuf = streamStateSessionDump(pInfo->streamAggSup.pState); - qDebug("===stream===final session%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single state delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "single state", GET_TASKID(pTaskInfo)); - return pBInfo->pRes; + SSDataBlock* resBlock = buildStateResult(pOperator); + if (resBlock != NULL) { + return resBlock; } setOperatorCompleted(pOperator); return NULL; @@ -3015,24 +2965,18 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { SStreamIntervalOperatorInfo* pInfo = pOperator->info; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SExprSupp* pSup = &pOperator->exprSupp; - SExprSupp* pSup = &pOperator->exprSupp; + qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status); if (pOperator->status == OP_EXEC_DONE) { return NULL; } if (pOperator->status == OP_RES_TO_RETURN) { - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows > 0) { - printDataBlock(pInfo->binfo.pRes, "single interval", GET_TASKID(pTaskInfo)); - return pInfo->binfo.pRes; + SSDataBlock* resBlock = buildIntervalResult(pOperator); + if (resBlock != NULL) { + return resBlock; } if (pInfo->recvGetAll) { @@ -3065,25 +3009,26 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { while (1) { SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); if (pBlock == NULL) { - qDebug("===stream===return data:single interval. recv datablock num:%" PRIu64, pInfo->numOfDatapack); + qDebug("===stream===return data:%s. recv datablock num:%" PRIu64, getStreamOpName(pOperator->operatorType), + pInfo->numOfDatapack); pInfo->numOfDatapack = 0; break; } pInfo->numOfDatapack++; - printDataBlock(pBlock, "single interval recv", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || pBlock->info.type == STREAM_CLEAR) { doDeleteWindows(pOperator, &pInfo->interval, pBlock, pInfo->pDelWins, pInfo->pUpdatedMap); continue; } else if (pBlock->info.type == STREAM_GET_ALL) { - qDebug("===stream===single interval recv|block type STREAM_GET_ALL"); + qDebug("===stream===%s recv|block type STREAM_GET_ALL", getStreamOpName(pOperator->operatorType)); pInfo->recvGetAll = true; getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); continue; } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - printDataBlock(pBlock, "single interval", GET_TASKID(pTaskInfo)); + printDataBlock(pBlock, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pBlock; } else { ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); @@ -3129,19 +3074,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { tSimpleHashCleanup(pInfo->pUpdatedMap); pInfo->pUpdatedMap = NULL; - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval delete", GET_TASKID(pTaskInfo)); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows > 0) { - printDataBlock(pInfo->binfo.pRes, "single interval", GET_TASKID(pTaskInfo)); - return pInfo->binfo.pRes; - } - - return NULL; + return buildIntervalResult(pOperator); } SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, From 1d33a8d4c09e0c3eaa48b08da506df3d1611aebf Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 14 Aug 2023 10:06:33 +0000 Subject: [PATCH 51/92] rebuild index at tag0 --- source/dnode/mnode/impl/src/mndStb.c | 43 ++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 70fd74afc0..903181282a 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -18,6 +18,7 @@ #include "mndDb.h" #include "mndDnode.h" #include "mndIndex.h" +#include "mndIndexComm.h" #include "mndInfoSchema.h" #include "mndMnode.h" #include "mndPerfSchema.h" @@ -822,7 +823,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat return -1; } - if(pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags){ + if (pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags) { terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW; return -1; } @@ -857,11 +858,36 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea SStbObj stbObj = {0}; int32_t code = -1; + char fullIdxName[TSDB_INDEX_FNAME_LEN * 2] = {0}; + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq, "create-stb"); if (pTrans == NULL) goto _OVER; mInfo("trans:%d, used to create stb:%s", pTrans->id, pCreate->name); if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER; + + SSchema *pSchema = &(stbObj.pTags[0]); + sprintf(fullIdxName, "%s.%s_default", pDb->name, pSchema->name); + + SSIdx idx = {0}; + if (mndAcquireGlobalIdx(pMnode, fullIdxName, SDB_IDX, &idx) == 0) { + terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; + mndReleaseIdx(pMnode, idx.pIdx); + goto _OVER; + } + + SIdxObj idxObj; + memcpy(idxObj.name, fullIdxName, TSDB_INDEX_FNAME_LEN); + memcpy(idxObj.stb, stbObj.name, TSDB_TABLE_FNAME_LEN); + memcpy(idxObj.db, stbObj.db, TSDB_DB_FNAME_LEN); + memcpy(idxObj.colName, pSchema->name, TSDB_COL_NAME_LEN); + idxObj.createdTime = taosGetTimestampMs(); + idxObj.uid = mndGenerateUid(fullIdxName, strlen(fullIdxName)); + idxObj.stbUid = stbObj.uid; + idxObj.dbUid = stbObj.dbUid; + + if (mndSetCreateIdxCommitLogs(pMnode, pTrans, &idxObj) < 0) goto _OVER; + if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER; if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; code = 0; @@ -956,7 +982,7 @@ static int32_t mndBuildStbFromAlter(SStbObj *pStb, SStbObj *pDst, SMCreateStbReq return -1; } - if(pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags){ + if (pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags) { terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW; return -1; } @@ -1188,7 +1214,7 @@ static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *p return -1; } - if(pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ntags){ + if (pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ntags) { terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW; return -1; } @@ -1478,7 +1504,8 @@ static int32_t mndAlterStbTagBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj SSchema *pTag = pNew->pTags + tag; - if (!(pTag->type == TSDB_DATA_TYPE_BINARY || pTag->type == TSDB_DATA_TYPE_NCHAR || pTag->type == TSDB_DATA_TYPE_GEOMETRY)) { + if (!(pTag->type == TSDB_DATA_TYPE_BINARY || pTag->type == TSDB_DATA_TYPE_NCHAR || + pTag->type == TSDB_DATA_TYPE_GEOMETRY)) { terrno = TSDB_CODE_MND_INVALID_STB_OPTION; return -1; } @@ -1506,7 +1533,7 @@ static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray return -1; } - if(pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ncols){ + if (pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ncols) { terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW; return -1; } @@ -1598,7 +1625,8 @@ static int32_t mndAlterStbColumnBytes(SMnode *pMnode, const SStbObj *pOld, SStbO } SSchema *pCol = pNew->pColumns + col; - if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR || pCol->type == TSDB_DATA_TYPE_GEOMETRY)) { + if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR || + pCol->type == TSDB_DATA_TYPE_GEOMETRY)) { terrno = TSDB_CODE_MND_INVALID_STB_OPTION; return -1; } @@ -3182,7 +3210,6 @@ static int32_t mndRetrieveStbCol(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB SSdb *pSdb = pMnode->pSdb; SStbObj *pStb = NULL; - int32_t numOfRows = 0; if (!pShow->sysDbRsp) { numOfRows = buildSysDbColsInfo(pBlock, pShow->db, pShow->filterTb); @@ -3206,7 +3233,7 @@ static int32_t mndRetrieveStbCol(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB if (pShow->pIter == NULL) break; } else { fetch = true; - void *pKey = taosHashGetKey(pShow->pIter, NULL); + void *pKey = taosHashGetKey(pShow->pIter, NULL); pStb = sdbAcquire(pSdb, SDB_STB, pKey); if (!pStb) continue; } From 5d3232d275f97ecf63205dc04c211b0887f5e39e Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Aug 2023 18:14:32 +0800 Subject: [PATCH 52/92] fix(stream): fix an syntax error. --- source/libs/stream/src/streamExec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index cebae0801d..b513d7c13e 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -548,7 +548,7 @@ int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); } } else { - qDebug("s-task:%d sink task does not transfer state", id); + qDebug("s-task:%s sink task does not transfer state", id); } } From 1a08ffc79f3a8f58c75b60cde50111bc8722ed42 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Aug 2023 19:27:09 +0800 Subject: [PATCH 53/92] fix(stream): check error. --- source/libs/stream/src/streamDispatch.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 557b92baf9..8de034d1ca 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -730,10 +730,14 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i // flag. here we need to retry dispatch this message to downstream task immediately. handle the case the failure // happened too fast. // todo handle the shuffle dispatch failure - qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", id, pRsp->downstreamTaskId, - tstrerror(code), ++pTask->msgInfo.retryCount); - int32_t ret = doDispatchAllBlocks(pTask, pTask->msgInfo.pData); - if (ret != TSDB_CODE_SUCCESS) { + if (code == TSDB_CODE_STREAM_TASK_NOT_EXIST) { // destination task does not exist, not retry anymore + qWarn("s-task:%s failed to dispatch msg to task:0x%x, no retry, since it is destroyed already", id); + } else { + qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", id, pRsp->downstreamTaskId, + tstrerror(code), ++pTask->msgInfo.retryCount); + int32_t ret = doDispatchAllBlocks(pTask, pTask->msgInfo.pData); + if (ret != TSDB_CODE_SUCCESS) { + } } return TSDB_CODE_SUCCESS; From a334547726a5a85a8092119773dd2f5e24a5eeab Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Aug 2023 19:28:36 +0800 Subject: [PATCH 54/92] fix(stream): fix an syntax error. --- source/libs/stream/src/streamDispatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 8de034d1ca..12ff064963 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -731,7 +731,7 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i // happened too fast. // todo handle the shuffle dispatch failure if (code == TSDB_CODE_STREAM_TASK_NOT_EXIST) { // destination task does not exist, not retry anymore - qWarn("s-task:%s failed to dispatch msg to task:0x%x, no retry, since it is destroyed already", id); + qWarn("s-task:%s failed to dispatch msg to task:0x%x, no retry, since it is destroyed already", id, pRsp->downstreamTaskId); } else { qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", id, pRsp->downstreamTaskId, tstrerror(code), ++pTask->msgInfo.retryCount); From a48d137d32c039fb68764abde491eb221e992e75 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 14 Aug 2023 11:56:47 +0000 Subject: [PATCH 55/92] rebuild index at tag0 --- source/dnode/mnode/impl/src/mndStb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 903181282a..cfac5d0a61 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -870,7 +870,7 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea sprintf(fullIdxName, "%s.%s_default", pDb->name, pSchema->name); SSIdx idx = {0}; - if (mndAcquireGlobalIdx(pMnode, fullIdxName, SDB_IDX, &idx) == 0) { + if (mndAcquireGlobalIdx(pMnode, fullIdxName, SDB_IDX, &idx) == 0 && idx.pIdx != NULL) { terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; mndReleaseIdx(pMnode, idx.pIdx); goto _OVER; From 3067417ea31eacf21f94fe57c6691f5c2a60d4d8 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 14 Aug 2023 12:01:17 +0000 Subject: [PATCH 56/92] rebuild index at tag0 --- source/dnode/mnode/impl/src/mndStb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index cfac5d0a61..03b05f8c82 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -873,6 +873,7 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea if (mndAcquireGlobalIdx(pMnode, fullIdxName, SDB_IDX, &idx) == 0 && idx.pIdx != NULL) { terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; mndReleaseIdx(pMnode, idx.pIdx); + goto _OVER; } From 1447d1d55c036ac5f050e3072e01d06d33f5200d Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 15 Aug 2023 00:40:12 +0000 Subject: [PATCH 57/92] rebuild index at tag0 --- include/os/osRand.h | 2 ++ source/dnode/mnode/impl/src/mndStb.c | 4 +++- source/os/src/osRand.c | 17 +++++++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/os/osRand.h b/include/os/osRand.h index 27d07e8c6f..5d907bba15 100644 --- a/include/os/osRand.h +++ b/include/os/osRand.h @@ -32,6 +32,8 @@ void taosSeedRand(uint32_t seed); uint32_t taosRand(void); uint32_t taosRandR(uint32_t* pSeed); void taosRandStr(char* str, int32_t size); +void taosRandStr2(char* str, int32_t size); + uint32_t taosSafeRand(void); #ifdef __cplusplus diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 03b05f8c82..ccfad404d8 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -866,8 +866,10 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea mInfo("trans:%d, used to create stb:%s", pTrans->id, pCreate->name); if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER; + char randStr[16] = {0}; + taosRandStr2(randStr, tListLen(randStr) - 1); SSchema *pSchema = &(stbObj.pTags[0]); - sprintf(fullIdxName, "%s.%s_default", pDb->name, pSchema->name); + sprintf(fullIdxName, "%s.%s_%s", pDb->name, pSchema->name, randStr); SSIdx idx = {0}; if (mndAcquireGlobalIdx(pMnode, fullIdxName, SDB_IDX, &idx) == 0 && idx.pIdx != NULL) { diff --git a/source/os/src/osRand.c b/source/os/src/osRand.c index 83c36a422d..9cb6f6e52a 100644 --- a/source/os/src/osRand.c +++ b/source/os/src/osRand.c @@ -27,11 +27,11 @@ void taosSeedRand(uint32_t seed) { return srand(seed); } uint32_t taosRand(void) { #ifdef WINDOWS - unsigned int pSeed; - rand_s(&pSeed); - return pSeed; + unsigned int pSeed; + rand_s(&pSeed); + return pSeed; #else - return rand(); + return rand(); #endif } @@ -80,6 +80,15 @@ void taosRandStr(char* str, int32_t size) { const char* set = "abcdefghijklmnopqrstuvwxyz0123456789-_."; int32_t len = 39; + for (int32_t i = 0; i < size; ++i) { + str[i] = set[taosRand() % len]; + } +} + +void taosRandStr2(char* str, int32_t size) { + const char* set = "abcdefghijklmnopqrstuvwxyz0123456789"; + int32_t len = 36; + for (int32_t i = 0; i < size; ++i) { str[i] = set[taosRand() % len]; } From ef7f762c62b6bb43272a189ca16225738209f872 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 15 Aug 2023 00:41:48 +0000 Subject: [PATCH 58/92] rebuild index at tag0 --- source/dnode/mnode/impl/src/mndStb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index ccfad404d8..f80e721324 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -866,7 +866,7 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea mInfo("trans:%d, used to create stb:%s", pTrans->id, pCreate->name); if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER; - char randStr[16] = {0}; + char randStr[24] = {0}; taosRandStr2(randStr, tListLen(randStr) - 1); SSchema *pSchema = &(stbObj.pTags[0]); sprintf(fullIdxName, "%s.%s_%s", pDb->name, pSchema->name, randStr); From 9ec64b9201a34223eaec8e46f91e9c8c00283d32 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 15 Aug 2023 02:01:13 +0000 Subject: [PATCH 59/92] rebuild index at tag0 --- source/dnode/mnode/impl/src/mndStb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index f80e721324..c6dce0d578 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -879,7 +879,7 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea goto _OVER; } - SIdxObj idxObj; + SIdxObj idxObj = {0}; memcpy(idxObj.name, fullIdxName, TSDB_INDEX_FNAME_LEN); memcpy(idxObj.stb, stbObj.name, TSDB_TABLE_FNAME_LEN); memcpy(idxObj.db, stbObj.db, TSDB_DB_FNAME_LEN); From 271ecf6beff4dcea8e83b6945406a3050dd2d793 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 15 Aug 2023 10:41:01 +0800 Subject: [PATCH 60/92] update tag index case --- tests/system-test/0-others/show_tag_index.py | 20 +++++++++++-------- tests/system-test/0-others/tag_index_basic.py | 7 +++++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/system-test/0-others/show_tag_index.py b/tests/system-test/0-others/show_tag_index.py index 663426b7ff..d39f9eaab9 100644 --- a/tests/system-test/0-others/show_tag_index.py +++ b/tests/system-test/0-others/show_tag_index.py @@ -59,14 +59,18 @@ class TDTestCase: tdSql.checkData(1, 2, 2) def check_indexes(self): - tdSql.checkRows(1) - tdSql.checkCols(7) - tdSql.checkData(0, 0, 'idx1') - tdSql.checkData(0, 1, 'db') - tdSql.checkData(0, 2, 'stb') - tdSql.checkData(0, 3, None) - tdSql.checkData(0, 5, 't1') - tdSql.checkData(0, 6, 'tag_index') + tdSql.checkRows(2) + for i in range(2): + col_name = tdSql.getData(i, 5) + if col_name == "t0": + continue + tdSql.checkCols(7) + tdSql.checkData(i, 0, 'idx1') + tdSql.checkData(i, 1, 'db') + tdSql.checkData(i, 2, 'stb') + tdSql.checkData(i, 3, None) + tdSql.checkData(i, 5, 't1') + tdSql.checkData(i, 6, 'tag_index') def run(self): tdSql.execute(f'create database db') diff --git a/tests/system-test/0-others/tag_index_basic.py b/tests/system-test/0-others/tag_index_basic.py index 72ed559ffd..c1e1d521d2 100644 --- a/tests/system-test/0-others/tag_index_basic.py +++ b/tests/system-test/0-others/tag_index_basic.py @@ -118,12 +118,15 @@ class TDTestCase: def show_tagidx(self, stbname): sql = f'select index_name,column_name from information_schema.ins_indexes where db_name="db"' tdSql.query(sql) - rows = len(self.tag_dict.keys())-1 + rows = len(self.tag_dict.keys()) tdSql.checkRows(rows) for i in range(rows): col_name = tdSql.getData(i, 1) idx_name = f'idx_{col_name}' + # skip first tag + if col_name == "t1": + continue tdSql.checkData(i, 0, idx_name) tdLog.info(f' show {rows} tag indexs ok.') @@ -201,7 +204,7 @@ class TDTestCase: # check idx result is 0 sql = f'select index_name,column_name from information_schema.ins_indexes where db_name="db"' tdSql.query(sql) - tdSql.checkRows(0) + tdSql.checkRows(1) tdLog.info(f' drop {cnt} tag indexs ok.') # create long name idx From 0acb00c5165de1b2031870b02a3085829bb9a07a Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 15 Aug 2023 11:48:56 +0800 Subject: [PATCH 61/92] fix(stream): add log. --- source/libs/stream/src/stream.c | 2 +- source/libs/stream/src/streamDispatch.c | 3 ++- source/libs/stream/src/streamExec.c | 12 +++--------- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index e9b38dfff2..af67490888 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -378,7 +378,7 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { } } else if (type == STREAM_INPUT__CHECKPOINT || type == STREAM_INPUT__TRANS_STATE) { taosWriteQitem(pTask->inputQueue->queue, pItem); - qDebug("s-task:%s trans-state blockdata enqueue, total in queue:%d, size:%.2fMiB", pTask->id.idStr, total, size); + qDebug("s-task:%s checkpoint/trans-state blockdata enqueue, total in queue:%d, size:%.2fMiB", pTask->id.idStr, total, size); } else if (type == STREAM_INPUT__GET_RES) { // use the default memory limit, refactor later. taosWriteQitem(pTask->inputQueue->queue, pItem); diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 12ff064963..bb32173404 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -364,7 +364,8 @@ static int32_t doSendDispatchMsg(SStreamTask* pTask, const SStreamDispatchReq* p msg.pCont = buf; msg.msgType = pTask->msgInfo.msgType; - qDebug("s-task:%s dispatch msg to taskId:0x%x vgId:%d data msg", pTask->id.idStr, pReq->taskId, vgId); + qDebug("s-task:%s dispatch msg to taskId:0x%x vgId:%d data msg, len:%d", pTask->id.idStr, pReq->taskId, vgId, + msg.contLen); return tmsgSendReq(pEpSet, &msg); FAIL: diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index b513d7c13e..6e6f23be01 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -421,17 +421,12 @@ static int32_t extractBlocksFromInputQ(SStreamTask* pTask, SStreamQueueItem** pI SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue); if (qItem == NULL) { - if (pTask->info.taskLevel == TASK_LEVEL__SOURCE && (++retryTimes) < MAX_RETRY_TIMES) { - taosMsleep(10); - qDebug("===stream===try again batchSize:%d, retry:%d, %s", *numOfBlocks, retryTimes, id); - continue; - } - qDebug("===stream===break batchSize:%d, %s", *numOfBlocks, id); return TSDB_CODE_SUCCESS; } - qDebug("s-task:%s sink task handle result block one-by-one", id); + qDebug("s-task:%s sink task handle block one-by-one, type:%d", id, qItem->type); + *numOfBlocks = 1; *pInput = qItem; return TSDB_CODE_SUCCESS; @@ -467,8 +462,7 @@ static int32_t extractBlocksFromInputQ(SStreamTask* pTask, SStreamQueueItem** pI return TSDB_CODE_SUCCESS; } else { // previous existed blocks needs to be handle, before handle the checkpoint msg block - qDebug("s-task:%s checkpoint/transtate msg extracted, handle previous block first, numOfBlocks:%d", id, - *numOfBlocks); + qDebug("s-task:%s checkpoint/transtate msg extracted, handle previous blocks, numOfBlocks:%d", id, *numOfBlocks); streamQueueProcessFail(pTask->inputQueue); return TSDB_CODE_SUCCESS; } From 01a7dfbc341dc6a41b0ecd8b3ec6150e51d6fd08 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 15 Aug 2023 12:59:30 +0800 Subject: [PATCH 62/92] feat: add irate distributed execution --- include/libs/function/functionMgt.h | 2 + source/libs/function/inc/builtinsimpl.h | 3 + source/libs/function/src/builtins.c | 63 +++++++++++++++++++ source/libs/function/src/builtinsimpl.c | 81 +++++++++++++++++++++++++ 4 files changed, 149 insertions(+) diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 402b8f0309..eebb69e6ba 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -157,6 +157,8 @@ typedef enum EFunctionType { FUNCTION_TYPE_AVG_MERGE, FUNCTION_TYPE_STDDEV_PARTIAL, FUNCTION_TYPE_STDDEV_MERGE, + FUNCTION_TYPE_IRATE_PARTIAL, + FUNCTION_TYPE_IRATE_MERGE, // geometry functions FUNCTION_TYPE_GEOM_FROM_TEXT = 4250, diff --git a/source/libs/function/inc/builtinsimpl.h b/source/libs/function/inc/builtinsimpl.h index c3afc30a7b..d2f19ed2eb 100644 --- a/source/libs/function/inc/builtinsimpl.h +++ b/source/libs/function/inc/builtinsimpl.h @@ -127,7 +127,10 @@ int32_t derivativeFunction(SqlFunctionCtx* pCtx); bool getIrateFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); bool irateFuncSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo); int32_t irateFunction(SqlFunctionCtx* pCtx); +int32_t irateFunctionMerge(SqlFunctionCtx* pCtx); int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); +int32_t iratePartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); +int32_t getIrateInfoSize(); int32_t cachedLastRowFunction(SqlFunctionCtx* pCtx); diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index cee4000155..ef7c9d1442 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1567,6 +1567,43 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len) return TSDB_CODE_SUCCESS; } +static int32_t translateIrateImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) { + if (3 != LIST_LENGTH(pFunc->pParameterList)) { + return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); + } + + uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; + if (isPartial) { + if (!IS_NUMERIC_TYPE(colType)) { + return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + } + pFunc->node.resType = (SDataType){.bytes = getIrateInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; + } else { + if (TSDB_DATA_TYPE_BINARY != colType) { + return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + } + pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE}; + + // add database precision as param + uint8_t dbPrec = pFunc->node.resType.precision; + int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + + + return TSDB_CODE_SUCCESS; +} + +static int32_t translateIratePartial(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { + return translateIrateImpl(pFunc, pErrBuf, len, true); +} + +static int32_t translateIrateMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { + return translateIrateImpl(pFunc, pErrBuf, len, false); +} + static int32_t translateInterp(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList); uint8_t dbPrec = pFunc->node.resType.precision; @@ -2604,6 +2641,32 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .initFunc = irateFuncSetup, .processFunc = irateFunction, .sprocessFunc = irateScalarFunction, + .finalizeFunc = irateFinalize, + .pPartialFunc = "_irate_partial", + .pMergeFunc = "_irate_merge" + }, + { + .name = "_irate_partial", + .type = FUNCTION_TYPE_IRATE_PARTIAL, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | + FUNC_MGT_FORBID_SYSTABLE_FUNC, + .translateFunc = translateIratePartial, + .getEnvFunc = getIrateFuncEnv, + .initFunc = irateFuncSetup, + .processFunc = irateFunction, + .sprocessFunc = irateScalarFunction, + .finalizeFunc = iratePartialFinalize + }, + { + .name = "_irate_merge", + .type = FUNCTION_TYPE_IRATE_MERGE, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | + FUNC_MGT_FORBID_SYSTABLE_FUNC, + .translateFunc = translateIrateMerge, + .getEnvFunc = getIrateFuncEnv, + .initFunc = irateFuncSetup, + .processFunc = irateFunctionMerge, + .sprocessFunc = irateScalarFunction, .finalizeFunc = irateFinalize }, { diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index fad8c9ca5b..631f943915 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -5768,6 +5768,8 @@ int32_t derivativeFunction(SqlFunctionCtx* pCtx) { return TSDB_CODE_SUCCESS; } +int32_t getIrateInfoSize() { return (int32_t)sizeof(SRateInfo); } + bool getIrateFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) { pEnv->calcMemSize = sizeof(SRateInfo); return true; @@ -5868,6 +5870,85 @@ static double doCalcRate(const SRateInfo* pRateInfo, double tickPerSec) { return (duration > 0) ? ((double)diff) / (duration / tickPerSec) : 0.0; } +static void irateTransferInfoImpl(TSKEY inputKey, SRateInfo* pInput, SRateInfo* pOutput) { + if (inputKey > pOutput->lastKey) { + pOutput->firstKey = pOutput->lastKey; + pOutput->lastKey = pInput->firstKey; + + pOutput->firstValue = pOutput->lastValue; + pOutput->lastValue = pInput->firstValue; + } else if ((inputKey < pOutput->lastKey) && (inputKey > pOutput->firstKey)) { + pOutput->firstKey = pOutput->lastKey; + pOutput->firstValue = pOutput->lastValue; + } else { + // inputKey < pOutput->firstKey + } +} + +static int32_t irateTransferInfo(SRateInfo* pInput, SRateInfo* pOutput) { + pOutput->hasResult = pInput->hasResult; + if (pInput->firstKey == pOutput->firstKey || pInput->firstKey == pOutput->lastKey || + pInput->lastKey == pOutput->firstKey || pInput->lastKey == pOutput->lastKey) { + return TSDB_CODE_FUNC_DUP_TIMESTAMP; + } + + if (pInput->firstKey != INT64_MIN) { + irateTransferInfoImpl(pInput->firstKey, pInput, pOutput); + } + + if (pInput->lastKey != INT64_MIN) { + irateTransferInfoImpl(pInput->lastKey, pInput, pOutput); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t irateFunctionMerge(SqlFunctionCtx* pCtx) { + SInputColumnInfoData* pInput = &pCtx->input; + SColumnInfoData* pCol = pInput->pData[0]; + if (pCol->info.type != TSDB_DATA_TYPE_BINARY) { + return TSDB_CODE_FUNC_FUNTION_PARA_TYPE; + } + + SRateInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + + int32_t start = pInput->startRowIndex; + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); + SRateInfo* pInputInfo = (SRateInfo*)varDataVal(data); + if (pInputInfo->hasResult) { + int32_t code = irateTransferInfo(pInputInfo, pInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + } + + if (pInfo->hasResult) { + GET_RES_INFO(pCtx)->numOfRes = 1; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t iratePartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { + SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); + SRateInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + int32_t resultBytes = getIrateInfoSize(); + char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char)); + + memcpy(varDataVal(res), pInfo, resultBytes); + varDataSetLen(res, resultBytes); + + int32_t slotId = pCtx->pExpr->base.resSchema.slotId; + SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); + + colDataSetVal(pCol, pBlock->info.rows, res, false); + + taosMemoryFree(res); + return pResInfo->numOfRes; +} + int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { int32_t slotId = pCtx->pExpr->base.resSchema.slotId; SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); From f7a5bef17dbd3d70365528370973618b31c2439e Mon Sep 17 00:00:00 2001 From: kailixu Date: Tue, 15 Aug 2023 13:02:32 +0800 Subject: [PATCH 63/92] enh: disable stream/udf on windows --- include/util/taoserror.h | 1 + source/dnode/mgmt/mgmt_dnode/src/dmInt.c | 2 ++ source/dnode/mgmt/mgmt_qnode/src/qmInt.c | 2 ++ source/dnode/mgmt/mgmt_snode/src/smInt.c | 2 ++ source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 2 ++ source/dnode/mgmt/node_mgmt/src/dmEnv.c | 4 +++- source/libs/parser/src/parTranslater.c | 13 +++++++++++++ source/util/src/terror.c | 1 + 8 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index b43985074c..75ab916230 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -707,6 +707,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_INVALID_OPTR_USAGE TAOS_DEF_ERROR_CODE(0, 0x2667) #define TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x2668) #define TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED TAOS_DEF_ERROR_CODE(0, 0x2669) +#define TSDB_CODE_PAR_INVALID_PLATFORM TAOS_DEF_ERROR_CODE(0, 0x2670) #define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF) //planner diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c index 09783a5ea9..f59d04e618 100644 --- a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c @@ -59,9 +59,11 @@ static int32_t dmOpenMgmt(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { return -1; } +#ifdef WINDOWS if (udfStartUdfd(pMgmt->pData->dnodeId) != 0) { dError("failed to start udfd"); } +#endif pOutput->pMgmt = pMgmt; return 0; diff --git a/source/dnode/mgmt/mgmt_qnode/src/qmInt.c b/source/dnode/mgmt/mgmt_qnode/src/qmInt.c index 3b425a0b49..82bc2f36f0 100644 --- a/source/dnode/mgmt/mgmt_qnode/src/qmInt.c +++ b/source/dnode/mgmt/mgmt_qnode/src/qmInt.c @@ -57,11 +57,13 @@ static int32_t qmOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("qnode-impl", "initialized"); +#ifdef WINDOWS if (udfcOpen() != 0) { dError("qnode can not open udfc"); qmClose(pMgmt); return -1; } +#endif if (qmStartWorker(pMgmt) != 0) { dError("failed to start qnode worker since %s", terrstr()); diff --git a/source/dnode/mgmt/mgmt_snode/src/smInt.c b/source/dnode/mgmt/mgmt_snode/src/smInt.c index e222349767..7607fcac61 100644 --- a/source/dnode/mgmt/mgmt_snode/src/smInt.c +++ b/source/dnode/mgmt/mgmt_snode/src/smInt.c @@ -65,11 +65,13 @@ int32_t smOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("snode-worker", "initialized"); +#ifdef WINDOWS if (udfcOpen() != 0) { dError("failed to open udfc in snode"); smClose(pMgmt); return -1; } +#endif pOutput->pMgmt = pMgmt; return 0; diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index 0ff2537e4c..872577cf28 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -571,10 +571,12 @@ static int32_t vmInit(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("vnode-vnodes", "initialized"); +#ifdef WINDOWS if (udfcOpen() != 0) { dError("failed to open udfc in vnode"); goto _OVER; } +#endif code = 0; diff --git a/source/dnode/mgmt/node_mgmt/src/dmEnv.c b/source/dnode/mgmt/node_mgmt/src/dmEnv.c index a34002161d..a8f871dc96 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmEnv.c +++ b/source/dnode/mgmt/node_mgmt/src/dmEnv.c @@ -198,8 +198,10 @@ void dmCleanup() { monCleanup(); syncCleanUp(); walCleanUp(); - udfcClose(); +#ifdef WINDOWS + udfcClose(); udfStopUdfd(); +#endif taosStopCacheRefreshWorker(); dmDiskClose(); dInfo("dnode env is cleaned up"); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index a41447edf3..9c3beea2d8 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -4418,6 +4418,10 @@ static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRete return TSDB_CODE_SUCCESS; } +#ifdef WINDOWS + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platform"); +#endif + if (LIST_LENGTH(pRetentions) > 3) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION, "Invalid option retentions"); } @@ -5867,6 +5871,9 @@ static int32_t checkCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pS } static int32_t translateCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) { +#ifdef WINDOWS + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platform"); +#endif int32_t code = checkCreateSmaIndex(pCxt, pStmt); pStmt->pReq = taosMemoryCalloc(1, sizeof(SMCreateSmaReq)); if (pStmt->pReq == NULL) code = TSDB_CODE_OUT_OF_MEMORY; @@ -7052,6 +7059,9 @@ static int32_t buildCreateStreamReq(STranslateContext* pCxt, SCreateStreamStmt* } static int32_t translateCreateStream(STranslateContext* pCxt, SCreateStreamStmt* pStmt) { +#ifdef WINDOWS + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platform"); +#endif SCMCreateStreamReq createReq = {0}; int32_t code = checkCreateStream(pCxt, pStmt); @@ -7201,6 +7211,9 @@ static int32_t readFromFile(char* pName, int32_t* len, char** buf) { } static int32_t translateCreateFunction(STranslateContext* pCxt, SCreateFunctionStmt* pStmt) { +#ifdef WINDOWS + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platform"); +#endif if (fmIsBuiltinFunc(pStmt->funcName)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FUNCTION_NAME); } diff --git a/source/util/src/terror.c b/source/util/src/terror.c index b0b407e2a5..74352f2799 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -570,6 +570,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_GET_META_ERROR, "Fail to get table i TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_UNIQUE_TABLE_ALIAS, "Not unique table/alias") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED_FUNC, "System table not allowed") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED, "System table not allowed") +TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platformXX") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INTERNAL_ERROR, "Parser internal error") //planner From 71c3c710e6db673658a5ead9b455166e28a8a5ab Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 15 Aug 2023 14:23:20 +0800 Subject: [PATCH 64/92] fix(stream): continue process when met with trans-state msg. --- source/libs/stream/src/streamExec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 6e6f23be01..02bbce6485 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -575,7 +575,7 @@ int32_t streamExecForAll(SStreamTask* pTask) { if (pInput->type == STREAM_INPUT__TRANS_STATE) { streamProcessTranstateBlock(pTask, (SStreamDataBlock*)pInput); - return 0; + continue; } if (pTask->info.taskLevel == TASK_LEVEL__SINK) { From a576a3b972ff69adde0b88907be7f37afadc7201 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 15 Aug 2023 06:23:27 +0000 Subject: [PATCH 65/92] rebuild index at tag0 --- tests/script/tsim/sma/drop_sma.sim | 65 +++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/tests/script/tsim/sma/drop_sma.sim b/tests/script/tsim/sma/drop_sma.sim index 8fd8ebdcfd..fcf48f2b36 100644 --- a/tests/script/tsim/sma/drop_sma.sim +++ b/tests/script/tsim/sma/drop_sma.sim @@ -52,19 +52,35 @@ sql create sma index sma_index_name1 on stb function(max(c1),max(c2),min(c1)) in print --> show sma sql show indexes from stb from d1; -if $rows != 1 then +if $rows != 2 then return -1 endi -if $data[0][0] != sma_index_name1 then - return -1 -endi -if $data[0][1] != d1 then - return -1 -endi -if $data[0][2] != stb then - return -1 + +if $data[0][6] == tag_index then + if $data[1][0] != sma_index_name1 then + return -1 + endi + if $data[1][1] != d1 then + return -1 + endi + if $data[1][2] != stb then + return -1 + endi +else + if $data[0][0] != sma_index_name1 then + return -1 + endi + if $data[0][1] != d1 then + return -1 + endi + if $data[0][2] != stb then + return -1 + endi endi + + + print --> drop stb sql drop table stb; @@ -78,17 +94,30 @@ sql create sma index sma_index_name1 on stb function(max(c1),max(c2),min(c1)) in print --> show sma sql show indexes from stb from d1; -if $rows != 1 then +if $rows != 2 then return -1 endi -if $data[0][0] != sma_index_name1 then - return -1 -endi -if $data[0][1] != d1 then - return -1 -endi -if $data[0][2] != stb then - return -1 + +if $data[0][6] == tag_index then + if $data[1][0] != sma_index_name1 then + return -1 + endi + if $data[1][1] != d1 then + return -1 + endi + if $data[1][2] != stb then + return -1 + endi +else + if $data[0][0] != sma_index_name1 then + return -1 + endi + if $data[0][1] != d1 then + return -1 + endi + if $data[0][2] != stb then + return -1 + endi endi print --> drop stb From 27db6cfd676bc238a640adfb5471c8b6df954c8c Mon Sep 17 00:00:00 2001 From: kailixu Date: Tue, 15 Aug 2023 14:25:31 +0800 Subject: [PATCH 66/92] enh: disable udf/stream for mnd on windows --- source/dnode/mnode/impl/src/mndDb.c | 6 ++++++ source/dnode/mnode/impl/src/mndFunc.c | 4 ++++ source/dnode/mnode/impl/src/mndSma.c | 4 ++++ source/dnode/mnode/impl/src/mndStream.c | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index 1bd629e56f..fdefe9e5b1 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -668,6 +668,12 @@ static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) { } mInfo("db:%s, start to create, vgroups:%d", createReq.db, createReq.numOfVgroups); +#ifdef WINDOWS + if (taosArrayGetSize(createReq.pRetensions) > 0) { + code = TSDB_CODE_PAR_INVALID_PLATFORM; + goto _OVER; + } +#endif if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DB, NULL) != 0) { goto _OVER; } diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c index 4ffc7a20c2..5f4ac830cd 100644 --- a/source/dnode/mnode/impl/src/mndFunc.c +++ b/source/dnode/mnode/impl/src/mndFunc.c @@ -361,6 +361,10 @@ static int32_t mndProcessCreateFuncReq(SRpcMsg *pReq) { } mInfo("func:%s, start to create, size:%d", createReq.name, createReq.codeLen); +#ifdef WINDOWS + code = TSDB_CODE_PAR_INVALID_PLATFORM; + goto _OVER; +#endif if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_FUNC) != 0) { goto _OVER; } diff --git a/source/dnode/mnode/impl/src/mndSma.c b/source/dnode/mnode/impl/src/mndSma.c index b84297f6bf..ff3f66efaf 100644 --- a/source/dnode/mnode/impl/src/mndSma.c +++ b/source/dnode/mnode/impl/src/mndSma.c @@ -655,6 +655,10 @@ _OVER: } static int32_t mndCheckCreateSmaReq(SMCreateSmaReq *pCreate) { +#ifdef WINDOWS + terrno = TSDB_CODE_PAR_INVALID_PLATFORM; + return -1; +#endif terrno = TSDB_CODE_MND_INVALID_SMA_OPTION; if (pCreate->name[0] == 0) return -1; if (pCreate->stb[0] == 0) return -1; diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index a0d53ec780..d6bb8c167f 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -253,6 +253,10 @@ static void mndShowStreamTrigger(char *dst, SStreamObj *pStream) { } static int32_t mndCheckCreateStreamReq(SCMCreateStreamReq *pCreate) { +#ifdef WINDOWS + terrno = TSDB_CODE_PAR_INVALID_PLATFORM; + return -1; +#endif if (pCreate->name[0] == 0 || pCreate->sql == NULL || pCreate->sql[0] == 0 || pCreate->sourceDB[0] == 0 || pCreate->targetStbFullName[0] == 0) { terrno = TSDB_CODE_MND_INVALID_STREAM_OPTION; From 0f0d0953cdbed4eaeed80e114cf2de6dccbd9290 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 15 Aug 2023 07:26:53 +0000 Subject: [PATCH 67/92] rebuild index at tag0 --- source/dnode/mnode/impl/src/mndIndex.c | 4 +- tests/parallel_test/cases.task | 3 ++ tests/script/tsim/tagindex/add_index.sim | 48 +++++++++++++++++-- .../tsim/tagindex/sma_and_tag_index.sim | 22 +++++---- 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndIndex.c b/source/dnode/mnode/impl/src/mndIndex.c index b56ea320cc..2e78116a86 100644 --- a/source/dnode/mnode/impl/src/mndIndex.c +++ b/source/dnode/mnode/impl/src/mndIndex.c @@ -696,8 +696,8 @@ int8_t mndCheckIndexNameByTagName(SMnode *pMnode, SIdxObj *pIdxObj) { continue; } if (strncmp(pIdxObj->colName, pIdx->colName, TSDB_COL_NAME_LEN) == 0) { + sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pIdx); - sdbCancelFetch(pSdb, pIdx); exist = 1; break; } @@ -854,8 +854,8 @@ int32_t mndDropIdxsByStb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *p if (pIdx->stbUid == pStb->uid) { if (mndSetDropIdxCommitLogs(pMnode, pTrans, pIdx) != 0) { + sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pIdx); - sdbCancelFetch(pSdb, pIdx); return -1; } } diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index a946a7feaf..e81339d705 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -1204,6 +1204,9 @@ ,,y,script,./test.sh -f tsim/tag/drop_tag.sim ,,y,script,./test.sh -f tsim/tag/tbNameIn.sim ,,y,script,./test.sh -f tmp/monitor.sim +,,y,script,./test.sh -f tsim/tagindex/add_index.sim +,,y,script,./test.sh -f tsim/tagindex/sma_and_tag_index.sim + #develop test ,,n,develop-test,python3 ./test.py -f 2-query/table_count_scan.py diff --git a/tests/script/tsim/tagindex/add_index.sim b/tests/script/tsim/tagindex/add_index.sim index cfbec90542..a6e9cae670 100644 --- a/tests/script/tsim/tagindex/add_index.sim +++ b/tests/script/tsim/tagindex/add_index.sim @@ -7,7 +7,7 @@ print ======== step0 $dbPrefix = ta_3_db $tbPrefix = ta_3_tb $mtPrefix = ta_3_mt -$tbNum = 500 +$tbNum = 50 $rowNum = 20 $totalNum = 200 @@ -48,12 +48,16 @@ while $i < $tbNum $i = $i + 1 endw - +sql_error create index ti1 on $mtPrefix (t1) sql create index ti2 on $mtPrefix (t2) sql create index ti5 on $mtPrefix (t5) print ==== test name conflict # + +sql_error create index ti1 on $mtPrefix(t1) +sql_error create index ti11 on $mtPrefix(t1) + sql_error create index ti3 on $mtPrefix(t2) sql_error create index ti2 on $mtPrefix(t2) @@ -73,6 +77,15 @@ while $i < $tbNum $i = $i + 1 endw +$i = 0 +while $i < $tbNum + sql select * from $mtPrefix where t1= $i ; + if $rows != 1 then + return -1 + endi + $i = $i + 1 +endw + print ===== test operator great equal @@ -250,7 +263,7 @@ endw print === show index sql select * from information_schema.ins_indexes -if $rows != 1 then +if $rows != 2 then return -1 endi @@ -259,12 +272,41 @@ print === drop index ti2 sql drop index ti2 print === drop not exist index + +sql select * from information_schema.ins_indexes +if $rows != 1 then + return -1 +endi + +sql drop index $data[0][0] + +if $rows != 0 then + return -1 +endi + + sql_error drop index t2 sql_error drop index t3 +sql create index ti0 on $mtPrefix (t1) + +$i = $interval +while $i < $limit + sql select * from $mtPrefix where t1 <= $i ; + + $tmp = $i - $interval + $tmp = $tmp + 1 + if $rows != $tmp then + return -1 + endi + $i = $i + 1 +endw sql_error create index ti0 on $mtPrefix (t1) +sql_error create index ti2 on $mtPrefix (t1) + + sql_error create index t2i on ta_3_tb17 (t2) diff --git a/tests/script/tsim/tagindex/sma_and_tag_index.sim b/tests/script/tsim/tagindex/sma_and_tag_index.sim index b15d22d439..e7e4682810 100644 --- a/tests/script/tsim/tagindex/sma_and_tag_index.sim +++ b/tests/script/tsim/tagindex/sma_and_tag_index.sim @@ -69,7 +69,7 @@ sql create sma index smat2i on $mtPrefix function(max(c1)) interval(6m,10s) slid sql select * from information_schema.ins_indexes -if $rows != 2 then +if $rows != 3 then return -1 endi @@ -84,7 +84,7 @@ while $i < 5 endw sql select * from information_schema.ins_indexes -if $rows != 6 then +if $rows != 7 then return -1 endi @@ -114,13 +114,13 @@ sql use $dbPrefix sql create table if not exists $mtPrefix (ts timestamp, c1 int) tags (t1 int, t2 int, t3 int, t4 int, t5 int) sql create index tagt2i on $mtPrefix (t2) sql select * from information_schema.ins_indexes -if $rows != 1 then +if $rows != 2 then return -1 endi sql alter table $mtPrefix drop tag t2 sql select * from information_schema.ins_indexes -if $rows != 0 then +if $rows != 1 then return -1 endi @@ -128,18 +128,22 @@ endi print ==== rename tag name, and update index colName sql create index tagt3i on $mtPrefix (t3) sql select * from information_schema.ins_indexes -if $rows != 1 then +if $rows != 2 then return -1 endi sql alter table $mtPrefix rename tag t3 txxx sql select * from information_schema.ins_indexes -if $rows != 1 then +if $rows != 2 then return -1 endi -if $data05 != txxx then - return -1 +if $data05 == txxx then + print "manual created index" +elif $data15 == txxx then + print "auto created index at tag0" +else + return -1; endi @@ -153,7 +157,7 @@ sql create table if not exists $mtPrefix (ts timestamp, c1 int) tags (t1 int, t2 sql create index tagt3i on $mtPrefix (t3) sql select * from information_schema.ins_indexes -if $rows != 2 then +if $rows != 4 then return -1 endi From beb84b2355199ea9fdedb5305273440f3c4331f0 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Tue, 15 Aug 2023 15:37:39 +0800 Subject: [PATCH 68/92] fix:tmq interface & remove snapshot code --- docs/en/07-develop/07-tmq.mdx | 91 +++++++++++----- docs/en/14-reference/03-connector/03-cpp.mdx | 93 +++++++++++++++- docs/en/14-reference/03-connector/04-java.mdx | 2 - docs/examples/c/tmq_example.c | 6 -- docs/examples/go/sub/main.go | 1 - docs/zh/07-develop/07-tmq.mdx | 91 +++++++++++----- docs/zh/08-connector/10-cpp.mdx | 102 ++++++++++++++++-- examples/c/tmq.c | 5 - include/client/taos.h | 62 +++++------ 9 files changed, 341 insertions(+), 112 deletions(-) diff --git a/docs/en/07-develop/07-tmq.mdx b/docs/en/07-develop/07-tmq.mdx index ccf39ef581..e78855dad3 100644 --- a/docs/en/07-develop/07-tmq.mdx +++ b/docs/en/07-develop/07-tmq.mdx @@ -23,7 +23,25 @@ By subscribing to a topic, a consumer can obtain the latest data in that topic i To implement these features, TDengine indexes its write-ahead log (WAL) file for fast random access and provides configurable methods for replacing and retaining this file. You can define a retention period and size for this file. For information, see the CREATE DATABASE statement. In this way, the WAL file is transformed into a persistent storage engine that remembers the order in which events occur. However, note that configuring an overly long retention period for your WAL files makes database compression inefficient. TDengine then uses the WAL file instead of the time-series database as its storage engine for queries in the form of topics. TDengine reads the data from the WAL file; uses a unified query engine instance to perform filtering, transformations, and other operations; and finally pushes the data to consumers. -Tips: Data subscription is to consume data from the wal. If some wal files are deleted according to WAL retention policy, the deleted data can't be consumed any more. So you need to set a reasonable value for parameter `WAL_RETENTION_PERIOD` or `WAL_RETENTION_SIZE` when creating the database and make sure your application consume the data in a timely way to make sure there is no data loss. This behavior is similar to Kafka and other widely used message queue products. +Tips:(c interface for example) +- A consumption group consumes all data under the same topic, and different consumption groups are independent of each other; +- A consumption group consumes all vgroups of the same topic, which can be composed of multiple consumers, but a vgroup is only consumed by one consumer. If the number of consumers exceeds the number of vgroups, the excess consumers do not consume data; +- On the server side, only one offset is saved for each vgroup, and the offsets for each vgroup are monotonically increasing, but not necessarily continuous. There is no correlation between the offsets of various vgroups; +- Each poll server will return a result block, which belongs to a vgroup and may contain data from multiple versions of wal. This block can be accessed through tmq_get_vgroup_offset. The offset interface obtains the offset of the first record in the block; +- If a consumer group has never committed an offset, when its member consumers restart and pull data again, they start consuming from the set value of the parameter auto.offset.reset; In a consumer lifecycle, the client locally records the offset of the most recent pull data and will not pull duplicate data; +- If a consumer terminates abnormally (without calling tmq_close), they need to wait for about 12 seconds to trigger their consumer group rebalance. The consumer's status on the server will change to LOST, and after about 1 day, the consumer will be automatically deleted; Exit normally, and after exiting, the consumer will be deleted; Add a new consumer, wait for about 2 seconds to trigger Rebalance, and the consumer's status on the server will change to ready; +- The consumer group Rebalance will reassign Vgroups to all consumer members in the ready state of the group, and consumers can only assign/see/commit/poll operations to the Vgroups they are responsible for; +- Consumers can tmq_position to obtain the offset of the current consumption, seek to the specified offset, and consume again; +- Seek points the position to the specified offset without executing the commit operation. Once the seek is successful, it can poll the specified offset and subsequent data; +- Position is to obtain the current consumption position, which is the position to be taken next time, not the current consumption position +- Commit is the submission of the consumption location. Without parameters, it is the submission of the current consumption location (the location to be taken next time, not the current consumption location). With parameters, it is the location in the submission parameters (i.e. the location to be taken after the next exit and restart) +- Seek is to set the consumer's consumption position. Wherever the seek goes, the position will be returned, all of which are the positions to be taken next time +- Seek does not affect commit, commit does not affect seek, independent of each other, the two are different concepts +- The begin interface is the offset of the first data in wal, and the end interface is the offset+1 of the last data in wal10. +- Before the seek operation, tmq must be call tmq_get_topic_assignment, The assignment interface obtains the vgroup ID and offset range of the consumer. The seek operation will detect whether the vgroup ID and offset are legal, and if they are illegal, an error will be reported; +- Due to the existence of a WAL expiration deletion mechanism, even if the seek operation is successful, it is possible that the offset has expired when polling data. If the offset of poll is less than the WAL minimum version number, it will be consumed from the WAL minimum version number; +- The tmq_get_vgroup_offset interface obtains the offset of the first data in the result block where the record is located. When seeking to this offset, it will consume all the data in this block. Refer to point four; +- Data subscription is to consume data from the wal. If some wal files are deleted according to WAL retention policy, the deleted data can't be consumed any more. So you need to set a reasonable value for parameter `WAL_RETENTION_PERIOD` or `WAL_RETENTION_SIZE` when creating the database and make sure your application consume the data in a timely way to make sure there is no data loss. This behavior is similar to Kafka and other widely used message queue products. ## Data Schema and API @@ -33,36 +51,57 @@ The related schemas and APIs in various languages are described as follows: ```c -typedef struct tmq_t tmq_t; -typedef struct tmq_conf_t tmq_conf_t; -typedef struct tmq_list_t tmq_list_t; + typedef struct tmq_t tmq_t; + typedef struct tmq_conf_t tmq_conf_t; + typedef struct tmq_list_t tmq_list_t; -typedef void(tmq_commit_cb(tmq_t *, int32_t code, void *param)); + typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param)); -DLL_EXPORT tmq_list_t *tmq_list_new(); -DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); -DLL_EXPORT void tmq_list_destroy(tmq_list_t *); -DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); -DLL_EXPORT const char *tmq_err2str(int32_t code); + typedef enum tmq_conf_res_t { + TMQ_CONF_UNKNOWN = -2, + TMQ_CONF_INVALID = -1, + TMQ_CONF_OK = 0, + } tmq_conf_res_t; -DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); -DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); -DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); -DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); -DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); -DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); + typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; // The last version of wal + 1 + } tmq_topic_assignment; -enum tmq_conf_res_t { - TMQ_CONF_UNKNOWN = -2, - TMQ_CONF_INVALID = -1, - TMQ_CONF_OK = 0, -}; -typedef enum tmq_conf_res_t tmq_conf_res_t; + DLL_EXPORT tmq_conf_t *tmq_conf_new(); + DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); + DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); + DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); -DLL_EXPORT tmq_conf_t *tmq_conf_new(); -DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); -DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); -DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); + DLL_EXPORT tmq_list_t *tmq_list_new(); + DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); + DLL_EXPORT void tmq_list_destroy(tmq_list_t *); + DLL_EXPORT int32_t tmq_list_get_size(const tmq_list_t *); + DLL_EXPORT char **tmq_list_to_c_array(const tmq_list_t *); + + DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); + DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); + DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); + DLL_EXPORT int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics); + DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); + DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); + DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); //Commit the msg’s offset + 1 + DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); + DLL_EXPORT int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); + DLL_EXPORT void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param); + DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment,int32_t *numOfAssignment); + DLL_EXPORT void tmq_free_assignment(tmq_topic_assignment* pAssignment); + DLL_EXPORT int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); + DLL_EXPORT int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId); // The current offset is the offset of the last consumed message + 1 + DLL_EXPORT int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId); + + DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res); + DLL_EXPORT const char *tmq_get_db_name(TAOS_RES *res); + DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res); + DLL_EXPORT int64_t tmq_get_vgroup_offset(TAOS_RES* res); // Get current offset of the result + DLL_EXPORT const char *tmq_err2str(int32_t code); ``` For more information, see [C/C++ Connector](/reference/connector/cpp). diff --git a/docs/en/14-reference/03-connector/03-cpp.mdx b/docs/en/14-reference/03-connector/03-cpp.mdx index 13029dbe91..0009902425 100644 --- a/docs/en/14-reference/03-connector/03-cpp.mdx +++ b/docs/en/14-reference/03-connector/03-cpp.mdx @@ -378,7 +378,7 @@ In addition to writing data using the SQL method or the parameter binding API, w - `TAOS_RES* taos_schemaless_insert(TAOS* taos, const char* lines[], int numLines, int protocol, int precision)` **Function description** - This interface writes the text data of the line protocol to TDengine. + - This interface writes the text data of the line protocol to TDengine. **Parameter description** - taos: database connection, established by the `taos_connect()` function. @@ -387,12 +387,13 @@ In addition to writing data using the SQL method or the parameter binding API, w - protocol: the protocol type of the lines, used to identify the text data format. - precision: precision string for the timestamp in the text data. - **return value** - TAOS_RES structure, application can get error message by using `taos_errstr()` and also error code by using `taos_errno()`. + **Return value** + - TAOS_RES structure, application can get error message by using `taos_errstr()` and also error code by using `taos_errno()`. In some cases, the returned TAOS_RES is `NULL`, and it is still possible to call `taos_errno()` to safely get the error code information. The returned TAOS_RES needs to be freed by the caller in order to avoid memory leaks. **Description** + The protocol type is enumerated and contains the following three formats. - TSDB_SML_LINE_PROTOCOL: InfluxDB line protocol (Line Protocol) @@ -427,3 +428,89 @@ In addition to writing data using the SQL method or the parameter binding API, w - Within _raw interfaces represent data through the passed parameters lines and len. In order to solve the problem that the original interface data contains '\0' and is truncated. The totalRows pointer returns the number of parsed data rows. - Within _ttl interfaces can pass the ttl parameter to control the ttl expiration time of the table. - Within _reqid interfaces can track the entire call chain by passing the reqid parameter. + +### Subscription API + +- `int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment, int32_t *numOfAssignment)` +- `void tmq_free_assignment(tmq_topic_assignment* pAssignment)` + + tmq_topic_assignment defined as follows: + ```c + typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; + } tmq_topic_assignment; + ``` + **Function description** + - tmq_get_topic_assignment get the current vgroup information of this consumer + + **Parameter description** + - numOfAssignment:the num of vgroups assigned to this consumer + - assignment:the information of vgroups, needed to be freed by tmq_free_assignment + + **Return value** + - zero success,none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId)` + **Function description** + - get the committed offset + + **Return value** + - the value of committed offset, -2147467247 means no committed value, Other values less than 0 indicate failure + +- `int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg)` +- `void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param)` +- `int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` +- `void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param)` + + **Function description** + + The commit interface is divided into two types, each with synchronous and asynchronous interfaces: + - The first type: based on message submission, submit the progress in the message. If the message passes NULL, submit the current progress of all vgroups consumed by the current consumer: tmq_commit_sync/tmq_commit_async + - The second type: submit based on the offset of a Vgroup in a topic: tmq_commit_offset_sync/tmq_commit_offset_async + + **Parameter description** + - msg:Message consumed, If the message passes NULL, submit the current progress of all vgroups consumed by the current consumer + + **Return value** + - zero success, none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId)` + + **Function description** + - Obtain the current consumption location, which is the next location of the data consumed + + **Return value** + - the current consumption location, none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` + + **Function description** + - Set the offset position of the consumer in a Vgroup of a certain topic to start consumption + + **Return value** + - zero success, none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int32_t int64_t tmq_get_vgroup_offset(TAOS_RES* res)` + + **Function description** + - Obtain the starting offset of the consumed data + + **Parameter description** + - msg:Message consumed + + **Return value** + - the starting offset of the consumed data, none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int32_t int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics)` + + **Function description** + - Obtain a list of topics subscribed by consumers + + **Parameter description** + - topics: a list of topics subscribed by consumers,need to be freed by tmq_list_destroy + + **Return value** + - zero success,none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` \ No newline at end of file diff --git a/docs/en/14-reference/03-connector/04-java.mdx b/docs/en/14-reference/03-connector/04-java.mdx index 69bbd287ed..ff1f209788 100644 --- a/docs/en/14-reference/03-connector/04-java.mdx +++ b/docs/en/14-reference/03-connector/04-java.mdx @@ -1091,8 +1091,6 @@ public abstract class ConsumerLoop { config.setProperty("client.id", "1"); config.setProperty("value.deserializer", "com.taosdata.jdbc.tmq.ConsumerTest.ConsumerLoop$ResultDeserializer"); config.setProperty("value.deserializer.encoding", "UTF-8"); - config.setProperty("experimental.snapshot.enable", "true"); - this.consumer = new TaosConsumer<>(config); this.topics = Collections.singletonList("topic_speed"); diff --git a/docs/examples/c/tmq_example.c b/docs/examples/c/tmq_example.c index d958428b8f..ca7c23e93b 100644 --- a/docs/examples/c/tmq_example.c +++ b/docs/examples/c/tmq_example.c @@ -227,12 +227,6 @@ tmq_t* build_consumer() { return NULL; } - code = tmq_conf_set(conf, "experimental.snapshot.enable", "false"); - if (TMQ_CONF_OK != code) { - tmq_conf_destroy(conf); - return NULL; - } - tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL); tmq_t* tmq = tmq_consumer_new(conf, NULL, 0); diff --git a/docs/examples/go/sub/main.go b/docs/examples/go/sub/main.go index cb24e351ab..ed335cfdea 100644 --- a/docs/examples/go/sub/main.go +++ b/docs/examples/go/sub/main.go @@ -35,7 +35,6 @@ func main() { "td.connect.port": "6030", "client.id": "test_tmq_client", "enable.auto.commit": "false", - "experimental.snapshot.enable": "true", "msg.with.table.name": "true", }) if err != nil { diff --git a/docs/zh/07-develop/07-tmq.mdx b/docs/zh/07-develop/07-tmq.mdx index 38b91d7cea..04c978679e 100644 --- a/docs/zh/07-develop/07-tmq.mdx +++ b/docs/zh/07-develop/07-tmq.mdx @@ -25,7 +25,25 @@ import CDemo from "./_sub_c.mdx"; 本文档不对消息队列本身的基础知识做介绍,如果需要了解,请自行搜索。 -注意:数据订阅是从 WAL 消费数据,如果一些 WAL 文件被基于 WAL 保留策略删除,则已经删除的 WAL 文件中的数据就无法再消费到。需要根据业务需要在创建数据库时合理设置 `WAL_RETENTION_PERIOD` 或 `WAL_RETENTION_SIZE` ,并确保应用及时消费数据,这样才不会产生数据丢失的现象。数据订阅的行为与 Kafka 等广泛使用的消息队列类产品的行为相似。 +说明(以c接口为例): +- 一个消费组消费同一个topic下的所有数据,不同消费组之间相互独立; +- 一个消费组消费同一个topic所有的vgroup,消费组可由多个消费者组成,但一个vgroup仅被一个消费者消费,如果消费者数量超过了vgroup数量,多余的消费者不消费数据; +- 在服务端每个vgroup仅保存一个offset,每个vgroup的offset是单调递增的,但不一定连续。各个vgroup的offset之间没有关联; +- 每次poll服务端会返回一个结果block,该block属于一个vgroup,可能包含多个wal版本的数据,可以通过 tmq_get_vgroup_offset 接口获得是该block第一条记录的offset; +- 一个消费组如果从未commit过offset,当其成员消费者重启重新拉取数据时,均从参数auto.offset.reset设定值开始消费;在一个消费者生命周期中,客户端本地记录了最近一次拉取数据的offset,不会拉取重复数据; +- 消费者如果异常终止(没有调用tmq_close),需等约12秒后触发其所属消费组rebalance,该消费者在服务端状态变为LOST,约1天后该消费者自动被删除;正常退出,退出后就会删除消费者;新增消费者,需等约2秒触发rebalance,该消费者在服务端状态变为ready; +- 消费组rebalance会对该组所有ready状态的消费者成员重新进行vgroup分配,消费者仅能对自己负责的vgroup进行assignment/seek/commit/poll操作; +- 消费者可利用 tmq_position 获得当前消费的offset,并seek到指定offset,重新消费; +- seek将position指向指定offset,不执行commit操作,一旦seek成功,可poll拉取指定offset及以后的数据; +- seek 操作之前须调用 tmq_get_topic_assignment 接口获取该consumer的vgroup ID和offset范围。seek 操作会检测vgroup ID 和 offset是否合法,如非法将报错; +- position是获取当前的消费位置,是下次要取的位置,不是当前消费到的位置 +- commit是提交消费位置,不带参数的话,是提交当前消费位置(下次要取的位置,不是当前消费到的位置),带参数的话,是提交参数里的位置(也即下次退出重启后要取的位置) +- seek是设置consumer消费位置,seek到哪,position就返回哪,都是下次要取的位置 +- seek不会影响commit,commit不影响seek,相互独立,两个是不同的概念 +- begin接口为wal 第一条数据的offset,end 接口为wal 最后一条数据的offset + 1 +- tmq_get_vgroup_offset接口获取的是记录所在结果block块里的第一条数据的offset,当seek至该offset时,将消费到这个block里的全部数据。参见第四点; +- 由于存在 WAL 过期删除机制,即使seek 操作成功,poll数据时有可能offset已失效。如果poll 的offset 小于 WAL 最小版本号,将会从WAL最小版本号消费; +- 数据订阅是从 WAL 消费数据,如果一些 WAL 文件被基于 WAL 保留策略删除,则已经删除的 WAL 文件中的数据就无法再消费到。需要根据业务需要在创建数据库时合理设置 `WAL_RETENTION_PERIOD` 或 `WAL_RETENTION_SIZE` ,并确保应用及时消费数据,这样才不会产生数据丢失的现象。数据订阅的行为与 Kafka 等广泛使用的消息队列类产品的行为相似; ## 主要数据结构和 API @@ -35,36 +53,57 @@ import CDemo from "./_sub_c.mdx"; ```c -typedef struct tmq_t tmq_t; -typedef struct tmq_conf_t tmq_conf_t; -typedef struct tmq_list_t tmq_list_t; + typedef struct tmq_t tmq_t; + typedef struct tmq_conf_t tmq_conf_t; + typedef struct tmq_list_t tmq_list_t; -typedef void(tmq_commit_cb(tmq_t *, int32_t code, void *param)); + typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param)); -DLL_EXPORT tmq_list_t *tmq_list_new(); -DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); -DLL_EXPORT void tmq_list_destroy(tmq_list_t *); -DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); -DLL_EXPORT const char *tmq_err2str(int32_t code); + typedef enum tmq_conf_res_t { + TMQ_CONF_UNKNOWN = -2, + TMQ_CONF_INVALID = -1, + TMQ_CONF_OK = 0, + } tmq_conf_res_t; -DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); -DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); -DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); -DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); -DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); -DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); + typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; // The last version of wal + 1 + } tmq_topic_assignment; -enum tmq_conf_res_t { - TMQ_CONF_UNKNOWN = -2, - TMQ_CONF_INVALID = -1, - TMQ_CONF_OK = 0, -}; -typedef enum tmq_conf_res_t tmq_conf_res_t; + DLL_EXPORT tmq_conf_t *tmq_conf_new(); + DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); + DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); + DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); -DLL_EXPORT tmq_conf_t *tmq_conf_new(); -DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); -DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); -DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); + DLL_EXPORT tmq_list_t *tmq_list_new(); + DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); + DLL_EXPORT void tmq_list_destroy(tmq_list_t *); + DLL_EXPORT int32_t tmq_list_get_size(const tmq_list_t *); + DLL_EXPORT char **tmq_list_to_c_array(const tmq_list_t *); + + DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); + DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); + DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); + DLL_EXPORT int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics); + DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); + DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); + DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); //Commit the msg’s offset + 1 + DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); + DLL_EXPORT int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); + DLL_EXPORT void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param); + DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment,int32_t *numOfAssignment); + DLL_EXPORT void tmq_free_assignment(tmq_topic_assignment* pAssignment); + DLL_EXPORT int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); + DLL_EXPORT int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId); // The current offset is the offset of the last consumed message + 1 + DLL_EXPORT int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId); + + DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res); + DLL_EXPORT const char *tmq_get_db_name(TAOS_RES *res); + DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res); + DLL_EXPORT int64_t tmq_get_vgroup_offset(TAOS_RES* res); // Get current offset of the result + DLL_EXPORT const char *tmq_err2str(int32_t code); ``` 这些 API 的文档请见 [C/C++ Connector](../../connector/cpp),下面介绍一下它们的具体用法(超级表和子表结构请参考“数据建模”一节),完整的示例代码请见下面 C 语言的示例代码。 diff --git a/docs/zh/08-connector/10-cpp.mdx b/docs/zh/08-connector/10-cpp.mdx index 9c5095f09c..c0723cd85c 100644 --- a/docs/zh/08-connector/10-cpp.mdx +++ b/docs/zh/08-connector/10-cpp.mdx @@ -467,21 +467,22 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多 - `TAOS_RES* taos_schemaless_insert(TAOS* taos, const char* lines[], int numLines, int protocol, int precision)` **功能说明** - 该接口将行协议的文本数据写入到 TDengine 中。 + - 该接口将行协议的文本数据写入到 TDengine 中。 **参数说明** - taos: 数据库连接,通过 `taos_connect()` 函数建立的数据库连接。 - lines:文本数据。满足解析格式要求的无模式文本字符串。 - numLines:文本数据的行数,不能为 0 。 - protocol: 行协议类型,用于标识文本数据格式。 - precision:文本数据中的时间戳精度字符串。 + - taos: 数据库连接,通过 `taos_connect()` 函数建立的数据库连接。 + - lines:文本数据。满足解析格式要求的无模式文本字符串。 + - numLines:文本数据的行数,不能为 0 。 + - protocol: 行协议类型,用于标识文本数据格式。 + - precision:文本数据中的时间戳精度字符串。 **返回值** - TAOS_RES 结构体,应用可以通过使用 `taos_errstr()` 获得错误信息,也可以使用 `taos_errno()` 获得错误码。 + - TAOS_RES 结构体,应用可以通过使用 `taos_errstr()` 获得错误信息,也可以使用 `taos_errno()` 获得错误码。 在某些情况下,返回的 TAOS_RES 为 `NULL`,此时仍然可以调用 `taos_errno()` 来安全地获得错误码信息。 返回的 TAOS_RES 需要调用方来负责释放,否则会出现内存泄漏。 **说明** + 协议类型是枚举类型,包含以下三种格式: - TSDB_SML_LINE_PROTOCOL:InfluxDB 行协议(Line Protocol) @@ -515,3 +516,90 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多 - 带_raw的接口通过传递的参数lines指针和长度len来表示数据,为了解决原始接口数据包含'\0'而被截断的问题。totalRows指针返回解析出来的数据行数。 - 带_ttl的接口可以传递ttl参数来控制建表的ttl到期时间。 - 带_reqid的接口可以通过传递reqid参数来追踪整个的调用链。 + +### 数据订阅 API + +- `int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment, int32_t *numOfAssignment)` +- `void tmq_free_assignment(tmq_topic_assignment* pAssignment)` + + tmq_topic_assignment结构体定义如下: + ```c + typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; + } tmq_topic_assignment; + ``` + **功能说明** + - tmq_get_topic_assignment 接口返回当前consumer分配的vgroup的信息,每个vgroup的信息包括vgId,wal的最大最小offset,以及当前消费到的offset。 + + **参数说明** + - numOfAssignment :分配给该consumer有效的vgroup个数。 + - assignment :分配的信息,数据大小为numOfAssignment,需要通过 tmq_free_assignment 接口释放。 + + **返回值** + - 错误码,0成功,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息。 + +- `int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId)` + **功能说明** + - 获取当前 consumer 在某个 topic 和 vgroup上的 commit 位置。 + + **返回值** + - 当前commit的位置,-2147467247表示没有消费进度,其他小于0的值表示失败,错误码就是返回值 + +- `int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg)` +- `void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param)` +- `int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` +- `void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param)` + + **功能说明** + + commit接口分为两种类型,每种类型有同步和异步接口: + - 第一种类型:根据消息提交,提交消息里的进度,如果消息传NULL,提交当前consumer所有消费的vgroup的当前进度 : tmq_commit_sync/tmq_commit_async + - 第二种类型:根据某个topic的某个vgroup的offset提交 : tmq_commit_offset_sync/tmq_commit_offset_async + + **参数说明** + - msg:消费到的消息结构,如果msg传NULL,提交当前consumer所有消费的vgroup的当前进度 + + **返回值** + - 错误码,0成功,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 + +- `int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId)` + + **功能说明** + - 获取当前消费位置,为消费到的数据位置的下一个位置 + + **返回值** + - 消费位置,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 + +- `int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` + + **功能说明** + - 设置 consumer 在某个topic的某个vgroup的 offset位置,开始消费 + + **返回值** + - 错误码,0成功,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 + +- `int32_t int64_t tmq_get_vgroup_offset(TAOS_RES* res)` + + **功能说明** + + 获取 poll 消费到的数据的起始offset + + **参数说明** + - msg:消费到的消息结构 + + **返回值** + - 消费到的offset,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 + +- `int32_t int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics)` + + **功能说明** + + 获取消费者订阅的 topic 列表 + **参数说明** + - topics: 获取的 topic 列表存储在这个结构中,接口内分配内存,需调用tmq_list_destroy释放 + + **返回值** + - 错误码,0成功,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 \ No newline at end of file diff --git a/examples/c/tmq.c b/examples/c/tmq.c index e1133c109e..136c54b874 100644 --- a/examples/c/tmq.c +++ b/examples/c/tmq.c @@ -228,11 +228,6 @@ tmq_t* build_consumer() { tmq_conf_destroy(conf); return NULL; } - code = tmq_conf_set(conf, "experimental.snapshot.enable", "false"); - if (TMQ_CONF_OK != code) { - tmq_conf_destroy(conf); - return NULL; - } tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL); tmq = tmq_consumer_new(conf, NULL, 0); diff --git a/include/client/taos.h b/include/client/taos.h index 3cc2d907ab..3ac25cf580 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -260,7 +260,25 @@ typedef struct tmq_t tmq_t; typedef struct tmq_conf_t tmq_conf_t; typedef struct tmq_list_t tmq_list_t; -typedef void(tmq_commit_cb(tmq_t *, int32_t code, void *param)); +typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param)); + +typedef enum tmq_conf_res_t { + TMQ_CONF_UNKNOWN = -2, + TMQ_CONF_INVALID = -1, + TMQ_CONF_OK = 0, +} tmq_conf_res_t; + +typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; // The last invalidate version of wal + 1 +} tmq_topic_assignment; + +DLL_EXPORT tmq_conf_t *tmq_conf_new(); +DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); +DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); +DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); DLL_EXPORT tmq_list_t *tmq_list_new(); DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); @@ -268,55 +286,27 @@ DLL_EXPORT void tmq_list_destroy(tmq_list_t *); DLL_EXPORT int32_t tmq_list_get_size(const tmq_list_t *); DLL_EXPORT char **tmq_list_to_c_array(const tmq_list_t *); -DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); - -DLL_EXPORT const char *tmq_err2str(int32_t code); - -/* ------------------------TMQ CONSUMER INTERFACE------------------------ */ -typedef struct tmq_topic_assignment { - int32_t vgId; - int64_t currentOffset; - int64_t begin; - int64_t end; -} tmq_topic_assignment; - +DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); DLL_EXPORT int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics); DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); -DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); +DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); //Commit the msg’s offset + 1 DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); DLL_EXPORT int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); DLL_EXPORT void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param); -DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment, - int32_t *numOfAssignment); +DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment,int32_t *numOfAssignment); DLL_EXPORT void tmq_free_assignment(tmq_topic_assignment* pAssignment); DLL_EXPORT int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); +DLL_EXPORT int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId); // The current offset is the offset of the last consumed message + 1 +DLL_EXPORT int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId); DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res); DLL_EXPORT const char *tmq_get_db_name(TAOS_RES *res); DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res); -DLL_EXPORT int64_t tmq_get_vgroup_offset(TAOS_RES* res); -DLL_EXPORT int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId); -DLL_EXPORT int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId); - -/* ----------------------TMQ CONFIGURATION INTERFACE---------------------- */ - -enum tmq_conf_res_t { - TMQ_CONF_UNKNOWN = -2, - TMQ_CONF_INVALID = -1, - TMQ_CONF_OK = 0, -}; - -typedef enum tmq_conf_res_t tmq_conf_res_t; - -DLL_EXPORT tmq_conf_t *tmq_conf_new(); -DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); -DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); -DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); - -/* -------------------------TMQ MSG HANDLE INTERFACE---------------------- */ +DLL_EXPORT int64_t tmq_get_vgroup_offset(TAOS_RES* res); // Get current offset of the result +DLL_EXPORT const char *tmq_err2str(int32_t code); /* ------------------------------ TAOSX -----------------------------------*/ // note: following apis are unstable From 37e6100204f309204462632178e9a5820b749e89 Mon Sep 17 00:00:00 2001 From: liuyao <54liuyao@163.com> Date: Tue, 15 Aug 2023 15:42:50 +0800 Subject: [PATCH 69/92] refactor stream scan log --- source/libs/executor/src/executil.c | 35 ++++++++-------------- source/libs/executor/src/projectoperator.c | 4 +++ source/libs/executor/src/scanoperator.c | 23 ++++++-------- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 9b4d0c1725..0344143fdb 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -2180,39 +2180,30 @@ int32_t createScanTableListInfo(SScanPhysiNode* pScanNode, SNodeList* pGroupTags char* getStreamOpName(uint16_t opType) { switch (opType) { - case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: return "stream scan"; - }; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: { + case QUERY_NODE_PHYSICAL_PLAN_PROJECT: + return "project"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: return "interval single"; - }; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: return "interval final"; - }; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: return "interval semi"; - }; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: return "stream fill"; - } - case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION: return "session single"; - }; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION: return "session semi"; - }; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION: return "session final"; - }; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE: return "state single"; - }; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION: return "stream partitionby"; - }; - case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT: { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT: return "stream event"; - }; } return ""; } diff --git a/source/libs/executor/src/projectoperator.c b/source/libs/executor/src/projectoperator.c index 1cc377b3ee..8e31bc042f 100644 --- a/source/libs/executor/src/projectoperator.c +++ b/source/libs/executor/src/projectoperator.c @@ -372,6 +372,10 @@ SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) { pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0; } + if (pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM) { + printDataBlock(p, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + } + return (p->info.rows > 0) ? p : NULL; } diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 86a368721b..4a8ef0565e 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1921,7 +1921,7 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { switch (pInfo->scanMode) { case STREAM_SCAN_FROM_RES: { pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE; - printDataBlock(pInfo->pRecoverRes, "scan recover", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pInfo->pRecoverRes, getStreamOpName(pOperator->operatorType), "recover", GET_TASKID(pTaskInfo)); return pInfo->pRecoverRes; } break; default: @@ -1932,22 +1932,17 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { if (pInfo->pRecoverRes != NULL) { calBlockTbName(pInfo, pInfo->pRecoverRes); if (!pInfo->igCheckUpdate && pInfo->pUpdateInfo) { - // if (pStreamInfo->recoverStep == STREAM_RECOVER_STEP__SCAN1) { TSKEY maxTs = pAPI->stateStore.updateInfoFillBlockData(pInfo->pUpdateInfo, pInfo->pRecoverRes, pInfo->primaryTsIndex); pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs); - // } else { - // pInfo->pUpdateInfo->maxDataVersion = TMAX(pInfo->pUpdateInfo->maxDataVersion, pStreamInfo->fillHistoryVer.maxVer); - // doCheckUpdate(pInfo, pInfo->pRecoverRes->info.window.ekey, pInfo->pRecoverRes); - // } } if (pInfo->pCreateTbRes->info.rows > 0) { pInfo->scanMode = STREAM_SCAN_FROM_RES; - printDataBlock(pInfo->pCreateTbRes, "recover createTbl", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pInfo->pCreateTbRes, getStreamOpName(pOperator->operatorType), "recover", GET_TASKID(pTaskInfo)); return pInfo->pCreateTbRes; } qDebug("stream recover scan get block, rows %" PRId64, pInfo->pRecoverRes->info.rows); - printDataBlock(pInfo->pRecoverRes, "scan recover", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pInfo->pRecoverRes, getStreamOpName(pOperator->operatorType), "recover", GET_TASKID(pTaskInfo)); return pInfo->pRecoverRes; } pStreamInfo->recoverStep = STREAM_RECOVER_STEP__NONE; @@ -2003,7 +1998,7 @@ FETCH_NEXT_BLOCK: pAPI->stateStore.updateInfoAddCloseWindowSBF(pInfo->pUpdateInfo); } break; case STREAM_DELETE_DATA: { - printDataBlock(pBlock, "stream scan delete recv", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "delete recv", GET_TASKID(pTaskInfo)); SSDataBlock* pDelBlock = NULL; if (pInfo->tqReader) { pDelBlock = createSpecialDataBlock(STREAM_DELETE_DATA); @@ -2014,7 +2009,7 @@ FETCH_NEXT_BLOCK: setBlockGroupIdByUid(pInfo, pDelBlock); rebuildDeleteBlockData(pDelBlock, &pStreamInfo->fillHistoryWindow, id); - printDataBlock(pDelBlock, "stream scan delete recv filtered", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pDelBlock, getStreamOpName(pOperator->operatorType), "delete recv filtered", GET_TASKID(pTaskInfo)); if (pDelBlock->info.rows == 0) { if (pInfo->tqReader) { blockDataDestroy(pDelBlock); @@ -2025,7 +2020,7 @@ FETCH_NEXT_BLOCK: if (!isIntervalWindow(pInfo) && !isSessionWindow(pInfo) && !isStateWindow(pInfo)) { generateDeleteResultBlock(pInfo, pDelBlock, pInfo->pDeleteDataRes); pInfo->pDeleteDataRes->info.type = STREAM_DELETE_RESULT; - printDataBlock(pDelBlock, "stream scan delete result", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pDelBlock, getStreamOpName(pOperator->operatorType), "delete result", GET_TASKID(pTaskInfo)); blockDataDestroy(pDelBlock); if (pInfo->pDeleteDataRes->info.rows > 0) { @@ -2040,7 +2035,7 @@ FETCH_NEXT_BLOCK: prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex); copyDataBlock(pInfo->pDeleteDataRes, pInfo->pUpdateRes); pInfo->pDeleteDataRes->info.type = STREAM_DELETE_DATA; - printDataBlock(pDelBlock, "stream scan delete data", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pDelBlock, getStreamOpName(pOperator->operatorType), "delete result", GET_TASKID(pTaskInfo)); if (pInfo->tqReader) { blockDataDestroy(pDelBlock); } @@ -2055,7 +2050,7 @@ FETCH_NEXT_BLOCK: default: break; } - // printDataBlock(pBlock, "stream scan recv"); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); return pBlock; } else if (pInfo->blockType == STREAM_INPUT__DATA_SUBMIT) { qDebug("stream scan mode:%d, %s", pInfo->scanMode, id); @@ -2091,7 +2086,7 @@ FETCH_NEXT_BLOCK: STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info; pSDB->info.type = pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER_RANGE ? STREAM_NORMAL : STREAM_PULL_DATA; checkUpdateData(pInfo, true, pSDB, false); - printDataBlock(pSDB, "stream scan update", GET_TASKID(pTaskInfo)); + printSpecDataBlock(pSDB, getStreamOpName(pOperator->operatorType), "update", GET_TASKID(pTaskInfo)); calBlockTbName(pInfo, pSDB); return pSDB; } From 8a84dce6417618332e7c22a01a7df5c0421367ad Mon Sep 17 00:00:00 2001 From: kailixu Date: Tue, 15 Aug 2023 16:04:30 +0800 Subject: [PATCH 70/92] enh: disable udf/stream/rsma/tsma for windows --- source/dnode/mnode/impl/src/mndDb.c | 3 +-- source/dnode/mnode/impl/src/mndFunc.c | 5 ++--- source/dnode/mnode/impl/src/mndSma.c | 9 ++++----- source/dnode/mnode/impl/src/mndStream.c | 9 ++++----- source/libs/parser/src/parTranslater.c | 13 ------------- 5 files changed, 11 insertions(+), 28 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index fdefe9e5b1..ada80b8370 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -666,14 +666,13 @@ static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) { terrno = TSDB_CODE_INVALID_MSG; goto _OVER; } - - mInfo("db:%s, start to create, vgroups:%d", createReq.db, createReq.numOfVgroups); #ifdef WINDOWS if (taosArrayGetSize(createReq.pRetensions) > 0) { code = TSDB_CODE_PAR_INVALID_PLATFORM; goto _OVER; } #endif + mInfo("db:%s, start to create, vgroups:%d", createReq.db, createReq.numOfVgroups); if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DB, NULL) != 0) { goto _OVER; } diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c index 5f4ac830cd..dc75a311e7 100644 --- a/source/dnode/mnode/impl/src/mndFunc.c +++ b/source/dnode/mnode/impl/src/mndFunc.c @@ -359,12 +359,11 @@ static int32_t mndProcessCreateFuncReq(SRpcMsg *pReq) { terrno = TSDB_CODE_INVALID_MSG; goto _OVER; } - - mInfo("func:%s, start to create, size:%d", createReq.name, createReq.codeLen); #ifdef WINDOWS - code = TSDB_CODE_PAR_INVALID_PLATFORM; + terrno = TSDB_CODE_PAR_INVALID_PLATFORM; goto _OVER; #endif + mInfo("func:%s, start to create, size:%d", createReq.name, createReq.codeLen); if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_FUNC) != 0) { goto _OVER; } diff --git a/source/dnode/mnode/impl/src/mndSma.c b/source/dnode/mnode/impl/src/mndSma.c index ff3f66efaf..55169a5d56 100644 --- a/source/dnode/mnode/impl/src/mndSma.c +++ b/source/dnode/mnode/impl/src/mndSma.c @@ -655,10 +655,6 @@ _OVER: } static int32_t mndCheckCreateSmaReq(SMCreateSmaReq *pCreate) { -#ifdef WINDOWS - terrno = TSDB_CODE_PAR_INVALID_PLATFORM; - return -1; -#endif terrno = TSDB_CODE_MND_INVALID_SMA_OPTION; if (pCreate->name[0] == 0) return -1; if (pCreate->stb[0] == 0) return -1; @@ -709,7 +705,10 @@ static int32_t mndProcessCreateSmaReq(SRpcMsg *pReq) { terrno = TSDB_CODE_INVALID_MSG; goto _OVER; } - +#ifdef WINDOWS + terrno = TSDB_CODE_PAR_INVALID_PLATFORM; + goto _OVER; +#endif mInfo("sma:%s, start to create", createReq.name); if (mndCheckCreateSmaReq(&createReq) != 0) { goto _OVER; diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index d6bb8c167f..7fd2444ab2 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -253,10 +253,6 @@ static void mndShowStreamTrigger(char *dst, SStreamObj *pStream) { } static int32_t mndCheckCreateStreamReq(SCMCreateStreamReq *pCreate) { -#ifdef WINDOWS - terrno = TSDB_CODE_PAR_INVALID_PLATFORM; - return -1; -#endif if (pCreate->name[0] == 0 || pCreate->sql == NULL || pCreate->sql[0] == 0 || pCreate->sourceDB[0] == 0 || pCreate->targetStbFullName[0] == 0) { terrno = TSDB_CODE_MND_INVALID_STREAM_OPTION; @@ -696,7 +692,10 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) { terrno = TSDB_CODE_INVALID_MSG; goto _OVER; } - +#ifdef WINDOWS + terrno = TSDB_CODE_PAR_INVALID_PLATFORM; + goto _OVER; +#endif mInfo("stream:%s, start to create, sql:%s", createStreamReq.name, createStreamReq.sql); if (mndCheckCreateStreamReq(&createStreamReq) != 0) { diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 9c3beea2d8..a41447edf3 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -4418,10 +4418,6 @@ static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRete return TSDB_CODE_SUCCESS; } -#ifdef WINDOWS - return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platform"); -#endif - if (LIST_LENGTH(pRetentions) > 3) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION, "Invalid option retentions"); } @@ -5871,9 +5867,6 @@ static int32_t checkCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pS } static int32_t translateCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) { -#ifdef WINDOWS - return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platform"); -#endif int32_t code = checkCreateSmaIndex(pCxt, pStmt); pStmt->pReq = taosMemoryCalloc(1, sizeof(SMCreateSmaReq)); if (pStmt->pReq == NULL) code = TSDB_CODE_OUT_OF_MEMORY; @@ -7059,9 +7052,6 @@ static int32_t buildCreateStreamReq(STranslateContext* pCxt, SCreateStreamStmt* } static int32_t translateCreateStream(STranslateContext* pCxt, SCreateStreamStmt* pStmt) { -#ifdef WINDOWS - return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platform"); -#endif SCMCreateStreamReq createReq = {0}; int32_t code = checkCreateStream(pCxt, pStmt); @@ -7211,9 +7201,6 @@ static int32_t readFromFile(char* pName, int32_t* len, char** buf) { } static int32_t translateCreateFunction(STranslateContext* pCxt, SCreateFunctionStmt* pStmt) { -#ifdef WINDOWS - return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platform"); -#endif if (fmIsBuiltinFunc(pStmt->funcName)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FUNCTION_NAME); } From 1876a94e264917dd57490591cc86a6ea8c08da7f Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 15 Aug 2023 16:05:09 +0800 Subject: [PATCH 71/92] fix bugs --- source/libs/function/src/builtins.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index ef7c9d1442..9a301b7f1c 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1568,17 +1568,19 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len) } static int32_t translateIrateImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) { - if (3 != LIST_LENGTH(pFunc->pParameterList)) { - return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); - } - uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; if (isPartial) { + if (3 != LIST_LENGTH(pFunc->pParameterList)) { + return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); + } if (!IS_NUMERIC_TYPE(colType)) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } pFunc->node.resType = (SDataType){.bytes = getIrateInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; } else { + if (1 != LIST_LENGTH(pFunc->pParameterList)) { + return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); + } if (TSDB_DATA_TYPE_BINARY != colType) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } @@ -2660,8 +2662,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { { .name = "_irate_merge", .type = FUNCTION_TYPE_IRATE_MERGE, - .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | - FUNC_MGT_FORBID_SYSTABLE_FUNC, + .classification = FUNC_MGT_AGG_FUNC, .translateFunc = translateIrateMerge, .getEnvFunc = getIrateFuncEnv, .initFunc = irateFuncSetup, From 242bf77f4c1d6e811b5b41a872eff91f3a5c0985 Mon Sep 17 00:00:00 2001 From: kailixu Date: Tue, 15 Aug 2023 16:13:51 +0800 Subject: [PATCH 72/92] chore: code optimization --- include/util/taoserror.h | 2 +- source/dnode/mnode/impl/src/mndDb.c | 2 +- source/dnode/mnode/impl/src/mndFunc.c | 2 +- source/dnode/mnode/impl/src/mndSma.c | 2 +- source/dnode/mnode/impl/src/mndStream.c | 2 +- source/util/src/terror.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 75ab916230..a5081f2c7d 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -191,6 +191,7 @@ int32_t* taosGetErrno(); // #define TSDB_CODE_MND_FAILED_TO_CREATE_DIR TAOS_DEF_ERROR_CODE(0, 0x0313) // 2.x // #define TSDB_CODE_MND_FAILED_TO_INIT_STEP TAOS_DEF_ERROR_CODE(0, 0x0314) // 2.x #define TSDB_CODE_MND_USER_DISABLED TAOS_DEF_ERROR_CODE(0, 0x0315) +#define TSDB_CODE_MND_INVALID_PLATFORM TAOS_DEF_ERROR_CODE(0, 0x0316) // mnode-sdb #define TSDB_CODE_SDB_OBJ_ALREADY_THERE TAOS_DEF_ERROR_CODE(0, 0x0320) // internal @@ -707,7 +708,6 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_INVALID_OPTR_USAGE TAOS_DEF_ERROR_CODE(0, 0x2667) #define TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x2668) #define TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED TAOS_DEF_ERROR_CODE(0, 0x2669) -#define TSDB_CODE_PAR_INVALID_PLATFORM TAOS_DEF_ERROR_CODE(0, 0x2670) #define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF) //planner diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index ada80b8370..4f7e80c0a3 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -668,7 +668,7 @@ static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) { } #ifdef WINDOWS if (taosArrayGetSize(createReq.pRetensions) > 0) { - code = TSDB_CODE_PAR_INVALID_PLATFORM; + terrno = TSDB_CODE_MND_INVALID_PLATFORM; goto _OVER; } #endif diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c index dc75a311e7..5eb7abf026 100644 --- a/source/dnode/mnode/impl/src/mndFunc.c +++ b/source/dnode/mnode/impl/src/mndFunc.c @@ -360,7 +360,7 @@ static int32_t mndProcessCreateFuncReq(SRpcMsg *pReq) { goto _OVER; } #ifdef WINDOWS - terrno = TSDB_CODE_PAR_INVALID_PLATFORM; + terrno = TSDB_CODE_MND_INVALID_PLATFORM; goto _OVER; #endif mInfo("func:%s, start to create, size:%d", createReq.name, createReq.codeLen); diff --git a/source/dnode/mnode/impl/src/mndSma.c b/source/dnode/mnode/impl/src/mndSma.c index 55169a5d56..e186a8742f 100644 --- a/source/dnode/mnode/impl/src/mndSma.c +++ b/source/dnode/mnode/impl/src/mndSma.c @@ -706,7 +706,7 @@ static int32_t mndProcessCreateSmaReq(SRpcMsg *pReq) { goto _OVER; } #ifdef WINDOWS - terrno = TSDB_CODE_PAR_INVALID_PLATFORM; + terrno = TSDB_CODE_MND_INVALID_PLATFORM; goto _OVER; #endif mInfo("sma:%s, start to create", createReq.name); diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index 7fd2444ab2..427a52af3b 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -693,7 +693,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) { goto _OVER; } #ifdef WINDOWS - terrno = TSDB_CODE_PAR_INVALID_PLATFORM; + terrno = TSDB_CODE_MND_INVALID_PLATFORM; goto _OVER; #endif mInfo("stream:%s, start to create, sql:%s", createStreamReq.name, createStreamReq.sql); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 74352f2799..466b9985e7 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -151,6 +151,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SHOWOBJ, "Data expired") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, "Invalid query id") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, "Invalid connection id") TAOS_DEFINE_ERROR(TSDB_CODE_MND_USER_DISABLED, "User is disabled") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_PLATFORM, "Unsupported feature on this platform") // mnode-sdb TAOS_DEFINE_ERROR(TSDB_CODE_SDB_OBJ_ALREADY_THERE, "Object already there") @@ -570,7 +571,6 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_GET_META_ERROR, "Fail to get table i TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_UNIQUE_TABLE_ALIAS, "Not unique table/alias") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED_FUNC, "System table not allowed") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED, "System table not allowed") -TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_PLATFORM, "Unsupported feature on this platformXX") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INTERNAL_ERROR, "Parser internal error") //planner From 7d1e4a9894c7c66b924a5dcbceecb708058e79f8 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 15 Aug 2023 08:25:33 +0000 Subject: [PATCH 73/92] rebuild index at tag0 --- source/common/src/tdatablock.c | 78 +++++++++++++++++----------------- tests/parallel_test/cases.task | 2 +- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 5188b1e27c..9f30d04b74 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -26,7 +26,7 @@ int32_t colDataGetLength(const SColumnInfoData* pColumnInfoData, int32_t numOfRo if (pColumnInfoData->reassigned) { int32_t totalSize = 0; for (int32_t row = 0; row < numOfRows; ++row) { - char* pColData = pColumnInfoData->pData + pColumnInfoData->varmeta.offset[row]; + char* pColData = pColumnInfoData->pData + pColumnInfoData->varmeta.offset[row]; int32_t colSize = 0; if (pColumnInfoData->info.type == TSDB_DATA_TYPE_JSON) { colSize = getJsonValueLen(pColData); @@ -142,7 +142,8 @@ int32_t colDataSetVal(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const return 0; } -int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, uint32_t srcRowIdx, const char* pData) { +int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, uint32_t srcRowIdx, + const char* pData) { int32_t type = pColumnInfoData->info.type; if (IS_VAR_DATA_TYPE(type)) { int32_t dataLen = 0; @@ -164,7 +165,6 @@ int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, return 0; } - static int32_t colDataReserve(SColumnInfoData* pColumnInfoData, size_t newSize) { if (!IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) { return TSDB_CODE_SUCCESS; @@ -188,16 +188,17 @@ static int32_t colDataReserve(SColumnInfoData* pColumnInfoData, size_t newSize) } static int32_t doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t currentRow, const char* pData, - int32_t itemLen, int32_t numOfRows, bool trimValue) { + int32_t itemLen, int32_t numOfRows, bool trimValue) { if (pColumnInfoData->info.bytes < itemLen) { - uWarn("column/tag actual data len %d is bigger than schema len %d, trim it:%d", itemLen, pColumnInfoData->info.bytes, trimValue); + uWarn("column/tag actual data len %d is bigger than schema len %d, trim it:%d", itemLen, + pColumnInfoData->info.bytes, trimValue); if (trimValue) { itemLen = pColumnInfoData->info.bytes; } else { return TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER; } } - + size_t start = 1; // the first item @@ -230,8 +231,8 @@ static int32_t doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t cur return TSDB_CODE_SUCCESS; } -int32_t colDataSetNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, - uint32_t numOfRows, bool trimValue) { +int32_t colDataSetNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, uint32_t numOfRows, + bool trimValue) { int32_t len = pColumnInfoData->info.bytes; if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) { len = varDataTLen(pData); @@ -262,7 +263,7 @@ static void doBitmapMerge(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, c uint8_t* p = (uint8_t*)pSource->nullbitmap; pColumnInfoData->nullbitmap[BitmapLen(numOfRow1) - 1] &= (0B11111111 << shiftBits); // clear remind bits - pColumnInfoData->nullbitmap[BitmapLen(numOfRow1) - 1] |= (p[0] >> remindBits); // copy remind bits + pColumnInfoData->nullbitmap[BitmapLen(numOfRow1) - 1] |= (p[0] >> remindBits); // copy remind bits if (BitmapLen(numOfRow1) == BitmapLen(total)) { return; @@ -350,7 +351,7 @@ int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, int pColumnInfoData->pData = tmp; if (BitmapLen(numOfRow1) < BitmapLen(finalNumOfRows)) { - char* btmp = taosMemoryRealloc(pColumnInfoData->nullbitmap, BitmapLen(finalNumOfRows)); + char* btmp = taosMemoryRealloc(pColumnInfoData->nullbitmap, BitmapLen(finalNumOfRows)); if (btmp == NULL) { return TSDB_CODE_OUT_OF_MEMORY; } @@ -622,7 +623,7 @@ int32_t blockDataToBuf(char* buf, const SSDataBlock* pBlock) { if (pCol->reassigned && IS_VAR_DATA_TYPE(pCol->info.type)) { for (int32_t row = 0; row < numOfRows; ++row) { - char* pColData = pCol->pData + pCol->varmeta.offset[row]; + char* pColData = pCol->pData + pCol->varmeta.offset[row]; int32_t colSize = 0; if (pCol->info.type == TSDB_DATA_TYPE_JSON) { colSize = getJsonValueLen(pColData); @@ -698,8 +699,7 @@ int32_t blockDataFromBuf(SSDataBlock* pBlock, const char* buf) { return TSDB_CODE_SUCCESS; } -static bool colDataIsNNull(const SColumnInfoData* pColumnInfoData, int32_t startIndex, - uint32_t nRows) { +static bool colDataIsNNull(const SColumnInfoData* pColumnInfoData, int32_t startIndex, uint32_t nRows) { if (!pColumnInfoData->hasNull) { return false; } @@ -880,7 +880,6 @@ int32_t dataBlockCompar(const void* p1, const void* p2, const void* param) { } static int32_t blockDataAssign(SColumnInfoData* pCols, const SSDataBlock* pDataBlock, const int32_t* index) { - size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock); for (int32_t i = 0; i < numOfCols; ++i) { SColumnInfoData* pDst = &pCols[i]; @@ -1131,6 +1130,7 @@ static int32_t doEnsureCapacity(SColumnInfoData* pColumn, const SDataBlockInfo* if (tmp == NULL) { return TSDB_CODE_OUT_OF_MEMORY; } + // memset(tmp, 0, numOfRows * pColumn->info.bytes); // copy back the existed data if (pColumn->pData != NULL) { @@ -1474,8 +1474,8 @@ size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize, int int end = nRows; while (start <= end) { int mid = start + (end - start) / 2; - //data size + var data type columns offset + fixed data type columns bitmap len - int midSize = rowSize * mid + numVarCols * sizeof(int32_t) * mid + numFixCols * BitmapLen(mid); + // data size + var data type columns offset + fixed data type columns bitmap len + int midSize = rowSize * mid + numVarCols * sizeof(int32_t) * mid + numFixCols * BitmapLen(mid); if (midSize > payloadSize) { result = mid; end = mid - 1; @@ -1669,7 +1669,7 @@ int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock) { if (pColData->reassigned && IS_VAR_DATA_TYPE(pColData->info.type)) { for (int32_t row = 0; row < rows; ++row) { - char* pData = pColData->pData + pColData->varmeta.offset[row]; + char* pData = pColData->pData + pColData->varmeta.offset[row]; int32_t colSize = 0; if (pColData->info.type == TSDB_DATA_TYPE_JSON) { colSize = getJsonValueLen(pData); @@ -1772,7 +1772,7 @@ static char* formatTimestamp(char* buf, int64_t val, int precision) { // for debug char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) { - int32_t size = 2048*1024; + int32_t size = 2048 * 1024; *pDataBuf = taosMemoryCalloc(size, 1); char* dumpBuf = *pDataBuf; char pBuf[128] = {0}; @@ -1780,8 +1780,8 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) int32_t rows = pDataBlock->info.rows; int32_t len = 0; len += snprintf(dumpBuf + len, size - len, - "===stream===%s|block type %d|child id %d|group id:%" PRIu64 "|uid:%" PRId64 - "|rows:%" PRId64 "|version:%" PRIu64 "|cal start:%" PRIu64 "|cal end:%" PRIu64 "|tbl:%s\n", + "===stream===%s|block type %d|child id %d|group id:%" PRIu64 "|uid:%" PRId64 "|rows:%" PRId64 + "|version:%" PRIu64 "|cal start:%" PRIu64 "|cal end:%" PRIu64 "|tbl:%s\n", flag, (int32_t)pDataBlock->info.type, pDataBlock->info.childId, pDataBlock->info.id.groupId, pDataBlock->info.id.uid, pDataBlock->info.rows, pDataBlock->info.version, pDataBlock->info.calWin.skey, pDataBlock->info.calWin.ekey, pDataBlock->info.parTbName); @@ -2156,21 +2156,21 @@ int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols) { data += metaSize; dataLen += metaSize; - if (pColRes->reassigned && IS_VAR_DATA_TYPE(pColRes->info.type)) { - colSizes[col] = 0; - for (int32_t row = 0; row < numOfRows; ++row) { - char* pColData = pColRes->pData + pColRes->varmeta.offset[row]; - int32_t colSize = 0; - if (pColRes->info.type == TSDB_DATA_TYPE_JSON) { - colSize = getJsonValueLen(pColData); - } else { - colSize = varDataTLen(pColData); - } - colSizes[col] += colSize; - dataLen += colSize; - memmove(data, pColData, colSize); - data += colSize; + if (pColRes->reassigned && IS_VAR_DATA_TYPE(pColRes->info.type)) { + colSizes[col] = 0; + for (int32_t row = 0; row < numOfRows; ++row) { + char* pColData = pColRes->pData + pColRes->varmeta.offset[row]; + int32_t colSize = 0; + if (pColRes->info.type == TSDB_DATA_TYPE_JSON) { + colSize = getJsonValueLen(pColData); + } else { + colSize = varDataTLen(pColData); } + colSizes[col] += colSize; + dataLen += colSize; + memmove(data, pColData, colSize); + data += colSize; + } } else { colSizes[col] = colDataGetLength(pColRes, numOfRows); dataLen += colSizes[col]; @@ -2181,7 +2181,8 @@ int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols) { } colSizes[col] = htonl(colSizes[col]); -// uError("blockEncode col bytes:%d, type:%d, size:%d, htonl size:%d", pColRes->info.bytes, pColRes->info.type, htonl(colSizes[col]), colSizes[col]); + // uError("blockEncode col bytes:%d, type:%d, size:%d, htonl size:%d", pColRes->info.bytes, pColRes->info.type, + // htonl(colSizes[col]), colSizes[col]); } *actualLen = dataLen; @@ -2283,7 +2284,7 @@ const char* blockDecode(SSDataBlock* pBlock, const char* pData) { } void trimDataBlock(SSDataBlock* pBlock, int32_t totalRows, const bool* pBoolList) { -// int32_t totalRows = pBlock->info.rows; + // int32_t totalRows = pBlock->info.rows; int32_t bmLen = BitmapLen(totalRows); char* pBitmap = NULL; int32_t maxRows = 0; @@ -2310,8 +2311,9 @@ void trimDataBlock(SSDataBlock* pBlock, int32_t totalRows, const bool* pBoolList if (colDataIsNull_var(pDst, j)) { colDataSetNull_var(pDst, numOfRows); } else { - // fix address sanitizer error. p1 may point to memory that will change during realloc of colDataSetVal, first copy it to p2 - char* p1 = colDataGetVarData(pDst, j); + // fix address sanitizer error. p1 may point to memory that will change during realloc of colDataSetVal, first + // copy it to p2 + char* p1 = colDataGetVarData(pDst, j); int32_t len = 0; if (pDst->info.type == TSDB_DATA_TYPE_JSON) { len = getJsonValueLen(p1); diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index e81339d705..8345a1112e 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -1205,7 +1205,7 @@ ,,y,script,./test.sh -f tsim/tag/tbNameIn.sim ,,y,script,./test.sh -f tmp/monitor.sim ,,y,script,./test.sh -f tsim/tagindex/add_index.sim -,,y,script,./test.sh -f tsim/tagindex/sma_and_tag_index.sim +,,n,script,./test.sh -f tsim/tagindex/sma_and_tag_index.sim #develop test From 19dfcf3a596406f143a47150e8468f005706fa46 Mon Sep 17 00:00:00 2001 From: liuyao <54liuyao@163.com> Date: Tue, 15 Aug 2023 16:29:48 +0800 Subject: [PATCH 74/92] refactor stream scan log --- source/libs/executor/src/scanoperator.c | 2 +- source/libs/stream/src/streamExec.c | 4 ++-- source/libs/stream/src/streamQueue.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 4a8ef0565e..9b313a50ad 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -2050,7 +2050,7 @@ FETCH_NEXT_BLOCK: default: break; } - printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); + printDataBlock(pBlock, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pBlock; } else if (pInfo->blockType == STREAM_INPUT__DATA_SUBMIT) { qDebug("stream scan mode:%d, %s", pInfo->scanMode, id); diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index c7da80fdaf..918b2c576c 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -415,11 +415,11 @@ static int32_t extractMsgFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInpu if (qItem == NULL) { if (pTask->info.taskLevel == TASK_LEVEL__SOURCE && (++retryTimes) < MAX_RETRY_TIMES) { taosMsleep(10); - qDebug("===stream===try again batchSize:%d, retry:%d", *numOfBlocks, retryTimes); + qDebug("try again batchSize:%d, retry:%d", *numOfBlocks, retryTimes); continue; } - qDebug("===stream===break batchSize:%d", *numOfBlocks); + qDebug("break batchSize:%d", *numOfBlocks); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/stream/src/streamQueue.c b/source/libs/stream/src/streamQueue.c index aaf9fdec72..65135ec9a1 100644 --- a/source/libs/stream/src/streamQueue.c +++ b/source/libs/stream/src/streamQueue.c @@ -130,11 +130,11 @@ SStreamQueueItem* doReadMultiBlocksFromQueue(SQueueReader* pReader, const char* if (pReader->taskLevel == TASK_LEVEL__SOURCE && numOfBlocks < MIN_STREAM_EXEC_BATCH_NUM && tryCount < pReader->waitDuration) { tryCount++; taosMsleep(1); - qDebug("===stream===try again batchSize:%d", numOfBlocks); + qDebug("try again batchSize:%d", numOfBlocks); continue; } - qDebug("===stream===break batchSize:%d", numOfBlocks); + qDebug("break batchSize:%d", numOfBlocks); break; } From dcbef83deae7b18e2a9b3e0c38af81d306c9ea58 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Tue, 15 Aug 2023 16:30:02 +0800 Subject: [PATCH 75/92] feat: support column comment --- include/common/tmsg.h | 2 + include/common/ttokendef.h | 236 +- include/libs/nodes/cmdnodes.h | 2 +- include/util/tdef.h | 1 + source/common/src/tmsg.c | 4 + source/dnode/mnode/impl/src/mndStb.c | 2 + source/libs/parser/inc/sql.y | 2 +- source/libs/parser/src/parTranslater.c | 2 + source/libs/parser/src/sql.c | 4635 ++++++++++++------------ tests/system-test/0-others/show.py | 13 + 10 files changed, 2464 insertions(+), 2435 deletions(-) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 01923d2b30..43b70141e2 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -231,6 +231,7 @@ typedef struct SField { uint8_t type; int8_t flags; int32_t bytes; + char comment[TSDB_COL_COMMENT_LEN]; } SField; typedef struct SRetention { @@ -309,6 +310,7 @@ struct SSchema { col_id_t colId; int32_t bytes; char name[TSDB_COL_NAME_LEN]; + char comment[TSDB_COL_COMMENT_LEN]; }; struct SSchema2 { diff --git a/include/common/ttokendef.h b/include/common/ttokendef.h index 8a6b7b5020..8225e4692d 100644 --- a/include/common/ttokendef.h +++ b/include/common/ttokendef.h @@ -16,105 +16,105 @@ #ifndef _TD_COMMON_TOKEN_H_ #define _TD_COMMON_TOKEN_H_ -#define TK_OR 1 -#define TK_AND 2 -#define TK_UNION 3 -#define TK_ALL 4 -#define TK_MINUS 5 -#define TK_EXCEPT 6 -#define TK_INTERSECT 7 -#define TK_NK_BITAND 8 -#define TK_NK_BITOR 9 -#define TK_NK_LSHIFT 10 -#define TK_NK_RSHIFT 11 -#define TK_NK_PLUS 12 -#define TK_NK_MINUS 13 -#define TK_NK_STAR 14 -#define TK_NK_SLASH 15 -#define TK_NK_REM 16 -#define TK_NK_CONCAT 17 -#define TK_CREATE 18 -#define TK_ACCOUNT 19 -#define TK_NK_ID 20 -#define TK_PASS 21 -#define TK_NK_STRING 22 -#define TK_ALTER 23 -#define TK_PPS 24 -#define TK_TSERIES 25 -#define TK_STORAGE 26 -#define TK_STREAMS 27 -#define TK_QTIME 28 -#define TK_DBS 29 -#define TK_USERS 30 -#define TK_CONNS 31 -#define TK_STATE 32 -#define TK_USER 33 -#define TK_ENABLE 34 -#define TK_NK_INTEGER 35 -#define TK_SYSINFO 36 -#define TK_DROP 37 -#define TK_GRANT 38 -#define TK_ON 39 -#define TK_TO 40 -#define TK_REVOKE 41 -#define TK_FROM 42 -#define TK_SUBSCRIBE 43 -#define TK_NK_COMMA 44 -#define TK_READ 45 -#define TK_WRITE 46 -#define TK_NK_DOT 47 -#define TK_WITH 48 -#define TK_DNODE 49 -#define TK_PORT 50 -#define TK_DNODES 51 -#define TK_RESTORE 52 -#define TK_NK_IPTOKEN 53 -#define TK_FORCE 54 -#define TK_UNSAFE 55 -#define TK_LOCAL 56 -#define TK_QNODE 57 -#define TK_BNODE 58 -#define TK_SNODE 59 -#define TK_MNODE 60 -#define TK_VNODE 61 -#define TK_DATABASE 62 -#define TK_USE 63 -#define TK_FLUSH 64 -#define TK_TRIM 65 -#define TK_COMPACT 66 -#define TK_IF 67 -#define TK_NOT 68 -#define TK_EXISTS 69 -#define TK_BUFFER 70 -#define TK_CACHEMODEL 71 -#define TK_CACHESIZE 72 -#define TK_COMP 73 -#define TK_DURATION 74 -#define TK_NK_VARIABLE 75 -#define TK_MAXROWS 76 -#define TK_MINROWS 77 -#define TK_KEEP 78 -#define TK_PAGES 79 -#define TK_PAGESIZE 80 -#define TK_TSDB_PAGESIZE 81 -#define TK_PRECISION 82 -#define TK_REPLICA 83 -#define TK_VGROUPS 84 -#define TK_SINGLE_STABLE 85 -#define TK_RETENTIONS 86 -#define TK_SCHEMALESS 87 -#define TK_WAL_LEVEL 88 -#define TK_WAL_FSYNC_PERIOD 89 -#define TK_WAL_RETENTION_PERIOD 90 -#define TK_WAL_RETENTION_SIZE 91 -#define TK_WAL_ROLL_PERIOD 92 -#define TK_WAL_SEGMENT_SIZE 93 -#define TK_STT_TRIGGER 94 -#define TK_TABLE_PREFIX 95 -#define TK_TABLE_SUFFIX 96 -#define TK_NK_COLON 97 -#define TK_MAX_SPEED 98 -#define TK_START 99 +#define TK_OR 1 +#define TK_AND 2 +#define TK_UNION 3 +#define TK_ALL 4 +#define TK_MINUS 5 +#define TK_EXCEPT 6 +#define TK_INTERSECT 7 +#define TK_NK_BITAND 8 +#define TK_NK_BITOR 9 +#define TK_NK_LSHIFT 10 +#define TK_NK_RSHIFT 11 +#define TK_NK_PLUS 12 +#define TK_NK_MINUS 13 +#define TK_NK_STAR 14 +#define TK_NK_SLASH 15 +#define TK_NK_REM 16 +#define TK_NK_CONCAT 17 +#define TK_CREATE 18 +#define TK_ACCOUNT 19 +#define TK_NK_ID 20 +#define TK_PASS 21 +#define TK_NK_STRING 22 +#define TK_ALTER 23 +#define TK_PPS 24 +#define TK_TSERIES 25 +#define TK_STORAGE 26 +#define TK_STREAMS 27 +#define TK_QTIME 28 +#define TK_DBS 29 +#define TK_USERS 30 +#define TK_CONNS 31 +#define TK_STATE 32 +#define TK_USER 33 +#define TK_ENABLE 34 +#define TK_NK_INTEGER 35 +#define TK_SYSINFO 36 +#define TK_DROP 37 +#define TK_GRANT 38 +#define TK_ON 39 +#define TK_TO 40 +#define TK_REVOKE 41 +#define TK_FROM 42 +#define TK_SUBSCRIBE 43 +#define TK_NK_COMMA 44 +#define TK_READ 45 +#define TK_WRITE 46 +#define TK_NK_DOT 47 +#define TK_WITH 48 +#define TK_DNODE 49 +#define TK_PORT 50 +#define TK_DNODES 51 +#define TK_RESTORE 52 +#define TK_NK_IPTOKEN 53 +#define TK_FORCE 54 +#define TK_UNSAFE 55 +#define TK_LOCAL 56 +#define TK_QNODE 57 +#define TK_BNODE 58 +#define TK_SNODE 59 +#define TK_MNODE 60 +#define TK_VNODE 61 +#define TK_DATABASE 62 +#define TK_USE 63 +#define TK_FLUSH 64 +#define TK_TRIM 65 +#define TK_COMPACT 66 +#define TK_IF 67 +#define TK_NOT 68 +#define TK_EXISTS 69 +#define TK_BUFFER 70 +#define TK_CACHEMODEL 71 +#define TK_CACHESIZE 72 +#define TK_COMP 73 +#define TK_DURATION 74 +#define TK_NK_VARIABLE 75 +#define TK_MAXROWS 76 +#define TK_MINROWS 77 +#define TK_KEEP 78 +#define TK_PAGES 79 +#define TK_PAGESIZE 80 +#define TK_TSDB_PAGESIZE 81 +#define TK_PRECISION 82 +#define TK_REPLICA 83 +#define TK_VGROUPS 84 +#define TK_SINGLE_STABLE 85 +#define TK_RETENTIONS 86 +#define TK_SCHEMALESS 87 +#define TK_WAL_LEVEL 88 +#define TK_WAL_FSYNC_PERIOD 89 +#define TK_WAL_RETENTION_PERIOD 90 +#define TK_WAL_RETENTION_SIZE 91 +#define TK_WAL_ROLL_PERIOD 92 +#define TK_WAL_SEGMENT_SIZE 93 +#define TK_STT_TRIGGER 94 +#define TK_TABLE_PREFIX 95 +#define TK_TABLE_SUFFIX 96 +#define TK_NK_COLON 97 +#define TK_MAX_SPEED 98 +#define TK_START 99 #define TK_TIMESTAMP 100 #define TK_END 101 #define TK_TABLE 102 @@ -130,25 +130,25 @@ #define TK_NK_EQ 112 #define TK_USING 113 #define TK_TAGS 114 -#define TK_BOOL 115 -#define TK_TINYINT 116 -#define TK_SMALLINT 117 -#define TK_INT 118 -#define TK_INTEGER 119 -#define TK_BIGINT 120 -#define TK_FLOAT 121 -#define TK_DOUBLE 122 -#define TK_BINARY 123 -#define TK_NCHAR 124 -#define TK_UNSIGNED 125 -#define TK_JSON 126 -#define TK_VARCHAR 127 -#define TK_MEDIUMBLOB 128 -#define TK_BLOB 129 -#define TK_VARBINARY 130 -#define TK_GEOMETRY 131 -#define TK_DECIMAL 132 -#define TK_COMMENT 133 +#define TK_COMMENT 115 +#define TK_BOOL 116 +#define TK_TINYINT 117 +#define TK_SMALLINT 118 +#define TK_INT 119 +#define TK_INTEGER 120 +#define TK_BIGINT 121 +#define TK_FLOAT 122 +#define TK_DOUBLE 123 +#define TK_BINARY 124 +#define TK_NCHAR 125 +#define TK_UNSIGNED 126 +#define TK_JSON 127 +#define TK_VARCHAR 128 +#define TK_MEDIUMBLOB 129 +#define TK_BLOB 130 +#define TK_VARBINARY 131 +#define TK_GEOMETRY 132 +#define TK_DECIMAL 133 #define TK_MAX_DELAY 134 #define TK_WATERMARK 135 #define TK_ROLLUP 136 diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index f0a715e651..b6c4e89a33 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -155,7 +155,7 @@ typedef struct SColumnDefNode { ENodeType type; char colName[TSDB_COL_NAME_LEN]; SDataType dataType; - char comments[TSDB_TB_COMMENT_LEN]; + char comments[TSDB_COL_COMMENT_LEN]; bool sma; } SColumnDefNode; diff --git a/include/util/tdef.h b/include/util/tdef.h index e4af88bf10..1e12f12087 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -230,6 +230,7 @@ typedef enum ELogicConditionType { #define TSDB_APP_NAME_LEN TSDB_UNI_LEN #define TSDB_TB_COMMENT_LEN 1025 +#define TSDB_COL_COMMENT_LEN 1025 #define TSDB_QUERY_ID_LEN 26 #define TSDB_TRANS_OPER_LEN 16 diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index ef0006e7ab..0e48ffd05a 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -534,6 +534,7 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq if (tEncodeI8(&encoder, pField->flags) < 0) return -1; if (tEncodeI32(&encoder, pField->bytes) < 0) return -1; if (tEncodeCStr(&encoder, pField->name) < 0) return -1; + if (tEncodeCStr(&encoder, pField->comment) < 0) return -1; } for (int32_t i = 0; i < pReq->numOfTags; ++i) { @@ -542,6 +543,7 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq if (tEncodeI8(&encoder, pField->flags) < 0) return -1; if (tEncodeI32(&encoder, pField->bytes) < 0) return -1; if (tEncodeCStr(&encoder, pField->name) < 0) return -1; + if (tEncodeCStr(&encoder, pField->comment) < 0) return -1; } for (int32_t i = 0; i < pReq->numOfFuncs; ++i) { @@ -608,6 +610,7 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR if (tDecodeI8(&decoder, &field.flags) < 0) return -1; if (tDecodeI32(&decoder, &field.bytes) < 0) return -1; if (tDecodeCStrTo(&decoder, field.name) < 0) return -1; + if (tDecodeCStrTo(&decoder, field.comment) < 0) return -1; if (taosArrayPush(pReq->pColumns, &field) == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; @@ -620,6 +623,7 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR if (tDecodeI8(&decoder, &field.flags) < 0) return -1; if (tDecodeI32(&decoder, &field.bytes) < 0) return -1; if (tDecodeCStrTo(&decoder, field.name) < 0) return -1; + if (tDecodeCStrTo(&decoder, field.comment) < 0) return -1; if (taosArrayPush(pReq->pTags, &field) == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 70fd74afc0..18f5a65196 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -834,6 +834,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat pSchema->bytes = pField->bytes; pSchema->flags = pField->flags; memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); + memcpy(pSchema->comment, pField->comment, TSDB_COL_COMMENT_LEN); pSchema->colId = pDst->nextColId; pDst->nextColId++; } @@ -847,6 +848,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat SSCHMEA_SET_IDX_ON(pSchema); } memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); + memcpy(pSchema->comment, pField->comment, TSDB_COL_COMMENT_LEN); pSchema->colId = pDst->nextColId; pDst->nextColId++; } diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 6c3f589159..e8f1371d4e 100755 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -358,7 +358,7 @@ column_def_list(A) ::= column_def(B). column_def_list(A) ::= column_def_list(B) NK_COMMA column_def(C). { A = addNodeToList(pCxt, B, C); } column_def(A) ::= column_name(B) type_name(C). { A = createColumnDefNode(pCxt, &B, C, NULL); } -//column_def(A) ::= column_name(B) type_name(C) COMMENT NK_STRING(D). { A = createColumnDefNode(pCxt, &B, C, &D); } +column_def(A) ::= column_name(B) type_name(C) COMMENT NK_STRING(D). { A = createColumnDefNode(pCxt, &B, C, &D); } %type type_name { SDataType } %destructor type_name { } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 38118c03f8..38294c6ac6 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -4688,6 +4688,7 @@ static int32_t columnDefNodeToField(SNodeList* pList, SArray** pArray) { SColumnDefNode* pCol = (SColumnDefNode*)pNode; SField field = {.type = pCol->dataType.type, .bytes = calcTypeBytes(pCol->dataType)}; strcpy(field.name, pCol->colName); + strcpy(field.comment, pCol->comments); if (pCol->sma) { field.flags |= COL_SMA_ON; } @@ -5035,6 +5036,7 @@ static void toSchema(const SColumnDefNode* pCol, col_id_t colId, SSchema* pSchem pSchema->bytes = calcTypeBytes(pCol->dataType); pSchema->flags = flags; strcpy(pSchema->name, pCol->colName); + strcpy(pSchema->comment, pCol->comments); } typedef struct SSampleAstInfo { diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index a912fb4e71..9024dbda62 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -1,3 +1,5 @@ +/* This file is automatically generated by Lemon from input grammar +** source file "./sql.y". */ /* ** 2000-05-29 ** @@ -22,10 +24,7 @@ ** The following is the concatenation of all %include directives from the ** input grammar file: */ -#include -#include /************ Begin %include sections from the grammar ************************/ - #include #include #include @@ -42,11 +41,6 @@ #define YYSTACKDEPTH 0 /**************** End of %include directives **********************************/ -/* These constants specify the various numeric values for terminal symbols -** in a format understandable to "makeheaders". This section is blank unless -** "lemon" is run with the "-m" command-line option. -***************** Begin makeheaders token definitions *************************/ -/**************** End makeheaders token definitions ***************************/ /* The next sections is a series of control #defines. ** various aspects of the generated parser. @@ -140,18 +134,18 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 800 -#define YYNRULE 600 -#define YYNRULE_WITH_ACTION 600 +#define YYNSTATE 802 +#define YYNRULE 601 +#define YYNRULE_WITH_ACTION 601 #define YYNTOKEN 338 -#define YY_MAX_SHIFT 799 -#define YY_MIN_SHIFTREDUCE 1180 -#define YY_MAX_SHIFTREDUCE 1779 -#define YY_ERROR_ACTION 1780 -#define YY_ACCEPT_ACTION 1781 -#define YY_NO_ACTION 1782 -#define YY_MIN_REDUCE 1783 -#define YY_MAX_REDUCE 2382 +#define YY_MAX_SHIFT 801 +#define YY_MIN_SHIFTREDUCE 1182 +#define YY_MAX_SHIFTREDUCE 1782 +#define YY_ERROR_ACTION 1783 +#define YY_ACCEPT_ACTION 1784 +#define YY_NO_ACTION 1785 +#define YY_MIN_REDUCE 1786 +#define YY_MAX_REDUCE 2386 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -220,474 +214,474 @@ typedef union { *********** Begin parsing tables **********************************************/ #define YY_ACTTAB_COUNT (2858) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 2126, 2193, 2171, 2082, 221, 690, 1960, 2154, 537, 1949, - /* 10 */ 1826, 670, 48, 46, 1706, 394, 2179, 1213, 2079, 677, - /* 20 */ 401, 2358, 1555, 41, 40, 135, 2175, 47, 45, 44, - /* 30 */ 43, 42, 574, 1636, 453, 1553, 2171, 539, 1582, 2211, - /* 40 */ 41, 40, 1781, 536, 47, 45, 44, 43, 42, 254, - /* 50 */ 1951, 2161, 1945, 706, 630, 531, 1215, 2353, 1218, 1219, - /* 60 */ 2175, 181, 1631, 529, 2177, 398, 525, 521, 19, 1238, - /* 70 */ 66, 1237, 2359, 188, 700, 1561, 30, 2354, 656, 348, - /* 80 */ 689, 369, 2065, 361, 140, 690, 1960, 2192, 1580, 2228, - /* 90 */ 667, 144, 112, 2194, 710, 2196, 2197, 705, 2177, 700, - /* 100 */ 796, 168, 1239, 15, 185, 135, 2281, 103, 700, 1901, - /* 110 */ 397, 2277, 579, 497, 2082, 416, 48, 46, 690, 1960, - /* 120 */ 415, 689, 1769, 190, 401, 264, 1555, 1665, 1371, 2080, - /* 130 */ 677, 2307, 1953, 1580, 38, 306, 1746, 1636, 193, 1553, - /* 140 */ 1638, 1639, 1806, 1362, 735, 734, 733, 1366, 732, 1368, - /* 150 */ 1369, 731, 728, 1805, 1377, 725, 1379, 1380, 722, 719, - /* 160 */ 716, 184, 630, 51, 655, 2353, 1631, 2353, 94, 62, - /* 170 */ 1611, 1621, 19, 2000, 212, 211, 1637, 1640, 675, 1561, - /* 180 */ 2359, 188, 654, 188, 1666, 2354, 656, 2354, 656, 2296, - /* 190 */ 288, 1556, 2161, 1554, 286, 2289, 666, 496, 136, 665, - /* 200 */ 169, 2353, 1795, 2161, 796, 41, 40, 15, 2193, 47, - /* 210 */ 45, 44, 43, 42, 62, 2293, 654, 188, 707, 1315, - /* 220 */ 435, 2354, 656, 1559, 1560, 1783, 1610, 1613, 1614, 1615, - /* 230 */ 1616, 1617, 1618, 1619, 1620, 702, 698, 1629, 1630, 1632, - /* 240 */ 1633, 1634, 1635, 2, 1638, 1639, 2211, 437, 433, 134, - /* 250 */ 133, 132, 131, 130, 129, 128, 127, 126, 2161, 1317, - /* 260 */ 706, 1784, 37, 399, 1660, 1661, 1662, 1663, 1664, 1668, - /* 270 */ 1669, 1670, 1671, 534, 1611, 1621, 535, 1819, 551, 1580, - /* 280 */ 1637, 1640, 125, 1464, 1465, 124, 123, 122, 121, 120, - /* 290 */ 119, 118, 117, 116, 2192, 1556, 2228, 1554, 645, 112, - /* 300 */ 2194, 710, 2196, 2197, 705, 650, 700, 2044, 395, 147, - /* 310 */ 1580, 151, 2252, 2281, 1581, 2193, 166, 397, 2277, 1238, - /* 320 */ 191, 1237, 667, 144, 1962, 670, 191, 1559, 1560, 1703, - /* 330 */ 1610, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 702, - /* 340 */ 698, 1629, 1630, 1632, 1633, 1634, 1635, 2, 12, 48, - /* 350 */ 46, 745, 1239, 2211, 2013, 410, 409, 401, 2182, 1555, - /* 360 */ 2358, 367, 62, 2353, 181, 2161, 1582, 706, 615, 2011, - /* 370 */ 1636, 191, 1553, 592, 591, 590, 690, 1960, 1562, 2357, - /* 380 */ 582, 141, 586, 2354, 2356, 2066, 585, 649, 651, 646, - /* 390 */ 639, 584, 589, 377, 376, 146, 56, 583, 2252, 1631, - /* 400 */ 252, 2192, 629, 2228, 251, 19, 112, 2194, 710, 2196, - /* 410 */ 2197, 705, 1561, 700, 2184, 2211, 297, 298, 185, 542, - /* 420 */ 2281, 296, 535, 1819, 397, 2277, 187, 2289, 2290, 2193, - /* 430 */ 142, 2294, 1221, 655, 1406, 1407, 2353, 796, 1579, 707, - /* 440 */ 15, 1828, 41, 40, 1272, 2308, 47, 45, 44, 43, - /* 450 */ 42, 654, 188, 48, 46, 1641, 2354, 656, 223, 2193, - /* 460 */ 1612, 401, 537, 1555, 1826, 93, 475, 2211, 356, 707, - /* 470 */ 648, 381, 166, 608, 1636, 474, 1553, 1638, 1639, 2161, - /* 480 */ 1963, 706, 2358, 125, 1273, 2353, 124, 123, 122, 121, - /* 490 */ 120, 119, 118, 117, 116, 2013, 62, 2211, 1804, 667, - /* 500 */ 144, 2357, 382, 1631, 12, 2354, 2355, 1611, 1621, 2161, - /* 510 */ 2011, 706, 109, 1637, 1640, 2192, 1561, 2228, 288, 191, - /* 520 */ 112, 2194, 710, 2196, 2197, 705, 60, 700, 1556, 145, - /* 530 */ 1554, 578, 2373, 627, 2281, 577, 1565, 1952, 397, 2277, - /* 540 */ 1710, 796, 690, 1960, 49, 2192, 1580, 2228, 2161, 2193, - /* 550 */ 170, 2194, 710, 2196, 2197, 705, 12, 700, 10, 707, - /* 560 */ 1559, 1560, 451, 1610, 1613, 1614, 1615, 1616, 1617, 1618, - /* 570 */ 1619, 1620, 702, 698, 1629, 1630, 1632, 1633, 1634, 1635, - /* 580 */ 2, 1638, 1639, 445, 1326, 444, 1702, 2211, 41, 40, - /* 590 */ 631, 2318, 47, 45, 44, 43, 42, 1325, 2296, 2161, - /* 600 */ 1583, 706, 669, 186, 2289, 2290, 165, 142, 2294, 1561, - /* 610 */ 1803, 1611, 1621, 690, 1960, 443, 406, 1637, 1640, 2006, - /* 620 */ 2008, 41, 40, 404, 2292, 47, 45, 44, 43, 42, - /* 630 */ 2296, 163, 1556, 452, 1554, 2192, 676, 2228, 383, 1962, - /* 640 */ 112, 2194, 710, 2196, 2197, 705, 2011, 700, 253, 689, - /* 650 */ 447, 2193, 2256, 191, 2281, 446, 2291, 2155, 397, 2277, - /* 660 */ 2161, 707, 506, 2315, 1559, 1560, 154, 1610, 1613, 1614, - /* 670 */ 1615, 1616, 1617, 1618, 1619, 1620, 702, 698, 1629, 1630, - /* 680 */ 1632, 1633, 1634, 1635, 2, 48, 46, 1937, 549, 2211, - /* 690 */ 2075, 457, 2061, 401, 755, 1555, 1612, 630, 667, 144, - /* 700 */ 2353, 2161, 2013, 706, 630, 1936, 1636, 2353, 1553, 391, - /* 710 */ 47, 45, 44, 43, 42, 2359, 188, 2011, 1526, 1527, - /* 720 */ 2354, 656, 2359, 188, 463, 2061, 55, 2354, 656, 14, - /* 730 */ 13, 1734, 51, 690, 1960, 1631, 1947, 2192, 202, 2228, - /* 740 */ 597, 676, 112, 2194, 710, 2196, 2197, 705, 1561, 700, - /* 750 */ 690, 1960, 266, 465, 2373, 607, 2281, 1862, 41, 40, - /* 760 */ 397, 2277, 47, 45, 44, 43, 42, 2193, 1802, 250, - /* 770 */ 480, 205, 745, 796, 690, 1960, 49, 704, 642, 641, - /* 780 */ 1732, 1733, 1735, 1736, 1737, 600, 490, 2061, 2357, 48, - /* 790 */ 46, 1935, 594, 674, 481, 2075, 1776, 401, 249, 1555, - /* 800 */ 404, 1581, 189, 2289, 2290, 2211, 142, 2294, 166, 692, - /* 810 */ 1636, 2253, 1553, 1638, 1639, 1846, 1962, 2161, 2161, 706, - /* 820 */ 743, 156, 155, 740, 739, 738, 153, 592, 591, 590, - /* 830 */ 2007, 2008, 1679, 210, 582, 141, 586, 593, 70, 1631, - /* 840 */ 585, 69, 52, 1611, 1621, 584, 589, 377, 376, 1637, - /* 850 */ 1640, 583, 1561, 2192, 1745, 2228, 1241, 1242, 342, 2194, - /* 860 */ 710, 2196, 2197, 705, 1556, 700, 1554, 2247, 41, 40, - /* 870 */ 1801, 1943, 47, 45, 44, 43, 42, 796, 570, 569, - /* 880 */ 15, 2193, 743, 156, 155, 740, 739, 738, 153, 1800, - /* 890 */ 613, 707, 207, 2328, 1799, 1964, 1559, 1560, 1775, 1610, - /* 900 */ 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 702, 698, - /* 910 */ 1629, 1630, 1632, 1633, 1634, 1635, 2, 1638, 1639, 2211, - /* 920 */ 2161, 1481, 1482, 606, 743, 156, 155, 740, 739, 738, - /* 930 */ 153, 2161, 86, 706, 2013, 85, 604, 630, 602, 2161, - /* 940 */ 2353, 396, 690, 1960, 2161, 690, 1960, 1611, 1621, 2011, - /* 950 */ 736, 690, 1960, 1637, 1640, 2359, 188, 1480, 1483, 259, - /* 960 */ 2354, 656, 550, 737, 1722, 1957, 2004, 2192, 1556, 2228, - /* 970 */ 1554, 255, 112, 2194, 710, 2196, 2197, 705, 9, 700, - /* 980 */ 588, 587, 34, 2147, 2373, 1330, 2281, 676, 41, 40, - /* 990 */ 397, 2277, 47, 45, 44, 43, 42, 1798, 1329, 191, - /* 1000 */ 1559, 1560, 1859, 1610, 1613, 1614, 1615, 1616, 1617, 1618, - /* 1010 */ 1619, 1620, 702, 698, 1629, 1630, 1632, 1633, 1634, 1635, - /* 1020 */ 2, 1646, 352, 167, 1578, 690, 1960, 1580, 327, 690, - /* 1030 */ 1960, 488, 423, 90, 504, 572, 571, 503, 2171, 685, - /* 1040 */ 407, 2075, 324, 73, 2144, 263, 72, 2161, 166, 673, - /* 1050 */ 371, 2013, 2180, 471, 671, 505, 1962, 349, 405, 1955, - /* 1060 */ 473, 701, 2175, 508, 1797, 658, 2011, 1794, 219, 516, - /* 1070 */ 514, 511, 773, 772, 771, 770, 413, 1938, 769, 768, - /* 1080 */ 148, 763, 762, 761, 760, 759, 758, 757, 158, 753, - /* 1090 */ 752, 751, 412, 411, 748, 747, 746, 176, 175, 1583, - /* 1100 */ 2177, 630, 690, 1960, 2353, 1583, 370, 237, 62, 374, - /* 1110 */ 700, 44, 43, 42, 2161, 690, 1960, 2161, 459, 2359, - /* 1120 */ 188, 149, 301, 173, 2354, 656, 690, 1960, 262, 690, - /* 1130 */ 1960, 568, 564, 560, 556, 687, 236, 1793, 662, 694, - /* 1140 */ 1667, 2253, 767, 765, 1792, 1791, 688, 111, 501, 307, - /* 1150 */ 1790, 495, 494, 493, 492, 487, 486, 485, 484, 483, - /* 1160 */ 479, 478, 477, 476, 351, 468, 467, 466, 659, 461, - /* 1170 */ 460, 368, 690, 1960, 2301, 1699, 91, 1612, 375, 234, - /* 1180 */ 373, 372, 1837, 576, 90, 1789, 1788, 2161, 81, 80, - /* 1190 */ 450, 2193, 408, 200, 2161, 2161, 1787, 2013, 1699, 741, - /* 1200 */ 2161, 707, 2004, 637, 595, 578, 442, 440, 1786, 577, - /* 1210 */ 1956, 742, 2012, 320, 2004, 1902, 1990, 350, 35, 54, - /* 1220 */ 431, 3, 2193, 429, 425, 421, 418, 443, 1672, 2211, - /* 1230 */ 756, 454, 707, 1922, 2346, 2161, 2161, 1218, 1219, 154, - /* 1240 */ 83, 2161, 137, 706, 455, 74, 2161, 233, 227, 580, - /* 1250 */ 242, 203, 2193, 240, 232, 547, 244, 265, 2161, 243, - /* 1260 */ 2211, 430, 707, 246, 2300, 191, 245, 248, 154, 581, - /* 1270 */ 247, 1313, 2161, 225, 706, 1835, 50, 2192, 610, 2228, - /* 1280 */ 609, 50, 112, 2194, 710, 2196, 2197, 705, 697, 700, - /* 1290 */ 2211, 1311, 1778, 1779, 2373, 84, 2281, 598, 1796, 1521, - /* 1300 */ 397, 2277, 2161, 643, 706, 1564, 270, 154, 2192, 108, - /* 1310 */ 2228, 2321, 283, 112, 2194, 710, 2196, 2197, 705, 105, - /* 1320 */ 700, 50, 294, 1563, 1555, 2373, 71, 2281, 1524, 152, - /* 1330 */ 154, 397, 2277, 14, 13, 64, 1731, 1553, 2192, 50, - /* 1340 */ 2228, 1730, 2193, 112, 2194, 710, 2196, 2197, 705, 50, - /* 1350 */ 700, 1829, 707, 410, 409, 2373, 277, 2281, 36, 714, - /* 1360 */ 139, 397, 2277, 1569, 41, 40, 272, 672, 47, 45, - /* 1370 */ 44, 43, 42, 2193, 1636, 1900, 1562, 1561, 663, 152, - /* 1380 */ 2211, 1478, 299, 707, 154, 749, 682, 1899, 2212, 303, - /* 1390 */ 1356, 750, 2161, 138, 706, 1673, 384, 152, 2070, 1622, - /* 1400 */ 414, 791, 796, 1631, 1820, 1825, 660, 1291, 2001, 319, - /* 1410 */ 2193, 2211, 2311, 1289, 668, 285, 1561, 282, 422, 1384, - /* 1420 */ 707, 1, 417, 2161, 5, 706, 365, 1586, 2192, 438, - /* 1430 */ 2228, 1502, 196, 112, 2194, 710, 2196, 2197, 705, 1388, - /* 1440 */ 700, 696, 439, 1657, 1395, 2254, 441, 2281, 2211, 195, - /* 1450 */ 198, 397, 2277, 1393, 314, 1579, 456, 157, 209, 2192, - /* 1460 */ 2161, 2228, 706, 1567, 112, 2194, 710, 2196, 2197, 705, - /* 1470 */ 1583, 700, 462, 458, 469, 499, 693, 2071, 2281, 464, - /* 1480 */ 1578, 1566, 397, 2277, 482, 491, 489, 2063, 498, 500, - /* 1490 */ 509, 510, 507, 1556, 213, 1554, 2192, 214, 2228, 2193, - /* 1500 */ 512, 113, 2194, 710, 2196, 2197, 705, 513, 700, 707, - /* 1510 */ 1584, 216, 532, 515, 517, 2281, 4, 533, 540, 2280, - /* 1520 */ 2277, 541, 543, 1581, 224, 1559, 1560, 226, 1585, 544, - /* 1530 */ 545, 1587, 1570, 546, 1565, 229, 548, 2211, 231, 88, - /* 1540 */ 89, 552, 235, 573, 355, 575, 1950, 114, 2193, 2161, - /* 1550 */ 239, 706, 1946, 612, 614, 92, 150, 618, 707, 315, - /* 1560 */ 256, 619, 617, 2135, 1573, 1575, 241, 159, 160, 1948, - /* 1570 */ 258, 260, 1944, 161, 2193, 162, 2132, 698, 1629, 1630, - /* 1580 */ 1632, 1633, 1634, 1635, 704, 2192, 2211, 2228, 625, 1509, - /* 1590 */ 113, 2194, 710, 2196, 2197, 705, 2131, 700, 2161, 644, - /* 1600 */ 706, 622, 634, 8, 2281, 2312, 2327, 680, 695, 2277, - /* 1610 */ 640, 2322, 2211, 387, 624, 2326, 647, 623, 268, 271, - /* 1620 */ 2303, 653, 276, 635, 2161, 2193, 706, 632, 633, 281, - /* 1630 */ 2376, 388, 1699, 661, 708, 707, 2228, 664, 2193, 113, - /* 1640 */ 2194, 710, 2196, 2197, 705, 143, 700, 1582, 707, 289, - /* 1650 */ 178, 1588, 278, 2281, 2076, 316, 98, 360, 2277, 2297, - /* 1660 */ 2192, 317, 2228, 2211, 678, 342, 2194, 710, 2196, 2197, - /* 1670 */ 705, 703, 700, 691, 2246, 2161, 2211, 706, 679, 683, - /* 1680 */ 2090, 279, 174, 684, 2089, 280, 100, 2193, 2161, 318, - /* 1690 */ 706, 2088, 393, 102, 61, 2262, 104, 707, 2352, 1961, - /* 1700 */ 712, 2005, 1923, 792, 2193, 284, 793, 321, 795, 2153, - /* 1710 */ 357, 2192, 310, 2228, 707, 358, 171, 2194, 710, 2196, - /* 1720 */ 2197, 705, 53, 700, 2192, 2211, 2228, 325, 323, 113, - /* 1730 */ 2194, 710, 2196, 2197, 705, 345, 700, 2161, 2152, 706, - /* 1740 */ 330, 344, 2211, 2281, 334, 2151, 78, 385, 2278, 2148, - /* 1750 */ 419, 420, 1546, 2193, 2161, 1547, 706, 194, 424, 2146, - /* 1760 */ 426, 427, 428, 707, 2145, 366, 2143, 657, 2374, 432, - /* 1770 */ 2142, 2141, 434, 2192, 436, 2228, 1537, 2193, 170, 2194, - /* 1780 */ 710, 2196, 2197, 705, 2122, 700, 197, 707, 2121, 199, - /* 1790 */ 2192, 2211, 2228, 1505, 79, 343, 2194, 710, 2196, 2197, - /* 1800 */ 705, 1504, 700, 2161, 2193, 706, 2103, 2102, 2101, 448, - /* 1810 */ 449, 2100, 2099, 2054, 707, 2211, 1455, 2053, 2050, 2319, - /* 1820 */ 386, 201, 2049, 82, 2193, 2048, 2047, 2161, 2052, 706, - /* 1830 */ 204, 2051, 2046, 2045, 707, 2043, 2042, 2041, 206, 2192, - /* 1840 */ 470, 2228, 2211, 2040, 336, 2194, 710, 2196, 2197, 705, - /* 1850 */ 472, 700, 2056, 2039, 2161, 2038, 706, 2037, 2036, 2035, - /* 1860 */ 2034, 2033, 2211, 2192, 2032, 2228, 2031, 392, 343, 2194, - /* 1870 */ 710, 2196, 2197, 705, 2161, 700, 706, 208, 2024, 2023, - /* 1880 */ 87, 2022, 2021, 2055, 2020, 2019, 215, 652, 2030, 2029, - /* 1890 */ 2192, 2193, 2228, 2028, 2027, 171, 2194, 710, 2196, 2197, - /* 1900 */ 705, 707, 700, 2026, 2025, 2018, 2017, 2016, 1457, 2015, - /* 1910 */ 2192, 502, 2228, 2014, 1327, 343, 2194, 710, 2196, 2197, - /* 1920 */ 705, 2193, 700, 353, 354, 1865, 1323, 1864, 1863, 2211, - /* 1930 */ 1331, 707, 217, 218, 400, 1861, 1858, 520, 1857, 519, - /* 1940 */ 524, 2161, 1850, 706, 523, 518, 522, 2375, 527, 526, - /* 1950 */ 1839, 528, 530, 1815, 1220, 76, 1814, 220, 2120, 2211, - /* 1960 */ 2110, 77, 182, 222, 402, 2098, 2181, 183, 538, 228, - /* 1970 */ 2097, 2161, 230, 706, 553, 554, 555, 2192, 2074, 2228, - /* 1980 */ 2193, 1939, 343, 2194, 710, 2196, 2197, 705, 616, 700, - /* 1990 */ 707, 1860, 1856, 1265, 1854, 558, 557, 1852, 559, 561, - /* 2000 */ 562, 563, 1849, 565, 566, 567, 799, 2192, 1834, 2228, - /* 2010 */ 1832, 1833, 343, 2194, 710, 2196, 2197, 705, 2211, 700, - /* 2020 */ 313, 1831, 1811, 1941, 1940, 1400, 1399, 764, 1314, 766, - /* 2030 */ 2161, 1312, 706, 1310, 1309, 1308, 180, 1847, 1307, 1301, - /* 2040 */ 1306, 63, 238, 1838, 789, 785, 781, 777, 1303, 311, - /* 2050 */ 1302, 1300, 378, 2193, 379, 1836, 380, 596, 1810, 1809, - /* 2060 */ 599, 601, 603, 707, 1808, 2119, 611, 605, 2228, 115, - /* 2070 */ 1531, 338, 2194, 710, 2196, 2197, 705, 1533, 700, 1530, - /* 2080 */ 1535, 1511, 29, 67, 2193, 1515, 2109, 2096, 1513, 110, - /* 2090 */ 164, 2211, 304, 620, 707, 2095, 2358, 20, 17, 1748, - /* 2100 */ 6, 21, 65, 2161, 31, 706, 57, 261, 7, 626, - /* 2110 */ 275, 638, 267, 621, 22, 1490, 1489, 274, 269, 2193, - /* 2120 */ 636, 172, 2211, 628, 1729, 686, 2182, 33, 24, 707, - /* 2130 */ 58, 273, 32, 23, 2161, 1721, 706, 1768, 18, 2192, - /* 2140 */ 1769, 2228, 95, 1763, 328, 2194, 710, 2196, 2197, 705, - /* 2150 */ 1762, 700, 389, 1767, 1766, 390, 2193, 2211, 287, 177, - /* 2160 */ 291, 2094, 2073, 292, 97, 1696, 707, 290, 59, 2161, - /* 2170 */ 2192, 706, 2228, 1695, 2072, 326, 2194, 710, 2196, 2197, - /* 2180 */ 705, 2193, 700, 96, 25, 295, 257, 99, 105, 293, - /* 2190 */ 305, 707, 1727, 300, 2211, 68, 26, 101, 1648, 11, - /* 2200 */ 13, 1647, 1571, 179, 2231, 2192, 2161, 2228, 706, 1658, - /* 2210 */ 329, 2194, 710, 2196, 2197, 705, 681, 700, 2193, 2211, - /* 2220 */ 302, 1603, 192, 711, 713, 1626, 1624, 403, 707, 699, - /* 2230 */ 39, 2161, 1623, 706, 16, 27, 717, 1595, 28, 720, - /* 2240 */ 1385, 715, 2192, 2193, 2228, 1382, 1381, 335, 2194, 710, - /* 2250 */ 2196, 2197, 705, 707, 700, 1378, 2211, 718, 721, 723, - /* 2260 */ 724, 726, 1372, 709, 1370, 729, 727, 2192, 2161, 2228, - /* 2270 */ 706, 730, 339, 2194, 710, 2196, 2197, 705, 1376, 700, - /* 2280 */ 106, 2211, 308, 1394, 1375, 1390, 107, 75, 1263, 1374, - /* 2290 */ 1373, 744, 1295, 2161, 1294, 706, 1293, 1292, 309, 1290, - /* 2300 */ 1288, 1287, 1286, 1321, 2192, 754, 2228, 1284, 1283, 331, - /* 2310 */ 2194, 710, 2196, 2197, 705, 2193, 700, 1282, 1281, 1280, - /* 2320 */ 1279, 1278, 1318, 1316, 1275, 707, 1274, 1271, 1270, 2192, - /* 2330 */ 2193, 2228, 1269, 1268, 340, 2194, 710, 2196, 2197, 705, - /* 2340 */ 707, 700, 1855, 774, 775, 776, 1853, 778, 2193, 779, - /* 2350 */ 1851, 782, 780, 2211, 783, 1848, 784, 786, 707, 788, - /* 2360 */ 1830, 790, 1210, 787, 1807, 2161, 312, 706, 2211, 794, - /* 2370 */ 1782, 1557, 798, 322, 797, 1782, 1782, 1782, 1782, 1782, - /* 2380 */ 2161, 1782, 706, 1782, 1782, 1782, 2211, 1782, 1782, 1782, - /* 2390 */ 1782, 1782, 1782, 1782, 1782, 2193, 1782, 1782, 2161, 1782, - /* 2400 */ 706, 2192, 1782, 2228, 1782, 707, 332, 2194, 710, 2196, - /* 2410 */ 2197, 705, 1782, 700, 1782, 1782, 2192, 2193, 2228, 1782, - /* 2420 */ 1782, 341, 2194, 710, 2196, 2197, 705, 707, 700, 1782, - /* 2430 */ 1782, 1782, 1782, 2211, 2192, 1782, 2228, 1782, 1782, 333, - /* 2440 */ 2194, 710, 2196, 2197, 705, 2161, 700, 706, 1782, 1782, - /* 2450 */ 1782, 1782, 1782, 1782, 1782, 2211, 1782, 1782, 1782, 1782, - /* 2460 */ 1782, 1782, 1782, 1782, 2193, 1782, 1782, 2161, 1782, 706, - /* 2470 */ 1782, 1782, 1782, 1782, 707, 1782, 1782, 1782, 1782, 1782, - /* 2480 */ 1782, 2192, 1782, 2228, 1782, 1782, 346, 2194, 710, 2196, - /* 2490 */ 2197, 705, 1782, 700, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2500 */ 1782, 1782, 2211, 2192, 1782, 2228, 1782, 1782, 347, 2194, - /* 2510 */ 710, 2196, 2197, 705, 2161, 700, 706, 1782, 1782, 1782, - /* 2520 */ 1782, 1782, 1782, 2193, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2530 */ 1782, 1782, 1782, 707, 1782, 1782, 2193, 1782, 1782, 1782, - /* 2540 */ 1782, 1782, 1782, 1782, 1782, 1782, 707, 1782, 1782, 1782, - /* 2550 */ 2192, 1782, 2228, 2193, 1782, 2205, 2194, 710, 2196, 2197, - /* 2560 */ 705, 2211, 700, 707, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2570 */ 1782, 1782, 1782, 2161, 2211, 706, 1782, 1782, 1782, 1782, - /* 2580 */ 1782, 1782, 1782, 1782, 1782, 2193, 2161, 1782, 706, 1782, - /* 2590 */ 1782, 2211, 1782, 1782, 1782, 707, 1782, 1782, 1782, 1782, - /* 2600 */ 1782, 1782, 1782, 2161, 1782, 706, 1782, 1782, 1782, 2192, - /* 2610 */ 1782, 2228, 1782, 1782, 2204, 2194, 710, 2196, 2197, 705, - /* 2620 */ 1782, 700, 2192, 2211, 2228, 1782, 1782, 2203, 2194, 710, - /* 2630 */ 2196, 2197, 705, 1782, 700, 2161, 1782, 706, 1782, 2192, - /* 2640 */ 1782, 2228, 1782, 1782, 362, 2194, 710, 2196, 2197, 705, - /* 2650 */ 1782, 700, 2193, 1782, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2660 */ 1782, 1782, 707, 1782, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2670 */ 1782, 2192, 2193, 2228, 1782, 1782, 363, 2194, 710, 2196, - /* 2680 */ 2197, 705, 707, 700, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2690 */ 2211, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2700 */ 1782, 1782, 2161, 1782, 706, 1782, 1782, 1782, 1782, 1782, - /* 2710 */ 2211, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2720 */ 1782, 1782, 2161, 1782, 706, 1782, 1782, 1782, 1782, 1782, - /* 2730 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 2192, 1782, - /* 2740 */ 2228, 1782, 2193, 359, 2194, 710, 2196, 2197, 705, 1782, - /* 2750 */ 700, 1782, 707, 1782, 1782, 1782, 1782, 1782, 2192, 2193, - /* 2760 */ 2228, 1782, 1782, 364, 2194, 710, 2196, 2197, 705, 707, - /* 2770 */ 700, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2780 */ 2211, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2790 */ 1782, 1782, 2161, 1782, 706, 1782, 1782, 2211, 1782, 1782, - /* 2800 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 2161, - /* 2810 */ 1782, 706, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, - /* 2820 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 708, 1782, - /* 2830 */ 2228, 1782, 1782, 338, 2194, 710, 2196, 2197, 705, 1782, - /* 2840 */ 700, 1782, 1782, 1782, 1782, 2192, 1782, 2228, 1782, 1782, - /* 2850 */ 337, 2194, 710, 2196, 2197, 705, 1782, 700, + /* 0 */ 1952, 2197, 2175, 2086, 221, 690, 1963, 2158, 537, 184, + /* 10 */ 1829, 670, 48, 46, 1709, 394, 2183, 1215, 2083, 677, + /* 20 */ 401, 2004, 1558, 41, 40, 135, 2179, 47, 45, 44, + /* 30 */ 43, 42, 574, 1639, 453, 1556, 2175, 539, 689, 2215, + /* 40 */ 41, 40, 1784, 536, 47, 45, 44, 43, 42, 689, + /* 50 */ 1954, 2165, 1948, 706, 630, 531, 1217, 2357, 1220, 1221, + /* 60 */ 2179, 181, 1634, 529, 2181, 398, 525, 521, 19, 1240, + /* 70 */ 66, 1239, 2363, 188, 700, 1564, 30, 2358, 656, 348, + /* 80 */ 168, 369, 2069, 361, 140, 690, 1963, 2196, 1904, 2232, + /* 90 */ 667, 144, 112, 2198, 710, 2200, 2201, 705, 2181, 700, + /* 100 */ 798, 1939, 1241, 15, 185, 135, 2285, 169, 700, 1798, + /* 110 */ 397, 2281, 579, 1583, 2086, 416, 48, 46, 2017, 2362, + /* 120 */ 415, 51, 2357, 190, 401, 382, 1558, 1668, 1374, 2084, + /* 130 */ 677, 2311, 51, 2015, 690, 1963, 1749, 1639, 2361, 1556, + /* 140 */ 1641, 1642, 2358, 2360, 1365, 735, 734, 733, 1369, 732, + /* 150 */ 1371, 1372, 731, 728, 193, 1380, 725, 1382, 1383, 722, + /* 160 */ 719, 716, 630, 1584, 655, 2357, 1634, 2357, 747, 62, + /* 170 */ 1614, 1624, 19, 457, 2065, 109, 1640, 1643, 689, 1564, + /* 180 */ 2363, 188, 654, 188, 1669, 2358, 656, 2358, 656, 38, + /* 190 */ 306, 1559, 145, 1557, 286, 2293, 666, 2362, 136, 665, + /* 200 */ 1955, 2357, 14, 13, 798, 41, 40, 15, 2197, 47, + /* 210 */ 45, 44, 43, 42, 1585, 675, 654, 188, 707, 1317, + /* 220 */ 202, 2358, 656, 1562, 1563, 1786, 1613, 1616, 1617, 1618, + /* 230 */ 1619, 1620, 1621, 1622, 1623, 702, 698, 1632, 1633, 1635, + /* 240 */ 1636, 1637, 1638, 2, 1641, 1642, 2215, 2011, 2012, 134, + /* 250 */ 133, 132, 131, 130, 129, 128, 127, 126, 2165, 1319, + /* 260 */ 706, 1787, 37, 399, 1663, 1664, 1665, 1666, 1667, 1671, + /* 270 */ 1672, 1673, 1674, 534, 1614, 1624, 535, 1822, 191, 1583, + /* 280 */ 1640, 1643, 125, 1484, 1485, 124, 123, 122, 121, 120, + /* 290 */ 119, 118, 117, 116, 2196, 1559, 2232, 1557, 1772, 112, + /* 300 */ 2198, 710, 2200, 2201, 705, 1682, 700, 2048, 395, 147, + /* 310 */ 551, 151, 2256, 2285, 1584, 2197, 166, 397, 2281, 1483, + /* 320 */ 1486, 1809, 667, 144, 1965, 670, 191, 1562, 1563, 650, + /* 330 */ 1613, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 702, + /* 340 */ 698, 1632, 1633, 1635, 1636, 1637, 1638, 2, 12, 48, + /* 350 */ 46, 1583, 1808, 2215, 2017, 410, 409, 401, 108, 1558, + /* 360 */ 2362, 367, 62, 2357, 2300, 2165, 288, 706, 105, 2015, + /* 370 */ 1639, 2165, 1556, 592, 591, 590, 690, 1963, 1565, 2361, + /* 380 */ 582, 141, 586, 2358, 2359, 542, 585, 649, 535, 1822, + /* 390 */ 2297, 584, 589, 377, 376, 2130, 56, 583, 615, 1634, + /* 400 */ 252, 2196, 2165, 2232, 251, 19, 112, 2198, 710, 2200, + /* 410 */ 2201, 705, 1564, 700, 253, 2215, 297, 298, 185, 406, + /* 420 */ 2285, 296, 2010, 2012, 397, 2281, 187, 2293, 2294, 2197, + /* 430 */ 142, 2298, 1807, 655, 1409, 1410, 2357, 798, 578, 707, + /* 440 */ 15, 1831, 41, 40, 254, 2312, 47, 45, 44, 43, + /* 450 */ 42, 654, 188, 48, 46, 1644, 2358, 656, 223, 2197, + /* 460 */ 577, 401, 537, 1558, 1829, 93, 475, 2215, 356, 707, + /* 470 */ 648, 381, 2300, 608, 1639, 474, 1556, 1641, 1642, 2165, + /* 480 */ 103, 706, 2165, 125, 1529, 1530, 124, 123, 122, 121, + /* 490 */ 120, 119, 118, 117, 116, 12, 62, 2215, 2296, 667, + /* 500 */ 144, 1467, 1468, 1634, 676, 1956, 1713, 1614, 1624, 2165, + /* 510 */ 404, 706, 1583, 1640, 1643, 2196, 1564, 2232, 166, 191, + /* 520 */ 112, 2198, 710, 2200, 2201, 705, 1965, 700, 1559, 1564, + /* 530 */ 1557, 62, 2377, 606, 2285, 12, 1568, 10, 397, 2281, + /* 540 */ 747, 798, 690, 1963, 49, 2196, 604, 2232, 602, 2197, + /* 550 */ 170, 2198, 710, 2200, 2201, 705, 549, 700, 2079, 707, + /* 560 */ 1562, 1563, 451, 1613, 1616, 1617, 1618, 1619, 1620, 1621, + /* 570 */ 1622, 1623, 702, 698, 1632, 1633, 1635, 1636, 1637, 1638, + /* 580 */ 2, 1641, 1642, 445, 1585, 444, 1806, 2215, 41, 40, + /* 590 */ 631, 2322, 47, 45, 44, 43, 42, 738, 1805, 2165, + /* 600 */ 1586, 706, 669, 186, 2293, 2294, 165, 142, 2298, 2017, + /* 610 */ 1832, 1614, 1624, 690, 1963, 443, 391, 1640, 1643, 463, + /* 620 */ 2065, 41, 40, 404, 2015, 47, 45, 44, 43, 42, + /* 630 */ 2300, 163, 1559, 452, 1557, 2196, 2165, 2232, 383, 1965, + /* 640 */ 112, 2198, 710, 2200, 2201, 705, 2015, 700, 2165, 2186, + /* 650 */ 447, 2197, 2260, 191, 2285, 446, 2295, 2159, 397, 2281, + /* 660 */ 793, 707, 1615, 2319, 1562, 1563, 205, 1613, 1616, 1617, + /* 670 */ 1618, 1619, 1620, 1621, 1622, 1623, 702, 698, 1632, 1633, + /* 680 */ 1635, 1636, 1637, 1638, 2, 48, 46, 1940, 191, 2215, + /* 690 */ 745, 490, 2065, 401, 757, 1558, 645, 630, 690, 1963, + /* 700 */ 2357, 2165, 435, 706, 630, 2188, 1639, 2357, 1556, 156, + /* 710 */ 155, 742, 741, 740, 153, 2363, 188, 692, 465, 2257, + /* 720 */ 2358, 656, 2363, 188, 44, 43, 42, 2358, 656, 437, + /* 730 */ 433, 1737, 497, 690, 1963, 1634, 288, 2196, 210, 2232, + /* 740 */ 597, 1950, 112, 2198, 710, 2200, 2201, 705, 1564, 700, + /* 750 */ 690, 1963, 266, 480, 2377, 607, 2285, 1865, 41, 40, + /* 760 */ 397, 2281, 47, 45, 44, 43, 42, 2197, 1649, 250, + /* 770 */ 481, 690, 1963, 798, 1583, 207, 49, 704, 642, 641, + /* 780 */ 1735, 1736, 1738, 1739, 1740, 600, 651, 646, 639, 48, + /* 790 */ 46, 550, 594, 212, 211, 407, 1779, 401, 249, 1558, + /* 800 */ 690, 1963, 745, 166, 52, 2215, 1938, 1804, 570, 569, + /* 810 */ 1639, 1965, 1556, 1641, 1642, 86, 496, 2165, 85, 706, + /* 820 */ 1960, 156, 155, 742, 741, 740, 153, 592, 591, 590, + /* 830 */ 667, 144, 629, 262, 582, 141, 586, 1583, 70, 1634, + /* 840 */ 585, 69, 1905, 1614, 1624, 584, 589, 377, 376, 1640, + /* 850 */ 1643, 583, 1564, 2196, 1748, 2232, 1946, 2165, 342, 2198, + /* 860 */ 710, 2200, 2201, 705, 1559, 700, 1557, 2251, 41, 40, + /* 870 */ 690, 1963, 47, 45, 44, 43, 42, 798, 1803, 737, + /* 880 */ 15, 2197, 47, 45, 44, 43, 42, 1243, 1244, 1223, + /* 890 */ 255, 707, 1240, 2332, 1239, 1582, 1562, 1563, 1778, 1613, + /* 900 */ 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 702, 698, + /* 910 */ 1632, 1633, 1635, 1636, 1637, 1638, 2, 1641, 1642, 2215, + /* 920 */ 90, 745, 572, 571, 1615, 1241, 676, 2361, 2165, 690, + /* 930 */ 1963, 2165, 259, 706, 189, 2293, 2294, 371, 142, 2298, + /* 940 */ 156, 155, 742, 741, 740, 153, 1958, 1614, 1624, 263, + /* 950 */ 701, 690, 1963, 1640, 1643, 2325, 60, 588, 587, 1706, + /* 960 */ 181, 191, 1670, 627, 1725, 690, 1963, 2196, 1559, 2232, + /* 970 */ 1557, 673, 112, 2198, 710, 2200, 2201, 705, 674, 700, + /* 980 */ 2079, 2070, 34, 1802, 2377, 301, 2285, 1615, 41, 40, + /* 990 */ 397, 2281, 47, 45, 44, 43, 42, 676, 769, 767, + /* 1000 */ 1562, 1563, 1862, 1613, 1616, 1617, 1618, 1619, 1620, 1621, + /* 1010 */ 1622, 1623, 702, 698, 1632, 1633, 1635, 1636, 1637, 1638, + /* 1020 */ 2, 2148, 352, 167, 1581, 690, 1963, 1801, 327, 9, + /* 1030 */ 694, 488, 2257, 2165, 504, 90, 146, 503, 2175, 2256, + /* 1040 */ 35, 739, 324, 73, 2008, 687, 72, 690, 1963, 685, + /* 1050 */ 1675, 2079, 2184, 471, 613, 505, 166, 349, 1586, 1586, + /* 1060 */ 473, 1959, 2179, 1800, 1966, 1797, 1796, 688, 219, 516, + /* 1070 */ 514, 511, 775, 774, 773, 772, 413, 2165, 771, 770, + /* 1080 */ 148, 765, 764, 763, 762, 761, 760, 759, 158, 755, + /* 1090 */ 754, 753, 412, 411, 750, 749, 748, 176, 175, 1328, + /* 1100 */ 2181, 630, 690, 1963, 2357, 580, 370, 237, 62, 374, + /* 1110 */ 700, 2017, 1327, 2165, 2017, 2165, 2165, 1332, 459, 2363, + /* 1120 */ 188, 396, 307, 173, 2358, 656, 2016, 1315, 2017, 2015, + /* 1130 */ 1331, 568, 564, 560, 556, 405, 236, 320, 758, 743, + /* 1140 */ 1994, 1925, 2008, 2015, 1795, 662, 1794, 111, 501, 1793, + /* 1150 */ 659, 495, 494, 493, 492, 487, 486, 485, 484, 483, + /* 1160 */ 479, 478, 477, 476, 351, 468, 467, 466, 1792, 461, + /* 1170 */ 460, 368, 690, 1963, 1220, 1221, 91, 506, 375, 234, + /* 1180 */ 373, 372, 54, 576, 3, 1791, 1790, 578, 81, 80, + /* 1190 */ 450, 2197, 408, 200, 2165, 508, 2165, 2305, 1702, 2165, + /* 1200 */ 1789, 707, 744, 637, 658, 2008, 442, 440, 2151, 577, + /* 1210 */ 203, 265, 83, 74, 137, 154, 1705, 350, 2165, 610, + /* 1220 */ 431, 609, 2197, 429, 425, 421, 418, 443, 154, 2215, + /* 1230 */ 242, 454, 707, 240, 2350, 2165, 2165, 1941, 430, 244, + /* 1240 */ 697, 2165, 243, 706, 455, 581, 1849, 233, 227, 1702, + /* 1250 */ 2165, 1799, 2197, 1274, 232, 547, 246, 423, 1840, 245, + /* 1260 */ 2215, 154, 707, 84, 2304, 191, 248, 1313, 593, 247, + /* 1270 */ 1838, 1567, 2165, 225, 706, 55, 264, 2196, 643, 2232, + /* 1280 */ 595, 149, 112, 2198, 710, 2200, 2201, 705, 1524, 700, + /* 1290 */ 2215, 50, 598, 1275, 2377, 1566, 2285, 1781, 1782, 50, + /* 1300 */ 397, 2281, 2165, 283, 706, 139, 270, 154, 2196, 277, + /* 1310 */ 2232, 1903, 1902, 112, 2198, 710, 2200, 2201, 705, 94, + /* 1320 */ 700, 1527, 50, 384, 1558, 2377, 294, 2285, 2216, 71, + /* 1330 */ 152, 397, 2281, 154, 14, 13, 64, 1556, 2196, 50, + /* 1340 */ 2232, 414, 2197, 112, 2198, 710, 2200, 2201, 705, 50, + /* 1350 */ 700, 1734, 707, 410, 409, 2377, 751, 2285, 36, 1733, + /* 1360 */ 2074, 397, 2281, 1572, 41, 40, 272, 672, 47, 45, + /* 1370 */ 44, 43, 42, 2197, 1639, 1823, 1565, 1564, 1293, 714, + /* 1380 */ 2215, 1828, 1481, 707, 152, 663, 299, 2005, 660, 682, + /* 1390 */ 303, 752, 2165, 1358, 706, 1660, 1676, 154, 138, 1625, + /* 1400 */ 2315, 668, 798, 1634, 285, 282, 5, 417, 1, 319, + /* 1410 */ 2197, 2215, 152, 1291, 422, 1589, 1564, 365, 438, 439, + /* 1420 */ 707, 196, 195, 2165, 441, 706, 198, 1505, 2196, 1570, + /* 1430 */ 2232, 314, 456, 112, 2198, 710, 2200, 2201, 705, 1387, + /* 1440 */ 700, 696, 1582, 209, 1391, 2258, 458, 2285, 2215, 1586, + /* 1450 */ 2075, 397, 2281, 1569, 462, 464, 499, 1398, 1396, 2196, + /* 1460 */ 2165, 2232, 706, 1581, 112, 2198, 710, 2200, 2201, 705, + /* 1470 */ 482, 700, 157, 489, 469, 2067, 693, 491, 2285, 498, + /* 1480 */ 500, 509, 397, 2281, 510, 507, 213, 214, 512, 513, + /* 1490 */ 1587, 671, 216, 1559, 532, 1557, 2196, 515, 2232, 2197, + /* 1500 */ 517, 113, 2198, 710, 2200, 2201, 705, 4, 700, 707, + /* 1510 */ 533, 540, 541, 224, 543, 2285, 1584, 1588, 545, 2284, + /* 1520 */ 2281, 226, 1590, 544, 546, 1562, 1563, 548, 229, 552, + /* 1530 */ 573, 575, 1573, 231, 1568, 88, 89, 2215, 630, 235, + /* 1540 */ 1953, 2357, 355, 239, 114, 92, 1949, 2139, 2197, 2165, + /* 1550 */ 150, 706, 241, 256, 612, 618, 2363, 188, 707, 614, + /* 1560 */ 159, 2358, 656, 619, 1576, 1578, 315, 160, 1951, 1947, + /* 1570 */ 161, 162, 617, 2136, 2197, 625, 2135, 698, 1632, 1633, + /* 1580 */ 1635, 1636, 1637, 1638, 704, 2196, 2215, 2232, 622, 1512, + /* 1590 */ 113, 2198, 710, 2200, 2201, 705, 260, 700, 2165, 644, + /* 1600 */ 706, 2316, 258, 2326, 2285, 2331, 634, 680, 695, 2281, + /* 1610 */ 624, 623, 2215, 640, 387, 2330, 268, 271, 647, 8, + /* 1620 */ 653, 2380, 174, 2307, 2165, 2197, 706, 635, 633, 276, + /* 1630 */ 632, 281, 664, 388, 708, 707, 2232, 1585, 2197, 113, + /* 1640 */ 2198, 710, 2200, 2201, 705, 661, 700, 1702, 707, 143, + /* 1650 */ 289, 2301, 278, 2285, 1591, 178, 98, 360, 2281, 316, + /* 1660 */ 2196, 280, 2232, 2215, 678, 342, 2198, 710, 2200, 2201, + /* 1670 */ 705, 703, 700, 691, 2250, 2165, 2215, 706, 279, 2080, + /* 1680 */ 317, 2356, 284, 683, 684, 679, 100, 2197, 2165, 318, + /* 1690 */ 706, 2094, 2093, 102, 61, 2092, 1964, 707, 393, 2266, + /* 1700 */ 104, 712, 2009, 1926, 2197, 321, 794, 2157, 310, 325, + /* 1710 */ 795, 2196, 797, 2232, 707, 357, 171, 2198, 710, 2200, + /* 1720 */ 2201, 705, 358, 700, 2196, 2215, 2232, 53, 345, 113, + /* 1730 */ 2198, 710, 2200, 2201, 705, 330, 700, 2165, 2156, 706, + /* 1740 */ 323, 2155, 2215, 2285, 344, 334, 78, 385, 2282, 2152, + /* 1750 */ 419, 420, 1549, 2197, 2165, 1550, 706, 194, 424, 2150, + /* 1760 */ 426, 427, 428, 707, 2149, 366, 2147, 657, 2378, 432, + /* 1770 */ 2146, 2145, 434, 2196, 436, 2232, 1540, 2197, 170, 2198, + /* 1780 */ 710, 2200, 2201, 705, 2126, 700, 197, 707, 2125, 199, + /* 1790 */ 2196, 2215, 2232, 79, 1508, 343, 2198, 710, 2200, 2201, + /* 1800 */ 705, 1507, 700, 2165, 2197, 706, 2107, 2106, 2105, 448, + /* 1810 */ 449, 2104, 2103, 2058, 707, 2215, 1458, 2057, 2054, 2323, + /* 1820 */ 386, 201, 2053, 82, 2197, 2052, 2051, 2165, 2056, 706, + /* 1830 */ 204, 2055, 2050, 2049, 707, 2047, 2046, 2045, 206, 2196, + /* 1840 */ 470, 2232, 2215, 2044, 336, 2198, 710, 2200, 2201, 705, + /* 1850 */ 472, 700, 2060, 2043, 2165, 2042, 706, 2041, 2040, 2039, + /* 1860 */ 2038, 2037, 2215, 2196, 2036, 2232, 2035, 392, 343, 2198, + /* 1870 */ 710, 2200, 2201, 705, 2165, 700, 706, 208, 2028, 2027, + /* 1880 */ 87, 2026, 2025, 2059, 2024, 2023, 215, 652, 2034, 2033, + /* 1890 */ 2196, 2197, 2232, 2032, 2031, 171, 2198, 710, 2200, 2201, + /* 1900 */ 705, 707, 700, 2030, 2029, 2022, 2021, 2020, 1460, 2019, + /* 1910 */ 2196, 502, 2232, 2018, 1329, 343, 2198, 710, 2200, 2201, + /* 1920 */ 705, 2197, 700, 353, 354, 1868, 1325, 1867, 1866, 2215, + /* 1930 */ 1333, 707, 217, 218, 400, 1864, 1861, 520, 1860, 519, + /* 1940 */ 524, 2165, 1853, 706, 523, 518, 522, 2379, 527, 526, + /* 1950 */ 1842, 528, 530, 1818, 1222, 76, 1817, 220, 2124, 2215, + /* 1960 */ 2114, 77, 182, 222, 402, 2102, 2185, 183, 538, 228, + /* 1970 */ 2101, 2165, 230, 706, 553, 554, 555, 2196, 2078, 2232, + /* 1980 */ 2197, 1942, 343, 2198, 710, 2200, 2201, 705, 616, 700, + /* 1990 */ 707, 1863, 1859, 1267, 1857, 558, 557, 1855, 559, 561, + /* 2000 */ 562, 563, 1852, 565, 566, 567, 801, 2196, 1837, 2232, + /* 2010 */ 1835, 1836, 343, 2198, 710, 2200, 2201, 705, 2215, 700, + /* 2020 */ 313, 1834, 1814, 1944, 1943, 1403, 1402, 766, 1316, 768, + /* 2030 */ 2165, 1314, 706, 1312, 1311, 1310, 180, 1850, 1309, 1303, + /* 2040 */ 1308, 63, 238, 1841, 791, 787, 783, 779, 1305, 311, + /* 2050 */ 1304, 1302, 378, 2197, 379, 1839, 380, 596, 1813, 1812, + /* 2060 */ 599, 601, 603, 707, 1811, 2123, 611, 605, 2232, 115, + /* 2070 */ 1534, 338, 2198, 710, 2200, 2201, 705, 1536, 700, 1533, + /* 2080 */ 1538, 1514, 29, 67, 2197, 1518, 2113, 2100, 1516, 110, + /* 2090 */ 164, 2215, 304, 620, 707, 2099, 2362, 20, 17, 1751, + /* 2100 */ 6, 21, 65, 2165, 31, 706, 57, 261, 7, 626, + /* 2110 */ 275, 638, 267, 621, 22, 1493, 1492, 274, 269, 2197, + /* 2120 */ 636, 172, 2215, 628, 1732, 686, 2186, 33, 24, 707, + /* 2130 */ 58, 273, 32, 23, 2165, 1724, 706, 1771, 18, 2196, + /* 2140 */ 1772, 2232, 95, 1766, 328, 2198, 710, 2200, 2201, 705, + /* 2150 */ 1765, 700, 389, 1770, 1769, 390, 2197, 2215, 287, 177, + /* 2160 */ 291, 2098, 2077, 292, 97, 1699, 707, 290, 59, 2165, + /* 2170 */ 2196, 706, 2232, 1698, 2076, 326, 2198, 710, 2200, 2201, + /* 2180 */ 705, 2197, 700, 96, 25, 295, 257, 99, 105, 293, + /* 2190 */ 305, 707, 1730, 300, 2215, 68, 26, 101, 1651, 11, + /* 2200 */ 13, 1650, 1574, 179, 2235, 2196, 2165, 2232, 706, 1661, + /* 2210 */ 329, 2198, 710, 2200, 2201, 705, 681, 700, 2197, 2215, + /* 2220 */ 302, 1606, 192, 711, 713, 1629, 1627, 403, 707, 699, + /* 2230 */ 39, 2165, 1626, 706, 16, 27, 717, 1598, 28, 720, + /* 2240 */ 1388, 715, 2196, 2197, 2232, 1385, 1384, 335, 2198, 710, + /* 2250 */ 2200, 2201, 705, 707, 700, 1381, 2215, 718, 721, 723, + /* 2260 */ 724, 726, 1375, 709, 1373, 729, 727, 2196, 2165, 2232, + /* 2270 */ 706, 730, 339, 2198, 710, 2200, 2201, 705, 1364, 700, + /* 2280 */ 106, 2215, 736, 308, 107, 1379, 1397, 75, 1393, 1265, + /* 2290 */ 1378, 1377, 1376, 2165, 1297, 706, 746, 1296, 1295, 1294, + /* 2300 */ 1292, 309, 1290, 1289, 2196, 1288, 2232, 1323, 756, 331, + /* 2310 */ 2198, 710, 2200, 2201, 705, 2197, 700, 1286, 1285, 1284, + /* 2320 */ 1283, 1282, 1281, 1280, 1320, 707, 1318, 1277, 1276, 2196, + /* 2330 */ 2197, 2232, 1273, 1858, 340, 2198, 710, 2200, 2201, 705, + /* 2340 */ 707, 700, 1272, 1271, 1270, 776, 1856, 778, 2197, 777, + /* 2350 */ 780, 781, 782, 2215, 1854, 784, 786, 1851, 707, 788, + /* 2360 */ 1833, 785, 790, 789, 792, 2165, 1810, 706, 2215, 1212, + /* 2370 */ 312, 796, 1785, 1560, 322, 1785, 799, 1785, 800, 1785, + /* 2380 */ 2165, 1785, 706, 1785, 1785, 1785, 2215, 1785, 1785, 1785, + /* 2390 */ 1785, 1785, 1785, 1785, 1785, 2197, 1785, 1785, 2165, 1785, + /* 2400 */ 706, 2196, 1785, 2232, 1785, 707, 332, 2198, 710, 2200, + /* 2410 */ 2201, 705, 1785, 700, 1785, 1785, 2196, 2197, 2232, 1785, + /* 2420 */ 1785, 341, 2198, 710, 2200, 2201, 705, 707, 700, 1785, + /* 2430 */ 1785, 1785, 1785, 2215, 2196, 1785, 2232, 1785, 1785, 333, + /* 2440 */ 2198, 710, 2200, 2201, 705, 2165, 700, 706, 1785, 1785, + /* 2450 */ 1785, 1785, 1785, 1785, 1785, 2215, 1785, 1785, 1785, 1785, + /* 2460 */ 1785, 1785, 1785, 1785, 2197, 1785, 1785, 2165, 1785, 706, + /* 2470 */ 1785, 1785, 1785, 1785, 707, 1785, 1785, 1785, 1785, 1785, + /* 2480 */ 1785, 2196, 1785, 2232, 1785, 1785, 346, 2198, 710, 2200, + /* 2490 */ 2201, 705, 1785, 700, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2500 */ 1785, 1785, 2215, 2196, 1785, 2232, 1785, 1785, 347, 2198, + /* 2510 */ 710, 2200, 2201, 705, 2165, 700, 706, 1785, 1785, 1785, + /* 2520 */ 1785, 1785, 1785, 2197, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2530 */ 1785, 1785, 1785, 707, 1785, 1785, 2197, 1785, 1785, 1785, + /* 2540 */ 1785, 1785, 1785, 1785, 1785, 1785, 707, 1785, 1785, 1785, + /* 2550 */ 2196, 1785, 2232, 2197, 1785, 2209, 2198, 710, 2200, 2201, + /* 2560 */ 705, 2215, 700, 707, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2570 */ 1785, 1785, 1785, 2165, 2215, 706, 1785, 1785, 1785, 1785, + /* 2580 */ 1785, 1785, 1785, 1785, 1785, 2197, 2165, 1785, 706, 1785, + /* 2590 */ 1785, 2215, 1785, 1785, 1785, 707, 1785, 1785, 1785, 1785, + /* 2600 */ 1785, 1785, 1785, 2165, 1785, 706, 1785, 1785, 1785, 2196, + /* 2610 */ 1785, 2232, 1785, 1785, 2208, 2198, 710, 2200, 2201, 705, + /* 2620 */ 1785, 700, 2196, 2215, 2232, 1785, 1785, 2207, 2198, 710, + /* 2630 */ 2200, 2201, 705, 1785, 700, 2165, 1785, 706, 1785, 2196, + /* 2640 */ 1785, 2232, 1785, 1785, 362, 2198, 710, 2200, 2201, 705, + /* 2650 */ 1785, 700, 2197, 1785, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2660 */ 1785, 1785, 707, 1785, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2670 */ 1785, 2196, 2197, 2232, 1785, 1785, 363, 2198, 710, 2200, + /* 2680 */ 2201, 705, 707, 700, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2690 */ 2215, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2700 */ 1785, 1785, 2165, 1785, 706, 1785, 1785, 1785, 1785, 1785, + /* 2710 */ 2215, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2720 */ 1785, 1785, 2165, 1785, 706, 1785, 1785, 1785, 1785, 1785, + /* 2730 */ 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 2196, 1785, + /* 2740 */ 2232, 1785, 2197, 359, 2198, 710, 2200, 2201, 705, 1785, + /* 2750 */ 700, 1785, 707, 1785, 1785, 1785, 1785, 1785, 2196, 2197, + /* 2760 */ 2232, 1785, 1785, 364, 2198, 710, 2200, 2201, 705, 707, + /* 2770 */ 700, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2780 */ 2215, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2790 */ 1785, 1785, 2165, 1785, 706, 1785, 1785, 2215, 1785, 1785, + /* 2800 */ 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 2165, + /* 2810 */ 1785, 706, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, + /* 2820 */ 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 708, 1785, + /* 2830 */ 2232, 1785, 1785, 338, 2198, 710, 2200, 2201, 705, 1785, + /* 2840 */ 700, 1785, 1785, 1785, 1785, 2196, 1785, 2232, 1785, 1785, + /* 2850 */ 337, 2198, 710, 2200, 2201, 705, 1785, 700, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 375, 341, 367, 393, 346, 350, 351, 411, 350, 380, + /* 0 */ 380, 341, 367, 393, 346, 350, 351, 411, 350, 378, /* 10 */ 352, 351, 12, 13, 14, 405, 381, 4, 408, 409, - /* 20 */ 20, 3, 22, 8, 9, 370, 391, 12, 13, 14, + /* 20 */ 20, 390, 22, 8, 9, 370, 391, 12, 13, 14, /* 30 */ 15, 16, 377, 33, 350, 35, 367, 14, 20, 379, - /* 40 */ 8, 9, 338, 20, 12, 13, 14, 15, 16, 424, + /* 40 */ 8, 9, 338, 20, 12, 13, 14, 15, 16, 20, /* 50 */ 381, 391, 380, 393, 458, 49, 43, 461, 45, 46, /* 60 */ 391, 379, 62, 57, 429, 430, 60, 61, 68, 20, /* 70 */ 4, 22, 476, 477, 439, 75, 44, 481, 482, 395, - /* 80 */ 20, 399, 400, 68, 35, 350, 351, 427, 20, 429, + /* 80 */ 360, 399, 400, 68, 35, 350, 351, 427, 368, 429, /* 90 */ 350, 351, 432, 433, 434, 435, 436, 437, 429, 439, - /* 100 */ 100, 360, 53, 103, 444, 370, 446, 357, 439, 368, - /* 110 */ 450, 451, 377, 84, 393, 411, 12, 13, 350, 351, - /* 120 */ 416, 20, 104, 463, 20, 62, 22, 112, 100, 408, - /* 130 */ 409, 471, 382, 20, 447, 448, 104, 33, 370, 35, - /* 140 */ 140, 141, 341, 115, 116, 117, 118, 119, 120, 121, - /* 150 */ 122, 123, 124, 341, 126, 127, 128, 129, 130, 131, - /* 160 */ 132, 378, 458, 103, 458, 461, 62, 461, 105, 103, - /* 170 */ 170, 171, 68, 390, 145, 146, 176, 177, 20, 75, - /* 180 */ 476, 477, 476, 477, 169, 481, 482, 481, 482, 431, - /* 190 */ 172, 191, 391, 193, 454, 455, 456, 168, 458, 459, - /* 200 */ 340, 461, 342, 391, 100, 8, 9, 103, 341, 12, - /* 210 */ 13, 14, 15, 16, 103, 457, 476, 477, 351, 35, - /* 220 */ 186, 481, 482, 223, 224, 0, 226, 227, 228, 229, + /* 100 */ 100, 0, 53, 103, 444, 370, 446, 340, 439, 342, + /* 110 */ 450, 451, 377, 20, 393, 411, 12, 13, 379, 458, + /* 120 */ 416, 103, 461, 463, 20, 386, 22, 112, 100, 408, + /* 130 */ 409, 471, 103, 394, 350, 351, 104, 33, 477, 35, + /* 140 */ 140, 141, 481, 482, 116, 117, 118, 119, 120, 121, + /* 150 */ 122, 123, 124, 125, 370, 127, 128, 129, 130, 131, + /* 160 */ 132, 133, 458, 20, 458, 461, 62, 461, 67, 103, + /* 170 */ 170, 171, 68, 350, 351, 357, 176, 177, 20, 75, + /* 180 */ 476, 477, 476, 477, 169, 481, 482, 481, 482, 447, + /* 190 */ 448, 191, 374, 193, 454, 455, 456, 3, 458, 459, + /* 200 */ 382, 461, 1, 2, 100, 8, 9, 103, 341, 12, + /* 210 */ 13, 14, 15, 16, 20, 20, 476, 477, 351, 35, + /* 220 */ 397, 481, 482, 223, 224, 0, 226, 227, 228, 229, /* 230 */ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - /* 240 */ 240, 241, 242, 243, 140, 141, 379, 213, 214, 24, + /* 240 */ 240, 241, 242, 243, 140, 141, 379, 392, 393, 24, /* 250 */ 25, 26, 27, 28, 29, 30, 31, 32, 391, 75, /* 260 */ 393, 0, 247, 248, 249, 250, 251, 252, 253, 254, - /* 270 */ 255, 256, 257, 345, 170, 171, 348, 349, 67, 20, - /* 280 */ 176, 177, 21, 170, 171, 24, 25, 26, 27, 28, - /* 290 */ 29, 30, 31, 32, 427, 191, 429, 193, 175, 432, - /* 300 */ 433, 434, 435, 436, 437, 20, 439, 0, 371, 442, - /* 310 */ 20, 444, 445, 446, 20, 341, 379, 450, 451, 20, - /* 320 */ 260, 22, 350, 351, 387, 351, 260, 223, 224, 4, + /* 270 */ 255, 256, 257, 345, 170, 171, 348, 349, 260, 20, + /* 280 */ 176, 177, 21, 140, 141, 24, 25, 26, 27, 28, + /* 290 */ 29, 30, 31, 32, 427, 191, 429, 193, 104, 432, + /* 300 */ 433, 434, 435, 436, 437, 104, 439, 0, 371, 442, + /* 310 */ 67, 444, 445, 446, 20, 341, 379, 450, 451, 176, + /* 320 */ 177, 341, 350, 351, 387, 351, 260, 223, 224, 20, /* 330 */ 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* 340 */ 236, 237, 238, 239, 240, 241, 242, 243, 244, 12, - /* 350 */ 13, 67, 53, 379, 379, 12, 13, 20, 47, 22, - /* 360 */ 458, 386, 103, 461, 379, 391, 20, 393, 114, 394, - /* 370 */ 33, 260, 35, 70, 71, 72, 350, 351, 35, 477, - /* 380 */ 77, 78, 79, 481, 482, 400, 83, 351, 265, 266, - /* 390 */ 267, 88, 89, 90, 91, 442, 370, 94, 445, 62, - /* 400 */ 135, 427, 48, 429, 139, 68, 432, 433, 434, 435, - /* 410 */ 436, 437, 75, 439, 103, 379, 134, 135, 444, 345, - /* 420 */ 446, 139, 348, 349, 450, 451, 454, 455, 456, 341, - /* 430 */ 458, 459, 14, 458, 140, 141, 461, 100, 20, 351, - /* 440 */ 103, 353, 8, 9, 35, 471, 12, 13, 14, 15, + /* 350 */ 13, 20, 341, 379, 379, 12, 13, 20, 103, 22, + /* 360 */ 458, 386, 103, 461, 431, 391, 172, 393, 113, 394, + /* 370 */ 33, 391, 35, 70, 71, 72, 350, 351, 35, 477, + /* 380 */ 77, 78, 79, 481, 482, 345, 83, 351, 348, 349, + /* 390 */ 457, 88, 89, 90, 91, 375, 370, 94, 114, 62, + /* 400 */ 135, 427, 391, 429, 139, 68, 432, 433, 434, 435, + /* 410 */ 436, 437, 75, 439, 134, 379, 134, 135, 444, 389, + /* 420 */ 446, 139, 392, 393, 450, 451, 454, 455, 456, 341, + /* 430 */ 458, 459, 341, 458, 140, 141, 461, 100, 115, 351, + /* 440 */ 103, 353, 8, 9, 424, 471, 12, 13, 14, 15, /* 450 */ 16, 476, 477, 12, 13, 14, 481, 482, 346, 341, - /* 460 */ 170, 20, 350, 22, 352, 200, 159, 379, 203, 351, - /* 470 */ 434, 206, 379, 208, 33, 168, 35, 140, 141, 391, - /* 480 */ 387, 393, 458, 21, 75, 461, 24, 25, 26, 27, - /* 490 */ 28, 29, 30, 31, 32, 379, 103, 379, 341, 350, - /* 500 */ 351, 477, 386, 62, 244, 481, 482, 170, 171, 391, - /* 510 */ 394, 393, 357, 176, 177, 427, 75, 429, 172, 260, - /* 520 */ 432, 433, 434, 435, 436, 437, 172, 439, 191, 374, - /* 530 */ 193, 133, 444, 179, 446, 137, 193, 382, 450, 451, - /* 540 */ 14, 100, 350, 351, 103, 427, 20, 429, 391, 341, - /* 550 */ 432, 433, 434, 435, 436, 437, 244, 439, 246, 351, + /* 460 */ 137, 20, 350, 22, 352, 200, 159, 379, 203, 351, + /* 470 */ 434, 206, 431, 208, 33, 168, 35, 140, 141, 391, + /* 480 */ 357, 393, 391, 21, 204, 205, 24, 25, 26, 27, + /* 490 */ 28, 29, 30, 31, 32, 244, 103, 379, 457, 350, + /* 500 */ 351, 170, 171, 62, 350, 382, 14, 170, 171, 391, + /* 510 */ 371, 393, 20, 176, 177, 427, 75, 429, 379, 260, + /* 520 */ 432, 433, 434, 435, 436, 437, 387, 439, 191, 75, + /* 530 */ 193, 103, 444, 21, 446, 244, 193, 246, 450, 451, + /* 540 */ 67, 100, 350, 351, 103, 427, 34, 429, 36, 341, + /* 550 */ 432, 433, 434, 435, 436, 437, 402, 439, 404, 351, /* 560 */ 223, 224, 370, 226, 227, 228, 229, 230, 231, 232, /* 570 */ 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - /* 580 */ 243, 140, 141, 190, 22, 192, 261, 379, 8, 9, - /* 590 */ 472, 473, 12, 13, 14, 15, 16, 35, 431, 391, - /* 600 */ 20, 393, 453, 454, 455, 456, 172, 458, 459, 75, - /* 610 */ 341, 170, 171, 350, 351, 222, 389, 176, 177, 392, - /* 620 */ 393, 8, 9, 371, 457, 12, 13, 14, 15, 16, - /* 630 */ 431, 379, 191, 370, 193, 427, 350, 429, 386, 387, - /* 640 */ 432, 433, 434, 435, 436, 437, 394, 439, 134, 20, + /* 580 */ 243, 140, 141, 190, 20, 192, 341, 379, 8, 9, + /* 590 */ 472, 473, 12, 13, 14, 15, 16, 114, 341, 391, + /* 600 */ 20, 393, 453, 454, 455, 456, 172, 458, 459, 379, + /* 610 */ 0, 170, 171, 350, 351, 222, 386, 176, 177, 350, + /* 620 */ 351, 8, 9, 371, 394, 12, 13, 14, 15, 16, + /* 630 */ 431, 379, 191, 370, 193, 427, 391, 429, 386, 387, + /* 640 */ 432, 433, 434, 435, 436, 437, 394, 439, 391, 47, /* 650 */ 411, 341, 444, 260, 446, 416, 457, 411, 450, 451, - /* 660 */ 391, 351, 100, 353, 223, 224, 44, 226, 227, 228, + /* 660 */ 50, 351, 170, 353, 223, 224, 397, 226, 227, 228, /* 670 */ 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - /* 680 */ 239, 240, 241, 242, 243, 12, 13, 0, 402, 379, - /* 690 */ 404, 350, 351, 20, 75, 22, 170, 458, 350, 351, - /* 700 */ 461, 391, 379, 393, 458, 0, 33, 461, 35, 386, - /* 710 */ 12, 13, 14, 15, 16, 476, 477, 394, 204, 205, - /* 720 */ 481, 482, 476, 477, 350, 351, 104, 481, 482, 1, - /* 730 */ 2, 223, 103, 350, 351, 62, 380, 427, 397, 429, - /* 740 */ 4, 350, 432, 433, 434, 435, 436, 437, 75, 439, + /* 680 */ 239, 240, 241, 242, 243, 12, 13, 0, 260, 379, + /* 690 */ 115, 350, 351, 20, 75, 22, 175, 458, 350, 351, + /* 700 */ 461, 391, 186, 393, 458, 103, 33, 461, 35, 134, + /* 710 */ 135, 136, 137, 138, 139, 476, 477, 443, 370, 445, + /* 720 */ 481, 482, 476, 477, 14, 15, 16, 481, 482, 213, + /* 730 */ 214, 223, 84, 350, 351, 62, 172, 427, 397, 429, + /* 740 */ 4, 380, 432, 433, 434, 435, 436, 437, 75, 439, /* 750 */ 350, 351, 172, 370, 444, 19, 446, 0, 8, 9, - /* 760 */ 450, 451, 12, 13, 14, 15, 16, 341, 341, 33, - /* 770 */ 370, 397, 67, 100, 350, 351, 103, 351, 270, 271, - /* 780 */ 272, 273, 274, 275, 276, 49, 350, 351, 3, 12, - /* 790 */ 13, 0, 56, 402, 370, 404, 183, 20, 62, 22, - /* 800 */ 371, 20, 454, 455, 456, 379, 458, 459, 379, 443, - /* 810 */ 33, 445, 35, 140, 141, 0, 387, 391, 391, 393, - /* 820 */ 133, 134, 135, 136, 137, 138, 139, 70, 71, 72, - /* 830 */ 392, 393, 104, 397, 77, 78, 79, 22, 102, 62, - /* 840 */ 83, 105, 103, 170, 171, 88, 89, 90, 91, 176, - /* 850 */ 177, 94, 75, 427, 104, 429, 54, 55, 432, 433, + /* 760 */ 450, 451, 12, 13, 14, 15, 16, 341, 14, 33, + /* 770 */ 370, 350, 351, 100, 20, 62, 103, 351, 270, 271, + /* 780 */ 272, 273, 274, 275, 276, 49, 265, 266, 267, 12, + /* 790 */ 13, 370, 56, 145, 146, 371, 183, 20, 62, 22, + /* 800 */ 350, 351, 115, 379, 103, 379, 0, 341, 355, 356, + /* 810 */ 33, 387, 35, 140, 141, 102, 168, 391, 105, 393, + /* 820 */ 370, 134, 135, 136, 137, 138, 139, 70, 71, 72, + /* 830 */ 350, 351, 48, 417, 77, 78, 79, 20, 102, 62, + /* 840 */ 83, 105, 368, 170, 171, 88, 89, 90, 91, 176, + /* 850 */ 177, 94, 75, 427, 104, 429, 380, 391, 432, 433, /* 860 */ 434, 435, 436, 437, 191, 439, 193, 441, 8, 9, - /* 870 */ 341, 380, 12, 13, 14, 15, 16, 100, 355, 356, - /* 880 */ 103, 341, 133, 134, 135, 136, 137, 138, 139, 341, - /* 890 */ 411, 351, 62, 353, 341, 380, 223, 224, 285, 226, + /* 870 */ 350, 351, 12, 13, 14, 15, 16, 100, 341, 380, + /* 880 */ 103, 341, 12, 13, 14, 15, 16, 54, 55, 14, + /* 890 */ 370, 351, 20, 353, 22, 20, 223, 224, 285, 226, /* 900 */ 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, /* 910 */ 237, 238, 239, 240, 241, 242, 243, 140, 141, 379, - /* 920 */ 391, 140, 141, 21, 133, 134, 135, 136, 137, 138, - /* 930 */ 139, 391, 102, 393, 379, 105, 34, 458, 36, 391, - /* 940 */ 461, 386, 350, 351, 391, 350, 351, 170, 171, 394, - /* 950 */ 114, 350, 351, 176, 177, 476, 477, 176, 177, 380, - /* 960 */ 481, 482, 370, 388, 104, 370, 391, 427, 191, 429, - /* 970 */ 193, 370, 432, 433, 434, 435, 436, 437, 39, 439, - /* 980 */ 364, 365, 2, 0, 444, 22, 446, 350, 8, 9, - /* 990 */ 450, 451, 12, 13, 14, 15, 16, 341, 35, 260, + /* 920 */ 359, 115, 355, 356, 170, 53, 350, 3, 391, 350, + /* 930 */ 351, 391, 380, 393, 454, 455, 456, 376, 458, 459, + /* 940 */ 134, 135, 136, 137, 138, 139, 385, 170, 171, 370, + /* 950 */ 380, 350, 351, 176, 177, 401, 172, 364, 365, 4, + /* 960 */ 379, 260, 169, 179, 104, 350, 351, 427, 191, 429, + /* 970 */ 193, 370, 432, 433, 434, 435, 436, 437, 402, 439, + /* 980 */ 404, 400, 2, 341, 444, 370, 446, 170, 8, 9, + /* 990 */ 450, 451, 12, 13, 14, 15, 16, 350, 364, 365, /* 1000 */ 223, 224, 0, 226, 227, 228, 229, 230, 231, 232, /* 1010 */ 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - /* 1020 */ 243, 14, 18, 18, 20, 350, 351, 20, 23, 350, - /* 1030 */ 351, 27, 49, 359, 30, 355, 356, 33, 367, 402, - /* 1040 */ 371, 404, 37, 38, 0, 370, 41, 391, 379, 370, - /* 1050 */ 376, 379, 381, 49, 411, 51, 387, 52, 386, 385, - /* 1060 */ 56, 380, 391, 100, 341, 280, 394, 341, 63, 64, - /* 1070 */ 65, 66, 70, 71, 72, 73, 74, 0, 76, 77, + /* 1020 */ 243, 0, 18, 18, 20, 350, 351, 341, 23, 39, + /* 1030 */ 443, 27, 445, 391, 30, 359, 442, 33, 367, 445, + /* 1040 */ 247, 388, 37, 38, 391, 370, 41, 350, 351, 402, + /* 1050 */ 257, 404, 381, 49, 411, 51, 379, 52, 20, 20, + /* 1060 */ 56, 385, 391, 341, 387, 341, 341, 370, 63, 64, + /* 1070 */ 65, 66, 70, 71, 72, 73, 74, 391, 76, 77, /* 1080 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - /* 1090 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 20, - /* 1100 */ 429, 458, 350, 351, 461, 20, 102, 33, 103, 37, - /* 1110 */ 439, 14, 15, 16, 391, 350, 351, 391, 114, 476, - /* 1120 */ 477, 44, 370, 49, 481, 482, 350, 351, 417, 350, - /* 1130 */ 351, 57, 58, 59, 60, 370, 62, 341, 44, 443, - /* 1140 */ 169, 445, 364, 365, 341, 341, 370, 142, 144, 370, - /* 1150 */ 341, 147, 148, 149, 150, 151, 152, 153, 154, 155, - /* 1160 */ 156, 157, 158, 159, 160, 161, 162, 163, 44, 165, - /* 1170 */ 166, 167, 350, 351, 258, 259, 102, 170, 106, 105, - /* 1180 */ 108, 109, 0, 111, 359, 341, 341, 391, 183, 184, - /* 1190 */ 185, 341, 370, 188, 391, 391, 341, 379, 259, 388, - /* 1200 */ 391, 351, 391, 353, 22, 133, 201, 202, 341, 137, - /* 1210 */ 385, 388, 394, 372, 391, 368, 375, 212, 247, 42, - /* 1220 */ 215, 44, 341, 218, 219, 220, 221, 222, 257, 379, - /* 1230 */ 366, 22, 351, 369, 353, 391, 391, 45, 46, 44, - /* 1240 */ 42, 391, 44, 393, 35, 114, 391, 173, 174, 13, - /* 1250 */ 107, 172, 341, 110, 180, 181, 107, 172, 391, 110, - /* 1260 */ 379, 217, 351, 107, 353, 260, 110, 107, 44, 13, - /* 1270 */ 110, 35, 391, 199, 393, 0, 44, 427, 207, 429, - /* 1280 */ 209, 44, 432, 433, 434, 435, 436, 437, 68, 439, - /* 1290 */ 379, 35, 140, 141, 444, 164, 446, 22, 342, 104, - /* 1300 */ 450, 451, 391, 474, 393, 35, 44, 44, 427, 103, - /* 1310 */ 429, 401, 485, 432, 433, 434, 435, 436, 437, 113, - /* 1320 */ 439, 44, 44, 35, 22, 444, 44, 446, 104, 44, - /* 1330 */ 44, 450, 451, 1, 2, 44, 104, 35, 427, 44, - /* 1340 */ 429, 104, 341, 432, 433, 434, 435, 436, 437, 44, - /* 1350 */ 439, 0, 351, 12, 13, 444, 468, 446, 2, 44, - /* 1360 */ 354, 450, 451, 22, 8, 9, 104, 104, 12, 13, - /* 1370 */ 14, 15, 16, 341, 33, 367, 35, 75, 284, 44, - /* 1380 */ 379, 104, 104, 351, 44, 13, 104, 367, 379, 104, - /* 1390 */ 104, 13, 391, 44, 393, 104, 410, 44, 401, 104, - /* 1400 */ 354, 50, 100, 62, 349, 351, 282, 35, 390, 104, - /* 1410 */ 341, 379, 401, 35, 460, 478, 75, 452, 49, 104, - /* 1420 */ 351, 462, 412, 391, 262, 393, 428, 20, 427, 206, - /* 1430 */ 429, 189, 359, 432, 433, 434, 435, 436, 437, 104, - /* 1440 */ 439, 100, 421, 223, 104, 444, 421, 446, 379, 426, - /* 1450 */ 359, 450, 451, 104, 414, 20, 351, 104, 42, 427, - /* 1460 */ 391, 429, 393, 193, 432, 433, 434, 435, 436, 437, - /* 1470 */ 20, 439, 351, 398, 396, 169, 444, 401, 446, 398, - /* 1480 */ 20, 193, 450, 451, 350, 398, 351, 350, 396, 396, - /* 1490 */ 101, 363, 99, 191, 362, 193, 427, 350, 429, 341, - /* 1500 */ 98, 432, 433, 434, 435, 436, 437, 361, 439, 351, - /* 1510 */ 20, 350, 343, 350, 350, 446, 48, 347, 343, 450, - /* 1520 */ 451, 347, 421, 20, 359, 223, 224, 359, 20, 393, - /* 1530 */ 352, 20, 191, 413, 193, 359, 352, 379, 359, 359, - /* 1540 */ 359, 350, 359, 343, 343, 379, 379, 350, 341, 391, - /* 1550 */ 379, 393, 379, 210, 425, 103, 423, 197, 351, 421, - /* 1560 */ 357, 420, 196, 391, 223, 224, 379, 379, 379, 379, - /* 1570 */ 419, 357, 379, 379, 341, 379, 391, 236, 237, 238, - /* 1580 */ 239, 240, 241, 242, 351, 427, 379, 429, 350, 195, - /* 1590 */ 432, 433, 434, 435, 436, 437, 391, 439, 391, 269, - /* 1600 */ 393, 393, 391, 277, 446, 401, 467, 268, 450, 451, - /* 1610 */ 391, 401, 379, 391, 412, 467, 391, 418, 406, 406, - /* 1620 */ 470, 182, 469, 279, 391, 341, 393, 263, 278, 412, - /* 1630 */ 486, 286, 259, 281, 427, 351, 429, 283, 341, 432, - /* 1640 */ 433, 434, 435, 436, 437, 351, 439, 20, 351, 357, - /* 1650 */ 352, 20, 466, 446, 404, 406, 357, 450, 451, 431, - /* 1660 */ 427, 406, 429, 379, 391, 432, 433, 434, 435, 436, - /* 1670 */ 437, 438, 439, 440, 441, 391, 379, 393, 391, 174, - /* 1680 */ 391, 465, 467, 403, 391, 464, 357, 341, 391, 375, - /* 1690 */ 393, 391, 391, 357, 103, 449, 103, 351, 480, 351, - /* 1700 */ 383, 391, 369, 36, 341, 479, 344, 350, 343, 0, - /* 1710 */ 407, 427, 357, 429, 351, 407, 432, 433, 434, 435, - /* 1720 */ 436, 437, 415, 439, 427, 379, 429, 339, 358, 432, - /* 1730 */ 433, 434, 435, 436, 437, 422, 439, 391, 0, 393, - /* 1740 */ 373, 373, 379, 446, 373, 0, 42, 384, 451, 0, + /* 1090 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 22, + /* 1100 */ 429, 458, 350, 351, 461, 13, 102, 33, 103, 37, + /* 1110 */ 439, 379, 35, 391, 379, 391, 391, 22, 114, 476, + /* 1120 */ 477, 386, 370, 49, 481, 482, 394, 35, 379, 394, + /* 1130 */ 35, 57, 58, 59, 60, 386, 62, 372, 366, 388, + /* 1140 */ 375, 369, 391, 394, 341, 44, 341, 142, 144, 341, + /* 1150 */ 44, 147, 148, 149, 150, 151, 152, 153, 154, 155, + /* 1160 */ 156, 157, 158, 159, 160, 161, 162, 163, 341, 165, + /* 1170 */ 166, 167, 350, 351, 45, 46, 102, 100, 106, 105, + /* 1180 */ 108, 109, 42, 111, 44, 341, 341, 115, 183, 184, + /* 1190 */ 185, 341, 370, 188, 391, 100, 391, 258, 259, 391, + /* 1200 */ 341, 351, 388, 353, 280, 391, 201, 202, 0, 137, + /* 1210 */ 172, 172, 42, 114, 44, 44, 261, 212, 391, 207, + /* 1220 */ 215, 209, 341, 218, 219, 220, 221, 222, 44, 379, + /* 1230 */ 107, 22, 351, 110, 353, 391, 391, 0, 217, 107, + /* 1240 */ 68, 391, 110, 393, 35, 13, 0, 173, 174, 259, + /* 1250 */ 391, 342, 341, 35, 180, 181, 107, 49, 0, 110, + /* 1260 */ 379, 44, 351, 164, 353, 260, 107, 35, 22, 110, + /* 1270 */ 0, 35, 391, 199, 393, 104, 62, 427, 474, 429, + /* 1280 */ 22, 44, 432, 433, 434, 435, 436, 437, 104, 439, + /* 1290 */ 379, 44, 22, 75, 444, 35, 446, 140, 141, 44, + /* 1300 */ 450, 451, 391, 485, 393, 354, 44, 44, 427, 468, + /* 1310 */ 429, 367, 367, 432, 433, 434, 435, 436, 437, 105, + /* 1320 */ 439, 104, 44, 410, 22, 444, 44, 446, 379, 44, + /* 1330 */ 44, 450, 451, 44, 1, 2, 44, 35, 427, 44, + /* 1340 */ 429, 354, 341, 432, 433, 434, 435, 436, 437, 44, + /* 1350 */ 439, 104, 351, 12, 13, 444, 13, 446, 2, 104, + /* 1360 */ 401, 450, 451, 22, 8, 9, 104, 104, 12, 13, + /* 1370 */ 14, 15, 16, 341, 33, 349, 35, 75, 35, 44, + /* 1380 */ 379, 351, 104, 351, 44, 284, 104, 390, 282, 104, + /* 1390 */ 104, 13, 391, 104, 393, 223, 104, 44, 44, 104, + /* 1400 */ 401, 460, 100, 62, 478, 452, 262, 412, 462, 104, + /* 1410 */ 341, 379, 44, 35, 49, 20, 75, 428, 206, 421, + /* 1420 */ 351, 359, 426, 391, 421, 393, 359, 189, 427, 193, + /* 1430 */ 429, 414, 351, 432, 433, 434, 435, 436, 437, 104, + /* 1440 */ 439, 100, 20, 42, 104, 444, 398, 446, 379, 20, + /* 1450 */ 401, 450, 451, 193, 351, 398, 169, 104, 104, 427, + /* 1460 */ 391, 429, 393, 20, 432, 433, 434, 435, 436, 437, + /* 1470 */ 350, 439, 104, 351, 396, 350, 444, 398, 446, 396, + /* 1480 */ 396, 101, 450, 451, 363, 99, 362, 350, 98, 361, + /* 1490 */ 20, 411, 350, 191, 343, 193, 427, 350, 429, 341, + /* 1500 */ 350, 432, 433, 434, 435, 436, 437, 48, 439, 351, + /* 1510 */ 347, 343, 347, 359, 421, 446, 20, 20, 352, 450, + /* 1520 */ 451, 359, 20, 393, 413, 223, 224, 352, 359, 350, + /* 1530 */ 343, 379, 191, 359, 193, 359, 359, 379, 458, 359, + /* 1540 */ 379, 461, 343, 379, 350, 103, 379, 391, 341, 391, + /* 1550 */ 423, 393, 379, 357, 210, 197, 476, 477, 351, 425, + /* 1560 */ 379, 481, 482, 420, 223, 224, 421, 379, 379, 379, + /* 1570 */ 379, 379, 196, 391, 341, 350, 391, 236, 237, 238, + /* 1580 */ 239, 240, 241, 242, 351, 427, 379, 429, 393, 195, + /* 1590 */ 432, 433, 434, 435, 436, 437, 357, 439, 391, 269, + /* 1600 */ 393, 401, 419, 401, 446, 467, 391, 268, 450, 451, + /* 1610 */ 412, 418, 379, 391, 391, 467, 406, 406, 391, 277, + /* 1620 */ 182, 486, 467, 470, 391, 341, 393, 279, 278, 469, + /* 1630 */ 263, 412, 283, 286, 427, 351, 429, 20, 341, 432, + /* 1640 */ 433, 434, 435, 436, 437, 281, 439, 259, 351, 351, + /* 1650 */ 357, 431, 466, 446, 20, 352, 357, 450, 451, 406, + /* 1660 */ 427, 464, 429, 379, 391, 432, 433, 434, 435, 436, + /* 1670 */ 437, 438, 439, 440, 441, 391, 379, 393, 465, 404, + /* 1680 */ 406, 480, 479, 174, 403, 391, 357, 341, 391, 375, + /* 1690 */ 393, 391, 391, 357, 103, 391, 351, 351, 391, 449, + /* 1700 */ 103, 383, 391, 369, 341, 350, 36, 0, 357, 339, + /* 1710 */ 344, 427, 343, 429, 351, 407, 432, 433, 434, 435, + /* 1720 */ 436, 437, 407, 439, 427, 379, 429, 415, 422, 432, + /* 1730 */ 433, 434, 435, 436, 437, 373, 439, 391, 0, 393, + /* 1740 */ 358, 0, 379, 446, 373, 373, 42, 384, 451, 0, /* 1750 */ 35, 216, 35, 341, 391, 35, 393, 35, 216, 0, /* 1760 */ 35, 35, 216, 351, 0, 216, 0, 483, 484, 35, /* 1770 */ 0, 0, 22, 427, 35, 429, 211, 341, 432, 433, /* 1780 */ 434, 435, 436, 437, 0, 439, 199, 351, 0, 199, - /* 1790 */ 427, 379, 429, 193, 200, 432, 433, 434, 435, 436, + /* 1790 */ 427, 379, 429, 200, 193, 432, 433, 434, 435, 436, /* 1800 */ 437, 191, 439, 391, 341, 393, 0, 0, 0, 187, /* 1810 */ 186, 0, 0, 0, 351, 379, 47, 0, 0, 473, /* 1820 */ 384, 47, 0, 42, 341, 0, 0, 391, 0, 393, @@ -735,17 +729,17 @@ static const YYCODETYPE yy_lookahead[] = { /* 2240 */ 104, 103, 427, 341, 429, 104, 104, 432, 433, 434, /* 2250 */ 435, 436, 437, 351, 439, 104, 379, 103, 103, 35, /* 2260 */ 103, 35, 104, 225, 104, 35, 103, 427, 391, 429, - /* 2270 */ 393, 103, 432, 433, 434, 435, 436, 437, 125, 439, - /* 2280 */ 103, 379, 44, 35, 125, 22, 103, 103, 69, 125, - /* 2290 */ 125, 68, 35, 391, 35, 393, 35, 35, 44, 35, - /* 2300 */ 35, 35, 35, 75, 427, 97, 429, 35, 35, 432, - /* 2310 */ 433, 434, 435, 436, 437, 341, 439, 35, 22, 35, - /* 2320 */ 35, 35, 75, 35, 35, 351, 35, 35, 35, 427, - /* 2330 */ 341, 429, 22, 35, 432, 433, 434, 435, 436, 437, - /* 2340 */ 351, 439, 0, 35, 49, 39, 0, 35, 341, 49, - /* 2350 */ 0, 35, 39, 379, 49, 0, 39, 35, 351, 39, - /* 2360 */ 0, 35, 35, 49, 0, 391, 22, 393, 379, 21, - /* 2370 */ 487, 22, 20, 22, 21, 487, 487, 487, 487, 487, + /* 2270 */ 393, 103, 432, 433, 434, 435, 436, 437, 22, 439, + /* 2280 */ 103, 379, 115, 44, 103, 126, 35, 103, 22, 69, + /* 2290 */ 126, 126, 126, 391, 35, 393, 68, 35, 35, 35, + /* 2300 */ 35, 44, 35, 35, 427, 35, 429, 75, 97, 432, + /* 2310 */ 433, 434, 435, 436, 437, 341, 439, 35, 35, 35, + /* 2320 */ 22, 35, 35, 35, 75, 351, 35, 35, 35, 427, + /* 2330 */ 341, 429, 35, 0, 432, 433, 434, 435, 436, 437, + /* 2340 */ 351, 439, 35, 22, 35, 35, 0, 39, 341, 49, + /* 2350 */ 35, 49, 39, 379, 0, 35, 39, 0, 351, 35, + /* 2360 */ 0, 49, 39, 49, 35, 391, 0, 393, 379, 35, + /* 2370 */ 22, 21, 487, 22, 22, 487, 21, 487, 20, 487, /* 2380 */ 391, 487, 393, 487, 487, 487, 379, 487, 487, 487, /* 2390 */ 487, 487, 487, 487, 487, 341, 487, 487, 391, 487, /* 2400 */ 393, 427, 487, 429, 487, 351, 432, 433, 434, 435, @@ -829,55 +823,55 @@ static const YYCODETYPE yy_lookahead[] = { /* 3180 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, /* 3190 */ 338, 338, 338, 338, 338, 338, }; -#define YY_SHIFT_COUNT (799) +#define YY_SHIFT_COUNT (801) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2364) +#define YY_SHIFT_MAX (2366) static const unsigned short int yy_shift_ofst[] = { /* 0 */ 1005, 0, 104, 0, 337, 337, 337, 337, 337, 337, /* 10 */ 337, 337, 337, 337, 337, 337, 441, 673, 673, 777, /* 20 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, /* 30 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, /* 40 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, - /* 50 */ 673, 60, 259, 393, 629, 111, 739, 111, 629, 629, - /* 60 */ 111, 1341, 111, 1341, 1341, 66, 111, 68, 781, 101, - /* 70 */ 101, 781, 13, 13, 113, 294, 23, 23, 101, 101, - /* 80 */ 101, 101, 101, 101, 101, 101, 101, 101, 158, 101, - /* 90 */ 101, 211, 68, 101, 101, 285, 68, 101, 158, 101, - /* 100 */ 158, 68, 101, 101, 68, 101, 68, 68, 68, 101, - /* 110 */ 284, 1004, 15, 15, 303, 462, 1302, 1302, 1302, 1302, + /* 50 */ 673, 18, 259, 393, 29, 428, 701, 428, 29, 29, + /* 60 */ 428, 1341, 428, 1341, 1341, 66, 428, 93, 143, 158, + /* 70 */ 158, 143, 13, 13, 331, 294, 23, 23, 158, 158, + /* 80 */ 158, 158, 158, 158, 158, 158, 158, 158, 195, 158, + /* 90 */ 158, 243, 93, 158, 158, 309, 93, 158, 195, 158, + /* 100 */ 195, 93, 158, 158, 93, 158, 93, 93, 93, 158, + /* 110 */ 473, 1004, 15, 15, 303, 462, 1302, 1302, 1302, 1302, /* 120 */ 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, - /* 130 */ 1302, 1302, 1302, 1302, 1302, 1072, 18, 113, 294, 802, - /* 140 */ 802, 184, 346, 346, 346, 705, 312, 312, 184, 211, - /* 150 */ 254, 260, 68, 534, 68, 534, 534, 836, 619, 28, + /* 130 */ 1302, 1302, 1302, 1302, 1302, 1072, 194, 331, 294, 833, + /* 140 */ 833, 184, 564, 564, 564, 101, 291, 291, 184, 243, + /* 150 */ 284, 251, 93, 454, 93, 454, 454, 483, 619, 28, /* 160 */ 28, 28, 28, 28, 28, 28, 28, 1987, 757, 261, - /* 170 */ 580, 613, 508, 49, 123, 343, 343, 526, 354, 1007, - /* 180 */ 299, 1079, 1192, 418, 398, 1085, 916, 939, 785, 916, - /* 190 */ 1177, 325, 290, 1162, 1369, 1407, 1223, 211, 1407, 211, - /* 200 */ 1242, 1435, 1416, 1450, 1435, 1416, 1306, 1460, 1435, 1460, - /* 210 */ 1416, 1306, 1306, 1389, 1393, 1460, 1402, 1460, 1460, 1460, - /* 220 */ 1490, 1468, 1490, 1468, 1407, 211, 1503, 211, 1508, 1511, - /* 230 */ 211, 1508, 211, 211, 211, 1460, 211, 1490, 68, 68, - /* 240 */ 68, 68, 68, 68, 68, 68, 68, 68, 68, 1460, - /* 250 */ 1490, 534, 534, 534, 1343, 1452, 1407, 284, 1360, 1366, - /* 260 */ 1503, 284, 1394, 1162, 1460, 1450, 1450, 534, 1330, 1339, - /* 270 */ 534, 1330, 1339, 534, 534, 68, 1326, 1439, 1330, 1344, - /* 280 */ 1350, 1364, 1162, 1345, 1354, 1352, 1373, 1435, 1627, 1508, - /* 290 */ 284, 284, 1631, 1339, 534, 534, 534, 534, 534, 1339, - /* 300 */ 534, 1505, 284, 836, 284, 1435, 1591, 1593, 534, 619, - /* 310 */ 1460, 284, 1667, 1490, 2858, 2858, 2858, 2858, 2858, 2858, + /* 170 */ 580, 613, 508, 49, 521, 343, 343, 492, 784, 754, + /* 180 */ 872, 1038, 1129, 875, 323, 1039, 939, 990, 924, 939, + /* 190 */ 1140, 955, 817, 1144, 1365, 1395, 1212, 243, 1395, 243, + /* 200 */ 1238, 1422, 1401, 1429, 1422, 1401, 1287, 1443, 1422, 1443, + /* 210 */ 1401, 1287, 1287, 1380, 1386, 1443, 1390, 1443, 1443, 1443, + /* 220 */ 1470, 1459, 1470, 1459, 1395, 243, 1496, 243, 1497, 1502, + /* 230 */ 243, 1497, 243, 243, 243, 1443, 243, 1470, 93, 93, + /* 240 */ 93, 93, 93, 93, 93, 93, 93, 93, 93, 1443, + /* 250 */ 1470, 454, 454, 454, 1344, 1442, 1395, 473, 1358, 1376, + /* 260 */ 1496, 473, 1394, 1144, 1443, 1429, 1429, 454, 1330, 1339, + /* 270 */ 454, 1330, 1339, 454, 454, 93, 1342, 1438, 1330, 1348, + /* 280 */ 1350, 1367, 1144, 1347, 1349, 1364, 1388, 1422, 1617, 1497, + /* 290 */ 473, 473, 1634, 1339, 454, 454, 454, 454, 454, 1339, + /* 300 */ 454, 1509, 473, 483, 473, 1422, 1591, 1597, 454, 619, + /* 310 */ 1443, 473, 1670, 1470, 2858, 2858, 2858, 2858, 2858, 2858, /* 320 */ 2858, 2858, 2858, 1002, 1074, 225, 32, 736, 750, 860, - /* 330 */ 687, 980, 1356, 434, 791, 197, 197, 197, 197, 197, - /* 340 */ 197, 197, 197, 197, 749, 265, 698, 698, 29, 6, - /* 350 */ 34, 307, 830, 562, 963, 902, 514, 282, 282, 1097, - /* 360 */ 728, 971, 1097, 1097, 1097, 983, 1044, 622, 1209, 1198, - /* 370 */ 1131, 1077, 1143, 1149, 1156, 1160, 1236, 1256, 815, 1182, - /* 380 */ 1275, 1071, 1195, 1224, 63, 1232, 1237, 1262, 1152, 1124, - /* 390 */ 1094, 1263, 1277, 1278, 1282, 1285, 1286, 1332, 1291, 1220, - /* 400 */ 1295, 311, 1305, 1315, 1335, 1340, 1349, 1353, 1206, 1270, - /* 410 */ 1288, 1372, 1378, 409, 1351, 1709, 1738, 1745, 1704, 1749, + /* 330 */ 687, 980, 1356, 434, 806, 197, 197, 197, 197, 197, + /* 340 */ 197, 197, 197, 197, 575, 265, 870, 870, 648, 6, + /* 350 */ 516, 307, 713, 1077, 1095, 512, 280, 282, 282, 710, + /* 360 */ 201, 793, 710, 710, 710, 1208, 1021, 1171, 1209, 1170, + /* 370 */ 1099, 1237, 1123, 1132, 1149, 1159, 1092, 1232, 1246, 1258, + /* 380 */ 1270, 1012, 1184, 1217, 1214, 1247, 1255, 1262, 1157, 1106, + /* 390 */ 1101, 1263, 1278, 1282, 1285, 1286, 1289, 1333, 1292, 1172, + /* 400 */ 1295, 602, 1305, 1335, 1340, 1353, 1354, 1368, 255, 1236, + /* 410 */ 1260, 1343, 1378, 1218, 610, 1707, 1738, 1741, 1704, 1749, /* 420 */ 1715, 1535, 1717, 1720, 1722, 1542, 1759, 1725, 1726, 1546, /* 430 */ 1764, 1549, 1766, 1734, 1770, 1750, 1771, 1739, 1565, 1784, - /* 440 */ 1587, 1788, 1590, 1594, 1600, 1610, 1806, 1807, 1808, 1622, + /* 440 */ 1587, 1788, 1590, 1593, 1601, 1610, 1806, 1807, 1808, 1622, /* 450 */ 1624, 1811, 1812, 1769, 1813, 1817, 1818, 1774, 1822, 1781, /* 460 */ 1825, 1826, 1828, 1783, 1831, 1832, 1833, 1835, 1836, 1837, /* 470 */ 1679, 1805, 1843, 1691, 1852, 1853, 1855, 1857, 1858, 1859, @@ -906,13 +900,14 @@ static const unsigned short int yy_shift_ofst[] = { /* 700 */ 2126, 2122, 2127, 2128, 2156, 2131, 2132, 2175, 2133, 2199, /* 710 */ 2038, 2135, 2109, 2136, 2189, 2192, 2138, 2141, 2201, 2154, /* 720 */ 2142, 2204, 2155, 2151, 2224, 2157, 2158, 2226, 2163, 2160, - /* 730 */ 2230, 2168, 2153, 2159, 2164, 2165, 2177, 2238, 2183, 2248, - /* 740 */ 2184, 2238, 2238, 2263, 2219, 2223, 2257, 2259, 2261, 2262, - /* 750 */ 2264, 2265, 2266, 2267, 2228, 2208, 2254, 2272, 2273, 2282, - /* 760 */ 2296, 2284, 2285, 2286, 2247, 1983, 2288, 1985, 2289, 2291, - /* 770 */ 2292, 2293, 2310, 2298, 2342, 2308, 2295, 2306, 2346, 2312, - /* 780 */ 2300, 2313, 2350, 2316, 2305, 2317, 2355, 2322, 2314, 2320, - /* 790 */ 2360, 2326, 2327, 2364, 2344, 2348, 2349, 2351, 2353, 2352, + /* 730 */ 2230, 2168, 2159, 2164, 2165, 2166, 2256, 2167, 2177, 2239, + /* 740 */ 2181, 2251, 2184, 2239, 2239, 2266, 2220, 2228, 2259, 2262, + /* 750 */ 2263, 2264, 2265, 2267, 2268, 2270, 2232, 2211, 2257, 2282, + /* 760 */ 2283, 2284, 2298, 2286, 2287, 2288, 2249, 1983, 2291, 1985, + /* 770 */ 2292, 2293, 2297, 2307, 2321, 2309, 2333, 2310, 2300, 2308, + /* 780 */ 2346, 2315, 2302, 2313, 2354, 2320, 2312, 2317, 2357, 2324, + /* 790 */ 2314, 2323, 2360, 2329, 2334, 2366, 2348, 2350, 2351, 2352, + /* 800 */ 2355, 2358, }; #define YY_REDUCE_COUNT (322) #define YY_REDUCE_MIN (-404) @@ -923,116 +918,117 @@ static const short yy_reduce_ofst[] = { /* 20 */ 1346, 1363, 1436, 1412, 1463, 1483, 426, 1550, 1580, 1639, /* 30 */ 1712, 1743, 1778, 1815, 1840, 1877, 1902, 1974, 1989, 2007, /* 40 */ 2054, 2076, 2123, 2182, 2195, 2212, 2244, 2311, 2331, 2401, - /* 50 */ 2418, -260, -25, 239, 149, -404, 246, 479, -28, 348, - /* 60 */ 643, -365, -294, -331, 671, -98, 24, 252, -390, -345, - /* 70 */ -265, -279, -72, 74, -318, 227, -342, 112, -232, 26, - /* 80 */ 192, 263, 341, 374, 383, 400, 424, 436, 286, 592, - /* 90 */ 595, 674, 116, 601, 675, 36, 323, 679, 391, 752, - /* 100 */ 637, -63, 765, 776, 555, 779, 429, 672, 669, 822, - /* 110 */ 155, -316, -313, -313, -259, -140, -199, -188, 157, 269, - /* 120 */ 427, 529, 548, 553, 656, 723, 726, 796, 803, 804, - /* 130 */ 809, 844, 845, 855, 867, -217, -242, -15, 438, 523, - /* 140 */ 680, 616, -242, 167, 199, -250, 366, 696, 778, 825, - /* 150 */ -375, -47, 93, 575, 818, 811, 823, 841, 864, -371, - /* 160 */ -328, 356, 491, 515, 579, 681, 515, 711, 847, 956, - /* 170 */ 910, 827, 829, 1006, 888, 1008, 1020, 1009, 986, 1009, - /* 180 */ 1046, 997, 1055, 1054, 1018, 1011, 954, 954, 937, 954, - /* 190 */ 965, 959, 1009, 1010, 998, 1021, 1023, 1073, 1025, 1091, - /* 200 */ 1040, 1105, 1075, 1076, 1121, 1081, 1078, 1134, 1135, 1137, - /* 210 */ 1087, 1092, 1093, 1128, 1132, 1147, 1146, 1161, 1163, 1164, - /* 220 */ 1169, 1170, 1175, 1174, 1101, 1165, 1136, 1168, 1178, 1120, - /* 230 */ 1176, 1184, 1179, 1180, 1181, 1191, 1183, 1200, 1166, 1167, - /* 240 */ 1171, 1173, 1187, 1188, 1189, 1190, 1193, 1194, 1196, 1197, - /* 250 */ 1201, 1172, 1185, 1205, 1129, 1133, 1138, 1203, 1141, 1151, - /* 260 */ 1208, 1214, 1199, 1202, 1238, 1204, 1210, 1211, 1139, 1212, - /* 270 */ 1219, 1148, 1213, 1222, 1225, 1009, 1150, 1153, 1215, 1186, - /* 280 */ 1216, 1221, 1217, 1144, 1218, 1226, 954, 1294, 1228, 1298, - /* 290 */ 1292, 1299, 1250, 1249, 1273, 1287, 1289, 1293, 1300, 1255, - /* 300 */ 1301, 1280, 1329, 1314, 1336, 1348, 1246, 1317, 1310, 1333, - /* 310 */ 1357, 1355, 1362, 1365, 1307, 1313, 1303, 1308, 1367, 1368, - /* 320 */ 1371, 1370, 1388, + /* 50 */ 2418, -260, -25, 239, 149, -404, 246, 643, -28, 480, + /* 60 */ 1080, -365, -294, -331, 671, -339, -98, 252, -390, -345, + /* 70 */ -265, -279, -72, 40, -318, 30, -342, 112, -216, 26, + /* 80 */ 192, 263, -177, 269, 348, 383, 400, 341, 154, 421, + /* 90 */ 450, 561, -261, 520, 579, 36, 230, 601, 576, 615, + /* 100 */ 647, -63, 675, 697, 735, 752, 139, 749, 424, 822, + /* 110 */ -182, -316, -258, -258, -280, -233, -20, 11, 91, 245, + /* 120 */ 257, 466, 537, 642, 686, 722, 724, 725, 803, 805, + /* 130 */ 808, 827, 844, 845, 859, -369, -67, 581, -145, 453, + /* 140 */ 567, 593, -67, 41, 199, 123, 274, 587, 634, 676, + /* 150 */ 20, 594, 677, 653, 732, 751, 814, 765, 772, -380, + /* 160 */ -328, 361, 476, 499, 552, 570, 499, 416, 474, 909, + /* 170 */ 554, 818, 804, 951, 841, 944, 945, 949, 913, 949, + /* 180 */ 987, 959, 1026, 1030, 997, 999, 941, 941, 926, 941, + /* 190 */ 953, 946, 949, 995, 989, 998, 996, 1062, 1003, 1067, + /* 200 */ 1017, 1081, 1048, 1049, 1103, 1057, 1078, 1120, 1122, 1125, + /* 210 */ 1079, 1083, 1084, 1121, 1124, 1137, 1128, 1142, 1147, 1150, + /* 220 */ 1151, 1163, 1168, 1165, 1093, 1154, 1130, 1162, 1166, 1111, + /* 230 */ 1169, 1175, 1174, 1176, 1177, 1179, 1180, 1187, 1152, 1161, + /* 240 */ 1164, 1167, 1173, 1181, 1188, 1189, 1190, 1191, 1192, 1194, + /* 250 */ 1199, 1156, 1182, 1185, 1134, 1127, 1145, 1196, 1143, 1183, + /* 260 */ 1195, 1239, 1193, 1198, 1225, 1200, 1202, 1215, 1138, 1210, + /* 270 */ 1222, 1148, 1211, 1223, 1227, 949, 1153, 1160, 1155, 1186, + /* 280 */ 1213, 1197, 1219, 1135, 1201, 1203, 941, 1298, 1220, 1303, + /* 290 */ 1293, 1299, 1275, 1253, 1273, 1294, 1300, 1301, 1304, 1274, + /* 300 */ 1307, 1281, 1329, 1314, 1336, 1345, 1250, 1318, 1311, 1334, + /* 310 */ 1355, 1351, 1366, 1369, 1312, 1306, 1308, 1315, 1362, 1371, + /* 320 */ 1372, 1382, 1370, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 10 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 20 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 30 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 40 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 50 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 60 */ 2091, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 70 */ 1780, 1780, 1780, 1780, 2064, 1780, 1780, 1780, 1780, 1780, - /* 80 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 90 */ 1780, 1869, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 100 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 110 */ 1867, 2057, 2283, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 120 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 130 */ 1780, 1780, 1780, 1780, 1780, 1780, 2295, 1780, 1780, 1843, - /* 140 */ 1843, 1780, 2295, 2295, 2295, 1867, 2255, 2255, 1780, 1869, - /* 150 */ 2125, 1780, 1780, 1780, 1780, 1780, 1780, 1989, 1780, 1780, - /* 160 */ 1780, 1780, 1780, 2013, 1780, 1780, 1780, 2117, 1780, 1780, - /* 170 */ 2320, 2377, 1780, 1780, 2323, 1780, 1780, 1780, 1780, 1780, - /* 180 */ 1780, 2069, 1780, 1780, 1942, 2310, 2287, 2301, 2361, 2288, - /* 190 */ 2285, 2304, 1780, 2314, 1780, 1780, 2139, 1869, 1780, 1869, - /* 200 */ 2104, 1780, 2062, 1780, 1780, 2062, 2059, 1780, 1780, 1780, - /* 210 */ 2062, 2059, 2059, 1931, 1927, 1780, 1925, 1780, 1780, 1780, - /* 220 */ 1780, 1827, 1780, 1827, 1780, 1869, 1780, 1869, 1780, 1780, - /* 230 */ 1869, 1780, 1869, 1869, 1869, 1780, 1869, 1780, 1780, 1780, - /* 240 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 250 */ 1780, 1780, 1780, 1780, 2137, 2123, 1780, 1867, 2115, 2113, - /* 260 */ 1780, 1867, 2111, 2314, 1780, 1780, 1780, 1780, 2331, 2329, - /* 270 */ 1780, 2331, 2329, 1780, 1780, 1780, 2345, 2341, 2331, 2350, - /* 280 */ 2347, 2316, 2314, 2380, 2367, 2363, 2301, 1780, 1780, 1780, - /* 290 */ 1867, 1867, 1780, 2329, 1780, 1780, 1780, 1780, 1780, 2329, - /* 300 */ 1780, 1780, 1867, 1780, 1867, 1780, 1780, 1958, 1780, 1780, - /* 310 */ 1780, 1867, 1812, 1780, 2106, 2128, 2087, 2087, 1992, 1992, - /* 320 */ 1992, 1870, 1785, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 330 */ 1780, 1780, 1780, 1780, 1780, 2344, 2343, 2210, 1780, 2259, - /* 340 */ 2258, 2257, 2248, 2209, 1954, 1780, 2208, 2207, 1780, 1780, - /* 350 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 2078, 2077, 2201, - /* 360 */ 1780, 1780, 2202, 2200, 2199, 1780, 1780, 1780, 1780, 1780, - /* 370 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 380 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 2364, - /* 390 */ 2368, 1780, 1780, 1780, 1780, 1780, 1780, 2284, 1780, 1780, - /* 400 */ 1780, 2183, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 410 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 420 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 430 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 440 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 450 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 460 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 470 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 480 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 490 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 500 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 510 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 520 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 530 */ 1780, 1780, 1780, 1780, 1780, 1817, 2188, 1780, 1780, 1780, - /* 540 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 550 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 560 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 570 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 580 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1908, 1907, 1780, - /* 590 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 600 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 610 */ 1780, 2192, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 620 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 630 */ 2360, 2317, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 640 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 650 */ 2183, 1780, 2342, 1780, 1780, 2358, 1780, 2362, 1780, 1780, - /* 660 */ 1780, 1780, 1780, 1780, 1780, 2294, 2290, 1780, 1780, 2286, - /* 670 */ 1780, 1780, 1780, 1780, 1780, 2191, 1780, 1780, 1780, 1780, - /* 680 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 2182, - /* 690 */ 1780, 2245, 1780, 1780, 1780, 2279, 1780, 1780, 2230, 1780, - /* 700 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 2192, 1780, - /* 710 */ 2195, 1780, 1780, 1780, 1780, 1780, 1986, 1780, 1780, 1780, - /* 720 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 730 */ 1780, 1780, 1970, 1968, 1967, 1966, 1780, 1999, 1780, 1780, - /* 740 */ 1780, 1995, 1994, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 750 */ 1780, 1780, 1780, 1780, 1780, 1780, 1888, 1780, 1780, 1780, - /* 760 */ 1780, 1780, 1780, 1780, 1780, 1880, 1780, 1879, 1780, 1780, - /* 770 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 780 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, - /* 790 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 0 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 10 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 20 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 30 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 40 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 50 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 60 */ 2095, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 70 */ 1783, 1783, 1783, 1783, 2068, 1783, 1783, 1783, 1783, 1783, + /* 80 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 90 */ 1783, 1872, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 100 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 110 */ 1870, 2061, 2287, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 120 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 130 */ 1783, 1783, 1783, 1783, 1783, 1783, 2299, 1783, 1783, 1846, + /* 140 */ 1846, 1783, 2299, 2299, 2299, 1870, 2259, 2259, 1783, 1872, + /* 150 */ 2129, 1783, 1783, 1783, 1783, 1783, 1783, 1993, 1783, 1783, + /* 160 */ 1783, 1783, 1783, 2017, 1783, 1783, 1783, 2121, 1783, 1783, + /* 170 */ 2324, 2381, 1783, 1783, 2327, 1783, 1783, 1783, 1783, 1783, + /* 180 */ 1783, 2073, 1783, 1783, 1945, 2314, 2291, 2305, 2365, 2292, + /* 190 */ 2289, 2308, 1783, 2318, 1783, 1783, 2143, 1872, 1783, 1872, + /* 200 */ 2108, 1783, 2066, 1783, 1783, 2066, 2063, 1783, 1783, 1783, + /* 210 */ 2066, 2063, 2063, 1934, 1930, 1783, 1928, 1783, 1783, 1783, + /* 220 */ 1783, 1830, 1783, 1830, 1783, 1872, 1783, 1872, 1783, 1783, + /* 230 */ 1872, 1783, 1872, 1872, 1872, 1783, 1872, 1783, 1783, 1783, + /* 240 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 250 */ 1783, 1783, 1783, 1783, 2141, 2127, 1783, 1870, 2119, 2117, + /* 260 */ 1783, 1870, 2115, 2318, 1783, 1783, 1783, 1783, 2335, 2333, + /* 270 */ 1783, 2335, 2333, 1783, 1783, 1783, 2349, 2345, 2335, 2354, + /* 280 */ 2351, 2320, 2318, 2384, 2371, 2367, 2305, 1783, 1783, 1783, + /* 290 */ 1870, 1870, 1783, 2333, 1783, 1783, 1783, 1783, 1783, 2333, + /* 300 */ 1783, 1783, 1870, 1783, 1870, 1783, 1783, 1961, 1783, 1783, + /* 310 */ 1783, 1870, 1815, 1783, 2110, 2132, 2091, 2091, 1996, 1996, + /* 320 */ 1996, 1873, 1788, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 330 */ 1783, 1783, 1783, 1783, 1783, 2348, 2347, 2214, 1783, 2263, + /* 340 */ 2262, 2261, 2252, 2213, 1957, 1783, 2212, 2211, 1783, 1783, + /* 350 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2082, 2081, 2205, + /* 360 */ 1783, 1783, 2206, 2204, 2203, 1783, 1783, 1783, 1783, 1783, + /* 370 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 380 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2368, + /* 390 */ 2372, 1783, 1783, 1783, 1783, 1783, 1783, 2288, 1783, 1783, + /* 400 */ 1783, 2187, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 410 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 420 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 430 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 440 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 450 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 460 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 470 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 480 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 490 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 500 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 510 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 520 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 530 */ 1783, 1783, 1783, 1783, 1783, 1820, 2192, 1783, 1783, 1783, + /* 540 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 550 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 560 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 570 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 580 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1911, 1910, 1783, + /* 590 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 600 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 610 */ 1783, 2196, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 620 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 630 */ 2364, 2321, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 640 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 650 */ 2187, 1783, 2346, 1783, 1783, 2362, 1783, 2366, 1783, 1783, + /* 660 */ 1783, 1783, 1783, 1783, 1783, 2298, 2294, 1783, 1783, 2290, + /* 670 */ 1783, 1783, 1783, 1783, 1783, 2195, 1783, 1783, 1783, 1783, + /* 680 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2186, + /* 690 */ 1783, 2249, 1783, 1783, 1783, 2283, 1783, 1783, 2234, 1783, + /* 700 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2196, 1783, + /* 710 */ 2199, 1783, 1783, 1783, 1783, 1783, 1990, 1783, 1783, 1783, + /* 720 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 730 */ 1783, 1783, 1974, 1972, 1971, 1970, 1783, 1967, 1783, 2003, + /* 740 */ 1783, 1783, 1783, 1999, 1998, 1783, 1783, 1783, 1783, 1783, + /* 750 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1891, 1783, + /* 760 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1883, 1783, 1882, + /* 770 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 780 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 790 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, + /* 800 */ 1783, 1783, }; /********** End of lemon-generated parsing tables *****************************/ @@ -1167,6 +1163,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* NK_EQ => nothing */ 0, /* USING => nothing */ 0, /* TAGS => nothing */ + 0, /* COMMENT => nothing */ 0, /* BOOL => nothing */ 0, /* TINYINT => nothing */ 0, /* SMALLINT => nothing */ @@ -1185,7 +1182,6 @@ static const YYCODETYPE yyFallback[] = { 0, /* VARBINARY => nothing */ 0, /* GEOMETRY => nothing */ 0, /* DECIMAL => nothing */ - 0, /* COMMENT => nothing */ 0, /* MAX_DELAY => nothing */ 0, /* WATERMARK => nothing */ 0, /* ROLLUP => nothing */ @@ -1443,6 +1439,7 @@ typedef struct yyParser yyParser; #ifndef NDEBUG #include +#include static FILE *yyTraceFILE = 0; static char *yyTracePrompt = 0; #endif /* NDEBUG */ @@ -1592,25 +1589,25 @@ static const char *const yyTokenName[] = { /* 112 */ "NK_EQ", /* 113 */ "USING", /* 114 */ "TAGS", - /* 115 */ "BOOL", - /* 116 */ "TINYINT", - /* 117 */ "SMALLINT", - /* 118 */ "INT", - /* 119 */ "INTEGER", - /* 120 */ "BIGINT", - /* 121 */ "FLOAT", - /* 122 */ "DOUBLE", - /* 123 */ "BINARY", - /* 124 */ "NCHAR", - /* 125 */ "UNSIGNED", - /* 126 */ "JSON", - /* 127 */ "VARCHAR", - /* 128 */ "MEDIUMBLOB", - /* 129 */ "BLOB", - /* 130 */ "VARBINARY", - /* 131 */ "GEOMETRY", - /* 132 */ "DECIMAL", - /* 133 */ "COMMENT", + /* 115 */ "COMMENT", + /* 116 */ "BOOL", + /* 117 */ "TINYINT", + /* 118 */ "SMALLINT", + /* 119 */ "INT", + /* 120 */ "INTEGER", + /* 121 */ "BIGINT", + /* 122 */ "FLOAT", + /* 123 */ "DOUBLE", + /* 124 */ "BINARY", + /* 125 */ "NCHAR", + /* 126 */ "UNSIGNED", + /* 127 */ "JSON", + /* 128 */ "VARCHAR", + /* 129 */ "MEDIUMBLOB", + /* 130 */ "BLOB", + /* 131 */ "VARBINARY", + /* 132 */ "GEOMETRY", + /* 133 */ "DECIMAL", /* 134 */ "MAX_DELAY", /* 135 */ "WATERMARK", /* 136 */ "ROLLUP", @@ -2153,424 +2150,425 @@ static const char *const yyRuleName[] = { /* 179 */ "column_def_list ::= column_def", /* 180 */ "column_def_list ::= column_def_list NK_COMMA column_def", /* 181 */ "column_def ::= column_name type_name", - /* 182 */ "type_name ::= BOOL", - /* 183 */ "type_name ::= TINYINT", - /* 184 */ "type_name ::= SMALLINT", - /* 185 */ "type_name ::= INT", - /* 186 */ "type_name ::= INTEGER", - /* 187 */ "type_name ::= BIGINT", - /* 188 */ "type_name ::= FLOAT", - /* 189 */ "type_name ::= DOUBLE", - /* 190 */ "type_name ::= BINARY NK_LP NK_INTEGER NK_RP", - /* 191 */ "type_name ::= TIMESTAMP", - /* 192 */ "type_name ::= NCHAR NK_LP NK_INTEGER NK_RP", - /* 193 */ "type_name ::= TINYINT UNSIGNED", - /* 194 */ "type_name ::= SMALLINT UNSIGNED", - /* 195 */ "type_name ::= INT UNSIGNED", - /* 196 */ "type_name ::= BIGINT UNSIGNED", - /* 197 */ "type_name ::= JSON", - /* 198 */ "type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP", - /* 199 */ "type_name ::= MEDIUMBLOB", - /* 200 */ "type_name ::= BLOB", - /* 201 */ "type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP", - /* 202 */ "type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP", - /* 203 */ "type_name ::= DECIMAL", - /* 204 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP", - /* 205 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP", - /* 206 */ "tags_def_opt ::=", - /* 207 */ "tags_def_opt ::= tags_def", - /* 208 */ "tags_def ::= TAGS NK_LP column_def_list NK_RP", - /* 209 */ "table_options ::=", - /* 210 */ "table_options ::= table_options COMMENT NK_STRING", - /* 211 */ "table_options ::= table_options MAX_DELAY duration_list", - /* 212 */ "table_options ::= table_options WATERMARK duration_list", - /* 213 */ "table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP", - /* 214 */ "table_options ::= table_options TTL NK_INTEGER", - /* 215 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP", - /* 216 */ "table_options ::= table_options DELETE_MARK duration_list", - /* 217 */ "alter_table_options ::= alter_table_option", - /* 218 */ "alter_table_options ::= alter_table_options alter_table_option", - /* 219 */ "alter_table_option ::= COMMENT NK_STRING", - /* 220 */ "alter_table_option ::= TTL NK_INTEGER", - /* 221 */ "duration_list ::= duration_literal", - /* 222 */ "duration_list ::= duration_list NK_COMMA duration_literal", - /* 223 */ "rollup_func_list ::= rollup_func_name", - /* 224 */ "rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name", - /* 225 */ "rollup_func_name ::= function_name", - /* 226 */ "rollup_func_name ::= FIRST", - /* 227 */ "rollup_func_name ::= LAST", - /* 228 */ "col_name_list ::= col_name", - /* 229 */ "col_name_list ::= col_name_list NK_COMMA col_name", - /* 230 */ "col_name ::= column_name", - /* 231 */ "cmd ::= SHOW DNODES", - /* 232 */ "cmd ::= SHOW USERS", - /* 233 */ "cmd ::= SHOW USER PRIVILEGES", - /* 234 */ "cmd ::= SHOW DATABASES", - /* 235 */ "cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt", - /* 236 */ "cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt", - /* 237 */ "cmd ::= SHOW db_name_cond_opt VGROUPS", - /* 238 */ "cmd ::= SHOW MNODES", - /* 239 */ "cmd ::= SHOW QNODES", - /* 240 */ "cmd ::= SHOW FUNCTIONS", - /* 241 */ "cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt", - /* 242 */ "cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name", - /* 243 */ "cmd ::= SHOW STREAMS", - /* 244 */ "cmd ::= SHOW ACCOUNTS", - /* 245 */ "cmd ::= SHOW APPS", - /* 246 */ "cmd ::= SHOW CONNECTIONS", - /* 247 */ "cmd ::= SHOW LICENCES", - /* 248 */ "cmd ::= SHOW GRANTS", - /* 249 */ "cmd ::= SHOW CREATE DATABASE db_name", - /* 250 */ "cmd ::= SHOW CREATE TABLE full_table_name", - /* 251 */ "cmd ::= SHOW CREATE STABLE full_table_name", - /* 252 */ "cmd ::= SHOW QUERIES", - /* 253 */ "cmd ::= SHOW SCORES", - /* 254 */ "cmd ::= SHOW TOPICS", - /* 255 */ "cmd ::= SHOW VARIABLES", - /* 256 */ "cmd ::= SHOW CLUSTER VARIABLES", - /* 257 */ "cmd ::= SHOW LOCAL VARIABLES", - /* 258 */ "cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt", - /* 259 */ "cmd ::= SHOW BNODES", - /* 260 */ "cmd ::= SHOW SNODES", - /* 261 */ "cmd ::= SHOW CLUSTER", - /* 262 */ "cmd ::= SHOW TRANSACTIONS", - /* 263 */ "cmd ::= SHOW TABLE DISTRIBUTED full_table_name", - /* 264 */ "cmd ::= SHOW CONSUMERS", - /* 265 */ "cmd ::= SHOW SUBSCRIPTIONS", - /* 266 */ "cmd ::= SHOW TAGS FROM table_name_cond from_db_opt", - /* 267 */ "cmd ::= SHOW TAGS FROM db_name NK_DOT table_name", - /* 268 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt", - /* 269 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name", - /* 270 */ "cmd ::= SHOW VNODES NK_INTEGER", - /* 271 */ "cmd ::= SHOW VNODES NK_STRING", - /* 272 */ "cmd ::= SHOW db_name_cond_opt ALIVE", - /* 273 */ "cmd ::= SHOW CLUSTER ALIVE", - /* 274 */ "db_name_cond_opt ::=", - /* 275 */ "db_name_cond_opt ::= db_name NK_DOT", - /* 276 */ "like_pattern_opt ::=", - /* 277 */ "like_pattern_opt ::= LIKE NK_STRING", - /* 278 */ "table_name_cond ::= table_name", - /* 279 */ "from_db_opt ::=", - /* 280 */ "from_db_opt ::= FROM db_name", - /* 281 */ "tag_list_opt ::=", - /* 282 */ "tag_list_opt ::= tag_item", - /* 283 */ "tag_list_opt ::= tag_list_opt NK_COMMA tag_item", - /* 284 */ "tag_item ::= TBNAME", - /* 285 */ "tag_item ::= QTAGS", - /* 286 */ "tag_item ::= column_name", - /* 287 */ "tag_item ::= column_name column_alias", - /* 288 */ "tag_item ::= column_name AS column_alias", - /* 289 */ "cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options", - /* 290 */ "cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP", - /* 291 */ "cmd ::= DROP INDEX exists_opt full_index_name", - /* 292 */ "full_index_name ::= index_name", - /* 293 */ "full_index_name ::= db_name NK_DOT index_name", - /* 294 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt", - /* 295 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt", - /* 296 */ "func_list ::= func", - /* 297 */ "func_list ::= func_list NK_COMMA func", - /* 298 */ "func ::= sma_func_name NK_LP expression_list NK_RP", - /* 299 */ "sma_func_name ::= function_name", - /* 300 */ "sma_func_name ::= COUNT", - /* 301 */ "sma_func_name ::= FIRST", - /* 302 */ "sma_func_name ::= LAST", - /* 303 */ "sma_func_name ::= LAST_ROW", - /* 304 */ "sma_stream_opt ::=", - /* 305 */ "sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal", - /* 306 */ "sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal", - /* 307 */ "sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal", - /* 308 */ "with_meta ::= AS", - /* 309 */ "with_meta ::= WITH META AS", - /* 310 */ "with_meta ::= ONLY META AS", - /* 311 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery", - /* 312 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name", - /* 313 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt", - /* 314 */ "cmd ::= DROP TOPIC exists_opt topic_name", - /* 315 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", - /* 316 */ "cmd ::= DESC full_table_name", - /* 317 */ "cmd ::= DESCRIBE full_table_name", - /* 318 */ "cmd ::= RESET QUERY CACHE", - /* 319 */ "cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery", - /* 320 */ "cmd ::= EXPLAIN analyze_opt explain_options insert_query", - /* 321 */ "analyze_opt ::=", - /* 322 */ "analyze_opt ::= ANALYZE", - /* 323 */ "explain_options ::=", - /* 324 */ "explain_options ::= explain_options VERBOSE NK_BOOL", - /* 325 */ "explain_options ::= explain_options RATIO NK_FLOAT", - /* 326 */ "cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt", - /* 327 */ "cmd ::= DROP FUNCTION exists_opt function_name", - /* 328 */ "agg_func_opt ::=", - /* 329 */ "agg_func_opt ::= AGGREGATE", - /* 330 */ "bufsize_opt ::=", - /* 331 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", - /* 332 */ "language_opt ::=", - /* 333 */ "language_opt ::= LANGUAGE NK_STRING", - /* 334 */ "or_replace_opt ::=", - /* 335 */ "or_replace_opt ::= OR REPLACE", - /* 336 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery", - /* 337 */ "cmd ::= DROP STREAM exists_opt stream_name", - /* 338 */ "cmd ::= PAUSE STREAM exists_opt stream_name", - /* 339 */ "cmd ::= RESUME STREAM exists_opt ignore_opt stream_name", - /* 340 */ "col_list_opt ::=", - /* 341 */ "col_list_opt ::= NK_LP col_name_list NK_RP", - /* 342 */ "tag_def_or_ref_opt ::=", - /* 343 */ "tag_def_or_ref_opt ::= tags_def", - /* 344 */ "tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP", - /* 345 */ "stream_options ::=", - /* 346 */ "stream_options ::= stream_options TRIGGER AT_ONCE", - /* 347 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", - /* 348 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", - /* 349 */ "stream_options ::= stream_options WATERMARK duration_literal", - /* 350 */ "stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER", - /* 351 */ "stream_options ::= stream_options FILL_HISTORY NK_INTEGER", - /* 352 */ "stream_options ::= stream_options DELETE_MARK duration_literal", - /* 353 */ "stream_options ::= stream_options IGNORE UPDATE NK_INTEGER", - /* 354 */ "subtable_opt ::=", - /* 355 */ "subtable_opt ::= SUBTABLE NK_LP expression NK_RP", - /* 356 */ "ignore_opt ::=", - /* 357 */ "ignore_opt ::= IGNORE UNTREATED", - /* 358 */ "cmd ::= KILL CONNECTION NK_INTEGER", - /* 359 */ "cmd ::= KILL QUERY NK_STRING", - /* 360 */ "cmd ::= KILL TRANSACTION NK_INTEGER", - /* 361 */ "cmd ::= BALANCE VGROUP", - /* 362 */ "cmd ::= BALANCE VGROUP LEADER", - /* 363 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", - /* 364 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", - /* 365 */ "cmd ::= SPLIT VGROUP NK_INTEGER", - /* 366 */ "dnode_list ::= DNODE NK_INTEGER", - /* 367 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", - /* 368 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", - /* 369 */ "cmd ::= query_or_subquery", - /* 370 */ "cmd ::= insert_query", - /* 371 */ "insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery", - /* 372 */ "insert_query ::= INSERT INTO full_table_name query_or_subquery", - /* 373 */ "literal ::= NK_INTEGER", - /* 374 */ "literal ::= NK_FLOAT", - /* 375 */ "literal ::= NK_STRING", - /* 376 */ "literal ::= NK_BOOL", - /* 377 */ "literal ::= TIMESTAMP NK_STRING", - /* 378 */ "literal ::= duration_literal", - /* 379 */ "literal ::= NULL", - /* 380 */ "literal ::= NK_QUESTION", - /* 381 */ "duration_literal ::= NK_VARIABLE", - /* 382 */ "signed ::= NK_INTEGER", - /* 383 */ "signed ::= NK_PLUS NK_INTEGER", - /* 384 */ "signed ::= NK_MINUS NK_INTEGER", - /* 385 */ "signed ::= NK_FLOAT", - /* 386 */ "signed ::= NK_PLUS NK_FLOAT", - /* 387 */ "signed ::= NK_MINUS NK_FLOAT", - /* 388 */ "signed_literal ::= signed", - /* 389 */ "signed_literal ::= NK_STRING", - /* 390 */ "signed_literal ::= NK_BOOL", - /* 391 */ "signed_literal ::= TIMESTAMP NK_STRING", - /* 392 */ "signed_literal ::= duration_literal", - /* 393 */ "signed_literal ::= NULL", - /* 394 */ "signed_literal ::= literal_func", - /* 395 */ "signed_literal ::= NK_QUESTION", - /* 396 */ "literal_list ::= signed_literal", - /* 397 */ "literal_list ::= literal_list NK_COMMA signed_literal", - /* 398 */ "db_name ::= NK_ID", - /* 399 */ "table_name ::= NK_ID", - /* 400 */ "column_name ::= NK_ID", - /* 401 */ "function_name ::= NK_ID", - /* 402 */ "table_alias ::= NK_ID", - /* 403 */ "column_alias ::= NK_ID", - /* 404 */ "user_name ::= NK_ID", - /* 405 */ "topic_name ::= NK_ID", - /* 406 */ "stream_name ::= NK_ID", - /* 407 */ "cgroup_name ::= NK_ID", - /* 408 */ "index_name ::= NK_ID", - /* 409 */ "expr_or_subquery ::= expression", - /* 410 */ "expression ::= literal", - /* 411 */ "expression ::= pseudo_column", - /* 412 */ "expression ::= column_reference", - /* 413 */ "expression ::= function_expression", - /* 414 */ "expression ::= case_when_expression", - /* 415 */ "expression ::= NK_LP expression NK_RP", - /* 416 */ "expression ::= NK_PLUS expr_or_subquery", - /* 417 */ "expression ::= NK_MINUS expr_or_subquery", - /* 418 */ "expression ::= expr_or_subquery NK_PLUS expr_or_subquery", - /* 419 */ "expression ::= expr_or_subquery NK_MINUS expr_or_subquery", - /* 420 */ "expression ::= expr_or_subquery NK_STAR expr_or_subquery", - /* 421 */ "expression ::= expr_or_subquery NK_SLASH expr_or_subquery", - /* 422 */ "expression ::= expr_or_subquery NK_REM expr_or_subquery", - /* 423 */ "expression ::= column_reference NK_ARROW NK_STRING", - /* 424 */ "expression ::= expr_or_subquery NK_BITAND expr_or_subquery", - /* 425 */ "expression ::= expr_or_subquery NK_BITOR expr_or_subquery", - /* 426 */ "expression_list ::= expr_or_subquery", - /* 427 */ "expression_list ::= expression_list NK_COMMA expr_or_subquery", - /* 428 */ "column_reference ::= column_name", - /* 429 */ "column_reference ::= table_name NK_DOT column_name", - /* 430 */ "pseudo_column ::= ROWTS", - /* 431 */ "pseudo_column ::= TBNAME", - /* 432 */ "pseudo_column ::= table_name NK_DOT TBNAME", - /* 433 */ "pseudo_column ::= QSTART", - /* 434 */ "pseudo_column ::= QEND", - /* 435 */ "pseudo_column ::= QDURATION", - /* 436 */ "pseudo_column ::= WSTART", - /* 437 */ "pseudo_column ::= WEND", - /* 438 */ "pseudo_column ::= WDURATION", - /* 439 */ "pseudo_column ::= IROWTS", - /* 440 */ "pseudo_column ::= ISFILLED", - /* 441 */ "pseudo_column ::= QTAGS", - /* 442 */ "function_expression ::= function_name NK_LP expression_list NK_RP", - /* 443 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", - /* 444 */ "function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP", - /* 445 */ "function_expression ::= literal_func", - /* 446 */ "literal_func ::= noarg_func NK_LP NK_RP", - /* 447 */ "literal_func ::= NOW", - /* 448 */ "noarg_func ::= NOW", - /* 449 */ "noarg_func ::= TODAY", - /* 450 */ "noarg_func ::= TIMEZONE", - /* 451 */ "noarg_func ::= DATABASE", - /* 452 */ "noarg_func ::= CLIENT_VERSION", - /* 453 */ "noarg_func ::= SERVER_VERSION", - /* 454 */ "noarg_func ::= SERVER_STATUS", - /* 455 */ "noarg_func ::= CURRENT_USER", - /* 456 */ "noarg_func ::= USER", - /* 457 */ "star_func ::= COUNT", - /* 458 */ "star_func ::= FIRST", - /* 459 */ "star_func ::= LAST", - /* 460 */ "star_func ::= LAST_ROW", - /* 461 */ "star_func_para_list ::= NK_STAR", - /* 462 */ "star_func_para_list ::= other_para_list", - /* 463 */ "other_para_list ::= star_func_para", - /* 464 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", - /* 465 */ "star_func_para ::= expr_or_subquery", - /* 466 */ "star_func_para ::= table_name NK_DOT NK_STAR", - /* 467 */ "case_when_expression ::= CASE when_then_list case_when_else_opt END", - /* 468 */ "case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END", - /* 469 */ "when_then_list ::= when_then_expr", - /* 470 */ "when_then_list ::= when_then_list when_then_expr", - /* 471 */ "when_then_expr ::= WHEN common_expression THEN common_expression", - /* 472 */ "case_when_else_opt ::=", - /* 473 */ "case_when_else_opt ::= ELSE common_expression", - /* 474 */ "predicate ::= expr_or_subquery compare_op expr_or_subquery", - /* 475 */ "predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery", - /* 476 */ "predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery", - /* 477 */ "predicate ::= expr_or_subquery IS NULL", - /* 478 */ "predicate ::= expr_or_subquery IS NOT NULL", - /* 479 */ "predicate ::= expr_or_subquery in_op in_predicate_value", - /* 480 */ "compare_op ::= NK_LT", - /* 481 */ "compare_op ::= NK_GT", - /* 482 */ "compare_op ::= NK_LE", - /* 483 */ "compare_op ::= NK_GE", - /* 484 */ "compare_op ::= NK_NE", - /* 485 */ "compare_op ::= NK_EQ", - /* 486 */ "compare_op ::= LIKE", - /* 487 */ "compare_op ::= NOT LIKE", - /* 488 */ "compare_op ::= MATCH", - /* 489 */ "compare_op ::= NMATCH", - /* 490 */ "compare_op ::= CONTAINS", - /* 491 */ "in_op ::= IN", - /* 492 */ "in_op ::= NOT IN", - /* 493 */ "in_predicate_value ::= NK_LP literal_list NK_RP", - /* 494 */ "boolean_value_expression ::= boolean_primary", - /* 495 */ "boolean_value_expression ::= NOT boolean_primary", - /* 496 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", - /* 497 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", - /* 498 */ "boolean_primary ::= predicate", - /* 499 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", - /* 500 */ "common_expression ::= expr_or_subquery", - /* 501 */ "common_expression ::= boolean_value_expression", - /* 502 */ "from_clause_opt ::=", - /* 503 */ "from_clause_opt ::= FROM table_reference_list", - /* 504 */ "table_reference_list ::= table_reference", - /* 505 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", - /* 506 */ "table_reference ::= table_primary", - /* 507 */ "table_reference ::= joined_table", - /* 508 */ "table_primary ::= table_name alias_opt", - /* 509 */ "table_primary ::= db_name NK_DOT table_name alias_opt", - /* 510 */ "table_primary ::= subquery alias_opt", - /* 511 */ "table_primary ::= parenthesized_joined_table", - /* 512 */ "alias_opt ::=", - /* 513 */ "alias_opt ::= table_alias", - /* 514 */ "alias_opt ::= AS table_alias", - /* 515 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", - /* 516 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", - /* 517 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", - /* 518 */ "join_type ::=", - /* 519 */ "join_type ::= INNER", - /* 520 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt", - /* 521 */ "set_quantifier_opt ::=", - /* 522 */ "set_quantifier_opt ::= DISTINCT", - /* 523 */ "set_quantifier_opt ::= ALL", - /* 524 */ "select_list ::= select_item", - /* 525 */ "select_list ::= select_list NK_COMMA select_item", - /* 526 */ "select_item ::= NK_STAR", - /* 527 */ "select_item ::= common_expression", - /* 528 */ "select_item ::= common_expression column_alias", - /* 529 */ "select_item ::= common_expression AS column_alias", - /* 530 */ "select_item ::= table_name NK_DOT NK_STAR", - /* 531 */ "where_clause_opt ::=", - /* 532 */ "where_clause_opt ::= WHERE search_condition", - /* 533 */ "partition_by_clause_opt ::=", - /* 534 */ "partition_by_clause_opt ::= PARTITION BY partition_list", - /* 535 */ "partition_list ::= partition_item", - /* 536 */ "partition_list ::= partition_list NK_COMMA partition_item", - /* 537 */ "partition_item ::= expr_or_subquery", - /* 538 */ "partition_item ::= expr_or_subquery column_alias", - /* 539 */ "partition_item ::= expr_or_subquery AS column_alias", - /* 540 */ "twindow_clause_opt ::=", - /* 541 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", - /* 542 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP", - /* 543 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", - /* 544 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", - /* 545 */ "twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition", - /* 546 */ "sliding_opt ::=", - /* 547 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", - /* 548 */ "fill_opt ::=", - /* 549 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", - /* 550 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP", - /* 551 */ "fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP", - /* 552 */ "fill_mode ::= NONE", - /* 553 */ "fill_mode ::= PREV", - /* 554 */ "fill_mode ::= NULL", - /* 555 */ "fill_mode ::= NULL_F", - /* 556 */ "fill_mode ::= LINEAR", - /* 557 */ "fill_mode ::= NEXT", - /* 558 */ "group_by_clause_opt ::=", - /* 559 */ "group_by_clause_opt ::= GROUP BY group_by_list", - /* 560 */ "group_by_list ::= expr_or_subquery", - /* 561 */ "group_by_list ::= group_by_list NK_COMMA expr_or_subquery", - /* 562 */ "having_clause_opt ::=", - /* 563 */ "having_clause_opt ::= HAVING search_condition", - /* 564 */ "range_opt ::=", - /* 565 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP", - /* 566 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_RP", - /* 567 */ "every_opt ::=", - /* 568 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", - /* 569 */ "query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt", - /* 570 */ "query_simple ::= query_specification", - /* 571 */ "query_simple ::= union_query_expression", - /* 572 */ "union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery", - /* 573 */ "union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery", - /* 574 */ "query_simple_or_subquery ::= query_simple", - /* 575 */ "query_simple_or_subquery ::= subquery", - /* 576 */ "query_or_subquery ::= query_expression", - /* 577 */ "query_or_subquery ::= subquery", - /* 578 */ "order_by_clause_opt ::=", - /* 579 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", - /* 580 */ "slimit_clause_opt ::=", - /* 581 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", - /* 582 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", - /* 583 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 584 */ "limit_clause_opt ::=", - /* 585 */ "limit_clause_opt ::= LIMIT NK_INTEGER", - /* 586 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", - /* 587 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 588 */ "subquery ::= NK_LP query_expression NK_RP", - /* 589 */ "subquery ::= NK_LP subquery NK_RP", - /* 590 */ "search_condition ::= common_expression", - /* 591 */ "sort_specification_list ::= sort_specification", - /* 592 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", - /* 593 */ "sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt", - /* 594 */ "ordering_specification_opt ::=", - /* 595 */ "ordering_specification_opt ::= ASC", - /* 596 */ "ordering_specification_opt ::= DESC", - /* 597 */ "null_ordering_opt ::=", - /* 598 */ "null_ordering_opt ::= NULLS FIRST", - /* 599 */ "null_ordering_opt ::= NULLS LAST", + /* 182 */ "column_def ::= column_name type_name COMMENT NK_STRING", + /* 183 */ "type_name ::= BOOL", + /* 184 */ "type_name ::= TINYINT", + /* 185 */ "type_name ::= SMALLINT", + /* 186 */ "type_name ::= INT", + /* 187 */ "type_name ::= INTEGER", + /* 188 */ "type_name ::= BIGINT", + /* 189 */ "type_name ::= FLOAT", + /* 190 */ "type_name ::= DOUBLE", + /* 191 */ "type_name ::= BINARY NK_LP NK_INTEGER NK_RP", + /* 192 */ "type_name ::= TIMESTAMP", + /* 193 */ "type_name ::= NCHAR NK_LP NK_INTEGER NK_RP", + /* 194 */ "type_name ::= TINYINT UNSIGNED", + /* 195 */ "type_name ::= SMALLINT UNSIGNED", + /* 196 */ "type_name ::= INT UNSIGNED", + /* 197 */ "type_name ::= BIGINT UNSIGNED", + /* 198 */ "type_name ::= JSON", + /* 199 */ "type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP", + /* 200 */ "type_name ::= MEDIUMBLOB", + /* 201 */ "type_name ::= BLOB", + /* 202 */ "type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP", + /* 203 */ "type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP", + /* 204 */ "type_name ::= DECIMAL", + /* 205 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP", + /* 206 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP", + /* 207 */ "tags_def_opt ::=", + /* 208 */ "tags_def_opt ::= tags_def", + /* 209 */ "tags_def ::= TAGS NK_LP column_def_list NK_RP", + /* 210 */ "table_options ::=", + /* 211 */ "table_options ::= table_options COMMENT NK_STRING", + /* 212 */ "table_options ::= table_options MAX_DELAY duration_list", + /* 213 */ "table_options ::= table_options WATERMARK duration_list", + /* 214 */ "table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP", + /* 215 */ "table_options ::= table_options TTL NK_INTEGER", + /* 216 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP", + /* 217 */ "table_options ::= table_options DELETE_MARK duration_list", + /* 218 */ "alter_table_options ::= alter_table_option", + /* 219 */ "alter_table_options ::= alter_table_options alter_table_option", + /* 220 */ "alter_table_option ::= COMMENT NK_STRING", + /* 221 */ "alter_table_option ::= TTL NK_INTEGER", + /* 222 */ "duration_list ::= duration_literal", + /* 223 */ "duration_list ::= duration_list NK_COMMA duration_literal", + /* 224 */ "rollup_func_list ::= rollup_func_name", + /* 225 */ "rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name", + /* 226 */ "rollup_func_name ::= function_name", + /* 227 */ "rollup_func_name ::= FIRST", + /* 228 */ "rollup_func_name ::= LAST", + /* 229 */ "col_name_list ::= col_name", + /* 230 */ "col_name_list ::= col_name_list NK_COMMA col_name", + /* 231 */ "col_name ::= column_name", + /* 232 */ "cmd ::= SHOW DNODES", + /* 233 */ "cmd ::= SHOW USERS", + /* 234 */ "cmd ::= SHOW USER PRIVILEGES", + /* 235 */ "cmd ::= SHOW DATABASES", + /* 236 */ "cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt", + /* 237 */ "cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt", + /* 238 */ "cmd ::= SHOW db_name_cond_opt VGROUPS", + /* 239 */ "cmd ::= SHOW MNODES", + /* 240 */ "cmd ::= SHOW QNODES", + /* 241 */ "cmd ::= SHOW FUNCTIONS", + /* 242 */ "cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt", + /* 243 */ "cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name", + /* 244 */ "cmd ::= SHOW STREAMS", + /* 245 */ "cmd ::= SHOW ACCOUNTS", + /* 246 */ "cmd ::= SHOW APPS", + /* 247 */ "cmd ::= SHOW CONNECTIONS", + /* 248 */ "cmd ::= SHOW LICENCES", + /* 249 */ "cmd ::= SHOW GRANTS", + /* 250 */ "cmd ::= SHOW CREATE DATABASE db_name", + /* 251 */ "cmd ::= SHOW CREATE TABLE full_table_name", + /* 252 */ "cmd ::= SHOW CREATE STABLE full_table_name", + /* 253 */ "cmd ::= SHOW QUERIES", + /* 254 */ "cmd ::= SHOW SCORES", + /* 255 */ "cmd ::= SHOW TOPICS", + /* 256 */ "cmd ::= SHOW VARIABLES", + /* 257 */ "cmd ::= SHOW CLUSTER VARIABLES", + /* 258 */ "cmd ::= SHOW LOCAL VARIABLES", + /* 259 */ "cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt", + /* 260 */ "cmd ::= SHOW BNODES", + /* 261 */ "cmd ::= SHOW SNODES", + /* 262 */ "cmd ::= SHOW CLUSTER", + /* 263 */ "cmd ::= SHOW TRANSACTIONS", + /* 264 */ "cmd ::= SHOW TABLE DISTRIBUTED full_table_name", + /* 265 */ "cmd ::= SHOW CONSUMERS", + /* 266 */ "cmd ::= SHOW SUBSCRIPTIONS", + /* 267 */ "cmd ::= SHOW TAGS FROM table_name_cond from_db_opt", + /* 268 */ "cmd ::= SHOW TAGS FROM db_name NK_DOT table_name", + /* 269 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt", + /* 270 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name", + /* 271 */ "cmd ::= SHOW VNODES NK_INTEGER", + /* 272 */ "cmd ::= SHOW VNODES NK_STRING", + /* 273 */ "cmd ::= SHOW db_name_cond_opt ALIVE", + /* 274 */ "cmd ::= SHOW CLUSTER ALIVE", + /* 275 */ "db_name_cond_opt ::=", + /* 276 */ "db_name_cond_opt ::= db_name NK_DOT", + /* 277 */ "like_pattern_opt ::=", + /* 278 */ "like_pattern_opt ::= LIKE NK_STRING", + /* 279 */ "table_name_cond ::= table_name", + /* 280 */ "from_db_opt ::=", + /* 281 */ "from_db_opt ::= FROM db_name", + /* 282 */ "tag_list_opt ::=", + /* 283 */ "tag_list_opt ::= tag_item", + /* 284 */ "tag_list_opt ::= tag_list_opt NK_COMMA tag_item", + /* 285 */ "tag_item ::= TBNAME", + /* 286 */ "tag_item ::= QTAGS", + /* 287 */ "tag_item ::= column_name", + /* 288 */ "tag_item ::= column_name column_alias", + /* 289 */ "tag_item ::= column_name AS column_alias", + /* 290 */ "cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options", + /* 291 */ "cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP", + /* 292 */ "cmd ::= DROP INDEX exists_opt full_index_name", + /* 293 */ "full_index_name ::= index_name", + /* 294 */ "full_index_name ::= db_name NK_DOT index_name", + /* 295 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt", + /* 296 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt", + /* 297 */ "func_list ::= func", + /* 298 */ "func_list ::= func_list NK_COMMA func", + /* 299 */ "func ::= sma_func_name NK_LP expression_list NK_RP", + /* 300 */ "sma_func_name ::= function_name", + /* 301 */ "sma_func_name ::= COUNT", + /* 302 */ "sma_func_name ::= FIRST", + /* 303 */ "sma_func_name ::= LAST", + /* 304 */ "sma_func_name ::= LAST_ROW", + /* 305 */ "sma_stream_opt ::=", + /* 306 */ "sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal", + /* 307 */ "sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal", + /* 308 */ "sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal", + /* 309 */ "with_meta ::= AS", + /* 310 */ "with_meta ::= WITH META AS", + /* 311 */ "with_meta ::= ONLY META AS", + /* 312 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery", + /* 313 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name", + /* 314 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt", + /* 315 */ "cmd ::= DROP TOPIC exists_opt topic_name", + /* 316 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", + /* 317 */ "cmd ::= DESC full_table_name", + /* 318 */ "cmd ::= DESCRIBE full_table_name", + /* 319 */ "cmd ::= RESET QUERY CACHE", + /* 320 */ "cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery", + /* 321 */ "cmd ::= EXPLAIN analyze_opt explain_options insert_query", + /* 322 */ "analyze_opt ::=", + /* 323 */ "analyze_opt ::= ANALYZE", + /* 324 */ "explain_options ::=", + /* 325 */ "explain_options ::= explain_options VERBOSE NK_BOOL", + /* 326 */ "explain_options ::= explain_options RATIO NK_FLOAT", + /* 327 */ "cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt", + /* 328 */ "cmd ::= DROP FUNCTION exists_opt function_name", + /* 329 */ "agg_func_opt ::=", + /* 330 */ "agg_func_opt ::= AGGREGATE", + /* 331 */ "bufsize_opt ::=", + /* 332 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", + /* 333 */ "language_opt ::=", + /* 334 */ "language_opt ::= LANGUAGE NK_STRING", + /* 335 */ "or_replace_opt ::=", + /* 336 */ "or_replace_opt ::= OR REPLACE", + /* 337 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery", + /* 338 */ "cmd ::= DROP STREAM exists_opt stream_name", + /* 339 */ "cmd ::= PAUSE STREAM exists_opt stream_name", + /* 340 */ "cmd ::= RESUME STREAM exists_opt ignore_opt stream_name", + /* 341 */ "col_list_opt ::=", + /* 342 */ "col_list_opt ::= NK_LP col_name_list NK_RP", + /* 343 */ "tag_def_or_ref_opt ::=", + /* 344 */ "tag_def_or_ref_opt ::= tags_def", + /* 345 */ "tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP", + /* 346 */ "stream_options ::=", + /* 347 */ "stream_options ::= stream_options TRIGGER AT_ONCE", + /* 348 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", + /* 349 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", + /* 350 */ "stream_options ::= stream_options WATERMARK duration_literal", + /* 351 */ "stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER", + /* 352 */ "stream_options ::= stream_options FILL_HISTORY NK_INTEGER", + /* 353 */ "stream_options ::= stream_options DELETE_MARK duration_literal", + /* 354 */ "stream_options ::= stream_options IGNORE UPDATE NK_INTEGER", + /* 355 */ "subtable_opt ::=", + /* 356 */ "subtable_opt ::= SUBTABLE NK_LP expression NK_RP", + /* 357 */ "ignore_opt ::=", + /* 358 */ "ignore_opt ::= IGNORE UNTREATED", + /* 359 */ "cmd ::= KILL CONNECTION NK_INTEGER", + /* 360 */ "cmd ::= KILL QUERY NK_STRING", + /* 361 */ "cmd ::= KILL TRANSACTION NK_INTEGER", + /* 362 */ "cmd ::= BALANCE VGROUP", + /* 363 */ "cmd ::= BALANCE VGROUP LEADER", + /* 364 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", + /* 365 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", + /* 366 */ "cmd ::= SPLIT VGROUP NK_INTEGER", + /* 367 */ "dnode_list ::= DNODE NK_INTEGER", + /* 368 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", + /* 369 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", + /* 370 */ "cmd ::= query_or_subquery", + /* 371 */ "cmd ::= insert_query", + /* 372 */ "insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery", + /* 373 */ "insert_query ::= INSERT INTO full_table_name query_or_subquery", + /* 374 */ "literal ::= NK_INTEGER", + /* 375 */ "literal ::= NK_FLOAT", + /* 376 */ "literal ::= NK_STRING", + /* 377 */ "literal ::= NK_BOOL", + /* 378 */ "literal ::= TIMESTAMP NK_STRING", + /* 379 */ "literal ::= duration_literal", + /* 380 */ "literal ::= NULL", + /* 381 */ "literal ::= NK_QUESTION", + /* 382 */ "duration_literal ::= NK_VARIABLE", + /* 383 */ "signed ::= NK_INTEGER", + /* 384 */ "signed ::= NK_PLUS NK_INTEGER", + /* 385 */ "signed ::= NK_MINUS NK_INTEGER", + /* 386 */ "signed ::= NK_FLOAT", + /* 387 */ "signed ::= NK_PLUS NK_FLOAT", + /* 388 */ "signed ::= NK_MINUS NK_FLOAT", + /* 389 */ "signed_literal ::= signed", + /* 390 */ "signed_literal ::= NK_STRING", + /* 391 */ "signed_literal ::= NK_BOOL", + /* 392 */ "signed_literal ::= TIMESTAMP NK_STRING", + /* 393 */ "signed_literal ::= duration_literal", + /* 394 */ "signed_literal ::= NULL", + /* 395 */ "signed_literal ::= literal_func", + /* 396 */ "signed_literal ::= NK_QUESTION", + /* 397 */ "literal_list ::= signed_literal", + /* 398 */ "literal_list ::= literal_list NK_COMMA signed_literal", + /* 399 */ "db_name ::= NK_ID", + /* 400 */ "table_name ::= NK_ID", + /* 401 */ "column_name ::= NK_ID", + /* 402 */ "function_name ::= NK_ID", + /* 403 */ "table_alias ::= NK_ID", + /* 404 */ "column_alias ::= NK_ID", + /* 405 */ "user_name ::= NK_ID", + /* 406 */ "topic_name ::= NK_ID", + /* 407 */ "stream_name ::= NK_ID", + /* 408 */ "cgroup_name ::= NK_ID", + /* 409 */ "index_name ::= NK_ID", + /* 410 */ "expr_or_subquery ::= expression", + /* 411 */ "expression ::= literal", + /* 412 */ "expression ::= pseudo_column", + /* 413 */ "expression ::= column_reference", + /* 414 */ "expression ::= function_expression", + /* 415 */ "expression ::= case_when_expression", + /* 416 */ "expression ::= NK_LP expression NK_RP", + /* 417 */ "expression ::= NK_PLUS expr_or_subquery", + /* 418 */ "expression ::= NK_MINUS expr_or_subquery", + /* 419 */ "expression ::= expr_or_subquery NK_PLUS expr_or_subquery", + /* 420 */ "expression ::= expr_or_subquery NK_MINUS expr_or_subquery", + /* 421 */ "expression ::= expr_or_subquery NK_STAR expr_or_subquery", + /* 422 */ "expression ::= expr_or_subquery NK_SLASH expr_or_subquery", + /* 423 */ "expression ::= expr_or_subquery NK_REM expr_or_subquery", + /* 424 */ "expression ::= column_reference NK_ARROW NK_STRING", + /* 425 */ "expression ::= expr_or_subquery NK_BITAND expr_or_subquery", + /* 426 */ "expression ::= expr_or_subquery NK_BITOR expr_or_subquery", + /* 427 */ "expression_list ::= expr_or_subquery", + /* 428 */ "expression_list ::= expression_list NK_COMMA expr_or_subquery", + /* 429 */ "column_reference ::= column_name", + /* 430 */ "column_reference ::= table_name NK_DOT column_name", + /* 431 */ "pseudo_column ::= ROWTS", + /* 432 */ "pseudo_column ::= TBNAME", + /* 433 */ "pseudo_column ::= table_name NK_DOT TBNAME", + /* 434 */ "pseudo_column ::= QSTART", + /* 435 */ "pseudo_column ::= QEND", + /* 436 */ "pseudo_column ::= QDURATION", + /* 437 */ "pseudo_column ::= WSTART", + /* 438 */ "pseudo_column ::= WEND", + /* 439 */ "pseudo_column ::= WDURATION", + /* 440 */ "pseudo_column ::= IROWTS", + /* 441 */ "pseudo_column ::= ISFILLED", + /* 442 */ "pseudo_column ::= QTAGS", + /* 443 */ "function_expression ::= function_name NK_LP expression_list NK_RP", + /* 444 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", + /* 445 */ "function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP", + /* 446 */ "function_expression ::= literal_func", + /* 447 */ "literal_func ::= noarg_func NK_LP NK_RP", + /* 448 */ "literal_func ::= NOW", + /* 449 */ "noarg_func ::= NOW", + /* 450 */ "noarg_func ::= TODAY", + /* 451 */ "noarg_func ::= TIMEZONE", + /* 452 */ "noarg_func ::= DATABASE", + /* 453 */ "noarg_func ::= CLIENT_VERSION", + /* 454 */ "noarg_func ::= SERVER_VERSION", + /* 455 */ "noarg_func ::= SERVER_STATUS", + /* 456 */ "noarg_func ::= CURRENT_USER", + /* 457 */ "noarg_func ::= USER", + /* 458 */ "star_func ::= COUNT", + /* 459 */ "star_func ::= FIRST", + /* 460 */ "star_func ::= LAST", + /* 461 */ "star_func ::= LAST_ROW", + /* 462 */ "star_func_para_list ::= NK_STAR", + /* 463 */ "star_func_para_list ::= other_para_list", + /* 464 */ "other_para_list ::= star_func_para", + /* 465 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", + /* 466 */ "star_func_para ::= expr_or_subquery", + /* 467 */ "star_func_para ::= table_name NK_DOT NK_STAR", + /* 468 */ "case_when_expression ::= CASE when_then_list case_when_else_opt END", + /* 469 */ "case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END", + /* 470 */ "when_then_list ::= when_then_expr", + /* 471 */ "when_then_list ::= when_then_list when_then_expr", + /* 472 */ "when_then_expr ::= WHEN common_expression THEN common_expression", + /* 473 */ "case_when_else_opt ::=", + /* 474 */ "case_when_else_opt ::= ELSE common_expression", + /* 475 */ "predicate ::= expr_or_subquery compare_op expr_or_subquery", + /* 476 */ "predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery", + /* 477 */ "predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery", + /* 478 */ "predicate ::= expr_or_subquery IS NULL", + /* 479 */ "predicate ::= expr_or_subquery IS NOT NULL", + /* 480 */ "predicate ::= expr_or_subquery in_op in_predicate_value", + /* 481 */ "compare_op ::= NK_LT", + /* 482 */ "compare_op ::= NK_GT", + /* 483 */ "compare_op ::= NK_LE", + /* 484 */ "compare_op ::= NK_GE", + /* 485 */ "compare_op ::= NK_NE", + /* 486 */ "compare_op ::= NK_EQ", + /* 487 */ "compare_op ::= LIKE", + /* 488 */ "compare_op ::= NOT LIKE", + /* 489 */ "compare_op ::= MATCH", + /* 490 */ "compare_op ::= NMATCH", + /* 491 */ "compare_op ::= CONTAINS", + /* 492 */ "in_op ::= IN", + /* 493 */ "in_op ::= NOT IN", + /* 494 */ "in_predicate_value ::= NK_LP literal_list NK_RP", + /* 495 */ "boolean_value_expression ::= boolean_primary", + /* 496 */ "boolean_value_expression ::= NOT boolean_primary", + /* 497 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", + /* 498 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", + /* 499 */ "boolean_primary ::= predicate", + /* 500 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", + /* 501 */ "common_expression ::= expr_or_subquery", + /* 502 */ "common_expression ::= boolean_value_expression", + /* 503 */ "from_clause_opt ::=", + /* 504 */ "from_clause_opt ::= FROM table_reference_list", + /* 505 */ "table_reference_list ::= table_reference", + /* 506 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", + /* 507 */ "table_reference ::= table_primary", + /* 508 */ "table_reference ::= joined_table", + /* 509 */ "table_primary ::= table_name alias_opt", + /* 510 */ "table_primary ::= db_name NK_DOT table_name alias_opt", + /* 511 */ "table_primary ::= subquery alias_opt", + /* 512 */ "table_primary ::= parenthesized_joined_table", + /* 513 */ "alias_opt ::=", + /* 514 */ "alias_opt ::= table_alias", + /* 515 */ "alias_opt ::= AS table_alias", + /* 516 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", + /* 517 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", + /* 518 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", + /* 519 */ "join_type ::=", + /* 520 */ "join_type ::= INNER", + /* 521 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt", + /* 522 */ "set_quantifier_opt ::=", + /* 523 */ "set_quantifier_opt ::= DISTINCT", + /* 524 */ "set_quantifier_opt ::= ALL", + /* 525 */ "select_list ::= select_item", + /* 526 */ "select_list ::= select_list NK_COMMA select_item", + /* 527 */ "select_item ::= NK_STAR", + /* 528 */ "select_item ::= common_expression", + /* 529 */ "select_item ::= common_expression column_alias", + /* 530 */ "select_item ::= common_expression AS column_alias", + /* 531 */ "select_item ::= table_name NK_DOT NK_STAR", + /* 532 */ "where_clause_opt ::=", + /* 533 */ "where_clause_opt ::= WHERE search_condition", + /* 534 */ "partition_by_clause_opt ::=", + /* 535 */ "partition_by_clause_opt ::= PARTITION BY partition_list", + /* 536 */ "partition_list ::= partition_item", + /* 537 */ "partition_list ::= partition_list NK_COMMA partition_item", + /* 538 */ "partition_item ::= expr_or_subquery", + /* 539 */ "partition_item ::= expr_or_subquery column_alias", + /* 540 */ "partition_item ::= expr_or_subquery AS column_alias", + /* 541 */ "twindow_clause_opt ::=", + /* 542 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", + /* 543 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP", + /* 544 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", + /* 545 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", + /* 546 */ "twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition", + /* 547 */ "sliding_opt ::=", + /* 548 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", + /* 549 */ "fill_opt ::=", + /* 550 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", + /* 551 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP", + /* 552 */ "fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP", + /* 553 */ "fill_mode ::= NONE", + /* 554 */ "fill_mode ::= PREV", + /* 555 */ "fill_mode ::= NULL", + /* 556 */ "fill_mode ::= NULL_F", + /* 557 */ "fill_mode ::= LINEAR", + /* 558 */ "fill_mode ::= NEXT", + /* 559 */ "group_by_clause_opt ::=", + /* 560 */ "group_by_clause_opt ::= GROUP BY group_by_list", + /* 561 */ "group_by_list ::= expr_or_subquery", + /* 562 */ "group_by_list ::= group_by_list NK_COMMA expr_or_subquery", + /* 563 */ "having_clause_opt ::=", + /* 564 */ "having_clause_opt ::= HAVING search_condition", + /* 565 */ "range_opt ::=", + /* 566 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP", + /* 567 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_RP", + /* 568 */ "every_opt ::=", + /* 569 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", + /* 570 */ "query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt", + /* 571 */ "query_simple ::= query_specification", + /* 572 */ "query_simple ::= union_query_expression", + /* 573 */ "union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery", + /* 574 */ "union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery", + /* 575 */ "query_simple_or_subquery ::= query_simple", + /* 576 */ "query_simple_or_subquery ::= subquery", + /* 577 */ "query_or_subquery ::= query_expression", + /* 578 */ "query_or_subquery ::= subquery", + /* 579 */ "order_by_clause_opt ::=", + /* 580 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", + /* 581 */ "slimit_clause_opt ::=", + /* 582 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", + /* 583 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", + /* 584 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 585 */ "limit_clause_opt ::=", + /* 586 */ "limit_clause_opt ::= LIMIT NK_INTEGER", + /* 587 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", + /* 588 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 589 */ "subquery ::= NK_LP query_expression NK_RP", + /* 590 */ "subquery ::= NK_LP subquery NK_RP", + /* 591 */ "search_condition ::= common_expression", + /* 592 */ "sort_specification_list ::= sort_specification", + /* 593 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", + /* 594 */ "sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt", + /* 595 */ "ordering_specification_opt ::=", + /* 596 */ "ordering_specification_opt ::= ASC", + /* 597 */ "ordering_specification_opt ::= DESC", + /* 598 */ "null_ordering_opt ::=", + /* 599 */ "null_ordering_opt ::= NULLS FIRST", + /* 600 */ "null_ordering_opt ::= NULLS LAST", }; #endif /* NDEBUG */ @@ -3070,7 +3068,7 @@ static YYACTIONTYPE yy_find_shift_action( #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ - assert( i>=0 && i=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) ); return yy_action[i]; } }while(1); @@ -3374,424 +3372,425 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 371, /* (179) column_def_list ::= column_def */ 371, /* (180) column_def_list ::= column_def_list NK_COMMA column_def */ 387, /* (181) column_def ::= column_name type_name */ - 380, /* (182) type_name ::= BOOL */ - 380, /* (183) type_name ::= TINYINT */ - 380, /* (184) type_name ::= SMALLINT */ - 380, /* (185) type_name ::= INT */ - 380, /* (186) type_name ::= INTEGER */ - 380, /* (187) type_name ::= BIGINT */ - 380, /* (188) type_name ::= FLOAT */ - 380, /* (189) type_name ::= DOUBLE */ - 380, /* (190) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ - 380, /* (191) type_name ::= TIMESTAMP */ - 380, /* (192) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ - 380, /* (193) type_name ::= TINYINT UNSIGNED */ - 380, /* (194) type_name ::= SMALLINT UNSIGNED */ - 380, /* (195) type_name ::= INT UNSIGNED */ - 380, /* (196) type_name ::= BIGINT UNSIGNED */ - 380, /* (197) type_name ::= JSON */ - 380, /* (198) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ - 380, /* (199) type_name ::= MEDIUMBLOB */ - 380, /* (200) type_name ::= BLOB */ - 380, /* (201) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ - 380, /* (202) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ - 380, /* (203) type_name ::= DECIMAL */ - 380, /* (204) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ - 380, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ - 372, /* (206) tags_def_opt ::= */ - 372, /* (207) tags_def_opt ::= tags_def */ - 375, /* (208) tags_def ::= TAGS NK_LP column_def_list NK_RP */ - 373, /* (209) table_options ::= */ - 373, /* (210) table_options ::= table_options COMMENT NK_STRING */ - 373, /* (211) table_options ::= table_options MAX_DELAY duration_list */ - 373, /* (212) table_options ::= table_options WATERMARK duration_list */ - 373, /* (213) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ - 373, /* (214) table_options ::= table_options TTL NK_INTEGER */ - 373, /* (215) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ - 373, /* (216) table_options ::= table_options DELETE_MARK duration_list */ - 378, /* (217) alter_table_options ::= alter_table_option */ - 378, /* (218) alter_table_options ::= alter_table_options alter_table_option */ - 390, /* (219) alter_table_option ::= COMMENT NK_STRING */ - 390, /* (220) alter_table_option ::= TTL NK_INTEGER */ - 388, /* (221) duration_list ::= duration_literal */ - 388, /* (222) duration_list ::= duration_list NK_COMMA duration_literal */ - 389, /* (223) rollup_func_list ::= rollup_func_name */ - 389, /* (224) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ - 392, /* (225) rollup_func_name ::= function_name */ - 392, /* (226) rollup_func_name ::= FIRST */ - 392, /* (227) rollup_func_name ::= LAST */ - 386, /* (228) col_name_list ::= col_name */ - 386, /* (229) col_name_list ::= col_name_list NK_COMMA col_name */ - 394, /* (230) col_name ::= column_name */ - 338, /* (231) cmd ::= SHOW DNODES */ - 338, /* (232) cmd ::= SHOW USERS */ - 338, /* (233) cmd ::= SHOW USER PRIVILEGES */ - 338, /* (234) cmd ::= SHOW DATABASES */ - 338, /* (235) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ - 338, /* (236) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ - 338, /* (237) cmd ::= SHOW db_name_cond_opt VGROUPS */ - 338, /* (238) cmd ::= SHOW MNODES */ - 338, /* (239) cmd ::= SHOW QNODES */ - 338, /* (240) cmd ::= SHOW FUNCTIONS */ - 338, /* (241) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ - 338, /* (242) cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ - 338, /* (243) cmd ::= SHOW STREAMS */ - 338, /* (244) cmd ::= SHOW ACCOUNTS */ - 338, /* (245) cmd ::= SHOW APPS */ - 338, /* (246) cmd ::= SHOW CONNECTIONS */ - 338, /* (247) cmd ::= SHOW LICENCES */ - 338, /* (248) cmd ::= SHOW GRANTS */ - 338, /* (249) cmd ::= SHOW CREATE DATABASE db_name */ - 338, /* (250) cmd ::= SHOW CREATE TABLE full_table_name */ - 338, /* (251) cmd ::= SHOW CREATE STABLE full_table_name */ - 338, /* (252) cmd ::= SHOW QUERIES */ - 338, /* (253) cmd ::= SHOW SCORES */ - 338, /* (254) cmd ::= SHOW TOPICS */ - 338, /* (255) cmd ::= SHOW VARIABLES */ - 338, /* (256) cmd ::= SHOW CLUSTER VARIABLES */ - 338, /* (257) cmd ::= SHOW LOCAL VARIABLES */ - 338, /* (258) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ - 338, /* (259) cmd ::= SHOW BNODES */ - 338, /* (260) cmd ::= SHOW SNODES */ - 338, /* (261) cmd ::= SHOW CLUSTER */ - 338, /* (262) cmd ::= SHOW TRANSACTIONS */ - 338, /* (263) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ - 338, /* (264) cmd ::= SHOW CONSUMERS */ - 338, /* (265) cmd ::= SHOW SUBSCRIPTIONS */ - 338, /* (266) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ - 338, /* (267) cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ - 338, /* (268) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ - 338, /* (269) cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ - 338, /* (270) cmd ::= SHOW VNODES NK_INTEGER */ - 338, /* (271) cmd ::= SHOW VNODES NK_STRING */ - 338, /* (272) cmd ::= SHOW db_name_cond_opt ALIVE */ - 338, /* (273) cmd ::= SHOW CLUSTER ALIVE */ - 395, /* (274) db_name_cond_opt ::= */ - 395, /* (275) db_name_cond_opt ::= db_name NK_DOT */ - 396, /* (276) like_pattern_opt ::= */ - 396, /* (277) like_pattern_opt ::= LIKE NK_STRING */ - 397, /* (278) table_name_cond ::= table_name */ - 398, /* (279) from_db_opt ::= */ - 398, /* (280) from_db_opt ::= FROM db_name */ - 399, /* (281) tag_list_opt ::= */ - 399, /* (282) tag_list_opt ::= tag_item */ - 399, /* (283) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ - 400, /* (284) tag_item ::= TBNAME */ - 400, /* (285) tag_item ::= QTAGS */ - 400, /* (286) tag_item ::= column_name */ - 400, /* (287) tag_item ::= column_name column_alias */ - 400, /* (288) tag_item ::= column_name AS column_alias */ - 338, /* (289) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ - 338, /* (290) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ - 338, /* (291) cmd ::= DROP INDEX exists_opt full_index_name */ - 402, /* (292) full_index_name ::= index_name */ - 402, /* (293) full_index_name ::= db_name NK_DOT index_name */ - 403, /* (294) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ - 403, /* (295) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ - 405, /* (296) func_list ::= func */ - 405, /* (297) func_list ::= func_list NK_COMMA func */ - 408, /* (298) func ::= sma_func_name NK_LP expression_list NK_RP */ - 409, /* (299) sma_func_name ::= function_name */ - 409, /* (300) sma_func_name ::= COUNT */ - 409, /* (301) sma_func_name ::= FIRST */ - 409, /* (302) sma_func_name ::= LAST */ - 409, /* (303) sma_func_name ::= LAST_ROW */ - 407, /* (304) sma_stream_opt ::= */ - 407, /* (305) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ - 407, /* (306) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ - 407, /* (307) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ - 410, /* (308) with_meta ::= AS */ - 410, /* (309) with_meta ::= WITH META AS */ - 410, /* (310) with_meta ::= ONLY META AS */ - 338, /* (311) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ - 338, /* (312) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ - 338, /* (313) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ - 338, /* (314) cmd ::= DROP TOPIC exists_opt topic_name */ - 338, /* (315) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ - 338, /* (316) cmd ::= DESC full_table_name */ - 338, /* (317) cmd ::= DESCRIBE full_table_name */ - 338, /* (318) cmd ::= RESET QUERY CACHE */ - 338, /* (319) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - 338, /* (320) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ - 414, /* (321) analyze_opt ::= */ - 414, /* (322) analyze_opt ::= ANALYZE */ - 415, /* (323) explain_options ::= */ - 415, /* (324) explain_options ::= explain_options VERBOSE NK_BOOL */ - 415, /* (325) explain_options ::= explain_options RATIO NK_FLOAT */ - 338, /* (326) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ - 338, /* (327) cmd ::= DROP FUNCTION exists_opt function_name */ - 418, /* (328) agg_func_opt ::= */ - 418, /* (329) agg_func_opt ::= AGGREGATE */ - 419, /* (330) bufsize_opt ::= */ - 419, /* (331) bufsize_opt ::= BUFSIZE NK_INTEGER */ - 420, /* (332) language_opt ::= */ - 420, /* (333) language_opt ::= LANGUAGE NK_STRING */ - 417, /* (334) or_replace_opt ::= */ - 417, /* (335) or_replace_opt ::= OR REPLACE */ - 338, /* (336) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ - 338, /* (337) cmd ::= DROP STREAM exists_opt stream_name */ - 338, /* (338) cmd ::= PAUSE STREAM exists_opt stream_name */ - 338, /* (339) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ - 423, /* (340) col_list_opt ::= */ - 423, /* (341) col_list_opt ::= NK_LP col_name_list NK_RP */ - 424, /* (342) tag_def_or_ref_opt ::= */ - 424, /* (343) tag_def_or_ref_opt ::= tags_def */ - 424, /* (344) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ - 422, /* (345) stream_options ::= */ - 422, /* (346) stream_options ::= stream_options TRIGGER AT_ONCE */ - 422, /* (347) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ - 422, /* (348) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ - 422, /* (349) stream_options ::= stream_options WATERMARK duration_literal */ - 422, /* (350) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ - 422, /* (351) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ - 422, /* (352) stream_options ::= stream_options DELETE_MARK duration_literal */ - 422, /* (353) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ - 425, /* (354) subtable_opt ::= */ - 425, /* (355) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - 426, /* (356) ignore_opt ::= */ - 426, /* (357) ignore_opt ::= IGNORE UNTREATED */ - 338, /* (358) cmd ::= KILL CONNECTION NK_INTEGER */ - 338, /* (359) cmd ::= KILL QUERY NK_STRING */ - 338, /* (360) cmd ::= KILL TRANSACTION NK_INTEGER */ - 338, /* (361) cmd ::= BALANCE VGROUP */ - 338, /* (362) cmd ::= BALANCE VGROUP LEADER */ - 338, /* (363) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ - 338, /* (364) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ - 338, /* (365) cmd ::= SPLIT VGROUP NK_INTEGER */ - 428, /* (366) dnode_list ::= DNODE NK_INTEGER */ - 428, /* (367) dnode_list ::= dnode_list DNODE NK_INTEGER */ - 338, /* (368) cmd ::= DELETE FROM full_table_name where_clause_opt */ - 338, /* (369) cmd ::= query_or_subquery */ - 338, /* (370) cmd ::= insert_query */ - 416, /* (371) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ - 416, /* (372) insert_query ::= INSERT INTO full_table_name query_or_subquery */ - 341, /* (373) literal ::= NK_INTEGER */ - 341, /* (374) literal ::= NK_FLOAT */ - 341, /* (375) literal ::= NK_STRING */ - 341, /* (376) literal ::= NK_BOOL */ - 341, /* (377) literal ::= TIMESTAMP NK_STRING */ - 341, /* (378) literal ::= duration_literal */ - 341, /* (379) literal ::= NULL */ - 341, /* (380) literal ::= NK_QUESTION */ - 391, /* (381) duration_literal ::= NK_VARIABLE */ - 367, /* (382) signed ::= NK_INTEGER */ - 367, /* (383) signed ::= NK_PLUS NK_INTEGER */ - 367, /* (384) signed ::= NK_MINUS NK_INTEGER */ - 367, /* (385) signed ::= NK_FLOAT */ - 367, /* (386) signed ::= NK_PLUS NK_FLOAT */ - 367, /* (387) signed ::= NK_MINUS NK_FLOAT */ - 381, /* (388) signed_literal ::= signed */ - 381, /* (389) signed_literal ::= NK_STRING */ - 381, /* (390) signed_literal ::= NK_BOOL */ - 381, /* (391) signed_literal ::= TIMESTAMP NK_STRING */ - 381, /* (392) signed_literal ::= duration_literal */ - 381, /* (393) signed_literal ::= NULL */ - 381, /* (394) signed_literal ::= literal_func */ - 381, /* (395) signed_literal ::= NK_QUESTION */ - 430, /* (396) literal_list ::= signed_literal */ - 430, /* (397) literal_list ::= literal_list NK_COMMA signed_literal */ - 350, /* (398) db_name ::= NK_ID */ - 351, /* (399) table_name ::= NK_ID */ - 379, /* (400) column_name ::= NK_ID */ - 393, /* (401) function_name ::= NK_ID */ - 431, /* (402) table_alias ::= NK_ID */ - 401, /* (403) column_alias ::= NK_ID */ - 343, /* (404) user_name ::= NK_ID */ - 352, /* (405) topic_name ::= NK_ID */ - 421, /* (406) stream_name ::= NK_ID */ - 413, /* (407) cgroup_name ::= NK_ID */ - 404, /* (408) index_name ::= NK_ID */ - 432, /* (409) expr_or_subquery ::= expression */ - 427, /* (410) expression ::= literal */ - 427, /* (411) expression ::= pseudo_column */ - 427, /* (412) expression ::= column_reference */ - 427, /* (413) expression ::= function_expression */ - 427, /* (414) expression ::= case_when_expression */ - 427, /* (415) expression ::= NK_LP expression NK_RP */ - 427, /* (416) expression ::= NK_PLUS expr_or_subquery */ - 427, /* (417) expression ::= NK_MINUS expr_or_subquery */ - 427, /* (418) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ - 427, /* (419) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ - 427, /* (420) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ - 427, /* (421) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ - 427, /* (422) expression ::= expr_or_subquery NK_REM expr_or_subquery */ - 427, /* (423) expression ::= column_reference NK_ARROW NK_STRING */ - 427, /* (424) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ - 427, /* (425) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ - 384, /* (426) expression_list ::= expr_or_subquery */ - 384, /* (427) expression_list ::= expression_list NK_COMMA expr_or_subquery */ - 434, /* (428) column_reference ::= column_name */ - 434, /* (429) column_reference ::= table_name NK_DOT column_name */ - 433, /* (430) pseudo_column ::= ROWTS */ - 433, /* (431) pseudo_column ::= TBNAME */ - 433, /* (432) pseudo_column ::= table_name NK_DOT TBNAME */ - 433, /* (433) pseudo_column ::= QSTART */ - 433, /* (434) pseudo_column ::= QEND */ - 433, /* (435) pseudo_column ::= QDURATION */ - 433, /* (436) pseudo_column ::= WSTART */ - 433, /* (437) pseudo_column ::= WEND */ - 433, /* (438) pseudo_column ::= WDURATION */ - 433, /* (439) pseudo_column ::= IROWTS */ - 433, /* (440) pseudo_column ::= ISFILLED */ - 433, /* (441) pseudo_column ::= QTAGS */ - 435, /* (442) function_expression ::= function_name NK_LP expression_list NK_RP */ - 435, /* (443) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ - 435, /* (444) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ - 435, /* (445) function_expression ::= literal_func */ - 429, /* (446) literal_func ::= noarg_func NK_LP NK_RP */ - 429, /* (447) literal_func ::= NOW */ - 439, /* (448) noarg_func ::= NOW */ - 439, /* (449) noarg_func ::= TODAY */ - 439, /* (450) noarg_func ::= TIMEZONE */ - 439, /* (451) noarg_func ::= DATABASE */ - 439, /* (452) noarg_func ::= CLIENT_VERSION */ - 439, /* (453) noarg_func ::= SERVER_VERSION */ - 439, /* (454) noarg_func ::= SERVER_STATUS */ - 439, /* (455) noarg_func ::= CURRENT_USER */ - 439, /* (456) noarg_func ::= USER */ - 437, /* (457) star_func ::= COUNT */ - 437, /* (458) star_func ::= FIRST */ - 437, /* (459) star_func ::= LAST */ - 437, /* (460) star_func ::= LAST_ROW */ - 438, /* (461) star_func_para_list ::= NK_STAR */ - 438, /* (462) star_func_para_list ::= other_para_list */ - 440, /* (463) other_para_list ::= star_func_para */ - 440, /* (464) other_para_list ::= other_para_list NK_COMMA star_func_para */ - 441, /* (465) star_func_para ::= expr_or_subquery */ - 441, /* (466) star_func_para ::= table_name NK_DOT NK_STAR */ - 436, /* (467) case_when_expression ::= CASE when_then_list case_when_else_opt END */ - 436, /* (468) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ - 442, /* (469) when_then_list ::= when_then_expr */ - 442, /* (470) when_then_list ::= when_then_list when_then_expr */ - 445, /* (471) when_then_expr ::= WHEN common_expression THEN common_expression */ - 443, /* (472) case_when_else_opt ::= */ - 443, /* (473) case_when_else_opt ::= ELSE common_expression */ - 446, /* (474) predicate ::= expr_or_subquery compare_op expr_or_subquery */ - 446, /* (475) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ - 446, /* (476) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ - 446, /* (477) predicate ::= expr_or_subquery IS NULL */ - 446, /* (478) predicate ::= expr_or_subquery IS NOT NULL */ - 446, /* (479) predicate ::= expr_or_subquery in_op in_predicate_value */ - 447, /* (480) compare_op ::= NK_LT */ - 447, /* (481) compare_op ::= NK_GT */ - 447, /* (482) compare_op ::= NK_LE */ - 447, /* (483) compare_op ::= NK_GE */ - 447, /* (484) compare_op ::= NK_NE */ - 447, /* (485) compare_op ::= NK_EQ */ - 447, /* (486) compare_op ::= LIKE */ - 447, /* (487) compare_op ::= NOT LIKE */ - 447, /* (488) compare_op ::= MATCH */ - 447, /* (489) compare_op ::= NMATCH */ - 447, /* (490) compare_op ::= CONTAINS */ - 448, /* (491) in_op ::= IN */ - 448, /* (492) in_op ::= NOT IN */ - 449, /* (493) in_predicate_value ::= NK_LP literal_list NK_RP */ - 450, /* (494) boolean_value_expression ::= boolean_primary */ - 450, /* (495) boolean_value_expression ::= NOT boolean_primary */ - 450, /* (496) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ - 450, /* (497) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ - 451, /* (498) boolean_primary ::= predicate */ - 451, /* (499) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ - 444, /* (500) common_expression ::= expr_or_subquery */ - 444, /* (501) common_expression ::= boolean_value_expression */ - 452, /* (502) from_clause_opt ::= */ - 452, /* (503) from_clause_opt ::= FROM table_reference_list */ - 453, /* (504) table_reference_list ::= table_reference */ - 453, /* (505) table_reference_list ::= table_reference_list NK_COMMA table_reference */ - 454, /* (506) table_reference ::= table_primary */ - 454, /* (507) table_reference ::= joined_table */ - 455, /* (508) table_primary ::= table_name alias_opt */ - 455, /* (509) table_primary ::= db_name NK_DOT table_name alias_opt */ - 455, /* (510) table_primary ::= subquery alias_opt */ - 455, /* (511) table_primary ::= parenthesized_joined_table */ - 457, /* (512) alias_opt ::= */ - 457, /* (513) alias_opt ::= table_alias */ - 457, /* (514) alias_opt ::= AS table_alias */ - 459, /* (515) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - 459, /* (516) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ - 456, /* (517) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ - 460, /* (518) join_type ::= */ - 460, /* (519) join_type ::= INNER */ - 461, /* (520) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ - 462, /* (521) set_quantifier_opt ::= */ - 462, /* (522) set_quantifier_opt ::= DISTINCT */ - 462, /* (523) set_quantifier_opt ::= ALL */ - 463, /* (524) select_list ::= select_item */ - 463, /* (525) select_list ::= select_list NK_COMMA select_item */ - 471, /* (526) select_item ::= NK_STAR */ - 471, /* (527) select_item ::= common_expression */ - 471, /* (528) select_item ::= common_expression column_alias */ - 471, /* (529) select_item ::= common_expression AS column_alias */ - 471, /* (530) select_item ::= table_name NK_DOT NK_STAR */ - 412, /* (531) where_clause_opt ::= */ - 412, /* (532) where_clause_opt ::= WHERE search_condition */ - 464, /* (533) partition_by_clause_opt ::= */ - 464, /* (534) partition_by_clause_opt ::= PARTITION BY partition_list */ - 472, /* (535) partition_list ::= partition_item */ - 472, /* (536) partition_list ::= partition_list NK_COMMA partition_item */ - 473, /* (537) partition_item ::= expr_or_subquery */ - 473, /* (538) partition_item ::= expr_or_subquery column_alias */ - 473, /* (539) partition_item ::= expr_or_subquery AS column_alias */ - 468, /* (540) twindow_clause_opt ::= */ - 468, /* (541) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ - 468, /* (542) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ - 468, /* (543) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ - 468, /* (544) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ - 468, /* (545) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ - 406, /* (546) sliding_opt ::= */ - 406, /* (547) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - 467, /* (548) fill_opt ::= */ - 467, /* (549) fill_opt ::= FILL NK_LP fill_mode NK_RP */ - 467, /* (550) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ - 467, /* (551) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ - 474, /* (552) fill_mode ::= NONE */ - 474, /* (553) fill_mode ::= PREV */ - 474, /* (554) fill_mode ::= NULL */ - 474, /* (555) fill_mode ::= NULL_F */ - 474, /* (556) fill_mode ::= LINEAR */ - 474, /* (557) fill_mode ::= NEXT */ - 469, /* (558) group_by_clause_opt ::= */ - 469, /* (559) group_by_clause_opt ::= GROUP BY group_by_list */ - 475, /* (560) group_by_list ::= expr_or_subquery */ - 475, /* (561) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ - 470, /* (562) having_clause_opt ::= */ - 470, /* (563) having_clause_opt ::= HAVING search_condition */ - 465, /* (564) range_opt ::= */ - 465, /* (565) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ - 465, /* (566) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ - 466, /* (567) every_opt ::= */ - 466, /* (568) every_opt ::= EVERY NK_LP duration_literal NK_RP */ - 476, /* (569) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ - 477, /* (570) query_simple ::= query_specification */ - 477, /* (571) query_simple ::= union_query_expression */ - 481, /* (572) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ - 481, /* (573) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ - 482, /* (574) query_simple_or_subquery ::= query_simple */ - 482, /* (575) query_simple_or_subquery ::= subquery */ - 411, /* (576) query_or_subquery ::= query_expression */ - 411, /* (577) query_or_subquery ::= subquery */ - 478, /* (578) order_by_clause_opt ::= */ - 478, /* (579) order_by_clause_opt ::= ORDER BY sort_specification_list */ - 479, /* (580) slimit_clause_opt ::= */ - 479, /* (581) slimit_clause_opt ::= SLIMIT NK_INTEGER */ - 479, /* (582) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - 479, /* (583) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - 480, /* (584) limit_clause_opt ::= */ - 480, /* (585) limit_clause_opt ::= LIMIT NK_INTEGER */ - 480, /* (586) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ - 480, /* (587) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - 458, /* (588) subquery ::= NK_LP query_expression NK_RP */ - 458, /* (589) subquery ::= NK_LP subquery NK_RP */ - 353, /* (590) search_condition ::= common_expression */ - 483, /* (591) sort_specification_list ::= sort_specification */ - 483, /* (592) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ - 484, /* (593) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ - 485, /* (594) ordering_specification_opt ::= */ - 485, /* (595) ordering_specification_opt ::= ASC */ - 485, /* (596) ordering_specification_opt ::= DESC */ - 486, /* (597) null_ordering_opt ::= */ - 486, /* (598) null_ordering_opt ::= NULLS FIRST */ - 486, /* (599) null_ordering_opt ::= NULLS LAST */ + 387, /* (182) column_def ::= column_name type_name COMMENT NK_STRING */ + 380, /* (183) type_name ::= BOOL */ + 380, /* (184) type_name ::= TINYINT */ + 380, /* (185) type_name ::= SMALLINT */ + 380, /* (186) type_name ::= INT */ + 380, /* (187) type_name ::= INTEGER */ + 380, /* (188) type_name ::= BIGINT */ + 380, /* (189) type_name ::= FLOAT */ + 380, /* (190) type_name ::= DOUBLE */ + 380, /* (191) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + 380, /* (192) type_name ::= TIMESTAMP */ + 380, /* (193) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + 380, /* (194) type_name ::= TINYINT UNSIGNED */ + 380, /* (195) type_name ::= SMALLINT UNSIGNED */ + 380, /* (196) type_name ::= INT UNSIGNED */ + 380, /* (197) type_name ::= BIGINT UNSIGNED */ + 380, /* (198) type_name ::= JSON */ + 380, /* (199) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + 380, /* (200) type_name ::= MEDIUMBLOB */ + 380, /* (201) type_name ::= BLOB */ + 380, /* (202) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + 380, /* (203) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ + 380, /* (204) type_name ::= DECIMAL */ + 380, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + 380, /* (206) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + 372, /* (207) tags_def_opt ::= */ + 372, /* (208) tags_def_opt ::= tags_def */ + 375, /* (209) tags_def ::= TAGS NK_LP column_def_list NK_RP */ + 373, /* (210) table_options ::= */ + 373, /* (211) table_options ::= table_options COMMENT NK_STRING */ + 373, /* (212) table_options ::= table_options MAX_DELAY duration_list */ + 373, /* (213) table_options ::= table_options WATERMARK duration_list */ + 373, /* (214) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ + 373, /* (215) table_options ::= table_options TTL NK_INTEGER */ + 373, /* (216) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ + 373, /* (217) table_options ::= table_options DELETE_MARK duration_list */ + 378, /* (218) alter_table_options ::= alter_table_option */ + 378, /* (219) alter_table_options ::= alter_table_options alter_table_option */ + 390, /* (220) alter_table_option ::= COMMENT NK_STRING */ + 390, /* (221) alter_table_option ::= TTL NK_INTEGER */ + 388, /* (222) duration_list ::= duration_literal */ + 388, /* (223) duration_list ::= duration_list NK_COMMA duration_literal */ + 389, /* (224) rollup_func_list ::= rollup_func_name */ + 389, /* (225) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ + 392, /* (226) rollup_func_name ::= function_name */ + 392, /* (227) rollup_func_name ::= FIRST */ + 392, /* (228) rollup_func_name ::= LAST */ + 386, /* (229) col_name_list ::= col_name */ + 386, /* (230) col_name_list ::= col_name_list NK_COMMA col_name */ + 394, /* (231) col_name ::= column_name */ + 338, /* (232) cmd ::= SHOW DNODES */ + 338, /* (233) cmd ::= SHOW USERS */ + 338, /* (234) cmd ::= SHOW USER PRIVILEGES */ + 338, /* (235) cmd ::= SHOW DATABASES */ + 338, /* (236) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ + 338, /* (237) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ + 338, /* (238) cmd ::= SHOW db_name_cond_opt VGROUPS */ + 338, /* (239) cmd ::= SHOW MNODES */ + 338, /* (240) cmd ::= SHOW QNODES */ + 338, /* (241) cmd ::= SHOW FUNCTIONS */ + 338, /* (242) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ + 338, /* (243) cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ + 338, /* (244) cmd ::= SHOW STREAMS */ + 338, /* (245) cmd ::= SHOW ACCOUNTS */ + 338, /* (246) cmd ::= SHOW APPS */ + 338, /* (247) cmd ::= SHOW CONNECTIONS */ + 338, /* (248) cmd ::= SHOW LICENCES */ + 338, /* (249) cmd ::= SHOW GRANTS */ + 338, /* (250) cmd ::= SHOW CREATE DATABASE db_name */ + 338, /* (251) cmd ::= SHOW CREATE TABLE full_table_name */ + 338, /* (252) cmd ::= SHOW CREATE STABLE full_table_name */ + 338, /* (253) cmd ::= SHOW QUERIES */ + 338, /* (254) cmd ::= SHOW SCORES */ + 338, /* (255) cmd ::= SHOW TOPICS */ + 338, /* (256) cmd ::= SHOW VARIABLES */ + 338, /* (257) cmd ::= SHOW CLUSTER VARIABLES */ + 338, /* (258) cmd ::= SHOW LOCAL VARIABLES */ + 338, /* (259) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ + 338, /* (260) cmd ::= SHOW BNODES */ + 338, /* (261) cmd ::= SHOW SNODES */ + 338, /* (262) cmd ::= SHOW CLUSTER */ + 338, /* (263) cmd ::= SHOW TRANSACTIONS */ + 338, /* (264) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + 338, /* (265) cmd ::= SHOW CONSUMERS */ + 338, /* (266) cmd ::= SHOW SUBSCRIPTIONS */ + 338, /* (267) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ + 338, /* (268) cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ + 338, /* (269) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ + 338, /* (270) cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ + 338, /* (271) cmd ::= SHOW VNODES NK_INTEGER */ + 338, /* (272) cmd ::= SHOW VNODES NK_STRING */ + 338, /* (273) cmd ::= SHOW db_name_cond_opt ALIVE */ + 338, /* (274) cmd ::= SHOW CLUSTER ALIVE */ + 395, /* (275) db_name_cond_opt ::= */ + 395, /* (276) db_name_cond_opt ::= db_name NK_DOT */ + 396, /* (277) like_pattern_opt ::= */ + 396, /* (278) like_pattern_opt ::= LIKE NK_STRING */ + 397, /* (279) table_name_cond ::= table_name */ + 398, /* (280) from_db_opt ::= */ + 398, /* (281) from_db_opt ::= FROM db_name */ + 399, /* (282) tag_list_opt ::= */ + 399, /* (283) tag_list_opt ::= tag_item */ + 399, /* (284) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ + 400, /* (285) tag_item ::= TBNAME */ + 400, /* (286) tag_item ::= QTAGS */ + 400, /* (287) tag_item ::= column_name */ + 400, /* (288) tag_item ::= column_name column_alias */ + 400, /* (289) tag_item ::= column_name AS column_alias */ + 338, /* (290) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ + 338, /* (291) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ + 338, /* (292) cmd ::= DROP INDEX exists_opt full_index_name */ + 402, /* (293) full_index_name ::= index_name */ + 402, /* (294) full_index_name ::= db_name NK_DOT index_name */ + 403, /* (295) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ + 403, /* (296) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ + 405, /* (297) func_list ::= func */ + 405, /* (298) func_list ::= func_list NK_COMMA func */ + 408, /* (299) func ::= sma_func_name NK_LP expression_list NK_RP */ + 409, /* (300) sma_func_name ::= function_name */ + 409, /* (301) sma_func_name ::= COUNT */ + 409, /* (302) sma_func_name ::= FIRST */ + 409, /* (303) sma_func_name ::= LAST */ + 409, /* (304) sma_func_name ::= LAST_ROW */ + 407, /* (305) sma_stream_opt ::= */ + 407, /* (306) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ + 407, /* (307) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ + 407, /* (308) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ + 410, /* (309) with_meta ::= AS */ + 410, /* (310) with_meta ::= WITH META AS */ + 410, /* (311) with_meta ::= ONLY META AS */ + 338, /* (312) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ + 338, /* (313) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ + 338, /* (314) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ + 338, /* (315) cmd ::= DROP TOPIC exists_opt topic_name */ + 338, /* (316) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + 338, /* (317) cmd ::= DESC full_table_name */ + 338, /* (318) cmd ::= DESCRIBE full_table_name */ + 338, /* (319) cmd ::= RESET QUERY CACHE */ + 338, /* (320) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + 338, /* (321) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ + 414, /* (322) analyze_opt ::= */ + 414, /* (323) analyze_opt ::= ANALYZE */ + 415, /* (324) explain_options ::= */ + 415, /* (325) explain_options ::= explain_options VERBOSE NK_BOOL */ + 415, /* (326) explain_options ::= explain_options RATIO NK_FLOAT */ + 338, /* (327) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ + 338, /* (328) cmd ::= DROP FUNCTION exists_opt function_name */ + 418, /* (329) agg_func_opt ::= */ + 418, /* (330) agg_func_opt ::= AGGREGATE */ + 419, /* (331) bufsize_opt ::= */ + 419, /* (332) bufsize_opt ::= BUFSIZE NK_INTEGER */ + 420, /* (333) language_opt ::= */ + 420, /* (334) language_opt ::= LANGUAGE NK_STRING */ + 417, /* (335) or_replace_opt ::= */ + 417, /* (336) or_replace_opt ::= OR REPLACE */ + 338, /* (337) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ + 338, /* (338) cmd ::= DROP STREAM exists_opt stream_name */ + 338, /* (339) cmd ::= PAUSE STREAM exists_opt stream_name */ + 338, /* (340) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ + 423, /* (341) col_list_opt ::= */ + 423, /* (342) col_list_opt ::= NK_LP col_name_list NK_RP */ + 424, /* (343) tag_def_or_ref_opt ::= */ + 424, /* (344) tag_def_or_ref_opt ::= tags_def */ + 424, /* (345) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ + 422, /* (346) stream_options ::= */ + 422, /* (347) stream_options ::= stream_options TRIGGER AT_ONCE */ + 422, /* (348) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + 422, /* (349) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + 422, /* (350) stream_options ::= stream_options WATERMARK duration_literal */ + 422, /* (351) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ + 422, /* (352) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ + 422, /* (353) stream_options ::= stream_options DELETE_MARK duration_literal */ + 422, /* (354) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ + 425, /* (355) subtable_opt ::= */ + 425, /* (356) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + 426, /* (357) ignore_opt ::= */ + 426, /* (358) ignore_opt ::= IGNORE UNTREATED */ + 338, /* (359) cmd ::= KILL CONNECTION NK_INTEGER */ + 338, /* (360) cmd ::= KILL QUERY NK_STRING */ + 338, /* (361) cmd ::= KILL TRANSACTION NK_INTEGER */ + 338, /* (362) cmd ::= BALANCE VGROUP */ + 338, /* (363) cmd ::= BALANCE VGROUP LEADER */ + 338, /* (364) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + 338, /* (365) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + 338, /* (366) cmd ::= SPLIT VGROUP NK_INTEGER */ + 428, /* (367) dnode_list ::= DNODE NK_INTEGER */ + 428, /* (368) dnode_list ::= dnode_list DNODE NK_INTEGER */ + 338, /* (369) cmd ::= DELETE FROM full_table_name where_clause_opt */ + 338, /* (370) cmd ::= query_or_subquery */ + 338, /* (371) cmd ::= insert_query */ + 416, /* (372) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ + 416, /* (373) insert_query ::= INSERT INTO full_table_name query_or_subquery */ + 341, /* (374) literal ::= NK_INTEGER */ + 341, /* (375) literal ::= NK_FLOAT */ + 341, /* (376) literal ::= NK_STRING */ + 341, /* (377) literal ::= NK_BOOL */ + 341, /* (378) literal ::= TIMESTAMP NK_STRING */ + 341, /* (379) literal ::= duration_literal */ + 341, /* (380) literal ::= NULL */ + 341, /* (381) literal ::= NK_QUESTION */ + 391, /* (382) duration_literal ::= NK_VARIABLE */ + 367, /* (383) signed ::= NK_INTEGER */ + 367, /* (384) signed ::= NK_PLUS NK_INTEGER */ + 367, /* (385) signed ::= NK_MINUS NK_INTEGER */ + 367, /* (386) signed ::= NK_FLOAT */ + 367, /* (387) signed ::= NK_PLUS NK_FLOAT */ + 367, /* (388) signed ::= NK_MINUS NK_FLOAT */ + 381, /* (389) signed_literal ::= signed */ + 381, /* (390) signed_literal ::= NK_STRING */ + 381, /* (391) signed_literal ::= NK_BOOL */ + 381, /* (392) signed_literal ::= TIMESTAMP NK_STRING */ + 381, /* (393) signed_literal ::= duration_literal */ + 381, /* (394) signed_literal ::= NULL */ + 381, /* (395) signed_literal ::= literal_func */ + 381, /* (396) signed_literal ::= NK_QUESTION */ + 430, /* (397) literal_list ::= signed_literal */ + 430, /* (398) literal_list ::= literal_list NK_COMMA signed_literal */ + 350, /* (399) db_name ::= NK_ID */ + 351, /* (400) table_name ::= NK_ID */ + 379, /* (401) column_name ::= NK_ID */ + 393, /* (402) function_name ::= NK_ID */ + 431, /* (403) table_alias ::= NK_ID */ + 401, /* (404) column_alias ::= NK_ID */ + 343, /* (405) user_name ::= NK_ID */ + 352, /* (406) topic_name ::= NK_ID */ + 421, /* (407) stream_name ::= NK_ID */ + 413, /* (408) cgroup_name ::= NK_ID */ + 404, /* (409) index_name ::= NK_ID */ + 432, /* (410) expr_or_subquery ::= expression */ + 427, /* (411) expression ::= literal */ + 427, /* (412) expression ::= pseudo_column */ + 427, /* (413) expression ::= column_reference */ + 427, /* (414) expression ::= function_expression */ + 427, /* (415) expression ::= case_when_expression */ + 427, /* (416) expression ::= NK_LP expression NK_RP */ + 427, /* (417) expression ::= NK_PLUS expr_or_subquery */ + 427, /* (418) expression ::= NK_MINUS expr_or_subquery */ + 427, /* (419) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + 427, /* (420) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + 427, /* (421) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + 427, /* (422) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + 427, /* (423) expression ::= expr_or_subquery NK_REM expr_or_subquery */ + 427, /* (424) expression ::= column_reference NK_ARROW NK_STRING */ + 427, /* (425) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + 427, /* (426) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + 384, /* (427) expression_list ::= expr_or_subquery */ + 384, /* (428) expression_list ::= expression_list NK_COMMA expr_or_subquery */ + 434, /* (429) column_reference ::= column_name */ + 434, /* (430) column_reference ::= table_name NK_DOT column_name */ + 433, /* (431) pseudo_column ::= ROWTS */ + 433, /* (432) pseudo_column ::= TBNAME */ + 433, /* (433) pseudo_column ::= table_name NK_DOT TBNAME */ + 433, /* (434) pseudo_column ::= QSTART */ + 433, /* (435) pseudo_column ::= QEND */ + 433, /* (436) pseudo_column ::= QDURATION */ + 433, /* (437) pseudo_column ::= WSTART */ + 433, /* (438) pseudo_column ::= WEND */ + 433, /* (439) pseudo_column ::= WDURATION */ + 433, /* (440) pseudo_column ::= IROWTS */ + 433, /* (441) pseudo_column ::= ISFILLED */ + 433, /* (442) pseudo_column ::= QTAGS */ + 435, /* (443) function_expression ::= function_name NK_LP expression_list NK_RP */ + 435, /* (444) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ + 435, /* (445) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ + 435, /* (446) function_expression ::= literal_func */ + 429, /* (447) literal_func ::= noarg_func NK_LP NK_RP */ + 429, /* (448) literal_func ::= NOW */ + 439, /* (449) noarg_func ::= NOW */ + 439, /* (450) noarg_func ::= TODAY */ + 439, /* (451) noarg_func ::= TIMEZONE */ + 439, /* (452) noarg_func ::= DATABASE */ + 439, /* (453) noarg_func ::= CLIENT_VERSION */ + 439, /* (454) noarg_func ::= SERVER_VERSION */ + 439, /* (455) noarg_func ::= SERVER_STATUS */ + 439, /* (456) noarg_func ::= CURRENT_USER */ + 439, /* (457) noarg_func ::= USER */ + 437, /* (458) star_func ::= COUNT */ + 437, /* (459) star_func ::= FIRST */ + 437, /* (460) star_func ::= LAST */ + 437, /* (461) star_func ::= LAST_ROW */ + 438, /* (462) star_func_para_list ::= NK_STAR */ + 438, /* (463) star_func_para_list ::= other_para_list */ + 440, /* (464) other_para_list ::= star_func_para */ + 440, /* (465) other_para_list ::= other_para_list NK_COMMA star_func_para */ + 441, /* (466) star_func_para ::= expr_or_subquery */ + 441, /* (467) star_func_para ::= table_name NK_DOT NK_STAR */ + 436, /* (468) case_when_expression ::= CASE when_then_list case_when_else_opt END */ + 436, /* (469) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ + 442, /* (470) when_then_list ::= when_then_expr */ + 442, /* (471) when_then_list ::= when_then_list when_then_expr */ + 445, /* (472) when_then_expr ::= WHEN common_expression THEN common_expression */ + 443, /* (473) case_when_else_opt ::= */ + 443, /* (474) case_when_else_opt ::= ELSE common_expression */ + 446, /* (475) predicate ::= expr_or_subquery compare_op expr_or_subquery */ + 446, /* (476) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + 446, /* (477) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + 446, /* (478) predicate ::= expr_or_subquery IS NULL */ + 446, /* (479) predicate ::= expr_or_subquery IS NOT NULL */ + 446, /* (480) predicate ::= expr_or_subquery in_op in_predicate_value */ + 447, /* (481) compare_op ::= NK_LT */ + 447, /* (482) compare_op ::= NK_GT */ + 447, /* (483) compare_op ::= NK_LE */ + 447, /* (484) compare_op ::= NK_GE */ + 447, /* (485) compare_op ::= NK_NE */ + 447, /* (486) compare_op ::= NK_EQ */ + 447, /* (487) compare_op ::= LIKE */ + 447, /* (488) compare_op ::= NOT LIKE */ + 447, /* (489) compare_op ::= MATCH */ + 447, /* (490) compare_op ::= NMATCH */ + 447, /* (491) compare_op ::= CONTAINS */ + 448, /* (492) in_op ::= IN */ + 448, /* (493) in_op ::= NOT IN */ + 449, /* (494) in_predicate_value ::= NK_LP literal_list NK_RP */ + 450, /* (495) boolean_value_expression ::= boolean_primary */ + 450, /* (496) boolean_value_expression ::= NOT boolean_primary */ + 450, /* (497) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + 450, /* (498) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + 451, /* (499) boolean_primary ::= predicate */ + 451, /* (500) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ + 444, /* (501) common_expression ::= expr_or_subquery */ + 444, /* (502) common_expression ::= boolean_value_expression */ + 452, /* (503) from_clause_opt ::= */ + 452, /* (504) from_clause_opt ::= FROM table_reference_list */ + 453, /* (505) table_reference_list ::= table_reference */ + 453, /* (506) table_reference_list ::= table_reference_list NK_COMMA table_reference */ + 454, /* (507) table_reference ::= table_primary */ + 454, /* (508) table_reference ::= joined_table */ + 455, /* (509) table_primary ::= table_name alias_opt */ + 455, /* (510) table_primary ::= db_name NK_DOT table_name alias_opt */ + 455, /* (511) table_primary ::= subquery alias_opt */ + 455, /* (512) table_primary ::= parenthesized_joined_table */ + 457, /* (513) alias_opt ::= */ + 457, /* (514) alias_opt ::= table_alias */ + 457, /* (515) alias_opt ::= AS table_alias */ + 459, /* (516) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + 459, /* (517) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ + 456, /* (518) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + 460, /* (519) join_type ::= */ + 460, /* (520) join_type ::= INNER */ + 461, /* (521) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + 462, /* (522) set_quantifier_opt ::= */ + 462, /* (523) set_quantifier_opt ::= DISTINCT */ + 462, /* (524) set_quantifier_opt ::= ALL */ + 463, /* (525) select_list ::= select_item */ + 463, /* (526) select_list ::= select_list NK_COMMA select_item */ + 471, /* (527) select_item ::= NK_STAR */ + 471, /* (528) select_item ::= common_expression */ + 471, /* (529) select_item ::= common_expression column_alias */ + 471, /* (530) select_item ::= common_expression AS column_alias */ + 471, /* (531) select_item ::= table_name NK_DOT NK_STAR */ + 412, /* (532) where_clause_opt ::= */ + 412, /* (533) where_clause_opt ::= WHERE search_condition */ + 464, /* (534) partition_by_clause_opt ::= */ + 464, /* (535) partition_by_clause_opt ::= PARTITION BY partition_list */ + 472, /* (536) partition_list ::= partition_item */ + 472, /* (537) partition_list ::= partition_list NK_COMMA partition_item */ + 473, /* (538) partition_item ::= expr_or_subquery */ + 473, /* (539) partition_item ::= expr_or_subquery column_alias */ + 473, /* (540) partition_item ::= expr_or_subquery AS column_alias */ + 468, /* (541) twindow_clause_opt ::= */ + 468, /* (542) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + 468, /* (543) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ + 468, /* (544) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + 468, /* (545) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + 468, /* (546) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ + 406, /* (547) sliding_opt ::= */ + 406, /* (548) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + 467, /* (549) fill_opt ::= */ + 467, /* (550) fill_opt ::= FILL NK_LP fill_mode NK_RP */ + 467, /* (551) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ + 467, /* (552) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ + 474, /* (553) fill_mode ::= NONE */ + 474, /* (554) fill_mode ::= PREV */ + 474, /* (555) fill_mode ::= NULL */ + 474, /* (556) fill_mode ::= NULL_F */ + 474, /* (557) fill_mode ::= LINEAR */ + 474, /* (558) fill_mode ::= NEXT */ + 469, /* (559) group_by_clause_opt ::= */ + 469, /* (560) group_by_clause_opt ::= GROUP BY group_by_list */ + 475, /* (561) group_by_list ::= expr_or_subquery */ + 475, /* (562) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ + 470, /* (563) having_clause_opt ::= */ + 470, /* (564) having_clause_opt ::= HAVING search_condition */ + 465, /* (565) range_opt ::= */ + 465, /* (566) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ + 465, /* (567) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ + 466, /* (568) every_opt ::= */ + 466, /* (569) every_opt ::= EVERY NK_LP duration_literal NK_RP */ + 476, /* (570) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + 477, /* (571) query_simple ::= query_specification */ + 477, /* (572) query_simple ::= union_query_expression */ + 481, /* (573) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ + 481, /* (574) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ + 482, /* (575) query_simple_or_subquery ::= query_simple */ + 482, /* (576) query_simple_or_subquery ::= subquery */ + 411, /* (577) query_or_subquery ::= query_expression */ + 411, /* (578) query_or_subquery ::= subquery */ + 478, /* (579) order_by_clause_opt ::= */ + 478, /* (580) order_by_clause_opt ::= ORDER BY sort_specification_list */ + 479, /* (581) slimit_clause_opt ::= */ + 479, /* (582) slimit_clause_opt ::= SLIMIT NK_INTEGER */ + 479, /* (583) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + 479, /* (584) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + 480, /* (585) limit_clause_opt ::= */ + 480, /* (586) limit_clause_opt ::= LIMIT NK_INTEGER */ + 480, /* (587) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ + 480, /* (588) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + 458, /* (589) subquery ::= NK_LP query_expression NK_RP */ + 458, /* (590) subquery ::= NK_LP subquery NK_RP */ + 353, /* (591) search_condition ::= common_expression */ + 483, /* (592) sort_specification_list ::= sort_specification */ + 483, /* (593) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ + 484, /* (594) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ + 485, /* (595) ordering_specification_opt ::= */ + 485, /* (596) ordering_specification_opt ::= ASC */ + 485, /* (597) ordering_specification_opt ::= DESC */ + 486, /* (598) null_ordering_opt ::= */ + 486, /* (599) null_ordering_opt ::= NULLS FIRST */ + 486, /* (600) null_ordering_opt ::= NULLS LAST */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -3979,424 +3978,425 @@ static const signed char yyRuleInfoNRhs[] = { -1, /* (179) column_def_list ::= column_def */ -3, /* (180) column_def_list ::= column_def_list NK_COMMA column_def */ -2, /* (181) column_def ::= column_name type_name */ - -1, /* (182) type_name ::= BOOL */ - -1, /* (183) type_name ::= TINYINT */ - -1, /* (184) type_name ::= SMALLINT */ - -1, /* (185) type_name ::= INT */ - -1, /* (186) type_name ::= INTEGER */ - -1, /* (187) type_name ::= BIGINT */ - -1, /* (188) type_name ::= FLOAT */ - -1, /* (189) type_name ::= DOUBLE */ - -4, /* (190) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ - -1, /* (191) type_name ::= TIMESTAMP */ - -4, /* (192) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ - -2, /* (193) type_name ::= TINYINT UNSIGNED */ - -2, /* (194) type_name ::= SMALLINT UNSIGNED */ - -2, /* (195) type_name ::= INT UNSIGNED */ - -2, /* (196) type_name ::= BIGINT UNSIGNED */ - -1, /* (197) type_name ::= JSON */ - -4, /* (198) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ - -1, /* (199) type_name ::= MEDIUMBLOB */ - -1, /* (200) type_name ::= BLOB */ - -4, /* (201) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ - -4, /* (202) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ - -1, /* (203) type_name ::= DECIMAL */ - -4, /* (204) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ - -6, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ - 0, /* (206) tags_def_opt ::= */ - -1, /* (207) tags_def_opt ::= tags_def */ - -4, /* (208) tags_def ::= TAGS NK_LP column_def_list NK_RP */ - 0, /* (209) table_options ::= */ - -3, /* (210) table_options ::= table_options COMMENT NK_STRING */ - -3, /* (211) table_options ::= table_options MAX_DELAY duration_list */ - -3, /* (212) table_options ::= table_options WATERMARK duration_list */ - -5, /* (213) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ - -3, /* (214) table_options ::= table_options TTL NK_INTEGER */ - -5, /* (215) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ - -3, /* (216) table_options ::= table_options DELETE_MARK duration_list */ - -1, /* (217) alter_table_options ::= alter_table_option */ - -2, /* (218) alter_table_options ::= alter_table_options alter_table_option */ - -2, /* (219) alter_table_option ::= COMMENT NK_STRING */ - -2, /* (220) alter_table_option ::= TTL NK_INTEGER */ - -1, /* (221) duration_list ::= duration_literal */ - -3, /* (222) duration_list ::= duration_list NK_COMMA duration_literal */ - -1, /* (223) rollup_func_list ::= rollup_func_name */ - -3, /* (224) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ - -1, /* (225) rollup_func_name ::= function_name */ - -1, /* (226) rollup_func_name ::= FIRST */ - -1, /* (227) rollup_func_name ::= LAST */ - -1, /* (228) col_name_list ::= col_name */ - -3, /* (229) col_name_list ::= col_name_list NK_COMMA col_name */ - -1, /* (230) col_name ::= column_name */ - -2, /* (231) cmd ::= SHOW DNODES */ - -2, /* (232) cmd ::= SHOW USERS */ - -3, /* (233) cmd ::= SHOW USER PRIVILEGES */ - -2, /* (234) cmd ::= SHOW DATABASES */ - -4, /* (235) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ - -4, /* (236) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ - -3, /* (237) cmd ::= SHOW db_name_cond_opt VGROUPS */ - -2, /* (238) cmd ::= SHOW MNODES */ - -2, /* (239) cmd ::= SHOW QNODES */ - -2, /* (240) cmd ::= SHOW FUNCTIONS */ - -5, /* (241) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ - -6, /* (242) cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ - -2, /* (243) cmd ::= SHOW STREAMS */ - -2, /* (244) cmd ::= SHOW ACCOUNTS */ - -2, /* (245) cmd ::= SHOW APPS */ - -2, /* (246) cmd ::= SHOW CONNECTIONS */ - -2, /* (247) cmd ::= SHOW LICENCES */ - -2, /* (248) cmd ::= SHOW GRANTS */ - -4, /* (249) cmd ::= SHOW CREATE DATABASE db_name */ - -4, /* (250) cmd ::= SHOW CREATE TABLE full_table_name */ - -4, /* (251) cmd ::= SHOW CREATE STABLE full_table_name */ - -2, /* (252) cmd ::= SHOW QUERIES */ - -2, /* (253) cmd ::= SHOW SCORES */ - -2, /* (254) cmd ::= SHOW TOPICS */ - -2, /* (255) cmd ::= SHOW VARIABLES */ - -3, /* (256) cmd ::= SHOW CLUSTER VARIABLES */ - -3, /* (257) cmd ::= SHOW LOCAL VARIABLES */ - -5, /* (258) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ - -2, /* (259) cmd ::= SHOW BNODES */ - -2, /* (260) cmd ::= SHOW SNODES */ - -2, /* (261) cmd ::= SHOW CLUSTER */ - -2, /* (262) cmd ::= SHOW TRANSACTIONS */ - -4, /* (263) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ - -2, /* (264) cmd ::= SHOW CONSUMERS */ - -2, /* (265) cmd ::= SHOW SUBSCRIPTIONS */ - -5, /* (266) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ - -6, /* (267) cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ - -7, /* (268) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ - -8, /* (269) cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ - -3, /* (270) cmd ::= SHOW VNODES NK_INTEGER */ - -3, /* (271) cmd ::= SHOW VNODES NK_STRING */ - -3, /* (272) cmd ::= SHOW db_name_cond_opt ALIVE */ - -3, /* (273) cmd ::= SHOW CLUSTER ALIVE */ - 0, /* (274) db_name_cond_opt ::= */ - -2, /* (275) db_name_cond_opt ::= db_name NK_DOT */ - 0, /* (276) like_pattern_opt ::= */ - -2, /* (277) like_pattern_opt ::= LIKE NK_STRING */ - -1, /* (278) table_name_cond ::= table_name */ - 0, /* (279) from_db_opt ::= */ - -2, /* (280) from_db_opt ::= FROM db_name */ - 0, /* (281) tag_list_opt ::= */ - -1, /* (282) tag_list_opt ::= tag_item */ - -3, /* (283) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ - -1, /* (284) tag_item ::= TBNAME */ - -1, /* (285) tag_item ::= QTAGS */ - -1, /* (286) tag_item ::= column_name */ - -2, /* (287) tag_item ::= column_name column_alias */ - -3, /* (288) tag_item ::= column_name AS column_alias */ - -8, /* (289) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ - -9, /* (290) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ - -4, /* (291) cmd ::= DROP INDEX exists_opt full_index_name */ - -1, /* (292) full_index_name ::= index_name */ - -3, /* (293) full_index_name ::= db_name NK_DOT index_name */ - -10, /* (294) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ - -12, /* (295) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ - -1, /* (296) func_list ::= func */ - -3, /* (297) func_list ::= func_list NK_COMMA func */ - -4, /* (298) func ::= sma_func_name NK_LP expression_list NK_RP */ - -1, /* (299) sma_func_name ::= function_name */ - -1, /* (300) sma_func_name ::= COUNT */ - -1, /* (301) sma_func_name ::= FIRST */ - -1, /* (302) sma_func_name ::= LAST */ - -1, /* (303) sma_func_name ::= LAST_ROW */ - 0, /* (304) sma_stream_opt ::= */ - -3, /* (305) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ - -3, /* (306) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ - -3, /* (307) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ - -1, /* (308) with_meta ::= AS */ - -3, /* (309) with_meta ::= WITH META AS */ - -3, /* (310) with_meta ::= ONLY META AS */ - -6, /* (311) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ - -7, /* (312) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ - -8, /* (313) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ - -4, /* (314) cmd ::= DROP TOPIC exists_opt topic_name */ - -7, /* (315) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ - -2, /* (316) cmd ::= DESC full_table_name */ - -2, /* (317) cmd ::= DESCRIBE full_table_name */ - -3, /* (318) cmd ::= RESET QUERY CACHE */ - -4, /* (319) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - -4, /* (320) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ - 0, /* (321) analyze_opt ::= */ - -1, /* (322) analyze_opt ::= ANALYZE */ - 0, /* (323) explain_options ::= */ - -3, /* (324) explain_options ::= explain_options VERBOSE NK_BOOL */ - -3, /* (325) explain_options ::= explain_options RATIO NK_FLOAT */ - -12, /* (326) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ - -4, /* (327) cmd ::= DROP FUNCTION exists_opt function_name */ - 0, /* (328) agg_func_opt ::= */ - -1, /* (329) agg_func_opt ::= AGGREGATE */ - 0, /* (330) bufsize_opt ::= */ - -2, /* (331) bufsize_opt ::= BUFSIZE NK_INTEGER */ - 0, /* (332) language_opt ::= */ - -2, /* (333) language_opt ::= LANGUAGE NK_STRING */ - 0, /* (334) or_replace_opt ::= */ - -2, /* (335) or_replace_opt ::= OR REPLACE */ - -12, /* (336) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ - -4, /* (337) cmd ::= DROP STREAM exists_opt stream_name */ - -4, /* (338) cmd ::= PAUSE STREAM exists_opt stream_name */ - -5, /* (339) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ - 0, /* (340) col_list_opt ::= */ - -3, /* (341) col_list_opt ::= NK_LP col_name_list NK_RP */ - 0, /* (342) tag_def_or_ref_opt ::= */ - -1, /* (343) tag_def_or_ref_opt ::= tags_def */ - -4, /* (344) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ - 0, /* (345) stream_options ::= */ - -3, /* (346) stream_options ::= stream_options TRIGGER AT_ONCE */ - -3, /* (347) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ - -4, /* (348) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ - -3, /* (349) stream_options ::= stream_options WATERMARK duration_literal */ - -4, /* (350) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ - -3, /* (351) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ - -3, /* (352) stream_options ::= stream_options DELETE_MARK duration_literal */ - -4, /* (353) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ - 0, /* (354) subtable_opt ::= */ - -4, /* (355) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - 0, /* (356) ignore_opt ::= */ - -2, /* (357) ignore_opt ::= IGNORE UNTREATED */ - -3, /* (358) cmd ::= KILL CONNECTION NK_INTEGER */ - -3, /* (359) cmd ::= KILL QUERY NK_STRING */ - -3, /* (360) cmd ::= KILL TRANSACTION NK_INTEGER */ - -2, /* (361) cmd ::= BALANCE VGROUP */ - -3, /* (362) cmd ::= BALANCE VGROUP LEADER */ - -4, /* (363) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ - -4, /* (364) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ - -3, /* (365) cmd ::= SPLIT VGROUP NK_INTEGER */ - -2, /* (366) dnode_list ::= DNODE NK_INTEGER */ - -3, /* (367) dnode_list ::= dnode_list DNODE NK_INTEGER */ - -4, /* (368) cmd ::= DELETE FROM full_table_name where_clause_opt */ - -1, /* (369) cmd ::= query_or_subquery */ - -1, /* (370) cmd ::= insert_query */ - -7, /* (371) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ - -4, /* (372) insert_query ::= INSERT INTO full_table_name query_or_subquery */ - -1, /* (373) literal ::= NK_INTEGER */ - -1, /* (374) literal ::= NK_FLOAT */ - -1, /* (375) literal ::= NK_STRING */ - -1, /* (376) literal ::= NK_BOOL */ - -2, /* (377) literal ::= TIMESTAMP NK_STRING */ - -1, /* (378) literal ::= duration_literal */ - -1, /* (379) literal ::= NULL */ - -1, /* (380) literal ::= NK_QUESTION */ - -1, /* (381) duration_literal ::= NK_VARIABLE */ - -1, /* (382) signed ::= NK_INTEGER */ - -2, /* (383) signed ::= NK_PLUS NK_INTEGER */ - -2, /* (384) signed ::= NK_MINUS NK_INTEGER */ - -1, /* (385) signed ::= NK_FLOAT */ - -2, /* (386) signed ::= NK_PLUS NK_FLOAT */ - -2, /* (387) signed ::= NK_MINUS NK_FLOAT */ - -1, /* (388) signed_literal ::= signed */ - -1, /* (389) signed_literal ::= NK_STRING */ - -1, /* (390) signed_literal ::= NK_BOOL */ - -2, /* (391) signed_literal ::= TIMESTAMP NK_STRING */ - -1, /* (392) signed_literal ::= duration_literal */ - -1, /* (393) signed_literal ::= NULL */ - -1, /* (394) signed_literal ::= literal_func */ - -1, /* (395) signed_literal ::= NK_QUESTION */ - -1, /* (396) literal_list ::= signed_literal */ - -3, /* (397) literal_list ::= literal_list NK_COMMA signed_literal */ - -1, /* (398) db_name ::= NK_ID */ - -1, /* (399) table_name ::= NK_ID */ - -1, /* (400) column_name ::= NK_ID */ - -1, /* (401) function_name ::= NK_ID */ - -1, /* (402) table_alias ::= NK_ID */ - -1, /* (403) column_alias ::= NK_ID */ - -1, /* (404) user_name ::= NK_ID */ - -1, /* (405) topic_name ::= NK_ID */ - -1, /* (406) stream_name ::= NK_ID */ - -1, /* (407) cgroup_name ::= NK_ID */ - -1, /* (408) index_name ::= NK_ID */ - -1, /* (409) expr_or_subquery ::= expression */ - -1, /* (410) expression ::= literal */ - -1, /* (411) expression ::= pseudo_column */ - -1, /* (412) expression ::= column_reference */ - -1, /* (413) expression ::= function_expression */ - -1, /* (414) expression ::= case_when_expression */ - -3, /* (415) expression ::= NK_LP expression NK_RP */ - -2, /* (416) expression ::= NK_PLUS expr_or_subquery */ - -2, /* (417) expression ::= NK_MINUS expr_or_subquery */ - -3, /* (418) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ - -3, /* (419) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ - -3, /* (420) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ - -3, /* (421) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ - -3, /* (422) expression ::= expr_or_subquery NK_REM expr_or_subquery */ - -3, /* (423) expression ::= column_reference NK_ARROW NK_STRING */ - -3, /* (424) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ - -3, /* (425) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ - -1, /* (426) expression_list ::= expr_or_subquery */ - -3, /* (427) expression_list ::= expression_list NK_COMMA expr_or_subquery */ - -1, /* (428) column_reference ::= column_name */ - -3, /* (429) column_reference ::= table_name NK_DOT column_name */ - -1, /* (430) pseudo_column ::= ROWTS */ - -1, /* (431) pseudo_column ::= TBNAME */ - -3, /* (432) pseudo_column ::= table_name NK_DOT TBNAME */ - -1, /* (433) pseudo_column ::= QSTART */ - -1, /* (434) pseudo_column ::= QEND */ - -1, /* (435) pseudo_column ::= QDURATION */ - -1, /* (436) pseudo_column ::= WSTART */ - -1, /* (437) pseudo_column ::= WEND */ - -1, /* (438) pseudo_column ::= WDURATION */ - -1, /* (439) pseudo_column ::= IROWTS */ - -1, /* (440) pseudo_column ::= ISFILLED */ - -1, /* (441) pseudo_column ::= QTAGS */ - -4, /* (442) function_expression ::= function_name NK_LP expression_list NK_RP */ - -4, /* (443) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ - -6, /* (444) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ - -1, /* (445) function_expression ::= literal_func */ - -3, /* (446) literal_func ::= noarg_func NK_LP NK_RP */ - -1, /* (447) literal_func ::= NOW */ - -1, /* (448) noarg_func ::= NOW */ - -1, /* (449) noarg_func ::= TODAY */ - -1, /* (450) noarg_func ::= TIMEZONE */ - -1, /* (451) noarg_func ::= DATABASE */ - -1, /* (452) noarg_func ::= CLIENT_VERSION */ - -1, /* (453) noarg_func ::= SERVER_VERSION */ - -1, /* (454) noarg_func ::= SERVER_STATUS */ - -1, /* (455) noarg_func ::= CURRENT_USER */ - -1, /* (456) noarg_func ::= USER */ - -1, /* (457) star_func ::= COUNT */ - -1, /* (458) star_func ::= FIRST */ - -1, /* (459) star_func ::= LAST */ - -1, /* (460) star_func ::= LAST_ROW */ - -1, /* (461) star_func_para_list ::= NK_STAR */ - -1, /* (462) star_func_para_list ::= other_para_list */ - -1, /* (463) other_para_list ::= star_func_para */ - -3, /* (464) other_para_list ::= other_para_list NK_COMMA star_func_para */ - -1, /* (465) star_func_para ::= expr_or_subquery */ - -3, /* (466) star_func_para ::= table_name NK_DOT NK_STAR */ - -4, /* (467) case_when_expression ::= CASE when_then_list case_when_else_opt END */ - -5, /* (468) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ - -1, /* (469) when_then_list ::= when_then_expr */ - -2, /* (470) when_then_list ::= when_then_list when_then_expr */ - -4, /* (471) when_then_expr ::= WHEN common_expression THEN common_expression */ - 0, /* (472) case_when_else_opt ::= */ - -2, /* (473) case_when_else_opt ::= ELSE common_expression */ - -3, /* (474) predicate ::= expr_or_subquery compare_op expr_or_subquery */ - -5, /* (475) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ - -6, /* (476) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ - -3, /* (477) predicate ::= expr_or_subquery IS NULL */ - -4, /* (478) predicate ::= expr_or_subquery IS NOT NULL */ - -3, /* (479) predicate ::= expr_or_subquery in_op in_predicate_value */ - -1, /* (480) compare_op ::= NK_LT */ - -1, /* (481) compare_op ::= NK_GT */ - -1, /* (482) compare_op ::= NK_LE */ - -1, /* (483) compare_op ::= NK_GE */ - -1, /* (484) compare_op ::= NK_NE */ - -1, /* (485) compare_op ::= NK_EQ */ - -1, /* (486) compare_op ::= LIKE */ - -2, /* (487) compare_op ::= NOT LIKE */ - -1, /* (488) compare_op ::= MATCH */ - -1, /* (489) compare_op ::= NMATCH */ - -1, /* (490) compare_op ::= CONTAINS */ - -1, /* (491) in_op ::= IN */ - -2, /* (492) in_op ::= NOT IN */ - -3, /* (493) in_predicate_value ::= NK_LP literal_list NK_RP */ - -1, /* (494) boolean_value_expression ::= boolean_primary */ - -2, /* (495) boolean_value_expression ::= NOT boolean_primary */ - -3, /* (496) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ - -3, /* (497) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ - -1, /* (498) boolean_primary ::= predicate */ - -3, /* (499) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ - -1, /* (500) common_expression ::= expr_or_subquery */ - -1, /* (501) common_expression ::= boolean_value_expression */ - 0, /* (502) from_clause_opt ::= */ - -2, /* (503) from_clause_opt ::= FROM table_reference_list */ - -1, /* (504) table_reference_list ::= table_reference */ - -3, /* (505) table_reference_list ::= table_reference_list NK_COMMA table_reference */ - -1, /* (506) table_reference ::= table_primary */ - -1, /* (507) table_reference ::= joined_table */ - -2, /* (508) table_primary ::= table_name alias_opt */ - -4, /* (509) table_primary ::= db_name NK_DOT table_name alias_opt */ - -2, /* (510) table_primary ::= subquery alias_opt */ - -1, /* (511) table_primary ::= parenthesized_joined_table */ - 0, /* (512) alias_opt ::= */ - -1, /* (513) alias_opt ::= table_alias */ - -2, /* (514) alias_opt ::= AS table_alias */ - -3, /* (515) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - -3, /* (516) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ - -6, /* (517) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ - 0, /* (518) join_type ::= */ - -1, /* (519) join_type ::= INNER */ - -12, /* (520) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ - 0, /* (521) set_quantifier_opt ::= */ - -1, /* (522) set_quantifier_opt ::= DISTINCT */ - -1, /* (523) set_quantifier_opt ::= ALL */ - -1, /* (524) select_list ::= select_item */ - -3, /* (525) select_list ::= select_list NK_COMMA select_item */ - -1, /* (526) select_item ::= NK_STAR */ - -1, /* (527) select_item ::= common_expression */ - -2, /* (528) select_item ::= common_expression column_alias */ - -3, /* (529) select_item ::= common_expression AS column_alias */ - -3, /* (530) select_item ::= table_name NK_DOT NK_STAR */ - 0, /* (531) where_clause_opt ::= */ - -2, /* (532) where_clause_opt ::= WHERE search_condition */ - 0, /* (533) partition_by_clause_opt ::= */ - -3, /* (534) partition_by_clause_opt ::= PARTITION BY partition_list */ - -1, /* (535) partition_list ::= partition_item */ - -3, /* (536) partition_list ::= partition_list NK_COMMA partition_item */ - -1, /* (537) partition_item ::= expr_or_subquery */ - -2, /* (538) partition_item ::= expr_or_subquery column_alias */ - -3, /* (539) partition_item ::= expr_or_subquery AS column_alias */ - 0, /* (540) twindow_clause_opt ::= */ - -6, /* (541) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ - -4, /* (542) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ - -6, /* (543) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ - -8, /* (544) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ - -7, /* (545) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ - 0, /* (546) sliding_opt ::= */ - -4, /* (547) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - 0, /* (548) fill_opt ::= */ - -4, /* (549) fill_opt ::= FILL NK_LP fill_mode NK_RP */ - -6, /* (550) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ - -6, /* (551) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ - -1, /* (552) fill_mode ::= NONE */ - -1, /* (553) fill_mode ::= PREV */ - -1, /* (554) fill_mode ::= NULL */ - -1, /* (555) fill_mode ::= NULL_F */ - -1, /* (556) fill_mode ::= LINEAR */ - -1, /* (557) fill_mode ::= NEXT */ - 0, /* (558) group_by_clause_opt ::= */ - -3, /* (559) group_by_clause_opt ::= GROUP BY group_by_list */ - -1, /* (560) group_by_list ::= expr_or_subquery */ - -3, /* (561) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ - 0, /* (562) having_clause_opt ::= */ - -2, /* (563) having_clause_opt ::= HAVING search_condition */ - 0, /* (564) range_opt ::= */ - -6, /* (565) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ - -4, /* (566) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ - 0, /* (567) every_opt ::= */ - -4, /* (568) every_opt ::= EVERY NK_LP duration_literal NK_RP */ - -4, /* (569) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ - -1, /* (570) query_simple ::= query_specification */ - -1, /* (571) query_simple ::= union_query_expression */ - -4, /* (572) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ - -3, /* (573) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ - -1, /* (574) query_simple_or_subquery ::= query_simple */ - -1, /* (575) query_simple_or_subquery ::= subquery */ - -1, /* (576) query_or_subquery ::= query_expression */ - -1, /* (577) query_or_subquery ::= subquery */ - 0, /* (578) order_by_clause_opt ::= */ - -3, /* (579) order_by_clause_opt ::= ORDER BY sort_specification_list */ - 0, /* (580) slimit_clause_opt ::= */ - -2, /* (581) slimit_clause_opt ::= SLIMIT NK_INTEGER */ - -4, /* (582) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - -4, /* (583) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - 0, /* (584) limit_clause_opt ::= */ - -2, /* (585) limit_clause_opt ::= LIMIT NK_INTEGER */ - -4, /* (586) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ - -4, /* (587) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - -3, /* (588) subquery ::= NK_LP query_expression NK_RP */ - -3, /* (589) subquery ::= NK_LP subquery NK_RP */ - -1, /* (590) search_condition ::= common_expression */ - -1, /* (591) sort_specification_list ::= sort_specification */ - -3, /* (592) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ - -3, /* (593) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ - 0, /* (594) ordering_specification_opt ::= */ - -1, /* (595) ordering_specification_opt ::= ASC */ - -1, /* (596) ordering_specification_opt ::= DESC */ - 0, /* (597) null_ordering_opt ::= */ - -2, /* (598) null_ordering_opt ::= NULLS FIRST */ - -2, /* (599) null_ordering_opt ::= NULLS LAST */ + -4, /* (182) column_def ::= column_name type_name COMMENT NK_STRING */ + -1, /* (183) type_name ::= BOOL */ + -1, /* (184) type_name ::= TINYINT */ + -1, /* (185) type_name ::= SMALLINT */ + -1, /* (186) type_name ::= INT */ + -1, /* (187) type_name ::= INTEGER */ + -1, /* (188) type_name ::= BIGINT */ + -1, /* (189) type_name ::= FLOAT */ + -1, /* (190) type_name ::= DOUBLE */ + -4, /* (191) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + -1, /* (192) type_name ::= TIMESTAMP */ + -4, /* (193) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + -2, /* (194) type_name ::= TINYINT UNSIGNED */ + -2, /* (195) type_name ::= SMALLINT UNSIGNED */ + -2, /* (196) type_name ::= INT UNSIGNED */ + -2, /* (197) type_name ::= BIGINT UNSIGNED */ + -1, /* (198) type_name ::= JSON */ + -4, /* (199) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + -1, /* (200) type_name ::= MEDIUMBLOB */ + -1, /* (201) type_name ::= BLOB */ + -4, /* (202) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + -4, /* (203) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ + -1, /* (204) type_name ::= DECIMAL */ + -4, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + -6, /* (206) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + 0, /* (207) tags_def_opt ::= */ + -1, /* (208) tags_def_opt ::= tags_def */ + -4, /* (209) tags_def ::= TAGS NK_LP column_def_list NK_RP */ + 0, /* (210) table_options ::= */ + -3, /* (211) table_options ::= table_options COMMENT NK_STRING */ + -3, /* (212) table_options ::= table_options MAX_DELAY duration_list */ + -3, /* (213) table_options ::= table_options WATERMARK duration_list */ + -5, /* (214) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ + -3, /* (215) table_options ::= table_options TTL NK_INTEGER */ + -5, /* (216) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ + -3, /* (217) table_options ::= table_options DELETE_MARK duration_list */ + -1, /* (218) alter_table_options ::= alter_table_option */ + -2, /* (219) alter_table_options ::= alter_table_options alter_table_option */ + -2, /* (220) alter_table_option ::= COMMENT NK_STRING */ + -2, /* (221) alter_table_option ::= TTL NK_INTEGER */ + -1, /* (222) duration_list ::= duration_literal */ + -3, /* (223) duration_list ::= duration_list NK_COMMA duration_literal */ + -1, /* (224) rollup_func_list ::= rollup_func_name */ + -3, /* (225) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ + -1, /* (226) rollup_func_name ::= function_name */ + -1, /* (227) rollup_func_name ::= FIRST */ + -1, /* (228) rollup_func_name ::= LAST */ + -1, /* (229) col_name_list ::= col_name */ + -3, /* (230) col_name_list ::= col_name_list NK_COMMA col_name */ + -1, /* (231) col_name ::= column_name */ + -2, /* (232) cmd ::= SHOW DNODES */ + -2, /* (233) cmd ::= SHOW USERS */ + -3, /* (234) cmd ::= SHOW USER PRIVILEGES */ + -2, /* (235) cmd ::= SHOW DATABASES */ + -4, /* (236) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ + -4, /* (237) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ + -3, /* (238) cmd ::= SHOW db_name_cond_opt VGROUPS */ + -2, /* (239) cmd ::= SHOW MNODES */ + -2, /* (240) cmd ::= SHOW QNODES */ + -2, /* (241) cmd ::= SHOW FUNCTIONS */ + -5, /* (242) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ + -6, /* (243) cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ + -2, /* (244) cmd ::= SHOW STREAMS */ + -2, /* (245) cmd ::= SHOW ACCOUNTS */ + -2, /* (246) cmd ::= SHOW APPS */ + -2, /* (247) cmd ::= SHOW CONNECTIONS */ + -2, /* (248) cmd ::= SHOW LICENCES */ + -2, /* (249) cmd ::= SHOW GRANTS */ + -4, /* (250) cmd ::= SHOW CREATE DATABASE db_name */ + -4, /* (251) cmd ::= SHOW CREATE TABLE full_table_name */ + -4, /* (252) cmd ::= SHOW CREATE STABLE full_table_name */ + -2, /* (253) cmd ::= SHOW QUERIES */ + -2, /* (254) cmd ::= SHOW SCORES */ + -2, /* (255) cmd ::= SHOW TOPICS */ + -2, /* (256) cmd ::= SHOW VARIABLES */ + -3, /* (257) cmd ::= SHOW CLUSTER VARIABLES */ + -3, /* (258) cmd ::= SHOW LOCAL VARIABLES */ + -5, /* (259) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ + -2, /* (260) cmd ::= SHOW BNODES */ + -2, /* (261) cmd ::= SHOW SNODES */ + -2, /* (262) cmd ::= SHOW CLUSTER */ + -2, /* (263) cmd ::= SHOW TRANSACTIONS */ + -4, /* (264) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + -2, /* (265) cmd ::= SHOW CONSUMERS */ + -2, /* (266) cmd ::= SHOW SUBSCRIPTIONS */ + -5, /* (267) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ + -6, /* (268) cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ + -7, /* (269) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ + -8, /* (270) cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ + -3, /* (271) cmd ::= SHOW VNODES NK_INTEGER */ + -3, /* (272) cmd ::= SHOW VNODES NK_STRING */ + -3, /* (273) cmd ::= SHOW db_name_cond_opt ALIVE */ + -3, /* (274) cmd ::= SHOW CLUSTER ALIVE */ + 0, /* (275) db_name_cond_opt ::= */ + -2, /* (276) db_name_cond_opt ::= db_name NK_DOT */ + 0, /* (277) like_pattern_opt ::= */ + -2, /* (278) like_pattern_opt ::= LIKE NK_STRING */ + -1, /* (279) table_name_cond ::= table_name */ + 0, /* (280) from_db_opt ::= */ + -2, /* (281) from_db_opt ::= FROM db_name */ + 0, /* (282) tag_list_opt ::= */ + -1, /* (283) tag_list_opt ::= tag_item */ + -3, /* (284) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ + -1, /* (285) tag_item ::= TBNAME */ + -1, /* (286) tag_item ::= QTAGS */ + -1, /* (287) tag_item ::= column_name */ + -2, /* (288) tag_item ::= column_name column_alias */ + -3, /* (289) tag_item ::= column_name AS column_alias */ + -8, /* (290) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ + -9, /* (291) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ + -4, /* (292) cmd ::= DROP INDEX exists_opt full_index_name */ + -1, /* (293) full_index_name ::= index_name */ + -3, /* (294) full_index_name ::= db_name NK_DOT index_name */ + -10, /* (295) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ + -12, /* (296) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ + -1, /* (297) func_list ::= func */ + -3, /* (298) func_list ::= func_list NK_COMMA func */ + -4, /* (299) func ::= sma_func_name NK_LP expression_list NK_RP */ + -1, /* (300) sma_func_name ::= function_name */ + -1, /* (301) sma_func_name ::= COUNT */ + -1, /* (302) sma_func_name ::= FIRST */ + -1, /* (303) sma_func_name ::= LAST */ + -1, /* (304) sma_func_name ::= LAST_ROW */ + 0, /* (305) sma_stream_opt ::= */ + -3, /* (306) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ + -3, /* (307) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ + -3, /* (308) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ + -1, /* (309) with_meta ::= AS */ + -3, /* (310) with_meta ::= WITH META AS */ + -3, /* (311) with_meta ::= ONLY META AS */ + -6, /* (312) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ + -7, /* (313) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ + -8, /* (314) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ + -4, /* (315) cmd ::= DROP TOPIC exists_opt topic_name */ + -7, /* (316) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + -2, /* (317) cmd ::= DESC full_table_name */ + -2, /* (318) cmd ::= DESCRIBE full_table_name */ + -3, /* (319) cmd ::= RESET QUERY CACHE */ + -4, /* (320) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + -4, /* (321) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ + 0, /* (322) analyze_opt ::= */ + -1, /* (323) analyze_opt ::= ANALYZE */ + 0, /* (324) explain_options ::= */ + -3, /* (325) explain_options ::= explain_options VERBOSE NK_BOOL */ + -3, /* (326) explain_options ::= explain_options RATIO NK_FLOAT */ + -12, /* (327) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ + -4, /* (328) cmd ::= DROP FUNCTION exists_opt function_name */ + 0, /* (329) agg_func_opt ::= */ + -1, /* (330) agg_func_opt ::= AGGREGATE */ + 0, /* (331) bufsize_opt ::= */ + -2, /* (332) bufsize_opt ::= BUFSIZE NK_INTEGER */ + 0, /* (333) language_opt ::= */ + -2, /* (334) language_opt ::= LANGUAGE NK_STRING */ + 0, /* (335) or_replace_opt ::= */ + -2, /* (336) or_replace_opt ::= OR REPLACE */ + -12, /* (337) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ + -4, /* (338) cmd ::= DROP STREAM exists_opt stream_name */ + -4, /* (339) cmd ::= PAUSE STREAM exists_opt stream_name */ + -5, /* (340) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ + 0, /* (341) col_list_opt ::= */ + -3, /* (342) col_list_opt ::= NK_LP col_name_list NK_RP */ + 0, /* (343) tag_def_or_ref_opt ::= */ + -1, /* (344) tag_def_or_ref_opt ::= tags_def */ + -4, /* (345) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ + 0, /* (346) stream_options ::= */ + -3, /* (347) stream_options ::= stream_options TRIGGER AT_ONCE */ + -3, /* (348) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + -4, /* (349) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + -3, /* (350) stream_options ::= stream_options WATERMARK duration_literal */ + -4, /* (351) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ + -3, /* (352) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ + -3, /* (353) stream_options ::= stream_options DELETE_MARK duration_literal */ + -4, /* (354) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ + 0, /* (355) subtable_opt ::= */ + -4, /* (356) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + 0, /* (357) ignore_opt ::= */ + -2, /* (358) ignore_opt ::= IGNORE UNTREATED */ + -3, /* (359) cmd ::= KILL CONNECTION NK_INTEGER */ + -3, /* (360) cmd ::= KILL QUERY NK_STRING */ + -3, /* (361) cmd ::= KILL TRANSACTION NK_INTEGER */ + -2, /* (362) cmd ::= BALANCE VGROUP */ + -3, /* (363) cmd ::= BALANCE VGROUP LEADER */ + -4, /* (364) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + -4, /* (365) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + -3, /* (366) cmd ::= SPLIT VGROUP NK_INTEGER */ + -2, /* (367) dnode_list ::= DNODE NK_INTEGER */ + -3, /* (368) dnode_list ::= dnode_list DNODE NK_INTEGER */ + -4, /* (369) cmd ::= DELETE FROM full_table_name where_clause_opt */ + -1, /* (370) cmd ::= query_or_subquery */ + -1, /* (371) cmd ::= insert_query */ + -7, /* (372) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ + -4, /* (373) insert_query ::= INSERT INTO full_table_name query_or_subquery */ + -1, /* (374) literal ::= NK_INTEGER */ + -1, /* (375) literal ::= NK_FLOAT */ + -1, /* (376) literal ::= NK_STRING */ + -1, /* (377) literal ::= NK_BOOL */ + -2, /* (378) literal ::= TIMESTAMP NK_STRING */ + -1, /* (379) literal ::= duration_literal */ + -1, /* (380) literal ::= NULL */ + -1, /* (381) literal ::= NK_QUESTION */ + -1, /* (382) duration_literal ::= NK_VARIABLE */ + -1, /* (383) signed ::= NK_INTEGER */ + -2, /* (384) signed ::= NK_PLUS NK_INTEGER */ + -2, /* (385) signed ::= NK_MINUS NK_INTEGER */ + -1, /* (386) signed ::= NK_FLOAT */ + -2, /* (387) signed ::= NK_PLUS NK_FLOAT */ + -2, /* (388) signed ::= NK_MINUS NK_FLOAT */ + -1, /* (389) signed_literal ::= signed */ + -1, /* (390) signed_literal ::= NK_STRING */ + -1, /* (391) signed_literal ::= NK_BOOL */ + -2, /* (392) signed_literal ::= TIMESTAMP NK_STRING */ + -1, /* (393) signed_literal ::= duration_literal */ + -1, /* (394) signed_literal ::= NULL */ + -1, /* (395) signed_literal ::= literal_func */ + -1, /* (396) signed_literal ::= NK_QUESTION */ + -1, /* (397) literal_list ::= signed_literal */ + -3, /* (398) literal_list ::= literal_list NK_COMMA signed_literal */ + -1, /* (399) db_name ::= NK_ID */ + -1, /* (400) table_name ::= NK_ID */ + -1, /* (401) column_name ::= NK_ID */ + -1, /* (402) function_name ::= NK_ID */ + -1, /* (403) table_alias ::= NK_ID */ + -1, /* (404) column_alias ::= NK_ID */ + -1, /* (405) user_name ::= NK_ID */ + -1, /* (406) topic_name ::= NK_ID */ + -1, /* (407) stream_name ::= NK_ID */ + -1, /* (408) cgroup_name ::= NK_ID */ + -1, /* (409) index_name ::= NK_ID */ + -1, /* (410) expr_or_subquery ::= expression */ + -1, /* (411) expression ::= literal */ + -1, /* (412) expression ::= pseudo_column */ + -1, /* (413) expression ::= column_reference */ + -1, /* (414) expression ::= function_expression */ + -1, /* (415) expression ::= case_when_expression */ + -3, /* (416) expression ::= NK_LP expression NK_RP */ + -2, /* (417) expression ::= NK_PLUS expr_or_subquery */ + -2, /* (418) expression ::= NK_MINUS expr_or_subquery */ + -3, /* (419) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + -3, /* (420) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + -3, /* (421) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + -3, /* (422) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + -3, /* (423) expression ::= expr_or_subquery NK_REM expr_or_subquery */ + -3, /* (424) expression ::= column_reference NK_ARROW NK_STRING */ + -3, /* (425) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + -3, /* (426) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + -1, /* (427) expression_list ::= expr_or_subquery */ + -3, /* (428) expression_list ::= expression_list NK_COMMA expr_or_subquery */ + -1, /* (429) column_reference ::= column_name */ + -3, /* (430) column_reference ::= table_name NK_DOT column_name */ + -1, /* (431) pseudo_column ::= ROWTS */ + -1, /* (432) pseudo_column ::= TBNAME */ + -3, /* (433) pseudo_column ::= table_name NK_DOT TBNAME */ + -1, /* (434) pseudo_column ::= QSTART */ + -1, /* (435) pseudo_column ::= QEND */ + -1, /* (436) pseudo_column ::= QDURATION */ + -1, /* (437) pseudo_column ::= WSTART */ + -1, /* (438) pseudo_column ::= WEND */ + -1, /* (439) pseudo_column ::= WDURATION */ + -1, /* (440) pseudo_column ::= IROWTS */ + -1, /* (441) pseudo_column ::= ISFILLED */ + -1, /* (442) pseudo_column ::= QTAGS */ + -4, /* (443) function_expression ::= function_name NK_LP expression_list NK_RP */ + -4, /* (444) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ + -6, /* (445) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ + -1, /* (446) function_expression ::= literal_func */ + -3, /* (447) literal_func ::= noarg_func NK_LP NK_RP */ + -1, /* (448) literal_func ::= NOW */ + -1, /* (449) noarg_func ::= NOW */ + -1, /* (450) noarg_func ::= TODAY */ + -1, /* (451) noarg_func ::= TIMEZONE */ + -1, /* (452) noarg_func ::= DATABASE */ + -1, /* (453) noarg_func ::= CLIENT_VERSION */ + -1, /* (454) noarg_func ::= SERVER_VERSION */ + -1, /* (455) noarg_func ::= SERVER_STATUS */ + -1, /* (456) noarg_func ::= CURRENT_USER */ + -1, /* (457) noarg_func ::= USER */ + -1, /* (458) star_func ::= COUNT */ + -1, /* (459) star_func ::= FIRST */ + -1, /* (460) star_func ::= LAST */ + -1, /* (461) star_func ::= LAST_ROW */ + -1, /* (462) star_func_para_list ::= NK_STAR */ + -1, /* (463) star_func_para_list ::= other_para_list */ + -1, /* (464) other_para_list ::= star_func_para */ + -3, /* (465) other_para_list ::= other_para_list NK_COMMA star_func_para */ + -1, /* (466) star_func_para ::= expr_or_subquery */ + -3, /* (467) star_func_para ::= table_name NK_DOT NK_STAR */ + -4, /* (468) case_when_expression ::= CASE when_then_list case_when_else_opt END */ + -5, /* (469) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ + -1, /* (470) when_then_list ::= when_then_expr */ + -2, /* (471) when_then_list ::= when_then_list when_then_expr */ + -4, /* (472) when_then_expr ::= WHEN common_expression THEN common_expression */ + 0, /* (473) case_when_else_opt ::= */ + -2, /* (474) case_when_else_opt ::= ELSE common_expression */ + -3, /* (475) predicate ::= expr_or_subquery compare_op expr_or_subquery */ + -5, /* (476) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + -6, /* (477) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + -3, /* (478) predicate ::= expr_or_subquery IS NULL */ + -4, /* (479) predicate ::= expr_or_subquery IS NOT NULL */ + -3, /* (480) predicate ::= expr_or_subquery in_op in_predicate_value */ + -1, /* (481) compare_op ::= NK_LT */ + -1, /* (482) compare_op ::= NK_GT */ + -1, /* (483) compare_op ::= NK_LE */ + -1, /* (484) compare_op ::= NK_GE */ + -1, /* (485) compare_op ::= NK_NE */ + -1, /* (486) compare_op ::= NK_EQ */ + -1, /* (487) compare_op ::= LIKE */ + -2, /* (488) compare_op ::= NOT LIKE */ + -1, /* (489) compare_op ::= MATCH */ + -1, /* (490) compare_op ::= NMATCH */ + -1, /* (491) compare_op ::= CONTAINS */ + -1, /* (492) in_op ::= IN */ + -2, /* (493) in_op ::= NOT IN */ + -3, /* (494) in_predicate_value ::= NK_LP literal_list NK_RP */ + -1, /* (495) boolean_value_expression ::= boolean_primary */ + -2, /* (496) boolean_value_expression ::= NOT boolean_primary */ + -3, /* (497) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + -3, /* (498) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + -1, /* (499) boolean_primary ::= predicate */ + -3, /* (500) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ + -1, /* (501) common_expression ::= expr_or_subquery */ + -1, /* (502) common_expression ::= boolean_value_expression */ + 0, /* (503) from_clause_opt ::= */ + -2, /* (504) from_clause_opt ::= FROM table_reference_list */ + -1, /* (505) table_reference_list ::= table_reference */ + -3, /* (506) table_reference_list ::= table_reference_list NK_COMMA table_reference */ + -1, /* (507) table_reference ::= table_primary */ + -1, /* (508) table_reference ::= joined_table */ + -2, /* (509) table_primary ::= table_name alias_opt */ + -4, /* (510) table_primary ::= db_name NK_DOT table_name alias_opt */ + -2, /* (511) table_primary ::= subquery alias_opt */ + -1, /* (512) table_primary ::= parenthesized_joined_table */ + 0, /* (513) alias_opt ::= */ + -1, /* (514) alias_opt ::= table_alias */ + -2, /* (515) alias_opt ::= AS table_alias */ + -3, /* (516) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + -3, /* (517) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ + -6, /* (518) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + 0, /* (519) join_type ::= */ + -1, /* (520) join_type ::= INNER */ + -12, /* (521) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + 0, /* (522) set_quantifier_opt ::= */ + -1, /* (523) set_quantifier_opt ::= DISTINCT */ + -1, /* (524) set_quantifier_opt ::= ALL */ + -1, /* (525) select_list ::= select_item */ + -3, /* (526) select_list ::= select_list NK_COMMA select_item */ + -1, /* (527) select_item ::= NK_STAR */ + -1, /* (528) select_item ::= common_expression */ + -2, /* (529) select_item ::= common_expression column_alias */ + -3, /* (530) select_item ::= common_expression AS column_alias */ + -3, /* (531) select_item ::= table_name NK_DOT NK_STAR */ + 0, /* (532) where_clause_opt ::= */ + -2, /* (533) where_clause_opt ::= WHERE search_condition */ + 0, /* (534) partition_by_clause_opt ::= */ + -3, /* (535) partition_by_clause_opt ::= PARTITION BY partition_list */ + -1, /* (536) partition_list ::= partition_item */ + -3, /* (537) partition_list ::= partition_list NK_COMMA partition_item */ + -1, /* (538) partition_item ::= expr_or_subquery */ + -2, /* (539) partition_item ::= expr_or_subquery column_alias */ + -3, /* (540) partition_item ::= expr_or_subquery AS column_alias */ + 0, /* (541) twindow_clause_opt ::= */ + -6, /* (542) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + -4, /* (543) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ + -6, /* (544) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + -8, /* (545) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + -7, /* (546) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ + 0, /* (547) sliding_opt ::= */ + -4, /* (548) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + 0, /* (549) fill_opt ::= */ + -4, /* (550) fill_opt ::= FILL NK_LP fill_mode NK_RP */ + -6, /* (551) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ + -6, /* (552) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ + -1, /* (553) fill_mode ::= NONE */ + -1, /* (554) fill_mode ::= PREV */ + -1, /* (555) fill_mode ::= NULL */ + -1, /* (556) fill_mode ::= NULL_F */ + -1, /* (557) fill_mode ::= LINEAR */ + -1, /* (558) fill_mode ::= NEXT */ + 0, /* (559) group_by_clause_opt ::= */ + -3, /* (560) group_by_clause_opt ::= GROUP BY group_by_list */ + -1, /* (561) group_by_list ::= expr_or_subquery */ + -3, /* (562) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ + 0, /* (563) having_clause_opt ::= */ + -2, /* (564) having_clause_opt ::= HAVING search_condition */ + 0, /* (565) range_opt ::= */ + -6, /* (566) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ + -4, /* (567) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ + 0, /* (568) every_opt ::= */ + -4, /* (569) every_opt ::= EVERY NK_LP duration_literal NK_RP */ + -4, /* (570) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + -1, /* (571) query_simple ::= query_specification */ + -1, /* (572) query_simple ::= union_query_expression */ + -4, /* (573) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ + -3, /* (574) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ + -1, /* (575) query_simple_or_subquery ::= query_simple */ + -1, /* (576) query_simple_or_subquery ::= subquery */ + -1, /* (577) query_or_subquery ::= query_expression */ + -1, /* (578) query_or_subquery ::= subquery */ + 0, /* (579) order_by_clause_opt ::= */ + -3, /* (580) order_by_clause_opt ::= ORDER BY sort_specification_list */ + 0, /* (581) slimit_clause_opt ::= */ + -2, /* (582) slimit_clause_opt ::= SLIMIT NK_INTEGER */ + -4, /* (583) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + -4, /* (584) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + 0, /* (585) limit_clause_opt ::= */ + -2, /* (586) limit_clause_opt ::= LIMIT NK_INTEGER */ + -4, /* (587) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ + -4, /* (588) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + -3, /* (589) subquery ::= NK_LP query_expression NK_RP */ + -3, /* (590) subquery ::= NK_LP subquery NK_RP */ + -1, /* (591) search_condition ::= common_expression */ + -1, /* (592) sort_specification_list ::= sort_specification */ + -3, /* (593) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ + -3, /* (594) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ + 0, /* (595) ordering_specification_opt ::= */ + -1, /* (596) ordering_specification_opt ::= ASC */ + -1, /* (597) ordering_specification_opt ::= DESC */ + 0, /* (598) null_ordering_opt ::= */ + -2, /* (599) null_ordering_opt ::= NULLS FIRST */ + -2, /* (600) null_ordering_opt ::= NULLS LAST */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -4426,8 +4426,9 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); #ifndef NDEBUG - if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + if( yyTraceFILE ){ yysize = yyRuleInfoNRhs[yyruleno]; if( yysize ){ fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", @@ -4602,25 +4603,25 @@ static YYACTIONTYPE yy_reduce( case 44: /* with_opt ::= */ case 144: /* start_opt ::= */ yytestcase(yyruleno==144); case 148: /* end_opt ::= */ yytestcase(yyruleno==148); - case 276: /* like_pattern_opt ::= */ yytestcase(yyruleno==276); - case 354: /* subtable_opt ::= */ yytestcase(yyruleno==354); - case 472: /* case_when_else_opt ::= */ yytestcase(yyruleno==472); - case 502: /* from_clause_opt ::= */ yytestcase(yyruleno==502); - case 531: /* where_clause_opt ::= */ yytestcase(yyruleno==531); - case 540: /* twindow_clause_opt ::= */ yytestcase(yyruleno==540); - case 546: /* sliding_opt ::= */ yytestcase(yyruleno==546); - case 548: /* fill_opt ::= */ yytestcase(yyruleno==548); - case 562: /* having_clause_opt ::= */ yytestcase(yyruleno==562); - case 564: /* range_opt ::= */ yytestcase(yyruleno==564); - case 567: /* every_opt ::= */ yytestcase(yyruleno==567); - case 580: /* slimit_clause_opt ::= */ yytestcase(yyruleno==580); - case 584: /* limit_clause_opt ::= */ yytestcase(yyruleno==584); + case 277: /* like_pattern_opt ::= */ yytestcase(yyruleno==277); + case 355: /* subtable_opt ::= */ yytestcase(yyruleno==355); + case 473: /* case_when_else_opt ::= */ yytestcase(yyruleno==473); + case 503: /* from_clause_opt ::= */ yytestcase(yyruleno==503); + case 532: /* where_clause_opt ::= */ yytestcase(yyruleno==532); + case 541: /* twindow_clause_opt ::= */ yytestcase(yyruleno==541); + case 547: /* sliding_opt ::= */ yytestcase(yyruleno==547); + case 549: /* fill_opt ::= */ yytestcase(yyruleno==549); + case 563: /* having_clause_opt ::= */ yytestcase(yyruleno==563); + case 565: /* range_opt ::= */ yytestcase(yyruleno==565); + case 568: /* every_opt ::= */ yytestcase(yyruleno==568); + case 581: /* slimit_clause_opt ::= */ yytestcase(yyruleno==581); + case 585: /* limit_clause_opt ::= */ yytestcase(yyruleno==585); { yymsp[1].minor.yy452 = NULL; } break; case 45: /* with_opt ::= WITH search_condition */ - case 503: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==503); - case 532: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==532); - case 563: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==563); + case 504: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==504); + case 533: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==533); + case 564: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==564); { yymsp[-1].minor.yy452 = yymsp[0].minor.yy452; } break; case 46: /* cmd ::= CREATE DNODE dnode_endpoint */ @@ -4659,52 +4660,52 @@ static YYACTIONTYPE yy_reduce( case 57: /* dnode_endpoint ::= NK_STRING */ case 58: /* dnode_endpoint ::= NK_ID */ yytestcase(yyruleno==58); case 59: /* dnode_endpoint ::= NK_IPTOKEN */ yytestcase(yyruleno==59); - case 300: /* sma_func_name ::= COUNT */ yytestcase(yyruleno==300); - case 301: /* sma_func_name ::= FIRST */ yytestcase(yyruleno==301); - case 302: /* sma_func_name ::= LAST */ yytestcase(yyruleno==302); - case 303: /* sma_func_name ::= LAST_ROW */ yytestcase(yyruleno==303); - case 398: /* db_name ::= NK_ID */ yytestcase(yyruleno==398); - case 399: /* table_name ::= NK_ID */ yytestcase(yyruleno==399); - case 400: /* column_name ::= NK_ID */ yytestcase(yyruleno==400); - case 401: /* function_name ::= NK_ID */ yytestcase(yyruleno==401); - case 402: /* table_alias ::= NK_ID */ yytestcase(yyruleno==402); - case 403: /* column_alias ::= NK_ID */ yytestcase(yyruleno==403); - case 404: /* user_name ::= NK_ID */ yytestcase(yyruleno==404); - case 405: /* topic_name ::= NK_ID */ yytestcase(yyruleno==405); - case 406: /* stream_name ::= NK_ID */ yytestcase(yyruleno==406); - case 407: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==407); - case 408: /* index_name ::= NK_ID */ yytestcase(yyruleno==408); - case 448: /* noarg_func ::= NOW */ yytestcase(yyruleno==448); - case 449: /* noarg_func ::= TODAY */ yytestcase(yyruleno==449); - case 450: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==450); - case 451: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==451); - case 452: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==452); - case 453: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==453); - case 454: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==454); - case 455: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==455); - case 456: /* noarg_func ::= USER */ yytestcase(yyruleno==456); - case 457: /* star_func ::= COUNT */ yytestcase(yyruleno==457); - case 458: /* star_func ::= FIRST */ yytestcase(yyruleno==458); - case 459: /* star_func ::= LAST */ yytestcase(yyruleno==459); - case 460: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==460); + case 301: /* sma_func_name ::= COUNT */ yytestcase(yyruleno==301); + case 302: /* sma_func_name ::= FIRST */ yytestcase(yyruleno==302); + case 303: /* sma_func_name ::= LAST */ yytestcase(yyruleno==303); + case 304: /* sma_func_name ::= LAST_ROW */ yytestcase(yyruleno==304); + case 399: /* db_name ::= NK_ID */ yytestcase(yyruleno==399); + case 400: /* table_name ::= NK_ID */ yytestcase(yyruleno==400); + case 401: /* column_name ::= NK_ID */ yytestcase(yyruleno==401); + case 402: /* function_name ::= NK_ID */ yytestcase(yyruleno==402); + case 403: /* table_alias ::= NK_ID */ yytestcase(yyruleno==403); + case 404: /* column_alias ::= NK_ID */ yytestcase(yyruleno==404); + case 405: /* user_name ::= NK_ID */ yytestcase(yyruleno==405); + case 406: /* topic_name ::= NK_ID */ yytestcase(yyruleno==406); + case 407: /* stream_name ::= NK_ID */ yytestcase(yyruleno==407); + case 408: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==408); + case 409: /* index_name ::= NK_ID */ yytestcase(yyruleno==409); + case 449: /* noarg_func ::= NOW */ yytestcase(yyruleno==449); + case 450: /* noarg_func ::= TODAY */ yytestcase(yyruleno==450); + case 451: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==451); + case 452: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==452); + case 453: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==453); + case 454: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==454); + case 455: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==455); + case 456: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==456); + case 457: /* noarg_func ::= USER */ yytestcase(yyruleno==457); + case 458: /* star_func ::= COUNT */ yytestcase(yyruleno==458); + case 459: /* star_func ::= FIRST */ yytestcase(yyruleno==459); + case 460: /* star_func ::= LAST */ yytestcase(yyruleno==460); + case 461: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==461); { yylhsminor.yy371 = yymsp[0].minor.yy0; } yymsp[0].minor.yy371 = yylhsminor.yy371; break; case 60: /* force_opt ::= */ case 84: /* not_exists_opt ::= */ yytestcase(yyruleno==84); case 86: /* exists_opt ::= */ yytestcase(yyruleno==86); - case 321: /* analyze_opt ::= */ yytestcase(yyruleno==321); - case 328: /* agg_func_opt ::= */ yytestcase(yyruleno==328); - case 334: /* or_replace_opt ::= */ yytestcase(yyruleno==334); - case 356: /* ignore_opt ::= */ yytestcase(yyruleno==356); - case 521: /* set_quantifier_opt ::= */ yytestcase(yyruleno==521); + case 322: /* analyze_opt ::= */ yytestcase(yyruleno==322); + case 329: /* agg_func_opt ::= */ yytestcase(yyruleno==329); + case 335: /* or_replace_opt ::= */ yytestcase(yyruleno==335); + case 357: /* ignore_opt ::= */ yytestcase(yyruleno==357); + case 522: /* set_quantifier_opt ::= */ yytestcase(yyruleno==522); { yymsp[1].minor.yy667 = false; } break; case 61: /* force_opt ::= FORCE */ case 62: /* unsafe_opt ::= UNSAFE */ yytestcase(yyruleno==62); - case 322: /* analyze_opt ::= ANALYZE */ yytestcase(yyruleno==322); - case 329: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==329); - case 522: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==522); + case 323: /* analyze_opt ::= ANALYZE */ yytestcase(yyruleno==323); + case 330: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==330); + case 523: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==523); { yymsp[0].minor.yy667 = true; } break; case 63: /* cmd ::= ALTER LOCAL NK_STRING */ @@ -4771,8 +4772,8 @@ static YYACTIONTYPE yy_reduce( { yymsp[-2].minor.yy667 = true; } break; case 85: /* exists_opt ::= IF EXISTS */ - case 335: /* or_replace_opt ::= OR REPLACE */ yytestcase(yyruleno==335); - case 357: /* ignore_opt ::= IGNORE UNTREATED */ yytestcase(yyruleno==357); + case 336: /* or_replace_opt ::= OR REPLACE */ yytestcase(yyruleno==336); + case 358: /* ignore_opt ::= IGNORE UNTREATED */ yytestcase(yyruleno==358); { yymsp[-1].minor.yy667 = true; } break; case 87: /* db_options ::= */ @@ -4964,7 +4965,7 @@ static YYACTIONTYPE yy_reduce( yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 136: /* integer_list ::= integer_list NK_COMMA NK_INTEGER */ - case 367: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==367); + case 368: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==368); { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } yymsp[-2].minor.yy812 = yylhsminor.yy812; break; @@ -4980,31 +4981,31 @@ static YYACTIONTYPE yy_reduce( case 169: /* multi_create_clause ::= create_subtable_clause */ yytestcase(yyruleno==169); case 172: /* multi_drop_clause ::= drop_table_clause */ yytestcase(yyruleno==172); case 179: /* column_def_list ::= column_def */ yytestcase(yyruleno==179); - case 223: /* rollup_func_list ::= rollup_func_name */ yytestcase(yyruleno==223); - case 228: /* col_name_list ::= col_name */ yytestcase(yyruleno==228); - case 282: /* tag_list_opt ::= tag_item */ yytestcase(yyruleno==282); - case 296: /* func_list ::= func */ yytestcase(yyruleno==296); - case 396: /* literal_list ::= signed_literal */ yytestcase(yyruleno==396); - case 463: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==463); - case 469: /* when_then_list ::= when_then_expr */ yytestcase(yyruleno==469); - case 524: /* select_list ::= select_item */ yytestcase(yyruleno==524); - case 535: /* partition_list ::= partition_item */ yytestcase(yyruleno==535); - case 591: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==591); + case 224: /* rollup_func_list ::= rollup_func_name */ yytestcase(yyruleno==224); + case 229: /* col_name_list ::= col_name */ yytestcase(yyruleno==229); + case 283: /* tag_list_opt ::= tag_item */ yytestcase(yyruleno==283); + case 297: /* func_list ::= func */ yytestcase(yyruleno==297); + case 397: /* literal_list ::= signed_literal */ yytestcase(yyruleno==397); + case 464: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==464); + case 470: /* when_then_list ::= when_then_expr */ yytestcase(yyruleno==470); + case 525: /* select_list ::= select_item */ yytestcase(yyruleno==525); + case 536: /* partition_list ::= partition_item */ yytestcase(yyruleno==536); + case 592: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==592); { yylhsminor.yy812 = createNodeList(pCxt, yymsp[0].minor.yy452); } yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 140: /* retention_list ::= retention_list NK_COMMA retention */ case 173: /* multi_drop_clause ::= multi_drop_clause NK_COMMA drop_table_clause */ yytestcase(yyruleno==173); case 180: /* column_def_list ::= column_def_list NK_COMMA column_def */ yytestcase(yyruleno==180); - case 224: /* rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ yytestcase(yyruleno==224); - case 229: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==229); - case 283: /* tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ yytestcase(yyruleno==283); - case 297: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==297); - case 397: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==397); - case 464: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==464); - case 525: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==525); - case 536: /* partition_list ::= partition_list NK_COMMA partition_item */ yytestcase(yyruleno==536); - case 592: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==592); + case 225: /* rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ yytestcase(yyruleno==225); + case 230: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==230); + case 284: /* tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ yytestcase(yyruleno==284); + case 298: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==298); + case 398: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==398); + case 465: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==465); + case 526: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==526); + case 537: /* partition_list ::= partition_list NK_COMMA partition_item */ yytestcase(yyruleno==537); + case 593: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==593); { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, yymsp[0].minor.yy452); } yymsp[-2].minor.yy812 = yylhsminor.yy812; break; @@ -5013,11 +5014,11 @@ static YYACTIONTYPE yy_reduce( yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 142: /* speed_opt ::= */ - case 330: /* bufsize_opt ::= */ yytestcase(yyruleno==330); + case 331: /* bufsize_opt ::= */ yytestcase(yyruleno==331); { yymsp[1].minor.yy416 = 0; } break; case 143: /* speed_opt ::= MAX_SPEED NK_INTEGER */ - case 331: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ yytestcase(yyruleno==331); + case 332: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ yytestcase(yyruleno==332); { yymsp[-1].minor.yy416 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); } break; case 145: /* start_opt ::= START WITH NK_INTEGER */ @@ -5046,8 +5047,8 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy667, yymsp[0].minor.yy452); } break; case 157: /* cmd ::= ALTER TABLE alter_table_clause */ - case 369: /* cmd ::= query_or_subquery */ yytestcase(yyruleno==369); - case 370: /* cmd ::= insert_query */ yytestcase(yyruleno==370); + case 370: /* cmd ::= query_or_subquery */ yytestcase(yyruleno==370); + case 371: /* cmd ::= insert_query */ yytestcase(yyruleno==371); { pCxt->pRootNode = yymsp[0].minor.yy452; } break; case 158: /* cmd ::= ALTER STABLE alter_table_clause */ @@ -5094,7 +5095,7 @@ static YYACTIONTYPE yy_reduce( yymsp[-5].minor.yy452 = yylhsminor.yy452; break; case 170: /* multi_create_clause ::= multi_create_clause create_subtable_clause */ - case 470: /* when_then_list ::= when_then_list when_then_expr */ yytestcase(yyruleno==470); + case 471: /* when_then_list ::= when_then_list when_then_expr */ yytestcase(yyruleno==471); { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-1].minor.yy812, yymsp[0].minor.yy452); } yymsp[-1].minor.yy812 = yylhsminor.yy812; break; @@ -5107,17 +5108,17 @@ static YYACTIONTYPE yy_reduce( yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 175: /* specific_cols_opt ::= */ - case 206: /* tags_def_opt ::= */ yytestcase(yyruleno==206); - case 281: /* tag_list_opt ::= */ yytestcase(yyruleno==281); - case 340: /* col_list_opt ::= */ yytestcase(yyruleno==340); - case 342: /* tag_def_or_ref_opt ::= */ yytestcase(yyruleno==342); - case 533: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==533); - case 558: /* group_by_clause_opt ::= */ yytestcase(yyruleno==558); - case 578: /* order_by_clause_opt ::= */ yytestcase(yyruleno==578); + case 207: /* tags_def_opt ::= */ yytestcase(yyruleno==207); + case 282: /* tag_list_opt ::= */ yytestcase(yyruleno==282); + case 341: /* col_list_opt ::= */ yytestcase(yyruleno==341); + case 343: /* tag_def_or_ref_opt ::= */ yytestcase(yyruleno==343); + case 534: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==534); + case 559: /* group_by_clause_opt ::= */ yytestcase(yyruleno==559); + case 579: /* order_by_clause_opt ::= */ yytestcase(yyruleno==579); { yymsp[1].minor.yy812 = NULL; } break; case 176: /* specific_cols_opt ::= NK_LP col_name_list NK_RP */ - case 341: /* col_list_opt ::= NK_LP col_name_list NK_RP */ yytestcase(yyruleno==341); + case 342: /* col_list_opt ::= NK_LP col_name_list NK_RP */ yytestcase(yyruleno==342); { yymsp[-2].minor.yy812 = yymsp[-1].minor.yy812; } break; case 177: /* full_table_name ::= table_name */ @@ -5132,563 +5133,567 @@ static YYACTIONTYPE yy_reduce( { yylhsminor.yy452 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310, NULL); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 182: /* type_name ::= BOOL */ + case 182: /* column_def ::= column_name type_name COMMENT NK_STRING */ +{ yylhsminor.yy452 = createColumnDefNode(pCxt, &yymsp[-3].minor.yy371, yymsp[-2].minor.yy310, &yymsp[0].minor.yy0); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; + break; + case 183: /* type_name ::= BOOL */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_BOOL); } break; - case 183: /* type_name ::= TINYINT */ + case 184: /* type_name ::= TINYINT */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_TINYINT); } break; - case 184: /* type_name ::= SMALLINT */ + case 185: /* type_name ::= SMALLINT */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_SMALLINT); } break; - case 185: /* type_name ::= INT */ - case 186: /* type_name ::= INTEGER */ yytestcase(yyruleno==186); + case 186: /* type_name ::= INT */ + case 187: /* type_name ::= INTEGER */ yytestcase(yyruleno==187); { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_INT); } break; - case 187: /* type_name ::= BIGINT */ + case 188: /* type_name ::= BIGINT */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_BIGINT); } break; - case 188: /* type_name ::= FLOAT */ + case 189: /* type_name ::= FLOAT */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_FLOAT); } break; - case 189: /* type_name ::= DOUBLE */ + case 190: /* type_name ::= DOUBLE */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_DOUBLE); } break; - case 190: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + case 191: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } break; - case 191: /* type_name ::= TIMESTAMP */ + case 192: /* type_name ::= TIMESTAMP */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } break; - case 192: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + case 193: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } break; - case 193: /* type_name ::= TINYINT UNSIGNED */ + case 194: /* type_name ::= TINYINT UNSIGNED */ { yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_UTINYINT); } break; - case 194: /* type_name ::= SMALLINT UNSIGNED */ + case 195: /* type_name ::= SMALLINT UNSIGNED */ { yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_USMALLINT); } break; - case 195: /* type_name ::= INT UNSIGNED */ + case 196: /* type_name ::= INT UNSIGNED */ { yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_UINT); } break; - case 196: /* type_name ::= BIGINT UNSIGNED */ + case 197: /* type_name ::= BIGINT UNSIGNED */ { yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_UBIGINT); } break; - case 197: /* type_name ::= JSON */ + case 198: /* type_name ::= JSON */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_JSON); } break; - case 198: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + case 199: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } break; - case 199: /* type_name ::= MEDIUMBLOB */ + case 200: /* type_name ::= MEDIUMBLOB */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } break; - case 200: /* type_name ::= BLOB */ + case 201: /* type_name ::= BLOB */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_BLOB); } break; - case 201: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + case 202: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } break; - case 202: /* type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ + case 203: /* type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_GEOMETRY, &yymsp[-1].minor.yy0); } break; - case 203: /* type_name ::= DECIMAL */ + case 204: /* type_name ::= DECIMAL */ { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; - case 204: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + case 205: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ { yymsp[-3].minor.yy310 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; - case 205: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + case 206: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ { yymsp[-5].minor.yy310 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; - case 207: /* tags_def_opt ::= tags_def */ - case 343: /* tag_def_or_ref_opt ::= tags_def */ yytestcase(yyruleno==343); - case 462: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==462); + case 208: /* tags_def_opt ::= tags_def */ + case 344: /* tag_def_or_ref_opt ::= tags_def */ yytestcase(yyruleno==344); + case 463: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==463); { yylhsminor.yy812 = yymsp[0].minor.yy812; } yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 208: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ - case 344: /* tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ yytestcase(yyruleno==344); + case 209: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ + case 345: /* tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ yytestcase(yyruleno==345); { yymsp[-3].minor.yy812 = yymsp[-1].minor.yy812; } break; - case 209: /* table_options ::= */ + case 210: /* table_options ::= */ { yymsp[1].minor.yy452 = createDefaultTableOptions(pCxt); } break; - case 210: /* table_options ::= table_options COMMENT NK_STRING */ + case 211: /* table_options ::= table_options COMMENT NK_STRING */ { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 211: /* table_options ::= table_options MAX_DELAY duration_list */ + case 212: /* table_options ::= table_options MAX_DELAY duration_list */ { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_MAXDELAY, yymsp[0].minor.yy812); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 212: /* table_options ::= table_options WATERMARK duration_list */ + case 213: /* table_options ::= table_options WATERMARK duration_list */ { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_WATERMARK, yymsp[0].minor.yy812); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 213: /* table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ + case 214: /* table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-4].minor.yy452, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy812); } yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 214: /* table_options ::= table_options TTL NK_INTEGER */ + case 215: /* table_options ::= table_options TTL NK_INTEGER */ { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 215: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ + case 216: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-4].minor.yy452, TABLE_OPTION_SMA, yymsp[-1].minor.yy812); } yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 216: /* table_options ::= table_options DELETE_MARK duration_list */ + case 217: /* table_options ::= table_options DELETE_MARK duration_list */ { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_DELETE_MARK, yymsp[0].minor.yy812); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 217: /* alter_table_options ::= alter_table_option */ + case 218: /* alter_table_options ::= alter_table_option */ { yylhsminor.yy452 = createAlterTableOptions(pCxt); yylhsminor.yy452 = setTableOption(pCxt, yylhsminor.yy452, yymsp[0].minor.yy365.type, &yymsp[0].minor.yy365.val); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 218: /* alter_table_options ::= alter_table_options alter_table_option */ + case 219: /* alter_table_options ::= alter_table_options alter_table_option */ { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy365.type, &yymsp[0].minor.yy365.val); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 219: /* alter_table_option ::= COMMENT NK_STRING */ + case 220: /* alter_table_option ::= COMMENT NK_STRING */ { yymsp[-1].minor.yy365.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; - case 220: /* alter_table_option ::= TTL NK_INTEGER */ + case 221: /* alter_table_option ::= TTL NK_INTEGER */ { yymsp[-1].minor.yy365.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; - case 221: /* duration_list ::= duration_literal */ - case 426: /* expression_list ::= expr_or_subquery */ yytestcase(yyruleno==426); + case 222: /* duration_list ::= duration_literal */ + case 427: /* expression_list ::= expr_or_subquery */ yytestcase(yyruleno==427); { yylhsminor.yy812 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 222: /* duration_list ::= duration_list NK_COMMA duration_literal */ - case 427: /* expression_list ::= expression_list NK_COMMA expr_or_subquery */ yytestcase(yyruleno==427); + case 223: /* duration_list ::= duration_list NK_COMMA duration_literal */ + case 428: /* expression_list ::= expression_list NK_COMMA expr_or_subquery */ yytestcase(yyruleno==428); { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } yymsp[-2].minor.yy812 = yylhsminor.yy812; break; - case 225: /* rollup_func_name ::= function_name */ + case 226: /* rollup_func_name ::= function_name */ { yylhsminor.yy452 = createFunctionNode(pCxt, &yymsp[0].minor.yy371, NULL); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 226: /* rollup_func_name ::= FIRST */ - case 227: /* rollup_func_name ::= LAST */ yytestcase(yyruleno==227); - case 285: /* tag_item ::= QTAGS */ yytestcase(yyruleno==285); + case 227: /* rollup_func_name ::= FIRST */ + case 228: /* rollup_func_name ::= LAST */ yytestcase(yyruleno==228); + case 286: /* tag_item ::= QTAGS */ yytestcase(yyruleno==286); { yylhsminor.yy452 = createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 230: /* col_name ::= column_name */ - case 286: /* tag_item ::= column_name */ yytestcase(yyruleno==286); + case 231: /* col_name ::= column_name */ + case 287: /* tag_item ::= column_name */ yytestcase(yyruleno==287); { yylhsminor.yy452 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy371); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 231: /* cmd ::= SHOW DNODES */ + case 232: /* cmd ::= SHOW DNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DNODES_STMT); } break; - case 232: /* cmd ::= SHOW USERS */ + case 233: /* cmd ::= SHOW USERS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_USERS_STMT); } break; - case 233: /* cmd ::= SHOW USER PRIVILEGES */ + case 234: /* cmd ::= SHOW USER PRIVILEGES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_USER_PRIVILEGES_STMT); } break; - case 234: /* cmd ::= SHOW DATABASES */ + case 235: /* cmd ::= SHOW DATABASES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT); } break; - case 235: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ + case 236: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, OP_TYPE_LIKE); } break; - case 236: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ + case 237: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, OP_TYPE_LIKE); } break; - case 237: /* cmd ::= SHOW db_name_cond_opt VGROUPS */ + case 238: /* cmd ::= SHOW db_name_cond_opt VGROUPS */ { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy452, NULL, OP_TYPE_LIKE); } break; - case 238: /* cmd ::= SHOW MNODES */ + case 239: /* cmd ::= SHOW MNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); } break; - case 239: /* cmd ::= SHOW QNODES */ + case 240: /* cmd ::= SHOW QNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT); } break; - case 240: /* cmd ::= SHOW FUNCTIONS */ + case 241: /* cmd ::= SHOW FUNCTIONS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT); } break; - case 241: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ + case 242: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[0].minor.yy452, yymsp[-1].minor.yy452, OP_TYPE_EQUAL); } break; - case 242: /* cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ + case 243: /* cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, createIdentifierValueNode(pCxt, &yymsp[-2].minor.yy371), createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371), OP_TYPE_EQUAL); } break; - case 243: /* cmd ::= SHOW STREAMS */ + case 244: /* cmd ::= SHOW STREAMS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT); } break; - case 244: /* cmd ::= SHOW ACCOUNTS */ + case 245: /* cmd ::= SHOW ACCOUNTS */ { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } break; - case 245: /* cmd ::= SHOW APPS */ + case 246: /* cmd ::= SHOW APPS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT); } break; - case 246: /* cmd ::= SHOW CONNECTIONS */ + case 247: /* cmd ::= SHOW CONNECTIONS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONNECTIONS_STMT); } break; - case 247: /* cmd ::= SHOW LICENCES */ - case 248: /* cmd ::= SHOW GRANTS */ yytestcase(yyruleno==248); + case 248: /* cmd ::= SHOW LICENCES */ + case 249: /* cmd ::= SHOW GRANTS */ yytestcase(yyruleno==249); { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LICENCES_STMT); } break; - case 249: /* cmd ::= SHOW CREATE DATABASE db_name */ + case 250: /* cmd ::= SHOW CREATE DATABASE db_name */ { pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy371); } break; - case 250: /* cmd ::= SHOW CREATE TABLE full_table_name */ + case 251: /* cmd ::= SHOW CREATE TABLE full_table_name */ { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy452); } break; - case 251: /* cmd ::= SHOW CREATE STABLE full_table_name */ + case 252: /* cmd ::= SHOW CREATE STABLE full_table_name */ { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy452); } break; - case 252: /* cmd ::= SHOW QUERIES */ + case 253: /* cmd ::= SHOW QUERIES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QUERIES_STMT); } break; - case 253: /* cmd ::= SHOW SCORES */ + case 254: /* cmd ::= SHOW SCORES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SCORES_STMT); } break; - case 254: /* cmd ::= SHOW TOPICS */ + case 255: /* cmd ::= SHOW TOPICS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TOPICS_STMT); } break; - case 255: /* cmd ::= SHOW VARIABLES */ - case 256: /* cmd ::= SHOW CLUSTER VARIABLES */ yytestcase(yyruleno==256); + case 256: /* cmd ::= SHOW VARIABLES */ + case 257: /* cmd ::= SHOW CLUSTER VARIABLES */ yytestcase(yyruleno==257); { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VARIABLES_STMT); } break; - case 257: /* cmd ::= SHOW LOCAL VARIABLES */ + case 258: /* cmd ::= SHOW LOCAL VARIABLES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT); } break; - case 258: /* cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ + case 259: /* cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ { pCxt->pRootNode = createShowDnodeVariablesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[-2].minor.yy0), yymsp[0].minor.yy452); } break; - case 259: /* cmd ::= SHOW BNODES */ + case 260: /* cmd ::= SHOW BNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_BNODES_STMT); } break; - case 260: /* cmd ::= SHOW SNODES */ + case 261: /* cmd ::= SHOW SNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SNODES_STMT); } break; - case 261: /* cmd ::= SHOW CLUSTER */ + case 262: /* cmd ::= SHOW CLUSTER */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CLUSTER_STMT); } break; - case 262: /* cmd ::= SHOW TRANSACTIONS */ + case 263: /* cmd ::= SHOW TRANSACTIONS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TRANSACTIONS_STMT); } break; - case 263: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + case 264: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ { pCxt->pRootNode = createShowTableDistributedStmt(pCxt, yymsp[0].minor.yy452); } break; - case 264: /* cmd ::= SHOW CONSUMERS */ + case 265: /* cmd ::= SHOW CONSUMERS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONSUMERS_STMT); } break; - case 265: /* cmd ::= SHOW SUBSCRIPTIONS */ + case 266: /* cmd ::= SHOW SUBSCRIPTIONS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SUBSCRIPTIONS_STMT); } break; - case 266: /* cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ + case 267: /* cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, yymsp[0].minor.yy452, yymsp[-1].minor.yy452, OP_TYPE_EQUAL); } break; - case 267: /* cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ + case 268: /* cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, createIdentifierValueNode(pCxt, &yymsp[-2].minor.yy371), createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371), OP_TYPE_EQUAL); } break; - case 268: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ + case 269: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ { pCxt->pRootNode = createShowTableTagsStmt(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy452, yymsp[-3].minor.yy812); } break; - case 269: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ + case 270: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ { pCxt->pRootNode = createShowTableTagsStmt(pCxt, createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371), createIdentifierValueNode(pCxt, &yymsp[-2].minor.yy371), yymsp[-4].minor.yy812); } break; - case 270: /* cmd ::= SHOW VNODES NK_INTEGER */ + case 271: /* cmd ::= SHOW VNODES NK_INTEGER */ { pCxt->pRootNode = createShowVnodesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0), NULL); } break; - case 271: /* cmd ::= SHOW VNODES NK_STRING */ + case 272: /* cmd ::= SHOW VNODES NK_STRING */ { pCxt->pRootNode = createShowVnodesStmt(pCxt, NULL, createValueNode(pCxt, TSDB_DATA_TYPE_VARCHAR, &yymsp[0].minor.yy0)); } break; - case 272: /* cmd ::= SHOW db_name_cond_opt ALIVE */ + case 273: /* cmd ::= SHOW db_name_cond_opt ALIVE */ { pCxt->pRootNode = createShowAliveStmt(pCxt, yymsp[-1].minor.yy452, QUERY_NODE_SHOW_DB_ALIVE_STMT); } break; - case 273: /* cmd ::= SHOW CLUSTER ALIVE */ + case 274: /* cmd ::= SHOW CLUSTER ALIVE */ { pCxt->pRootNode = createShowAliveStmt(pCxt, NULL, QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT); } break; - case 274: /* db_name_cond_opt ::= */ - case 279: /* from_db_opt ::= */ yytestcase(yyruleno==279); + case 275: /* db_name_cond_opt ::= */ + case 280: /* from_db_opt ::= */ yytestcase(yyruleno==280); { yymsp[1].minor.yy452 = createDefaultDatabaseCondValue(pCxt); } break; - case 275: /* db_name_cond_opt ::= db_name NK_DOT */ + case 276: /* db_name_cond_opt ::= db_name NK_DOT */ { yylhsminor.yy452 = createIdentifierValueNode(pCxt, &yymsp[-1].minor.yy371); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 277: /* like_pattern_opt ::= LIKE NK_STRING */ + case 278: /* like_pattern_opt ::= LIKE NK_STRING */ { yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } break; - case 278: /* table_name_cond ::= table_name */ + case 279: /* table_name_cond ::= table_name */ { yylhsminor.yy452 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 280: /* from_db_opt ::= FROM db_name */ + case 281: /* from_db_opt ::= FROM db_name */ { yymsp[-1].minor.yy452 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371); } break; - case 284: /* tag_item ::= TBNAME */ + case 285: /* tag_item ::= TBNAME */ { yylhsminor.yy452 = setProjectionAlias(pCxt, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL), &yymsp[0].minor.yy0); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 287: /* tag_item ::= column_name column_alias */ + case 288: /* tag_item ::= column_name column_alias */ { yylhsminor.yy452 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-1].minor.yy371), &yymsp[0].minor.yy371); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 288: /* tag_item ::= column_name AS column_alias */ + case 289: /* tag_item ::= column_name AS column_alias */ { yylhsminor.yy452 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-2].minor.yy371), &yymsp[0].minor.yy371); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 289: /* cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ + case 290: /* cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy667, yymsp[-3].minor.yy452, yymsp[-1].minor.yy452, NULL, yymsp[0].minor.yy452); } break; - case 290: /* cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ + case 291: /* cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_NORMAL, yymsp[-6].minor.yy667, yymsp[-5].minor.yy452, yymsp[-3].minor.yy452, yymsp[-1].minor.yy812, NULL); } break; - case 291: /* cmd ::= DROP INDEX exists_opt full_index_name */ + case 292: /* cmd ::= DROP INDEX exists_opt full_index_name */ { pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-1].minor.yy667, yymsp[0].minor.yy452); } break; - case 292: /* full_index_name ::= index_name */ + case 293: /* full_index_name ::= index_name */ { yylhsminor.yy452 = createRealTableNodeForIndexName(pCxt, NULL, &yymsp[0].minor.yy371); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 293: /* full_index_name ::= db_name NK_DOT index_name */ + case 294: /* full_index_name ::= db_name NK_DOT index_name */ { yylhsminor.yy452 = createRealTableNodeForIndexName(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 294: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ + case 295: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ { yymsp[-9].minor.yy452 = createIndexOption(pCxt, yymsp[-7].minor.yy812, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), NULL, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 295: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ + case 296: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ { yymsp[-11].minor.yy452 = createIndexOption(pCxt, yymsp[-9].minor.yy812, releaseRawExprNode(pCxt, yymsp[-5].minor.yy452), releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 298: /* func ::= sma_func_name NK_LP expression_list NK_RP */ + case 299: /* func ::= sma_func_name NK_LP expression_list NK_RP */ { yylhsminor.yy452 = createFunctionNode(pCxt, &yymsp[-3].minor.yy371, yymsp[-1].minor.yy812); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 299: /* sma_func_name ::= function_name */ - case 513: /* alias_opt ::= table_alias */ yytestcase(yyruleno==513); + case 300: /* sma_func_name ::= function_name */ + case 514: /* alias_opt ::= table_alias */ yytestcase(yyruleno==514); { yylhsminor.yy371 = yymsp[0].minor.yy371; } yymsp[0].minor.yy371 = yylhsminor.yy371; break; - case 304: /* sma_stream_opt ::= */ - case 345: /* stream_options ::= */ yytestcase(yyruleno==345); + case 305: /* sma_stream_opt ::= */ + case 346: /* stream_options ::= */ yytestcase(yyruleno==346); { yymsp[1].minor.yy452 = createStreamOptions(pCxt); } break; - case 305: /* sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ + case 306: /* sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ { ((SStreamOptions*)yymsp[-2].minor.yy452)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = yymsp[-2].minor.yy452; } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 306: /* sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ + case 307: /* sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ { ((SStreamOptions*)yymsp[-2].minor.yy452)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = yymsp[-2].minor.yy452; } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 307: /* sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ + case 308: /* sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ { ((SStreamOptions*)yymsp[-2].minor.yy452)->pDeleteMark = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = yymsp[-2].minor.yy452; } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 308: /* with_meta ::= AS */ + case 309: /* with_meta ::= AS */ { yymsp[0].minor.yy416 = 0; } break; - case 309: /* with_meta ::= WITH META AS */ + case 310: /* with_meta ::= WITH META AS */ { yymsp[-2].minor.yy416 = 1; } break; - case 310: /* with_meta ::= ONLY META AS */ + case 311: /* with_meta ::= ONLY META AS */ { yymsp[-2].minor.yy416 = 2; } break; - case 311: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ + case 312: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ { pCxt->pRootNode = createCreateTopicStmtUseQuery(pCxt, yymsp[-3].minor.yy667, &yymsp[-2].minor.yy371, yymsp[0].minor.yy452); } break; - case 312: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ + case 313: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ { pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-4].minor.yy667, &yymsp[-3].minor.yy371, &yymsp[0].minor.yy371, yymsp[-2].minor.yy416); } break; - case 313: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ + case 314: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ { pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-5].minor.yy667, &yymsp[-4].minor.yy371, yymsp[-1].minor.yy452, yymsp[-3].minor.yy416, yymsp[0].minor.yy452); } break; - case 314: /* cmd ::= DROP TOPIC exists_opt topic_name */ + case 315: /* cmd ::= DROP TOPIC exists_opt topic_name */ { pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 315: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + case 316: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ { pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy667, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371); } break; - case 316: /* cmd ::= DESC full_table_name */ - case 317: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==317); + case 317: /* cmd ::= DESC full_table_name */ + case 318: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==318); { pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy452); } break; - case 318: /* cmd ::= RESET QUERY CACHE */ + case 319: /* cmd ::= RESET QUERY CACHE */ { pCxt->pRootNode = createResetQueryCacheStmt(pCxt); } break; - case 319: /* cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - case 320: /* cmd ::= EXPLAIN analyze_opt explain_options insert_query */ yytestcase(yyruleno==320); + case 320: /* cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + case 321: /* cmd ::= EXPLAIN analyze_opt explain_options insert_query */ yytestcase(yyruleno==321); { pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy667, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 323: /* explain_options ::= */ + case 324: /* explain_options ::= */ { yymsp[1].minor.yy452 = createDefaultExplainOptions(pCxt); } break; - case 324: /* explain_options ::= explain_options VERBOSE NK_BOOL */ + case 325: /* explain_options ::= explain_options VERBOSE NK_BOOL */ { yylhsminor.yy452 = setExplainVerbose(pCxt, yymsp[-2].minor.yy452, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 325: /* explain_options ::= explain_options RATIO NK_FLOAT */ + case 326: /* explain_options ::= explain_options RATIO NK_FLOAT */ { yylhsminor.yy452 = setExplainRatio(pCxt, yymsp[-2].minor.yy452, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 326: /* cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ + case 327: /* cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ { pCxt->pRootNode = createCreateFunctionStmt(pCxt, yymsp[-7].minor.yy667, yymsp[-9].minor.yy667, &yymsp[-6].minor.yy371, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy310, yymsp[-1].minor.yy416, &yymsp[0].minor.yy371, yymsp[-10].minor.yy667); } break; - case 327: /* cmd ::= DROP FUNCTION exists_opt function_name */ + case 328: /* cmd ::= DROP FUNCTION exists_opt function_name */ { pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 332: /* language_opt ::= */ + case 333: /* language_opt ::= */ { yymsp[1].minor.yy371 = nil_token; } break; - case 333: /* language_opt ::= LANGUAGE NK_STRING */ + case 334: /* language_opt ::= LANGUAGE NK_STRING */ { yymsp[-1].minor.yy371 = yymsp[0].minor.yy0; } break; - case 336: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ + case 337: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ { pCxt->pRootNode = createCreateStreamStmt(pCxt, yymsp[-9].minor.yy667, &yymsp[-8].minor.yy371, yymsp[-5].minor.yy452, yymsp[-7].minor.yy452, yymsp[-3].minor.yy812, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, yymsp[-4].minor.yy812); } break; - case 337: /* cmd ::= DROP STREAM exists_opt stream_name */ + case 338: /* cmd ::= DROP STREAM exists_opt stream_name */ { pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 338: /* cmd ::= PAUSE STREAM exists_opt stream_name */ + case 339: /* cmd ::= PAUSE STREAM exists_opt stream_name */ { pCxt->pRootNode = createPauseStreamStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 339: /* cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ + case 340: /* cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ { pCxt->pRootNode = createResumeStreamStmt(pCxt, yymsp[-2].minor.yy667, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 346: /* stream_options ::= stream_options TRIGGER AT_ONCE */ - case 347: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ yytestcase(yyruleno==347); + case 347: /* stream_options ::= stream_options TRIGGER AT_ONCE */ + case 348: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ yytestcase(yyruleno==348); { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_TRIGGER_TYPE_SET, &yymsp[0].minor.yy0, NULL); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 348: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + case 349: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-3].minor.yy452, SOPT_TRIGGER_TYPE_SET, &yymsp[-1].minor.yy0, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 349: /* stream_options ::= stream_options WATERMARK duration_literal */ + case 350: /* stream_options ::= stream_options WATERMARK duration_literal */ { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_WATERMARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 350: /* stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ + case 351: /* stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-3].minor.yy452, SOPT_IGNORE_EXPIRED_SET, &yymsp[0].minor.yy0, NULL); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 351: /* stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ + case 352: /* stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_FILL_HISTORY_SET, &yymsp[0].minor.yy0, NULL); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 352: /* stream_options ::= stream_options DELETE_MARK duration_literal */ + case 353: /* stream_options ::= stream_options DELETE_MARK duration_literal */ { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_DELETE_MARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 353: /* stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ + case 354: /* stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-3].minor.yy452, SOPT_IGNORE_UPDATE_SET, &yymsp[0].minor.yy0, NULL); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 355: /* subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - case 547: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ yytestcase(yyruleno==547); - case 568: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==568); + case 356: /* subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + case 548: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ yytestcase(yyruleno==548); + case 569: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==569); { yymsp[-3].minor.yy452 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy452); } break; - case 358: /* cmd ::= KILL CONNECTION NK_INTEGER */ + case 359: /* cmd ::= KILL CONNECTION NK_INTEGER */ { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_CONNECTION_STMT, &yymsp[0].minor.yy0); } break; - case 359: /* cmd ::= KILL QUERY NK_STRING */ + case 360: /* cmd ::= KILL QUERY NK_STRING */ { pCxt->pRootNode = createKillQueryStmt(pCxt, &yymsp[0].minor.yy0); } break; - case 360: /* cmd ::= KILL TRANSACTION NK_INTEGER */ + case 361: /* cmd ::= KILL TRANSACTION NK_INTEGER */ { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_TRANSACTION_STMT, &yymsp[0].minor.yy0); } break; - case 361: /* cmd ::= BALANCE VGROUP */ + case 362: /* cmd ::= BALANCE VGROUP */ { pCxt->pRootNode = createBalanceVgroupStmt(pCxt); } break; - case 362: /* cmd ::= BALANCE VGROUP LEADER */ + case 363: /* cmd ::= BALANCE VGROUP LEADER */ { pCxt->pRootNode = createBalanceVgroupLeaderStmt(pCxt); } break; - case 363: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + case 364: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ { pCxt->pRootNode = createMergeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } break; - case 364: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + case 365: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ { pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy812); } break; - case 365: /* cmd ::= SPLIT VGROUP NK_INTEGER */ + case 366: /* cmd ::= SPLIT VGROUP NK_INTEGER */ { pCxt->pRootNode = createSplitVgroupStmt(pCxt, &yymsp[0].minor.yy0); } break; - case 366: /* dnode_list ::= DNODE NK_INTEGER */ + case 367: /* dnode_list ::= DNODE NK_INTEGER */ { yymsp[-1].minor.yy812 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } break; - case 368: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ + case 369: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ { pCxt->pRootNode = createDeleteStmt(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 371: /* insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ + case 372: /* insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ { yymsp[-6].minor.yy452 = createInsertStmt(pCxt, yymsp[-4].minor.yy452, yymsp[-2].minor.yy812, yymsp[0].minor.yy452); } break; - case 372: /* insert_query ::= INSERT INTO full_table_name query_or_subquery */ + case 373: /* insert_query ::= INSERT INTO full_table_name query_or_subquery */ { yymsp[-3].minor.yy452 = createInsertStmt(pCxt, yymsp[-1].minor.yy452, NULL, yymsp[0].minor.yy452); } break; - case 373: /* literal ::= NK_INTEGER */ + case 374: /* literal ::= NK_INTEGER */ { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 374: /* literal ::= NK_FLOAT */ + case 375: /* literal ::= NK_FLOAT */ { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 375: /* literal ::= NK_STRING */ + case 376: /* literal ::= NK_STRING */ { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 376: /* literal ::= NK_BOOL */ + case 377: /* literal ::= NK_BOOL */ { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 377: /* literal ::= TIMESTAMP NK_STRING */ + case 378: /* literal ::= TIMESTAMP NK_STRING */ { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 378: /* literal ::= duration_literal */ - case 388: /* signed_literal ::= signed */ yytestcase(yyruleno==388); - case 409: /* expr_or_subquery ::= expression */ yytestcase(yyruleno==409); - case 410: /* expression ::= literal */ yytestcase(yyruleno==410); - case 411: /* expression ::= pseudo_column */ yytestcase(yyruleno==411); - case 412: /* expression ::= column_reference */ yytestcase(yyruleno==412); - case 413: /* expression ::= function_expression */ yytestcase(yyruleno==413); - case 414: /* expression ::= case_when_expression */ yytestcase(yyruleno==414); - case 445: /* function_expression ::= literal_func */ yytestcase(yyruleno==445); - case 494: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==494); - case 498: /* boolean_primary ::= predicate */ yytestcase(yyruleno==498); - case 500: /* common_expression ::= expr_or_subquery */ yytestcase(yyruleno==500); - case 501: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==501); - case 504: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==504); - case 506: /* table_reference ::= table_primary */ yytestcase(yyruleno==506); - case 507: /* table_reference ::= joined_table */ yytestcase(yyruleno==507); - case 511: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==511); - case 570: /* query_simple ::= query_specification */ yytestcase(yyruleno==570); - case 571: /* query_simple ::= union_query_expression */ yytestcase(yyruleno==571); - case 574: /* query_simple_or_subquery ::= query_simple */ yytestcase(yyruleno==574); - case 576: /* query_or_subquery ::= query_expression */ yytestcase(yyruleno==576); + case 379: /* literal ::= duration_literal */ + case 389: /* signed_literal ::= signed */ yytestcase(yyruleno==389); + case 410: /* expr_or_subquery ::= expression */ yytestcase(yyruleno==410); + case 411: /* expression ::= literal */ yytestcase(yyruleno==411); + case 412: /* expression ::= pseudo_column */ yytestcase(yyruleno==412); + case 413: /* expression ::= column_reference */ yytestcase(yyruleno==413); + case 414: /* expression ::= function_expression */ yytestcase(yyruleno==414); + case 415: /* expression ::= case_when_expression */ yytestcase(yyruleno==415); + case 446: /* function_expression ::= literal_func */ yytestcase(yyruleno==446); + case 495: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==495); + case 499: /* boolean_primary ::= predicate */ yytestcase(yyruleno==499); + case 501: /* common_expression ::= expr_or_subquery */ yytestcase(yyruleno==501); + case 502: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==502); + case 505: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==505); + case 507: /* table_reference ::= table_primary */ yytestcase(yyruleno==507); + case 508: /* table_reference ::= joined_table */ yytestcase(yyruleno==508); + case 512: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==512); + case 571: /* query_simple ::= query_specification */ yytestcase(yyruleno==571); + case 572: /* query_simple ::= union_query_expression */ yytestcase(yyruleno==572); + case 575: /* query_simple_or_subquery ::= query_simple */ yytestcase(yyruleno==575); + case 577: /* query_or_subquery ::= query_expression */ yytestcase(yyruleno==577); { yylhsminor.yy452 = yymsp[0].minor.yy452; } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 379: /* literal ::= NULL */ + case 380: /* literal ::= NULL */ { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 380: /* literal ::= NK_QUESTION */ + case 381: /* literal ::= NK_QUESTION */ { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 381: /* duration_literal ::= NK_VARIABLE */ + case 382: /* duration_literal ::= NK_VARIABLE */ { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 382: /* signed ::= NK_INTEGER */ + case 383: /* signed ::= NK_INTEGER */ { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 383: /* signed ::= NK_PLUS NK_INTEGER */ + case 384: /* signed ::= NK_PLUS NK_INTEGER */ { yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } break; - case 384: /* signed ::= NK_MINUS NK_INTEGER */ + case 385: /* signed ::= NK_MINUS NK_INTEGER */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; @@ -5696,14 +5701,14 @@ static YYACTIONTYPE yy_reduce( } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 385: /* signed ::= NK_FLOAT */ + case 386: /* signed ::= NK_FLOAT */ { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 386: /* signed ::= NK_PLUS NK_FLOAT */ + case 387: /* signed ::= NK_PLUS NK_FLOAT */ { yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } break; - case 387: /* signed ::= NK_MINUS NK_FLOAT */ + case 388: /* signed ::= NK_MINUS NK_FLOAT */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; @@ -5711,57 +5716,57 @@ static YYACTIONTYPE yy_reduce( } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 389: /* signed_literal ::= NK_STRING */ + case 390: /* signed_literal ::= NK_STRING */ { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 390: /* signed_literal ::= NK_BOOL */ + case 391: /* signed_literal ::= NK_BOOL */ { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 391: /* signed_literal ::= TIMESTAMP NK_STRING */ + case 392: /* signed_literal ::= TIMESTAMP NK_STRING */ { yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } break; - case 392: /* signed_literal ::= duration_literal */ - case 394: /* signed_literal ::= literal_func */ yytestcase(yyruleno==394); - case 465: /* star_func_para ::= expr_or_subquery */ yytestcase(yyruleno==465); - case 527: /* select_item ::= common_expression */ yytestcase(yyruleno==527); - case 537: /* partition_item ::= expr_or_subquery */ yytestcase(yyruleno==537); - case 575: /* query_simple_or_subquery ::= subquery */ yytestcase(yyruleno==575); - case 577: /* query_or_subquery ::= subquery */ yytestcase(yyruleno==577); - case 590: /* search_condition ::= common_expression */ yytestcase(yyruleno==590); + case 393: /* signed_literal ::= duration_literal */ + case 395: /* signed_literal ::= literal_func */ yytestcase(yyruleno==395); + case 466: /* star_func_para ::= expr_or_subquery */ yytestcase(yyruleno==466); + case 528: /* select_item ::= common_expression */ yytestcase(yyruleno==528); + case 538: /* partition_item ::= expr_or_subquery */ yytestcase(yyruleno==538); + case 576: /* query_simple_or_subquery ::= subquery */ yytestcase(yyruleno==576); + case 578: /* query_or_subquery ::= subquery */ yytestcase(yyruleno==578); + case 591: /* search_condition ::= common_expression */ yytestcase(yyruleno==591); { yylhsminor.yy452 = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 393: /* signed_literal ::= NULL */ + case 394: /* signed_literal ::= NULL */ { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 395: /* signed_literal ::= NK_QUESTION */ + case 396: /* signed_literal ::= NK_QUESTION */ { yylhsminor.yy452 = createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 415: /* expression ::= NK_LP expression NK_RP */ - case 499: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==499); - case 589: /* subquery ::= NK_LP subquery NK_RP */ yytestcase(yyruleno==589); + case 416: /* expression ::= NK_LP expression NK_RP */ + case 500: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==500); + case 590: /* subquery ::= NK_LP subquery NK_RP */ yytestcase(yyruleno==590); { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 416: /* expression ::= NK_PLUS expr_or_subquery */ + case 417: /* expression ::= NK_PLUS expr_or_subquery */ { SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 417: /* expression ::= NK_MINUS expr_or_subquery */ + case 418: /* expression ::= NK_MINUS expr_or_subquery */ { SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy452), NULL)); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 418: /* expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + case 419: /* expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5769,7 +5774,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 419: /* expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + case 420: /* expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5777,7 +5782,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 420: /* expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + case 421: /* expression ::= expr_or_subquery NK_STAR expr_or_subquery */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5785,7 +5790,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 421: /* expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + case 422: /* expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5793,7 +5798,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 422: /* expression ::= expr_or_subquery NK_REM expr_or_subquery */ + case 423: /* expression ::= expr_or_subquery NK_REM expr_or_subquery */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5801,14 +5806,14 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 423: /* expression ::= column_reference NK_ARROW NK_STRING */ + case 424: /* expression ::= column_reference NK_ARROW NK_STRING */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 424: /* expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + case 425: /* expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5816,7 +5821,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 425: /* expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + case 426: /* expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5824,71 +5829,71 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 428: /* column_reference ::= column_name */ + case 429: /* column_reference ::= column_name */ { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy371, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy371)); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 429: /* column_reference ::= table_name NK_DOT column_name */ + case 430: /* column_reference ::= table_name NK_DOT column_name */ { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371, createColumnNode(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371)); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 430: /* pseudo_column ::= ROWTS */ - case 431: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==431); - case 433: /* pseudo_column ::= QSTART */ yytestcase(yyruleno==433); - case 434: /* pseudo_column ::= QEND */ yytestcase(yyruleno==434); - case 435: /* pseudo_column ::= QDURATION */ yytestcase(yyruleno==435); - case 436: /* pseudo_column ::= WSTART */ yytestcase(yyruleno==436); - case 437: /* pseudo_column ::= WEND */ yytestcase(yyruleno==437); - case 438: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==438); - case 439: /* pseudo_column ::= IROWTS */ yytestcase(yyruleno==439); - case 440: /* pseudo_column ::= ISFILLED */ yytestcase(yyruleno==440); - case 441: /* pseudo_column ::= QTAGS */ yytestcase(yyruleno==441); - case 447: /* literal_func ::= NOW */ yytestcase(yyruleno==447); + case 431: /* pseudo_column ::= ROWTS */ + case 432: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==432); + case 434: /* pseudo_column ::= QSTART */ yytestcase(yyruleno==434); + case 435: /* pseudo_column ::= QEND */ yytestcase(yyruleno==435); + case 436: /* pseudo_column ::= QDURATION */ yytestcase(yyruleno==436); + case 437: /* pseudo_column ::= WSTART */ yytestcase(yyruleno==437); + case 438: /* pseudo_column ::= WEND */ yytestcase(yyruleno==438); + case 439: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==439); + case 440: /* pseudo_column ::= IROWTS */ yytestcase(yyruleno==440); + case 441: /* pseudo_column ::= ISFILLED */ yytestcase(yyruleno==441); + case 442: /* pseudo_column ::= QTAGS */ yytestcase(yyruleno==442); + case 448: /* literal_func ::= NOW */ yytestcase(yyruleno==448); { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 432: /* pseudo_column ::= table_name NK_DOT TBNAME */ + case 433: /* pseudo_column ::= table_name NK_DOT TBNAME */ { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy371)))); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 442: /* function_expression ::= function_name NK_LP expression_list NK_RP */ - case 443: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==443); + case 443: /* function_expression ::= function_name NK_LP expression_list NK_RP */ + case 444: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==444); { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy371, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy371, yymsp[-1].minor.yy812)); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 444: /* function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ + case 445: /* function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-1].minor.yy310)); } yymsp[-5].minor.yy452 = yylhsminor.yy452; break; - case 446: /* literal_func ::= noarg_func NK_LP NK_RP */ + case 447: /* literal_func ::= noarg_func NK_LP NK_RP */ { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy371, NULL)); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 461: /* star_func_para_list ::= NK_STAR */ + case 462: /* star_func_para_list ::= NK_STAR */ { yylhsminor.yy812 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 466: /* star_func_para ::= table_name NK_DOT NK_STAR */ - case 530: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==530); + case 467: /* star_func_para ::= table_name NK_DOT NK_STAR */ + case 531: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==531); { yylhsminor.yy452 = createColumnNode(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 467: /* case_when_expression ::= CASE when_then_list case_when_else_opt END */ + case 468: /* case_when_expression ::= CASE when_then_list case_when_else_opt END */ { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, NULL, yymsp[-2].minor.yy812, yymsp[-1].minor.yy452)); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 468: /* case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ + case 469: /* case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-2].minor.yy812, yymsp[-1].minor.yy452)); } yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 471: /* when_then_expr ::= WHEN common_expression THEN common_expression */ + case 472: /* when_then_expr ::= WHEN common_expression THEN common_expression */ { yymsp[-3].minor.yy452 = createWhenThenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } break; - case 473: /* case_when_else_opt ::= ELSE common_expression */ + case 474: /* case_when_else_opt ::= ELSE common_expression */ { yymsp[-1].minor.yy452 = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); } break; - case 474: /* predicate ::= expr_or_subquery compare_op expr_or_subquery */ - case 479: /* predicate ::= expr_or_subquery in_op in_predicate_value */ yytestcase(yyruleno==479); + case 475: /* predicate ::= expr_or_subquery compare_op expr_or_subquery */ + case 480: /* predicate ::= expr_or_subquery in_op in_predicate_value */ yytestcase(yyruleno==480); { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5896,7 +5901,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 475: /* predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + case 476: /* predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5904,7 +5909,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 476: /* predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + case 477: /* predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5912,71 +5917,71 @@ static YYACTIONTYPE yy_reduce( } yymsp[-5].minor.yy452 = yylhsminor.yy452; break; - case 477: /* predicate ::= expr_or_subquery IS NULL */ + case 478: /* predicate ::= expr_or_subquery IS NULL */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), NULL)); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 478: /* predicate ::= expr_or_subquery IS NOT NULL */ + case 479: /* predicate ::= expr_or_subquery IS NOT NULL */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), NULL)); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 480: /* compare_op ::= NK_LT */ + case 481: /* compare_op ::= NK_LT */ { yymsp[0].minor.yy354 = OP_TYPE_LOWER_THAN; } break; - case 481: /* compare_op ::= NK_GT */ + case 482: /* compare_op ::= NK_GT */ { yymsp[0].minor.yy354 = OP_TYPE_GREATER_THAN; } break; - case 482: /* compare_op ::= NK_LE */ + case 483: /* compare_op ::= NK_LE */ { yymsp[0].minor.yy354 = OP_TYPE_LOWER_EQUAL; } break; - case 483: /* compare_op ::= NK_GE */ + case 484: /* compare_op ::= NK_GE */ { yymsp[0].minor.yy354 = OP_TYPE_GREATER_EQUAL; } break; - case 484: /* compare_op ::= NK_NE */ + case 485: /* compare_op ::= NK_NE */ { yymsp[0].minor.yy354 = OP_TYPE_NOT_EQUAL; } break; - case 485: /* compare_op ::= NK_EQ */ + case 486: /* compare_op ::= NK_EQ */ { yymsp[0].minor.yy354 = OP_TYPE_EQUAL; } break; - case 486: /* compare_op ::= LIKE */ + case 487: /* compare_op ::= LIKE */ { yymsp[0].minor.yy354 = OP_TYPE_LIKE; } break; - case 487: /* compare_op ::= NOT LIKE */ + case 488: /* compare_op ::= NOT LIKE */ { yymsp[-1].minor.yy354 = OP_TYPE_NOT_LIKE; } break; - case 488: /* compare_op ::= MATCH */ + case 489: /* compare_op ::= MATCH */ { yymsp[0].minor.yy354 = OP_TYPE_MATCH; } break; - case 489: /* compare_op ::= NMATCH */ + case 490: /* compare_op ::= NMATCH */ { yymsp[0].minor.yy354 = OP_TYPE_NMATCH; } break; - case 490: /* compare_op ::= CONTAINS */ + case 491: /* compare_op ::= CONTAINS */ { yymsp[0].minor.yy354 = OP_TYPE_JSON_CONTAINS; } break; - case 491: /* in_op ::= IN */ + case 492: /* in_op ::= IN */ { yymsp[0].minor.yy354 = OP_TYPE_IN; } break; - case 492: /* in_op ::= NOT IN */ + case 493: /* in_op ::= NOT IN */ { yymsp[-1].minor.yy354 = OP_TYPE_NOT_IN; } break; - case 493: /* in_predicate_value ::= NK_LP literal_list NK_RP */ + case 494: /* in_predicate_value ::= NK_LP literal_list NK_RP */ { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy812)); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 495: /* boolean_value_expression ::= NOT boolean_primary */ + case 496: /* boolean_value_expression ::= NOT boolean_primary */ { SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy452), NULL)); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 496: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + case 497: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5984,7 +5989,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 497: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + case 498: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); @@ -5992,43 +5997,43 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 505: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ + case 506: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ { yylhsminor.yy452 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, NULL); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 508: /* table_primary ::= table_name alias_opt */ + case 509: /* table_primary ::= table_name alias_opt */ { yylhsminor.yy452 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 509: /* table_primary ::= db_name NK_DOT table_name alias_opt */ + case 510: /* table_primary ::= db_name NK_DOT table_name alias_opt */ { yylhsminor.yy452 = createRealTableNode(pCxt, &yymsp[-3].minor.yy371, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 510: /* table_primary ::= subquery alias_opt */ + case 511: /* table_primary ::= subquery alias_opt */ { yylhsminor.yy452 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452), &yymsp[0].minor.yy371); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 512: /* alias_opt ::= */ + case 513: /* alias_opt ::= */ { yymsp[1].minor.yy371 = nil_token; } break; - case 514: /* alias_opt ::= AS table_alias */ + case 515: /* alias_opt ::= AS table_alias */ { yymsp[-1].minor.yy371 = yymsp[0].minor.yy371; } break; - case 515: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - case 516: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==516); + case 516: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + case 517: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==517); { yymsp[-2].minor.yy452 = yymsp[-1].minor.yy452; } break; - case 517: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + case 518: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ { yylhsminor.yy452 = createJoinTableNode(pCxt, yymsp[-4].minor.yy140, yymsp[-5].minor.yy452, yymsp[-2].minor.yy452, yymsp[0].minor.yy452); } yymsp[-5].minor.yy452 = yylhsminor.yy452; break; - case 518: /* join_type ::= */ + case 519: /* join_type ::= */ { yymsp[1].minor.yy140 = JOIN_TYPE_INNER; } break; - case 519: /* join_type ::= INNER */ + case 520: /* join_type ::= INNER */ { yymsp[0].minor.yy140 = JOIN_TYPE_INNER; } break; - case 520: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + case 521: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ { yymsp[-11].minor.yy452 = createSelectStmt(pCxt, yymsp[-10].minor.yy667, yymsp[-9].minor.yy812, yymsp[-8].minor.yy452); yymsp[-11].minor.yy452 = addWhereClause(pCxt, yymsp[-11].minor.yy452, yymsp[-7].minor.yy452); @@ -6041,85 +6046,85 @@ static YYACTIONTYPE yy_reduce( yymsp[-11].minor.yy452 = addFillClause(pCxt, yymsp[-11].minor.yy452, yymsp[-3].minor.yy452); } break; - case 523: /* set_quantifier_opt ::= ALL */ + case 524: /* set_quantifier_opt ::= ALL */ { yymsp[0].minor.yy667 = false; } break; - case 526: /* select_item ::= NK_STAR */ + case 527: /* select_item ::= NK_STAR */ { yylhsminor.yy452 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0); } yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 528: /* select_item ::= common_expression column_alias */ - case 538: /* partition_item ::= expr_or_subquery column_alias */ yytestcase(yyruleno==538); + case 529: /* select_item ::= common_expression column_alias */ + case 539: /* partition_item ::= expr_or_subquery column_alias */ yytestcase(yyruleno==539); { yylhsminor.yy452 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452), &yymsp[0].minor.yy371); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 529: /* select_item ::= common_expression AS column_alias */ - case 539: /* partition_item ::= expr_or_subquery AS column_alias */ yytestcase(yyruleno==539); + case 530: /* select_item ::= common_expression AS column_alias */ + case 540: /* partition_item ::= expr_or_subquery AS column_alias */ yytestcase(yyruleno==540); { yylhsminor.yy452 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), &yymsp[0].minor.yy371); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 534: /* partition_by_clause_opt ::= PARTITION BY partition_list */ - case 559: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==559); - case 579: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==579); + case 535: /* partition_by_clause_opt ::= PARTITION BY partition_list */ + case 560: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==560); + case 580: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==580); { yymsp[-2].minor.yy812 = yymsp[0].minor.yy812; } break; - case 541: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + case 542: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ { yymsp[-5].minor.yy452 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } break; - case 542: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ + case 543: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ { yymsp[-3].minor.yy452 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } break; - case 543: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + case 544: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ { yymsp[-5].minor.yy452 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), NULL, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 544: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + case 545: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ { yymsp[-7].minor.yy452 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy452), releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 545: /* twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ + case 546: /* twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ { yymsp[-6].minor.yy452 = createEventWindowNode(pCxt, yymsp[-3].minor.yy452, yymsp[0].minor.yy452); } break; - case 549: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ + case 550: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ { yymsp[-3].minor.yy452 = createFillNode(pCxt, yymsp[-1].minor.yy844, NULL); } break; - case 550: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ + case 551: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ { yymsp[-5].minor.yy452 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy812)); } break; - case 551: /* fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ + case 552: /* fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ { yymsp[-5].minor.yy452 = createFillNode(pCxt, FILL_MODE_VALUE_F, createNodeListNode(pCxt, yymsp[-1].minor.yy812)); } break; - case 552: /* fill_mode ::= NONE */ + case 553: /* fill_mode ::= NONE */ { yymsp[0].minor.yy844 = FILL_MODE_NONE; } break; - case 553: /* fill_mode ::= PREV */ + case 554: /* fill_mode ::= PREV */ { yymsp[0].minor.yy844 = FILL_MODE_PREV; } break; - case 554: /* fill_mode ::= NULL */ + case 555: /* fill_mode ::= NULL */ { yymsp[0].minor.yy844 = FILL_MODE_NULL; } break; - case 555: /* fill_mode ::= NULL_F */ + case 556: /* fill_mode ::= NULL_F */ { yymsp[0].minor.yy844 = FILL_MODE_NULL_F; } break; - case 556: /* fill_mode ::= LINEAR */ + case 557: /* fill_mode ::= LINEAR */ { yymsp[0].minor.yy844 = FILL_MODE_LINEAR; } break; - case 557: /* fill_mode ::= NEXT */ + case 558: /* fill_mode ::= NEXT */ { yymsp[0].minor.yy844 = FILL_MODE_NEXT; } break; - case 560: /* group_by_list ::= expr_or_subquery */ + case 561: /* group_by_list ::= expr_or_subquery */ { yylhsminor.yy812 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 561: /* group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ + case 562: /* group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } yymsp[-2].minor.yy812 = yylhsminor.yy812; break; - case 565: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ + case 566: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ { yymsp[-5].minor.yy452 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } break; - case 566: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ + case 567: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ { yymsp[-3].minor.yy452 = createInterpTimePoint(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } break; - case 569: /* query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + case 570: /* query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ { yylhsminor.yy452 = addOrderByClause(pCxt, yymsp[-3].minor.yy452, yymsp[-2].minor.yy812); yylhsminor.yy452 = addSlimitClause(pCxt, yylhsminor.yy452, yymsp[-1].minor.yy452); @@ -6127,50 +6132,50 @@ static YYACTIONTYPE yy_reduce( } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 572: /* union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ + case 573: /* union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ { yylhsminor.yy452 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy452, yymsp[0].minor.yy452); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 573: /* union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ + case 574: /* union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ { yylhsminor.yy452 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy452, yymsp[0].minor.yy452); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 581: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ - case 585: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==585); + case 582: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ + case 586: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==586); { yymsp[-1].minor.yy452 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } break; - case 582: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - case 586: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==586); + case 583: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + case 587: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==587); { yymsp[-3].minor.yy452 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 583: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - case 587: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==587); + case 584: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + case 588: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==588); { yymsp[-3].minor.yy452 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } break; - case 588: /* subquery ::= NK_LP query_expression NK_RP */ + case 589: /* subquery ::= NK_LP query_expression NK_RP */ { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy452); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 593: /* sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ + case 594: /* sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ { yylhsminor.yy452 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), yymsp[-1].minor.yy690, yymsp[0].minor.yy399); } yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 594: /* ordering_specification_opt ::= */ + case 595: /* ordering_specification_opt ::= */ { yymsp[1].minor.yy690 = ORDER_ASC; } break; - case 595: /* ordering_specification_opt ::= ASC */ + case 596: /* ordering_specification_opt ::= ASC */ { yymsp[0].minor.yy690 = ORDER_ASC; } break; - case 596: /* ordering_specification_opt ::= DESC */ + case 597: /* ordering_specification_opt ::= DESC */ { yymsp[0].minor.yy690 = ORDER_DESC; } break; - case 597: /* null_ordering_opt ::= */ + case 598: /* null_ordering_opt ::= */ { yymsp[1].minor.yy399 = NULL_ORDER_DEFAULT; } break; - case 598: /* null_ordering_opt ::= NULLS FIRST */ + case 599: /* null_ordering_opt ::= NULLS FIRST */ { yymsp[-1].minor.yy399 = NULL_ORDER_FIRST; } break; - case 599: /* null_ordering_opt ::= NULLS LAST */ + case 600: /* null_ordering_opt ::= NULLS LAST */ { yymsp[-1].minor.yy399 = NULL_ORDER_LAST; } break; default: diff --git a/tests/system-test/0-others/show.py b/tests/system-test/0-others/show.py index 9d26b3a2ae..7366a4f60a 100644 --- a/tests/system-test/0-others/show.py +++ b/tests/system-test/0-others/show.py @@ -210,6 +210,18 @@ class TDTestCase: licences_info = tdSql.queryResult tdSql.checkEqual(grants_info,licences_info) + def show_create_table_with_col_comment(self): + tdSql.execute("create database comment_test_db") + tdSql.execute("use comment_test_db") + tdSql.execute("create table normal_table(ts timestamp, c2 int comment 'c2 comment')") + tdSql.execute("create stable super_table(ts timestamp comment 'ts', c2 int comment 'c2 comment') tags(tg int comment 'tg comment')") + tdSql.query('show create table normal_table') + create_sql = "create table `normal_table` (`ts` timestamp, `c2` int)" + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + tdSql.query('show create table super_table') + create_sql = "create stable `super_table` (`ts` timestamp, `c2` int) tags (`tg` int)" + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + def run(self): self.check_gitinfo() self.show_base() @@ -218,6 +230,7 @@ class TDTestCase: self.show_create_sql() self.show_create_sysdb_sql() self.show_create_systb_sql() + self.show_create_table_with_col_comment() def stop(self): tdSql.close() From ccce04ceb98ea22c9e6d67ced1237c10b2b0bda2 Mon Sep 17 00:00:00 2001 From: kailixu Date: Tue, 15 Aug 2023 17:01:45 +0800 Subject: [PATCH 76/92] enh: disable udf on windows --- source/dnode/mgmt/mgmt_dnode/src/dmInt.c | 2 +- source/dnode/mgmt/mgmt_qnode/src/qmInt.c | 2 +- source/dnode/mgmt/mgmt_snode/src/smInt.c | 2 +- source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 2 +- source/dnode/mgmt/node_mgmt/src/dmEnv.c | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c index f59d04e618..ae62c74e03 100644 --- a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c @@ -59,7 +59,7 @@ static int32_t dmOpenMgmt(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { return -1; } -#ifdef WINDOWS +#ifndef WINDOWS if (udfStartUdfd(pMgmt->pData->dnodeId) != 0) { dError("failed to start udfd"); } diff --git a/source/dnode/mgmt/mgmt_qnode/src/qmInt.c b/source/dnode/mgmt/mgmt_qnode/src/qmInt.c index 82bc2f36f0..657f15920a 100644 --- a/source/dnode/mgmt/mgmt_qnode/src/qmInt.c +++ b/source/dnode/mgmt/mgmt_qnode/src/qmInt.c @@ -57,7 +57,7 @@ static int32_t qmOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("qnode-impl", "initialized"); -#ifdef WINDOWS +#ifndef WINDOWS if (udfcOpen() != 0) { dError("qnode can not open udfc"); qmClose(pMgmt); diff --git a/source/dnode/mgmt/mgmt_snode/src/smInt.c b/source/dnode/mgmt/mgmt_snode/src/smInt.c index 7607fcac61..58d4b6139b 100644 --- a/source/dnode/mgmt/mgmt_snode/src/smInt.c +++ b/source/dnode/mgmt/mgmt_snode/src/smInt.c @@ -65,7 +65,7 @@ int32_t smOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("snode-worker", "initialized"); -#ifdef WINDOWS +#ifndef WINDOWS if (udfcOpen() != 0) { dError("failed to open udfc in snode"); smClose(pMgmt); diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index 872577cf28..2dd0130d56 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -571,7 +571,7 @@ static int32_t vmInit(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("vnode-vnodes", "initialized"); -#ifdef WINDOWS +#ifndef WINDOWS if (udfcOpen() != 0) { dError("failed to open udfc in vnode"); goto _OVER; diff --git a/source/dnode/mgmt/node_mgmt/src/dmEnv.c b/source/dnode/mgmt/node_mgmt/src/dmEnv.c index a8f871dc96..f7e429f938 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmEnv.c +++ b/source/dnode/mgmt/node_mgmt/src/dmEnv.c @@ -198,10 +198,10 @@ void dmCleanup() { monCleanup(); syncCleanUp(); walCleanUp(); -#ifdef WINDOWS +#ifndef WINDOWS udfcClose(); udfStopUdfd(); -#endif +#endif taosStopCacheRefreshWorker(); dmDiskClose(); dInfo("dnode env is cleaned up"); From adaaa922beaac65e7f4a6c83fda69a4213f5db36 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 15 Aug 2023 17:47:19 +0800 Subject: [PATCH 77/92] fix bugs --- source/libs/function/src/builtinsimpl.c | 35 ++++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 631f943915..9d4868c9cd 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -5819,6 +5819,7 @@ int32_t irateFunction(SqlFunctionCtx* pCtx) { if (INT64_MIN == pRateInfo->lastKey) { pRateInfo->lastValue = v; pRateInfo->lastKey = tsList[i]; + pRateInfo->hasResult = 1; continue; } @@ -5870,36 +5871,50 @@ static double doCalcRate(const SRateInfo* pRateInfo, double tickPerSec) { return (duration > 0) ? ((double)diff) / (duration / tickPerSec) : 0.0; } -static void irateTransferInfoImpl(TSKEY inputKey, SRateInfo* pInput, SRateInfo* pOutput) { +static void irateTransferInfoImpl(TSKEY inputKey, SRateInfo* pInput, SRateInfo* pOutput, bool isFirstKey) { if (inputKey > pOutput->lastKey) { - pOutput->firstKey = pOutput->lastKey; - pOutput->lastKey = pInput->firstKey; + pOutput->firstKey = pOutput->lastKey; + pOutput->firstValue = pOutput->lastValue; - pOutput->firstValue = pOutput->lastValue; - pOutput->lastValue = pInput->firstValue; + pOutput->lastKey = isFirstKey ? pInput->firstKey : pInput->lastKey; + pOutput->lastValue = isFirstKey ? pInput->firstValue : pInput->lastValue; } else if ((inputKey < pOutput->lastKey) && (inputKey > pOutput->firstKey)) { - pOutput->firstKey = pOutput->lastKey; - pOutput->firstValue = pOutput->lastValue; + pOutput->firstKey = isFirstKey ? pInput->firstKey : pInput->lastKey; + pOutput->firstValue = isFirstKey ? pInput->firstValue : pInput->lastValue; } else { // inputKey < pOutput->firstKey } } +static void irateCopyInfo(SRateInfo* pInput, SRateInfo* pOutput) { + pOutput->firstKey = pInput->firstKey; + pOutput->lastKey = pInput->lastKey; + + pOutput->firstValue = pInput->firstValue; + pOutput->lastValue = pInput->lastValue; +} + static int32_t irateTransferInfo(SRateInfo* pInput, SRateInfo* pOutput) { - pOutput->hasResult = pInput->hasResult; if (pInput->firstKey == pOutput->firstKey || pInput->firstKey == pOutput->lastKey || pInput->lastKey == pOutput->firstKey || pInput->lastKey == pOutput->lastKey) { return TSDB_CODE_FUNC_DUP_TIMESTAMP; } + if (pOutput->hasResult == 0) { + irateCopyInfo(pInput, pOutput); + pOutput->hasResult = pInput->hasResult; + return TSDB_CODE_SUCCESS; + } + if (pInput->firstKey != INT64_MIN) { - irateTransferInfoImpl(pInput->firstKey, pInput, pOutput); + irateTransferInfoImpl(pInput->firstKey, pInput, pOutput, true); } if (pInput->lastKey != INT64_MIN) { - irateTransferInfoImpl(pInput->lastKey, pInput, pOutput); + irateTransferInfoImpl(pInput->lastKey, pInput, pOutput, false); } + pOutput->hasResult = pInput->hasResult; return TSDB_CODE_SUCCESS; } From 3c6ddad61114369819dc57bb2b699f1534ae63e5 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 15 Aug 2023 17:58:12 +0800 Subject: [PATCH 78/92] fix bugs --- source/libs/function/src/builtinsimpl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 9d4868c9cd..bcbb3af950 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -5895,8 +5895,8 @@ static void irateCopyInfo(SRateInfo* pInput, SRateInfo* pOutput) { } static int32_t irateTransferInfo(SRateInfo* pInput, SRateInfo* pOutput) { - if (pInput->firstKey == pOutput->firstKey || pInput->firstKey == pOutput->lastKey || - pInput->lastKey == pOutput->firstKey || pInput->lastKey == pOutput->lastKey) { + if ((pInput->firstKey != INT64_MIN && (pInput->firstKey == pOutput->firstKey || pInput->firstKey == pOutput->lastKey)) || + (pInput->lastKey != INT64_MIN && (pInput->lastKey == pOutput->firstKey || pInput->lastKey == pOutput->lastKey))) { return TSDB_CODE_FUNC_DUP_TIMESTAMP; } From 3b69736b29baff03808b1f0281728520e8be0df6 Mon Sep 17 00:00:00 2001 From: kailixu Date: Tue, 15 Aug 2023 19:59:13 +0800 Subject: [PATCH 79/92] fix: set precision of interval with value from table scan node --- source/libs/executor/src/executil.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index aa0c7945b0..0f62b4f0a0 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1677,6 +1677,7 @@ SInterval extractIntervalInfo(const STableScanPhysiNode* pTableScanNode) { .intervalUnit = pTableScanNode->intervalUnit, .slidingUnit = pTableScanNode->slidingUnit, .offset = pTableScanNode->offset, + .precision = pTableScanNode->scan.node.pOutputDataBlockDesc->precision, }; return interval; From f2d8078d6619d61b9c14af5f4a24e62b08535544 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Wed, 16 Aug 2023 08:10:39 +0800 Subject: [PATCH 80/92] Update 25-grant.md --- docs/zh/12-taos-sql/25-grant.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/12-taos-sql/25-grant.md b/docs/zh/12-taos-sql/25-grant.md index a9c3910500..d53f951e67 100644 --- a/docs/zh/12-taos-sql/25-grant.md +++ b/docs/zh/12-taos-sql/25-grant.md @@ -4,7 +4,7 @@ title: 权限管理 description: 企业版中才具有的权限管理功能 --- -本节讲述如何在 TDengine 中进行权限管理的相关操作。 +本节讲述如何在 TDengine 中进行权限管理的相关操作。权限管理是 TDengine 企业版的特有功能,本节只列举了一些基本的权限管理功能作为示例,更丰富的权限管理请联系 TDengine 销售或市场团队。 ## 创建用户 From 6d80f21ba3ce5a4eb6eac61840ddbb9c7fe85987 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Wed, 16 Aug 2023 08:14:07 +0800 Subject: [PATCH 81/92] Update 25-grant.md --- docs/en/12-taos-sql/25-grant.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/12-taos-sql/25-grant.md b/docs/en/12-taos-sql/25-grant.md index c214e11876..139b2729ae 100644 --- a/docs/en/12-taos-sql/25-grant.md +++ b/docs/en/12-taos-sql/25-grant.md @@ -4,7 +4,7 @@ sidebar_label: Access Control description: This document describes how to manage users and permissions in TDengine. --- -This document describes how to manage permissions in TDengine. +This document describes how to manage permissions in TDengine. User and Access control is a distingguished feature of TDengine enterprise edition. In this section, only the most fundamental functionalities of user and access control are demonstrated. To get the full knowledge of user and access control, please contact the TDengine team. ## Create a User From 6b961fc04866e187bda66163d4073c68ee9e3037 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Wed, 16 Aug 2023 08:15:25 +0800 Subject: [PATCH 82/92] Update 25-grant.md --- docs/en/12-taos-sql/25-grant.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/12-taos-sql/25-grant.md b/docs/en/12-taos-sql/25-grant.md index 139b2729ae..5ebed12b59 100644 --- a/docs/en/12-taos-sql/25-grant.md +++ b/docs/en/12-taos-sql/25-grant.md @@ -4,7 +4,7 @@ sidebar_label: Access Control description: This document describes how to manage users and permissions in TDengine. --- -This document describes how to manage permissions in TDengine. User and Access control is a distingguished feature of TDengine enterprise edition. In this section, only the most fundamental functionalities of user and access control are demonstrated. To get the full knowledge of user and access control, please contact the TDengine team. +User and Access control is a distingguished feature of TDengine enterprise edition. In this section, only the most fundamental functionalities of user and access control are demonstrated. To get the full knowledge of user and access control, please contact the TDengine team. ## Create a User From b54d6e298250fb62459903ca8c741036e180986b Mon Sep 17 00:00:00 2001 From: kailixu Date: Wed, 16 Aug 2023 09:55:30 +0800 Subject: [PATCH 83/92] chore: set default value of tsStartUdfd false on windows --- source/common/src/tglobal.c | 6 +++++- source/dnode/mgmt/mgmt_dnode/src/dmInt.c | 2 -- source/dnode/mgmt/mgmt_qnode/src/qmInt.c | 2 -- source/dnode/mgmt/mgmt_snode/src/smInt.c | 2 -- source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 2 -- source/dnode/mgmt/node_mgmt/src/dmEnv.c | 2 -- 6 files changed, 5 insertions(+), 11 deletions(-) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index a772efc33c..da2917f144 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -216,7 +216,11 @@ uint32_t tsCurRange = 100; // range char tsCompressor[32] = "ZSTD_COMPRESSOR"; // ZSTD_COMPRESSOR or GZIP_COMPRESSOR // udf -bool tsStartUdfd = true; +#ifdef WINDOWS +bool tsStartUdfd = false; +#else +bool tsStartUdfd = true; +#endif // wal int64_t tsWalFsyncDataSizeLimit = (100 * 1024 * 1024L); diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c index ae62c74e03..09783a5ea9 100644 --- a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c @@ -59,11 +59,9 @@ static int32_t dmOpenMgmt(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { return -1; } -#ifndef WINDOWS if (udfStartUdfd(pMgmt->pData->dnodeId) != 0) { dError("failed to start udfd"); } -#endif pOutput->pMgmt = pMgmt; return 0; diff --git a/source/dnode/mgmt/mgmt_qnode/src/qmInt.c b/source/dnode/mgmt/mgmt_qnode/src/qmInt.c index 657f15920a..3b425a0b49 100644 --- a/source/dnode/mgmt/mgmt_qnode/src/qmInt.c +++ b/source/dnode/mgmt/mgmt_qnode/src/qmInt.c @@ -57,13 +57,11 @@ static int32_t qmOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("qnode-impl", "initialized"); -#ifndef WINDOWS if (udfcOpen() != 0) { dError("qnode can not open udfc"); qmClose(pMgmt); return -1; } -#endif if (qmStartWorker(pMgmt) != 0) { dError("failed to start qnode worker since %s", terrstr()); diff --git a/source/dnode/mgmt/mgmt_snode/src/smInt.c b/source/dnode/mgmt/mgmt_snode/src/smInt.c index 58d4b6139b..e222349767 100644 --- a/source/dnode/mgmt/mgmt_snode/src/smInt.c +++ b/source/dnode/mgmt/mgmt_snode/src/smInt.c @@ -65,13 +65,11 @@ int32_t smOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("snode-worker", "initialized"); -#ifndef WINDOWS if (udfcOpen() != 0) { dError("failed to open udfc in snode"); smClose(pMgmt); return -1; } -#endif pOutput->pMgmt = pMgmt; return 0; diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index 2dd0130d56..0ff2537e4c 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -571,12 +571,10 @@ static int32_t vmInit(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("vnode-vnodes", "initialized"); -#ifndef WINDOWS if (udfcOpen() != 0) { dError("failed to open udfc in vnode"); goto _OVER; } -#endif code = 0; diff --git a/source/dnode/mgmt/node_mgmt/src/dmEnv.c b/source/dnode/mgmt/node_mgmt/src/dmEnv.c index f7e429f938..65683e5061 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmEnv.c +++ b/source/dnode/mgmt/node_mgmt/src/dmEnv.c @@ -198,10 +198,8 @@ void dmCleanup() { monCleanup(); syncCleanUp(); walCleanUp(); -#ifndef WINDOWS udfcClose(); udfStopUdfd(); -#endif taosStopCacheRefreshWorker(); dmDiskClose(); dInfo("dnode env is cleaned up"); From 777ece27ae1c47aec575791186eff416758ecc09 Mon Sep 17 00:00:00 2001 From: kailixu Date: Wed, 16 Aug 2023 09:56:25 +0800 Subject: [PATCH 84/92] chore: code format --- source/dnode/mgmt/node_mgmt/src/dmEnv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/mgmt/node_mgmt/src/dmEnv.c b/source/dnode/mgmt/node_mgmt/src/dmEnv.c index 65683e5061..a34002161d 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmEnv.c +++ b/source/dnode/mgmt/node_mgmt/src/dmEnv.c @@ -198,7 +198,7 @@ void dmCleanup() { monCleanup(); syncCleanUp(); walCleanUp(); - udfcClose(); + udfcClose(); udfStopUdfd(); taosStopCacheRefreshWorker(); dmDiskClose(); From cb027cc5c53ad481d9b401f0b742e5542770b5d9 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Tue, 15 Aug 2023 17:50:36 +0800 Subject: [PATCH 85/92] feat: support alter table add column with comment --- include/common/tmsg.h | 3 + include/libs/nodes/cmdnodes.h | 1 + source/libs/parser/inc/parAst.h | 3 +- source/libs/parser/inc/sql.y | 8 +- source/libs/parser/src/parAstCreater.c | 12 +- source/libs/parser/src/parTranslater.c | 18 + source/libs/parser/src/sql.c | 1719 ++++++++++++------------ tests/system-test/0-others/show.py | 42 +- 8 files changed, 949 insertions(+), 857 deletions(-) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 43b70141e2..8aaf6bfc15 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -2389,6 +2389,9 @@ typedef struct { int8_t type; int8_t flags; int32_t bytes; + bool hasColComment; + char* colComment; + int32_t colCommentLen; // TSDB_ALTER_TABLE_DROP_COLUMN // TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES int8_t colModType; diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index b6c4e89a33..78b7f1babf 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -214,6 +214,7 @@ typedef struct SAlterTableStmt { char newColName[TSDB_COL_NAME_LEN]; STableOptions* pOptions; SDataType dataType; + char colComment[TSDB_COL_COMMENT_LEN]; SValueNode* pVal; } SAlterTableStmt; diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h index 78422bf746..6d7d4dbc43 100644 --- a/source/libs/parser/inc/parAst.h +++ b/source/libs/parser/inc/parAst.h @@ -171,8 +171,7 @@ SNode* createDropTableClause(SAstCreateContext* pCxt, bool ignoreNotExists, SNod SNode* createDropTableStmt(SAstCreateContext* pCxt, SNodeList* pTables); SNode* createDropSuperTableStmt(SAstCreateContext* pCxt, bool ignoreNotExists, SNode* pRealTable); SNode* createAlterTableModifyOptions(SAstCreateContext* pCxt, SNode* pRealTable, SNode* pOptions); -SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName, - SDataType dataType); +SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SNode* pColDefNode); SNode* createAlterTableDropCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName); SNode* createAlterTableRenameCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pOldColName, SToken* pNewColName); diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index e8f1371d4e..04635ac78e 100755 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -312,17 +312,17 @@ cmd ::= ALTER STABLE alter_table_clause(A). alter_table_clause(A) ::= full_table_name(B) alter_table_options(C). { A = createAlterTableModifyOptions(pCxt, B, C); } alter_table_clause(A) ::= - full_table_name(B) ADD COLUMN column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_ADD_COLUMN, &C, D); } + full_table_name(B) ADD COLUMN column_def(C). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_ADD_COLUMN, C); } alter_table_clause(A) ::= full_table_name(B) DROP COLUMN column_name(C). { A = createAlterTableDropCol(pCxt, B, TSDB_ALTER_TABLE_DROP_COLUMN, &C); } alter_table_clause(A) ::= - full_table_name(B) MODIFY COLUMN column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &C, D); } + full_table_name(B) MODIFY COLUMN column_def(C). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, C); } alter_table_clause(A) ::= full_table_name(B) RENAME COLUMN column_name(C) column_name(D). { A = createAlterTableRenameCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &C, &D); } alter_table_clause(A) ::= - full_table_name(B) ADD TAG column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_ADD_TAG, &C, D); } + full_table_name(B) ADD TAG column_def(C). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_ADD_TAG, C); } alter_table_clause(A) ::= full_table_name(B) DROP TAG column_name(C). { A = createAlterTableDropCol(pCxt, B, TSDB_ALTER_TABLE_DROP_TAG, &C); } alter_table_clause(A) ::= - full_table_name(B) MODIFY TAG column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &C, D); } + full_table_name(B) MODIFY TAG column_def(C). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, C); } alter_table_clause(A) ::= full_table_name(B) RENAME TAG column_name(C) column_name(D). { A = createAlterTableRenameCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &C, &D); } alter_table_clause(A) ::= diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index f85218c50a..c95fb5d348 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -1333,17 +1333,15 @@ SNode* createAlterTableModifyOptions(SAstCreateContext* pCxt, SNode* pRealTable, return createAlterTableStmtFinalize(pRealTable, pStmt); } -SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName, - SDataType dataType) { +SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SNode* pColDefNode) { CHECK_PARSER_STATUS(pCxt); - if (!checkColumnName(pCxt, pColName)) { - return NULL; - } + SColumnDefNode* pCol = (SColumnDefNode*)pColDefNode; SAlterTableStmt* pStmt = (SAlterTableStmt*)nodesMakeNode(QUERY_NODE_ALTER_TABLE_STMT); CHECK_OUT_OF_MEM(pStmt); pStmt->alterType = alterType; - COPY_STRING_FORM_ID_TOKEN(pStmt->colName, pColName); - pStmt->dataType = dataType; + strcpy(pStmt->colName, pCol->colName); + strcpy(pStmt->colComment, pCol->comments); + pStmt->dataType = pCol->dataType; return createAlterTableStmtFinalize(pRealTable, pStmt); } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 38294c6ac6..edd09aa0a9 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -8863,6 +8863,15 @@ static int32_t buildAddColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, S pReq->type = pStmt->dataType.type; pReq->flags = COL_SMA_ON; pReq->bytes = calcTypeBytes(pStmt->dataType); + if (pStmt->colComment[0]) { + pReq->colComment = taosStrdup(pStmt->colComment); + if (pReq->colComment == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pReq->colCommentLen = strlen(pReq->colComment); + } else { + pReq->colCommentLen = -1; + } return TSDB_CODE_SUCCESS; } @@ -8913,6 +8922,15 @@ static int32_t buildUpdateColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt return TSDB_CODE_OUT_OF_MEMORY; } pReq->colId = pSchema->colId; + if (pStmt->colComment[0]) { + pReq->colComment = taosStrdup(pStmt->colComment); + if (pReq->colComment == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pReq->colCommentLen = strlen(pReq->colComment); + } else { + pReq->colCommentLen = -1; + } return TSDB_CODE_SUCCESS; } diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index 9024dbda62..06dd5de879 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -1,5 +1,5 @@ /* This file is automatically generated by Lemon from input grammar -** source file "./sql.y". */ +** source file "sql.y". */ /* ** 2000-05-29 ** @@ -134,18 +134,18 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 802 +#define YYNSTATE 798 #define YYNRULE 601 #define YYNRULE_WITH_ACTION 601 #define YYNTOKEN 338 -#define YY_MAX_SHIFT 801 -#define YY_MIN_SHIFTREDUCE 1182 -#define YY_MAX_SHIFTREDUCE 1782 -#define YY_ERROR_ACTION 1783 -#define YY_ACCEPT_ACTION 1784 -#define YY_NO_ACTION 1785 -#define YY_MIN_REDUCE 1786 -#define YY_MAX_REDUCE 2386 +#define YY_MAX_SHIFT 797 +#define YY_MIN_SHIFTREDUCE 1178 +#define YY_MAX_SHIFTREDUCE 1778 +#define YY_ERROR_ACTION 1779 +#define YY_ACCEPT_ACTION 1780 +#define YY_NO_ACTION 1781 +#define YY_MIN_REDUCE 1782 +#define YY_MAX_REDUCE 2382 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -212,600 +212,618 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2858) +#define YY_ACTTAB_COUNT (3033) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 1952, 2197, 2175, 2086, 221, 690, 1963, 2158, 537, 184, - /* 10 */ 1829, 670, 48, 46, 1709, 394, 2183, 1215, 2083, 677, - /* 20 */ 401, 2004, 1558, 41, 40, 135, 2179, 47, 45, 44, - /* 30 */ 43, 42, 574, 1639, 453, 1556, 2175, 539, 689, 2215, - /* 40 */ 41, 40, 1784, 536, 47, 45, 44, 43, 42, 689, - /* 50 */ 1954, 2165, 1948, 706, 630, 531, 1217, 2357, 1220, 1221, - /* 60 */ 2179, 181, 1634, 529, 2181, 398, 525, 521, 19, 1240, - /* 70 */ 66, 1239, 2363, 188, 700, 1564, 30, 2358, 656, 348, - /* 80 */ 168, 369, 2069, 361, 140, 690, 1963, 2196, 1904, 2232, - /* 90 */ 667, 144, 112, 2198, 710, 2200, 2201, 705, 2181, 700, - /* 100 */ 798, 1939, 1241, 15, 185, 135, 2285, 169, 700, 1798, - /* 110 */ 397, 2281, 579, 1583, 2086, 416, 48, 46, 2017, 2362, - /* 120 */ 415, 51, 2357, 190, 401, 382, 1558, 1668, 1374, 2084, - /* 130 */ 677, 2311, 51, 2015, 690, 1963, 1749, 1639, 2361, 1556, - /* 140 */ 1641, 1642, 2358, 2360, 1365, 735, 734, 733, 1369, 732, - /* 150 */ 1371, 1372, 731, 728, 193, 1380, 725, 1382, 1383, 722, - /* 160 */ 719, 716, 630, 1584, 655, 2357, 1634, 2357, 747, 62, - /* 170 */ 1614, 1624, 19, 457, 2065, 109, 1640, 1643, 689, 1564, - /* 180 */ 2363, 188, 654, 188, 1669, 2358, 656, 2358, 656, 38, - /* 190 */ 306, 1559, 145, 1557, 286, 2293, 666, 2362, 136, 665, - /* 200 */ 1955, 2357, 14, 13, 798, 41, 40, 15, 2197, 47, - /* 210 */ 45, 44, 43, 42, 1585, 675, 654, 188, 707, 1317, - /* 220 */ 202, 2358, 656, 1562, 1563, 1786, 1613, 1616, 1617, 1618, - /* 230 */ 1619, 1620, 1621, 1622, 1623, 702, 698, 1632, 1633, 1635, - /* 240 */ 1636, 1637, 1638, 2, 1641, 1642, 2215, 2011, 2012, 134, - /* 250 */ 133, 132, 131, 130, 129, 128, 127, 126, 2165, 1319, - /* 260 */ 706, 1787, 37, 399, 1663, 1664, 1665, 1666, 1667, 1671, - /* 270 */ 1672, 1673, 1674, 534, 1614, 1624, 535, 1822, 191, 1583, - /* 280 */ 1640, 1643, 125, 1484, 1485, 124, 123, 122, 121, 120, - /* 290 */ 119, 118, 117, 116, 2196, 1559, 2232, 1557, 1772, 112, - /* 300 */ 2198, 710, 2200, 2201, 705, 1682, 700, 2048, 395, 147, - /* 310 */ 551, 151, 2256, 2285, 1584, 2197, 166, 397, 2281, 1483, - /* 320 */ 1486, 1809, 667, 144, 1965, 670, 191, 1562, 1563, 650, - /* 330 */ 1613, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 702, - /* 340 */ 698, 1632, 1633, 1635, 1636, 1637, 1638, 2, 12, 48, - /* 350 */ 46, 1583, 1808, 2215, 2017, 410, 409, 401, 108, 1558, - /* 360 */ 2362, 367, 62, 2357, 2300, 2165, 288, 706, 105, 2015, - /* 370 */ 1639, 2165, 1556, 592, 591, 590, 690, 1963, 1565, 2361, - /* 380 */ 582, 141, 586, 2358, 2359, 542, 585, 649, 535, 1822, - /* 390 */ 2297, 584, 589, 377, 376, 2130, 56, 583, 615, 1634, - /* 400 */ 252, 2196, 2165, 2232, 251, 19, 112, 2198, 710, 2200, - /* 410 */ 2201, 705, 1564, 700, 253, 2215, 297, 298, 185, 406, - /* 420 */ 2285, 296, 2010, 2012, 397, 2281, 187, 2293, 2294, 2197, - /* 430 */ 142, 2298, 1807, 655, 1409, 1410, 2357, 798, 578, 707, - /* 440 */ 15, 1831, 41, 40, 254, 2312, 47, 45, 44, 43, - /* 450 */ 42, 654, 188, 48, 46, 1644, 2358, 656, 223, 2197, - /* 460 */ 577, 401, 537, 1558, 1829, 93, 475, 2215, 356, 707, - /* 470 */ 648, 381, 2300, 608, 1639, 474, 1556, 1641, 1642, 2165, - /* 480 */ 103, 706, 2165, 125, 1529, 1530, 124, 123, 122, 121, - /* 490 */ 120, 119, 118, 117, 116, 12, 62, 2215, 2296, 667, - /* 500 */ 144, 1467, 1468, 1634, 676, 1956, 1713, 1614, 1624, 2165, - /* 510 */ 404, 706, 1583, 1640, 1643, 2196, 1564, 2232, 166, 191, - /* 520 */ 112, 2198, 710, 2200, 2201, 705, 1965, 700, 1559, 1564, - /* 530 */ 1557, 62, 2377, 606, 2285, 12, 1568, 10, 397, 2281, - /* 540 */ 747, 798, 690, 1963, 49, 2196, 604, 2232, 602, 2197, - /* 550 */ 170, 2198, 710, 2200, 2201, 705, 549, 700, 2079, 707, - /* 560 */ 1562, 1563, 451, 1613, 1616, 1617, 1618, 1619, 1620, 1621, - /* 570 */ 1622, 1623, 702, 698, 1632, 1633, 1635, 1636, 1637, 1638, - /* 580 */ 2, 1641, 1642, 445, 1585, 444, 1806, 2215, 41, 40, - /* 590 */ 631, 2322, 47, 45, 44, 43, 42, 738, 1805, 2165, - /* 600 */ 1586, 706, 669, 186, 2293, 2294, 165, 142, 2298, 2017, - /* 610 */ 1832, 1614, 1624, 690, 1963, 443, 391, 1640, 1643, 463, - /* 620 */ 2065, 41, 40, 404, 2015, 47, 45, 44, 43, 42, - /* 630 */ 2300, 163, 1559, 452, 1557, 2196, 2165, 2232, 383, 1965, - /* 640 */ 112, 2198, 710, 2200, 2201, 705, 2015, 700, 2165, 2186, - /* 650 */ 447, 2197, 2260, 191, 2285, 446, 2295, 2159, 397, 2281, - /* 660 */ 793, 707, 1615, 2319, 1562, 1563, 205, 1613, 1616, 1617, - /* 670 */ 1618, 1619, 1620, 1621, 1622, 1623, 702, 698, 1632, 1633, - /* 680 */ 1635, 1636, 1637, 1638, 2, 48, 46, 1940, 191, 2215, - /* 690 */ 745, 490, 2065, 401, 757, 1558, 645, 630, 690, 1963, - /* 700 */ 2357, 2165, 435, 706, 630, 2188, 1639, 2357, 1556, 156, - /* 710 */ 155, 742, 741, 740, 153, 2363, 188, 692, 465, 2257, - /* 720 */ 2358, 656, 2363, 188, 44, 43, 42, 2358, 656, 437, - /* 730 */ 433, 1737, 497, 690, 1963, 1634, 288, 2196, 210, 2232, - /* 740 */ 597, 1950, 112, 2198, 710, 2200, 2201, 705, 1564, 700, - /* 750 */ 690, 1963, 266, 480, 2377, 607, 2285, 1865, 41, 40, - /* 760 */ 397, 2281, 47, 45, 44, 43, 42, 2197, 1649, 250, - /* 770 */ 481, 690, 1963, 798, 1583, 207, 49, 704, 642, 641, - /* 780 */ 1735, 1736, 1738, 1739, 1740, 600, 651, 646, 639, 48, - /* 790 */ 46, 550, 594, 212, 211, 407, 1779, 401, 249, 1558, - /* 800 */ 690, 1963, 745, 166, 52, 2215, 1938, 1804, 570, 569, - /* 810 */ 1639, 1965, 1556, 1641, 1642, 86, 496, 2165, 85, 706, - /* 820 */ 1960, 156, 155, 742, 741, 740, 153, 592, 591, 590, - /* 830 */ 667, 144, 629, 262, 582, 141, 586, 1583, 70, 1634, - /* 840 */ 585, 69, 1905, 1614, 1624, 584, 589, 377, 376, 1640, - /* 850 */ 1643, 583, 1564, 2196, 1748, 2232, 1946, 2165, 342, 2198, - /* 860 */ 710, 2200, 2201, 705, 1559, 700, 1557, 2251, 41, 40, - /* 870 */ 690, 1963, 47, 45, 44, 43, 42, 798, 1803, 737, - /* 880 */ 15, 2197, 47, 45, 44, 43, 42, 1243, 1244, 1223, - /* 890 */ 255, 707, 1240, 2332, 1239, 1582, 1562, 1563, 1778, 1613, - /* 900 */ 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 702, 698, - /* 910 */ 1632, 1633, 1635, 1636, 1637, 1638, 2, 1641, 1642, 2215, - /* 920 */ 90, 745, 572, 571, 1615, 1241, 676, 2361, 2165, 690, - /* 930 */ 1963, 2165, 259, 706, 189, 2293, 2294, 371, 142, 2298, - /* 940 */ 156, 155, 742, 741, 740, 153, 1958, 1614, 1624, 263, - /* 950 */ 701, 690, 1963, 1640, 1643, 2325, 60, 588, 587, 1706, - /* 960 */ 181, 191, 1670, 627, 1725, 690, 1963, 2196, 1559, 2232, - /* 970 */ 1557, 673, 112, 2198, 710, 2200, 2201, 705, 674, 700, - /* 980 */ 2079, 2070, 34, 1802, 2377, 301, 2285, 1615, 41, 40, - /* 990 */ 397, 2281, 47, 45, 44, 43, 42, 676, 769, 767, - /* 1000 */ 1562, 1563, 1862, 1613, 1616, 1617, 1618, 1619, 1620, 1621, - /* 1010 */ 1622, 1623, 702, 698, 1632, 1633, 1635, 1636, 1637, 1638, - /* 1020 */ 2, 2148, 352, 167, 1581, 690, 1963, 1801, 327, 9, - /* 1030 */ 694, 488, 2257, 2165, 504, 90, 146, 503, 2175, 2256, - /* 1040 */ 35, 739, 324, 73, 2008, 687, 72, 690, 1963, 685, - /* 1050 */ 1675, 2079, 2184, 471, 613, 505, 166, 349, 1586, 1586, - /* 1060 */ 473, 1959, 2179, 1800, 1966, 1797, 1796, 688, 219, 516, - /* 1070 */ 514, 511, 775, 774, 773, 772, 413, 2165, 771, 770, - /* 1080 */ 148, 765, 764, 763, 762, 761, 760, 759, 158, 755, - /* 1090 */ 754, 753, 412, 411, 750, 749, 748, 176, 175, 1328, - /* 1100 */ 2181, 630, 690, 1963, 2357, 580, 370, 237, 62, 374, - /* 1110 */ 700, 2017, 1327, 2165, 2017, 2165, 2165, 1332, 459, 2363, - /* 1120 */ 188, 396, 307, 173, 2358, 656, 2016, 1315, 2017, 2015, - /* 1130 */ 1331, 568, 564, 560, 556, 405, 236, 320, 758, 743, - /* 1140 */ 1994, 1925, 2008, 2015, 1795, 662, 1794, 111, 501, 1793, - /* 1150 */ 659, 495, 494, 493, 492, 487, 486, 485, 484, 483, - /* 1160 */ 479, 478, 477, 476, 351, 468, 467, 466, 1792, 461, - /* 1170 */ 460, 368, 690, 1963, 1220, 1221, 91, 506, 375, 234, - /* 1180 */ 373, 372, 54, 576, 3, 1791, 1790, 578, 81, 80, - /* 1190 */ 450, 2197, 408, 200, 2165, 508, 2165, 2305, 1702, 2165, - /* 1200 */ 1789, 707, 744, 637, 658, 2008, 442, 440, 2151, 577, - /* 1210 */ 203, 265, 83, 74, 137, 154, 1705, 350, 2165, 610, - /* 1220 */ 431, 609, 2197, 429, 425, 421, 418, 443, 154, 2215, - /* 1230 */ 242, 454, 707, 240, 2350, 2165, 2165, 1941, 430, 244, - /* 1240 */ 697, 2165, 243, 706, 455, 581, 1849, 233, 227, 1702, - /* 1250 */ 2165, 1799, 2197, 1274, 232, 547, 246, 423, 1840, 245, - /* 1260 */ 2215, 154, 707, 84, 2304, 191, 248, 1313, 593, 247, - /* 1270 */ 1838, 1567, 2165, 225, 706, 55, 264, 2196, 643, 2232, - /* 1280 */ 595, 149, 112, 2198, 710, 2200, 2201, 705, 1524, 700, - /* 1290 */ 2215, 50, 598, 1275, 2377, 1566, 2285, 1781, 1782, 50, - /* 1300 */ 397, 2281, 2165, 283, 706, 139, 270, 154, 2196, 277, - /* 1310 */ 2232, 1903, 1902, 112, 2198, 710, 2200, 2201, 705, 94, - /* 1320 */ 700, 1527, 50, 384, 1558, 2377, 294, 2285, 2216, 71, - /* 1330 */ 152, 397, 2281, 154, 14, 13, 64, 1556, 2196, 50, - /* 1340 */ 2232, 414, 2197, 112, 2198, 710, 2200, 2201, 705, 50, - /* 1350 */ 700, 1734, 707, 410, 409, 2377, 751, 2285, 36, 1733, - /* 1360 */ 2074, 397, 2281, 1572, 41, 40, 272, 672, 47, 45, - /* 1370 */ 44, 43, 42, 2197, 1639, 1823, 1565, 1564, 1293, 714, - /* 1380 */ 2215, 1828, 1481, 707, 152, 663, 299, 2005, 660, 682, - /* 1390 */ 303, 752, 2165, 1358, 706, 1660, 1676, 154, 138, 1625, - /* 1400 */ 2315, 668, 798, 1634, 285, 282, 5, 417, 1, 319, - /* 1410 */ 2197, 2215, 152, 1291, 422, 1589, 1564, 365, 438, 439, - /* 1420 */ 707, 196, 195, 2165, 441, 706, 198, 1505, 2196, 1570, - /* 1430 */ 2232, 314, 456, 112, 2198, 710, 2200, 2201, 705, 1387, - /* 1440 */ 700, 696, 1582, 209, 1391, 2258, 458, 2285, 2215, 1586, - /* 1450 */ 2075, 397, 2281, 1569, 462, 464, 499, 1398, 1396, 2196, - /* 1460 */ 2165, 2232, 706, 1581, 112, 2198, 710, 2200, 2201, 705, - /* 1470 */ 482, 700, 157, 489, 469, 2067, 693, 491, 2285, 498, - /* 1480 */ 500, 509, 397, 2281, 510, 507, 213, 214, 512, 513, - /* 1490 */ 1587, 671, 216, 1559, 532, 1557, 2196, 515, 2232, 2197, - /* 1500 */ 517, 113, 2198, 710, 2200, 2201, 705, 4, 700, 707, - /* 1510 */ 533, 540, 541, 224, 543, 2285, 1584, 1588, 545, 2284, - /* 1520 */ 2281, 226, 1590, 544, 546, 1562, 1563, 548, 229, 552, - /* 1530 */ 573, 575, 1573, 231, 1568, 88, 89, 2215, 630, 235, - /* 1540 */ 1953, 2357, 355, 239, 114, 92, 1949, 2139, 2197, 2165, - /* 1550 */ 150, 706, 241, 256, 612, 618, 2363, 188, 707, 614, - /* 1560 */ 159, 2358, 656, 619, 1576, 1578, 315, 160, 1951, 1947, - /* 1570 */ 161, 162, 617, 2136, 2197, 625, 2135, 698, 1632, 1633, - /* 1580 */ 1635, 1636, 1637, 1638, 704, 2196, 2215, 2232, 622, 1512, - /* 1590 */ 113, 2198, 710, 2200, 2201, 705, 260, 700, 2165, 644, - /* 1600 */ 706, 2316, 258, 2326, 2285, 2331, 634, 680, 695, 2281, - /* 1610 */ 624, 623, 2215, 640, 387, 2330, 268, 271, 647, 8, - /* 1620 */ 653, 2380, 174, 2307, 2165, 2197, 706, 635, 633, 276, - /* 1630 */ 632, 281, 664, 388, 708, 707, 2232, 1585, 2197, 113, - /* 1640 */ 2198, 710, 2200, 2201, 705, 661, 700, 1702, 707, 143, - /* 1650 */ 289, 2301, 278, 2285, 1591, 178, 98, 360, 2281, 316, - /* 1660 */ 2196, 280, 2232, 2215, 678, 342, 2198, 710, 2200, 2201, - /* 1670 */ 705, 703, 700, 691, 2250, 2165, 2215, 706, 279, 2080, - /* 1680 */ 317, 2356, 284, 683, 684, 679, 100, 2197, 2165, 318, - /* 1690 */ 706, 2094, 2093, 102, 61, 2092, 1964, 707, 393, 2266, - /* 1700 */ 104, 712, 2009, 1926, 2197, 321, 794, 2157, 310, 325, - /* 1710 */ 795, 2196, 797, 2232, 707, 357, 171, 2198, 710, 2200, - /* 1720 */ 2201, 705, 358, 700, 2196, 2215, 2232, 53, 345, 113, - /* 1730 */ 2198, 710, 2200, 2201, 705, 330, 700, 2165, 2156, 706, - /* 1740 */ 323, 2155, 2215, 2285, 344, 334, 78, 385, 2282, 2152, - /* 1750 */ 419, 420, 1549, 2197, 2165, 1550, 706, 194, 424, 2150, - /* 1760 */ 426, 427, 428, 707, 2149, 366, 2147, 657, 2378, 432, - /* 1770 */ 2146, 2145, 434, 2196, 436, 2232, 1540, 2197, 170, 2198, - /* 1780 */ 710, 2200, 2201, 705, 2126, 700, 197, 707, 2125, 199, - /* 1790 */ 2196, 2215, 2232, 79, 1508, 343, 2198, 710, 2200, 2201, - /* 1800 */ 705, 1507, 700, 2165, 2197, 706, 2107, 2106, 2105, 448, - /* 1810 */ 449, 2104, 2103, 2058, 707, 2215, 1458, 2057, 2054, 2323, - /* 1820 */ 386, 201, 2053, 82, 2197, 2052, 2051, 2165, 2056, 706, - /* 1830 */ 204, 2055, 2050, 2049, 707, 2047, 2046, 2045, 206, 2196, - /* 1840 */ 470, 2232, 2215, 2044, 336, 2198, 710, 2200, 2201, 705, - /* 1850 */ 472, 700, 2060, 2043, 2165, 2042, 706, 2041, 2040, 2039, - /* 1860 */ 2038, 2037, 2215, 2196, 2036, 2232, 2035, 392, 343, 2198, - /* 1870 */ 710, 2200, 2201, 705, 2165, 700, 706, 208, 2028, 2027, - /* 1880 */ 87, 2026, 2025, 2059, 2024, 2023, 215, 652, 2034, 2033, - /* 1890 */ 2196, 2197, 2232, 2032, 2031, 171, 2198, 710, 2200, 2201, - /* 1900 */ 705, 707, 700, 2030, 2029, 2022, 2021, 2020, 1460, 2019, - /* 1910 */ 2196, 502, 2232, 2018, 1329, 343, 2198, 710, 2200, 2201, - /* 1920 */ 705, 2197, 700, 353, 354, 1868, 1325, 1867, 1866, 2215, - /* 1930 */ 1333, 707, 217, 218, 400, 1864, 1861, 520, 1860, 519, - /* 1940 */ 524, 2165, 1853, 706, 523, 518, 522, 2379, 527, 526, - /* 1950 */ 1842, 528, 530, 1818, 1222, 76, 1817, 220, 2124, 2215, - /* 1960 */ 2114, 77, 182, 222, 402, 2102, 2185, 183, 538, 228, - /* 1970 */ 2101, 2165, 230, 706, 553, 554, 555, 2196, 2078, 2232, - /* 1980 */ 2197, 1942, 343, 2198, 710, 2200, 2201, 705, 616, 700, - /* 1990 */ 707, 1863, 1859, 1267, 1857, 558, 557, 1855, 559, 561, - /* 2000 */ 562, 563, 1852, 565, 566, 567, 801, 2196, 1837, 2232, - /* 2010 */ 1835, 1836, 343, 2198, 710, 2200, 2201, 705, 2215, 700, - /* 2020 */ 313, 1834, 1814, 1944, 1943, 1403, 1402, 766, 1316, 768, - /* 2030 */ 2165, 1314, 706, 1312, 1311, 1310, 180, 1850, 1309, 1303, - /* 2040 */ 1308, 63, 238, 1841, 791, 787, 783, 779, 1305, 311, - /* 2050 */ 1304, 1302, 378, 2197, 379, 1839, 380, 596, 1813, 1812, - /* 2060 */ 599, 601, 603, 707, 1811, 2123, 611, 605, 2232, 115, - /* 2070 */ 1534, 338, 2198, 710, 2200, 2201, 705, 1536, 700, 1533, - /* 2080 */ 1538, 1514, 29, 67, 2197, 1518, 2113, 2100, 1516, 110, - /* 2090 */ 164, 2215, 304, 620, 707, 2099, 2362, 20, 17, 1751, - /* 2100 */ 6, 21, 65, 2165, 31, 706, 57, 261, 7, 626, - /* 2110 */ 275, 638, 267, 621, 22, 1493, 1492, 274, 269, 2197, - /* 2120 */ 636, 172, 2215, 628, 1732, 686, 2186, 33, 24, 707, - /* 2130 */ 58, 273, 32, 23, 2165, 1724, 706, 1771, 18, 2196, - /* 2140 */ 1772, 2232, 95, 1766, 328, 2198, 710, 2200, 2201, 705, - /* 2150 */ 1765, 700, 389, 1770, 1769, 390, 2197, 2215, 287, 177, - /* 2160 */ 291, 2098, 2077, 292, 97, 1699, 707, 290, 59, 2165, - /* 2170 */ 2196, 706, 2232, 1698, 2076, 326, 2198, 710, 2200, 2201, - /* 2180 */ 705, 2197, 700, 96, 25, 295, 257, 99, 105, 293, - /* 2190 */ 305, 707, 1730, 300, 2215, 68, 26, 101, 1651, 11, - /* 2200 */ 13, 1650, 1574, 179, 2235, 2196, 2165, 2232, 706, 1661, - /* 2210 */ 329, 2198, 710, 2200, 2201, 705, 681, 700, 2197, 2215, - /* 2220 */ 302, 1606, 192, 711, 713, 1629, 1627, 403, 707, 699, - /* 2230 */ 39, 2165, 1626, 706, 16, 27, 717, 1598, 28, 720, - /* 2240 */ 1388, 715, 2196, 2197, 2232, 1385, 1384, 335, 2198, 710, - /* 2250 */ 2200, 2201, 705, 707, 700, 1381, 2215, 718, 721, 723, - /* 2260 */ 724, 726, 1375, 709, 1373, 729, 727, 2196, 2165, 2232, - /* 2270 */ 706, 730, 339, 2198, 710, 2200, 2201, 705, 1364, 700, - /* 2280 */ 106, 2215, 736, 308, 107, 1379, 1397, 75, 1393, 1265, - /* 2290 */ 1378, 1377, 1376, 2165, 1297, 706, 746, 1296, 1295, 1294, - /* 2300 */ 1292, 309, 1290, 1289, 2196, 1288, 2232, 1323, 756, 331, - /* 2310 */ 2198, 710, 2200, 2201, 705, 2197, 700, 1286, 1285, 1284, - /* 2320 */ 1283, 1282, 1281, 1280, 1320, 707, 1318, 1277, 1276, 2196, - /* 2330 */ 2197, 2232, 1273, 1858, 340, 2198, 710, 2200, 2201, 705, - /* 2340 */ 707, 700, 1272, 1271, 1270, 776, 1856, 778, 2197, 777, - /* 2350 */ 780, 781, 782, 2215, 1854, 784, 786, 1851, 707, 788, - /* 2360 */ 1833, 785, 790, 789, 792, 2165, 1810, 706, 2215, 1212, - /* 2370 */ 312, 796, 1785, 1560, 322, 1785, 799, 1785, 800, 1785, - /* 2380 */ 2165, 1785, 706, 1785, 1785, 1785, 2215, 1785, 1785, 1785, - /* 2390 */ 1785, 1785, 1785, 1785, 1785, 2197, 1785, 1785, 2165, 1785, - /* 2400 */ 706, 2196, 1785, 2232, 1785, 707, 332, 2198, 710, 2200, - /* 2410 */ 2201, 705, 1785, 700, 1785, 1785, 2196, 2197, 2232, 1785, - /* 2420 */ 1785, 341, 2198, 710, 2200, 2201, 705, 707, 700, 1785, - /* 2430 */ 1785, 1785, 1785, 2215, 2196, 1785, 2232, 1785, 1785, 333, - /* 2440 */ 2198, 710, 2200, 2201, 705, 2165, 700, 706, 1785, 1785, - /* 2450 */ 1785, 1785, 1785, 1785, 1785, 2215, 1785, 1785, 1785, 1785, - /* 2460 */ 1785, 1785, 1785, 1785, 2197, 1785, 1785, 2165, 1785, 706, - /* 2470 */ 1785, 1785, 1785, 1785, 707, 1785, 1785, 1785, 1785, 1785, - /* 2480 */ 1785, 2196, 1785, 2232, 1785, 1785, 346, 2198, 710, 2200, - /* 2490 */ 2201, 705, 1785, 700, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2500 */ 1785, 1785, 2215, 2196, 1785, 2232, 1785, 1785, 347, 2198, - /* 2510 */ 710, 2200, 2201, 705, 2165, 700, 706, 1785, 1785, 1785, - /* 2520 */ 1785, 1785, 1785, 2197, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2530 */ 1785, 1785, 1785, 707, 1785, 1785, 2197, 1785, 1785, 1785, - /* 2540 */ 1785, 1785, 1785, 1785, 1785, 1785, 707, 1785, 1785, 1785, - /* 2550 */ 2196, 1785, 2232, 2197, 1785, 2209, 2198, 710, 2200, 2201, - /* 2560 */ 705, 2215, 700, 707, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2570 */ 1785, 1785, 1785, 2165, 2215, 706, 1785, 1785, 1785, 1785, - /* 2580 */ 1785, 1785, 1785, 1785, 1785, 2197, 2165, 1785, 706, 1785, - /* 2590 */ 1785, 2215, 1785, 1785, 1785, 707, 1785, 1785, 1785, 1785, - /* 2600 */ 1785, 1785, 1785, 2165, 1785, 706, 1785, 1785, 1785, 2196, - /* 2610 */ 1785, 2232, 1785, 1785, 2208, 2198, 710, 2200, 2201, 705, - /* 2620 */ 1785, 700, 2196, 2215, 2232, 1785, 1785, 2207, 2198, 710, - /* 2630 */ 2200, 2201, 705, 1785, 700, 2165, 1785, 706, 1785, 2196, - /* 2640 */ 1785, 2232, 1785, 1785, 362, 2198, 710, 2200, 2201, 705, - /* 2650 */ 1785, 700, 2197, 1785, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2660 */ 1785, 1785, 707, 1785, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2670 */ 1785, 2196, 2197, 2232, 1785, 1785, 363, 2198, 710, 2200, - /* 2680 */ 2201, 705, 707, 700, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2690 */ 2215, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2700 */ 1785, 1785, 2165, 1785, 706, 1785, 1785, 1785, 1785, 1785, - /* 2710 */ 2215, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2720 */ 1785, 1785, 2165, 1785, 706, 1785, 1785, 1785, 1785, 1785, - /* 2730 */ 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 2196, 1785, - /* 2740 */ 2232, 1785, 2197, 359, 2198, 710, 2200, 2201, 705, 1785, - /* 2750 */ 700, 1785, 707, 1785, 1785, 1785, 1785, 1785, 2196, 2197, - /* 2760 */ 2232, 1785, 1785, 364, 2198, 710, 2200, 2201, 705, 707, - /* 2770 */ 700, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2780 */ 2215, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2790 */ 1785, 1785, 2165, 1785, 706, 1785, 1785, 2215, 1785, 1785, - /* 2800 */ 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 2165, - /* 2810 */ 1785, 706, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, - /* 2820 */ 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 708, 1785, - /* 2830 */ 2232, 1785, 1785, 338, 2198, 710, 2200, 2201, 705, 1785, - /* 2840 */ 700, 1785, 1785, 1785, 1785, 2196, 1785, 2232, 1785, 1785, - /* 2850 */ 337, 2198, 710, 2200, 2201, 705, 1785, 700, + /* 0 */ 443, 2193, 221, 2013, 449, 442, 533, 2154, 1825, 378, + /* 10 */ 2082, 666, 48, 46, 1705, 2358, 733, 2011, 2353, 645, + /* 20 */ 397, 181, 1554, 41, 40, 2080, 673, 47, 45, 44, + /* 30 */ 43, 42, 255, 1635, 2357, 1552, 685, 400, 2354, 2356, + /* 40 */ 2211, 2066, 1780, 2082, 1579, 1961, 163, 626, 2211, 344, + /* 50 */ 2353, 2161, 379, 702, 626, 390, 685, 2353, 2079, 673, + /* 60 */ 2011, 651, 1630, 223, 2353, 2359, 188, 533, 19, 1825, + /* 70 */ 2354, 652, 2359, 188, 1236, 1560, 1235, 2354, 652, 650, + /* 80 */ 188, 686, 1959, 357, 2354, 652, 1579, 2192, 90, 2228, + /* 90 */ 663, 144, 112, 2194, 706, 2196, 2197, 701, 2182, 696, + /* 100 */ 794, 135, 644, 15, 185, 367, 2281, 1237, 570, 530, + /* 110 */ 393, 2277, 531, 1818, 1954, 412, 48, 46, 1805, 51, + /* 120 */ 411, 527, 1554, 190, 397, 655, 1554, 1664, 1370, 525, + /* 130 */ 260, 2307, 521, 517, 671, 1552, 685, 1635, 672, 1552, + /* 140 */ 1637, 1638, 453, 2061, 1361, 731, 730, 729, 1365, 728, + /* 150 */ 1367, 1368, 727, 724, 2184, 1376, 721, 1378, 1379, 718, + /* 160 */ 715, 712, 626, 547, 2358, 2353, 1630, 2353, 2161, 62, + /* 170 */ 1610, 1620, 19, 94, 66, 1560, 1636, 1639, 2144, 1560, + /* 180 */ 2359, 188, 646, 2357, 1665, 2354, 652, 2354, 2355, 202, + /* 190 */ 545, 1555, 2075, 1553, 282, 2289, 662, 2358, 136, 661, + /* 200 */ 794, 2353, 38, 302, 794, 41, 40, 15, 2193, 47, + /* 210 */ 45, 44, 43, 42, 1581, 743, 650, 188, 703, 51, + /* 220 */ 611, 2354, 652, 1558, 1559, 1783, 1609, 1612, 1613, 1614, + /* 230 */ 1615, 1616, 1617, 1618, 1619, 698, 694, 1628, 1629, 1631, + /* 240 */ 1632, 1633, 1634, 2, 1637, 1638, 125, 2211, 12, 124, + /* 250 */ 123, 122, 121, 120, 119, 118, 117, 116, 2161, 169, + /* 260 */ 702, 1794, 37, 395, 1659, 1660, 1661, 1662, 1663, 1667, + /* 270 */ 1668, 1669, 1670, 62, 1610, 1620, 191, 1579, 1560, 125, + /* 280 */ 1636, 1639, 124, 123, 122, 121, 120, 119, 118, 117, + /* 290 */ 116, 1555, 602, 1553, 2192, 1555, 2228, 1553, 1768, 112, + /* 300 */ 2194, 706, 2196, 2197, 701, 600, 696, 598, 2013, 147, + /* 310 */ 734, 155, 2252, 2281, 387, 2193, 538, 393, 2277, 531, + /* 320 */ 1818, 168, 2011, 1558, 1559, 666, 191, 1558, 1559, 1900, + /* 330 */ 1609, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 698, + /* 340 */ 694, 1628, 1629, 1631, 1632, 1633, 1634, 2, 12, 48, + /* 350 */ 46, 686, 1959, 62, 2211, 2013, 753, 397, 535, 1554, + /* 360 */ 493, 363, 1580, 656, 532, 2161, 284, 702, 181, 2011, + /* 370 */ 1635, 135, 1552, 588, 587, 586, 686, 1959, 575, 103, + /* 380 */ 578, 141, 582, 1236, 658, 1235, 581, 365, 2065, 52, + /* 390 */ 184, 580, 585, 373, 372, 426, 193, 579, 140, 1630, + /* 400 */ 2296, 2192, 2000, 2228, 1952, 19, 112, 2194, 706, 2196, + /* 410 */ 2197, 701, 1560, 696, 686, 1959, 1237, 697, 185, 1324, + /* 420 */ 2281, 212, 211, 1211, 393, 2277, 2293, 1463, 1464, 2193, + /* 430 */ 191, 248, 1323, 651, 56, 247, 2353, 794, 1935, 703, + /* 440 */ 15, 1827, 41, 40, 492, 2308, 47, 45, 44, 43, + /* 450 */ 42, 650, 188, 48, 46, 1640, 2354, 652, 258, 2193, + /* 460 */ 1782, 397, 1213, 1554, 1216, 1217, 2013, 402, 2211, 700, + /* 470 */ 2006, 2008, 392, 431, 1635, 1901, 1552, 1637, 1638, 2161, + /* 480 */ 2011, 702, 1480, 1481, 134, 133, 132, 131, 130, 129, + /* 490 */ 128, 127, 126, 459, 2061, 1580, 93, 502, 2211, 352, + /* 500 */ 433, 429, 377, 1630, 604, 743, 1709, 1610, 1620, 2161, + /* 510 */ 191, 702, 1579, 1636, 1639, 2192, 1560, 2228, 1479, 1482, + /* 520 */ 112, 2194, 706, 2196, 2197, 701, 146, 696, 1555, 2252, + /* 530 */ 1553, 1861, 2373, 1795, 2281, 663, 144, 2321, 393, 2277, + /* 540 */ 205, 794, 686, 1959, 49, 2192, 191, 2228, 2007, 2008, + /* 550 */ 338, 2194, 706, 2196, 2197, 701, 699, 696, 687, 2246, + /* 560 */ 1558, 1559, 447, 1609, 1612, 1613, 1614, 1615, 1616, 1617, + /* 570 */ 1618, 1619, 698, 694, 1628, 1629, 1631, 1632, 1633, 1634, + /* 580 */ 2, 1637, 1638, 41, 40, 686, 1959, 47, 45, 44, + /* 590 */ 43, 42, 41, 40, 450, 1582, 47, 45, 44, 43, + /* 600 */ 42, 588, 587, 586, 1733, 448, 165, 451, 578, 141, + /* 610 */ 582, 1610, 1620, 1328, 581, 1405, 1406, 1636, 1639, 580, + /* 620 */ 585, 373, 372, 2013, 659, 579, 1327, 391, 30, 401, + /* 630 */ 686, 1959, 1555, 370, 1553, 1961, 166, 2011, 665, 186, + /* 640 */ 2289, 2290, 279, 142, 2294, 486, 2061, 2155, 2193, 1936, + /* 650 */ 461, 638, 637, 1731, 1732, 1734, 1735, 1736, 703, 1581, + /* 660 */ 2315, 1313, 1611, 9, 1558, 1559, 1934, 1609, 1612, 1613, + /* 670 */ 1614, 1615, 1616, 1617, 1618, 1619, 698, 694, 1628, 1629, + /* 680 */ 1631, 1632, 1633, 1634, 2, 48, 46, 2211, 1745, 686, + /* 690 */ 1959, 504, 210, 397, 626, 1554, 2126, 2353, 2161, 1804, + /* 700 */ 702, 1315, 371, 639, 369, 368, 1635, 572, 1552, 476, + /* 710 */ 1270, 574, 2359, 188, 2044, 41, 40, 2354, 652, 47, + /* 720 */ 45, 44, 43, 42, 41, 40, 1239, 1240, 47, 45, + /* 730 */ 44, 43, 42, 573, 2192, 1630, 2228, 566, 565, 112, + /* 740 */ 2194, 706, 2196, 2197, 701, 250, 696, 262, 1560, 2161, + /* 750 */ 1271, 2373, 207, 2281, 2296, 41, 40, 393, 2277, 47, + /* 760 */ 45, 44, 43, 42, 741, 14, 13, 2193, 47, 45, + /* 770 */ 44, 43, 42, 794, 686, 1959, 49, 700, 593, 641, + /* 780 */ 2292, 741, 2013, 160, 159, 738, 737, 736, 157, 48, + /* 790 */ 46, 139, 86, 603, 477, 85, 2012, 397, 2296, 1554, + /* 800 */ 160, 159, 738, 737, 736, 157, 2211, 246, 568, 567, + /* 810 */ 1635, 284, 1552, 1637, 1638, 34, 273, 2161, 249, 702, + /* 820 */ 1744, 41, 40, 596, 2291, 47, 45, 44, 43, 42, + /* 830 */ 590, 1899, 672, 672, 686, 1959, 245, 686, 1959, 1630, + /* 840 */ 293, 294, 1645, 1610, 1620, 292, 1666, 1898, 1579, 1636, + /* 850 */ 1639, 1721, 1560, 2192, 546, 2228, 2212, 1956, 338, 2194, + /* 860 */ 706, 2196, 2197, 701, 1555, 696, 1553, 2247, 1678, 647, + /* 870 */ 642, 635, 609, 471, 686, 1959, 70, 794, 1803, 69, + /* 880 */ 15, 2193, 470, 1698, 670, 681, 2075, 2075, 1525, 1526, + /* 890 */ 1775, 703, 735, 2328, 251, 2004, 1558, 1559, 2357, 1609, + /* 900 */ 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 698, 694, + /* 910 */ 1628, 1629, 1631, 1632, 1633, 1634, 2, 1637, 1638, 626, + /* 920 */ 2211, 2171, 2353, 739, 35, 2171, 2004, 2171, 2161, 406, + /* 930 */ 405, 2161, 380, 702, 1671, 1950, 410, 2359, 188, 2179, + /* 940 */ 1219, 2180, 2354, 652, 1802, 2175, 1578, 1610, 1620, 2175, + /* 950 */ 36, 2175, 1561, 1636, 1639, 1702, 41, 40, 584, 583, + /* 960 */ 47, 45, 44, 43, 42, 686, 1959, 2192, 1555, 2228, + /* 970 */ 1553, 1801, 112, 2194, 706, 2196, 2197, 701, 625, 696, + /* 980 */ 44, 43, 42, 2177, 2373, 259, 2281, 2177, 394, 2177, + /* 990 */ 393, 2277, 1774, 696, 2161, 663, 144, 696, 1611, 696, + /* 1000 */ 1558, 1559, 1858, 1609, 1612, 1613, 1614, 1615, 1616, 1617, + /* 1010 */ 1618, 1619, 698, 694, 1628, 1629, 1631, 1632, 1633, 1634, + /* 1020 */ 2, 2161, 348, 167, 1577, 574, 62, 1800, 323, 686, + /* 1030 */ 1959, 484, 686, 1959, 500, 663, 144, 499, 686, 1959, + /* 1040 */ 765, 763, 320, 73, 686, 1959, 72, 573, 12, 669, + /* 1050 */ 10, 2070, 297, 467, 400, 501, 1824, 345, 683, 688, + /* 1060 */ 469, 2253, 1961, 166, 684, 2311, 1799, 1798, 219, 512, + /* 1070 */ 510, 507, 771, 770, 769, 768, 409, 2161, 767, 766, + /* 1080 */ 148, 761, 760, 759, 758, 757, 756, 755, 162, 751, + /* 1090 */ 750, 749, 408, 407, 746, 745, 744, 176, 175, 187, + /* 1100 */ 2289, 2290, 60, 142, 2294, 1582, 366, 237, 62, 623, + /* 1110 */ 1564, 403, 690, 441, 2253, 440, 2161, 2161, 455, 1961, + /* 1120 */ 166, 1948, 166, 173, 1582, 109, 686, 1959, 1797, 686, + /* 1130 */ 1959, 564, 560, 556, 552, 1796, 236, 1793, 1579, 189, + /* 1140 */ 2289, 2290, 145, 142, 2294, 439, 303, 111, 497, 404, + /* 1150 */ 1951, 491, 490, 489, 488, 483, 482, 481, 480, 479, + /* 1160 */ 475, 474, 473, 472, 347, 464, 463, 462, 667, 457, + /* 1170 */ 456, 364, 1792, 1819, 90, 654, 91, 693, 2161, 234, + /* 1180 */ 1944, 166, 1791, 191, 664, 2161, 1790, 2161, 81, 80, + /* 1190 */ 446, 2193, 1789, 200, 1788, 1787, 1786, 1946, 166, 1785, + /* 1200 */ 1955, 703, 1563, 633, 1942, 166, 438, 436, 1962, 166, + /* 1210 */ 740, 316, 1701, 2004, 1990, 626, 1937, 346, 2353, 2193, + /* 1220 */ 427, 2147, 2161, 425, 421, 417, 414, 439, 74, 703, + /* 1230 */ 2211, 2346, 2161, 2359, 188, 158, 2161, 754, 2354, 652, + /* 1240 */ 1921, 2161, 2161, 702, 2161, 2161, 2161, 233, 227, 2161, + /* 1250 */ 1216, 1217, 2193, 242, 232, 543, 240, 203, 2211, 576, + /* 1260 */ 149, 54, 703, 3, 2300, 191, 2301, 1698, 1562, 2161, + /* 1270 */ 419, 702, 83, 225, 137, 577, 261, 2192, 84, 2228, + /* 1280 */ 2001, 1311, 112, 2194, 706, 2196, 2197, 701, 1611, 696, + /* 1290 */ 151, 2211, 281, 150, 2373, 55, 2281, 1309, 1845, 1836, + /* 1300 */ 393, 2277, 2161, 244, 702, 2192, 243, 2228, 1834, 158, + /* 1310 */ 112, 2194, 706, 2196, 2197, 701, 153, 696, 158, 152, + /* 1320 */ 589, 591, 2373, 606, 2281, 605, 1777, 1778, 393, 2277, + /* 1330 */ 594, 50, 1656, 50, 747, 266, 158, 278, 2192, 50, + /* 1340 */ 2228, 290, 2193, 112, 2194, 706, 2196, 2197, 701, 1, + /* 1350 */ 696, 71, 703, 406, 405, 2373, 1289, 2281, 156, 158, + /* 1360 */ 1566, 393, 2277, 1568, 741, 14, 13, 64, 5, 1520, + /* 1370 */ 2193, 50, 413, 418, 1635, 1828, 1561, 361, 1523, 1585, + /* 1380 */ 703, 2211, 435, 160, 159, 738, 737, 736, 157, 50, + /* 1390 */ 710, 1730, 2161, 1729, 702, 268, 668, 156, 434, 1477, + /* 1400 */ 158, 295, 748, 1630, 108, 195, 196, 138, 437, 2211, + /* 1410 */ 156, 678, 198, 1501, 105, 452, 1560, 310, 299, 1354, + /* 1420 */ 2161, 1578, 702, 209, 1287, 789, 1565, 1672, 2192, 454, + /* 1430 */ 2228, 1621, 2193, 112, 2194, 706, 2196, 2197, 701, 1582, + /* 1440 */ 696, 692, 703, 2071, 458, 2256, 460, 2281, 495, 315, + /* 1450 */ 1383, 393, 2277, 465, 1577, 478, 2192, 1387, 2228, 485, + /* 1460 */ 1394, 112, 2194, 706, 2196, 2197, 701, 1392, 696, 2063, + /* 1470 */ 161, 2211, 505, 2254, 487, 2281, 494, 496, 506, 393, + /* 1480 */ 2277, 503, 2161, 213, 702, 214, 508, 509, 216, 511, + /* 1490 */ 513, 1583, 528, 4, 529, 536, 539, 537, 1580, 2193, + /* 1500 */ 224, 226, 1584, 540, 1586, 541, 544, 542, 569, 703, + /* 1510 */ 229, 548, 571, 1949, 231, 88, 89, 239, 2192, 235, + /* 1520 */ 2228, 114, 351, 112, 2194, 706, 2196, 2197, 701, 608, + /* 1530 */ 696, 92, 1569, 311, 1564, 689, 2135, 2281, 2211, 1945, + /* 1540 */ 154, 393, 2277, 241, 1947, 610, 1943, 252, 614, 2161, + /* 1550 */ 615, 702, 256, 2132, 621, 254, 613, 1508, 676, 2131, + /* 1560 */ 2303, 2193, 618, 640, 1572, 1574, 619, 630, 2327, 636, + /* 1570 */ 2326, 703, 383, 643, 2312, 2322, 264, 694, 1628, 1629, + /* 1580 */ 1631, 1632, 1633, 1634, 620, 2192, 267, 2228, 8, 649, + /* 1590 */ 113, 2194, 706, 2196, 2197, 701, 272, 696, 174, 631, + /* 1600 */ 2211, 628, 384, 629, 2281, 277, 1698, 276, 2280, 2277, + /* 1610 */ 274, 2161, 660, 702, 2376, 657, 1581, 143, 2297, 178, + /* 1620 */ 285, 98, 1587, 312, 2193, 674, 2076, 675, 2090, 2089, + /* 1630 */ 2088, 313, 389, 679, 703, 680, 314, 100, 102, 1960, + /* 1640 */ 275, 61, 104, 2262, 2005, 1922, 317, 2192, 790, 2228, + /* 1650 */ 306, 708, 113, 2194, 706, 2196, 2197, 701, 53, 696, + /* 1660 */ 2153, 791, 341, 2211, 2352, 793, 2281, 280, 319, 321, + /* 1670 */ 691, 2277, 2152, 326, 2161, 340, 702, 353, 354, 330, + /* 1680 */ 2151, 78, 2148, 415, 416, 2193, 1545, 1546, 194, 420, + /* 1690 */ 2146, 422, 423, 424, 2145, 703, 362, 2143, 428, 2193, + /* 1700 */ 2142, 430, 2141, 432, 1536, 2122, 197, 2121, 199, 703, + /* 1710 */ 704, 79, 2228, 1504, 1503, 113, 2194, 706, 2196, 2197, + /* 1720 */ 701, 2103, 696, 2102, 2211, 2101, 2100, 444, 445, 2281, + /* 1730 */ 2099, 1454, 2054, 356, 2277, 2161, 2193, 702, 2211, 2053, + /* 1740 */ 2050, 2049, 201, 82, 2048, 2047, 703, 206, 466, 2161, + /* 1750 */ 2052, 702, 2051, 204, 2046, 2045, 2043, 2042, 2041, 2040, + /* 1760 */ 468, 2056, 2193, 2039, 2038, 2037, 2036, 2035, 2034, 2033, + /* 1770 */ 2032, 2192, 703, 2228, 2031, 2211, 170, 2194, 706, 2196, + /* 1780 */ 2197, 701, 2030, 696, 2029, 2192, 2161, 2228, 702, 2028, + /* 1790 */ 171, 2194, 706, 2196, 2197, 701, 2027, 696, 2026, 2025, + /* 1800 */ 208, 2211, 2024, 2023, 87, 2022, 2021, 2055, 2020, 2019, + /* 1810 */ 1456, 2018, 2161, 2017, 702, 2016, 627, 2318, 498, 2015, + /* 1820 */ 2014, 1864, 2192, 1325, 2228, 349, 2193, 170, 2194, 706, + /* 1830 */ 2196, 2197, 701, 350, 696, 1321, 703, 215, 1329, 1863, + /* 1840 */ 217, 653, 2374, 1862, 1860, 218, 1857, 514, 2192, 1856, + /* 1850 */ 2228, 2193, 518, 113, 2194, 706, 2196, 2197, 701, 515, + /* 1860 */ 696, 703, 516, 519, 520, 2211, 1849, 2281, 2319, 381, + /* 1870 */ 522, 523, 2278, 524, 1838, 526, 2161, 2193, 702, 1814, + /* 1880 */ 220, 76, 1218, 2181, 1813, 182, 77, 703, 2120, 2110, + /* 1890 */ 2211, 222, 183, 2098, 382, 534, 228, 230, 2097, 2074, + /* 1900 */ 1938, 2161, 1263, 702, 1859, 1855, 549, 550, 551, 1853, + /* 1910 */ 553, 554, 2192, 1851, 2228, 555, 2211, 339, 2194, 706, + /* 1920 */ 2196, 2197, 701, 1848, 696, 557, 558, 2161, 1833, 702, + /* 1930 */ 559, 561, 562, 563, 1831, 1832, 1830, 2192, 1810, 2228, + /* 1940 */ 1940, 63, 339, 2194, 706, 2196, 2197, 701, 1398, 696, + /* 1950 */ 2193, 1399, 1939, 1312, 1310, 1308, 1307, 1306, 762, 1305, + /* 1960 */ 703, 764, 1304, 2192, 238, 2228, 2193, 612, 332, 2194, + /* 1970 */ 706, 2196, 2197, 701, 1301, 696, 703, 1300, 1299, 1298, + /* 1980 */ 1846, 374, 1837, 375, 592, 797, 376, 1809, 595, 2211, + /* 1990 */ 1835, 1808, 597, 599, 1807, 601, 115, 1530, 1532, 309, + /* 2000 */ 2161, 1534, 702, 1529, 29, 2211, 2119, 1510, 2109, 388, + /* 2010 */ 67, 648, 164, 2096, 1512, 180, 2161, 616, 702, 2095, + /* 2020 */ 2358, 20, 57, 787, 783, 779, 775, 2193, 307, 1514, + /* 2030 */ 257, 617, 1489, 622, 31, 1488, 2192, 703, 2228, 624, + /* 2040 */ 17, 171, 2194, 706, 2196, 2197, 701, 1747, 696, 263, + /* 2050 */ 6, 632, 2192, 7, 2228, 265, 21, 339, 2194, 706, + /* 2060 */ 2196, 2197, 701, 172, 696, 22, 2211, 270, 110, 634, + /* 2070 */ 396, 300, 271, 1728, 269, 2182, 33, 2161, 32, 702, + /* 2080 */ 65, 1762, 1720, 1767, 95, 24, 1761, 1768, 2193, 385, + /* 2090 */ 23, 18, 1766, 2375, 1765, 386, 283, 1695, 703, 59, + /* 2100 */ 1694, 2094, 2073, 177, 682, 97, 96, 25, 288, 2072, + /* 2110 */ 291, 58, 296, 2192, 2193, 2228, 677, 68, 339, 2194, + /* 2120 */ 706, 2196, 2197, 701, 703, 696, 289, 2211, 1726, 99, + /* 2130 */ 101, 398, 301, 105, 1647, 26, 1646, 11, 2161, 287, + /* 2140 */ 702, 13, 1570, 2231, 179, 695, 286, 298, 1657, 1625, + /* 2150 */ 192, 1623, 1622, 2211, 1594, 39, 16, 1602, 707, 709, + /* 2160 */ 399, 27, 705, 713, 2161, 253, 702, 28, 716, 1384, + /* 2170 */ 711, 719, 1381, 714, 2192, 1380, 2228, 717, 2193, 339, + /* 2180 */ 2194, 706, 2196, 2197, 701, 1377, 696, 720, 703, 722, + /* 2190 */ 1371, 723, 725, 2193, 1360, 1375, 1369, 726, 1374, 1373, + /* 2200 */ 607, 1372, 2228, 703, 732, 334, 2194, 706, 2196, 2197, + /* 2210 */ 701, 2193, 696, 106, 304, 107, 1393, 2211, 75, 1389, + /* 2220 */ 1261, 703, 1293, 742, 1292, 1291, 1290, 1288, 2161, 1286, + /* 2230 */ 702, 1285, 2211, 1284, 1319, 752, 1282, 305, 1281, 1280, + /* 2240 */ 1279, 1278, 1277, 2161, 1276, 702, 1316, 1314, 1273, 1272, + /* 2250 */ 2211, 1269, 1268, 1267, 1266, 1854, 772, 773, 1852, 774, + /* 2260 */ 776, 2161, 778, 702, 2192, 1850, 2228, 780, 782, 324, + /* 2270 */ 2194, 706, 2196, 2197, 701, 777, 696, 781, 1847, 2192, + /* 2280 */ 784, 2228, 785, 1829, 322, 2194, 706, 2196, 2197, 701, + /* 2290 */ 786, 696, 788, 1806, 1208, 308, 792, 2192, 1556, 2228, + /* 2300 */ 796, 318, 325, 2194, 706, 2196, 2197, 701, 2193, 696, + /* 2310 */ 795, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 703, 1781, + /* 2320 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 2193, 1781, 1781, + /* 2330 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 703, 1781, 1781, + /* 2340 */ 1781, 2193, 1781, 1781, 1781, 1781, 1781, 2211, 1781, 1781, + /* 2350 */ 1781, 703, 1781, 1781, 1781, 1781, 1781, 1781, 2161, 1781, + /* 2360 */ 702, 1781, 1781, 1781, 1781, 1781, 2211, 1781, 1781, 1781, + /* 2370 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 2161, 2193, 702, + /* 2380 */ 2211, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 703, 1781, + /* 2390 */ 1781, 2161, 1781, 702, 2192, 1781, 2228, 1781, 1781, 331, + /* 2400 */ 2194, 706, 2196, 2197, 701, 1781, 696, 1781, 1781, 1781, + /* 2410 */ 1781, 1781, 1781, 2192, 1781, 2228, 1781, 2211, 335, 2194, + /* 2420 */ 706, 2196, 2197, 701, 1781, 696, 1781, 2192, 2161, 2228, + /* 2430 */ 702, 1781, 327, 2194, 706, 2196, 2197, 701, 1781, 696, + /* 2440 */ 2193, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2450 */ 703, 1781, 1781, 1781, 1781, 2193, 1781, 1781, 1781, 1781, + /* 2460 */ 1781, 1781, 1781, 1781, 2192, 703, 2228, 1781, 1781, 336, + /* 2470 */ 2194, 706, 2196, 2197, 701, 1781, 696, 1781, 1781, 2211, + /* 2480 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2490 */ 2161, 1781, 702, 1781, 2211, 1781, 1781, 1781, 1781, 1781, + /* 2500 */ 1781, 1781, 1781, 1781, 1781, 2161, 2193, 702, 1781, 1781, + /* 2510 */ 1781, 1781, 1781, 1781, 1781, 1781, 703, 1781, 1781, 1781, + /* 2520 */ 2193, 1781, 1781, 1781, 1781, 1781, 2192, 1781, 2228, 1781, + /* 2530 */ 703, 328, 2194, 706, 2196, 2197, 701, 1781, 696, 1781, + /* 2540 */ 1781, 2192, 1781, 2228, 1781, 2211, 337, 2194, 706, 2196, + /* 2550 */ 2197, 701, 1781, 696, 1781, 1781, 2161, 1781, 702, 2211, + /* 2560 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2570 */ 2161, 1781, 702, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2580 */ 1781, 1781, 1781, 1781, 1781, 2193, 1781, 1781, 1781, 1781, + /* 2590 */ 1781, 1781, 2192, 1781, 2228, 703, 1781, 329, 2194, 706, + /* 2600 */ 2196, 2197, 701, 1781, 696, 1781, 2192, 1781, 2228, 1781, + /* 2610 */ 1781, 342, 2194, 706, 2196, 2197, 701, 1781, 696, 1781, + /* 2620 */ 1781, 1781, 1781, 1781, 2211, 1781, 1781, 1781, 1781, 1781, + /* 2630 */ 1781, 1781, 1781, 1781, 1781, 2161, 1781, 702, 1781, 1781, + /* 2640 */ 1781, 1781, 1781, 1781, 1781, 2193, 1781, 1781, 1781, 1781, + /* 2650 */ 1781, 1781, 1781, 1781, 1781, 703, 1781, 1781, 1781, 1781, + /* 2660 */ 2193, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2670 */ 703, 2192, 1781, 2228, 1781, 1781, 343, 2194, 706, 2196, + /* 2680 */ 2197, 701, 1781, 696, 2211, 1781, 1781, 1781, 1781, 1781, + /* 2690 */ 1781, 1781, 1781, 1781, 1781, 2161, 1781, 702, 1781, 2211, + /* 2700 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2710 */ 2161, 1781, 702, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2720 */ 2193, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2730 */ 703, 2192, 1781, 2228, 1781, 2193, 2205, 2194, 706, 2196, + /* 2740 */ 2197, 701, 1781, 696, 1781, 703, 2192, 1781, 2228, 1781, + /* 2750 */ 1781, 2204, 2194, 706, 2196, 2197, 701, 2193, 696, 2211, + /* 2760 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 703, 1781, 1781, + /* 2770 */ 2161, 1781, 702, 1781, 2211, 1781, 1781, 1781, 1781, 1781, + /* 2780 */ 1781, 1781, 1781, 1781, 1781, 2161, 1781, 702, 1781, 1781, + /* 2790 */ 1781, 1781, 1781, 1781, 1781, 1781, 2211, 1781, 1781, 1781, + /* 2800 */ 1781, 1781, 1781, 1781, 1781, 1781, 2192, 2161, 2228, 702, + /* 2810 */ 1781, 2203, 2194, 706, 2196, 2197, 701, 1781, 696, 1781, + /* 2820 */ 1781, 2192, 1781, 2228, 1781, 1781, 358, 2194, 706, 2196, + /* 2830 */ 2197, 701, 2193, 696, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2840 */ 1781, 1781, 703, 2192, 1781, 2228, 1781, 2193, 359, 2194, + /* 2850 */ 706, 2196, 2197, 701, 1781, 696, 1781, 703, 1781, 1781, + /* 2860 */ 1781, 1781, 2193, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2870 */ 1781, 2211, 703, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2880 */ 1781, 1781, 2161, 1781, 702, 1781, 2211, 1781, 1781, 1781, + /* 2890 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 2161, 1781, 702, + /* 2900 */ 1781, 2211, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2910 */ 1781, 1781, 2161, 1781, 702, 1781, 1781, 1781, 2192, 1781, + /* 2920 */ 2228, 1781, 1781, 355, 2194, 706, 2196, 2197, 701, 1781, + /* 2930 */ 696, 1781, 1781, 2192, 2193, 2228, 1781, 1781, 360, 2194, + /* 2940 */ 706, 2196, 2197, 701, 703, 696, 1781, 1781, 704, 1781, + /* 2950 */ 2228, 1781, 1781, 334, 2194, 706, 2196, 2197, 701, 1781, + /* 2960 */ 696, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2970 */ 1781, 1781, 1781, 2211, 1781, 1781, 1781, 1781, 1781, 1781, + /* 2980 */ 1781, 1781, 1781, 1781, 2161, 1781, 702, 1781, 1781, 1781, + /* 2990 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 3000 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 3010 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + /* 3020 */ 2192, 1781, 2228, 1781, 1781, 333, 2194, 706, 2196, 2197, + /* 3030 */ 701, 1781, 696, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 380, 341, 367, 393, 346, 350, 351, 411, 350, 378, - /* 10 */ 352, 351, 12, 13, 14, 405, 381, 4, 408, 409, - /* 20 */ 20, 390, 22, 8, 9, 370, 391, 12, 13, 14, - /* 30 */ 15, 16, 377, 33, 350, 35, 367, 14, 20, 379, - /* 40 */ 8, 9, 338, 20, 12, 13, 14, 15, 16, 20, - /* 50 */ 381, 391, 380, 393, 458, 49, 43, 461, 45, 46, - /* 60 */ 391, 379, 62, 57, 429, 430, 60, 61, 68, 20, - /* 70 */ 4, 22, 476, 477, 439, 75, 44, 481, 482, 395, - /* 80 */ 360, 399, 400, 68, 35, 350, 351, 427, 368, 429, - /* 90 */ 350, 351, 432, 433, 434, 435, 436, 437, 429, 439, - /* 100 */ 100, 0, 53, 103, 444, 370, 446, 340, 439, 342, - /* 110 */ 450, 451, 377, 20, 393, 411, 12, 13, 379, 458, - /* 120 */ 416, 103, 461, 463, 20, 386, 22, 112, 100, 408, - /* 130 */ 409, 471, 103, 394, 350, 351, 104, 33, 477, 35, - /* 140 */ 140, 141, 481, 482, 116, 117, 118, 119, 120, 121, - /* 150 */ 122, 123, 124, 125, 370, 127, 128, 129, 130, 131, - /* 160 */ 132, 133, 458, 20, 458, 461, 62, 461, 67, 103, - /* 170 */ 170, 171, 68, 350, 351, 357, 176, 177, 20, 75, - /* 180 */ 476, 477, 476, 477, 169, 481, 482, 481, 482, 447, - /* 190 */ 448, 191, 374, 193, 454, 455, 456, 3, 458, 459, - /* 200 */ 382, 461, 1, 2, 100, 8, 9, 103, 341, 12, - /* 210 */ 13, 14, 15, 16, 20, 20, 476, 477, 351, 35, - /* 220 */ 397, 481, 482, 223, 224, 0, 226, 227, 228, 229, + /* 0 */ 411, 341, 346, 380, 350, 416, 350, 411, 352, 386, + /* 10 */ 393, 351, 12, 13, 14, 458, 387, 394, 461, 351, + /* 20 */ 20, 380, 22, 8, 9, 408, 409, 12, 13, 14, + /* 30 */ 15, 16, 387, 33, 477, 35, 20, 371, 481, 482, + /* 40 */ 380, 400, 338, 393, 20, 379, 380, 458, 380, 395, + /* 50 */ 461, 391, 386, 393, 458, 405, 20, 461, 408, 409, + /* 60 */ 394, 458, 62, 346, 461, 476, 477, 350, 68, 352, + /* 70 */ 481, 482, 476, 477, 20, 75, 22, 481, 482, 476, + /* 80 */ 477, 350, 351, 68, 481, 482, 20, 427, 359, 429, + /* 90 */ 350, 351, 432, 433, 434, 435, 436, 437, 47, 439, + /* 100 */ 100, 370, 434, 103, 444, 376, 446, 53, 377, 345, + /* 110 */ 450, 451, 348, 349, 385, 411, 12, 13, 341, 103, + /* 120 */ 416, 49, 22, 463, 20, 44, 22, 112, 100, 57, + /* 130 */ 62, 471, 60, 61, 20, 35, 20, 33, 350, 35, + /* 140 */ 140, 141, 350, 351, 116, 117, 118, 119, 120, 121, + /* 150 */ 122, 123, 124, 125, 103, 127, 128, 129, 130, 131, + /* 160 */ 132, 133, 458, 67, 458, 461, 62, 461, 391, 103, + /* 170 */ 170, 171, 68, 105, 4, 75, 176, 177, 0, 75, + /* 180 */ 476, 477, 20, 477, 169, 481, 482, 481, 482, 397, + /* 190 */ 402, 191, 404, 193, 454, 455, 456, 3, 458, 459, + /* 200 */ 100, 461, 447, 448, 100, 8, 9, 103, 341, 12, + /* 210 */ 13, 14, 15, 16, 20, 67, 476, 477, 351, 103, + /* 220 */ 114, 481, 482, 223, 224, 0, 226, 227, 228, 229, /* 230 */ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - /* 240 */ 240, 241, 242, 243, 140, 141, 379, 392, 393, 24, - /* 250 */ 25, 26, 27, 28, 29, 30, 31, 32, 391, 75, - /* 260 */ 393, 0, 247, 248, 249, 250, 251, 252, 253, 254, - /* 270 */ 255, 256, 257, 345, 170, 171, 348, 349, 260, 20, - /* 280 */ 176, 177, 21, 140, 141, 24, 25, 26, 27, 28, - /* 290 */ 29, 30, 31, 32, 427, 191, 429, 193, 104, 432, - /* 300 */ 433, 434, 435, 436, 437, 104, 439, 0, 371, 442, - /* 310 */ 67, 444, 445, 446, 20, 341, 379, 450, 451, 176, - /* 320 */ 177, 341, 350, 351, 387, 351, 260, 223, 224, 20, + /* 240 */ 240, 241, 242, 243, 140, 141, 21, 380, 244, 24, + /* 250 */ 25, 26, 27, 28, 29, 30, 31, 32, 391, 340, + /* 260 */ 393, 342, 247, 248, 249, 250, 251, 252, 253, 254, + /* 270 */ 255, 256, 257, 103, 170, 171, 260, 20, 75, 21, + /* 280 */ 176, 177, 24, 25, 26, 27, 28, 29, 30, 31, + /* 290 */ 32, 191, 21, 193, 427, 191, 429, 193, 104, 432, + /* 300 */ 433, 434, 435, 436, 437, 34, 439, 36, 380, 442, + /* 310 */ 114, 444, 445, 446, 386, 341, 345, 450, 451, 348, + /* 320 */ 349, 360, 394, 223, 224, 351, 260, 223, 224, 368, /* 330 */ 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* 340 */ 236, 237, 238, 239, 240, 241, 242, 243, 244, 12, - /* 350 */ 13, 20, 341, 379, 379, 12, 13, 20, 103, 22, - /* 360 */ 458, 386, 103, 461, 431, 391, 172, 393, 113, 394, - /* 370 */ 33, 391, 35, 70, 71, 72, 350, 351, 35, 477, - /* 380 */ 77, 78, 79, 481, 482, 345, 83, 351, 348, 349, - /* 390 */ 457, 88, 89, 90, 91, 375, 370, 94, 114, 62, - /* 400 */ 135, 427, 391, 429, 139, 68, 432, 433, 434, 435, - /* 410 */ 436, 437, 75, 439, 134, 379, 134, 135, 444, 389, - /* 420 */ 446, 139, 392, 393, 450, 451, 454, 455, 456, 341, - /* 430 */ 458, 459, 341, 458, 140, 141, 461, 100, 115, 351, - /* 440 */ 103, 353, 8, 9, 424, 471, 12, 13, 14, 15, - /* 450 */ 16, 476, 477, 12, 13, 14, 481, 482, 346, 341, - /* 460 */ 137, 20, 350, 22, 352, 200, 159, 379, 203, 351, - /* 470 */ 434, 206, 431, 208, 33, 168, 35, 140, 141, 391, - /* 480 */ 357, 393, 391, 21, 204, 205, 24, 25, 26, 27, - /* 490 */ 28, 29, 30, 31, 32, 244, 103, 379, 457, 350, - /* 500 */ 351, 170, 171, 62, 350, 382, 14, 170, 171, 391, - /* 510 */ 371, 393, 20, 176, 177, 427, 75, 429, 379, 260, - /* 520 */ 432, 433, 434, 435, 436, 437, 387, 439, 191, 75, - /* 530 */ 193, 103, 444, 21, 446, 244, 193, 246, 450, 451, - /* 540 */ 67, 100, 350, 351, 103, 427, 34, 429, 36, 341, - /* 550 */ 432, 433, 434, 435, 436, 437, 402, 439, 404, 351, + /* 350 */ 13, 350, 351, 103, 380, 380, 75, 20, 14, 22, + /* 360 */ 84, 386, 20, 282, 20, 391, 172, 393, 380, 394, + /* 370 */ 33, 370, 35, 70, 71, 72, 350, 351, 377, 357, + /* 380 */ 77, 78, 79, 20, 44, 22, 83, 399, 400, 103, + /* 390 */ 378, 88, 89, 90, 91, 217, 370, 94, 35, 62, + /* 400 */ 431, 427, 390, 429, 382, 68, 432, 433, 434, 435, + /* 410 */ 436, 437, 75, 439, 350, 351, 53, 387, 444, 22, + /* 420 */ 446, 145, 146, 4, 450, 451, 457, 170, 171, 341, + /* 430 */ 260, 135, 35, 458, 370, 139, 461, 100, 0, 351, + /* 440 */ 103, 353, 8, 9, 168, 471, 12, 13, 14, 15, + /* 450 */ 16, 476, 477, 12, 13, 14, 481, 482, 417, 341, + /* 460 */ 0, 20, 43, 22, 45, 46, 380, 389, 380, 351, + /* 470 */ 392, 393, 386, 186, 33, 368, 35, 140, 141, 391, + /* 480 */ 394, 393, 140, 141, 24, 25, 26, 27, 28, 29, + /* 490 */ 30, 31, 32, 350, 351, 20, 200, 100, 380, 203, + /* 500 */ 213, 214, 206, 62, 208, 67, 14, 170, 171, 391, + /* 510 */ 260, 393, 20, 176, 177, 427, 75, 429, 176, 177, + /* 520 */ 432, 433, 434, 435, 436, 437, 442, 439, 191, 445, + /* 530 */ 193, 0, 444, 342, 446, 350, 351, 401, 450, 451, + /* 540 */ 397, 100, 350, 351, 103, 427, 260, 429, 392, 393, + /* 550 */ 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, /* 560 */ 223, 224, 370, 226, 227, 228, 229, 230, 231, 232, /* 570 */ 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - /* 580 */ 243, 140, 141, 190, 20, 192, 341, 379, 8, 9, - /* 590 */ 472, 473, 12, 13, 14, 15, 16, 114, 341, 391, - /* 600 */ 20, 393, 453, 454, 455, 456, 172, 458, 459, 379, - /* 610 */ 0, 170, 171, 350, 351, 222, 386, 176, 177, 350, - /* 620 */ 351, 8, 9, 371, 394, 12, 13, 14, 15, 16, - /* 630 */ 431, 379, 191, 370, 193, 427, 391, 429, 386, 387, - /* 640 */ 432, 433, 434, 435, 436, 437, 394, 439, 391, 47, - /* 650 */ 411, 341, 444, 260, 446, 416, 457, 411, 450, 451, - /* 660 */ 50, 351, 170, 353, 223, 224, 397, 226, 227, 228, + /* 580 */ 243, 140, 141, 8, 9, 350, 351, 12, 13, 14, + /* 590 */ 15, 16, 8, 9, 22, 20, 12, 13, 14, 15, + /* 600 */ 16, 70, 71, 72, 223, 370, 172, 35, 77, 78, + /* 610 */ 79, 170, 171, 22, 83, 140, 141, 176, 177, 88, + /* 620 */ 89, 90, 91, 380, 284, 94, 35, 371, 44, 386, + /* 630 */ 350, 351, 191, 37, 193, 379, 380, 394, 453, 454, + /* 640 */ 455, 456, 485, 458, 459, 350, 351, 411, 341, 0, + /* 650 */ 370, 270, 271, 272, 273, 274, 275, 276, 351, 20, + /* 660 */ 353, 35, 170, 39, 223, 224, 0, 226, 227, 228, /* 670 */ 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - /* 680 */ 239, 240, 241, 242, 243, 12, 13, 0, 260, 379, - /* 690 */ 115, 350, 351, 20, 75, 22, 175, 458, 350, 351, - /* 700 */ 461, 391, 186, 393, 458, 103, 33, 461, 35, 134, - /* 710 */ 135, 136, 137, 138, 139, 476, 477, 443, 370, 445, - /* 720 */ 481, 482, 476, 477, 14, 15, 16, 481, 482, 213, - /* 730 */ 214, 223, 84, 350, 351, 62, 172, 427, 397, 429, - /* 740 */ 4, 380, 432, 433, 434, 435, 436, 437, 75, 439, - /* 750 */ 350, 351, 172, 370, 444, 19, 446, 0, 8, 9, - /* 760 */ 450, 451, 12, 13, 14, 15, 16, 341, 14, 33, - /* 770 */ 370, 350, 351, 100, 20, 62, 103, 351, 270, 271, - /* 780 */ 272, 273, 274, 275, 276, 49, 265, 266, 267, 12, - /* 790 */ 13, 370, 56, 145, 146, 371, 183, 20, 62, 22, - /* 800 */ 350, 351, 115, 379, 103, 379, 0, 341, 355, 356, - /* 810 */ 33, 387, 35, 140, 141, 102, 168, 391, 105, 393, - /* 820 */ 370, 134, 135, 136, 137, 138, 139, 70, 71, 72, - /* 830 */ 350, 351, 48, 417, 77, 78, 79, 20, 102, 62, - /* 840 */ 83, 105, 368, 170, 171, 88, 89, 90, 91, 176, - /* 850 */ 177, 94, 75, 427, 104, 429, 380, 391, 432, 433, - /* 860 */ 434, 435, 436, 437, 191, 439, 193, 441, 8, 9, - /* 870 */ 350, 351, 12, 13, 14, 15, 16, 100, 341, 380, - /* 880 */ 103, 341, 12, 13, 14, 15, 16, 54, 55, 14, - /* 890 */ 370, 351, 20, 353, 22, 20, 223, 224, 285, 226, + /* 680 */ 239, 240, 241, 242, 243, 12, 13, 380, 104, 350, + /* 690 */ 351, 100, 397, 20, 458, 22, 375, 461, 391, 341, + /* 700 */ 393, 75, 106, 474, 108, 109, 33, 111, 35, 370, + /* 710 */ 35, 115, 476, 477, 0, 8, 9, 481, 482, 12, + /* 720 */ 13, 14, 15, 16, 8, 9, 54, 55, 12, 13, + /* 730 */ 14, 15, 16, 137, 427, 62, 429, 355, 356, 432, + /* 740 */ 433, 434, 435, 436, 437, 424, 439, 172, 75, 391, + /* 750 */ 75, 444, 62, 446, 431, 8, 9, 450, 451, 12, + /* 760 */ 13, 14, 15, 16, 115, 1, 2, 341, 12, 13, + /* 770 */ 14, 15, 16, 100, 350, 351, 103, 351, 4, 175, + /* 780 */ 457, 115, 380, 134, 135, 136, 137, 138, 139, 12, + /* 790 */ 13, 354, 102, 19, 370, 105, 394, 20, 431, 22, + /* 800 */ 134, 135, 136, 137, 138, 139, 380, 33, 355, 356, + /* 810 */ 33, 172, 35, 140, 141, 2, 468, 391, 134, 393, + /* 820 */ 104, 8, 9, 49, 457, 12, 13, 14, 15, 16, + /* 830 */ 56, 367, 350, 350, 350, 351, 62, 350, 351, 62, + /* 840 */ 134, 135, 14, 170, 171, 139, 169, 367, 20, 176, + /* 850 */ 177, 104, 75, 427, 370, 429, 380, 370, 432, 433, + /* 860 */ 434, 435, 436, 437, 191, 439, 193, 441, 104, 265, + /* 870 */ 266, 267, 411, 159, 350, 351, 102, 100, 341, 105, + /* 880 */ 103, 341, 168, 259, 402, 402, 404, 404, 204, 205, + /* 890 */ 183, 351, 388, 353, 370, 391, 223, 224, 3, 226, /* 900 */ 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - /* 910 */ 237, 238, 239, 240, 241, 242, 243, 140, 141, 379, - /* 920 */ 359, 115, 355, 356, 170, 53, 350, 3, 391, 350, - /* 930 */ 351, 391, 380, 393, 454, 455, 456, 376, 458, 459, - /* 940 */ 134, 135, 136, 137, 138, 139, 385, 170, 171, 370, - /* 950 */ 380, 350, 351, 176, 177, 401, 172, 364, 365, 4, - /* 960 */ 379, 260, 169, 179, 104, 350, 351, 427, 191, 429, - /* 970 */ 193, 370, 432, 433, 434, 435, 436, 437, 402, 439, - /* 980 */ 404, 400, 2, 341, 444, 370, 446, 170, 8, 9, - /* 990 */ 450, 451, 12, 13, 14, 15, 16, 350, 364, 365, + /* 910 */ 237, 238, 239, 240, 241, 242, 243, 140, 141, 458, + /* 920 */ 380, 367, 461, 388, 247, 367, 391, 367, 391, 12, + /* 930 */ 13, 391, 410, 393, 257, 381, 354, 476, 477, 381, + /* 940 */ 14, 381, 481, 482, 341, 391, 20, 170, 171, 391, + /* 950 */ 2, 391, 35, 176, 177, 4, 8, 9, 364, 365, + /* 960 */ 12, 13, 14, 15, 16, 350, 351, 427, 191, 429, + /* 970 */ 193, 341, 432, 433, 434, 435, 436, 437, 48, 439, + /* 980 */ 14, 15, 16, 429, 444, 370, 446, 429, 430, 429, + /* 990 */ 450, 451, 285, 439, 391, 350, 351, 439, 170, 439, /* 1000 */ 223, 224, 0, 226, 227, 228, 229, 230, 231, 232, /* 1010 */ 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - /* 1020 */ 243, 0, 18, 18, 20, 350, 351, 341, 23, 39, - /* 1030 */ 443, 27, 445, 391, 30, 359, 442, 33, 367, 445, - /* 1040 */ 247, 388, 37, 38, 391, 370, 41, 350, 351, 402, - /* 1050 */ 257, 404, 381, 49, 411, 51, 379, 52, 20, 20, - /* 1060 */ 56, 385, 391, 341, 387, 341, 341, 370, 63, 64, + /* 1020 */ 243, 391, 18, 18, 20, 115, 103, 341, 23, 350, + /* 1030 */ 351, 27, 350, 351, 30, 350, 351, 33, 350, 351, + /* 1040 */ 364, 365, 37, 38, 350, 351, 41, 137, 244, 370, + /* 1050 */ 246, 401, 370, 49, 371, 51, 351, 52, 370, 443, + /* 1060 */ 56, 445, 379, 380, 370, 401, 341, 341, 63, 64, /* 1070 */ 65, 66, 70, 71, 72, 73, 74, 391, 76, 77, /* 1080 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - /* 1090 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 22, - /* 1100 */ 429, 458, 350, 351, 461, 13, 102, 33, 103, 37, - /* 1110 */ 439, 379, 35, 391, 379, 391, 391, 22, 114, 476, - /* 1120 */ 477, 386, 370, 49, 481, 482, 394, 35, 379, 394, - /* 1130 */ 35, 57, 58, 59, 60, 386, 62, 372, 366, 388, - /* 1140 */ 375, 369, 391, 394, 341, 44, 341, 142, 144, 341, - /* 1150 */ 44, 147, 148, 149, 150, 151, 152, 153, 154, 155, - /* 1160 */ 156, 157, 158, 159, 160, 161, 162, 163, 341, 165, - /* 1170 */ 166, 167, 350, 351, 45, 46, 102, 100, 106, 105, - /* 1180 */ 108, 109, 42, 111, 44, 341, 341, 115, 183, 184, - /* 1190 */ 185, 341, 370, 188, 391, 100, 391, 258, 259, 391, - /* 1200 */ 341, 351, 388, 353, 280, 391, 201, 202, 0, 137, - /* 1210 */ 172, 172, 42, 114, 44, 44, 261, 212, 391, 207, - /* 1220 */ 215, 209, 341, 218, 219, 220, 221, 222, 44, 379, - /* 1230 */ 107, 22, 351, 110, 353, 391, 391, 0, 217, 107, - /* 1240 */ 68, 391, 110, 393, 35, 13, 0, 173, 174, 259, - /* 1250 */ 391, 342, 341, 35, 180, 181, 107, 49, 0, 110, - /* 1260 */ 379, 44, 351, 164, 353, 260, 107, 35, 22, 110, - /* 1270 */ 0, 35, 391, 199, 393, 104, 62, 427, 474, 429, - /* 1280 */ 22, 44, 432, 433, 434, 435, 436, 437, 104, 439, - /* 1290 */ 379, 44, 22, 75, 444, 35, 446, 140, 141, 44, - /* 1300 */ 450, 451, 391, 485, 393, 354, 44, 44, 427, 468, - /* 1310 */ 429, 367, 367, 432, 433, 434, 435, 436, 437, 105, - /* 1320 */ 439, 104, 44, 410, 22, 444, 44, 446, 379, 44, - /* 1330 */ 44, 450, 451, 44, 1, 2, 44, 35, 427, 44, - /* 1340 */ 429, 354, 341, 432, 433, 434, 435, 436, 437, 44, - /* 1350 */ 439, 104, 351, 12, 13, 444, 13, 446, 2, 104, - /* 1360 */ 401, 450, 451, 22, 8, 9, 104, 104, 12, 13, - /* 1370 */ 14, 15, 16, 341, 33, 349, 35, 75, 35, 44, - /* 1380 */ 379, 351, 104, 351, 44, 284, 104, 390, 282, 104, - /* 1390 */ 104, 13, 391, 104, 393, 223, 104, 44, 44, 104, - /* 1400 */ 401, 460, 100, 62, 478, 452, 262, 412, 462, 104, - /* 1410 */ 341, 379, 44, 35, 49, 20, 75, 428, 206, 421, - /* 1420 */ 351, 359, 426, 391, 421, 393, 359, 189, 427, 193, - /* 1430 */ 429, 414, 351, 432, 433, 434, 435, 436, 437, 104, - /* 1440 */ 439, 100, 20, 42, 104, 444, 398, 446, 379, 20, - /* 1450 */ 401, 450, 451, 193, 351, 398, 169, 104, 104, 427, - /* 1460 */ 391, 429, 393, 20, 432, 433, 434, 435, 436, 437, - /* 1470 */ 350, 439, 104, 351, 396, 350, 444, 398, 446, 396, - /* 1480 */ 396, 101, 450, 451, 363, 99, 362, 350, 98, 361, - /* 1490 */ 20, 411, 350, 191, 343, 193, 427, 350, 429, 341, - /* 1500 */ 350, 432, 433, 434, 435, 436, 437, 48, 439, 351, - /* 1510 */ 347, 343, 347, 359, 421, 446, 20, 20, 352, 450, - /* 1520 */ 451, 359, 20, 393, 413, 223, 224, 352, 359, 350, - /* 1530 */ 343, 379, 191, 359, 193, 359, 359, 379, 458, 359, - /* 1540 */ 379, 461, 343, 379, 350, 103, 379, 391, 341, 391, - /* 1550 */ 423, 393, 379, 357, 210, 197, 476, 477, 351, 425, - /* 1560 */ 379, 481, 482, 420, 223, 224, 421, 379, 379, 379, - /* 1570 */ 379, 379, 196, 391, 341, 350, 391, 236, 237, 238, - /* 1580 */ 239, 240, 241, 242, 351, 427, 379, 429, 393, 195, - /* 1590 */ 432, 433, 434, 435, 436, 437, 357, 439, 391, 269, - /* 1600 */ 393, 401, 419, 401, 446, 467, 391, 268, 450, 451, - /* 1610 */ 412, 418, 379, 391, 391, 467, 406, 406, 391, 277, - /* 1620 */ 182, 486, 467, 470, 391, 341, 393, 279, 278, 469, - /* 1630 */ 263, 412, 283, 286, 427, 351, 429, 20, 341, 432, - /* 1640 */ 433, 434, 435, 436, 437, 281, 439, 259, 351, 351, - /* 1650 */ 357, 431, 466, 446, 20, 352, 357, 450, 451, 406, - /* 1660 */ 427, 464, 429, 379, 391, 432, 433, 434, 435, 436, - /* 1670 */ 437, 438, 439, 440, 441, 391, 379, 393, 465, 404, - /* 1680 */ 406, 480, 479, 174, 403, 391, 357, 341, 391, 375, - /* 1690 */ 393, 391, 391, 357, 103, 391, 351, 351, 391, 449, - /* 1700 */ 103, 383, 391, 369, 341, 350, 36, 0, 357, 339, - /* 1710 */ 344, 427, 343, 429, 351, 407, 432, 433, 434, 435, - /* 1720 */ 436, 437, 407, 439, 427, 379, 429, 415, 422, 432, - /* 1730 */ 433, 434, 435, 436, 437, 373, 439, 391, 0, 393, - /* 1740 */ 358, 0, 379, 446, 373, 373, 42, 384, 451, 0, - /* 1750 */ 35, 216, 35, 341, 391, 35, 393, 35, 216, 0, - /* 1760 */ 35, 35, 216, 351, 0, 216, 0, 483, 484, 35, - /* 1770 */ 0, 0, 22, 427, 35, 429, 211, 341, 432, 433, - /* 1780 */ 434, 435, 436, 437, 0, 439, 199, 351, 0, 199, - /* 1790 */ 427, 379, 429, 200, 193, 432, 433, 434, 435, 436, - /* 1800 */ 437, 191, 439, 391, 341, 393, 0, 0, 0, 187, - /* 1810 */ 186, 0, 0, 0, 351, 379, 47, 0, 0, 473, - /* 1820 */ 384, 47, 0, 42, 341, 0, 0, 391, 0, 393, - /* 1830 */ 47, 0, 0, 0, 351, 0, 0, 0, 159, 427, - /* 1840 */ 35, 429, 379, 0, 432, 433, 434, 435, 436, 437, - /* 1850 */ 159, 439, 0, 0, 391, 0, 393, 0, 0, 0, - /* 1860 */ 0, 0, 379, 427, 0, 429, 0, 384, 432, 433, - /* 1870 */ 434, 435, 436, 437, 391, 439, 393, 47, 0, 0, - /* 1880 */ 42, 0, 0, 0, 0, 0, 62, 475, 0, 0, - /* 1890 */ 427, 341, 429, 0, 0, 432, 433, 434, 435, 436, - /* 1900 */ 437, 351, 439, 0, 0, 0, 0, 0, 22, 0, - /* 1910 */ 427, 143, 429, 0, 22, 432, 433, 434, 435, 436, - /* 1920 */ 437, 341, 439, 48, 48, 0, 35, 0, 0, 379, - /* 1930 */ 22, 351, 62, 62, 384, 0, 0, 39, 0, 49, - /* 1940 */ 39, 391, 0, 393, 49, 35, 35, 484, 49, 35, - /* 1950 */ 0, 39, 35, 0, 14, 39, 0, 42, 0, 379, - /* 1960 */ 0, 39, 44, 40, 384, 0, 47, 47, 47, 39, - /* 1970 */ 0, 391, 182, 393, 35, 49, 39, 427, 0, 429, - /* 1980 */ 341, 0, 432, 433, 434, 435, 436, 437, 1, 439, - /* 1990 */ 351, 0, 0, 69, 0, 49, 35, 0, 39, 35, - /* 2000 */ 49, 39, 0, 35, 49, 39, 19, 427, 0, 429, - /* 2010 */ 0, 0, 432, 433, 434, 435, 436, 437, 379, 439, - /* 2020 */ 33, 0, 0, 0, 0, 35, 22, 44, 35, 44, - /* 2030 */ 391, 35, 393, 35, 35, 35, 49, 0, 35, 22, - /* 2040 */ 35, 112, 110, 0, 57, 58, 59, 60, 35, 62, - /* 2050 */ 35, 35, 22, 341, 22, 0, 22, 51, 0, 0, - /* 2060 */ 35, 35, 35, 351, 0, 0, 427, 22, 429, 20, - /* 2070 */ 35, 432, 433, 434, 435, 436, 437, 35, 439, 35, - /* 2080 */ 104, 35, 103, 103, 341, 198, 0, 0, 22, 102, - /* 2090 */ 194, 379, 105, 22, 351, 0, 3, 44, 264, 104, - /* 2100 */ 48, 44, 3, 391, 103, 393, 172, 174, 48, 178, - /* 2110 */ 47, 99, 103, 172, 44, 172, 172, 44, 104, 341, - /* 2120 */ 101, 103, 379, 178, 104, 138, 47, 44, 44, 351, - /* 2130 */ 258, 103, 103, 264, 391, 104, 393, 104, 264, 427, - /* 2140 */ 104, 429, 103, 35, 432, 433, 434, 435, 436, 437, - /* 2150 */ 35, 439, 35, 35, 35, 35, 341, 379, 47, 47, - /* 2160 */ 173, 0, 0, 47, 39, 104, 351, 180, 44, 391, - /* 2170 */ 427, 393, 429, 104, 0, 432, 433, 434, 435, 436, - /* 2180 */ 437, 341, 439, 103, 103, 103, 199, 39, 113, 104, - /* 2190 */ 47, 351, 104, 103, 379, 103, 44, 103, 101, 245, - /* 2200 */ 2, 101, 22, 47, 103, 427, 391, 429, 393, 223, - /* 2210 */ 432, 433, 434, 435, 436, 437, 175, 439, 341, 379, - /* 2220 */ 173, 22, 47, 114, 35, 104, 104, 35, 351, 103, - /* 2230 */ 103, 391, 104, 393, 103, 103, 35, 104, 103, 35, - /* 2240 */ 104, 103, 427, 341, 429, 104, 104, 432, 433, 434, - /* 2250 */ 435, 436, 437, 351, 439, 104, 379, 103, 103, 35, - /* 2260 */ 103, 35, 104, 225, 104, 35, 103, 427, 391, 429, - /* 2270 */ 393, 103, 432, 433, 434, 435, 436, 437, 22, 439, - /* 2280 */ 103, 379, 115, 44, 103, 126, 35, 103, 22, 69, - /* 2290 */ 126, 126, 126, 391, 35, 393, 68, 35, 35, 35, - /* 2300 */ 35, 44, 35, 35, 427, 35, 429, 75, 97, 432, - /* 2310 */ 433, 434, 435, 436, 437, 341, 439, 35, 35, 35, - /* 2320 */ 22, 35, 35, 35, 75, 351, 35, 35, 35, 427, - /* 2330 */ 341, 429, 35, 0, 432, 433, 434, 435, 436, 437, - /* 2340 */ 351, 439, 35, 22, 35, 35, 0, 39, 341, 49, - /* 2350 */ 35, 49, 39, 379, 0, 35, 39, 0, 351, 35, - /* 2360 */ 0, 49, 39, 49, 35, 391, 0, 393, 379, 35, - /* 2370 */ 22, 21, 487, 22, 22, 487, 21, 487, 20, 487, - /* 2380 */ 391, 487, 393, 487, 487, 487, 379, 487, 487, 487, - /* 2390 */ 487, 487, 487, 487, 487, 341, 487, 487, 391, 487, - /* 2400 */ 393, 427, 487, 429, 487, 351, 432, 433, 434, 435, - /* 2410 */ 436, 437, 487, 439, 487, 487, 427, 341, 429, 487, - /* 2420 */ 487, 432, 433, 434, 435, 436, 437, 351, 439, 487, - /* 2430 */ 487, 487, 487, 379, 427, 487, 429, 487, 487, 432, - /* 2440 */ 433, 434, 435, 436, 437, 391, 439, 393, 487, 487, - /* 2450 */ 487, 487, 487, 487, 487, 379, 487, 487, 487, 487, - /* 2460 */ 487, 487, 487, 487, 341, 487, 487, 391, 487, 393, - /* 2470 */ 487, 487, 487, 487, 351, 487, 487, 487, 487, 487, - /* 2480 */ 487, 427, 487, 429, 487, 487, 432, 433, 434, 435, - /* 2490 */ 436, 437, 487, 439, 487, 487, 487, 487, 487, 487, - /* 2500 */ 487, 487, 379, 427, 487, 429, 487, 487, 432, 433, - /* 2510 */ 434, 435, 436, 437, 391, 439, 393, 487, 487, 487, - /* 2520 */ 487, 487, 487, 341, 487, 487, 487, 487, 487, 487, - /* 2530 */ 487, 487, 487, 351, 487, 487, 341, 487, 487, 487, - /* 2540 */ 487, 487, 487, 487, 487, 487, 351, 487, 487, 487, - /* 2550 */ 427, 487, 429, 341, 487, 432, 433, 434, 435, 436, - /* 2560 */ 437, 379, 439, 351, 487, 487, 487, 487, 487, 487, - /* 2570 */ 487, 487, 487, 391, 379, 393, 487, 487, 487, 487, - /* 2580 */ 487, 487, 487, 487, 487, 341, 391, 487, 393, 487, - /* 2590 */ 487, 379, 487, 487, 487, 351, 487, 487, 487, 487, - /* 2600 */ 487, 487, 487, 391, 487, 393, 487, 487, 487, 427, - /* 2610 */ 487, 429, 487, 487, 432, 433, 434, 435, 436, 437, - /* 2620 */ 487, 439, 427, 379, 429, 487, 487, 432, 433, 434, - /* 2630 */ 435, 436, 437, 487, 439, 391, 487, 393, 487, 427, - /* 2640 */ 487, 429, 487, 487, 432, 433, 434, 435, 436, 437, - /* 2650 */ 487, 439, 341, 487, 487, 487, 487, 487, 487, 487, - /* 2660 */ 487, 487, 351, 487, 487, 487, 487, 487, 487, 487, - /* 2670 */ 487, 427, 341, 429, 487, 487, 432, 433, 434, 435, - /* 2680 */ 436, 437, 351, 439, 487, 487, 487, 487, 487, 487, - /* 2690 */ 379, 487, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2700 */ 487, 487, 391, 487, 393, 487, 487, 487, 487, 487, - /* 2710 */ 379, 487, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2720 */ 487, 487, 391, 487, 393, 487, 487, 487, 487, 487, - /* 2730 */ 487, 487, 487, 487, 487, 487, 487, 487, 427, 487, - /* 2740 */ 429, 487, 341, 432, 433, 434, 435, 436, 437, 487, - /* 2750 */ 439, 487, 351, 487, 487, 487, 487, 487, 427, 341, - /* 2760 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 351, - /* 2770 */ 439, 487, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2780 */ 379, 487, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2790 */ 487, 487, 391, 487, 393, 487, 487, 379, 487, 487, - /* 2800 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 391, - /* 2810 */ 487, 393, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2820 */ 487, 487, 487, 487, 487, 487, 487, 487, 427, 487, - /* 2830 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 487, - /* 2840 */ 439, 487, 487, 487, 487, 427, 487, 429, 487, 487, - /* 2850 */ 432, 433, 434, 435, 436, 437, 487, 439, 338, 338, - /* 2860 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2870 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2880 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2890 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2900 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2910 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2920 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2930 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2940 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2950 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2960 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2970 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2980 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2990 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3000 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3010 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3020 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3030 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 1090 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 454, + /* 1100 */ 455, 456, 172, 458, 459, 20, 102, 33, 103, 179, + /* 1110 */ 193, 371, 443, 190, 445, 192, 391, 391, 114, 379, + /* 1120 */ 380, 379, 380, 49, 20, 357, 350, 351, 341, 350, + /* 1130 */ 351, 57, 58, 59, 60, 341, 62, 341, 20, 454, + /* 1140 */ 455, 456, 374, 458, 459, 222, 370, 142, 144, 370, + /* 1150 */ 382, 147, 148, 149, 150, 151, 152, 153, 154, 155, + /* 1160 */ 156, 157, 158, 159, 160, 161, 162, 163, 411, 165, + /* 1170 */ 166, 167, 341, 349, 359, 280, 102, 68, 391, 105, + /* 1180 */ 379, 380, 341, 260, 460, 391, 341, 391, 183, 184, + /* 1190 */ 185, 341, 341, 188, 341, 341, 341, 379, 380, 341, + /* 1200 */ 385, 351, 35, 353, 379, 380, 201, 202, 379, 380, + /* 1210 */ 388, 372, 261, 391, 375, 458, 0, 212, 461, 341, + /* 1220 */ 215, 0, 391, 218, 219, 220, 221, 222, 114, 351, + /* 1230 */ 380, 353, 391, 476, 477, 44, 391, 366, 481, 482, + /* 1240 */ 369, 391, 391, 393, 391, 391, 391, 173, 174, 391, + /* 1250 */ 45, 46, 341, 107, 180, 181, 110, 172, 380, 13, + /* 1260 */ 44, 42, 351, 44, 353, 260, 258, 259, 35, 391, + /* 1270 */ 49, 393, 42, 199, 44, 13, 172, 427, 164, 429, + /* 1280 */ 390, 35, 432, 433, 434, 435, 436, 437, 170, 439, + /* 1290 */ 107, 380, 478, 110, 444, 104, 446, 35, 0, 0, + /* 1300 */ 450, 451, 391, 107, 393, 427, 110, 429, 0, 44, + /* 1310 */ 432, 433, 434, 435, 436, 437, 107, 439, 44, 110, + /* 1320 */ 22, 22, 444, 207, 446, 209, 140, 141, 450, 451, + /* 1330 */ 22, 44, 223, 44, 13, 44, 44, 452, 427, 44, + /* 1340 */ 429, 44, 341, 432, 433, 434, 435, 436, 437, 462, + /* 1350 */ 439, 44, 351, 12, 13, 444, 35, 446, 44, 44, + /* 1360 */ 193, 450, 451, 22, 115, 1, 2, 44, 262, 104, + /* 1370 */ 341, 44, 412, 49, 33, 0, 35, 428, 104, 20, + /* 1380 */ 351, 380, 421, 134, 135, 136, 137, 138, 139, 44, + /* 1390 */ 44, 104, 391, 104, 393, 104, 104, 44, 206, 104, + /* 1400 */ 44, 104, 13, 62, 103, 426, 359, 44, 421, 380, + /* 1410 */ 44, 104, 359, 189, 113, 351, 75, 414, 104, 104, + /* 1420 */ 391, 20, 393, 42, 35, 50, 193, 104, 427, 398, + /* 1430 */ 429, 104, 341, 432, 433, 434, 435, 436, 437, 20, + /* 1440 */ 439, 100, 351, 401, 351, 444, 398, 446, 169, 104, + /* 1450 */ 104, 450, 451, 396, 20, 350, 427, 104, 429, 351, + /* 1460 */ 104, 432, 433, 434, 435, 436, 437, 104, 439, 350, + /* 1470 */ 104, 380, 101, 444, 398, 446, 396, 396, 363, 450, + /* 1480 */ 451, 99, 391, 362, 393, 350, 98, 361, 350, 350, + /* 1490 */ 350, 20, 343, 48, 347, 343, 421, 347, 20, 341, + /* 1500 */ 359, 359, 20, 393, 20, 352, 352, 413, 343, 351, + /* 1510 */ 359, 350, 380, 380, 359, 359, 359, 380, 427, 359, + /* 1520 */ 429, 350, 343, 432, 433, 434, 435, 436, 437, 210, + /* 1530 */ 439, 103, 191, 421, 193, 444, 391, 446, 380, 380, + /* 1540 */ 423, 450, 451, 380, 380, 425, 380, 357, 197, 391, + /* 1550 */ 420, 393, 357, 391, 350, 419, 196, 195, 268, 391, + /* 1560 */ 470, 341, 393, 269, 223, 224, 418, 391, 467, 391, + /* 1570 */ 467, 351, 391, 391, 401, 401, 406, 236, 237, 238, + /* 1580 */ 239, 240, 241, 242, 412, 427, 406, 429, 277, 182, + /* 1590 */ 432, 433, 434, 435, 436, 437, 469, 439, 467, 279, + /* 1600 */ 380, 263, 286, 278, 446, 412, 259, 464, 450, 451, + /* 1610 */ 466, 391, 283, 393, 486, 281, 20, 351, 431, 352, + /* 1620 */ 357, 357, 20, 406, 341, 391, 404, 391, 391, 391, + /* 1630 */ 391, 406, 391, 174, 351, 403, 375, 357, 357, 351, + /* 1640 */ 465, 103, 103, 449, 391, 369, 350, 427, 36, 429, + /* 1650 */ 357, 383, 432, 433, 434, 435, 436, 437, 415, 439, + /* 1660 */ 0, 344, 422, 380, 480, 343, 446, 479, 358, 339, + /* 1670 */ 450, 451, 0, 373, 391, 373, 393, 407, 407, 373, + /* 1680 */ 0, 42, 0, 35, 216, 341, 35, 35, 35, 216, + /* 1690 */ 0, 35, 35, 216, 0, 351, 216, 0, 35, 341, + /* 1700 */ 0, 22, 0, 35, 211, 0, 199, 0, 199, 351, + /* 1710 */ 427, 200, 429, 193, 191, 432, 433, 434, 435, 436, + /* 1720 */ 437, 0, 439, 0, 380, 0, 0, 187, 186, 446, + /* 1730 */ 0, 47, 0, 450, 451, 391, 341, 393, 380, 0, + /* 1740 */ 0, 0, 47, 42, 0, 0, 351, 159, 35, 391, + /* 1750 */ 0, 393, 0, 47, 0, 0, 0, 0, 0, 0, + /* 1760 */ 159, 0, 341, 0, 0, 0, 0, 0, 0, 0, + /* 1770 */ 0, 427, 351, 429, 0, 380, 432, 433, 434, 435, + /* 1780 */ 436, 437, 0, 439, 0, 427, 391, 429, 393, 0, + /* 1790 */ 432, 433, 434, 435, 436, 437, 0, 439, 0, 0, + /* 1800 */ 47, 380, 0, 0, 42, 0, 0, 0, 0, 0, + /* 1810 */ 22, 0, 391, 0, 393, 0, 472, 473, 143, 0, + /* 1820 */ 0, 0, 427, 22, 429, 48, 341, 432, 433, 434, + /* 1830 */ 435, 436, 437, 48, 439, 35, 351, 62, 22, 0, + /* 1840 */ 62, 483, 484, 0, 0, 62, 0, 35, 427, 0, + /* 1850 */ 429, 341, 35, 432, 433, 434, 435, 436, 437, 49, + /* 1860 */ 439, 351, 39, 49, 39, 380, 0, 446, 473, 384, + /* 1870 */ 35, 49, 451, 39, 0, 35, 391, 341, 393, 0, + /* 1880 */ 42, 39, 14, 47, 0, 44, 39, 351, 0, 0, + /* 1890 */ 380, 40, 47, 0, 384, 47, 39, 182, 0, 0, + /* 1900 */ 0, 391, 69, 393, 0, 0, 35, 49, 39, 0, + /* 1910 */ 35, 49, 427, 0, 429, 39, 380, 432, 433, 434, + /* 1920 */ 435, 436, 437, 0, 439, 35, 49, 391, 0, 393, + /* 1930 */ 39, 35, 49, 39, 0, 0, 0, 427, 0, 429, + /* 1940 */ 0, 112, 432, 433, 434, 435, 436, 437, 22, 439, + /* 1950 */ 341, 35, 0, 35, 35, 35, 35, 35, 44, 35, + /* 1960 */ 351, 44, 35, 427, 110, 429, 341, 1, 432, 433, + /* 1970 */ 434, 435, 436, 437, 35, 439, 351, 35, 22, 35, + /* 1980 */ 0, 22, 0, 22, 51, 19, 22, 0, 35, 380, + /* 1990 */ 0, 0, 35, 35, 0, 22, 20, 35, 35, 33, + /* 2000 */ 391, 104, 393, 35, 103, 380, 0, 35, 0, 384, + /* 2010 */ 103, 475, 194, 0, 22, 49, 391, 22, 393, 0, + /* 2020 */ 3, 44, 172, 57, 58, 59, 60, 341, 62, 198, + /* 2030 */ 174, 172, 172, 178, 103, 172, 427, 351, 429, 178, + /* 2040 */ 264, 432, 433, 434, 435, 436, 437, 104, 439, 103, + /* 2050 */ 48, 101, 427, 48, 429, 104, 44, 432, 433, 434, + /* 2060 */ 435, 436, 437, 103, 439, 44, 380, 44, 102, 99, + /* 2070 */ 384, 105, 47, 104, 103, 47, 44, 391, 103, 393, + /* 2080 */ 3, 35, 104, 104, 103, 44, 35, 104, 341, 35, + /* 2090 */ 264, 264, 35, 484, 35, 35, 47, 104, 351, 44, + /* 2100 */ 104, 0, 0, 47, 138, 39, 103, 103, 47, 0, + /* 2110 */ 103, 258, 103, 427, 341, 429, 175, 103, 432, 433, + /* 2120 */ 434, 435, 436, 437, 351, 439, 104, 380, 104, 39, + /* 2130 */ 103, 384, 47, 113, 101, 44, 101, 245, 391, 173, + /* 2140 */ 393, 2, 22, 103, 47, 103, 180, 173, 223, 104, + /* 2150 */ 47, 104, 104, 380, 104, 103, 103, 22, 114, 35, + /* 2160 */ 35, 103, 225, 35, 391, 199, 393, 103, 35, 104, + /* 2170 */ 103, 35, 104, 103, 427, 104, 429, 103, 341, 432, + /* 2180 */ 433, 434, 435, 436, 437, 104, 439, 103, 351, 35, + /* 2190 */ 104, 103, 35, 341, 22, 126, 104, 103, 126, 126, + /* 2200 */ 427, 126, 429, 351, 115, 432, 433, 434, 435, 436, + /* 2210 */ 437, 341, 439, 103, 44, 103, 35, 380, 103, 22, + /* 2220 */ 69, 351, 35, 68, 35, 35, 35, 35, 391, 35, + /* 2230 */ 393, 35, 380, 35, 75, 97, 35, 44, 35, 35, + /* 2240 */ 22, 35, 35, 391, 35, 393, 75, 35, 35, 35, + /* 2250 */ 380, 35, 35, 22, 35, 0, 35, 49, 0, 39, + /* 2260 */ 35, 391, 39, 393, 427, 0, 429, 35, 39, 432, + /* 2270 */ 433, 434, 435, 436, 437, 49, 439, 49, 0, 427, + /* 2280 */ 35, 429, 49, 0, 432, 433, 434, 435, 436, 437, + /* 2290 */ 39, 439, 35, 0, 35, 22, 21, 427, 22, 429, + /* 2300 */ 20, 22, 432, 433, 434, 435, 436, 437, 341, 439, + /* 2310 */ 21, 487, 487, 487, 487, 487, 487, 487, 351, 487, + /* 2320 */ 487, 487, 487, 487, 487, 487, 487, 341, 487, 487, + /* 2330 */ 487, 487, 487, 487, 487, 487, 487, 351, 487, 487, + /* 2340 */ 487, 341, 487, 487, 487, 487, 487, 380, 487, 487, + /* 2350 */ 487, 351, 487, 487, 487, 487, 487, 487, 391, 487, + /* 2360 */ 393, 487, 487, 487, 487, 487, 380, 487, 487, 487, + /* 2370 */ 487, 487, 487, 487, 487, 487, 487, 391, 341, 393, + /* 2380 */ 380, 487, 487, 487, 487, 487, 487, 487, 351, 487, + /* 2390 */ 487, 391, 487, 393, 427, 487, 429, 487, 487, 432, + /* 2400 */ 433, 434, 435, 436, 437, 487, 439, 487, 487, 487, + /* 2410 */ 487, 487, 487, 427, 487, 429, 487, 380, 432, 433, + /* 2420 */ 434, 435, 436, 437, 487, 439, 487, 427, 391, 429, + /* 2430 */ 393, 487, 432, 433, 434, 435, 436, 437, 487, 439, + /* 2440 */ 341, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2450 */ 351, 487, 487, 487, 487, 341, 487, 487, 487, 487, + /* 2460 */ 487, 487, 487, 487, 427, 351, 429, 487, 487, 432, + /* 2470 */ 433, 434, 435, 436, 437, 487, 439, 487, 487, 380, + /* 2480 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2490 */ 391, 487, 393, 487, 380, 487, 487, 487, 487, 487, + /* 2500 */ 487, 487, 487, 487, 487, 391, 341, 393, 487, 487, + /* 2510 */ 487, 487, 487, 487, 487, 487, 351, 487, 487, 487, + /* 2520 */ 341, 487, 487, 487, 487, 487, 427, 487, 429, 487, + /* 2530 */ 351, 432, 433, 434, 435, 436, 437, 487, 439, 487, + /* 2540 */ 487, 427, 487, 429, 487, 380, 432, 433, 434, 435, + /* 2550 */ 436, 437, 487, 439, 487, 487, 391, 487, 393, 380, + /* 2560 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2570 */ 391, 487, 393, 487, 487, 487, 487, 487, 487, 487, + /* 2580 */ 487, 487, 487, 487, 487, 341, 487, 487, 487, 487, + /* 2590 */ 487, 487, 427, 487, 429, 351, 487, 432, 433, 434, + /* 2600 */ 435, 436, 437, 487, 439, 487, 427, 487, 429, 487, + /* 2610 */ 487, 432, 433, 434, 435, 436, 437, 487, 439, 487, + /* 2620 */ 487, 487, 487, 487, 380, 487, 487, 487, 487, 487, + /* 2630 */ 487, 487, 487, 487, 487, 391, 487, 393, 487, 487, + /* 2640 */ 487, 487, 487, 487, 487, 341, 487, 487, 487, 487, + /* 2650 */ 487, 487, 487, 487, 487, 351, 487, 487, 487, 487, + /* 2660 */ 341, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2670 */ 351, 427, 487, 429, 487, 487, 432, 433, 434, 435, + /* 2680 */ 436, 437, 487, 439, 380, 487, 487, 487, 487, 487, + /* 2690 */ 487, 487, 487, 487, 487, 391, 487, 393, 487, 380, + /* 2700 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2710 */ 391, 487, 393, 487, 487, 487, 487, 487, 487, 487, + /* 2720 */ 341, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2730 */ 351, 427, 487, 429, 487, 341, 432, 433, 434, 435, + /* 2740 */ 436, 437, 487, 439, 487, 351, 427, 487, 429, 487, + /* 2750 */ 487, 432, 433, 434, 435, 436, 437, 341, 439, 380, + /* 2760 */ 487, 487, 487, 487, 487, 487, 487, 351, 487, 487, + /* 2770 */ 391, 487, 393, 487, 380, 487, 487, 487, 487, 487, + /* 2780 */ 487, 487, 487, 487, 487, 391, 487, 393, 487, 487, + /* 2790 */ 487, 487, 487, 487, 487, 487, 380, 487, 487, 487, + /* 2800 */ 487, 487, 487, 487, 487, 487, 427, 391, 429, 393, + /* 2810 */ 487, 432, 433, 434, 435, 436, 437, 487, 439, 487, + /* 2820 */ 487, 427, 487, 429, 487, 487, 432, 433, 434, 435, + /* 2830 */ 436, 437, 341, 439, 487, 487, 487, 487, 487, 487, + /* 2840 */ 487, 487, 351, 427, 487, 429, 487, 341, 432, 433, + /* 2850 */ 434, 435, 436, 437, 487, 439, 487, 351, 487, 487, + /* 2860 */ 487, 487, 341, 487, 487, 487, 487, 487, 487, 487, + /* 2870 */ 487, 380, 351, 487, 487, 487, 487, 487, 487, 487, + /* 2880 */ 487, 487, 391, 487, 393, 487, 380, 487, 487, 487, + /* 2890 */ 487, 487, 487, 487, 487, 487, 487, 391, 487, 393, + /* 2900 */ 487, 380, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2910 */ 487, 487, 391, 487, 393, 487, 487, 487, 427, 487, + /* 2920 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 487, + /* 2930 */ 439, 487, 487, 427, 341, 429, 487, 487, 432, 433, + /* 2940 */ 434, 435, 436, 437, 351, 439, 487, 487, 427, 487, + /* 2950 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 487, + /* 2960 */ 439, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2970 */ 487, 487, 487, 380, 487, 487, 487, 487, 487, 487, + /* 2980 */ 487, 487, 487, 487, 391, 487, 393, 487, 487, 487, + /* 2990 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 3000 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 3010 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 3020 */ 427, 487, 429, 487, 487, 432, 433, 434, 435, 436, + /* 3030 */ 437, 487, 439, 338, 338, 338, 338, 338, 338, 338, /* 3040 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, /* 3050 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, /* 3060 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, @@ -821,214 +839,229 @@ static const YYCODETYPE yy_lookahead[] = { /* 3160 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, /* 3170 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, /* 3180 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3190 */ 338, 338, 338, 338, 338, 338, + /* 3190 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3200 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3210 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3220 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3230 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3240 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3250 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3260 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3270 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3280 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3290 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3300 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3310 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3320 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3330 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3340 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3350 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3360 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3370 */ 338, }; -#define YY_SHIFT_COUNT (801) +#define YY_SHIFT_COUNT (797) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2366) +#define YY_SHIFT_MAX (2293) static const unsigned short int yy_shift_ofst[] = { /* 0 */ 1005, 0, 104, 0, 337, 337, 337, 337, 337, 337, /* 10 */ 337, 337, 337, 337, 337, 337, 441, 673, 673, 777, /* 20 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, /* 30 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, /* 40 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, - /* 50 */ 673, 18, 259, 393, 29, 428, 701, 428, 29, 29, - /* 60 */ 428, 1341, 428, 1341, 1341, 66, 428, 93, 143, 158, - /* 70 */ 158, 143, 13, 13, 331, 294, 23, 23, 158, 158, - /* 80 */ 158, 158, 158, 158, 158, 158, 158, 158, 195, 158, - /* 90 */ 158, 243, 93, 158, 158, 309, 93, 158, 195, 158, - /* 100 */ 195, 93, 158, 158, 93, 158, 93, 93, 93, 158, - /* 110 */ 473, 1004, 15, 15, 303, 462, 1302, 1302, 1302, 1302, - /* 120 */ 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, - /* 130 */ 1302, 1302, 1302, 1302, 1302, 1072, 194, 331, 294, 833, - /* 140 */ 833, 184, 564, 564, 564, 101, 291, 291, 184, 243, - /* 150 */ 284, 251, 93, 454, 93, 454, 454, 483, 619, 28, - /* 160 */ 28, 28, 28, 28, 28, 28, 28, 1987, 757, 261, - /* 170 */ 580, 613, 508, 49, 521, 343, 343, 492, 784, 754, - /* 180 */ 872, 1038, 1129, 875, 323, 1039, 939, 990, 924, 939, - /* 190 */ 1140, 955, 817, 1144, 1365, 1395, 1212, 243, 1395, 243, - /* 200 */ 1238, 1422, 1401, 1429, 1422, 1401, 1287, 1443, 1422, 1443, - /* 210 */ 1401, 1287, 1287, 1380, 1386, 1443, 1390, 1443, 1443, 1443, - /* 220 */ 1470, 1459, 1470, 1459, 1395, 243, 1496, 243, 1497, 1502, - /* 230 */ 243, 1497, 243, 243, 243, 1443, 243, 1470, 93, 93, - /* 240 */ 93, 93, 93, 93, 93, 93, 93, 93, 93, 1443, - /* 250 */ 1470, 454, 454, 454, 1344, 1442, 1395, 473, 1358, 1376, - /* 260 */ 1496, 473, 1394, 1144, 1443, 1429, 1429, 454, 1330, 1339, - /* 270 */ 454, 1330, 1339, 454, 454, 93, 1342, 1438, 1330, 1348, - /* 280 */ 1350, 1367, 1144, 1347, 1349, 1364, 1388, 1422, 1617, 1497, - /* 290 */ 473, 473, 1634, 1339, 454, 454, 454, 454, 454, 1339, - /* 300 */ 454, 1509, 473, 483, 473, 1422, 1591, 1597, 454, 619, - /* 310 */ 1443, 473, 1670, 1470, 2858, 2858, 2858, 2858, 2858, 2858, - /* 320 */ 2858, 2858, 2858, 1002, 1074, 225, 32, 736, 750, 860, - /* 330 */ 687, 980, 1356, 434, 806, 197, 197, 197, 197, 197, - /* 340 */ 197, 197, 197, 197, 575, 265, 870, 870, 648, 6, - /* 350 */ 516, 307, 713, 1077, 1095, 512, 280, 282, 282, 710, - /* 360 */ 201, 793, 710, 710, 710, 1208, 1021, 1171, 1209, 1170, - /* 370 */ 1099, 1237, 1123, 1132, 1149, 1159, 1092, 1232, 1246, 1258, - /* 380 */ 1270, 1012, 1184, 1217, 1214, 1247, 1255, 1262, 1157, 1106, - /* 390 */ 1101, 1263, 1278, 1282, 1285, 1286, 1289, 1333, 1292, 1172, - /* 400 */ 1295, 602, 1305, 1335, 1340, 1353, 1354, 1368, 255, 1236, - /* 410 */ 1260, 1343, 1378, 1218, 610, 1707, 1738, 1741, 1704, 1749, - /* 420 */ 1715, 1535, 1717, 1720, 1722, 1542, 1759, 1725, 1726, 1546, - /* 430 */ 1764, 1549, 1766, 1734, 1770, 1750, 1771, 1739, 1565, 1784, - /* 440 */ 1587, 1788, 1590, 1593, 1601, 1610, 1806, 1807, 1808, 1622, - /* 450 */ 1624, 1811, 1812, 1769, 1813, 1817, 1818, 1774, 1822, 1781, - /* 460 */ 1825, 1826, 1828, 1783, 1831, 1832, 1833, 1835, 1836, 1837, - /* 470 */ 1679, 1805, 1843, 1691, 1852, 1853, 1855, 1857, 1858, 1859, - /* 480 */ 1860, 1861, 1864, 1866, 1888, 1889, 1893, 1894, 1903, 1904, - /* 490 */ 1830, 1878, 1838, 1879, 1881, 1882, 1883, 1884, 1885, 1886, - /* 500 */ 1905, 1906, 1907, 1768, 1909, 1913, 1892, 1875, 1908, 1876, - /* 510 */ 1925, 1824, 1891, 1927, 1870, 1928, 1871, 1935, 1936, 1910, - /* 520 */ 1890, 1898, 1938, 1911, 1895, 1901, 1942, 1914, 1899, 1912, - /* 530 */ 1950, 1917, 1953, 1915, 1916, 1918, 1919, 1920, 1940, 1921, - /* 540 */ 1956, 1923, 1922, 1958, 1960, 1965, 1930, 1790, 1970, 1978, - /* 550 */ 1981, 1924, 1991, 1992, 1939, 1926, 1937, 1994, 1961, 1946, - /* 560 */ 1959, 1997, 1964, 1951, 1962, 2002, 1968, 1955, 1966, 2008, - /* 570 */ 2010, 2011, 2021, 2022, 2023, 1929, 1932, 1990, 2004, 2024, - /* 580 */ 1993, 1996, 1998, 1999, 2000, 2003, 2005, 1983, 1985, 2013, - /* 590 */ 2015, 2017, 2016, 2037, 2030, 2043, 2032, 2006, 2055, 2034, - /* 600 */ 2025, 2058, 2026, 2059, 2027, 2064, 2045, 2049, 2035, 2042, - /* 610 */ 2044, 1976, 1979, 2065, 1934, 1980, 1887, 2046, 2066, 2086, - /* 620 */ 1896, 2071, 1941, 1933, 2087, 2095, 1943, 1931, 1944, 1945, - /* 630 */ 2093, 2053, 1834, 2001, 1995, 2009, 2052, 2019, 2060, 2012, - /* 640 */ 2014, 2057, 2070, 2020, 2018, 2028, 2029, 2031, 2073, 2063, - /* 650 */ 2079, 2039, 2083, 1869, 2033, 2036, 2099, 2084, 1874, 2108, - /* 660 */ 2115, 2117, 2118, 2119, 2120, 2061, 2069, 2111, 1872, 2124, - /* 670 */ 2112, 2161, 2162, 2080, 2125, 1919, 2116, 2081, 2085, 2088, - /* 680 */ 2082, 2090, 2041, 2092, 2174, 2148, 2047, 2094, 2075, 1919, - /* 690 */ 2143, 2152, 2097, 1954, 2100, 2198, 2180, 1986, 2101, 2121, - /* 700 */ 2126, 2122, 2127, 2128, 2156, 2131, 2132, 2175, 2133, 2199, - /* 710 */ 2038, 2135, 2109, 2136, 2189, 2192, 2138, 2141, 2201, 2154, - /* 720 */ 2142, 2204, 2155, 2151, 2224, 2157, 2158, 2226, 2163, 2160, - /* 730 */ 2230, 2168, 2159, 2164, 2165, 2166, 2256, 2167, 2177, 2239, - /* 740 */ 2181, 2251, 2184, 2239, 2239, 2266, 2220, 2228, 2259, 2262, - /* 750 */ 2263, 2264, 2265, 2267, 2268, 2270, 2232, 2211, 2257, 2282, - /* 760 */ 2283, 2284, 2298, 2286, 2287, 2288, 2249, 1983, 2291, 1985, - /* 770 */ 2292, 2293, 2297, 2307, 2321, 2309, 2333, 2310, 2300, 2308, - /* 780 */ 2346, 2315, 2302, 2313, 2354, 2320, 2312, 2317, 2357, 2324, - /* 790 */ 2314, 2323, 2360, 2329, 2334, 2366, 2348, 2350, 2351, 2352, - /* 800 */ 2355, 2358, + /* 50 */ 673, 16, 66, 923, 116, 250, 286, 250, 116, 116, + /* 60 */ 250, 1341, 250, 1341, 1341, 170, 250, 24, 342, 36, + /* 70 */ 36, 342, 419, 419, 257, 475, 344, 344, 36, 36, + /* 80 */ 36, 36, 36, 36, 36, 36, 36, 36, 114, 36, + /* 90 */ 36, 96, 24, 36, 36, 162, 24, 36, 114, 36, + /* 100 */ 114, 24, 36, 36, 24, 36, 24, 24, 24, 36, + /* 110 */ 148, 1004, 15, 15, 303, 258, 100, 100, 100, 100, + /* 120 */ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + /* 130 */ 100, 100, 100, 100, 100, 596, 194, 257, 475, 672, + /* 140 */ 672, 626, 639, 639, 639, 438, 804, 804, 626, 96, + /* 150 */ 24, 24, 24, 24, 106, 4, 24, 203, 24, 203, + /* 160 */ 203, 196, 281, 28, 28, 28, 28, 1966, 531, 225, + /* 170 */ 575, 707, 381, 363, 604, 917, 917, 492, 930, 828, + /* 180 */ 54, 1085, 1205, 926, 910, 1104, 1008, 624, 895, 1008, + /* 190 */ 1219, 951, 1118, 1106, 1324, 1359, 1192, 96, 1359, 96, + /* 200 */ 1224, 1401, 1381, 1419, 1401, 1381, 1279, 1434, 1401, 1434, + /* 210 */ 1381, 1279, 1279, 1371, 1382, 1434, 1388, 1434, 1434, 1434, + /* 220 */ 1471, 1445, 1471, 1445, 1359, 96, 1478, 96, 1482, 1484, + /* 230 */ 96, 1482, 96, 96, 96, 1434, 96, 1471, 24, 24, + /* 240 */ 24, 24, 24, 24, 24, 1434, 1471, 203, 203, 203, + /* 250 */ 1319, 1428, 1359, 148, 1351, 1360, 1478, 148, 1362, 1106, + /* 260 */ 1434, 1419, 1419, 203, 1294, 1290, 203, 1294, 1290, 203, + /* 270 */ 203, 24, 1311, 1407, 1294, 1320, 1325, 1338, 1106, 1316, + /* 280 */ 1329, 1334, 1347, 1401, 1596, 1482, 148, 148, 1602, 1290, + /* 290 */ 203, 203, 203, 203, 203, 1290, 203, 1459, 148, 196, + /* 300 */ 148, 1401, 1538, 1539, 203, 281, 1434, 148, 1612, 1471, + /* 310 */ 3033, 3033, 3033, 3033, 3033, 3033, 3033, 3033, 3033, 1002, + /* 320 */ 1074, 460, 584, 774, 716, 747, 649, 813, 948, 434, + /* 330 */ 666, 197, 197, 197, 197, 197, 197, 197, 197, 197, + /* 340 */ 1249, 296, 756, 756, 276, 72, 287, 714, 690, 397, + /* 350 */ 591, 271, 684, 706, 706, 966, 764, 677, 966, 966, + /* 360 */ 966, 1221, 178, 1191, 572, 1230, 1114, 1216, 1146, 1183, + /* 370 */ 1196, 1209, 1246, 1262, 1298, 1299, 1308, 1116, 1265, 1274, + /* 380 */ 68, 1287, 1289, 1291, 1186, 81, 340, 1292, 1295, 1297, + /* 390 */ 1307, 1314, 1315, 1364, 1323, 1109, 1327, 51, 1345, 1346, + /* 400 */ 1353, 1356, 1363, 1366, 1301, 1167, 1233, 1321, 1389, 675, + /* 410 */ 1375, 1660, 1672, 1680, 1639, 1682, 1648, 1468, 1651, 1652, + /* 420 */ 1653, 1473, 1690, 1656, 1657, 1477, 1694, 1480, 1697, 1663, + /* 430 */ 1700, 1679, 1702, 1668, 1493, 1705, 1507, 1707, 1509, 1511, + /* 440 */ 1520, 1523, 1721, 1723, 1725, 1540, 1542, 1726, 1730, 1684, + /* 450 */ 1732, 1739, 1740, 1695, 1741, 1701, 1744, 1745, 1750, 1706, + /* 460 */ 1752, 1754, 1755, 1756, 1757, 1758, 1588, 1713, 1759, 1601, + /* 470 */ 1761, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1774, + /* 480 */ 1782, 1784, 1789, 1796, 1798, 1799, 1753, 1802, 1762, 1803, + /* 490 */ 1805, 1806, 1807, 1808, 1809, 1788, 1811, 1813, 1815, 1675, + /* 500 */ 1819, 1820, 1801, 1777, 1816, 1785, 1821, 1775, 1800, 1839, + /* 510 */ 1778, 1843, 1783, 1844, 1846, 1812, 1810, 1823, 1849, 1817, + /* 520 */ 1814, 1825, 1866, 1835, 1822, 1834, 1874, 1840, 1879, 1838, + /* 530 */ 1842, 1841, 1836, 1845, 1868, 1848, 1884, 1851, 1847, 1888, + /* 540 */ 1889, 1893, 1857, 1715, 1898, 1899, 1900, 1833, 1904, 1905, + /* 550 */ 1871, 1858, 1869, 1909, 1875, 1862, 1876, 1913, 1890, 1877, + /* 560 */ 1891, 1923, 1896, 1883, 1894, 1928, 1934, 1935, 1936, 1938, + /* 570 */ 1940, 1829, 1854, 1916, 1926, 1952, 1918, 1919, 1920, 1921, + /* 580 */ 1922, 1924, 1927, 1914, 1917, 1939, 1942, 1956, 1944, 1980, + /* 590 */ 1959, 1982, 1961, 1933, 1990, 1964, 1953, 1987, 1957, 1991, + /* 600 */ 1958, 1994, 1973, 1976, 1962, 1963, 1968, 1897, 1901, 2006, + /* 610 */ 1850, 1907, 1831, 1972, 1992, 2008, 1818, 1995, 1859, 1856, + /* 620 */ 2013, 2019, 1860, 1855, 1863, 1861, 2017, 1977, 1776, 1931, + /* 630 */ 1943, 1946, 2002, 1950, 2005, 1970, 1951, 2012, 2021, 1969, + /* 640 */ 1960, 1971, 1975, 1978, 2023, 2025, 2028, 1981, 2032, 1826, + /* 650 */ 1979, 1983, 2077, 2041, 1827, 2046, 2051, 2054, 2057, 2059, + /* 660 */ 2060, 1993, 1996, 2049, 1853, 2055, 2056, 2101, 2102, 2003, + /* 670 */ 2066, 1836, 2061, 2004, 2022, 2024, 2007, 2009, 1941, 2014, + /* 680 */ 2109, 2090, 1974, 2027, 2020, 1836, 2085, 2091, 2033, 1892, + /* 690 */ 2035, 2139, 2120, 1925, 2040, 2045, 2042, 2047, 2052, 2048, + /* 700 */ 2097, 2053, 2058, 2103, 2050, 2135, 1937, 2064, 2044, 2065, + /* 710 */ 2124, 2125, 2067, 2068, 2128, 2070, 2071, 2133, 2074, 2081, + /* 720 */ 2136, 2084, 2086, 2154, 2088, 2092, 2157, 2094, 2069, 2072, + /* 730 */ 2073, 2075, 2172, 2089, 2110, 2170, 2112, 2181, 2115, 2170, + /* 740 */ 2170, 2197, 2151, 2155, 2187, 2189, 2190, 2191, 2192, 2194, + /* 750 */ 2196, 2198, 2159, 2138, 2193, 2201, 2203, 2204, 2218, 2206, + /* 760 */ 2207, 2209, 2171, 1914, 2212, 1917, 2213, 2214, 2216, 2217, + /* 770 */ 2231, 2219, 2255, 2221, 2208, 2220, 2258, 2225, 2226, 2223, + /* 780 */ 2265, 2232, 2228, 2229, 2278, 2245, 2233, 2251, 2283, 2257, + /* 790 */ 2259, 2293, 2273, 2275, 2276, 2279, 2289, 2280, }; -#define YY_REDUCE_COUNT (322) -#define YY_REDUCE_MIN (-404) -#define YY_REDUCE_MAX (2418) +#define YY_REDUCE_COUNT (318) +#define YY_REDUCE_MIN (-443) +#define YY_REDUCE_MAX (2593) static const short yy_reduce_ofst[] = { - /* 0 */ -296, -340, -133, -26, 88, 310, 540, 850, 881, 911, - /* 10 */ 208, 1001, 1032, 1069, 1158, 1207, 1233, 118, 1284, 1297, - /* 20 */ 1346, 1363, 1436, 1412, 1463, 1483, 426, 1550, 1580, 1639, - /* 30 */ 1712, 1743, 1778, 1815, 1840, 1877, 1902, 1974, 1989, 2007, - /* 40 */ 2054, 2076, 2123, 2182, 2195, 2212, 2244, 2311, 2331, 2401, - /* 50 */ 2418, -260, -25, 239, 149, -404, 246, 643, -28, 480, - /* 60 */ 1080, -365, -294, -331, 671, -339, -98, 252, -390, -345, - /* 70 */ -265, -279, -72, 40, -318, 30, -342, 112, -216, 26, - /* 80 */ 192, 263, -177, 269, 348, 383, 400, 341, 154, 421, - /* 90 */ 450, 561, -261, 520, 579, 36, 230, 601, 576, 615, - /* 100 */ 647, -63, 675, 697, 735, 752, 139, 749, 424, 822, - /* 110 */ -182, -316, -258, -258, -280, -233, -20, 11, 91, 245, - /* 120 */ 257, 466, 537, 642, 686, 722, 724, 725, 803, 805, - /* 130 */ 808, 827, 844, 845, 859, -369, -67, 581, -145, 453, - /* 140 */ 567, 593, -67, 41, 199, 123, 274, 587, 634, 676, - /* 150 */ 20, 594, 677, 653, 732, 751, 814, 765, 772, -380, - /* 160 */ -328, 361, 476, 499, 552, 570, 499, 416, 474, 909, - /* 170 */ 554, 818, 804, 951, 841, 944, 945, 949, 913, 949, - /* 180 */ 987, 959, 1026, 1030, 997, 999, 941, 941, 926, 941, - /* 190 */ 953, 946, 949, 995, 989, 998, 996, 1062, 1003, 1067, - /* 200 */ 1017, 1081, 1048, 1049, 1103, 1057, 1078, 1120, 1122, 1125, - /* 210 */ 1079, 1083, 1084, 1121, 1124, 1137, 1128, 1142, 1147, 1150, - /* 220 */ 1151, 1163, 1168, 1165, 1093, 1154, 1130, 1162, 1166, 1111, - /* 230 */ 1169, 1175, 1174, 1176, 1177, 1179, 1180, 1187, 1152, 1161, - /* 240 */ 1164, 1167, 1173, 1181, 1188, 1189, 1190, 1191, 1192, 1194, - /* 250 */ 1199, 1156, 1182, 1185, 1134, 1127, 1145, 1196, 1143, 1183, - /* 260 */ 1195, 1239, 1193, 1198, 1225, 1200, 1202, 1215, 1138, 1210, - /* 270 */ 1222, 1148, 1211, 1223, 1227, 949, 1153, 1160, 1155, 1186, - /* 280 */ 1213, 1197, 1219, 1135, 1201, 1203, 941, 1298, 1220, 1303, - /* 290 */ 1293, 1299, 1275, 1253, 1273, 1294, 1300, 1301, 1304, 1274, - /* 300 */ 1307, 1281, 1329, 1314, 1336, 1345, 1250, 1318, 1311, 1334, - /* 310 */ 1355, 1351, 1366, 1369, 1312, 1306, 1308, 1315, 1362, 1371, - /* 320 */ 1372, 1382, 1370, + /* 0 */ -296, -340, -133, -26, 88, 307, 540, 850, 878, 911, + /* 10 */ 1001, 1029, 1091, 1158, 1220, 1283, 118, 1344, 1358, 1421, + /* 20 */ 1395, 1485, 1510, 1536, 1609, 1625, 426, 1686, 1747, 1773, + /* 30 */ 1837, 1852, 1870, 1967, 1986, 2000, 2037, 2099, 2114, 2165, + /* 40 */ 2179, 2244, 2304, 2319, 2379, 2394, 2416, 2491, 2506, 2521, + /* 50 */ 2593, -260, -25, -411, 185, -404, 236, 461, 645, 685, + /* 60 */ 757, 558, -397, 554, 560, -443, -294, -334, -350, -269, + /* 70 */ 1, -383, -236, -29, -12, 78, -344, -283, 26, 64, + /* 80 */ 192, 235, -208, 143, 280, 339, 424, 295, -212, 484, + /* 90 */ 487, -271, -377, 524, 615, -332, -72, 679, 482, 682, + /* 100 */ 483, 256, 688, 694, 86, 776, 683, 243, 740, 779, + /* 110 */ 768, -346, -245, -245, -39, -81, -223, 358, 537, 603, + /* 120 */ 630, 686, 725, 726, 787, 794, 796, 831, 841, 845, + /* 130 */ 851, 853, 854, 855, 858, 12, -31, -359, 156, 382, + /* 140 */ 453, 594, -31, 323, 367, 22, 616, 669, 676, 815, + /* 150 */ 742, 801, 818, 825, 321, 84, 829, 504, 402, 535, + /* 160 */ 822, 839, 871, -371, -355, 30, -371, 41, 107, 191, + /* 170 */ 136, 157, 229, 437, 348, 464, 480, 476, 522, 476, + /* 180 */ 582, 650, 824, 705, 890, 664, 724, 724, 814, 724, + /* 190 */ 885, 887, 476, 960, 949, 961, 979, 1047, 987, 1053, + /* 200 */ 1003, 1064, 1031, 1042, 1093, 1048, 1057, 1105, 1108, 1119, + /* 210 */ 1076, 1080, 1081, 1115, 1121, 1135, 1126, 1138, 1139, 1140, + /* 220 */ 1149, 1147, 1152, 1150, 1075, 1141, 1110, 1142, 1153, 1094, + /* 230 */ 1151, 1154, 1155, 1156, 1157, 1161, 1160, 1165, 1132, 1133, + /* 240 */ 1137, 1159, 1163, 1164, 1166, 1171, 1179, 1145, 1162, 1168, + /* 250 */ 1120, 1117, 1112, 1190, 1130, 1136, 1169, 1195, 1148, 1172, + /* 260 */ 1204, 1173, 1174, 1176, 1101, 1170, 1178, 1103, 1180, 1181, + /* 270 */ 1182, 476, 1090, 1127, 1131, 1144, 1175, 1143, 1193, 1128, + /* 280 */ 1184, 1188, 724, 1266, 1187, 1267, 1263, 1264, 1222, 1217, + /* 290 */ 1234, 1236, 1237, 1238, 1239, 1225, 1241, 1232, 1280, 1261, + /* 300 */ 1281, 1288, 1194, 1268, 1253, 1276, 1296, 1293, 1317, 1322, + /* 310 */ 1243, 1240, 1270, 1271, 1300, 1302, 1306, 1310, 1330, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 10 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 20 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 30 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 40 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 50 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 60 */ 2095, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 70 */ 1783, 1783, 1783, 1783, 2068, 1783, 1783, 1783, 1783, 1783, - /* 80 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 90 */ 1783, 1872, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 100 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 110 */ 1870, 2061, 2287, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 120 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 130 */ 1783, 1783, 1783, 1783, 1783, 1783, 2299, 1783, 1783, 1846, - /* 140 */ 1846, 1783, 2299, 2299, 2299, 1870, 2259, 2259, 1783, 1872, - /* 150 */ 2129, 1783, 1783, 1783, 1783, 1783, 1783, 1993, 1783, 1783, - /* 160 */ 1783, 1783, 1783, 2017, 1783, 1783, 1783, 2121, 1783, 1783, - /* 170 */ 2324, 2381, 1783, 1783, 2327, 1783, 1783, 1783, 1783, 1783, - /* 180 */ 1783, 2073, 1783, 1783, 1945, 2314, 2291, 2305, 2365, 2292, - /* 190 */ 2289, 2308, 1783, 2318, 1783, 1783, 2143, 1872, 1783, 1872, - /* 200 */ 2108, 1783, 2066, 1783, 1783, 2066, 2063, 1783, 1783, 1783, - /* 210 */ 2066, 2063, 2063, 1934, 1930, 1783, 1928, 1783, 1783, 1783, - /* 220 */ 1783, 1830, 1783, 1830, 1783, 1872, 1783, 1872, 1783, 1783, - /* 230 */ 1872, 1783, 1872, 1872, 1872, 1783, 1872, 1783, 1783, 1783, - /* 240 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 250 */ 1783, 1783, 1783, 1783, 2141, 2127, 1783, 1870, 2119, 2117, - /* 260 */ 1783, 1870, 2115, 2318, 1783, 1783, 1783, 1783, 2335, 2333, - /* 270 */ 1783, 2335, 2333, 1783, 1783, 1783, 2349, 2345, 2335, 2354, - /* 280 */ 2351, 2320, 2318, 2384, 2371, 2367, 2305, 1783, 1783, 1783, - /* 290 */ 1870, 1870, 1783, 2333, 1783, 1783, 1783, 1783, 1783, 2333, - /* 300 */ 1783, 1783, 1870, 1783, 1870, 1783, 1783, 1961, 1783, 1783, - /* 310 */ 1783, 1870, 1815, 1783, 2110, 2132, 2091, 2091, 1996, 1996, - /* 320 */ 1996, 1873, 1788, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 330 */ 1783, 1783, 1783, 1783, 1783, 2348, 2347, 2214, 1783, 2263, - /* 340 */ 2262, 2261, 2252, 2213, 1957, 1783, 2212, 2211, 1783, 1783, - /* 350 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2082, 2081, 2205, - /* 360 */ 1783, 1783, 2206, 2204, 2203, 1783, 1783, 1783, 1783, 1783, - /* 370 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 380 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2368, - /* 390 */ 2372, 1783, 1783, 1783, 1783, 1783, 1783, 2288, 1783, 1783, - /* 400 */ 1783, 2187, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 410 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 420 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 430 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 440 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 450 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 460 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 470 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 480 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 490 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 500 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 510 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 520 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 530 */ 1783, 1783, 1783, 1783, 1783, 1820, 2192, 1783, 1783, 1783, - /* 540 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 550 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 560 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 570 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 580 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1911, 1910, 1783, - /* 590 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 600 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 610 */ 1783, 2196, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 620 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 630 */ 2364, 2321, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 640 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 650 */ 2187, 1783, 2346, 1783, 1783, 2362, 1783, 2366, 1783, 1783, - /* 660 */ 1783, 1783, 1783, 1783, 1783, 2298, 2294, 1783, 1783, 2290, - /* 670 */ 1783, 1783, 1783, 1783, 1783, 2195, 1783, 1783, 1783, 1783, - /* 680 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2186, - /* 690 */ 1783, 2249, 1783, 1783, 1783, 2283, 1783, 1783, 2234, 1783, - /* 700 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2196, 1783, - /* 710 */ 2199, 1783, 1783, 1783, 1783, 1783, 1990, 1783, 1783, 1783, - /* 720 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 730 */ 1783, 1783, 1974, 1972, 1971, 1970, 1783, 1967, 1783, 2003, - /* 740 */ 1783, 1783, 1783, 1999, 1998, 1783, 1783, 1783, 1783, 1783, - /* 750 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1891, 1783, - /* 760 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1883, 1783, 1882, - /* 770 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 780 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 790 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 800 */ 1783, 1783, + /* 0 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 10 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 20 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 30 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 40 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 50 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 60 */ 2091, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 70 */ 1779, 1779, 1779, 1779, 2064, 1779, 1779, 1779, 1779, 1779, + /* 80 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 90 */ 1779, 1868, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 100 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 110 */ 1866, 2057, 2283, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 120 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 130 */ 1779, 1779, 1779, 1779, 1779, 1779, 2295, 1779, 1779, 1842, + /* 140 */ 1842, 1779, 2295, 2295, 2295, 1866, 2255, 2255, 1779, 1868, + /* 150 */ 1779, 1779, 1779, 1779, 2125, 1779, 1779, 1779, 1779, 1779, + /* 160 */ 1779, 1989, 1779, 2013, 1779, 1779, 1779, 2117, 1779, 1779, + /* 170 */ 2320, 2377, 1779, 1779, 2323, 1779, 1779, 1779, 1779, 1779, + /* 180 */ 1779, 2069, 1779, 1779, 1941, 2310, 2287, 2301, 2361, 2288, + /* 190 */ 2285, 2304, 1779, 2314, 1779, 1779, 2139, 1868, 1779, 1868, + /* 200 */ 2104, 1779, 2062, 1779, 1779, 2062, 2059, 1779, 1779, 1779, + /* 210 */ 2062, 2059, 2059, 1930, 1926, 1779, 1924, 1779, 1779, 1779, + /* 220 */ 1779, 1826, 1779, 1826, 1779, 1868, 1779, 1868, 1779, 1779, + /* 230 */ 1868, 1779, 1868, 1868, 1868, 1779, 1868, 1779, 1779, 1779, + /* 240 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 250 */ 2137, 2123, 1779, 1866, 2115, 2113, 1779, 1866, 2111, 2314, + /* 260 */ 1779, 1779, 1779, 1779, 2331, 2329, 1779, 2331, 2329, 1779, + /* 270 */ 1779, 1779, 2345, 2341, 2331, 2350, 2347, 2316, 2314, 2380, + /* 280 */ 2367, 2363, 2301, 1779, 1779, 1779, 1866, 1866, 1779, 2329, + /* 290 */ 1779, 1779, 1779, 1779, 1779, 2329, 1779, 1779, 1866, 1779, + /* 300 */ 1866, 1779, 1779, 1957, 1779, 1779, 1779, 1866, 1811, 1779, + /* 310 */ 2106, 2128, 2087, 2087, 1992, 1992, 1992, 1869, 1784, 1779, + /* 320 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 330 */ 1779, 2344, 2343, 2210, 1779, 2259, 2258, 2257, 2248, 2209, + /* 340 */ 1953, 1779, 2208, 2207, 1779, 1779, 1779, 1779, 1779, 1779, + /* 350 */ 1779, 1779, 1779, 2078, 2077, 2201, 1779, 1779, 2202, 2200, + /* 360 */ 2199, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 370 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 380 */ 1779, 1779, 1779, 1779, 1779, 2364, 2368, 1779, 1779, 1779, + /* 390 */ 1779, 1779, 1779, 2284, 1779, 1779, 1779, 2183, 1779, 1779, + /* 400 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 410 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 420 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 430 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 440 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 450 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 460 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 470 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 480 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 490 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 500 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 510 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 520 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 530 */ 1779, 1816, 2188, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 540 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 550 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 560 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 570 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 580 */ 1779, 1779, 1779, 1907, 1906, 1779, 1779, 1779, 1779, 1779, + /* 590 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 600 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 2192, 1779, 1779, + /* 610 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 620 */ 1779, 1779, 1779, 1779, 1779, 1779, 2360, 2317, 1779, 1779, + /* 630 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 640 */ 1779, 1779, 1779, 1779, 1779, 1779, 2183, 1779, 2342, 1779, + /* 650 */ 1779, 2358, 1779, 2362, 1779, 1779, 1779, 1779, 1779, 1779, + /* 660 */ 1779, 2294, 2290, 1779, 1779, 2286, 1779, 1779, 1779, 1779, + /* 670 */ 1779, 2191, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 680 */ 1779, 1779, 1779, 1779, 1779, 2182, 1779, 2245, 1779, 1779, + /* 690 */ 1779, 2279, 1779, 1779, 2230, 1779, 1779, 1779, 1779, 1779, + /* 700 */ 1779, 1779, 1779, 1779, 2192, 1779, 2195, 1779, 1779, 1779, + /* 710 */ 1779, 1779, 1986, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 720 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1970, 1968, + /* 730 */ 1967, 1966, 1779, 1963, 1779, 1999, 1779, 1779, 1779, 1995, + /* 740 */ 1994, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 750 */ 1779, 1779, 1779, 1779, 1887, 1779, 1779, 1779, 1779, 1779, + /* 760 */ 1779, 1779, 1779, 1879, 1779, 1878, 1779, 1779, 1779, 1779, + /* 770 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 780 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + /* 790 */ 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, }; /********** End of lemon-generated parsing tables *****************************/ @@ -1853,15 +1886,15 @@ static const char *const yyTokenName[] = { /* 376 */ "multi_drop_clause", /* 377 */ "alter_table_clause", /* 378 */ "alter_table_options", - /* 379 */ "column_name", - /* 380 */ "type_name", + /* 379 */ "column_def", + /* 380 */ "column_name", /* 381 */ "signed_literal", /* 382 */ "create_subtable_clause", /* 383 */ "specific_cols_opt", /* 384 */ "expression_list", /* 385 */ "drop_table_clause", /* 386 */ "col_name_list", - /* 387 */ "column_def", + /* 387 */ "type_name", /* 388 */ "duration_list", /* 389 */ "rollup_func_list", /* 390 */ "alter_table_option", @@ -2128,13 +2161,13 @@ static const char *const yyRuleName[] = { /* 157 */ "cmd ::= ALTER TABLE alter_table_clause", /* 158 */ "cmd ::= ALTER STABLE alter_table_clause", /* 159 */ "alter_table_clause ::= full_table_name alter_table_options", - /* 160 */ "alter_table_clause ::= full_table_name ADD COLUMN column_name type_name", + /* 160 */ "alter_table_clause ::= full_table_name ADD COLUMN column_def", /* 161 */ "alter_table_clause ::= full_table_name DROP COLUMN column_name", - /* 162 */ "alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name", + /* 162 */ "alter_table_clause ::= full_table_name MODIFY COLUMN column_def", /* 163 */ "alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name", - /* 164 */ "alter_table_clause ::= full_table_name ADD TAG column_name type_name", + /* 164 */ "alter_table_clause ::= full_table_name ADD TAG column_def", /* 165 */ "alter_table_clause ::= full_table_name DROP TAG column_name", - /* 166 */ "alter_table_clause ::= full_table_name MODIFY TAG column_name type_name", + /* 166 */ "alter_table_clause ::= full_table_name MODIFY TAG column_def", /* 167 */ "alter_table_clause ::= full_table_name RENAME TAG column_name column_name", /* 168 */ "alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal", /* 169 */ "multi_create_clause ::= create_subtable_clause", @@ -2709,10 +2742,10 @@ static void yy_destructor( case 373: /* table_options */ case 377: /* alter_table_clause */ case 378: /* alter_table_options */ + case 379: /* column_def */ case 381: /* signed_literal */ case 382: /* create_subtable_clause */ case 385: /* drop_table_clause */ - case 387: /* column_def */ case 391: /* duration_literal */ case 392: /* rollup_func_name */ case 394: /* col_name */ @@ -2788,7 +2821,7 @@ static void yy_destructor( case 351: /* table_name */ case 352: /* topic_name */ case 354: /* dnode_endpoint */ - case 379: /* column_name */ + case 380: /* column_name */ case 393: /* function_name */ case 401: /* column_alias */ case 404: /* index_name */ @@ -2873,7 +2906,7 @@ static void yy_destructor( } break; - case 380: /* type_name */ + case 387: /* type_name */ { } @@ -3350,13 +3383,13 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 338, /* (157) cmd ::= ALTER TABLE alter_table_clause */ 338, /* (158) cmd ::= ALTER STABLE alter_table_clause */ 377, /* (159) alter_table_clause ::= full_table_name alter_table_options */ - 377, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ + 377, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_def */ 377, /* (161) alter_table_clause ::= full_table_name DROP COLUMN column_name */ - 377, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ + 377, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_def */ 377, /* (163) alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ - 377, /* (164) alter_table_clause ::= full_table_name ADD TAG column_name type_name */ + 377, /* (164) alter_table_clause ::= full_table_name ADD TAG column_def */ 377, /* (165) alter_table_clause ::= full_table_name DROP TAG column_name */ - 377, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ + 377, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_def */ 377, /* (167) alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ 377, /* (168) alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ 374, /* (169) multi_create_clause ::= create_subtable_clause */ @@ -3371,32 +3404,32 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 370, /* (178) full_table_name ::= db_name NK_DOT table_name */ 371, /* (179) column_def_list ::= column_def */ 371, /* (180) column_def_list ::= column_def_list NK_COMMA column_def */ - 387, /* (181) column_def ::= column_name type_name */ - 387, /* (182) column_def ::= column_name type_name COMMENT NK_STRING */ - 380, /* (183) type_name ::= BOOL */ - 380, /* (184) type_name ::= TINYINT */ - 380, /* (185) type_name ::= SMALLINT */ - 380, /* (186) type_name ::= INT */ - 380, /* (187) type_name ::= INTEGER */ - 380, /* (188) type_name ::= BIGINT */ - 380, /* (189) type_name ::= FLOAT */ - 380, /* (190) type_name ::= DOUBLE */ - 380, /* (191) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ - 380, /* (192) type_name ::= TIMESTAMP */ - 380, /* (193) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ - 380, /* (194) type_name ::= TINYINT UNSIGNED */ - 380, /* (195) type_name ::= SMALLINT UNSIGNED */ - 380, /* (196) type_name ::= INT UNSIGNED */ - 380, /* (197) type_name ::= BIGINT UNSIGNED */ - 380, /* (198) type_name ::= JSON */ - 380, /* (199) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ - 380, /* (200) type_name ::= MEDIUMBLOB */ - 380, /* (201) type_name ::= BLOB */ - 380, /* (202) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ - 380, /* (203) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ - 380, /* (204) type_name ::= DECIMAL */ - 380, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ - 380, /* (206) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + 379, /* (181) column_def ::= column_name type_name */ + 379, /* (182) column_def ::= column_name type_name COMMENT NK_STRING */ + 387, /* (183) type_name ::= BOOL */ + 387, /* (184) type_name ::= TINYINT */ + 387, /* (185) type_name ::= SMALLINT */ + 387, /* (186) type_name ::= INT */ + 387, /* (187) type_name ::= INTEGER */ + 387, /* (188) type_name ::= BIGINT */ + 387, /* (189) type_name ::= FLOAT */ + 387, /* (190) type_name ::= DOUBLE */ + 387, /* (191) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + 387, /* (192) type_name ::= TIMESTAMP */ + 387, /* (193) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + 387, /* (194) type_name ::= TINYINT UNSIGNED */ + 387, /* (195) type_name ::= SMALLINT UNSIGNED */ + 387, /* (196) type_name ::= INT UNSIGNED */ + 387, /* (197) type_name ::= BIGINT UNSIGNED */ + 387, /* (198) type_name ::= JSON */ + 387, /* (199) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + 387, /* (200) type_name ::= MEDIUMBLOB */ + 387, /* (201) type_name ::= BLOB */ + 387, /* (202) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + 387, /* (203) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ + 387, /* (204) type_name ::= DECIMAL */ + 387, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + 387, /* (206) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ 372, /* (207) tags_def_opt ::= */ 372, /* (208) tags_def_opt ::= tags_def */ 375, /* (209) tags_def ::= TAGS NK_LP column_def_list NK_RP */ @@ -3591,7 +3624,7 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 430, /* (398) literal_list ::= literal_list NK_COMMA signed_literal */ 350, /* (399) db_name ::= NK_ID */ 351, /* (400) table_name ::= NK_ID */ - 379, /* (401) column_name ::= NK_ID */ + 380, /* (401) column_name ::= NK_ID */ 393, /* (402) function_name ::= NK_ID */ 431, /* (403) table_alias ::= NK_ID */ 401, /* (404) column_alias ::= NK_ID */ @@ -3956,13 +3989,13 @@ static const signed char yyRuleInfoNRhs[] = { -3, /* (157) cmd ::= ALTER TABLE alter_table_clause */ -3, /* (158) cmd ::= ALTER STABLE alter_table_clause */ -2, /* (159) alter_table_clause ::= full_table_name alter_table_options */ - -5, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ + -4, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_def */ -4, /* (161) alter_table_clause ::= full_table_name DROP COLUMN column_name */ - -5, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ + -4, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_def */ -5, /* (163) alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ - -5, /* (164) alter_table_clause ::= full_table_name ADD TAG column_name type_name */ + -4, /* (164) alter_table_clause ::= full_table_name ADD TAG column_def */ -4, /* (165) alter_table_clause ::= full_table_name DROP TAG column_name */ - -5, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ + -4, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_def */ -5, /* (167) alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ -6, /* (168) alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ -1, /* (169) multi_create_clause ::= create_subtable_clause */ @@ -5058,33 +5091,33 @@ static YYACTIONTYPE yy_reduce( { yylhsminor.yy452 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 160: /* alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ -{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } - yymsp[-4].minor.yy452 = yylhsminor.yy452; + case 160: /* alter_table_clause ::= full_table_name ADD COLUMN column_def */ +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_ADD_COLUMN, yymsp[0].minor.yy452); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 161: /* alter_table_clause ::= full_table_name DROP COLUMN column_name */ { yylhsminor.yy452 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy371); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 162: /* alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ -{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } - yymsp[-4].minor.yy452 = yylhsminor.yy452; + case 162: /* alter_table_clause ::= full_table_name MODIFY COLUMN column_def */ +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, yymsp[0].minor.yy452); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 163: /* alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ { yylhsminor.yy452 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 164: /* alter_table_clause ::= full_table_name ADD TAG column_name type_name */ -{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } - yymsp[-4].minor.yy452 = yylhsminor.yy452; + case 164: /* alter_table_clause ::= full_table_name ADD TAG column_def */ +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_ADD_TAG, yymsp[0].minor.yy452); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 165: /* alter_table_clause ::= full_table_name DROP TAG column_name */ { yylhsminor.yy452 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy371); } yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 166: /* alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ -{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } - yymsp[-4].minor.yy452 = yylhsminor.yy452; + case 166: /* alter_table_clause ::= full_table_name MODIFY TAG column_def */ +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, yymsp[0].minor.yy452); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 167: /* alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ { yylhsminor.yy452 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } diff --git a/tests/system-test/0-others/show.py b/tests/system-test/0-others/show.py index 7366a4f60a..64a0a8b48d 100644 --- a/tests/system-test/0-others/show.py +++ b/tests/system-test/0-others/show.py @@ -215,12 +215,51 @@ class TDTestCase: tdSql.execute("use comment_test_db") tdSql.execute("create table normal_table(ts timestamp, c2 int comment 'c2 comment')") tdSql.execute("create stable super_table(ts timestamp comment 'ts', c2 int comment 'c2 comment') tags(tg int comment 'tg comment')") - tdSql.query('show create table normal_table') + create_sql = "create table `normal_table` (`ts` timestamp, `c2` int)" + tdSql.query('show create table normal_table') tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) tdSql.query('show create table super_table') create_sql = "create stable `super_table` (`ts` timestamp, `c2` int) tags (`tg` int)" tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + tdSql.execute("drop database comment_test_db") + + def alter_table_with_col_comment(self): + tdSql.execute("create database comment_test_db") + tdSql.execute("use comment_test_db") + tdSql.execute("create table normal_table(ts timestamp, c2 int comment 'c2 comment')") + tdSql.execute("create stable super_table(ts timestamp comment 'ts', c2 int comment 'c2 comment') tags(tg int comment 'tg comment')") + + create_sql = "create table `normal_table` (`ts` timestamp, `c2` int, `c3` int)" + tdSql.execute("alter table normal_table add column c3 int comment 'c3 comment'", queryTimes=1) + tdSql.query("show create table normal_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create table `normal_table` (`ts` timestamp, `c2` int, `c3` int, `c4` varchar(255))" + tdSql.execute("alter table normal_table add column c4 varchar(255) comment 'c4 comment'", queryTimes=1) + tdSql.query("show create table normal_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create table `normal_table` (`ts` timestamp, `c2` int, `c3` int, `c4` varchar(255), `c5` varchar(255))" + tdSql.execute("alter table normal_table add column c5 varchar(255)", queryTimes=1) + tdSql.query("show create table normal_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create stable `super_table` (`ts` timestamp, `c2` int, `c3` int) tags (`tg` int) sma(`ts`,`c2`)" + tdSql.execute("alter table super_table add column c3 int comment 'c3 comment'", queryTimes=1) + tdSql.query("show create table super_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create stable `super_table` (`ts` timestamp, `c2` int, `c3` int, `c4` varchar(255)) tags (`tg` int) sma(`ts`,`c2`)" + tdSql.execute("alter table super_table add column c4 varchar(255) comment 'c4 comment'", queryTimes=1) + tdSql.query("show create table super_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create stable `super_table` (`ts` timestamp, `c2` int, `c3` int, `c4` varchar(256)) tags (`tg` int) sma(`ts`,`c2`)" + tdSql.execute("alter table super_table modify column c4 varchar(256) comment 'c4 256 comment'", queryTimes=1) + tdSql.query("show create table super_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + tdSql.execute("drop database comment_test_db") def run(self): self.check_gitinfo() @@ -231,6 +270,7 @@ class TDTestCase: self.show_create_sysdb_sql() self.show_create_systb_sql() self.show_create_table_with_col_comment() + self.alter_table_with_col_comment() def stop(self): tdSql.close() From e587cc50e64af3ff7b3a7912da655f073a5fb7b6 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Thu, 10 Aug 2023 11:09:21 +0800 Subject: [PATCH 86/92] feat: optimize select agg_func partition by tag slimit --- include/libs/nodes/plannodes.h | 2 + source/libs/executor/src/executor.c | 9 +++- source/libs/nodes/src/nodesCodeFuncs.c | 14 ++++++ source/libs/nodes/src/nodesMsgFuncs.c | 12 +++++ source/libs/planner/inc/planInt.h | 10 +++- source/libs/planner/src/planOptimizer.c | 34 ++++++-------- source/libs/planner/src/planPhysiCreater.c | 10 +++- source/libs/planner/src/planSpliter.c | 10 +++- source/libs/planner/src/planUtil.c | 53 ++++++++++++++++++++-- 9 files changed, 124 insertions(+), 30 deletions(-) diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 063318332a..4b6704df43 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -603,6 +603,8 @@ typedef struct SSubplan { SNode* pTagCond; SNode* pTagIndexCond; bool showRewrite; + int32_t rowsThreshold; + bool dynamicRowThreshold; } SSubplan; typedef enum EExplainMode { EXPLAIN_MODE_DISABLE = 1, EXPLAIN_MODE_STATIC, EXPLAIN_MODE_ANALYZE } EExplainMode; diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index 05767db286..b101a5916c 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -589,6 +589,10 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo int64_t st = taosGetTimestampUs(); int32_t blockIndex = 0; + int32_t rowsThreshold = pTaskInfo->pSubplan->rowsThreshold; + if (!pTaskInfo->pSubplan->dynamicRowThreshold || 4096 <= pTaskInfo->pSubplan->rowsThreshold) { + rowsThreshold = 4096; + } while ((pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot)) != NULL) { SSDataBlock* p = NULL; if (blockIndex >= taosArrayGetSize(pTaskInfo->pResultBlockList)) { @@ -606,10 +610,13 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo ASSERT(p->info.rows > 0); taosArrayPush(pResList, &p); - if (current >= 4096) { + if (current >= rowsThreshold) { break; } } + if (pTaskInfo->pSubplan->dynamicRowThreshold) { + pTaskInfo->pSubplan->rowsThreshold -= current; + } *hasMore = (pRes != NULL); uint64_t el = (taosGetTimestampUs() - st); diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index f25616065e..dc53dbb230 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -2814,6 +2814,8 @@ static const char* jkSubplanDataSink = "DataSink"; static const char* jkSubplanTagCond = "TagCond"; static const char* jkSubplanTagIndexCond = "TagIndexCond"; static const char* jkSubplanShowRewrite = "ShowRewrite"; +static const char* jkSubplanRowsThreshold = "RowThreshold"; +static const char* jkSubplanDynamicRowsThreshold = "DyRowThreshold"; static int32_t subplanToJson(const void* pObj, SJson* pJson) { const SSubplan* pNode = (const SSubplan*)pObj; @@ -2852,6 +2854,12 @@ static int32_t subplanToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = tjsonAddBoolToObject(pJson, jkSubplanShowRewrite, pNode->showRewrite); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkSubplanRowsThreshold, pNode->rowsThreshold); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddBoolToObject(pJson, jkSubplanDynamicRowsThreshold, pNode->dynamicRowThreshold); + } return code; } @@ -2893,6 +2901,12 @@ static int32_t jsonToSubplan(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tjsonGetBoolValue(pJson, jkSubplanShowRewrite, &pNode->showRewrite); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetIntValue(pJson, jkSubplanRowsThreshold, &pNode->rowsThreshold); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBoolValue(pJson, jkSubplanDynamicRowsThreshold, &pNode->dynamicRowThreshold); + } return code; } diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index 20e829766d..37315c9f42 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -3538,6 +3538,12 @@ static int32_t subplanInlineToMsg(const void* pObj, STlvEncoder* pEncoder) { if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeValueBool(pEncoder, pNode->showRewrite); } + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeValueI32(pEncoder, pNode->rowsThreshold); + } + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeValueBool(pEncoder, pNode->dynamicRowThreshold); + } return code; } @@ -3587,6 +3593,12 @@ static int32_t msgToSubplanInline(STlvDecoder* pDecoder, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tlvDecodeValueBool(pDecoder, &pNode->showRewrite); } + if (TSDB_CODE_SUCCESS == code) { + code = tlvDecodeValueI32(pDecoder, &pNode->rowsThreshold); + } + if (TSDB_CODE_SUCCESS == code) { + code = tlvDecodeValueBool(pDecoder, &pNode->dynamicRowThreshold); + } return code; } diff --git a/source/libs/planner/inc/planInt.h b/source/libs/planner/inc/planInt.h index 092fe17411..24d77cb9a4 100644 --- a/source/libs/planner/inc/planInt.h +++ b/source/libs/planner/inc/planInt.h @@ -43,8 +43,14 @@ int32_t splitLogicPlan(SPlanContext* pCxt, SLogicSubplan* pLogicSubplan); int32_t scaleOutLogicPlan(SPlanContext* pCxt, SLogicSubplan* pLogicSubplan, SQueryLogicPlan** pLogicPlan); int32_t createPhysiPlan(SPlanContext* pCxt, SQueryLogicPlan* pLogicPlan, SQueryPlan** pPlan, SArray* pExecNodeList); -bool isPartTableAgg(SAggLogicNode* pAgg); -bool isPartTableWinodw(SWindowLogicNode* pWindow); +bool isPartTableAgg(SAggLogicNode* pAgg); +bool isPartTagAgg(SAggLogicNode* pAgg); +bool isPartTableWinodw(SWindowLogicNode* pWindow); + +#define CLONE_LIMIT 1 +#define CLONE_SLIMIT 1 << 1 +#define CLONE_LIMIT_SLIMIT (CLONE_LIMIT | CLONE_SLIMIT) +bool cloneLimit(SLogicNode* pParent, SLogicNode* pChild, uint8_t cloneWhat); #ifdef __cplusplus } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 16440be511..c73da5e19d 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -368,8 +368,8 @@ static void scanPathOptSetGroupOrderScan(SScanLogicNode* pScan) { if (pScan->node.pParent && nodeType(pScan->node.pParent) == QUERY_NODE_LOGIC_PLAN_AGG) { SAggLogicNode* pAgg = (SAggLogicNode*)pScan->node.pParent; - bool withSlimit = pAgg->node.pSlimit != NULL || (pAgg->node.pParent && pAgg->node.pParent->pSlimit); - if (withSlimit && isPartTableAgg(pAgg)) { + bool withSlimit = pAgg->node.pSlimit != NULL; + if (withSlimit && (isPartTableAgg(pAgg) || isPartTagAgg(pAgg))) { pScan->groupOrderScan = pAgg->node.forceCreateNonBlockingOptr = true; } } @@ -2698,39 +2698,31 @@ static void swapLimit(SLogicNode* pParent, SLogicNode* pChild) { pParent->pLimit = NULL; } -static void cloneLimit(SLogicNode* pParent, SLogicNode* pChild) { - SLimitNode* pLimit = NULL; - if (pParent->pLimit) { - pChild->pLimit = nodesCloneNode(pParent->pLimit); - pLimit = (SLimitNode*)pChild->pLimit; - pLimit->limit += pLimit->offset; - pLimit->offset = 0; - } - - if (pParent->pSlimit) { - pChild->pSlimit = nodesCloneNode(pParent->pSlimit); - pLimit = (SLimitNode*)pChild->pSlimit; - pLimit->limit += pLimit->offset; - pLimit->offset = 0; - } -} - static bool pushDownLimitHow(SLogicNode* pNodeWithLimit, SLogicNode* pNodeLimitPushTo); static bool pushDownLimitTo(SLogicNode* pNodeWithLimit, SLogicNode* pNodeLimitPushTo) { switch (nodeType(pNodeLimitPushTo)) { case QUERY_NODE_LOGIC_PLAN_WINDOW: { SWindowLogicNode* pWindow = (SWindowLogicNode*)pNodeLimitPushTo; if (pWindow->winType != WINDOW_TYPE_INTERVAL) break; - cloneLimit(pNodeWithLimit, pNodeLimitPushTo); + cloneLimit(pNodeWithLimit, pNodeLimitPushTo, CLONE_LIMIT_SLIMIT); return true; } case QUERY_NODE_LOGIC_PLAN_FILL: case QUERY_NODE_LOGIC_PLAN_SORT: { - cloneLimit(pNodeWithLimit, pNodeLimitPushTo); + cloneLimit(pNodeWithLimit, pNodeLimitPushTo, CLONE_LIMIT_SLIMIT); SNode* pChild = NULL; FOREACH(pChild, pNodeLimitPushTo->pChildren) { pushDownLimitHow(pNodeLimitPushTo, (SLogicNode*)pChild); } return true; } + case QUERY_NODE_LOGIC_PLAN_AGG: { + if (nodeType(pNodeWithLimit) == QUERY_NODE_LOGIC_PLAN_PROJECT && + (isPartTagAgg((SAggLogicNode*)pNodeLimitPushTo) || isPartTableAgg((SAggLogicNode*)pNodeLimitPushTo))) { + // when part by tag, slimit will be cloned to agg, and it will be pipelined. + // The scan below will do scanning with group order + return cloneLimit(pNodeWithLimit, pNodeLimitPushTo, CLONE_SLIMIT); + } + break; + } case QUERY_NODE_LOGIC_PLAN_SCAN: if (nodeType(pNodeWithLimit) == QUERY_NODE_LOGIC_PLAN_PROJECT && pNodeWithLimit->pLimit) { swapLimit(pNodeWithLimit, pNodeLimitPushTo); diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 1b92dcd2e7..ee7aea9deb 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -872,12 +872,16 @@ static int32_t rewritePrecalcExpr(SPhysiPlanContext* pCxt, SNode* pNode, SNodeLi } static int32_t createAggPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SAggLogicNode* pAggLogicNode, - SPhysiNode** pPhyNode) { + SPhysiNode** pPhyNode, SSubplan* pSubPlan) { SAggPhysiNode* pAgg = (SAggPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pAggLogicNode, QUERY_NODE_PHYSICAL_PLAN_HASH_AGG); if (NULL == pAgg) { return TSDB_CODE_OUT_OF_MEMORY; } + if (pAgg->node.pSlimit) { + pSubPlan->dynamicRowThreshold = true; + pSubPlan->rowsThreshold = ((SLimitNode*)pAgg->node.pSlimit)->limit; + } pAgg->mergeDataBlock = (GROUP_ACTION_KEEP == pAggLogicNode->node.groupAction ? false : true); pAgg->groupKeyOptimized = pAggLogicNode->hasGroupKeyOptimized; @@ -1617,7 +1621,7 @@ static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode case QUERY_NODE_LOGIC_PLAN_JOIN: return createJoinPhysiNode(pCxt, pChildren, (SJoinLogicNode*)pLogicNode, pPhyNode); case QUERY_NODE_LOGIC_PLAN_AGG: - return createAggPhysiNode(pCxt, pChildren, (SAggLogicNode*)pLogicNode, pPhyNode); + return createAggPhysiNode(pCxt, pChildren, (SAggLogicNode*)pLogicNode, pPhyNode, pSubplan); case QUERY_NODE_LOGIC_PLAN_PROJECT: return createProjectPhysiNode(pCxt, pChildren, (SProjectLogicNode*)pLogicNode, pPhyNode); case QUERY_NODE_LOGIC_PLAN_EXCHANGE: @@ -1721,6 +1725,8 @@ static SSubplan* makeSubplan(SPhysiPlanContext* pCxt, SLogicSubplan* pLogicSubpl pSubplan->id = pLogicSubplan->id; pSubplan->subplanType = pLogicSubplan->subplanType; pSubplan->level = pLogicSubplan->level; + pSubplan->rowsThreshold = 4096; + pSubplan->dynamicRowThreshold = false; if (NULL != pCxt->pPlanCxt->pUser) { snprintf(pSubplan->user, sizeof(pSubplan->user), "%s", pCxt->pPlanCxt->pUser); } diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 3f6c73b4e5..868aee7147 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -867,8 +867,16 @@ static int32_t stbSplSplitAggNodeForPartTable(SSplitContext* pCxt, SStableSplitI static int32_t stbSplSplitAggNodeForCrossTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) { SLogicNode* pPartAgg = NULL; int32_t code = stbSplCreatePartAggNode((SAggLogicNode*)pInfo->pSplitNode, &pPartAgg); + + if (TSDB_CODE_SUCCESS == code) { - code = stbSplCreateExchangeNode(pCxt, pInfo->pSplitNode, pPartAgg); + // if slimit was pushed down to agg, agg will be pipelined mode, add sort merge before parent agg + if ((SAggLogicNode*)pInfo->pSplitNode->pSlimit) + code = stbSplCreateMergeNode(pCxt, NULL, pInfo->pSplitNode, NULL, pPartAgg, true); + else + code = stbSplCreateExchangeNode(pCxt, pInfo->pSplitNode, pPartAgg); + } else { + nodesDestroyNode((SNode*)pPartAgg); } if (TSDB_CODE_SUCCESS == code) { code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren, diff --git a/source/libs/planner/src/planUtil.c b/source/libs/planner/src/planUtil.c index 88086cde1d..9febe102f6 100644 --- a/source/libs/planner/src/planUtil.c +++ b/source/libs/planner/src/planUtil.c @@ -349,7 +349,7 @@ static bool stbHasPartTbname(SNodeList* pPartKeys) { return false; } -static SNodeList* stbSplGetPartKeys(SLogicNode* pNode) { +static SNodeList* stbGetPartKeys(SLogicNode* pNode) { if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) { return ((SScanLogicNode*)pNode)->pGroupTags; } else if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode)) { @@ -367,11 +367,58 @@ bool isPartTableAgg(SAggLogicNode* pAgg) { return stbHasPartTbname(pAgg->pGroupKeys) && stbNotSystemScan((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0)); } - return stbHasPartTbname(stbSplGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))); + return stbHasPartTbname(stbGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))); +} + +static bool stbHasPartTag(SNodeList* pPartKeys) { + if (NULL == pPartKeys) { + return false; + } + SNode* pPartKey = NULL; + FOREACH(pPartKey, pPartKeys) { + if (QUERY_NODE_GROUPING_SET == nodeType(pPartKey)) { + pPartKey = nodesListGetNode(((SGroupingSetNode*)pPartKey)->pParameterList, 0); + } + if ((QUERY_NODE_FUNCTION == nodeType(pPartKey) && FUNCTION_TYPE_TAGS == ((SFunctionNode*)pPartKey)->funcType) || + (QUERY_NODE_COLUMN == nodeType(pPartKey) && COLUMN_TYPE_TAG == ((SColumnNode*)pPartKey)->colType)) { + return true; + } + } + return false; +} + +bool isPartTagAgg(SAggLogicNode* pAgg) { + if (1 != LIST_LENGTH(pAgg->node.pChildren)) { + return false; + } + if (pAgg->pGroupKeys) { + return stbHasPartTag(pAgg->pGroupKeys) && + stbNotSystemScan((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0)); + } + return stbHasPartTag(stbGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))); } bool isPartTableWinodw(SWindowLogicNode* pWindow) { - return stbHasPartTbname(stbSplGetPartKeys((SLogicNode*)nodesListGetNode(pWindow->node.pChildren, 0))); + return stbHasPartTbname(stbGetPartKeys((SLogicNode*)nodesListGetNode(pWindow->node.pChildren, 0))); } +bool cloneLimit(SLogicNode* pParent, SLogicNode* pChild, uint8_t cloneWhat) { + SLimitNode* pLimit; + bool cloned = false; + if (pParent->pLimit && (cloneWhat & CLONE_LIMIT)) { + pChild->pLimit = nodesCloneNode(pParent->pLimit); + pLimit = (SLimitNode*)pChild->pLimit; + pLimit->limit += pLimit->offset; + pLimit->offset = 0; + cloned = true; + } + if (pParent->pSlimit && (cloneWhat & CLONE_SLIMIT)) { + pChild->pSlimit = nodesCloneNode(pParent->pSlimit); + pLimit = (SLimitNode*)pChild->pSlimit; + pLimit->limit += pLimit->offset; + pLimit->offset = 0; + cloned = true; + } + return cloned; +} From ec84d7fd81deb3a9c9bedf34a2a1d8747f12bca5 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Aug 2023 19:00:35 +0800 Subject: [PATCH 87/92] fix(stream): add the back pressure for sink node. --- source/libs/stream/src/stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index af67490888..03a0f3586d 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -362,7 +362,7 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { msgLen, ver, total, size + msgLen/1048576.0); } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE || type == STREAM_INPUT__REF_DATA_BLOCK) { - if ((pTask->info.taskLevel == TASK_LEVEL__SOURCE) && (tInputQueueIsFull(pTask))) { + if (/*(pTask->info.taskLevel == TASK_LEVEL__SOURCE) && */(tInputQueueIsFull(pTask))) { qError("s-task:%s input queue is full, capacity:%d size:%d MiB, current(blocks:%d, size:%.2fMiB) abort", pTask->id.idStr, STREAM_TASK_INPUT_QUEUE_CAPACITY, STREAM_TASK_INPUT_QUEUE_CAPACITY_IN_SIZE, total, size); From 9a76ae72d625c3e97ab9968f47321b7512e9cac9 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Aug 2023 19:11:43 +0800 Subject: [PATCH 88/92] fix(stream): add the back pressure for sink node. --- source/dnode/vnode/src/tq/tqRestore.c | 7 +++++++ source/libs/stream/src/streamExec.c | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/source/dnode/vnode/src/tq/tqRestore.c b/source/dnode/vnode/src/tq/tqRestore.c index d363031db1..ed612587f5 100644 --- a/source/dnode/vnode/src/tq/tqRestore.c +++ b/source/dnode/vnode/src/tq/tqRestore.c @@ -287,6 +287,13 @@ int32_t createStreamTaskRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) { continue; } + // downstream task has blocked the output, stopped for a while + if (pTask->inputStatus == TASK_INPUT_STATUS__BLOCKED) { + tqDebug("s-task:%s inputQ is blocked, do nothing", pTask->id.idStr); + streamMetaReleaseTask(pStreamMeta, pTask); + continue; + } + *pScanIdle = false; // seek the stored version and extract data from WAL diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 02bbce6485..d761c5ad24 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -191,6 +191,12 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSize) { return 0; } + if (pTask->inputStatus == TASK_INPUT_STATUS__BLOCKED) { + qDebug("s-task:%s inputQ is blocked, wait for 5sec and retry", pTask->id.idStr); + taosMsleep(10000); + continue; + } + SSDataBlock* output = NULL; uint64_t ts = 0; code = qExecTask(exec, &output, &ts); From cc62c400c6b697d7c0f89bdaa731224c879d534b Mon Sep 17 00:00:00 2001 From: kailixu Date: Wed, 16 Aug 2023 19:13:24 +0800 Subject: [PATCH 89/92] fix: tmq drop/common python script on windows --- tests/system-test/7-tmq/tmqCommon.py | 30 ++++++++++++++++------ tests/system-test/7-tmq/tmqDropConsumer.py | 5 +++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/tests/system-test/7-tmq/tmqCommon.py b/tests/system-test/7-tmq/tmqCommon.py index 3ea8273e7f..c1583be009 100644 --- a/tests/system-test/7-tmq/tmqCommon.py +++ b/tests/system-test/7-tmq/tmqCommon.py @@ -578,18 +578,32 @@ class TMQCom: tdLog.info("wait subscriptions exit for %d s"%wait_cnt) def killProcesser(self, processerName): - killCmd = ( - "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs kill -TERM > /dev/null 2>&1" - % processerName - ) - - psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % processerName - processID = subprocess.check_output(psCmd, shell=True) + if platform.system().lower() == 'windows': + killCmd = ("wmic process where name=\"%s.exe\" call terminate > NUL 2>&1" % processerName) + psCmd = ("wmic process where name=\"%s.exe\" | findstr \"%s.exe\"" % (processerName, processerName)) + else: + killCmd = ( + "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs kill -TERM > /dev/null 2>&1" + % processerName + ) + psCmd = ("ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % processerName) + processID = "" + + try: + processID = subprocess.check_output(psCmd, shell=True) + except Exception as err: + processID = "" + print('**** warn: ', err) + while processID: os.system(killCmd) time.sleep(1) - processID = subprocess.check_output(psCmd, shell=True) + try: + processID = subprocess.check_output(psCmd, shell=True) + except Exception as err: + processID = "" + print('**** warn: ', err) def close(self): self.cursor.close() diff --git a/tests/system-test/7-tmq/tmqDropConsumer.py b/tests/system-test/7-tmq/tmqDropConsumer.py index 06ce4c0fd7..0f8cffa595 100644 --- a/tests/system-test/7-tmq/tmqDropConsumer.py +++ b/tests/system-test/7-tmq/tmqDropConsumer.py @@ -176,7 +176,10 @@ class TDTestCase: # use taosBenchmark to subscribe binPath = self.getPath() - cmd = "nohup %s -f ./7-tmq/tmqDropConsumer.json > /dev/null 2>&1 & " % binPath + if platform.system().lower() == 'windows': + cmd = f"mintty -h never %s -f ./7-tmq/tmqDropConsumer.json > NUL 2>&1" % binPath + else: + cmd = f"nohup %s -f ./7-tmq/tmqDropConsumer.json > /dev/null 2>&1 & " % binPath tdLog.info("%s"%(cmd)) os.system(cmd) From 59d5858b95895b62e60c132c9dc9c8791ef9093b Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Aug 2023 19:22:45 +0800 Subject: [PATCH 90/92] fix(stream): fix a typo --- source/libs/stream/src/streamExec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index d761c5ad24..3ab6643802 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -192,7 +192,7 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSize) { } if (pTask->inputStatus == TASK_INPUT_STATUS__BLOCKED) { - qDebug("s-task:%s inputQ is blocked, wait for 5sec and retry", pTask->id.idStr); + qDebug("s-task:%s inputQ is blocked, wait for 10sec and retry", pTask->id.idStr); taosMsleep(10000); continue; } From cf4da465e1dc70422e09002d2f644dadee72dcec Mon Sep 17 00:00:00 2001 From: kailixu Date: Wed, 16 Aug 2023 22:43:01 +0800 Subject: [PATCH 91/92] chore: add startProcess for tmq common --- tests/system-test/7-tmq/tmqCommon.py | 8 ++++++++ tests/system-test/7-tmq/tmqDropConsumer.py | 7 +------ tests/system-test/7-tmq/tmqMaxGroupIds.py | 4 +--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/system-test/7-tmq/tmqCommon.py b/tests/system-test/7-tmq/tmqCommon.py index c1583be009..7f972d857e 100644 --- a/tests/system-test/7-tmq/tmqCommon.py +++ b/tests/system-test/7-tmq/tmqCommon.py @@ -604,6 +604,14 @@ class TMQCom: except Exception as err: processID = "" print('**** warn: ', err) + + def startProcess(self, processName, param): + if platform.system().lower() == 'windows': + cmd = f"mintty -h never %s %s > NUL 2>&1" % (processName, param) + else: + cmd = f"nohup %s %s > /dev/null 2>&1 &" % (processName, param) + tdLog.info("%s"%(cmd)) + os.system(cmd) def close(self): self.cursor.close() diff --git a/tests/system-test/7-tmq/tmqDropConsumer.py b/tests/system-test/7-tmq/tmqDropConsumer.py index 0f8cffa595..137b5c6584 100644 --- a/tests/system-test/7-tmq/tmqDropConsumer.py +++ b/tests/system-test/7-tmq/tmqDropConsumer.py @@ -176,12 +176,7 @@ class TDTestCase: # use taosBenchmark to subscribe binPath = self.getPath() - if platform.system().lower() == 'windows': - cmd = f"mintty -h never %s -f ./7-tmq/tmqDropConsumer.json > NUL 2>&1" % binPath - else: - cmd = f"nohup %s -f ./7-tmq/tmqDropConsumer.json > /dev/null 2>&1 & " % binPath - tdLog.info("%s"%(cmd)) - os.system(cmd) + tmqCom.startProcess(binPath, "-f ./7-tmq/tmqDropConsumer.json") expectTopicNum = len(topicNameList) consumerThreadNum = 2 diff --git a/tests/system-test/7-tmq/tmqMaxGroupIds.py b/tests/system-test/7-tmq/tmqMaxGroupIds.py index d22b79a44c..75e2993a5b 100644 --- a/tests/system-test/7-tmq/tmqMaxGroupIds.py +++ b/tests/system-test/7-tmq/tmqMaxGroupIds.py @@ -176,9 +176,7 @@ class TDTestCase: # use taosBenchmark to subscribe binPath = self.getPath() - cmd = "nohup %s -f ./7-tmq/tmqMaxGroupIds.json > /dev/null 2>&1 & " % binPath - tdLog.info("%s"%(cmd)) - os.system(cmd) + tmqCom.startProcess(binPath, "-f ./7-tmq/tmqMaxGroupIds.json") expectTopicNum = 1 expectConsumerNUm = 99 From 16754b5ac166380677927960bed6b014fed2d48d Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Thu, 17 Aug 2023 11:39:34 +0800 Subject: [PATCH 92/92] feat: show create table, desc table with col comments --- include/libs/nodes/cmdnodes.h | 9 +++++---- source/common/src/tmsg.c | 4 ++-- source/dnode/vnode/src/vnd/vnodeQuery.c | 2 +- source/libs/command/src/command.c | 23 ++++++++++++++++++++--- source/libs/parser/src/parTranslater.c | 4 ++++ tests/system-test/0-others/show.py | 9 +++++++++ 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index 78b7f1babf..ff02070882 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -23,10 +23,11 @@ extern "C" { #include "query.h" #include "querynodes.h" -#define DESCRIBE_RESULT_COLS 4 -#define DESCRIBE_RESULT_FIELD_LEN (TSDB_COL_NAME_LEN - 1 + VARSTR_HEADER_SIZE) -#define DESCRIBE_RESULT_TYPE_LEN (20 + VARSTR_HEADER_SIZE) -#define DESCRIBE_RESULT_NOTE_LEN (8 + VARSTR_HEADER_SIZE) +#define DESCRIBE_RESULT_COLS 5 +#define DESCRIBE_RESULT_FIELD_LEN (TSDB_COL_NAME_LEN - 1 + VARSTR_HEADER_SIZE) +#define DESCRIBE_RESULT_TYPE_LEN (20 + VARSTR_HEADER_SIZE) +#define DESCRIBE_RESULT_NOTE_LEN (8 + VARSTR_HEADER_SIZE) +#define DESCRIBE_RESULT_COL_COMMENT_LEN (TSDB_COL_COMMENT_LEN) #define SHOW_CREATE_DB_RESULT_COLS 2 #define SHOW_CREATE_DB_RESULT_FIELD1_LEN (TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE) diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 0e48ffd05a..362c829dbc 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -2305,7 +2305,7 @@ int32_t tDeserializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp) } int32_t totalCols = pRsp->numOfTags + pRsp->numOfColumns; - pRsp->pSchemas = taosMemoryMalloc(sizeof(SSchema) * totalCols); + pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema)); if (pRsp->pSchemas == NULL) return -1; for (int32_t i = 0; i < totalCols; ++i) { @@ -3688,7 +3688,7 @@ static int32_t tDecodeSTableMetaRsp(SDecoder *pDecoder, STableMetaRsp *pRsp) { int32_t totalCols = pRsp->numOfTags + pRsp->numOfColumns; if (totalCols > 0) { - pRsp->pSchemas = taosMemoryMalloc(sizeof(SSchema) * totalCols); + pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema)); if (pRsp->pSchemas == NULL) return -1; for (int32_t i = 0; i < totalCols; ++i) { diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c index 51f4cee40c..4d422946db 100644 --- a/source/dnode/vnode/src/vnd/vnodeQuery.c +++ b/source/dnode/vnode/src/vnd/vnodeQuery.c @@ -216,7 +216,7 @@ int vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) { cfgRsp.numOfTags = schemaTag.nCols; cfgRsp.numOfColumns = schema.nCols; - cfgRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (cfgRsp.numOfColumns + cfgRsp.numOfTags)); + cfgRsp.pSchemas = (SSchema *)taosMemoryCalloc(cfgRsp.numOfColumns + cfgRsp.numOfTags, sizeof(SSchema)); memcpy(cfgRsp.pSchemas, schema.pSchema, sizeof(SSchema) * schema.nCols); if (schemaTag.nCols) { diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index 8ddf730d5a..db734e1042 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -78,6 +78,10 @@ static int32_t buildDescResultDataBlock(SSDataBlock** pOutput) { infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, DESCRIBE_RESULT_NOTE_LEN, 4); code = blockDataAppendColInfo(pBlock, &infoData); } + if (TSDB_CODE_SUCCESS == code) { + infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, DESCRIBE_RESULT_COL_COMMENT_LEN, 5); + code = blockDataAppendColInfo(pBlock, &infoData); + } if (TSDB_CODE_SUCCESS == code) { *pOutput = pBlock; @@ -99,7 +103,9 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock, SColumnInfoData* pCol3 = taosArrayGet(pBlock->pDataBlock, 2); // Note SColumnInfoData* pCol4 = taosArrayGet(pBlock->pDataBlock, 3); - char buf[DESCRIBE_RESULT_FIELD_LEN] = {0}; + // Comment + SColumnInfoData* pCol5 = taosArrayGet(pBlock->pDataBlock, 4); + char buf[DESCRIBE_RESULT_COL_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0}; for (int32_t i = 0; i < numOfRows; ++i) { if (invisibleColumn(sysInfoUser, pMeta->tableType, pMeta->schema[i].flags)) { continue; @@ -112,6 +118,8 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock, colDataSetVal(pCol3, pBlock->info.rows, (const char*)&bytes, false); STR_TO_VARSTR(buf, i >= pMeta->tableInfo.numOfColumns ? "TAG" : ""); colDataSetVal(pCol4, pBlock->info.rows, buf, false); + STR_TO_VARSTR(buf, pMeta->schema[i].comment); + colDataSetVal(pCol5, pBlock->info.rows, buf, false); ++(pBlock->info.rows); } if (pBlock->info.rows <= 0) { @@ -456,14 +464,19 @@ void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) { for (int32_t i = 0; i < pCfg->numOfColumns; ++i) { SSchema* pSchema = pCfg->pSchemas + i; char type[32]; + char comments[TSDB_COL_COMMENT_LEN + 16] = {0}; sprintf(type, "%s", tDataTypes[pSchema->type].name); if (TSDB_DATA_TYPE_VARCHAR == pSchema->type || TSDB_DATA_TYPE_GEOMETRY == pSchema->type) { sprintf(type + strlen(type), "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE)); } else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) { sprintf(type + strlen(type), "(%d)", (int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)); } + if (pSchema->comment[0]) { + sprintf(comments, " COMMENT '%s'", pSchema->comment); + } - *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type); + *len += + sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s%s", ((i > 0) ? ", " : ""), pSchema->name, type, comments); } } @@ -471,14 +484,18 @@ void appendTagFields(char* buf, int32_t* len, STableCfg* pCfg) { for (int32_t i = 0; i < pCfg->numOfTags; ++i) { SSchema* pSchema = pCfg->pSchemas + pCfg->numOfColumns + i; char type[32]; + char comments[TSDB_COL_COMMENT_LEN + 16] = {0}; sprintf(type, "%s", tDataTypes[pSchema->type].name); if (TSDB_DATA_TYPE_VARCHAR == pSchema->type || TSDB_DATA_TYPE_GEOMETRY == pSchema->type) { sprintf(type + strlen(type), "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE)); } else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) { sprintf(type + strlen(type), "(%d)", (int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)); } + if (pSchema->comment[0]) { + sprintf(comments, " COMMENT '%s'", pSchema->comment); + } - *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type); + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s%s", ((i > 0) ? ", " : ""), pSchema->name, type, comments); } } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index edd09aa0a9..cc08901399 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -7683,6 +7683,10 @@ static int32_t extractDescribeResultSchema(int32_t* numOfCols, SSchema** pSchema (*pSchema)[3].bytes = DESCRIBE_RESULT_NOTE_LEN; strcpy((*pSchema)[3].name, "note"); + (*pSchema)[4].type = TSDB_DATA_TYPE_BINARY; + (*pSchema)[4].bytes = DESCRIBE_RESULT_COL_COMMENT_LEN; + strcpy((*pSchema)[4].name, "comment"); + return TSDB_CODE_SUCCESS; } diff --git a/tests/system-test/0-others/show.py b/tests/system-test/0-others/show.py index 64a0a8b48d..5445352f43 100644 --- a/tests/system-test/0-others/show.py +++ b/tests/system-test/0-others/show.py @@ -222,6 +222,15 @@ class TDTestCase: tdSql.query('show create table super_table') create_sql = "create stable `super_table` (`ts` timestamp, `c2` int) tags (`tg` int)" tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + tdSql.query("desc normal_table") + tdSql.checkCols(5) + tdSql.checkData(0, 4, "") + + tdSql.query("desc super_table") + tdSql.checkCols(5) + tdSql.checkData(0, 4, "") + tdSql.execute("drop database comment_test_db") def alter_table_with_col_comment(self):