From 703bdf9459f1a3de7f0957903fb7f3618cb33aec Mon Sep 17 00:00:00 2001 From: Shuaiqiang Chang Date: Tue, 21 Mar 2023 10:07:15 +0800 Subject: [PATCH 01/14] Add files via upload --- docs/zh/05-get-started/xiaot-03.webp | Bin 0 -> 55176 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/zh/05-get-started/xiaot-03.webp diff --git a/docs/zh/05-get-started/xiaot-03.webp b/docs/zh/05-get-started/xiaot-03.webp new file mode 100644 index 0000000000000000000000000000000000000000..c115346e9e84ffb990aec5947b2107b5daf6e19b GIT binary patch literal 55176 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 N*qiW(ZsL%z008V|KCJ)% literal 0 HcmV?d00001 From c9e3d68a6eae527a5413c6b91dfd08645007b591 Mon Sep 17 00:00:00 2001 From: Shuaiqiang Chang Date: Tue, 21 Mar 2023 10:08:13 +0800 Subject: [PATCH 02/14] Update index.md --- docs/zh/05-get-started/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/05-get-started/index.md b/docs/zh/05-get-started/index.md index 62eeb2f1c2..78c801a99b 100644 --- a/docs/zh/05-get-started/index.md +++ b/docs/zh/05-get-started/index.md @@ -25,7 +25,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; - + From 61882c9226deba5127cf017750e54209dbbeb163 Mon Sep 17 00:00:00 2001 From: Shuaiqiang Chang Date: Tue, 21 Mar 2023 10:09:11 +0800 Subject: [PATCH 03/14] Update index.md --- docs/zh/05-get-started/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh/05-get-started/index.md b/docs/zh/05-get-started/index.md index 78c801a99b..16172277b5 100644 --- a/docs/zh/05-get-started/index.md +++ b/docs/zh/05-get-started/index.md @@ -4,7 +4,7 @@ description: '快速设置 TDengine 环境并体验其高效写入和查询' --- import xiaot from './xiaot.webp' -import xiaot_new from './xiaot-new.webp' +import xiaot_new from './xiaot-03.webp' import channel from './channel.webp' import official_account from './official-account.webp' @@ -25,7 +25,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
小 T 的二维码小 T 的二维码 TDengine 微信视频号 TDengine 微信公众号
- + From b6542fb286a6cb153c50809ea12bef893f28585c Mon Sep 17 00:00:00 2001 From: shenglian zhou Date: Tue, 28 Mar 2023 08:43:34 +0800 Subject: [PATCH 04/14] fix: add language and definition body to ins_functions --- source/common/src/systable.c | 2 ++ source/dnode/mnode/impl/src/mndFunc.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 919a09962b..06fe7482e2 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -114,6 +114,8 @@ static const SSysDbTableSchema userFuncSchema[] = { {.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false}, {.name = "code_len", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, {.name = "bufsize", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, + {.name = "language", .bytes = TSDB_TYPE_STR_MAX_LEN - 1 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, + {.name = "body", .bytes = TSDB_MAX_BINARY_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, }; static const SSysDbTableSchema userIdxSchema[] = { diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c index 8d006f1029..7a475c61b6 100644 --- a/source/dnode/mnode/impl/src/mndFunc.c +++ b/source/dnode/mnode/impl/src/mndFunc.c @@ -519,6 +519,7 @@ static int32_t mndRetrieveFuncs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, numOfRows, (const char *)b2, false); + taosMemoryFree(b2); } else { pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, numOfRows, NULL, true); @@ -545,6 +546,26 @@ static int32_t mndRetrieveFuncs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, numOfRows, (const char *)&pFunc->bufSize, false); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + char* language = ""; + if (pFunc->scriptType == TSDB_FUNC_SCRIPT_BIN_LIB) { + language = "C"; + } else if (pFunc->scriptType == TSDB_FUNC_SCRIPT_PYTHON) { + language = "Python"; + } + char varLang[TSDB_TYPE_STR_MAX_LEN + 1] = {0}; + varDataSetLen(varLang, strlen(language)); + strcpy(varDataVal(varLang), language); + colDataSetVal(pColInfo, numOfRows, (const char *)varLang, false); + + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + int32_t varCodeLen = (pFunc->codeSize + VARSTR_HEADER_SIZE) > TSDB_MAX_BINARY_LEN ? TSDB_MAX_BINARY_LEN : pFunc->codeSize + VARSTR_HEADER_SIZE; + char *b4 = taosMemoryMalloc(varCodeLen); + memcpy(varDataVal(b4), pFunc->pCode, varCodeLen - VARSTR_HEADER_SIZE); + varDataSetLen(b4, varCodeLen - VARSTR_HEADER_SIZE); + colDataSetVal(pColInfo, numOfRows, (const char*)b4, false); + taosMemoryFree(b4); + numOfRows++; sdbRelease(pSdb, pFunc); } From 169d0ee13cd6451a11de9984707ea3b47e4f591a Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 28 Mar 2023 11:18:14 +0800 Subject: [PATCH 05/14] fix: scalar return and log error of udf execution --- source/libs/function/src/tudf.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/libs/function/src/tudf.c b/source/libs/function/src/tudf.c index 611344063b..fad118297e 100644 --- a/source/libs/function/src/tudf.c +++ b/source/libs/function/src/tudf.c @@ -1070,8 +1070,15 @@ int32_t callUdfScalarFunc(char *udfName, SScalarParam *input, int32_t numOfCols, if (code != 0) { return code; } + SUdfcUvSession *session = handle; code = doCallUdfScalarFunc(handle, input, numOfCols, output); + if (code != TSDB_CODE_SUCCESS) { + fnError("udfc scalar function execution failure"); + releaseUdfFuncHandle(udfName); + return code; + } + if (output->columnData == NULL) { fnError("udfc scalar function calculate error. no column data"); code = TSDB_CODE_UDF_INVALID_OUTPUT_TYPE; From eb1612483c84ea74982d5984dae433e255ce7000 Mon Sep 17 00:00:00 2001 From: slzhou Date: Wed, 29 Mar 2023 08:56:49 +0800 Subject: [PATCH 06/14] fix: pass odbc.py test. add two columns --- tests/system-test/2-query/odbc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/2-query/odbc.py b/tests/system-test/2-query/odbc.py index 9bbff4af21..f9232dddf8 100644 --- a/tests/system-test/2-query/odbc.py +++ b/tests/system-test/2-query/odbc.py @@ -22,7 +22,7 @@ class TDTestCase: tdSql.execute("insert into db.ctb using db.stb tags(1) (ts, c1) values (now, 1)") tdSql.query("select count(*) from information_schema.ins_columns") - tdSql.checkData(0, 0, 272) + tdSql.checkData(0, 0, 274) tdSql.query("select * from information_schema.ins_columns where table_name = 'ntb'") tdSql.checkRows(14) From dcf5f98b4b83b452fd1837d1548a545fe3a73fd7 Mon Sep 17 00:00:00 2001 From: slzhou Date: Wed, 29 Mar 2023 15:52:08 +0800 Subject: [PATCH 07/14] fix: change name and body to func_name and func_body --- source/common/src/systable.c | 4 ++-- tests/script/tsim/query/udfpy.sim | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 06fe7482e2..2c15980167 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -114,8 +114,8 @@ static const SSysDbTableSchema userFuncSchema[] = { {.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false}, {.name = "code_len", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, {.name = "bufsize", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, - {.name = "language", .bytes = TSDB_TYPE_STR_MAX_LEN - 1 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, - {.name = "body", .bytes = TSDB_MAX_BINARY_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, + {.name = "func_language", .bytes = TSDB_TYPE_STR_MAX_LEN - 1 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, + {.name = "func_body", .bytes = TSDB_MAX_BINARY_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, }; static const SSysDbTableSchema userIdxSchema[] = { diff --git a/tests/script/tsim/query/udfpy.sim b/tests/script/tsim/query/udfpy.sim index 2340235daa..025df7984b 100644 --- a/tests/script/tsim/query/udfpy.sim +++ b/tests/script/tsim/query/udfpy.sim @@ -42,6 +42,25 @@ sql show functions; if $rows != 4 then return -1 endi + +sql select func_language, func_body,name from information_schema.ins_functions order by name +if $rows != 4 then + return -1 +endi + +if $data00 != @C@ then + return -1 +endi +if $data10 != @C@ then + return -1 +endi +if $data20 != @Python@ then + return -1 +endi +if $data30 != @Python@ then + return -1 +endi + sql select bit_and(f, f) from t; if $rows != 2 then return -1 From 5e2b26f1467a528a9c2d72df627e083f87d4283a Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 30 Mar 2023 19:30:54 +0800 Subject: [PATCH 08/14] chore: refactor cus prompt (#20688) * chore: refactor cus prompt * fix: client name in install.sh * fix: -Wno-reserved-user-defined-literal * fix: update taos-tools commit * fix: include/os/osDir.h * fix: check cus name * fix: makepkg.sh * chore: update taos-tools d194dc9 --------- Co-authored-by: chenhaoran --- cmake/cmake.define | 2 +- cmake/taostools_CMakeLists.txt.in | 2 +- include/os/osDir.h | 28 ++++++++++++++++++++++ include/util/cus_name.h | 31 ++++++++++++++++++++++++ packaging/cfg/taos.cfg | 15 ++++++------ packaging/tools/makepkg.sh | 4 +++- source/client/src/clientEnv.c | 14 +++++++++-- source/common/src/tglobal.c | 4 ++++ source/os/src/osSysinfo.c | 12 ++++++++++ tools/shell/CMakeLists.txt | 4 ---- tools/shell/src/shellArguments.c | 39 +++++++++++++++++-------------- 11 files changed, 121 insertions(+), 34 deletions(-) create mode 100644 include/util/cus_name.h diff --git a/cmake/cmake.define b/cmake/cmake.define index 10f2172541..5b65738c70 100644 --- a/cmake/cmake.define +++ b/cmake/cmake.define @@ -121,7 +121,7 @@ ELSE () MESSAGE(STATUS "Compile with Address Sanitizer!") ELSE () SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Werror=return-type -fPIC -gdwarf-2 -g3 -Wformat=2 -Wno-format-nonliteral -Wno-format-truncation -Wno-format-y2k") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-literal-suffix -Werror=return-type -fPIC -gdwarf-2 -g3 -Wformat=2 -Wno-format-nonliteral -Wno-format-truncation -Wno-format-y2k") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-reserved-user-defined-literal -Wno-literal-suffix -Werror=return-type -fPIC -gdwarf-2 -g3 -Wformat=2 -Wno-format-nonliteral -Wno-format-truncation -Wno-format-y2k") ENDIF () # disable all assert diff --git a/cmake/taostools_CMakeLists.txt.in b/cmake/taostools_CMakeLists.txt.in index 3f7a43ab2d..aef89a2d42 100644 --- a/cmake/taostools_CMakeLists.txt.in +++ b/cmake/taostools_CMakeLists.txt.in @@ -2,7 +2,7 @@ # taos-tools ExternalProject_Add(taos-tools GIT_REPOSITORY https://github.com/taosdata/taos-tools.git - GIT_TAG e82b9fc + GIT_TAG d194dc9 SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools" BINARY_DIR "" #BUILD_IN_SOURCE TRUE diff --git a/include/os/osDir.h b/include/os/osDir.h index 73871602c5..55c7a15764 100644 --- a/include/os/osDir.h +++ b/include/os/osDir.h @@ -31,21 +31,49 @@ extern "C" { #endif +#if defined(CUS_NAME) || defined(CUS_PROMPT) || defined(CUS_EMAIL) +#include "cus_name.h" +#endif + #ifdef WINDOWS + #define TD_TMP_DIR_PATH "C:\\Windows\\Temp\\" +#ifdef CUS_NAME +#define TD_CFG_DIR_PATH "C:\\"CUS_NAME"\\cfg\\" +#define TD_DATA_DIR_PATH "C:\\"CUS_NAME"\\data\\" +#define TD_LOG_DIR_PATH "C:\\"CUS_NAME"\\log\\" +#else #define TD_CFG_DIR_PATH "C:\\TDengine\\cfg\\" #define TD_DATA_DIR_PATH "C:\\TDengine\\data\\" #define TD_LOG_DIR_PATH "C:\\TDengine\\log\\" +#endif // CUS_NAME + #elif defined(_TD_DARWIN_64) + +#ifdef CUS_PROMPT +#define TD_TMP_DIR_PATH "/tmp/"CUS_PROMPT"d/" +#define TD_CFG_DIR_PATH "/etc/"CUS_PROMPT"/" +#define TD_DATA_DIR_PATH "/var/lib/"CUS_PROMPT"/" +#define TD_LOG_DIR_PATH "/var/log/"CUS_PROMPT"/" +#else #define TD_TMP_DIR_PATH "/tmp/taosd/" #define TD_CFG_DIR_PATH "/etc/taos/" #define TD_DATA_DIR_PATH "/var/lib/taos/" #define TD_LOG_DIR_PATH "/var/log/taos/" +#endif // CUS_PROMPT + #else + #define TD_TMP_DIR_PATH "/tmp/" +#ifdef CUS_PROMPT +#define TD_CFG_DIR_PATH "/etc/"CUS_PROMPT"/" +#define TD_DATA_DIR_PATH "/var/lib/"CUS_PROMPT"/" +#define TD_LOG_DIR_PATH "/var/log/"CUS_PROMPT"/" +#else #define TD_CFG_DIR_PATH "/etc/taos/" #define TD_DATA_DIR_PATH "/var/lib/taos/" #define TD_LOG_DIR_PATH "/var/log/taos/" +#endif // CUS_PROMPT #endif typedef struct TdDir *TdDirPtr; diff --git a/include/util/cus_name.h b/include/util/cus_name.h new file mode 100644 index 0000000000..16f677f855 --- /dev/null +++ b/include/util/cus_name.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _CUS_NAME_H_ +#define _CUS_NAME_H_ + +#ifndef CUS_NAME +#define CUS_NAME "TDengine" +#endif + +#ifndef CUS_PROMPT +#define CUS_PROMPT "taos" +#endif + +#ifndef CUS_EMAIL +#define CUS_EMAIL "" +#endif + +#endif // _CUS_NAME_H_ diff --git a/packaging/cfg/taos.cfg b/packaging/cfg/taos.cfg index a98dc5a236..2159899aa2 100644 --- a/packaging/cfg/taos.cfg +++ b/packaging/cfg/taos.cfg @@ -1,7 +1,6 @@ ######################################################## # # # Configuration # -# Any questions, please email support@taosdata.com # # # ######################################################## @@ -13,7 +12,7 @@ ############### 1. Cluster End point ############################ -# The end point of the first dnode in the cluster to be connected to when this dnode or a CLI `taos` is started +# The end point of the first dnode in the cluster to be connected to when this dnode or the CLI utility is started # firstEp hostname:6030 # The end point of the second dnode to be connected to if the firstEp is not available @@ -25,7 +24,7 @@ # The FQDN of the host on which this dnode will be started. It can be IP address # fqdn hostname -# The port for external access after this dnode is started +# The port for external access after this dnode is started # serverPort 6030 # The maximum number of connections a dnode can accept @@ -96,7 +95,7 @@ # if free disk space is less than this value, this dnode will fail to start # minimalDataDirGB 2.0 -# enable/disable system monitor +# enable/disable system monitor # monitor 1 # The following parameter is used to limit the maximum number of lines in log files. @@ -114,8 +113,8 @@ # The following parameters are used for debug purpose only by this dnode. # debugFlag is a 8 bits mask: FILE-SCREEN-UNUSED-HeartBeat-DUMP-TRACE_WARN-ERROR -# Available debug levels are: -# 131: output warning and error +# Available debug levels are: +# 131: output warning and error # 135: output debug, warning and error # 143: output trace, debug, warning and error to log # 199: output debug, warning and error to both screen and file @@ -130,7 +129,7 @@ # debug flag for util # uDebugFlag 131 -# debug flag for rpc +# debug flag for rpc # rpcDebugFlag 131 # debug flag for jni @@ -139,7 +138,7 @@ # debug flag for query # qDebugFlag 131 -# debug flag for taosc driver +# debug flag for client driver # cDebugFlag 131 # debug flag for dnode messages diff --git a/packaging/tools/makepkg.sh b/packaging/tools/makepkg.sh index 29160238ce..f30ec23b9f 100755 --- a/packaging/tools/makepkg.sh +++ b/packaging/tools/makepkg.sh @@ -234,7 +234,9 @@ if [ "$verMode" == "cluster" ]; then sed -i "s/serverName2=\"taosd\"/serverName2=\"${serverName2}\"/g" remove_temp.sh sed -i "s/clientName2=\"taos\"/clientName2=\"${clientName2}\"/g" remove_temp.sh sed -i "s/productName2=\"TDengine\"/productName2=\"${productName2}\"/g" remove_temp.sh - sed -i "s/emailName2=\"taosdata.com\"/emailName2=\"${cusEmail2}\"/g" remove_temp.sh + cusDomain=`echo "${cusEmail2}" | sed 's/^[^@]*@//'` + echo "domain is ${cusDomain}" + sed -i "s/emailName2=\"taosdata.com\"/emailName2=\"${cusDomain}\"/g" remove_temp.sh mv remove_temp.sh ${install_dir}/bin/remove.sh fi if [ "$verMode" == "cloud" ]; then diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index de08ba66cc..874ac12f5c 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -30,6 +30,10 @@ #include "tsched.h" #include "ttime.h" +#if defined(CUS_NAME) || defined(CUS_PROMPT) || defined(CUS_EMAIL) +#include "cus_name.h" +#endif + #define TSC_VAR_NOT_RELEASE 1 #define TSC_VAR_RELEASED 0 @@ -541,9 +545,15 @@ void taos_init_imp(void) { deltaToUtcInitOnce(); - if (taosCreateLog("taoslog", 10, configDir, NULL, NULL, NULL, NULL, 1) != 0) { + char logDirName[64] = {0}; +#ifdef CUS_PROMPT + snprintf(logDirName, 64, "%slog", CUS_PROMPT); +#else + snprintf(logDirName, 64, "taoslog"); +#endif + if (taosCreateLog(logDirName, 10, configDir, NULL, NULL, NULL, NULL, 1) != 0) { // ignore create log failed, only print - printf(" WARING: Create taoslog failed:%s. configDir=%s\n", strerror(errno), configDir); + printf(" WARING: Create %s failed:%s. configDir=%s\n", logDirName, strerror(errno), configDir); } if (taosInitCfg(configDir, NULL, NULL, NULL, NULL, 1) != 0) { diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index aeeec1d61c..1c2d533977 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -228,7 +228,11 @@ static int32_t taosLoadCfg(SConfig *pCfg, const char **envCmd, const char *input taosExpandDir(inputCfgDir, cfgDir, PATH_MAX); if (taosIsDir(cfgDir)) { +#ifdef CUS_PROMPT + snprintf(cfgFile, sizeof(cfgFile), "%s" TD_DIRSEP "%s.cfg", CUS_PROMPT, cfgDir); +#else snprintf(cfgFile, sizeof(cfgFile), "%s" TD_DIRSEP "taos.cfg", cfgDir); +#endif } else { tstrncpy(cfgFile, cfgDir, sizeof(cfgDir)); } diff --git a/source/os/src/osSysinfo.c b/source/os/src/osSysinfo.c index 52309a7b35..84004ed3c1 100644 --- a/source/os/src/osSysinfo.c +++ b/source/os/src/osSysinfo.c @@ -17,6 +17,10 @@ #include "os.h" #include "taoserror.h" +#if defined(CUS_NAME) || defined(CUS_PROMPT) || defined(CUS_EMAIL) +#include "cus_name.h" +#endif + #define PROCESS_ITEM 12 #define UUIDLEN37 37 @@ -252,7 +256,11 @@ int32_t taosGetEmail(char *email, int32_t maxLen) { #ifdef WINDOWS // ASSERT(0); #elif defined(_TD_DARWIN_64) +#ifdef CUS_PROMPT + const char *filepath = "/usr/local/"CUS_PROMPT"/email"; +#else const char *filepath = "/usr/local/taos/email"; +#endif // CUS_PROMPT TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ); if (pFile == NULL) return false; @@ -264,8 +272,12 @@ int32_t taosGetEmail(char *email, int32_t maxLen) { taosCloseFile(&pFile); return 0; +#else +#ifdef CUS_PROMPT + const char *filepath = "/usr/local/"CUS_PROMPT"/email"; #else const char *filepath = "/usr/local/taos/email"; +#endif // CUS_PROMPT TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ); if (pFile == NULL) return false; diff --git a/tools/shell/CMakeLists.txt b/tools/shell/CMakeLists.txt index 600e33feab..7b1dc3a541 100644 --- a/tools/shell/CMakeLists.txt +++ b/tools/shell/CMakeLists.txt @@ -26,10 +26,6 @@ ELSE () SET(LINK_WEBSOCKET "") ENDIF () -IF (CUS_NAME OR CUS_PROMPT OR CUS_EMAIL) - ADD_DEFINITIONS(-I${CMAKE_CURRENT_SOURCE_DIR}/../../../enterprise/packaging) -ENDIF (CUS_NAME OR CUS_PROMPT OR CUS_EMAIL) - IF (TD_LINUX AND TD_ALPINE) SET(LINK_ARGP "/usr/lib/libargp.a") ELSE () diff --git a/tools/shell/src/shellArguments.c b/tools/shell/src/shellArguments.c index 2b7d829652..f7008548f6 100644 --- a/tools/shell/src/shellArguments.c +++ b/tools/shell/src/shellArguments.c @@ -19,18 +19,6 @@ #include "shellInt.h" -#ifndef CUS_NAME - char cusName[] = "TDengine"; -#endif - -#ifndef CUS_PROMPT - char cusPrompt[] = "taos"; -#endif - -#ifndef CUS_EMAIL - char cusEmail[] = ""; -#endif - #if defined(CUS_NAME) || defined(CUS_PROMPT) || defined(CUS_EMAIL) #include "cus_name.h" #endif @@ -92,7 +80,11 @@ void shellPrintHelp() { #endif printf("%s%s%s%s\r\n", indent, "-w,", indent, SHELL_WIDTH); printf("%s%s%s%s\r\n", indent, "-V,", indent, SHELL_VERSION); - printf("\r\n\r\nReport bugs to %s.\r\n", cusEmail); +#ifdef CUS_EMAIL + printf("\r\n\r\nReport bugs to %s.\r\n", CUS_EMAIL); +#else + printf("\r\n\r\nReport bugs to %s.\r\n", "support@taosdata.com"); +#endif } #ifdef LINUX @@ -104,7 +96,11 @@ void shellPrintHelp() { #endif const char *argp_program_version = version; -const char *argp_program_bug_address = cusEmail; +#ifdef CUS_EMAIL +const char *argp_program_bug_address = CUS_EMAIL; +#else +const char *argp_program_bug_address = "support@taosdata.com"; +#endif static struct argp_option shellOptions[] = { {"host", 'h', "HOST", 0, SHELL_HOST}, @@ -414,10 +410,19 @@ int32_t shellParseArgs(int32_t argc, char *argv[]) { shell.info.clientVersion = "Welcome to the %s Command Line Interface, Client Version:%s\r\n" "Copyright (c) 2022 by %s, all rights reserved.\r\n\r\n"; - strcpy(shell.info.cusName, cusName); - sprintf(shell.info.promptHeader, "%s> ", cusPrompt); +#ifdef CUS_NAME + strcpy(shell.info.cusName, CUS_NAME); +#else + strcpy(shell.info.cusName, "TDengine"); +#endif char promptContinueFormat[32] = {0}; - sprintf(promptContinueFormat, "%%%zus> ", strlen(cusPrompt)); +#ifdef CUS_PROMPT + sprintf(shell.info.promptHeader, "%s> ", CUS_PROMPT); + sprintf(promptContinueFormat, "%%%zus> ", strlen(CUS_PROMPT)); +#else + sprintf(shell.info.promptHeader, "taos> "); + sprintf(promptContinueFormat, "%%%zus> ", strlen("taos")); +#endif sprintf(shell.info.promptContinue, promptContinueFormat, " "); shell.info.promptSize = strlen(shell.info.promptHeader); snprintf(shell.info.programVersion, sizeof(shell.info.programVersion), From 1e2d3a78963bae6695a2c9c57f0e634fc79fa398 Mon Sep 17 00:00:00 2001 From: Xuefeng Tan <1172915550@qq.com> Date: Fri, 31 Mar 2023 09:41:06 +0800 Subject: [PATCH 09/14] enh(taosAdapter): TMQ parameter adjustment (#20711) --- cmake/taosadapter_CMakeLists.txt.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/taosadapter_CMakeLists.txt.in b/cmake/taosadapter_CMakeLists.txt.in index 1c401ae80e..b2f335e1f7 100644 --- a/cmake/taosadapter_CMakeLists.txt.in +++ b/cmake/taosadapter_CMakeLists.txt.in @@ -2,7 +2,7 @@ # taosadapter ExternalProject_Add(taosadapter GIT_REPOSITORY https://github.com/taosdata/taosadapter.git - GIT_TAG d8059ff + GIT_TAG cb1e89c SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter" BINARY_DIR "" #BUILD_IN_SOURCE TRUE From 171d360cac593c889432a4c9c77e1d627a00eece Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Fri, 31 Mar 2023 15:25:00 +0800 Subject: [PATCH 10/14] Revert "current from binary to json" --- include/util/tjson.h | 2 +- include/util/tutil.h | 28 +-- source/dnode/vnode/src/tsdb/tsdbFS.c | 262 +++----------------- source/dnode/vnode/src/tsdb/tsdbFile.c | 321 +------------------------ 4 files changed, 45 insertions(+), 568 deletions(-) diff --git a/include/util/tjson.h b/include/util/tjson.h index af0b163986..6922930c13 100644 --- a/include/util/tjson.h +++ b/include/util/tjson.h @@ -25,7 +25,7 @@ extern "C" { #define tjsonGetNumberValue(pJson, pName, val, code) \ do { \ - int64_t _tmp = 0; \ + uint64_t _tmp = 0; \ code = tjsonGetBigIntValue(pJson, pName, &_tmp); \ val = _tmp; \ } while (0) diff --git a/include/util/tutil.h b/include/util/tutil.h index c8f1b29e10..e0801e5295 100644 --- a/include/util/tutil.h +++ b/include/util/tutil.h @@ -29,7 +29,7 @@ extern "C" { int32_t strdequote(char *src); size_t strtrim(char *src); char *strnchr(const char *haystack, char needle, int32_t len, bool skipquote); -TdUcs4 *wcsnchr(const TdUcs4 *haystack, TdUcs4 needle, size_t len); +TdUcs4* wcsnchr(const TdUcs4* haystack, TdUcs4 needle, size_t len); char **strsplit(char *src, const char *delim, int32_t *num); char *strtolower(char *dst, const char *src); @@ -37,11 +37,11 @@ char *strntolower(char *dst, const char *src, int32_t n); char *strntolower_s(char *dst, const char *src, int32_t n); int64_t strnatoi(char *num, int32_t len); -size_t tstrncspn(const char *str, size_t ssize, const char *reject, size_t rsize); -size_t twcsncspn(const TdUcs4 *wcs, size_t size, const TdUcs4 *reject, size_t rsize); +size_t tstrncspn(const char *str, size_t ssize, const char *reject, size_t rsize); +size_t twcsncspn(const TdUcs4 *wcs, size_t size, const TdUcs4 *reject, size_t rsize); -char *strbetween(char *string, char *begin, char *end); -char *paGetToken(char *src, char **token, int32_t *tokenLen); +char *strbetween(char *string, char *begin, char *end); +char *paGetToken(char *src, char **token, int32_t *tokenLen); int32_t taosByteArrayToHexStr(char bytes[], int32_t len, char hexstr[]); int32_t taosHexStrToByteArray(char hexstr[], char bytes[]); @@ -92,26 +92,12 @@ static FORCE_INLINE int32_t taosGetTbHashVal(const char *tbname, int32_t tblen, } } -#define TSDB_CHECK(condition, CODE, LINO, LABEL, ERRNO) \ - if (!(condition)) { \ - (CODE) = (ERRNO); \ - (LINO) = __LINE__; \ - goto LABEL; \ - } - #define TSDB_CHECK_CODE(CODE, LINO, LABEL) \ - if ((CODE)) { \ - (LINO) = __LINE__; \ + if (CODE) { \ + LINO = __LINE__; \ goto LABEL; \ } -#define TSDB_CHECK_NULL(ptr, CODE, LINO, LABEL, ERRNO) \ - if ((ptr) == NULL) { \ - (CODE) = (ERRNO); \ - (LINO) = __LINE__; \ - goto LABEL; \ - } - #ifdef __cplusplus } #endif diff --git a/source/dnode/vnode/src/tsdb/tsdbFS.c b/source/dnode/vnode/src/tsdb/tsdbFS.c index b85d8d7746..5519d43012 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFS.c +++ b/source/dnode/vnode/src/tsdb/tsdbFS.c @@ -88,98 +88,6 @@ _exit: return code; } -extern int32_t tsdbDelFileToJson(const SDelFile *pDelFile, cJSON *pJson); -extern int32_t tsdbJsonToDelFile(const cJSON *pJson, SDelFile *pDelFile); -extern int32_t tsdbDFileSetToJson(const SDFileSet *pSet, cJSON *pJson); -extern int32_t tsdbJsonToDFileSet(const cJSON *pJson, SDFileSet *pDelFile); - -static int32_t tsdbFSToJsonStr(STsdbFS *pFS, char **ppStr) { - int32_t code = 0; - int32_t lino = 0; - cJSON *pJson; - - ppStr[0] = NULL; - - pJson = cJSON_CreateObject(); - TSDB_CHECK_NULL(pJson, code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - - // format version - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "format", 1), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - - // SDelFile - if (pFS->pDelFile) { - code = tsdbDelFileToJson(pFS->pDelFile, cJSON_AddObjectToObject(pJson, "del")); - TSDB_CHECK_CODE(code, lino, _exit); - } - - // aDFileSet - cJSON *aSetJson = cJSON_AddArrayToObject(pJson, "file set"); - TSDB_CHECK_NULL(aSetJson, code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - for (int32_t iSet = 0; iSet < taosArrayGetSize(pFS->aDFileSet); iSet++) { - cJSON *pSetJson = cJSON_CreateObject(); - TSDB_CHECK_NULL(pSetJson, code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - - cJSON_AddItemToArray(aSetJson, pSetJson); - - code = tsdbDFileSetToJson(taosArrayGet(pFS->aDFileSet, iSet), pSetJson); - TSDB_CHECK_CODE(code, lino, _exit); - } - - // print - ppStr[0] = cJSON_Print(pJson); - TSDB_CHECK_NULL(ppStr[0], code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - -_exit: - cJSON_Delete(pJson); - if (code) tsdbError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); - return code; -} - -static int32_t tsdbJsonStrToFS(const char *pStr, STsdbFS *pFS) { - int32_t code = 0; - int32_t lino; - - cJSON *pJson = cJSON_Parse(pStr); - TSDB_CHECK(pJson, code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - - const cJSON *pItem; - - // format version - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "format")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - - // SDelFile - if (cJSON_IsObject(pItem = cJSON_GetObjectItem(pJson, "del"))) { - pFS->pDelFile = (SDelFile *)taosMemoryCalloc(1, sizeof(SDelFile)); - TSDB_CHECK_NULL(pFS->pDelFile, code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - - code = tsdbJsonToDelFile(pItem, pFS->pDelFile); - TSDB_CHECK_CODE(code, lino, _exit); - - pFS->pDelFile->nRef = 1; - } else { - pFS->pDelFile = NULL; - } - - // aDFileSet - taosArrayClear(pFS->aDFileSet); - - const cJSON *pSetJson; - TSDB_CHECK(cJSON_IsArray(pItem = cJSON_GetObjectItem(pJson, "file set")), code, lino, _exit, - TSDB_CODE_FILE_CORRUPTED); - cJSON_ArrayForEach(pSetJson, pItem) { - SDFileSet *pSet = (SDFileSet *)taosArrayReserve(pFS->aDFileSet, 1); - TSDB_CHECK_NULL(pSet, code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - - code = tsdbJsonToDFileSet(pSetJson, pSet); - TSDB_CHECK_CODE(code, lino, _exit); - } - -_exit: - cJSON_Delete(pJson); - if (code) tsdbError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); - return code; -} - static int32_t tsdbSaveFSToFile(STsdbFS *pFS, const char *fname) { int32_t code = 0; int32_t lino = 0; @@ -224,84 +132,6 @@ _exit: return code; } -static int32_t tsdbSaveFSToJsonFile(STsdbFS *pFS, const char *fname) { - int32_t code; - int32_t lino; - char *pData; - - code = tsdbFSToJsonStr(pFS, &pData); - if (code) return code; - - TdFilePtr pFD = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC); - if (pFD == NULL) { - code = TAOS_SYSTEM_ERROR(errno); - TSDB_CHECK_CODE(code, lino, _exit); - } - - int64_t n = taosWriteFile(pFD, pData, strlen(pData) + 1); - if (n < 0) { - code = TAOS_SYSTEM_ERROR(errno); - taosCloseFile(&pFD); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if (taosFsyncFile(pFD) < 0) { - code = TAOS_SYSTEM_ERROR(errno); - taosCloseFile(&pFD); - TSDB_CHECK_CODE(code, lino, _exit); - } - - taosCloseFile(&pFD); - -_exit: - taosMemoryFree(pData); - if (code) { - tsdbError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); - } - - return code; -} - -static int32_t tsdbLoadFSFromJsonFile(const char *fname, STsdbFS *pFS) { - int32_t code = 0; - int32_t lino = 0; - char *pData = NULL; - - TdFilePtr pFD = taosOpenFile(fname, TD_FILE_READ); - if (pFD == NULL) { - code = TAOS_SYSTEM_ERROR(errno); - TSDB_CHECK_CODE(code, lino, _exit); - } - - int64_t size; - if (taosFStatFile(pFD, &size, NULL) < 0) { - code = TAOS_SYSTEM_ERROR(errno); - taosCloseFile(&pFD); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if ((pData = taosMemoryMalloc(size)) == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - taosCloseFile(&pFD); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if (taosReadFile(pFD, pData, size) < 0) { - code = TAOS_SYSTEM_ERROR(errno); - taosCloseFile(&pFD); - TSDB_CHECK_CODE(code, lino, _exit); - } - - taosCloseFile(&pFD); - - TSDB_CHECK_CODE(code = tsdbJsonStrToFS(pData, pFS), lino, _exit); - -_exit: - if (pData) taosMemoryFree(pData); - if (code) tsdbError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); - return code; -} - int32_t tsdbFSCreate(STsdbFS *pFS) { int32_t code = 0; @@ -439,8 +269,7 @@ int32_t tDFileSetCmprFn(const void *p1, const void *p2) { return 0; } -static void tsdbGetCurrentFName(STsdb *pTsdb, char *current, char *current_t, char *current_json, - char *current_json_t) { +static void tsdbGetCurrentFName(STsdb *pTsdb, char *current, char *current_t) { SVnode *pVnode = pTsdb->pVnode; if (pVnode->pTfs) { if (current) { @@ -451,14 +280,6 @@ static void tsdbGetCurrentFName(STsdb *pTsdb, char *current, char *current_t, ch snprintf(current_t, TSDB_FILENAME_LEN - 1, "%s%s%s%sCURRENT.t", tfsGetPrimaryPath(pTsdb->pVnode->pTfs), TD_DIRSEP, pTsdb->path, TD_DIRSEP); } - if (current_json) { - snprintf(current_json, TSDB_FILENAME_LEN - 1, "%s%s%s%scurrent.json", tfsGetPrimaryPath(pTsdb->pVnode->pTfs), - TD_DIRSEP, pTsdb->path, TD_DIRSEP); - } - if (current_json_t) { - snprintf(current_json_t, TSDB_FILENAME_LEN - 1, "%s%s%s%scurrent.json.t", tfsGetPrimaryPath(pTsdb->pVnode->pTfs), - TD_DIRSEP, pTsdb->path, TD_DIRSEP); - } } else { if (current) { snprintf(current, TSDB_FILENAME_LEN - 1, "%s%sCURRENT", pTsdb->path, TD_DIRSEP); @@ -466,12 +287,6 @@ static void tsdbGetCurrentFName(STsdb *pTsdb, char *current, char *current_t, ch if (current_t) { snprintf(current_t, TSDB_FILENAME_LEN - 1, "%s%sCURRENT.t", pTsdb->path, TD_DIRSEP); } - if (current_json) { - snprintf(current_json, TSDB_FILENAME_LEN - 1, "%s%scurrent.json", pTsdb->path, TD_DIRSEP); - } - if (current_json_t) { - snprintf(current_json_t, TSDB_FILENAME_LEN - 1, "%s%scurrent.json.t", pTsdb->path, TD_DIRSEP); - } } } @@ -887,15 +702,20 @@ _exit: return code; } -static int32_t tsdbFSCommitImpl(STsdb *pTsdb, const char *fname, const char *tfname, bool isJson) { +// EXPOSED APIS ==================================================================================== +int32_t tsdbFSCommit(STsdb *pTsdb) { int32_t code = 0; int32_t lino = 0; STsdbFS fs = {0}; - if (!taosCheckExistFile(tfname)) goto _exit; + char current[TSDB_FILENAME_LEN] = {0}; + char current_t[TSDB_FILENAME_LEN] = {0}; + tsdbGetCurrentFName(pTsdb, current, current_t); + + if (!taosCheckExistFile(current_t)) goto _exit; // rename the file - if (taosRenameFile(tfname, fname) < 0) { + if (taosRenameFile(current_t, current) < 0) { code = TAOS_SYSTEM_ERROR(errno); TSDB_CHECK_CODE(code, lino, _exit); } @@ -904,11 +724,7 @@ static int32_t tsdbFSCommitImpl(STsdb *pTsdb, const char *fname, const char *tfn code = tsdbFSCreate(&fs); TSDB_CHECK_CODE(code, lino, _exit); - if (isJson) { - code = tsdbLoadFSFromJsonFile(fname, &fs); - } else { - code = tsdbLoadFSFromFile(fname, &fs); - } + code = tsdbLoadFSFromFile(current, &fs); TSDB_CHECK_CODE(code, lino, _exit); // apply file change @@ -923,19 +739,18 @@ _exit: return code; } -// EXPOSED APIS ==================================================================================== -int32_t tsdbFSCommit(STsdb *pTsdb) { - char current_json[TSDB_FILENAME_LEN] = {0}; - char current_json_t[TSDB_FILENAME_LEN] = {0}; - tsdbGetCurrentFName(pTsdb, NULL, NULL, current_json, current_json_t); - return tsdbFSCommitImpl(pTsdb, current_json, current_json_t, true); -} - int32_t tsdbFSRollback(STsdb *pTsdb) { int32_t code = 0; - char current_json_t[TSDB_FILENAME_LEN] = {0}; - tsdbGetCurrentFName(pTsdb, NULL, NULL, NULL, current_json_t); - (void)taosRemoveFile(current_json_t); + int32_t lino = 0; + + char current_t[TSDB_FILENAME_LEN] = {0}; + tsdbGetCurrentFName(pTsdb, NULL, current_t); + (void)taosRemoveFile(current_t); + +_exit: + if (code) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(errno)); + } return code; } @@ -951,33 +766,13 @@ int32_t tsdbFSOpen(STsdb *pTsdb, int8_t rollback) { // open impl char current[TSDB_FILENAME_LEN] = {0}; char current_t[TSDB_FILENAME_LEN] = {0}; - char current_json[TSDB_FILENAME_LEN] = {0}; - char current_json_t[TSDB_FILENAME_LEN] = {0}; - tsdbGetCurrentFName(pTsdb, current, current_t, current_json, current_json_t); + tsdbGetCurrentFName(pTsdb, current, current_t); if (taosCheckExistFile(current)) { - // CURRENT file exists code = tsdbLoadFSFromFile(current, &pTsdb->fs); TSDB_CHECK_CODE(code, lino, _exit); if (taosCheckExistFile(current_t)) { - if (rollback) { - (void)taosRemoveFile(current_t); - } else { - code = tsdbFSCommitImpl(pTsdb, current, current_t, false); - TSDB_CHECK_CODE(code, lino, _exit); - } - } - - code = tsdbSaveFSToJsonFile(&pTsdb->fs, current_json); - TSDB_CHECK_CODE(code, lino, _exit); - (void)taosRemoveFile(current); - } else if (taosCheckExistFile(current_json)) { - // current.json exists - code = tsdbLoadFSFromJsonFile(current_json, &pTsdb->fs); - TSDB_CHECK_CODE(code, lino, _exit); - - if (taosCheckExistFile(current_json_t)) { if (rollback) { code = tsdbFSRollback(pTsdb); TSDB_CHECK_CODE(code, lino, _exit); @@ -987,10 +782,11 @@ int32_t tsdbFSOpen(STsdb *pTsdb, int8_t rollback) { } } } else { - // empty TSDB - ASSERT(!rollback); - code = tsdbSaveFSToJsonFile(&pTsdb->fs, current_json); + // empty one + code = tsdbSaveFSToFile(&pTsdb->fs, current); TSDB_CHECK_CODE(code, lino, _exit); + + ASSERT(!rollback); } // scan and fix FS @@ -1228,12 +1024,12 @@ _exit: int32_t tsdbFSPrepareCommit(STsdb *pTsdb, STsdbFS *pFSNew) { int32_t code = 0; int32_t lino = 0; - char current_json_t[TSDB_FILENAME_LEN]; + char tfname[TSDB_FILENAME_LEN]; - tsdbGetCurrentFName(pTsdb, NULL, NULL, NULL, current_json_t); + tsdbGetCurrentFName(pTsdb, NULL, tfname); - // generate current.json - code = tsdbSaveFSToJsonFile(pFSNew, current_json_t); + // gnrt CURRENT.t + code = tsdbSaveFSToFile(pFSNew, tfname); TSDB_CHECK_CODE(code, lino, _exit); _exit: diff --git a/source/dnode/vnode/src/tsdb/tsdbFile.c b/source/dnode/vnode/src/tsdb/tsdbFile.c index 8b2b2caec7..d91475376b 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFile.c +++ b/source/dnode/vnode/src/tsdb/tsdbFile.c @@ -92,11 +92,11 @@ static int32_t tGetSmaFile(uint8_t *p, SSmaFile *pSmaFile) { } // EXPOSED APIS ================================================== -static char *getFileNamePrefix(STsdb *pTsdb, SDiskID did, int32_t fid, uint64_t commitId, char fname[]) { - const char *p1 = tfsGetDiskPath(pTsdb->pVnode->pTfs, did); - int32_t len = strlen(p1); +static char* getFileNamePrefix(STsdb *pTsdb, SDiskID did, int32_t fid, uint64_t commitId, char fname[]) { + const char* p1 = tfsGetDiskPath(pTsdb->pVnode->pTfs, did); + int32_t len = strlen(p1); - char *p = memcpy(fname, p1, len); + char* p = memcpy(fname, p1, len); p += len; *(p++) = TD_DIRSEP[0]; @@ -121,25 +121,25 @@ static char *getFileNamePrefix(STsdb *pTsdb, SDiskID did, int32_t fid, uint64_t } void tsdbHeadFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SHeadFile *pHeadF, char fname[]) { - char *p = getFileNamePrefix(pTsdb, did, fid, pHeadF->commitID, fname); + char* p = getFileNamePrefix(pTsdb, did, fid, pHeadF->commitID, fname); memcpy(p, ".head", 5); p[5] = 0; } void tsdbDataFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SDataFile *pDataF, char fname[]) { - char *p = getFileNamePrefix(pTsdb, did, fid, pDataF->commitID, fname); + char* p = getFileNamePrefix(pTsdb, did, fid, pDataF->commitID, fname); memcpy(p, ".data", 5); p[5] = 0; } void tsdbSttFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SSttFile *pSttF, char fname[]) { - char *p = getFileNamePrefix(pTsdb, did, fid, pSttF->commitID, fname); + char* p = getFileNamePrefix(pTsdb, did, fid, pSttF->commitID, fname); memcpy(p, ".stt", 4); p[4] = 0; } void tsdbSmaFileName(STsdb *pTsdb, SDiskID did, int32_t fid, SSmaFile *pSmaF, char fname[]) { - char *p = getFileNamePrefix(pTsdb, did, fid, pSmaF->commitID, fname); + char* p = getFileNamePrefix(pTsdb, did, fid, pSmaF->commitID, fname); memcpy(p, ".sma", 4); p[4] = 0; } @@ -280,272 +280,6 @@ int32_t tGetDFileSet(uint8_t *p, SDFileSet *pSet) { return n; } -static int32_t tDiskIdToJson(const SDiskID *pDiskId, cJSON *pJson) { - int32_t code = 0; - int32_t lino; - - if (pJson == NULL) return TSDB_CODE_OUT_OF_MEMORY; - - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "level", pDiskId->level), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "id", pDiskId->id), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - -_exit: - return code; -} -static int32_t tJsonToDiskId(const cJSON *pJson, SDiskID *pDiskId) { - int32_t code = 0; - int32_t lino; - - const cJSON *pItem; - - // level - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "level")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pDiskId->level = (int32_t)pItem->valuedouble; - - // id - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "id")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pDiskId->id = (int32_t)pItem->valuedouble; - -_exit: - return code; -} - -static int32_t tHeadFileToJson(const SHeadFile *pHeadF, cJSON *pJson) { - int32_t code = 0; - int32_t lino; - - if (pJson == NULL) return TSDB_CODE_OUT_OF_MEMORY; - - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "commit id", pHeadF->commitID), code, lino, _exit, - TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "size", pHeadF->size), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "offset", pHeadF->offset), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - -_exit: - return code; -} - -static int32_t tJsonToHeadFile(const cJSON *pJson, SHeadFile *pHeadF) { - int32_t code = 0; - int32_t lino; - - const cJSON *pItem; - - // commit id - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "commit id")), code, lino, _exit, - TSDB_CODE_FILE_CORRUPTED); - pHeadF->commitID = (int64_t)pItem->valuedouble; - - // size - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "size")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pHeadF->size = (int64_t)pItem->valuedouble; - - // offset - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "offset")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pHeadF->offset = (int64_t)pItem->valuedouble; - -_exit: - return code; -} - -static int32_t tDataFileToJson(const SDataFile *pDataF, cJSON *pJson) { - int32_t code = 0; - int32_t lino; - - if (pJson == NULL) return TSDB_CODE_OUT_OF_MEMORY; - - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "commit id", pDataF->commitID), code, lino, _exit, - TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "size", pDataF->size), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - -_exit: - return code; -} - -static int32_t tJsonToDataFile(const cJSON *pJson, SDataFile *pDataF) { - int32_t code = 0; - int32_t lino; - - const cJSON *pItem; - - // commit id - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "commit id")), code, lino, _exit, - TSDB_CODE_FILE_CORRUPTED); - pDataF->commitID = (int64_t)pItem->valuedouble; - - // size - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "size")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pDataF->size = (int64_t)pItem->valuedouble; - -_exit: - return code; -} - -static int32_t tSmaFileToJson(const SSmaFile *pSmaF, cJSON *pJson) { - int32_t code = 0; - int32_t lino; - - if (pJson == NULL) return TSDB_CODE_OUT_OF_MEMORY; - - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "commit id", pSmaF->commitID), code, lino, _exit, - TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "size", pSmaF->size), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - -_exit: - return code; -} - -static int32_t tJsonToSmaFile(const cJSON *pJson, SSmaFile *pSmaF) { - int32_t code = 0; - int32_t lino; - - // commit id - const cJSON *pItem; - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "commit id")), code, lino, _exit, - TSDB_CODE_FILE_CORRUPTED); - pSmaF->commitID = (int64_t)pItem->valuedouble; - - // size - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "size")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pSmaF->size = (int64_t)pItem->valuedouble; - -_exit: - return code; -} - -static int32_t tSttFileToJson(const SSttFile *pSttF, cJSON *pJson) { - int32_t code = 0; - int32_t lino; - - if (pJson == NULL) return TSDB_CODE_OUT_OF_MEMORY; - - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "commit id", pSttF->commitID), code, lino, _exit, - TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "size", pSttF->size), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "offset", pSttF->offset), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - -_exit: - return code; -} - -static int32_t tJsonToSttFile(const cJSON *pJson, SSttFile *pSttF) { - int32_t code = 0; - int32_t lino; - - const cJSON *pItem; - - // commit id - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "commit id")), code, lino, _exit, - TSDB_CODE_FILE_CORRUPTED); - pSttF->commitID = (int64_t)pItem->valuedouble; - - // size - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "size")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pSttF->size = (int64_t)pItem->valuedouble; - - // offset - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "offset")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pSttF->offset = (int64_t)pItem->valuedouble; - -_exit: - return code; -} - -int32_t tsdbDFileSetToJson(const SDFileSet *pSet, cJSON *pJson) { - int32_t code = 0; - int32_t lino; - - if (pJson == NULL) return TSDB_CODE_OUT_OF_MEMORY; - - code = tDiskIdToJson(&pSet->diskId, cJSON_AddObjectToObject(pJson, "disk id")); - TSDB_CHECK_CODE(code, lino, _exit); - - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "fid", pSet->fid), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - - // head - code = tHeadFileToJson(pSet->pHeadF, cJSON_AddObjectToObject(pJson, "head")); - TSDB_CHECK_CODE(code, lino, _exit); - - // data - code = tDataFileToJson(pSet->pDataF, cJSON_AddObjectToObject(pJson, "data")); - TSDB_CHECK_CODE(code, lino, _exit); - - // sma - code = tSmaFileToJson(pSet->pSmaF, cJSON_AddObjectToObject(pJson, "sma")); - TSDB_CHECK_CODE(code, lino, _exit); - - // stt array - cJSON *aSttJson = cJSON_AddArrayToObject(pJson, "stt"); - TSDB_CHECK_NULL(aSttJson, code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) { - cJSON *pSttJson = cJSON_CreateObject(); - TSDB_CHECK_NULL(pSttJson, code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - - cJSON_AddItemToArray(aSttJson, pSttJson); - - code = tSttFileToJson(pSet->aSttF[iStt], pSttJson); - TSDB_CHECK_CODE(code, lino, _exit); - } - -_exit: - return code; -} - -int32_t tsdbJsonToDFileSet(const cJSON *pJson, SDFileSet *pSet) { - int32_t code = 0; - int32_t lino; - - const cJSON *pItem; - // disk id - TSDB_CHECK(cJSON_IsObject(pItem = cJSON_GetObjectItem(pJson, "disk id")), code, lino, _exit, - TSDB_CODE_FILE_CORRUPTED); - code = tJsonToDiskId(pItem, &pSet->diskId); - TSDB_CHECK_CODE(code, lino, _exit); - - // fid - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "fid")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pSet->fid = (int32_t)pItem->valuedouble; - - // head - TSDB_CHECK(cJSON_IsObject(pItem = cJSON_GetObjectItem(pJson, "head")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - TSDB_CHECK_NULL(pSet->pHeadF = (SHeadFile *)taosMemoryMalloc(sizeof(SHeadFile)), code, lino, _exit, - TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_CODE(code = tJsonToHeadFile(pItem, pSet->pHeadF), lino, _exit); - pSet->pHeadF->nRef = 1; - - // data - TSDB_CHECK(cJSON_IsObject(pItem = cJSON_GetObjectItem(pJson, "data")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - TSDB_CHECK_NULL(pSet->pDataF = (SDataFile *)taosMemoryMalloc(sizeof(SDataFile)), code, lino, _exit, - TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_CODE(code = tJsonToDataFile(pItem, pSet->pDataF), lino, _exit); - pSet->pDataF->nRef = 1; - - // sma - TSDB_CHECK(cJSON_IsObject(pItem = cJSON_GetObjectItem(pJson, "sma")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - TSDB_CHECK_NULL(pSet->pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile)), code, lino, _exit, - TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_CODE(code = tJsonToSmaFile(pItem, pSet->pSmaF), lino, _exit); - pSet->pSmaF->nRef = 1; - - // stt array - const cJSON *element; - pSet->nSttF = 0; - TSDB_CHECK(cJSON_IsArray(pItem = cJSON_GetObjectItem(pJson, "stt")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - cJSON_ArrayForEach(element, pItem) { - TSDB_CHECK(cJSON_IsObject(element), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - - pSet->aSttF[pSet->nSttF] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile)); - TSDB_CHECK_NULL(pSet->aSttF[pSet->nSttF], code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_CODE(code = tJsonToSttFile(element, pSet->aSttF[pSet->nSttF]), lino, _exit); - pSet->aSttF[pSet->nSttF]->nRef = 1; - pSet->nSttF++; - } - -_exit: - if (code) tsdbError("%s failed at line %d since %s", __func__, lino, tstrerror(code)); - return code; -} - // SDelFile =============================================== void tsdbDelFileName(STsdb *pTsdb, SDelFile *pFile, char fname[]) { snprintf(fname, TSDB_FILENAME_LEN - 1, "%s%s%s%sv%dver%" PRId64 "%s", tfsGetPrimaryPath(pTsdb->pVnode->pTfs), @@ -571,42 +305,3 @@ int32_t tGetDelFile(uint8_t *p, SDelFile *pDelFile) { return n; } - -int32_t tsdbDelFileToJson(const SDelFile *pDelFile, cJSON *pJson) { - if (pJson == NULL) return TSDB_CODE_OUT_OF_MEMORY; - - int32_t code = 0; - int32_t lino; - - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "commit id", pDelFile->commitID), code, lino, _exit, - TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "size", pDelFile->size), code, lino, _exit, TSDB_CODE_OUT_OF_MEMORY); - TSDB_CHECK_NULL(cJSON_AddNumberToObject(pJson, "offset", pDelFile->offset), code, lino, _exit, - TSDB_CODE_OUT_OF_MEMORY); - -_exit: - return code; -} - -int32_t tsdbJsonToDelFile(const cJSON *pJson, SDelFile *pDelFile) { - int32_t code = 0; - int32_t lino; - - const cJSON *pItem; - - // commit id - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "commit id")), code, lino, _exit, - TSDB_CODE_FILE_CORRUPTED); - pDelFile->commitID = cJSON_GetNumberValue(pItem); - - // size - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "size")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pDelFile->size = cJSON_GetNumberValue(pItem); - - // offset - TSDB_CHECK(cJSON_IsNumber(pItem = cJSON_GetObjectItem(pJson, "offset")), code, lino, _exit, TSDB_CODE_FILE_CORRUPTED); - pDelFile->offset = cJSON_GetNumberValue(pItem); - -_exit: - return code; -} \ No newline at end of file From 7c93e32fb5a9f63b175603aa6ea92d697a78fbb2 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Fri, 31 Mar 2023 17:21:41 +0800 Subject: [PATCH 11/14] Update 14-java.mdx --- docs/zh/08-connector/14-java.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/08-connector/14-java.mdx b/docs/zh/08-connector/14-java.mdx index 0a9bd56bfb..d1c1258365 100644 --- a/docs/zh/08-connector/14-java.mdx +++ b/docs/zh/08-connector/14-java.mdx @@ -17,7 +17,7 @@ import TabItem from '@theme/TabItem'; - JDBC 原生连接:Java 应用在物理节点 1(pnode1)上使用 TSDBDriver 直接调用客户端驱动(libtaos.so 或 taos.dll)的 API 将写入和查询请求发送到位于物理节点 2(pnode2)上的 taosd 实例。 - JDBC REST 连接:Java 应用通过 RestfulDriver 将 SQL 封装成一个 REST 请求,发送给物理节点 2 的 REST 服务器(taosAdapter),通过 REST 服务器请求 taosd 并返回结果。 -使用 REST 连接,不依赖 TDengine 客户端驱动,可以跨平台,更加方便灵活,但性能比原生连接器低约 30%。 +使用 REST 连接,不依赖 TDengine 客户端驱动,可以跨平台,更加方便灵活。 :::info TDengine 的 JDBC 驱动实现尽可能与关系型数据库驱动保持一致,但 TDengine 与关系对象型数据库的使用场景和技术特征存在差异,所以`taos-jdbcdriver` 与传统的 JDBC driver 也存在一定差异。在使用时需要注意以下几点: From e8b7c089eef0b215263d293e0c5f2926b694bff2 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Fri, 31 Mar 2023 18:09:50 +0800 Subject: [PATCH 12/14] change test case --- tests/system-test/0-others/telemetry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/0-others/telemetry.py b/tests/system-test/0-others/telemetry.py index bc5d276faa..c62e3c2487 100644 --- a/tests/system-test/0-others/telemetry.py +++ b/tests/system-test/0-others/telemetry.py @@ -181,7 +181,7 @@ class TDTestCase: def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring tdSql.prepare() # time.sleep(2) - vgroups = "30" + vgroups = "8" sql = "create database db3 vgroups " + vgroups tdSql.query(sql) From 41e29f418d0c773865e6103b4fdeab8d373c4fed Mon Sep 17 00:00:00 2001 From: robotspace Date: Sat, 1 Apr 2023 12:19:38 +0800 Subject: [PATCH 13/14] Infactor Lua connection pool implementation. (#20720) * Do not retrieve err msg when connection is established successfully to avoid exception. * Restore check script for lua installation. * Infactor connection pool implementation. --- examples/lua/OpenResty/rest/tdpool/init.lua | 47 ++++++++++++--------- examples/lua/OpenResty/rest/test.lua | 21 ++++++--- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/examples/lua/OpenResty/rest/tdpool/init.lua b/examples/lua/OpenResty/rest/tdpool/init.lua index ebf8e91756..c0c6d56590 100644 --- a/examples/lua/OpenResty/rest/tdpool/init.lua +++ b/examples/lua/OpenResty/rest/tdpool/init.lua @@ -1,16 +1,15 @@ local _M = {} local driver = require "luaconnector51" -local water_mark = 0 -local occupied = 0 -local connection_pool = {} +td_pool_watermark = 0 +td_pool_occupied = 0 +td_connection_pool = {} -function _M.new(o,config) +function _M.new(o, config) o = o or {} - o.connection_pool = connection_pool - o.water_mark = water_mark - o.occupied = occupied - if #connection_pool == 0 then - + o.connection_pool = td_connection_pool + o.watermark = td_pool_watermark + o.occupied = td_pool_occupied + if #td_connection_pool == 0 then for i = 1, config.connection_pool_size do local res = driver.connect(config) if res.code ~= 0 then @@ -18,8 +17,8 @@ function _M.new(o,config) return nil else local object = {obj = res.conn, state = 0} - table.insert(o.connection_pool,i, object) - ngx.log(ngx.INFO, "add connection, now pool size:"..#(o.connection_pool)) + table.insert(td_connection_pool, i, object) + ngx.log(ngx.INFO, "add connection, now pool size:"..#(td_connection_pool)) end end @@ -32,13 +31,13 @@ function _M:get_connection() local connection_obj - for i = 1, #connection_pool do - connection_obj = connection_pool[i] + for i = 1, #td_connection_pool do + connection_obj = td_connection_pool[i] if connection_obj.state == 0 then connection_obj.state = 1 - occupied = occupied +1 - if occupied > water_mark then - water_mark = occupied + td_pool_occupied = td_pool_occupied + 1 + if td_pool_occupied > td_pool_watermark then + td_pool_watermark = td_pool_occupied end return connection_obj["obj"] end @@ -49,21 +48,27 @@ function _M:get_connection() return nil end -function _M:get_water_mark() +function _M:get_watermark() - return water_mark + return td_pool_watermark +end + + +function _M:get_current_load() + + return td_pool_occupied end function _M:release_connection(conn) local connection_obj - for i = 1, #connection_pool do - connection_obj = connection_pool[i] + for i = 1, #td_connection_pool do + connection_obj = td_connection_pool[i] if connection_obj["obj"] == conn then connection_obj["state"] = 0 - occupied = occupied -1 + td_pool_occupied = td_pool_occupied -1 return end end diff --git a/examples/lua/OpenResty/rest/test.lua b/examples/lua/OpenResty/rest/test.lua index 48aeef3fb4..cb4a1479f3 100644 --- a/examples/lua/OpenResty/rest/test.lua +++ b/examples/lua/OpenResty/rest/test.lua @@ -4,8 +4,21 @@ local Pool = require "tdpool" local config = require "config" ngx.say("start time:"..os.time()) -local pool = Pool.new(Pool,config) -local conn = pool:get_connection() +local pool = Pool.new(Pool, config) +local another_pool = Pool.new(Pool, config) +local conn, conn1, conn2 +conn = pool:get_connection() +conn1 = pool:get_connection() +conn2 = pool:get_connection() +local temp_conn = another_pool:get_connection() +ngx.say("pool size:"..config.connection_pool_size) +ngx.say("pool watermark:"..pool:get_watermark()) +ngx.say("pool current load:"..pool:get_current_load()) +pool:release_connection(conn1) +pool:release_connection(conn2) +another_pool:release_connection(temp_conn) +ngx.say("pool watermark:"..pool:get_watermark()) +ngx.say("pool current load:"..pool:get_current_load()) local res = driver.query(conn,"drop database if exists nginx") if res.code ~=0 then @@ -31,7 +44,6 @@ end res = driver.query(conn,"create table m1 (ts timestamp, speed int,owner binary(20))") if res.code ~=0 then ngx.say("create table---failed: "..res.error) - else ngx.say("create table--- pass.") end @@ -83,8 +95,5 @@ while not flag do -- ngx.say("i am here once...") ngx.sleep(0.001) -- time unit is second end - -ngx.say("pool water_mark:"..pool:get_water_mark()) - pool:release_connection(conn) ngx.say("end time:"..os.time()) From ebc997f769a1ef5ad89fbc68285a4da5e7e68df1 Mon Sep 17 00:00:00 2001 From: chenhaoran Date: Mon, 3 Apr 2023 11:01:42 +0800 Subject: [PATCH 14/14] test:decreas vgroups --- tests/system-test/0-others/show.py | 2 +- tests/system-test/0-others/taosdMonitor.py | 2 +- tests/system-test/0-others/telemetry.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/system-test/0-others/show.py b/tests/system-test/0-others/show.py index 3e176fe251..b284605a0e 100644 --- a/tests/system-test/0-others/show.py +++ b/tests/system-test/0-others/show.py @@ -28,7 +28,7 @@ class TDTestCase: self.perf_param = ['apps','connections','consumers','queries','transactions'] self.perf_param_list = ['apps','connections','consumers','queries','trans'] self.dbname = "db" - self.vgroups = 10 + self.vgroups = 4 self.stbname = f'`{tdCom.getLongName(5)}`' self.tbname = f'`{tdCom.getLongName(3)}`' self.db_param = { diff --git a/tests/system-test/0-others/taosdMonitor.py b/tests/system-test/0-others/taosdMonitor.py index 944ff52d5b..8094c4e0f5 100644 --- a/tests/system-test/0-others/taosdMonitor.py +++ b/tests/system-test/0-others/taosdMonitor.py @@ -292,7 +292,7 @@ class TDTestCase: def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring tdSql.prepare() # time.sleep(2) - vgroups = "30" + vgroups = "4" sql = "create database db3 vgroups " + vgroups tdSql.query(sql) sql = "create table db3.stb (ts timestamp, f int) tags (t int)" diff --git a/tests/system-test/0-others/telemetry.py b/tests/system-test/0-others/telemetry.py index c62e3c2487..3b6cb10509 100644 --- a/tests/system-test/0-others/telemetry.py +++ b/tests/system-test/0-others/telemetry.py @@ -181,7 +181,7 @@ class TDTestCase: def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring tdSql.prepare() # time.sleep(2) - vgroups = "8" + vgroups = "4" sql = "create database db3 vgroups " + vgroups tdSql.query(sql)
小 T 的二维码小 T 的二维码 TDengine 微信视频号 TDengine 微信公众号