From 49865ed294ec75a1d0cc1b5f10a958901de21b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chappyguoxy=E2=80=9D?= <“happy_guoxy@163.com”> Date: Mon, 11 Nov 2024 14:57:06 +0800 Subject: [PATCH 01/47] test:add stream test cases --- tests/system-test/8-stream/checkpoint_info.py | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 tests/system-test/8-stream/checkpoint_info.py diff --git a/tests/system-test/8-stream/checkpoint_info.py b/tests/system-test/8-stream/checkpoint_info.py new file mode 100644 index 0000000000..00e5d1f688 --- /dev/null +++ b/tests/system-test/8-stream/checkpoint_info.py @@ -0,0 +1,139 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + + +from util.log import * +from util.cases import * +from util.sql import * +from util.common import * +from util.sqlset import * +from util.cluster import * +import threading +# should be used by -N option +class TDTestCase: + + #updatecfgDict = {'checkpointInterval': 60 ,} + def init(self, conn, logSql, replicaVar=1): + print("========init========") + + self.replicaVar = int(replicaVar) + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + def find_checkpoint_info_file(self, dirpath, checkpointid, task_id): + for root, dirs, files in os.walk(dirpath): + if f'checkpoint{checkpointid}' in dirs: + info_path = os.path.join(root, f'checkpoint{checkpointid}', 'info') + if os.path.exists(info_path): + if task_id in info_path: + return info_path + else: + continue + else: + return None + def get_dnode_info(self): + ''' + get a dict from vnode to dnode + ''' + self.vnode_dict = {} + sql = 'select dnode_id, vgroup_id from information_schema.ins_vnodes' + result = tdSql.getResult(sql) + for (dnode,vnode) in result: + self.vnode_dict[vnode] = dnode + def print_time_info(self): + ''' + sometimes, we need to wait for a while to check the info (for example, the checkpoint info file won't be created immediately after the redistribute) + ''' + times= 0 + while(True): + if(self.check_info()): + tdLog.success(f'Time to finish is {times}') + return + else: + if times > 200: + tdLog.exit("time out") + times += 10 + time.sleep(10) + def check_info(self): + ''' + first, check if the vnode is restored + ''' + while(True): + if(self.check_vnodestate()): + break + sql = 'select task_id, node_id, checkpoint_id, checkpoint_ver from information_schema.ins_stream_tasks where `level` = "source" or `level` = "agg" and node_type == "vnode"' + for task_id, vnode, checkpoint_id, checkpoint_ver in tdSql.getResult(sql): + dirpath = f"{cluster.dnodes[self.vnode_dict[vnode]-1].dataDir}/vnode/vnode{vnode}/" + info_path = self.find_checkpoint_info_file(dirpath, checkpoint_id, task_id) + if info_path is None: + return False + with open(info_path, 'r') as f: + info_id, info_ver = f.read().split() + if int(info_id) != int(checkpoint_id) or int(info_ver) != int(checkpoint_ver): + return False + return True + + def restart_stream(self): + tdLog.debug("========restart stream========") + for i in range(5): + tdSql.execute("pause stream s1") + time.sleep(2) + tdSql.execute("resume stream s1") + def initstream(self): + tdLog.debug("========case1 start========") + os.system("nohup taosBenchmark -y -B 1 -t 4 -S 500 -n 1000 -v 3 > /dev/null 2>&1 &") + time.sleep(5) + tdSql.execute("create snode on dnode 1") + tdSql.execute("use test") + tdSql.execute("create stream if not exists s1 trigger at_once ignore expired 0 ignore update 0 fill_history 1 into st1 as select _wstart,sum(voltage),groupid from meters partition by groupid interval(1s)") + tdLog.debug("========create stream using snode and insert data ok========") + self.get_dnode_info() + def redistribute_vnode(self): + tdLog.debug("========redistribute vnode========") + tdSql.redistribute_db_all_vgroups() + self.get_dnode_info() + def replicate_db(self): + tdLog.debug("========replicate db========") + while True: + res = tdSql.getResult("SHOW TRANSACTIONS") + if res == []: + tdLog.debug("========== no transaction, begin to replicate db =========") + tdSql.execute("alter database test replica 3") + return + else: + time.sleep(5) + continue + def check_vnodestate(self): + sql = 'select distinct restored from information_schema.ins_vnodes' + if tdSql.getResult(sql) != [(True,)]: + tdLog.debug(f"vnode not restored, wait 5s") + time.sleep(5) + return False + else: + return True + def run(self): + print("========run========") + self.initstream() + self.restart_stream() + time.sleep(60) + self.print_time_info() + self.redistribute_vnode() + self.restart_stream() + time.sleep(60) + self.print_time_info() + + def stop(self): + print("========stop========") + tdSql.close() + tdLog.success(f"{__file__} successfully executed") +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) \ No newline at end of file From 7eff826097036ab41a44d9faca8bb1a7e4f8e37a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chappyguoxy=E2=80=9D?= <“happy_guoxy@163.com”> Date: Mon, 11 Nov 2024 14:57:19 +0800 Subject: [PATCH 02/47] test:add stream test cases --- .../system-test/8-stream/checkpoint_info2.py | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 tests/system-test/8-stream/checkpoint_info2.py diff --git a/tests/system-test/8-stream/checkpoint_info2.py b/tests/system-test/8-stream/checkpoint_info2.py new file mode 100644 index 0000000000..7f2e8b0672 --- /dev/null +++ b/tests/system-test/8-stream/checkpoint_info2.py @@ -0,0 +1,134 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + + +from util.log import * +from util.cases import * +from util.sql import * +from util.common import * +from util.sqlset import * +from util.cluster import * + +# should be used by -N option +class TDTestCase: + updatecfgDict = {'checkpointInterval': 60 , + } + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), True) + def find_checkpoint_info_file(self, dirpath, checkpointid, task_id): + for root, dirs, files in os.walk(dirpath): + if f'checkpoint{checkpointid}' in dirs: + info_path = os.path.join(root, f'checkpoint{checkpointid}', 'info') + if os.path.exists(info_path): + if task_id in info_path: + return info_path + else: + continue + else: + return None + def get_dnode_info(self): + ''' + get a dict from vnode to dnode + ''' + self.vnode_dict = {} + sql = 'select dnode_id, vgroup_id from information_schema.ins_vnodes' + result = tdSql.getResult(sql) + for (dnode,vnode) in result: + self.vnode_dict[vnode] = dnode + def print_time_info(self): + ''' + sometimes, we need to wait for a while to check the info (for example, the checkpoint info file won't be created immediately after the redistribute) + ''' + times= 0 + while(True): + if(self.check_info()): + tdLog.success(f'Time to finish is {times}') + return + else: + if times > 400: + tdLog.exit("time out") + times += 10 + time.sleep(10) + def check_info(self): + ''' + first, check if the vnode is restored + ''' + while(True): + if(self.check_vnodestate()): + break + sql = 'select task_id, node_id, checkpoint_id, checkpoint_ver from information_schema.ins_stream_tasks where `level` = "source" or `level` = "agg" and node_type == "vnode"' + for task_id, vnode, checkpoint_id, checkpoint_ver in tdSql.getResult(sql): + dirpath = f"{cluster.dnodes[self.vnode_dict[vnode]-1].dataDir}/vnode/vnode{vnode}/" + info_path = self.find_checkpoint_info_file(dirpath, checkpoint_id, task_id) + if info_path is None: + return False + with open(info_path, 'r') as f: + info_id, info_ver = f.read().split() + if int(info_id) != int(checkpoint_id) or int(info_ver) != int(checkpoint_ver): + return False + return True + + def restart_stream(self): + tdLog.debug("========restart stream========") + for i in range(5): + tdSql.execute("pause stream s1") + time.sleep(2) + tdSql.execute("resume stream s1") + def initstream(self): + tdLog.debug("========case1 start========") + os.system("nohup taosBenchmark -y -B 1 -t 4 -S 500 -n 1000 -v 3 > /dev/null 2>&1 &") + time.sleep(5) + tdSql.execute("create snode on dnode 1") + tdSql.execute("use test") + tdSql.execute("create stream if not exists s1 trigger at_once ignore expired 0 ignore update 0 fill_history 1 into st1 as select _wstart,sum(voltage),groupid from meters partition by groupid interval(1s)") + tdLog.debug("========create stream using snode and insert data ok========") + self.get_dnode_info() + def redistribute_vnode(self): + tdLog.debug("========redistribute vnode========") + tdSql.redistribute_db_all_vgroups() + self.get_dnode_info() + def replicate_db(self): + tdLog.debug("========replicate db========") + while True: + res = tdSql.getResult("SHOW TRANSACTIONS") + if res == []: + tdLog.debug("========== no transaction, begin to replicate db =========") + tdSql.execute("alter database test replica 3") + return + else: + time.sleep(5) + continue + def check_vnodestate(self): + sql = 'select distinct restored from information_schema.ins_vnodes' + if tdSql.getResult(sql) != [(True,)]: + tdLog.debug(f"vnode not restored, wait 5s") + time.sleep(5) + return False + else: + return True + def run(self): + self.initstream() + self.replicate_db() + self.print_time_info() + self.restart_stream() + time.sleep(60) + self.print_time_info() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) \ No newline at end of file From 26e9ed055f39758490b3a8c2ce82d974bccb7f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chappyguoxy=E2=80=9D?= <“happy_guoxy@163.com”> Date: Mon, 11 Nov 2024 14:58:17 +0800 Subject: [PATCH 03/47] test:add insert test cases --- .../system-test/1-insert/test_multi_insert.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/system-test/1-insert/test_multi_insert.py diff --git a/tests/system-test/1-insert/test_multi_insert.py b/tests/system-test/1-insert/test_multi_insert.py new file mode 100644 index 0000000000..d1b6d28ffd --- /dev/null +++ b/tests/system-test/1-insert/test_multi_insert.py @@ -0,0 +1,32 @@ +from util.sql import * +from util.common import * +import taos +taos.taos_connect +class TDTestCase: + def init(self, conn, logSql, replicaVar = 1): + self.replicaVar = int(replicaVar) + tdLog.debug(f"start to excute {__file__}") + self.conn = conn + tdSql.init(conn.cursor(), logSql) + def initdb(self): + tdSql.execute("drop database if exists d0") + tdSql.execute("create database d0") + tdSql.execute("use d0") + tdSql.execute("create stable stb0 (ts timestamp, w_ts timestamp, opc nchar(100), quality int) tags(t0 int)") + tdSql.execute("create table t0 using stb0 tags(1)") + tdSql.execute("create table t1 using stb0 tags(2)") + def multi_insert(self): + for i in range(5): + tdSql.execute(f"insert into t1 values(1721265436000, now() + {i + 1}s, '0', 12) t1(opc, quality, ts) values ('opc2', 192, now()+ {i + 2}s) t1(ts, opc, quality) values(now() + {i + 3}s, 'opc4', 10) t1 values(1721265436000, now() + {i + 4}s, '1', 191) t1(opc, quality, ts) values('opc5', 192, now() + {i + 5}s) t1 values(now(), now() + {i + 6}s, '2', 192)") + tdSql.execute("insert into t0 values(1721265436000,now(),'0',192) t0(quality,w_ts,ts) values(192,now(),1721265326000) t0(quality,w_t\ +s,ts) values(190,now()+1s,1721265326000) t0 values(1721265436000,now()+2s,'1',191) t0(quality,w_ts,ts) values(192,now()+3s,\ +1721265326002) t0(ts,w_ts,opc,quality) values(1721265436003,now()+4s,'3',193) t0 values(now(), now() + 4s , '2', 192)") + def run(self): + self.initdb() + self.multi_insert() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) \ No newline at end of file From e2f43410dff3b4284a368dfcf19dce7e67c22dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chappyguoxy=E2=80=9D?= <“happy_guoxy@163.com”> Date: Mon, 11 Nov 2024 14:59:01 +0800 Subject: [PATCH 04/47] test:add stddev test cases --- tests/system-test/2-query/stddev_test.py | 54 ++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 tests/system-test/2-query/stddev_test.py diff --git a/tests/system-test/2-query/stddev_test.py b/tests/system-test/2-query/stddev_test.py new file mode 100644 index 0000000000..c0cb51fe57 --- /dev/null +++ b/tests/system-test/2-query/stddev_test.py @@ -0,0 +1,54 @@ +import numpy as np +from util.log import * +from util.cases import * +from util.sql import * +from util.common import * +from util.sqlset import * + +''' +Test case for TS-5150 +''' +class TDTestCase: + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + self.ts = 1537146000000 + def initdabase(self): + tdSql.execute('create database if not exists db_test vgroups 2 buffer 10') + tdSql.execute('use db_test') + tdSql.execute('create stable stb(ts timestamp, delay int) tags(groupid int)') + tdSql.execute('create table t1 using stb tags(1)') + tdSql.execute('create table t2 using stb tags(2)') + tdSql.execute('create table t3 using stb tags(3)') + tdSql.execute('create table t4 using stb tags(4)') + tdSql.execute('create table t5 using stb tags(5)') + tdSql.execute('create table t6 using stb tags(6)') + def insert_data(self): + for i in range(5000): + tdSql.execute(f"insert into t1 values({self.ts + i * 1000}, {i%5})") + tdSql.execute(f"insert into t2 values({self.ts + i * 1000}, {i%5})") + tdSql.execute(f"insert into t3 values({self.ts + i * 1000}, {i%5})") + + def verify_stddev(self): + for i in range(20): + tdSql.query(f'SELECT MAX(CASE WHEN delay != 0 THEN delay ELSE NULL END) AS maxDelay,\ + MIN(CASE WHEN delay != 0 THEN delay ELSE NULL END) AS minDelay,\ + AVG(CASE WHEN delay != 0 THEN delay ELSE NULL END) AS avgDelay,\ + STDDEV(CASE WHEN delay != 0 THEN delay ELSE NULL END) AS jitter,\ + COUNT(CASE WHEN delay = 0 THEN 1 ELSE NULL END) AS timeoutCount,\ + COUNT(*) AS totalCount from stb where ts between {1537146000000 + i * 1000} and {1537146000000 + (i+10) * 1000}') + res = tdSql.queryResult[0][3] + assert res > 0.8 + def run(self): + self.initdabase() + self.insert_data() + self.verify_stddev() + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) + From b38411a0767c9ed7095dbeb27d81aa8f975763a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chappyguoxy=E2=80=9D?= <“happy_guoxy@163.com”> Date: Mon, 11 Nov 2024 14:59:36 +0800 Subject: [PATCH 05/47] test:add stream test cases --- tests/pytest/util/sql.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/pytest/util/sql.py b/tests/pytest/util/sql.py index 1d3333264a..46b7e1f795 100644 --- a/tests/pytest/util/sql.py +++ b/tests/pytest/util/sql.py @@ -843,9 +843,10 @@ class TDSql: tdSql.query("select * from information_schema.ins_vnodes") #result: dnode_id|vgroup_id|db_name|status|role_time|start_time|restored| + results = list(tdSql.queryResult) for vnode_group_id in db_vgroups_list: - print(tdSql.queryResult) - for result in tdSql.queryResult: + for result in results: + print(f'result[2] is {result[2]}, db_name is {db_name}, result[1] is {result[1]}, vnode_group_id is {vnode_group_id}') if result[2] == db_name and result[1] == vnode_group_id: tdLog.debug(f"dbname: {db_name}, vgroup :{vnode_group_id}, dnode is {result[0]}") print(useful_trans_dnodes_list) From 2dbd0bacb506d0cc166b9813247d6f02a49915f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chappyguoxy=E2=80=9D?= <“happy_guoxy@163.com”> Date: Mon, 11 Nov 2024 15:00:10 +0800 Subject: [PATCH 06/47] test:add stream and query test cases --- tests/parallel_test/cases.task | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 151358aec3..2b45142156 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -230,6 +230,14 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/agg_group_NotReturnValue.py -Q 4 ,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/td-32548.py +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/stddev_test.py +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/stddev_test.py -Q 2 +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/stddev_test.py -Q 3 +,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/stddev_test.py -Q 4 +,,y,system-test,./pytest.sh python3 ./test.py -f 8-stream/checkpoint_info.py -N 4 +,,y,system-test,./pytest.sh python3 ./test.py -f 8-stream/checkpoint_info2.py -N 4 +,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/test_multi_insert.py + ,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreDnode.py -N 5 -M 3 -i False ,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreVnode.py -N 5 -M 3 -i False ,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreMnode.py -N 5 -M 3 -i False From 6c03a8c1ca4a951e3402d9937881c9395ef6c168 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 11 Nov 2024 15:06:17 +0800 Subject: [PATCH 07/47] fix double free --- source/dnode/mgmt/mgmt_snode/src/smWorker.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/source/dnode/mgmt/mgmt_snode/src/smWorker.c b/source/dnode/mgmt/mgmt_snode/src/smWorker.c index 8c33c5bb4b..1e882fc656 100644 --- a/source/dnode/mgmt/mgmt_snode/src/smWorker.c +++ b/source/dnode/mgmt/mgmt_snode/src/smWorker.c @@ -36,14 +36,15 @@ static void smProcessWriteQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO dTrace("msg:%p, get from snode-write queue", pMsg); int32_t code = sndProcessWriteMsg(pMgmt->pSnode, pMsg, NULL); - if (code < 0) { - dGError("snd, msg:%p failed to process write since %s", pMsg, tstrerror(code)); - if (pMsg->info.handle != NULL) { - tmsgSendRsp(pMsg); - } - } else { - smSendRsp(pMsg, 0); - } + // if (code < 0) { + // dGError("snd, msg:%p failed to process write since %s", pMsg, tstrerror(code)); + // if (pMsg->info.handle != NULL) { + // tmsgSendRsp(pMsg); + // } + // } else { + // smSendRsp(pMsg, 0); + // } + smSendRsp(pMsg, code); dTrace("msg:%p, is freed", pMsg); rpcFreeCont(pMsg->pCont); From 3c34ce6e96575fd28b650842e6563b2f3f989236 Mon Sep 17 00:00:00 2001 From: dmchen Date: Tue, 12 Nov 2024 14:08:23 +0800 Subject: [PATCH 08/47] fix/TD-32863-add-lock-for-allocate-primary --- source/dnode/mgmt/mgmt_vnode/inc/vmInt.h | 1 + source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 29 ++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h index 989adf84ac..f289035689 100644 --- a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h +++ b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h @@ -38,6 +38,7 @@ typedef struct SVnodeMgmt { SHashObj *hash; SHashObj *closedHash; TdThreadRwlock lock; + TdThreadMutex mutex; SVnodesStat state; STfs *pTfs; TdThread thread; diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index 682c179270..9440920866 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -66,6 +66,12 @@ int32_t vmAllocPrimaryDisk(SVnodeMgmt *pMgmt, int32_t vgId) { if (code != 0) { return code; } + + code = taosThreadMutexLock(&pMgmt->mutex); + if (code != 0) { + goto _OVER; + } + for (int32_t v = 0; v < numOfVnodes; v++) { SVnodeObj *pVnode = ppVnodes[v]; disks[pVnode->diskPrimary] += 1; @@ -81,6 +87,13 @@ int32_t vmAllocPrimaryDisk(SVnodeMgmt *pMgmt, int32_t vgId) { } } + code = taosThreadMutexUnlock(&pMgmt->mutex); + if (code != 0) { + goto _OVER; + } + +_OVER: + for (int32_t i = 0; i < numOfVnodes; ++i) { if (ppVnodes == NULL || ppVnodes[i] == NULL) continue; vmReleaseVnode(pMgmt, ppVnodes[i]); @@ -89,8 +102,13 @@ int32_t vmAllocPrimaryDisk(SVnodeMgmt *pMgmt, int32_t vgId) { taosMemoryFree(ppVnodes); } - dInfo("vgId:%d, alloc disk:%d of level 0. ndisk:%d, vnodes: %d", vgId, diskId, ndisk, numOfVnodes); - return diskId; + if (code != 0) { + dError("vgId:%d, failed to alloc disk since %s", vgId, tstrerror(code)); + return code; + } else { + dInfo("vgId:%d, alloc disk:%d of level 0. ndisk:%d, vnodes: %d", vgId, diskId, ndisk, numOfVnodes); + return diskId; + } } SVnodeObj *vmAcquireVnodeImpl(SVnodeMgmt *pMgmt, int32_t vgId, bool strict) { @@ -622,6 +640,7 @@ static void vmCleanup(SVnodeMgmt *pMgmt) { vmStopWorker(pMgmt); vnodeCleanup(); (void)taosThreadRwlockDestroy(&pMgmt->lock); + (void)taosThreadMutexDestroy(&pMgmt->mutex); (void)taosThreadMutexDestroy(&pMgmt->fileLock); taosMemoryFree(pMgmt); } @@ -714,6 +733,12 @@ static int32_t vmInit(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { goto _OVER; } + code = taosThreadMutexInit(&pMgmt->mutex, NULL); + if (code != 0) { + code = TAOS_SYSTEM_ERROR(errno); + goto _OVER; + } + code = taosThreadMutexInit(&pMgmt->fileLock, NULL); if (code != 0) { code = TAOS_SYSTEM_ERROR(errno); From b141e0e2ba20791c9e14c30db83559d954013081 Mon Sep 17 00:00:00 2001 From: dmchen Date: Wed, 13 Nov 2024 12:37:09 +0800 Subject: [PATCH 09/47] fix/TD-32863-add-creating-hash --- source/dnode/mgmt/mgmt_vnode/inc/vmInt.h | 3 + source/dnode/mgmt/mgmt_vnode/src/vmFile.c | 48 ++++++++++++++ source/dnode/mgmt/mgmt_vnode/src/vmHandle.c | 2 + source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 70 +++++++++++++++++++-- 4 files changed, 118 insertions(+), 5 deletions(-) diff --git a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h index f289035689..7842077d88 100644 --- a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h +++ b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h @@ -37,6 +37,7 @@ typedef struct SVnodeMgmt { SSingleWorker mgmtMultiWorker; SHashObj *hash; SHashObj *closedHash; + SHashObj *creatingHash; TdThreadRwlock lock; TdThreadMutex mutex; SVnodesStat state; @@ -97,6 +98,7 @@ SVnodeObj *vmAcquireVnodeImpl(SVnodeMgmt *pMgmt, int32_t vgId, bool strict); void vmReleaseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode); int32_t vmOpenVnode(SVnodeMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl); void vmCloseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode, bool commitAndRemoveWal, bool keepClosed); +void vmRemoveFromCreatingHash(SVnodeMgmt *pMgmt, int32_t vgId); // vmHandle.c SArray *vmGetMsgHandles(); @@ -114,6 +116,7 @@ int32_t vmGetVnodeListFromFile(SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt); int32_t vmGetVnodeListFromHash(SVnodeMgmt *pMgmt, int32_t *numOfVnodes, SVnodeObj ***ppVnodes); int32_t vmGetAllVnodeListFromHash(SVnodeMgmt *pMgmt, int32_t *numOfVnodes, SVnodeObj ***ppVnodes); +int32_t vmGetAllVnodeListFromHashWithCreating(SVnodeMgmt *pMgmt, int32_t *numOfVnodes, SVnodeObj ***ppVnodes); // vmWorker.c int32_t vmStartWorker(SVnodeMgmt *pMgmt); diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c index 7566b69c02..b4453ad6fc 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c @@ -67,6 +67,54 @@ int32_t vmGetAllVnodeListFromHash(SVnodeMgmt *pMgmt, int32_t *numOfVnodes, SVnod return 0; } +int32_t vmGetAllVnodeListFromHashWithCreating(SVnodeMgmt *pMgmt, int32_t *numOfVnodes, SVnodeObj ***ppVnodes) { + (void)taosThreadRwlockRdlock(&pMgmt->lock); + + int32_t num = 0; + int32_t size = taosHashGetSize(pMgmt->hash); + int32_t creatingSize = taosHashGetSize(pMgmt->creatingHash); + size += creatingSize; + SVnodeObj **pVnodes = taosMemoryCalloc(size, sizeof(SVnodeObj *)); + if (pVnodes == NULL) { + (void)taosThreadRwlockUnlock(&pMgmt->lock); + return terrno; + } + + void *pIter = taosHashIterate(pMgmt->hash, NULL); + while (pIter) { + SVnodeObj **ppVnode = pIter; + SVnodeObj *pVnode = *ppVnode; + if (pVnode && num < size) { + int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1); + dTrace("vgId:%d,acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount); + pVnodes[num++] = (*ppVnode); + pIter = taosHashIterate(pMgmt->hash, pIter); + } else { + taosHashCancelIterate(pMgmt->hash, pIter); + } + } + + pIter = taosHashIterate(pMgmt->creatingHash, NULL); + while (pIter) { + SVnodeObj **ppVnode = pIter; + SVnodeObj *pVnode = *ppVnode; + if (pVnode && num < size) { + int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1); + dTrace("vgId:%d, acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount); + pVnodes[num++] = (*ppVnode); + pIter = taosHashIterate(pMgmt->creatingHash, pIter); + } else { + taosHashCancelIterate(pMgmt->creatingHash, pIter); + } + } + (void)taosThreadRwlockUnlock(&pMgmt->lock); + + *numOfVnodes = num; + *ppVnodes = pVnodes; + + return 0; +} + int32_t vmGetVnodeListFromHash(SVnodeMgmt *pMgmt, int32_t *numOfVnodes, SVnodeObj ***ppVnodes) { (void)taosThreadRwlockRdlock(&pMgmt->lock); diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index 006f44b349..c9512d06d4 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -421,6 +421,8 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { goto _OVER; } + vmRemoveFromCreatingHash(pMgmt, req.vgId); + _OVER: if (code != 0) { int32_t r = 0; diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index 9440920866..26ac901f58 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -62,7 +62,7 @@ int32_t vmAllocPrimaryDisk(SVnodeMgmt *pMgmt, int32_t vgId) { int32_t numOfVnodes = 0; SVnodeObj **ppVnodes = NULL; - code = vmGetVnodeListFromHash(pMgmt, &numOfVnodes, &ppVnodes); + code = vmGetAllVnodeListFromHashWithCreating(pMgmt, &numOfVnodes, &ppVnodes); if (code != 0) { return code; } @@ -92,6 +92,25 @@ int32_t vmAllocPrimaryDisk(SVnodeMgmt *pMgmt, int32_t vgId) { goto _OVER; } + (void)taosThreadRwlockWrlock(&pMgmt->lock); + + SVnodeObj *pCreatingVnode = taosMemoryCalloc(1, sizeof(SVnodeObj)); + if (pCreatingVnode == NULL) { + (void)taosThreadRwlockUnlock(&pMgmt->lock); + dError("failed to alloc vnode since %s", terrstr()); + goto _OVER; + } + (void)memset(pCreatingVnode, 0, sizeof(SVnodeObj)); + + pCreatingVnode->vgId = vgId; + pCreatingVnode->diskPrimary = diskId; + + int32_t r = taosHashPut(pMgmt->creatingHash, &vgId, sizeof(int32_t), &pCreatingVnode, sizeof(SVnodeObj *)); + if (r != 0) { + dError("vgId:%d, failed to put vnode to creatingHash", vgId); + } + (void)taosThreadRwlockUnlock(&pMgmt->lock); + _OVER: for (int32_t i = 0; i < numOfVnodes; ++i) { @@ -234,12 +253,12 @@ void vmCloseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode, bool commitAndRemoveWal, } if (keepClosed) { SVnodeObj *pClosedVnode = taosMemoryCalloc(1, sizeof(SVnodeObj)); - (void)memset(pClosedVnode, 0, sizeof(SVnodeObj)); - if (pVnode == NULL) { - dError("vgId:%d, failed to alloc vnode since %s", pVnode->vgId, terrstr()); + if (pClosedVnode == NULL) { + dError("failed to alloc vnode since %s", terrstr()); (void)taosThreadRwlockUnlock(&pMgmt->lock); return; } + (void)memset(pClosedVnode, 0, sizeof(SVnodeObj)); pClosedVnode->vgId = pVnode->vgId; pClosedVnode->dropped = pVnode->dropped; @@ -445,11 +464,18 @@ static int32_t vmOpenVnodes(SVnodeMgmt *pMgmt) { pMgmt->closedHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); - if (pMgmt->hash == NULL) { + if (pMgmt->closedHash == NULL) { dError("failed to init vnode closed hash since %s", terrstr()); return TSDB_CODE_OUT_OF_MEMORY; } + pMgmt->creatingHash = + taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); + if (pMgmt->creatingHash == NULL) { + dError("failed to init vnode creatingHash hash since %s", terrstr()); + return TSDB_CODE_OUT_OF_MEMORY; + } + SWrapperCfg *pCfgs = NULL; int32_t numOfVnodes = 0; if (vmGetVnodeListFromFile(pMgmt, &pCfgs, &numOfVnodes) != 0) { @@ -527,6 +553,28 @@ static int32_t vmOpenVnodes(SVnodeMgmt *pMgmt) { return 0; } +void vmRemoveFromCreatingHash(SVnodeMgmt *pMgmt, int32_t vgId) { + (void)taosThreadRwlockWrlock(&pMgmt->lock); + SVnodeObj *pOld = NULL; + int32_t r = taosHashGetDup(pMgmt->closedHash, &vgId, sizeof(int32_t), (void *)&pOld); + if (r != 0) { + dError("vgId:%d, failed to get vnode from closedHash", vgId); + } + if (pOld) { + vmFreeVnodeObj(&pOld); + } + r = taosHashRemove(pMgmt->creatingHash, &vgId, sizeof(int32_t)); + if (r != 0) { + dError("vgId:%d, failed to remove vnode from hash", vgId); + } + (void)taosThreadRwlockUnlock(&pMgmt->lock); + +_OVER: + if (r != 0) { + dError("vgId:%d, failed to remove vnode from creatingHash since %s", vgId, tstrerror(r)); + } +} + static void *vmCloseVnodeInThread(void *param) { SVnodeThread *pThread = param; SVnodeMgmt *pMgmt = pThread->pMgmt; @@ -632,6 +680,18 @@ static void vmCloseVnodes(SVnodeMgmt *pMgmt) { pMgmt->closedHash = NULL; } + pIter = taosHashIterate(pMgmt->creatingHash, NULL); + while (pIter) { + SVnodeObj **ppVnode = pIter; + vmFreeVnodeObj(ppVnode); + pIter = taosHashIterate(pMgmt->creatingHash, pIter); + } + + if (pMgmt->creatingHash != NULL) { + taosHashCleanup(pMgmt->creatingHash); + pMgmt->creatingHash = NULL; + } + dInfo("total vnodes:%d are all closed", numOfVnodes); } From 156421f8a03aa36d35ca98c6b9ca1d5a767851f1 Mon Sep 17 00:00:00 2001 From: dmchen Date: Wed, 13 Nov 2024 13:53:55 +0800 Subject: [PATCH 10/47] fix/TD-32863-add-creating-hash-fix-case --- source/dnode/mgmt/mgmt_vnode/src/vmHandle.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index c9512d06d4..90b3f0025d 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -381,6 +381,7 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { if (vnodeCreate(path, &vnodeCfg, diskPrimary, pMgmt->pTfs) < 0) { dError("vgId:%d, failed to create vnode since %s", req.vgId, terrstr()); vmReleaseVnode(pMgmt, pVnode); + vmRemoveFromCreatingHash(pMgmt, req.vgId); (void)tFreeSCreateVnodeReq(&req); code = terrno != 0 ? terrno : -1; return code; @@ -421,9 +422,9 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { goto _OVER; } +_OVER: vmRemoveFromCreatingHash(pMgmt, req.vgId); -_OVER: if (code != 0) { int32_t r = 0; r = taosThreadRwlockWrlock(&pMgmt->lock); From 2b069db01fe2ff08e083b9eda0d9e4b17d717e6f Mon Sep 17 00:00:00 2001 From: dmchen Date: Wed, 13 Nov 2024 14:26:44 +0800 Subject: [PATCH 11/47] fix/TD-32863-add-creating-hash-add-testcase --- tests/parallel_test/cases.task | 1 + .../0-others/multilevel_createdb.py | 89 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 tests/system-test/0-others/multilevel_createdb.py diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 67fb784b61..90b5f4fee9 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -351,6 +351,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_privilege_all.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/fsync.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/multilevel.py +,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/multilevel_createdb.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/ttl.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/ttlChangeOnWrite.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/compress_tsz1.py diff --git a/tests/system-test/0-others/multilevel_createdb.py b/tests/system-test/0-others/multilevel_createdb.py new file mode 100644 index 0000000000..a4fd94f4c1 --- /dev/null +++ b/tests/system-test/0-others/multilevel_createdb.py @@ -0,0 +1,89 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + + +from util.log import * +from util.cases import * +from util.sql import * +from util.common import * +from util.sqlset import * +import glob + +def scanFiles(pattern): + res = [] + for f in glob.iglob(pattern): + res += [f] + return res + +def checkFiles(pattern, state): + res = scanFiles(pattern) + tdLog.info(res) + num = len(res) + if num: + if state: + tdLog.info("%s: %d files exist. expect: files exist" % (pattern, num)) + else: + tdLog.exit("%s: %d files exist. expect: files not exist." % (pattern, num)) + else: + if state: + tdLog.exit("%s: %d files exist. expect: files exist" % (pattern, num)) + else: + tdLog.info("%s: %d files exist. expect: files not exist." % (pattern, num)) + +class TDTestCase: + def init(self, conn, logSql, replicaVar=1): + + self.replicaVar = int(replicaVar) + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + self.setsql = TDSetSql() + + def basic(self): + tdLog.info("============== basic test ===============") + cfg={ + '/mnt/data1 0 1 0' : 'dataDir', + '/mnt/data2 0 0 0' : 'dataDir', + '/mnt/data3 0 0 0' : 'dataDir', + '/mnt/data4 0 0 0' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + tdSql.createDir('/mnt/data2') + tdSql.createDir('/mnt/data3') + tdSql.createDir('/mnt/data4') + + tdDnodes.stop(1) + tdDnodes.deploy(1,cfg) + tdDnodes.start(1) + + checkFiles(r'/mnt/data1/*/*',1) + checkFiles(r'/mnt/data2/*/*',0) + + tdSql.execute('create database nws vgroups 20 buffer 3000 stt_trigger 1 wal_level 1 wal_retention_period 0') + + checkFiles(r'/mnt/data1/vnode/*/wal',5) + checkFiles(r'/mnt/data2/vnode/*/wal',5) + checkFiles(r'/mnt/data3/vnode/*/wal',5) + checkFiles(r'/mnt/data4/vnode/*/wal',5) + + def run(self): + self.basic() + + + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file From 0b9f15817489d3823c47e8a91e655463e8afb325 Mon Sep 17 00:00:00 2001 From: dmchen Date: Wed, 13 Nov 2024 14:48:57 +0800 Subject: [PATCH 12/47] fix/TD-32863-add-creating-hash-fix-case --- source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index 26ac901f58..d28394e332 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -105,6 +105,7 @@ int32_t vmAllocPrimaryDisk(SVnodeMgmt *pMgmt, int32_t vgId) { pCreatingVnode->vgId = vgId; pCreatingVnode->diskPrimary = diskId; + dTrace("vgId:%d, put vnode into creating hash, pCreatingVnode:%p", vgId, pCreatingVnode); int32_t r = taosHashPut(pMgmt->creatingHash, &vgId, sizeof(int32_t), &pCreatingVnode, sizeof(SVnodeObj *)); if (r != 0) { dError("vgId:%d, failed to put vnode to creatingHash", vgId); @@ -556,13 +557,15 @@ static int32_t vmOpenVnodes(SVnodeMgmt *pMgmt) { void vmRemoveFromCreatingHash(SVnodeMgmt *pMgmt, int32_t vgId) { (void)taosThreadRwlockWrlock(&pMgmt->lock); SVnodeObj *pOld = NULL; - int32_t r = taosHashGetDup(pMgmt->closedHash, &vgId, sizeof(int32_t), (void *)&pOld); + int32_t r = taosHashGetDup(pMgmt->creatingHash, &vgId, sizeof(int32_t), (void *)&pOld); if (r != 0) { - dError("vgId:%d, failed to get vnode from closedHash", vgId); + dError("vgId:%d, failed to get vnode from creating Hash", vgId); } if (pOld) { + dTrace("vgId:%d, free vnode pOld:%p", vgId, &pOld); vmFreeVnodeObj(&pOld); } + dTrace("vgId:%d, remove from creating Hash", vgId); r = taosHashRemove(pMgmt->creatingHash, &vgId, sizeof(int32_t)); if (r != 0) { dError("vgId:%d, failed to remove vnode from hash", vgId); From 7ff6884779cde6a77e201c5886e022ee1d740b26 Mon Sep 17 00:00:00 2001 From: dmchen Date: Wed, 13 Nov 2024 16:07:45 +0800 Subject: [PATCH 13/47] fix/TD-32863-add-creating-hash-change-lock --- source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 47 +++++++++++++++++------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index d28394e332..a81208c567 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -16,6 +16,7 @@ #define _DEFAULT_SOURCE #include "vmInt.h" #include "libs/function/tudf.h" +#include "osMemory.h" #include "tfs.h" #include "vnd.h" @@ -87,17 +88,15 @@ int32_t vmAllocPrimaryDisk(SVnodeMgmt *pMgmt, int32_t vgId) { } } - code = taosThreadMutexUnlock(&pMgmt->mutex); - if (code != 0) { - goto _OVER; - } - - (void)taosThreadRwlockWrlock(&pMgmt->lock); - SVnodeObj *pCreatingVnode = taosMemoryCalloc(1, sizeof(SVnodeObj)); if (pCreatingVnode == NULL) { - (void)taosThreadRwlockUnlock(&pMgmt->lock); - dError("failed to alloc vnode since %s", terrstr()); + code = -1; + if (terrno != 0) code = terrno; + dError("failed to alloc vnode since %s", tstrerror(code)); + int32_t r = taosThreadMutexUnlock(&pMgmt->mutex); + if (r != 0) { + dError("vgId:%d, failed to unlock mutex since %s", vgId, tstrerror(r)); + } goto _OVER; } (void)memset(pCreatingVnode, 0, sizeof(SVnodeObj)); @@ -105,12 +104,32 @@ int32_t vmAllocPrimaryDisk(SVnodeMgmt *pMgmt, int32_t vgId) { pCreatingVnode->vgId = vgId; pCreatingVnode->diskPrimary = diskId; - dTrace("vgId:%d, put vnode into creating hash, pCreatingVnode:%p", vgId, pCreatingVnode); - int32_t r = taosHashPut(pMgmt->creatingHash, &vgId, sizeof(int32_t), &pCreatingVnode, sizeof(SVnodeObj *)); - if (r != 0) { - dError("vgId:%d, failed to put vnode to creatingHash", vgId); + code = taosThreadRwlockWrlock(&pMgmt->lock); + if (code != 0) { + int32_t r = taosThreadMutexUnlock(&pMgmt->mutex); + if (r != 0) { + dError("vgId:%d, failed to unlock mutex since %s", vgId, tstrerror(r)); + } + taosMemoryFree(pCreatingVnode); + goto _OVER; + } + + dTrace("vgId:%d, put vnode into creating hash, pCreatingVnode:%p", vgId, pCreatingVnode); + code = taosHashPut(pMgmt->creatingHash, &vgId, sizeof(int32_t), &pCreatingVnode, sizeof(SVnodeObj *)); + if (code != 0) { + dError("vgId:%d, failed to put vnode to creatingHash", vgId); + taosMemoryFree(pCreatingVnode); + } + + int32_t r = taosThreadRwlockUnlock(&pMgmt->lock); + if (r != 0) { + dError("vgId:%d, failed to unlock since %s", vgId, tstrerror(r)); + } + + code = taosThreadMutexUnlock(&pMgmt->mutex); + if (code != 0) { + goto _OVER; } - (void)taosThreadRwlockUnlock(&pMgmt->lock); _OVER: From ea7c30505a8c1394a8c315defdf08b84f5eb011f Mon Sep 17 00:00:00 2001 From: 54liuyao <54liuyao@163.com> Date: Wed, 13 Nov 2024 19:37:22 +0800 Subject: [PATCH 14/47] fix(stream):fix bloom filter decode issue --- source/libs/executor/src/scanoperator.c | 28 +++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 5b5d5c5d11..ecb6bd7aee 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -3468,11 +3468,6 @@ void streamScanOperatorDecode(void* pBuff, int32_t len, SStreamScanInfo* pInfo) goto _end; } - void* pUpInfo = taosMemoryCalloc(1, sizeof(SUpdateInfo)); - if (!pUpInfo) { - lino = __LINE__; - goto _end; - } SDecoder decoder = {0}; pDeCoder = &decoder; tDecoderInit(pDeCoder, buf, tlen); @@ -3481,14 +3476,21 @@ void streamScanOperatorDecode(void* pBuff, int32_t len, SStreamScanInfo* pInfo) goto _end; } - code = pInfo->stateStore.updateInfoDeserialize(pDeCoder, pUpInfo); - if (code == TSDB_CODE_SUCCESS) { - pInfo->stateStore.updateInfoDestroy(pInfo->pUpdateInfo); - pInfo->pUpdateInfo = pUpInfo; - } else { - taosMemoryFree(pUpInfo); - lino = __LINE__; - goto _end; + if (pInfo->pUpdateInfo != NULL) { + void* pUpInfo = taosMemoryCalloc(1, sizeof(SUpdateInfo)); + if (!pUpInfo) { + lino = __LINE__; + goto _end; + } + code = pInfo->stateStore.updateInfoDeserialize(pDeCoder, pUpInfo); + if (code == TSDB_CODE_SUCCESS) { + pInfo->stateStore.updateInfoDestroy(pInfo->pUpdateInfo); + pInfo->pUpdateInfo = pUpInfo; + } else { + taosMemoryFree(pUpInfo); + lino = __LINE__; + goto _end; + } } if (tDecodeIsEnd(pDeCoder)) { From 336429e14904e60ce05188c3b82988363c272da5 Mon Sep 17 00:00:00 2001 From: dmchen Date: Thu, 14 Nov 2024 16:01:28 +0800 Subject: [PATCH 15/47] fix/TD-32863-add-creating-hash-fix-review --- source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index a81208c567..2ee607949d 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -63,14 +63,18 @@ int32_t vmAllocPrimaryDisk(SVnodeMgmt *pMgmt, int32_t vgId) { int32_t numOfVnodes = 0; SVnodeObj **ppVnodes = NULL; - code = vmGetAllVnodeListFromHashWithCreating(pMgmt, &numOfVnodes, &ppVnodes); + code = taosThreadMutexLock(&pMgmt->mutex); if (code != 0) { return code; } - code = taosThreadMutexLock(&pMgmt->mutex); + code = vmGetAllVnodeListFromHashWithCreating(pMgmt, &numOfVnodes, &ppVnodes); if (code != 0) { - goto _OVER; + int32_t r = taosThreadMutexUnlock(&pMgmt->mutex); + if (r != 0) { + dError("vgId:%d, failed to unlock mutex since %s", vgId, tstrerror(r)); + } + return code; } for (int32_t v = 0; v < numOfVnodes; v++) { From 4a09cb7138b36007e974dcb0725fd818d2a1e62f Mon Sep 17 00:00:00 2001 From: dmchen Date: Fri, 15 Nov 2024 08:05:50 +0800 Subject: [PATCH 16/47] fix/TD-32863-add-creating-hash-fix-case --- tests/system-test/0-others/multilevel_createdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/0-others/multilevel_createdb.py b/tests/system-test/0-others/multilevel_createdb.py index a4fd94f4c1..70131a760b 100644 --- a/tests/system-test/0-others/multilevel_createdb.py +++ b/tests/system-test/0-others/multilevel_createdb.py @@ -68,7 +68,7 @@ class TDTestCase: checkFiles(r'/mnt/data1/*/*',1) checkFiles(r'/mnt/data2/*/*',0) - tdSql.execute('create database nws vgroups 20 buffer 3000 stt_trigger 1 wal_level 1 wal_retention_period 0') + tdSql.execute('create database nws vgroups 20 stt_trigger 1 wal_level 1 wal_retention_period 0') checkFiles(r'/mnt/data1/vnode/*/wal',5) checkFiles(r'/mnt/data2/vnode/*/wal',5) From a854597de14c05b8fcf172f2484bcc01f69e84b5 Mon Sep 17 00:00:00 2001 From: Yu Chen <74105241+yu285@users.noreply.github.com> Date: Fri, 15 Nov 2024 13:48:57 +0800 Subject: [PATCH 17/47] docs:Update keep description in 02-database.md --- docs/zh/14-reference/03-taos-sql/02-database.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/14-reference/03-taos-sql/02-database.md b/docs/zh/14-reference/03-taos-sql/02-database.md index 91b39976a1..0d9ab019c0 100644 --- a/docs/zh/14-reference/03-taos-sql/02-database.md +++ b/docs/zh/14-reference/03-taos-sql/02-database.md @@ -63,7 +63,7 @@ database_option: { - DURATION:数据文件存储数据的时间跨度。可以使用加单位的表示形式,如 DURATION 100h、DURATION 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。不加时间单位时默认单位为天,如 DURATION 50 表示 50 天。 - MAXROWS:文件块中记录的最大条数,默认为 4096 条。 - MINROWS:文件块中记录的最小条数,默认为 100 条。 -- KEEP:表示数据文件保存的天数,缺省值为 3650,取值范围 [1, 365000],且必须大于或等于3倍的 DURATION 参数值。数据库会自动删除保存时间超过 KEEP 值的数据。KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。也可以不写单位,如 KEEP 50,此时默认单位为天。企业版支持[多级存储](https://docs.taosdata.com/tdinternal/arch/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 \<= keep 1 \<= keep 2,如 KEEP 100h,100d,3650d); 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间)。 +- KEEP:表示数据文件保存的天数,缺省值为 3650,取值范围 [1, 365000],且必须大于或等于3倍的 DURATION 参数值。数据库会自动删除保存时间超过 KEEP 值的数据从而释放存储空间。KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。也可以不写单位,如 KEEP 50,此时默认单位为天。企业版支持[多级存储](https://docs.taosdata.com/tdinternal/arch/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 \<= keep 1 \<= keep 2,如 KEEP 100h,100d,3650d); 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间)。 - STT_TRIGGER:表示落盘文件触发文件合并的个数。开源版本固定为 1,企业版本可设置范围为 1 到 16。对于少表高频写入场景,此参数建议使用默认配置;而对于多表低频写入场景,此参数建议配置较大的值。 - SINGLE_STABLE:表示此数据库中是否只可以创建一个超级表,用于超级表列非常多的情况。 - 0:表示可以创建多张超级表。 From 07a11a4ea58498c1f0befa7b7b778128412f68d5 Mon Sep 17 00:00:00 2001 From: happyguoxy Date: Fri, 15 Nov 2024 13:49:26 +0800 Subject: [PATCH 18/47] test:add stream test cases --- tests/system-test/8-stream/checkpoint_info.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/system-test/8-stream/checkpoint_info.py b/tests/system-test/8-stream/checkpoint_info.py index 00e5d1f688..522017a702 100644 --- a/tests/system-test/8-stream/checkpoint_info.py +++ b/tests/system-test/8-stream/checkpoint_info.py @@ -84,6 +84,7 @@ class TDTestCase: def restart_stream(self): tdLog.debug("========restart stream========") + time.sleep(10) for i in range(5): tdSql.execute("pause stream s1") time.sleep(2) @@ -136,4 +137,4 @@ class TDTestCase: tdSql.close() tdLog.success(f"{__file__} successfully executed") tdCases.addLinux(__file__, TDTestCase()) -tdCases.addWindows(__file__, TDTestCase()) \ No newline at end of file +tdCases.addWindows(__file__, TDTestCase()) From 0c45c80d71b55feff88a56af68f28c2c7d8a361d Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Fri, 15 Nov 2024 14:26:53 +0800 Subject: [PATCH 19/47] enh: add dangle child table filter in recovery mode --- source/dnode/vnode/src/meta/metaOpen.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/dnode/vnode/src/meta/metaOpen.c b/source/dnode/vnode/src/meta/metaOpen.c index 659ba3f777..9a5bea33e3 100644 --- a/source/dnode/vnode/src/meta/metaOpen.c +++ b/source/dnode/vnode/src/meta/metaOpen.c @@ -324,7 +324,11 @@ static int32_t metaGenerateNewMeta(SMeta **ppMeta) { SMetaEntry me = {0}; tDecoderInit(&dc, value, valueSize); if (metaDecodeEntry(&dc, &me) == 0) { - if (metaHandleEntry(pNewMeta, &me) != 0) { + if (me.type == TSDB_CHILD_TABLE && + tdbTbGet(pMeta->pUidIdx, &me.ctbEntry.suid, sizeof(me.ctbEntry.suid), NULL, NULL) != 0) { + metaError("vgId:%d failed to get super table uid:%" PRId64 " for child table uid:%" PRId64, + TD_VID(pVnode), me.ctbEntry.suid, uid); + } else if (metaHandleEntry(pNewMeta, &me) != 0) { metaError("vgId:%d failed to handle entry, uid:%" PRId64, TD_VID(pVnode), uid); } } From 2f978a11c2721ea7bfe7a3e7e958a2d4e67baeac Mon Sep 17 00:00:00 2001 From: happyguoxy Date: Fri, 15 Nov 2024 15:01:34 +0800 Subject: [PATCH 20/47] test:add stream test cases --- tests/system-test/8-stream/checkpoint_info2.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/system-test/8-stream/checkpoint_info2.py b/tests/system-test/8-stream/checkpoint_info2.py index 7f2e8b0672..3dc57477f7 100644 --- a/tests/system-test/8-stream/checkpoint_info2.py +++ b/tests/system-test/8-stream/checkpoint_info2.py @@ -33,17 +33,21 @@ class TDTestCase: info_path = os.path.join(root, f'checkpoint{checkpointid}', 'info') if os.path.exists(info_path): if task_id in info_path: + tdLog.info(f"info file found in {info_path}") return info_path else: continue else: + tdLog.info(f"info file not found in {info_path}") return None + else: + tdLog.info(f"no checkpoint{checkpointid} in {dirpath}") def get_dnode_info(self): ''' get a dict from vnode to dnode ''' self.vnode_dict = {} - sql = 'select dnode_id, vgroup_id from information_schema.ins_vnodes' + sql = 'select dnode_id, vgroup_id from information_schema.ins_vnodes where status = "leader"' result = tdSql.getResult(sql) for (dnode,vnode) in result: self.vnode_dict[vnode] = dnode @@ -68,15 +72,18 @@ class TDTestCase: while(True): if(self.check_vnodestate()): break + self.get_dnode_info() sql = 'select task_id, node_id, checkpoint_id, checkpoint_ver from information_schema.ins_stream_tasks where `level` = "source" or `level` = "agg" and node_type == "vnode"' for task_id, vnode, checkpoint_id, checkpoint_ver in tdSql.getResult(sql): dirpath = f"{cluster.dnodes[self.vnode_dict[vnode]-1].dataDir}/vnode/vnode{vnode}/" info_path = self.find_checkpoint_info_file(dirpath, checkpoint_id, task_id) if info_path is None: + tdLog.info(f"info path: {dirpath} is null") return False with open(info_path, 'r') as f: info_id, info_ver = f.read().split() if int(info_id) != int(checkpoint_id) or int(info_ver) != int(checkpoint_ver): + tdLog.info(f"infoId: {info_id}, checkpointId: {checkpoint_id}, infoVer: {info_ver}, checkpointVer: {checkpoint_ver}") return False return True @@ -131,4 +138,4 @@ class TDTestCase: tdLog.success(f"{__file__} successfully executed") tdCases.addLinux(__file__, TDTestCase()) -tdCases.addWindows(__file__, TDTestCase()) \ No newline at end of file +tdCases.addWindows(__file__, TDTestCase()) From 9cc2aec9d66d27aa5a9d1873291f9be797d064b1 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 15 Nov 2024 17:12:01 +0800 Subject: [PATCH 21/47] fix(stream): set correct value and open inputQ for stream if reset checkpoint. --- source/dnode/mnode/impl/src/mndStream.c | 7 ++++++- source/libs/stream/src/streamCheckpoint.c | 15 +++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index 81db427afd..6336cd6e49 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -2434,7 +2434,12 @@ static void doAddReportStreamTask(SArray *pList, int64_t reportChkptId, const SC mDebug("s-task:0x%x expired checkpoint-report msg in checkpoint-report list update from %" PRId64 "->%" PRId64, pReport->taskId, p->checkpointId, pReport->checkpointId); - memcpy(p, pReport, sizeof(STaskChkptInfo)); + // update the checkpoint report info + p->checkpointId = pReport->checkpointId; + p->ts = pReport->checkpointTs; + p->version = pReport->checkpointVer; + p->transId = pReport->transId; + p->dropHTask = pReport->dropHTask; } else { mWarn("taskId:0x%x already in checkpoint-report list", pReport->taskId); } diff --git a/source/libs/stream/src/streamCheckpoint.c b/source/libs/stream/src/streamCheckpoint.c index 7724d1c5ff..df13b9a585 100644 --- a/source/libs/stream/src/streamCheckpoint.c +++ b/source/libs/stream/src/streamCheckpoint.c @@ -255,8 +255,7 @@ static int32_t doCheckBeforeHandleChkptTrigger(SStreamTask* pTask, int64_t check "the interrupted checkpoint", id, vgId, pBlock->srcTaskId); - streamTaskOpenUpstreamInput(pTask, pBlock->srcTaskId); - return code; + return TSDB_CODE_STREAM_INVLD_CHKPT; } if (streamTaskGetStatus(pTask).state == TASK_STATUS__CK) { @@ -264,14 +263,14 @@ static int32_t doCheckBeforeHandleChkptTrigger(SStreamTask* pTask, int64_t check stError("s-task:%s vgId:%d active checkpointId:%" PRId64 ", recv invalid checkpoint-trigger checkpointId:%" PRId64 " discard", id, vgId, pActiveInfo->activeId, checkpointId); - return code; + return TSDB_CODE_STREAM_INVLD_CHKPT; } else { // checkpointId == pActiveInfo->activeId if (pActiveInfo->allUpstreamTriggerRecv == 1) { stDebug( "s-task:%s vgId:%d all upstream checkpoint-trigger recv, discard this checkpoint-trigger, " "checkpointId:%" PRId64 " transId:%d", id, vgId, checkpointId, transId); - return code; + return TSDB_CODE_STREAM_INVLD_CHKPT; } if (taskLevel == TASK_LEVEL__SINK || taskLevel == TASK_LEVEL__AGG) { @@ -286,14 +285,14 @@ static int32_t doCheckBeforeHandleChkptTrigger(SStreamTask* pTask, int64_t check stWarn("s-task:%s repeatly recv checkpoint-source msg from task:0x%x vgId:%d, checkpointId:%" PRId64 ", prev recvTs:%" PRId64 " discard", pTask->id.idStr, p->upstreamTaskId, p->upstreamNodeId, p->checkpointId, p->recvTs); - return code; + return TSDB_CODE_STREAM_INVLD_CHKPT; } } } } } - return 0; + return TSDB_CODE_SUCCESS; } int32_t streamProcessCheckpointTriggerBlock(SStreamTask* pTask, SStreamDataBlock* pBlock) { @@ -317,6 +316,10 @@ int32_t streamProcessCheckpointTriggerBlock(SStreamTask* pTask, SStreamDataBlock code = doCheckBeforeHandleChkptTrigger(pTask, checkpointId, pBlock, transId); streamMutexUnlock(&pTask->lock); if (code) { + if (taskLevel != TASK_LEVEL__SOURCE) { // the checkpoint-trigger is discard, open the inputQ for upstream tasks + streamTaskOpenUpstreamInput(pTask, pBlock->srcTaskId); + } + streamFreeQitem((SStreamQueueItem*)pBlock); return code; } From 628808c9a4bbfe83d8efff189b284442de1ed066 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 15 Nov 2024 17:16:47 +0800 Subject: [PATCH 22/47] fix(stream): fix dead lock. --- source/libs/stream/src/streamDispatch.c | 2 ++ source/libs/stream/src/streamStartTask.c | 1 + 2 files changed, 3 insertions(+) diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index e0fa199199..5807240f5e 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -1170,6 +1170,7 @@ int32_t streamTaskSendCheckpointReadyMsg(SStreamTask* pTask) { if (taosArrayGetSize(pTask->upstreamInfo.pList) != num) { stError("s-task:%s invalid number of sent readyMsg:%d to upstream:%d", id, num, (int32_t)taosArrayGetSize(pTask->upstreamInfo.pList)); + streamMutexUnlock(&pActiveInfo->lock); return TSDB_CODE_STREAM_INTERNAL_ERROR; } @@ -1412,6 +1413,7 @@ int32_t streamAddCheckpointSourceRspMsg(SStreamCheckpointSourceReq* pReq, SRpcHa if (size > 0) { STaskCheckpointReadyInfo* pReady = taosArrayGet(pActiveInfo->pReadyMsgList, 0); if (pReady == NULL) { + streamMutexUnlock(&pActiveInfo->lock); return terrno; } diff --git a/source/libs/stream/src/streamStartTask.c b/source/libs/stream/src/streamStartTask.c index ed12687e41..9c16ff036e 100644 --- a/source/libs/stream/src/streamStartTask.c +++ b/source/libs/stream/src/streamStartTask.c @@ -433,6 +433,7 @@ int32_t streamMetaStopAllTasks(SStreamMeta* pMeta) { // send hb msg to mnode before closing all tasks. int32_t code = streamMetaSendMsgBeforeCloseTasks(pMeta, &pTaskList); if (code != TSDB_CODE_SUCCESS) { + streamMetaRUnLock(pMeta); return code; } From f304a92229ab4e4cc072165cdb8a5632a87682f6 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 15 Nov 2024 17:21:20 +0800 Subject: [PATCH 23/47] refactor: add new error code. --- include/util/taoserror.h | 1 + source/util/src/terror.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 9a8b39b84c..b563c186c3 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -1010,6 +1010,7 @@ int32_t taosGetErrSize(); #define TSDB_CODE_STREAM_CONFLICT_EVENT TAOS_DEF_ERROR_CODE(0, 0x4106) #define TSDB_CODE_STREAM_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x4107) #define TSDB_CODE_STREAM_INPUTQ_FULL TAOS_DEF_ERROR_CODE(0, 0x4108) +#define TSDB_CODE_STREAM_INVLD_CHKPT TAOS_DEF_ERROR_CODE(0, 0x4109) // TDLite #define TSDB_CODE_TDLITE_IVLD_OPEN_FLAGS TAOS_DEF_ERROR_CODE(0, 0x5100) diff --git a/source/util/src/terror.c b/source/util/src/terror.c index ce209cc718..ce754e8795 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -852,7 +852,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_TASK_IVLD_STATUS, "Invalid task status TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_CONFLICT_EVENT, "Stream conflict event") TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_INTERNAL_ERROR, "Stream internal error") TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_NOT_LEADER, "Stream task not on leader vnode") -TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_INPUTQ_FULL, "Task input queue is full") +TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_INPUTQ_FULL, "Task input queue is full") +TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_INVLD_CHKPT, "Invalid checkpoint trigger msg") // TDLite TAOS_DEFINE_ERROR(TSDB_CODE_TDLITE_IVLD_OPEN_FLAGS, "Invalid TDLite open flags") From b1981d309fefe53bd85a6bf1e5b034127fb2e372 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 15 Nov 2024 17:41:14 +0800 Subject: [PATCH 24/47] fix(stream): return error code. --- source/libs/stream/src/streamCheckpoint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/libs/stream/src/streamCheckpoint.c b/source/libs/stream/src/streamCheckpoint.c index df13b9a585..6c4c285ded 100644 --- a/source/libs/stream/src/streamCheckpoint.c +++ b/source/libs/stream/src/streamCheckpoint.c @@ -222,14 +222,14 @@ static int32_t doCheckBeforeHandleChkptTrigger(SStreamTask* pTask, int64_t check stError("s-task:%s vgId:%d current checkpointId:%" PRId64 " recv expired checkpoint-trigger block, checkpointId:%" PRId64 " transId:%d, discard", id, vgId, pTask->chkInfo.checkpointId, checkpointId, transId); - return code; + return TSDB_CODE_STREAM_TASK_NOT_EXIST; } if (pActiveInfo->failedId >= checkpointId) { stError("s-task:%s vgId:%d checkpointId:%" PRId64 " transId:%d, has been marked failed, failedId:%" PRId64 " discard the checkpoint-trigger block", id, vgId, checkpointId, transId, pActiveInfo->failedId); - return code; + return TSDB_CODE_STREAM_TASK_NOT_EXIST; } if (pTask->chkInfo.checkpointId == checkpointId) { From 09fe252a31831e05707a139172b546b0ab1a1468 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Fri, 15 Nov 2024 17:52:06 +0800 Subject: [PATCH 25/47] remove duplicate group by cols --- include/libs/nodes/nodes.h | 1 + source/libs/nodes/src/nodesEqualFuncs.c | 9 +++++- source/libs/nodes/src/nodesUtilFuncs.c | 34 ++++++++++++++++++++ source/libs/parser/src/parTranslater.c | 2 -- source/libs/planner/src/planLogicCreater.c | 7 ++-- tests/system-test/2-query/group_partition.py | 13 ++++++++ 6 files changed, 61 insertions(+), 5 deletions(-) diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 72dd3ef3e0..6384c536ce 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -174,6 +174,7 @@ char* nodesGetNameFromColumnNode(SNode* pNode); int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots); void nodesSortList(SNodeList** pList, int32_t (*)(SNode* pNode1, SNode* pNode2)); void destroyFuncParam(void* pFuncStruct); +int32_t nodesListDeduplicate(SNodeList** pList); #ifdef __cplusplus } diff --git a/source/libs/nodes/src/nodesEqualFuncs.c b/source/libs/nodes/src/nodesEqualFuncs.c index 241da85267..891843761a 100644 --- a/source/libs/nodes/src/nodesEqualFuncs.c +++ b/source/libs/nodes/src/nodesEqualFuncs.c @@ -153,6 +153,12 @@ static bool caseWhenNodeEqual(const SCaseWhenNode* a, const SCaseWhenNode* b) { return true; } +static bool groupingSetNodeEqual(const SGroupingSetNode* a, const SGroupingSetNode* b) { + COMPARE_SCALAR_FIELD(groupingSetType); + COMPARE_NODE_LIST_FIELD(pParameterList); + return true; +} + bool nodesEqualNode(const SNode* a, const SNode* b) { if (a == b) { return true; @@ -181,10 +187,11 @@ bool nodesEqualNode(const SNode* a, const SNode* b) { return whenThenNodeEqual((const SWhenThenNode*)a, (const SWhenThenNode*)b); case QUERY_NODE_CASE_WHEN: return caseWhenNodeEqual((const SCaseWhenNode*)a, (const SCaseWhenNode*)b); + case QUERY_NODE_GROUPING_SET: + return groupingSetNodeEqual((const SGroupingSetNode*)a, (const SGroupingSetNode*)b); case QUERY_NODE_REAL_TABLE: case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_JOIN_TABLE: - case QUERY_NODE_GROUPING_SET: case QUERY_NODE_ORDER_BY_EXPR: case QUERY_NODE_LIMIT: return false; diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index a9d0aa2924..4677b5d5f0 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -2948,3 +2948,37 @@ void nodesSortList(SNodeList** pList, int32_t (*comp)(SNode* pNode1, SNode* pNod inSize *= 2; } } + +static SNode* nodesListFindNode(SNodeList* pList, SNode* pNode) { + SNode* pFound = NULL; + FOREACH(pFound, pList) { + if (nodesEqualNode(pFound, pNode)) { + break; + } + } + return pFound; +} + +int32_t nodesListDeduplicate(SNodeList** ppList) { + if (!ppList || LIST_LENGTH(*ppList) == 0) return TSDB_CODE_SUCCESS; + SNodeList* pTmp = NULL; + int32_t code = nodesMakeList(&pTmp); + if (TSDB_CODE_SUCCESS == code) { + SNode* pNode = NULL; + FOREACH(pNode, *ppList) { + SNode* pFound = nodesListFindNode(pTmp, pNode); + if (NULL == pFound) { + code = nodesCloneNode(pNode, &pFound); + if (TSDB_CODE_SUCCESS == code) code = nodesListStrictAppend(pTmp, pFound); + if (TSDB_CODE_SUCCESS != code) break; + } + } + } + if (TSDB_CODE_SUCCESS == code) { + nodesDestroyList(*ppList); + *ppList = pTmp; + } else { + nodesDestroyList(pTmp); + } + return code; +} diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 9bea3491c3..b77c349a78 100755 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5531,7 +5531,6 @@ static int32_t translateGroupByList(STranslateContext* pCxt, SSelectStmt* pSelec SReplaceGroupByAliasCxt cxt = { .pTranslateCxt = pCxt, .pProjectionList = pSelect->pProjectionList}; nodesRewriteExprsPostOrder(pSelect->pGroupByList, translateGroupPartitionByImpl, &cxt); - return pCxt->errCode; } @@ -5543,7 +5542,6 @@ static int32_t translatePartitionByList(STranslateContext* pCxt, SSelectStmt* pS SReplaceGroupByAliasCxt cxt = { .pTranslateCxt = pCxt, .pProjectionList = pSelect->pProjectionList}; nodesRewriteExprsPostOrder(pSelect->pPartitionByList, translateGroupPartitionByImpl, &cxt); - return pCxt->errCode; } diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 34c83acee8..f4c4926ca1 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -838,8 +838,11 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, } if (NULL != pSelect->pGroupByList) { - pAgg->pGroupKeys = NULL; - code = nodesCloneList(pSelect->pGroupByList, &pAgg->pGroupKeys); + code = nodesListDeduplicate(&pSelect->pGroupByList); + if (TSDB_CODE_SUCCESS == code) { + pAgg->pGroupKeys = NULL; + code = nodesCloneList(pSelect->pGroupByList, &pAgg->pGroupKeys); + } } // rewrite the expression in subsequent clauses diff --git a/tests/system-test/2-query/group_partition.py b/tests/system-test/2-query/group_partition.py index 7ee528841c..d48df16231 100644 --- a/tests/system-test/2-query/group_partition.py +++ b/tests/system-test/2-query/group_partition.py @@ -437,6 +437,18 @@ class TDTestCase: tdSql.checkRows(10) tdSql.query(f"select const_col from (select 1 as const_col, count(c1) from {self.dbname}.{self.stable} t group by c1) partition by 1") tdSql.checkRows(10) + + def test_TD_32883(self): + sql = "select avg(c1), t9 from stb group by t9,t9, tbname" + tdSql.query(sql, queryTimes=1) + tdSql.checkRows(5) + sql = "select avg(c1), t10 from stb group by t10,t10, tbname" + tdSql.query(sql, queryTimes=1) + tdSql.checkRows(5) + sql = "select avg(c1), t10 from stb partition by t10,t10, tbname" + tdSql.query(sql, queryTimes=1) + tdSql.checkRows(5) + def run(self): tdSql.prepare() self.prepare_db() @@ -470,6 +482,7 @@ class TDTestCase: self.test_event_window(nonempty_tb_num) self.test_TS5567() + self.test_TD_32883() ## test old version before changed # self.test_groupby('group', 0, 0) From 2be0ca15d8653b6b593c38b9bcc90f1befa84690 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Fri, 15 Nov 2024 18:10:44 +0800 Subject: [PATCH 26/47] fix group_partition test --- source/dnode/vnode/src/tsdb/tsdbRead2.c | 4 ++-- source/libs/parser/src/parCalcConst.c | 2 ++ tests/system-test/2-query/group_partition.py | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRead2.c b/source/dnode/vnode/src/tsdb/tsdbRead2.c index f30f7eb310..cc896dfa80 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead2.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead2.c @@ -6115,7 +6115,7 @@ int32_t tsdbNextDataBlock2(STsdbReader* pReader, bool* hasNext) { TSDB_CHECK_CODE(code, lino, _end); } - goto _end; + return code; } } @@ -6142,7 +6142,7 @@ int32_t tsdbNextDataBlock2(STsdbReader* pReader, bool* hasNext) { acquired = false; TSDB_CHECK_CODE(code, lino, _end); } - goto _end; + return code; } if (pReader->step == EXTERNAL_ROWS_MAIN && pReader->innerReader[1] != NULL) { diff --git a/source/libs/parser/src/parCalcConst.c b/source/libs/parser/src/parCalcConst.c index e757ec8b24..778c34ff02 100644 --- a/source/libs/parser/src/parCalcConst.c +++ b/source/libs/parser/src/parCalcConst.c @@ -326,6 +326,7 @@ static int32_t calcConstProjections(SCalcConstContext* pCxt, SSelectStmt* pSelec static int32_t calcConstGroupBy(SCalcConstContext* pCxt, SSelectStmt* pSelect) { int32_t code = calcConstList(pSelect->pGroupByList); +#if 0 if (TSDB_CODE_SUCCESS == code) { SNode* pNode = NULL; FOREACH(pNode, pSelect->pGroupByList) { @@ -338,6 +339,7 @@ static int32_t calcConstGroupBy(SCalcConstContext* pCxt, SSelectStmt* pSelect) { } NODES_DESTORY_LIST(pSelect->pGroupByList); } +#endif return code; } diff --git a/tests/system-test/2-query/group_partition.py b/tests/system-test/2-query/group_partition.py index d48df16231..b77cf3f8b7 100644 --- a/tests/system-test/2-query/group_partition.py +++ b/tests/system-test/2-query/group_partition.py @@ -422,19 +422,19 @@ class TDTestCase: def test_TS5567(self): tdSql.query(f"select const_col from (select 1 as const_col from {self.dbname}.{self.stable}) t group by const_col") - tdSql.checkRows(50) + tdSql.checkRows(1) tdSql.query(f"select const_col from (select 1 as const_col from {self.dbname}.{self.stable}) t partition by const_col") tdSql.checkRows(50) tdSql.query(f"select const_col from (select 1 as const_col, count(c1) from {self.dbname}.{self.stable} t group by c1) group by const_col") - tdSql.checkRows(10) + tdSql.checkRows(1) tdSql.query(f"select const_col from (select 1 as const_col, count(c1) from {self.dbname}.{self.stable} t group by c1) partition by const_col") tdSql.checkRows(10) tdSql.query(f"select const_col as c_c from (select 1 as const_col from {self.dbname}.{self.stable}) t group by c_c") - tdSql.checkRows(50) + tdSql.checkRows(1) tdSql.query(f"select const_col as c_c from (select 1 as const_col from {self.dbname}.{self.stable}) t partition by c_c") tdSql.checkRows(50) tdSql.query(f"select const_col from (select 1 as const_col, count(c1) from {self.dbname}.{self.stable} t group by c1) group by 1") - tdSql.checkRows(10) + tdSql.checkRows(1) tdSql.query(f"select const_col from (select 1 as const_col, count(c1) from {self.dbname}.{self.stable} t group by c1) partition by 1") tdSql.checkRows(10) From 55239964a979cd44f5ca965b4aa92a9e72b81a0d Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 16 Nov 2024 01:56:33 +0800 Subject: [PATCH 27/47] refactor: injection error. --- source/libs/stream/src/streamCheckpoint.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/libs/stream/src/streamCheckpoint.c b/source/libs/stream/src/streamCheckpoint.c index 6c4c285ded..2280b7f06f 100644 --- a/source/libs/stream/src/streamCheckpoint.c +++ b/source/libs/stream/src/streamCheckpoint.c @@ -362,6 +362,10 @@ int32_t streamProcessCheckpointTriggerBlock(SStreamTask* pTask, SStreamDataBlock } } +#if 0 + taosMsleep(20*1000); +#endif + if (taskLevel == TASK_LEVEL__SOURCE) { int8_t type = pTask->outputInfo.type; pActiveInfo->allUpstreamTriggerRecv = 1; From b589f9089c3956ddb354ee5666036b6bc06b6112 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Mon, 18 Nov 2024 09:33:43 +0800 Subject: [PATCH 28/47] add test case --- source/libs/executor/src/scanoperator.c | 1 - source/libs/parser/src/parTranslater.c | 2 ++ tests/system-test/2-query/group_partition.py | 9 ++++++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index ecb6bd7aee..eac4f87b14 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -3043,7 +3043,6 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock } if (code) { - blockDataFreeRes((SSDataBlock*)pBlock); QUERY_CHECK_CODE(code, lino, _end); } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index b77c349a78..9bea3491c3 100755 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5531,6 +5531,7 @@ static int32_t translateGroupByList(STranslateContext* pCxt, SSelectStmt* pSelec SReplaceGroupByAliasCxt cxt = { .pTranslateCxt = pCxt, .pProjectionList = pSelect->pProjectionList}; nodesRewriteExprsPostOrder(pSelect->pGroupByList, translateGroupPartitionByImpl, &cxt); + return pCxt->errCode; } @@ -5542,6 +5543,7 @@ static int32_t translatePartitionByList(STranslateContext* pCxt, SSelectStmt* pS SReplaceGroupByAliasCxt cxt = { .pTranslateCxt = pCxt, .pProjectionList = pSelect->pProjectionList}; nodesRewriteExprsPostOrder(pSelect->pPartitionByList, translateGroupPartitionByImpl, &cxt); + return pCxt->errCode; } diff --git a/tests/system-test/2-query/group_partition.py b/tests/system-test/2-query/group_partition.py index b77cf3f8b7..74f5e86267 100644 --- a/tests/system-test/2-query/group_partition.py +++ b/tests/system-test/2-query/group_partition.py @@ -439,13 +439,16 @@ class TDTestCase: tdSql.checkRows(10) def test_TD_32883(self): - sql = "select avg(c1), t9 from stb group by t9,t9, tbname" + sql = "select avg(c1), t9 from db.stb group by t9,t9, tbname" tdSql.query(sql, queryTimes=1) tdSql.checkRows(5) - sql = "select avg(c1), t10 from stb group by t10,t10, tbname" + sql = "select avg(c1), t10 from db.stb group by t10,t10, tbname" tdSql.query(sql, queryTimes=1) tdSql.checkRows(5) - sql = "select avg(c1), t10 from stb partition by t10,t10, tbname" + sql = "select avg(c1), t10 from db.stb partition by t10,t10, tbname" + tdSql.query(sql, queryTimes=1) + tdSql.checkRows(5) + sql = "select avg(c1), concat(t9,t10) from db.stb group by concat(t9,t10), concat(t9,t10),tbname" tdSql.query(sql, queryTimes=1) tdSql.checkRows(5) From 6d8a5b892ee5abe10b94b9d10a05d95babcd200a Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Mon, 18 Nov 2024 09:37:20 +0800 Subject: [PATCH 29/47] rename doc 28-index.md ->28-tsma.md --- docs/zh/14-reference/03-taos-sql/{28-index.md => 28-tsma.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/zh/14-reference/03-taos-sql/{28-index.md => 28-tsma.md} (100%) diff --git a/docs/zh/14-reference/03-taos-sql/28-index.md b/docs/zh/14-reference/03-taos-sql/28-tsma.md similarity index 100% rename from docs/zh/14-reference/03-taos-sql/28-index.md rename to docs/zh/14-reference/03-taos-sql/28-tsma.md From c6657653c68e5049f64247d38acfeafccb7c97a6 Mon Sep 17 00:00:00 2001 From: Yu Chen <74105241+yu285@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:42:15 +0800 Subject: [PATCH 30/47] docs/Update 03-stream.md --- docs/zh/06-advanced/03-stream.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh/06-advanced/03-stream.md b/docs/zh/06-advanced/03-stream.md index c47831dde3..c26924561c 100644 --- a/docs/zh/06-advanced/03-stream.md +++ b/docs/zh/06-advanced/03-stream.md @@ -124,7 +124,7 @@ create stream if not exists count_history_s fill_history 1 into count_history as 窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,此时事件时间无法更新,可能导致无法得到最新的计算结果。 -因此,流计算提供了以事件时间结合处理时间计算的 MAX_DELAY 触发模式。MAX_DELAY 模式在窗口关闭时会立即触发计算。此外,当数据写入后,计算触发的时间超过 max delay 指定的时间,则立即触发计算。 +因此,流计算提供了以事件时间结合处理时间计算的 MAX_DELAY 触发模式:MAX_DELAY 模式在窗口关闭时会立即触发计算,它的单位可以自行指定,具体单位:a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。此外,当数据写入后,计算触发的时间超过 MAX_DELAY 指定的时间,则立即触发计算。 ### 流计算的窗口关闭 @@ -259,4 +259,4 @@ flush database test1; 5.修改 taos.cfg,去掉 disableStream 1,或将 disableStream 改为 0 -6.启动 taosd \ No newline at end of file +6.启动 taosd From c954d0ac7addd1e8f395c8a0d9f006c97a0e2b59 Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Mon, 18 Nov 2024 11:20:32 +0800 Subject: [PATCH 31/47] fix:skip begin&end snapshot while wal level = 0. --- source/libs/wal/src/walWrite.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/libs/wal/src/walWrite.c b/source/libs/wal/src/walWrite.c index 1a9652b3bb..66ead2fd26 100644 --- a/source/libs/wal/src/walWrite.c +++ b/source/libs/wal/src/walWrite.c @@ -376,6 +376,10 @@ static FORCE_INLINE int32_t walCheckAndRoll(SWal *pWal) { int32_t walBeginSnapshot(SWal *pWal, int64_t ver, int64_t logRetention) { int32_t code = 0; + if (pWal->cfg.level == TAOS_WAL_SKIP) { + TAOS_RETURN(TSDB_CODE_SUCCESS); + } + if (logRetention < 0) { TAOS_RETURN(TSDB_CODE_FAILED); } @@ -404,6 +408,10 @@ _exit: int32_t walEndSnapshot(SWal *pWal) { int32_t code = 0, lino = 0; + if (pWal->cfg.level == TAOS_WAL_SKIP) { + TAOS_RETURN(TSDB_CODE_SUCCESS); + } + TAOS_UNUSED(taosThreadRwlockWrlock(&pWal->mutex)); int64_t ver = pWal->vers.verInSnapshotting; From 7348cbe5ef1394e10fc0784c8570582d06d2367b Mon Sep 17 00:00:00 2001 From: dmchen Date: Mon, 18 Nov 2024 12:31:38 +0800 Subject: [PATCH 32/47] fix/TD-32914-free-vnode-after-lock --- source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index 2ee607949d..17a99c1806 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -578,16 +578,13 @@ static int32_t vmOpenVnodes(SVnodeMgmt *pMgmt) { } void vmRemoveFromCreatingHash(SVnodeMgmt *pMgmt, int32_t vgId) { - (void)taosThreadRwlockWrlock(&pMgmt->lock); SVnodeObj *pOld = NULL; + + (void)taosThreadRwlockWrlock(&pMgmt->lock); int32_t r = taosHashGetDup(pMgmt->creatingHash, &vgId, sizeof(int32_t), (void *)&pOld); if (r != 0) { dError("vgId:%d, failed to get vnode from creating Hash", vgId); } - if (pOld) { - dTrace("vgId:%d, free vnode pOld:%p", vgId, &pOld); - vmFreeVnodeObj(&pOld); - } dTrace("vgId:%d, remove from creating Hash", vgId); r = taosHashRemove(pMgmt->creatingHash, &vgId, sizeof(int32_t)); if (r != 0) { @@ -595,6 +592,11 @@ void vmRemoveFromCreatingHash(SVnodeMgmt *pMgmt, int32_t vgId) { } (void)taosThreadRwlockUnlock(&pMgmt->lock); + if (pOld) { + dTrace("vgId:%d, free vnode pOld:%p", vgId, &pOld); + vmFreeVnodeObj(&pOld); + } + _OVER: if (r != 0) { dError("vgId:%d, failed to remove vnode from creatingHash since %s", vgId, tstrerror(r)); From f0c182988cd23c3dc8561559a351b553e0fd6024 Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Mon, 18 Nov 2024 13:49:03 +0800 Subject: [PATCH 33/47] Add test case for begin&end snapshot while wal_level =0 . --- source/libs/wal/test/walMetaTest.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source/libs/wal/test/walMetaTest.cpp b/source/libs/wal/test/walMetaTest.cpp index 3e6fab116f..a958ad74e0 100644 --- a/source/libs/wal/test/walMetaTest.cpp +++ b/source/libs/wal/test/walMetaTest.cpp @@ -510,4 +510,27 @@ TEST_F(WalSkipLevel, restart) { TearDown(); SetUp(); +} + +TEST_F(WalSkipLevel, roll) { + int code; + int i; + for (i = 0; i < 100; i++) { + code = walAppendLog(pWal, i, 0, syncMeta, (void*)ranStr, ranStrLen); + ASSERT_EQ(code, 0); + code = walCommit(pWal, i); + } + walBeginSnapshot(pWal, i - 1, 0); + walEndSnapshot(pWal); + code = walAppendLog(pWal, 5, 0, syncMeta, (void*)ranStr, ranStrLen); + ASSERT_NE(code, 0); + for (; i < 200; i++) { + code = walAppendLog(pWal, i, 0, syncMeta, (void*)ranStr, ranStrLen); + ASSERT_EQ(code, 0); + code = walCommit(pWal, i); + } + code = walBeginSnapshot(pWal, i - 1, 0); + ASSERT_EQ(code, 0); + code = walEndSnapshot(pWal); + ASSERT_EQ(code, 0); } \ No newline at end of file From 6c18289de0f0a85e48f37abba6f3c6bebe660f10 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Wed, 13 Nov 2024 17:01:50 +0800 Subject: [PATCH 34/47] fix tsbs perf issue --- include/libs/catalog/catalog.h | 1 + include/util/tbuffer.inc | 18 +++++- source/dnode/vnode/src/tsdb/tsdbDataFileRW.c | 2 +- source/dnode/vnode/src/tsdb/tsdbRead2.c | 11 +++- source/libs/catalog/inc/catalogInt.h | 1 + source/libs/catalog/src/ctgAsync.c | 32 +++++----- source/libs/function/src/builtinsimpl.c | 61 ++++++++++---------- source/libs/parser/inc/parUtil.h | 1 + source/libs/parser/src/parAstParser.c | 3 +- source/libs/parser/src/parUtil.c | 1 + 10 files changed, 80 insertions(+), 51 deletions(-) diff --git a/include/libs/catalog/catalog.h b/include/libs/catalog/catalog.h index df3f87973f..7c6f02513e 100644 --- a/include/libs/catalog/catalog.h +++ b/include/libs/catalog/catalog.h @@ -102,6 +102,7 @@ typedef struct SCatalogReq { bool svrVerRequired; bool forceUpdate; bool cloned; + bool forceFetchViewMeta; } SCatalogReq; typedef struct SMetaRes { diff --git a/include/util/tbuffer.inc b/include/util/tbuffer.inc index 39090fb7fa..633517ca58 100644 --- a/include/util/tbuffer.inc +++ b/include/util/tbuffer.inc @@ -186,11 +186,25 @@ static int32_t tBufferGetI16(SBufferReader *reader, int16_t *value) { } static int32_t tBufferGetI32(SBufferReader *reader, int32_t *value) { - return tBufferGet(reader, sizeof(*value), value); + if (reader->offset + sizeof(int32_t) > reader->buffer->size) { + return TSDB_CODE_OUT_OF_RANGE; + } + if (value) { + *value = *(int32_t*)BR_PTR(reader); + } + reader->offset += sizeof(int32_t); + return 0; } static int32_t tBufferGetI64(SBufferReader *reader, int64_t *value) { - return tBufferGet(reader, sizeof(*value), value); + if (reader->offset + sizeof(int64_t) > reader->buffer->size) { + return TSDB_CODE_OUT_OF_RANGE; + } + if (value) { + *value = *(int64_t*)BR_PTR(reader); + } + reader->offset += sizeof(int64_t); + return 0; } static int32_t tBufferGetU8(SBufferReader *reader, uint8_t *value) { return tBufferGet(reader, sizeof(*value), value); } diff --git a/source/dnode/vnode/src/tsdb/tsdbDataFileRW.c b/source/dnode/vnode/src/tsdb/tsdbDataFileRW.c index 720ba68414..f51ffe0c83 100644 --- a/source/dnode/vnode/src/tsdb/tsdbDataFileRW.c +++ b/source/dnode/vnode/src/tsdb/tsdbDataFileRW.c @@ -972,7 +972,7 @@ static int32_t tsdbDataFileWriteBrinRecord(SDataFileWriter *writer, const SBrinR break; } - if ((writer->brinBlock->numOfRecords) >= writer->config->maxRow) { + if ((writer->brinBlock->numOfRecords) >= 256) { TAOS_CHECK_GOTO(tsdbDataFileWriteBrinBlock(writer), &lino, _exit); } diff --git a/source/dnode/vnode/src/tsdb/tsdbRead2.c b/source/dnode/vnode/src/tsdb/tsdbRead2.c index f30f7eb310..2b1be747dd 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead2.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead2.c @@ -836,6 +836,7 @@ static int32_t doLoadBlockIndex(STsdbReader* pReader, SDataFileReader* pFileRead pList = &pReader->status.uidList; int32_t i = 0; + int32_t j = 0; while (i < TARRAY2_SIZE(pBlkArray)) { pBrinBlk = &pBlkArray->data[i]; if (pBrinBlk->maxTbid.suid < pReader->info.suid) { @@ -851,7 +852,7 @@ static int32_t doLoadBlockIndex(STsdbReader* pReader, SDataFileReader* pFileRead (pBrinBlk->minTbid.suid <= pReader->info.suid) && (pBrinBlk->maxTbid.suid >= pReader->info.suid), code, lino, _end, TSDB_CODE_INTERNAL_ERROR); - if (pBrinBlk->maxTbid.suid == pReader->info.suid && pBrinBlk->maxTbid.uid < pList->tableUidList[0]) { + if (pBrinBlk->maxTbid.suid == pReader->info.suid && pBrinBlk->maxTbid.uid < pList->tableUidList[j]) { i += 1; continue; } @@ -864,6 +865,14 @@ static int32_t doLoadBlockIndex(STsdbReader* pReader, SDataFileReader* pFileRead TSDB_CHECK_NULL(p1, code, lino, _end, terrno); i += 1; + if (pBrinBlk->maxTbid.suid == pReader->info.suid) { + while (j < numOfTables && pList->tableUidList[j] < pBrinBlk->maxTbid.uid) { + j++; + } + if (j >= numOfTables) { + break; + } + } } et2 = taosGetTimestampUs(); diff --git a/source/libs/catalog/inc/catalogInt.h b/source/libs/catalog/inc/catalogInt.h index e757163ba8..bfc5ca9142 100644 --- a/source/libs/catalog/inc/catalogInt.h +++ b/source/libs/catalog/inc/catalogInt.h @@ -271,6 +271,7 @@ typedef struct SCtgViewsCtx { SArray* pNames; SArray* pResList; SArray* pFetchs; + bool forceFetch; } SCtgViewsCtx; typedef enum { diff --git a/source/libs/catalog/src/ctgAsync.c b/source/libs/catalog/src/ctgAsync.c index c1dcdf2741..9bfb4102aa 100644 --- a/source/libs/catalog/src/ctgAsync.c +++ b/source/libs/catalog/src/ctgAsync.c @@ -20,6 +20,11 @@ #include "tref.h" #include "trpc.h" +typedef struct SCtgViewTaskParam { + bool forceFetch; + SArray* pTableReqs; +} SCtgViewTaskParam; + void ctgIsTaskDone(SCtgJob* pJob, CTG_TASK_TYPE type, bool* done) { SCtgTask* pTask = NULL; @@ -500,7 +505,7 @@ int32_t ctgInitGetTbTagTask(SCtgJob* pJob, int32_t taskIdx, void* param) { int32_t ctgInitGetViewsTask(SCtgJob* pJob, int32_t taskIdx, void* param) { SCtgTask task = {0}; - + SCtgViewTaskParam* p = param; task.type = CTG_TASK_GET_VIEW; task.taskId = taskIdx; task.pJob = pJob; @@ -511,7 +516,8 @@ int32_t ctgInitGetViewsTask(SCtgJob* pJob, int32_t taskIdx, void* param) { } SCtgViewsCtx* ctx = task.taskCtx; - ctx->pNames = param; + ctx->pNames = p->pTableReqs; + ctx->forceFetch = p->forceFetch; ctx->pResList = taosArrayInit(pJob->viewNum, sizeof(SMetaRes)); if (NULL == ctx->pResList) { qError("QID:0x%" PRIx64 " taosArrayInit %d SMetaRes %d failed", pJob->queryId, pJob->viewNum, @@ -849,13 +855,12 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgJob** job, const int32_t tbCfgNum = (int32_t)taosArrayGetSize(pReq->pTableCfg); int32_t tbTagNum = (int32_t)taosArrayGetSize(pReq->pTableTag); int32_t viewNum = (int32_t)ctgGetTablesReqNum(pReq->pView); - int32_t tbTsmaNum = (int32_t)taosArrayGetSize(pReq->pTableTSMAs); + int32_t tbTsmaNum = tsQuerySmaOptimize ? (int32_t)taosArrayGetSize(pReq->pTableTSMAs) : 0; int32_t tsmaNum = (int32_t)taosArrayGetSize(pReq->pTSMAs); int32_t tbNameNum = (int32_t)ctgGetTablesReqNum(pReq->pTableName); int32_t taskNum = tbMetaNum + dbVgNum + udfNum + tbHashNum + qnodeNum + dnodeNum + svrVerNum + dbCfgNum + indexNum + userNum + dbInfoNum + tbIndexNum + tbCfgNum + tbTagNum + viewNum + tbTsmaNum + tbNameNum; - *job = taosMemoryCalloc(1, sizeof(SCtgJob)); if (NULL == *job) { ctgError("failed to calloc, size:%d,QID:0x%" PRIx64, (int32_t)sizeof(SCtgJob), pConn->requestId); @@ -1014,7 +1019,8 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgJob** job, const } if (viewNum > 0) { - CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_VIEW, pReq->pView, NULL)); + SCtgViewTaskParam param = {.forceFetch = pReq->forceFetchViewMeta, .pTableReqs = pReq->pView}; + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_VIEW, ¶m, NULL)); } if (tbTsmaNum > 0) { CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_TB_TSMA, pReq->pTableTSMAs, NULL)); @@ -3712,16 +3718,14 @@ int32_t ctgLaunchGetViewsTask(SCtgTask* pTask) { bool tbMetaDone = false; SName* pName = NULL; - /* - ctgIsTaskDone(pJob, CTG_TASK_GET_TB_META_BATCH, &tbMetaDone); - if (tbMetaDone) { - CTG_ERR_RET(ctgBuildViewNullRes(pTask, pCtx)); - TSWAP(pTask->res, pCtx->pResList); + ctgIsTaskDone(pJob, CTG_TASK_GET_TB_META_BATCH, &tbMetaDone); + if (tbMetaDone && !pCtx->forceFetch) { + CTG_ERR_RET(ctgBuildViewNullRes(pTask, pCtx)); + TSWAP(pTask->res, pCtx->pResList); - CTG_ERR_RET(ctgHandleTaskEnd(pTask, 0)); - return TSDB_CODE_SUCCESS; - } - */ + CTG_ERR_RET(ctgHandleTaskEnd(pTask, 0)); + return TSDB_CODE_SUCCESS; + } int32_t dbNum = taosArrayGetSize(pCtx->pNames); int32_t fetchIdx = 0; diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index c2e2e9c17c..1b755e0f38 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -3037,61 +3037,58 @@ int32_t lastRowFunction(SqlFunctionCtx* pCtx) { TSKEY startKey = getRowPTs(pInput->pPTS, 0); TSKEY endKey = getRowPTs(pInput->pPTS, pInput->totalRows - 1); -#if 0 - int32_t blockDataOrder = (startKey <= endKey) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; - - // the optimized version only valid if all tuples in one block are monotonious increasing or descreasing. - // this assumption is NOT always works if project operator exists in downstream. - if (blockDataOrder == TSDB_ORDER_ASC) { + if (pCtx->order == TSDB_ORDER_ASC && !pCtx->hasPrimaryKey) { for (int32_t i = pInput->numOfRows + pInput->startRowIndex - 1; i >= pInput->startRowIndex; --i) { char* data = colDataGetData(pInputCol, i); TSKEY cts = getRowPTs(pInput->pPTS, i); numOfElems++; if (pResInfo->numOfRes == 0 || pInfo->ts < cts) { - doSaveLastrow(pCtx, data, i, cts, pInfo); + int32_t code = doSaveLastrow(pCtx, data, i, cts, pInfo); + if (code != TSDB_CODE_SUCCESS) return code; } break; } - } else { // descending order + } else if (!pCtx->hasPrimaryKey && pCtx->order == TSDB_ORDER_DESC) { + // the optimized version only valid if all tuples in one block are monotonious increasing or descreasing. + // this assumption is NOT always works if project operator exists in downstream. for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { char* data = colDataGetData(pInputCol, i); TSKEY cts = getRowPTs(pInput->pPTS, i); numOfElems++; if (pResInfo->numOfRes == 0 || pInfo->ts < cts) { - doSaveLastrow(pCtx, data, i, cts, pInfo); + int32_t code = doSaveLastrow(pCtx, data, i, cts, pInfo); + if (code != TSDB_CODE_SUCCESS) return code; } break; } - } -#else + } else { + int64_t* pts = (int64_t*)pInput->pPTS->pData; + int from = -1; + int32_t i = -1; + while (funcInputGetNextRowIndex(pInput, from, false, &i, &from)) { + bool isNull = colDataIsNull(pInputCol, pInput->numOfRows, i, NULL); + char* data = isNull ? NULL : colDataGetData(pInputCol, i); + TSKEY cts = pts[i]; - int64_t* pts = (int64_t*)pInput->pPTS->pData; - int from = -1; - int32_t i = -1; - while (funcInputGetNextRowIndex(pInput, from, false, &i, &from)) { - bool isNull = colDataIsNull(pInputCol, pInput->numOfRows, i, NULL); - char* data = isNull ? NULL : colDataGetData(pInputCol, i); - TSKEY cts = pts[i]; - - numOfElems++; - char* pkData = NULL; - if (pCtx->hasPrimaryKey) { - pkData = colDataGetData(pkCol, i); - } - if (pResInfo->numOfRes == 0 || pInfo->ts < cts || - (pInfo->ts == pts[i] && pkCompareFn && pkCompareFn(pkData, pInfo->pkData) < 0)) { - int32_t code = doSaveLastrow(pCtx, data, i, cts, pInfo); - if (code != TSDB_CODE_SUCCESS) { - return code; + numOfElems++; + char* pkData = NULL; + if (pCtx->hasPrimaryKey) { + pkData = colDataGetData(pkCol, i); + } + if (pResInfo->numOfRes == 0 || pInfo->ts < cts || + (pInfo->ts == pts[i] && pkCompareFn && pkCompareFn(pkData, pInfo->pkData) < 0)) { + int32_t code = doSaveLastrow(pCtx, data, i, cts, pInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + pResInfo->numOfRes = 1; } - pResInfo->numOfRes = 1; } - } -#endif + } SET_VAL(pResInfo, numOfElems, 1); return TSDB_CODE_SUCCESS; diff --git a/source/libs/parser/inc/parUtil.h b/source/libs/parser/inc/parUtil.h index 857c7604a9..7298b04eb0 100644 --- a/source/libs/parser/inc/parUtil.h +++ b/source/libs/parser/inc/parUtil.h @@ -115,6 +115,7 @@ typedef struct SParseMetaCache { SHashObj* pTableName; // key is tbFUid, elements is STableMeta*(append with tbName) SArray* pDnodes; // element is SEpSet bool dnodeRequired; + bool forceFetchViewMeta; } SParseMetaCache; int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...); diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index eecc04658b..b78e10768f 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -810,7 +810,7 @@ static int32_t collectMetaKeyFromShowCreateView(SCollectMetaKeyCxt* pCxt, SShowC if (TSDB_CODE_SUCCESS == code) { code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->viewName, pCxt->pMetaCache); } - + pCxt->pMetaCache->forceFetchViewMeta = true; return code; } @@ -888,6 +888,7 @@ static int32_t collectMetaKeyFromCreateViewStmt(SCollectMetaKeyCxt* pCxt, SCreat static int32_t collectMetaKeyFromDropViewStmt(SCollectMetaKeyCxt* pCxt, SDropViewStmt* pStmt) { int32_t code = reserveViewUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName, pStmt->viewName, AUTH_TYPE_ALTER, pCxt->pMetaCache); + pCxt->pMetaCache->forceFetchViewMeta = true; return code; } diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index e35eea9e72..44e44982a3 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -817,6 +817,7 @@ int32_t buildCatalogReq(const SParseMetaCache* pMetaCache, SCatalogReq* pCatalog } #endif pCatalogReq->dNodeRequired = pMetaCache->dnodeRequired; + pCatalogReq->forceFetchViewMeta = pMetaCache->forceFetchViewMeta; return code; } From a6ab76b02e97186f91226d958fdcacea1a8c2856 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Thu, 14 Nov 2024 10:50:27 +0800 Subject: [PATCH 35/47] fix lastrow function tests --- source/libs/function/src/builtinsimpl.c | 6 ++++-- source/libs/planner/src/planOptimizer.c | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 1b755e0f38..83227dea9e 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -3039,7 +3039,8 @@ int32_t lastRowFunction(SqlFunctionCtx* pCtx) { if (pCtx->order == TSDB_ORDER_ASC && !pCtx->hasPrimaryKey) { for (int32_t i = pInput->numOfRows + pInput->startRowIndex - 1; i >= pInput->startRowIndex; --i) { - char* data = colDataGetData(pInputCol, i); + bool isNull = colDataIsNull(pInputCol, pInput->numOfRows, i, NULL); + char* data = isNull ? NULL : colDataGetData(pInputCol, i); TSKEY cts = getRowPTs(pInput->pPTS, i); numOfElems++; @@ -3054,7 +3055,8 @@ int32_t lastRowFunction(SqlFunctionCtx* pCtx) { // the optimized version only valid if all tuples in one block are monotonious increasing or descreasing. // this assumption is NOT always works if project operator exists in downstream. for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { - char* data = colDataGetData(pInputCol, i); + bool isNull = colDataIsNull(pInputCol, pInput->numOfRows, i, NULL); + char* data = isNull ? NULL : colDataGetData(pInputCol, i); TSKEY cts = getRowPTs(pInput->pPTS, i); numOfElems++; diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 39024731ed..a1809ff137 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -204,6 +204,7 @@ static void optSetParentOrder(SLogicNode* pNode, EOrder order, SLogicNode* pNode // case QUERY_NODE_LOGIC_PLAN_WINDOW: case QUERY_NODE_LOGIC_PLAN_AGG: case QUERY_NODE_LOGIC_PLAN_SORT: + case QUERY_NODE_LOGIC_PLAN_FILL: if (pNode == pNodeForcePropagate) { pNode->outputTsOrder = order; break; From 2d9b78216b10896f5bdc7137df581f48791fe212 Mon Sep 17 00:00:00 2001 From: WANG Xu Date: Mon, 18 Nov 2024 14:52:21 +0800 Subject: [PATCH 36/47] Create pull_request_template.md --- .github/pull_request_template.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..7d877987ac --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,5 @@ +# Pull Request Checklist + +- [ ] Is the user manual updated? +- [ ] Are the test cases passed and automated? +- [ ] Is there no significant decrease in test coverage? From f5c66cec19d01f74d0595c59b0d9dc0fa1522806 Mon Sep 17 00:00:00 2001 From: Jinqing Kuang Date: Mon, 18 Nov 2024 15:04:40 +0800 Subject: [PATCH 37/47] fix(query)[TD-32861]. fix that WHERE condition not work with INTERP function Previously, a statement with INTERP would force underlying TABLE SCAN operator to scan all data within the RANGE clause, causing the time range constraint in the WHERE condition to be ignored. This fix ensures that the TABLE SCAN respects both the RANGE clause and WHERE condition, improving query accuracy and performance. --- include/common/tcommon.h | 1 + source/dnode/vnode/src/tsdb/tsdbRead2.c | 19 +- source/libs/executor/src/timesliceoperator.c | 47 +- tests/army/query/function/ans/interp.csv | 649 +++++++++++++++++++ tests/army/query/function/in/interp.in | 50 ++ tests/army/query/function/test_interp.py | 11 + 6 files changed, 766 insertions(+), 11 deletions(-) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index ea764e6760..111c9dde3c 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -250,6 +250,7 @@ typedef struct SQueryTableDataCond { int32_t type; // data block load type: bool skipRollup; STimeWindow twindows; + STimeWindow extTwindows[2]; int64_t startVersion; int64_t endVersion; bool notLoadData; // response the actual data, not only the rows in the attribute of info.row of ssdatablock diff --git a/source/dnode/vnode/src/tsdb/tsdbRead2.c b/source/dnode/vnode/src/tsdb/tsdbRead2.c index f30f7eb310..ae1488f11b 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead2.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead2.c @@ -1134,7 +1134,12 @@ static int32_t getCurrentBlockInfo(SDataBlockIter* pBlockIter, SFileDataBlockInf *pInfo = NULL; size_t num = TARRAY_SIZE(pBlockIter->blockList); - TSDB_CHECK_CONDITION(num != 0, code, lino, _end, TSDB_CODE_INVALID_PARA); + if (num == 0) { + // Some callers would attempt to call this function. Filter out certain normal cases and return directly to avoid + // generating excessive unnecessary error logs. + TSDB_CHECK_CONDITION(num == pBlockIter->numOfBlocks, code, lino, _end, TSDB_CODE_INVALID_PARA); + return TSDB_CODE_INVALID_PARA; + } *pInfo = taosArrayGet(pBlockIter->blockList, pBlockIter->index); TSDB_CHECK_NULL(*pInfo, code, lino, _end, TSDB_CODE_INVALID_PARA); @@ -5530,12 +5535,10 @@ int32_t tsdbReaderOpen2(void* pVnode, SQueryTableDataCond* pCond, void* pTableLi // update the SQueryTableDataCond to create inner reader int32_t order = pCond->order; if (order == TSDB_ORDER_ASC) { - pCond->twindows.ekey = window.skey - 1; - pCond->twindows.skey = INT64_MIN; + pCond->twindows = pCond->extTwindows[0]; pCond->order = TSDB_ORDER_DESC; } else { - pCond->twindows.skey = window.ekey + 1; - pCond->twindows.ekey = INT64_MAX; + pCond->twindows = pCond->extTwindows[1]; pCond->order = TSDB_ORDER_ASC; } @@ -5544,11 +5547,9 @@ int32_t tsdbReaderOpen2(void* pVnode, SQueryTableDataCond* pCond, void* pTableLi TSDB_CHECK_CODE(code, lino, _end); if (order == TSDB_ORDER_ASC) { - pCond->twindows.skey = window.ekey + 1; - pCond->twindows.ekey = INT64_MAX; + pCond->twindows = pCond->extTwindows[1]; } else { - pCond->twindows.skey = INT64_MIN; - pCond->twindows.ekey = window.ekey - 1; + pCond->twindows = pCond->extTwindows[0]; } pCond->order = order; diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index f77aa8f34a..50deba932f 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -1131,6 +1131,47 @@ static int32_t extractPkColumnFromFuncs(SNodeList* pFuncs, bool* pHasPk, SColumn return TSDB_CODE_SUCCESS; } +/** + * @brief Determine the actual time range for reading data based on the RANGE clause and the WHERE conditions. + * @param[in] cond The range specified by WHERE condition. + * @param[in] range The range specified by RANGE clause. + * @param[out] twindow The range to be read in DESC order, and only one record is needed. + * @param[out] extTwindow The external range to read for only one record, which is used for FILL clause. + * @note `cond` and `twindow` may be the same address. + */ +static int32_t getQueryExtWindow(const STimeWindow* cond, const STimeWindow* range, STimeWindow* twindow, + STimeWindow* extTwindows) { + int32_t code = TSDB_CODE_SUCCESS; + int32_t lino = 0; + STimeWindow tempWindow; + + if (cond->skey > cond->ekey || range->skey > range->ekey) { + *twindow = extTwindows[0] = extTwindows[1] = TSWINDOW_DESC_INITIALIZER; + return code; + } + + if (range->ekey < cond->skey) { + extTwindows[1] = *cond; + *twindow = extTwindows[0] = TSWINDOW_DESC_INITIALIZER; + return code; + } + + if (cond->ekey < range->skey) { + extTwindows[0] = *cond; + *twindow = extTwindows[1] = TSWINDOW_DESC_INITIALIZER; + return code; + } + + // Only scan data in the time range intersecion. + extTwindows[0] = extTwindows[1] = *cond; + twindow->skey = TMAX(cond->skey, range->skey); + twindow->ekey = TMIN(cond->ekey, range->ekey); + extTwindows[0].ekey = twindow->skey - 1; + extTwindows[1].skey = twindow->ekey + 1; + + return code; +} + int32_t createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pOptrInfo) { QRY_PARAM_CHECK(pOptrInfo); @@ -1206,8 +1247,10 @@ int32_t createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyN if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) { STableScanInfo* pScanInfo = (STableScanInfo*)downstream->info; - pScanInfo->base.cond.twindows = pInfo->win; - pScanInfo->base.cond.type = TIMEWINDOW_RANGE_EXTERNAL; + SQueryTableDataCond *cond = &pScanInfo->base.cond; + cond->type = TIMEWINDOW_RANGE_EXTERNAL; + code = getQueryExtWindow(&cond->twindows, &pInfo->win, &cond->twindows, cond->extTwindows); + QUERY_CHECK_CODE(code, lino, _error); } setOperatorInfo(pOperator, "TimeSliceOperator", QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC, false, OP_NOT_OPENED, pInfo, diff --git a/tests/army/query/function/ans/interp.csv b/tests/army/query/function/ans/interp.csv index e1ba236aa1..3eaccd887a 100644 --- a/tests/army/query/function/ans/interp.csv +++ b/tests/army/query/function/ans/interp.csv @@ -366,3 +366,652 @@ taos> select _irowts as irowts ,tbname as table_name, c2 as c_c2, c3 as c_c3, _i 2020-02-01 00:00:16.000 | td32727 | 10 | 10 | true | 1 | 2020-02-01 00:00:16.000 | td32727 | 15 | 15 | true | 1 | +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(null); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(value, 1); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(prev); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(next); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(linear); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(null); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(value, 1); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(prev); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(next); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(linear); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(null); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(value, 1); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(prev); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(next); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(linear); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(null); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:21.000 | false | 21 | + 2020-01-01 00:00:22.000 | true | NULL | + 2020-01-01 00:00:23.000 | true | NULL | + 2020-01-01 00:00:24.000 | true | NULL | + 2020-01-01 00:00:25.000 | true | NULL | + 2020-01-01 00:00:26.000 | true | NULL | + 2020-01-01 00:00:27.000 | true | NULL | + 2020-01-01 00:00:28.000 | true | NULL | + 2020-01-01 00:00:29.000 | true | NULL | + 2020-01-01 00:00:30.000 | true | NULL | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(value, 1); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:21.000 | false | 21 | + 2020-01-01 00:00:22.000 | true | 1 | + 2020-01-01 00:00:23.000 | true | 1 | + 2020-01-01 00:00:24.000 | true | 1 | + 2020-01-01 00:00:25.000 | true | 1 | + 2020-01-01 00:00:26.000 | true | 1 | + 2020-01-01 00:00:27.000 | true | 1 | + 2020-01-01 00:00:28.000 | true | 1 | + 2020-01-01 00:00:29.000 | true | 1 | + 2020-01-01 00:00:30.000 | true | 1 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(prev); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:21.000 | false | 21 | + 2020-01-01 00:00:22.000 | true | 21 | + 2020-01-01 00:00:23.000 | true | 21 | + 2020-01-01 00:00:24.000 | true | 21 | + 2020-01-01 00:00:25.000 | true | 21 | + 2020-01-01 00:00:26.000 | true | 21 | + 2020-01-01 00:00:27.000 | true | 21 | + 2020-01-01 00:00:28.000 | true | 21 | + 2020-01-01 00:00:29.000 | true | 21 | + 2020-01-01 00:00:30.000 | true | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(next); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(linear); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(null); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | NULL | + 2020-01-01 00:00:17.000 | true | NULL | + 2020-01-01 00:00:18.000 | true | NULL | + 2020-01-01 00:00:19.000 | true | NULL | + 2020-01-01 00:00:20.000 | true | NULL | + 2020-01-01 00:00:21.000 | false | 21 | + 2020-01-01 00:00:22.000 | true | NULL | + 2020-01-01 00:00:23.000 | true | NULL | + 2020-01-01 00:00:24.000 | true | NULL | + 2020-01-01 00:00:25.000 | true | NULL | + 2020-01-01 00:00:26.000 | true | NULL | + 2020-01-01 00:00:27.000 | true | NULL | + 2020-01-01 00:00:28.000 | true | NULL | + 2020-01-01 00:00:29.000 | true | NULL | + 2020-01-01 00:00:30.000 | true | NULL | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(value, 1); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 1 | + 2020-01-01 00:00:17.000 | true | 1 | + 2020-01-01 00:00:18.000 | true | 1 | + 2020-01-01 00:00:19.000 | true | 1 | + 2020-01-01 00:00:20.000 | true | 1 | + 2020-01-01 00:00:21.000 | false | 21 | + 2020-01-01 00:00:22.000 | true | 1 | + 2020-01-01 00:00:23.000 | true | 1 | + 2020-01-01 00:00:24.000 | true | 1 | + 2020-01-01 00:00:25.000 | true | 1 | + 2020-01-01 00:00:26.000 | true | 1 | + 2020-01-01 00:00:27.000 | true | 1 | + 2020-01-01 00:00:28.000 | true | 1 | + 2020-01-01 00:00:29.000 | true | 1 | + 2020-01-01 00:00:30.000 | true | 1 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(prev); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 15 | + 2020-01-01 00:00:17.000 | true | 15 | + 2020-01-01 00:00:18.000 | true | 15 | + 2020-01-01 00:00:19.000 | true | 15 | + 2020-01-01 00:00:20.000 | true | 15 | + 2020-01-01 00:00:21.000 | false | 21 | + 2020-01-01 00:00:22.000 | true | 21 | + 2020-01-01 00:00:23.000 | true | 21 | + 2020-01-01 00:00:24.000 | true | 21 | + 2020-01-01 00:00:25.000 | true | 21 | + 2020-01-01 00:00:26.000 | true | 21 | + 2020-01-01 00:00:27.000 | true | 21 | + 2020-01-01 00:00:28.000 | true | 21 | + 2020-01-01 00:00:29.000 | true | 21 | + 2020-01-01 00:00:30.000 | true | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(next); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 21 | + 2020-01-01 00:00:17.000 | true | 21 | + 2020-01-01 00:00:18.000 | true | 21 | + 2020-01-01 00:00:19.000 | true | 21 | + 2020-01-01 00:00:20.000 | true | 21 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(linear); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 16 | + 2020-01-01 00:00:17.000 | true | 17 | + 2020-01-01 00:00:18.000 | true | 18 | + 2020-01-01 00:00:19.000 | true | 19 | + 2020-01-01 00:00:20.000 | true | 20 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(null); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | NULL | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | NULL | + 2020-01-01 00:00:05.000 | true | NULL | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | NULL | + 2020-01-01 00:00:08.000 | true | NULL | + 2020-01-01 00:00:09.000 | true | NULL | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | NULL | + 2020-01-01 00:00:12.000 | true | NULL | + 2020-01-01 00:00:13.000 | true | NULL | + 2020-01-01 00:00:14.000 | true | NULL | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | NULL | + 2020-01-01 00:00:17.000 | true | NULL | + 2020-01-01 00:00:18.000 | true | NULL | + 2020-01-01 00:00:19.000 | true | NULL | + 2020-01-01 00:00:20.000 | true | NULL | + 2020-01-01 00:00:21.000 | false | 21 | + 2020-01-01 00:00:22.000 | true | NULL | + 2020-01-01 00:00:23.000 | true | NULL | + 2020-01-01 00:00:24.000 | true | NULL | + 2020-01-01 00:00:25.000 | true | NULL | + 2020-01-01 00:00:26.000 | true | NULL | + 2020-01-01 00:00:27.000 | true | NULL | + 2020-01-01 00:00:28.000 | true | NULL | + 2020-01-01 00:00:29.000 | true | NULL | + 2020-01-01 00:00:30.000 | true | NULL | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(value, 1); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | 1 | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | 1 | + 2020-01-01 00:00:05.000 | true | 1 | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | 1 | + 2020-01-01 00:00:08.000 | true | 1 | + 2020-01-01 00:00:09.000 | true | 1 | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | 1 | + 2020-01-01 00:00:12.000 | true | 1 | + 2020-01-01 00:00:13.000 | true | 1 | + 2020-01-01 00:00:14.000 | true | 1 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 1 | + 2020-01-01 00:00:17.000 | true | 1 | + 2020-01-01 00:00:18.000 | true | 1 | + 2020-01-01 00:00:19.000 | true | 1 | + 2020-01-01 00:00:20.000 | true | 1 | + 2020-01-01 00:00:21.000 | false | 21 | + 2020-01-01 00:00:22.000 | true | 1 | + 2020-01-01 00:00:23.000 | true | 1 | + 2020-01-01 00:00:24.000 | true | 1 | + 2020-01-01 00:00:25.000 | true | 1 | + 2020-01-01 00:00:26.000 | true | 1 | + 2020-01-01 00:00:27.000 | true | 1 | + 2020-01-01 00:00:28.000 | true | 1 | + 2020-01-01 00:00:29.000 | true | 1 | + 2020-01-01 00:00:30.000 | true | 1 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(prev); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | 1 | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | 3 | + 2020-01-01 00:00:05.000 | true | 3 | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | 6 | + 2020-01-01 00:00:08.000 | true | 6 | + 2020-01-01 00:00:09.000 | true | 6 | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | 10 | + 2020-01-01 00:00:12.000 | true | 10 | + 2020-01-01 00:00:13.000 | true | 10 | + 2020-01-01 00:00:14.000 | true | 10 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 15 | + 2020-01-01 00:00:17.000 | true | 15 | + 2020-01-01 00:00:18.000 | true | 15 | + 2020-01-01 00:00:19.000 | true | 15 | + 2020-01-01 00:00:20.000 | true | 15 | + 2020-01-01 00:00:21.000 | false | 21 | + 2020-01-01 00:00:22.000 | true | 21 | + 2020-01-01 00:00:23.000 | true | 21 | + 2020-01-01 00:00:24.000 | true | 21 | + 2020-01-01 00:00:25.000 | true | 21 | + 2020-01-01 00:00:26.000 | true | 21 | + 2020-01-01 00:00:27.000 | true | 21 | + 2020-01-01 00:00:28.000 | true | 21 | + 2020-01-01 00:00:29.000 | true | 21 | + 2020-01-01 00:00:30.000 | true | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(next); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | 3 | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | 6 | + 2020-01-01 00:00:05.000 | true | 6 | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | 10 | + 2020-01-01 00:00:08.000 | true | 10 | + 2020-01-01 00:00:09.000 | true | 10 | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | 15 | + 2020-01-01 00:00:12.000 | true | 15 | + 2020-01-01 00:00:13.000 | true | 15 | + 2020-01-01 00:00:14.000 | true | 15 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 21 | + 2020-01-01 00:00:17.000 | true | 21 | + 2020-01-01 00:00:18.000 | true | 21 | + 2020-01-01 00:00:19.000 | true | 21 | + 2020-01-01 00:00:20.000 | true | 21 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(linear); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | 2 | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | 4 | + 2020-01-01 00:00:05.000 | true | 5 | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | 7 | + 2020-01-01 00:00:08.000 | true | 8 | + 2020-01-01 00:00:09.000 | true | 9 | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | 11 | + 2020-01-01 00:00:12.000 | true | 12 | + 2020-01-01 00:00:13.000 | true | 13 | + 2020-01-01 00:00:14.000 | true | 14 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 16 | + 2020-01-01 00:00:17.000 | true | 17 | + 2020-01-01 00:00:18.000 | true | 18 | + 2020-01-01 00:00:19.000 | true | 19 | + 2020-01-01 00:00:20.000 | true | 20 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(null); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | NULL | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | NULL | + 2020-01-01 00:00:05.000 | true | NULL | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | NULL | + 2020-01-01 00:00:08.000 | true | NULL | + 2020-01-01 00:00:09.000 | true | NULL | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | NULL | + 2020-01-01 00:00:12.000 | true | NULL | + 2020-01-01 00:00:13.000 | true | NULL | + 2020-01-01 00:00:14.000 | true | NULL | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | NULL | + 2020-01-01 00:00:17.000 | true | NULL | + 2020-01-01 00:00:18.000 | true | NULL | + 2020-01-01 00:00:19.000 | true | NULL | + 2020-01-01 00:00:20.000 | true | NULL | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(value, 1); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | 1 | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | 1 | + 2020-01-01 00:00:05.000 | true | 1 | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | 1 | + 2020-01-01 00:00:08.000 | true | 1 | + 2020-01-01 00:00:09.000 | true | 1 | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | 1 | + 2020-01-01 00:00:12.000 | true | 1 | + 2020-01-01 00:00:13.000 | true | 1 | + 2020-01-01 00:00:14.000 | true | 1 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 1 | + 2020-01-01 00:00:17.000 | true | 1 | + 2020-01-01 00:00:18.000 | true | 1 | + 2020-01-01 00:00:19.000 | true | 1 | + 2020-01-01 00:00:20.000 | true | 1 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(prev); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | 1 | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | 3 | + 2020-01-01 00:00:05.000 | true | 3 | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | 6 | + 2020-01-01 00:00:08.000 | true | 6 | + 2020-01-01 00:00:09.000 | true | 6 | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | 10 | + 2020-01-01 00:00:12.000 | true | 10 | + 2020-01-01 00:00:13.000 | true | 10 | + 2020-01-01 00:00:14.000 | true | 10 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 15 | + 2020-01-01 00:00:17.000 | true | 15 | + 2020-01-01 00:00:18.000 | true | 15 | + 2020-01-01 00:00:19.000 | true | 15 | + 2020-01-01 00:00:20.000 | true | 15 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(next); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | 3 | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | 6 | + 2020-01-01 00:00:05.000 | true | 6 | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | 10 | + 2020-01-01 00:00:08.000 | true | 10 | + 2020-01-01 00:00:09.000 | true | 10 | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | 15 | + 2020-01-01 00:00:12.000 | true | 15 | + 2020-01-01 00:00:13.000 | true | 15 | + 2020-01-01 00:00:14.000 | true | 15 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 21 | + 2020-01-01 00:00:17.000 | true | 21 | + 2020-01-01 00:00:18.000 | true | 21 | + 2020-01-01 00:00:19.000 | true | 21 | + 2020-01-01 00:00:20.000 | true | 21 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(linear); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | false | 0 | + 2020-01-01 00:00:01.000 | false | 1 | + 2020-01-01 00:00:02.000 | true | 2 | + 2020-01-01 00:00:03.000 | false | 3 | + 2020-01-01 00:00:04.000 | true | 4 | + 2020-01-01 00:00:05.000 | true | 5 | + 2020-01-01 00:00:06.000 | false | 6 | + 2020-01-01 00:00:07.000 | true | 7 | + 2020-01-01 00:00:08.000 | true | 8 | + 2020-01-01 00:00:09.000 | true | 9 | + 2020-01-01 00:00:10.000 | false | 10 | + 2020-01-01 00:00:11.000 | true | 11 | + 2020-01-01 00:00:12.000 | true | 12 | + 2020-01-01 00:00:13.000 | true | 13 | + 2020-01-01 00:00:14.000 | true | 14 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 16 | + 2020-01-01 00:00:17.000 | true | 17 | + 2020-01-01 00:00:18.000 | true | 18 | + 2020-01-01 00:00:19.000 | true | 19 | + 2020-01-01 00:00:20.000 | true | 20 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(null); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | true | NULL | + 2020-01-01 00:00:01.000 | true | NULL | + 2020-01-01 00:00:02.000 | true | NULL | + 2020-01-01 00:00:03.000 | true | NULL | + 2020-01-01 00:00:04.000 | true | NULL | + 2020-01-01 00:00:05.000 | true | NULL | + 2020-01-01 00:00:06.000 | true | NULL | + 2020-01-01 00:00:07.000 | true | NULL | + 2020-01-01 00:00:08.000 | true | NULL | + 2020-01-01 00:00:09.000 | true | NULL | + 2020-01-01 00:00:10.000 | true | NULL | + 2020-01-01 00:00:11.000 | true | NULL | + 2020-01-01 00:00:12.000 | true | NULL | + 2020-01-01 00:00:13.000 | true | NULL | + 2020-01-01 00:00:14.000 | true | NULL | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | NULL | + 2020-01-01 00:00:17.000 | true | NULL | + 2020-01-01 00:00:18.000 | true | NULL | + 2020-01-01 00:00:19.000 | true | NULL | + 2020-01-01 00:00:20.000 | true | NULL | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(value, 1); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | true | 1 | + 2020-01-01 00:00:01.000 | true | 1 | + 2020-01-01 00:00:02.000 | true | 1 | + 2020-01-01 00:00:03.000 | true | 1 | + 2020-01-01 00:00:04.000 | true | 1 | + 2020-01-01 00:00:05.000 | true | 1 | + 2020-01-01 00:00:06.000 | true | 1 | + 2020-01-01 00:00:07.000 | true | 1 | + 2020-01-01 00:00:08.000 | true | 1 | + 2020-01-01 00:00:09.000 | true | 1 | + 2020-01-01 00:00:10.000 | true | 1 | + 2020-01-01 00:00:11.000 | true | 1 | + 2020-01-01 00:00:12.000 | true | 1 | + 2020-01-01 00:00:13.000 | true | 1 | + 2020-01-01 00:00:14.000 | true | 1 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 1 | + 2020-01-01 00:00:17.000 | true | 1 | + 2020-01-01 00:00:18.000 | true | 1 | + 2020-01-01 00:00:19.000 | true | 1 | + 2020-01-01 00:00:20.000 | true | 1 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(prev); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 15 | + 2020-01-01 00:00:17.000 | true | 15 | + 2020-01-01 00:00:18.000 | true | 15 | + 2020-01-01 00:00:19.000 | true | 15 | + 2020-01-01 00:00:20.000 | true | 15 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(next); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | true | 15 | + 2020-01-01 00:00:01.000 | true | 15 | + 2020-01-01 00:00:02.000 | true | 15 | + 2020-01-01 00:00:03.000 | true | 15 | + 2020-01-01 00:00:04.000 | true | 15 | + 2020-01-01 00:00:05.000 | true | 15 | + 2020-01-01 00:00:06.000 | true | 15 | + 2020-01-01 00:00:07.000 | true | 15 | + 2020-01-01 00:00:08.000 | true | 15 | + 2020-01-01 00:00:09.000 | true | 15 | + 2020-01-01 00:00:10.000 | true | 15 | + 2020-01-01 00:00:11.000 | true | 15 | + 2020-01-01 00:00:12.000 | true | 15 | + 2020-01-01 00:00:13.000 | true | 15 | + 2020-01-01 00:00:14.000 | true | 15 | + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 21 | + 2020-01-01 00:00:17.000 | true | 21 | + 2020-01-01 00:00:18.000 | true | 21 | + 2020-01-01 00:00:19.000 | true | 21 | + 2020-01-01 00:00:20.000 | true | 21 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(linear); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:15.000 | false | 15 | + 2020-01-01 00:00:16.000 | true | 16 | + 2020-01-01 00:00:17.000 | true | 17 | + 2020-01-01 00:00:18.000 | true | 18 | + 2020-01-01 00:00:19.000 | true | 19 | + 2020-01-01 00:00:20.000 | true | 20 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(null); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | true | NULL | + 2020-01-01 00:00:01.000 | true | NULL | + 2020-01-01 00:00:02.000 | true | NULL | + 2020-01-01 00:00:03.000 | true | NULL | + 2020-01-01 00:00:04.000 | true | NULL | + 2020-01-01 00:00:05.000 | true | NULL | + 2020-01-01 00:00:06.000 | true | NULL | + 2020-01-01 00:00:07.000 | true | NULL | + 2020-01-01 00:00:08.000 | true | NULL | + 2020-01-01 00:00:09.000 | true | NULL | + 2020-01-01 00:00:10.000 | true | NULL | + 2020-01-01 00:00:11.000 | true | NULL | + 2020-01-01 00:00:12.000 | true | NULL | + 2020-01-01 00:00:13.000 | true | NULL | + 2020-01-01 00:00:14.000 | true | NULL | + 2020-01-01 00:00:15.000 | true | NULL | + 2020-01-01 00:00:16.000 | true | NULL | + 2020-01-01 00:00:17.000 | true | NULL | + 2020-01-01 00:00:18.000 | true | NULL | + 2020-01-01 00:00:19.000 | true | NULL | + 2020-01-01 00:00:20.000 | true | NULL | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(value, 1); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | true | 1 | + 2020-01-01 00:00:01.000 | true | 1 | + 2020-01-01 00:00:02.000 | true | 1 | + 2020-01-01 00:00:03.000 | true | 1 | + 2020-01-01 00:00:04.000 | true | 1 | + 2020-01-01 00:00:05.000 | true | 1 | + 2020-01-01 00:00:06.000 | true | 1 | + 2020-01-01 00:00:07.000 | true | 1 | + 2020-01-01 00:00:08.000 | true | 1 | + 2020-01-01 00:00:09.000 | true | 1 | + 2020-01-01 00:00:10.000 | true | 1 | + 2020-01-01 00:00:11.000 | true | 1 | + 2020-01-01 00:00:12.000 | true | 1 | + 2020-01-01 00:00:13.000 | true | 1 | + 2020-01-01 00:00:14.000 | true | 1 | + 2020-01-01 00:00:15.000 | true | 1 | + 2020-01-01 00:00:16.000 | true | 1 | + 2020-01-01 00:00:17.000 | true | 1 | + 2020-01-01 00:00:18.000 | true | 1 | + 2020-01-01 00:00:19.000 | true | 1 | + 2020-01-01 00:00:20.000 | true | 1 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(prev); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(next); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:00.000 | true | 21 | + 2020-01-01 00:00:01.000 | true | 21 | + 2020-01-01 00:00:02.000 | true | 21 | + 2020-01-01 00:00:03.000 | true | 21 | + 2020-01-01 00:00:04.000 | true | 21 | + 2020-01-01 00:00:05.000 | true | 21 | + 2020-01-01 00:00:06.000 | true | 21 | + 2020-01-01 00:00:07.000 | true | 21 | + 2020-01-01 00:00:08.000 | true | 21 | + 2020-01-01 00:00:09.000 | true | 21 | + 2020-01-01 00:00:10.000 | true | 21 | + 2020-01-01 00:00:11.000 | true | 21 | + 2020-01-01 00:00:12.000 | true | 21 | + 2020-01-01 00:00:13.000 | true | 21 | + 2020-01-01 00:00:14.000 | true | 21 | + 2020-01-01 00:00:15.000 | true | 21 | + 2020-01-01 00:00:16.000 | true | 21 | + 2020-01-01 00:00:17.000 | true | 21 | + 2020-01-01 00:00:18.000 | true | 21 | + 2020-01-01 00:00:19.000 | true | 21 | + 2020-01-01 00:00:20.000 | true | 21 | + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(linear); + _irowts | _isfilled | interp(c1) | +==================================================== + 2020-01-01 00:00:21.000 | false | 21 | + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(null); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(value, 1); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(prev); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(next); + +taos> select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(linear); + diff --git a/tests/army/query/function/in/interp.in b/tests/army/query/function/in/interp.in index 4825ab46b1..97a9936b8d 100644 --- a/tests/army/query/function/in/interp.in +++ b/tests/army/query/function/in/interp.in @@ -13,3 +13,53 @@ select _irowts as irowts ,tbname as table_name, c2 as c_c2, c3 as c_c3, _isfille select _irowts as irowts ,tbname as table_name, c2 as c_c2, c3 as c_c3, _isfilled as isfilled , interp(c1) as intp_c1 from test.td32727 partition by tbname,c2,c3 range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill (prev) order by irowts, c2, c3; select _irowts as irowts ,tbname as table_name, c2 as c_c2, c3 as c_c3, _isfilled as isfilled , interp(c1) as intp_c1 from test.td32727 partition by tbname,c2,c3 range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill (linear) order by irowts, c2, c3; select _irowts as irowts ,tbname as table_name, c2 as c_c2, c3 as c_c3, _isfilled as isfilled , interp(c1) as intp_c1 from test.td32727 partition by tbname,c2,c3 range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill (value, 1) order by irowts, c2, c3; +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-02 00:00:00' and '2020-01-01 00:00:00' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(linear); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-02 00:00:00' range('2020-01-01 00:00:30', '2020-01-01 00:00:00') every(1s) fill(linear); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:20' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(linear); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:21', '2020-01-01 00:00:30') every(1s) fill(linear); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:15', '2020-01-01 00:00:30') every(1s) fill(linear); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:21' range('2020-01-01 00:00:00', '2020-01-01 00:00:30') every(1s) fill(linear); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:00' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(linear); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:15' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(linear); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:21' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(linear); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(null); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(value, 1); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(prev); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(next); +select _irowts, _isfilled, interp(c1) from test.td32861 where ts between '2020-01-01 00:00:22' and '2020-01-01 00:00:30' range('2020-01-01 00:00:00', '2020-01-01 00:00:21') every(1s) fill(linear); diff --git a/tests/army/query/function/test_interp.py b/tests/army/query/function/test_interp.py index f903e7be73..106ef1e58e 100644 --- a/tests/army/query/function/test_interp.py +++ b/tests/army/query/function/test_interp.py @@ -38,6 +38,7 @@ class TDTestCase(TBase): (ts timestamp, c0 tinyint, c1 smallint, c2 int, c3 bigint, c4 double, c5 float, c6 bool, c7 varchar(10), c8 nchar(10), c9 tinyint unsigned, c10 smallint unsigned, c11 int unsigned, c12 bigint unsigned) ''' ) + tdSql.execute("create table if not exists test.td32861(ts timestamp, c1 int);") tdLog.printNoPrefix("==========step2:insert data") @@ -45,6 +46,16 @@ class TDTestCase(TBase): tdSql.execute(f"insert into test.td32727 values ('2020-02-01 00:00:10', 10, 10, 10, 10, 10.0, 10.0, true, 'varchar', 'nchar', 10, 10, 10, 10)") tdSql.execute(f"insert into test.td32727 values ('2020-02-01 00:00:15', 15, 15, 15, 15, 15.0, 15.0, true, 'varchar', 'nchar', 15, 15, 15, 15)") + tdSql.execute( + """insert into test.td32861 values + ('2020-01-01 00:00:00', 0), + ('2020-01-01 00:00:01', 1), + ('2020-01-01 00:00:03', 3), + ('2020-01-01 00:00:06', 6), + ('2020-01-01 00:00:10', 10), + ('2020-01-01 00:00:15', 15), + ('2020-01-01 00:00:21', 21);""" + ) def test_normal_query_new(self, testCase): # read sql from .sql file and execute From cb44efd3297dc74d3a805d2296b1840174a34635 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Mon, 18 Nov 2024 15:22:11 +0800 Subject: [PATCH 38/47] fix comments --- source/libs/nodes/src/nodesUtilFuncs.c | 11 ++++++++++- source/libs/parser/src/parCalcConst.c | 7 ++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 4677b5d5f0..30cc552761 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -2960,7 +2960,16 @@ static SNode* nodesListFindNode(SNodeList* pList, SNode* pNode) { } int32_t nodesListDeduplicate(SNodeList** ppList) { - if (!ppList || LIST_LENGTH(*ppList) == 0) return TSDB_CODE_SUCCESS; + if (!ppList || LIST_LENGTH(*ppList) <= 1) return TSDB_CODE_SUCCESS; + if (LIST_LENGTH(*ppList) == 2) { + SNode* pNode1 = nodesListGetNode(*ppList, 0); + SNode* pNode2 = nodesListGetNode(*ppList, 1); + if (nodesEqualNode(pNode1, pNode2)) { + SListCell* pCell = nodesListGetCell(*ppList, 1); + (void)nodesListErase(*ppList, pCell); + } + return TSDB_CODE_SUCCESS; + } SNodeList* pTmp = NULL; int32_t code = nodesMakeList(&pTmp); if (TSDB_CODE_SUCCESS == code) { diff --git a/source/libs/parser/src/parCalcConst.c b/source/libs/parser/src/parCalcConst.c index 778c34ff02..9702c2e760 100644 --- a/source/libs/parser/src/parCalcConst.c +++ b/source/libs/parser/src/parCalcConst.c @@ -326,7 +326,6 @@ static int32_t calcConstProjections(SCalcConstContext* pCxt, SSelectStmt* pSelec static int32_t calcConstGroupBy(SCalcConstContext* pCxt, SSelectStmt* pSelect) { int32_t code = calcConstList(pSelect->pGroupByList); -#if 0 if (TSDB_CODE_SUCCESS == code) { SNode* pNode = NULL; FOREACH(pNode, pSelect->pGroupByList) { @@ -337,9 +336,11 @@ static int32_t calcConstGroupBy(SCalcConstContext* pCxt, SSelectStmt* pSelect) { } } } - NODES_DESTORY_LIST(pSelect->pGroupByList); + FOREACH(pNode, pSelect->pGroupByList) { + if (!cell->pPrev) continue; + ERASE_NODE(pSelect->pGroupByList); + } } -#endif return code; } From 31f5055f21bf60cd447a4f95e59291ea7190c497 Mon Sep 17 00:00:00 2001 From: dmchen Date: Mon, 18 Nov 2024 19:06:46 +0800 Subject: [PATCH 39/47] fix/TS-5639-check-mnode-leader --- source/dnode/mnode/impl/src/mndMain.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c index 6c30193ea7..9dd43225b1 100644 --- a/source/dnode/mnode/impl/src/mndMain.c +++ b/source/dnode/mnode/impl/src/mndMain.c @@ -53,7 +53,7 @@ static inline int32_t mndAcquireRpc(SMnode *pMnode) { if (pMnode->stopped) { code = TSDB_CODE_APP_IS_STOPPING; } else if (!mndIsLeader(pMnode)) { - code = -1; + code = 1; } else { #if 1 (void)atomic_add_fetch_32(&pMnode->rpcRef, 1); @@ -1002,8 +1002,12 @@ int64_t mndGenerateUid(const char *name, int32_t len) { int32_t mndGetMonitorInfo(SMnode *pMnode, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo, SMonStbInfo *pStbInfo, SMonGrantInfo *pGrantInfo) { - int32_t code = 0; - TAOS_CHECK_RETURN(mndAcquireRpc(pMnode)); + int32_t code = mndAcquireRpc(pMnode); + if (code < 0) { + TAOS_RETURN(code); + } else if (code == 1) { + TAOS_RETURN(TSDB_CODE_SUCCESS); + } SSdb *pSdb = pMnode->pSdb; int64_t ms = taosGetTimestampMs(); From 7f92585b93bf917ed4313ce335751fa55e2e4162 Mon Sep 17 00:00:00 2001 From: menshibin Date: Mon, 18 Nov 2024 20:09:37 +0800 Subject: [PATCH 40/47] add test tzlocal dependent --- docs/examples/node/package.json | 10 ++++++++-- tests/requirements.txt | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/examples/node/package.json b/docs/examples/node/package.json index 14303c8f37..d77c96fbb3 100644 --- a/docs/examples/node/package.json +++ b/docs/examples/node/package.json @@ -4,6 +4,12 @@ "main": "index.js", "license": "MIT", "dependencies": { - "@tdengine/websocket": "^3.1.1" - } + "@tdengine/websocket": "^3.1.2" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "description": "" } diff --git a/tests/requirements.txt b/tests/requirements.txt index c6dd044c86..a036c2b3d0 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -9,4 +9,5 @@ requests pexpect faker pyopenssl -hyperloglog \ No newline at end of file +hyperloglog +tzlocal \ No newline at end of file From b3eb84c0047dc5d960092f11f97482ff9443d3e6 Mon Sep 17 00:00:00 2001 From: factosea <285808407@qq.com> Date: Tue, 19 Nov 2024 18:30:27 +0800 Subject: [PATCH 41/47] fix: fetch_row callback error code --- source/client/src/clientImpl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 8a0b1ddaab..94d06166f2 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -3032,13 +3032,13 @@ static void fetchCallback(void* pResult, void* param, int32_t code) { if (code != TSDB_CODE_SUCCESS) { pRequest->code = code; taosMemoryFreeClear(pResultInfo->pData); - pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, 0); + pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, code); return; } if (pRequest->code != TSDB_CODE_SUCCESS) { taosMemoryFreeClear(pResultInfo->pData); - pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, 0); + pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, pRequest->code); return; } From 15bccef3920d7c375dc9a612dbb808e411617b38 Mon Sep 17 00:00:00 2001 From: Shungang Li Date: Wed, 20 Nov 2024 11:02:17 +0800 Subject: [PATCH 42/47] docs: describe KEEP_TIME_OFFSET --- docs/en/14-reference/12-config/index.md | 4 ++-- docs/zh/14-reference/03-taos-sql/02-database.md | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/en/14-reference/12-config/index.md b/docs/en/14-reference/12-config/index.md index 77d183a5ef..63aa6ed447 100755 --- a/docs/en/14-reference/12-config/index.md +++ b/docs/en/14-reference/12-config/index.md @@ -773,7 +773,7 @@ lossyColumns float|double 02/22 10:49:27.607990 00002933 UTL lossyColumns float|double ``` -### ifAdtFse +### ifAdtFse | Attribute | Description | | -------- | -------------------------------- | @@ -898,4 +898,4 @@ lossyColumns float|double | 53 | udf | Yes | Yes | | | 54 | enableCoreFile | Yes | Yes | | | 55 | ttlChangeOnWrite | No | Yes | | -| 56 | keepTimeOffset | Yes | Yes(discarded since 3.2.0.0) | | +| 56 | keepTimeOffset | Yes | Yes(discarded since 3.2.0.0) | see "KEEP_TIME_OFFSET" | diff --git a/docs/zh/14-reference/03-taos-sql/02-database.md b/docs/zh/14-reference/03-taos-sql/02-database.md index 0d9ab019c0..25d7e54823 100644 --- a/docs/zh/14-reference/03-taos-sql/02-database.md +++ b/docs/zh/14-reference/03-taos-sql/02-database.md @@ -8,10 +8,10 @@ description: "创建、删除数据库,查看、修改数据库参数" ```sql CREATE DATABASE [IF NOT EXISTS] db_name [database_options] - + database_options: database_option ... - + database_option: { VGROUPS value | PRECISION {'ms' | 'us' | 'ns'} @@ -26,6 +26,7 @@ database_option: { | MAXROWS value | MINROWS value | KEEP value + | KEEP_TIME_OFFSET value | STT_TRIGGER value | SINGLE_STABLE {0 | 1} | TABLE_PREFIX value @@ -43,7 +44,7 @@ database_option: { - VGROUPS:数据库中初始 vgroup 的数目。 - PRECISION:数据库的时间戳精度。ms 表示毫秒,us 表示微秒,ns 表示纳秒,默认 ms 毫秒。 -- REPLICA:表示数据库副本数,取值为 1、2 或 3,默认为 1; 2 仅在企业版 3.3.0.0 及以后版本中可用。在集群中使用,副本数必须小于或等于 DNODE 的数目。且使用时存在以下限制: +- REPLICA:表示数据库副本数,取值为 1、2 或 3,默认为 1; 2 仅在企业版 3.3.0.0 及以后版本中可用。在集群中使用,副本数必须小于或等于 DNODE 的数目。且使用时存在以下限制: - 暂不支持对双副本数据库相关 Vgroup 进行 SPLITE VGROUP 或 REDISTRIBUTE VGROUP 操作 - 单副本数据库可变更为双副本数据库,但不支持从双副本变更为其它副本数,也不支持从三副本变更为双副本 - BUFFER: 一个 VNODE 写入内存池大小,单位为 MB,默认为 256,最小为 3,最大为 16384。 @@ -64,6 +65,7 @@ database_option: { - MAXROWS:文件块中记录的最大条数,默认为 4096 条。 - MINROWS:文件块中记录的最小条数,默认为 100 条。 - KEEP:表示数据文件保存的天数,缺省值为 3650,取值范围 [1, 365000],且必须大于或等于3倍的 DURATION 参数值。数据库会自动删除保存时间超过 KEEP 值的数据从而释放存储空间。KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。也可以不写单位,如 KEEP 50,此时默认单位为天。企业版支持[多级存储](https://docs.taosdata.com/tdinternal/arch/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 \<= keep 1 \<= keep 2,如 KEEP 100h,100d,3650d); 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间)。 +- KEEP_TIME_OFFSET:自 3.2.0.0 版本生效。删除或迁移保存时间超过 KEEP 值的数据的延迟执行时间,默认值为 0 (小时)。在数据文件保存时间超过 KEEP 后,删除或迁移操作不会立即执行,而会额外等待本参数指定的时间间隔,以实现与业务高峰期错开的目的。 - STT_TRIGGER:表示落盘文件触发文件合并的个数。开源版本固定为 1,企业版本可设置范围为 1 到 16。对于少表高频写入场景,此参数建议使用默认配置;而对于多表低频写入场景,此参数建议配置较大的值。 - SINGLE_STABLE:表示此数据库中是否只可以创建一个超级表,用于超级表列非常多的情况。 - 0:表示可以创建多张超级表。 From 9314dfb80cf26cfbecb4668994fff9a008fc519d Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Wed, 20 Nov 2024 14:29:27 +0800 Subject: [PATCH 43/47] fix not setting step in tsdbread --- source/dnode/vnode/src/tsdb/tsdbRead2.c | 4 ++-- tests/system-test/2-query/partition_by_col.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRead2.c b/source/dnode/vnode/src/tsdb/tsdbRead2.c index 441d073666..527486270c 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead2.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead2.c @@ -4812,7 +4812,7 @@ static int32_t checkForNeighborFileBlock(STsdbReader* pReader, STableBlockScanIn pBlockData = &pReader->status.fileBlockData; asc = ASCENDING_TRAVERSE(pReader->info.order); pVerRange = &pReader->info.verRange; - ASCENDING_TRAVERSE(pReader->info.order) ? 1 : -1; + step = ASCENDING_TRAVERSE(pReader->info.order) ? 1 : -1; *state = CHECK_FILEBLOCK_QUIT; code = loadNeighborIfOverlap(pFBlock, pScanInfo, pReader, &loadNeighbor); @@ -6169,7 +6169,7 @@ int32_t tsdbNextDataBlock2(STsdbReader* pReader, bool* hasNext) { TSDB_CHECK_CODE(code, lino, _end); } - goto _end; + return code; } } diff --git a/tests/system-test/2-query/partition_by_col.py b/tests/system-test/2-query/partition_by_col.py index ef88e88cbd..da7fe78124 100644 --- a/tests/system-test/2-query/partition_by_col.py +++ b/tests/system-test/2-query/partition_by_col.py @@ -313,7 +313,21 @@ class TDTestCase: order_by_list = 'ts,c1,c2,c3,c4,c5,c6,c7,c8,c9,t1,t2,t3,t4,t5,t6' self.prepare_and_query_and_compare(sqls, order_by_list, compare_what=COMPARE_LEN) + + def test_tsdb_read(self): + tdSql.execute('delete from t0') + tdSql.execute('flush database test') + for i in range(0, 4096): + tdSql.execute(f"insert into test.t0 values({1537146000000 + i}, 1,1,1,1,1,1,1,'a','1')") + tdSql.execute("flush database test") + tdSql.execute(f"insert into t0 values({1537146000000 + 4095}, 1,1,1,1,1,1,1,'a','1')") + for i in range(4095, 4096*2 + 100): + tdSql.execute(f"insert into test.t0 values({1537146000000 + i}, 1,1,1,1,1,1,1,'a','1')") + tdSql.execute("flush database test") + time.sleep(5) + tdSql.query('select first(ts), last(ts) from t0', queryTimes=1) + tdSql.checkRows(1) def run(self): self.prepareTestEnv() @@ -323,6 +337,8 @@ class TDTestCase: self.test_sort_for_partition_res() self.test_sort_for_partition_interval() self.test_sort_for_partition_no_agg_limit() + self.test_tsdb_read() + def stop(self): tdSql.close() From 3a4ed77b170702c4f6fdfdd4b45fa596656e6017 Mon Sep 17 00:00:00 2001 From: menshibin Date: Wed, 20 Nov 2024 16:35:27 +0800 Subject: [PATCH 44/47] upgrade python version --- Jenkinsfile2 | 2 +- docs/en/14-reference/05-connectors/30-python.mdx | 6 ++++++ docs/en/14-reference/05-connectors/35-node.mdx | 2 ++ docs/zh/14-reference/05-connector/30-python.mdx | 2 ++ docs/zh/14-reference/05-connector/35-node.mdx | 1 + tests/ci/Dockerfile | 2 +- tests/docs-examples-test/python.sh | 2 +- tests/parallel_test/run_case.sh | 4 ++-- 8 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index 7ba9b4a933..910388fa8c 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -355,7 +355,7 @@ def pre_test_build_win() { bat ''' cd %WIN_COMMUNITY_ROOT%/tests/ci pip3 install taospy==2.7.16 - pip3 install taos-ws-py==0.3.3 + pip3 install taos-ws-py==0.3.5 xcopy /e/y/i/f %WIN_INTERNAL_ROOT%\\debug\\build\\lib\\taos.dll C:\\Windows\\System32 ''' return 1 diff --git a/docs/en/14-reference/05-connectors/30-python.mdx b/docs/en/14-reference/05-connectors/30-python.mdx index 7263a3caa6..4f17261b33 100644 --- a/docs/en/14-reference/05-connectors/30-python.mdx +++ b/docs/en/14-reference/05-connectors/30-python.mdx @@ -41,12 +41,18 @@ We recommend using the latest version of `taospy`, regardless of the version of |Python Client Library Version|major changes| |:-------------------:|:----:| +|2.7.16|add subscription configuration (session.timeout.ms, max.poll.interval.ms)| +|2.7.15|added support for VARBINARY and GEOMETRY types| +|2.7.14|fix known issues| +|2.7.13|add TMQ synchronous submission offset interface| |2.7.12|1. added support for `varbinary` type (STMT does not yet support)
2. improved query performance (thanks to contributor [hadrianl](https://github.com/taosdata/taos-connector-python/pull/209))| |2.7.9|support for getting assignment and seek function on subscription| |2.7.8|add `execute_many` method| |Python Websocket Connection Version|major changes| |:----------------------------:|:-----:| +|0.3.5|1. added support for VARBINARY and GEOMETRY types
2. Fix known issues| +|0.3.2|1. optimize WebSocket SQL query and insertion performance
2. Fix known issues
3. Modify the readme and document| |0.2.9|bugs fixes| |0.2.5|1. support for getting assignment and seek function on subscription
2. support schemaless
3. support STMT| |0.2.4|support `unsubscribe` on subscription| diff --git a/docs/en/14-reference/05-connectors/35-node.mdx b/docs/en/14-reference/05-connectors/35-node.mdx index 476f9bab71..2aeef7af1e 100644 --- a/docs/en/14-reference/05-connectors/35-node.mdx +++ b/docs/en/14-reference/05-connectors/35-node.mdx @@ -27,6 +27,8 @@ Node.js client library needs to be run with Node.js 14 or higher version. | Node.js connector version | major changes | TDengine 版本 | | :-----------------------: | :------------------: | :----------------:| +| 3.1.2 | Optimized the data protocol and parsing, resulting in a significant improvement in performance | 3.2.0.0 or later | +| 3.1.1 | Optimized data transmission performance | 3.2.0.0 or later | | 3.1.0 | new version, supports websocket | 3.2.0.0 or later | ## Supported features diff --git a/docs/zh/14-reference/05-connector/30-python.mdx b/docs/zh/14-reference/05-connector/30-python.mdx index 8436c30249..3991477635 100644 --- a/docs/zh/14-reference/05-connector/30-python.mdx +++ b/docs/zh/14-reference/05-connector/30-python.mdx @@ -41,6 +41,7 @@ Python 连接器的源码托管在 [GitHub](https://github.com/taosdata/taos-con |Python Connector 版本|主要变化| |:-------------------:|:----:| +|2.7.16|新增订阅配置 (session.timeout.ms, max.poll.interval.ms)| |2.7.15|新增 VARBINARY 和 GEOMETRY 类型支持| |2.7.14|修复已知问题| |2.7.13|新增 tmq 同步提交 offset 接口| @@ -50,6 +51,7 @@ Python 连接器的源码托管在 [GitHub](https://github.com/taosdata/taos-con |Python WebSocket Connector 版本|主要变化| |:----------------------------:|:-----:| +|0.3.5|新增 VARBINARY 和 GEOMETRY 类型支持,修复已知问题| |0.3.2|优化 WebSocket sql 查询和插入性能,修改 readme 和 文档,修复已知问题| |0.2.9|已知问题修复| |0.2.5|1. 数据订阅支持获取消费进度和重置消费进度
2. 支持 schemaless
3. 支持 STMT| diff --git a/docs/zh/14-reference/05-connector/35-node.mdx b/docs/zh/14-reference/05-connector/35-node.mdx index d9512eae78..df2abfab3d 100644 --- a/docs/zh/14-reference/05-connector/35-node.mdx +++ b/docs/zh/14-reference/05-connector/35-node.mdx @@ -26,6 +26,7 @@ Node.js 连接器目前仅支持 WebSocket 连接器, 其通过 taosAdapter | Node.js 连接器 版本 | 主要变化 | TDengine 版本 | | :------------------: | :----------------------: | :----------------: | +| 3.1.2 | 对数据协议和解析进行了优化,性能得到大幅提升| 3.3.2.0 及更高版本 | | 3.1.1 | 优化了数据传输性能 | 3.3.2.0 及更高版本 | | 3.1.0 | 新版本发布,支持 WebSocket 连接 | 3.2.0.0 及更高版本 | diff --git a/tests/ci/Dockerfile b/tests/ci/Dockerfile index d3d574b484..1caa6fea9e 100644 --- a/tests/ci/Dockerfile +++ b/tests/ci/Dockerfile @@ -7,7 +7,7 @@ RUN apt-get install -y locales psmisc sudo tree libgeos-dev libgflags2.2 libgfl RUN sed -i 's/# en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen && locale-gen RUN pip3 config set global.index-url http://admin:123456@192.168.0.212:3141/admin/dev/+simple/ RUN pip3 config set global.trusted-host 192.168.0.212 -RUN pip3 install taospy==2.7.16 taos-ws-py==0.3.3 pandas psutil fabric2 requests faker simplejson toml pexpect tzlocal distro decorator loguru hyperloglog +RUN pip3 install taospy==2.7.16 taos-ws-py==0.3.5 pandas psutil fabric2 requests faker simplejson toml pexpect tzlocal distro decorator loguru hyperloglog ENV LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 LC_ALL=en_US.UTF-8 RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 RUN add-apt-repository 'deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/' diff --git a/tests/docs-examples-test/python.sh b/tests/docs-examples-test/python.sh index 6a25683b58..3a9812637c 100644 --- a/tests/docs-examples-test/python.sh +++ b/tests/docs-examples-test/python.sh @@ -130,7 +130,7 @@ pip3 install kafka-python python3 kafka_example_consumer.py # 21 -pip3 install taos-ws-py==0.3.3 +pip3 install taos-ws-py==0.3.5 python3 conn_websocket_pandas.py # 22 diff --git a/tests/parallel_test/run_case.sh b/tests/parallel_test/run_case.sh index 5b0d34fc0a..a78d0aa4a4 100755 --- a/tests/parallel_test/run_case.sh +++ b/tests/parallel_test/run_case.sh @@ -76,9 +76,9 @@ ulimit -c unlimited md5sum /usr/lib/libtaos.so.1 md5sum /home/TDinternal/debug/build/lib/libtaos.so -#get python connector and update: taospy 2.7.16 taos-ws-py 0.3.3 +#get python connector and update: taospy 2.7.16 taos-ws-py 0.3.5 pip3 install taospy==2.7.16 -pip3 install taos-ws-py==0.3.3 +pip3 install taos-ws-py==0.3.5 $TIMEOUT_CMD $cmd RET=$? echo "cmd exit code: $RET" From da51741e66dc7992ac3d3edfe03500a4a5581c05 Mon Sep 17 00:00:00 2001 From: huohong <346479823@qq.com> Date: Wed, 20 Nov 2024 17:39:25 +0800 Subject: [PATCH 45/47] test:update 3.3.4.3 release notes in office web --- docs/en/28-releases/01-tdengine.md | 4 + docs/zh/28-releases/01-tdengine.md | 4 + docs/zh/28-releases/03-notes/3.3.4.3.md | 123 +++++++++++------------- docs/zh/28-releases/03-notes/index.md | 1 + 4 files changed, 66 insertions(+), 66 deletions(-) diff --git a/docs/en/28-releases/01-tdengine.md b/docs/en/28-releases/01-tdengine.md index b24931b166..161efe0d61 100644 --- a/docs/en/28-releases/01-tdengine.md +++ b/docs/en/28-releases/01-tdengine.md @@ -24,6 +24,10 @@ import Release from "/components/ReleaseV3"; +## 3.3.4.3 + + + ## 3.3.3.0 diff --git a/docs/zh/28-releases/01-tdengine.md b/docs/zh/28-releases/01-tdengine.md index cf9d7b6878..d285cb36ae 100644 --- a/docs/zh/28-releases/01-tdengine.md +++ b/docs/zh/28-releases/01-tdengine.md @@ -28,6 +28,10 @@ import Release from "/components/ReleaseV3"; +## 3.3.4.3 + + + ## 3.3.3.0 diff --git a/docs/zh/28-releases/03-notes/3.3.4.3.md b/docs/zh/28-releases/03-notes/3.3.4.3.md index 8ffd5802ed..364732b478 100644 --- a/docs/zh/28-releases/03-notes/3.3.4.3.md +++ b/docs/zh/28-releases/03-notes/3.3.4.3.md @@ -1,69 +1,60 @@ ---- -title: 3.3.4.3 版本说明 -sidebar_label: 3.3.4.3 -description: 3.3.4.3 版本说明 ---- +## 新特性 +* 新功能:流计算的 TWA 函数支持时间驱动的结果推送模式 +* 新功能:流计算的 Interp 函数支持时间驱动的结果推送模式 +* 优化:顺序执行 compact 和 split vgroup操作时的日志错误提示 +* 新功能:支持微软对象存储 -### 行为变更及兼容性 -1. 多副本流计算中必须使用 snode -1. 增加了流计算的兼容性保证机制,避免后续函数变更产生新的兼容性问题,但之前版本的流计算必须重建,具体参见 https://docs.taosdata.com/advanced/stream/#流计算升级故障恢复 -1. 调整 case when 语句结果类型的判断方法 - -### 新特性 -1. 新功能:流计算的 TWA 函数支持时间驱动的结果推送模式 -1. 新功能:流计算的 Interp 函数支持时间驱动的结果推送模式 -1. 新功能:支持微软对象存储 +## 优化 +* 优化:提升并发大查询时节点之间互相拉数据的效率 +* 优化:支持使用 AVX2 和 AVX512 对 double 、timestamp 和 bigint 类型进行解码优化 +* 优化:调整 case when 语句的结果类型判断方法 +* 优化:提升查询 “select ... from ... where ts in (...)” 的数据扫描速度 +* 优化:增加了流计算的兼容性保证机制,避免后续函数变更产生新的兼容性问题,之前版本的流计算必须重建 +* 优化:提升 taosX 在交叉写入场景下的数据同步性能 +* 优化:支持关闭整数/浮点数类型的编码 +* 优化:多副本流计算中必须使用 snode +* 优化:客户端生成唯一 ID 标识每一个查询任务,避免重复 ID 导致的内存损坏 +* 优化:加快数据库的创建时间 +* 优化:修改 s3MigrateEnabled 默认值为0 +* 优化:支持在审计数据库中记录删除操作 +* 优化:支持在指定的 dnode 中创建数据库 [企业版] +* 优化:调整删除超级表数据列时的报错信息 -### 优化 -1. 优化:提升并发大查询时节点之间互相拉数据的效率 -1. 优化:支持使用 AVX2 和 AVX512 对 double 、timestamp 和 bigint 类型进行解码优化 -1. 优化:调整 case when 语句的结果类型判断方法 -1. 优化:顺序执行 compact 和 split vgroup操作时的日志错误提示 -1. 优化:提升查询 “select ... from ... where ts in (...)” 的数据扫描速度 -1. 优化:增加了流计算的兼容性保证机制,避免后续函数变更产生新的兼容性问题,之前版本的流计算必须重建 -1. 优化:提升 taosX 在交叉写入场景下的数据同步性能 -1. 优化:支持关闭整数/浮点数类型的编码 -1. 优化:多副本流计算中必须使用 snode -1. 优化:客户端生成唯一 ID 标识每一个查询任务,避免重复 ID 导致的内存损坏 -1. 优化:加快数据库的创建时间 -1. 优化:修改 s3MigrateEnabled 默认值为0 -1. 优化:支持在审计数据库中记录删除操作 -1. 优化:支持在指定的 dnode 中创建数据库 [企业版] -1. 优化:调整删除超级表数据列时的报错信息 +## 修复 +* 修复:last_row 查询性能在 3.3.3.0 中大幅下降的问题 +* 修复:WAL 条目不完整时 taosd 无法启动的问题 +* 修复: partition by 常量时查询结果错误的问题 +* 修复:标量函数包含 _wstart 且填充方式为 prev 时计算结果错误 +* 修复:Windows 平台下的时区设置问题 +* 修复:空数据库进行 compact 操作时,事务无法结束【企业版】 +* 修复:事务冲突的逻辑错误 +* 修复:管理节点某些错误会导致事务无法停止 +* 修复:管理节点某些错误会导致事务无法停止 +* 修复:dnode 数据清空后 taosc 重试错误的问题 +* 修复:Data Compact 被异常终止后,中间文件未被清理 +* 修复:新增列后,Kafka 连接器的 earliest 模式消费不到新列数据 +* 修复:interp 函数在 fill(prev) 时行为不正确 +* 修复:TSMA 在高频元数据操作时异常停止的问题 +* 修复:show create stable 语句执行结果的标签显示错误 +* 修复:Percentile 函数在大数据量查询时会崩溃。 +* 修复:partition by 和 having 联合使用时的语法错误问题 +* 修复:interp 在 partition by tbname,c1 时 tbname 为空的问题 +* 修复:通过 stmt 写入非法布尔数值时 taosd 可能 crash +* 修复:Explorer OPC-UA 表名模板说明 +* 修复:库符号 version 与使用相同符号的库冲突的问题 https://github.com/taosdata/TDengine/issues/25920 +* 修复:在 windows 平台下 JDBC 驱动的句柄数持续升高问题 +* 修复:3.3.3.1 升级至 3.3.4.0 偶现的启动失败问题 +* 修复:Windows 平台重复增删表的内存泄漏 +* 修复:无法限制并发拉起 checkpoint 数量导致流计算消耗资源过多 +* 修复:并发查询时的 too many session 问题 +* 修复:Windows 平台下 taos shell 在慢查询场景中崩溃的问题 +* 修复:当打开 dnode日志时,加密数据库无法恢复的问题 +* 修复:由于 mnode 同步超时,进而导致 taosd 无法启动的问题 +* 修复:由于在快照同步过程中整理文件组数据的速度过慢,从而导致 Vnode(虚拟节点)无法恢复的问题 +* 修复:通过行协议向字符串类型的字段中写入带转义符的数据时,taosd 会崩溃 +* 修复:Error Code 逻辑处理错误导致的元数据文件损坏 +* 修复:查询语句中包含多个 “not” 条件语句嵌套时,未设置标量模式导致查询错误 +* 修复:vnode 统计信息上报超时导致的 dnode offline 问题 +* 修复:在不支持 avx 指令集的服务器上,taosd 启动失败问题 +* 修复:taosX 数据迁移容错处理 0x09xx 错误码 -### 修复 -1. 修复:last_row 查询性能在 3.3.3.0 中大幅下降的问题 -1. 修复:WAL 条目不完整时 taosd 无法启动的问题 -1. 修复: partition by 常量时查询结果错误的问题 -1. 修复:标量函数包含 _wstart 且填充方式为 prev 时计算结果错误 -1. 修复:Windows 平台下的时区设置问题 -1. 修复:空数据库进行 compact 操作时,事务无法结束【企业版】 -1. 修复:事务冲突的逻辑错误 -1. 修复:管理节点某些错误会导致事务无法停止 -1. 修复:管理节点某些错误会导致事务无法停止 -1. 修复:dnode 数据清空后 taosc 重试错误的问题 -1. 修复:Data Compact 被异常终止后,中间文件未被清理 -1. 修复:新增列后,Kafka 连接器的 earliest 模式消费不到新列数据 -1. 修复:interp 函数在 fill(prev) 时行为不正确 -1. 修复:TSMA 在高频元数据操作时异常停止的问题 -1. 修复:show create stable 语句执行结果的标签显示错误 -1. 修复:Percentile 函数在大数据量查询时会崩溃。 -1. 修复:partition by 和 having 联合使用时的语法错误问题 -1. 修复:interp 在 partition by tbname,c1 时 tbname 为空的问题 -1. 修复:通过 stmt 写入非法布尔数值时 taosd 可能 crash -1. 修复:库符号 version 与使用相同符号的库冲突的问题 -1. 修复:在 windows 平台下 JDBC 驱动的句柄数持续升高问题 -1. 修复:3.3.3.1 升级至 3.3.4.0 偶现的启动失败问题 -1. 修复:Windows 平台重复增删表的内存泄漏 -1. 修复:无法限制并发拉起 checkpoint 数量导致流计算消耗资源过多 -1. 修复:并发查询时的 too many session 问题 -1. 修复:Windows 平台下 taos shell 在慢查询场景中崩溃的问题 -1. 修复:当打开 dnode日志时,加密数据库无法恢复的问题 -1. 修复:由于 mnode 同步超时,进而导致 taosd 无法启动的问题 -1. 修复:由于在快照同步过程中整理文件组数据的速度过慢,从而导致 Vnode(虚拟节点)无法恢复的问题 -1. 修复:通过行协议向字符串类型的字段中写入带转义符的数据时,taosd 会崩溃 -1. 修复:Error Code 逻辑处理错误导致的元数据文件损坏 -1. 修复:查询语句中包含多个 “not” 条件语句嵌套时,未设置标量模式导致查询错误 -1. 修复:vnode 统计信息上报超时导致的 dnode offline 问题 -1. 修复:在不支持 avx 指令集的服务器上,taosd 启动失败问题 -1. 修复:taosX 数据迁移容错处理 0x09xx 错误码 diff --git a/docs/zh/28-releases/03-notes/index.md b/docs/zh/28-releases/03-notes/index.md index d1a48ab9a8..1cdd3239e7 100644 --- a/docs/zh/28-releases/03-notes/index.md +++ b/docs/zh/28-releases/03-notes/index.md @@ -4,6 +4,7 @@ sidebar_label: 版本说明 description: 各版本版本说明 --- +[3.3.4.3](./3.3.4.3) [3.3.4.3](./3.3.4.3) [3.3.3.0](./3.3.3.0) [3.3.2.0](./3.3.2.0) From 5ebb44903e944ec799b7e7c4886d78bed80cf462 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 21 Nov 2024 10:30:18 +0800 Subject: [PATCH 46/47] Revert "Update release note for 3.3.4.3 in office web" --- docs/en/28-releases/01-tdengine.md | 4 - docs/zh/28-releases/01-tdengine.md | 4 - docs/zh/28-releases/03-notes/3.3.4.3.md | 123 +++++++++++++----------- docs/zh/28-releases/03-notes/index.md | 1 - 4 files changed, 66 insertions(+), 66 deletions(-) diff --git a/docs/en/28-releases/01-tdengine.md b/docs/en/28-releases/01-tdengine.md index 161efe0d61..b24931b166 100644 --- a/docs/en/28-releases/01-tdengine.md +++ b/docs/en/28-releases/01-tdengine.md @@ -24,10 +24,6 @@ import Release from "/components/ReleaseV3"; -## 3.3.4.3 - - - ## 3.3.3.0 diff --git a/docs/zh/28-releases/01-tdengine.md b/docs/zh/28-releases/01-tdengine.md index d285cb36ae..cf9d7b6878 100644 --- a/docs/zh/28-releases/01-tdengine.md +++ b/docs/zh/28-releases/01-tdengine.md @@ -28,10 +28,6 @@ import Release from "/components/ReleaseV3"; -## 3.3.4.3 - - - ## 3.3.3.0 diff --git a/docs/zh/28-releases/03-notes/3.3.4.3.md b/docs/zh/28-releases/03-notes/3.3.4.3.md index 364732b478..8ffd5802ed 100644 --- a/docs/zh/28-releases/03-notes/3.3.4.3.md +++ b/docs/zh/28-releases/03-notes/3.3.4.3.md @@ -1,60 +1,69 @@ -## 新特性 -* 新功能:流计算的 TWA 函数支持时间驱动的结果推送模式 -* 新功能:流计算的 Interp 函数支持时间驱动的结果推送模式 -* 优化:顺序执行 compact 和 split vgroup操作时的日志错误提示 -* 新功能:支持微软对象存储 +--- +title: 3.3.4.3 版本说明 +sidebar_label: 3.3.4.3 +description: 3.3.4.3 版本说明 +--- -## 优化 -* 优化:提升并发大查询时节点之间互相拉数据的效率 -* 优化:支持使用 AVX2 和 AVX512 对 double 、timestamp 和 bigint 类型进行解码优化 -* 优化:调整 case when 语句的结果类型判断方法 -* 优化:提升查询 “select ... from ... where ts in (...)” 的数据扫描速度 -* 优化:增加了流计算的兼容性保证机制,避免后续函数变更产生新的兼容性问题,之前版本的流计算必须重建 -* 优化:提升 taosX 在交叉写入场景下的数据同步性能 -* 优化:支持关闭整数/浮点数类型的编码 -* 优化:多副本流计算中必须使用 snode -* 优化:客户端生成唯一 ID 标识每一个查询任务,避免重复 ID 导致的内存损坏 -* 优化:加快数据库的创建时间 -* 优化:修改 s3MigrateEnabled 默认值为0 -* 优化:支持在审计数据库中记录删除操作 -* 优化:支持在指定的 dnode 中创建数据库 [企业版] -* 优化:调整删除超级表数据列时的报错信息 +### 行为变更及兼容性 +1. 多副本流计算中必须使用 snode +1. 增加了流计算的兼容性保证机制,避免后续函数变更产生新的兼容性问题,但之前版本的流计算必须重建,具体参见 https://docs.taosdata.com/advanced/stream/#流计算升级故障恢复 +1. 调整 case when 语句结果类型的判断方法 + +### 新特性 +1. 新功能:流计算的 TWA 函数支持时间驱动的结果推送模式 +1. 新功能:流计算的 Interp 函数支持时间驱动的结果推送模式 +1. 新功能:支持微软对象存储 -## 修复 -* 修复:last_row 查询性能在 3.3.3.0 中大幅下降的问题 -* 修复:WAL 条目不完整时 taosd 无法启动的问题 -* 修复: partition by 常量时查询结果错误的问题 -* 修复:标量函数包含 _wstart 且填充方式为 prev 时计算结果错误 -* 修复:Windows 平台下的时区设置问题 -* 修复:空数据库进行 compact 操作时,事务无法结束【企业版】 -* 修复:事务冲突的逻辑错误 -* 修复:管理节点某些错误会导致事务无法停止 -* 修复:管理节点某些错误会导致事务无法停止 -* 修复:dnode 数据清空后 taosc 重试错误的问题 -* 修复:Data Compact 被异常终止后,中间文件未被清理 -* 修复:新增列后,Kafka 连接器的 earliest 模式消费不到新列数据 -* 修复:interp 函数在 fill(prev) 时行为不正确 -* 修复:TSMA 在高频元数据操作时异常停止的问题 -* 修复:show create stable 语句执行结果的标签显示错误 -* 修复:Percentile 函数在大数据量查询时会崩溃。 -* 修复:partition by 和 having 联合使用时的语法错误问题 -* 修复:interp 在 partition by tbname,c1 时 tbname 为空的问题 -* 修复:通过 stmt 写入非法布尔数值时 taosd 可能 crash -* 修复:Explorer OPC-UA 表名模板说明 -* 修复:库符号 version 与使用相同符号的库冲突的问题 https://github.com/taosdata/TDengine/issues/25920 -* 修复:在 windows 平台下 JDBC 驱动的句柄数持续升高问题 -* 修复:3.3.3.1 升级至 3.3.4.0 偶现的启动失败问题 -* 修复:Windows 平台重复增删表的内存泄漏 -* 修复:无法限制并发拉起 checkpoint 数量导致流计算消耗资源过多 -* 修复:并发查询时的 too many session 问题 -* 修复:Windows 平台下 taos shell 在慢查询场景中崩溃的问题 -* 修复:当打开 dnode日志时,加密数据库无法恢复的问题 -* 修复:由于 mnode 同步超时,进而导致 taosd 无法启动的问题 -* 修复:由于在快照同步过程中整理文件组数据的速度过慢,从而导致 Vnode(虚拟节点)无法恢复的问题 -* 修复:通过行协议向字符串类型的字段中写入带转义符的数据时,taosd 会崩溃 -* 修复:Error Code 逻辑处理错误导致的元数据文件损坏 -* 修复:查询语句中包含多个 “not” 条件语句嵌套时,未设置标量模式导致查询错误 -* 修复:vnode 统计信息上报超时导致的 dnode offline 问题 -* 修复:在不支持 avx 指令集的服务器上,taosd 启动失败问题 -* 修复:taosX 数据迁移容错处理 0x09xx 错误码 +### 优化 +1. 优化:提升并发大查询时节点之间互相拉数据的效率 +1. 优化:支持使用 AVX2 和 AVX512 对 double 、timestamp 和 bigint 类型进行解码优化 +1. 优化:调整 case when 语句的结果类型判断方法 +1. 优化:顺序执行 compact 和 split vgroup操作时的日志错误提示 +1. 优化:提升查询 “select ... from ... where ts in (...)” 的数据扫描速度 +1. 优化:增加了流计算的兼容性保证机制,避免后续函数变更产生新的兼容性问题,之前版本的流计算必须重建 +1. 优化:提升 taosX 在交叉写入场景下的数据同步性能 +1. 优化:支持关闭整数/浮点数类型的编码 +1. 优化:多副本流计算中必须使用 snode +1. 优化:客户端生成唯一 ID 标识每一个查询任务,避免重复 ID 导致的内存损坏 +1. 优化:加快数据库的创建时间 +1. 优化:修改 s3MigrateEnabled 默认值为0 +1. 优化:支持在审计数据库中记录删除操作 +1. 优化:支持在指定的 dnode 中创建数据库 [企业版] +1. 优化:调整删除超级表数据列时的报错信息 +### 修复 +1. 修复:last_row 查询性能在 3.3.3.0 中大幅下降的问题 +1. 修复:WAL 条目不完整时 taosd 无法启动的问题 +1. 修复: partition by 常量时查询结果错误的问题 +1. 修复:标量函数包含 _wstart 且填充方式为 prev 时计算结果错误 +1. 修复:Windows 平台下的时区设置问题 +1. 修复:空数据库进行 compact 操作时,事务无法结束【企业版】 +1. 修复:事务冲突的逻辑错误 +1. 修复:管理节点某些错误会导致事务无法停止 +1. 修复:管理节点某些错误会导致事务无法停止 +1. 修复:dnode 数据清空后 taosc 重试错误的问题 +1. 修复:Data Compact 被异常终止后,中间文件未被清理 +1. 修复:新增列后,Kafka 连接器的 earliest 模式消费不到新列数据 +1. 修复:interp 函数在 fill(prev) 时行为不正确 +1. 修复:TSMA 在高频元数据操作时异常停止的问题 +1. 修复:show create stable 语句执行结果的标签显示错误 +1. 修复:Percentile 函数在大数据量查询时会崩溃。 +1. 修复:partition by 和 having 联合使用时的语法错误问题 +1. 修复:interp 在 partition by tbname,c1 时 tbname 为空的问题 +1. 修复:通过 stmt 写入非法布尔数值时 taosd 可能 crash +1. 修复:库符号 version 与使用相同符号的库冲突的问题 +1. 修复:在 windows 平台下 JDBC 驱动的句柄数持续升高问题 +1. 修复:3.3.3.1 升级至 3.3.4.0 偶现的启动失败问题 +1. 修复:Windows 平台重复增删表的内存泄漏 +1. 修复:无法限制并发拉起 checkpoint 数量导致流计算消耗资源过多 +1. 修复:并发查询时的 too many session 问题 +1. 修复:Windows 平台下 taos shell 在慢查询场景中崩溃的问题 +1. 修复:当打开 dnode日志时,加密数据库无法恢复的问题 +1. 修复:由于 mnode 同步超时,进而导致 taosd 无法启动的问题 +1. 修复:由于在快照同步过程中整理文件组数据的速度过慢,从而导致 Vnode(虚拟节点)无法恢复的问题 +1. 修复:通过行协议向字符串类型的字段中写入带转义符的数据时,taosd 会崩溃 +1. 修复:Error Code 逻辑处理错误导致的元数据文件损坏 +1. 修复:查询语句中包含多个 “not” 条件语句嵌套时,未设置标量模式导致查询错误 +1. 修复:vnode 统计信息上报超时导致的 dnode offline 问题 +1. 修复:在不支持 avx 指令集的服务器上,taosd 启动失败问题 +1. 修复:taosX 数据迁移容错处理 0x09xx 错误码 diff --git a/docs/zh/28-releases/03-notes/index.md b/docs/zh/28-releases/03-notes/index.md index 1cdd3239e7..d1a48ab9a8 100644 --- a/docs/zh/28-releases/03-notes/index.md +++ b/docs/zh/28-releases/03-notes/index.md @@ -4,7 +4,6 @@ sidebar_label: 版本说明 description: 各版本版本说明 --- -[3.3.4.3](./3.3.4.3) [3.3.4.3](./3.3.4.3) [3.3.3.0](./3.3.3.0) [3.3.2.0](./3.3.2.0) From 274e40b559e3d9b340c80e66be3fe6972961d4a2 Mon Sep 17 00:00:00 2001 From: kailixu Date: Thu, 21 Nov 2024 16:16:48 +0800 Subject: [PATCH 47/47] test: improve the robustness of alterConfig.py --- tests/army/alter/alterConfig.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/army/alter/alterConfig.py b/tests/army/alter/alterConfig.py index ef8de0011b..6a22dd014f 100644 --- a/tests/army/alter/alterConfig.py +++ b/tests/army/alter/alterConfig.py @@ -113,6 +113,15 @@ class TDTestCase(TBase): if not result: raise Exception(f"key:{key} not found") + def checkRows(self, sql, nExpect, nRetry): + for i in range(nRetry): + res = tdSql.getResult(sql) + if len(res) == nExpect: + break + time.sleep(1) + if len(res) != nExpect: + raise Exception(f"rows:{len(res)} != {nExpect}") + def alterBypassFlag(self): """Add test case for altering bypassFlag(TD-32907) """ @@ -151,8 +160,7 @@ class TDTestCase(TBase): tdSql.query("select * from stb0") tdSql.checkRows(2) tdSql.execute("flush database db") - tdSql.query("select * from stb0") - tdSql.checkRows(0) + self.checkRows("select * from stb0", 0, 10) tdSql.execute("alter all dnodes 'bypassFlag 0'") self.checkKeyValue(tdSql.getResult("show local variables"), "bypassFlag", "0") self.checkKeyValue(tdSql.getResult("show dnode 1 variables like 'bypassFlag'"), "bypassFlag", "0", 1, 2) @@ -161,8 +169,9 @@ class TDTestCase(TBase): tdSql.query("select * from stb0") tdSql.checkRows(2) tdSql.execute("flush database db") - tdSql.query("select * from stb0") - tdSql.checkRows(2) + for i in range(5): + self.checkRows("select * from stb0", 2, 1) + time.sleep(1) # run def run(self):