From 7e06a70e01f34822cf36a2b4b4c7f3b3197ffaa7 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Thu, 2 Jun 2022 22:22:22 +0800 Subject: [PATCH 001/380] test: add test case for TS-1577 --- tests/pytest/query/queryError.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/pytest/query/queryError.py b/tests/pytest/query/queryError.py index e5c468600b..7d752a9863 100644 --- a/tests/pytest/query/queryError.py +++ b/tests/pytest/query/queryError.py @@ -68,6 +68,16 @@ class TDTestCase: # TD-6006 tdSql.error("select * from dev_001 where 'name' is not null") tdSql.error("select * from dev_001 where \"name\" = 'first'") + + # TS-1577 + tdSql.query("show databases") + rows = tdSql.queryRows + + for i in range(1000): + tdSql.execute("create database test%d" % i) + + tdSql.query("show databases") + tdSql.checkRows(rows + 1000) def stop(self): tdSql.close() -- GitLab From 592588bb371322199bbbba85d6b4ea98786079b5 Mon Sep 17 00:00:00 2001 From: zyyang Date: Tue, 7 Jun 2022 13:46:46 +0800 Subject: [PATCH 002/380] other: release script modify --- packaging/deb/taosd | 16 -- packaging/release.bat | 41 +++- packaging/release.sh | 7 +- packaging/tools/install_arbi.sh | 23 ++- packaging/tools/install_client.sh | 316 +++++++++++++++--------------- packaging/tools/make_install.sh | 111 ++++++----- packaging/tools/makearbi.sh | 2 - packaging/tools/makeclient.sh | 32 +-- packaging/tools/remove.sh | 50 ++--- packaging/tools/remove_client.sh | 43 ++-- 10 files changed, 321 insertions(+), 320 deletions(-) diff --git a/packaging/deb/taosd b/packaging/deb/taosd index fe356ca656..8f8ab2f1ea 100644 --- a/packaging/deb/taosd +++ b/packaging/deb/taosd @@ -1,20 +1,4 @@ #!/bin/bash -# -# Modified from original source: Elastic Search -# https://github.com/elasticsearch/elasticsearch -# Thank you to the Elastic Search authors -# -# chkconfig: 2345 99 01 -# -### BEGIN INIT INFO -# Provides: TDengine -# Required-Start: $local_fs $network $syslog -# Required-Stop: $local_fs $network $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Starts TDengine taosd -# Description: Starts TDengine taosd, a time-series database engine -### END INIT INFO set -e diff --git a/packaging/release.bat b/packaging/release.bat index c1cf7875a5..6a25026f62 100644 --- a/packaging/release.bat +++ b/packaging/release.bat @@ -6,9 +6,10 @@ cd %community_dir% git checkout -- . cd %community_dir%\packaging -:: %1 name %2 version +:: %1 name %2 version %3 cpuType if !%1==! GOTO USAGE if !%2==! GOTO USAGE +if !%3==! GOTO USAGE if %1 == taos GOTO TAOS if %1 == power GOTO POWER if %1 == tq GOTO TQ @@ -21,42 +22,66 @@ GOTO USAGE goto RELEASE :POWER +cd %internal_dir%\enterprise\packaging\oem call sed_power.bat %community_dir% +cd %community_dir%\packaging goto RELEASE :TQ +cd %internal_dir%\enterprise\packaging\oem call sed_tq.bat %community_dir% +cd %community_dir%\packaging goto RELEASE :PRO +cd %internal_dir%\enterprise\packaging\oem call sed_pro.bat %community_dir% +cd %community_dir%\packaging goto RELEASE :KH +cd %internal_dir%\enterprise\packaging\oem call sed_kh.bat %community_dir% +cd %community_dir%\packaging goto RELEASE :JH +cd %internal_dir%\enterprise\packaging\oem call sed_jh.bat %community_dir% +cd %community_dir%\packaging goto RELEASE :RELEASE -echo release windows-client-64 for %1, version: %2 -if not exist %internal_dir%\debug\ver-%2-64bit-%1 ( - md %internal_dir%\debug\ver-%2-64bit-%1 +echo release windows-client for %1, version: %2, cpyType: %3 +if not exist %internal_dir%\debug\ver-%2-%1-%3 ( + md %internal_dir%\debug\ver-%2-%1-%3 ) else ( - rd /S /Q %internal_dir%\debug\ver-%2-64bit-%1 - md %internal_dir%\debug\ver-%2-64bit-%1 + rd /S /Q %internal_dir%\debug\ver-%2-%1-%3 + md %internal_dir%\debug\ver-%2-%1-%3 ) -cd %internal_dir%\debug\ver-%2-64bit-%1 +cd %internal_dir%\debug\ver-%2-%1-%3 + +if %3% == x64 GOTO X64 +if %3% == x86 GOTO X86 +GOTO USAGE + +:X86 +call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 +cmake ../../ -G "NMake Makefiles" -DVERNUMBER=%2 -DCPUTYPE=x86 +GOTO MAKE_AND_INSTALL + +:X64 call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64 cmake ../../ -G "NMake Makefiles" -DVERNUMBER=%2 -DCPUTYPE=x64 +GOTO MAKE_AND_INSTALL + +:MAKE_AND_INSTALL set CL=/MP4 nmake install goto EXIT0 :USAGE -echo Usage: release.bat $productName $version +echo Usage: release.bat $productName $version $cpuType goto EXIT0 :EXIT0 \ No newline at end of file diff --git a/packaging/release.sh b/packaging/release.sh index a96b312999..354d713e28 100755 --- a/packaging/release.sh +++ b/packaging/release.sh @@ -101,13 +101,13 @@ echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} curr_dir=$(pwd) if [ "$osType" == "Darwin" ]; then + script_dir="$(dirname $(readlink -f $0))" + top_dir="$(readlink -f ${script_dir}/..)" +else script_dir=$(dirname $0) cd ${script_dir} script_dir="$(pwd)" top_dir=${script_dir}/.. -else - script_dir="$(dirname $(readlink -f $0))" - top_dir="$(readlink -f ${script_dir}/..)" fi csudo="" @@ -198,6 +198,7 @@ else allocator_macro="" fi +# 3. replace product info if [[ "$dbName" != "taos" ]]; then source ${enterprise_dir}/packaging/oem/sed_$dbName.sh replace_community_$dbName diff --git a/packaging/tools/install_arbi.sh b/packaging/tools/install_arbi.sh index e3c63965d4..6e9be8489b 100755 --- a/packaging/tools/install_arbi.sh +++ b/packaging/tools/install_arbi.sh @@ -7,6 +7,9 @@ set -e #set -x # -----------------------Variables definition--------------------- +productName="TDengine" +emailName="taosdata.com" + script_dir=$(dirname $(readlink -f "$0")) bin_link_dir="/usr/bin" @@ -83,7 +86,7 @@ else echo " osinfo: ${osinfo}" echo " This is an officially unverified linux system," echo " if there are any problems with the installation and operation, " - echo " please feel free to contact taosdata.com for support." + echo " please feel free to contact ${emailName} for support." os_type=1 fi @@ -241,7 +244,7 @@ function install_service_on_systemd() { tarbitratord_service_config="${service_config_dir}/tarbitratord.service" ${csudo}bash -c "echo '[Unit]' >> ${tarbitratord_service_config}" - ${csudo}bash -c "echo 'Description=TDengine arbitrator service' >> ${tarbitratord_service_config}" + ${csudo}bash -c "echo 'Description=${productName} arbitrator service' >> ${tarbitratord_service_config}" ${csudo}bash -c "echo 'After=network-online.target' >> ${tarbitratord_service_config}" ${csudo}bash -c "echo 'Wants=network-online.target' >> ${tarbitratord_service_config}" ${csudo}bash -c "echo >> ${tarbitratord_service_config}" @@ -273,9 +276,9 @@ function install_service() { fi } -function update_TDengine() { +function update_Product() { # Start to update - echo -e "${GREEN}Start to update TDengine's arbitrator ...${NC}" + echo -e "${GREEN}Start to update ${productName}'s arbitrator ...${NC}" # Stop the service if running if pidof tarbitrator &>/dev/null; then if ((${service_mod} == 0)); then @@ -303,12 +306,12 @@ function update_TDengine() { echo -e "${GREEN_DARK}To start arbitrator ${NC}: ./tarbitrator${NC}" fi echo - echo -e "\033[44;32;1mTDengine's arbitrator is updated successfully!${NC}" + echo -e "\033[44;32;1m${productName}'s arbitrator is updated successfully!${NC}" } -function install_TDengine() { +function install_Product() { # Start to install - echo -e "${GREEN}Start to install TDengine's arbitrator ...${NC}" + echo -e "${GREEN}Start to install ${productName}'s arbitrator ...${NC}" install_main_path #install_header @@ -325,7 +328,7 @@ function install_TDengine() { echo -e "${GREEN_DARK}To start arbitrator ${NC}: tarbitrator${NC}" fi - echo -e "\033[44;32;1mTDengine's arbitrator is installed successfully!${NC}" + echo -e "\033[44;32;1m${productName}'s arbitrator is installed successfully!${NC}" echo } @@ -333,7 +336,7 @@ function install_TDengine() { # Install server and client if [ -x ${bin_dir}/tarbitrator ]; then update_flag=1 - update_TDengine + update_Product else - install_TDengine + install_Product fi diff --git a/packaging/tools/install_client.sh b/packaging/tools/install_client.sh index 28001fb769..844ac16a26 100755 --- a/packaging/tools/install_client.sh +++ b/packaging/tools/install_client.sh @@ -18,22 +18,23 @@ clientName="taos" uninstallScript="rmtaos" configFile="taos.cfg" tarName="taos.tar.gz" +demoName="taosdemo" osType=Linux pagMode=full verMode=edge if [ "$osType" != "Darwin" ]; then - script_dir=$(dirname $(readlink -f "$0")) - # Dynamic directory - data_dir=${dataDir} - log_dir=${logDir} + script_dir=$(dirname $(readlink -f "$0")) + # Dynamic directory + data_dir=${dataDir} + log_dir=${logDir} else - script_dir=`dirname $0` - cd ${script_dir} - script_dir="$(pwd)" - data_dir=${dataDir} - log_dir=~/${productName}/log + script_dir=$(dirname $0) + cd ${script_dir} + script_dir="$(pwd)" + data_dir=${dataDir} + log_dir=~/${productName}/log fi log_link_dir="${installDir}/log" @@ -41,14 +42,14 @@ log_link_dir="${installDir}/log" cfg_install_dir=${configDir} if [ "$osType" != "Darwin" ]; then - bin_link_dir="/usr/bin" - lib_link_dir="/usr/lib" - lib64_link_dir="/usr/lib64" - inc_link_dir="/usr/include" + bin_link_dir="/usr/bin" + lib_link_dir="/usr/lib" + lib64_link_dir="/usr/lib64" + inc_link_dir="/usr/include" else - bin_link_dir="/usr/local/bin" - lib_link_dir="/usr/local/lib" - inc_link_dir="/usr/local/include" + bin_link_dir="/usr/local/bin" + lib_link_dir="/usr/local/lib" + inc_link_dir="/usr/local/include" fi #install main path @@ -65,8 +66,8 @@ GREEN_UNDERLINE='\033[4;32m' NC='\033[0m' csudo="" -if command -v sudo > /dev/null; then - csudo="sudo " +if command -v sudo >/dev/null; then + csudo="sudo " fi update_flag=0 @@ -74,7 +75,7 @@ update_flag=0 function kill_client() { pid=$(ps -ef | grep "${clientName}" | grep -v "grep" | awk '{print $2}') if [ -n "$pid" ]; then - ${csudo}kill -9 $pid || : + ${csudo}kill -9 $pid || : fi } @@ -96,186 +97,184 @@ function install_main_path() { function install_bin() { # Remove links - ${csudo}rm -f ${bin_link_dir}/${clientName} || : + ${csudo}rm -f ${bin_link_dir}/${clientName} || : if [ "$osType" != "Darwin" ]; then - ${csudo}rm -f ${bin_link_dir}/taosdemo || : + ${csudo}rm -f ${bin_link_dir}/${demoName} || : fi - ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : - ${csudo}rm -f ${bin_link_dir}/set_core || : + ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : + ${csudo}rm -f ${bin_link_dir}/set_core || : ${csudo}cp -r ${script_dir}/bin/* ${install_main_dir}/bin && ${csudo}chmod 0555 ${install_main_dir}/bin/* #Make link - [ -x ${install_main_dir}/bin/${clientName} ] && ${csudo}ln -s ${install_main_dir}/bin/${clientName} ${bin_link_dir}/${clientName} || : + [ -x ${install_main_dir}/bin/${clientName} ] && ${csudo}ln -s ${install_main_dir}/bin/${clientName} ${bin_link_dir}/${clientName} || : if [ "$osType" != "Darwin" ]; then - [ -x ${install_main_dir}/bin/taosdemo ] && ${csudo}ln -s ${install_main_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || : + [ -x ${install_main_dir}/bin/${demoName} ] && ${csudo}ln -s ${install_main_dir}/bin/${demoName} ${bin_link_dir}/${demoName} || : fi [ -x ${install_main_dir}/bin/remove_client.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/${uninstallScript} || : [ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || : } function clean_lib() { - sudo rm -f /usr/lib/libtaos.* || : - sudo rm -rf ${lib_dir} || : + sudo rm -f /usr/lib/libtaos.* || : + sudo rm -rf ${lib_dir} || : } function install_lib() { - # Remove links - ${csudo}rm -f ${lib_link_dir}/libtaos.* || : - ${csudo}rm -f ${lib64_link_dir}/libtaos.* || : - #${csudo}rm -rf ${v15_java_app_dir} || : + # Remove links + ${csudo}rm -f ${lib_link_dir}/libtaos.* || : + ${csudo}rm -f ${lib64_link_dir}/libtaos.* || : - ${csudo}cp -rf ${script_dir}/driver/* ${install_main_dir}/driver && ${csudo}chmod 777 ${install_main_dir}/driver/* + ${csudo}cp -rf ${script_dir}/driver/* ${install_main_dir}/driver && ${csudo}chmod 777 ${install_main_dir}/driver/* - if [ "$osType" != "Darwin" ]; then - ${csudo}ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.so.1 - ${csudo}ln -s ${lib_link_dir}/libtaos.so.1 ${lib_link_dir}/libtaos.so + if [ "$osType" != "Darwin" ]; then + ${csudo}ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.so.1 + ${csudo}ln -s ${lib_link_dir}/libtaos.so.1 ${lib_link_dir}/libtaos.so - if [ -d "${lib64_link_dir}" ]; then - ${csudo}ln -s ${install_main_dir}/driver/libtaos.* ${lib64_link_dir}/libtaos.so.1 || : - ${csudo}ln -s ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so || : - fi - else - ${csudo}ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.1.dylib - ${csudo}ln -s ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib + if [ -d "${lib64_link_dir}" ]; then + ${csudo}ln -s ${install_main_dir}/driver/libtaos.* ${lib64_link_dir}/libtaos.so.1 || : + ${csudo}ln -s ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so || : fi + else + ${csudo}ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.1.dylib + ${csudo}ln -s ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib + fi - if [ "$osType" != "Darwin" ]; then - ${csudo}ldconfig - else - ${csudo}update_dyld_shared_cache - fi + if [ "$osType" != "Darwin" ]; then + ${csudo}ldconfig + else + ${csudo}update_dyld_shared_cache + fi } function install_header() { - ${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h || : - ${csudo}cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/* - ${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h - ${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h - ${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h + ${csudo}rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taosdef.h ${inc_link_dir}/taoserror.h || : + ${csudo}cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo}chmod 644 ${install_main_dir}/include/* + ${csudo}ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h + ${csudo}ln -s ${install_main_dir}/include/taosdef.h ${inc_link_dir}/taosdef.h + ${csudo}ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h } function install_jemalloc() { - jemalloc_dir=${script_dir}/jemalloc - - if [ -d ${jemalloc_dir} ]; then - ${csudo}/usr/bin/install -c -d /usr/local/bin - - if [ -f ${jemalloc_dir}/bin/jemalloc-config ]; then - ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc-config /usr/local/bin - fi - if [ -f ${jemalloc_dir}/bin/jemalloc.sh ]; then - ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc.sh /usr/local/bin - fi - if [ -f ${jemalloc_dir}/bin/jeprof ]; then - ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jeprof /usr/local/bin - fi - if [ -f ${jemalloc_dir}/include/jemalloc/jemalloc.h ]; then - ${csudo}/usr/bin/install -c -d /usr/local/include/jemalloc - ${csudo}/usr/bin/install -c -m 644 ${jemalloc_dir}/include/jemalloc/jemalloc.h /usr/local/include/jemalloc - fi - if [ -f ${jemalloc_dir}/lib/libjemalloc.so.2 ]; then - ${csudo}/usr/bin/install -c -d /usr/local/lib - ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.so.2 /usr/local/lib - ${csudo}ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so - ${csudo}/usr/bin/install -c -d /usr/local/lib - if [ -f ${jemalloc_dir}/lib/libjemalloc.a ]; then - ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.a /usr/local/lib - fi - if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then - ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc_pic.a /usr/local/lib - fi - if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then - ${csudo}/usr/bin/install -c -d /usr/local/lib/pkgconfig - ${csudo}/usr/bin/install -c -m 644 ${jemalloc_dir}/lib/pkgconfig/jemalloc.pc /usr/local/lib/pkgconfig - fi - fi - if [ -f ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html ]; then - ${csudo}/usr/bin/install -c -d /usr/local/share/doc/jemalloc - ${csudo}/usr/bin/install -c -m 644 ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html /usr/local/share/doc/jemalloc - fi - if [ -f ${jemalloc_dir}/share/man/man3/jemalloc.3 ]; then - ${csudo}/usr/bin/install -c -d /usr/local/share/man/man3 - ${csudo}/usr/bin/install -c -m 644 ${jemalloc_dir}/share/man/man3/jemalloc.3 /usr/local/share/man/man3 - fi - - if [ -d /etc/ld.so.conf.d ]; then - echo "/usr/local/lib" | ${csudo}tee /etc/ld.so.conf.d/jemalloc.conf > /dev/null || echo -e "failed to write /etc/ld.so.conf.d/jemalloc.conf" - ${csudo}ldconfig - else - echo "/etc/ld.so.conf.d not found!" - fi + jemalloc_dir=${script_dir}/jemalloc + + if [ -d ${jemalloc_dir} ]; then + ${csudo}/usr/bin/install -c -d /usr/local/bin + + if [ -f ${jemalloc_dir}/bin/jemalloc-config ]; then + ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc-config /usr/local/bin + fi + if [ -f ${jemalloc_dir}/bin/jemalloc.sh ]; then + ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc.sh /usr/local/bin + fi + if [ -f ${jemalloc_dir}/bin/jeprof ]; then + ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jeprof /usr/local/bin + fi + if [ -f ${jemalloc_dir}/include/jemalloc/jemalloc.h ]; then + ${csudo}/usr/bin/install -c -d /usr/local/include/jemalloc + ${csudo}/usr/bin/install -c -m 644 ${jemalloc_dir}/include/jemalloc/jemalloc.h /usr/local/include/jemalloc + fi + if [ -f ${jemalloc_dir}/lib/libjemalloc.so.2 ]; then + ${csudo}/usr/bin/install -c -d /usr/local/lib + ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.so.2 /usr/local/lib + ${csudo}ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so + ${csudo}/usr/bin/install -c -d /usr/local/lib + if [ -f ${jemalloc_dir}/lib/libjemalloc.a ]; then + ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.a /usr/local/lib + fi + if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then + ${csudo}/usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc_pic.a /usr/local/lib + fi + if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then + ${csudo}/usr/bin/install -c -d /usr/local/lib/pkgconfig + ${csudo}/usr/bin/install -c -m 644 ${jemalloc_dir}/lib/pkgconfig/jemalloc.pc /usr/local/lib/pkgconfig + fi fi + if [ -f ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html ]; then + ${csudo}/usr/bin/install -c -d /usr/local/share/doc/jemalloc + ${csudo}/usr/bin/install -c -m 644 ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html /usr/local/share/doc/jemalloc + fi + if [ -f ${jemalloc_dir}/share/man/man3/jemalloc.3 ]; then + ${csudo}/usr/bin/install -c -d /usr/local/share/man/man3 + ${csudo}/usr/bin/install -c -m 644 ${jemalloc_dir}/share/man/man3/jemalloc.3 /usr/local/share/man/man3 + fi + + if [ -d /etc/ld.so.conf.d ]; then + echo "/usr/local/lib" | ${csudo}tee /etc/ld.so.conf.d/jemalloc.conf >/dev/null || echo -e "failed to write /etc/ld.so.conf.d/jemalloc.conf" + ${csudo}ldconfig + else + echo "/etc/ld.so.conf.d not found!" + fi + fi } function install_config() { - if [ ! -f ${cfg_install_dir}/${configFile} ]; then - ${csudo}mkdir -p ${cfg_install_dir} - [ -f ${script_dir}/cfg/${configFile} ] && ${csudo}cp ${script_dir}/cfg/${configFile} ${cfg_install_dir} - ${csudo}chmod 644 ${cfg_install_dir}/* - fi + if [ ! -f ${cfg_install_dir}/${configFile} ]; then + ${csudo}mkdir -p ${cfg_install_dir} + [ -f ${script_dir}/cfg/${configFile} ] && ${csudo}cp ${script_dir}/cfg/${configFile} ${cfg_install_dir} + ${csudo}chmod 644 ${cfg_install_dir}/* + fi - ${csudo}cp -f ${script_dir}/cfg/${configFile} ${install_main_dir}/cfg/${configFile}.org - ${csudo}ln -s ${cfg_install_dir}/${configFile} ${install_main_dir}/cfg + ${csudo}cp -f ${script_dir}/cfg/${configFile} ${install_main_dir}/cfg/${configFile}.org + ${csudo}ln -s ${cfg_install_dir}/${configFile} ${install_main_dir}/cfg } - function install_log() { - ${csudo}rm -rf ${log_dir} || : + ${csudo}rm -rf ${log_dir} || : - if [ "$osType" != "Darwin" ]; then - ${csudo}mkdir -p ${log_dir} && ${csudo}chmod 777 ${log_dir} - else - mkdir -p ${log_dir} && ${csudo}chmod 777 ${log_dir} - fi - ${csudo}ln -s ${log_dir} ${install_main_dir}/log + if [ "$osType" != "Darwin" ]; then + ${csudo}mkdir -p ${log_dir} && ${csudo}chmod 777 ${log_dir} + else + mkdir -p ${log_dir} && ${csudo}chmod 777 ${log_dir} + fi + ${csudo}ln -s ${log_dir} ${install_main_dir}/log } function install_connector() { - ${csudo}cp -rf ${script_dir}/connector/ ${install_main_dir}/ + ${csudo}cp -rf ${script_dir}/connector/ ${install_main_dir}/ } function install_examples() { - if [ -d ${script_dir}/examples ]; then - ${csudo}cp -rf ${script_dir}/examples/* ${install_main_dir}/examples - fi + if [ -d ${script_dir}/examples ]; then + ${csudo}cp -rf ${script_dir}/examples/* ${install_main_dir}/examples + fi } -function update_TDengine() { - # Start to update - if [ ! -e ${tarName} ]; then - echo "File ${tarName} does not exist" - exit 1 - fi - tar -zxf ${tarName} +function update_Product() { + # Start to update + if [ ! -e ${tarName} ]; then + echo "File ${tarName} does not exist" + exit 1 + fi + tar -zxf ${tarName} - echo -e "${GREEN}Start to update ${productName} client...${NC}" - # Stop the client shell if running - if pidof ${clientName} &> /dev/null; then - kill_client - sleep 1 - fi + echo -e "${GREEN}Start to update ${productName} client...${NC}" + # Stop the client shell if running + if pidof ${clientName} &>/dev/null; then + kill_client + sleep 1 + fi - install_main_path + install_main_path - install_log - install_header - install_lib - install_jemalloc - if [ "$verMode" == "cluster" ]; then - install_connector - fi - install_examples - install_bin - install_config + install_log + install_header + install_lib + install_jemalloc + if [ "$verMode" == "cluster" ]; then + install_connector + fi + install_examples + install_bin + install_config - echo - echo -e "\033[44;32;1m${productName} client is updated successfully!${NC}" + echo + echo -e "\033[44;32;1m${productName} client is updated successfully!${NC}" - rm -rf $(tar -tf ${tarName}) + rm -rf $(tar -tf ${tarName}) } -function install_TDengine() { +function install_Product() { # Start to install if [ ! -e ${tarName} ]; then echo "File ${tarName} does not exist" @@ -303,18 +302,17 @@ function install_TDengine() { rm -rf $(tar -tf ${tarName}) } - ## ==============================Main program starts from here============================ # Install or updata client and client # if server is already install, don't install client - if [ -e ${bin_dir}/${serverName} ]; then - echo -e "\033[44;32;1mThere are already installed ${productName} server, so don't need install client!${NC}" - exit 0 - fi +if [ -e ${bin_dir}/${serverName} ]; then + echo -e "\033[44;32;1mThere are already installed ${productName} server, so don't need install client!${NC}" + exit 0 +fi - if [ -x ${bin_dir}/${clientName} ]; then - update_flag=1 - update_TDengine - else - install_TDengine - fi +if [ -x ${bin_dir}/${clientName} ]; then + update_flag=1 + update_Product +else + install_Product +fi diff --git a/packaging/tools/make_install.sh b/packaging/tools/make_install.sh index dc5d9f1bc6..bcb3664c29 100755 --- a/packaging/tools/make_install.sh +++ b/packaging/tools/make_install.sh @@ -29,7 +29,11 @@ installDir="/usr/local/taos" productName="TDengine" emailName="taosdata.com" uninstallScript="rmtaos" +adapterName="taosadapter" +demoName="taosdemo" +benchmarkName="taosBenchmark" +# Dynamic directory if [ "$osType" != "Darwin" ]; then data_dir=${dataDir} log_dir=${logDir} @@ -125,14 +129,14 @@ if [ "$osType" != "Darwin" ]; then fi fi -function kill_taosadapter() { - pid=$(ps -ef | grep "taosadapter" | grep -v "grep" | awk '{print $2}') +function kill_adapter() { + pid=$(ps -ef | grep "${adapterName}" | grep -v "grep" | awk '{print $2}') if [ -n "$pid" ]; then ${csudo}kill -9 $pid || : fi } -function kill_taosd() { +function kill_server() { ps -ef | grep ${serverName} pid=$(ps -ef | grep -w ${serverName} | grep -v "grep" | awk '{print $2}') if [ -n "$pid" ]; then @@ -168,40 +172,39 @@ function install_bin() { # Remove links ${csudo}rm -f ${bin_link_dir}/${clientName} || : ${csudo}rm -f ${bin_link_dir}/${serverName} || : - ${csudo}rm -f ${bin_link_dir}/taosadapter || : - ${csudo}rm -f ${bin_link_dir}/taosdemo || : - ${csudo}rm -f ${bin_link_dir}/taosdump || : + ${csudo}rm -f ${bin_link_dir}/${adapterName} || : + ${csudo}rm -f ${bin_link_dir}/${demoName} || : if [ "$osType" != "Darwin" ]; then ${csudo}rm -f ${bin_link_dir}/perfMonitor || : ${csudo}rm -f ${bin_link_dir}/set_core || : - ${csudo}rm -f ${bin_link_dir}/run_taosd_and_taosadapter.sh || : + ${csudo}rm -f ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : ${csudo}cp -r ${binary_dir}/build/bin/${clientName} ${install_main_dir}/bin || : - [ -f ${binary_dir}/build/bin/taosBenchmark ] && ${csudo}cp -r ${binary_dir}/build/bin/taosBenchmark ${install_main_dir}/bin || : - [ -f ${install_main_dir}/bin/taosBenchmark ] && ${csudo}ln -sf ${install_main_dir}/bin/taosBenchmark ${install_main_dir}/bin/taosdemo || : - [ -f ${binary_dir}/build/bin/taosdump ] && ${csudo}cp -r ${binary_dir}/build/bin/taosdump ${install_main_dir}/bin || : - [ -f ${binary_dir}/build/bin/taosadapter ] && ${csudo}cp -r ${binary_dir}/build/bin/taosadapter ${install_main_dir}/bin || : + [ -f ${binary_dir}/build/bin/${benchmarkName} ] && ${csudo}cp -r ${binary_dir}/build/bin/${benchmarkName} ${install_main_dir}/bin || : + [ -f ${install_main_dir}/bin/${benchmarkName} ] && ${csudo}ln -sf ${install_main_dir}/bin/${benchmarkName} ${install_main_dir}/bin/${demoName} || : + # [ -f ${binary_dir}/build/bin/taosdump ] && ${csudo}cp -r ${binary_dir}/build/bin/taosdump ${install_main_dir}/bin || : + [ -f ${binary_dir}/build/bin/${adapterName} ] && ${csudo}cp -r ${binary_dir}/build/bin/${adapterName} ${install_main_dir}/bin || : ${csudo}cp -r ${binary_dir}/build/bin/${serverName} ${install_main_dir}/bin || : ${csudo}cp -r ${binary_dir}/build/bin/tarbitrator ${install_main_dir}/bin || : ${csudo}cp -r ${script_dir}/taosd-dump-cfg.gdb ${install_main_dir}/bin ${csudo}cp -r ${script_dir}/remove.sh ${install_main_dir}/bin ${csudo}cp -r ${script_dir}/set_core.sh ${install_main_dir}/bin - ${csudo}cp -r ${script_dir}/run_taosd_and_taosadapter.sh ${install_main_dir}/bin + ${csudo}cp -r ${script_dir}/run_${serverName}_and_${adapterName}.sh ${install_main_dir}/bin ${csudo}cp -r ${script_dir}/startPre.sh ${install_main_dir}/bin ${csudo}chmod 0555 ${install_main_dir}/bin/* #Make link [ -x ${install_main_dir}/bin/${clientName} ] && ${csudo}ln -s ${install_main_dir}/bin/${clientName} ${bin_link_dir}/${clientName} || : [ -x ${install_main_dir}/bin/${serverName} ] && ${csudo}ln -s ${install_main_dir}/bin/${serverName} ${bin_link_dir}/${serverName} || : - [ -x ${install_main_dir}/bin/taosadapter ] && ${csudo}ln -s ${install_main_dir}/bin/taosadapter ${bin_link_dir}/taosadapter || : - [ -x ${install_main_dir}/bin/taosdump ] && ${csudo}ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || : - [ -x ${install_main_dir}/bin/taosdemo ] && ${csudo}ln -s ${install_main_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || : + [ -x ${install_main_dir}/bin/${adapterName} ] && ${csudo}ln -s ${install_main_dir}/bin/${adapterName} ${bin_link_dir}/${adapterName} || : + # [ -x ${install_main_dir}/bin/taosdump ] && ${csudo}ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || : + [ -x ${install_main_dir}/bin/${demoName} ] && ${csudo}ln -s ${install_main_dir}/bin/${demoName} ${bin_link_dir}/${demoName} || : [ -x ${install_main_dir}/bin/perfMonitor ] && ${csudo}ln -s ${install_main_dir}/bin/perfMonitor ${bin_link_dir}/perfMonitor || : [ -x ${install_main_dir}/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || : - [ -x ${install_main_dir}/run_taosd_and_taosadapter.sh ] && ${csudo}ln -s ${install_main_dir}/bin/run_taosd_and_taosadapter.sh ${bin_link_dir}/run_taosd_and_taosadapter.sh || : + [ -x ${install_main_dir}/run_${serverName}_and_${adapterName}.sh ] && ${csudo}ln -s ${install_main_dir}/bin/run_${serverName}_and_${adapterName}.sh ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : [ -x ${install_main_dir}/bin/remove.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/${uninstallScript} || : else @@ -212,9 +215,9 @@ function install_bin() { #Make link [ -x ${install_main_dir}/bin/${clientName} ] || [ -x ${install_main_2_dir}/bin/${clientName} ] && ${csudo}ln -s ${install_main_dir}/bin/${clientName} ${bin_link_dir}/${clientName} || ${csudo}ln -s ${install_main_2_dir}/bin/${clientName} || : [ -x ${install_main_dir}/bin/${serverName} ] || [ -x ${install_main_2_dir}/bin/${serverName} ] && ${csudo}ln -s ${install_main_dir}/bin/${serverName} ${bin_link_dir}/${serverName} || ${csudo}ln -s ${install_main_2_dir}/bin/${serverName} || : - [ -x ${install_main_dir}/bin/taosadapter ] || [ -x ${install_main_2_dir}/bin/taosadapter ] && ${csudo}ln -s ${install_main_dir}/bin/taosadapter ${bin_link_dir}/taosadapter || ${csudo}ln -s ${install_main_2_dir}/bin/taosadapter || : - [ -x ${install_main_dir}/bin/taosdump ] || [ -x ${install_main_2_dir}/bin/taosdump ] && ${csudo}ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || ln -s ${install_main_2_dir}/bin/taosdump ${bin_link_dir}/taosdump || : - [ -x ${install_main_dir}/bin/taosdemo ] || [ -x ${install_main_2_dir}/bin/taosdemo ] && ${csudo}ln -s ${install_main_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || ln -s ${install_main_2_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || : + [ -x ${install_main_dir}/bin/${adapterName} ] || [ -x ${install_main_2_dir}/bin/${adapterName} ] && ${csudo}ln -s ${install_main_dir}/bin/${adapterName} ${bin_link_dir}/${adapterName} || ${csudo}ln -s ${install_main_2_dir}/bin/${adapterName} || : + # [ -x ${install_main_dir}/bin/taosdump ] || [ -x ${install_main_2_dir}/bin/taosdump ] && ${csudo}ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || ln -s ${install_main_2_dir}/bin/taosdump ${bin_link_dir}/taosdump || : + [ -x ${install_main_dir}/bin/${demoName} ] || [ -x ${install_main_2_dir}/bin/${demoName} ] && ${csudo}ln -s ${install_main_dir}/bin/${demoName} ${bin_link_dir}/${demoName} || ln -s ${install_main_2_dir}/bin/${demoName} ${bin_link_dir}/${demoName} || : fi } @@ -380,23 +383,23 @@ function install_config() { fi } -function install_taosadapter_config() { - if [ ! -f "${cfg_install_dir}/taosadapter.toml" ]; then +function install_adapter_config() { + if [ ! -f "${cfg_install_dir}/${adapterName}.toml" ]; then ${csudo}mkdir -p ${cfg_install_dir} - [ -f ${binary_dir}/test/cfg/taosadapter.toml ] && - ${csudo}cp ${binary_dir}/test/cfg/taosadapter.toml ${cfg_install_dir} - [ -f ${cfg_install_dir}/taosadapter.toml ] && - ${csudo}chmod 644 ${cfg_install_dir}/taosadapter.toml - [ -f ${binary_dir}/test/cfg/taosadapter.toml ] && - ${csudo}cp -f ${binary_dir}/test/cfg/taosadapter.toml \ - ${cfg_install_dir}/taosadapter.toml.${verNumber} - [ -f ${cfg_install_dir}/taosadapter.toml ] && - ${csudo}ln -s ${cfg_install_dir}/taosadapter.toml \ - ${install_main_dir}/cfg/taosadapter.toml + [ -f ${binary_dir}/test/cfg/${adapterName}.toml ] && + ${csudo}cp ${binary_dir}/test/cfg/${adapterName}.toml ${cfg_install_dir} + [ -f ${cfg_install_dir}/${adapterName}.toml ] && + ${csudo}chmod 644 ${cfg_install_dir}/${adapterName}.toml + [ -f ${binary_dir}/test/cfg/${adapterName}.toml ] && + ${csudo}cp -f ${binary_dir}/test/cfg/${adapterName}.toml \ + ${cfg_install_dir}/${adapterName}.toml.${verNumber} + [ -f ${cfg_install_dir}/${adapterName}.toml ] && + ${csudo}ln -s ${cfg_install_dir}/${adapterName}.toml \ + ${install_main_dir}/cfg/${adapterName}.toml else - if [ -f "${binary_dir}/test/cfg/taosadapter.toml" ]; then - ${csudo}cp -f ${binary_dir}/test/cfg/taosadapter.toml \ - ${cfg_install_dir}/taosadapter.toml.${verNumber} + if [ -f "${binary_dir}/test/cfg/${adapterName}.toml" ]; then + ${csudo}cp -f ${binary_dir}/test/cfg/${adapterName}.toml \ + ${cfg_install_dir}/${adapterName}.toml.${verNumber} fi fi } @@ -529,10 +532,10 @@ function install_service_on_systemd() { ${csudo}systemctl enable ${serverName} } -function install_taosadapter_service() { +function install_adapter_service() { if ((${service_mod} == 0)); then - [ -f ${binary_dir}/test/cfg/taosadapter.service ] && - ${csudo}cp ${binary_dir}/test/cfg/taosadapter.service \ + [ -f ${binary_dir}/test/cfg/${adapterName}.service ] && + ${csudo}cp ${binary_dir}/test/cfg/${adapterName}.service \ ${service_config_dir}/ || : ${csudo}systemctl daemon-reload fi @@ -544,11 +547,11 @@ function install_service() { elif ((${service_mod} == 1)); then install_service_on_sysvinit else - kill_taosd + kill_server fi } -function update_TDengine() { +function update_Product() { echo -e "${GREEN}Start to update ${productName}...${NC}" # Stop the service if running @@ -558,8 +561,8 @@ function update_TDengine() { elif ((${service_mod} == 1)); then ${csudo}service ${serverName} stop || : else - kill_taosadapter - kill_taosd + kill_adapter + kill_server fi sleep 1 fi @@ -574,23 +577,23 @@ function update_TDengine() { install_bin install_service - install_taosadapter_service + install_adapter_service install_config - install_taosadapter_config + install_adapter_config echo echo -e "\033[44;32;1m${productName} is updated successfully!${NC}" echo echo -e "${GREEN_DARK}To configure ${productName} ${NC}: edit ${configDir}/${configFile}" - echo -e "${GREEN_DARK}To configure Taos Adapter (if has) ${NC}: edit ${configDir}/taosadapter.toml" + echo -e "${GREEN_DARK}To configure ${adapterName} (if has) ${NC}: edit ${configDir}/${adapterName}.toml" if ((${service_mod} == 0)); then echo -e "${GREEN_DARK}To start ${productName} ${NC}: ${csudo}systemctl start ${serverName}${NC}" elif ((${service_mod} == 1)); then echo -e "${GREEN_DARK}To start ${productName} ${NC}: ${csudo}service ${serverName} start${NC}" else - echo -e "${GREEN_DARK}To start Taos Adapter (if has)${NC}: taosadapter &${NC}" + echo -e "${GREEN_DARK}To start ${adapterName} (if has)${NC}: ${adapterName} &${NC}" echo -e "${GREEN_DARK}To start ${productName} ${NC}: ${serverName}${NC}" fi @@ -599,7 +602,7 @@ function update_TDengine() { echo -e "\033[44;32;1m${productName} is updated successfully!${NC}" } -function install_TDengine() { +function install_Product() { # Start to install echo -e "${GREEN}Start to install ${productName}...${NC}" @@ -614,23 +617,23 @@ function install_TDengine() { install_bin install_service - install_taosadapter_service + install_adapter_service install_config - install_taosadapter_config + install_adapter_config # Ask if to start the service echo echo -e "\033[44;32;1m${productName} is installed successfully!${NC}" echo echo -e "${GREEN_DARK}To configure ${productName} ${NC}: edit ${configDir}/${configFile}" - echo -e "${GREEN_DARK}To configure taosadapter (if has) ${NC}: edit ${configDir}/taosadapter.toml" + echo -e "${GREEN_DARK}To configure ${adapterName} (if has) ${NC}: edit ${configDir}/${adapterName}.toml" if ((${service_mod} == 0)); then echo -e "${GREEN_DARK}To start ${productName} ${NC}: ${csudo}systemctl start ${serverName}${NC}" elif ((${service_mod} == 1)); then echo -e "${GREEN_DARK}To start ${productName} ${NC}: ${csudo}service ${serverName} start${NC}" else - echo -e "${GREEN_DARK}To start Taos Adapter (if has)${NC}: taosadapter &${NC}" + echo -e "${GREEN_DARK}To start ${adapterName} (if has)${NC}: ${adapterName} &${NC}" echo -e "${GREEN_DARK}To start ${productName} ${NC}: ./${serverName}${NC}" fi @@ -644,14 +647,14 @@ echo source directory: $1 echo binary directory: $2 if [ "$osType" != "Darwin" ]; then if [ -x ${bin_dir}/${clientName} ]; then - update_TDengine + update_Product else - install_TDengine + install_Product fi else if [ -x ${bin_dir}/${clientName} ] || [ -x ${bin_2_dir}/${clientName} ]; then - update_TDengine + update_Product else - install_TDengine + install_Product fi fi diff --git a/packaging/tools/makearbi.sh b/packaging/tools/makearbi.sh index 6dacfdd90d..4991dcb934 100755 --- a/packaging/tools/makearbi.sh +++ b/packaging/tools/makearbi.sh @@ -36,13 +36,11 @@ fi bin_files="${build_dir}/bin/tarbitrator ${script_dir}/remove_arbi.sh" install_files="${script_dir}/install_arbi.sh" -#header_files="${code_dir}/inc/taos.h ${code_dir}/inc/taosdef.h ${code_dir}/inc/taoserror.h" init_file_tarbitrator_deb=${script_dir}/../deb/tarbitratord init_file_tarbitrator_rpm=${script_dir}/../rpm/tarbitratord # make directories. mkdir -p ${install_dir} && cp ${install_files} ${install_dir} && chmod a+x ${install_dir}/install_arbi.sh || : -#mkdir -p ${install_dir}/inc && cp ${header_files} ${install_dir}/inc || : mkdir -p ${install_dir}/bin && cp ${bin_files} ${install_dir}/bin && chmod a+x ${install_dir}/bin/* || : mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_deb} ${install_dir}/init.d/tarbitratord.deb || : mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_rpm} ${install_dir}/init.d/tarbitratord.rpm || : diff --git a/packaging/tools/makeclient.sh b/packaging/tools/makeclient.sh index 89865ae54f..1b5a3f159d 100755 --- a/packaging/tools/makeclient.sh +++ b/packaging/tools/makeclient.sh @@ -44,7 +44,6 @@ else fi # Directories and files. - if [ "$osType" != "Darwin" ]; then if [ "$pagMode" == "lite" ]; then strip ${build_dir}/bin/${clientName} @@ -182,26 +181,27 @@ if [[ $productName == "TDengine" ]]; then fi fi fi + # Copy driver mkdir -p ${install_dir}/driver cp ${lib_files} ${install_dir}/driver # Copy connector -connector_dir="${code_dir}/connector" -mkdir -p ${install_dir}/connector - -if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then - if [ "$osType" != "Darwin" ]; then - cp ${build_dir}/lib/*.jar ${install_dir}/connector || : - fi - if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then - cp -r ${connector_dir}/go ${install_dir}/connector - else - echo "WARNING: go connector not found, please check if want to use it!" - fi - cp -r ${connector_dir}/python ${install_dir}/connector - cp -r ${connector_dir}/nodejs ${install_dir}/connector -fi +#connector_dir="${code_dir}/connector" +#mkdir -p ${install_dir}/connector +# +#if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then +# if [ "$osType" != "Darwin" ]; then +# cp ${build_dir}/lib/*.jar ${install_dir}/connector || : +# fi +# if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then +# cp -r ${connector_dir}/go ${install_dir}/connector +# else +# echo "WARNING: go connector not found, please check if want to use it!" +# fi +# cp -r ${connector_dir}/python ${install_dir}/connector +# cp -r ${connector_dir}/nodejs ${install_dir}/connector +#fi # Copy release note # cp ${script_dir}/release_note ${install_dir} diff --git a/packaging/tools/remove.sh b/packaging/tools/remove.sh index f886d08df0..db8a209747 100755 --- a/packaging/tools/remove.sh +++ b/packaging/tools/remove.sh @@ -16,12 +16,16 @@ serverName="taosd" clientName="taos" uninstallScript="rmtaos" productName="TDengine" +adapterName="taosadapter" +benchmarkName="taosBenchmark" +dumpName="taosdump" +demoName="taosdemo" #install main path install_main_dir=${installDir} -data_link_dir=${installDir}/data -log_link_dir=${installDir}/log -cfg_link_dir=${installDir}/cfg +data_link_dir="${installDir}/data" +log_link_dir="${installDir}/log" +cfg_link_dir="${installDir}/cfg" bin_link_dir="/usr/bin" local_bin_link_dir="/usr/local/bin" lib_link_dir="/usr/lib" @@ -31,7 +35,7 @@ install_nginxd_dir="/usr/local/nginxd" service_config_dir="/etc/systemd/system" taos_service_name=${serverName} -taosadapter_service_name="taosadapter" +taosadapter_service_name=${adapterName} tarbitrator_service_name="tarbitratord" nginx_service_name="nginxd" csudo="" @@ -59,22 +63,8 @@ else service_mod=2 fi -function kill_taosadapter() { - pid=$(ps -ef | grep "taosadapter" | grep -v "grep" | awk '{print $2}') - if [ -n "$pid" ]; then - ${csudo}kill -9 $pid || : - fi -} - -function kill_taosd() { - pid=$(ps -ef | grep ${serverName} | grep -v "grep" | awk '{print $2}') - if [ -n "$pid" ]; then - ${csudo}kill -9 $pid || : - fi -} - -function kill_tarbitrator() { - pid=$(ps -ef | grep "tarbitrator" | grep -v "grep" | awk '{print $2}') +function kill_process() { + pid=$(ps -ef | grep "$1" | grep -v "grep" | awk '{print $2}') if [ -n "$pid" ]; then ${csudo}kill -9 $pid || : fi @@ -84,14 +74,14 @@ function clean_bin() { # Remove link ${csudo}rm -f ${bin_link_dir}/${clientName} || : ${csudo}rm -f ${bin_link_dir}/${serverName} || : - ${csudo}rm -f ${bin_link_dir}/taosadapter || : - ${csudo}rm -f ${bin_link_dir}/taosBenchmark || : - ${csudo}rm -f ${bin_link_dir}/taosdemo || : - ${csudo}rm -f ${bin_link_dir}/taosdump || : + ${csudo}rm -f ${bin_link_dir}/${adapterName} || : + ${csudo}rm -f ${bin_link_dir}/${benchmarkName} || : + ${csudo}rm -f ${bin_link_dir}/${demoName} || : + ${csudo}rm -f ${bin_link_dir}/${dumpName} || : ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : ${csudo}rm -f ${bin_link_dir}/tarbitrator || : ${csudo}rm -f ${bin_link_dir}/set_core || : - ${csudo}rm -f ${bin_link_dir}/run_taosd_and_taosadapter.sh || : + ${csudo}rm -f ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : ${csudo}rm -f ${bin_link_dir}/TDinsight.sh || : } @@ -133,9 +123,9 @@ function clean_service_on_systemd() { ${csudo}systemctl disable ${taos_service_name} &>/dev/null || echo &>/dev/null ${csudo}rm -f ${taosd_service_config} - taosadapter_service_config="${service_config_dir}/taosadapter.service" + taosadapter_service_config="${service_config_dir}/${adapterName}.service" if systemctl is-active --quiet ${taosadapter_service_name}; then - echo "${productName} taosAdapter is running, stopping it..." + echo "${productName} ${adapterName} is running, stopping it..." ${csudo}systemctl stop ${taosadapter_service_name} &>/dev/null || echo &>/dev/null fi ${csudo}systemctl disable ${taosadapter_service_name} &>/dev/null || echo &>/dev/null @@ -210,9 +200,9 @@ function clean_service() { elif ((${service_mod} == 1)); then clean_service_on_sysvinit else - kill_taosadapter - kill_taosd - kill_tarbitrator + kill_process ${adapterName} + kill_process ${serverName} + kill_process "tarbitrator" fi } diff --git a/packaging/tools/remove_client.sh b/packaging/tools/remove_client.sh index f2cbccb45f..701bfde273 100755 --- a/packaging/tools/remove_client.sh +++ b/packaging/tools/remove_client.sh @@ -23,47 +23,46 @@ lib64_link_dir="/usr/lib64" inc_link_dir="/usr/include" csudo="" -if command -v sudo > /dev/null; then - csudo="sudo " +if command -v sudo >/dev/null; then + csudo="sudo " fi function kill_client() { if [ -n "$(pidof ${clientName})" ]; then - ${csudo}kill -9 $pid || : + ${csudo}kill -9 $pid || : fi } function clean_bin() { - # Remove link - ${csudo}rm -f ${bin_link_dir}/${clientName} || : - ${csudo}rm -f ${bin_link_dir}/taosdemo || : - ${csudo}rm -f ${bin_link_dir}/taosdump || : - ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : - ${csudo}rm -f ${bin_link_dir}/set_core || : + # Remove link + ${csudo}rm -f ${bin_link_dir}/${clientName} || : + ${csudo}rm -f ${bin_link_dir}/taosdemo || : + ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : + ${csudo}rm -f ${bin_link_dir}/set_core || : } function clean_lib() { - # Remove link - ${csudo}rm -f ${lib_link_dir}/libtaos.* || : - ${csudo}rm -f ${lib64_link_dir}/libtaos.* || : - #${csudo}rm -rf ${v15_java_app_dir} || : + # Remove link + ${csudo}rm -f ${lib_link_dir}/libtaos.* || : + ${csudo}rm -f ${lib64_link_dir}/libtaos.* || : + #${csudo}rm -rf ${v15_java_app_dir} || : } function clean_header() { - # Remove link - ${csudo}rm -f ${inc_link_dir}/taos.h || : - ${csudo}rm -f ${inc_link_dir}/taosdef.h || : - ${csudo}rm -f ${inc_link_dir}/taoserror.h || : + # Remove link + ${csudo}rm -f ${inc_link_dir}/taos.h || : + ${csudo}rm -f ${inc_link_dir}/taosdef.h || : + ${csudo}rm -f ${inc_link_dir}/taoserror.h || : } function clean_config() { - # Remove link - ${csudo}rm -f ${cfg_link_dir}/* || : + # Remove link + ${csudo}rm -f ${cfg_link_dir}/* || : } function clean_log() { - # Remove link - ${csudo}rm -rf ${log_link_dir} || : + # Remove link + ${csudo}rm -rf ${log_link_dir} || : } # Stop client. @@ -82,4 +81,4 @@ clean_config ${csudo}rm -rf ${install_main_dir} echo -e "${GREEN}TDengine client is removed successfully!${NC}" -echo +echo -- GitLab From 3975eef51d3f7888471c7c89a69d3c65338924c4 Mon Sep 17 00:00:00 2001 From: zyyang Date: Tue, 7 Jun 2022 13:47:46 +0800 Subject: [PATCH 003/380] other: change blance default value to 0 in 2.6 --- packaging/cfg/taos.cfg | 2 +- src/common/src/tglobal.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/cfg/taos.cfg b/packaging/cfg/taos.cfg index 7d77a0b23e..1918a4c469 100644 --- a/packaging/cfg/taos.cfg +++ b/packaging/cfg/taos.cfg @@ -52,7 +52,7 @@ keepColumnName 1 # telemetryReporting 1 # enable/disable load balancing -# balance 1 +# balance 0 # role for dnode. 0 - any, 1 - mnode, 2 - dnode # role 0 diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 616c5fba89..cc0e6b0e97 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -164,7 +164,7 @@ bool tsdbForceCompactFile = false; // compact TSDB fileset int32_t tsdbWalFlushSize = TSDB_DEFAULT_WAL_FLUSH_SIZE; // MB // balance -int8_t tsEnableBalance = 1; +int8_t tsEnableBalance = 0; int8_t tsAlternativeRole = 0; int32_t tsBalanceInterval = 300; // seconds int32_t tsOfflineInterval = 3; // seconds -- GitLab From a1a09373c7fae305f47f8ae35ca038fb5fd5b82a Mon Sep 17 00:00:00 2001 From: zyyang Date: Tue, 7 Jun 2022 14:06:57 +0800 Subject: [PATCH 004/380] other: release script modify --- packaging/clean_env.bat | 37 ++++++++++++++++++++++++++++++++++++ packaging/clean_env.sh | 42 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 packaging/clean_env.bat create mode 100644 packaging/clean_env.sh diff --git a/packaging/clean_env.bat b/packaging/clean_env.bat new file mode 100644 index 0000000000..069102cf7b --- /dev/null +++ b/packaging/clean_env.bat @@ -0,0 +1,37 @@ +@echo off + +set CUR_DIR=%~dp0 +set SHELL_DIR=%cd% +set ENTERPRISE_DIR="%SHELL_DIR%\..\.." +set COMMUNITY_DIR="%SHELL_DIR%\.." +set TOOLS_DIR="%SHELL_DIR%\..\src\kit\taos-tools" + +cd %ENTERPRISE_DIR% +git checkout -- . +if exist "enterprise\src\plugins\taosainternal\taosadapter" ( + del /f "enterprise\src\plugins\taosainternal\taosadapter" +) +if exist "enterprise\src\plugins\taosainternal\upx.tar.xz" ( + del /f "enterprise\src\plugins\taosainternal\upx.tar.xz" +) + +cd %COMMUNITY_DIR% +git checkout -- . + +cd %TOOLS_DIR% +git checkout -- . +if exist "packaging\tools\install-khtools.sh" ( + del /f "packaging\tools\install-khtools.sh" +) +if exist "packaging\tools\uninstall-khtools.sh" ( + del /f "packaging/tools/uninstall-khtools.sh" +) + +if exist "packaging\tools\install-prodbtools.sh" ( + del /f "packaging\tools\install-prodbtools.sh" +) +if exist "packaging\tools\uninstall-prodbtools.sh" ( + del /f "packaging\tools\uninstall-prodbtools.sh" +) + +cd %CUR_DIR% \ No newline at end of file diff --git a/packaging/clean_env.sh b/packaging/clean_env.sh new file mode 100644 index 0000000000..51a0fe4eb2 --- /dev/null +++ b/packaging/clean_env.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +CUR_DIR=$(pwd) +SHELL_DIR=$(dirname $(readlink -f "$0")) +ENTERPRISE_DIR=$SHELL_DIR/../.. +COMMUNITY_DIR=$SHELL_DIR/.. +TOOLS_DIR=$COMMUNITY_DIR/src/kit/taos-tools + +cd $ENTERPRISE_DIR +git checkout -- . +if [[ -e enterprise/src/plugins/taosainternal/taosadapter ]]; then + rm -f enterprise/src/plugins/taosainternal/taosadapter +fi +if [[ -e enterprise/src/plugins/taosainternal/upx.tar.xz ]]; then + rm -f enterprise/src/plugins/taosainternal/upx.tar.xz +fi + +cd $COMMUNITY_DIR +git checkout -- . +if [[ -e src/plugins/taosadapter/taosadapter ]]; then + rm -f src/plugins/taosadapter/taosadapter +fi +if [[ -e src/plugins/taosadapter/upx.tar.xz ]]; then + rm -f src/plugins/taosadapter/upx.tar.xz +fi + +cd $TOOLS_DIR +git checkout -- . + +rm -f $(find packaging/tools/ -name install-*tools.sh | grep -v taos) +rm -f $(find packaging/tools/ -name uninstall-*tools.sh | grep -v taos) + +rm -rf $COMMUNITY_DIR/debug/* +rm -rf $COMMUNITY_DIR/release/* +if [[ -e $COMMUNITY_DIR/rpms ]]; then + rm -rf $COMMUNITY_DIR/rpms +fi +if [[ -e $COMMUNITY_DIR/debs ]]; then + rm -rf $COMMUNITY_DIR/debs +fi + +cd $CUR_DIR -- GitLab From 513dbadf373c15e475f7f81b81f55fcdf3376c54 Mon Sep 17 00:00:00 2001 From: zyyang Date: Tue, 7 Jun 2022 16:39:48 +0800 Subject: [PATCH 005/380] release script modify --- packaging/tools/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index f07705ff44..b14c14c7ee 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -207,7 +207,7 @@ function install_bin() { [ -x ${install_main_dir}/bin/${adapterName} ] && ${csudo}ln -s ${install_main_dir}/bin/${adapterName} ${bin_link_dir}/${adapterName} || : [ -x ${install_main_dir}/bin/${benchmarkName} ] && ${csudo}ln -s ${install_main_dir}/bin/${benchmarkName} ${bin_link_dir}/${demoName} || : [ -x ${install_main_dir}/bin/${benchmarkName} ] && ${csudo}ln -s ${install_main_dir}/bin/${benchmarkName} ${bin_link_dir}/${benchmarkName} || : - [ -x ${install_main_dir}/bin/${dumpName} ] && ${csudo}ln -s ${install_main_dir}/bin/${dumpName} ${bin_link_dir}/${dumpName} || : +# [ -x ${install_main_dir}/bin/${dumpName} ] && ${csudo}ln -s ${install_main_dir}/bin/${dumpName} ${bin_link_dir}/${dumpName} || : [ -x ${install_main_dir}/bin/TDinsight.sh ] && ${csudo}ln -s ${install_main_dir}/bin/TDinsight.sh ${bin_link_dir}/TDinsight.sh || : [ -x ${install_main_dir}/bin/remove.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/${uninstallScript} || : [ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || : -- GitLab From d0345c89183df6021d75828577c53099448519bc Mon Sep 17 00:00:00 2001 From: dingbo Date: Mon, 13 Jun 2022 15:15:57 +0800 Subject: [PATCH 006/380] docs: move docs-cn and docs-en to docs --- docs-cn/07-develop/01-connect/_connect_c.mdx | 3 -- .../07-develop/01-connect/_connect_node.mdx | 7 ----- .../07-develop/01-connect/_connect_php.mdx | 3 -- .../07-develop/01-connect/_connect_python.mdx | 3 -- docs-cn/07-develop/01-connect/_connect_r.mdx | 3 -- docs-cn/07-develop/03-insert-data/_c_line.mdx | 3 -- .../03-insert-data/_c_opts_json.mdx | 3 -- .../03-insert-data/_c_opts_telnet.mdx | 3 -- docs-cn/07-develop/03-insert-data/_c_sql.mdx | 3 -- docs-cn/07-develop/03-insert-data/_c_stmt.mdx | 6 ---- .../07-develop/03-insert-data/_cs_line.mdx | 3 -- .../03-insert-data/_cs_opts_json.mdx | 3 -- .../03-insert-data/_cs_opts_telnet.mdx | 3 -- docs-cn/07-develop/03-insert-data/_cs_sql.mdx | 3 -- .../07-develop/03-insert-data/_cs_stmt.mdx | 3 -- .../07-develop/03-insert-data/_go_line.mdx | 3 -- .../03-insert-data/_go_opts_json.mdx | 3 -- .../03-insert-data/_go_opts_telnet.mdx | 3 -- docs-cn/07-develop/03-insert-data/_go_sql.mdx | 3 -- .../07-develop/03-insert-data/_java_line.mdx | 3 -- .../03-insert-data/_java_opts_json.mdx | 3 -- .../03-insert-data/_java_opts_telnet.mdx | 3 -- .../07-develop/03-insert-data/_java_sql.mdx | 3 -- .../07-develop/03-insert-data/_java_stmt.mdx | 3 -- .../07-develop/03-insert-data/_js_line.mdx | 3 -- .../03-insert-data/_js_opts_json.mdx | 3 -- .../03-insert-data/_js_opts_telnet.mdx | 3 -- docs-cn/07-develop/03-insert-data/_js_sql.mdx | 3 -- .../07-develop/03-insert-data/_php_sql.mdx | 3 -- .../07-develop/03-insert-data/_php_stmt.mdx | 3 -- .../07-develop/03-insert-data/_py_line.mdx | 3 -- .../03-insert-data/_py_opts_json.mdx | 3 -- .../03-insert-data/_py_opts_telnet.mdx | 3 -- docs-cn/07-develop/03-insert-data/_py_sql.mdx | 3 -- .../07-develop/03-insert-data/_rust_line.mdx | 3 -- .../03-insert-data/_rust_opts_json.mdx | 3 -- .../03-insert-data/_rust_opts_telnet.mdx | 3 -- .../07-develop/03-insert-data/_rust_sql.mdx | 3 -- .../07-develop/03-insert-data/_rust_stmt.mdx | 3 -- docs-cn/07-develop/04-query-data/_c.mdx | 3 -- docs-cn/07-develop/04-query-data/_c_async.mdx | 3 -- docs-cn/07-develop/04-query-data/_cs.mdx | 3 -- .../07-develop/04-query-data/_cs_async.mdx | 3 -- docs-cn/07-develop/04-query-data/_go.mdx | 3 -- .../07-develop/04-query-data/_go_async.mdx | 3 -- docs-cn/07-develop/04-query-data/_java.mdx | 3 -- docs-cn/07-develop/04-query-data/_js.mdx | 3 -- .../07-develop/04-query-data/_js_async.mdx | 3 -- docs-cn/07-develop/04-query-data/_php.mdx | 3 -- docs-cn/07-develop/04-query-data/_rust.mdx | 3 -- docs-cn/07-develop/_sub_c.mdx | 3 -- docs-cn/07-develop/_sub_cs.mdx | 3 -- docs-cn/07-develop/_sub_go.mdx | 3 -- docs-cn/07-develop/_sub_node.mdx | 3 -- docs-cn/07-develop/_sub_python.mdx | 3 -- docs-cn/07-develop/_sub_rust.mdx | 3 -- docs-en/07-develop/01-connect/_connect_c.mdx | 3 -- .../07-develop/01-connect/_connect_node.mdx | 7 ----- .../07-develop/01-connect/_connect_python.mdx | 3 -- docs-en/07-develop/01-connect/_connect_r.mdx | 3 -- docs-en/07-develop/03-insert-data/_c_line.mdx | 3 -- .../03-insert-data/_c_opts_json.mdx | 3 -- .../03-insert-data/_c_opts_telnet.mdx | 3 -- docs-en/07-develop/03-insert-data/_c_sql.mdx | 3 -- docs-en/07-develop/03-insert-data/_c_stmt.mdx | 6 ---- .../07-develop/03-insert-data/_cs_line.mdx | 3 -- .../03-insert-data/_cs_opts_json.mdx | 3 -- .../03-insert-data/_cs_opts_telnet.mdx | 3 -- docs-en/07-develop/03-insert-data/_cs_sql.mdx | 3 -- .../07-develop/03-insert-data/_cs_stmt.mdx | 3 -- .../07-develop/03-insert-data/_go_line.mdx | 3 -- .../03-insert-data/_go_opts_json.mdx | 3 -- .../03-insert-data/_go_opts_telnet.mdx | 3 -- docs-en/07-develop/03-insert-data/_go_sql.mdx | 3 -- .../07-develop/03-insert-data/_java_line.mdx | 3 -- .../03-insert-data/_java_opts_json.mdx | 3 -- .../03-insert-data/_java_opts_telnet.mdx | 3 -- .../07-develop/03-insert-data/_java_sql.mdx | 3 -- .../07-develop/03-insert-data/_java_stmt.mdx | 3 -- .../07-develop/03-insert-data/_js_line.mdx | 3 -- .../03-insert-data/_js_opts_json.mdx | 3 -- .../03-insert-data/_js_opts_telnet.mdx | 3 -- docs-en/07-develop/03-insert-data/_js_sql.mdx | 3 -- .../07-develop/03-insert-data/_py_line.mdx | 3 -- .../03-insert-data/_py_opts_json.mdx | 3 -- .../03-insert-data/_py_opts_telnet.mdx | 3 -- docs-en/07-develop/03-insert-data/_py_sql.mdx | 3 -- .../07-develop/03-insert-data/_rust_line.mdx | 3 -- .../03-insert-data/_rust_opts_json.mdx | 3 -- .../03-insert-data/_rust_opts_telnet.mdx | 3 -- .../07-develop/03-insert-data/_rust_sql.mdx | 3 -- .../07-develop/03-insert-data/_rust_stmt.mdx | 3 -- docs-en/07-develop/04-query-data/_c.mdx | 3 -- docs-en/07-develop/04-query-data/_c_async.mdx | 3 -- docs-en/07-develop/04-query-data/_cs.mdx | 3 -- .../07-develop/04-query-data/_cs_async.mdx | 3 -- docs-en/07-develop/04-query-data/_go.mdx | 3 -- .../07-develop/04-query-data/_go_async.mdx | 3 -- docs-en/07-develop/04-query-data/_java.mdx | 3 -- docs-en/07-develop/04-query-data/_js.mdx | 3 -- .../07-develop/04-query-data/_js_async.mdx | 3 -- docs-en/07-develop/04-query-data/_rust.mdx | 3 -- docs-en/07-develop/_sub_c.mdx | 3 -- docs-en/07-develop/_sub_cs.mdx | 3 -- docs-en/07-develop/_sub_go.mdx | 3 -- docs-en/07-develop/_sub_node.mdx | 3 -- docs-en/07-develop/_sub_python.mdx | 3 -- docs-en/07-develop/_sub_rust.mdx | 3 -- {docs-en => docs/en}/01-index.md | 0 {docs-en => docs/en}/02-intro/_category_.yml | 0 {docs-cn => docs/en/02-intro}/eco_system.webp | Bin {docs-en => docs/en}/02-intro/index.md | 0 .../en}/04-concept/_category_.yml | 0 {docs-en => docs/en}/04-concept/index.md | 0 .../en}/05-get-started/_apt_get_install.mdx | 0 .../en}/05-get-started/_category_.yml | 0 .../en}/05-get-started/_pkg_install.mdx | 0 {docs-en => docs/en}/05-get-started/index.md | 0 .../en}/07-develop/01-connect/_category_.yml | 0 docs/en/07-develop/01-connect/_connect_c.mdx | 3 ++ .../en}/07-develop/01-connect/_connect_cs.mdx | 2 +- .../en}/07-develop/01-connect/_connect_go.mdx | 6 ++-- .../07-develop/01-connect/_connect_java.mdx | 6 ++-- .../07-develop/01-connect/_connect_node.mdx | 7 +++++ .../07-develop/01-connect/_connect_python.mdx | 3 ++ docs/en/07-develop/01-connect/_connect_r.mdx | 3 ++ .../07-develop/01-connect/_connect_rust.mdx | 2 +- .../en}/07-develop/01-connect/index.md | 0 .../en}/07-develop/02-model/_category_.yml | 0 .../en}/07-develop/02-model/index.mdx | 0 .../03-insert-data/01-sql-writing.mdx | 0 .../03-insert-data/02-influxdb-line.mdx | 0 .../03-insert-data/03-opentsdb-telnet.mdx | 0 .../03-insert-data/04-opentsdb-json.mdx | 0 docs/en/07-develop/03-insert-data/_c_line.mdx | 3 ++ .../03-insert-data/_c_opts_json.mdx | 3 ++ .../03-insert-data/_c_opts_telnet.mdx | 3 ++ docs/en/07-develop/03-insert-data/_c_sql.mdx | 3 ++ docs/en/07-develop/03-insert-data/_c_stmt.mdx | 6 ++++ .../07-develop/03-insert-data/_category_.yml | 0 .../en/07-develop/03-insert-data/_cs_line.mdx | 3 ++ .../03-insert-data/_cs_opts_json.mdx | 3 ++ .../03-insert-data/_cs_opts_telnet.mdx | 3 ++ docs/en/07-develop/03-insert-data/_cs_sql.mdx | 3 ++ .../en/07-develop/03-insert-data/_cs_stmt.mdx | 3 ++ .../en/07-develop/03-insert-data/_go_line.mdx | 3 ++ .../03-insert-data/_go_opts_json.mdx | 3 ++ .../03-insert-data/_go_opts_telnet.mdx | 3 ++ docs/en/07-develop/03-insert-data/_go_sql.mdx | 3 ++ .../07-develop/03-insert-data/_go_stmt.mdx | 2 +- .../07-develop/03-insert-data/_java_line.mdx | 3 ++ .../03-insert-data/_java_opts_json.mdx | 3 ++ .../03-insert-data/_java_opts_telnet.mdx | 3 ++ .../07-develop/03-insert-data/_java_sql.mdx | 3 ++ .../07-develop/03-insert-data/_java_stmt.mdx | 3 ++ .../en/07-develop/03-insert-data/_js_line.mdx | 3 ++ .../03-insert-data/_js_opts_json.mdx | 3 ++ .../03-insert-data/_js_opts_telnet.mdx | 3 ++ docs/en/07-develop/03-insert-data/_js_sql.mdx | 3 ++ .../07-develop/03-insert-data/_js_stmt.mdx | 4 +-- .../en/07-develop/03-insert-data/_py_line.mdx | 3 ++ .../03-insert-data/_py_opts_json.mdx | 3 ++ .../03-insert-data/_py_opts_telnet.mdx | 3 ++ docs/en/07-develop/03-insert-data/_py_sql.mdx | 3 ++ .../07-develop/03-insert-data/_py_stmt.mdx | 4 +-- .../07-develop/03-insert-data/_rust_line.mdx | 3 ++ .../03-insert-data/_rust_opts_json.mdx | 3 ++ .../03-insert-data/_rust_opts_telnet.mdx | 3 ++ .../07-develop/03-insert-data/_rust_sql.mdx | 3 ++ .../07-develop/03-insert-data/_rust_stmt.mdx | 3 ++ .../en}/07-develop/03-insert-data/index.md | 0 docs/en/07-develop/04-query-data/_c.mdx | 3 ++ docs/en/07-develop/04-query-data/_c_async.mdx | 3 ++ .../07-develop/04-query-data/_category_.yml | 0 docs/en/07-develop/04-query-data/_cs.mdx | 3 ++ .../en/07-develop/04-query-data/_cs_async.mdx | 3 ++ docs/en/07-develop/04-query-data/_go.mdx | 3 ++ .../en/07-develop/04-query-data/_go_async.mdx | 3 ++ docs/en/07-develop/04-query-data/_java.mdx | 3 ++ docs/en/07-develop/04-query-data/_js.mdx | 3 ++ .../en/07-develop/04-query-data/_js_async.mdx | 3 ++ .../en}/07-develop/04-query-data/_py.mdx | 4 +-- .../07-develop/04-query-data/_py_async.mdx | 2 +- docs/en/07-develop/04-query-data/_rust.mdx | 3 ++ .../en}/07-develop/04-query-data/index.mdx | 0 .../en}/07-develop/05-delete-data.mdx | 0 .../en}/07-develop/06-continuous-query.mdx | 0 .../en}/07-develop/07-subscribe.mdx | 0 {docs-en => docs/en}/07-develop/08-cache.md | 0 {docs-en => docs/en}/07-develop/09-udf.md | 0 .../en}/07-develop/_category_.yml | 0 docs/en/07-develop/_sub_c.mdx | 3 ++ docs/en/07-develop/_sub_cs.mdx | 3 ++ docs/en/07-develop/_sub_go.mdx | 3 ++ {docs-en => docs/en}/07-develop/_sub_java.mdx | 2 +- docs/en/07-develop/_sub_node.mdx | 3 ++ docs/en/07-develop/_sub_python.mdx | 3 ++ docs/en/07-develop/_sub_rust.mdx | 3 ++ {docs-en => docs/en}/07-develop/index.md | 0 {docs-en => docs/en}/10-cluster/01-deploy.md | 0 .../en}/10-cluster/02-cluster-mgmt.md | 0 .../en}/10-cluster/03-ha-and-lb.md | 0 .../en}/10-cluster/_category_.yml | 0 {docs-en => docs/en}/10-cluster/index.md | 0 .../en}/12-taos-sql/01-data-type.md | 0 .../en}/12-taos-sql/02-database.md | 0 {docs-en => docs/en}/12-taos-sql/03-table.md | 0 {docs-en => docs/en}/12-taos-sql/04-stable.md | 0 {docs-en => docs/en}/12-taos-sql/05-insert.md | 0 {docs-en => docs/en}/12-taos-sql/06-select.md | 0 .../en}/12-taos-sql/07-function.md | 0 .../en}/12-taos-sql/08-interval.md | 0 {docs-en => docs/en}/12-taos-sql/09-limit.md | 0 {docs-en => docs/en}/12-taos-sql/10-json.md | 0 {docs-en => docs/en}/12-taos-sql/11-escape.md | 0 .../en}/12-taos-sql/12-keywords.md | 0 .../en}/12-taos-sql/_category_.yml | 0 {docs-en => docs/en}/12-taos-sql/index.md | 0 .../en}/12-taos-sql/timewindow-1.webp | Bin .../en}/12-taos-sql/timewindow-2.webp | Bin .../en}/12-taos-sql/timewindow-3.webp | Bin .../en}/13-operation/01-pkg-install.md | 0 .../en}/13-operation/02-planning.mdx | 0 .../en}/13-operation/03-tolerance.md | 0 {docs-en => docs/en}/13-operation/06-admin.md | 0 .../en}/13-operation/07-import.md | 0 .../en}/13-operation/08-export.md | 0 .../en}/13-operation/09-status.md | 0 .../en}/13-operation/10-monitor.md | 0 .../en}/13-operation/11-optimize.md | 0 .../en}/13-operation/17-diagnose.md | 0 .../en}/13-operation/_category_.yml | 0 {docs-en => docs/en}/13-operation/index.md | 0 .../14-reference/02-rest-api/02-rest-api.mdx | 0 .../14-reference/02-rest-api/_category_.yml | 0 .../03-connector/03-connector.mdx | 0 .../14-reference/03-connector/_category_.yml | 0 .../03-connector/_linux_install.mdx | 0 .../03-connector/_preparation.mdx | 0 .../03-connector/_verify_linux.mdx | 0 .../03-connector/_verify_windows.mdx | 28 +++++++++--------- .../03-connector/_windows_install.mdx | 0 .../14-reference/03-connector/connector.webp | Bin .../en}/14-reference/03-connector/cpp.mdx | 0 .../en}/14-reference/03-connector/csharp.mdx | 0 .../en}/14-reference/03-connector/go.mdx | 0 .../en}/14-reference/03-connector/java.mdx | 0 .../en}/14-reference/03-connector/node.mdx | 0 .../en}/14-reference/03-connector/php.mdx | 8 ++--- .../en}/14-reference/03-connector/python.mdx | 22 +++++++------- .../en}/14-reference/03-connector/rust.mdx | 0 .../03-connector/tdengine-jdbc-connector.webp | Bin .../en}/14-reference/04-taosadapter.md | 0 .../en}/14-reference/05-taosbenchmark.md | 0 .../en}/14-reference/06-taosdump.md | 0 .../15146-tdengine-monitor-dashboard.json | 0 .../assets/15155-tdengine-alert-demo.json | 0 .../assets/TDinsight-1-cluster-status.webp | Bin .../assets/TDinsight-2-dnodes.webp | Bin .../assets/TDinsight-3-mnodes.webp | Bin .../assets/TDinsight-4-requests.webp | Bin .../assets/TDinsight-5-database.webp | Bin .../assets/TDinsight-6-dnode-usage.webp | Bin .../assets/TDinsight-7-login-history.webp | Bin .../assets/TDinsight-8-taosadapter.webp | Bin .../07-tdinsight/assets/TDinsight-full.webp | Bin .../assets/alert-manager-status.webp | Bin .../assets/alert-notification-channel.webp | Bin .../07-tdinsight/assets/alert-query-demo.webp | Bin .../alert-rule-condition-notifications.webp | Bin .../07-tdinsight/assets/alert-rule-test.webp | Bin .../assets/howto-add-datasource-button.webp | Bin .../assets/howto-add-datasource-tdengine.webp | Bin .../assets/howto-add-datasource-test.webp | Bin .../assets/howto-add-datasource.webp | Bin .../assets/howto-dashboard-display.webp | Bin .../howto-dashboard-import-options.webp | Bin .../assets/howto-import-dashboard.webp | Bin .../assets/import-dashboard-15167.webp | Bin .../assets/import-dashboard-for-tdengine.webp | Bin .../assets/import-via-grafana-dot-com.webp | Bin .../07-tdinsight/assets/import_dashboard.webp | Bin .../assets/tdengine-grafana-7.x.json | 0 .../07-tdinsight/assets/tdengine-grafana.json | 0 .../assets/tdengine_dashboard.webp | Bin .../en}/14-reference/07-tdinsight/index.md | 0 .../en}/14-reference/08-taos-shell.md | 0 .../09-support-platform/_category_.yml | 0 .../14-reference/09-support-platform/index.md | 0 .../en}/14-reference/11-docker/_category_.yml | 0 .../en}/14-reference/11-docker/index.md | 0 .../en}/14-reference/12-config/_category_.yml | 0 .../en}/14-reference/12-config/index.md | 0 .../en}/14-reference/12-directory.md | 0 .../13-schemaless/13-schemaless.md | 0 .../14-reference/13-schemaless/_category_.yml | 0 .../en}/14-reference/_category_.yml | 0 .../en}/14-reference/_collectd.mdx | 0 .../en}/14-reference/_icinga2.mdx | 0 .../en}/14-reference/_prometheus.mdx | 0 {docs-en => docs/en}/14-reference/_statsd.mdx | 0 .../en}/14-reference/_tcollector.mdx | 0 .../en}/14-reference/_telegraf.mdx | 0 {docs-en => docs/en}/14-reference/index.md | 0 .../taosAdapter-architecture.webp | Bin .../en}/20-third-party/01-grafana.mdx | 0 .../en}/20-third-party/02-prometheus.md | 0 .../en}/20-third-party/03-telegraf.md | 0 .../en}/20-third-party/05-collectd.md | 0 .../en}/20-third-party/06-statsd.md | 0 .../en}/20-third-party/07-icinga2.md | 0 .../en}/20-third-party/08-tcollector.md | 0 .../en}/20-third-party/09-emq-broker.md | 2 +- .../en}/20-third-party/10-hive-mq-broker.md | 0 .../en}/20-third-party/11-kafka.md | 0 .../en}/20-third-party/_category_.yml | 0 .../en}/20-third-party/_deploytaosadapter.mdx | 0 .../emqx/add-action-handler.webp | Bin .../emqx/check-result-in-taos.webp | Bin .../emqx/check-rule-matched.webp | Bin .../en}/20-third-party/emqx/client-num.webp | Bin .../20-third-party/emqx/create-resource.webp | Bin .../en}/20-third-party/emqx/create-rule.webp | Bin .../en}/20-third-party/emqx/edit-action.webp | Bin .../20-third-party/emqx/edit-resource.webp | Bin .../20-third-party/emqx/login-dashboard.webp | Bin .../en}/20-third-party/emqx/rule-engine.webp | Bin .../emqx/rule-header-key-value.webp | Bin .../en}/20-third-party/emqx/run-mock.webp | Bin .../grafana}/add_datasource1.webp | Bin .../grafana}/add_datasource2.webp | Bin .../grafana}/add_datasource3.webp | Bin .../grafana}/add_datasource4.webp | Bin .../grafana}/create_dashboard1.webp | Bin .../grafana}/create_dashboard2.webp | Bin {docs-en => docs/en}/20-third-party/index.md | 0 .../20-third-party/kafka/Kafka_Connect.webp | Bin .../kafka/confluentPlatform.webp | Bin ...eaming-integration-with-kafka-connect.webp | Bin {docs-en => docs/en}/21-tdinternal/01-arch.md | 0 .../en}/21-tdinternal/30-iot-big-data.md | 0 .../en}/21-tdinternal/_category_.yml | 0 {docs-cn => docs/en}/21-tdinternal/dnode.webp | Bin {docs-en => docs/en}/21-tdinternal/index.md | 0 .../en}/21-tdinternal/message.webp | Bin .../en}/21-tdinternal/modules.webp | Bin .../en}/21-tdinternal/multi_tables.webp | Bin .../en}/21-tdinternal/replica-forward.webp | Bin .../en}/21-tdinternal/replica-master.webp | Bin .../en}/21-tdinternal/replica-restore.webp | Bin .../en}/21-tdinternal/structure.webp | Bin {docs-cn => docs/en}/21-tdinternal/vnode.webp | Bin .../en}/21-tdinternal/write_master.webp | Bin .../en}/21-tdinternal/write_slave.webp | Bin .../en}/25-application/01-telegraf.md | 0 .../en}/25-application/02-collectd.md | 0 .../en}/25-application/03-immigrate.md | 0 .../IT-DevOps-Solutions-Collectd-StatsD.webp | Bin ...Ops-Solutions-Immigrate-OpenTSDB-Arch.webp | Bin ...olutions-Immigrate-OpenTSDB-Dashboard.webp | Bin ...Ops-Solutions-Immigrate-TDengine-Arch.webp | Bin .../IT-DevOps-Solutions-Telegraf.webp | Bin ...T-DevOps-Solutions-collectd-dashboard.webp | Bin .../IT-DevOps-Solutions-statsd-dashboard.webp | Bin ...T-DevOps-Solutions-telegraf-dashboard.webp | Bin .../en}/25-application/_category_.yml | 0 {docs-en => docs/en}/25-application/index.md | 0 {docs-en => docs/en}/27-train-faq/01-faq.md | 0 .../en}/27-train-faq/03-docker.md | 0 .../en}/27-train-faq/_category_.yml | 0 {docs-en => docs/en}/27-train-faq/index.md | 0 {docs-cn => docs/en}/30-release/01-2.6.md | 0 {docs-cn => docs/en}/30-release/02-2.4.md | 0 .../en}/30-release/_category_.yml | 0 {docs-en => docs/en}/30-release/index.md | 0 {docs-examples => docs/examples}/.gitignore | 0 {docs-examples => docs/examples}/.gitignre | 0 .../examples}/R/connect_native.r | 0 .../examples}/R/connect_rest.r | 0 {docs-examples => docs/examples}/c/.gitignore | 0 .../examples}/c/async_query_example.c | 0 .../examples}/c/connect_example.c | 0 .../examples}/c/error_handle_example.c | 0 .../examples}/c/insert_example.c | 0 .../examples}/c/json_protocol_example.c | 0 .../examples}/c/line_example.c | 0 .../examples}/c/multi_bind_example.c | 0 .../examples}/c/query_example.c | 0 .../examples}/c/stmt_example.c | 0 .../examples}/c/subscribe_demo.c | 0 .../examples}/c/telnet_line_example.c | 0 .../examples}/csharp/.gitignore | 0 .../examples}/csharp/AsyncQueryExample.cs | 0 .../examples}/csharp/ConnectExample.cs | 0 .../examples}/csharp/InfluxDBLineExample.cs | 0 .../examples}/csharp/OptsJsonExample.cs | 0 .../examples}/csharp/OptsTelnetExample.cs | 0 .../examples}/csharp/QueryExample.cs | 0 .../examples}/csharp/SQLInsertExample.cs | 0 .../examples}/csharp/StmtInsertExample.cs | 0 .../examples}/csharp/SubscribeDemo.cs | 0 .../examples}/csharp/asyncquery.csproj | 0 .../examples}/csharp/connect.csproj | 0 .../examples}/csharp/influxdbline.csproj | 0 .../examples}/csharp/optsjson.csproj | 0 .../examples}/csharp/optstelnet.csproj | 0 .../examples}/csharp/query.csproj | 0 .../examples}/csharp/sqlinsert.csproj | 0 .../examples}/csharp/stmtinsert.csproj | 0 .../examples}/csharp/subscribe.csproj | 0 .../examples}/go/.gitignore | 0 .../examples}/go/connect/afconn/main.go | 0 .../examples}/go/connect/cgoexample/main.go | 0 .../examples}/go/connect/restexample/main.go | 0 .../examples}/go/connect/wrapper/main.go | 0 {docs-examples => docs/examples}/go/go.mod | 0 .../examples}/go/insert/json/main.go | 0 .../examples}/go/insert/line/main.go | 0 .../examples}/go/insert/sql/main.go | 0 .../examples}/go/insert/stmt/main.go | 0 .../examples}/go/insert/telnet/main.go | 0 .../examples}/go/query/async/main.go | 0 .../examples}/go/query/sync/main.go | 0 .../examples}/go/rest/opentsdbjson/main.go | 0 .../examples}/go/sub/main.go | 0 .../examples}/java/.gitignore | 0 {docs-examples => docs/examples}/java/pom.xml | 0 .../com/taos/example/JNIConnectExample.java | 0 .../com/taos/example/JSONProtocolExample.java | 0 .../com/taos/example/LineProtocolExample.java | 0 .../com/taos/example/RESTConnectExample.java | 0 .../com/taos/example/RestInsertExample.java | 0 .../com/taos/example/RestQueryExample.java | 0 .../com/taos/example/StmtInsertExample.java | 0 .../java/com/taos/example/SubscribeDemo.java | 0 .../example/TelnetLineProtocolExample.java | 0 .../com/taos/example/WSConnectExample.java | 0 .../src/test/java/com/taos/test/TestAll.java | 0 .../examples}/node/.gitignore | 0 .../node/nativeexample/async_query_example.js | 0 .../examples}/node/nativeexample/connect.js | 0 .../nativeexample/influxdb_line_example.js | 0 .../node/nativeexample/insert_example.js | 0 .../node/nativeexample/multi_bind_example.js | 0 .../nativeexample/opentsdb_json_example.js | 0 .../nativeexample/opentsdb_telnet_example.js | 0 .../node/nativeexample/param_bind_example.js | 0 .../node/nativeexample/query_example.js | 0 .../node/nativeexample/subscribe_demo.js | 0 .../examples}/node/package.json | 0 .../examples}/node/restexample/connect.js | 0 .../examples}/other/mock.js | 0 .../examples}/php/connect.php | 0 .../examples}/php/insert.php | 0 .../examples}/php/insert_stmt.php | 0 .../examples}/php/query.php | 0 .../examples}/python/.gitignore | 0 .../examples}/python/.gitkeep | 0 .../examples}/python/async_query_example.py | 0 .../examples}/python/bind_param_example.py | 0 .../examples}/python/conn_native_pandas.py | 0 .../examples}/python/conn_rest_pandas.py | 0 .../examples}/python/connect_example.py | 0 .../python/connect_native_reference.py | 0 .../examples}/python/connect_rest_examples.py | 0 .../connection_usage_native_reference.py | 0 .../python/cursor_usage_native_reference.py | 0 .../examples}/python/handle_exception.py | 0 .../examples}/python/json_protocol_example.py | 0 .../examples}/python/line_protocol_example.py | 0 .../examples}/python/multi_bind_example.py | 0 .../examples}/python/native_insert_example.py | 0 .../examples}/python/query_example.py | 0 .../examples}/python/rest_client_example.py | 0 .../examples}/python/result_set_examples.py | 0 .../examples}/python/subscribe_demo.py | 0 .../python/telnet_line_protocol_example.py | 0 .../examples}/rust/Cargo.toml | 0 .../examples}/rust/nativeexample/Cargo.toml | 0 .../rust/nativeexample/examples/connect.rs | 0 .../nativeexample/examples/stmt_example.rs | 0 .../nativeexample/examples/subscribe_demo.rs | 0 .../examples}/rust/nativeexample/src/main.rs | 0 .../examples}/rust/restexample/Cargo.toml | 0 .../rust/restexample/examples/connect.rs | 0 .../restexample/examples/insert_example.rs | 0 .../restexample/examples/query_example.rs | 0 .../examples}/rust/restexample/src/main.rs | 0 .../rust/schemalessexample/Cargo.toml | 0 .../examples/influxdb_line_example.rs | 0 .../examples/opentsdb_json_example.rs | 0 .../examples/opentsdb_telnet_example.rs | 0 .../rust/schemalessexample/src/main.rs | 0 {docs-cn => docs/zh}/01-index.md | 0 {docs-cn => docs/zh}/02-intro.md | 0 .../zh}/04-concept/_category_.yml | 0 {docs-cn => docs/zh}/04-concept/index.md | 0 .../zh}/05-get-started/_apt_get_install.mdx | 0 .../zh}/05-get-started/_category_.yml | 0 .../zh}/05-get-started/_pkg_install.mdx | 0 {docs-cn => docs/zh}/05-get-started/index.md | 0 .../zh}/07-develop/01-connect/_category_.yml | 0 docs/zh/07-develop/01-connect/_connect_c.mdx | 3 ++ .../zh}/07-develop/01-connect/_connect_cs.mdx | 2 +- .../zh}/07-develop/01-connect/_connect_go.mdx | 6 ++-- .../07-develop/01-connect/_connect_java.mdx | 6 ++-- .../07-develop/01-connect/_connect_node.mdx | 7 +++++ .../zh/07-develop/01-connect/_connect_php.mdx | 3 ++ .../07-develop/01-connect/_connect_python.mdx | 3 ++ docs/zh/07-develop/01-connect/_connect_r.mdx | 3 ++ .../07-develop/01-connect/_connect_rust.mdx | 2 +- .../zh}/07-develop/01-connect/index.md | 0 .../zh}/07-develop/02-model/_category_.yml | 0 .../zh}/07-develop/02-model/index.mdx | 0 .../03-insert-data/01-sql-writing.mdx | 0 .../03-insert-data/02-influxdb-line.mdx | 0 .../03-insert-data/03-opentsdb-telnet.mdx | 0 .../03-insert-data/04-opentsdb-json.mdx | 0 docs/zh/07-develop/03-insert-data/_c_line.mdx | 3 ++ .../03-insert-data/_c_opts_json.mdx | 3 ++ .../03-insert-data/_c_opts_telnet.mdx | 3 ++ docs/zh/07-develop/03-insert-data/_c_sql.mdx | 3 ++ docs/zh/07-develop/03-insert-data/_c_stmt.mdx | 6 ++++ .../07-develop/03-insert-data/_category_.yml | 0 .../zh/07-develop/03-insert-data/_cs_line.mdx | 3 ++ .../03-insert-data/_cs_opts_json.mdx | 3 ++ .../03-insert-data/_cs_opts_telnet.mdx | 3 ++ docs/zh/07-develop/03-insert-data/_cs_sql.mdx | 3 ++ .../zh/07-develop/03-insert-data/_cs_stmt.mdx | 3 ++ .../zh/07-develop/03-insert-data/_go_line.mdx | 3 ++ .../03-insert-data/_go_opts_json.mdx | 3 ++ .../03-insert-data/_go_opts_telnet.mdx | 3 ++ docs/zh/07-develop/03-insert-data/_go_sql.mdx | 3 ++ .../07-develop/03-insert-data/_go_stmt.mdx | 2 +- .../07-develop/03-insert-data/_java_line.mdx | 3 ++ .../03-insert-data/_java_opts_json.mdx | 3 ++ .../03-insert-data/_java_opts_telnet.mdx | 3 ++ .../07-develop/03-insert-data/_java_sql.mdx | 3 ++ .../07-develop/03-insert-data/_java_stmt.mdx | 3 ++ .../zh/07-develop/03-insert-data/_js_line.mdx | 3 ++ .../03-insert-data/_js_opts_json.mdx | 3 ++ .../03-insert-data/_js_opts_telnet.mdx | 3 ++ docs/zh/07-develop/03-insert-data/_js_sql.mdx | 3 ++ .../07-develop/03-insert-data/_js_stmt.mdx | 4 +-- .../zh/07-develop/03-insert-data/_php_sql.mdx | 3 ++ .../07-develop/03-insert-data/_php_stmt.mdx | 3 ++ .../zh/07-develop/03-insert-data/_py_line.mdx | 3 ++ .../03-insert-data/_py_opts_json.mdx | 3 ++ .../03-insert-data/_py_opts_telnet.mdx | 3 ++ docs/zh/07-develop/03-insert-data/_py_sql.mdx | 3 ++ .../07-develop/03-insert-data/_py_stmt.mdx | 4 +-- .../07-develop/03-insert-data/_rust_line.mdx | 3 ++ .../03-insert-data/_rust_opts_json.mdx | 3 ++ .../03-insert-data/_rust_opts_telnet.mdx | 3 ++ .../07-develop/03-insert-data/_rust_sql.mdx | 3 ++ .../07-develop/03-insert-data/_rust_stmt.mdx | 3 ++ .../zh}/07-develop/03-insert-data/index.md | 0 docs/zh/07-develop/04-query-data/_c.mdx | 3 ++ docs/zh/07-develop/04-query-data/_c_async.mdx | 3 ++ .../07-develop/04-query-data/_category_.yml | 0 docs/zh/07-develop/04-query-data/_cs.mdx | 3 ++ .../zh/07-develop/04-query-data/_cs_async.mdx | 3 ++ docs/zh/07-develop/04-query-data/_go.mdx | 3 ++ .../zh/07-develop/04-query-data/_go_async.mdx | 3 ++ docs/zh/07-develop/04-query-data/_java.mdx | 3 ++ docs/zh/07-develop/04-query-data/_js.mdx | 3 ++ .../zh/07-develop/04-query-data/_js_async.mdx | 3 ++ docs/zh/07-develop/04-query-data/_php.mdx | 3 ++ .../zh}/07-develop/04-query-data/_py.mdx | 4 +-- .../07-develop/04-query-data/_py_async.mdx | 2 +- docs/zh/07-develop/04-query-data/_rust.mdx | 3 ++ .../zh}/07-develop/04-query-data/index.mdx | 0 .../zh}/07-develop/05-delete-data.mdx | 0 .../zh}/07-develop/06-continuous-query.mdx | 0 .../zh}/07-develop/07-subscribe.mdx | 0 {docs-cn => docs/zh}/07-develop/08-cache.md | 0 {docs-cn => docs/zh}/07-develop/09-udf.md | 0 .../zh}/07-develop/_category_.yml | 0 docs/zh/07-develop/_sub_c.mdx | 3 ++ docs/zh/07-develop/_sub_cs.mdx | 3 ++ docs/zh/07-develop/_sub_go.mdx | 3 ++ {docs-cn => docs/zh}/07-develop/_sub_java.mdx | 2 +- docs/zh/07-develop/_sub_node.mdx | 3 ++ docs/zh/07-develop/_sub_python.mdx | 3 ++ docs/zh/07-develop/_sub_rust.mdx | 3 ++ {docs-cn => docs/zh}/07-develop/index.md | 0 {docs-cn => docs/zh}/10-cluster/01-deploy.md | 0 .../zh}/10-cluster/02-cluster-mgmt.md | 0 .../zh}/10-cluster/03-ha-and-lb.md | 0 .../zh}/10-cluster/_category_.yml | 0 {docs-cn => docs/zh}/10-cluster/index.md | 0 .../zh}/12-taos-sql/01-data-type.md | 0 .../zh}/12-taos-sql/02-database.md | 0 {docs-cn => docs/zh}/12-taos-sql/03-table.md | 0 {docs-cn => docs/zh}/12-taos-sql/04-stable.md | 0 {docs-cn => docs/zh}/12-taos-sql/05-insert.md | 0 {docs-cn => docs/zh}/12-taos-sql/06-select.md | 0 .../zh}/12-taos-sql/07-function.md | 0 .../zh}/12-taos-sql/08-interval.md | 0 {docs-cn => docs/zh}/12-taos-sql/09-limit.md | 0 {docs-cn => docs/zh}/12-taos-sql/10-json.md | 0 {docs-cn => docs/zh}/12-taos-sql/11-escape.md | 0 .../12-taos-sql/12-keywords/_category_.yml | 0 .../zh}/12-taos-sql/12-keywords/index.md | 0 .../zh}/12-taos-sql/_category_.yml | 0 {docs-cn => docs/zh}/12-taos-sql/index.md | 0 .../zh}/12-taos-sql/timewindow-1.webp | Bin .../zh}/12-taos-sql/timewindow-2.webp | Bin .../zh}/12-taos-sql/timewindow-3.webp | Bin .../zh}/13-operation/01-pkg-install.md | 0 .../zh}/13-operation/02-planning.mdx | 0 .../zh}/13-operation/03-tolerance.md | 0 {docs-cn => docs/zh}/13-operation/06-admin.md | 0 .../zh}/13-operation/07-import.md | 0 .../zh}/13-operation/08-export.md | 0 .../zh}/13-operation/09-status.md | 0 .../zh}/13-operation/10-monitor.md | 0 .../zh}/13-operation/11-optimize.md | 0 .../zh}/13-operation/17-diagnose.md | 0 .../zh}/13-operation/_category_.yml | 0 {docs-cn => docs/zh}/13-operation/index.md | 0 .../14-reference/02-rest-api/02-rest-api.mdx | 0 .../14-reference/02-rest-api/_category_.yml | 0 .../03-connector/03-connector.mdx | 0 .../14-reference/03-connector/_category_.yml | 0 .../03-connector/_linux_install.mdx | 0 .../03-connector/_preparition.mdx | 0 .../03-connector/_verify_linux.mdx | 28 +++++++++--------- .../03-connector/_verify_windows.mdx | 28 +++++++++--------- .../03-connector/_windows_install.mdx | 0 .../14-reference/03-connector/connector.webp | Bin .../zh}/14-reference/03-connector/cpp.mdx | 0 .../zh}/14-reference/03-connector/csharp.mdx | 0 .../zh}/14-reference/03-connector/go.mdx | 0 .../zh}/14-reference/03-connector/java.mdx | 0 .../zh}/14-reference/03-connector/node.mdx | 0 .../zh}/14-reference/03-connector/php.mdx | 8 ++--- .../zh}/14-reference/03-connector/python.mdx | 22 +++++++------- .../zh}/14-reference/03-connector/rust.mdx | 0 .../03-connector/tdengine-jdbc-connector.webp | Bin .../zh}/14-reference/04-taosadapter.md | 0 .../zh}/14-reference/05-taosbenchmark.md | 0 .../zh}/14-reference/06-taosdump.md | 0 .../15146-tdengine-monitor-dashboard.json | 0 .../assets/15155-tdengine-alert-demo.json | 0 .../assets/TDinsight-1-cluster-status.webp | Bin .../assets/TDinsight-2-dnodes.webp | Bin .../assets/TDinsight-3-mnodes.webp | Bin .../assets/TDinsight-4-requests.webp | Bin .../assets/TDinsight-5-database.webp | Bin .../assets/TDinsight-6-dnode-usage.webp | Bin .../assets/TDinsight-7-login-history.webp | Bin .../assets/TDinsight-8-taosadapter.webp | Bin .../07-tdinsight/assets/TDinsight-full.webp | Bin .../assets/alert-manager-status.webp | Bin .../assets/alert-notification-channel.webp | Bin .../07-tdinsight/assets/alert-query-demo.webp | Bin .../alert-rule-condition-notifications.webp | Bin .../07-tdinsight/assets/alert-rule-test.webp | Bin .../assets/howto-add-datasource-button.webp | Bin .../assets/howto-add-datasource-tdengine.webp | Bin .../assets/howto-add-datasource-test.webp | Bin .../assets/howto-add-datasource.webp | Bin .../assets/howto-dashboard-display.webp | Bin .../howto-dashboard-import-options.webp | Bin .../assets/howto-import-dashboard.webp | Bin .../assets/import-dashboard-15167.webp | Bin .../assets/import-dashboard-for-tdengine.webp | Bin .../assets/import-via-grafana-dot-com.webp | Bin .../07-tdinsight/assets/import_dashboard.webp | Bin .../assets/tdengine-grafana-7.x.json | 0 .../07-tdinsight/assets/tdengine-grafana.json | 0 .../assets/tdengine_dashboard.webp | Bin .../zh}/14-reference/07-tdinsight/index.md | 0 .../zh}/14-reference/08-taos-shell.md | 0 .../09-support-platform/_category_.yml | 0 .../14-reference/09-support-platform/index.md | 0 .../zh}/14-reference/11-docker/_category_.yml | 0 .../zh}/14-reference/11-docker/index.md | 0 .../zh}/14-reference/12-config/_category_.yml | 0 .../zh}/14-reference/12-config/index.md | 0 .../zh}/14-reference/12-directory.md | 0 .../13-schemaless/13-schemaless.md | 0 .../14-reference/13-schemaless/_category_.yml | 0 .../zh}/14-reference/_category_.yml | 0 .../zh}/14-reference/_collectd.mdx | 0 .../zh}/14-reference/_icinga2.mdx | 0 .../zh}/14-reference/_prometheus.mdx | 0 {docs-cn => docs/zh}/14-reference/_statsd.mdx | 0 .../zh}/14-reference/_tcollector.mdx | 0 .../zh}/14-reference/_telegraf.mdx | 0 {docs-cn => docs/zh}/14-reference/index.md | 0 .../taosAdapter-architecture.webp | Bin .../zh}/20-third-party/01-grafana.mdx | 0 .../zh}/20-third-party/02-prometheus.md | 0 .../zh}/20-third-party/03-telegraf.md | 0 .../zh}/20-third-party/05-collectd.md | 0 .../zh}/20-third-party/06-statsd.md | 0 .../zh}/20-third-party/07-icinga2.md | 0 .../zh}/20-third-party/08-tcollector.md | 0 .../zh}/20-third-party/09-emq-broker.md | 2 +- .../zh}/20-third-party/10-hive-mq-broker.md | 0 .../zh}/20-third-party/11-kafka.md | 0 .../zh}/20-third-party/_category_.yml | 0 .../zh}/20-third-party/_deploytaosadapter.mdx | 0 .../zh/20-third-party}/add_datasource1.webp | Bin .../zh/20-third-party}/add_datasource2.webp | Bin .../zh/20-third-party}/add_datasource3.webp | Bin .../zh/20-third-party}/add_datasource4.webp | Bin .../zh/20-third-party}/create_dashboard1.webp | Bin .../zh/20-third-party}/create_dashboard2.webp | Bin .../zh}/20-third-party/dashboard-15146.webp | Bin .../emqx/add-action-handler.webp | Bin .../emqx/check-result-in-taos.webp | Bin .../emqx/check-rule-matched.webp | Bin .../zh}/20-third-party/emqx/client-num.webp | Bin .../20-third-party/emqx/create-resource.webp | Bin .../zh}/20-third-party/emqx/create-rule.webp | Bin .../zh}/20-third-party/emqx/edit-action.webp | Bin .../20-third-party/emqx/edit-resource.webp | Bin .../20-third-party/emqx/login-dashboard.webp | Bin .../zh}/20-third-party/emqx/rule-engine.webp | Bin .../emqx/rule-header-key-value.webp | Bin .../zh}/20-third-party/emqx/run-mock.webp | Bin .../zh}/20-third-party/import_dashboard1.webp | Bin .../zh}/20-third-party/import_dashboard2.webp | Bin {docs-cn => docs/zh}/20-third-party/index.md | 0 .../20-third-party/kafka/Kafka_Connect.webp | Bin .../kafka/confluentPlatform.webp | Bin ...eaming-integration-with-kafka-connect.webp | Bin {docs-cn => docs/zh}/21-tdinternal/01-arch.md | 0 .../zh}/21-tdinternal/02-replica.md | 0 .../zh}/21-tdinternal/03-taosd.md | 0 .../zh}/21-tdinternal/12-tsz-compress.md | 0 .../zh}/21-tdinternal/30-iot-big-data.md | 0 .../zh}/21-tdinternal/_category_.yml | 0 {docs-en => docs/zh}/21-tdinternal/dnode.webp | Bin {docs-cn => docs/zh}/21-tdinternal/index.md | 0 .../zh}/21-tdinternal/message.webp | Bin .../zh}/21-tdinternal/modules.webp | Bin .../zh}/21-tdinternal/multi_tables.webp | Bin .../zh}/21-tdinternal/replica-forward.webp | Bin .../zh}/21-tdinternal/replica-master.webp | Bin .../zh}/21-tdinternal/replica-restore.webp | Bin .../zh}/21-tdinternal/structure.webp | Bin {docs-en => docs/zh}/21-tdinternal/vnode.webp | Bin .../zh}/21-tdinternal/write_master.webp | Bin .../zh}/21-tdinternal/write_slave.webp | Bin .../zh}/25-application/01-telegraf.md | 0 .../zh}/25-application/02-collectd.md | 0 .../zh}/25-application/03-immigrate.md | 0 .../IT-DevOps-Solutions-Collectd-StatsD.webp | Bin ...Ops-Solutions-Immigrate-OpenTSDB-Arch.webp | Bin ...olutions-Immigrate-OpenTSDB-Dashboard.webp | Bin ...Ops-Solutions-Immigrate-TDengine-Arch.webp | Bin .../IT-DevOps-Solutions-Telegraf.webp | Bin ...T-DevOps-Solutions-collectd-dashboard.webp | Bin .../IT-DevOps-Solutions-statsd-dashboard.webp | Bin ...T-DevOps-Solutions-telegraf-dashboard.webp | Bin .../zh}/25-application/_category_.yml | 0 {docs-cn => docs/zh}/25-application/index.md | 0 {docs-cn => docs/zh}/27-train-faq/01-faq.md | 0 .../zh}/27-train-faq/02-video.mdx | 0 .../zh}/27-train-faq/03-docker.md | 0 .../zh}/27-train-faq/_category_.yml | 0 {docs-cn => docs/zh}/27-train-faq/index.md | 0 {docs-en => docs/zh}/30-release/01-2.6.md | 0 {docs-en => docs/zh}/30-release/02-2.4.md | 0 .../zh}/30-release/_category_.yml | 0 {docs-cn => docs/zh}/30-release/index.md | 0 {docs-en/02-intro => docs/zh}/eco_system.webp | Bin tests/docs-examples-test/test_R.sh | 2 +- tests/docs-examples-test/test_c.sh | 2 +- tests/docs-examples-test/test_csharp.sh | 2 +- tests/docs-examples-test/test_go.sh | 2 +- tests/docs-examples-test/test_java.sh | 2 +- tests/docs-examples-test/test_node.sh | 2 +- tests/docs-examples-test/test_python.sh | 2 +- tests/docs-examples-test/test_rust.sh | 2 +- 779 files changed, 454 insertions(+), 454 deletions(-) delete mode 100644 docs-cn/07-develop/01-connect/_connect_c.mdx delete mode 100644 docs-cn/07-develop/01-connect/_connect_node.mdx delete mode 100644 docs-cn/07-develop/01-connect/_connect_php.mdx delete mode 100644 docs-cn/07-develop/01-connect/_connect_python.mdx delete mode 100644 docs-cn/07-develop/01-connect/_connect_r.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_c_line.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_c_opts_json.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_c_opts_telnet.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_c_sql.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_c_stmt.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_cs_line.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_cs_opts_json.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_cs_opts_telnet.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_cs_sql.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_cs_stmt.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_go_line.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_go_opts_json.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_go_opts_telnet.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_go_sql.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_java_line.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_java_opts_json.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_java_opts_telnet.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_java_sql.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_java_stmt.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_js_line.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_js_opts_json.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_js_opts_telnet.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_js_sql.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_php_sql.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_php_stmt.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_py_line.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_py_opts_json.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_py_opts_telnet.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_py_sql.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_rust_line.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_rust_opts_json.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_rust_opts_telnet.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_rust_sql.mdx delete mode 100644 docs-cn/07-develop/03-insert-data/_rust_stmt.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_c.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_c_async.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_cs.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_cs_async.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_go.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_go_async.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_java.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_js.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_js_async.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_php.mdx delete mode 100644 docs-cn/07-develop/04-query-data/_rust.mdx delete mode 100644 docs-cn/07-develop/_sub_c.mdx delete mode 100644 docs-cn/07-develop/_sub_cs.mdx delete mode 100644 docs-cn/07-develop/_sub_go.mdx delete mode 100644 docs-cn/07-develop/_sub_node.mdx delete mode 100644 docs-cn/07-develop/_sub_python.mdx delete mode 100644 docs-cn/07-develop/_sub_rust.mdx delete mode 100644 docs-en/07-develop/01-connect/_connect_c.mdx delete mode 100644 docs-en/07-develop/01-connect/_connect_node.mdx delete mode 100644 docs-en/07-develop/01-connect/_connect_python.mdx delete mode 100644 docs-en/07-develop/01-connect/_connect_r.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_c_line.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_c_opts_json.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_c_opts_telnet.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_c_sql.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_c_stmt.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_cs_line.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_cs_opts_json.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_cs_opts_telnet.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_cs_sql.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_cs_stmt.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_go_line.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_go_opts_json.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_go_opts_telnet.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_go_sql.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_java_line.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_java_opts_json.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_java_opts_telnet.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_java_sql.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_java_stmt.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_js_line.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_js_opts_json.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_js_opts_telnet.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_js_sql.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_py_line.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_py_opts_json.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_py_opts_telnet.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_py_sql.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_rust_line.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_rust_opts_json.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_rust_opts_telnet.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_rust_sql.mdx delete mode 100644 docs-en/07-develop/03-insert-data/_rust_stmt.mdx delete mode 100644 docs-en/07-develop/04-query-data/_c.mdx delete mode 100644 docs-en/07-develop/04-query-data/_c_async.mdx delete mode 100644 docs-en/07-develop/04-query-data/_cs.mdx delete mode 100644 docs-en/07-develop/04-query-data/_cs_async.mdx delete mode 100644 docs-en/07-develop/04-query-data/_go.mdx delete mode 100644 docs-en/07-develop/04-query-data/_go_async.mdx delete mode 100644 docs-en/07-develop/04-query-data/_java.mdx delete mode 100644 docs-en/07-develop/04-query-data/_js.mdx delete mode 100644 docs-en/07-develop/04-query-data/_js_async.mdx delete mode 100644 docs-en/07-develop/04-query-data/_rust.mdx delete mode 100644 docs-en/07-develop/_sub_c.mdx delete mode 100644 docs-en/07-develop/_sub_cs.mdx delete mode 100644 docs-en/07-develop/_sub_go.mdx delete mode 100644 docs-en/07-develop/_sub_node.mdx delete mode 100644 docs-en/07-develop/_sub_python.mdx delete mode 100644 docs-en/07-develop/_sub_rust.mdx rename {docs-en => docs/en}/01-index.md (100%) rename {docs-en => docs/en}/02-intro/_category_.yml (100%) rename {docs-cn => docs/en/02-intro}/eco_system.webp (100%) rename {docs-en => docs/en}/02-intro/index.md (100%) rename {docs-en => docs/en}/04-concept/_category_.yml (100%) rename {docs-en => docs/en}/04-concept/index.md (100%) rename {docs-en => docs/en}/05-get-started/_apt_get_install.mdx (100%) rename {docs-en => docs/en}/05-get-started/_category_.yml (100%) rename {docs-en => docs/en}/05-get-started/_pkg_install.mdx (100%) rename {docs-en => docs/en}/05-get-started/index.md (100%) rename {docs-en => docs/en}/07-develop/01-connect/_category_.yml (100%) create mode 100644 docs/en/07-develop/01-connect/_connect_c.mdx rename {docs-en => docs/en}/07-develop/01-connect/_connect_cs.mdx (67%) rename {docs-en => docs/en}/07-develop/01-connect/_connect_go.mdx (69%) rename {docs-en => docs/en}/07-develop/01-connect/_connect_java.mdx (68%) create mode 100644 docs/en/07-develop/01-connect/_connect_node.mdx create mode 100644 docs/en/07-develop/01-connect/_connect_python.mdx create mode 100644 docs/en/07-develop/01-connect/_connect_r.mdx rename {docs-en => docs/en}/07-develop/01-connect/_connect_rust.mdx (78%) rename {docs-en => docs/en}/07-develop/01-connect/index.md (100%) rename {docs-en => docs/en}/07-develop/02-model/_category_.yml (100%) rename {docs-en => docs/en}/07-develop/02-model/index.mdx (100%) rename {docs-en => docs/en}/07-develop/03-insert-data/01-sql-writing.mdx (100%) rename {docs-en => docs/en}/07-develop/03-insert-data/02-influxdb-line.mdx (100%) rename {docs-en => docs/en}/07-develop/03-insert-data/03-opentsdb-telnet.mdx (100%) rename {docs-en => docs/en}/07-develop/03-insert-data/04-opentsdb-json.mdx (100%) create mode 100644 docs/en/07-develop/03-insert-data/_c_line.mdx create mode 100644 docs/en/07-develop/03-insert-data/_c_opts_json.mdx create mode 100644 docs/en/07-develop/03-insert-data/_c_opts_telnet.mdx create mode 100644 docs/en/07-develop/03-insert-data/_c_sql.mdx create mode 100644 docs/en/07-develop/03-insert-data/_c_stmt.mdx rename {docs-en => docs/en}/07-develop/03-insert-data/_category_.yml (100%) create mode 100644 docs/en/07-develop/03-insert-data/_cs_line.mdx create mode 100644 docs/en/07-develop/03-insert-data/_cs_opts_json.mdx create mode 100644 docs/en/07-develop/03-insert-data/_cs_opts_telnet.mdx create mode 100644 docs/en/07-develop/03-insert-data/_cs_sql.mdx create mode 100644 docs/en/07-develop/03-insert-data/_cs_stmt.mdx create mode 100644 docs/en/07-develop/03-insert-data/_go_line.mdx create mode 100644 docs/en/07-develop/03-insert-data/_go_opts_json.mdx create mode 100644 docs/en/07-develop/03-insert-data/_go_opts_telnet.mdx create mode 100644 docs/en/07-develop/03-insert-data/_go_sql.mdx rename {docs-en => docs/en}/07-develop/03-insert-data/_go_stmt.mdx (76%) create mode 100644 docs/en/07-develop/03-insert-data/_java_line.mdx create mode 100644 docs/en/07-develop/03-insert-data/_java_opts_json.mdx create mode 100644 docs/en/07-develop/03-insert-data/_java_opts_telnet.mdx create mode 100644 docs/en/07-develop/03-insert-data/_java_sql.mdx create mode 100644 docs/en/07-develop/03-insert-data/_java_stmt.mdx create mode 100644 docs/en/07-develop/03-insert-data/_js_line.mdx create mode 100644 docs/en/07-develop/03-insert-data/_js_opts_json.mdx create mode 100644 docs/en/07-develop/03-insert-data/_js_opts_telnet.mdx create mode 100644 docs/en/07-develop/03-insert-data/_js_sql.mdx rename {docs-en => docs/en}/07-develop/03-insert-data/_js_stmt.mdx (70%) create mode 100644 docs/en/07-develop/03-insert-data/_py_line.mdx create mode 100644 docs/en/07-develop/03-insert-data/_py_opts_json.mdx create mode 100644 docs/en/07-develop/03-insert-data/_py_opts_telnet.mdx create mode 100644 docs/en/07-develop/03-insert-data/_py_sql.mdx rename {docs-en => docs/en}/07-develop/03-insert-data/_py_stmt.mdx (69%) create mode 100644 docs/en/07-develop/03-insert-data/_rust_line.mdx create mode 100644 docs/en/07-develop/03-insert-data/_rust_opts_json.mdx create mode 100644 docs/en/07-develop/03-insert-data/_rust_opts_telnet.mdx create mode 100644 docs/en/07-develop/03-insert-data/_rust_sql.mdx create mode 100644 docs/en/07-develop/03-insert-data/_rust_stmt.mdx rename {docs-en => docs/en}/07-develop/03-insert-data/index.md (100%) create mode 100644 docs/en/07-develop/04-query-data/_c.mdx create mode 100644 docs/en/07-develop/04-query-data/_c_async.mdx rename {docs-en => docs/en}/07-develop/04-query-data/_category_.yml (100%) create mode 100644 docs/en/07-develop/04-query-data/_cs.mdx create mode 100644 docs/en/07-develop/04-query-data/_cs_async.mdx create mode 100644 docs/en/07-develop/04-query-data/_go.mdx create mode 100644 docs/en/07-develop/04-query-data/_go_async.mdx create mode 100644 docs/en/07-develop/04-query-data/_java.mdx create mode 100644 docs/en/07-develop/04-query-data/_js.mdx create mode 100644 docs/en/07-develop/04-query-data/_js_async.mdx rename {docs-en => docs/en}/07-develop/04-query-data/_py.mdx (53%) rename {docs-en => docs/en}/07-develop/04-query-data/_py_async.mdx (58%) create mode 100644 docs/en/07-develop/04-query-data/_rust.mdx rename {docs-en => docs/en}/07-develop/04-query-data/index.mdx (100%) rename {docs-en => docs/en}/07-develop/05-delete-data.mdx (100%) rename {docs-en => docs/en}/07-develop/06-continuous-query.mdx (100%) rename {docs-en => docs/en}/07-develop/07-subscribe.mdx (100%) rename {docs-en => docs/en}/07-develop/08-cache.md (100%) rename {docs-en => docs/en}/07-develop/09-udf.md (100%) rename {docs-en => docs/en}/07-develop/_category_.yml (100%) create mode 100644 docs/en/07-develop/_sub_c.mdx create mode 100644 docs/en/07-develop/_sub_cs.mdx create mode 100644 docs/en/07-develop/_sub_go.mdx rename {docs-en => docs/en}/07-develop/_sub_java.mdx (70%) create mode 100644 docs/en/07-develop/_sub_node.mdx create mode 100644 docs/en/07-develop/_sub_python.mdx create mode 100644 docs/en/07-develop/_sub_rust.mdx rename {docs-en => docs/en}/07-develop/index.md (100%) rename {docs-en => docs/en}/10-cluster/01-deploy.md (100%) rename {docs-en => docs/en}/10-cluster/02-cluster-mgmt.md (100%) rename {docs-en => docs/en}/10-cluster/03-ha-and-lb.md (100%) rename {docs-en => docs/en}/10-cluster/_category_.yml (100%) rename {docs-en => docs/en}/10-cluster/index.md (100%) rename {docs-en => docs/en}/12-taos-sql/01-data-type.md (100%) rename {docs-en => docs/en}/12-taos-sql/02-database.md (100%) rename {docs-en => docs/en}/12-taos-sql/03-table.md (100%) rename {docs-en => docs/en}/12-taos-sql/04-stable.md (100%) rename {docs-en => docs/en}/12-taos-sql/05-insert.md (100%) rename {docs-en => docs/en}/12-taos-sql/06-select.md (100%) rename {docs-en => docs/en}/12-taos-sql/07-function.md (100%) rename {docs-en => docs/en}/12-taos-sql/08-interval.md (100%) rename {docs-en => docs/en}/12-taos-sql/09-limit.md (100%) rename {docs-en => docs/en}/12-taos-sql/10-json.md (100%) rename {docs-en => docs/en}/12-taos-sql/11-escape.md (100%) rename {docs-en => docs/en}/12-taos-sql/12-keywords.md (100%) rename {docs-en => docs/en}/12-taos-sql/_category_.yml (100%) rename {docs-en => docs/en}/12-taos-sql/index.md (100%) rename {docs-cn => docs/en}/12-taos-sql/timewindow-1.webp (100%) rename {docs-cn => docs/en}/12-taos-sql/timewindow-2.webp (100%) rename {docs-cn => docs/en}/12-taos-sql/timewindow-3.webp (100%) rename {docs-en => docs/en}/13-operation/01-pkg-install.md (100%) rename {docs-en => docs/en}/13-operation/02-planning.mdx (100%) rename {docs-en => docs/en}/13-operation/03-tolerance.md (100%) rename {docs-en => docs/en}/13-operation/06-admin.md (100%) rename {docs-en => docs/en}/13-operation/07-import.md (100%) rename {docs-en => docs/en}/13-operation/08-export.md (100%) rename {docs-en => docs/en}/13-operation/09-status.md (100%) rename {docs-en => docs/en}/13-operation/10-monitor.md (100%) rename {docs-en => docs/en}/13-operation/11-optimize.md (100%) rename {docs-en => docs/en}/13-operation/17-diagnose.md (100%) rename {docs-en => docs/en}/13-operation/_category_.yml (100%) rename {docs-en => docs/en}/13-operation/index.md (100%) rename {docs-en => docs/en}/14-reference/02-rest-api/02-rest-api.mdx (100%) rename {docs-cn => docs/en}/14-reference/02-rest-api/_category_.yml (100%) rename {docs-en => docs/en}/14-reference/03-connector/03-connector.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/_category_.yml (100%) rename {docs-en => docs/en}/14-reference/03-connector/_linux_install.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/_preparation.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/_verify_linux.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/_verify_windows.mdx (98%) rename {docs-en => docs/en}/14-reference/03-connector/_windows_install.mdx (100%) rename {docs-cn => docs/en}/14-reference/03-connector/connector.webp (100%) rename {docs-en => docs/en}/14-reference/03-connector/cpp.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/csharp.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/go.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/java.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/node.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/php.mdx (95%) rename {docs-en => docs/en}/14-reference/03-connector/python.mdx (95%) rename {docs-en => docs/en}/14-reference/03-connector/rust.mdx (100%) rename {docs-en => docs/en}/14-reference/03-connector/tdengine-jdbc-connector.webp (100%) rename {docs-en => docs/en}/14-reference/04-taosadapter.md (100%) rename {docs-en => docs/en}/14-reference/05-taosbenchmark.md (100%) rename {docs-en => docs/en}/14-reference/06-taosdump.md (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/TDinsight-5-database.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/TDinsight-full.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/alert-manager-status.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/alert-notification-channel.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/alert-query-demo.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/alert-rule-test.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/howto-add-datasource.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/howto-dashboard-display.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/howto-import-dashboard.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/import-dashboard-15167.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/import_dashboard.webp (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/tdengine-grafana.json (100%) rename {docs-cn => docs/en}/14-reference/07-tdinsight/assets/tdengine_dashboard.webp (100%) rename {docs-en => docs/en}/14-reference/07-tdinsight/index.md (100%) rename {docs-en => docs/en}/14-reference/08-taos-shell.md (100%) rename {docs-en => docs/en}/14-reference/09-support-platform/_category_.yml (100%) rename {docs-en => docs/en}/14-reference/09-support-platform/index.md (100%) rename {docs-en => docs/en}/14-reference/11-docker/_category_.yml (100%) rename {docs-en => docs/en}/14-reference/11-docker/index.md (100%) rename {docs-en => docs/en}/14-reference/12-config/_category_.yml (100%) rename {docs-en => docs/en}/14-reference/12-config/index.md (100%) rename {docs-en => docs/en}/14-reference/12-directory.md (100%) rename {docs-en => docs/en}/14-reference/13-schemaless/13-schemaless.md (100%) rename {docs-en => docs/en}/14-reference/13-schemaless/_category_.yml (100%) rename {docs-en => docs/en}/14-reference/_category_.yml (100%) rename {docs-en => docs/en}/14-reference/_collectd.mdx (100%) rename {docs-en => docs/en}/14-reference/_icinga2.mdx (100%) rename {docs-en => docs/en}/14-reference/_prometheus.mdx (100%) rename {docs-en => docs/en}/14-reference/_statsd.mdx (100%) rename {docs-en => docs/en}/14-reference/_tcollector.mdx (100%) rename {docs-en => docs/en}/14-reference/_telegraf.mdx (100%) rename {docs-en => docs/en}/14-reference/index.md (100%) rename {docs-cn => docs/en}/14-reference/taosAdapter-architecture.webp (100%) rename {docs-en => docs/en}/20-third-party/01-grafana.mdx (100%) rename {docs-en => docs/en}/20-third-party/02-prometheus.md (100%) rename {docs-en => docs/en}/20-third-party/03-telegraf.md (100%) rename {docs-en => docs/en}/20-third-party/05-collectd.md (100%) rename {docs-en => docs/en}/20-third-party/06-statsd.md (100%) rename {docs-en => docs/en}/20-third-party/07-icinga2.md (100%) rename {docs-en => docs/en}/20-third-party/08-tcollector.md (100%) rename {docs-en => docs/en}/20-third-party/09-emq-broker.md (99%) rename {docs-en => docs/en}/20-third-party/10-hive-mq-broker.md (100%) rename {docs-en => docs/en}/20-third-party/11-kafka.md (100%) rename {docs-en => docs/en}/20-third-party/_category_.yml (100%) rename {docs-en => docs/en}/20-third-party/_deploytaosadapter.mdx (100%) rename {docs-cn => docs/en}/20-third-party/emqx/add-action-handler.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/check-result-in-taos.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/check-rule-matched.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/client-num.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/create-resource.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/create-rule.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/edit-action.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/edit-resource.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/login-dashboard.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/rule-engine.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/rule-header-key-value.webp (100%) rename {docs-cn => docs/en}/20-third-party/emqx/run-mock.webp (100%) rename {docs-cn/20-third-party => docs/en/20-third-party/grafana}/add_datasource1.webp (100%) rename {docs-cn/20-third-party => docs/en/20-third-party/grafana}/add_datasource2.webp (100%) rename {docs-cn/20-third-party => docs/en/20-third-party/grafana}/add_datasource3.webp (100%) rename {docs-cn/20-third-party => docs/en/20-third-party/grafana}/add_datasource4.webp (100%) rename {docs-cn/20-third-party => docs/en/20-third-party/grafana}/create_dashboard1.webp (100%) rename {docs-cn/20-third-party => docs/en/20-third-party/grafana}/create_dashboard2.webp (100%) rename {docs-en => docs/en}/20-third-party/index.md (100%) rename {docs-cn => docs/en}/20-third-party/kafka/Kafka_Connect.webp (100%) rename {docs-cn => docs/en}/20-third-party/kafka/confluentPlatform.webp (100%) rename {docs-cn => docs/en}/20-third-party/kafka/streaming-integration-with-kafka-connect.webp (100%) rename {docs-en => docs/en}/21-tdinternal/01-arch.md (100%) rename {docs-en => docs/en}/21-tdinternal/30-iot-big-data.md (100%) rename {docs-en => docs/en}/21-tdinternal/_category_.yml (100%) rename {docs-cn => docs/en}/21-tdinternal/dnode.webp (100%) rename {docs-en => docs/en}/21-tdinternal/index.md (100%) rename {docs-cn => docs/en}/21-tdinternal/message.webp (100%) rename {docs-cn => docs/en}/21-tdinternal/modules.webp (100%) rename {docs-cn => docs/en}/21-tdinternal/multi_tables.webp (100%) rename {docs-cn => docs/en}/21-tdinternal/replica-forward.webp (100%) rename {docs-cn => docs/en}/21-tdinternal/replica-master.webp (100%) rename {docs-cn => docs/en}/21-tdinternal/replica-restore.webp (100%) rename {docs-cn => docs/en}/21-tdinternal/structure.webp (100%) rename {docs-cn => docs/en}/21-tdinternal/vnode.webp (100%) rename {docs-cn => docs/en}/21-tdinternal/write_master.webp (100%) rename {docs-cn => docs/en}/21-tdinternal/write_slave.webp (100%) rename {docs-en => docs/en}/25-application/01-telegraf.md (100%) rename {docs-en => docs/en}/25-application/02-collectd.md (100%) rename {docs-en => docs/en}/25-application/03-immigrate.md (100%) rename {docs-cn => docs/en}/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp (100%) rename {docs-cn => docs/en}/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp (100%) rename {docs-cn => docs/en}/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp (100%) rename {docs-cn => docs/en}/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp (100%) rename {docs-cn => docs/en}/25-application/IT-DevOps-Solutions-Telegraf.webp (100%) rename {docs-cn => docs/en}/25-application/IT-DevOps-Solutions-collectd-dashboard.webp (100%) rename {docs-cn => docs/en}/25-application/IT-DevOps-Solutions-statsd-dashboard.webp (100%) rename {docs-cn => docs/en}/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp (100%) rename {docs-en => docs/en}/25-application/_category_.yml (100%) rename {docs-en => docs/en}/25-application/index.md (100%) rename {docs-en => docs/en}/27-train-faq/01-faq.md (100%) rename {docs-en => docs/en}/27-train-faq/03-docker.md (100%) rename {docs-en => docs/en}/27-train-faq/_category_.yml (100%) rename {docs-en => docs/en}/27-train-faq/index.md (100%) rename {docs-cn => docs/en}/30-release/01-2.6.md (100%) rename {docs-cn => docs/en}/30-release/02-2.4.md (100%) rename {docs-en => docs/en}/30-release/_category_.yml (100%) rename {docs-en => docs/en}/30-release/index.md (100%) rename {docs-examples => docs/examples}/.gitignore (100%) rename {docs-examples => docs/examples}/.gitignre (100%) rename {docs-examples => docs/examples}/R/connect_native.r (100%) rename {docs-examples => docs/examples}/R/connect_rest.r (100%) rename {docs-examples => docs/examples}/c/.gitignore (100%) rename {docs-examples => docs/examples}/c/async_query_example.c (100%) rename {docs-examples => docs/examples}/c/connect_example.c (100%) rename {docs-examples => docs/examples}/c/error_handle_example.c (100%) rename {docs-examples => docs/examples}/c/insert_example.c (100%) rename {docs-examples => docs/examples}/c/json_protocol_example.c (100%) rename {docs-examples => docs/examples}/c/line_example.c (100%) rename {docs-examples => docs/examples}/c/multi_bind_example.c (100%) rename {docs-examples => docs/examples}/c/query_example.c (100%) rename {docs-examples => docs/examples}/c/stmt_example.c (100%) rename {docs-examples => docs/examples}/c/subscribe_demo.c (100%) rename {docs-examples => docs/examples}/c/telnet_line_example.c (100%) rename {docs-examples => docs/examples}/csharp/.gitignore (100%) rename {docs-examples => docs/examples}/csharp/AsyncQueryExample.cs (100%) rename {docs-examples => docs/examples}/csharp/ConnectExample.cs (100%) rename {docs-examples => docs/examples}/csharp/InfluxDBLineExample.cs (100%) rename {docs-examples => docs/examples}/csharp/OptsJsonExample.cs (100%) rename {docs-examples => docs/examples}/csharp/OptsTelnetExample.cs (100%) rename {docs-examples => docs/examples}/csharp/QueryExample.cs (100%) rename {docs-examples => docs/examples}/csharp/SQLInsertExample.cs (100%) rename {docs-examples => docs/examples}/csharp/StmtInsertExample.cs (100%) rename {docs-examples => docs/examples}/csharp/SubscribeDemo.cs (100%) rename {docs-examples => docs/examples}/csharp/asyncquery.csproj (100%) rename {docs-examples => docs/examples}/csharp/connect.csproj (100%) rename {docs-examples => docs/examples}/csharp/influxdbline.csproj (100%) rename {docs-examples => docs/examples}/csharp/optsjson.csproj (100%) rename {docs-examples => docs/examples}/csharp/optstelnet.csproj (100%) rename {docs-examples => docs/examples}/csharp/query.csproj (100%) rename {docs-examples => docs/examples}/csharp/sqlinsert.csproj (100%) rename {docs-examples => docs/examples}/csharp/stmtinsert.csproj (100%) rename {docs-examples => docs/examples}/csharp/subscribe.csproj (100%) rename {docs-examples => docs/examples}/go/.gitignore (100%) rename {docs-examples => docs/examples}/go/connect/afconn/main.go (100%) rename {docs-examples => docs/examples}/go/connect/cgoexample/main.go (100%) rename {docs-examples => docs/examples}/go/connect/restexample/main.go (100%) rename {docs-examples => docs/examples}/go/connect/wrapper/main.go (100%) rename {docs-examples => docs/examples}/go/go.mod (100%) rename {docs-examples => docs/examples}/go/insert/json/main.go (100%) rename {docs-examples => docs/examples}/go/insert/line/main.go (100%) rename {docs-examples => docs/examples}/go/insert/sql/main.go (100%) rename {docs-examples => docs/examples}/go/insert/stmt/main.go (100%) rename {docs-examples => docs/examples}/go/insert/telnet/main.go (100%) rename {docs-examples => docs/examples}/go/query/async/main.go (100%) rename {docs-examples => docs/examples}/go/query/sync/main.go (100%) rename {docs-examples => docs/examples}/go/rest/opentsdbjson/main.go (100%) rename {docs-examples => docs/examples}/go/sub/main.go (100%) rename {docs-examples => docs/examples}/java/.gitignore (100%) rename {docs-examples => docs/examples}/java/pom.xml (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/JNIConnectExample.java (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/JSONProtocolExample.java (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/LineProtocolExample.java (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/RESTConnectExample.java (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/RestInsertExample.java (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/RestQueryExample.java (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/StmtInsertExample.java (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/SubscribeDemo.java (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/TelnetLineProtocolExample.java (100%) rename {docs-examples => docs/examples}/java/src/main/java/com/taos/example/WSConnectExample.java (100%) rename {docs-examples => docs/examples}/java/src/test/java/com/taos/test/TestAll.java (100%) rename {docs-examples => docs/examples}/node/.gitignore (100%) rename {docs-examples => docs/examples}/node/nativeexample/async_query_example.js (100%) rename {docs-examples => docs/examples}/node/nativeexample/connect.js (100%) rename {docs-examples => docs/examples}/node/nativeexample/influxdb_line_example.js (100%) rename {docs-examples => docs/examples}/node/nativeexample/insert_example.js (100%) rename {docs-examples => docs/examples}/node/nativeexample/multi_bind_example.js (100%) rename {docs-examples => docs/examples}/node/nativeexample/opentsdb_json_example.js (100%) rename {docs-examples => docs/examples}/node/nativeexample/opentsdb_telnet_example.js (100%) rename {docs-examples => docs/examples}/node/nativeexample/param_bind_example.js (100%) rename {docs-examples => docs/examples}/node/nativeexample/query_example.js (100%) rename {docs-examples => docs/examples}/node/nativeexample/subscribe_demo.js (100%) rename {docs-examples => docs/examples}/node/package.json (100%) rename {docs-examples => docs/examples}/node/restexample/connect.js (100%) rename {docs-examples => docs/examples}/other/mock.js (100%) rename {docs-examples => docs/examples}/php/connect.php (100%) rename {docs-examples => docs/examples}/php/insert.php (100%) rename {docs-examples => docs/examples}/php/insert_stmt.php (100%) rename {docs-examples => docs/examples}/php/query.php (100%) rename {docs-examples => docs/examples}/python/.gitignore (100%) rename {docs-examples => docs/examples}/python/.gitkeep (100%) rename {docs-examples => docs/examples}/python/async_query_example.py (100%) rename {docs-examples => docs/examples}/python/bind_param_example.py (100%) rename {docs-examples => docs/examples}/python/conn_native_pandas.py (100%) rename {docs-examples => docs/examples}/python/conn_rest_pandas.py (100%) rename {docs-examples => docs/examples}/python/connect_example.py (100%) rename {docs-examples => docs/examples}/python/connect_native_reference.py (100%) rename {docs-examples => docs/examples}/python/connect_rest_examples.py (100%) rename {docs-examples => docs/examples}/python/connection_usage_native_reference.py (100%) rename {docs-examples => docs/examples}/python/cursor_usage_native_reference.py (100%) rename {docs-examples => docs/examples}/python/handle_exception.py (100%) rename {docs-examples => docs/examples}/python/json_protocol_example.py (100%) rename {docs-examples => docs/examples}/python/line_protocol_example.py (100%) rename {docs-examples => docs/examples}/python/multi_bind_example.py (100%) rename {docs-examples => docs/examples}/python/native_insert_example.py (100%) rename {docs-examples => docs/examples}/python/query_example.py (100%) rename {docs-examples => docs/examples}/python/rest_client_example.py (100%) rename {docs-examples => docs/examples}/python/result_set_examples.py (100%) rename {docs-examples => docs/examples}/python/subscribe_demo.py (100%) rename {docs-examples => docs/examples}/python/telnet_line_protocol_example.py (100%) rename {docs-examples => docs/examples}/rust/Cargo.toml (100%) rename {docs-examples => docs/examples}/rust/nativeexample/Cargo.toml (100%) rename {docs-examples => docs/examples}/rust/nativeexample/examples/connect.rs (100%) rename {docs-examples => docs/examples}/rust/nativeexample/examples/stmt_example.rs (100%) rename {docs-examples => docs/examples}/rust/nativeexample/examples/subscribe_demo.rs (100%) rename {docs-examples => docs/examples}/rust/nativeexample/src/main.rs (100%) rename {docs-examples => docs/examples}/rust/restexample/Cargo.toml (100%) rename {docs-examples => docs/examples}/rust/restexample/examples/connect.rs (100%) rename {docs-examples => docs/examples}/rust/restexample/examples/insert_example.rs (100%) rename {docs-examples => docs/examples}/rust/restexample/examples/query_example.rs (100%) rename {docs-examples => docs/examples}/rust/restexample/src/main.rs (100%) rename {docs-examples => docs/examples}/rust/schemalessexample/Cargo.toml (100%) rename {docs-examples => docs/examples}/rust/schemalessexample/examples/influxdb_line_example.rs (100%) rename {docs-examples => docs/examples}/rust/schemalessexample/examples/opentsdb_json_example.rs (100%) rename {docs-examples => docs/examples}/rust/schemalessexample/examples/opentsdb_telnet_example.rs (100%) rename {docs-examples => docs/examples}/rust/schemalessexample/src/main.rs (100%) rename {docs-cn => docs/zh}/01-index.md (100%) rename {docs-cn => docs/zh}/02-intro.md (100%) rename {docs-cn => docs/zh}/04-concept/_category_.yml (100%) rename {docs-cn => docs/zh}/04-concept/index.md (100%) rename {docs-cn => docs/zh}/05-get-started/_apt_get_install.mdx (100%) rename {docs-cn => docs/zh}/05-get-started/_category_.yml (100%) rename {docs-cn => docs/zh}/05-get-started/_pkg_install.mdx (100%) rename {docs-cn => docs/zh}/05-get-started/index.md (100%) rename {docs-cn => docs/zh}/07-develop/01-connect/_category_.yml (100%) create mode 100644 docs/zh/07-develop/01-connect/_connect_c.mdx rename {docs-cn => docs/zh}/07-develop/01-connect/_connect_cs.mdx (63%) rename {docs-cn => docs/zh}/07-develop/01-connect/_connect_go.mdx (65%) rename {docs-cn => docs/zh}/07-develop/01-connect/_connect_java.mdx (65%) create mode 100644 docs/zh/07-develop/01-connect/_connect_node.mdx create mode 100644 docs/zh/07-develop/01-connect/_connect_php.mdx create mode 100644 docs/zh/07-develop/01-connect/_connect_python.mdx create mode 100644 docs/zh/07-develop/01-connect/_connect_r.mdx rename {docs-cn => docs/zh}/07-develop/01-connect/_connect_rust.mdx (78%) rename {docs-cn => docs/zh}/07-develop/01-connect/index.md (100%) rename {docs-cn => docs/zh}/07-develop/02-model/_category_.yml (100%) rename {docs-cn => docs/zh}/07-develop/02-model/index.mdx (100%) rename {docs-cn => docs/zh}/07-develop/03-insert-data/01-sql-writing.mdx (100%) rename {docs-cn => docs/zh}/07-develop/03-insert-data/02-influxdb-line.mdx (100%) rename {docs-cn => docs/zh}/07-develop/03-insert-data/03-opentsdb-telnet.mdx (100%) rename {docs-cn => docs/zh}/07-develop/03-insert-data/04-opentsdb-json.mdx (100%) create mode 100644 docs/zh/07-develop/03-insert-data/_c_line.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_c_opts_json.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_c_opts_telnet.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_c_sql.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_c_stmt.mdx rename {docs-cn => docs/zh}/07-develop/03-insert-data/_category_.yml (100%) create mode 100644 docs/zh/07-develop/03-insert-data/_cs_line.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_cs_opts_json.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_cs_opts_telnet.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_cs_sql.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_cs_stmt.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_go_line.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_go_opts_json.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_go_opts_telnet.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_go_sql.mdx rename {docs-cn => docs/zh}/07-develop/03-insert-data/_go_stmt.mdx (77%) create mode 100644 docs/zh/07-develop/03-insert-data/_java_line.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_java_opts_json.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_java_opts_telnet.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_java_sql.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_java_stmt.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_js_line.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_js_opts_json.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_js_opts_telnet.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_js_sql.mdx rename {docs-cn => docs/zh}/07-develop/03-insert-data/_js_stmt.mdx (65%) create mode 100644 docs/zh/07-develop/03-insert-data/_php_sql.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_php_stmt.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_py_line.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_py_opts_json.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_py_opts_telnet.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_py_sql.mdx rename {docs-cn => docs/zh}/07-develop/03-insert-data/_py_stmt.mdx (64%) create mode 100644 docs/zh/07-develop/03-insert-data/_rust_line.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_rust_opts_json.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_rust_opts_telnet.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_rust_sql.mdx create mode 100644 docs/zh/07-develop/03-insert-data/_rust_stmt.mdx rename {docs-cn => docs/zh}/07-develop/03-insert-data/index.md (100%) create mode 100644 docs/zh/07-develop/04-query-data/_c.mdx create mode 100644 docs/zh/07-develop/04-query-data/_c_async.mdx rename {docs-cn => docs/zh}/07-develop/04-query-data/_category_.yml (100%) create mode 100644 docs/zh/07-develop/04-query-data/_cs.mdx create mode 100644 docs/zh/07-develop/04-query-data/_cs_async.mdx create mode 100644 docs/zh/07-develop/04-query-data/_go.mdx create mode 100644 docs/zh/07-develop/04-query-data/_go_async.mdx create mode 100644 docs/zh/07-develop/04-query-data/_java.mdx create mode 100644 docs/zh/07-develop/04-query-data/_js.mdx create mode 100644 docs/zh/07-develop/04-query-data/_js_async.mdx create mode 100644 docs/zh/07-develop/04-query-data/_php.mdx rename {docs-cn => docs/zh}/07-develop/04-query-data/_py.mdx (54%) rename {docs-cn => docs/zh}/07-develop/04-query-data/_py_async.mdx (60%) create mode 100644 docs/zh/07-develop/04-query-data/_rust.mdx rename {docs-cn => docs/zh}/07-develop/04-query-data/index.mdx (100%) rename {docs-cn => docs/zh}/07-develop/05-delete-data.mdx (100%) rename {docs-cn => docs/zh}/07-develop/06-continuous-query.mdx (100%) rename {docs-cn => docs/zh}/07-develop/07-subscribe.mdx (100%) rename {docs-cn => docs/zh}/07-develop/08-cache.md (100%) rename {docs-cn => docs/zh}/07-develop/09-udf.md (100%) rename {docs-cn => docs/zh}/07-develop/_category_.yml (100%) create mode 100644 docs/zh/07-develop/_sub_c.mdx create mode 100644 docs/zh/07-develop/_sub_cs.mdx create mode 100644 docs/zh/07-develop/_sub_go.mdx rename {docs-cn => docs/zh}/07-develop/_sub_java.mdx (71%) create mode 100644 docs/zh/07-develop/_sub_node.mdx create mode 100644 docs/zh/07-develop/_sub_python.mdx create mode 100644 docs/zh/07-develop/_sub_rust.mdx rename {docs-cn => docs/zh}/07-develop/index.md (100%) rename {docs-cn => docs/zh}/10-cluster/01-deploy.md (100%) rename {docs-cn => docs/zh}/10-cluster/02-cluster-mgmt.md (100%) rename {docs-cn => docs/zh}/10-cluster/03-ha-and-lb.md (100%) rename {docs-cn => docs/zh}/10-cluster/_category_.yml (100%) rename {docs-cn => docs/zh}/10-cluster/index.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/01-data-type.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/02-database.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/03-table.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/04-stable.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/05-insert.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/06-select.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/07-function.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/08-interval.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/09-limit.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/10-json.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/11-escape.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/12-keywords/_category_.yml (100%) rename {docs-cn => docs/zh}/12-taos-sql/12-keywords/index.md (100%) rename {docs-cn => docs/zh}/12-taos-sql/_category_.yml (100%) rename {docs-cn => docs/zh}/12-taos-sql/index.md (100%) rename {docs-en => docs/zh}/12-taos-sql/timewindow-1.webp (100%) rename {docs-en => docs/zh}/12-taos-sql/timewindow-2.webp (100%) rename {docs-en => docs/zh}/12-taos-sql/timewindow-3.webp (100%) rename {docs-cn => docs/zh}/13-operation/01-pkg-install.md (100%) rename {docs-cn => docs/zh}/13-operation/02-planning.mdx (100%) rename {docs-cn => docs/zh}/13-operation/03-tolerance.md (100%) rename {docs-cn => docs/zh}/13-operation/06-admin.md (100%) rename {docs-cn => docs/zh}/13-operation/07-import.md (100%) rename {docs-cn => docs/zh}/13-operation/08-export.md (100%) rename {docs-cn => docs/zh}/13-operation/09-status.md (100%) rename {docs-cn => docs/zh}/13-operation/10-monitor.md (100%) rename {docs-cn => docs/zh}/13-operation/11-optimize.md (100%) rename {docs-cn => docs/zh}/13-operation/17-diagnose.md (100%) rename {docs-cn => docs/zh}/13-operation/_category_.yml (100%) rename {docs-cn => docs/zh}/13-operation/index.md (100%) rename {docs-cn => docs/zh}/14-reference/02-rest-api/02-rest-api.mdx (100%) rename {docs-en => docs/zh}/14-reference/02-rest-api/_category_.yml (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/03-connector.mdx (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/_category_.yml (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/_linux_install.mdx (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/_preparition.mdx (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/_verify_linux.mdx (98%) rename {docs-cn => docs/zh}/14-reference/03-connector/_verify_windows.mdx (98%) rename {docs-cn => docs/zh}/14-reference/03-connector/_windows_install.mdx (100%) rename {docs-en => docs/zh}/14-reference/03-connector/connector.webp (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/cpp.mdx (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/csharp.mdx (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/go.mdx (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/java.mdx (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/node.mdx (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/php.mdx (95%) rename {docs-cn => docs/zh}/14-reference/03-connector/python.mdx (95%) rename {docs-cn => docs/zh}/14-reference/03-connector/rust.mdx (100%) rename {docs-cn => docs/zh}/14-reference/03-connector/tdengine-jdbc-connector.webp (100%) rename {docs-cn => docs/zh}/14-reference/04-taosadapter.md (100%) rename {docs-cn => docs/zh}/14-reference/05-taosbenchmark.md (100%) rename {docs-cn => docs/zh}/14-reference/06-taosdump.md (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/TDinsight-5-database.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/TDinsight-full.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/alert-manager-status.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/alert-notification-channel.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/alert-query-demo.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/alert-rule-test.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/howto-add-datasource.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/howto-dashboard-display.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/howto-import-dashboard.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/import-dashboard-15167.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/import_dashboard.webp (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/tdengine-grafana.json (100%) rename {docs-en => docs/zh}/14-reference/07-tdinsight/assets/tdengine_dashboard.webp (100%) rename {docs-cn => docs/zh}/14-reference/07-tdinsight/index.md (100%) rename {docs-cn => docs/zh}/14-reference/08-taos-shell.md (100%) rename {docs-cn => docs/zh}/14-reference/09-support-platform/_category_.yml (100%) rename {docs-cn => docs/zh}/14-reference/09-support-platform/index.md (100%) rename {docs-cn => docs/zh}/14-reference/11-docker/_category_.yml (100%) rename {docs-cn => docs/zh}/14-reference/11-docker/index.md (100%) rename {docs-cn => docs/zh}/14-reference/12-config/_category_.yml (100%) rename {docs-cn => docs/zh}/14-reference/12-config/index.md (100%) rename {docs-cn => docs/zh}/14-reference/12-directory.md (100%) rename {docs-cn => docs/zh}/14-reference/13-schemaless/13-schemaless.md (100%) rename {docs-cn => docs/zh}/14-reference/13-schemaless/_category_.yml (100%) rename {docs-cn => docs/zh}/14-reference/_category_.yml (100%) rename {docs-cn => docs/zh}/14-reference/_collectd.mdx (100%) rename {docs-cn => docs/zh}/14-reference/_icinga2.mdx (100%) rename {docs-cn => docs/zh}/14-reference/_prometheus.mdx (100%) rename {docs-cn => docs/zh}/14-reference/_statsd.mdx (100%) rename {docs-cn => docs/zh}/14-reference/_tcollector.mdx (100%) rename {docs-cn => docs/zh}/14-reference/_telegraf.mdx (100%) rename {docs-cn => docs/zh}/14-reference/index.md (100%) rename {docs-en => docs/zh}/14-reference/taosAdapter-architecture.webp (100%) rename {docs-cn => docs/zh}/20-third-party/01-grafana.mdx (100%) rename {docs-cn => docs/zh}/20-third-party/02-prometheus.md (100%) rename {docs-cn => docs/zh}/20-third-party/03-telegraf.md (100%) rename {docs-cn => docs/zh}/20-third-party/05-collectd.md (100%) rename {docs-cn => docs/zh}/20-third-party/06-statsd.md (100%) rename {docs-cn => docs/zh}/20-third-party/07-icinga2.md (100%) rename {docs-cn => docs/zh}/20-third-party/08-tcollector.md (100%) rename {docs-cn => docs/zh}/20-third-party/09-emq-broker.md (99%) rename {docs-cn => docs/zh}/20-third-party/10-hive-mq-broker.md (100%) rename {docs-cn => docs/zh}/20-third-party/11-kafka.md (100%) rename {docs-cn => docs/zh}/20-third-party/_category_.yml (100%) rename {docs-cn => docs/zh}/20-third-party/_deploytaosadapter.mdx (100%) rename {docs-en/20-third-party/grafana => docs/zh/20-third-party}/add_datasource1.webp (100%) rename {docs-en/20-third-party/grafana => docs/zh/20-third-party}/add_datasource2.webp (100%) rename {docs-en/20-third-party/grafana => docs/zh/20-third-party}/add_datasource3.webp (100%) rename {docs-en/20-third-party/grafana => docs/zh/20-third-party}/add_datasource4.webp (100%) rename {docs-en/20-third-party/grafana => docs/zh/20-third-party}/create_dashboard1.webp (100%) rename {docs-en/20-third-party/grafana => docs/zh/20-third-party}/create_dashboard2.webp (100%) rename {docs-cn => docs/zh}/20-third-party/dashboard-15146.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/add-action-handler.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/check-result-in-taos.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/check-rule-matched.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/client-num.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/create-resource.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/create-rule.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/edit-action.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/edit-resource.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/login-dashboard.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/rule-engine.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/rule-header-key-value.webp (100%) rename {docs-en => docs/zh}/20-third-party/emqx/run-mock.webp (100%) rename {docs-cn => docs/zh}/20-third-party/import_dashboard1.webp (100%) rename {docs-cn => docs/zh}/20-third-party/import_dashboard2.webp (100%) rename {docs-cn => docs/zh}/20-third-party/index.md (100%) rename {docs-en => docs/zh}/20-third-party/kafka/Kafka_Connect.webp (100%) rename {docs-en => docs/zh}/20-third-party/kafka/confluentPlatform.webp (100%) rename {docs-en => docs/zh}/20-third-party/kafka/streaming-integration-with-kafka-connect.webp (100%) rename {docs-cn => docs/zh}/21-tdinternal/01-arch.md (100%) rename {docs-cn => docs/zh}/21-tdinternal/02-replica.md (100%) rename {docs-cn => docs/zh}/21-tdinternal/03-taosd.md (100%) rename {docs-cn => docs/zh}/21-tdinternal/12-tsz-compress.md (100%) rename {docs-cn => docs/zh}/21-tdinternal/30-iot-big-data.md (100%) rename {docs-cn => docs/zh}/21-tdinternal/_category_.yml (100%) rename {docs-en => docs/zh}/21-tdinternal/dnode.webp (100%) rename {docs-cn => docs/zh}/21-tdinternal/index.md (100%) rename {docs-en => docs/zh}/21-tdinternal/message.webp (100%) rename {docs-en => docs/zh}/21-tdinternal/modules.webp (100%) rename {docs-en => docs/zh}/21-tdinternal/multi_tables.webp (100%) rename {docs-en => docs/zh}/21-tdinternal/replica-forward.webp (100%) rename {docs-en => docs/zh}/21-tdinternal/replica-master.webp (100%) rename {docs-en => docs/zh}/21-tdinternal/replica-restore.webp (100%) rename {docs-en => docs/zh}/21-tdinternal/structure.webp (100%) rename {docs-en => docs/zh}/21-tdinternal/vnode.webp (100%) rename {docs-en => docs/zh}/21-tdinternal/write_master.webp (100%) rename {docs-en => docs/zh}/21-tdinternal/write_slave.webp (100%) rename {docs-cn => docs/zh}/25-application/01-telegraf.md (100%) rename {docs-cn => docs/zh}/25-application/02-collectd.md (100%) rename {docs-cn => docs/zh}/25-application/03-immigrate.md (100%) rename {docs-en => docs/zh}/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp (100%) rename {docs-en => docs/zh}/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp (100%) rename {docs-en => docs/zh}/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp (100%) rename {docs-en => docs/zh}/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp (100%) rename {docs-en => docs/zh}/25-application/IT-DevOps-Solutions-Telegraf.webp (100%) rename {docs-en => docs/zh}/25-application/IT-DevOps-Solutions-collectd-dashboard.webp (100%) rename {docs-en => docs/zh}/25-application/IT-DevOps-Solutions-statsd-dashboard.webp (100%) rename {docs-en => docs/zh}/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp (100%) rename {docs-cn => docs/zh}/25-application/_category_.yml (100%) rename {docs-cn => docs/zh}/25-application/index.md (100%) rename {docs-cn => docs/zh}/27-train-faq/01-faq.md (100%) rename {docs-cn => docs/zh}/27-train-faq/02-video.mdx (100%) rename {docs-cn => docs/zh}/27-train-faq/03-docker.md (100%) rename {docs-cn => docs/zh}/27-train-faq/_category_.yml (100%) rename {docs-cn => docs/zh}/27-train-faq/index.md (100%) rename {docs-en => docs/zh}/30-release/01-2.6.md (100%) rename {docs-en => docs/zh}/30-release/02-2.4.md (100%) rename {docs-cn => docs/zh}/30-release/_category_.yml (100%) rename {docs-cn => docs/zh}/30-release/index.md (100%) rename {docs-en/02-intro => docs/zh}/eco_system.webp (100%) diff --git a/docs-cn/07-develop/01-connect/_connect_c.mdx b/docs-cn/07-develop/01-connect/_connect_c.mdx deleted file mode 100644 index 9cd8669561..0000000000 --- a/docs-cn/07-develop/01-connect/_connect_c.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c title="原生连接" -{{#include docs-examples/c/connect_example.c}} -``` diff --git a/docs-cn/07-develop/01-connect/_connect_node.mdx b/docs-cn/07-develop/01-connect/_connect_node.mdx deleted file mode 100644 index 199a6e3faa..0000000000 --- a/docs-cn/07-develop/01-connect/_connect_node.mdx +++ /dev/null @@ -1,7 +0,0 @@ -```js title="原生连接" -{{#include docs-examples/node/nativeexample/connect.js}} -``` - -```js title="REST 连接" -{{#include docs-examples/node/restexample/connect.js}} -``` diff --git a/docs-cn/07-develop/01-connect/_connect_php.mdx b/docs-cn/07-develop/01-connect/_connect_php.mdx deleted file mode 100644 index 2431df2a72..0000000000 --- a/docs-cn/07-develop/01-connect/_connect_php.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```php title="原生连接" -{{#include docs-examples/php/connect.php}} -``` diff --git a/docs-cn/07-develop/01-connect/_connect_python.mdx b/docs-cn/07-develop/01-connect/_connect_python.mdx deleted file mode 100644 index c0043c752e..0000000000 --- a/docs-cn/07-develop/01-connect/_connect_python.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```python title="原生连接" -{{#include docs-examples/python/connect_example.py}} -``` diff --git a/docs-cn/07-develop/01-connect/_connect_r.mdx b/docs-cn/07-develop/01-connect/_connect_r.mdx deleted file mode 100644 index 8aab6121a6..0000000000 --- a/docs-cn/07-develop/01-connect/_connect_r.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```r title="原生连接" -{{#include docs-examples/R/connect_native.r:demo}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_c_line.mdx b/docs-cn/07-develop/03-insert-data/_c_line.mdx deleted file mode 100644 index 5ef2e9af77..0000000000 --- a/docs-cn/07-develop/03-insert-data/_c_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/line_example.c:main}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/03-insert-data/_c_opts_json.mdx b/docs-cn/07-develop/03-insert-data/_c_opts_json.mdx deleted file mode 100644 index 22ad2e0122..0000000000 --- a/docs-cn/07-develop/03-insert-data/_c_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/json_protocol_example.c:main}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/03-insert-data/_c_opts_telnet.mdx b/docs-cn/07-develop/03-insert-data/_c_opts_telnet.mdx deleted file mode 100644 index 508d7bc98a..0000000000 --- a/docs-cn/07-develop/03-insert-data/_c_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/telnet_line_example.c:main}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/03-insert-data/_c_sql.mdx b/docs-cn/07-develop/03-insert-data/_c_sql.mdx deleted file mode 100644 index f4153fd2c4..0000000000 --- a/docs-cn/07-develop/03-insert-data/_c_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/insert_example.c}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/03-insert-data/_c_stmt.mdx b/docs-cn/07-develop/03-insert-data/_c_stmt.mdx deleted file mode 100644 index 01ac067519..0000000000 --- a/docs-cn/07-develop/03-insert-data/_c_stmt.mdx +++ /dev/null @@ -1,6 +0,0 @@ -```c title=一次绑定一行 -{{#include docs-examples/c/stmt_example.c}} -``` -```c title=一次绑定多行 72:117 -{{#include docs-examples/c/multi_bind_example.c}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/03-insert-data/_cs_line.mdx b/docs-cn/07-develop/03-insert-data/_cs_line.mdx deleted file mode 100644 index 9c275ee3d7..0000000000 --- a/docs-cn/07-develop/03-insert-data/_cs_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/InfluxDBLineExample.cs}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_cs_opts_json.mdx b/docs-cn/07-develop/03-insert-data/_cs_opts_json.mdx deleted file mode 100644 index 3d538b8506..0000000000 --- a/docs-cn/07-develop/03-insert-data/_cs_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/OptsJsonExample.cs}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_cs_opts_telnet.mdx b/docs-cn/07-develop/03-insert-data/_cs_opts_telnet.mdx deleted file mode 100644 index c53bf3d723..0000000000 --- a/docs-cn/07-develop/03-insert-data/_cs_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/OptsTelnetExample.cs}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_cs_sql.mdx b/docs-cn/07-develop/03-insert-data/_cs_sql.mdx deleted file mode 100644 index c7688bfbe7..0000000000 --- a/docs-cn/07-develop/03-insert-data/_cs_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/SQLInsertExample.cs}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_cs_stmt.mdx b/docs-cn/07-develop/03-insert-data/_cs_stmt.mdx deleted file mode 100644 index 97c3b910ff..0000000000 --- a/docs-cn/07-develop/03-insert-data/_cs_stmt.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/StmtInsertExample.cs}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_go_line.mdx b/docs-cn/07-develop/03-insert-data/_go_line.mdx deleted file mode 100644 index cd225945b7..0000000000 --- a/docs-cn/07-develop/03-insert-data/_go_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/insert/line/main.go}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_go_opts_json.mdx b/docs-cn/07-develop/03-insert-data/_go_opts_json.mdx deleted file mode 100644 index 0c0d3e5b63..0000000000 --- a/docs-cn/07-develop/03-insert-data/_go_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/insert/json/main.go}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_go_opts_telnet.mdx b/docs-cn/07-develop/03-insert-data/_go_opts_telnet.mdx deleted file mode 100644 index d5ca40cc14..0000000000 --- a/docs-cn/07-develop/03-insert-data/_go_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/insert/telnet/main.go}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_go_sql.mdx b/docs-cn/07-develop/03-insert-data/_go_sql.mdx deleted file mode 100644 index 613a65add1..0000000000 --- a/docs-cn/07-develop/03-insert-data/_go_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/insert/sql/main.go}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_java_line.mdx b/docs-cn/07-develop/03-insert-data/_java_line.mdx deleted file mode 100644 index 2e59a5d470..0000000000 --- a/docs-cn/07-develop/03-insert-data/_java_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/LineProtocolExample.java}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_java_opts_json.mdx b/docs-cn/07-develop/03-insert-data/_java_opts_json.mdx deleted file mode 100644 index 826a1a07d9..0000000000 --- a/docs-cn/07-develop/03-insert-data/_java_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/JSONProtocolExample.java}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_java_opts_telnet.mdx b/docs-cn/07-develop/03-insert-data/_java_opts_telnet.mdx deleted file mode 100644 index 954dcc1a48..0000000000 --- a/docs-cn/07-develop/03-insert-data/_java_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/TelnetLineProtocolExample.java}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_java_sql.mdx b/docs-cn/07-develop/03-insert-data/_java_sql.mdx deleted file mode 100644 index a863378def..0000000000 --- a/docs-cn/07-develop/03-insert-data/_java_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/RestInsertExample.java:insert}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/03-insert-data/_java_stmt.mdx b/docs-cn/07-develop/03-insert-data/_java_stmt.mdx deleted file mode 100644 index 54443e535f..0000000000 --- a/docs-cn/07-develop/03-insert-data/_java_stmt.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/StmtInsertExample.java}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_js_line.mdx b/docs-cn/07-develop/03-insert-data/_js_line.mdx deleted file mode 100644 index 172c9bc17b..0000000000 --- a/docs-cn/07-develop/03-insert-data/_js_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/influxdb_line_example.js}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_js_opts_json.mdx b/docs-cn/07-develop/03-insert-data/_js_opts_json.mdx deleted file mode 100644 index 20ac9ec91e..0000000000 --- a/docs-cn/07-develop/03-insert-data/_js_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/opentsdb_json_example.js}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_js_opts_telnet.mdx b/docs-cn/07-develop/03-insert-data/_js_opts_telnet.mdx deleted file mode 100644 index c3c8c40bd6..0000000000 --- a/docs-cn/07-develop/03-insert-data/_js_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/opentsdb_telnet_example.js}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_js_sql.mdx b/docs-cn/07-develop/03-insert-data/_js_sql.mdx deleted file mode 100644 index f5e17c7689..0000000000 --- a/docs-cn/07-develop/03-insert-data/_js_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/insert_example.js}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_php_sql.mdx b/docs-cn/07-develop/03-insert-data/_php_sql.mdx deleted file mode 100644 index 42d6a54847..0000000000 --- a/docs-cn/07-develop/03-insert-data/_php_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```php -{{#include docs-examples/php/insert.php}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_php_stmt.mdx b/docs-cn/07-develop/03-insert-data/_php_stmt.mdx deleted file mode 100644 index c1ba4ed3b1..0000000000 --- a/docs-cn/07-develop/03-insert-data/_php_stmt.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```php -{{#include docs-examples/php/insert_stmt.php}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_py_line.mdx b/docs-cn/07-develop/03-insert-data/_py_line.mdx deleted file mode 100644 index d3bb1ebb34..0000000000 --- a/docs-cn/07-develop/03-insert-data/_py_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/line_protocol_example.py}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_py_opts_json.mdx b/docs-cn/07-develop/03-insert-data/_py_opts_json.mdx deleted file mode 100644 index cfbfe13ccf..0000000000 --- a/docs-cn/07-develop/03-insert-data/_py_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/json_protocol_example.py}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_py_opts_telnet.mdx b/docs-cn/07-develop/03-insert-data/_py_opts_telnet.mdx deleted file mode 100644 index 14bc65a7a3..0000000000 --- a/docs-cn/07-develop/03-insert-data/_py_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/telnet_line_protocol_example.py}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_py_sql.mdx b/docs-cn/07-develop/03-insert-data/_py_sql.mdx deleted file mode 100644 index c0e15b8ec1..0000000000 --- a/docs-cn/07-develop/03-insert-data/_py_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/native_insert_example.py}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_rust_line.mdx b/docs-cn/07-develop/03-insert-data/_rust_line.mdx deleted file mode 100644 index 696ddb7b85..0000000000 --- a/docs-cn/07-develop/03-insert-data/_rust_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/schemalessexample/examples/influxdb_line_example.rs}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_rust_opts_json.mdx b/docs-cn/07-develop/03-insert-data/_rust_opts_json.mdx deleted file mode 100644 index 97d9052dac..0000000000 --- a/docs-cn/07-develop/03-insert-data/_rust_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/schemalessexample/examples/opentsdb_json_example.rs}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_rust_opts_telnet.mdx b/docs-cn/07-develop/03-insert-data/_rust_opts_telnet.mdx deleted file mode 100644 index 14021f43d8..0000000000 --- a/docs-cn/07-develop/03-insert-data/_rust_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/schemalessexample/examples/opentsdb_telnet_example.rs}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_rust_sql.mdx b/docs-cn/07-develop/03-insert-data/_rust_sql.mdx deleted file mode 100644 index 8e8013e4ad..0000000000 --- a/docs-cn/07-develop/03-insert-data/_rust_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/restexample/examples/insert_example.rs}} -``` diff --git a/docs-cn/07-develop/03-insert-data/_rust_stmt.mdx b/docs-cn/07-develop/03-insert-data/_rust_stmt.mdx deleted file mode 100644 index 590a7a0e71..0000000000 --- a/docs-cn/07-develop/03-insert-data/_rust_stmt.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/nativeexample/examples/stmt_example.rs}} -``` diff --git a/docs-cn/07-develop/04-query-data/_c.mdx b/docs-cn/07-develop/04-query-data/_c.mdx deleted file mode 100644 index 76c9067e2f..0000000000 --- a/docs-cn/07-develop/04-query-data/_c.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/query_example.c}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/04-query-data/_c_async.mdx b/docs-cn/07-develop/04-query-data/_c_async.mdx deleted file mode 100644 index 09f3d3b3ff..0000000000 --- a/docs-cn/07-develop/04-query-data/_c_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/async_query_example.c:demo}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/04-query-data/_cs.mdx b/docs-cn/07-develop/04-query-data/_cs.mdx deleted file mode 100644 index 2ab52feb56..0000000000 --- a/docs-cn/07-develop/04-query-data/_cs.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/QueryExample.cs}} -``` diff --git a/docs-cn/07-develop/04-query-data/_cs_async.mdx b/docs-cn/07-develop/04-query-data/_cs_async.mdx deleted file mode 100644 index f868994b30..0000000000 --- a/docs-cn/07-develop/04-query-data/_cs_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/AsyncQueryExample.cs}} -``` diff --git a/docs-cn/07-develop/04-query-data/_go.mdx b/docs-cn/07-develop/04-query-data/_go.mdx deleted file mode 100644 index 417c12315c..0000000000 --- a/docs-cn/07-develop/04-query-data/_go.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/query/sync/main.go}} -``` diff --git a/docs-cn/07-develop/04-query-data/_go_async.mdx b/docs-cn/07-develop/04-query-data/_go_async.mdx deleted file mode 100644 index 72fff411b9..0000000000 --- a/docs-cn/07-develop/04-query-data/_go_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/query/async/main.go}} -``` diff --git a/docs-cn/07-develop/04-query-data/_java.mdx b/docs-cn/07-develop/04-query-data/_java.mdx deleted file mode 100644 index 519b926614..0000000000 --- a/docs-cn/07-develop/04-query-data/_java.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/RestQueryExample.java}} -``` diff --git a/docs-cn/07-develop/04-query-data/_js.mdx b/docs-cn/07-develop/04-query-data/_js.mdx deleted file mode 100644 index c5e4c4f3fc..0000000000 --- a/docs-cn/07-develop/04-query-data/_js.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/query_example.js}} -``` diff --git a/docs-cn/07-develop/04-query-data/_js_async.mdx b/docs-cn/07-develop/04-query-data/_js_async.mdx deleted file mode 100644 index c65d54ed12..0000000000 --- a/docs-cn/07-develop/04-query-data/_js_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/async_query_example.js}} -``` diff --git a/docs-cn/07-develop/04-query-data/_php.mdx b/docs-cn/07-develop/04-query-data/_php.mdx deleted file mode 100644 index 6264bd99f5..0000000000 --- a/docs-cn/07-develop/04-query-data/_php.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/php/query.php}} -``` diff --git a/docs-cn/07-develop/04-query-data/_rust.mdx b/docs-cn/07-develop/04-query-data/_rust.mdx deleted file mode 100644 index 742d70fd02..0000000000 --- a/docs-cn/07-develop/04-query-data/_rust.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/restexample/examples/query_example.rs}} -``` diff --git a/docs-cn/07-develop/_sub_c.mdx b/docs-cn/07-develop/_sub_c.mdx deleted file mode 100644 index 95fef0042d..0000000000 --- a/docs-cn/07-develop/_sub_c.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/subscribe_demo.c}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/_sub_cs.mdx b/docs-cn/07-develop/_sub_cs.mdx deleted file mode 100644 index 80934aa4d0..0000000000 --- a/docs-cn/07-develop/_sub_cs.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/SubscribeDemo.cs}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/_sub_go.mdx b/docs-cn/07-develop/_sub_go.mdx deleted file mode 100644 index cd908fc12c..0000000000 --- a/docs-cn/07-develop/_sub_go.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/sub/main.go}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/_sub_node.mdx b/docs-cn/07-develop/_sub_node.mdx deleted file mode 100644 index c93ad627ce..0000000000 --- a/docs-cn/07-develop/_sub_node.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/subscribe_demo.js}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/_sub_python.mdx b/docs-cn/07-develop/_sub_python.mdx deleted file mode 100644 index b817deeba6..0000000000 --- a/docs-cn/07-develop/_sub_python.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/subscribe_demo.py}} -``` \ No newline at end of file diff --git a/docs-cn/07-develop/_sub_rust.mdx b/docs-cn/07-develop/_sub_rust.mdx deleted file mode 100644 index 4750cf7a3b..0000000000 --- a/docs-cn/07-develop/_sub_rust.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rs -{{#include docs-examples/rust/nativeexample/examples/subscribe_demo.rs}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/01-connect/_connect_c.mdx b/docs-en/07-develop/01-connect/_connect_c.mdx deleted file mode 100644 index 174bf45c4e..0000000000 --- a/docs-en/07-develop/01-connect/_connect_c.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c title="Native Connection" -{{#include docs-examples/c/connect_example.c}} -``` diff --git a/docs-en/07-develop/01-connect/_connect_node.mdx b/docs-en/07-develop/01-connect/_connect_node.mdx deleted file mode 100644 index 489b0386e9..0000000000 --- a/docs-en/07-develop/01-connect/_connect_node.mdx +++ /dev/null @@ -1,7 +0,0 @@ -```js title="Native Connection" -{{#include docs-examples/node/nativeexample/connect.js}} -``` - -```js title="REST Connection" -{{#include docs-examples/node/restexample/connect.js}} -``` diff --git a/docs-en/07-develop/01-connect/_connect_python.mdx b/docs-en/07-develop/01-connect/_connect_python.mdx deleted file mode 100644 index 44b7586fad..0000000000 --- a/docs-en/07-develop/01-connect/_connect_python.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```python title="Native Connection" -{{#include docs-examples/python/connect_example.py}} -``` diff --git a/docs-en/07-develop/01-connect/_connect_r.mdx b/docs-en/07-develop/01-connect/_connect_r.mdx deleted file mode 100644 index 09c3d71ac3..0000000000 --- a/docs-en/07-develop/01-connect/_connect_r.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```r title="Native Connection" -{{#include docs-examples/R/connect_native.r:demo}} -``` diff --git a/docs-en/07-develop/03-insert-data/_c_line.mdx b/docs-en/07-develop/03-insert-data/_c_line.mdx deleted file mode 100644 index 5ef2e9af77..0000000000 --- a/docs-en/07-develop/03-insert-data/_c_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/line_example.c:main}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/03-insert-data/_c_opts_json.mdx b/docs-en/07-develop/03-insert-data/_c_opts_json.mdx deleted file mode 100644 index 22ad2e0122..0000000000 --- a/docs-en/07-develop/03-insert-data/_c_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/json_protocol_example.c:main}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/03-insert-data/_c_opts_telnet.mdx b/docs-en/07-develop/03-insert-data/_c_opts_telnet.mdx deleted file mode 100644 index 508d7bc98a..0000000000 --- a/docs-en/07-develop/03-insert-data/_c_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/telnet_line_example.c:main}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/03-insert-data/_c_sql.mdx b/docs-en/07-develop/03-insert-data/_c_sql.mdx deleted file mode 100644 index f4153fd2c4..0000000000 --- a/docs-en/07-develop/03-insert-data/_c_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/insert_example.c}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/03-insert-data/_c_stmt.mdx b/docs-en/07-develop/03-insert-data/_c_stmt.mdx deleted file mode 100644 index 7f5ef23a84..0000000000 --- a/docs-en/07-develop/03-insert-data/_c_stmt.mdx +++ /dev/null @@ -1,6 +0,0 @@ -```c title=Single Row Binding -{{#include docs-examples/c/stmt_example.c}} -``` -```c title=Multiple Row Binding 72:117 -{{#include docs-examples/c/multi_bind_example.c}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/03-insert-data/_cs_line.mdx b/docs-en/07-develop/03-insert-data/_cs_line.mdx deleted file mode 100644 index 9c275ee3d7..0000000000 --- a/docs-en/07-develop/03-insert-data/_cs_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/InfluxDBLineExample.cs}} -``` diff --git a/docs-en/07-develop/03-insert-data/_cs_opts_json.mdx b/docs-en/07-develop/03-insert-data/_cs_opts_json.mdx deleted file mode 100644 index 3d538b8506..0000000000 --- a/docs-en/07-develop/03-insert-data/_cs_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/OptsJsonExample.cs}} -``` diff --git a/docs-en/07-develop/03-insert-data/_cs_opts_telnet.mdx b/docs-en/07-develop/03-insert-data/_cs_opts_telnet.mdx deleted file mode 100644 index c53bf3d723..0000000000 --- a/docs-en/07-develop/03-insert-data/_cs_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/OptsTelnetExample.cs}} -``` diff --git a/docs-en/07-develop/03-insert-data/_cs_sql.mdx b/docs-en/07-develop/03-insert-data/_cs_sql.mdx deleted file mode 100644 index c7688bfbe7..0000000000 --- a/docs-en/07-develop/03-insert-data/_cs_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/SQLInsertExample.cs}} -``` diff --git a/docs-en/07-develop/03-insert-data/_cs_stmt.mdx b/docs-en/07-develop/03-insert-data/_cs_stmt.mdx deleted file mode 100644 index 97c3b910ff..0000000000 --- a/docs-en/07-develop/03-insert-data/_cs_stmt.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/StmtInsertExample.cs}} -``` diff --git a/docs-en/07-develop/03-insert-data/_go_line.mdx b/docs-en/07-develop/03-insert-data/_go_line.mdx deleted file mode 100644 index cd225945b7..0000000000 --- a/docs-en/07-develop/03-insert-data/_go_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/insert/line/main.go}} -``` diff --git a/docs-en/07-develop/03-insert-data/_go_opts_json.mdx b/docs-en/07-develop/03-insert-data/_go_opts_json.mdx deleted file mode 100644 index 0c0d3e5b63..0000000000 --- a/docs-en/07-develop/03-insert-data/_go_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/insert/json/main.go}} -``` diff --git a/docs-en/07-develop/03-insert-data/_go_opts_telnet.mdx b/docs-en/07-develop/03-insert-data/_go_opts_telnet.mdx deleted file mode 100644 index d5ca40cc14..0000000000 --- a/docs-en/07-develop/03-insert-data/_go_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/insert/telnet/main.go}} -``` diff --git a/docs-en/07-develop/03-insert-data/_go_sql.mdx b/docs-en/07-develop/03-insert-data/_go_sql.mdx deleted file mode 100644 index 613a65add1..0000000000 --- a/docs-en/07-develop/03-insert-data/_go_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/insert/sql/main.go}} -``` diff --git a/docs-en/07-develop/03-insert-data/_java_line.mdx b/docs-en/07-develop/03-insert-data/_java_line.mdx deleted file mode 100644 index 2e59a5d470..0000000000 --- a/docs-en/07-develop/03-insert-data/_java_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/LineProtocolExample.java}} -``` diff --git a/docs-en/07-develop/03-insert-data/_java_opts_json.mdx b/docs-en/07-develop/03-insert-data/_java_opts_json.mdx deleted file mode 100644 index 826a1a07d9..0000000000 --- a/docs-en/07-develop/03-insert-data/_java_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/JSONProtocolExample.java}} -``` diff --git a/docs-en/07-develop/03-insert-data/_java_opts_telnet.mdx b/docs-en/07-develop/03-insert-data/_java_opts_telnet.mdx deleted file mode 100644 index 954dcc1a48..0000000000 --- a/docs-en/07-develop/03-insert-data/_java_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/TelnetLineProtocolExample.java}} -``` diff --git a/docs-en/07-develop/03-insert-data/_java_sql.mdx b/docs-en/07-develop/03-insert-data/_java_sql.mdx deleted file mode 100644 index a863378def..0000000000 --- a/docs-en/07-develop/03-insert-data/_java_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/RestInsertExample.java:insert}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/03-insert-data/_java_stmt.mdx b/docs-en/07-develop/03-insert-data/_java_stmt.mdx deleted file mode 100644 index 54443e535f..0000000000 --- a/docs-en/07-develop/03-insert-data/_java_stmt.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/StmtInsertExample.java}} -``` diff --git a/docs-en/07-develop/03-insert-data/_js_line.mdx b/docs-en/07-develop/03-insert-data/_js_line.mdx deleted file mode 100644 index 172c9bc17b..0000000000 --- a/docs-en/07-develop/03-insert-data/_js_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/influxdb_line_example.js}} -``` diff --git a/docs-en/07-develop/03-insert-data/_js_opts_json.mdx b/docs-en/07-develop/03-insert-data/_js_opts_json.mdx deleted file mode 100644 index 20ac9ec91e..0000000000 --- a/docs-en/07-develop/03-insert-data/_js_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/opentsdb_json_example.js}} -``` diff --git a/docs-en/07-develop/03-insert-data/_js_opts_telnet.mdx b/docs-en/07-develop/03-insert-data/_js_opts_telnet.mdx deleted file mode 100644 index c3c8c40bd6..0000000000 --- a/docs-en/07-develop/03-insert-data/_js_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/opentsdb_telnet_example.js}} -``` diff --git a/docs-en/07-develop/03-insert-data/_js_sql.mdx b/docs-en/07-develop/03-insert-data/_js_sql.mdx deleted file mode 100644 index f5e17c7689..0000000000 --- a/docs-en/07-develop/03-insert-data/_js_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/insert_example.js}} -``` diff --git a/docs-en/07-develop/03-insert-data/_py_line.mdx b/docs-en/07-develop/03-insert-data/_py_line.mdx deleted file mode 100644 index d3bb1ebb34..0000000000 --- a/docs-en/07-develop/03-insert-data/_py_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/line_protocol_example.py}} -``` diff --git a/docs-en/07-develop/03-insert-data/_py_opts_json.mdx b/docs-en/07-develop/03-insert-data/_py_opts_json.mdx deleted file mode 100644 index cfbfe13ccf..0000000000 --- a/docs-en/07-develop/03-insert-data/_py_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/json_protocol_example.py}} -``` diff --git a/docs-en/07-develop/03-insert-data/_py_opts_telnet.mdx b/docs-en/07-develop/03-insert-data/_py_opts_telnet.mdx deleted file mode 100644 index 14bc65a7a3..0000000000 --- a/docs-en/07-develop/03-insert-data/_py_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/telnet_line_protocol_example.py}} -``` diff --git a/docs-en/07-develop/03-insert-data/_py_sql.mdx b/docs-en/07-develop/03-insert-data/_py_sql.mdx deleted file mode 100644 index c0e15b8ec1..0000000000 --- a/docs-en/07-develop/03-insert-data/_py_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/native_insert_example.py}} -``` diff --git a/docs-en/07-develop/03-insert-data/_rust_line.mdx b/docs-en/07-develop/03-insert-data/_rust_line.mdx deleted file mode 100644 index 696ddb7b85..0000000000 --- a/docs-en/07-develop/03-insert-data/_rust_line.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/schemalessexample/examples/influxdb_line_example.rs}} -``` diff --git a/docs-en/07-develop/03-insert-data/_rust_opts_json.mdx b/docs-en/07-develop/03-insert-data/_rust_opts_json.mdx deleted file mode 100644 index 97d9052dac..0000000000 --- a/docs-en/07-develop/03-insert-data/_rust_opts_json.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/schemalessexample/examples/opentsdb_json_example.rs}} -``` diff --git a/docs-en/07-develop/03-insert-data/_rust_opts_telnet.mdx b/docs-en/07-develop/03-insert-data/_rust_opts_telnet.mdx deleted file mode 100644 index 14021f43d8..0000000000 --- a/docs-en/07-develop/03-insert-data/_rust_opts_telnet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/schemalessexample/examples/opentsdb_telnet_example.rs}} -``` diff --git a/docs-en/07-develop/03-insert-data/_rust_sql.mdx b/docs-en/07-develop/03-insert-data/_rust_sql.mdx deleted file mode 100644 index 8e8013e4ad..0000000000 --- a/docs-en/07-develop/03-insert-data/_rust_sql.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/restexample/examples/insert_example.rs}} -``` diff --git a/docs-en/07-develop/03-insert-data/_rust_stmt.mdx b/docs-en/07-develop/03-insert-data/_rust_stmt.mdx deleted file mode 100644 index 590a7a0e71..0000000000 --- a/docs-en/07-develop/03-insert-data/_rust_stmt.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/nativeexample/examples/stmt_example.rs}} -``` diff --git a/docs-en/07-develop/04-query-data/_c.mdx b/docs-en/07-develop/04-query-data/_c.mdx deleted file mode 100644 index 76c9067e2f..0000000000 --- a/docs-en/07-develop/04-query-data/_c.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/query_example.c}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/04-query-data/_c_async.mdx b/docs-en/07-develop/04-query-data/_c_async.mdx deleted file mode 100644 index 09f3d3b3ff..0000000000 --- a/docs-en/07-develop/04-query-data/_c_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/async_query_example.c:demo}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/04-query-data/_cs.mdx b/docs-en/07-develop/04-query-data/_cs.mdx deleted file mode 100644 index 2ab52feb56..0000000000 --- a/docs-en/07-develop/04-query-data/_cs.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/QueryExample.cs}} -``` diff --git a/docs-en/07-develop/04-query-data/_cs_async.mdx b/docs-en/07-develop/04-query-data/_cs_async.mdx deleted file mode 100644 index f868994b30..0000000000 --- a/docs-en/07-develop/04-query-data/_cs_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/AsyncQueryExample.cs}} -``` diff --git a/docs-en/07-develop/04-query-data/_go.mdx b/docs-en/07-develop/04-query-data/_go.mdx deleted file mode 100644 index 417c12315c..0000000000 --- a/docs-en/07-develop/04-query-data/_go.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/query/sync/main.go}} -``` diff --git a/docs-en/07-develop/04-query-data/_go_async.mdx b/docs-en/07-develop/04-query-data/_go_async.mdx deleted file mode 100644 index 72fff411b9..0000000000 --- a/docs-en/07-develop/04-query-data/_go_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/query/async/main.go}} -``` diff --git a/docs-en/07-develop/04-query-data/_java.mdx b/docs-en/07-develop/04-query-data/_java.mdx deleted file mode 100644 index 519b926614..0000000000 --- a/docs-en/07-develop/04-query-data/_java.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```java -{{#include docs-examples/java/src/main/java/com/taos/example/RestQueryExample.java}} -``` diff --git a/docs-en/07-develop/04-query-data/_js.mdx b/docs-en/07-develop/04-query-data/_js.mdx deleted file mode 100644 index c5e4c4f3fc..0000000000 --- a/docs-en/07-develop/04-query-data/_js.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/query_example.js}} -``` diff --git a/docs-en/07-develop/04-query-data/_js_async.mdx b/docs-en/07-develop/04-query-data/_js_async.mdx deleted file mode 100644 index c65d54ed12..0000000000 --- a/docs-en/07-develop/04-query-data/_js_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/async_query_example.js}} -``` diff --git a/docs-en/07-develop/04-query-data/_rust.mdx b/docs-en/07-develop/04-query-data/_rust.mdx deleted file mode 100644 index 742d70fd02..0000000000 --- a/docs-en/07-develop/04-query-data/_rust.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rust -{{#include docs-examples/rust/restexample/examples/query_example.rs}} -``` diff --git a/docs-en/07-develop/_sub_c.mdx b/docs-en/07-develop/_sub_c.mdx deleted file mode 100644 index 95fef0042d..0000000000 --- a/docs-en/07-develop/_sub_c.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```c -{{#include docs-examples/c/subscribe_demo.c}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/_sub_cs.mdx b/docs-en/07-develop/_sub_cs.mdx deleted file mode 100644 index 80934aa4d0..0000000000 --- a/docs-en/07-develop/_sub_cs.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs-examples/csharp/SubscribeDemo.cs}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/_sub_go.mdx b/docs-en/07-develop/_sub_go.mdx deleted file mode 100644 index cd908fc12c..0000000000 --- a/docs-en/07-develop/_sub_go.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```go -{{#include docs-examples/go/sub/main.go}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/_sub_node.mdx b/docs-en/07-develop/_sub_node.mdx deleted file mode 100644 index c93ad627ce..0000000000 --- a/docs-en/07-develop/_sub_node.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```js -{{#include docs-examples/node/nativeexample/subscribe_demo.js}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/_sub_python.mdx b/docs-en/07-develop/_sub_python.mdx deleted file mode 100644 index b817deeba6..0000000000 --- a/docs-en/07-develop/_sub_python.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```py -{{#include docs-examples/python/subscribe_demo.py}} -``` \ No newline at end of file diff --git a/docs-en/07-develop/_sub_rust.mdx b/docs-en/07-develop/_sub_rust.mdx deleted file mode 100644 index 4750cf7a3b..0000000000 --- a/docs-en/07-develop/_sub_rust.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```rs -{{#include docs-examples/rust/nativeexample/examples/subscribe_demo.rs}} -``` \ No newline at end of file diff --git a/docs-en/01-index.md b/docs/en/01-index.md similarity index 100% rename from docs-en/01-index.md rename to docs/en/01-index.md diff --git a/docs-en/02-intro/_category_.yml b/docs/en/02-intro/_category_.yml similarity index 100% rename from docs-en/02-intro/_category_.yml rename to docs/en/02-intro/_category_.yml diff --git a/docs-cn/eco_system.webp b/docs/en/02-intro/eco_system.webp similarity index 100% rename from docs-cn/eco_system.webp rename to docs/en/02-intro/eco_system.webp diff --git a/docs-en/02-intro/index.md b/docs/en/02-intro/index.md similarity index 100% rename from docs-en/02-intro/index.md rename to docs/en/02-intro/index.md diff --git a/docs-en/04-concept/_category_.yml b/docs/en/04-concept/_category_.yml similarity index 100% rename from docs-en/04-concept/_category_.yml rename to docs/en/04-concept/_category_.yml diff --git a/docs-en/04-concept/index.md b/docs/en/04-concept/index.md similarity index 100% rename from docs-en/04-concept/index.md rename to docs/en/04-concept/index.md diff --git a/docs-en/05-get-started/_apt_get_install.mdx b/docs/en/05-get-started/_apt_get_install.mdx similarity index 100% rename from docs-en/05-get-started/_apt_get_install.mdx rename to docs/en/05-get-started/_apt_get_install.mdx diff --git a/docs-en/05-get-started/_category_.yml b/docs/en/05-get-started/_category_.yml similarity index 100% rename from docs-en/05-get-started/_category_.yml rename to docs/en/05-get-started/_category_.yml diff --git a/docs-en/05-get-started/_pkg_install.mdx b/docs/en/05-get-started/_pkg_install.mdx similarity index 100% rename from docs-en/05-get-started/_pkg_install.mdx rename to docs/en/05-get-started/_pkg_install.mdx diff --git a/docs-en/05-get-started/index.md b/docs/en/05-get-started/index.md similarity index 100% rename from docs-en/05-get-started/index.md rename to docs/en/05-get-started/index.md diff --git a/docs-en/07-develop/01-connect/_category_.yml b/docs/en/07-develop/01-connect/_category_.yml similarity index 100% rename from docs-en/07-develop/01-connect/_category_.yml rename to docs/en/07-develop/01-connect/_category_.yml diff --git a/docs/en/07-develop/01-connect/_connect_c.mdx b/docs/en/07-develop/01-connect/_connect_c.mdx new file mode 100644 index 0000000000..4d13d80e08 --- /dev/null +++ b/docs/en/07-develop/01-connect/_connect_c.mdx @@ -0,0 +1,3 @@ +```c title="Native Connection" +{{#include docs/examples/c/connect_example.c}} +``` diff --git a/docs-en/07-develop/01-connect/_connect_cs.mdx b/docs/en/07-develop/01-connect/_connect_cs.mdx similarity index 67% rename from docs-en/07-develop/01-connect/_connect_cs.mdx rename to docs/en/07-develop/01-connect/_connect_cs.mdx index 52ea2d4371..f8d8e519fd 100644 --- a/docs-en/07-develop/01-connect/_connect_cs.mdx +++ b/docs/en/07-develop/01-connect/_connect_cs.mdx @@ -1,5 +1,5 @@ ```csharp title="Native Connection" -{{#include docs-examples/csharp/ConnectExample.cs}} +{{#include docs/examples/csharp/ConnectExample.cs}} ``` :::info diff --git a/docs-en/07-develop/01-connect/_connect_go.mdx b/docs/en/07-develop/01-connect/_connect_go.mdx similarity index 69% rename from docs-en/07-develop/01-connect/_connect_go.mdx rename to docs/en/07-develop/01-connect/_connect_go.mdx index 1dd5d67e35..6f742ea0bc 100644 --- a/docs-en/07-develop/01-connect/_connect_go.mdx +++ b/docs/en/07-develop/01-connect/_connect_go.mdx @@ -1,11 +1,11 @@ #### Unified Database Access Interface ```go title="Native Connection" -{{#include docs-examples/go/connect/cgoexample/main.go}} +{{#include docs/examples/go/connect/cgoexample/main.go}} ``` ```go title="REST Connection" -{{#include docs-examples/go/connect/restexample/main.go}} +{{#include docs/examples/go/connect/restexample/main.go}} ``` #### Advanced Features @@ -13,5 +13,5 @@ The af package of driver-go can also be used to establish connection, with this way some advanced features of TDengine, like parameter binding and subscription, can be used. ```go title="Establish native connection using af package" -{{#include docs-examples/go/connect/afconn/main.go}} +{{#include docs/examples/go/connect/afconn/main.go}} ``` diff --git a/docs-en/07-develop/01-connect/_connect_java.mdx b/docs/en/07-develop/01-connect/_connect_java.mdx similarity index 68% rename from docs-en/07-develop/01-connect/_connect_java.mdx rename to docs/en/07-develop/01-connect/_connect_java.mdx index 1c3e9326bf..880d2aa3e4 100644 --- a/docs-en/07-develop/01-connect/_connect_java.mdx +++ b/docs/en/07-develop/01-connect/_connect_java.mdx @@ -1,15 +1,15 @@ ```java title="Native Connection" -{{#include docs-examples/java/src/main/java/com/taos/example/JNIConnectExample.java}} +{{#include docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java}} ``` ```java title="REST Connection" -{{#include docs-examples/java/src/main/java/com/taos/example/RESTConnectExample.java:main}} +{{#include docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java:main}} ``` When using REST connection, the feature of bulk pulling can be enabled if the size of resulting data set is huge. ```java title="Enable Bulk Pulling" {4} -{{#include docs-examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}} +{{#include docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}} ``` More configuration about connection,please refer to [Java Connector](/reference/connector/java) diff --git a/docs/en/07-develop/01-connect/_connect_node.mdx b/docs/en/07-develop/01-connect/_connect_node.mdx new file mode 100644 index 0000000000..943677b36b --- /dev/null +++ b/docs/en/07-develop/01-connect/_connect_node.mdx @@ -0,0 +1,7 @@ +```js title="Native Connection" +{{#include docs/examples/node/nativeexample/connect.js}} +``` + +```js title="REST Connection" +{{#include docs/examples/node/restexample/connect.js}} +``` diff --git a/docs/en/07-develop/01-connect/_connect_python.mdx b/docs/en/07-develop/01-connect/_connect_python.mdx new file mode 100644 index 0000000000..60b454d52f --- /dev/null +++ b/docs/en/07-develop/01-connect/_connect_python.mdx @@ -0,0 +1,3 @@ +```python title="Native Connection" +{{#include docs/examples/python/connect_example.py}} +``` diff --git a/docs/en/07-develop/01-connect/_connect_r.mdx b/docs/en/07-develop/01-connect/_connect_r.mdx new file mode 100644 index 0000000000..e2d7f631d2 --- /dev/null +++ b/docs/en/07-develop/01-connect/_connect_r.mdx @@ -0,0 +1,3 @@ +```r title="Native Connection" +{{#include docs/examples/R/connect_native.r:demo}} +``` diff --git a/docs-en/07-develop/01-connect/_connect_rust.mdx b/docs/en/07-develop/01-connect/_connect_rust.mdx similarity index 78% rename from docs-en/07-develop/01-connect/_connect_rust.mdx rename to docs/en/07-develop/01-connect/_connect_rust.mdx index aa19f58de6..80ac1f4ff4 100644 --- a/docs-en/07-develop/01-connect/_connect_rust.mdx +++ b/docs/en/07-develop/01-connect/_connect_rust.mdx @@ -1,5 +1,5 @@ ```rust title="Native Connection/REST Connection" -{{#include docs-examples/rust/nativeexample/examples/connect.rs}} +{{#include docs/examples/rust/nativeexample/examples/connect.rs}} ``` :::note diff --git a/docs-en/07-develop/01-connect/index.md b/docs/en/07-develop/01-connect/index.md similarity index 100% rename from docs-en/07-develop/01-connect/index.md rename to docs/en/07-develop/01-connect/index.md diff --git a/docs-en/07-develop/02-model/_category_.yml b/docs/en/07-develop/02-model/_category_.yml similarity index 100% rename from docs-en/07-develop/02-model/_category_.yml rename to docs/en/07-develop/02-model/_category_.yml diff --git a/docs-en/07-develop/02-model/index.mdx b/docs/en/07-develop/02-model/index.mdx similarity index 100% rename from docs-en/07-develop/02-model/index.mdx rename to docs/en/07-develop/02-model/index.mdx diff --git a/docs-en/07-develop/03-insert-data/01-sql-writing.mdx b/docs/en/07-develop/03-insert-data/01-sql-writing.mdx similarity index 100% rename from docs-en/07-develop/03-insert-data/01-sql-writing.mdx rename to docs/en/07-develop/03-insert-data/01-sql-writing.mdx diff --git a/docs-en/07-develop/03-insert-data/02-influxdb-line.mdx b/docs/en/07-develop/03-insert-data/02-influxdb-line.mdx similarity index 100% rename from docs-en/07-develop/03-insert-data/02-influxdb-line.mdx rename to docs/en/07-develop/03-insert-data/02-influxdb-line.mdx diff --git a/docs-en/07-develop/03-insert-data/03-opentsdb-telnet.mdx b/docs/en/07-develop/03-insert-data/03-opentsdb-telnet.mdx similarity index 100% rename from docs-en/07-develop/03-insert-data/03-opentsdb-telnet.mdx rename to docs/en/07-develop/03-insert-data/03-opentsdb-telnet.mdx diff --git a/docs-en/07-develop/03-insert-data/04-opentsdb-json.mdx b/docs/en/07-develop/03-insert-data/04-opentsdb-json.mdx similarity index 100% rename from docs-en/07-develop/03-insert-data/04-opentsdb-json.mdx rename to docs/en/07-develop/03-insert-data/04-opentsdb-json.mdx diff --git a/docs/en/07-develop/03-insert-data/_c_line.mdx b/docs/en/07-develop/03-insert-data/_c_line.mdx new file mode 100644 index 0000000000..7f2f0d5dd8 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_c_line.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/line_example.c:main}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/03-insert-data/_c_opts_json.mdx b/docs/en/07-develop/03-insert-data/_c_opts_json.mdx new file mode 100644 index 0000000000..34b1d8ab3c --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_c_opts_json.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/json_protocol_example.c:main}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/03-insert-data/_c_opts_telnet.mdx b/docs/en/07-develop/03-insert-data/_c_opts_telnet.mdx new file mode 100644 index 0000000000..6bda068d12 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_c_opts_telnet.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/telnet_line_example.c:main}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/03-insert-data/_c_sql.mdx b/docs/en/07-develop/03-insert-data/_c_sql.mdx new file mode 100644 index 0000000000..4e55c3387e --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_c_sql.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/insert_example.c}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/03-insert-data/_c_stmt.mdx b/docs/en/07-develop/03-insert-data/_c_stmt.mdx new file mode 100644 index 0000000000..4b609efe5e --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_c_stmt.mdx @@ -0,0 +1,6 @@ +```c title=Single Row Binding +{{#include docs/examples/c/stmt_example.c}} +``` +```c title=Multiple Row Binding 72:117 +{{#include docs/examples/c/multi_bind_example.c}} +``` \ No newline at end of file diff --git a/docs-en/07-develop/03-insert-data/_category_.yml b/docs/en/07-develop/03-insert-data/_category_.yml similarity index 100% rename from docs-en/07-develop/03-insert-data/_category_.yml rename to docs/en/07-develop/03-insert-data/_category_.yml diff --git a/docs/en/07-develop/03-insert-data/_cs_line.mdx b/docs/en/07-develop/03-insert-data/_cs_line.mdx new file mode 100644 index 0000000000..71f46c62be --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_cs_line.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/InfluxDBLineExample.cs}} +``` diff --git a/docs/en/07-develop/03-insert-data/_cs_opts_json.mdx b/docs/en/07-develop/03-insert-data/_cs_opts_json.mdx new file mode 100644 index 0000000000..8d80d042c9 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_cs_opts_json.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/OptsJsonExample.cs}} +``` diff --git a/docs/en/07-develop/03-insert-data/_cs_opts_telnet.mdx b/docs/en/07-develop/03-insert-data/_cs_opts_telnet.mdx new file mode 100644 index 0000000000..cff32abf1f --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_cs_opts_telnet.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/OptsTelnetExample.cs}} +``` diff --git a/docs/en/07-develop/03-insert-data/_cs_sql.mdx b/docs/en/07-develop/03-insert-data/_cs_sql.mdx new file mode 100644 index 0000000000..1dc7bb3d13 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_cs_sql.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/SQLInsertExample.cs}} +``` diff --git a/docs/en/07-develop/03-insert-data/_cs_stmt.mdx b/docs/en/07-develop/03-insert-data/_cs_stmt.mdx new file mode 100644 index 0000000000..229c874ab9 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_cs_stmt.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/StmtInsertExample.cs}} +``` diff --git a/docs/en/07-develop/03-insert-data/_go_line.mdx b/docs/en/07-develop/03-insert-data/_go_line.mdx new file mode 100644 index 0000000000..df2afc0e87 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_go_line.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/insert/line/main.go}} +``` diff --git a/docs/en/07-develop/03-insert-data/_go_opts_json.mdx b/docs/en/07-develop/03-insert-data/_go_opts_json.mdx new file mode 100644 index 0000000000..362ce43051 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_go_opts_json.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/insert/json/main.go}} +``` diff --git a/docs/en/07-develop/03-insert-data/_go_opts_telnet.mdx b/docs/en/07-develop/03-insert-data/_go_opts_telnet.mdx new file mode 100644 index 0000000000..518ea4c816 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_go_opts_telnet.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/insert/telnet/main.go}} +``` diff --git a/docs/en/07-develop/03-insert-data/_go_sql.mdx b/docs/en/07-develop/03-insert-data/_go_sql.mdx new file mode 100644 index 0000000000..02f4d4e2ba --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_go_sql.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/insert/sql/main.go}} +``` diff --git a/docs-en/07-develop/03-insert-data/_go_stmt.mdx b/docs/en/07-develop/03-insert-data/_go_stmt.mdx similarity index 76% rename from docs-en/07-develop/03-insert-data/_go_stmt.mdx rename to docs/en/07-develop/03-insert-data/_go_stmt.mdx index c32bc21fb9..ab519c9a80 100644 --- a/docs-en/07-develop/03-insert-data/_go_stmt.mdx +++ b/docs/en/07-develop/03-insert-data/_go_stmt.mdx @@ -1,5 +1,5 @@ ```go -{{#include docs-examples/go/insert/stmt/main.go}} +{{#include docs/examples/go/insert/stmt/main.go}} ``` :::tip diff --git a/docs/en/07-develop/03-insert-data/_java_line.mdx b/docs/en/07-develop/03-insert-data/_java_line.mdx new file mode 100644 index 0000000000..17f759d30f --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_java_line.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java}} +``` diff --git a/docs/en/07-develop/03-insert-data/_java_opts_json.mdx b/docs/en/07-develop/03-insert-data/_java_opts_json.mdx new file mode 100644 index 0000000000..1fc0adc202 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_java_opts_json.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/JSONProtocolExample.java}} +``` diff --git a/docs/en/07-develop/03-insert-data/_java_opts_telnet.mdx b/docs/en/07-develop/03-insert-data/_java_opts_telnet.mdx new file mode 100644 index 0000000000..b68f54b4e8 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_java_opts_telnet.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/TelnetLineProtocolExample.java}} +``` diff --git a/docs/en/07-develop/03-insert-data/_java_sql.mdx b/docs/en/07-develop/03-insert-data/_java_sql.mdx new file mode 100644 index 0000000000..636c7e00eb --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_java_sql.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/RestInsertExample.java:insert}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/03-insert-data/_java_stmt.mdx b/docs/en/07-develop/03-insert-data/_java_stmt.mdx new file mode 100644 index 0000000000..2f6a337690 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_java_stmt.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/StmtInsertExample.java}} +``` diff --git a/docs/en/07-develop/03-insert-data/_js_line.mdx b/docs/en/07-develop/03-insert-data/_js_line.mdx new file mode 100644 index 0000000000..cc138a76bd --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_js_line.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/influxdb_line_example.js}} +``` diff --git a/docs/en/07-develop/03-insert-data/_js_opts_json.mdx b/docs/en/07-develop/03-insert-data/_js_opts_json.mdx new file mode 100644 index 0000000000..cb3c275ce8 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_js_opts_json.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/opentsdb_json_example.js}} +``` diff --git a/docs/en/07-develop/03-insert-data/_js_opts_telnet.mdx b/docs/en/07-develop/03-insert-data/_js_opts_telnet.mdx new file mode 100644 index 0000000000..db96742f31 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_js_opts_telnet.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/opentsdb_telnet_example.js}} +``` diff --git a/docs/en/07-develop/03-insert-data/_js_sql.mdx b/docs/en/07-develop/03-insert-data/_js_sql.mdx new file mode 100644 index 0000000000..a9a12f5d2c --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_js_sql.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/insert_example.js}} +``` diff --git a/docs-en/07-develop/03-insert-data/_js_stmt.mdx b/docs/en/07-develop/03-insert-data/_js_stmt.mdx similarity index 70% rename from docs-en/07-develop/03-insert-data/_js_stmt.mdx rename to docs/en/07-develop/03-insert-data/_js_stmt.mdx index 964d7ddc11..8df1065c4a 100644 --- a/docs-en/07-develop/03-insert-data/_js_stmt.mdx +++ b/docs/en/07-develop/03-insert-data/_js_stmt.mdx @@ -1,9 +1,9 @@ ```js title=Single Row Binding -{{#include docs-examples/node/nativeexample/param_bind_example.js}} +{{#include docs/examples/node/nativeexample/param_bind_example.js}} ``` ```js title=Multiple Row Binding -{{#include docs-examples/node/nativeexample/multi_bind_example.js:insertData}} +{{#include docs/examples/node/nativeexample/multi_bind_example.js:insertData}} ``` :::info diff --git a/docs/en/07-develop/03-insert-data/_py_line.mdx b/docs/en/07-develop/03-insert-data/_py_line.mdx new file mode 100644 index 0000000000..85f7e32e66 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_py_line.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/line_protocol_example.py}} +``` diff --git a/docs/en/07-develop/03-insert-data/_py_opts_json.mdx b/docs/en/07-develop/03-insert-data/_py_opts_json.mdx new file mode 100644 index 0000000000..195c7090c0 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_py_opts_json.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/json_protocol_example.py}} +``` diff --git a/docs/en/07-develop/03-insert-data/_py_opts_telnet.mdx b/docs/en/07-develop/03-insert-data/_py_opts_telnet.mdx new file mode 100644 index 0000000000..3bae1ea57b --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_py_opts_telnet.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/telnet_line_protocol_example.py}} +``` diff --git a/docs/en/07-develop/03-insert-data/_py_sql.mdx b/docs/en/07-develop/03-insert-data/_py_sql.mdx new file mode 100644 index 0000000000..1557e3994b --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_py_sql.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/native_insert_example.py}} +``` diff --git a/docs-en/07-develop/03-insert-data/_py_stmt.mdx b/docs/en/07-develop/03-insert-data/_py_stmt.mdx similarity index 69% rename from docs-en/07-develop/03-insert-data/_py_stmt.mdx rename to docs/en/07-develop/03-insert-data/_py_stmt.mdx index 16d98f5432..4f7636bfb8 100644 --- a/docs-en/07-develop/03-insert-data/_py_stmt.mdx +++ b/docs/en/07-develop/03-insert-data/_py_stmt.mdx @@ -1,9 +1,9 @@ ```py title=Single Row Binding -{{#include docs-examples/python/bind_param_example.py}} +{{#include docs/examples/python/bind_param_example.py}} ``` ```py title=Multiple Row Binding -{{#include docs-examples/python/multi_bind_example.py:bind_batch}} +{{#include docs/examples/python/multi_bind_example.py:bind_batch}} ``` :::info diff --git a/docs/en/07-develop/03-insert-data/_rust_line.mdx b/docs/en/07-develop/03-insert-data/_rust_line.mdx new file mode 100644 index 0000000000..dbb35d76bc --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_rust_line.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/schemalessexample/examples/influxdb_line_example.rs}} +``` diff --git a/docs/en/07-develop/03-insert-data/_rust_opts_json.mdx b/docs/en/07-develop/03-insert-data/_rust_opts_json.mdx new file mode 100644 index 0000000000..cc2055510b --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_rust_opts_json.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/schemalessexample/examples/opentsdb_json_example.rs}} +``` diff --git a/docs/en/07-develop/03-insert-data/_rust_opts_telnet.mdx b/docs/en/07-develop/03-insert-data/_rust_opts_telnet.mdx new file mode 100644 index 0000000000..109c0c5d01 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_rust_opts_telnet.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/schemalessexample/examples/opentsdb_telnet_example.rs}} +``` diff --git a/docs/en/07-develop/03-insert-data/_rust_sql.mdx b/docs/en/07-develop/03-insert-data/_rust_sql.mdx new file mode 100644 index 0000000000..fb59a48265 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_rust_sql.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/restexample/examples/insert_example.rs}} +``` diff --git a/docs/en/07-develop/03-insert-data/_rust_stmt.mdx b/docs/en/07-develop/03-insert-data/_rust_stmt.mdx new file mode 100644 index 0000000000..a889b56745 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_rust_stmt.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/nativeexample/examples/stmt_example.rs}} +``` diff --git a/docs-en/07-develop/03-insert-data/index.md b/docs/en/07-develop/03-insert-data/index.md similarity index 100% rename from docs-en/07-develop/03-insert-data/index.md rename to docs/en/07-develop/03-insert-data/index.md diff --git a/docs/en/07-develop/04-query-data/_c.mdx b/docs/en/07-develop/04-query-data/_c.mdx new file mode 100644 index 0000000000..c51557ef29 --- /dev/null +++ b/docs/en/07-develop/04-query-data/_c.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/query_example.c}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/04-query-data/_c_async.mdx b/docs/en/07-develop/04-query-data/_c_async.mdx new file mode 100644 index 0000000000..641a53e82d --- /dev/null +++ b/docs/en/07-develop/04-query-data/_c_async.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/async_query_example.c:demo}} +``` \ No newline at end of file diff --git a/docs-en/07-develop/04-query-data/_category_.yml b/docs/en/07-develop/04-query-data/_category_.yml similarity index 100% rename from docs-en/07-develop/04-query-data/_category_.yml rename to docs/en/07-develop/04-query-data/_category_.yml diff --git a/docs/en/07-develop/04-query-data/_cs.mdx b/docs/en/07-develop/04-query-data/_cs.mdx new file mode 100644 index 0000000000..4bb582ecbf --- /dev/null +++ b/docs/en/07-develop/04-query-data/_cs.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/QueryExample.cs}} +``` diff --git a/docs/en/07-develop/04-query-data/_cs_async.mdx b/docs/en/07-develop/04-query-data/_cs_async.mdx new file mode 100644 index 0000000000..3ecf635fd3 --- /dev/null +++ b/docs/en/07-develop/04-query-data/_cs_async.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/AsyncQueryExample.cs}} +``` diff --git a/docs/en/07-develop/04-query-data/_go.mdx b/docs/en/07-develop/04-query-data/_go.mdx new file mode 100644 index 0000000000..b43894a1eb --- /dev/null +++ b/docs/en/07-develop/04-query-data/_go.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/query/sync/main.go}} +``` diff --git a/docs/en/07-develop/04-query-data/_go_async.mdx b/docs/en/07-develop/04-query-data/_go_async.mdx new file mode 100644 index 0000000000..3fbc6f5b6d --- /dev/null +++ b/docs/en/07-develop/04-query-data/_go_async.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/query/async/main.go}} +``` diff --git a/docs/en/07-develop/04-query-data/_java.mdx b/docs/en/07-develop/04-query-data/_java.mdx new file mode 100644 index 0000000000..74de32658c --- /dev/null +++ b/docs/en/07-develop/04-query-data/_java.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/RestQueryExample.java}} +``` diff --git a/docs/en/07-develop/04-query-data/_js.mdx b/docs/en/07-develop/04-query-data/_js.mdx new file mode 100644 index 0000000000..5883d378e7 --- /dev/null +++ b/docs/en/07-develop/04-query-data/_js.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/query_example.js}} +``` diff --git a/docs/en/07-develop/04-query-data/_js_async.mdx b/docs/en/07-develop/04-query-data/_js_async.mdx new file mode 100644 index 0000000000..4b0f54a034 --- /dev/null +++ b/docs/en/07-develop/04-query-data/_js_async.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/async_query_example.js}} +``` diff --git a/docs-en/07-develop/04-query-data/_py.mdx b/docs/en/07-develop/04-query-data/_py.mdx similarity index 53% rename from docs-en/07-develop/04-query-data/_py.mdx rename to docs/en/07-develop/04-query-data/_py.mdx index aeae42a15e..8ebeca450b 100644 --- a/docs-en/07-develop/04-query-data/_py.mdx +++ b/docs/en/07-develop/04-query-data/_py.mdx @@ -1,11 +1,11 @@ Result set is iterated row by row. ```py -{{#include docs-examples/python/query_example.py:iter}} +{{#include docs/examples/python/query_example.py:iter}} ``` Result set is retrieved as a whole, each row is converted to a dict and returned. ```py -{{#include docs-examples/python/query_example.py:fetch_all}} +{{#include docs/examples/python/query_example.py:fetch_all}} ``` \ No newline at end of file diff --git a/docs-en/07-develop/04-query-data/_py_async.mdx b/docs/en/07-develop/04-query-data/_py_async.mdx similarity index 58% rename from docs-en/07-develop/04-query-data/_py_async.mdx rename to docs/en/07-develop/04-query-data/_py_async.mdx index ed6880ae64..393a5b1733 100644 --- a/docs-en/07-develop/04-query-data/_py_async.mdx +++ b/docs/en/07-develop/04-query-data/_py_async.mdx @@ -1,5 +1,5 @@ ```py -{{#include docs-examples/python/async_query_example.py}} +{{#include docs/examples/python/async_query_example.py}} ``` :::note diff --git a/docs/en/07-develop/04-query-data/_rust.mdx b/docs/en/07-develop/04-query-data/_rust.mdx new file mode 100644 index 0000000000..cab1b403fb --- /dev/null +++ b/docs/en/07-develop/04-query-data/_rust.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/restexample/examples/query_example.rs}} +``` diff --git a/docs-en/07-develop/04-query-data/index.mdx b/docs/en/07-develop/04-query-data/index.mdx similarity index 100% rename from docs-en/07-develop/04-query-data/index.mdx rename to docs/en/07-develop/04-query-data/index.mdx diff --git a/docs-en/07-develop/05-delete-data.mdx b/docs/en/07-develop/05-delete-data.mdx similarity index 100% rename from docs-en/07-develop/05-delete-data.mdx rename to docs/en/07-develop/05-delete-data.mdx diff --git a/docs-en/07-develop/06-continuous-query.mdx b/docs/en/07-develop/06-continuous-query.mdx similarity index 100% rename from docs-en/07-develop/06-continuous-query.mdx rename to docs/en/07-develop/06-continuous-query.mdx diff --git a/docs-en/07-develop/07-subscribe.mdx b/docs/en/07-develop/07-subscribe.mdx similarity index 100% rename from docs-en/07-develop/07-subscribe.mdx rename to docs/en/07-develop/07-subscribe.mdx diff --git a/docs-en/07-develop/08-cache.md b/docs/en/07-develop/08-cache.md similarity index 100% rename from docs-en/07-develop/08-cache.md rename to docs/en/07-develop/08-cache.md diff --git a/docs-en/07-develop/09-udf.md b/docs/en/07-develop/09-udf.md similarity index 100% rename from docs-en/07-develop/09-udf.md rename to docs/en/07-develop/09-udf.md diff --git a/docs-en/07-develop/_category_.yml b/docs/en/07-develop/_category_.yml similarity index 100% rename from docs-en/07-develop/_category_.yml rename to docs/en/07-develop/_category_.yml diff --git a/docs/en/07-develop/_sub_c.mdx b/docs/en/07-develop/_sub_c.mdx new file mode 100644 index 0000000000..da492a0269 --- /dev/null +++ b/docs/en/07-develop/_sub_c.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/subscribe_demo.c}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/_sub_cs.mdx b/docs/en/07-develop/_sub_cs.mdx new file mode 100644 index 0000000000..a435ea0273 --- /dev/null +++ b/docs/en/07-develop/_sub_cs.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/SubscribeDemo.cs}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/_sub_go.mdx b/docs/en/07-develop/_sub_go.mdx new file mode 100644 index 0000000000..34b2aefd92 --- /dev/null +++ b/docs/en/07-develop/_sub_go.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/sub/main.go}} +``` \ No newline at end of file diff --git a/docs-en/07-develop/_sub_java.mdx b/docs/en/07-develop/_sub_java.mdx similarity index 70% rename from docs-en/07-develop/_sub_java.mdx rename to docs/en/07-develop/_sub_java.mdx index e65bc576eb..ab77f61348 100644 --- a/docs-en/07-develop/_sub_java.mdx +++ b/docs/en/07-develop/_sub_java.mdx @@ -1,5 +1,5 @@ ```java -{{#include docs-examples/java/src/main/java/com/taos/example/SubscribeDemo.java}} +{{#include docs/examples/java/src/main/java/com/taos/example/SubscribeDemo.java}} ``` :::note For now Java connector doesn't provide asynchronous subscription, but `TimerTask` can be used to achieve similar purpose. diff --git a/docs/en/07-develop/_sub_node.mdx b/docs/en/07-develop/_sub_node.mdx new file mode 100644 index 0000000000..3eeff0922a --- /dev/null +++ b/docs/en/07-develop/_sub_node.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/subscribe_demo.js}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/_sub_python.mdx b/docs/en/07-develop/_sub_python.mdx new file mode 100644 index 0000000000..490b76fca6 --- /dev/null +++ b/docs/en/07-develop/_sub_python.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/subscribe_demo.py}} +``` \ No newline at end of file diff --git a/docs/en/07-develop/_sub_rust.mdx b/docs/en/07-develop/_sub_rust.mdx new file mode 100644 index 0000000000..afb8d79daa --- /dev/null +++ b/docs/en/07-develop/_sub_rust.mdx @@ -0,0 +1,3 @@ +```rs +{{#include docs/examples/rust/nativeexample/examples/subscribe_demo.rs}} +``` \ No newline at end of file diff --git a/docs-en/07-develop/index.md b/docs/en/07-develop/index.md similarity index 100% rename from docs-en/07-develop/index.md rename to docs/en/07-develop/index.md diff --git a/docs-en/10-cluster/01-deploy.md b/docs/en/10-cluster/01-deploy.md similarity index 100% rename from docs-en/10-cluster/01-deploy.md rename to docs/en/10-cluster/01-deploy.md diff --git a/docs-en/10-cluster/02-cluster-mgmt.md b/docs/en/10-cluster/02-cluster-mgmt.md similarity index 100% rename from docs-en/10-cluster/02-cluster-mgmt.md rename to docs/en/10-cluster/02-cluster-mgmt.md diff --git a/docs-en/10-cluster/03-ha-and-lb.md b/docs/en/10-cluster/03-ha-and-lb.md similarity index 100% rename from docs-en/10-cluster/03-ha-and-lb.md rename to docs/en/10-cluster/03-ha-and-lb.md diff --git a/docs-en/10-cluster/_category_.yml b/docs/en/10-cluster/_category_.yml similarity index 100% rename from docs-en/10-cluster/_category_.yml rename to docs/en/10-cluster/_category_.yml diff --git a/docs-en/10-cluster/index.md b/docs/en/10-cluster/index.md similarity index 100% rename from docs-en/10-cluster/index.md rename to docs/en/10-cluster/index.md diff --git a/docs-en/12-taos-sql/01-data-type.md b/docs/en/12-taos-sql/01-data-type.md similarity index 100% rename from docs-en/12-taos-sql/01-data-type.md rename to docs/en/12-taos-sql/01-data-type.md diff --git a/docs-en/12-taos-sql/02-database.md b/docs/en/12-taos-sql/02-database.md similarity index 100% rename from docs-en/12-taos-sql/02-database.md rename to docs/en/12-taos-sql/02-database.md diff --git a/docs-en/12-taos-sql/03-table.md b/docs/en/12-taos-sql/03-table.md similarity index 100% rename from docs-en/12-taos-sql/03-table.md rename to docs/en/12-taos-sql/03-table.md diff --git a/docs-en/12-taos-sql/04-stable.md b/docs/en/12-taos-sql/04-stable.md similarity index 100% rename from docs-en/12-taos-sql/04-stable.md rename to docs/en/12-taos-sql/04-stable.md diff --git a/docs-en/12-taos-sql/05-insert.md b/docs/en/12-taos-sql/05-insert.md similarity index 100% rename from docs-en/12-taos-sql/05-insert.md rename to docs/en/12-taos-sql/05-insert.md diff --git a/docs-en/12-taos-sql/06-select.md b/docs/en/12-taos-sql/06-select.md similarity index 100% rename from docs-en/12-taos-sql/06-select.md rename to docs/en/12-taos-sql/06-select.md diff --git a/docs-en/12-taos-sql/07-function.md b/docs/en/12-taos-sql/07-function.md similarity index 100% rename from docs-en/12-taos-sql/07-function.md rename to docs/en/12-taos-sql/07-function.md diff --git a/docs-en/12-taos-sql/08-interval.md b/docs/en/12-taos-sql/08-interval.md similarity index 100% rename from docs-en/12-taos-sql/08-interval.md rename to docs/en/12-taos-sql/08-interval.md diff --git a/docs-en/12-taos-sql/09-limit.md b/docs/en/12-taos-sql/09-limit.md similarity index 100% rename from docs-en/12-taos-sql/09-limit.md rename to docs/en/12-taos-sql/09-limit.md diff --git a/docs-en/12-taos-sql/10-json.md b/docs/en/12-taos-sql/10-json.md similarity index 100% rename from docs-en/12-taos-sql/10-json.md rename to docs/en/12-taos-sql/10-json.md diff --git a/docs-en/12-taos-sql/11-escape.md b/docs/en/12-taos-sql/11-escape.md similarity index 100% rename from docs-en/12-taos-sql/11-escape.md rename to docs/en/12-taos-sql/11-escape.md diff --git a/docs-en/12-taos-sql/12-keywords.md b/docs/en/12-taos-sql/12-keywords.md similarity index 100% rename from docs-en/12-taos-sql/12-keywords.md rename to docs/en/12-taos-sql/12-keywords.md diff --git a/docs-en/12-taos-sql/_category_.yml b/docs/en/12-taos-sql/_category_.yml similarity index 100% rename from docs-en/12-taos-sql/_category_.yml rename to docs/en/12-taos-sql/_category_.yml diff --git a/docs-en/12-taos-sql/index.md b/docs/en/12-taos-sql/index.md similarity index 100% rename from docs-en/12-taos-sql/index.md rename to docs/en/12-taos-sql/index.md diff --git a/docs-cn/12-taos-sql/timewindow-1.webp b/docs/en/12-taos-sql/timewindow-1.webp similarity index 100% rename from docs-cn/12-taos-sql/timewindow-1.webp rename to docs/en/12-taos-sql/timewindow-1.webp diff --git a/docs-cn/12-taos-sql/timewindow-2.webp b/docs/en/12-taos-sql/timewindow-2.webp similarity index 100% rename from docs-cn/12-taos-sql/timewindow-2.webp rename to docs/en/12-taos-sql/timewindow-2.webp diff --git a/docs-cn/12-taos-sql/timewindow-3.webp b/docs/en/12-taos-sql/timewindow-3.webp similarity index 100% rename from docs-cn/12-taos-sql/timewindow-3.webp rename to docs/en/12-taos-sql/timewindow-3.webp diff --git a/docs-en/13-operation/01-pkg-install.md b/docs/en/13-operation/01-pkg-install.md similarity index 100% rename from docs-en/13-operation/01-pkg-install.md rename to docs/en/13-operation/01-pkg-install.md diff --git a/docs-en/13-operation/02-planning.mdx b/docs/en/13-operation/02-planning.mdx similarity index 100% rename from docs-en/13-operation/02-planning.mdx rename to docs/en/13-operation/02-planning.mdx diff --git a/docs-en/13-operation/03-tolerance.md b/docs/en/13-operation/03-tolerance.md similarity index 100% rename from docs-en/13-operation/03-tolerance.md rename to docs/en/13-operation/03-tolerance.md diff --git a/docs-en/13-operation/06-admin.md b/docs/en/13-operation/06-admin.md similarity index 100% rename from docs-en/13-operation/06-admin.md rename to docs/en/13-operation/06-admin.md diff --git a/docs-en/13-operation/07-import.md b/docs/en/13-operation/07-import.md similarity index 100% rename from docs-en/13-operation/07-import.md rename to docs/en/13-operation/07-import.md diff --git a/docs-en/13-operation/08-export.md b/docs/en/13-operation/08-export.md similarity index 100% rename from docs-en/13-operation/08-export.md rename to docs/en/13-operation/08-export.md diff --git a/docs-en/13-operation/09-status.md b/docs/en/13-operation/09-status.md similarity index 100% rename from docs-en/13-operation/09-status.md rename to docs/en/13-operation/09-status.md diff --git a/docs-en/13-operation/10-monitor.md b/docs/en/13-operation/10-monitor.md similarity index 100% rename from docs-en/13-operation/10-monitor.md rename to docs/en/13-operation/10-monitor.md diff --git a/docs-en/13-operation/11-optimize.md b/docs/en/13-operation/11-optimize.md similarity index 100% rename from docs-en/13-operation/11-optimize.md rename to docs/en/13-operation/11-optimize.md diff --git a/docs-en/13-operation/17-diagnose.md b/docs/en/13-operation/17-diagnose.md similarity index 100% rename from docs-en/13-operation/17-diagnose.md rename to docs/en/13-operation/17-diagnose.md diff --git a/docs-en/13-operation/_category_.yml b/docs/en/13-operation/_category_.yml similarity index 100% rename from docs-en/13-operation/_category_.yml rename to docs/en/13-operation/_category_.yml diff --git a/docs-en/13-operation/index.md b/docs/en/13-operation/index.md similarity index 100% rename from docs-en/13-operation/index.md rename to docs/en/13-operation/index.md diff --git a/docs-en/14-reference/02-rest-api/02-rest-api.mdx b/docs/en/14-reference/02-rest-api/02-rest-api.mdx similarity index 100% rename from docs-en/14-reference/02-rest-api/02-rest-api.mdx rename to docs/en/14-reference/02-rest-api/02-rest-api.mdx diff --git a/docs-cn/14-reference/02-rest-api/_category_.yml b/docs/en/14-reference/02-rest-api/_category_.yml similarity index 100% rename from docs-cn/14-reference/02-rest-api/_category_.yml rename to docs/en/14-reference/02-rest-api/_category_.yml diff --git a/docs-en/14-reference/03-connector/03-connector.mdx b/docs/en/14-reference/03-connector/03-connector.mdx similarity index 100% rename from docs-en/14-reference/03-connector/03-connector.mdx rename to docs/en/14-reference/03-connector/03-connector.mdx diff --git a/docs-en/14-reference/03-connector/_category_.yml b/docs/en/14-reference/03-connector/_category_.yml similarity index 100% rename from docs-en/14-reference/03-connector/_category_.yml rename to docs/en/14-reference/03-connector/_category_.yml diff --git a/docs-en/14-reference/03-connector/_linux_install.mdx b/docs/en/14-reference/03-connector/_linux_install.mdx similarity index 100% rename from docs-en/14-reference/03-connector/_linux_install.mdx rename to docs/en/14-reference/03-connector/_linux_install.mdx diff --git a/docs-en/14-reference/03-connector/_preparation.mdx b/docs/en/14-reference/03-connector/_preparation.mdx similarity index 100% rename from docs-en/14-reference/03-connector/_preparation.mdx rename to docs/en/14-reference/03-connector/_preparation.mdx diff --git a/docs-en/14-reference/03-connector/_verify_linux.mdx b/docs/en/14-reference/03-connector/_verify_linux.mdx similarity index 100% rename from docs-en/14-reference/03-connector/_verify_linux.mdx rename to docs/en/14-reference/03-connector/_verify_linux.mdx diff --git a/docs-en/14-reference/03-connector/_verify_windows.mdx b/docs/en/14-reference/03-connector/_verify_windows.mdx similarity index 98% rename from docs-en/14-reference/03-connector/_verify_windows.mdx rename to docs/en/14-reference/03-connector/_verify_windows.mdx index c3d6af84d8..daeb151bb1 100644 --- a/docs-en/14-reference/03-connector/_verify_windows.mdx +++ b/docs/en/14-reference/03-connector/_verify_windows.mdx @@ -1,14 +1,14 @@ -Go to the `C:\TDengine` directory from `cmd` and execute TDengine CLI program `taos.exe` directly to connect to the TDengine service and enter the TDengine CLI interface, for example, as follows: - -```text - C:\TDengine>taos - Welcome to the TDengine shell from Linux, Client Version:2.0.5.0 - Copyright (c) 2017 by TAOS Data, Inc. All rights reserved. - taos> show databases; - name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | precision | status | - =================================================================================================================================================================================================================================================================== - test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16 | 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready | - log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready | - Query OK, 2 row(s) in set (0.045000s) - taos> -``` +Go to the `C:\TDengine` directory from `cmd` and execute TDengine CLI program `taos.exe` directly to connect to the TDengine service and enter the TDengine CLI interface, for example, as follows: + +```text + C:\TDengine>taos + Welcome to the TDengine shell from Linux, Client Version:2.0.5.0 + Copyright (c) 2017 by TAOS Data, Inc. All rights reserved. + taos> show databases; + name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | precision | status | + =================================================================================================================================================================================================================================================================== + test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16 | 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready | + log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready | + Query OK, 2 row(s) in set (0.045000s) + taos> +``` diff --git a/docs-en/14-reference/03-connector/_windows_install.mdx b/docs/en/14-reference/03-connector/_windows_install.mdx similarity index 100% rename from docs-en/14-reference/03-connector/_windows_install.mdx rename to docs/en/14-reference/03-connector/_windows_install.mdx diff --git a/docs-cn/14-reference/03-connector/connector.webp b/docs/en/14-reference/03-connector/connector.webp similarity index 100% rename from docs-cn/14-reference/03-connector/connector.webp rename to docs/en/14-reference/03-connector/connector.webp diff --git a/docs-en/14-reference/03-connector/cpp.mdx b/docs/en/14-reference/03-connector/cpp.mdx similarity index 100% rename from docs-en/14-reference/03-connector/cpp.mdx rename to docs/en/14-reference/03-connector/cpp.mdx diff --git a/docs-en/14-reference/03-connector/csharp.mdx b/docs/en/14-reference/03-connector/csharp.mdx similarity index 100% rename from docs-en/14-reference/03-connector/csharp.mdx rename to docs/en/14-reference/03-connector/csharp.mdx diff --git a/docs-en/14-reference/03-connector/go.mdx b/docs/en/14-reference/03-connector/go.mdx similarity index 100% rename from docs-en/14-reference/03-connector/go.mdx rename to docs/en/14-reference/03-connector/go.mdx diff --git a/docs-en/14-reference/03-connector/java.mdx b/docs/en/14-reference/03-connector/java.mdx similarity index 100% rename from docs-en/14-reference/03-connector/java.mdx rename to docs/en/14-reference/03-connector/java.mdx diff --git a/docs-en/14-reference/03-connector/node.mdx b/docs/en/14-reference/03-connector/node.mdx similarity index 100% rename from docs-en/14-reference/03-connector/node.mdx rename to docs/en/14-reference/03-connector/node.mdx diff --git a/docs-en/14-reference/03-connector/php.mdx b/docs/en/14-reference/03-connector/php.mdx similarity index 95% rename from docs-en/14-reference/03-connector/php.mdx rename to docs/en/14-reference/03-connector/php.mdx index 839a5c8c3c..69dcce91e8 100644 --- a/docs-en/14-reference/03-connector/php.mdx +++ b/docs/en/14-reference/03-connector/php.mdx @@ -91,7 +91,7 @@ In this section a few sample programs which use TDengine PHP connector to access Establish Connection ```c -{{#include docs-examples/php/connect.php}} +{{#include docs/examples/php/connect.php}} ``` @@ -102,7 +102,7 @@ In this section a few sample programs which use TDengine PHP connector to access Insert Data ```c -{{#include docs-examples/php/insert.php}} +{{#include docs/examples/php/insert.php}} ``` @@ -113,7 +113,7 @@ In this section a few sample programs which use TDengine PHP connector to access Synchronous Query ```c -{{#include docs-examples/php/query.php}} +{{#include docs/examples/php/query.php}} ``` @@ -124,7 +124,7 @@ In this section a few sample programs which use TDengine PHP connector to access Parameter Binding ```c -{{#include docs-examples/php/insert_stmt.php}} +{{#include docs/examples/php/insert_stmt.php}} ``` diff --git a/docs-en/14-reference/03-connector/python.mdx b/docs/en/14-reference/03-connector/python.mdx similarity index 95% rename from docs-en/14-reference/03-connector/python.mdx rename to docs/en/14-reference/03-connector/python.mdx index 58b94f13ae..04eb2e57d4 100644 --- a/docs-en/14-reference/03-connector/python.mdx +++ b/docs/en/14-reference/03-connector/python.mdx @@ -169,7 +169,7 @@ The following example code assumes that TDengine is installed locally and that t ```python -{{#include docs-examples/python/connect_native_reference.py}} +{{#include docs/examples/python/connect_native_reference.py}} ``` All arguments of the `connect()` function are optional keyword arguments. The following are the connection parameters specified. @@ -194,7 +194,7 @@ The `connect()` function returns a `taos.TaosConnection` instance. In client-sid ```python -{{#include docs-examples/python/connect_rest_examples.py:connect}} +{{#include docs/examples/python/connect_rest_examples.py:connect}} ``` All arguments to the `connect()` function are optional keyword arguments. The following are the connection parameters specified. @@ -219,11 +219,11 @@ All arguments to the `connect()` function are optional keyword arguments. The fo The `TaosConnection` class contains both an implementation of the PEP249 Connection interface (e.g., the `cursor()` method and the `close()` method) and many extensions (e.g., the `execute()`, `query()`, `schemaless_insert()`, and `subscribe()` methods). ```python title="execute method" -{{#include docs-examples/python/connection_usage_native_reference.py:insert}} +{{#include docs/examples/python/connection_usage_native_reference.py:insert}} ``` ```python title="query method" -{{#include docs-examples/python/connection_usage_native_reference.py:query}} +{{#include docs/examples/python/connection_usage_native_reference.py:query}} ``` :::tip @@ -235,14 +235,14 @@ The queried results can only be fetched once. For example, only one of `fetch_al In the above example of using the `TaosConnection` class, we have shown two ways to get the result of a query: `fetch_all()` and `fetch_all_into_dict()`. In addition, `TaosResult` also provides methods to iterate through the result set by rows (`rows_iter`) or by data blocks (`blocks_iter`). Using these two methods will be more efficient in scenarios where the query has a large amount of data. ```python title="blocks_iter method" -{{#include docs-examples/python/result_set_examples.py}} +{{#include docs/examples/python/result_set_examples.py}} ``` ##### Use of the TaosCursor class The `TaosConnection` class and the `TaosResult` class already implement all the functionality of the native interface. If you are familiar with the interfaces in the PEP249 specification, you can also use the methods provided by the `TaosCursor` class. ```python title="Use of TaosCursor" -{{#include docs-examples/python/cursor_usage_native_reference.py}} +{{#include docs/examples/python/cursor_usage_native_reference.py}} ``` :::note @@ -258,7 +258,7 @@ The TaosCursor class uses native connections for write and query operations. In The ``TaosRestCursor`` class is an implementation of the PEP249 Cursor interface. ```python title="Use of TaosRestCursor" -{{#include docs-examples/python/connect_rest_examples.py:basic}} +{{#include docs/examples/python/connect_rest_examples.py:basic}} ``` - `cursor.execute` : Used to execute arbitrary SQL statements. - `cursor.rowcount` : For write operations, returns the number of successful rows written. For query operations, returns the number of rows in the result set. @@ -269,7 +269,7 @@ The ``TaosRestCursor`` class is an implementation of the PEP249 Cursor interface The `RestClient` class is a direct wrapper for the [REST API](/reference/rest-api). It contains only a `sql()` method for executing arbitrary SQL statements and returning the result. ```python title="Use of RestClient" -{{#include docs-examples/python/rest_client_example.py}} +{{#include docs/examples/python/rest_client_example.py}} ``` For a more detailed description of the `sql()` method, please refer to [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html). @@ -283,14 +283,14 @@ For a more detailed description of the `sql()` method, please refer to [RestClie ```python -{{#include docs-examples/python/conn_native_pandas.py}} +{{#include docs/examples/python/conn_native_pandas.py}} ``` ```python -{{#include docs-examples/python/conn_rest_pandas.py}} +{{#include docs/examples/python/conn_rest_pandas.py}} ``` @@ -314,7 +314,7 @@ For a more detailed description of the `sql()` method, please refer to [RestClie All errors from database operations are thrown directly as exceptions and the error message from the database is passed up the exception stack. The application is responsible for exception handling. For example: ```python -{{#include docs-examples/python/handle_exception.py}} +{{#include docs/examples/python/handle_exception.py}} ``` ### About nanoseconds diff --git a/docs-en/14-reference/03-connector/rust.mdx b/docs/en/14-reference/03-connector/rust.mdx similarity index 100% rename from docs-en/14-reference/03-connector/rust.mdx rename to docs/en/14-reference/03-connector/rust.mdx diff --git a/docs-en/14-reference/03-connector/tdengine-jdbc-connector.webp b/docs/en/14-reference/03-connector/tdengine-jdbc-connector.webp similarity index 100% rename from docs-en/14-reference/03-connector/tdengine-jdbc-connector.webp rename to docs/en/14-reference/03-connector/tdengine-jdbc-connector.webp diff --git a/docs-en/14-reference/04-taosadapter.md b/docs/en/14-reference/04-taosadapter.md similarity index 100% rename from docs-en/14-reference/04-taosadapter.md rename to docs/en/14-reference/04-taosadapter.md diff --git a/docs-en/14-reference/05-taosbenchmark.md b/docs/en/14-reference/05-taosbenchmark.md similarity index 100% rename from docs-en/14-reference/05-taosbenchmark.md rename to docs/en/14-reference/05-taosbenchmark.md diff --git a/docs-en/14-reference/06-taosdump.md b/docs/en/14-reference/06-taosdump.md similarity index 100% rename from docs-en/14-reference/06-taosdump.md rename to docs/en/14-reference/06-taosdump.md diff --git a/docs-cn/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json b/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json rename to docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json diff --git a/docs-cn/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json b/docs/en/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json rename to docs/en/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json diff --git a/docs-cn/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp b/docs/en/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp rename to docs/en/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp b/docs/en/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp rename to docs/en/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp b/docs/en/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp rename to docs/en/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp b/docs/en/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp rename to docs/en/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/TDinsight-5-database.webp b/docs/en/14-reference/07-tdinsight/assets/TDinsight-5-database.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/TDinsight-5-database.webp rename to docs/en/14-reference/07-tdinsight/assets/TDinsight-5-database.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp b/docs/en/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp rename to docs/en/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp b/docs/en/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp rename to docs/en/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp b/docs/en/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp rename to docs/en/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/TDinsight-full.webp b/docs/en/14-reference/07-tdinsight/assets/TDinsight-full.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/TDinsight-full.webp rename to docs/en/14-reference/07-tdinsight/assets/TDinsight-full.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/alert-manager-status.webp b/docs/en/14-reference/07-tdinsight/assets/alert-manager-status.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/alert-manager-status.webp rename to docs/en/14-reference/07-tdinsight/assets/alert-manager-status.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/alert-notification-channel.webp b/docs/en/14-reference/07-tdinsight/assets/alert-notification-channel.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/alert-notification-channel.webp rename to docs/en/14-reference/07-tdinsight/assets/alert-notification-channel.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/alert-query-demo.webp b/docs/en/14-reference/07-tdinsight/assets/alert-query-demo.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/alert-query-demo.webp rename to docs/en/14-reference/07-tdinsight/assets/alert-query-demo.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp b/docs/en/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp rename to docs/en/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/alert-rule-test.webp b/docs/en/14-reference/07-tdinsight/assets/alert-rule-test.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/alert-rule-test.webp rename to docs/en/14-reference/07-tdinsight/assets/alert-rule-test.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp b/docs/en/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp rename to docs/en/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp b/docs/en/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp rename to docs/en/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp b/docs/en/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp rename to docs/en/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/howto-add-datasource.webp b/docs/en/14-reference/07-tdinsight/assets/howto-add-datasource.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/howto-add-datasource.webp rename to docs/en/14-reference/07-tdinsight/assets/howto-add-datasource.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/howto-dashboard-display.webp b/docs/en/14-reference/07-tdinsight/assets/howto-dashboard-display.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/howto-dashboard-display.webp rename to docs/en/14-reference/07-tdinsight/assets/howto-dashboard-display.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp b/docs/en/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp rename to docs/en/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/howto-import-dashboard.webp b/docs/en/14-reference/07-tdinsight/assets/howto-import-dashboard.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/howto-import-dashboard.webp rename to docs/en/14-reference/07-tdinsight/assets/howto-import-dashboard.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/import-dashboard-15167.webp b/docs/en/14-reference/07-tdinsight/assets/import-dashboard-15167.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/import-dashboard-15167.webp rename to docs/en/14-reference/07-tdinsight/assets/import-dashboard-15167.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp b/docs/en/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp rename to docs/en/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp b/docs/en/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp rename to docs/en/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/import_dashboard.webp b/docs/en/14-reference/07-tdinsight/assets/import_dashboard.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/import_dashboard.webp rename to docs/en/14-reference/07-tdinsight/assets/import_dashboard.webp diff --git a/docs-cn/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json b/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json rename to docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json diff --git a/docs-cn/14-reference/07-tdinsight/assets/tdengine-grafana.json b/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana.json similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/tdengine-grafana.json rename to docs/en/14-reference/07-tdinsight/assets/tdengine-grafana.json diff --git a/docs-cn/14-reference/07-tdinsight/assets/tdengine_dashboard.webp b/docs/en/14-reference/07-tdinsight/assets/tdengine_dashboard.webp similarity index 100% rename from docs-cn/14-reference/07-tdinsight/assets/tdengine_dashboard.webp rename to docs/en/14-reference/07-tdinsight/assets/tdengine_dashboard.webp diff --git a/docs-en/14-reference/07-tdinsight/index.md b/docs/en/14-reference/07-tdinsight/index.md similarity index 100% rename from docs-en/14-reference/07-tdinsight/index.md rename to docs/en/14-reference/07-tdinsight/index.md diff --git a/docs-en/14-reference/08-taos-shell.md b/docs/en/14-reference/08-taos-shell.md similarity index 100% rename from docs-en/14-reference/08-taos-shell.md rename to docs/en/14-reference/08-taos-shell.md diff --git a/docs-en/14-reference/09-support-platform/_category_.yml b/docs/en/14-reference/09-support-platform/_category_.yml similarity index 100% rename from docs-en/14-reference/09-support-platform/_category_.yml rename to docs/en/14-reference/09-support-platform/_category_.yml diff --git a/docs-en/14-reference/09-support-platform/index.md b/docs/en/14-reference/09-support-platform/index.md similarity index 100% rename from docs-en/14-reference/09-support-platform/index.md rename to docs/en/14-reference/09-support-platform/index.md diff --git a/docs-en/14-reference/11-docker/_category_.yml b/docs/en/14-reference/11-docker/_category_.yml similarity index 100% rename from docs-en/14-reference/11-docker/_category_.yml rename to docs/en/14-reference/11-docker/_category_.yml diff --git a/docs-en/14-reference/11-docker/index.md b/docs/en/14-reference/11-docker/index.md similarity index 100% rename from docs-en/14-reference/11-docker/index.md rename to docs/en/14-reference/11-docker/index.md diff --git a/docs-en/14-reference/12-config/_category_.yml b/docs/en/14-reference/12-config/_category_.yml similarity index 100% rename from docs-en/14-reference/12-config/_category_.yml rename to docs/en/14-reference/12-config/_category_.yml diff --git a/docs-en/14-reference/12-config/index.md b/docs/en/14-reference/12-config/index.md similarity index 100% rename from docs-en/14-reference/12-config/index.md rename to docs/en/14-reference/12-config/index.md diff --git a/docs-en/14-reference/12-directory.md b/docs/en/14-reference/12-directory.md similarity index 100% rename from docs-en/14-reference/12-directory.md rename to docs/en/14-reference/12-directory.md diff --git a/docs-en/14-reference/13-schemaless/13-schemaless.md b/docs/en/14-reference/13-schemaless/13-schemaless.md similarity index 100% rename from docs-en/14-reference/13-schemaless/13-schemaless.md rename to docs/en/14-reference/13-schemaless/13-schemaless.md diff --git a/docs-en/14-reference/13-schemaless/_category_.yml b/docs/en/14-reference/13-schemaless/_category_.yml similarity index 100% rename from docs-en/14-reference/13-schemaless/_category_.yml rename to docs/en/14-reference/13-schemaless/_category_.yml diff --git a/docs-en/14-reference/_category_.yml b/docs/en/14-reference/_category_.yml similarity index 100% rename from docs-en/14-reference/_category_.yml rename to docs/en/14-reference/_category_.yml diff --git a/docs-en/14-reference/_collectd.mdx b/docs/en/14-reference/_collectd.mdx similarity index 100% rename from docs-en/14-reference/_collectd.mdx rename to docs/en/14-reference/_collectd.mdx diff --git a/docs-en/14-reference/_icinga2.mdx b/docs/en/14-reference/_icinga2.mdx similarity index 100% rename from docs-en/14-reference/_icinga2.mdx rename to docs/en/14-reference/_icinga2.mdx diff --git a/docs-en/14-reference/_prometheus.mdx b/docs/en/14-reference/_prometheus.mdx similarity index 100% rename from docs-en/14-reference/_prometheus.mdx rename to docs/en/14-reference/_prometheus.mdx diff --git a/docs-en/14-reference/_statsd.mdx b/docs/en/14-reference/_statsd.mdx similarity index 100% rename from docs-en/14-reference/_statsd.mdx rename to docs/en/14-reference/_statsd.mdx diff --git a/docs-en/14-reference/_tcollector.mdx b/docs/en/14-reference/_tcollector.mdx similarity index 100% rename from docs-en/14-reference/_tcollector.mdx rename to docs/en/14-reference/_tcollector.mdx diff --git a/docs-en/14-reference/_telegraf.mdx b/docs/en/14-reference/_telegraf.mdx similarity index 100% rename from docs-en/14-reference/_telegraf.mdx rename to docs/en/14-reference/_telegraf.mdx diff --git a/docs-en/14-reference/index.md b/docs/en/14-reference/index.md similarity index 100% rename from docs-en/14-reference/index.md rename to docs/en/14-reference/index.md diff --git a/docs-cn/14-reference/taosAdapter-architecture.webp b/docs/en/14-reference/taosAdapter-architecture.webp similarity index 100% rename from docs-cn/14-reference/taosAdapter-architecture.webp rename to docs/en/14-reference/taosAdapter-architecture.webp diff --git a/docs-en/20-third-party/01-grafana.mdx b/docs/en/20-third-party/01-grafana.mdx similarity index 100% rename from docs-en/20-third-party/01-grafana.mdx rename to docs/en/20-third-party/01-grafana.mdx diff --git a/docs-en/20-third-party/02-prometheus.md b/docs/en/20-third-party/02-prometheus.md similarity index 100% rename from docs-en/20-third-party/02-prometheus.md rename to docs/en/20-third-party/02-prometheus.md diff --git a/docs-en/20-third-party/03-telegraf.md b/docs/en/20-third-party/03-telegraf.md similarity index 100% rename from docs-en/20-third-party/03-telegraf.md rename to docs/en/20-third-party/03-telegraf.md diff --git a/docs-en/20-third-party/05-collectd.md b/docs/en/20-third-party/05-collectd.md similarity index 100% rename from docs-en/20-third-party/05-collectd.md rename to docs/en/20-third-party/05-collectd.md diff --git a/docs-en/20-third-party/06-statsd.md b/docs/en/20-third-party/06-statsd.md similarity index 100% rename from docs-en/20-third-party/06-statsd.md rename to docs/en/20-third-party/06-statsd.md diff --git a/docs-en/20-third-party/07-icinga2.md b/docs/en/20-third-party/07-icinga2.md similarity index 100% rename from docs-en/20-third-party/07-icinga2.md rename to docs/en/20-third-party/07-icinga2.md diff --git a/docs-en/20-third-party/08-tcollector.md b/docs/en/20-third-party/08-tcollector.md similarity index 100% rename from docs-en/20-third-party/08-tcollector.md rename to docs/en/20-third-party/08-tcollector.md diff --git a/docs-en/20-third-party/09-emq-broker.md b/docs/en/20-third-party/09-emq-broker.md similarity index 99% rename from docs-en/20-third-party/09-emq-broker.md rename to docs/en/20-third-party/09-emq-broker.md index 7c6b83cf99..8dfa09e6c7 100644 --- a/docs-en/20-third-party/09-emq-broker.md +++ b/docs/en/20-third-party/09-emq-broker.md @@ -108,7 +108,7 @@ Finally, click the "Create" button at bottom left corner saving the rule. ## Compose program to mock data ```javascript -{{#include docs-examples/other/mock.js}} +{{#include docs/examples/other/mock.js}} ``` Note: `CLIENT_NUM` in the code can be set to a smaller value at the beginning of the test to avoid hardware performance be not capable to handle a more significant number of concurrent clients. diff --git a/docs-en/20-third-party/10-hive-mq-broker.md b/docs/en/20-third-party/10-hive-mq-broker.md similarity index 100% rename from docs-en/20-third-party/10-hive-mq-broker.md rename to docs/en/20-third-party/10-hive-mq-broker.md diff --git a/docs-en/20-third-party/11-kafka.md b/docs/en/20-third-party/11-kafka.md similarity index 100% rename from docs-en/20-third-party/11-kafka.md rename to docs/en/20-third-party/11-kafka.md diff --git a/docs-en/20-third-party/_category_.yml b/docs/en/20-third-party/_category_.yml similarity index 100% rename from docs-en/20-third-party/_category_.yml rename to docs/en/20-third-party/_category_.yml diff --git a/docs-en/20-third-party/_deploytaosadapter.mdx b/docs/en/20-third-party/_deploytaosadapter.mdx similarity index 100% rename from docs-en/20-third-party/_deploytaosadapter.mdx rename to docs/en/20-third-party/_deploytaosadapter.mdx diff --git a/docs-cn/20-third-party/emqx/add-action-handler.webp b/docs/en/20-third-party/emqx/add-action-handler.webp similarity index 100% rename from docs-cn/20-third-party/emqx/add-action-handler.webp rename to docs/en/20-third-party/emqx/add-action-handler.webp diff --git a/docs-cn/20-third-party/emqx/check-result-in-taos.webp b/docs/en/20-third-party/emqx/check-result-in-taos.webp similarity index 100% rename from docs-cn/20-third-party/emqx/check-result-in-taos.webp rename to docs/en/20-third-party/emqx/check-result-in-taos.webp diff --git a/docs-cn/20-third-party/emqx/check-rule-matched.webp b/docs/en/20-third-party/emqx/check-rule-matched.webp similarity index 100% rename from docs-cn/20-third-party/emqx/check-rule-matched.webp rename to docs/en/20-third-party/emqx/check-rule-matched.webp diff --git a/docs-cn/20-third-party/emqx/client-num.webp b/docs/en/20-third-party/emqx/client-num.webp similarity index 100% rename from docs-cn/20-third-party/emqx/client-num.webp rename to docs/en/20-third-party/emqx/client-num.webp diff --git a/docs-cn/20-third-party/emqx/create-resource.webp b/docs/en/20-third-party/emqx/create-resource.webp similarity index 100% rename from docs-cn/20-third-party/emqx/create-resource.webp rename to docs/en/20-third-party/emqx/create-resource.webp diff --git a/docs-cn/20-third-party/emqx/create-rule.webp b/docs/en/20-third-party/emqx/create-rule.webp similarity index 100% rename from docs-cn/20-third-party/emqx/create-rule.webp rename to docs/en/20-third-party/emqx/create-rule.webp diff --git a/docs-cn/20-third-party/emqx/edit-action.webp b/docs/en/20-third-party/emqx/edit-action.webp similarity index 100% rename from docs-cn/20-third-party/emqx/edit-action.webp rename to docs/en/20-third-party/emqx/edit-action.webp diff --git a/docs-cn/20-third-party/emqx/edit-resource.webp b/docs/en/20-third-party/emqx/edit-resource.webp similarity index 100% rename from docs-cn/20-third-party/emqx/edit-resource.webp rename to docs/en/20-third-party/emqx/edit-resource.webp diff --git a/docs-cn/20-third-party/emqx/login-dashboard.webp b/docs/en/20-third-party/emqx/login-dashboard.webp similarity index 100% rename from docs-cn/20-third-party/emqx/login-dashboard.webp rename to docs/en/20-third-party/emqx/login-dashboard.webp diff --git a/docs-cn/20-third-party/emqx/rule-engine.webp b/docs/en/20-third-party/emqx/rule-engine.webp similarity index 100% rename from docs-cn/20-third-party/emqx/rule-engine.webp rename to docs/en/20-third-party/emqx/rule-engine.webp diff --git a/docs-cn/20-third-party/emqx/rule-header-key-value.webp b/docs/en/20-third-party/emqx/rule-header-key-value.webp similarity index 100% rename from docs-cn/20-third-party/emqx/rule-header-key-value.webp rename to docs/en/20-third-party/emqx/rule-header-key-value.webp diff --git a/docs-cn/20-third-party/emqx/run-mock.webp b/docs/en/20-third-party/emqx/run-mock.webp similarity index 100% rename from docs-cn/20-third-party/emqx/run-mock.webp rename to docs/en/20-third-party/emqx/run-mock.webp diff --git a/docs-cn/20-third-party/add_datasource1.webp b/docs/en/20-third-party/grafana/add_datasource1.webp similarity index 100% rename from docs-cn/20-third-party/add_datasource1.webp rename to docs/en/20-third-party/grafana/add_datasource1.webp diff --git a/docs-cn/20-third-party/add_datasource2.webp b/docs/en/20-third-party/grafana/add_datasource2.webp similarity index 100% rename from docs-cn/20-third-party/add_datasource2.webp rename to docs/en/20-third-party/grafana/add_datasource2.webp diff --git a/docs-cn/20-third-party/add_datasource3.webp b/docs/en/20-third-party/grafana/add_datasource3.webp similarity index 100% rename from docs-cn/20-third-party/add_datasource3.webp rename to docs/en/20-third-party/grafana/add_datasource3.webp diff --git a/docs-cn/20-third-party/add_datasource4.webp b/docs/en/20-third-party/grafana/add_datasource4.webp similarity index 100% rename from docs-cn/20-third-party/add_datasource4.webp rename to docs/en/20-third-party/grafana/add_datasource4.webp diff --git a/docs-cn/20-third-party/create_dashboard1.webp b/docs/en/20-third-party/grafana/create_dashboard1.webp similarity index 100% rename from docs-cn/20-third-party/create_dashboard1.webp rename to docs/en/20-third-party/grafana/create_dashboard1.webp diff --git a/docs-cn/20-third-party/create_dashboard2.webp b/docs/en/20-third-party/grafana/create_dashboard2.webp similarity index 100% rename from docs-cn/20-third-party/create_dashboard2.webp rename to docs/en/20-third-party/grafana/create_dashboard2.webp diff --git a/docs-en/20-third-party/index.md b/docs/en/20-third-party/index.md similarity index 100% rename from docs-en/20-third-party/index.md rename to docs/en/20-third-party/index.md diff --git a/docs-cn/20-third-party/kafka/Kafka_Connect.webp b/docs/en/20-third-party/kafka/Kafka_Connect.webp similarity index 100% rename from docs-cn/20-third-party/kafka/Kafka_Connect.webp rename to docs/en/20-third-party/kafka/Kafka_Connect.webp diff --git a/docs-cn/20-third-party/kafka/confluentPlatform.webp b/docs/en/20-third-party/kafka/confluentPlatform.webp similarity index 100% rename from docs-cn/20-third-party/kafka/confluentPlatform.webp rename to docs/en/20-third-party/kafka/confluentPlatform.webp diff --git a/docs-cn/20-third-party/kafka/streaming-integration-with-kafka-connect.webp b/docs/en/20-third-party/kafka/streaming-integration-with-kafka-connect.webp similarity index 100% rename from docs-cn/20-third-party/kafka/streaming-integration-with-kafka-connect.webp rename to docs/en/20-third-party/kafka/streaming-integration-with-kafka-connect.webp diff --git a/docs-en/21-tdinternal/01-arch.md b/docs/en/21-tdinternal/01-arch.md similarity index 100% rename from docs-en/21-tdinternal/01-arch.md rename to docs/en/21-tdinternal/01-arch.md diff --git a/docs-en/21-tdinternal/30-iot-big-data.md b/docs/en/21-tdinternal/30-iot-big-data.md similarity index 100% rename from docs-en/21-tdinternal/30-iot-big-data.md rename to docs/en/21-tdinternal/30-iot-big-data.md diff --git a/docs-en/21-tdinternal/_category_.yml b/docs/en/21-tdinternal/_category_.yml similarity index 100% rename from docs-en/21-tdinternal/_category_.yml rename to docs/en/21-tdinternal/_category_.yml diff --git a/docs-cn/21-tdinternal/dnode.webp b/docs/en/21-tdinternal/dnode.webp similarity index 100% rename from docs-cn/21-tdinternal/dnode.webp rename to docs/en/21-tdinternal/dnode.webp diff --git a/docs-en/21-tdinternal/index.md b/docs/en/21-tdinternal/index.md similarity index 100% rename from docs-en/21-tdinternal/index.md rename to docs/en/21-tdinternal/index.md diff --git a/docs-cn/21-tdinternal/message.webp b/docs/en/21-tdinternal/message.webp similarity index 100% rename from docs-cn/21-tdinternal/message.webp rename to docs/en/21-tdinternal/message.webp diff --git a/docs-cn/21-tdinternal/modules.webp b/docs/en/21-tdinternal/modules.webp similarity index 100% rename from docs-cn/21-tdinternal/modules.webp rename to docs/en/21-tdinternal/modules.webp diff --git a/docs-cn/21-tdinternal/multi_tables.webp b/docs/en/21-tdinternal/multi_tables.webp similarity index 100% rename from docs-cn/21-tdinternal/multi_tables.webp rename to docs/en/21-tdinternal/multi_tables.webp diff --git a/docs-cn/21-tdinternal/replica-forward.webp b/docs/en/21-tdinternal/replica-forward.webp similarity index 100% rename from docs-cn/21-tdinternal/replica-forward.webp rename to docs/en/21-tdinternal/replica-forward.webp diff --git a/docs-cn/21-tdinternal/replica-master.webp b/docs/en/21-tdinternal/replica-master.webp similarity index 100% rename from docs-cn/21-tdinternal/replica-master.webp rename to docs/en/21-tdinternal/replica-master.webp diff --git a/docs-cn/21-tdinternal/replica-restore.webp b/docs/en/21-tdinternal/replica-restore.webp similarity index 100% rename from docs-cn/21-tdinternal/replica-restore.webp rename to docs/en/21-tdinternal/replica-restore.webp diff --git a/docs-cn/21-tdinternal/structure.webp b/docs/en/21-tdinternal/structure.webp similarity index 100% rename from docs-cn/21-tdinternal/structure.webp rename to docs/en/21-tdinternal/structure.webp diff --git a/docs-cn/21-tdinternal/vnode.webp b/docs/en/21-tdinternal/vnode.webp similarity index 100% rename from docs-cn/21-tdinternal/vnode.webp rename to docs/en/21-tdinternal/vnode.webp diff --git a/docs-cn/21-tdinternal/write_master.webp b/docs/en/21-tdinternal/write_master.webp similarity index 100% rename from docs-cn/21-tdinternal/write_master.webp rename to docs/en/21-tdinternal/write_master.webp diff --git a/docs-cn/21-tdinternal/write_slave.webp b/docs/en/21-tdinternal/write_slave.webp similarity index 100% rename from docs-cn/21-tdinternal/write_slave.webp rename to docs/en/21-tdinternal/write_slave.webp diff --git a/docs-en/25-application/01-telegraf.md b/docs/en/25-application/01-telegraf.md similarity index 100% rename from docs-en/25-application/01-telegraf.md rename to docs/en/25-application/01-telegraf.md diff --git a/docs-en/25-application/02-collectd.md b/docs/en/25-application/02-collectd.md similarity index 100% rename from docs-en/25-application/02-collectd.md rename to docs/en/25-application/02-collectd.md diff --git a/docs-en/25-application/03-immigrate.md b/docs/en/25-application/03-immigrate.md similarity index 100% rename from docs-en/25-application/03-immigrate.md rename to docs/en/25-application/03-immigrate.md diff --git a/docs-cn/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp b/docs/en/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp similarity index 100% rename from docs-cn/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp rename to docs/en/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp diff --git a/docs-cn/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp b/docs/en/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp similarity index 100% rename from docs-cn/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp rename to docs/en/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp diff --git a/docs-cn/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp b/docs/en/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp similarity index 100% rename from docs-cn/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp rename to docs/en/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp diff --git a/docs-cn/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp b/docs/en/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp similarity index 100% rename from docs-cn/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp rename to docs/en/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp diff --git a/docs-cn/25-application/IT-DevOps-Solutions-Telegraf.webp b/docs/en/25-application/IT-DevOps-Solutions-Telegraf.webp similarity index 100% rename from docs-cn/25-application/IT-DevOps-Solutions-Telegraf.webp rename to docs/en/25-application/IT-DevOps-Solutions-Telegraf.webp diff --git a/docs-cn/25-application/IT-DevOps-Solutions-collectd-dashboard.webp b/docs/en/25-application/IT-DevOps-Solutions-collectd-dashboard.webp similarity index 100% rename from docs-cn/25-application/IT-DevOps-Solutions-collectd-dashboard.webp rename to docs/en/25-application/IT-DevOps-Solutions-collectd-dashboard.webp diff --git a/docs-cn/25-application/IT-DevOps-Solutions-statsd-dashboard.webp b/docs/en/25-application/IT-DevOps-Solutions-statsd-dashboard.webp similarity index 100% rename from docs-cn/25-application/IT-DevOps-Solutions-statsd-dashboard.webp rename to docs/en/25-application/IT-DevOps-Solutions-statsd-dashboard.webp diff --git a/docs-cn/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp b/docs/en/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp similarity index 100% rename from docs-cn/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp rename to docs/en/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp diff --git a/docs-en/25-application/_category_.yml b/docs/en/25-application/_category_.yml similarity index 100% rename from docs-en/25-application/_category_.yml rename to docs/en/25-application/_category_.yml diff --git a/docs-en/25-application/index.md b/docs/en/25-application/index.md similarity index 100% rename from docs-en/25-application/index.md rename to docs/en/25-application/index.md diff --git a/docs-en/27-train-faq/01-faq.md b/docs/en/27-train-faq/01-faq.md similarity index 100% rename from docs-en/27-train-faq/01-faq.md rename to docs/en/27-train-faq/01-faq.md diff --git a/docs-en/27-train-faq/03-docker.md b/docs/en/27-train-faq/03-docker.md similarity index 100% rename from docs-en/27-train-faq/03-docker.md rename to docs/en/27-train-faq/03-docker.md diff --git a/docs-en/27-train-faq/_category_.yml b/docs/en/27-train-faq/_category_.yml similarity index 100% rename from docs-en/27-train-faq/_category_.yml rename to docs/en/27-train-faq/_category_.yml diff --git a/docs-en/27-train-faq/index.md b/docs/en/27-train-faq/index.md similarity index 100% rename from docs-en/27-train-faq/index.md rename to docs/en/27-train-faq/index.md diff --git a/docs-cn/30-release/01-2.6.md b/docs/en/30-release/01-2.6.md similarity index 100% rename from docs-cn/30-release/01-2.6.md rename to docs/en/30-release/01-2.6.md diff --git a/docs-cn/30-release/02-2.4.md b/docs/en/30-release/02-2.4.md similarity index 100% rename from docs-cn/30-release/02-2.4.md rename to docs/en/30-release/02-2.4.md diff --git a/docs-en/30-release/_category_.yml b/docs/en/30-release/_category_.yml similarity index 100% rename from docs-en/30-release/_category_.yml rename to docs/en/30-release/_category_.yml diff --git a/docs-en/30-release/index.md b/docs/en/30-release/index.md similarity index 100% rename from docs-en/30-release/index.md rename to docs/en/30-release/index.md diff --git a/docs-examples/.gitignore b/docs/examples/.gitignore similarity index 100% rename from docs-examples/.gitignore rename to docs/examples/.gitignore diff --git a/docs-examples/.gitignre b/docs/examples/.gitignre similarity index 100% rename from docs-examples/.gitignre rename to docs/examples/.gitignre diff --git a/docs-examples/R/connect_native.r b/docs/examples/R/connect_native.r similarity index 100% rename from docs-examples/R/connect_native.r rename to docs/examples/R/connect_native.r diff --git a/docs-examples/R/connect_rest.r b/docs/examples/R/connect_rest.r similarity index 100% rename from docs-examples/R/connect_rest.r rename to docs/examples/R/connect_rest.r diff --git a/docs-examples/c/.gitignore b/docs/examples/c/.gitignore similarity index 100% rename from docs-examples/c/.gitignore rename to docs/examples/c/.gitignore diff --git a/docs-examples/c/async_query_example.c b/docs/examples/c/async_query_example.c similarity index 100% rename from docs-examples/c/async_query_example.c rename to docs/examples/c/async_query_example.c diff --git a/docs-examples/c/connect_example.c b/docs/examples/c/connect_example.c similarity index 100% rename from docs-examples/c/connect_example.c rename to docs/examples/c/connect_example.c diff --git a/docs-examples/c/error_handle_example.c b/docs/examples/c/error_handle_example.c similarity index 100% rename from docs-examples/c/error_handle_example.c rename to docs/examples/c/error_handle_example.c diff --git a/docs-examples/c/insert_example.c b/docs/examples/c/insert_example.c similarity index 100% rename from docs-examples/c/insert_example.c rename to docs/examples/c/insert_example.c diff --git a/docs-examples/c/json_protocol_example.c b/docs/examples/c/json_protocol_example.c similarity index 100% rename from docs-examples/c/json_protocol_example.c rename to docs/examples/c/json_protocol_example.c diff --git a/docs-examples/c/line_example.c b/docs/examples/c/line_example.c similarity index 100% rename from docs-examples/c/line_example.c rename to docs/examples/c/line_example.c diff --git a/docs-examples/c/multi_bind_example.c b/docs/examples/c/multi_bind_example.c similarity index 100% rename from docs-examples/c/multi_bind_example.c rename to docs/examples/c/multi_bind_example.c diff --git a/docs-examples/c/query_example.c b/docs/examples/c/query_example.c similarity index 100% rename from docs-examples/c/query_example.c rename to docs/examples/c/query_example.c diff --git a/docs-examples/c/stmt_example.c b/docs/examples/c/stmt_example.c similarity index 100% rename from docs-examples/c/stmt_example.c rename to docs/examples/c/stmt_example.c diff --git a/docs-examples/c/subscribe_demo.c b/docs/examples/c/subscribe_demo.c similarity index 100% rename from docs-examples/c/subscribe_demo.c rename to docs/examples/c/subscribe_demo.c diff --git a/docs-examples/c/telnet_line_example.c b/docs/examples/c/telnet_line_example.c similarity index 100% rename from docs-examples/c/telnet_line_example.c rename to docs/examples/c/telnet_line_example.c diff --git a/docs-examples/csharp/.gitignore b/docs/examples/csharp/.gitignore similarity index 100% rename from docs-examples/csharp/.gitignore rename to docs/examples/csharp/.gitignore diff --git a/docs-examples/csharp/AsyncQueryExample.cs b/docs/examples/csharp/AsyncQueryExample.cs similarity index 100% rename from docs-examples/csharp/AsyncQueryExample.cs rename to docs/examples/csharp/AsyncQueryExample.cs diff --git a/docs-examples/csharp/ConnectExample.cs b/docs/examples/csharp/ConnectExample.cs similarity index 100% rename from docs-examples/csharp/ConnectExample.cs rename to docs/examples/csharp/ConnectExample.cs diff --git a/docs-examples/csharp/InfluxDBLineExample.cs b/docs/examples/csharp/InfluxDBLineExample.cs similarity index 100% rename from docs-examples/csharp/InfluxDBLineExample.cs rename to docs/examples/csharp/InfluxDBLineExample.cs diff --git a/docs-examples/csharp/OptsJsonExample.cs b/docs/examples/csharp/OptsJsonExample.cs similarity index 100% rename from docs-examples/csharp/OptsJsonExample.cs rename to docs/examples/csharp/OptsJsonExample.cs diff --git a/docs-examples/csharp/OptsTelnetExample.cs b/docs/examples/csharp/OptsTelnetExample.cs similarity index 100% rename from docs-examples/csharp/OptsTelnetExample.cs rename to docs/examples/csharp/OptsTelnetExample.cs diff --git a/docs-examples/csharp/QueryExample.cs b/docs/examples/csharp/QueryExample.cs similarity index 100% rename from docs-examples/csharp/QueryExample.cs rename to docs/examples/csharp/QueryExample.cs diff --git a/docs-examples/csharp/SQLInsertExample.cs b/docs/examples/csharp/SQLInsertExample.cs similarity index 100% rename from docs-examples/csharp/SQLInsertExample.cs rename to docs/examples/csharp/SQLInsertExample.cs diff --git a/docs-examples/csharp/StmtInsertExample.cs b/docs/examples/csharp/StmtInsertExample.cs similarity index 100% rename from docs-examples/csharp/StmtInsertExample.cs rename to docs/examples/csharp/StmtInsertExample.cs diff --git a/docs-examples/csharp/SubscribeDemo.cs b/docs/examples/csharp/SubscribeDemo.cs similarity index 100% rename from docs-examples/csharp/SubscribeDemo.cs rename to docs/examples/csharp/SubscribeDemo.cs diff --git a/docs-examples/csharp/asyncquery.csproj b/docs/examples/csharp/asyncquery.csproj similarity index 100% rename from docs-examples/csharp/asyncquery.csproj rename to docs/examples/csharp/asyncquery.csproj diff --git a/docs-examples/csharp/connect.csproj b/docs/examples/csharp/connect.csproj similarity index 100% rename from docs-examples/csharp/connect.csproj rename to docs/examples/csharp/connect.csproj diff --git a/docs-examples/csharp/influxdbline.csproj b/docs/examples/csharp/influxdbline.csproj similarity index 100% rename from docs-examples/csharp/influxdbline.csproj rename to docs/examples/csharp/influxdbline.csproj diff --git a/docs-examples/csharp/optsjson.csproj b/docs/examples/csharp/optsjson.csproj similarity index 100% rename from docs-examples/csharp/optsjson.csproj rename to docs/examples/csharp/optsjson.csproj diff --git a/docs-examples/csharp/optstelnet.csproj b/docs/examples/csharp/optstelnet.csproj similarity index 100% rename from docs-examples/csharp/optstelnet.csproj rename to docs/examples/csharp/optstelnet.csproj diff --git a/docs-examples/csharp/query.csproj b/docs/examples/csharp/query.csproj similarity index 100% rename from docs-examples/csharp/query.csproj rename to docs/examples/csharp/query.csproj diff --git a/docs-examples/csharp/sqlinsert.csproj b/docs/examples/csharp/sqlinsert.csproj similarity index 100% rename from docs-examples/csharp/sqlinsert.csproj rename to docs/examples/csharp/sqlinsert.csproj diff --git a/docs-examples/csharp/stmtinsert.csproj b/docs/examples/csharp/stmtinsert.csproj similarity index 100% rename from docs-examples/csharp/stmtinsert.csproj rename to docs/examples/csharp/stmtinsert.csproj diff --git a/docs-examples/csharp/subscribe.csproj b/docs/examples/csharp/subscribe.csproj similarity index 100% rename from docs-examples/csharp/subscribe.csproj rename to docs/examples/csharp/subscribe.csproj diff --git a/docs-examples/go/.gitignore b/docs/examples/go/.gitignore similarity index 100% rename from docs-examples/go/.gitignore rename to docs/examples/go/.gitignore diff --git a/docs-examples/go/connect/afconn/main.go b/docs/examples/go/connect/afconn/main.go similarity index 100% rename from docs-examples/go/connect/afconn/main.go rename to docs/examples/go/connect/afconn/main.go diff --git a/docs-examples/go/connect/cgoexample/main.go b/docs/examples/go/connect/cgoexample/main.go similarity index 100% rename from docs-examples/go/connect/cgoexample/main.go rename to docs/examples/go/connect/cgoexample/main.go diff --git a/docs-examples/go/connect/restexample/main.go b/docs/examples/go/connect/restexample/main.go similarity index 100% rename from docs-examples/go/connect/restexample/main.go rename to docs/examples/go/connect/restexample/main.go diff --git a/docs-examples/go/connect/wrapper/main.go b/docs/examples/go/connect/wrapper/main.go similarity index 100% rename from docs-examples/go/connect/wrapper/main.go rename to docs/examples/go/connect/wrapper/main.go diff --git a/docs-examples/go/go.mod b/docs/examples/go/go.mod similarity index 100% rename from docs-examples/go/go.mod rename to docs/examples/go/go.mod diff --git a/docs-examples/go/insert/json/main.go b/docs/examples/go/insert/json/main.go similarity index 100% rename from docs-examples/go/insert/json/main.go rename to docs/examples/go/insert/json/main.go diff --git a/docs-examples/go/insert/line/main.go b/docs/examples/go/insert/line/main.go similarity index 100% rename from docs-examples/go/insert/line/main.go rename to docs/examples/go/insert/line/main.go diff --git a/docs-examples/go/insert/sql/main.go b/docs/examples/go/insert/sql/main.go similarity index 100% rename from docs-examples/go/insert/sql/main.go rename to docs/examples/go/insert/sql/main.go diff --git a/docs-examples/go/insert/stmt/main.go b/docs/examples/go/insert/stmt/main.go similarity index 100% rename from docs-examples/go/insert/stmt/main.go rename to docs/examples/go/insert/stmt/main.go diff --git a/docs-examples/go/insert/telnet/main.go b/docs/examples/go/insert/telnet/main.go similarity index 100% rename from docs-examples/go/insert/telnet/main.go rename to docs/examples/go/insert/telnet/main.go diff --git a/docs-examples/go/query/async/main.go b/docs/examples/go/query/async/main.go similarity index 100% rename from docs-examples/go/query/async/main.go rename to docs/examples/go/query/async/main.go diff --git a/docs-examples/go/query/sync/main.go b/docs/examples/go/query/sync/main.go similarity index 100% rename from docs-examples/go/query/sync/main.go rename to docs/examples/go/query/sync/main.go diff --git a/docs-examples/go/rest/opentsdbjson/main.go b/docs/examples/go/rest/opentsdbjson/main.go similarity index 100% rename from docs-examples/go/rest/opentsdbjson/main.go rename to docs/examples/go/rest/opentsdbjson/main.go diff --git a/docs-examples/go/sub/main.go b/docs/examples/go/sub/main.go similarity index 100% rename from docs-examples/go/sub/main.go rename to docs/examples/go/sub/main.go diff --git a/docs-examples/java/.gitignore b/docs/examples/java/.gitignore similarity index 100% rename from docs-examples/java/.gitignore rename to docs/examples/java/.gitignore diff --git a/docs-examples/java/pom.xml b/docs/examples/java/pom.xml similarity index 100% rename from docs-examples/java/pom.xml rename to docs/examples/java/pom.xml diff --git a/docs-examples/java/src/main/java/com/taos/example/JNIConnectExample.java b/docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/JNIConnectExample.java rename to docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java diff --git a/docs-examples/java/src/main/java/com/taos/example/JSONProtocolExample.java b/docs/examples/java/src/main/java/com/taos/example/JSONProtocolExample.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/JSONProtocolExample.java rename to docs/examples/java/src/main/java/com/taos/example/JSONProtocolExample.java diff --git a/docs-examples/java/src/main/java/com/taos/example/LineProtocolExample.java b/docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/LineProtocolExample.java rename to docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java diff --git a/docs-examples/java/src/main/java/com/taos/example/RESTConnectExample.java b/docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/RESTConnectExample.java rename to docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java diff --git a/docs-examples/java/src/main/java/com/taos/example/RestInsertExample.java b/docs/examples/java/src/main/java/com/taos/example/RestInsertExample.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/RestInsertExample.java rename to docs/examples/java/src/main/java/com/taos/example/RestInsertExample.java diff --git a/docs-examples/java/src/main/java/com/taos/example/RestQueryExample.java b/docs/examples/java/src/main/java/com/taos/example/RestQueryExample.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/RestQueryExample.java rename to docs/examples/java/src/main/java/com/taos/example/RestQueryExample.java diff --git a/docs-examples/java/src/main/java/com/taos/example/StmtInsertExample.java b/docs/examples/java/src/main/java/com/taos/example/StmtInsertExample.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/StmtInsertExample.java rename to docs/examples/java/src/main/java/com/taos/example/StmtInsertExample.java diff --git a/docs-examples/java/src/main/java/com/taos/example/SubscribeDemo.java b/docs/examples/java/src/main/java/com/taos/example/SubscribeDemo.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/SubscribeDemo.java rename to docs/examples/java/src/main/java/com/taos/example/SubscribeDemo.java diff --git a/docs-examples/java/src/main/java/com/taos/example/TelnetLineProtocolExample.java b/docs/examples/java/src/main/java/com/taos/example/TelnetLineProtocolExample.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/TelnetLineProtocolExample.java rename to docs/examples/java/src/main/java/com/taos/example/TelnetLineProtocolExample.java diff --git a/docs-examples/java/src/main/java/com/taos/example/WSConnectExample.java b/docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java similarity index 100% rename from docs-examples/java/src/main/java/com/taos/example/WSConnectExample.java rename to docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java diff --git a/docs-examples/java/src/test/java/com/taos/test/TestAll.java b/docs/examples/java/src/test/java/com/taos/test/TestAll.java similarity index 100% rename from docs-examples/java/src/test/java/com/taos/test/TestAll.java rename to docs/examples/java/src/test/java/com/taos/test/TestAll.java diff --git a/docs-examples/node/.gitignore b/docs/examples/node/.gitignore similarity index 100% rename from docs-examples/node/.gitignore rename to docs/examples/node/.gitignore diff --git a/docs-examples/node/nativeexample/async_query_example.js b/docs/examples/node/nativeexample/async_query_example.js similarity index 100% rename from docs-examples/node/nativeexample/async_query_example.js rename to docs/examples/node/nativeexample/async_query_example.js diff --git a/docs-examples/node/nativeexample/connect.js b/docs/examples/node/nativeexample/connect.js similarity index 100% rename from docs-examples/node/nativeexample/connect.js rename to docs/examples/node/nativeexample/connect.js diff --git a/docs-examples/node/nativeexample/influxdb_line_example.js b/docs/examples/node/nativeexample/influxdb_line_example.js similarity index 100% rename from docs-examples/node/nativeexample/influxdb_line_example.js rename to docs/examples/node/nativeexample/influxdb_line_example.js diff --git a/docs-examples/node/nativeexample/insert_example.js b/docs/examples/node/nativeexample/insert_example.js similarity index 100% rename from docs-examples/node/nativeexample/insert_example.js rename to docs/examples/node/nativeexample/insert_example.js diff --git a/docs-examples/node/nativeexample/multi_bind_example.js b/docs/examples/node/nativeexample/multi_bind_example.js similarity index 100% rename from docs-examples/node/nativeexample/multi_bind_example.js rename to docs/examples/node/nativeexample/multi_bind_example.js diff --git a/docs-examples/node/nativeexample/opentsdb_json_example.js b/docs/examples/node/nativeexample/opentsdb_json_example.js similarity index 100% rename from docs-examples/node/nativeexample/opentsdb_json_example.js rename to docs/examples/node/nativeexample/opentsdb_json_example.js diff --git a/docs-examples/node/nativeexample/opentsdb_telnet_example.js b/docs/examples/node/nativeexample/opentsdb_telnet_example.js similarity index 100% rename from docs-examples/node/nativeexample/opentsdb_telnet_example.js rename to docs/examples/node/nativeexample/opentsdb_telnet_example.js diff --git a/docs-examples/node/nativeexample/param_bind_example.js b/docs/examples/node/nativeexample/param_bind_example.js similarity index 100% rename from docs-examples/node/nativeexample/param_bind_example.js rename to docs/examples/node/nativeexample/param_bind_example.js diff --git a/docs-examples/node/nativeexample/query_example.js b/docs/examples/node/nativeexample/query_example.js similarity index 100% rename from docs-examples/node/nativeexample/query_example.js rename to docs/examples/node/nativeexample/query_example.js diff --git a/docs-examples/node/nativeexample/subscribe_demo.js b/docs/examples/node/nativeexample/subscribe_demo.js similarity index 100% rename from docs-examples/node/nativeexample/subscribe_demo.js rename to docs/examples/node/nativeexample/subscribe_demo.js diff --git a/docs-examples/node/package.json b/docs/examples/node/package.json similarity index 100% rename from docs-examples/node/package.json rename to docs/examples/node/package.json diff --git a/docs-examples/node/restexample/connect.js b/docs/examples/node/restexample/connect.js similarity index 100% rename from docs-examples/node/restexample/connect.js rename to docs/examples/node/restexample/connect.js diff --git a/docs-examples/other/mock.js b/docs/examples/other/mock.js similarity index 100% rename from docs-examples/other/mock.js rename to docs/examples/other/mock.js diff --git a/docs-examples/php/connect.php b/docs/examples/php/connect.php similarity index 100% rename from docs-examples/php/connect.php rename to docs/examples/php/connect.php diff --git a/docs-examples/php/insert.php b/docs/examples/php/insert.php similarity index 100% rename from docs-examples/php/insert.php rename to docs/examples/php/insert.php diff --git a/docs-examples/php/insert_stmt.php b/docs/examples/php/insert_stmt.php similarity index 100% rename from docs-examples/php/insert_stmt.php rename to docs/examples/php/insert_stmt.php diff --git a/docs-examples/php/query.php b/docs/examples/php/query.php similarity index 100% rename from docs-examples/php/query.php rename to docs/examples/php/query.php diff --git a/docs-examples/python/.gitignore b/docs/examples/python/.gitignore similarity index 100% rename from docs-examples/python/.gitignore rename to docs/examples/python/.gitignore diff --git a/docs-examples/python/.gitkeep b/docs/examples/python/.gitkeep similarity index 100% rename from docs-examples/python/.gitkeep rename to docs/examples/python/.gitkeep diff --git a/docs-examples/python/async_query_example.py b/docs/examples/python/async_query_example.py similarity index 100% rename from docs-examples/python/async_query_example.py rename to docs/examples/python/async_query_example.py diff --git a/docs-examples/python/bind_param_example.py b/docs/examples/python/bind_param_example.py similarity index 100% rename from docs-examples/python/bind_param_example.py rename to docs/examples/python/bind_param_example.py diff --git a/docs-examples/python/conn_native_pandas.py b/docs/examples/python/conn_native_pandas.py similarity index 100% rename from docs-examples/python/conn_native_pandas.py rename to docs/examples/python/conn_native_pandas.py diff --git a/docs-examples/python/conn_rest_pandas.py b/docs/examples/python/conn_rest_pandas.py similarity index 100% rename from docs-examples/python/conn_rest_pandas.py rename to docs/examples/python/conn_rest_pandas.py diff --git a/docs-examples/python/connect_example.py b/docs/examples/python/connect_example.py similarity index 100% rename from docs-examples/python/connect_example.py rename to docs/examples/python/connect_example.py diff --git a/docs-examples/python/connect_native_reference.py b/docs/examples/python/connect_native_reference.py similarity index 100% rename from docs-examples/python/connect_native_reference.py rename to docs/examples/python/connect_native_reference.py diff --git a/docs-examples/python/connect_rest_examples.py b/docs/examples/python/connect_rest_examples.py similarity index 100% rename from docs-examples/python/connect_rest_examples.py rename to docs/examples/python/connect_rest_examples.py diff --git a/docs-examples/python/connection_usage_native_reference.py b/docs/examples/python/connection_usage_native_reference.py similarity index 100% rename from docs-examples/python/connection_usage_native_reference.py rename to docs/examples/python/connection_usage_native_reference.py diff --git a/docs-examples/python/cursor_usage_native_reference.py b/docs/examples/python/cursor_usage_native_reference.py similarity index 100% rename from docs-examples/python/cursor_usage_native_reference.py rename to docs/examples/python/cursor_usage_native_reference.py diff --git a/docs-examples/python/handle_exception.py b/docs/examples/python/handle_exception.py similarity index 100% rename from docs-examples/python/handle_exception.py rename to docs/examples/python/handle_exception.py diff --git a/docs-examples/python/json_protocol_example.py b/docs/examples/python/json_protocol_example.py similarity index 100% rename from docs-examples/python/json_protocol_example.py rename to docs/examples/python/json_protocol_example.py diff --git a/docs-examples/python/line_protocol_example.py b/docs/examples/python/line_protocol_example.py similarity index 100% rename from docs-examples/python/line_protocol_example.py rename to docs/examples/python/line_protocol_example.py diff --git a/docs-examples/python/multi_bind_example.py b/docs/examples/python/multi_bind_example.py similarity index 100% rename from docs-examples/python/multi_bind_example.py rename to docs/examples/python/multi_bind_example.py diff --git a/docs-examples/python/native_insert_example.py b/docs/examples/python/native_insert_example.py similarity index 100% rename from docs-examples/python/native_insert_example.py rename to docs/examples/python/native_insert_example.py diff --git a/docs-examples/python/query_example.py b/docs/examples/python/query_example.py similarity index 100% rename from docs-examples/python/query_example.py rename to docs/examples/python/query_example.py diff --git a/docs-examples/python/rest_client_example.py b/docs/examples/python/rest_client_example.py similarity index 100% rename from docs-examples/python/rest_client_example.py rename to docs/examples/python/rest_client_example.py diff --git a/docs-examples/python/result_set_examples.py b/docs/examples/python/result_set_examples.py similarity index 100% rename from docs-examples/python/result_set_examples.py rename to docs/examples/python/result_set_examples.py diff --git a/docs-examples/python/subscribe_demo.py b/docs/examples/python/subscribe_demo.py similarity index 100% rename from docs-examples/python/subscribe_demo.py rename to docs/examples/python/subscribe_demo.py diff --git a/docs-examples/python/telnet_line_protocol_example.py b/docs/examples/python/telnet_line_protocol_example.py similarity index 100% rename from docs-examples/python/telnet_line_protocol_example.py rename to docs/examples/python/telnet_line_protocol_example.py diff --git a/docs-examples/rust/Cargo.toml b/docs/examples/rust/Cargo.toml similarity index 100% rename from docs-examples/rust/Cargo.toml rename to docs/examples/rust/Cargo.toml diff --git a/docs-examples/rust/nativeexample/Cargo.toml b/docs/examples/rust/nativeexample/Cargo.toml similarity index 100% rename from docs-examples/rust/nativeexample/Cargo.toml rename to docs/examples/rust/nativeexample/Cargo.toml diff --git a/docs-examples/rust/nativeexample/examples/connect.rs b/docs/examples/rust/nativeexample/examples/connect.rs similarity index 100% rename from docs-examples/rust/nativeexample/examples/connect.rs rename to docs/examples/rust/nativeexample/examples/connect.rs diff --git a/docs-examples/rust/nativeexample/examples/stmt_example.rs b/docs/examples/rust/nativeexample/examples/stmt_example.rs similarity index 100% rename from docs-examples/rust/nativeexample/examples/stmt_example.rs rename to docs/examples/rust/nativeexample/examples/stmt_example.rs diff --git a/docs-examples/rust/nativeexample/examples/subscribe_demo.rs b/docs/examples/rust/nativeexample/examples/subscribe_demo.rs similarity index 100% rename from docs-examples/rust/nativeexample/examples/subscribe_demo.rs rename to docs/examples/rust/nativeexample/examples/subscribe_demo.rs diff --git a/docs-examples/rust/nativeexample/src/main.rs b/docs/examples/rust/nativeexample/src/main.rs similarity index 100% rename from docs-examples/rust/nativeexample/src/main.rs rename to docs/examples/rust/nativeexample/src/main.rs diff --git a/docs-examples/rust/restexample/Cargo.toml b/docs/examples/rust/restexample/Cargo.toml similarity index 100% rename from docs-examples/rust/restexample/Cargo.toml rename to docs/examples/rust/restexample/Cargo.toml diff --git a/docs-examples/rust/restexample/examples/connect.rs b/docs/examples/rust/restexample/examples/connect.rs similarity index 100% rename from docs-examples/rust/restexample/examples/connect.rs rename to docs/examples/rust/restexample/examples/connect.rs diff --git a/docs-examples/rust/restexample/examples/insert_example.rs b/docs/examples/rust/restexample/examples/insert_example.rs similarity index 100% rename from docs-examples/rust/restexample/examples/insert_example.rs rename to docs/examples/rust/restexample/examples/insert_example.rs diff --git a/docs-examples/rust/restexample/examples/query_example.rs b/docs/examples/rust/restexample/examples/query_example.rs similarity index 100% rename from docs-examples/rust/restexample/examples/query_example.rs rename to docs/examples/rust/restexample/examples/query_example.rs diff --git a/docs-examples/rust/restexample/src/main.rs b/docs/examples/rust/restexample/src/main.rs similarity index 100% rename from docs-examples/rust/restexample/src/main.rs rename to docs/examples/rust/restexample/src/main.rs diff --git a/docs-examples/rust/schemalessexample/Cargo.toml b/docs/examples/rust/schemalessexample/Cargo.toml similarity index 100% rename from docs-examples/rust/schemalessexample/Cargo.toml rename to docs/examples/rust/schemalessexample/Cargo.toml diff --git a/docs-examples/rust/schemalessexample/examples/influxdb_line_example.rs b/docs/examples/rust/schemalessexample/examples/influxdb_line_example.rs similarity index 100% rename from docs-examples/rust/schemalessexample/examples/influxdb_line_example.rs rename to docs/examples/rust/schemalessexample/examples/influxdb_line_example.rs diff --git a/docs-examples/rust/schemalessexample/examples/opentsdb_json_example.rs b/docs/examples/rust/schemalessexample/examples/opentsdb_json_example.rs similarity index 100% rename from docs-examples/rust/schemalessexample/examples/opentsdb_json_example.rs rename to docs/examples/rust/schemalessexample/examples/opentsdb_json_example.rs diff --git a/docs-examples/rust/schemalessexample/examples/opentsdb_telnet_example.rs b/docs/examples/rust/schemalessexample/examples/opentsdb_telnet_example.rs similarity index 100% rename from docs-examples/rust/schemalessexample/examples/opentsdb_telnet_example.rs rename to docs/examples/rust/schemalessexample/examples/opentsdb_telnet_example.rs diff --git a/docs-examples/rust/schemalessexample/src/main.rs b/docs/examples/rust/schemalessexample/src/main.rs similarity index 100% rename from docs-examples/rust/schemalessexample/src/main.rs rename to docs/examples/rust/schemalessexample/src/main.rs diff --git a/docs-cn/01-index.md b/docs/zh/01-index.md similarity index 100% rename from docs-cn/01-index.md rename to docs/zh/01-index.md diff --git a/docs-cn/02-intro.md b/docs/zh/02-intro.md similarity index 100% rename from docs-cn/02-intro.md rename to docs/zh/02-intro.md diff --git a/docs-cn/04-concept/_category_.yml b/docs/zh/04-concept/_category_.yml similarity index 100% rename from docs-cn/04-concept/_category_.yml rename to docs/zh/04-concept/_category_.yml diff --git a/docs-cn/04-concept/index.md b/docs/zh/04-concept/index.md similarity index 100% rename from docs-cn/04-concept/index.md rename to docs/zh/04-concept/index.md diff --git a/docs-cn/05-get-started/_apt_get_install.mdx b/docs/zh/05-get-started/_apt_get_install.mdx similarity index 100% rename from docs-cn/05-get-started/_apt_get_install.mdx rename to docs/zh/05-get-started/_apt_get_install.mdx diff --git a/docs-cn/05-get-started/_category_.yml b/docs/zh/05-get-started/_category_.yml similarity index 100% rename from docs-cn/05-get-started/_category_.yml rename to docs/zh/05-get-started/_category_.yml diff --git a/docs-cn/05-get-started/_pkg_install.mdx b/docs/zh/05-get-started/_pkg_install.mdx similarity index 100% rename from docs-cn/05-get-started/_pkg_install.mdx rename to docs/zh/05-get-started/_pkg_install.mdx diff --git a/docs-cn/05-get-started/index.md b/docs/zh/05-get-started/index.md similarity index 100% rename from docs-cn/05-get-started/index.md rename to docs/zh/05-get-started/index.md diff --git a/docs-cn/07-develop/01-connect/_category_.yml b/docs/zh/07-develop/01-connect/_category_.yml similarity index 100% rename from docs-cn/07-develop/01-connect/_category_.yml rename to docs/zh/07-develop/01-connect/_category_.yml diff --git a/docs/zh/07-develop/01-connect/_connect_c.mdx b/docs/zh/07-develop/01-connect/_connect_c.mdx new file mode 100644 index 0000000000..1b145538dc --- /dev/null +++ b/docs/zh/07-develop/01-connect/_connect_c.mdx @@ -0,0 +1,3 @@ +```c title="原生连接" +{{#include docs/examples/c/connect_example.c}} +``` diff --git a/docs-cn/07-develop/01-connect/_connect_cs.mdx b/docs/zh/07-develop/01-connect/_connect_cs.mdx similarity index 63% rename from docs-cn/07-develop/01-connect/_connect_cs.mdx rename to docs/zh/07-develop/01-connect/_connect_cs.mdx index 821820e8fe..13b8a5dff2 100644 --- a/docs-cn/07-develop/01-connect/_connect_cs.mdx +++ b/docs/zh/07-develop/01-connect/_connect_cs.mdx @@ -1,5 +1,5 @@ ```csharp title="原生连接" -{{#include docs-examples/csharp/ConnectExample.cs}} +{{#include docs/examples/csharp/ConnectExample.cs}} ``` :::info diff --git a/docs-cn/07-develop/01-connect/_connect_go.mdx b/docs/zh/07-develop/01-connect/_connect_go.mdx similarity index 65% rename from docs-cn/07-develop/01-connect/_connect_go.mdx rename to docs/zh/07-develop/01-connect/_connect_go.mdx index 478768caaa..d69720496d 100644 --- a/docs-cn/07-develop/01-connect/_connect_go.mdx +++ b/docs/zh/07-develop/01-connect/_connect_go.mdx @@ -1,11 +1,11 @@ #### 使用数据库访问统一接口 ```go title="原生连接" -{{#include docs-examples/go/connect/cgoexample/main.go}} +{{#include docs/examples/go/connect/cgoexample/main.go}} ``` ```go title="REST 连接" -{{#include docs-examples/go/connect/restexample/main.go}} +{{#include docs/examples/go/connect/restexample/main.go}} ``` #### 使用高级封装 @@ -13,5 +13,5 @@ 也可以使用 driver-go 的 af 包建立连接。这个模块封装了 TDengine 的高级功能, 如:参数绑定、订阅等。 ```go title="使用 af 包建立原生连接" -{{#include docs-examples/go/connect/afconn/main.go}} +{{#include docs/examples/go/connect/afconn/main.go}} ``` diff --git a/docs-cn/07-develop/01-connect/_connect_java.mdx b/docs/zh/07-develop/01-connect/_connect_java.mdx similarity index 65% rename from docs-cn/07-develop/01-connect/_connect_java.mdx rename to docs/zh/07-develop/01-connect/_connect_java.mdx index 635f39ceb2..f5b8ea1cc2 100644 --- a/docs-cn/07-develop/01-connect/_connect_java.mdx +++ b/docs/zh/07-develop/01-connect/_connect_java.mdx @@ -1,15 +1,15 @@ ```java title="原生连接" -{{#include docs-examples/java/src/main/java/com/taos/example/JNIConnectExample.java}} +{{#include docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java}} ``` ```java title="REST 连接" -{{#include docs-examples/java/src/main/java/com/taos/example/RESTConnectExample.java:main}} +{{#include docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java:main}} ``` 使用 REST 连接时,如果查询数据量比较大,还可开启批量拉取功能。 ```java title="开启批量拉取功能" {4} -{{#include docs-examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}} +{{#include docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}} ``` 更多连接参数配置,参考[Java 连接器](/reference/connector/java) diff --git a/docs/zh/07-develop/01-connect/_connect_node.mdx b/docs/zh/07-develop/01-connect/_connect_node.mdx new file mode 100644 index 0000000000..3a856d4022 --- /dev/null +++ b/docs/zh/07-develop/01-connect/_connect_node.mdx @@ -0,0 +1,7 @@ +```js title="原生连接" +{{#include docs/examples/node/nativeexample/connect.js}} +``` + +```js title="REST 连接" +{{#include docs/examples/node/restexample/connect.js}} +``` diff --git a/docs/zh/07-develop/01-connect/_connect_php.mdx b/docs/zh/07-develop/01-connect/_connect_php.mdx new file mode 100644 index 0000000000..dbad72bc19 --- /dev/null +++ b/docs/zh/07-develop/01-connect/_connect_php.mdx @@ -0,0 +1,3 @@ +```php title="原生连接" +{{#include docs/examples/php/connect.php}} +``` diff --git a/docs/zh/07-develop/01-connect/_connect_python.mdx b/docs/zh/07-develop/01-connect/_connect_python.mdx new file mode 100644 index 0000000000..b331f4648c --- /dev/null +++ b/docs/zh/07-develop/01-connect/_connect_python.mdx @@ -0,0 +1,3 @@ +```python title="原生连接" +{{#include docs/examples/python/connect_example.py}} +``` diff --git a/docs/zh/07-develop/01-connect/_connect_r.mdx b/docs/zh/07-develop/01-connect/_connect_r.mdx new file mode 100644 index 0000000000..ba72dc848c --- /dev/null +++ b/docs/zh/07-develop/01-connect/_connect_r.mdx @@ -0,0 +1,3 @@ +```r title="原生连接" +{{#include docs/examples/R/connect_native.r:demo}} +``` diff --git a/docs-cn/07-develop/01-connect/_connect_rust.mdx b/docs/zh/07-develop/01-connect/_connect_rust.mdx similarity index 78% rename from docs-cn/07-develop/01-connect/_connect_rust.mdx rename to docs/zh/07-develop/01-connect/_connect_rust.mdx index 9e64724c17..25f178a285 100644 --- a/docs-cn/07-develop/01-connect/_connect_rust.mdx +++ b/docs/zh/07-develop/01-connect/_connect_rust.mdx @@ -1,5 +1,5 @@ ```rust title="原生连接/REST 连接" -{{#include docs-examples/rust/nativeexample/examples/connect.rs}} +{{#include docs/examples/rust/nativeexample/examples/connect.rs}} ``` :::note diff --git a/docs-cn/07-develop/01-connect/index.md b/docs/zh/07-develop/01-connect/index.md similarity index 100% rename from docs-cn/07-develop/01-connect/index.md rename to docs/zh/07-develop/01-connect/index.md diff --git a/docs-cn/07-develop/02-model/_category_.yml b/docs/zh/07-develop/02-model/_category_.yml similarity index 100% rename from docs-cn/07-develop/02-model/_category_.yml rename to docs/zh/07-develop/02-model/_category_.yml diff --git a/docs-cn/07-develop/02-model/index.mdx b/docs/zh/07-develop/02-model/index.mdx similarity index 100% rename from docs-cn/07-develop/02-model/index.mdx rename to docs/zh/07-develop/02-model/index.mdx diff --git a/docs-cn/07-develop/03-insert-data/01-sql-writing.mdx b/docs/zh/07-develop/03-insert-data/01-sql-writing.mdx similarity index 100% rename from docs-cn/07-develop/03-insert-data/01-sql-writing.mdx rename to docs/zh/07-develop/03-insert-data/01-sql-writing.mdx diff --git a/docs-cn/07-develop/03-insert-data/02-influxdb-line.mdx b/docs/zh/07-develop/03-insert-data/02-influxdb-line.mdx similarity index 100% rename from docs-cn/07-develop/03-insert-data/02-influxdb-line.mdx rename to docs/zh/07-develop/03-insert-data/02-influxdb-line.mdx diff --git a/docs-cn/07-develop/03-insert-data/03-opentsdb-telnet.mdx b/docs/zh/07-develop/03-insert-data/03-opentsdb-telnet.mdx similarity index 100% rename from docs-cn/07-develop/03-insert-data/03-opentsdb-telnet.mdx rename to docs/zh/07-develop/03-insert-data/03-opentsdb-telnet.mdx diff --git a/docs-cn/07-develop/03-insert-data/04-opentsdb-json.mdx b/docs/zh/07-develop/03-insert-data/04-opentsdb-json.mdx similarity index 100% rename from docs-cn/07-develop/03-insert-data/04-opentsdb-json.mdx rename to docs/zh/07-develop/03-insert-data/04-opentsdb-json.mdx diff --git a/docs/zh/07-develop/03-insert-data/_c_line.mdx b/docs/zh/07-develop/03-insert-data/_c_line.mdx new file mode 100644 index 0000000000..7f2f0d5dd8 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_c_line.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/line_example.c:main}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/03-insert-data/_c_opts_json.mdx b/docs/zh/07-develop/03-insert-data/_c_opts_json.mdx new file mode 100644 index 0000000000..34b1d8ab3c --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_c_opts_json.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/json_protocol_example.c:main}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/03-insert-data/_c_opts_telnet.mdx b/docs/zh/07-develop/03-insert-data/_c_opts_telnet.mdx new file mode 100644 index 0000000000..6bda068d12 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_c_opts_telnet.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/telnet_line_example.c:main}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/03-insert-data/_c_sql.mdx b/docs/zh/07-develop/03-insert-data/_c_sql.mdx new file mode 100644 index 0000000000..4e55c3387e --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_c_sql.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/insert_example.c}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/03-insert-data/_c_stmt.mdx b/docs/zh/07-develop/03-insert-data/_c_stmt.mdx new file mode 100644 index 0000000000..78f2d20dfb --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_c_stmt.mdx @@ -0,0 +1,6 @@ +```c title=一次绑定一行 +{{#include docs/examples/c/stmt_example.c}} +``` +```c title=一次绑定多行 72:117 +{{#include docs/examples/c/multi_bind_example.c}} +``` \ No newline at end of file diff --git a/docs-cn/07-develop/03-insert-data/_category_.yml b/docs/zh/07-develop/03-insert-data/_category_.yml similarity index 100% rename from docs-cn/07-develop/03-insert-data/_category_.yml rename to docs/zh/07-develop/03-insert-data/_category_.yml diff --git a/docs/zh/07-develop/03-insert-data/_cs_line.mdx b/docs/zh/07-develop/03-insert-data/_cs_line.mdx new file mode 100644 index 0000000000..71f46c62be --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_cs_line.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/InfluxDBLineExample.cs}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_cs_opts_json.mdx b/docs/zh/07-develop/03-insert-data/_cs_opts_json.mdx new file mode 100644 index 0000000000..8d80d042c9 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_cs_opts_json.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/OptsJsonExample.cs}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_cs_opts_telnet.mdx b/docs/zh/07-develop/03-insert-data/_cs_opts_telnet.mdx new file mode 100644 index 0000000000..cff32abf1f --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_cs_opts_telnet.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/OptsTelnetExample.cs}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_cs_sql.mdx b/docs/zh/07-develop/03-insert-data/_cs_sql.mdx new file mode 100644 index 0000000000..1dc7bb3d13 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_cs_sql.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/SQLInsertExample.cs}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_cs_stmt.mdx b/docs/zh/07-develop/03-insert-data/_cs_stmt.mdx new file mode 100644 index 0000000000..229c874ab9 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_cs_stmt.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/StmtInsertExample.cs}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_go_line.mdx b/docs/zh/07-develop/03-insert-data/_go_line.mdx new file mode 100644 index 0000000000..df2afc0e87 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_go_line.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/insert/line/main.go}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_go_opts_json.mdx b/docs/zh/07-develop/03-insert-data/_go_opts_json.mdx new file mode 100644 index 0000000000..362ce43051 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_go_opts_json.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/insert/json/main.go}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_go_opts_telnet.mdx b/docs/zh/07-develop/03-insert-data/_go_opts_telnet.mdx new file mode 100644 index 0000000000..518ea4c816 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_go_opts_telnet.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/insert/telnet/main.go}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_go_sql.mdx b/docs/zh/07-develop/03-insert-data/_go_sql.mdx new file mode 100644 index 0000000000..02f4d4e2ba --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_go_sql.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/insert/sql/main.go}} +``` diff --git a/docs-cn/07-develop/03-insert-data/_go_stmt.mdx b/docs/zh/07-develop/03-insert-data/_go_stmt.mdx similarity index 77% rename from docs-cn/07-develop/03-insert-data/_go_stmt.mdx rename to docs/zh/07-develop/03-insert-data/_go_stmt.mdx index 7bb6792d6d..d65a96549f 100644 --- a/docs-cn/07-develop/03-insert-data/_go_stmt.mdx +++ b/docs/zh/07-develop/03-insert-data/_go_stmt.mdx @@ -1,5 +1,5 @@ ```go -{{#include docs-examples/go/insert/stmt/main.go}} +{{#include docs/examples/go/insert/stmt/main.go}} ``` :::tip diff --git a/docs/zh/07-develop/03-insert-data/_java_line.mdx b/docs/zh/07-develop/03-insert-data/_java_line.mdx new file mode 100644 index 0000000000..17f759d30f --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_java_line.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_java_opts_json.mdx b/docs/zh/07-develop/03-insert-data/_java_opts_json.mdx new file mode 100644 index 0000000000..1fc0adc202 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_java_opts_json.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/JSONProtocolExample.java}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_java_opts_telnet.mdx b/docs/zh/07-develop/03-insert-data/_java_opts_telnet.mdx new file mode 100644 index 0000000000..b68f54b4e8 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_java_opts_telnet.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/TelnetLineProtocolExample.java}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_java_sql.mdx b/docs/zh/07-develop/03-insert-data/_java_sql.mdx new file mode 100644 index 0000000000..636c7e00eb --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_java_sql.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/RestInsertExample.java:insert}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/03-insert-data/_java_stmt.mdx b/docs/zh/07-develop/03-insert-data/_java_stmt.mdx new file mode 100644 index 0000000000..2f6a337690 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_java_stmt.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/StmtInsertExample.java}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_js_line.mdx b/docs/zh/07-develop/03-insert-data/_js_line.mdx new file mode 100644 index 0000000000..cc138a76bd --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_js_line.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/influxdb_line_example.js}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_js_opts_json.mdx b/docs/zh/07-develop/03-insert-data/_js_opts_json.mdx new file mode 100644 index 0000000000..cb3c275ce8 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_js_opts_json.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/opentsdb_json_example.js}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_js_opts_telnet.mdx b/docs/zh/07-develop/03-insert-data/_js_opts_telnet.mdx new file mode 100644 index 0000000000..db96742f31 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_js_opts_telnet.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/opentsdb_telnet_example.js}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_js_sql.mdx b/docs/zh/07-develop/03-insert-data/_js_sql.mdx new file mode 100644 index 0000000000..a9a12f5d2c --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_js_sql.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/insert_example.js}} +``` diff --git a/docs-cn/07-develop/03-insert-data/_js_stmt.mdx b/docs/zh/07-develop/03-insert-data/_js_stmt.mdx similarity index 65% rename from docs-cn/07-develop/03-insert-data/_js_stmt.mdx rename to docs/zh/07-develop/03-insert-data/_js_stmt.mdx index 17a6c9785c..b94ae121c5 100644 --- a/docs-cn/07-develop/03-insert-data/_js_stmt.mdx +++ b/docs/zh/07-develop/03-insert-data/_js_stmt.mdx @@ -1,9 +1,9 @@ ```js title=一次绑定一行 -{{#include docs-examples/node/nativeexample/param_bind_example.js}} +{{#include docs/examples/node/nativeexample/param_bind_example.js}} ``` ```js title=一次绑定多行 -{{#include docs-examples/node/nativeexample/multi_bind_example.js:insertData}} +{{#include docs/examples/node/nativeexample/multi_bind_example.js:insertData}} ``` :::info diff --git a/docs/zh/07-develop/03-insert-data/_php_sql.mdx b/docs/zh/07-develop/03-insert-data/_php_sql.mdx new file mode 100644 index 0000000000..78cd663ec2 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_php_sql.mdx @@ -0,0 +1,3 @@ +```php +{{#include docs/examples/php/insert.php}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_php_stmt.mdx b/docs/zh/07-develop/03-insert-data/_php_stmt.mdx new file mode 100644 index 0000000000..3bb7b2f8da --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_php_stmt.mdx @@ -0,0 +1,3 @@ +```php +{{#include docs/examples/php/insert_stmt.php}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_py_line.mdx b/docs/zh/07-develop/03-insert-data/_py_line.mdx new file mode 100644 index 0000000000..85f7e32e66 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_py_line.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/line_protocol_example.py}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_py_opts_json.mdx b/docs/zh/07-develop/03-insert-data/_py_opts_json.mdx new file mode 100644 index 0000000000..195c7090c0 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_py_opts_json.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/json_protocol_example.py}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_py_opts_telnet.mdx b/docs/zh/07-develop/03-insert-data/_py_opts_telnet.mdx new file mode 100644 index 0000000000..3bae1ea57b --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_py_opts_telnet.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/telnet_line_protocol_example.py}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_py_sql.mdx b/docs/zh/07-develop/03-insert-data/_py_sql.mdx new file mode 100644 index 0000000000..1557e3994b --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_py_sql.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/native_insert_example.py}} +``` diff --git a/docs-cn/07-develop/03-insert-data/_py_stmt.mdx b/docs/zh/07-develop/03-insert-data/_py_stmt.mdx similarity index 64% rename from docs-cn/07-develop/03-insert-data/_py_stmt.mdx rename to docs/zh/07-develop/03-insert-data/_py_stmt.mdx index 8241ea86bc..e244288401 100644 --- a/docs-cn/07-develop/03-insert-data/_py_stmt.mdx +++ b/docs/zh/07-develop/03-insert-data/_py_stmt.mdx @@ -1,9 +1,9 @@ ```py title=一次绑定一行 -{{#include docs-examples/python/bind_param_example.py}} +{{#include docs/examples/python/bind_param_example.py}} ``` ```py title=一次绑定多行 -{{#include docs-examples/python/multi_bind_example.py:bind_batch}} +{{#include docs/examples/python/multi_bind_example.py:bind_batch}} ``` :::info diff --git a/docs/zh/07-develop/03-insert-data/_rust_line.mdx b/docs/zh/07-develop/03-insert-data/_rust_line.mdx new file mode 100644 index 0000000000..dbb35d76bc --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_rust_line.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/schemalessexample/examples/influxdb_line_example.rs}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_rust_opts_json.mdx b/docs/zh/07-develop/03-insert-data/_rust_opts_json.mdx new file mode 100644 index 0000000000..cc2055510b --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_rust_opts_json.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/schemalessexample/examples/opentsdb_json_example.rs}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_rust_opts_telnet.mdx b/docs/zh/07-develop/03-insert-data/_rust_opts_telnet.mdx new file mode 100644 index 0000000000..109c0c5d01 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_rust_opts_telnet.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/schemalessexample/examples/opentsdb_telnet_example.rs}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_rust_sql.mdx b/docs/zh/07-develop/03-insert-data/_rust_sql.mdx new file mode 100644 index 0000000000..fb59a48265 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_rust_sql.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/restexample/examples/insert_example.rs}} +``` diff --git a/docs/zh/07-develop/03-insert-data/_rust_stmt.mdx b/docs/zh/07-develop/03-insert-data/_rust_stmt.mdx new file mode 100644 index 0000000000..a889b56745 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_rust_stmt.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/nativeexample/examples/stmt_example.rs}} +``` diff --git a/docs-cn/07-develop/03-insert-data/index.md b/docs/zh/07-develop/03-insert-data/index.md similarity index 100% rename from docs-cn/07-develop/03-insert-data/index.md rename to docs/zh/07-develop/03-insert-data/index.md diff --git a/docs/zh/07-develop/04-query-data/_c.mdx b/docs/zh/07-develop/04-query-data/_c.mdx new file mode 100644 index 0000000000..c51557ef29 --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_c.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/query_example.c}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/04-query-data/_c_async.mdx b/docs/zh/07-develop/04-query-data/_c_async.mdx new file mode 100644 index 0000000000..641a53e82d --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_c_async.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/async_query_example.c:demo}} +``` \ No newline at end of file diff --git a/docs-cn/07-develop/04-query-data/_category_.yml b/docs/zh/07-develop/04-query-data/_category_.yml similarity index 100% rename from docs-cn/07-develop/04-query-data/_category_.yml rename to docs/zh/07-develop/04-query-data/_category_.yml diff --git a/docs/zh/07-develop/04-query-data/_cs.mdx b/docs/zh/07-develop/04-query-data/_cs.mdx new file mode 100644 index 0000000000..4bb582ecbf --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_cs.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/QueryExample.cs}} +``` diff --git a/docs/zh/07-develop/04-query-data/_cs_async.mdx b/docs/zh/07-develop/04-query-data/_cs_async.mdx new file mode 100644 index 0000000000..3ecf635fd3 --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_cs_async.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/AsyncQueryExample.cs}} +``` diff --git a/docs/zh/07-develop/04-query-data/_go.mdx b/docs/zh/07-develop/04-query-data/_go.mdx new file mode 100644 index 0000000000..b43894a1eb --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_go.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/query/sync/main.go}} +``` diff --git a/docs/zh/07-develop/04-query-data/_go_async.mdx b/docs/zh/07-develop/04-query-data/_go_async.mdx new file mode 100644 index 0000000000..3fbc6f5b6d --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_go_async.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/query/async/main.go}} +``` diff --git a/docs/zh/07-develop/04-query-data/_java.mdx b/docs/zh/07-develop/04-query-data/_java.mdx new file mode 100644 index 0000000000..74de32658c --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_java.mdx @@ -0,0 +1,3 @@ +```java +{{#include docs/examples/java/src/main/java/com/taos/example/RestQueryExample.java}} +``` diff --git a/docs/zh/07-develop/04-query-data/_js.mdx b/docs/zh/07-develop/04-query-data/_js.mdx new file mode 100644 index 0000000000..5883d378e7 --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_js.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/query_example.js}} +``` diff --git a/docs/zh/07-develop/04-query-data/_js_async.mdx b/docs/zh/07-develop/04-query-data/_js_async.mdx new file mode 100644 index 0000000000..4b0f54a034 --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_js_async.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/async_query_example.js}} +``` diff --git a/docs/zh/07-develop/04-query-data/_php.mdx b/docs/zh/07-develop/04-query-data/_php.mdx new file mode 100644 index 0000000000..bcafd1cfbc --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_php.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/php/query.php}} +``` diff --git a/docs-cn/07-develop/04-query-data/_py.mdx b/docs/zh/07-develop/04-query-data/_py.mdx similarity index 54% rename from docs-cn/07-develop/04-query-data/_py.mdx rename to docs/zh/07-develop/04-query-data/_py.mdx index 6a1bacdd3e..7184c66b8e 100644 --- a/docs-cn/07-develop/04-query-data/_py.mdx +++ b/docs/zh/07-develop/04-query-data/_py.mdx @@ -1,11 +1,11 @@ 通过迭代逐行获取查询结果。 ```py -{{#include docs-examples/python/query_example.py:iter}} +{{#include docs/examples/python/query_example.py:iter}} ``` 一次获取所有查询结果,并把每一行转化为一个字典返回。 ```py -{{#include docs-examples/python/query_example.py:fetch_all}} +{{#include docs/examples/python/query_example.py:fetch_all}} ``` diff --git a/docs-cn/07-develop/04-query-data/_py_async.mdx b/docs/zh/07-develop/04-query-data/_py_async.mdx similarity index 60% rename from docs-cn/07-develop/04-query-data/_py_async.mdx rename to docs/zh/07-develop/04-query-data/_py_async.mdx index 2399a50df6..dd323ef364 100644 --- a/docs-cn/07-develop/04-query-data/_py_async.mdx +++ b/docs/zh/07-develop/04-query-data/_py_async.mdx @@ -1,5 +1,5 @@ ```py -{{#include docs-examples/python/async_query_example.py}} +{{#include docs/examples/python/async_query_example.py}} ``` :::note diff --git a/docs/zh/07-develop/04-query-data/_rust.mdx b/docs/zh/07-develop/04-query-data/_rust.mdx new file mode 100644 index 0000000000..cab1b403fb --- /dev/null +++ b/docs/zh/07-develop/04-query-data/_rust.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/restexample/examples/query_example.rs}} +``` diff --git a/docs-cn/07-develop/04-query-data/index.mdx b/docs/zh/07-develop/04-query-data/index.mdx similarity index 100% rename from docs-cn/07-develop/04-query-data/index.mdx rename to docs/zh/07-develop/04-query-data/index.mdx diff --git a/docs-cn/07-develop/05-delete-data.mdx b/docs/zh/07-develop/05-delete-data.mdx similarity index 100% rename from docs-cn/07-develop/05-delete-data.mdx rename to docs/zh/07-develop/05-delete-data.mdx diff --git a/docs-cn/07-develop/06-continuous-query.mdx b/docs/zh/07-develop/06-continuous-query.mdx similarity index 100% rename from docs-cn/07-develop/06-continuous-query.mdx rename to docs/zh/07-develop/06-continuous-query.mdx diff --git a/docs-cn/07-develop/07-subscribe.mdx b/docs/zh/07-develop/07-subscribe.mdx similarity index 100% rename from docs-cn/07-develop/07-subscribe.mdx rename to docs/zh/07-develop/07-subscribe.mdx diff --git a/docs-cn/07-develop/08-cache.md b/docs/zh/07-develop/08-cache.md similarity index 100% rename from docs-cn/07-develop/08-cache.md rename to docs/zh/07-develop/08-cache.md diff --git a/docs-cn/07-develop/09-udf.md b/docs/zh/07-develop/09-udf.md similarity index 100% rename from docs-cn/07-develop/09-udf.md rename to docs/zh/07-develop/09-udf.md diff --git a/docs-cn/07-develop/_category_.yml b/docs/zh/07-develop/_category_.yml similarity index 100% rename from docs-cn/07-develop/_category_.yml rename to docs/zh/07-develop/_category_.yml diff --git a/docs/zh/07-develop/_sub_c.mdx b/docs/zh/07-develop/_sub_c.mdx new file mode 100644 index 0000000000..da492a0269 --- /dev/null +++ b/docs/zh/07-develop/_sub_c.mdx @@ -0,0 +1,3 @@ +```c +{{#include docs/examples/c/subscribe_demo.c}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/_sub_cs.mdx b/docs/zh/07-develop/_sub_cs.mdx new file mode 100644 index 0000000000..a435ea0273 --- /dev/null +++ b/docs/zh/07-develop/_sub_cs.mdx @@ -0,0 +1,3 @@ +```csharp +{{#include docs/examples/csharp/SubscribeDemo.cs}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/_sub_go.mdx b/docs/zh/07-develop/_sub_go.mdx new file mode 100644 index 0000000000..34b2aefd92 --- /dev/null +++ b/docs/zh/07-develop/_sub_go.mdx @@ -0,0 +1,3 @@ +```go +{{#include docs/examples/go/sub/main.go}} +``` \ No newline at end of file diff --git a/docs-cn/07-develop/_sub_java.mdx b/docs/zh/07-develop/_sub_java.mdx similarity index 71% rename from docs-cn/07-develop/_sub_java.mdx rename to docs/zh/07-develop/_sub_java.mdx index 1ee0cb1a21..52df23f7dd 100644 --- a/docs-cn/07-develop/_sub_java.mdx +++ b/docs/zh/07-develop/_sub_java.mdx @@ -1,5 +1,5 @@ ```java -{{#include docs-examples/java/src/main/java/com/taos/example/SubscribeDemo.java}} +{{#include docs/examples/java/src/main/java/com/taos/example/SubscribeDemo.java}} ``` :::note 目前 Java 接口没有提供异步订阅模式,但用户程序可以通过创建 `TimerTask` 等方式达到同样的效果。 diff --git a/docs/zh/07-develop/_sub_node.mdx b/docs/zh/07-develop/_sub_node.mdx new file mode 100644 index 0000000000..3eeff0922a --- /dev/null +++ b/docs/zh/07-develop/_sub_node.mdx @@ -0,0 +1,3 @@ +```js +{{#include docs/examples/node/nativeexample/subscribe_demo.js}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/_sub_python.mdx b/docs/zh/07-develop/_sub_python.mdx new file mode 100644 index 0000000000..490b76fca6 --- /dev/null +++ b/docs/zh/07-develop/_sub_python.mdx @@ -0,0 +1,3 @@ +```py +{{#include docs/examples/python/subscribe_demo.py}} +``` \ No newline at end of file diff --git a/docs/zh/07-develop/_sub_rust.mdx b/docs/zh/07-develop/_sub_rust.mdx new file mode 100644 index 0000000000..afb8d79daa --- /dev/null +++ b/docs/zh/07-develop/_sub_rust.mdx @@ -0,0 +1,3 @@ +```rs +{{#include docs/examples/rust/nativeexample/examples/subscribe_demo.rs}} +``` \ No newline at end of file diff --git a/docs-cn/07-develop/index.md b/docs/zh/07-develop/index.md similarity index 100% rename from docs-cn/07-develop/index.md rename to docs/zh/07-develop/index.md diff --git a/docs-cn/10-cluster/01-deploy.md b/docs/zh/10-cluster/01-deploy.md similarity index 100% rename from docs-cn/10-cluster/01-deploy.md rename to docs/zh/10-cluster/01-deploy.md diff --git a/docs-cn/10-cluster/02-cluster-mgmt.md b/docs/zh/10-cluster/02-cluster-mgmt.md similarity index 100% rename from docs-cn/10-cluster/02-cluster-mgmt.md rename to docs/zh/10-cluster/02-cluster-mgmt.md diff --git a/docs-cn/10-cluster/03-ha-and-lb.md b/docs/zh/10-cluster/03-ha-and-lb.md similarity index 100% rename from docs-cn/10-cluster/03-ha-and-lb.md rename to docs/zh/10-cluster/03-ha-and-lb.md diff --git a/docs-cn/10-cluster/_category_.yml b/docs/zh/10-cluster/_category_.yml similarity index 100% rename from docs-cn/10-cluster/_category_.yml rename to docs/zh/10-cluster/_category_.yml diff --git a/docs-cn/10-cluster/index.md b/docs/zh/10-cluster/index.md similarity index 100% rename from docs-cn/10-cluster/index.md rename to docs/zh/10-cluster/index.md diff --git a/docs-cn/12-taos-sql/01-data-type.md b/docs/zh/12-taos-sql/01-data-type.md similarity index 100% rename from docs-cn/12-taos-sql/01-data-type.md rename to docs/zh/12-taos-sql/01-data-type.md diff --git a/docs-cn/12-taos-sql/02-database.md b/docs/zh/12-taos-sql/02-database.md similarity index 100% rename from docs-cn/12-taos-sql/02-database.md rename to docs/zh/12-taos-sql/02-database.md diff --git a/docs-cn/12-taos-sql/03-table.md b/docs/zh/12-taos-sql/03-table.md similarity index 100% rename from docs-cn/12-taos-sql/03-table.md rename to docs/zh/12-taos-sql/03-table.md diff --git a/docs-cn/12-taos-sql/04-stable.md b/docs/zh/12-taos-sql/04-stable.md similarity index 100% rename from docs-cn/12-taos-sql/04-stable.md rename to docs/zh/12-taos-sql/04-stable.md diff --git a/docs-cn/12-taos-sql/05-insert.md b/docs/zh/12-taos-sql/05-insert.md similarity index 100% rename from docs-cn/12-taos-sql/05-insert.md rename to docs/zh/12-taos-sql/05-insert.md diff --git a/docs-cn/12-taos-sql/06-select.md b/docs/zh/12-taos-sql/06-select.md similarity index 100% rename from docs-cn/12-taos-sql/06-select.md rename to docs/zh/12-taos-sql/06-select.md diff --git a/docs-cn/12-taos-sql/07-function.md b/docs/zh/12-taos-sql/07-function.md similarity index 100% rename from docs-cn/12-taos-sql/07-function.md rename to docs/zh/12-taos-sql/07-function.md diff --git a/docs-cn/12-taos-sql/08-interval.md b/docs/zh/12-taos-sql/08-interval.md similarity index 100% rename from docs-cn/12-taos-sql/08-interval.md rename to docs/zh/12-taos-sql/08-interval.md diff --git a/docs-cn/12-taos-sql/09-limit.md b/docs/zh/12-taos-sql/09-limit.md similarity index 100% rename from docs-cn/12-taos-sql/09-limit.md rename to docs/zh/12-taos-sql/09-limit.md diff --git a/docs-cn/12-taos-sql/10-json.md b/docs/zh/12-taos-sql/10-json.md similarity index 100% rename from docs-cn/12-taos-sql/10-json.md rename to docs/zh/12-taos-sql/10-json.md diff --git a/docs-cn/12-taos-sql/11-escape.md b/docs/zh/12-taos-sql/11-escape.md similarity index 100% rename from docs-cn/12-taos-sql/11-escape.md rename to docs/zh/12-taos-sql/11-escape.md diff --git a/docs-cn/12-taos-sql/12-keywords/_category_.yml b/docs/zh/12-taos-sql/12-keywords/_category_.yml similarity index 100% rename from docs-cn/12-taos-sql/12-keywords/_category_.yml rename to docs/zh/12-taos-sql/12-keywords/_category_.yml diff --git a/docs-cn/12-taos-sql/12-keywords/index.md b/docs/zh/12-taos-sql/12-keywords/index.md similarity index 100% rename from docs-cn/12-taos-sql/12-keywords/index.md rename to docs/zh/12-taos-sql/12-keywords/index.md diff --git a/docs-cn/12-taos-sql/_category_.yml b/docs/zh/12-taos-sql/_category_.yml similarity index 100% rename from docs-cn/12-taos-sql/_category_.yml rename to docs/zh/12-taos-sql/_category_.yml diff --git a/docs-cn/12-taos-sql/index.md b/docs/zh/12-taos-sql/index.md similarity index 100% rename from docs-cn/12-taos-sql/index.md rename to docs/zh/12-taos-sql/index.md diff --git a/docs-en/12-taos-sql/timewindow-1.webp b/docs/zh/12-taos-sql/timewindow-1.webp similarity index 100% rename from docs-en/12-taos-sql/timewindow-1.webp rename to docs/zh/12-taos-sql/timewindow-1.webp diff --git a/docs-en/12-taos-sql/timewindow-2.webp b/docs/zh/12-taos-sql/timewindow-2.webp similarity index 100% rename from docs-en/12-taos-sql/timewindow-2.webp rename to docs/zh/12-taos-sql/timewindow-2.webp diff --git a/docs-en/12-taos-sql/timewindow-3.webp b/docs/zh/12-taos-sql/timewindow-3.webp similarity index 100% rename from docs-en/12-taos-sql/timewindow-3.webp rename to docs/zh/12-taos-sql/timewindow-3.webp diff --git a/docs-cn/13-operation/01-pkg-install.md b/docs/zh/13-operation/01-pkg-install.md similarity index 100% rename from docs-cn/13-operation/01-pkg-install.md rename to docs/zh/13-operation/01-pkg-install.md diff --git a/docs-cn/13-operation/02-planning.mdx b/docs/zh/13-operation/02-planning.mdx similarity index 100% rename from docs-cn/13-operation/02-planning.mdx rename to docs/zh/13-operation/02-planning.mdx diff --git a/docs-cn/13-operation/03-tolerance.md b/docs/zh/13-operation/03-tolerance.md similarity index 100% rename from docs-cn/13-operation/03-tolerance.md rename to docs/zh/13-operation/03-tolerance.md diff --git a/docs-cn/13-operation/06-admin.md b/docs/zh/13-operation/06-admin.md similarity index 100% rename from docs-cn/13-operation/06-admin.md rename to docs/zh/13-operation/06-admin.md diff --git a/docs-cn/13-operation/07-import.md b/docs/zh/13-operation/07-import.md similarity index 100% rename from docs-cn/13-operation/07-import.md rename to docs/zh/13-operation/07-import.md diff --git a/docs-cn/13-operation/08-export.md b/docs/zh/13-operation/08-export.md similarity index 100% rename from docs-cn/13-operation/08-export.md rename to docs/zh/13-operation/08-export.md diff --git a/docs-cn/13-operation/09-status.md b/docs/zh/13-operation/09-status.md similarity index 100% rename from docs-cn/13-operation/09-status.md rename to docs/zh/13-operation/09-status.md diff --git a/docs-cn/13-operation/10-monitor.md b/docs/zh/13-operation/10-monitor.md similarity index 100% rename from docs-cn/13-operation/10-monitor.md rename to docs/zh/13-operation/10-monitor.md diff --git a/docs-cn/13-operation/11-optimize.md b/docs/zh/13-operation/11-optimize.md similarity index 100% rename from docs-cn/13-operation/11-optimize.md rename to docs/zh/13-operation/11-optimize.md diff --git a/docs-cn/13-operation/17-diagnose.md b/docs/zh/13-operation/17-diagnose.md similarity index 100% rename from docs-cn/13-operation/17-diagnose.md rename to docs/zh/13-operation/17-diagnose.md diff --git a/docs-cn/13-operation/_category_.yml b/docs/zh/13-operation/_category_.yml similarity index 100% rename from docs-cn/13-operation/_category_.yml rename to docs/zh/13-operation/_category_.yml diff --git a/docs-cn/13-operation/index.md b/docs/zh/13-operation/index.md similarity index 100% rename from docs-cn/13-operation/index.md rename to docs/zh/13-operation/index.md diff --git a/docs-cn/14-reference/02-rest-api/02-rest-api.mdx b/docs/zh/14-reference/02-rest-api/02-rest-api.mdx similarity index 100% rename from docs-cn/14-reference/02-rest-api/02-rest-api.mdx rename to docs/zh/14-reference/02-rest-api/02-rest-api.mdx diff --git a/docs-en/14-reference/02-rest-api/_category_.yml b/docs/zh/14-reference/02-rest-api/_category_.yml similarity index 100% rename from docs-en/14-reference/02-rest-api/_category_.yml rename to docs/zh/14-reference/02-rest-api/_category_.yml diff --git a/docs-cn/14-reference/03-connector/03-connector.mdx b/docs/zh/14-reference/03-connector/03-connector.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/03-connector.mdx rename to docs/zh/14-reference/03-connector/03-connector.mdx diff --git a/docs-cn/14-reference/03-connector/_category_.yml b/docs/zh/14-reference/03-connector/_category_.yml similarity index 100% rename from docs-cn/14-reference/03-connector/_category_.yml rename to docs/zh/14-reference/03-connector/_category_.yml diff --git a/docs-cn/14-reference/03-connector/_linux_install.mdx b/docs/zh/14-reference/03-connector/_linux_install.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/_linux_install.mdx rename to docs/zh/14-reference/03-connector/_linux_install.mdx diff --git a/docs-cn/14-reference/03-connector/_preparition.mdx b/docs/zh/14-reference/03-connector/_preparition.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/_preparition.mdx rename to docs/zh/14-reference/03-connector/_preparition.mdx diff --git a/docs-cn/14-reference/03-connector/_verify_linux.mdx b/docs/zh/14-reference/03-connector/_verify_linux.mdx similarity index 98% rename from docs-cn/14-reference/03-connector/_verify_linux.mdx rename to docs/zh/14-reference/03-connector/_verify_linux.mdx index af543108f8..fcb8aae6ae 100644 --- a/docs-cn/14-reference/03-connector/_verify_linux.mdx +++ b/docs/zh/14-reference/03-connector/_verify_linux.mdx @@ -1,14 +1,14 @@ -在 Linux shell 下直接执行 `taos` 连接到 TDengine 服务,进入到 TDengine CLI 界面,示例如下: - -```text -$ taos -Welcome to the TDengine shell from Linux, Client Version:2.0.5.0 -Copyright (c) 2017 by TAOS Data, Inc. All rights reserved. -taos> show databases; -name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB)| blocks | minrows | maxrows | wallevel | fsync | comp | precision | status | -========================================================================================================================================================================================================================= -test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16| 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready | -log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1| 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready | -Query OK, 2 row(s) in set (0.001198s) -taos> -``` +在 Linux shell 下直接执行 `taos` 连接到 TDengine 服务,进入到 TDengine CLI 界面,示例如下: + +```text +$ taos +Welcome to the TDengine shell from Linux, Client Version:2.0.5.0 +Copyright (c) 2017 by TAOS Data, Inc. All rights reserved. +taos> show databases; +name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB)| blocks | minrows | maxrows | wallevel | fsync | comp | precision | status | +========================================================================================================================================================================================================================= +test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16| 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready | +log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1| 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready | +Query OK, 2 row(s) in set (0.001198s) +taos> +``` diff --git a/docs-cn/14-reference/03-connector/_verify_windows.mdx b/docs/zh/14-reference/03-connector/_verify_windows.mdx similarity index 98% rename from docs-cn/14-reference/03-connector/_verify_windows.mdx rename to docs/zh/14-reference/03-connector/_verify_windows.mdx index 19ac71ec31..87c9fbd024 100644 --- a/docs-cn/14-reference/03-connector/_verify_windows.mdx +++ b/docs/zh/14-reference/03-connector/_verify_windows.mdx @@ -1,14 +1,14 @@ -在 cmd 下进入到 C:\TDengine 目录下直接执行 `taos.exe`,连接到 TDengine 服务,进入到 TDengine CLI 界面,示例如下: - -```text - C:\TDengine>taos - Welcome to the TDengine shell from Linux, Client Version:2.0.5.0 - Copyright (c) 2017 by TAOS Data, Inc. All rights reserved. - taos> show databases; - name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | precision | status | - =================================================================================================================================================================================================================================================================== - test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16 | 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready | - log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready | - Query OK, 2 row(s) in set (0.045000s) - taos> -``` +在 cmd 下进入到 C:\TDengine 目录下直接执行 `taos.exe`,连接到 TDengine 服务,进入到 TDengine CLI 界面,示例如下: + +```text + C:\TDengine>taos + Welcome to the TDengine shell from Linux, Client Version:2.0.5.0 + Copyright (c) 2017 by TAOS Data, Inc. All rights reserved. + taos> show databases; + name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | precision | status | + =================================================================================================================================================================================================================================================================== + test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16 | 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready | + log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready | + Query OK, 2 row(s) in set (0.045000s) + taos> +``` diff --git a/docs-cn/14-reference/03-connector/_windows_install.mdx b/docs/zh/14-reference/03-connector/_windows_install.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/_windows_install.mdx rename to docs/zh/14-reference/03-connector/_windows_install.mdx diff --git a/docs-en/14-reference/03-connector/connector.webp b/docs/zh/14-reference/03-connector/connector.webp similarity index 100% rename from docs-en/14-reference/03-connector/connector.webp rename to docs/zh/14-reference/03-connector/connector.webp diff --git a/docs-cn/14-reference/03-connector/cpp.mdx b/docs/zh/14-reference/03-connector/cpp.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/cpp.mdx rename to docs/zh/14-reference/03-connector/cpp.mdx diff --git a/docs-cn/14-reference/03-connector/csharp.mdx b/docs/zh/14-reference/03-connector/csharp.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/csharp.mdx rename to docs/zh/14-reference/03-connector/csharp.mdx diff --git a/docs-cn/14-reference/03-connector/go.mdx b/docs/zh/14-reference/03-connector/go.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/go.mdx rename to docs/zh/14-reference/03-connector/go.mdx diff --git a/docs-cn/14-reference/03-connector/java.mdx b/docs/zh/14-reference/03-connector/java.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/java.mdx rename to docs/zh/14-reference/03-connector/java.mdx diff --git a/docs-cn/14-reference/03-connector/node.mdx b/docs/zh/14-reference/03-connector/node.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/node.mdx rename to docs/zh/14-reference/03-connector/node.mdx diff --git a/docs-cn/14-reference/03-connector/php.mdx b/docs/zh/14-reference/03-connector/php.mdx similarity index 95% rename from docs-cn/14-reference/03-connector/php.mdx rename to docs/zh/14-reference/03-connector/php.mdx index f150aed4c8..2b7ff2a6fe 100644 --- a/docs-cn/14-reference/03-connector/php.mdx +++ b/docs/zh/14-reference/03-connector/php.mdx @@ -91,7 +91,7 @@ phpize && ./configure --enable-swoole && make -j && make install 建立连接 ```c -{{#include docs-examples/php/connect.php}} +{{#include docs/examples/php/connect.php}} ``` @@ -102,7 +102,7 @@ phpize && ./configure --enable-swoole && make -j && make install 插入数据 ```c -{{#include docs-examples/php/insert.php}} +{{#include docs/examples/php/insert.php}} ``` @@ -113,7 +113,7 @@ phpize && ./configure --enable-swoole && make -j && make install 同步查询 ```c -{{#include docs-examples/php/query.php}} +{{#include docs/examples/php/query.php}} ``` @@ -124,7 +124,7 @@ phpize && ./configure --enable-swoole && make -j && make install 参数绑定 ```c -{{#include docs-examples/php/insert_stmt.php}} +{{#include docs/examples/php/insert_stmt.php}} ``` diff --git a/docs-cn/14-reference/03-connector/python.mdx b/docs/zh/14-reference/03-connector/python.mdx similarity index 95% rename from docs-cn/14-reference/03-connector/python.mdx rename to docs/zh/14-reference/03-connector/python.mdx index 828e0a4abb..a77dc71db7 100644 --- a/docs-cn/14-reference/03-connector/python.mdx +++ b/docs/zh/14-reference/03-connector/python.mdx @@ -169,7 +169,7 @@ curl -u root:taosdata http://:/rest/sql -d "select server_version()" ```python -{{#include docs-examples/python/connect_native_reference.py}} +{{#include docs/examples/python/connect_native_reference.py}} ``` `connect` 函数的所有参数都是可选的关键字参数。下面是连接参数的具体说明: @@ -194,7 +194,7 @@ curl -u root:taosdata http://:/rest/sql -d "select server_version()" ```python -{{#include docs-examples/python/connect_rest_examples.py:connect}} +{{#include docs/examples/python/connect_rest_examples.py:connect}} ``` `connect()` 函数的所有参数都是可选的关键字参数。下面是连接参数的具体说明: @@ -219,11 +219,11 @@ curl -u root:taosdata http://:/rest/sql -d "select server_version()" `TaosConnection` 类既包含对 PEP249 Connection 接口的实现(如:`cursor`方法和 `close` 方法),也包含很多扩展功能(如: `execute`、 `query`、`schemaless_insert` 和 `subscribe` 方法。 ```python title="execute 方法" -{{#include docs-examples/python/connection_usage_native_reference.py:insert}} +{{#include docs/examples/python/connection_usage_native_reference.py:insert}} ``` ```python title="query 方法" -{{#include docs-examples/python/connection_usage_native_reference.py:query}} +{{#include docs/examples/python/connection_usage_native_reference.py:query}} ``` :::tip @@ -235,14 +235,14 @@ curl -u root:taosdata http://:/rest/sql -d "select server_version()" 上面 `TaosConnection` 类的使用示例中,我们已经展示了两种获取查询结果的方法: `fetch_all()` 和 `fetch_all_into_dict()`。除此之外 `TaosResult` 还提供了按行迭代(`rows_iter`)或按数据块迭代(`blocks_iter`)结果集的方法。在查询数据量较大的场景,使用这两个方法会更高效。 ```python title="blocks_iter 方法" -{{#include docs-examples/python/result_set_examples.py}} +{{#include docs/examples/python/result_set_examples.py}} ``` ##### TaosCursor 类的使用 `TaosConnection` 类和 `TaosResult` 类已经实现了原生接口的所有功能。如果你对 PEP249 规范中的接口比较熟悉也可以使用 `TaosCursor` 类提供的方法。 ```python title="TaosCursor 的使用" -{{#include docs-examples/python/cursor_usage_native_reference.py}} +{{#include docs/examples/python/cursor_usage_native_reference.py}} ``` :::note @@ -258,7 +258,7 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线 `TaosRestCursor` 类是对 PEP249 Cursor 接口的实现。 ```python title="TaosRestCursor 的使用" -{{#include docs-examples/python/connect_rest_examples.py:basic}} +{{#include docs/examples/python/connect_rest_examples.py:basic}} ``` - `cursor.execute` : 用来执行任意 SQL 语句。 - `cursor.rowcount`: 对于写入操作返回写入成功记录数。对于查询操作,返回结果集行数。 @@ -269,7 +269,7 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线 `RestClient` 类是对于 [REST API](/reference/rest-api) 的直接封装。它只包含一个 `sql()` 方法用于执行任意 SQL 语句, 并返回执行结果。 ```python title="RestClient 的使用" -{{#include docs-examples/python/rest_client_example.py}} +{{#include docs/examples/python/rest_client_example.py}} ``` 对于 `sql()` 方法更详细的介绍, 请参考 [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html)。 @@ -285,14 +285,14 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线 ```python -{{#include docs-examples/python/conn_native_pandas.py}} +{{#include docs/examples/python/conn_native_pandas.py}} ``` ```python -{{#include docs-examples/python/conn_rest_pandas.py}} +{{#include docs/examples/python/conn_rest_pandas.py}} ``` @@ -316,7 +316,7 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线 所有数据库操作如果出现异常,都会直接抛出来。由应用程序负责异常处理。比如: ```python -{{#include docs-examples/python/handle_exception.py}} +{{#include docs/examples/python/handle_exception.py}} ``` ### 关于纳秒 (nanosecond) diff --git a/docs-cn/14-reference/03-connector/rust.mdx b/docs/zh/14-reference/03-connector/rust.mdx similarity index 100% rename from docs-cn/14-reference/03-connector/rust.mdx rename to docs/zh/14-reference/03-connector/rust.mdx diff --git a/docs-cn/14-reference/03-connector/tdengine-jdbc-connector.webp b/docs/zh/14-reference/03-connector/tdengine-jdbc-connector.webp similarity index 100% rename from docs-cn/14-reference/03-connector/tdengine-jdbc-connector.webp rename to docs/zh/14-reference/03-connector/tdengine-jdbc-connector.webp diff --git a/docs-cn/14-reference/04-taosadapter.md b/docs/zh/14-reference/04-taosadapter.md similarity index 100% rename from docs-cn/14-reference/04-taosadapter.md rename to docs/zh/14-reference/04-taosadapter.md diff --git a/docs-cn/14-reference/05-taosbenchmark.md b/docs/zh/14-reference/05-taosbenchmark.md similarity index 100% rename from docs-cn/14-reference/05-taosbenchmark.md rename to docs/zh/14-reference/05-taosbenchmark.md diff --git a/docs-cn/14-reference/06-taosdump.md b/docs/zh/14-reference/06-taosdump.md similarity index 100% rename from docs-cn/14-reference/06-taosdump.md rename to docs/zh/14-reference/06-taosdump.md diff --git a/docs-en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json b/docs/zh/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json rename to docs/zh/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json diff --git a/docs-en/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json b/docs/zh/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json rename to docs/zh/14-reference/07-tdinsight/assets/15155-tdengine-alert-demo.json diff --git a/docs-en/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp b/docs/zh/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp rename to docs/zh/14-reference/07-tdinsight/assets/TDinsight-1-cluster-status.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp b/docs/zh/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp rename to docs/zh/14-reference/07-tdinsight/assets/TDinsight-2-dnodes.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp b/docs/zh/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp rename to docs/zh/14-reference/07-tdinsight/assets/TDinsight-3-mnodes.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp b/docs/zh/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp rename to docs/zh/14-reference/07-tdinsight/assets/TDinsight-4-requests.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/TDinsight-5-database.webp b/docs/zh/14-reference/07-tdinsight/assets/TDinsight-5-database.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/TDinsight-5-database.webp rename to docs/zh/14-reference/07-tdinsight/assets/TDinsight-5-database.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp b/docs/zh/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp rename to docs/zh/14-reference/07-tdinsight/assets/TDinsight-6-dnode-usage.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp b/docs/zh/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp rename to docs/zh/14-reference/07-tdinsight/assets/TDinsight-7-login-history.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp b/docs/zh/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp rename to docs/zh/14-reference/07-tdinsight/assets/TDinsight-8-taosadapter.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/TDinsight-full.webp b/docs/zh/14-reference/07-tdinsight/assets/TDinsight-full.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/TDinsight-full.webp rename to docs/zh/14-reference/07-tdinsight/assets/TDinsight-full.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/alert-manager-status.webp b/docs/zh/14-reference/07-tdinsight/assets/alert-manager-status.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/alert-manager-status.webp rename to docs/zh/14-reference/07-tdinsight/assets/alert-manager-status.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/alert-notification-channel.webp b/docs/zh/14-reference/07-tdinsight/assets/alert-notification-channel.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/alert-notification-channel.webp rename to docs/zh/14-reference/07-tdinsight/assets/alert-notification-channel.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/alert-query-demo.webp b/docs/zh/14-reference/07-tdinsight/assets/alert-query-demo.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/alert-query-demo.webp rename to docs/zh/14-reference/07-tdinsight/assets/alert-query-demo.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp b/docs/zh/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp rename to docs/zh/14-reference/07-tdinsight/assets/alert-rule-condition-notifications.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/alert-rule-test.webp b/docs/zh/14-reference/07-tdinsight/assets/alert-rule-test.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/alert-rule-test.webp rename to docs/zh/14-reference/07-tdinsight/assets/alert-rule-test.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp b/docs/zh/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp rename to docs/zh/14-reference/07-tdinsight/assets/howto-add-datasource-button.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp b/docs/zh/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp rename to docs/zh/14-reference/07-tdinsight/assets/howto-add-datasource-tdengine.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp b/docs/zh/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp rename to docs/zh/14-reference/07-tdinsight/assets/howto-add-datasource-test.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/howto-add-datasource.webp b/docs/zh/14-reference/07-tdinsight/assets/howto-add-datasource.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/howto-add-datasource.webp rename to docs/zh/14-reference/07-tdinsight/assets/howto-add-datasource.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/howto-dashboard-display.webp b/docs/zh/14-reference/07-tdinsight/assets/howto-dashboard-display.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/howto-dashboard-display.webp rename to docs/zh/14-reference/07-tdinsight/assets/howto-dashboard-display.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp b/docs/zh/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp rename to docs/zh/14-reference/07-tdinsight/assets/howto-dashboard-import-options.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/howto-import-dashboard.webp b/docs/zh/14-reference/07-tdinsight/assets/howto-import-dashboard.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/howto-import-dashboard.webp rename to docs/zh/14-reference/07-tdinsight/assets/howto-import-dashboard.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/import-dashboard-15167.webp b/docs/zh/14-reference/07-tdinsight/assets/import-dashboard-15167.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/import-dashboard-15167.webp rename to docs/zh/14-reference/07-tdinsight/assets/import-dashboard-15167.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp b/docs/zh/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp rename to docs/zh/14-reference/07-tdinsight/assets/import-dashboard-for-tdengine.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp b/docs/zh/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp rename to docs/zh/14-reference/07-tdinsight/assets/import-via-grafana-dot-com.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/import_dashboard.webp b/docs/zh/14-reference/07-tdinsight/assets/import_dashboard.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/import_dashboard.webp rename to docs/zh/14-reference/07-tdinsight/assets/import_dashboard.webp diff --git a/docs-en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json b/docs/zh/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json rename to docs/zh/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json diff --git a/docs-en/14-reference/07-tdinsight/assets/tdengine-grafana.json b/docs/zh/14-reference/07-tdinsight/assets/tdengine-grafana.json similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/tdengine-grafana.json rename to docs/zh/14-reference/07-tdinsight/assets/tdengine-grafana.json diff --git a/docs-en/14-reference/07-tdinsight/assets/tdengine_dashboard.webp b/docs/zh/14-reference/07-tdinsight/assets/tdengine_dashboard.webp similarity index 100% rename from docs-en/14-reference/07-tdinsight/assets/tdengine_dashboard.webp rename to docs/zh/14-reference/07-tdinsight/assets/tdengine_dashboard.webp diff --git a/docs-cn/14-reference/07-tdinsight/index.md b/docs/zh/14-reference/07-tdinsight/index.md similarity index 100% rename from docs-cn/14-reference/07-tdinsight/index.md rename to docs/zh/14-reference/07-tdinsight/index.md diff --git a/docs-cn/14-reference/08-taos-shell.md b/docs/zh/14-reference/08-taos-shell.md similarity index 100% rename from docs-cn/14-reference/08-taos-shell.md rename to docs/zh/14-reference/08-taos-shell.md diff --git a/docs-cn/14-reference/09-support-platform/_category_.yml b/docs/zh/14-reference/09-support-platform/_category_.yml similarity index 100% rename from docs-cn/14-reference/09-support-platform/_category_.yml rename to docs/zh/14-reference/09-support-platform/_category_.yml diff --git a/docs-cn/14-reference/09-support-platform/index.md b/docs/zh/14-reference/09-support-platform/index.md similarity index 100% rename from docs-cn/14-reference/09-support-platform/index.md rename to docs/zh/14-reference/09-support-platform/index.md diff --git a/docs-cn/14-reference/11-docker/_category_.yml b/docs/zh/14-reference/11-docker/_category_.yml similarity index 100% rename from docs-cn/14-reference/11-docker/_category_.yml rename to docs/zh/14-reference/11-docker/_category_.yml diff --git a/docs-cn/14-reference/11-docker/index.md b/docs/zh/14-reference/11-docker/index.md similarity index 100% rename from docs-cn/14-reference/11-docker/index.md rename to docs/zh/14-reference/11-docker/index.md diff --git a/docs-cn/14-reference/12-config/_category_.yml b/docs/zh/14-reference/12-config/_category_.yml similarity index 100% rename from docs-cn/14-reference/12-config/_category_.yml rename to docs/zh/14-reference/12-config/_category_.yml diff --git a/docs-cn/14-reference/12-config/index.md b/docs/zh/14-reference/12-config/index.md similarity index 100% rename from docs-cn/14-reference/12-config/index.md rename to docs/zh/14-reference/12-config/index.md diff --git a/docs-cn/14-reference/12-directory.md b/docs/zh/14-reference/12-directory.md similarity index 100% rename from docs-cn/14-reference/12-directory.md rename to docs/zh/14-reference/12-directory.md diff --git a/docs-cn/14-reference/13-schemaless/13-schemaless.md b/docs/zh/14-reference/13-schemaless/13-schemaless.md similarity index 100% rename from docs-cn/14-reference/13-schemaless/13-schemaless.md rename to docs/zh/14-reference/13-schemaless/13-schemaless.md diff --git a/docs-cn/14-reference/13-schemaless/_category_.yml b/docs/zh/14-reference/13-schemaless/_category_.yml similarity index 100% rename from docs-cn/14-reference/13-schemaless/_category_.yml rename to docs/zh/14-reference/13-schemaless/_category_.yml diff --git a/docs-cn/14-reference/_category_.yml b/docs/zh/14-reference/_category_.yml similarity index 100% rename from docs-cn/14-reference/_category_.yml rename to docs/zh/14-reference/_category_.yml diff --git a/docs-cn/14-reference/_collectd.mdx b/docs/zh/14-reference/_collectd.mdx similarity index 100% rename from docs-cn/14-reference/_collectd.mdx rename to docs/zh/14-reference/_collectd.mdx diff --git a/docs-cn/14-reference/_icinga2.mdx b/docs/zh/14-reference/_icinga2.mdx similarity index 100% rename from docs-cn/14-reference/_icinga2.mdx rename to docs/zh/14-reference/_icinga2.mdx diff --git a/docs-cn/14-reference/_prometheus.mdx b/docs/zh/14-reference/_prometheus.mdx similarity index 100% rename from docs-cn/14-reference/_prometheus.mdx rename to docs/zh/14-reference/_prometheus.mdx diff --git a/docs-cn/14-reference/_statsd.mdx b/docs/zh/14-reference/_statsd.mdx similarity index 100% rename from docs-cn/14-reference/_statsd.mdx rename to docs/zh/14-reference/_statsd.mdx diff --git a/docs-cn/14-reference/_tcollector.mdx b/docs/zh/14-reference/_tcollector.mdx similarity index 100% rename from docs-cn/14-reference/_tcollector.mdx rename to docs/zh/14-reference/_tcollector.mdx diff --git a/docs-cn/14-reference/_telegraf.mdx b/docs/zh/14-reference/_telegraf.mdx similarity index 100% rename from docs-cn/14-reference/_telegraf.mdx rename to docs/zh/14-reference/_telegraf.mdx diff --git a/docs-cn/14-reference/index.md b/docs/zh/14-reference/index.md similarity index 100% rename from docs-cn/14-reference/index.md rename to docs/zh/14-reference/index.md diff --git a/docs-en/14-reference/taosAdapter-architecture.webp b/docs/zh/14-reference/taosAdapter-architecture.webp similarity index 100% rename from docs-en/14-reference/taosAdapter-architecture.webp rename to docs/zh/14-reference/taosAdapter-architecture.webp diff --git a/docs-cn/20-third-party/01-grafana.mdx b/docs/zh/20-third-party/01-grafana.mdx similarity index 100% rename from docs-cn/20-third-party/01-grafana.mdx rename to docs/zh/20-third-party/01-grafana.mdx diff --git a/docs-cn/20-third-party/02-prometheus.md b/docs/zh/20-third-party/02-prometheus.md similarity index 100% rename from docs-cn/20-third-party/02-prometheus.md rename to docs/zh/20-third-party/02-prometheus.md diff --git a/docs-cn/20-third-party/03-telegraf.md b/docs/zh/20-third-party/03-telegraf.md similarity index 100% rename from docs-cn/20-third-party/03-telegraf.md rename to docs/zh/20-third-party/03-telegraf.md diff --git a/docs-cn/20-third-party/05-collectd.md b/docs/zh/20-third-party/05-collectd.md similarity index 100% rename from docs-cn/20-third-party/05-collectd.md rename to docs/zh/20-third-party/05-collectd.md diff --git a/docs-cn/20-third-party/06-statsd.md b/docs/zh/20-third-party/06-statsd.md similarity index 100% rename from docs-cn/20-third-party/06-statsd.md rename to docs/zh/20-third-party/06-statsd.md diff --git a/docs-cn/20-third-party/07-icinga2.md b/docs/zh/20-third-party/07-icinga2.md similarity index 100% rename from docs-cn/20-third-party/07-icinga2.md rename to docs/zh/20-third-party/07-icinga2.md diff --git a/docs-cn/20-third-party/08-tcollector.md b/docs/zh/20-third-party/08-tcollector.md similarity index 100% rename from docs-cn/20-third-party/08-tcollector.md rename to docs/zh/20-third-party/08-tcollector.md diff --git a/docs-cn/20-third-party/09-emq-broker.md b/docs/zh/20-third-party/09-emq-broker.md similarity index 99% rename from docs-cn/20-third-party/09-emq-broker.md rename to docs/zh/20-third-party/09-emq-broker.md index 2125545f39..84b1027f6b 100644 --- a/docs-cn/20-third-party/09-emq-broker.md +++ b/docs/zh/20-third-party/09-emq-broker.md @@ -116,7 +116,7 @@ INSERT INTO test.sensor_data VALUES( ## 编写模拟测试程序 ```javascript -{{#include docs-examples/other/mock.js}} +{{#include docs/examples/other/mock.js}} ``` 注意:代码中 CLIENT_NUM 在开始测试中可以先设置一个较小的值,避免硬件性能不能完全处理较大并发客户端数量。 diff --git a/docs-cn/20-third-party/10-hive-mq-broker.md b/docs/zh/20-third-party/10-hive-mq-broker.md similarity index 100% rename from docs-cn/20-third-party/10-hive-mq-broker.md rename to docs/zh/20-third-party/10-hive-mq-broker.md diff --git a/docs-cn/20-third-party/11-kafka.md b/docs/zh/20-third-party/11-kafka.md similarity index 100% rename from docs-cn/20-third-party/11-kafka.md rename to docs/zh/20-third-party/11-kafka.md diff --git a/docs-cn/20-third-party/_category_.yml b/docs/zh/20-third-party/_category_.yml similarity index 100% rename from docs-cn/20-third-party/_category_.yml rename to docs/zh/20-third-party/_category_.yml diff --git a/docs-cn/20-third-party/_deploytaosadapter.mdx b/docs/zh/20-third-party/_deploytaosadapter.mdx similarity index 100% rename from docs-cn/20-third-party/_deploytaosadapter.mdx rename to docs/zh/20-third-party/_deploytaosadapter.mdx diff --git a/docs-en/20-third-party/grafana/add_datasource1.webp b/docs/zh/20-third-party/add_datasource1.webp similarity index 100% rename from docs-en/20-third-party/grafana/add_datasource1.webp rename to docs/zh/20-third-party/add_datasource1.webp diff --git a/docs-en/20-third-party/grafana/add_datasource2.webp b/docs/zh/20-third-party/add_datasource2.webp similarity index 100% rename from docs-en/20-third-party/grafana/add_datasource2.webp rename to docs/zh/20-third-party/add_datasource2.webp diff --git a/docs-en/20-third-party/grafana/add_datasource3.webp b/docs/zh/20-third-party/add_datasource3.webp similarity index 100% rename from docs-en/20-third-party/grafana/add_datasource3.webp rename to docs/zh/20-third-party/add_datasource3.webp diff --git a/docs-en/20-third-party/grafana/add_datasource4.webp b/docs/zh/20-third-party/add_datasource4.webp similarity index 100% rename from docs-en/20-third-party/grafana/add_datasource4.webp rename to docs/zh/20-third-party/add_datasource4.webp diff --git a/docs-en/20-third-party/grafana/create_dashboard1.webp b/docs/zh/20-third-party/create_dashboard1.webp similarity index 100% rename from docs-en/20-third-party/grafana/create_dashboard1.webp rename to docs/zh/20-third-party/create_dashboard1.webp diff --git a/docs-en/20-third-party/grafana/create_dashboard2.webp b/docs/zh/20-third-party/create_dashboard2.webp similarity index 100% rename from docs-en/20-third-party/grafana/create_dashboard2.webp rename to docs/zh/20-third-party/create_dashboard2.webp diff --git a/docs-cn/20-third-party/dashboard-15146.webp b/docs/zh/20-third-party/dashboard-15146.webp similarity index 100% rename from docs-cn/20-third-party/dashboard-15146.webp rename to docs/zh/20-third-party/dashboard-15146.webp diff --git a/docs-en/20-third-party/emqx/add-action-handler.webp b/docs/zh/20-third-party/emqx/add-action-handler.webp similarity index 100% rename from docs-en/20-third-party/emqx/add-action-handler.webp rename to docs/zh/20-third-party/emqx/add-action-handler.webp diff --git a/docs-en/20-third-party/emqx/check-result-in-taos.webp b/docs/zh/20-third-party/emqx/check-result-in-taos.webp similarity index 100% rename from docs-en/20-third-party/emqx/check-result-in-taos.webp rename to docs/zh/20-third-party/emqx/check-result-in-taos.webp diff --git a/docs-en/20-third-party/emqx/check-rule-matched.webp b/docs/zh/20-third-party/emqx/check-rule-matched.webp similarity index 100% rename from docs-en/20-third-party/emqx/check-rule-matched.webp rename to docs/zh/20-third-party/emqx/check-rule-matched.webp diff --git a/docs-en/20-third-party/emqx/client-num.webp b/docs/zh/20-third-party/emqx/client-num.webp similarity index 100% rename from docs-en/20-third-party/emqx/client-num.webp rename to docs/zh/20-third-party/emqx/client-num.webp diff --git a/docs-en/20-third-party/emqx/create-resource.webp b/docs/zh/20-third-party/emqx/create-resource.webp similarity index 100% rename from docs-en/20-third-party/emqx/create-resource.webp rename to docs/zh/20-third-party/emqx/create-resource.webp diff --git a/docs-en/20-third-party/emqx/create-rule.webp b/docs/zh/20-third-party/emqx/create-rule.webp similarity index 100% rename from docs-en/20-third-party/emqx/create-rule.webp rename to docs/zh/20-third-party/emqx/create-rule.webp diff --git a/docs-en/20-third-party/emqx/edit-action.webp b/docs/zh/20-third-party/emqx/edit-action.webp similarity index 100% rename from docs-en/20-third-party/emqx/edit-action.webp rename to docs/zh/20-third-party/emqx/edit-action.webp diff --git a/docs-en/20-third-party/emqx/edit-resource.webp b/docs/zh/20-third-party/emqx/edit-resource.webp similarity index 100% rename from docs-en/20-third-party/emqx/edit-resource.webp rename to docs/zh/20-third-party/emqx/edit-resource.webp diff --git a/docs-en/20-third-party/emqx/login-dashboard.webp b/docs/zh/20-third-party/emqx/login-dashboard.webp similarity index 100% rename from docs-en/20-third-party/emqx/login-dashboard.webp rename to docs/zh/20-third-party/emqx/login-dashboard.webp diff --git a/docs-en/20-third-party/emqx/rule-engine.webp b/docs/zh/20-third-party/emqx/rule-engine.webp similarity index 100% rename from docs-en/20-third-party/emqx/rule-engine.webp rename to docs/zh/20-third-party/emqx/rule-engine.webp diff --git a/docs-en/20-third-party/emqx/rule-header-key-value.webp b/docs/zh/20-third-party/emqx/rule-header-key-value.webp similarity index 100% rename from docs-en/20-third-party/emqx/rule-header-key-value.webp rename to docs/zh/20-third-party/emqx/rule-header-key-value.webp diff --git a/docs-en/20-third-party/emqx/run-mock.webp b/docs/zh/20-third-party/emqx/run-mock.webp similarity index 100% rename from docs-en/20-third-party/emqx/run-mock.webp rename to docs/zh/20-third-party/emqx/run-mock.webp diff --git a/docs-cn/20-third-party/import_dashboard1.webp b/docs/zh/20-third-party/import_dashboard1.webp similarity index 100% rename from docs-cn/20-third-party/import_dashboard1.webp rename to docs/zh/20-third-party/import_dashboard1.webp diff --git a/docs-cn/20-third-party/import_dashboard2.webp b/docs/zh/20-third-party/import_dashboard2.webp similarity index 100% rename from docs-cn/20-third-party/import_dashboard2.webp rename to docs/zh/20-third-party/import_dashboard2.webp diff --git a/docs-cn/20-third-party/index.md b/docs/zh/20-third-party/index.md similarity index 100% rename from docs-cn/20-third-party/index.md rename to docs/zh/20-third-party/index.md diff --git a/docs-en/20-third-party/kafka/Kafka_Connect.webp b/docs/zh/20-third-party/kafka/Kafka_Connect.webp similarity index 100% rename from docs-en/20-third-party/kafka/Kafka_Connect.webp rename to docs/zh/20-third-party/kafka/Kafka_Connect.webp diff --git a/docs-en/20-third-party/kafka/confluentPlatform.webp b/docs/zh/20-third-party/kafka/confluentPlatform.webp similarity index 100% rename from docs-en/20-third-party/kafka/confluentPlatform.webp rename to docs/zh/20-third-party/kafka/confluentPlatform.webp diff --git a/docs-en/20-third-party/kafka/streaming-integration-with-kafka-connect.webp b/docs/zh/20-third-party/kafka/streaming-integration-with-kafka-connect.webp similarity index 100% rename from docs-en/20-third-party/kafka/streaming-integration-with-kafka-connect.webp rename to docs/zh/20-third-party/kafka/streaming-integration-with-kafka-connect.webp diff --git a/docs-cn/21-tdinternal/01-arch.md b/docs/zh/21-tdinternal/01-arch.md similarity index 100% rename from docs-cn/21-tdinternal/01-arch.md rename to docs/zh/21-tdinternal/01-arch.md diff --git a/docs-cn/21-tdinternal/02-replica.md b/docs/zh/21-tdinternal/02-replica.md similarity index 100% rename from docs-cn/21-tdinternal/02-replica.md rename to docs/zh/21-tdinternal/02-replica.md diff --git a/docs-cn/21-tdinternal/03-taosd.md b/docs/zh/21-tdinternal/03-taosd.md similarity index 100% rename from docs-cn/21-tdinternal/03-taosd.md rename to docs/zh/21-tdinternal/03-taosd.md diff --git a/docs-cn/21-tdinternal/12-tsz-compress.md b/docs/zh/21-tdinternal/12-tsz-compress.md similarity index 100% rename from docs-cn/21-tdinternal/12-tsz-compress.md rename to docs/zh/21-tdinternal/12-tsz-compress.md diff --git a/docs-cn/21-tdinternal/30-iot-big-data.md b/docs/zh/21-tdinternal/30-iot-big-data.md similarity index 100% rename from docs-cn/21-tdinternal/30-iot-big-data.md rename to docs/zh/21-tdinternal/30-iot-big-data.md diff --git a/docs-cn/21-tdinternal/_category_.yml b/docs/zh/21-tdinternal/_category_.yml similarity index 100% rename from docs-cn/21-tdinternal/_category_.yml rename to docs/zh/21-tdinternal/_category_.yml diff --git a/docs-en/21-tdinternal/dnode.webp b/docs/zh/21-tdinternal/dnode.webp similarity index 100% rename from docs-en/21-tdinternal/dnode.webp rename to docs/zh/21-tdinternal/dnode.webp diff --git a/docs-cn/21-tdinternal/index.md b/docs/zh/21-tdinternal/index.md similarity index 100% rename from docs-cn/21-tdinternal/index.md rename to docs/zh/21-tdinternal/index.md diff --git a/docs-en/21-tdinternal/message.webp b/docs/zh/21-tdinternal/message.webp similarity index 100% rename from docs-en/21-tdinternal/message.webp rename to docs/zh/21-tdinternal/message.webp diff --git a/docs-en/21-tdinternal/modules.webp b/docs/zh/21-tdinternal/modules.webp similarity index 100% rename from docs-en/21-tdinternal/modules.webp rename to docs/zh/21-tdinternal/modules.webp diff --git a/docs-en/21-tdinternal/multi_tables.webp b/docs/zh/21-tdinternal/multi_tables.webp similarity index 100% rename from docs-en/21-tdinternal/multi_tables.webp rename to docs/zh/21-tdinternal/multi_tables.webp diff --git a/docs-en/21-tdinternal/replica-forward.webp b/docs/zh/21-tdinternal/replica-forward.webp similarity index 100% rename from docs-en/21-tdinternal/replica-forward.webp rename to docs/zh/21-tdinternal/replica-forward.webp diff --git a/docs-en/21-tdinternal/replica-master.webp b/docs/zh/21-tdinternal/replica-master.webp similarity index 100% rename from docs-en/21-tdinternal/replica-master.webp rename to docs/zh/21-tdinternal/replica-master.webp diff --git a/docs-en/21-tdinternal/replica-restore.webp b/docs/zh/21-tdinternal/replica-restore.webp similarity index 100% rename from docs-en/21-tdinternal/replica-restore.webp rename to docs/zh/21-tdinternal/replica-restore.webp diff --git a/docs-en/21-tdinternal/structure.webp b/docs/zh/21-tdinternal/structure.webp similarity index 100% rename from docs-en/21-tdinternal/structure.webp rename to docs/zh/21-tdinternal/structure.webp diff --git a/docs-en/21-tdinternal/vnode.webp b/docs/zh/21-tdinternal/vnode.webp similarity index 100% rename from docs-en/21-tdinternal/vnode.webp rename to docs/zh/21-tdinternal/vnode.webp diff --git a/docs-en/21-tdinternal/write_master.webp b/docs/zh/21-tdinternal/write_master.webp similarity index 100% rename from docs-en/21-tdinternal/write_master.webp rename to docs/zh/21-tdinternal/write_master.webp diff --git a/docs-en/21-tdinternal/write_slave.webp b/docs/zh/21-tdinternal/write_slave.webp similarity index 100% rename from docs-en/21-tdinternal/write_slave.webp rename to docs/zh/21-tdinternal/write_slave.webp diff --git a/docs-cn/25-application/01-telegraf.md b/docs/zh/25-application/01-telegraf.md similarity index 100% rename from docs-cn/25-application/01-telegraf.md rename to docs/zh/25-application/01-telegraf.md diff --git a/docs-cn/25-application/02-collectd.md b/docs/zh/25-application/02-collectd.md similarity index 100% rename from docs-cn/25-application/02-collectd.md rename to docs/zh/25-application/02-collectd.md diff --git a/docs-cn/25-application/03-immigrate.md b/docs/zh/25-application/03-immigrate.md similarity index 100% rename from docs-cn/25-application/03-immigrate.md rename to docs/zh/25-application/03-immigrate.md diff --git a/docs-en/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp b/docs/zh/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp similarity index 100% rename from docs-en/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp rename to docs/zh/25-application/IT-DevOps-Solutions-Collectd-StatsD.webp diff --git a/docs-en/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp b/docs/zh/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp similarity index 100% rename from docs-en/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp rename to docs/zh/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.webp diff --git a/docs-en/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp b/docs/zh/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp similarity index 100% rename from docs-en/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp rename to docs/zh/25-application/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.webp diff --git a/docs-en/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp b/docs/zh/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp similarity index 100% rename from docs-en/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp rename to docs/zh/25-application/IT-DevOps-Solutions-Immigrate-TDengine-Arch.webp diff --git a/docs-en/25-application/IT-DevOps-Solutions-Telegraf.webp b/docs/zh/25-application/IT-DevOps-Solutions-Telegraf.webp similarity index 100% rename from docs-en/25-application/IT-DevOps-Solutions-Telegraf.webp rename to docs/zh/25-application/IT-DevOps-Solutions-Telegraf.webp diff --git a/docs-en/25-application/IT-DevOps-Solutions-collectd-dashboard.webp b/docs/zh/25-application/IT-DevOps-Solutions-collectd-dashboard.webp similarity index 100% rename from docs-en/25-application/IT-DevOps-Solutions-collectd-dashboard.webp rename to docs/zh/25-application/IT-DevOps-Solutions-collectd-dashboard.webp diff --git a/docs-en/25-application/IT-DevOps-Solutions-statsd-dashboard.webp b/docs/zh/25-application/IT-DevOps-Solutions-statsd-dashboard.webp similarity index 100% rename from docs-en/25-application/IT-DevOps-Solutions-statsd-dashboard.webp rename to docs/zh/25-application/IT-DevOps-Solutions-statsd-dashboard.webp diff --git a/docs-en/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp b/docs/zh/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp similarity index 100% rename from docs-en/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp rename to docs/zh/25-application/IT-DevOps-Solutions-telegraf-dashboard.webp diff --git a/docs-cn/25-application/_category_.yml b/docs/zh/25-application/_category_.yml similarity index 100% rename from docs-cn/25-application/_category_.yml rename to docs/zh/25-application/_category_.yml diff --git a/docs-cn/25-application/index.md b/docs/zh/25-application/index.md similarity index 100% rename from docs-cn/25-application/index.md rename to docs/zh/25-application/index.md diff --git a/docs-cn/27-train-faq/01-faq.md b/docs/zh/27-train-faq/01-faq.md similarity index 100% rename from docs-cn/27-train-faq/01-faq.md rename to docs/zh/27-train-faq/01-faq.md diff --git a/docs-cn/27-train-faq/02-video.mdx b/docs/zh/27-train-faq/02-video.mdx similarity index 100% rename from docs-cn/27-train-faq/02-video.mdx rename to docs/zh/27-train-faq/02-video.mdx diff --git a/docs-cn/27-train-faq/03-docker.md b/docs/zh/27-train-faq/03-docker.md similarity index 100% rename from docs-cn/27-train-faq/03-docker.md rename to docs/zh/27-train-faq/03-docker.md diff --git a/docs-cn/27-train-faq/_category_.yml b/docs/zh/27-train-faq/_category_.yml similarity index 100% rename from docs-cn/27-train-faq/_category_.yml rename to docs/zh/27-train-faq/_category_.yml diff --git a/docs-cn/27-train-faq/index.md b/docs/zh/27-train-faq/index.md similarity index 100% rename from docs-cn/27-train-faq/index.md rename to docs/zh/27-train-faq/index.md diff --git a/docs-en/30-release/01-2.6.md b/docs/zh/30-release/01-2.6.md similarity index 100% rename from docs-en/30-release/01-2.6.md rename to docs/zh/30-release/01-2.6.md diff --git a/docs-en/30-release/02-2.4.md b/docs/zh/30-release/02-2.4.md similarity index 100% rename from docs-en/30-release/02-2.4.md rename to docs/zh/30-release/02-2.4.md diff --git a/docs-cn/30-release/_category_.yml b/docs/zh/30-release/_category_.yml similarity index 100% rename from docs-cn/30-release/_category_.yml rename to docs/zh/30-release/_category_.yml diff --git a/docs-cn/30-release/index.md b/docs/zh/30-release/index.md similarity index 100% rename from docs-cn/30-release/index.md rename to docs/zh/30-release/index.md diff --git a/docs-en/02-intro/eco_system.webp b/docs/zh/eco_system.webp similarity index 100% rename from docs-en/02-intro/eco_system.webp rename to docs/zh/eco_system.webp diff --git a/tests/docs-examples-test/test_R.sh b/tests/docs-examples-test/test_R.sh index 8d2db4546f..80e5e81373 100755 --- a/tests/docs-examples-test/test_R.sh +++ b/tests/docs-examples-test/test_R.sh @@ -5,7 +5,7 @@ set -e pgrep taosd || taosd >> /dev/null 2>&1 & pgrep taosadapter || taosadapter >> /dev/null 2>&1 & -cd ../../docs-examples/R +cd ../../docs/examples/R jar_path=`find ../../../debug/build -name taos-jdbcdriver-*-dist.jar` echo jar_path=$jar_path diff --git a/tests/docs-examples-test/test_c.sh b/tests/docs-examples-test/test_c.sh index 2d47eff585..8d4c51e817 100755 --- a/tests/docs-examples-test/test_c.sh +++ b/tests/docs-examples-test/test_c.sh @@ -5,7 +5,7 @@ set -e taosd >> /dev/null 2>&1 & taosadapter >> /dev/null 2>&1 & -cd ../../docs-examples/c +cd ../../docs/examples/c # 1 gcc connect_example.c -o connect_example -ltaos diff --git a/tests/docs-examples-test/test_csharp.sh b/tests/docs-examples-test/test_csharp.sh index 64d28d945f..f26fa22d19 100755 --- a/tests/docs-examples-test/test_csharp.sh +++ b/tests/docs-examples-test/test_csharp.sh @@ -4,7 +4,7 @@ set -e pgrep taosd || taosd >> /dev/null 2>&1 & pgrep taosadapter || taosadapter >> /dev/null 2>&1 & -cd ../../docs-examples/csharp +cd ../../docs/examples/csharp dotnet run --project connect.csproj diff --git a/tests/docs-examples-test/test_go.sh b/tests/docs-examples-test/test_go.sh index d959d8c1ed..dc2332f237 100755 --- a/tests/docs-examples-test/test_go.sh +++ b/tests/docs-examples-test/test_go.sh @@ -5,7 +5,7 @@ set -e taosd >> /dev/null 2>&1 & taosadapter >> /dev/null 2>&1 & -cd ../../docs-examples/go +cd ../../docs/examples/go go mod tidy diff --git a/tests/docs-examples-test/test_java.sh b/tests/docs-examples-test/test_java.sh index 0e8e8266a1..12ebda7936 100755 --- a/tests/docs-examples-test/test_java.sh +++ b/tests/docs-examples-test/test_java.sh @@ -4,6 +4,6 @@ set -e taosd >> /dev/null 2>&1 & taosadapter >> /dev/null 2>&1 & -cd ../../docs-examples/java +cd ../../docs/examples/java mvn test \ No newline at end of file diff --git a/tests/docs-examples-test/test_node.sh b/tests/docs-examples-test/test_node.sh index 14aab236f9..2dd4d5735d 100755 --- a/tests/docs-examples-test/test_node.sh +++ b/tests/docs-examples-test/test_node.sh @@ -5,7 +5,7 @@ set -e pgrep taosd || taosd >> /dev/null 2>&1 & pgrep taosadapter || taosadapter >> /dev/null 2>&1 & -cd ../../docs-examples/node +cd ../../docs/examples/node npm install cd restexample; diff --git a/tests/docs-examples-test/test_python.sh b/tests/docs-examples-test/test_python.sh index 2b96311b29..0886b2b3ef 100755 --- a/tests/docs-examples-test/test_python.sh +++ b/tests/docs-examples-test/test_python.sh @@ -5,7 +5,7 @@ set -e taosd >> /dev/null 2>&1 & taosadapter >> /dev/null 2>&1 & -cd ../../docs-examples/python +cd ../../docs/examples/python # 1 taos -s "create database if not exists log" diff --git a/tests/docs-examples-test/test_rust.sh b/tests/docs-examples-test/test_rust.sh index 6bf0fe457a..394d3d22c7 100755 --- a/tests/docs-examples-test/test_rust.sh +++ b/tests/docs-examples-test/test_rust.sh @@ -5,7 +5,7 @@ set -e pgrep taosd || taosd >> /dev/null 2>&1 & pgrep taosadapter || taosadapter >> /dev/null 2>&1 & -cd ../../docs-examples/rust +cd ../../docs/examples/rust cargo run -p nativeexample --example connect cargo run -p restexample --example connect -- GitLab From 07bd5e283475a1488f7bee0f3c4e4990286ed908 Mon Sep 17 00:00:00 2001 From: dingbo Date: Mon, 13 Jun 2022 15:52:12 +0800 Subject: [PATCH 007/380] fix: test_R.sh --- tests/docs-examples-test/test_R.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/docs-examples-test/test_R.sh b/tests/docs-examples-test/test_R.sh index 80e5e81373..d59daf5d34 100755 --- a/tests/docs-examples-test/test_R.sh +++ b/tests/docs-examples-test/test_R.sh @@ -7,7 +7,7 @@ pgrep taosadapter || taosadapter >> /dev/null 2>&1 & cd ../../docs/examples/R -jar_path=`find ../../../debug/build -name taos-jdbcdriver-*-dist.jar` +jar_path=`find ../../../../debug/build -name taos-jdbcdriver-*-dist.jar` echo jar_path=$jar_path R -f connect_native.r --args $jar_path # R -f connect_rest.r --args $jar_path # bug 14704 -- GitLab From 24a6a0a9fe02d75d7b98ff33fe6afa41c679a475 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Mon, 13 Jun 2022 16:14:37 +0800 Subject: [PATCH 008/380] fix: port the fixing of issue 13529 from develop to 2.6 --- src/tsdb/inc/tsdbFile.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tsdb/inc/tsdbFile.h b/src/tsdb/inc/tsdbFile.h index 75e9563151..8436786157 100644 --- a/src/tsdb/inc/tsdbFile.h +++ b/src/tsdb/inc/tsdbFile.h @@ -257,7 +257,13 @@ static FORCE_INLINE int tsdbAppendDFile(SDFile* pDFile, void* buf, int64_t nbyte return -1; } - ASSERT(pDFile->info.size == toffset); + //bug fix. To avoid data corruption, + //the end offset of current file should be checked with file size, + //if not equal, known as file corrupted and return error. + if (pDFile->info.size != toffset) { + terrno = TSDB_CODE_TDB_FILE_CORRUPTED; + return -1; + } if (offset) { *offset = toffset; -- GitLab From f5b00e3f376f64fc026597ed8da0be4e59dac43d Mon Sep 17 00:00:00 2001 From: tangfangzhi Date: Mon, 13 Jun 2022 16:46:57 +0800 Subject: [PATCH 009/380] fix: map docs directory into container --- tests/parallel_test/run_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/parallel_test/run_container.sh b/tests/parallel_test/run_container.sh index 6ba16ee646..31e0ccd51b 100755 --- a/tests/parallel_test/run_container.sh +++ b/tests/parallel_test/run_container.sh @@ -95,7 +95,7 @@ docker run \ -v $REPDIR/packaging/cfg/taos.cfg:/etc/taos/taos.cfg:ro \ -v $REPDIR/packaging:$CONTAINER_TESTDIR/packaging:ro \ -v $REPDIR/README.md:$CONTAINER_TESTDIR/README.md:ro \ - -v $REPDIR/docs-examples:$CONTAINER_TESTDIR/docs-examples \ + -v $REPDIR/docs:$CONTAINER_TESTDIR/docs \ -v $REPDIR/src/connector/python/taos:/usr/local/lib/python3.8/site-packages/taos:ro \ -e LD_LIBRARY_PATH=/home/debug/build/lib:/home/debug/build/lib64 \ --rm --ulimit core=-1 taos_test:v1.0 $CONTAINER_TESTDIR/tests/parallel_test/run_case.sh -d "$exec_dir" -c "$cmd" $timeout_param -- GitLab From 054cd11df13e758b2450038ac0f83030e0596344 Mon Sep 17 00:00:00 2001 From: dingbo Date: Mon, 13 Jun 2022 18:54:59 +0800 Subject: [PATCH 010/380] docs: test --- docs/en/02-intro/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index f6766f910f..52b25bf949 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -110,4 +110,4 @@ As a high-performance, scalable and SQL supported time-series database, TDengine - [TDengine vs InfluxDB、OpenTSDB、Cassandra、MySQL、ClickHouse](https://www.tdengine.com/downloads/TDengine_Testing_Report_en.pdf) - [TDengine vs OpenTSDB](https://tdengine.com/2019/09/12/710.html) - [TDengine vs Cassandra](https://tdengine.com/2019/09/12/708.html) -- [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html) +- [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html) \ No newline at end of file -- GitLab From 0c1a225ad215b410953af520cd45e3da46c4cb0e Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Tue, 14 Jun 2022 11:42:11 +0800 Subject: [PATCH 011/380] docs: refine keywords section and add delete keywords --- docs/en/12-taos-sql/12-keywords.md | 309 +++++++++++++++++++--- docs/zh/12-taos-sql/12-keywords/index.md | 310 ++++++++++++++++++++--- 2 files changed, 535 insertions(+), 84 deletions(-) diff --git a/docs/en/12-taos-sql/12-keywords.md b/docs/en/12-taos-sql/12-keywords.md index 56a82a02a1..6c015c3ae3 100644 --- a/docs/en/12-taos-sql/12-keywords.md +++ b/docs/en/12-taos-sql/12-keywords.md @@ -6,48 +6,273 @@ There are about 200 keywords reserved by TDengine, they can't be used as the nam **Keywords List** -| | | | | | -| ----------- | ---------- | --------- | ---------- | ------------ | -| ABORT | CREATE | IGNORE | NULL | STAR | -| ACCOUNT | CTIME | IMMEDIATE | OF | STATE | -| ACCOUNTS | DATABASE | IMPORT | OFFSET | STATEMENT | -| ADD | DATABASES | IN | OR | STATE_WINDOW | -| AFTER | DAYS | INITIALLY | ORDER | STORAGE | -| ALL | DBS | INSERT | PARTITIONS | STREAM | -| ALTER | DEFERRED | INSTEAD | PASS | STREAMS | -| AND | DELIMITERS | INT | PLUS | STRING | -| AS | DESC | INTEGER | PPS | SYNCDB | -| ASC | DESCRIBE | INTERVAL | PRECISION | TABLE | -| ATTACH | DETACH | INTO | PREV | TABLES | -| BEFORE | DISTINCT | IS | PRIVILEGE | TAG | -| BEGIN | DIVIDE | ISNULL | QTIME | TAGS | -| BETWEEN | DNODE | JOIN | QUERIES | TBNAME | -| BIGINT | DNODES | KEEP | QUERY | TIMES | -| BINARY | DOT | KEY | QUORUM | TIMESTAMP | -| BITAND | DOUBLE | KILL | RAISE | TINYINT | -| BITNOT | DROP | LE | REM | TOPIC | -| BITOR | EACH | LIKE | REPLACE | TOPICS | -| BLOCKS | END | LIMIT | REPLICA | TRIGGER | -| BOOL | EQ | LINEAR | RESET | TSERIES | -| BY | EXISTS | LOCAL | RESTRICT | UMINUS | -| CACHE | EXPLAIN | LP | ROW | UNION | -| CACHELAST | FAIL | LSHIFT | RP | UNSIGNED | -| CASCADE | FILE | LT | RSHIFT | UPDATE | -| CHANGE | FILL | MATCH | SCORES | UPLUS | -| CLUSTER | FLOAT | MAXROWS | SELECT | USE | -| COLON | FOR | MINROWS | SEMI | USER | -| COLUMN | FROM | MINUS | SESSION | USERS | -| COMMA | FSYNC | MNODES | SET | USING | -| COMP | GE | MODIFY | SHOW | VALUES | -| COMPACT | GLOB | MODULES | SLASH | VARIABLE | -| CONCAT | GRANTS | NCHAR | SLIDING | VARIABLES | -| CONFLICT | GROUP | NE | SLIMIT | VGROUPS | -| CONNECTION | GT | NONE | SMALLINT | VIEW | -| CONNECTIONS | HAVING | NOT | SOFFSET | VNODES | -| CONNS | ID | NOTNULL | STable | WAL | -| COPY | IF | NOW | STableS | WHERE | -| _C0 | _QSTART | _QSTOP | _QDURATION | _WSTART | -| _WSTOP | _WDURATION | +### A + +- ABORT +- ACCOUNT +- ACCOUNTS +- ADD +- AFTER +- ALL +- ALTER +- AND +- AS +- ASC +- ATTACH + +### B + +- BEFORE +- BEGIN +- BETWEEN +- BIGINT +- BINARY +- BITAND +- BITNOT +- BITOR +- BLOCKS +- BOOL +- BY + +### C + +- CACHE +- CACHELAST +- CASCADE +- CHANGE +- CLUSTER +- COLON +- COLUMN +- COMMA +- COMP +- COMPACT +- CONCAT +- CONFLICT +- CONNECTION +- CONNECTIONS +- CONNS +- COPY +- CREATE +- CTIME + +### D + +- DATABASE +- DATABASES +- DAYS +- DBS +- DEFERRED +- DELETE +- DELIMITERS +- DESC +- DESCRIBE +- DETACH +- DISTINCT +- DIVIDE +- DNODE +- DNODES +- DOT +- DOUBLE +- DROP + +### E + +- END +- EQ +- EXISTS +- EXPLAIN + +### F + +- FAIL +- FILE +- FILL +- FLOAT +- FOR +- FROM +- FSYNC + +### G + +- GE +- GLOB +- GRANTS +- GROUP +- GT + +### H + +- HAVING + +### I + +- ID +- IF +- IGNORE +- IMMEDIA +- IMPORT +- IN +- INITIAL +- INSERT +- INSTEAD +- INT +- INTEGER +- INTERVA +- INTO +- IS +- ISNULL + +### J + +- JOIN + +### K + +- KEEP +- KEY +- KILL + +### L + +- LE +- LIKE +- LIMIT +- LINEAR +- LOCAL +- LP +- LSHIFT +- LT + +### M + +- MATCH +- MAXROWS +- MINROWS +- MINUS +- MNODES +- MODIFY +- MODULES + +### N + +- NE +- NONE +- NOT +- NOTNULL +- NOW +- NULL + +### O + +- OF +- OFFSET +- OR +- ORDER + +### P + +- PARTITION +- PASS +- PLUS +- PPS +- PRECISION +- PREV +- PRIVILEGE + +### Q + +- QTIME +- QUERIE +- QUERY +- QUORUM + +### R + +- RAISE +- REM +- REPLACE +- REPLICA +- RESET +- RESTRIC +- ROW +- RP +- RSHIFT + +### S + +- SCORES +- SELECT +- SEMI +- SESSION +- SET +- SHOW +- SLASH +- SLIDING +- SLIMIT +- SMALLIN +- SOFFSET +- STable +- STableS +- STAR +- STATE +- STATEMEN +- STATE_WI +- STORAGE +- STREAM +- STREAMS +- STRING +- SYNCDB + +### T + +- TABLE +- TABLES +- TAG +- TAGS +- TBNAME +- TIMES +- TIMESTAMP +- TINYINT +- TOPIC +- TOPICS +- TRIGGER +- TSERIES + +### U + +- UMINUS +- UNION +- UNSIGNED +- UPDATE +- UPLUS +- USE +- USER +- USERS +- USING + +### V + +- VALUES +- VARIABLE +- VARIABLES +- VGROUPS +- VIEW +- VNODES + +### W + +- WAL +- WHERE + +### _ + +- _C0 +- _QSTART +- _QSTOP +- _QDURATION +- _WSTART +- _WSTOP +- _WDURATION ## Explanations ### TBNAME diff --git a/docs/zh/12-taos-sql/12-keywords/index.md b/docs/zh/12-taos-sql/12-keywords/index.md index 0b9ec4de86..91dd601ad6 100644 --- a/docs/zh/12-taos-sql/12-keywords/index.md +++ b/docs/zh/12-taos-sql/12-keywords/index.md @@ -45,48 +45,274 @@ title: TDengine 参数限制与保留关键字 目前 TDengine 有将近 200 个内部保留关键字,这些关键字无论大小写均不可以用作库名、表名、STable 名、数据列名及标签列名等。这些关键字列表如下: -| 关键字列表 | | | | | -| ----------- | ---------- | --------- | ---------- | ------------ | -| ABORT | CREATE | IGNORE | NULL | STAR | -| ACCOUNT | CTIME | IMMEDIATE | OF | STATE | -| ACCOUNTS | DATABASE | IMPORT | OFFSET | STATEMENT | -| ADD | DATABASES | IN | OR | STATE_WINDOW | -| AFTER | DAYS | INITIALLY | ORDER | STORAGE | -| ALL | DBS | INSERT | PARTITIONS | STREAM | -| ALTER | DEFERRED | INSTEAD | PASS | STREAMS | -| AND | DELIMITERS | INT | PLUS | STRING | -| AS | DESC | INTEGER | PPS | SYNCDB | -| ASC | DESCRIBE | INTERVAL | PRECISION | TABLE | -| ATTACH | DETACH | INTO | PREV | TABLES | -| BEFORE | DISTINCT | IS | PRIVILEGE | TAG | -| BEGIN | DIVIDE | ISNULL | QTIME | TAGS | -| BETWEEN | DNODE | JOIN | QUERIES | TBNAME | -| BIGINT | DNODES | KEEP | QUERY | TIMES | -| BINARY | DOT | KEY | QUORUM | TIMESTAMP | -| BITAND | DOUBLE | KILL | RAISE | TINYINT | -| BITNOT | DROP | LE | REM | TOPIC | -| BITOR | EACH | LIKE | REPLACE | TOPICS | -| BLOCKS | END | LIMIT | REPLICA | TRIGGER | -| BOOL | EQ | LINEAR | RESET | TSERIES | -| BY | EXISTS | LOCAL | RESTRICT | UMINUS | -| CACHE | EXPLAIN | LP | ROW | UNION | -| CACHELAST | FAIL | LSHIFT | RP | UNSIGNED | -| CASCADE | FILE | LT | RSHIFT | UPDATE | -| CHANGE | FILL | MATCH | SCORES | UPLUS | -| CLUSTER | FLOAT | MAXROWS | SELECT | USE | -| COLON | FOR | MINROWS | SEMI | USER | -| COLUMN | FROM | MINUS | SESSION | USERS | -| COMMA | FSYNC | MNODES | SET | USING | -| COMP | GE | MODIFY | SHOW | VALUES | -| COMPACT | GLOB | MODULES | SLASH | VARIABLE | -| CONCAT | GRANTS | NCHAR | SLIDING | VARIABLES | -| CONFLICT | GROUP | NE | SLIMIT | VGROUPS | -| CONNECTION | GT | NONE | SMALLINT | VIEW | -| CONNECTIONS | HAVING | NOT | SOFFSET | VNODES | -| CONNS | ID | NOTNULL | STABLE | WAL | -| COPY | IF | NOW | STABLES | WHERE | -| _C0 | _QSTART | _QSTOP | _QDURATION | _WSTART | -| _WSTOP | _WDURATION | +### A + +- ABORT +- ACCOUNT +- ACCOUNTS +- ADD +- AFTER +- ALL +- ALTER +- AND +- AS +- ASC +- ATTACH + +### B + +- BEFORE +- BEGIN +- BETWEEN +- BIGINT +- BINARY +- BITAND +- BITNOT +- BITOR +- BLOCKS +- BOOL +- BY + +### C + +- CACHE +- CACHELAST +- CASCADE +- CHANGE +- CLUSTER +- COLON +- COLUMN +- COMMA +- COMP +- COMPACT +- CONCAT +- CONFLICT +- CONNECTION +- CONNECTIONS +- CONNS +- COPY +- CREATE +- CTIME + +### D + +- DATABASE +- DATABASES +- DAYS +- DBS +- DEFERRED +- DELETE +- DELIMITERS +- DESC +- DESCRIBE +- DETACH +- DISTINCT +- DIVIDE +- DNODE +- DNODES +- DOT +- DOUBLE +- DROP + +### E + +- END +- EQ +- EXISTS +- EXPLAIN + +### F + +- FAIL +- FILE +- FILL +- FLOAT +- FOR +- FROM +- FSYNC + +### G + +- GE +- GLOB +- GRANTS +- GROUP +- GT + +### H + +- HAVING + +### I + +- ID +- IF +- IGNORE +- IMMEDIA +- IMPORT +- IN +- INITIAL +- INSERT +- INSTEAD +- INT +- INTEGER +- INTERVA +- INTO +- IS +- ISNULL + +### J + +- JOIN + +### K + +- KEEP +- KEY +- KILL + +### L + +- LE +- LIKE +- LIMIT +- LINEAR +- LOCAL +- LP +- LSHIFT +- LT + +### M + +- MATCH +- MAXROWS +- MINROWS +- MINUS +- MNODES +- MODIFY +- MODULES + +### N + +- NE +- NONE +- NOT +- NOTNULL +- NOW +- NULL + +### O + +- OF +- OFFSET +- OR +- ORDER + +### P + +- PARTITION +- PASS +- PLUS +- PPS +- PRECISION +- PREV +- PRIVILEGE + +### Q + +- QTIME +- QUERIE +- QUERY +- QUORUM + +### R + +- RAISE +- REM +- REPLACE +- REPLICA +- RESET +- RESTRIC +- ROW +- RP +- RSHIFT + +### S + +- SCORES +- SELECT +- SEMI +- SESSION +- SET +- SHOW +- SLASH +- SLIDING +- SLIMIT +- SMALLIN +- SOFFSET +- STable +- STableS +- STAR +- STATE +- STATEMEN +- STATE_WI +- STORAGE +- STREAM +- STREAMS +- STRING +- SYNCDB + +### T + +- TABLE +- TABLES +- TAG +- TAGS +- TBNAME +- TIMES +- TIMESTAMP +- TINYINT +- TOPIC +- TOPICS +- TRIGGER +- TSERIES + +### U + +- UMINUS +- UNION +- UNSIGNED +- UPDATE +- UPLUS +- USE +- USER +- USERS +- USING + +### V + +- VALUES +- VARIABLE +- VARIABLES +- VGROUPS +- VIEW +- VNODES + +### W + +- WAL +- WHERE + +### _ + +- _C0 +- _QSTART +- _QSTOP +- _QDURATION +- _WSTART +- _WSTOP +- _WDURATION + ## 特殊说明 ### TBNAME -- GitLab From 125bc0ea5a5de1187de65d156925ee7df6e327a1 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Tue, 14 Jun 2022 11:49:04 +0800 Subject: [PATCH 012/380] Update 12-keywords.md --- docs/en/12-taos-sql/12-keywords.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/12-taos-sql/12-keywords.md b/docs/en/12-taos-sql/12-keywords.md index 6c015c3ae3..b01ff4c648 100644 --- a/docs/en/12-taos-sql/12-keywords.md +++ b/docs/en/12-taos-sql/12-keywords.md @@ -4,7 +4,7 @@ title: Keywords There are about 200 keywords reserved by TDengine, they can't be used as the name of database, STable or table with either upper case, lower case or mixed case. -**Keywords List** +## Keyword List ### A @@ -311,4 +311,4 @@ The start, stop and duration of a query time window (Since version 2.6.0.0). The start, stop and duration of aggegate query by time window, like interval, session window, state window (Since version 2.6.0.0). ### _c0 -The first column of a table or STable. \ No newline at end of file +The first column of a table or STable. -- GitLab From dbd1cab805fada32b2811325ca8b2ca3f762a411 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Tue, 14 Jun 2022 12:03:06 +0800 Subject: [PATCH 013/380] docs: resolve one sql error --- docs/en/12-taos-sql/12-keywords.md | 1 + docs/zh/12-taos-sql/12-keywords/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/en/12-taos-sql/12-keywords.md b/docs/en/12-taos-sql/12-keywords.md index b01ff4c648..fb7bb02bff 100644 --- a/docs/en/12-taos-sql/12-keywords.md +++ b/docs/en/12-taos-sql/12-keywords.md @@ -281,6 +281,7 @@ There are about 200 keywords reserved by TDengine, they can't be used as the nam Get the table name and tag values of all subtables in a STable. ```mysql SELECT TBNAME, location FROM meters; +``` Count the number of subtables in a STable. ```mysql diff --git a/docs/zh/12-taos-sql/12-keywords/index.md b/docs/zh/12-taos-sql/12-keywords/index.md index 91dd601ad6..f7a6107791 100644 --- a/docs/zh/12-taos-sql/12-keywords/index.md +++ b/docs/zh/12-taos-sql/12-keywords/index.md @@ -321,6 +321,7 @@ title: TDengine 参数限制与保留关键字 获取一个超级表所有的子表名及相关的标签信息: ```mysql SELECT TBNAME, location FROM meters; +``` 统计超级表下辖子表数量: ```mysql -- GitLab From 7d44636df956269ac05fe1d369d52b1381dc635f Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Tue, 14 Jun 2022 12:26:44 +0800 Subject: [PATCH 014/380] Update 12-keywords.md --- docs/en/12-taos-sql/12-keywords.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/en/12-taos-sql/12-keywords.md b/docs/en/12-taos-sql/12-keywords.md index fb7bb02bff..6233108906 100644 --- a/docs/en/12-taos-sql/12-keywords.md +++ b/docs/en/12-taos-sql/12-keywords.md @@ -62,7 +62,6 @@ There are about 200 keywords reserved by TDengine, they can't be used as the nam - DAYS - DBS - DEFERRED -- DELETE - DELIMITERS - DESC - DESCRIBE -- GitLab From 17fd08be421167c6df53dbdabb2557b20fd36646 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Tue, 14 Jun 2022 13:40:48 +0800 Subject: [PATCH 015/380] docs: move delete data from developer guide to sql reference guide --- .../05-delete-data.mdx => 12-taos-sql/08-delete-data.mdx} | 0 docs/en/12-taos-sql/{07-function.md => 10-function.md} | 0 docs/en/12-taos-sql/{08-interval.md => 12-interval.md} | 0 docs/en/12-taos-sql/{09-limit.md => 14-limit.md} | 0 docs/en/12-taos-sql/{10-json.md => 16-json.md} | 0 docs/en/12-taos-sql/{11-escape.md => 18-escape.md} | 0 docs/en/12-taos-sql/{12-keywords.md => 20-keywords.md} | 0 .../05-delete-data.mdx => 12-taos-sql/08-delete-data.mdx} | 0 docs/zh/12-taos-sql/{07-function.md => 10-function.md} | 0 docs/zh/12-taos-sql/{08-interval.md => 12-interval.md} | 0 docs/zh/12-taos-sql/12-keywords/_category_.yml | 1 - docs/zh/12-taos-sql/{09-limit.md => 14-limit.md} | 0 docs/zh/12-taos-sql/{10-json.md => 16-json.md} | 0 docs/zh/12-taos-sql/{11-escape.md => 18-escape.md} | 0 docs/zh/12-taos-sql/{12-keywords/index.md => 20-keywords.md} | 0 15 files changed, 1 deletion(-) rename docs/en/{07-develop/05-delete-data.mdx => 12-taos-sql/08-delete-data.mdx} (100%) rename docs/en/12-taos-sql/{07-function.md => 10-function.md} (100%) rename docs/en/12-taos-sql/{08-interval.md => 12-interval.md} (100%) rename docs/en/12-taos-sql/{09-limit.md => 14-limit.md} (100%) rename docs/en/12-taos-sql/{10-json.md => 16-json.md} (100%) rename docs/en/12-taos-sql/{11-escape.md => 18-escape.md} (100%) rename docs/en/12-taos-sql/{12-keywords.md => 20-keywords.md} (100%) rename docs/zh/{07-develop/05-delete-data.mdx => 12-taos-sql/08-delete-data.mdx} (100%) rename docs/zh/12-taos-sql/{07-function.md => 10-function.md} (100%) rename docs/zh/12-taos-sql/{08-interval.md => 12-interval.md} (100%) delete mode 100644 docs/zh/12-taos-sql/12-keywords/_category_.yml rename docs/zh/12-taos-sql/{09-limit.md => 14-limit.md} (100%) rename docs/zh/12-taos-sql/{10-json.md => 16-json.md} (100%) rename docs/zh/12-taos-sql/{11-escape.md => 18-escape.md} (100%) rename docs/zh/12-taos-sql/{12-keywords/index.md => 20-keywords.md} (100%) diff --git a/docs/en/07-develop/05-delete-data.mdx b/docs/en/12-taos-sql/08-delete-data.mdx similarity index 100% rename from docs/en/07-develop/05-delete-data.mdx rename to docs/en/12-taos-sql/08-delete-data.mdx diff --git a/docs/en/12-taos-sql/07-function.md b/docs/en/12-taos-sql/10-function.md similarity index 100% rename from docs/en/12-taos-sql/07-function.md rename to docs/en/12-taos-sql/10-function.md diff --git a/docs/en/12-taos-sql/08-interval.md b/docs/en/12-taos-sql/12-interval.md similarity index 100% rename from docs/en/12-taos-sql/08-interval.md rename to docs/en/12-taos-sql/12-interval.md diff --git a/docs/en/12-taos-sql/09-limit.md b/docs/en/12-taos-sql/14-limit.md similarity index 100% rename from docs/en/12-taos-sql/09-limit.md rename to docs/en/12-taos-sql/14-limit.md diff --git a/docs/en/12-taos-sql/10-json.md b/docs/en/12-taos-sql/16-json.md similarity index 100% rename from docs/en/12-taos-sql/10-json.md rename to docs/en/12-taos-sql/16-json.md diff --git a/docs/en/12-taos-sql/11-escape.md b/docs/en/12-taos-sql/18-escape.md similarity index 100% rename from docs/en/12-taos-sql/11-escape.md rename to docs/en/12-taos-sql/18-escape.md diff --git a/docs/en/12-taos-sql/12-keywords.md b/docs/en/12-taos-sql/20-keywords.md similarity index 100% rename from docs/en/12-taos-sql/12-keywords.md rename to docs/en/12-taos-sql/20-keywords.md diff --git a/docs/zh/07-develop/05-delete-data.mdx b/docs/zh/12-taos-sql/08-delete-data.mdx similarity index 100% rename from docs/zh/07-develop/05-delete-data.mdx rename to docs/zh/12-taos-sql/08-delete-data.mdx diff --git a/docs/zh/12-taos-sql/07-function.md b/docs/zh/12-taos-sql/10-function.md similarity index 100% rename from docs/zh/12-taos-sql/07-function.md rename to docs/zh/12-taos-sql/10-function.md diff --git a/docs/zh/12-taos-sql/08-interval.md b/docs/zh/12-taos-sql/12-interval.md similarity index 100% rename from docs/zh/12-taos-sql/08-interval.md rename to docs/zh/12-taos-sql/12-interval.md diff --git a/docs/zh/12-taos-sql/12-keywords/_category_.yml b/docs/zh/12-taos-sql/12-keywords/_category_.yml deleted file mode 100644 index 67738650a4..0000000000 --- a/docs/zh/12-taos-sql/12-keywords/_category_.yml +++ /dev/null @@ -1 +0,0 @@ -label: 参数限制与保留关键字 \ No newline at end of file diff --git a/docs/zh/12-taos-sql/09-limit.md b/docs/zh/12-taos-sql/14-limit.md similarity index 100% rename from docs/zh/12-taos-sql/09-limit.md rename to docs/zh/12-taos-sql/14-limit.md diff --git a/docs/zh/12-taos-sql/10-json.md b/docs/zh/12-taos-sql/16-json.md similarity index 100% rename from docs/zh/12-taos-sql/10-json.md rename to docs/zh/12-taos-sql/16-json.md diff --git a/docs/zh/12-taos-sql/11-escape.md b/docs/zh/12-taos-sql/18-escape.md similarity index 100% rename from docs/zh/12-taos-sql/11-escape.md rename to docs/zh/12-taos-sql/18-escape.md diff --git a/docs/zh/12-taos-sql/12-keywords/index.md b/docs/zh/12-taos-sql/20-keywords.md similarity index 100% rename from docs/zh/12-taos-sql/12-keywords/index.md rename to docs/zh/12-taos-sql/20-keywords.md -- GitLab From 034ee47986de83b4c4f54da9c0ca0b4e4acf52f3 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Tue, 14 Jun 2022 15:12:15 +0800 Subject: [PATCH 016/380] Update 20-keywords.md --- docs/en/12-taos-sql/20-keywords.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/12-taos-sql/20-keywords.md b/docs/en/12-taos-sql/20-keywords.md index 6233108906..0e79a07362 100644 --- a/docs/en/12-taos-sql/20-keywords.md +++ b/docs/en/12-taos-sql/20-keywords.md @@ -63,6 +63,7 @@ There are about 200 keywords reserved by TDengine, they can't be used as the nam - DBS - DEFERRED - DELIMITERS +- DELETE - DESC - DESCRIBE - DETACH -- GitLab From 4b30c8daba1c5b72dbe53a528f4488214d8bebfc Mon Sep 17 00:00:00 2001 From: zyyang Date: Tue, 14 Jun 2022 15:13:38 +0800 Subject: [PATCH 017/380] reset balance since test cases failed --- packaging/cfg/taos.cfg | 2 +- src/common/src/tglobal.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/cfg/taos.cfg b/packaging/cfg/taos.cfg index 1918a4c469..7d77a0b23e 100644 --- a/packaging/cfg/taos.cfg +++ b/packaging/cfg/taos.cfg @@ -52,7 +52,7 @@ keepColumnName 1 # telemetryReporting 1 # enable/disable load balancing -# balance 0 +# balance 1 # role for dnode. 0 - any, 1 - mnode, 2 - dnode # role 0 diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index cc0e6b0e97..616c5fba89 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -164,7 +164,7 @@ bool tsdbForceCompactFile = false; // compact TSDB fileset int32_t tsdbWalFlushSize = TSDB_DEFAULT_WAL_FLUSH_SIZE; // MB // balance -int8_t tsEnableBalance = 0; +int8_t tsEnableBalance = 1; int8_t tsAlternativeRole = 0; int32_t tsBalanceInterval = 300; // seconds int32_t tsOfflineInterval = 3; // seconds -- GitLab From 392e2572fdd5297bfb89223ad03a33d23d1698fc Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 14 Jun 2022 17:06:52 +0800 Subject: [PATCH 018/380] fix(query): fixed group by col_proj_function des error on client. [TS-1605] --- src/query/src/qAggMain.c | 6 ++++++ src/query/src/qExecutor.c | 8 +++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 42e649be10..fc36974c9b 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -3347,6 +3347,12 @@ static void col_project_function(SQLFunctionCtx *pCtx) { memcpy(pCtx->pOutput, pData, (size_t) numOfRows * pCtx->inputBytes); } else { // DESC + if (pCtx->param[0].i64 == 1) { + // only output one row, copy first row to output + memcpy(pCtx->pOutput, pData, (size_t)pCtx->inputBytes); + return ; + } + for(int32_t i = 0; i < pCtx->size; ++i) { char* dst = pCtx->pOutput + (pCtx->size - 1 - i) * pCtx->inputBytes; char* src = pData + i * pCtx->inputBytes; diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index f8a1871f53..6052f266d6 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -944,8 +944,6 @@ void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset, int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput) { - SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; - for (int32_t k = 0; k < numOfOutput; ++k) { bool hasAggregates = pCtx[k].preAggVals.isSet; @@ -956,13 +954,13 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx // keep it temporarialy char* start = pCtx[k].pInput; - int32_t pos = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? offset : offset - (forwardStep - 1); + // deal order by in aAggs.xFunction, not here if (pCtx[k].pInput != NULL) { - pCtx[k].pInput = (char *)pCtx[k].pInput + pos * pCtx[k].inputBytes; + pCtx[k].pInput = (char *)pCtx[k].pInput + offset * pCtx[k].inputBytes; } if (tsCol != NULL) { - pCtx[k].ptsList = &tsCol[pos]; + pCtx[k].ptsList = &tsCol[offset]; } // not a whole block involved in query processing, statistics data can not be used -- GitLab From dfbf9138d216c51bac9f4940e6c762d47b0cc3b2 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 14 Jun 2022 17:20:30 +0800 Subject: [PATCH 019/380] fix: taosdump incorrect count when dump in (#13815) for 2.6 [TD-16517] --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 3d5aa76f8c..99e283a40b 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 3d5aa76f8c718dcffa100b45e4cbf313d499c356 +Subproject commit 99e283a40b8671d82ebdb02b9b9a4ea6cd990553 -- GitLab From e255165d4cbcc39216cc07d46ccd74c6f72fb8b0 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 14 Jun 2022 18:24:13 +0800 Subject: [PATCH 020/380] fix(query): doHashGroupbyAgg need check order by . [TS-1605] --- src/query/src/qExecutor.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 6052f266d6..fb6396d0f4 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -944,6 +944,8 @@ void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset, int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput) { + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + for (int32_t k = 0; k < numOfOutput; ++k) { bool hasAggregates = pCtx[k].preAggVals.isSet; @@ -954,13 +956,13 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx // keep it temporarialy char* start = pCtx[k].pInput; - // deal order by in aAggs.xFunction, not here + int32_t pos = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? offset : offset - (forwardStep - 1); if (pCtx[k].pInput != NULL) { - pCtx[k].pInput = (char *)pCtx[k].pInput + offset * pCtx[k].inputBytes; + pCtx[k].pInput = (char *)pCtx[k].pInput + pos * pCtx[k].inputBytes; } if (tsCol != NULL) { - pCtx[k].ptsList = &tsCol[offset]; + pCtx[k].ptsList = &tsCol[pos]; } // not a whole block involved in query processing, statistics data can not be used @@ -1711,6 +1713,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); } + int32_t offset = QUERY_IS_ASC_QUERY(pQueryAttr) ? j - num : j - 1; doApplyFunctions(pRuntimeEnv, pInfo->binfo.pCtx, &w, j - num, num, tsList, pSDataBlock->info.rows, pOperator->numOfOutput); num = 1; @@ -1731,7 +1734,8 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); } - doApplyFunctions(pRuntimeEnv, pInfo->binfo.pCtx, &w, pSDataBlock->info.rows - num, num, tsList, pSDataBlock->info.rows, pOperator->numOfOutput); + int32_t offset = QUERY_IS_ASC_QUERY(pQueryAttr) ? pSDataBlock->info.rows - num : pSDataBlock->info.rows - 1; + doApplyFunctions(pRuntimeEnv, pInfo->binfo.pCtx, &w, offset, num, tsList, pSDataBlock->info.rows, pOperator->numOfOutput); } } -- GitLab From 0edaa50200f0d56f7a9ed17ee1fcbc7dc9088757 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 14 Jun 2022 18:25:43 +0800 Subject: [PATCH 021/380] fix(query): doHashGroupbyAgg need check order by. [TS-1605] --- src/query/src/qExecutor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index fb6396d0f4..492bf5241c 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1714,7 +1714,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn } int32_t offset = QUERY_IS_ASC_QUERY(pQueryAttr) ? j - num : j - 1; - doApplyFunctions(pRuntimeEnv, pInfo->binfo.pCtx, &w, j - num, num, tsList, pSDataBlock->info.rows, pOperator->numOfOutput); + doApplyFunctions(pRuntimeEnv, pInfo->binfo.pCtx, &w, offset, num, tsList, pSDataBlock->info.rows, pOperator->numOfOutput); num = 1; -- GitLab From 3eb3e5fb8291a3d67b88f3f4b8440200c1d88da1 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Wed, 15 Jun 2022 17:17:34 +0800 Subject: [PATCH 022/380] test: add test case for TS-1612 --- tests/pytest/functions/data.tar.gz | Bin 0 -> 2250 bytes tests/pytest/functions/function_diff.py | 21 ++++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/pytest/functions/data.tar.gz diff --git a/tests/pytest/functions/data.tar.gz b/tests/pytest/functions/data.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..9b0fd32993cb2654e9b6c2a9546903436da43f27 GIT binary patch literal 2250 zcmV;*2sQT~iwFP!000001MQm4&L*`Hg=fuGd^OBJCgfU zvH>B4Eu<&Up78cx@x*& z4LK&xQVbHO!)g$ToaGpb42RWFs`E@KA-2L;zG4a^(mjB+FbZ8uzETRaG>7#NtMkm9 zL+s8oai3DB`>R)xkdwzokWBYiuPU&oGp`QVjIOg?Q9@~SonRx>CY&V+jqeX^hBBy6 zv@4fTW_Q>Oby8cmOGX%(?ysrMMseN;o6SOP*3@RRQC|X^@TE5^SAxIbY^6F3XG_k( zSjxCZZ+kA*Lne2uT+*+cU>7z|Cfpv+e4oQ&E#&^TOSwwa`;f^wEY^ZdwiYnlhmzj* zT&#tf*;>G`hn}2gX3Q(jS|o*5m_3y>_@ML5g7=X-wpa^&I(C6QM{@Q6dyY)!CDRwa z&ZPF7l|D16PsB?1p42B&bKVDiNz^Bl!Iy@^B;(wfUn}d-7w3H?Ltox^bFmJ6arRep zsNVi+4~^cjVt33rKf7aNIP+l7Ih=X0=bY4cp~(_br0WD5A!X`k`4Y_IcFC$){7!>G zv!pufgk}|fZ?kC@iDQe6&<16qI^QOJpQz4vp>`3~`H|`Vz*Jl5xr^$2;(HL)dB^9) zV)$^Li9957pO>o?Kc+I?seX2ahZDiV=39@2jejMd&l@$|Kp? z)}b1bBRju3RYNk3Rmw0=*jm7#A({HMGL6&D`=H4}9GB)ywp(Bw+vtukmN^?5L8 z^5Axvs>vg>^8PjTkKp0m8yqKBvUoW!pe!@T~si!o?O?CtCJ-b|hDLA2h?BtC%ERj1OmRI5`9-FwwKwUV04m_)=Jk0BnB+Q}I7x)0`` z%2aoqwLq_5c9~k|#I8Ou_GjJcuutOfRb z>F2{xbM5+hGsM5R*8vafV9b|R-JkaU%fpZtQ2$(YzwEW)!;ly3HQvpTPt-jJdl>S9 zUCVEVe4=yT&6-bi?l0N$iR3&}^NBrQx|!w^dvE4p{aqt0W;IEqT9B+JiFvJI!ncroC<@!}Qau9`?TI_j)H-MH>D&yul)U{Ft^epA ztmc}0p4D7DJ}85R>^+v7;cR&fP&N<)9ELlc_a61bFpp}TM7`6p=ZX(QEkk`mtmdjz z>%?lVw)exWlw^kJAseF6+Ni`>>$a~1D>(7KxG-jmg1RL{h|Wi^*+UBxs64E7v*t^F{}qq!7V zE$`mwVp((VNOfKr>MHIpdG&4R`DLxE3e7dZke64Np+2Iy2AI}Wdp-8BiagTU18SMU z?^sq%j#LN1tgdq22fdzD=S3_pPwXCPkJFo{eN5!Ldq47F&Dn$Y2XPL2FKDr9c_hux zz%-Afd8;zyk<>qneWx5W4=K&QG0^w`rr#K-7AQmh$=}yBP7BSGi+#uIH1?OS`TVON z^04m2RIsFZGP^6vuui^*uKB!kw%uYCw{=%-jr%w6hmH4l%A0Ad+It=kLyV(2EttkC zS{o|Uz8ih!uy4tGzvp4dmuRjJrm>3VJ<2p+a-ONN%6leam2(b5?KztBK8;m0zJtM@ zbMMVOOkwvRI?~ zY0Rm^7i+YKWUOjl_g?2>9d>#9XSUub@^aEkSPb(jU5kBdWqp*z^qVQ&pQi1Ie{?PD z+ZoYaV^&wu{aKwlNDgL9>m!nXE(U)gxrQ+*?>^?uihi@9cCl|~h4}np&`%O`jKQz# z-iv+Me1BJ4%)Xs9ZWsG@#`M}4{Cbeyj4{MGc5fF$j1Gn&zh7Ex+P5syYI~|D*E{2+tMzNDKOrRVS*+7u zvoYjEh1<-2KQY$*`?G(;cg7iKoN>k(XPj}y8E2ev#u;avamE>EoN>k(XPj}y8E2ev Y#u;avamE>E{5{8i06#h15dcsC03~;=pa1{> literal 0 HcmV?d00001 diff --git a/tests/pytest/functions/function_diff.py b/tests/pytest/functions/function_diff.py index 5995b821d1..9742518886 100644 --- a/tests/pytest/functions/function_diff.py +++ b/tests/pytest/functions/function_diff.py @@ -16,6 +16,7 @@ import taos from util.log import * from util.cases import * from util.sql import * +from util.dnodes import * import numpy as np @@ -156,7 +157,25 @@ class TDTestCase: tdSql.error("select diff(col) from st group by dev") tdSql.error("select diff(col) from st group by col") - + + # TS-1612 + os.system("tar -zxf %s/functions/data.tar.gz" % os.getcwd()) + tdSql.execute("create database radb") + tdSql.execute("use radb") + tdSql.execute("CREATE TABLE `vehicle_automode` (`time` TIMESTAMP,`auto_ctl_odom` INT) TAGS (`mac_address` BINARY(30))") + tdSql.execute("CREATE TABLE `va_00545a230327` USING `vehicle_automode` TAGS ('00545a230327')") + tdSql.execute("insert into va_00545a230327 file 'data/va_00545a230327.csv' ") + tdSql.query("select * from vehicle_automode") + rows = tdSql.queryRows + tdSql.query("select diff(auto_ctl_odom,1) as aco from radb.vehicle_automode GROUP BY tbname") + tdSql.checkRows(rows - 1) + os.system("rm -rf data") + + tdDnodes.stop(1) + tdDnodes.start(1) + tdSql.query("select diff(auto_ctl_odom,1) as aco from radb.vehicle_automode GROUP BY tbname") + tdSql.checkRows(rows - 1) + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) -- GitLab From c8946cdd6229dfc2e3253016dfcf9536eaab062a Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Wed, 15 Jun 2022 18:06:26 +0800 Subject: [PATCH 023/380] fix: Support backquote escape for db names --- .gitignore | 1 + src/client/src/tscSQLParser.c | 229 ++++++++++++++---------------- src/client/src/tscUtil.c | 32 +++-- src/kit/shell/src/shellEngine.c | 6 +- src/plugins/monitor/src/monMain.c | 11 +- 5 files changed, 138 insertions(+), 141 deletions(-) diff --git a/.gitignore b/.gitignore index 0eba25231f..091e1d7361 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ build/ cmake-build-debug/ cmake-build-release/ cscope.out +cscope.files .DS_Store debug/ release/ diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 3d806bdac5..2745857e25 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -606,8 +606,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { case TSDB_SQL_DROP_TABLE: case TSDB_SQL_DROP_USER: case TSDB_SQL_DROP_ACCT: - case TSDB_SQL_DROP_DNODE: - case TSDB_SQL_DROP_DB: { + case TSDB_SQL_DROP_DNODE: { const char* msg2 = "invalid name"; const char* msg3 = "param name too long"; @@ -626,14 +625,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { } } - if (pInfo->type == TSDB_SQL_DROP_DB) { - assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1); - code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName); - if (code != TSDB_CODE_SUCCESS) { - return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); - } - - } else if (pInfo->type == TSDB_SQL_DROP_TABLE) { + if (pInfo->type == TSDB_SQL_DROP_TABLE) { assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1); code = tscSetTableFullName(&pTableMetaInfo->name, &sTblToken, pSql, dbIncluded); @@ -656,11 +648,12 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { break; } + case TSDB_SQL_DROP_DB: case TSDB_SQL_USE_DB: { const char* msg = "invalid db name"; SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); - if (tscValidateName(pToken, false, NULL) != TSDB_CODE_SUCCESS) { + if (tscValidateName(pToken, true, NULL) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } @@ -707,7 +700,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { char buf[TSDB_DB_NAME_LEN] = {0}; SStrToken token = taosTokenDup(&pCreateDB->dbname, buf, tListLen(buf)); - if (tscValidateName(&token, false, NULL) != TSDB_CODE_SUCCESS) { + if (tscValidateName(&token, true, NULL) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -816,7 +809,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); - if (tscValidateName(pToken, false, NULL) != TSDB_CODE_SUCCESS) { + if (tscValidateName(pToken, true, NULL) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -1088,7 +1081,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (code != TSDB_CODE_SUCCESS) { return code ; // async load table meta } - + // vgroupInfo if super if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { code = tscGetSTableVgroupInfo(pSql, pQueryInfo); @@ -1124,7 +1117,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { */ static bool isTopBottomUniqueQuery(SQueryInfo* pQueryInfo) { size_t size = tscNumOfExprs(pQueryInfo); - + for (int32_t i = 0; i < size; ++i) { int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId; @@ -1235,7 +1228,7 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS if (interpQuery) { return addPrimaryTsColumnForTimeWindowQuery(pQueryInfo, pCmd); } - + return TSDB_CODE_SUCCESS; } @@ -1351,7 +1344,7 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } } - + tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; taosArrayPush(pGroupExpr->columnInfo, &colIndex); @@ -1522,11 +1515,11 @@ int32_t tscSetTableFullName(SName* pName, SStrToken* pTableName, SSqlObj* pSql, SSqlCmd* pCmd = &pSql->cmd; int32_t code = TSDB_CODE_SUCCESS; int32_t idx = -1; - + if (dbIncluded) { idx = getDelimiterIndex(pTableName); } - + if (idx != -1) { // db has been specified in sql string so we ignore current db path char* acctId = getAccountId(pSql); if (acctId == NULL || strlen(acctId) <= 0) { @@ -1829,10 +1822,10 @@ int32_t validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { // assert(pCmd->numOfClause == 1); STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - + int32_t numOfTags = tscGetNumOfTags(pTableMeta); int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - + // no more max columns if (numOfCols >= TSDB_MAX_COLUMNS || numOfTags + numOfCols >= TSDB_MAX_COLUMNS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -2249,7 +2242,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS const char* msg3 = "not support query expression"; const char* msg4 = "not support distinct mixed with proj/agg func"; const char* msg5 = "invalid function name"; - const char* msg6 = "not support distinct mixed with join"; + const char* msg6 = "not support distinct mixed with join"; const char* msg7 = "not support distinct mixed with groupby"; const char* msg8 = "not support distinct in nest query"; const char* msg9 = "_block_dist not support subquery, only support stable/table"; @@ -2390,11 +2383,11 @@ int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnLi SSchema* pSchema = tscGetTableSchema(pTableMeta); tscColumnListInsert(pQueryInfo->colList, pColList->ids[i].columnIndex, uid, &pSchema[pColList->ids[i].columnIndex]); } - + TAOS_FIELD f = tscCreateField(type, fieldName, bytes); SInternalField* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f); pInfo->pExpr = pSqlExpr; - + return TSDB_CODE_SUCCESS; } @@ -2402,12 +2395,12 @@ SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tab STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex); int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ); SColumnIndex index = {.tableIndex = tableIndex,}; - + if (functionId == TSDB_FUNC_TAGPRJ) { index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta); tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); @@ -2435,7 +2428,7 @@ SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColInd pExpr->base.colInfo.flag = flag; STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); - + if (TSDB_COL_IS_TAG(flag)) { tscColumnListInsert(pTableMetaInfo->tagColList, pIndex->columnIndex, pTableMetaInfo->pTableMeta->id.uid, pColSchema); } @@ -2451,7 +2444,7 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum SSchema* pSchema = tscGetTableSchema(pTableMeta); STableComInfo tinfo = tscGetTableInfo(pTableMeta); - + if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags; } else { @@ -2681,7 +2674,7 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS pExpr->base.param[0].i64 = TSDB_ORDER_DESC; pExpr->base.param[0].nType = TSDB_DATA_TYPE_INT; } - + // for all queries, the timestamp column needs to be loaded SSchema s = {.colId = PRIMARYKEY_TIMESTAMP_COL_INDEX, .bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP,}; tscColumnListInsert(pQueryInfo->colList, PRIMARYKEY_TIMESTAMP_COL_INDEX, pExpr->base.uid, &s); @@ -3956,7 +3949,7 @@ static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // create tmp buf to avoid alter orginal sqlstr strncpy(tmpTokenBuf, pToken->z, pToken->n); - + pToken->z = tmpTokenBuf; pToken->n = stringProcess(pToken->z, pToken->n); @@ -4110,7 +4103,7 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (pDbPrefixToken->n <= 0) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } - if (tscValidateName(pDbPrefixToken, false, NULL) != TSDB_CODE_SUCCESS) { + if (tscValidateName(pDbPrefixToken, true, NULL) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -4147,7 +4140,7 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (pShowInfo->prefix.n <= 0) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - } + } return TSDB_CODE_SUCCESS; } @@ -4158,7 +4151,7 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { SSqlCmd* pCmd = &pSql->cmd; pCmd->command = pInfo->type; - + SStrToken* idStr = &(pInfo->pMiscInfo->id); if (idStr->n > TSDB_KILL_MSG_LEN) { return TSDB_CODE_TSC_INVALID_OPERATION; @@ -4191,7 +4184,7 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } - + return TSDB_CODE_SUCCESS; } static int32_t setCompactVnodeInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { @@ -4213,7 +4206,7 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { int32_t bytes = 0; int16_t type = 0; int32_t interBytes = 0; - + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t k = 0; k < size; ++k) { SExprInfo* pExpr = tscExprGet(pQueryInfo, k); @@ -4225,7 +4218,7 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { int32_t colIndex = pExpr->base.colInfo.colIndex; SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex); - + if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) || (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_STDDEV_DST) || (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_IRATE) || @@ -4257,16 +4250,16 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { return; } - + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex); - + // the final result size and type in the same as query on single table. // so here, set the flag to be false; int32_t inter = 0; - + int32_t functionId = pExpr->base.functionId; if (functionId < 0) { continue; @@ -4275,7 +4268,7 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) { continue; } - + if (functionId == TSDB_FUNC_FIRST_DST) { functionId = TSDB_FUNC_FIRST; } else if (functionId == TSDB_FUNC_LAST_DST) { @@ -4330,7 +4323,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) return true; } } - + if (tscIsSessionWindowQuery(pQueryInfo)) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return true; @@ -4679,7 +4672,7 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, } if (pExpr->tokenId == TK_IN) { - tVariant *pVal; + tVariant* pVal; if (pRight->tokenId != TK_SET || !serializeExprListToVariant(pRight->Expr.paramList, &pVal, colType, timePrecision)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } @@ -4714,7 +4707,7 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, if (retVal != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); - } + } switch (pExpr->tokenId) { case TK_LE: @@ -4779,7 +4772,7 @@ enum { TSQL_EXPR_TAG = 2, TSQL_EXPR_COLUMN = 4, TSQL_EXPR_TBNAME = 8, - TSQL_EXPR_JOIN = 16, + TSQL_EXPR_JOIN = 16, }; #define GET_MIXED_TYPE(t) (((t) >= TSQL_EXPR_JOIN) || ((t) > TSQL_EXPR_COLUMN && (t) < TSQL_EXPR_TBNAME) || ((t) == (TSQL_EXPR_TS|TSQL_EXPR_TAG))) @@ -4811,7 +4804,7 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); goto _err_ret; } - + if (pSchema->type == TSDB_DATA_TYPE_BOOL) { int32_t t = pExpr->tokenId; if (t != TK_EQ && t != TK_NE && t != TK_NOTNULL && t != TK_ISNULL && t != TK_IN) { @@ -4831,7 +4824,7 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol _err_ret: freeColumnFilterInfo(pColFilter, 1); - + return ret; } @@ -4861,7 +4854,7 @@ static int32_t addAllColumn(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pEx static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr) { int32_t ret = TSDB_CODE_SUCCESS; const char* msg6 = "illegal condition expression"; - + for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { tSqlExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i); if (p1 == NULL) { // no query condition on this table @@ -4870,7 +4863,7 @@ static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlEx tExprNode* p = NULL; - SArray* colList = taosArrayInit(10, sizeof(SColIndex)); + SArray* colList = taosArrayInit(10, sizeof(SColIndex)); ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL); size_t colNum = taosArrayGetSize(colList); for (int32_t k = 0; k < colNum; k++) { @@ -4909,12 +4902,12 @@ static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlEx if (pQueryInfo->colCond == NULL) { pQueryInfo->colCond = taosArrayInit(2, sizeof(STblCond)); } - - taosArrayPush(pQueryInfo->colCond, &cond); + + taosArrayPush(pQueryInfo->colCond, &cond); tSqlExprDestroy(p1); tExprTreeDestroy(p, NULL); - + if (ret) { break; } @@ -5040,7 +5033,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema2); atomic_add_fetch_32(&pTableMetaInfo->joinTagNum, 1); - + if (pTableMetaInfo->joinTagNum > 1) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } @@ -5084,9 +5077,9 @@ static int32_t validateSQLExprItemSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr, int32_t code = TSDB_CODE_SUCCESS; const char* msg1 = "invalid function parameters"; const char* msg2 = "not supported functions in arithmetic expression"; - + int32_t functionId = isValidFunction(pExpr->Expr.operand.z, pExpr->Expr.operand.n); - + pExpr->functionId = functionId; if (pExpr->Expr.paramList != NULL) { size_t numChildren = taosArrayGetSize(pExpr->Expr.paramList); @@ -6052,7 +6045,7 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* *pOut = NULL; return; } - + if (!isLogicalOperator(*pExpr)) { tSqlExpr* pLeft = (*pExpr)->pLeft; @@ -6110,17 +6103,17 @@ int32_t mergeTimeRange(SSqlCmd* pCmd, STimeWindow* res, STimeWindow* win, int32_ #define SET_EMPTY_RANGE(w) do { (w)->skey = INT64_MAX; (w)->ekey = INT64_MIN; } while (0) #define IS_EMPTY_RANGE(w) ((w)->skey == INT64_MAX && (w)->ekey == INT64_MIN) - + if (optr == TSDB_RELATION_AND) { if (res->skey > win->ekey || win->skey > res->ekey) { SET_EMPTY_RANGE(res); return TSDB_CODE_SUCCESS; } - + if (res->skey < win->skey) { res->skey = win->skey; } - + if (res->ekey > win->ekey) { res->ekey = win->ekey; } @@ -6145,7 +6138,7 @@ int32_t mergeTimeRange(SSqlCmd* pCmd, STimeWindow* res, STimeWindow* win, int32_ if (res->skey > win->skey) { res->skey = win->skey; } - + if (res->ekey < win->ekey) { res->ekey = win->ekey; } @@ -6155,7 +6148,7 @@ int32_t mergeTimeRange(SSqlCmd* pCmd, STimeWindow* res, STimeWindow* win, int32_ static int32_t createTimeRangeExpr(tSqlExpr** pExpr, STimeWindow* win, uint32_t tokenId) { *pExpr = calloc(1, sizeof(tSqlExpr)); - + (*pExpr)->type = SQL_NODE_VALUE; (*pExpr)->tokenId = tokenId; (*pExpr)->value.nType = TSDB_DATA_TYPE_VALUE_ARRAY; @@ -6178,7 +6171,6 @@ static int32_t convertTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return TSDB_CODE_SUCCESS; } pQueryInfo->onlyHasTagCond &= false; - if (!tSqlExprIsParentOfLeaf(pExpr)) { code = convertTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pLeft); @@ -6198,7 +6190,7 @@ static int32_t convertTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - + tSqlExpr* pRight = pExpr->pRight; if (getTimeRange(&win, pRight, pExpr->tokenId, tinfo.precision) != TSDB_CODE_SUCCESS) { @@ -6275,7 +6267,7 @@ static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInf SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); - + if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->ColName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (right)", pQueryInfo); } @@ -6381,7 +6373,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE if (pCondExpr->pTagCond == NULL) { return ret; } - + for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { tSqlExpr* p1 = extractExprForSTable(pCmd, &pCondExpr->pTagCond, pQueryInfo, i); if (p1 == NULL) { // no query condition on this table @@ -6389,7 +6381,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE } tExprNode* p = NULL; - + SArray* colList = taosArrayInit(10, sizeof(SColIndex)); ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL); size_t colNum = taosArrayGetSize(colList); @@ -6406,7 +6398,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE //if (ret == TSDB_CODE_SUCCESS) { // ret = filterInitFromTree(p, &pQueryInfo->tagFilter, (int32_t)taosArrayGetSize(colList), NULL); //} - + SBufferWriter bw = tbufInitWriter(NULL, false); TRY(0) { @@ -6421,7 +6413,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); int64_t uid = pTableMetaInfo->pTableMeta->id.uid; int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - + size_t num = taosArrayGetSize(colList); for(int32_t j = 0; j < num; ++j) { SColIndex* pIndex = taosArrayGet(colList, j); @@ -6431,7 +6423,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, &s[pIndex->colIndex]); } - + tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw); tSqlExprCompact(&pCondExpr->pTagCond); @@ -6441,7 +6433,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE tSqlExprDestroy(p1); tExprTreeDestroy(p, NULL); //TODO - + taosArrayDestroy(&colList); if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table"); @@ -6556,13 +6548,13 @@ static int32_t getQueryTimeRange(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr if (*pExpr == NULL) { return ret; } - + //multiple tables's query time range mixed together - + tExprNode* p = NULL; void *filter = NULL; - SArray* colList = taosArrayInit(10, sizeof(SColIndex)); + SArray* colList = taosArrayInit(10, sizeof(SColIndex)); ret = exprTreeFromSqlExpr(pCmd, &p, *pExpr, pQueryInfo, colList, NULL); taosArrayDestroy(&colList); @@ -6819,7 +6811,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo if ((!isTimeWindowQuery(pQueryInfo)) && (!pointInterp)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } - + if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && (!pointInterp)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } @@ -6835,9 +6827,9 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - + size_t numOfFields = tscNumOfFields(pQueryInfo); - + if (pQueryInfo->fillVal == NULL) { pQueryInfo->fillVal = calloc(numOfFields, sizeof(int64_t)); pQueryInfo->numOfFillVal = (int32_t)numOfFields; @@ -6898,7 +6890,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } } - + if ((num < numOfFields) || ((num - 1 < numOfFields) && pointInterp)) { tVariantListItem* lastItem = taosArrayGetLast(pFillToken); @@ -6934,13 +6926,13 @@ int32_t validateRangeNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlN const char *msg0 = "invalid usage of range clause"; const char* msg1 = "invalid timestamp in range"; SSqlCmd* pCmd = &pSql->cmd; - + bool interpQuery = tscIsPointInterpQuery(pQueryInfo); if ((!interpQuery) && (pSqlNode->pRange.start || pSqlNode->pRange.end)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } - + if (pSqlNode->pRange.start == NULL || pSqlNode->pRange.end == NULL) { pQueryInfo->range.skey = INT64_MIN; pQueryInfo->range.ekey = INT64_MIN; @@ -7018,8 +7010,8 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq setDefaultOrderInfo(pQueryInfo); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (pSqlNode->pSortOrder == NULL) { - return TSDB_CODE_SUCCESS; - } + return TSDB_CODE_SUCCESS; + } char* pMsgBuf = tscGetErrorMsgPayload(pCmd); SArray* pSortOrder = pSqlNode->pSortOrder; @@ -7590,12 +7582,12 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { len = varDataTLen(pUpdateMsg->data + schemaLen); if(len > pTagsSchema->bytes) return invalidOperationMsg(pMsg, msg14); } - + pUpdateMsg->tagValLen = htonl(len); // length may be changed after dump data - + int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen; pUpdateMsg->head.contLen = htonl(total); - + } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) { SArray* pFieldList = pAlterSQL->pAddColumns; if (taosArrayGetSize(pFieldList) > 1) { @@ -7608,7 +7600,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (ret != TSDB_CODE_SUCCESS) { return ret; } - + tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p); } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) { if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) { // @@ -7761,7 +7753,7 @@ int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { pQueryInfo->interval.intervalUnit != 'y') { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } - + size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { int32_t functId = tscExprGet(pQueryInfo, i)->base.functionId; @@ -7782,7 +7774,7 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu // multi-output set/ todo refactor size_t size = taosArrayGetSize(pQueryInfo->exprList); - + for (int32_t k = 0; k < size; ++k) { SExprInfo* pExpr = tscExprGet(pQueryInfo, k); @@ -7840,8 +7832,7 @@ typedef struct SDNodeDynConfOption { int32_t len; // name string length } SDNodeDynConfOption; - -int32_t validateEp(char* ep) { +int32_t validateEp(char* ep) { char buf[TSDB_EP_LEN + 1] = {0}; tstrncpy(buf, ep, TSDB_EP_LEN); @@ -8044,10 +8035,10 @@ int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlN pQueryInfo->limit = pSqlNode->limit; pQueryInfo->clauseLimit = pQueryInfo->limit.limit; pQueryInfo->slimit = pSqlNode->slimit; - + tscDebug("0x%"PRIx64" limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql->self, pQueryInfo->limit.limit, pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset); - + if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } @@ -8342,7 +8333,7 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); - + for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); @@ -8350,7 +8341,7 @@ static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { bool qualifiedCol = false; for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j); - + if (pExpr->base.colInfo.colId == pColIndex->colId) { qualifiedCol = true; doLimitOutputNormalColOfGroupby(pExpr); @@ -8390,7 +8381,7 @@ static bool tagColumnInGroupby(SGroupbyExpr* pGroupbyExpr, int16_t columnId, int static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) { bool hasTagPrj = false; bool hasColumnPrj = false; - + size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); @@ -8428,7 +8419,7 @@ static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) { static void updateTagPrjFunction(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); - + for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ) { @@ -8618,7 +8609,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo s = &pSchema[colIndex]; } } - + if (TSDB_COL_IS_TAG(pColIndex->flag)) { int32_t f = TSDB_FUNC_TAG; @@ -8626,7 +8617,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo f = TSDB_FUNC_TAGPRJ; } - int32_t pos = tscGetFirstInvisibleFieldPos(pQueryInfo); + int32_t pos = tscGetFirstInvisibleFieldPos(pQueryInfo); SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; SExprInfo* pExpr = tscExprInsert(pQueryInfo, pos, f, &index, s->type, s->bytes, getNewResColId(pCmd), s->bytes, true); @@ -8816,10 +8807,10 @@ int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) { int32_t numOfExprs = (int32_t)tscNumOfExprs(pQueryInfo); size_t upNum = taosArrayGetSize(pQueryInfo->pUpstream); - + for (int32_t i = 0; i < numOfExprs; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); - + int32_t f = pExpr->base.functionId; if (f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || @@ -8836,7 +8827,7 @@ int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) { return TSDB_CODE_SUCCESS; } } - + return invalidOperationMsg(msg, msg1); } else if (f == TSDB_FUNC_INTERP) { if (pQueryInfo->groupbyExpr.columnInfo) { @@ -8852,7 +8843,7 @@ int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) { if (pUp->groupbyExpr.columnInfo) { return invalidOperationMsg(msg, msg2); } - + if (pUp->order.order == TSDB_ORDER_DESC || (pUp->order.orderColId != INT32_MIN && pUp->order.orderColId != PRIMARYKEY_TIMESTAMP_COL_INDEX)) { return invalidOperationMsg(msg, msg3); } @@ -8873,7 +8864,7 @@ int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) { if (TSDB_QUERY_HAS_TYPE(pUp->type, TSDB_QUERY_TYPE_PROJECTION_QUERY)) { return invalidOperationMsg(msg, msg5); } - + for (int32_t n = 0; n < exprNum; ++n) { expr = taosArrayGetP(pUp->exprList, n); if (expr->functionId == TSDB_FUNC_TOP || @@ -8910,11 +8901,11 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (pExpr->Expr.operand.z == NULL) { //handle 'select 1' if (pExpr->exprToken.n == 1 && 0 == strncasecmp(pExpr->exprToken.z, "1", 1)) { - server_status = true; + server_status = true; } else { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); - } - } + } + } // TODO redefine the function SDNodeDynConfOption functionsInfo[5] = {{"database()", 10}, {"server_version()", 16}, @@ -8948,7 +8939,7 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq pQueryInfo->command = TSDB_SQL_CURRENT_USER;break; default: { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } - + SColumnIndex ind = {0}; SExprInfo* pExpr1 = tscExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT, tDataTypes[TSDB_DATA_TYPE_INT].bytes, getNewResColId(pCmd), tDataTypes[TSDB_DATA_TYPE_INT].bytes, false); @@ -8956,7 +8947,7 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq tSqlExprItem* item = taosArrayGet(pExprList, 0); const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[index].name; tstrncpy(pExpr1->base.aliasName, name, tListLen(pExpr1->base.aliasName)); - + return TSDB_CODE_SUCCESS; } @@ -9117,7 +9108,7 @@ int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* p // if sql specifies db, use it, otherwise use default db SStrToken* pzTableName = &(pCreateTable->name); - + bool dbIncluded = false; if (tscValidateName(pzTableName, true, &dbIncluded) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -9395,7 +9386,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { kvRowCpy(pTag->data, row); free(row); - + bool dbIncluded2 = false; char tmp[TSDB_TABLE_FNAME_LEN] = {0}; SStrToken tbName = taosTokenDup(&pCreateTableInfo->name, tmp, tListLen(tmp)); @@ -9447,7 +9438,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { if (tscValidateName(pName, true, &dbIncluded1) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), STR_INVALID_TABLE_NAME); } - + // check to valid and create to name if(pInfo->pCreateTableInfo->to.n > 0) { bool dbInclude = false; @@ -9922,12 +9913,12 @@ static int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList if (t->type == TK_INTEGER || t->type == TK_FLOAT) { return invalidOperationMsg(msgBuf, STR_INVALID_TABLE_NAME); } - + bool dbIncluded = false; char buf[TSDB_TABLE_FNAME_LEN]; SStrToken sTblToken; sTblToken.z = buf; - + if (validateTableName(t->z, t->n, &sTblToken, &dbIncluded) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(msgBuf, STR_INVALID_TABLE_NAME); } @@ -9956,7 +9947,7 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis if (p->from == NULL) { return TSDB_CODE_TSC_INVALID_OPERATION; } - + if (p->from->type == SQL_NODE_FROM_TABLELIST) { int32_t code = getTableNameFromSqlNode(p, tableNameList, msgBuf, pSql); if (code != TSDB_CODE_SUCCESS) { @@ -10054,7 +10045,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { tNameExtractFullName(pname, name); size_t len = strlen(name); - + if (NULL == taosHashGetCloneExt(UTIL_GET_TABLEMETA(pSql), name, len, NULL, (void **)&pTableMeta, &tableMetaCapacity)) { // not found tfree(pTableMeta); @@ -10067,7 +10058,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { void* pVgroupIdList = NULL; if (pTableMeta->tableType == TSDB_CHILD_TABLE) { code = tscCreateTableMetaFromSTableMeta(pSql, (STableMeta **)(&pTableMeta), name, &tableMetaCapacity, (STableMeta **)(&pSTMeta)); - pSql->pBuf = (void *)pSTMeta; + pSql->pBuf = (void*)pSTMeta; // create the child table meta from super table failed, try load it from mnode if (code != TSDB_CODE_SUCCESS) { @@ -10148,7 +10139,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { } else if (taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) { int32_t usize = (int32_t)taosArrayGetSize(pQueryInfo->pUdfInfo); int32_t exist = 0; - + for (int32_t j = 0; j < usize; ++j) { SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, j); int32_t len = (int32_t)strlen(pUdfInfo->name); @@ -10168,7 +10159,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (taosArrayGetSize(pQueryInfo->pUdfInfo) > 1) { code = tscInvalidOperationMsg(pCmd->payload, "only one udf allowed", NULL); goto _end; - } + } } } } @@ -10826,9 +10817,9 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS *pExpr = calloc(1, sizeof(tExprNode)); (*pExpr)->nodeType = TSQL_NODE_TYPE; (*pExpr)->pType = calloc(1, sizeof(TAOS_FIELD)); - - *(*pExpr)->pType = pSqlExpr->dataType; - + + *(*pExpr)->pType = pSqlExpr->dataType; + return TSDB_CODE_SUCCESS; } else if (pSqlExpr->tokenId == TK_SET) { int32_t colType = -1; diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 11b51f97bd..8bbcf9b057 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -1418,7 +1418,7 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue }; SUdfInfo* pUdfInfo = NULL; - + size_t size = tscNumOfExprs(px); for (int32_t j = 0; j < size; ++j) { SExprInfo* pExprInfo = tscExprGet(px, j); @@ -1429,7 +1429,7 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue pSql->res.code = tscInvalidOperationMsg(pSql->cmd.payload, "only one udf allowed", NULL); return; } - + pUdfInfo = taosArrayGet(px->pUdfInfo, -1 * functionId - 1); int32_t code = initUdfInfo(pUdfInfo); if (code != TSDB_CODE_SUCCESS) { @@ -1537,7 +1537,7 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue px->pQInfo->runtimeEnv.udfIsCopy = true; px->pQInfo->runtimeEnv.pUdfInfo = pUdfInfo; - + tfree(schema); // set the pRuntimeEnv for pSourceOperator @@ -2702,11 +2702,9 @@ int32_t tscExprTopBottomIndex(SQueryInfo* pQueryInfo){ SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr == NULL) continue; - if (pExpr->base.functionId == TSDB_FUNC_TOP - || pExpr->base.functionId == TSDB_FUNC_BOTTOM - || pExpr->base.functionId == TSDB_FUNC_SAMPLE - || pExpr->base.functionId == TSDB_FUNC_UNIQUE - || pExpr->base.functionId == TSDB_FUNC_TAIL) { + if (pExpr->base.functionId == TSDB_FUNC_TOP || pExpr->base.functionId == TSDB_FUNC_BOTTOM || + pExpr->base.functionId == TSDB_FUNC_SAMPLE || pExpr->base.functionId == TSDB_FUNC_UNIQUE || + pExpr->base.functionId == TSDB_FUNC_TAIL) { return i; } } @@ -3068,6 +3066,12 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded) } } + if (escapeEnabled && pToken->type == TK_ID) { + if (pToken->z[0] == TS_BACKQUOTE_CHAR) { + pToken->n = stringProcess(pToken->z, pToken->n); + firstPartQuote = true; + } + } int32_t firstPartLen = pToken->n; pToken->z = sep + 1; @@ -4191,20 +4195,20 @@ static void tscSubqueryCompleteCallback(void* param, TAOS_RES* tres, int code) { } int32_t doInitSubState(SSqlObj* pSql, int32_t numOfSubqueries) { - //bug fix. Above doInitSubState level, the loop invocation with the same SSqlObj will be fail. - //assert(pSql->subState.numOfSub == 0 && pSql->pSubs == NULL && pSql->subState.states == NULL); + // bug fix. Above doInitSubState level, the loop invocation with the same SSqlObj will be fail. + // assert(pSql->subState.numOfSub == 0 && pSql->pSubs == NULL && pSql->subState.states == NULL); if(pSql->pSubs) { free(pSql->pSubs); pSql->pSubs = NULL; } - + if(pSql->subState.states) { free(pSql->subState.states); pSql->subState.states = NULL; } - + pSql->subState.numOfSub = numOfSubqueries; - + pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES); pSql->subState.states = calloc(pSql->subState.numOfSub, sizeof(int8_t)); @@ -4230,7 +4234,7 @@ void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { (*pSql->fp)(pSql->param, pSql, 0); } return ; - } + } if (pSql->cmd.command == TSDB_SQL_SELECT) { tscAddIntoSqlList(pSql); diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index bc855ea2f7..9048734a2d 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -148,7 +148,7 @@ void shellInit(SShellArguments *_args) { exit(EXIT_SUCCESS); } #endif - + return; } @@ -335,7 +335,7 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { int64_t oresult = atomic_load_64(&result); - if (regex_match(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) { + if (regex_match(command, "^\\s*use\\s+([a-zA-Z0-9_]+|`.+`)\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) { fprintf(stdout, "Database changed.\n\n"); fflush(stdout); @@ -1520,7 +1520,7 @@ int wsclient_print_data(int rows, TAOS_FIELD *fields, int cols, int64_t id, int if (*pshowed_rows == DEFAULT_RES_SHOW_NUM) { free(recv_buffer); return 0; - } + } for (int c = 0; c < cols; c++) { pos = start; pos += i * fields[c].bytes; diff --git a/src/plugins/monitor/src/monMain.c b/src/plugins/monitor/src/monMain.c index dac264e418..2cd0139f5b 100644 --- a/src/plugins/monitor/src/monMain.c +++ b/src/plugins/monitor/src/monMain.c @@ -719,13 +719,14 @@ static int32_t monBuildMnodesTotalSql(char *sql) { static int32_t monGetVgroupsTotalStats(char *dbName, int32_t *totalVgroups, int32_t *totalVgroupsAlive) { - char subsql[TSDB_DB_NAME_LEN + 14]; + int bufLen = TSDB_DB_NAME_LEN + 16; + char subsql[bufLen]; memset(subsql, 0, sizeof(subsql)); - snprintf(subsql, TSDB_DB_NAME_LEN + 13, "show %s.vgroups", dbName); + snprintf(subsql, bufLen - 1, "show `%s`.vgroups", dbName); TAOS_RES *result = taos_query(tsMonitor.conn, subsql); int32_t code = taos_errno(result); if (code != TSDB_CODE_SUCCESS) { - monError("failed to execute cmd: show %s.vgroups, reason:%s", dbName, tstrerror(code)); + monError("failed to execute cmd: show `%s`.vgroups, reason:%s", dbName, tstrerror(code)); } TAOS_ROW row; @@ -1110,11 +1111,11 @@ static uint32_t monBuildVgroupsInfoSql(char *sql, char *dbName) { int64_t ts = taosGetTimestampUs(); memset(sql, 0, SQL_LENGTH + 1); - snprintf(sql, SQL_LENGTH, "show %s.vgroups", dbName); + snprintf(sql, SQL_LENGTH, "show `%s`.vgroups", dbName); TAOS_RES *result = taos_query(tsMonitor.conn, sql); int32_t code = taos_errno(result); if (code != TSDB_CODE_SUCCESS) { - monError("failed to execute cmd: show %s.vgroups, reason:%s", dbName, tstrerror(code)); + monError("failed to execute cmd: show `%s`.vgroups, reason:%s", dbName, tstrerror(code)); } TAOS_ROW row; -- GitLab From de7f86065985274845b346175f551e7ef19044f9 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Thu, 16 Jun 2022 10:46:20 +0800 Subject: [PATCH 024/380] Update index.mdx --- docs/en/07-develop/02-model/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/07-develop/02-model/index.mdx b/docs/en/07-develop/02-model/index.mdx index 86853aaaa3..e0378cc77c 100644 --- a/docs/en/07-develop/02-model/index.mdx +++ b/docs/en/07-develop/02-model/index.mdx @@ -37,7 +37,7 @@ USE power; ## Create STable -In a time-series application, there may be multiple kinds of data collection points. For example, in the electrical power system there are meters, transformers, bus bars, switches, etc. For easy and efficient aggregation of multiple tables, one STable needs to be created for each kind of data collection point. For example, for the meters in [table 1](/tdinternal/arch#model_table1), the SQL statement below can be used to create the super table. +In a time-series application, there may be multiple kinds of data collection points. For example, in the electrical power system there are meters, transformers, bus bars, switches, etc. For easy and efficient aggregation of multiple tables, one STable needs to be created for each kind of data collection point. For example, for the meters in [table 1](/concept/#model_table1), the SQL statement below can be used to create the super table. ```sql CREATE STable meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int); -- GitLab From 6d82e6a40b26a229b43b230f7d7328f5c9532e6c Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Thu, 16 Jun 2022 11:17:36 +0800 Subject: [PATCH 025/380] docs: correct TAOS CLI to TDengine CLI --- docs/en/05-get-started/index.md | 4 ++-- docs/en/07-develop/03-insert-data/01-sql-writing.mdx | 2 +- docs/zh/05-get-started/index.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/en/05-get-started/index.md b/docs/en/05-get-started/index.md index 56958ef3ec..9c5a853820 100644 --- a/docs/en/05-get-started/index.md +++ b/docs/en/05-get-started/index.md @@ -1,6 +1,6 @@ --- title: Get Started -description: 'Install TDengine from Docker image, apt-get or package, and run TAOS CLI and taosBenchmark to experience the features' +description: 'Install TDengine from Docker image, apt-get or package, and run TDengine CLI and taosBenchmark to experience the features' --- import Tabs from "@theme/Tabs"; @@ -120,7 +120,7 @@ select * from t; Query OK, 2 row(s) in set (0.003128s) ``` -Besides executing SQL commands, system administrators can check running status, add/drop user accounts and manage the running instances. TAOS CLI with client driver can be installed and run on either Linux or Windows machines. For more details on CLI, please [check here](../reference/taos-shell/). +Besides executing SQL commands, system administrators can check running status, add/drop user accounts and manage the running instances. TDengine CLI with client driver can be installed and run on either Linux or Windows machines. For more details on CLI, please [check here](../reference/taos-shell/). ## Experience the blazing fast speed diff --git a/docs/en/07-develop/03-insert-data/01-sql-writing.mdx b/docs/en/07-develop/03-insert-data/01-sql-writing.mdx index 397b1a14fd..d8c4453f40 100644 --- a/docs/en/07-develop/03-insert-data/01-sql-writing.mdx +++ b/docs/en/07-develop/03-insert-data/01-sql-writing.mdx @@ -22,7 +22,7 @@ import CStmt from "./_c_stmt.mdx"; ## Introduction -Application programs can execute `INSERT` statement through connectors to insert rows. The TAOS CLI can also be used to manually insert data. +Application programs can execute `INSERT` statement through connectors to insert rows. The TDengine CLI can also be used to manually insert data. ### Insert Single Row diff --git a/docs/zh/05-get-started/index.md b/docs/zh/05-get-started/index.md index 878d7f0202..818027174e 100644 --- a/docs/zh/05-get-started/index.md +++ b/docs/zh/05-get-started/index.md @@ -1,6 +1,6 @@ --- title: 立即开始 -description: '从 Docker,安装包或使用 apt-get 快速安装 TDengine, 通过命令行程序TAOS CLI和工具 taosdemo 快速体验 TDengine 功能' +description: '从 Docker,安装包或使用 apt-get 快速安装 TDengine, 通过命令行程序TDengine CLI和工具 taosdemo 快速体验 TDengine 功能' --- import Tabs from "@theme/Tabs"; @@ -122,7 +122,7 @@ select * from t; Query OK, 2 row(s) in set (0.003128s) ``` -除执行 SQL 语句外,系统管理员还可以从 TDengine CLI 进行检查系统运行状态、添加删除用户账号等操作。TAOS CLI 连同应用驱动也可以独立安装在 Linux 或 Windows 机器上运行,更多细节请参考 [这里](../reference/taos-shell/) +除执行 SQL 语句外,系统管理员还可以从 TDengine CLI 进行检查系统运行状态、添加删除用户账号等操作。TDengine CLI 连同应用驱动也可以独立安装在 Linux 或 Windows 机器上运行,更多细节请参考 [这里](../reference/taos-shell/) ## 使用 taosBenchmark 体验写入速度 -- GitLab From 280958a9b48fa4b9613c58a54b6a2e015978252e Mon Sep 17 00:00:00 2001 From: Yang Zhao Date: Thu, 16 Jun 2022 11:48:23 +0800 Subject: [PATCH 026/380] enh: taos shell support cloud service 2.6 (#13880) * enh: taos shell support cloud 2.6 * enh: taos shell support cloud (#13879) * enh: support url in commandline taos shell * fix: normal host logic * enh: add default -R if env var set * fix: refine taos shell cloud service * fix: improve user friendly * fix: add cloud tcp connection * fix: header file * fix: add other os --- src/kit/shell/inc/shell.h | 11 +++-- src/kit/shell/src/shellDarwin.c | 58 +++++++++++++----------- src/kit/shell/src/shellEngine.c | 76 +++++++++++++++++++++----------- src/kit/shell/src/shellLinux.c | 62 ++++++++++++++++---------- src/kit/shell/src/shellMain.c | 52 +++++++--------------- src/kit/shell/src/shellWindows.c | 48 +++++++++++--------- 6 files changed, 175 insertions(+), 132 deletions(-) diff --git a/src/kit/shell/inc/shell.h b/src/kit/shell/inc/shell.h index 1e2136a8ab..5c48728d72 100644 --- a/src/kit/shell/inc/shell.h +++ b/src/kit/shell/inc/shell.h @@ -48,13 +48,11 @@ typedef struct SShellArguments { char* database; char* timezone; bool restful; - char* token; #ifdef WINDOWS SOCKET socket; #else int socket; #endif - TAOS* con; bool is_raw_time; bool is_use_passwd; @@ -70,6 +68,11 @@ typedef struct SShellArguments { int pktNum; char* pktType; char* netTestRole; + char* cloudDsn; + bool cloud; + char* cloudHost; + char* cloudPort; + char* cloudToken; } SShellArguments; typedef enum WS_ACTION_TYPE_S { WS_CONN, WS_QUERY, WS_FETCH, WS_FETCH_BLOCK } WS_ACTION_TYPE; @@ -91,7 +94,6 @@ void shellCheck(TAOS* con, SShellArguments* args); void get_history_path(char* history); void shellCheck(TAOS* con, SShellArguments* args); void cleanup_handler(void* arg); -char *last_strstr(const char *haystack, const char *needle); void exitShell(); int shellDumpResult(TAOS_RES* con, char* fname, int* error_no, bool printMode); void shellGetGrantInfo(void* con); @@ -99,7 +101,8 @@ int isCommentLine(char* line); int wsclient_handshake(); int wsclient_conn(); void wsclient_query(char* command); -int tcpConnect(); +int tcpConnect(char* host, int port); +int parse_cloud_dsn(); /**************** Global variable declarations ****************/ extern char PROMPT_HEADER[]; diff --git a/src/kit/shell/src/shellDarwin.c b/src/kit/shell/src/shellDarwin.c index f5e5b87280..7803113a0f 100644 --- a/src/kit/shell/src/shellDarwin.c +++ b/src/kit/shell/src/shellDarwin.c @@ -62,8 +62,8 @@ void printHelp() { printf("%s%s%s\n", indent, indent, "Number of threads when using multi-thread to import data."); printf("%s%s\n", indent, "-R"); printf("%s%s%s\n", indent, indent, "Connect and interact with TDengine use restful."); - printf("%s%s\n", indent, "-t"); - printf("%s%s%s\n", indent, indent, "The token to use when connecting TDengine's cloud services."); + printf("%s%s\n", indent, "-E"); + printf("%s%s%s\n", indent, indent, "The DSN to use when connecting TDengine's cloud services."); exit(EXIT_SUCCESS); } @@ -76,20 +76,13 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { for (int i = 1; i < argc; i++) { // for host if (strcmp(argv[i], "-h") == 0) { - if (i < argc - 1) { - char* arg = argv[++i]; - char* tmp = strstr(arg, ":"); - if (tmp == NULL) { - arguments->host = arg; - } else if ((tmp + 1) != NULL) { - arguments->port = atoi(tmp + 1); - tmp[0] = '\0'; - arguments->host = arg; - } - } else { - fprintf(stderr, "option -h requires an argument\n"); - exit(EXIT_FAILURE); - } + if (i < argc - 1) { + arguments->cloud = false; + arguments->host = argv[++i]; + } else { + fprintf(stderr, "option -h requires an argument\n"); + exit(EXIT_FAILURE); + } } // for password else if ((strncmp(argv[i], "-p", 2) == 0) @@ -116,6 +109,7 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { // for management port else if (strcmp(argv[i], "-P") == 0) { if (i < argc - 1) { + arguments->cloud = false; arguments->port = atoi(argv[++i]); } else { fprintf(stderr, "option -P requires an argument\n"); @@ -132,6 +126,7 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { } } else if (strcmp(argv[i], "-c") == 0) { if (i < argc - 1) { + arguments->cloud = false; if (strlen(argv[++i]) >= TSDB_FILENAME_LEN) { fprintf(stderr, "config file path: %s overflow max len %d\n", argv[i], TSDB_FILENAME_LEN - 1); exit(EXIT_FAILURE); @@ -203,14 +198,15 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { } else if (strcmp(argv[i], "-R") == 0) { + arguments->cloud = false; arguments->restful = true; } - else if (strcmp(argv[i], "-t") == 0) { + else if (strcmp(argv[i], "-E") == 0) { if (i < argc - 1) { - arguments->token = argv[++i]; + arguments->cloudDsn = argv[++i]; } else { - fprintf(stderr, "options -t requires an argument\n"); + fprintf(stderr, "options -E requires an argument\n"); exit(EXIT_FAILURE); } } @@ -225,6 +221,16 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { exit(EXIT_FAILURE); } } + if (args.cloudDsn == NULL) { + if (args.cloud) { + args.cloudDsn = getenv("TDENGINE_CLOUD_DSN"); + if (args.cloudDsn == NULL) { + args.cloud = false; + } + } + } else { + args.cloud = true; + } } int32_t shellReadCommand(TAOS *con, char *command) { @@ -573,23 +579,25 @@ void exitShell() { exit(EXIT_SUCCESS); } -int tcpConnect() { +int tcpConnect(char* host, int port) { struct sockaddr_in serv_addr; - if (args.port == 0) { + if (port == 0) { + port = 6041; args.port = 6041; } - if (NULL == args.host) { + if (NULL == host) { + host = "localhost"; args.host = "localhost"; } - struct hostent *server = gethostbyname(args.host); + struct hostent *server = gethostbyname(host); if ((server == NULL) || (server->h_addr == NULL)) { - fprintf(stderr, "no such host: %s\n", args.host); + fprintf(stderr, "no such host: %s\n", host); return -1; } memset(&serv_addr, 0, sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(args.port); + serv_addr.sin_port = htons(port); memcpy(&(serv_addr.sin_addr.s_addr), server->h_addr, server->h_length); args.socket = socket(AF_INET, SOCK_STREAM, 0); if (args.socket < 0) { diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index b4c9aee4ea..2d5ce2cdcb 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -72,8 +72,7 @@ void shellInit(SShellArguments *_args) { _args->user = TSDB_DEFAULT_USER; } - if (_args->restful) { - _args->database = calloc(1, 128); + if (_args->restful || _args->cloud) { if (wsclient_handshake()) { exit(EXIT_FAILURE); } @@ -159,7 +158,7 @@ static int32_t shellRunSingleCommand(TAOS *con, char *command) { // Analyse the command. if (regex_match(command, "^[ \t]*(quit|q|exit)[ \t;]*$", REG_EXTENDED | REG_ICASE)) { - if (args.restful) { + if (args.restful || args.cloud) { close(args.socket); } else { taos_close(con); @@ -309,7 +308,7 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { printMode = true; // When output to a file, the switch does not work. } - if (args.restful) { + if (args.restful || args.cloud) { wsclient_query(command); return; } @@ -1153,18 +1152,39 @@ int taos_base64_encode(unsigned char *source, size_t sourcelen, char *target, si return 1; } -char *last_strstr(const char *haystack, const char *needle) { - if (*needle == '\0') - return (char *) haystack; - - char *res = NULL; - for (;;) { - char *p = strstr(haystack, needle); - if (p == NULL) break; - res = p; - haystack = p + 1; +int parse_cloud_dsn() { + if (args.cloudDsn == NULL) { + fprintf(stderr, "Cannot read cloud service info\n"); + return 1; + } else { + char *start = strstr(args.cloudDsn, "http://"); + if (start != NULL) { + args.cloudHost = start + strlen("http://"); + } else { + start = strstr(args.cloudDsn, "https://"); + if (start != NULL) { + args.cloudHost = start + strlen("https://"); + } else { + args.cloudHost = args.cloudDsn; + } + } + char *port = strstr(args.cloudHost, ":"); + if ((port == NULL) || (port + strlen(":")) == NULL) { + fprintf(stderr, "Invalid format in TDengine cloud dsn: %s\n", args.cloudDsn); + return 1; + } + char *token = strstr(port + strlen(":"), "?token="); + if ((token == NULL) || (token + strlen("?token=")) == NULL || + (strlen(token + strlen("?token=")) == 0)) { + fprintf(stderr, "Invalid format in TDengine cloud dsn: %s\n", args.cloudDsn); + return -1; + } + port[0] = '\0'; + args.cloudPort = port + strlen(":"); + token[0] = '\0'; + args.cloudToken = token + strlen("?token="); } - return res; + return 0; } int wsclient_handshake() { @@ -1180,12 +1200,12 @@ int wsclient_handshake() { key_nonce[i] = rand() & 0xff; } taos_base64_encode(key_nonce, 16, websocket_key, 256); - if (args.token) { - snprintf(request_header, 1024, - "GET /rest/ws?token=%s HTTP/1.1\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nHost: " - "%s:%d\r\nSec-WebSocket-Key: " - "%s\r\nSec-WebSocket-Version: 13\r\n\r\n", - args.token, args.host, args.port, websocket_key); + if (args.cloud) { + snprintf(request_header, 1024, + "GET /rest/ws?token=%s HTTP/1.1\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nHost: " + "%s:%s\r\nSec-WebSocket-Key: " + "%s\r\nSec-WebSocket-Version: 13\r\n\r\n", + args.cloudToken, args.cloudHost, args.cloudPort, websocket_key); } else { snprintf(request_header, 1024, "GET /rest/ws HTTP/1.1\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nHost: %s:%d\r\nSec-WebSocket-Key: " @@ -1286,9 +1306,9 @@ int wsclient_send_sql(char *command, WS_ACTION_TYPE type, int id) { switch (type) { case WS_CONN: cJSON_AddStringToObject(json, "action", "conn"); - cJSON_AddStringToObject(_args, "user", "root"); - cJSON_AddStringToObject(_args, "password", "taosdata"); - cJSON_AddStringToObject(_args, "db", ""); + cJSON_AddStringToObject(_args, "user", args.user); + cJSON_AddStringToObject(_args, "password", args.password); + cJSON_AddStringToObject(_args, "db", args.database); break; case WS_QUERY: @@ -1341,6 +1361,12 @@ int wsclient_conn() { } if (code->valueint == 0) { cJSON_Delete(root); + if (args.cloud) { + fprintf(stdout, "Successfully connect to %s:%s in restful mode\n\n", args.cloudHost, args.cloudPort); + } else { + fprintf(stdout, "Successfully connect to %s:%d in restful mode\n\n", args.host, args.port); + } + return 0; } else { cJSON *message = cJSON_GetObjectItem(root, "message"); @@ -1606,4 +1632,4 @@ void wsclient_query(char *command) { } cJSON_Delete(query); return; -} +} \ No newline at end of file diff --git a/src/kit/shell/src/shellLinux.c b/src/kit/shell/src/shellLinux.c index b9a8005ec7..aa67019628 100644 --- a/src/kit/shell/src/shellLinux.c +++ b/src/kit/shell/src/shellLinux.c @@ -54,7 +54,7 @@ static struct argp_option options[] = { {"pktnum", 'N', "PKTNUM", 0, "Packet numbers used for net test, default is 100."}, {"pkttype", 'S', "PKTTYPE", 0, "Choose packet type used for net test, default is TCP. Only speed test could be either TCP or UDP."}, {"restful", 'R', 0, 0, "Connect and interact with TDengine use restful."}, - {"token", 't', "TOKEN", 0, "The token to use when connecting TDengine's cloud services."}, + {0, 'E', "DSN", 0, "The DSN to use when connecting TDengine's cloud services."}, {0}}; static error_t parse_opt(int key, char *arg, struct argp_state *state) { @@ -64,21 +64,20 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { wordexp_t full_path; switch (key) { - case 'h':{ - char* tmp = strstr(arg, ":"); - if (tmp == NULL) { - arguments->host = arg; - } else if ((tmp + 1) != NULL) { - arguments->port = atoi(tmp + 1); - tmp[0] = '\0'; - arguments->host = arg; - } - break; - } + case 'h': + if (arg) { + args.cloud = false; + args.host = arg; + } else { + fprintf(stderr, "Invalid host\n"); + return -1; + } + break; case 'p': break; case 'P': if (arg) { + args.cloud = false; tsDnodeShellPort = atoi(arg); p_port = atoi(arg); } else { @@ -106,6 +105,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { wordfree(&full_path); return -1; } + args.cloud = false; tstrncpy(configDir, full_path.we_wordv[0], TSDB_FILENAME_LEN); wordfree(&full_path); break; @@ -173,11 +173,17 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { case OPT_ABORT: arguments->abort = 1; break; - case 't': - arguments->token = arg; - break; case 'R': arguments->restful = true; + arguments->cloud = false; + break; + case 'E': + if (arg) { + arguments->cloudDsn = arg; + } else { + fprintf(stderr, "Invalid -E option\n"); + return -1; + } break; default: return ARGP_ERR_UNKNOWN; @@ -231,8 +237,16 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { } argp_parse(&argp, argc, argv, 0, 0, arguments); - if (arguments->token == NULL) { - arguments->port = p_port; + + if (args.cloudDsn == NULL) { + if (args.cloud) { + args.cloudDsn = getenv("TDENGINE_CLOUD_DSN"); + if (args.cloudDsn == NULL) { + args.cloud = false; + } + } + } else { + args.cloud = true; } if (arguments->abort) { @@ -595,23 +609,25 @@ void exitShell() { exit(EXIT_SUCCESS); } -int tcpConnect() { +int tcpConnect(char* host, int port) { struct sockaddr_in serv_addr; - if (args.port == 0) { + if (port == 0) { + port = 6041; args.port = 6041; } - if (NULL == args.host) { + if (NULL == host) { + host = "localhost"; args.host = "localhost"; } - struct hostent *server = gethostbyname(args.host); + struct hostent *server = gethostbyname(host); if ((server == NULL) || (server->h_addr == NULL)) { - fprintf(stderr, "no such host: %s\n", args.host); + fprintf(stderr, "no such host: %s\n", host); return -1; } memset(&serv_addr, 0, sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(args.port); + serv_addr.sin_port = htons(port); memcpy(&(serv_addr.sin_addr.s_addr), server->h_addr, server->h_length); args.socket = socket(AF_INET, SOCK_STREAM, 0); if (args.socket < 0) { diff --git a/src/kit/shell/src/shellMain.c b/src/kit/shell/src/shellMain.c index ecd6e22b72..149afc503e 100644 --- a/src/kit/shell/src/shellMain.c +++ b/src/kit/shell/src/shellMain.c @@ -76,7 +76,6 @@ SShellArguments args = {.host = NULL, .database = NULL, .timezone = NULL, .restful = false, - .token = NULL, .is_raw_time = false, .is_use_passwd = false, .dump_config = false, @@ -87,7 +86,12 @@ SShellArguments args = {.host = NULL, .pktLen = 1000, .pktNum = 100, .pktType = "TCP", - .netTestRole = NULL}; + .netTestRole = NULL, + .cloud = true, + .cloudHost = NULL, + .cloudPort = NULL, + .cloudToken = NULL, + }; /* * Main function. @@ -102,35 +106,6 @@ int main(int argc, char* argv[]) { exit(EXIT_FAILURE); } - char* cloud_url = getenv("TDENGINE_CLOUD_URL"); - if (cloud_url != NULL) { - char* start = strstr(cloud_url, "http://"); - if (start != NULL) { - cloud_url = start + strlen("http://"); - } else { - start = strstr(cloud_url, "https://"); - if (start != NULL) { - cloud_url = start + strlen("https://"); - } - } - - char* tmp = last_strstr(cloud_url, ":"); - if ((tmp == NULL) && ((tmp + 1) != NULL )) { - fprintf(stderr, "Invalid format in environment variable TDENGINE_CLOUD_URL: %s\n", cloud_url); - exit(EXIT_FAILURE); - } else { - args.port = atoi(tmp + 1); - tmp[0] = '\0'; - args.host = cloud_url; - } - } - - char* cloud_token = getenv("TDENGINE_CLOUD_TOKEN"); - - if (cloud_token != NULL) { - args.token = cloud_token; - } - shellParseArgument(argc, argv, &args); if (args.dump_config) { @@ -155,10 +130,17 @@ int main(int argc, char* argv[]) { exit(0); } - if (args.restful) { - if (tcpConnect()) { - exit(EXIT_FAILURE); - } + if (args.cloud) { + if (parse_cloud_dsn()) { + exit(EXIT_FAILURE); + } + if (tcpConnect(args.cloudHost, atoi(args.cloudPort))) { + exit(EXIT_FAILURE); + } + } else if (args.restful) { + if (tcpConnect(args.host, args.port)) { + exit(EXIT_FAILURE); + } } /* Initialize the shell */ diff --git a/src/kit/shell/src/shellWindows.c b/src/kit/shell/src/shellWindows.c index a3aa7a6fe4..f7a2e47bc8 100644 --- a/src/kit/shell/src/shellWindows.c +++ b/src/kit/shell/src/shellWindows.c @@ -64,8 +64,8 @@ void printHelp() { printf("%s%s%s\n", indent, indent, "Packet numbers used for net test, default is 100."); printf("%s%s\n", indent, "-R"); printf("%s%s%s\n", indent, indent, "Connect and interact with TDengine use restful."); - printf("%s%s\n", indent, "-t"); - printf("%s%s%s\n", indent, indent, "The token to use when connecting TDengine's cloud services."); + printf("%s%s\n", indent, "-E"); + printf("%s%s%s\n", indent, indent, "The DSN to use when connecting TDengine's cloud services."); printf("%s%s\n", indent, "-S"); printf("%s%s%s\n", indent, indent, "Packet type used for net test, default is TCP."); printf("%s%s\n", indent, "-V"); @@ -80,15 +80,8 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { // for host if (strcmp(argv[i], "-h") == 0) { if (i < argc - 1) { - char* arg = argv[++i]; - char* tmp = strstr(arg, ":"); - if (tmp == NULL) { - arguments->host = arg; - } else if ((tmp + 1) != NULL) { - arguments->port = atoi(tmp + 1); - tmp[0] = '\0'; - arguments->host = arg; - } + arguments->cloud = false; + arguments->host = argv[++i]; } else { fprintf(stderr, "option -h requires an argument\n"); exit(EXIT_FAILURE); @@ -119,6 +112,7 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { // for management port else if (strcmp(argv[i], "-P") == 0) { if (i < argc - 1) { + arguments->cloud = false; arguments->port = atoi(argv[++i]); } else { fprintf(stderr, "option -P requires an argument\n"); @@ -142,6 +136,7 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { } } else if (strcmp(argv[i], "-c") == 0) { if (i < argc - 1) { + arguments->cloud = false; char *tmp = argv[++i]; if (strlen(tmp) >= TSDB_FILENAME_LEN) { fprintf(stderr, "config file path: %s overflow max len %d\n", tmp, TSDB_FILENAME_LEN - 1); @@ -225,14 +220,15 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { } else if (strcmp(argv[i], "-R") == 0) { + arguments->cloud = false; arguments->restful = true; } - else if (strcmp(argv[i], "-t") == 0) { + else if (strcmp(argv[i], "-E") == 0) { if (i < argc - 1) { - arguments->token = argv[++i]; + arguments->cloudDsn = argv[++i]; } else { - fprintf(stderr, "options -t requires an argument\n"); + fprintf(stderr, "options -E requires an argument\n"); exit(EXIT_FAILURE); } } @@ -251,6 +247,16 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { exit(EXIT_FAILURE); } } + if (args.cloudDsn == NULL) { + if (args.cloud) { + args.cloudDsn = getenv("TDENGINE_CLOUD_DSN"); + if (args.cloudDsn == NULL) { + args.cloud = false; + } + } + } else { + args.cloud = true; + } } void shellPrintContinuePrompt() { printf("%s", CONTINUE_PROMPT); } @@ -363,21 +369,23 @@ void get_history_path(char *history) { void exitShell() { exit(EXIT_SUCCESS); } -int tcpConnect() { +int tcpConnect(char* host, int iport) { int iResult; WSADATA wsaData; struct addrinfo *aResult = NULL, *ptr = NULL, hints; - if (args.port == 0) { - args.port = 6041; + if (iport == 0) { + iport = 6041; + args.port = iport; } - if (NULL == args.host) { + if (NULL == host) { + host = "localhost"; args.host = "localhost"; } char port[10] = {0}; - sprintf_s(port, 10, "%d", args.port); + sprintf_s(port, 10, "%d", iport); iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { @@ -388,7 +396,7 @@ int tcpConnect() { hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - iResult = getaddrinfo(args.host, port, &hints, &aResult); + iResult = getaddrinfo(host, port, &hints, &aResult); if ( iResult != 0 ) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); -- GitLab From 16edfadde208c0a6a20a3232a8ffc76f0b0bf1b4 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 16 Jun 2022 12:48:20 +0800 Subject: [PATCH 027/380] chore: support build taosdump on rhel (#13885) [TS-1616] for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 99e283a40b..0a81480420 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 99e283a40b8671d82ebdb02b9b9a4ea6cd990553 +Subproject commit 0a81480420d6601bbdb57770ee64e40f24c4ea83 -- GitLab From 0ccf417e4f8a8742f963f7707965b5d329f342c3 Mon Sep 17 00:00:00 2001 From: xywang Date: Thu, 16 Jun 2022 15:35:54 +0800 Subject: [PATCH 028/380] fix: added upstream check to avoid crash --- src/client/src/tscUtil.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 11b51f97bd..15ae41f9b4 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -4236,7 +4236,8 @@ void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { tscAddIntoSqlList(pSql); } - if (taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // nest query. do execute it firstly + // upstream may be freed before retry + if (pQueryInfo->pUpstream && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // nest query. do execute it firstly code = doInitSubState(pSql, (int32_t) taosArrayGetSize(pQueryInfo->pUpstream)); if (code != TSDB_CODE_SUCCESS) { goto _error; -- GitLab From ec5135c959c01a5850017e714dac582f0e48b78b Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 16 Jun 2022 17:46:23 +0800 Subject: [PATCH 029/380] fix(query): optimization diff_function and remove assert --- src/query/src/qAggMain.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index fc36974c9b..8d9560f7ec 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -3645,7 +3645,6 @@ static void diff_function(SQLFunctionCtx *pCtx) { SDiffFuncInfo *pDiffInfo = GET_ROWCELL_INTERBUF(pResInfo); void *data = GET_INPUT_DATA_LIST(pCtx); - bool isFirstBlock = (pDiffInfo->valueAssigned == false); int32_t notNullElems = 0; @@ -3668,7 +3667,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pDiffInfo->valueAssigned) { int32_t diff = (int32_t)(pData[i] - pDiffInfo->i64Prev); if (diff >= 0 || !pDiffInfo->ignoreNegative) { - *pOutput = (int32_t)(pData[i] - pDiffInfo->i64Prev); // direct previous may be null + *pOutput = diff; *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; @@ -3694,7 +3693,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pDiffInfo->valueAssigned) { int64_t diff = pData[i] - pDiffInfo->i64Prev; if (diff >= 0 || !pDiffInfo->ignoreNegative) { - *pOutput = pData[i] - pDiffInfo->i64Prev; // direct previous may be null + *pOutput = diff; *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; @@ -3720,7 +3719,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pDiffInfo->valueAssigned) { double diff = pData[i] - pDiffInfo->d64Prev; if (diff >= 0 || !pDiffInfo->ignoreNegative) { - SET_DOUBLE_VAL(pOutput, pData[i] - pDiffInfo->d64Prev); // direct previous may be null + SET_DOUBLE_VAL(pOutput, diff); *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; @@ -3746,7 +3745,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pDiffInfo->valueAssigned) { float diff = (float)(pData[i] - pDiffInfo->d64Prev); if (diff >= 0 || !pDiffInfo->ignoreNegative) { - *pOutput = (float)(pData[i] - pDiffInfo->d64Prev); + *pOutput = diff; *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; @@ -3772,7 +3771,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pDiffInfo->valueAssigned) { int16_t diff = (int16_t)(pData[i] - pDiffInfo->i64Prev); if (diff >= 0 || !pDiffInfo->ignoreNegative) { - *pOutput = (int16_t)(pData[i] - pDiffInfo->i64Prev); + *pOutput = diff; *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; @@ -3798,7 +3797,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pDiffInfo->valueAssigned) { int8_t diff = (int8_t)(pData[i] - pDiffInfo->i64Prev); if (diff >= 0 || !pDiffInfo->ignoreNegative) { - *pOutput = (int8_t)(pData[i] - pDiffInfo->i64Prev); + *pOutput = diff; *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; @@ -3816,23 +3815,15 @@ static void diff_function(SQLFunctionCtx *pCtx) { qError("error input type"); } - // initial value is not set yet - if (!pDiffInfo->valueAssigned || notNullElems <= 0) { - /* - * 1. current block and blocks before are full of null - * 2. current block may be null value - */ - assert(pCtx->hasNull); - } else { + if (notNullElems > 0) { for (int t = 0; t < pCtx->tagInfo.numOfTagCols; ++t) { SQLFunctionCtx* tagCtx = pCtx->tagInfo.pTagCtxList[t]; if (tagCtx->functionId == TSDB_FUNC_TAG_DUMMY) { aAggs[TSDB_FUNC_TAGPRJ].xFunction(tagCtx); } } - int32_t forwardStep = (isFirstBlock) ? notNullElems : notNullElems; - GET_RES_INFO(pCtx)->numOfRes += forwardStep; + GET_RES_INFO(pCtx)->numOfRes += notNullElems; } } -- GitLab From 23d478269726a87c6f3b91fec146308187ada942 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Thu, 16 Jun 2022 19:50:02 +0800 Subject: [PATCH 030/380] test: add test case for TS-1619 --- tests/pytest/query/queryGroupbySort.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/pytest/query/queryGroupbySort.py b/tests/pytest/query/queryGroupbySort.py index 6439fc6560..c5ca1efacd 100644 --- a/tests/pytest/query/queryGroupbySort.py +++ b/tests/pytest/query/queryGroupbySort.py @@ -88,6 +88,23 @@ class TDTestCase: tdSql.query("select count(*) from tb group by c1") tdSql.checkRows(0) + # TS-1619 + tdSql.execute("create database test") + tdSql.execute("use test") + tdSql.execute("create table stb(ts timestamp, c1 int, c2 nchar(30)) tags(t1 int)") + for i in range(3): + tdSql.execute("create table t%d using stb tags(%d)" % (i, i)) + sql = "insert into t%d values " % i + for j in range(16): + if j % 4 == 0: + s = '00' + else: + s = str (j % 4 * 15) + sql += "(%d, %d, '2022-06-01 0%d:%s')" % (self.ts + j, i, int( j / 4 ), s) + tdSql.execute(sql) + + tdSql.query("select c2, sum(c1) from stb group by c2") + tdSql.checkRows(16) def stop(self): tdSql.close() -- GitLab From 7057b5961511c4a4d64dcbb2c0dcc5f2fa2d5c12 Mon Sep 17 00:00:00 2001 From: dingbo Date: Fri, 17 Jun 2022 09:32:32 +0800 Subject: [PATCH 031/380] docs: reference rust --- docs/en/14-reference/03-connector/rust.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/14-reference/03-connector/rust.mdx b/docs/en/14-reference/03-connector/rust.mdx index a5cbaeac80..56ca586c7e 100644 --- a/docs/en/14-reference/03-connector/rust.mdx +++ b/docs/en/14-reference/03-connector/rust.mdx @@ -250,7 +250,7 @@ The [Taos] structure is the connection manager in [libtaos] and provides two mai Column information is stored using [ColumnMeta]. - ``rust + ```rust let cols = &q.column_meta; for col in cols { println!("name: {}, type: {:?} , bytes: {}", col.name, col.type_, col.bytes); -- GitLab From 65b0ae28208dc1f542d30ef10be5c4752bcb6c91 Mon Sep 17 00:00:00 2001 From: XingY Wang Date: Fri, 17 Jun 2022 16:00:43 +0800 Subject: [PATCH 032/380] fix: fixed connection error if -h was used (#13926) * test: add test case for TS-1613 * fix: fixed connection error if -h was used * fix: assign port if -P is specified * fix: windows read env Co-authored-by: Ping Xiao Co-authored-by: xywang Co-authored-by: Yang Zhao --- src/kit/shell/src/shellLinux.c | 19 +++++++++---------- src/kit/shell/src/shellWindows.c | 6 ++++++ tests/pytest/client/client.py | 9 +++++++++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/kit/shell/src/shellLinux.c b/src/kit/shell/src/shellLinux.c index aa67019628..863da2e1a7 100644 --- a/src/kit/shell/src/shellLinux.c +++ b/src/kit/shell/src/shellLinux.c @@ -24,7 +24,6 @@ #define OPT_ABORT 1 /* �Cabort */ int indicator = 1; -int p_port = 6041; struct termios oldtio; extern int wcwidth(wchar_t c); @@ -79,7 +78,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { if (arg) { args.cloud = false; tsDnodeShellPort = atoi(arg); - p_port = atoi(arg); + args.port = atoi(arg); } else { fprintf(stderr, "Invalid port\n"); return -1; @@ -239,16 +238,16 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { argp_parse(&argp, argc, argv, 0, 0, arguments); if (args.cloudDsn == NULL) { - if (args.cloud) { - args.cloudDsn = getenv("TDENGINE_CLOUD_DSN"); - if (args.cloudDsn == NULL) { - args.cloud = false; - } - } + if (args.cloud) { + args.cloudDsn = getenv("TDENGINE_CLOUD_DSN"); + if (args.cloudDsn == NULL) { + args.cloud = false; + } + } } else { - args.cloud = true; + args.cloud = true; } - + if (arguments->abort) { #ifndef _ALPINE error(10, 0, "ABORTED"); diff --git a/src/kit/shell/src/shellWindows.c b/src/kit/shell/src/shellWindows.c index f7a2e47bc8..9aab9f49cd 100644 --- a/src/kit/shell/src/shellWindows.c +++ b/src/kit/shell/src/shellWindows.c @@ -250,6 +250,12 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { if (args.cloudDsn == NULL) { if (args.cloud) { args.cloudDsn = getenv("TDENGINE_CLOUD_DSN"); + if (args.cloudDsn[strlen(args.cloudDsn) - 1] == '\"') { + args.cloudDsn[strlen(args.cloudDsn) - 1] = '\0'; + } + if (args.cloudDsn[0] == '\"') { + args.cloudDsn += 1; + } if (args.cloudDsn == NULL) { args.cloud = false; } diff --git a/tests/pytest/client/client.py b/tests/pytest/client/client.py index 9a155a4df9..9192f7e6d3 100644 --- a/tests/pytest/client/client.py +++ b/tests/pytest/client/client.py @@ -15,6 +15,7 @@ import sys from util.log import * from util.cases import * from util.sql import * +import os from datetime import timedelta @@ -73,6 +74,14 @@ class TDTestCase: tdSql.checkRows(1) tdSql.checkData(0, 0, 2) tdSql.checkData(0, 1, "master") + + cmd = "taos -h 127.0.0.1 -s 'show databases'" + r = os.popen(cmd) + text = r.read() + r.close + + if 'Unable to establish connection' in text: + tdLog.exit("%s failed: command 'taos -h 127.0.0.1' Unable to establish connection" % __file__) def stop(self): tdSql.close() -- GitLab From 74e801a44c47843fd0cbe694d52bf65869572b06 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Fri, 17 Jun 2022 16:42:25 +0800 Subject: [PATCH 033/380] fix: Case sensitive comparison of field names (#TS-1609) --- src/client/src/tscSQLParser.c | 2 +- src/mnode/src/mnodeTable.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 2745857e25..3d05433ae7 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1857,7 +1857,7 @@ int32_t validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { // field name must be unique for (int32_t i = 0; i < numOfTags + numOfCols; ++i) { - if (strncasecmp(pColField->name, pSchema[i].name, sizeof(pColField->name) - 1) == 0) { + if (strncmp(pColField->name, pSchema[i].name, sizeof(pColField->name) - 1) == 0) { //return tscErrorMsgWithCode(TSDB_CODE_TSC_DUP_COL_NAMES, tscGetErrorMsgPayload(pCmd), pColField->name, NULL); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "duplicated column names"); } diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c index 9a4ed705f8..1188dc8843 100644 --- a/src/mnode/src/mnodeTable.c +++ b/src/mnode/src/mnodeTable.c @@ -1047,7 +1047,7 @@ static int32_t mnodeCreateSuperTableCb(SMnodeMsg *pMsg, int32_t code) { if (code == TSDB_CODE_SUCCESS) { mLInfo("stable:%s, is created in sdb, uid:%" PRIu64, pTable->info.tableId, pTable->uid); if(pMsg->pBatchMasterMsg) - pMsg->pBatchMasterMsg->successed ++; + pMsg->pBatchMasterMsg->successed ++; } else { mError("msg:%p, app:%p stable:%s, failed to create in sdb, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, tstrerror(code)); @@ -1060,7 +1060,7 @@ static int32_t mnodeCreateSuperTableCb(SMnodeMsg *pMsg, int32_t code) { // if super table create by batch msg, check done and send finished to client if(pMsg->pBatchMasterMsg) { if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received >= pMsg->pBatchMasterMsg->expected) - dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code); + dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code); } return code; @@ -1235,7 +1235,7 @@ static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg) { static int32_t mnodeFindSuperTableTagIndex(SSTableObj *pStable, const char *tagName) { SSchema *schema = (SSchema *) pStable->schema; for (int32_t tag = 0; tag < pStable->numOfTags; tag++) { - if (strcasecmp(schema[pStable->numOfColumns + tag].name, tagName) == 0) { + if (strcmp(schema[pStable->numOfColumns + tag].name, tagName) == 0) { return tag; } } @@ -1388,7 +1388,7 @@ static int32_t mnodeModifySuperTableTagName(SMnodeMsg *pMsg, char *oldTagName, c static int32_t mnodeFindSuperTableColumnIndex(SSTableObj *pStable, char *colName) { SSchema *schema = (SSchema *) pStable->schema; for (int32_t col = 0; col < pStable->numOfColumns; col++) { - if (strcasecmp(schema[col].name, colName) == 0) { + if (strcmp(schema[col].name, colName) == 0) { return col; } } @@ -3558,7 +3558,7 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pTable->sql, pShow->bytes[cols]); + STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pTable->sql, pShow->bytes[cols]); cols++; numOfRows++; @@ -3593,13 +3593,13 @@ static int32_t mnodeCompactSuperTables() { }; //mInfo("compact super %" PRIu64, pTable->uid); - + sdbInsertCompactRow(&row); } mInfo("end to compact super table..."); - return 0; + return 0; } static int32_t mnodeCompactChildTables() { @@ -3619,13 +3619,13 @@ static int32_t mnodeCompactChildTables() { }; //mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid); - + sdbInsertCompactRow(&row); } mInfo("end to compact child table..."); - return 0; + return 0; } int32_t mnodeCompactTables() { -- GitLab From d52d14749c113f20e40e24b1f39ca3c5008b134b Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Fri, 17 Jun 2022 19:13:56 +0800 Subject: [PATCH 034/380] fix: Relax restriction on alias names (#TS-1502) --- src/client/src/tscSQLParser.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 3d05433ae7..866ecb3927 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -2270,10 +2270,6 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS hasDistinct = (pItem->distinct == true); distIdx = hasDistinct ? i : -1; } - if(pItem->aliasName != NULL && validateColumnName(pItem->aliasName) != TSDB_CODE_SUCCESS){ - return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11); - } - if(pItem->aliasName != NULL && strcasecmp(pItem->aliasName, DEFAULT_PRIMARY_TIMESTAMP_COL_NAME) == 0){ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11); } -- GitLab From 9e7eaaadbf03d61d019beebf28e01e409d81eb77 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Fri, 17 Jun 2022 20:03:15 +0800 Subject: [PATCH 035/380] test: add test cases for case sensitive --- tests/parallel_test/cases.task | 5 + tests/pytest/dbmgmt/dbNameCaseSensitive.py | 76 ++++++++ .../pytest/insert/schemalessCaseSensitive.py | 69 ++++++++ tests/pytest/table/columnNameCaseSensitive.py | 162 ++++++++++++++++++ tests/pytest/table/tagNameCaseSensitive.py | 60 +++++++ tests/pytest/table/tbNameCaseSensitive.py | 121 +++++++++++++ 6 files changed, 493 insertions(+) create mode 100644 tests/pytest/dbmgmt/dbNameCaseSensitive.py create mode 100644 tests/pytest/insert/schemalessCaseSensitive.py create mode 100644 tests/pytest/table/columnNameCaseSensitive.py create mode 100644 tests/pytest/table/tagNameCaseSensitive.py create mode 100644 tests/pytest/table/tbNameCaseSensitive.py diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index a5b683d4c8..578756d03e 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -807,6 +807,11 @@ 4,,pytest,python3 test.py -f insert/line_insert.py 3,,pytest,python3 test.py -f tag_lite/binary.py 3,,pytest,python3 test.py -f query/filterAllIntTypes.py +3,,pytest,python3 test.py -f dbmgmt/dbNameCaseSensitive.py +3,,pytest,python3 test.py -f insert/schemalessCaseSensitive.py +3,,pytest,python3 test.py -f table/columnNameCaseSensitive.py +3,,pytest,python3 test.py -f table/tagNameCaseSensitive.py +3,,pytest,python3 test.py -f table/tbNameCaseSensitive.py 3,,develop-test,python3 ./test.py -f 2-query/ts_hidden_column.py 3,,develop-test,python3 ./test.py -f 2-query/ts_shortcut.py 3,,develop-test,python3 ./test.py -f 2-query/nchar_funcs.py diff --git a/tests/pytest/dbmgmt/dbNameCaseSensitive.py b/tests/pytest/dbmgmt/dbNameCaseSensitive.py new file mode 100644 index 0000000000..92a815b144 --- /dev/null +++ b/tests/pytest/dbmgmt/dbNameCaseSensitive.py @@ -0,0 +1,76 @@ +################################################################### +# 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 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + self._conn = conn + + def run(self): + + # database name + tdSql.execute("create database db") + tdSql.query("show databases") + tdSql.checkRows(1) + + tdSql.error("create database Db") + tdSql.error("create database `db`") + tdSql.execute("create database `Db`") + tdSql.query("show databases") + tdSql.checkRows(2) + + tdSql.execute("alter database db cachelast 1") + tdSql.execute("alter database `Db` cachelast 1") + + tdSql.execute("use db") + tdSql.query("select database()") + tdSql.checkData(0, 0, 'db'); + tdSql.query("show db.vgroups") + tdSql.checkRows(0) + + tdSql.execute("use `Db`") + tdSql.query("select database()") + tdSql.checkData(0, 0, 'Db'); + tdSql.query("show `Db`.vgroups") + tdSql.checkRows(0) + tdSql.query("show create database `Db`") + tdSql.checkRows(1) + + + tdSql.execute("drop database db") + tdSql.execute("drop database `Db`") + + tdSql.query("show databases") + tdSql.checkRows(0) + + # corner cases + tdSql.execute("create database `电力系统`") + tdSql.query("show `电力系统`.vgroups") + tdSql.checkRows(0) + tdSql.query("show databases") + tdSql.checkRows(1) + tdSql.checkData(0, 0, "电力系统") + + 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 diff --git a/tests/pytest/insert/schemalessCaseSensitive.py b/tests/pytest/insert/schemalessCaseSensitive.py new file mode 100644 index 0000000000..c7db1bed1a --- /dev/null +++ b/tests/pytest/insert/schemalessCaseSensitive.py @@ -0,0 +1,69 @@ +################################################################### +# 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.types import TDSmlProtocolType, TDSmlTimestampType + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + self._conn = conn + + def run(self): + + # schemaless + tdSql.execute("create database line_insert precision 'ns' ") + tdSql.execute("use line_insert") + lines = [ + "St,deviceId=1i voltage=1,phase=\"Test\" 1626006833639000000", + "St,DeviceId=3i voltage=2,phase=\"Test\" 1626006833639000000", + "St,deviceId=2i,DeviceId=3 Voltage=2,Phase=\"Test2\" 1626006833639000000", + "St,deviceId=4i,DeviceId=3 voltage=1,phase=\"Test\",Voltage=2,Phase=\"Test1\" 1626006833639000000", + "tbl,deviceId=\"sensor0\" Hello=3i 1646053743694400029", + "tbl,deviceId=\"sensor0\" n=3i,N=4i 1646053743694400030", + "tbl,deviceId=\"sensor0\" g=3i 1646053743694400031", + "tbl,deviceId=\"sensor0\" G=3i 1646053743694400032", + "tbl,deviceId=\"sensor0\" nice=2i,Nice=3i 1646053743694400033", + "tbl,deviceId=\"sensor0\" hello=3i 1646053743694400034", + "超级表,deviceId=\"sensor0\" 电压=3i 1646053743694400035", + ] + + code = self._conn.schemaless_insert(lines, TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + tdSql.query("show stables") + tdSql.checkRows(3) + + tdSql.query("show tables") + tdSql.checkRows(6) + + tdSql.query("describe `St`") + tdSql.checkRows(7) + + tdSql.query("select * from `St`") + tdSql.checkRows(4) + + tdSql.query("select * from tbl") + tdSql.checkRows(6) + + tdSql.query("select * from `超级表`") + tdSql.checkRows(1) + + + 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 diff --git a/tests/pytest/table/columnNameCaseSensitive.py b/tests/pytest/table/columnNameCaseSensitive.py new file mode 100644 index 0000000000..036786ae70 --- /dev/null +++ b/tests/pytest/table/columnNameCaseSensitive.py @@ -0,0 +1,162 @@ +################################################################### +# 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 * + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + def run(self): + tdSql.prepare() + + # column + tdSql.execute("create table tb(ts timestamp, c1 int)") + tdSql.execute("create table `TB`(ts timestamp, c1 int)") + tdSql.error("alter table tb add column C1 int") + tdSql.execute("alter table tb add column `C1` int") + tdSql.error("alter table `TB` add column C1 int") + tdSql.execute("alter table `TB` add column `C1` int") + + tdSql.error("create table tb2(ts timestamp, c1 int, C1 int)") + tdSql.execute("create table tb2(ts timestamp, c1 int, `C1` int)") + tdSql.query("describe tb2") + tdSql.checkRows(3) + tdSql.checkData(0, 0, 'ts') + tdSql.checkData(1, 0, 'c1') + tdSql.checkData(2, 0, 'C1') + + tdSql.execute("insert into tb2(ts, c1) values(now, 1)") + tdSql.execute("insert into tb2(ts, `C1`) values(now, 1)") + tdSql.execute("insert into tb2(ts, c1, `C1`) values(now, 1, 2)") + tdSql.query("select * from tb2") + tdSql.checkRows(3) + + tdSql.query("select * from tb2 where c1 = 1") + tdSql.checkRows(2) + + tdSql.query("select * from tb2 where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select c1 `C1` from tb2 where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select c1 as `C1` from tb2 where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select `C1` a from tb2 where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select `C1` as a from tb2 where `C1` = 1") + tdSql.checkRows(1) + + tdSql.execute("alter table tb2 drop column c1") + tdSql.query("describe tb2") + tdSql.checkRows(2) + + tdSql.error("create table `TB2`(ts timestamp, c1 int, C1 int)") + tdSql.execute("create table `TB2`(ts timestamp, c1 int, `C1` int)") + tdSql.query("describe `TB2`") + tdSql.checkRows(3) + tdSql.checkData(0, 0, 'ts') + tdSql.checkData(1, 0, 'c1') + tdSql.checkData(2, 0, 'C1') + + tdSql.execute("insert into `TB2`(ts, c1) values(now, 1)") + tdSql.execute("insert into `TB2`(ts, `C1`) values(now, 1)") + tdSql.execute("insert into `TB2`(ts, c1, `C1`) values(now, 1, 2)") + tdSql.query("select * from `TB2`") + tdSql.checkRows(3) + + tdSql.query("select * from `TB2` where c1 = 1") + tdSql.checkRows(2) + + tdSql.query("select * from `TB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select c1 `C1` from `TB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select c1 as `C1` from `TB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select `C1` a from `TB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select `C1` as a from `TB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.execute("alter table `TB2` drop column `C1`") + tdSql.query("describe tb2") + tdSql.checkRows(2) + + tdSql.error("create table `STB2`(ts timestamp, c1 int, C1 int) tags (t1 int)") + tdSql.execute("create table `STB2`(ts timestamp, c1 int, `C1` int) tags (t1 int)") + tdSql.query("describe `STB2`") + tdSql.checkRows(4) + tdSql.checkData(0, 0, 'ts') + tdSql.checkData(1, 0, 'c1') + tdSql.checkData(2, 0, 'C1') + tdSql.checkData(3, 0, 't1') + + tdSql.execute("insert into tt2(ts, c1) using `STB2` tags(1) values(now, 1)") + tdSql.execute("insert into tt2(ts, `C1`) using `STB2` tags(1) values(now, 1)") + tdSql.execute("insert into tt2(ts, c1, `C1`) using `STB2` tags(1) values(now, 1, 2)") + tdSql.query("select * from `STB2`") + tdSql.checkRows(3) + + tdSql.query("select * from `STB2` where c1 = 1") + tdSql.checkRows(2) + + tdSql.query("select * from `STB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select c1 `C1` from `STB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select c1 as `C1` from `STB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select `C1` a from `STB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.query("select `C1` as a from `STB2` where `C1` = 1") + tdSql.checkRows(1) + + tdSql.execute("alter table `STB2` drop column `C1`") + tdSql.query("describe tb2") + tdSql.checkRows(2) + + # cornor cases + tdSql.execute("alter table `STB2` add column `数量` int") + tdSql.execute("insert into tt3(ts, `数量`) using `STB2` tags(2) values(now, 1)") + tdSql.query("select * from tt3") + tdSql.checkRows(1) + tdSql.query("select ts `TS` from tt3") + tdSql.checkRows(1) + tdSql.query("select ts as `TS` from tt3") + tdSql.checkRows(1) + tdSql.query("select ts as `时间戳` from tt3") + tdSql.checkRows(1) + tdSql.query("select ts `时间戳` from tt3") + tdSql.checkRows(1) + + 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 diff --git a/tests/pytest/table/tagNameCaseSensitive.py b/tests/pytest/table/tagNameCaseSensitive.py new file mode 100644 index 0000000000..d448d702ca --- /dev/null +++ b/tests/pytest/table/tagNameCaseSensitive.py @@ -0,0 +1,60 @@ +################################################################### +# 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 * + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + self._conn = conn + + def run(self): + tdSql.prepare() + + # tag + tdSql.error("create table `STB3`(ts timesatmp, c1 int) tags(t1 int, T1 int)") + tdSql.execute("create table `STB3`(ts timestamp, c1 int) tags(t1 int)") + tdSql.execute("alter table `STB3` add tag `T1` int") + tdSql.execute("create table `STB4`(ts timestamp, c1 int) tags(t1 int, `T1` int)") + tdSql.execute("create table tt3 using `STB3`(t1) tags(1)") + tdSql.execute("create table tt4 using `STB3`(`T1`) tags(1)") + tdSql.query("select t1, `T1` from `STB3`") + tdSql.checkRows(2) + + tdSql.execute("alter table `STB3` drop tag `T1`") + tdSql.query("describe `STB3`") + tdSql.checkRows(3) + + # cornor case + tdSql.execute("create table `STB5`(ts timestamp, c1 int) tags(t1 int, `标签` int)") + tdSql.execute("insert into `测试` using `STB5` tags(1, 1) values(now, 1)") + tdSql.query("select * from `测试`") + tdSql.checkRows(1) + + tdSql.query("select `标签` t from `测试`") + tdSql.checkRows(1) + + tdSql.execute("alter table `STB5` add tag `标签2` double") + tdSql.query("describe `STB5`") + tdSql.checkRows(5) + + 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 diff --git a/tests/pytest/table/tbNameCaseSensitive.py b/tests/pytest/table/tbNameCaseSensitive.py new file mode 100644 index 0000000000..70d7ee3095 --- /dev/null +++ b/tests/pytest/table/tbNameCaseSensitive.py @@ -0,0 +1,121 @@ +################################################################### +# 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 * + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + def run(self): + + # table/stable + tdSql.execute("create database test") + tdSql.execute("create database `Test`") + tdSql.execute("use test") + tdSql.execute("create table tb(ts timestamp, c1 int)") + + tdSql.query("show tables") + tdSql.checkRows(1) + tdSql.query("show create table tb") + tdSql.checkRows(1) + + tdSql.error("create table Tb(ts timestamp, c1 int)") + tdSql.execute("create table `TB`(ts timestamp, c1 int)") + + tdSql.query("show tables") + tdSql.checkRows(2) + tdSql.query("show create table `TB`") + tdSql.checkRows(1) + + tdSql.query("describe tb") + tdSql.checkRows(2) + + tdSql.query("describe `TB`") + tdSql.checkRows(2) + + tdSql.execute("insert into tb values(now, 1)") + tdSql.error("select * from `Test`.tb") + tdSql.query("select * from test.tb") + tdSql.checkRows(1) + + tdSql.execute("insert into `TB` values(now, 1)") + tdSql.error("select * from `Test`.`TB`") + tdSql.query("select * from test.`TB`") + tdSql.checkRows(1) + + tdSql.execute("create stable stb(ts timestamp, c1 int) tags(t1 int)") + tdSql.query("show stables") + tdSql.checkRows(1) + + tdSql.error("create stable STb(ts timestamp, c1 int) tags(t1 int)") + tdSql.error("create stable `stb`(ts timestamp, c1 int) tags(t1 int)") + tdSql.execute("create stable `STB`(ts timestamp, c1 int) tags(t1 int)") + tdSql.query("show stables") + tdSql.checkRows(2) + + tdSql.query("describe stb") + tdSql.checkRows(3) + + tdSql.query("describe `STB`") + tdSql.checkRows(3) + + tdSql.execute("insert into t1 using stb tags(1) values(now, 1)") + tdSql.query("select * from stb") + tdSql.checkRows(1) + + tdSql.execute("insert into t2 using `STB` tags(1) values(now, 1)") + tdSql.query("select * from `STB`") + tdSql.checkRows(1) + + tdSql.execute("insert into `T2` using `STB` tags(1) values(now, 1)") + tdSql.query("select * from `STB`") + tdSql.checkRows(2) + + tdSql.query("select tbname from `STB`") + tdSql.checkRows(2) + + tdSql.execute("alter table stb add column c2 int") + tdSql.execute("alter table stb add tag t2 int") + tdSql.execute("alter table `STB` add column c2 int") + tdSql.execute("alter table `STB` add tag t2 int") + tdSql.execute("alter table `TB` add column c2 int") + + # corner cases + tdSql.execute("create table `超级表`(ts timestamp, c1 int) tags(t1 int)") + tdSql.execute("create table `子表一` using `超级表` tags(1)") + tdSql.execute("insert into `子表二` using `超级表` tags(1) values(now, 1)") + + tdSql.query("select * from `超级表`") + tdSql.checkRows(1) + tdSql.query("select * from `子表二`") + tdSql.checkRows(1) + tdSql.query("show tables") + tdSql.checkRows(7) + + tdSql.execute("create table `普通表` (ts timestamp, c1 int)") + tdSql.execute("insert into `普通表` values(now, 2)") + tdSql.query("select * from `普通表`") + tdSql.checkRows(1) + tdSql.query("show tables") + tdSql.checkRows(8) + + 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 -- GitLab From c10ca6ae9d00153b9772abfd8e49c1ffcc17f5f5 Mon Sep 17 00:00:00 2001 From: Linhe Huo Date: Fri, 17 Jun 2022 21:06:57 +0800 Subject: [PATCH 036/380] docs(Grafana): update to simplify Grafana installtion (#13953) Ref: [TD-16627](https://jira.taosdata.com:18080/browse/TD-16627) --- docs/en/20-third-party/01-grafana.mdx | 114 ++++++++++++++---- .../grafana/grafana-data-source.png | Bin 0 -> 28949 bytes .../grafana/grafana-install-and-config.png | Bin 0 -> 89018 bytes .../grafana-plugin-search-tdengine.png | Bin 0 -> 35146 bytes docs/zh/20-third-party/01-grafana.mdx | 113 +++++++++++++---- .../zh/20-third-party/grafana-data-source.png | Bin 0 -> 28949 bytes .../grafana-install-and-config.png | Bin 0 -> 89018 bytes .../grafana-plugin-search-tdengine.png | Bin 0 -> 35146 bytes 8 files changed, 183 insertions(+), 44 deletions(-) create mode 100644 docs/en/20-third-party/grafana/grafana-data-source.png create mode 100644 docs/en/20-third-party/grafana/grafana-install-and-config.png create mode 100644 docs/en/20-third-party/grafana/grafana-plugin-search-tdengine.png create mode 100644 docs/zh/20-third-party/grafana-data-source.png create mode 100644 docs/zh/20-third-party/grafana-install-and-config.png create mode 100644 docs/zh/20-third-party/grafana-plugin-search-tdengine.png diff --git a/docs/en/20-third-party/01-grafana.mdx b/docs/en/20-third-party/01-grafana.mdx index b51d5a8d90..e63cbb7426 100644 --- a/docs/en/20-third-party/01-grafana.mdx +++ b/docs/en/20-third-party/01-grafana.mdx @@ -31,38 +31,41 @@ TDengine currently supports Grafana versions 7.5 and above. Users can go to the ### Install Grafana Plugin and Configure Data Source - + -Set the url and authorization environment variables by `export` or a [`.env`(dotenv) file](https://hexdocs.pm/dotenvy/dotenv-file-format.html): +Under Grafana 8, plugin catalog allows you to [browse and manage plugins within Grafana](https://grafana.com/docs/grafana/next/administration/plugin-management/#plugin-catalog) (but for Grafana 7.x, use **With Script** or **Install & Configure Manually**). Find the page at **Configurations > Plugins**, search **TDengine** and click it to install. -```sh -export TDENGINE_API=http://tdengine.local:6041 -# user + password -export TDENGINE_USER=user -export TDENGINE_PASSWORD=password - -# Other useful variables -# - If to install TDengine data source, default is true -export TDENGINE_DS_ENABLED=false -# - Data source name to be created, default is TDengine -export TDENGINE_DS_NAME=TDengine -# - Data source organization id, default is 1 -export GF_ORG_ID=1 -# - Data source is editable in admin ui or not, default is 0 (false) -export TDENGINE_EDITABLE=1 -``` +![Search tdengine in grafana plugins](./grafana/grafana-plugin-search-tdengine.png) + +Installation may cost some minutes, then you can **Create a TDengine data source**: + +![Install and configure Grafana data source](./grafana/grafana-install-and-config.png) + +Then you can add a TDengine data source by filling up the configuration options. + +![TDengine Database Grafana plugin add data source](./grafana/grafana-data-source.png) + +You can create dashboards with TDengine now. + + + -Run `install.sh`: +In Grafana server, run `install.sh` with TDengine url and username/passwords will install TDengine data source plugin and add a data source named TDengine. This is the recommended way for Grafana 7.x or [Grafana provisioning](https://grafana.com/docs/grafana/latest/administration/provisioning/) users. ```sh -bash -c "$(curl -fsSL https://raw.githubusercontent.com/taosdata/grafanaplugin/master/install.sh)" +bash -c "$(curl -fsSL \ + https://raw.githubusercontent.com/taosdata/grafanaplugin/master/install.sh)" -- \ + -a http://localhost:6041 \ + -u root \ + -p taosdata ``` -With this script, TDengine data source plugin and the Grafana data source will be installed and created automatically with Grafana provisioning configurations. Save the script and type `./install.sh --help` for the full usage of the script. +Restart Grafana service and open Grafana in web-browser, usually . -And then, restart Grafana service and open Grafana in web-browser, usually . +Save the script and type `./install.sh --help` for the full usage of the script. + Follow the installation steps in [Grafana](https://grafana.com/grafana/plugins/tdengine-datasource/?tab=installation) with the [``grafana-cli`` command-line tool](https://grafana.com/docs/grafana/latest/administration/cli/) for plugin installation. @@ -115,6 +118,73 @@ Click `Save & Test` to test. You should see a success message if the test worked ![TDengine Database TDinsight plugin add database 4](./grafana/add_datasource4.webp) + + + +Please refer to [Install plugins in the Docker container](https://grafana.com/docs/grafana/next/setup-grafana/installation/docker/#install-plugins-in-the-docker-container). This will install `tdengine-datasource` plugin when Grafana container starts: + +```bash +docker run -d \ + -p 3000:3000 \ + --name=grafana \ + -e "GF_INSTALL_PLUGINS=tdengine-datasource" \ + grafana/grafana +``` + +You can setup a zero-configuration stack for TDengine + Grafana by [docker-compose](https://docs.docker.com/compose/) and [Grafana provisioning](https://grafana.com/docs/grafana/latest/administration/provisioning/) file: + +1. Save the provisioning configuration file to `tdengine.yml`. + + ```yml + apiVersion: 1 + datasources: + - name: TDengine + type: tdengine-datasource + orgId: 1 + url: "$TDENGINE_API" + isDefault: true + secureJsonData: + url: "$TDENGINE_URL" + basicAuth: "$TDENGINE_BASIC_AUTH" + token: "$TDENGINE_CLOUD_TOKEN" + version: 1 + editable: true + ``` + +2. Write `docker-compose.yml` with [TDengine](https://hub.docker.com/r/tdengine/tdengine) and [Grafana](https://hub.docker.com/r/grafana/grafana) image. + + ```yml + version: "3.7" + + services: + tdengine: + image: tdengine/tdengine:2.6.0.2 + environment: + TAOS_FQDN: tdengine + volumes: + - tdengine-data:/var/lib/taos/ + grafana: + image: grafana/grafana:8.5.6 + volumes: + - ./tdengine.yml/:/etc/grafana/provisioning/tdengine.yml + - grafana-data:/var/lib/grafana + environment: + # install tdengine plugin at start + GF_INSTALL_PLUGINS: "tdengine-datasource" + TDENGINE_URL: "http://tdengine:6041" + #printf "$TDENGINE_USER:$TDENGINE_PASSWORD" | base64 + TDENGINE_BASIC_AUTH: "cm9vdDp0YmFzZTEyNQ==" + ports: + - 3000:3000 + volumes: + grafana-data: + tdengine-data: + ``` + +3. Start TDengine and Grafana services: `docker-compose up -d`. + +Open Grafana , and you can add dashboard with TDengine now. + diff --git a/docs/en/20-third-party/grafana/grafana-data-source.png b/docs/en/20-third-party/grafana/grafana-data-source.png new file mode 100644 index 0000000000000000000000000000000000000000..989ffcca0bf5baae8798b0695e259aca35f0442a GIT binary patch literal 28949 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 literal 0 HcmV?d00001 diff --git a/docs/en/20-third-party/grafana/grafana-plugin-search-tdengine.png b/docs/en/20-third-party/grafana/grafana-plugin-search-tdengine.png new file mode 100644 index 0000000000000000000000000000000000000000..cf3b66977b64f7dcd617f06024a66066cd62810e GIT binary patch literal 35146 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 - + -将集群信息设置为环境变量;也可以使用 `.env` 文件,请参考 [dotenv](https://hexdocs.pm/dotenvy/dotenv-file-format.html): +使用 Grafana 最新版本(8.5+),您可以在 Grafana 中[浏览和管理插件](https://grafana.com/docs/grafana/next/administration/plugin-management/#plugin-catalog)(对于 7.x 版本,请使用 **安装脚本** 或 **手动安装并配置** 方式)。在 Grafana 管理界面中的 **Configurations > Plugins** 页面直接搜索并按照提示安装 TDengine。 -```sh -export TDENGINE_API=http://tdengine.local:6041 -# user + password -export TDENGINE_USER=user -export TDENGINE_PASSWORD=password - -# 其他环境变量: -# - 是否安装数据源,默认为 true,表示安装 -export TDENGINE_DS_ENABLED=false -# - 数据源名称,默认为 TDengine -export TDENGINE_DS_NAME=TDengine -# - 数据源所属组织 ID,默认为 1 -export GF_ORG_ID=1 -# - 数据源是否可通过管理面板编辑,默认为 0,表示不可编辑 -export TDENGINE_EDITABLE=1 -``` +![Search tdengine in grafana plugins](grafana-plugin-search-tdengine.png) + +如图示即安装完毕,按照指示 **Create a TDengine data source** 添加数据源。 + +![Install and configure Grafana data source](grafana-install-and-config.png) + +输入 TDengine 相关配置,完成数据源配置。 + +![TDengine Database Grafana plugin add data source](./grafana-data-source.png) + +配置完毕,现在可以使用 TDengine 创建 Dashboard 了。 + + + -运行安装脚本: +对于使用 Grafana 7.x 版本或使用 [Grafana Provisioning](https://grafana.com/docs/grafana/latest/administration/provisioning/) 配置的用户,可以在 Grafana 服务器上使用安装脚本自动安装插件即添加数据源 Provisioning 配置文件。 ```sh -bash -c "$(curl -fsSL https://raw.githubusercontent.com/taosdata/grafanaplugin/master/install.sh)" +bash -c "$(curl -fsSL \ + https://raw.githubusercontent.com/taosdata/grafanaplugin/master/install.sh)" -- \ + -a http://localhost:6041 \ + -u root \ + -p taosdata ``` -该脚本将自动安装 Grafana 插件并配置数据源。安装完毕后,需要重启 Grafana 服务后生效。 +安装完毕后,需要重启 Grafana 服务后方可生效。 保存该脚本并执行 `./install.sh --help` 可查看详细帮助文档。 - + 使用 [`grafana-cli` 命令行工具](https://grafana.com/docs/grafana/latest/administration/cli/) 进行插件[安装](https://grafana.com/grafana/plugins/tdengine-datasource/?tab=installation)。 @@ -113,6 +115,73 @@ GF_INSTALL_PLUGINS=tdengine-datasource ![TDengine Database Grafana plugin add data source](./add_datasource4.webp) + + + +参考 [Grafana 容器化安装说明](https://grafana.com/docs/grafana/next/setup-grafana/installation/docker/#install-plugins-in-the-docker-container)。使用如下命令启动一个容器,并自动安装 TDengine 插件: + +```bash +docker run -d \ + -p 3000:3000 \ + --name=grafana \ + -e "GF_INSTALL_PLUGINS=tdengine-datasource" \ + grafana/grafana +``` + +使用 docker-compose,配置 Grafana Provisioning 自动化配置,体验 TDengine + Grafana 组合的零配置启动: + +1. 保存该文件为 `tdengine.yml`。 + + ```yml + apiVersion: 1 + datasources: + - name: TDengine + type: tdengine-datasource + orgId: 1 + url: "$TDENGINE_API" + isDefault: true + secureJsonData: + url: "$TDENGINE_URL" + basicAuth: "$TDENGINE_BASIC_AUTH" + token: "$TDENGINE_CLOUD_TOKEN" + version: 1 + editable: true + ``` + +2. 保存该文件为 `docker-compose.yml`。 + + ```yml + version: "3.7" + + services: + tdengine: + image: tdengine/tdengine:2.6.0.2 + environment: + TAOS_FQDN: tdengine + volumes: + - tdengine-data:/var/lib/taos/ + grafana: + image: grafana/grafana:8.5.6 + volumes: + - ./tdengine.yml/:/etc/grafana/provisioning/tdengine.yml + - grafana-data:/var/lib/grafana + environment: + # install tdengine plugin at start + GF_INSTALL_PLUGINS: "tdengine-datasource" + TDENGINE_URL: "http://tdengine:6041" + #printf "$TDENGINE_USER:$TDENGINE_PASSWORD" | base64 + TDENGINE_BASIC_AUTH: "cm9vdDp0YmFzZTEyNQ==" + ports: + - 3000:3000 + volumes: + grafana-data: + tdengine-data: + ``` + +3. 使用 docker-compose 命令启动 TDengine + Grafana :`docker-compose up -d`。 + +打开 Grafana ,现在可以添加 Dashboard 了。 + diff --git a/docs/zh/20-third-party/grafana-data-source.png b/docs/zh/20-third-party/grafana-data-source.png new file mode 100644 index 0000000000000000000000000000000000000000..989ffcca0bf5baae8798b0695e259aca35f0442a GIT binary patch literal 28949 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 literal 0 HcmV?d00001 diff --git a/docs/zh/20-third-party/grafana-plugin-search-tdengine.png b/docs/zh/20-third-party/grafana-plugin-search-tdengine.png new file mode 100644 index 0000000000000000000000000000000000000000..cf3b66977b64f7dcd617f06024a66066cd62810e GIT binary patch literal 35146 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 Date: Fri, 17 Jun 2022 21:42:12 +0800 Subject: [PATCH 037/380] docs(Grafana): update to simplify Grafana installtion (#13955) Ref: [TD-16627](https://jira.taosdata.com:18080/browse/TD-16627) --- docs/en/20-third-party/01-grafana.mdx | 2 +- docs/zh/20-third-party/01-grafana.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/20-third-party/01-grafana.mdx b/docs/en/20-third-party/01-grafana.mdx index e63cbb7426..696be9e4d5 100644 --- a/docs/en/20-third-party/01-grafana.mdx +++ b/docs/en/20-third-party/01-grafana.mdx @@ -50,7 +50,7 @@ You can create dashboards with TDengine now. -In Grafana server, run `install.sh` with TDengine url and username/passwords will install TDengine data source plugin and add a data source named TDengine. This is the recommended way for Grafana 7.x or [Grafana provisioning](https://grafana.com/docs/grafana/latest/administration/provisioning/) users. +On a server with Grafana installed, run `install.sh` with TDengine url and username/passwords will install TDengine data source plugin and add a data source named TDengine. This is the recommended way for Grafana 7.x or [Grafana provisioning](https://grafana.com/docs/grafana/latest/administration/provisioning/) users. ```sh bash -c "$(curl -fsSL \ diff --git a/docs/zh/20-third-party/01-grafana.mdx b/docs/zh/20-third-party/01-grafana.mdx index 0c8938154d..d7a03ba6c8 100644 --- a/docs/zh/20-third-party/01-grafana.mdx +++ b/docs/zh/20-third-party/01-grafana.mdx @@ -116,7 +116,7 @@ GF_INSTALL_PLUGINS=tdengine-datasource ![TDengine Database Grafana plugin add data source](./add_datasource4.webp) - + 参考 [Grafana 容器化安装说明](https://grafana.com/docs/grafana/next/setup-grafana/installation/docker/#install-plugins-in-the-docker-container)。使用如下命令启动一个容器,并自动安装 TDengine 插件: -- GitLab From 7a7312fafd8b8d015f5973c05dc7d1f13617862e Mon Sep 17 00:00:00 2001 From: dingbo Date: Sat, 18 Jun 2022 13:59:51 +0800 Subject: [PATCH 038/380] docs: fix error links in taosbenchmark --- docs/en/14-reference/05-taosbenchmark.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/en/14-reference/05-taosbenchmark.md b/docs/en/14-reference/05-taosbenchmark.md index 7cf1f95eb1..824d0e5d7f 100644 --- a/docs/en/14-reference/05-taosbenchmark.md +++ b/docs/en/14-reference/05-taosbenchmark.md @@ -7,7 +7,7 @@ description: "taosBenchmark (once called taosdemo ) is a tool for testing the pe ## Introduction -taosBenchmark (formerly taosdemo ) is a tool for testing the performance of TDengine products. taosBenchmark can test the performance of TDengine's insert, query, and subscription functions and simulate large amounts of data generated by many devices. taosBenchmark can flexibly control the number and type of databases, supertables, tag columns, number and type of data columns, and sub-tables, and types of databases, super tables, the number and types of data columns, the number of sub-tables, the amount of data per sub-table, the time interval for inserting data, the number of working threads, whether and how to insert disordered data, and so on. The installer provides taosdemo as a soft link to taosBenchmark for compatibility and for the convenience of past users. +taosBenchmark (formerly taosdemo ) is a tool for testing the performance of TDengine products. taosBenchmark can test the performance of TDengine's insert, query, and subscription functions and simulate large amounts of data generated by many devices. taosBenchmark can be configured to generate user defined databases, supertables, subtables, and the time series data to populate these for performance benchmarking. taosBenchmark is highly configurable and some of the configurations include the time interval for inserting data, the number of working threads and the capability to insert disordered data. The installer provides taosdemo as a soft link to taosBenchmark for compatibility with past users. ## Installation @@ -21,7 +21,7 @@ There are two ways to install taosBenchmark: ### Configuration and running methods -TaosBenchmark needs to be executed on the terminal of the operating system, it supports two configuration methods: [Command-line arguments](#Command-line arguments in detailed) and [JSON configuration file](#Configuration file arguments in detailed). These two methods are mutually exclusive. Users can use `-f ` to specify a configuration file. When running taosBenchmark with command-line arguments to control its behavior, users should use other parameters for configuration, but not the `-f` parameter. In addition, taosBenchmark offers a special way of running without parameters. +TaosBenchmark needs to be executed on the terminal of the operating system, it supports two configuration methods: [Command-line arguments](#command-line-arguments-in-detail) and [JSON configuration file](#configuration-file-parameters-in-detail). These two methods are mutually exclusive. Users can use `-f ` to specify a configuration file. When running taosBenchmark with command-line arguments to control its behavior, users should use other parameters for configuration, but not the `-f` parameter. In addition, taosBenchmark offers a special way of running without parameters. taosBenchmark supports complete performance testing of TDengine. taosBenchmark supports the TDengine functions in three categories: write, query, and subscribe. These three functions are mutually exclusive, and users can select only one of them each time taosBenchmark runs. It is important to note that the type of functionality to be tested is not configurable when using the command-line configuration method, which can only test writing performance. To test the query and subscription performance of the TDengine, you must use the configuration file method and specify the function type to test via the parameter `filetype` in the configuration file. @@ -57,9 +57,8 @@ Use the following command-line to run taosBenchmark and control its behavior via taosBenchmark -f ``` -**Here are a few examples of configuration files:** - -#### Example of inserting a scenario JSON configuration file +#### Configuration file examples +##### Example of inserting a scenario JSON configuration file
insert.json @@ -70,7 +69,7 @@ taosBenchmark -f
-#### Query Scenario JSON Profile Example +##### Query Scenario JSON Profile Example
query.json @@ -81,7 +80,7 @@ taosBenchmark -f
-#### Subscription JSON configuration example +##### Subscription JSON configuration example
subscribe.json @@ -373,7 +372,7 @@ The configuration parameters for querying the sub-tables or the normal tables ar - **sqls**. - **sql**: the SQL command to be executed. - - **result**: the file to save the query result. If it is unspecified, taosBenchark will not save the result. + - **result**: the file to save the query result. If it is unspecified, taosBenchmark will not save the result. #### Configuration parameters of query super table -- GitLab From 88d9ca2fd85e290612be84f7d883efe28dd7d54f Mon Sep 17 00:00:00 2001 From: dingbo Date: Sat, 18 Jun 2022 14:05:13 +0800 Subject: [PATCH 039/380] docs: typo --- docs/en/14-reference/05-taosbenchmark.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/en/14-reference/05-taosbenchmark.md b/docs/en/14-reference/05-taosbenchmark.md index 824d0e5d7f..0951717f5a 100644 --- a/docs/en/14-reference/05-taosbenchmark.md +++ b/docs/en/14-reference/05-taosbenchmark.md @@ -23,7 +23,7 @@ There are two ways to install taosBenchmark: TaosBenchmark needs to be executed on the terminal of the operating system, it supports two configuration methods: [Command-line arguments](#command-line-arguments-in-detail) and [JSON configuration file](#configuration-file-parameters-in-detail). These two methods are mutually exclusive. Users can use `-f ` to specify a configuration file. When running taosBenchmark with command-line arguments to control its behavior, users should use other parameters for configuration, but not the `-f` parameter. In addition, taosBenchmark offers a special way of running without parameters. -taosBenchmark supports complete performance testing of TDengine. taosBenchmark supports the TDengine functions in three categories: write, query, and subscribe. These three functions are mutually exclusive, and users can select only one of them each time taosBenchmark runs. It is important to note that the type of functionality to be tested is not configurable when using the command-line configuration method, which can only test writing performance. To test the query and subscription performance of the TDengine, you must use the configuration file method and specify the function type to test via the parameter `filetype` in the configuration file. +taosBenchmark supports the complete performance testing of TDengine by providing functionally to write, query, and subscribe. These three functions are mutually exclusive, users can only select one of them each time taosBenchmark runs. The query and subscribe functionalities are only configurable using a json configuration file by specifying the parameter `filetype`, while write can be performed through both the command-line and a configuration file. **Make sure that the TDengine cluster is running correctly before running taosBenchmark. ** @@ -171,7 +171,11 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\) Switch parameter specifying whether to use escape characters in the super table and sub-table names. By default is not used. - **-C/--chinese** : +<<<<<<< HEAD Switch specifying whether to use Unicode Chinese characters in nchar and binary. By default is not used. +======= + specify whether to use Unicode Chinese characters in nchar and binary, the default is no. +>>>>>>> 108548b4d6 (docs: typo) - **-N/--normal-table** : This parameter indicates that taosBenchmark will create only normal tables instead of super tables. The default value is false. It can be used if the insert mode is taosc, stmt, and rest. -- GitLab From c1f56ddf9a541bcfe53ecbafb63c5b44aa08cdcf Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 18 Jun 2022 15:12:51 +0800 Subject: [PATCH 040/380] feat: update taos-tools for 2.6 (#13968) prepare for 3.0 [TD-13052] --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 0a81480420..28a49b447f 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 0a81480420d6601bbdb57770ee64e40f24c4ea83 +Subproject commit 28a49b447f71c4f014ebbac858b7215b897d57fd -- GitLab From ab3fef10495a82e8ec8438c07f94378c73e35bd9 Mon Sep 17 00:00:00 2001 From: Yu Chen <74105241+yu285@users.noreply.github.com> Date: Fri, 17 Jun 2022 19:15:51 +0800 Subject: [PATCH 041/380] docs: yu285-patch-1 --- docs/en/14-reference/06-taosdump.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/14-reference/06-taosdump.md b/docs/en/14-reference/06-taosdump.md index 5403e40925..ffda70710e 100644 --- a/docs/en/14-reference/06-taosdump.md +++ b/docs/en/14-reference/06-taosdump.md @@ -36,6 +36,8 @@ There are two ways to install taosdump: :::tip - taosdump versions after 1.4.1 provide the `-I` argument for parsing Avro file schema and data. If users specify `-s` then only taosdump will parse schema. - Backups after taosdump 1.4.2 use the batch count specified by the `-B` parameter. The default value is 16384. If, in some environments, low network speed or disk performance causes "Error actual dump ... batch ...", then try changing the `-B` parameter to a smaller value. +- The export of taosdump does not support resuming from an interruption. Therefore, if a process terminates unexpectedly, delete all related files that have been exported or generated. +- The import of taosdump supports resuming from an interruption, but when the process resumes, you will receive some "table already exists" messages, which could be ignored. ::: -- GitLab From 1774d5968433a8ad074ebd84cfb34166fc9120f1 Mon Sep 17 00:00:00 2001 From: Yu Chen <74105241+yu285@users.noreply.github.com> Date: Fri, 17 Jun 2022 19:17:17 +0800 Subject: [PATCH 042/380] Update 06-taosdump.md --- docs/en/14-reference/06-taosdump.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/14-reference/06-taosdump.md b/docs/en/14-reference/06-taosdump.md index ffda70710e..96e68d0edb 100644 --- a/docs/en/14-reference/06-taosdump.md +++ b/docs/en/14-reference/06-taosdump.md @@ -36,7 +36,7 @@ There are two ways to install taosdump: :::tip - taosdump versions after 1.4.1 provide the `-I` argument for parsing Avro file schema and data. If users specify `-s` then only taosdump will parse schema. - Backups after taosdump 1.4.2 use the batch count specified by the `-B` parameter. The default value is 16384. If, in some environments, low network speed or disk performance causes "Error actual dump ... batch ...", then try changing the `-B` parameter to a smaller value. -- The export of taosdump does not support resuming from an interruption. Therefore, if a process terminates unexpectedly, delete all related files that have been exported or generated. +- The export of taosdump does not support resuming from an interruption. Therefore, if the taosdump process terminates unexpectedly, delete all related files that have been exported or generated. - The import of taosdump supports resuming from an interruption, but when the process resumes, you will receive some "table already exists" messages, which could be ignored. ::: -- GitLab From b528f2483b4b4f48f1314e1fc65b3ce7727ed6a2 Mon Sep 17 00:00:00 2001 From: Yu Chen <74105241+yu285@users.noreply.github.com> Date: Fri, 17 Jun 2022 18:49:10 +0800 Subject: [PATCH 043/380] docs: Update taosdump --- docs/zh/14-reference/06-taosdump.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/zh/14-reference/06-taosdump.md b/docs/zh/14-reference/06-taosdump.md index 3a9f2e9acd..95ee20bfba 100644 --- a/docs/zh/14-reference/06-taosdump.md +++ b/docs/zh/14-reference/06-taosdump.md @@ -39,6 +39,8 @@ taosdump 有两种安装方式: :::tip - taosdump 1.4.1 之后的版本提供 `-I` 参数,用于解析 avro 文件 schema 和数据,如果指定 `-s` 参数将只解析 schema。 - taosdump 1.4.2 之后的备份使用 `-B` 参数指定的批次数,默认值为 16384,如果在某些环境下由于网络速度或磁盘性能不足导致 "Error actual dump .. batch .." 可以通过 `-B` 参数调整为更小的值进行尝试。 +- taosdump 的导出不支持中断恢复,所以当进程意外终止后,正确的处理方式是删除当前已导出或生成的所有相关文件。 +- taosdump 的导入支持中断恢复,但是当进程重新启动时,会收到一些“表已经存在”的提示,可以忽视。 ::: -- GitLab From 3a2d5bb5425a56286579cf14c2059fbbda52448e Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Mon, 20 Jun 2022 10:52:13 +0800 Subject: [PATCH 044/380] test: update timestamp to avoid overlap --- tests/pytest/table/columnNameCaseSensitive.py | 14 +++++++------- tests/pytest/table/tbNameCaseSensitive.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/pytest/table/columnNameCaseSensitive.py b/tests/pytest/table/columnNameCaseSensitive.py index 036786ae70..e5246e8175 100644 --- a/tests/pytest/table/columnNameCaseSensitive.py +++ b/tests/pytest/table/columnNameCaseSensitive.py @@ -40,8 +40,8 @@ class TDTestCase: tdSql.checkData(2, 0, 'C1') tdSql.execute("insert into tb2(ts, c1) values(now, 1)") - tdSql.execute("insert into tb2(ts, `C1`) values(now, 1)") - tdSql.execute("insert into tb2(ts, c1, `C1`) values(now, 1, 2)") + tdSql.execute("insert into tb2(ts, `C1`) values(now + 1s, 1)") + tdSql.execute("insert into tb2(ts, c1, `C1`) values(now + 2s, 1, 2)") tdSql.query("select * from tb2") tdSql.checkRows(3) @@ -76,8 +76,8 @@ class TDTestCase: tdSql.checkData(2, 0, 'C1') tdSql.execute("insert into `TB2`(ts, c1) values(now, 1)") - tdSql.execute("insert into `TB2`(ts, `C1`) values(now, 1)") - tdSql.execute("insert into `TB2`(ts, c1, `C1`) values(now, 1, 2)") + tdSql.execute("insert into `TB2`(ts, `C1`) values(now + 1s, 1)") + tdSql.execute("insert into `TB2`(ts, c1, `C1`) values(now + 2s, 1, 2)") tdSql.query("select * from `TB2`") tdSql.checkRows(3) @@ -113,8 +113,8 @@ class TDTestCase: tdSql.checkData(3, 0, 't1') tdSql.execute("insert into tt2(ts, c1) using `STB2` tags(1) values(now, 1)") - tdSql.execute("insert into tt2(ts, `C1`) using `STB2` tags(1) values(now, 1)") - tdSql.execute("insert into tt2(ts, c1, `C1`) using `STB2` tags(1) values(now, 1, 2)") + tdSql.execute("insert into tt2(ts, `C1`) using `STB2` tags(1) values(now + 1s, 1)") + tdSql.execute("insert into tt2(ts, c1, `C1`) using `STB2` tags(1) values(now + 2s, 1, 2)") tdSql.query("select * from `STB2`") tdSql.checkRows(3) @@ -142,7 +142,7 @@ class TDTestCase: # cornor cases tdSql.execute("alter table `STB2` add column `数量` int") - tdSql.execute("insert into tt3(ts, `数量`) using `STB2` tags(2) values(now, 1)") + tdSql.execute("insert into tt3(ts, `数量`) using `STB2` tags(2) values(now + 3s, 1)") tdSql.query("select * from tt3") tdSql.checkRows(1) tdSql.query("select ts `TS` from tt3") diff --git a/tests/pytest/table/tbNameCaseSensitive.py b/tests/pytest/table/tbNameCaseSensitive.py index 70d7ee3095..85e9b7d720 100644 --- a/tests/pytest/table/tbNameCaseSensitive.py +++ b/tests/pytest/table/tbNameCaseSensitive.py @@ -81,7 +81,7 @@ class TDTestCase: tdSql.query("select * from `STB`") tdSql.checkRows(1) - tdSql.execute("insert into `T2` using `STB` tags(1) values(now, 1)") + tdSql.execute("insert into `T2` using `STB` tags(1) values(now + 1s, 1)") tdSql.query("select * from `STB`") tdSql.checkRows(2) -- GitLab From 6e3cc9ea455a3f6fc3463512e626185e15667d23 Mon Sep 17 00:00:00 2001 From: tangfangzhi Date: Mon, 20 Jun 2022 13:15:57 +0800 Subject: [PATCH 045/380] ci: split ci environment into two --- Jenkinsfile2 | 117 ++++++++++++++------------------------------------- 1 file changed, 31 insertions(+), 86 deletions(-) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index e03994b975..c3b95a166f 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -7,7 +7,8 @@ def sync_source() { sh ''' hostname date - ''' + env + ''' sh ''' cd ${WKC} [ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md" @@ -57,6 +58,7 @@ def sync_source() { [ -f src/connector/grafanaplugin/README.md ] && rm -f src/connector/grafanaplugin/README.md > /dev/null || echo "failed to remove grafanaplugin README.md" git pull >/dev/null git clean -dfx + git log -5 ''' script { if (env.CHANGE_TARGET == 'master') { @@ -90,6 +92,7 @@ def sync_source() { cd ${WK} git pull >/dev/null git clean -dfx + git log -5 ''' script { if (env.CHANGE_URL =~ /\/TDengine\//) { @@ -98,7 +101,10 @@ def sync_source() { cd ${WKC} git fetch origin +refs/pull/${CHANGE_ID}/merge git checkout -qf FETCH_HEAD - + git log -5 + ''' + sh ''' + cd ${WKC} if [ ! -d src/connector/python/.github ]; then rm -rf src/connector/python/* || : rm -rf src/connector/python/.* || : @@ -106,7 +112,6 @@ def sync_source() { else cd src/connector/python || echo "src/connector/python not exist" git pull || : - cd ${WKC} fi ''' } else if (env.CHANGE_URL =~ /\/TDinternal\//) { @@ -115,7 +120,10 @@ def sync_source() { cd ${WK} git fetch origin +refs/pull/${CHANGE_ID}/merge git checkout -qf FETCH_HEAD - + git log -5 + ''' + sh ''' + cd ${WKC} if [ ! -d community/src/connector/python/.github ]; then rm -rf community/src/connector/python/* || : rm -rf community/src/connector/python/.* || : @@ -123,7 +131,6 @@ def sync_source() { else cd community/src/connector/python || echo "community/src/connector/python not exist" git pull || : - cd ${WK} fi ''' } else { @@ -136,16 +143,6 @@ def sync_source() { cd ${WKC} git submodule update --init --recursive ''' - sh ''' - cd ${WKC} - git branch - git log -5 - ''' - sh ''' - cd ${WK} - git branch - git log -5 - ''' } def pre_test() { sync_source() @@ -174,7 +171,7 @@ def pre_test_mac() { return 1 } pipeline { - agent {label " dispatcher "} + agent none options { skipDefaultCheckout() } environment{ WK = '/var/data/jenkins/workspace/TDinternal' @@ -182,69 +179,6 @@ pipeline { LOGDIR = '/var/data/jenkins/workspace/log' } stages { - stage ('pre_build') { - steps { - sh ''' - date - pwd - env - hostname - ''' - } - } - stage ('Parallel build stage') { - //only build pr - options { skipDefaultCheckout() } - when { - allOf { - changeRequest() - not { expression { env.CHANGE_BRANCH =~ /docs\// }} - } - } - parallel { - stage ('dispatcher sync source') { - steps { - timeout(time: 20, unit: 'MINUTES') { - sync_source() - script { - sh ''' - echo "dispatcher ready" - date - ''' - } - } - } - } - stage ('build worker01') { - agent {label " worker01 "} - steps { - timeout(time: 20, unit: 'MINUTES') { - pre_test() - script { - sh ''' - echo "worker01 build done" - date - ''' - } - } - } - } - stage ('build worker02') { - agent {label " worker02 "} - steps { - timeout(time: 20, unit: 'MINUTES') { - pre_test() - script { - sh ''' - echo "worker02 build done" - date - ''' - } - } - } - } - } - } stage('run test') { options { skipDefaultCheckout() } when { @@ -254,28 +188,28 @@ pipeline { } } parallel { - stage ('build worker07_arm64') { - agent {label " worker07_arm64 "} + stage ('build arm64') { + agent {label " worker07_arm64 || worker09_arm64 "} steps { timeout(time: 20, unit: 'MINUTES') { pre_test() script { sh ''' - echo "worker07_arm64 build done" + echo "arm64 build done" date ''' } } } } - stage ('build Mac_catalina ') { + stage ('build Mac') { agent {label " Mac_catalina "} steps { timeout(time: 20, unit: 'MINUTES') { pre_test_mac() script { sh ''' - echo "Mac_catalina build done" + echo "Mac build done" date ''' } @@ -283,17 +217,28 @@ pipeline { } } stage('run cases') { + agent {label " worker01 || worker02 "} steps { sh ''' date + pwd hostname ''' + timeout(time: 15, unit: 'MINUTES') { + pre_test() + script { + sh ''' + echo "Linux build done" + date + ''' + } + } catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { - timeout(time: 20, unit: 'MINUTES') { + timeout(time: 25, unit: 'MINUTES') { sh ''' date cd ${WKC}/tests/parallel_test - time ./run.sh -m m.json -t cases.task -l ${LOGDIR} -b ${BRANCH_NAME} + time ./run.sh -m /home/m.json -t cases.task -l ${LOGDIR} -b ${BRANCH_NAME} date hostname ''' -- GitLab From d1116bd84aa87b33362b5d47cafee7495d8fed59 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Mon, 20 Jun 2022 17:08:00 +0800 Subject: [PATCH 046/380] fix: Remove install warning for red hat --- packaging/tools/install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index b14c14c7ee..85280cc509 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -105,6 +105,9 @@ elif echo $osinfo | grep -qwi "debian"; then elif echo $osinfo | grep -qwi "Kylin"; then # echo "This is Kylin system" os_type=1 +elif echo $osinfo | grep -qwi "Red"; then + # echo "This is Red Hat system" + os_type=1 elif echo $osinfo | grep -qwi "centos"; then # echo "This is centos system" os_type=2 -- GitLab From ac94bb85f9bf067c0dd11385b1e777c5c3cd4230 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Mon, 20 Jun 2022 17:43:19 +0800 Subject: [PATCH 047/380] fix: show create database output case sensitively --- src/client/src/tscLocal.c | 132 +++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 65 deletions(-) diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index 81d658d964..05d8e77a3e 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -25,23 +25,23 @@ #include "taos.h" #include "tscSubquery.h" -#define STR_NOCASE_EQUAL(str1, len1, str2, len2) ((len1 == len2) && 0 == strncasecmp(str1, str2, len1)) +#define STR_NOCASE_EQUAL(str1, len1, str2, len2) ((len1 == len2) && 0 == strncasecmp(str1, str2, len1)) typedef enum BuildType { - SCREATE_BUILD_TABLE = 1, - SCREATE_BUILD_DB = 2, -} BuildType; + SCREATE_BUILD_TABLE = 1, + SCREATE_BUILD_DB = 2, +} BuildType; typedef enum Stage { SCREATE_CALLBACK_QUERY = 1, SCREATE_CALLBACK_RETRIEVE = 2, } Stage; -// support 'show create table' +// support 'show create table' typedef struct SCreateBuilder { char sTableName[TSDB_TABLE_FNAME_LEN]; char buf[TSDB_TABLE_FNAME_LEN]; - SSqlObj *pParentSql; + SSqlObj *pParentSql; SSqlObj *pInterSql; int32_t (*fp)(void *para, char* result); Stage callStage; @@ -54,7 +54,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { // one column for each row SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); - + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -121,7 +121,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { // type name pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1); char *type = tDataTypes[pSchema[i].type].name; - + output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i; STR_WITH_MAXSIZE_TO_VARSTR(output, type, pField->bytes); @@ -153,7 +153,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, int32_t noteColLength) { int32_t rowLen = 0; SColumnIndex index = {0}; - + pSql->cmd.numOfCols = numOfCols; SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); @@ -161,48 +161,48 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, TAOS_FIELD f = {.type = TSDB_DATA_TYPE_BINARY, .bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE}; tstrncpy(f.name, "Field", sizeof(f.name)); - + SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false); - + rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE); f.bytes = (int16_t)(typeColLength + VARSTR_HEADER_SIZE); f.type = TSDB_DATA_TYPE_BINARY; tstrncpy(f.name, "Type", sizeof(f.name)); - + pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), -1000, typeColLength, false); - + rowLen += typeColLength + VARSTR_HEADER_SIZE; f.bytes = sizeof(int32_t); f.type = TSDB_DATA_TYPE_INT; tstrncpy(f.name, "Length", sizeof(f.name)); - + pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), -1000, sizeof(int32_t), false); - + rowLen += sizeof(int32_t); f.bytes = (int16_t)(noteColLength + VARSTR_HEADER_SIZE); f.type = TSDB_DATA_TYPE_BINARY; tstrncpy(f.name, "Note", sizeof(f.name)); - + pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), -1000, noteColLength, false); - + rowLen += noteColLength + VARSTR_HEADER_SIZE; return rowLen; } static int32_t tscProcessDescribeTable(SSqlObj *pSql) { SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); - + assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL); const int32_t NUM_OF_DESC_TABLE_COLUMNS = 4; @@ -220,25 +220,25 @@ static int32_t tscGetNthFieldResult(TAOS_ROW row, TAOS_FIELD* fields, int *lengt if (val == NULL) { sprintf(result, "%s", TSDB_DATA_NULL_STR); return -1; - } + } uint8_t type = fields[idx].type; int32_t length = lengths[idx]; switch (type) { - case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_BOOL: sprintf(result, "%s", ((((int32_t)(*((char *)val))) == 1) ? "true" : "false")); break; case TSDB_DATA_TYPE_TINYINT: sprintf(result, "%d", *((int8_t *)val)); break; - case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_SMALLINT: sprintf(result, "%d", *((int16_t *)val)); break; case TSDB_DATA_TYPE_INT: sprintf(result, "%d", *((int32_t *)val)); break; - case TSDB_DATA_TYPE_BIGINT: - sprintf(result, "%"PRId64, *((int64_t *)val)); + case TSDB_DATA_TYPE_BIGINT: + sprintf(result, "%" PRId64, *((int64_t *)val)); break; case TSDB_DATA_TYPE_UTINYINT: sprintf(result, "%u", *((uint8_t *)val)); @@ -253,57 +253,57 @@ static int32_t tscGetNthFieldResult(TAOS_ROW row, TAOS_FIELD* fields, int *lengt sprintf(result, "%"PRIu64, *((uint64_t *)val)); break; case TSDB_DATA_TYPE_FLOAT: - sprintf(result, "%f", GET_FLOAT_VAL(val)); + sprintf(result, "%f", GET_FLOAT_VAL(val)); break; case TSDB_DATA_TYPE_DOUBLE: - sprintf(result, "%f", GET_DOUBLE_VAL(val)); + sprintf(result, "%f", GET_DOUBLE_VAL(val)); break; case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_JSON: - memcpy(result, val, length); + memcpy(result, val, length); break; case TSDB_DATA_TYPE_TIMESTAMP: ///formatTimestamp(buf, *(int64_t*)val, TSDB_TIME_PRECISION_MICRO); //memcpy(result, val, strlen(buf)); - sprintf(result, "%"PRId64, *((int64_t *)val)); + sprintf(result, "%" PRId64, *((int64_t *)val)); break; default: - break; + break; } return 0; -} +} void tscSCreateCallBack(void *param, TAOS_RES *tres, int code) { if (param == NULL || tres == NULL) { return; - } + } SCreateBuilder *builder = (SCreateBuilder *)(param); - SSqlObj *pParentSql = builder->pParentSql; - SSqlObj *pSql = (SSqlObj *)tres; + SSqlObj *pParentSql = builder->pParentSql; + SSqlObj *pSql = (SSqlObj *)tres; SSqlRes *pRes = &pParentSql->res; - pRes->code = taos_errno(pSql); + pRes->code = taos_errno(pSql); if (pRes->code != TSDB_CODE_SUCCESS) { - taos_free_result(pSql); + taos_free_result(pSql); free(builder); tscAsyncResultOnError(pParentSql); return; } if (builder->callStage == SCREATE_CALLBACK_QUERY) { - taos_fetch_rows_a(tres, tscSCreateCallBack, param); + taos_fetch_rows_a(tres, tscSCreateCallBack, param); builder->callStage = SCREATE_CALLBACK_RETRIEVE; } else { char *result = calloc(1, TSDB_MAX_BINARY_LEN); pRes->code = builder->fp(builder, result); - taos_free_result(pSql); + taos_free_result(pSql); free(builder); free(result); if (pRes->code == TSDB_CODE_SUCCESS) { - (*pParentSql->fp)(pParentSql->param, pParentSql, code); + (*pParentSql->fp)(pParentSql->param, pParentSql, code); } else { tscAsyncResultOnError(pParentSql); } @@ -314,16 +314,16 @@ TAOS_ROW tscFetchRow(void *param) { SCreateBuilder *builder = (SCreateBuilder *)param; if (builder == NULL) { return NULL; - } + } SSqlObj *pSql = builder->pInterSql; if (pSql == NULL || pSql->signature != pSql) { terrno = TSDB_CODE_TSC_DISCONNECTED; return NULL; } - + SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; - + if (pRes->qId == 0 || pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pCmd->command == TSDB_SQL_INSERT) { @@ -367,7 +367,7 @@ static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) { return TSDB_CODE_TSC_INVALID_TABLE_NAME; } - int32_t* lengths = taos_fetch_lengths(pSql); + int32_t *lengths = taos_fetch_lengths(pSql); int num_fields = taos_num_fields(pSql); TAOS_FIELD *fields = taos_fetch_fields(pSql); @@ -382,10 +382,10 @@ static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) { if (i == 0) { snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s", "("); - } - if ((fields[i].type == TSDB_DATA_TYPE_NCHAR - || fields[i].type == TSDB_DATA_TYPE_BINARY - || fields[i].type == TSDB_DATA_TYPE_TIMESTAMP) && 0 == ret) { + } + if ((fields[i].type == TSDB_DATA_TYPE_NCHAR || fields[i].type == TSDB_DATA_TYPE_BINARY || + fields[i].type == TSDB_DATA_TYPE_TIMESTAMP) && + 0 == ret) { snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "\"%s\",", buf); } else if (fields[i].type == TSDB_DATA_TYPE_JSON) { snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "'%s,", buf); @@ -410,18 +410,17 @@ static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) { return TSDB_CODE_SUCCESS; } - -// build 'show create table/database' result fields +// build 'show create table/database' result fields static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const char *ddl) { int32_t rowLen = 0; - int16_t ddlLen = (int16_t)strlen(ddl); + int16_t ddlLen = (int16_t)strlen(ddl); SColumnIndex index = {0}; pSql->cmd.numOfCols = 2; SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); pQueryInfo->order.order = TSDB_ORDER_ASC; - TAOS_FIELD f; + TAOS_FIELD f; if (type == SCREATE_BUILD_TABLE) { f.type = TSDB_DATA_TYPE_BINARY; f.bytes = (TSDB_TABLE_NAME_LEN - 1) + VARSTR_HEADER_SIZE; @@ -430,12 +429,12 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const f.type = TSDB_DATA_TYPE_BINARY; f.bytes = (TSDB_DB_NAME_LEN - 1) + VARSTR_HEADER_SIZE; tstrncpy(f.name, "Database", sizeof(f.name)); - } + } SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); - rowLen += f.bytes; + rowLen += f.bytes; f.bytes = (int16_t)(ddlLen + VARSTR_HEADER_SIZE); f.type = TSDB_DATA_TYPE_BINARY; @@ -453,6 +452,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const return rowLen; } + static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) { SSqlRes *pRes = &pSql->res; @@ -473,6 +473,7 @@ static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const c STR_WITH_MAXSIZE_TO_VARSTR(dst, ddl, pField->bytes); return 0; } + static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char *str, const char *result) { SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result); @@ -480,6 +481,7 @@ static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char * tscFieldInfoUpdateOffset(pQueryInfo); return tscSCreateSetValueToResObj(pSql, rowLen, str, result); } + int32_t tscRebuildCreateTableStatement(void *param,char *result) { SCreateBuilder *builder = (SCreateBuilder *)param; int32_t code = TSDB_CODE_SUCCESS; @@ -533,8 +535,8 @@ static int32_t tscGetDBInfo(SCreateBuilder *builder, char *result) { memset(buf, 0, sizeof(buf)); int32_t* lengths = taos_fetch_lengths(pSql); int32_t ret = tscGetNthFieldResult(row, fields, lengths, 0, buf); - if (0 == ret && STR_NOCASE_EQUAL(buf, strlen(buf), builder->buf, strlen(builder->buf))) { - snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "CREATE DATABASE %s", buf); + if (0 == ret && 0 == strcmp(buf, builder->buf)) { + snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "CREATE DATABASE `%s`", buf); for (int i = 1; i < num_fields; i++) { for (int j = 0; showColumns[j][0] != NULL; j++) { if (STR_NOCASE_EQUAL(fields[i].name, strlen(fields[i].name), showColumns[j][0], strlen(showColumns[j][0]))) { @@ -637,7 +639,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch param->fp = tscRebuildCreateTableStatement; param->callStage = SCREATE_CALLBACK_QUERY; - char *query = (char *)calloc(1, TSDB_MAX_BINARY_LEN); + char *query = (char *)calloc(1, TSDB_MAX_BINARY_LEN); if (query == NULL) { free(param); free(pInterSql); @@ -647,7 +649,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch char *columns = NULL; int32_t code = tscGetTableTagColumnName(pSql, &columns) ; if (code != TSDB_CODE_SUCCESS) { - free(param); + free(param); free(pInterSql); free(query); return code; @@ -658,7 +660,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch free(query); free(columns); - return TSDB_CODE_TSC_ACTION_IN_PROGRESS; + return TSDB_CODE_TSC_ACTION_IN_PROGRESS; } static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) { @@ -753,7 +755,7 @@ static int32_t tscProcessShowCreateTable(SSqlObj *pSql) { if (code == TSDB_CODE_SUCCESS) { code = tscSCreateBuildResult(pSql, SCREATE_BUILD_TABLE, tableName, result); - } + } free(result); return code; } @@ -763,12 +765,12 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - SSqlObj *pInterSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); + SSqlObj *pInterSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); if (pInterSql == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; - } + } - SCreateBuilder *param = (SCreateBuilder *)calloc(1, sizeof(SCreateBuilder)); + SCreateBuilder *param = (SCreateBuilder *)calloc(1, sizeof(SCreateBuilder)); if (param == NULL) { free(pInterSql); return TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -779,7 +781,7 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { param->pInterSql = pInterSql; param->fp = tscRebuildCreateDBStatement; param->callStage = SCREATE_CALLBACK_QUERY; - + const char *query = "show databases"; doAsyncQuery(pSql->pTscObj, pInterSql, tscSCreateCallBack, param, query, strlen(query)); return TSDB_CODE_TSC_ACTION_IN_PROGRESS; @@ -958,8 +960,8 @@ int tscProcessLocalCmd(SSqlObj *pSql) { if (taosCfgDynamicOptions(pCmd->payload)) { pRes->code = TSDB_CODE_SUCCESS; } else { - pRes->code = TSDB_CODE_COM_INVALID_CFG_MSG; - } + pRes->code = TSDB_CODE_COM_INVALID_CFG_MSG; + } pRes->numOfRows = 0; } else if (pCmd->command == TSDB_SQL_DESCRIBE_TABLE) { pRes->code = (uint8_t)tscProcessDescribeTable(pSql); @@ -971,9 +973,9 @@ int tscProcessLocalCmd(SSqlObj *pSql) { pRes->qId = 0x1; pRes->numOfRows = 0; } else if (pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE || pCmd->command == TSDB_SQL_SHOW_CREATE_STABLE) { - pRes->code = tscProcessShowCreateTable(pSql); + pRes->code = tscProcessShowCreateTable(pSql); } else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) { - pRes->code = tscProcessShowCreateDatabase(pSql); + pRes->code = tscProcessShowCreateDatabase(pSql); } else if (pCmd->command == TSDB_SQL_RESET_CACHE) { taosHashClear(UTIL_GET_TABLEMETA(pSql)); taosCacheEmpty(UTIL_GET_VGROUPLIST(pSql)); -- GitLab From 7bfc103e9ada9b8c842ab2e5a0be93394613b3a1 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Mon, 20 Jun 2022 17:58:04 +0800 Subject: [PATCH 048/380] test: add test case for TS-1601 --- tests/pytest/functions/function_first.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/pytest/functions/function_first.py b/tests/pytest/functions/function_first.py index f1a916b168..c1f7692dfd 100644 --- a/tests/pytest/functions/function_first.py +++ b/tests/pytest/functions/function_first.py @@ -142,6 +142,29 @@ class TDTestCase: # TD-2607 first,last + where none exist condition + interval tdSql.query("select first(*),last(*) from test1 where ts < 23 interval(1s)") tdSql.checkRows(0) + + # TS-1601 + tdSql.execute("create database test") + tdSql.execute("use test") + tdSql.execute("create table tb01(ts timestamp, c1 double, c2 int)") + tdSql.execute("insert into tb01 values(now, 2.3987401, 20)(now + 2s, 4.58123, 11)") + + r = os.popen("taos -s 'select first(c1) + last(c1) from test.tb01'") + text = r.read() + r.close() + result = float(text.split("|")[1].split("\n")[2]) + + tdSql.query("select first(c1) + last(c1) from tb01") + tdSql.checkData(0, 0, result) + + r = os.popen("taos -s 'select first(c1) - last(c1) from test.tb01'") + text = r.read() + r.close() + result = float(text.split("|")[1].split("\n")[2]) + tdSql.query("select first(c1) - last(c1) from tb01") + tdSql.checkData(0, 0, result) + + def stop(self): tdSql.close() -- GitLab From dab08cb589913c3f8e4ccb07acdaf9b70f538cad Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Mon, 20 Jun 2022 18:08:28 +0800 Subject: [PATCH 049/380] test: add test case for TS-1601 --- tests/pytest/functions/function_first.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/pytest/functions/function_first.py b/tests/pytest/functions/function_first.py index c1f7692dfd..6c3a747feb 100644 --- a/tests/pytest/functions/function_first.py +++ b/tests/pytest/functions/function_first.py @@ -17,6 +17,7 @@ from util.log import * from util.cases import * from util.sql import * import numpy as np +import re class TDTestCase: @@ -152,7 +153,7 @@ class TDTestCase: r = os.popen("taos -s 'select first(c1) + last(c1) from test.tb01'") text = r.read() r.close() - result = float(text.split("|")[1].split("\n")[2]) + result = float(re.split('\n |\|', text)[3]) tdSql.query("select first(c1) + last(c1) from tb01") tdSql.checkData(0, 0, result) @@ -160,8 +161,8 @@ class TDTestCase: r = os.popen("taos -s 'select first(c1) - last(c1) from test.tb01'") text = r.read() r.close() - result = float(text.split("|")[1].split("\n")[2]) - tdSql.query("select first(c1) - last(c1) from tb01") + result = float(re.split('\n |\|', text)[3]) + tdSql.query("select first(c1) + last(c1) from tb01") tdSql.checkData(0, 0, result) -- GitLab From fcad15f74c0a31f09a2449bf8d5c50166275c85f Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Mon, 20 Jun 2022 18:58:15 +0800 Subject: [PATCH 050/380] fix: remove useless script --- packaging/tools/run_taosd_and_taosadapter.sh | 3 --- 1 file changed, 3 deletions(-) delete mode 100755 packaging/tools/run_taosd_and_taosadapter.sh diff --git a/packaging/tools/run_taosd_and_taosadapter.sh b/packaging/tools/run_taosd_and_taosadapter.sh deleted file mode 100755 index 9ab9eb484a..0000000000 --- a/packaging/tools/run_taosd_and_taosadapter.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -[[ -x /usr/bin/taosadapter ]] && /usr/bin/taosadapter & -taosd -- GitLab From 288afe340ca12121f76f9349444d32aa28dbc46a Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Mon, 20 Jun 2022 19:31:48 +0800 Subject: [PATCH 051/380] fix(query): offset optimation order by desc calc skip block error --- src/tsdb/src/tsdbRead.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 56e215e0b2..992b6285d6 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -1298,7 +1298,7 @@ static int32_t offsetSkipBlock(STsdbQueryHandle* q, SBlockInfo* pBlockInfo, int6 range.from = i; } } - range.to = 0; + range.to = sblock; taosArrayPush(pArray, &range); range.from = -1; break; @@ -1314,7 +1314,7 @@ static int32_t offsetSkipBlock(STsdbQueryHandle* q, SBlockInfo* pBlockInfo, int6 if(range.from == -1) { range.from = i; } else { - if(range.to + 1 != i) { + if(range.to - 1 != i) { // add the previous taosArrayPush(pArray, &range); range.from = i; @@ -1359,16 +1359,17 @@ static void shrinkBlocksByQuery(STsdbQueryHandle *pQueryHandle, STableCheckInfo SBlockIdx *compIndex = pQueryHandle->rhelper.pBlkIdx; bool order = ASCENDING_TRAVERSE(pQueryHandle->order); + TSKEY s = TSKEY_INITIAL_VAL, e = TSKEY_INITIAL_VAL; if (order) { assert(pCheckInfo->lastKey <= pQueryHandle->window.ekey && pQueryHandle->window.skey <= pQueryHandle->window.ekey); + s = pQueryHandle->window.skey; + e = pQueryHandle->window.ekey; } else { assert(pCheckInfo->lastKey >= pQueryHandle->window.ekey && pQueryHandle->window.skey >= pQueryHandle->window.ekey); + e = pQueryHandle->window.skey; + s = pQueryHandle->window.ekey; } - TSKEY s = TSKEY_INITIAL_VAL, e = TSKEY_INITIAL_VAL; - s = MIN(pCheckInfo->lastKey, pQueryHandle->window.ekey); - e = MAX(pCheckInfo->lastKey, pQueryHandle->window.ekey); - // discard the unqualified data block based on the query time window int32_t start = binarySearchForBlock(pCompInfo->blocks, compIndex->numOfBlocks, s, TSDB_ORDER_ASC); if (s > pCompInfo->blocks[start].keyLast) { -- GitLab From 0839e57da78eb21dceb29b406487eca7736c81db Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Mon, 20 Jun 2022 20:10:00 +0800 Subject: [PATCH 052/380] test: add test cases --- tests/pytest/dbmgmt/dbNameCaseSensitive.py | 3 +++ tests/pytest/table/columnNameCaseSensitive.py | 7 ++++++- tests/pytest/table/tagNameCaseSensitive.py | 7 ++++++- tests/pytest/table/tbNameCaseSensitive.py | 13 ++++++++++--- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/tests/pytest/dbmgmt/dbNameCaseSensitive.py b/tests/pytest/dbmgmt/dbNameCaseSensitive.py index 92a815b144..dd19a2b25b 100644 --- a/tests/pytest/dbmgmt/dbNameCaseSensitive.py +++ b/tests/pytest/dbmgmt/dbNameCaseSensitive.py @@ -52,6 +52,7 @@ class TDTestCase: tdSql.checkRows(0) tdSql.query("show create database `Db`") tdSql.checkRows(1) + tdSql.checkData(0, 1, "CREATE DATABASE `Db` REPLICA 1 QUORUM 1 DAYS 10 KEEP 3650 CACHE 16 BLOCKS 6 MINROWS 100 MAXROWS 4096 WAL 2 FSYNC 1000 COMP 2 CACHELAST 0 PRECISION 'ms' UPDATE 0") tdSql.execute("drop database db") @@ -67,6 +68,8 @@ class TDTestCase: tdSql.query("show databases") tdSql.checkRows(1) tdSql.checkData(0, 0, "电力系统") + tdSql.query("show create database `电力系统`") + tdSql.checkData(0, 1, "CREATE DATABASE `电力系统` REPLICA 1 QUORUM 1 DAYS 10 KEEP 3650 CACHE 16 BLOCKS 6 MINROWS 100 MAXROWS 4096 WAL 2 FSYNC 1000 COMP 2 CACHELAST 0 PRECISION 'ms' UPDATE 0") def stop(self): tdSql.close() diff --git a/tests/pytest/table/columnNameCaseSensitive.py b/tests/pytest/table/columnNameCaseSensitive.py index e5246e8175..b3ae863a46 100644 --- a/tests/pytest/table/columnNameCaseSensitive.py +++ b/tests/pytest/table/columnNameCaseSensitive.py @@ -136,6 +136,9 @@ class TDTestCase: tdSql.query("select `C1` as a from `STB2` where `C1` = 1") tdSql.checkRows(1) + tdSql.query("show create table `STB2`") + tdSql.checkData(0, 1, "CREATE TABLE `STB2` (`ts` TIMESTAMP,`c1` INT,`C1` INT) TAGS (`t1` INT)") + tdSql.execute("alter table `STB2` drop column `C1`") tdSql.query("describe tb2") tdSql.checkRows(2) @@ -143,6 +146,8 @@ class TDTestCase: # cornor cases tdSql.execute("alter table `STB2` add column `数量` int") tdSql.execute("insert into tt3(ts, `数量`) using `STB2` tags(2) values(now + 3s, 1)") + tdSql.query("show create table `STB2`") + tdSql.checkData(0, 1, "CREATE TABLE `STB2` (`ts` TIMESTAMP,`c1` INT,`数量` INT) TAGS (`t1` INT)") tdSql.query("select * from tt3") tdSql.checkRows(1) tdSql.query("select ts `TS` from tt3") @@ -151,7 +156,7 @@ class TDTestCase: tdSql.checkRows(1) tdSql.query("select ts as `时间戳` from tt3") tdSql.checkRows(1) - tdSql.query("select ts `时间戳` from tt3") + tdSql.query("select ts `时间戳` from tt3") tdSql.checkRows(1) def stop(self): diff --git a/tests/pytest/table/tagNameCaseSensitive.py b/tests/pytest/table/tagNameCaseSensitive.py index d448d702ca..ad0a960eb0 100644 --- a/tests/pytest/table/tagNameCaseSensitive.py +++ b/tests/pytest/table/tagNameCaseSensitive.py @@ -34,13 +34,18 @@ class TDTestCase: tdSql.query("select t1, `T1` from `STB3`") tdSql.checkRows(2) + tdSql.query("show create table `STB3`") + tdSql.checkData(0, 1, "CREATE TABLE `STB3` (`ts` TIMESTAMP,`c1` INT) TAGS (`t1` INT,`T1` INT)") + tdSql.execute("alter table `STB3` drop tag `T1`") tdSql.query("describe `STB3`") tdSql.checkRows(3) # cornor case - tdSql.execute("create table `STB5`(ts timestamp, c1 int) tags(t1 int, `标签` int)") + tdSql.execute("create table `STB5`(ts timestamp, c1 int) tags(t1 int, `标签` int)") tdSql.execute("insert into `测试` using `STB5` tags(1, 1) values(now, 1)") + tdSql.query("show create table `STB5`") + tdSql.checkData(0, 1, "CREATE TABLE `STB5` (`ts` TIMESTAMP,`c1` INT) TAGS (`t1` INT,`标签` INT)") tdSql.query("select * from `测试`") tdSql.checkRows(1) diff --git a/tests/pytest/table/tbNameCaseSensitive.py b/tests/pytest/table/tbNameCaseSensitive.py index 85e9b7d720..eafef9fc57 100644 --- a/tests/pytest/table/tbNameCaseSensitive.py +++ b/tests/pytest/table/tbNameCaseSensitive.py @@ -32,6 +32,7 @@ class TDTestCase: tdSql.checkRows(1) tdSql.query("show create table tb") tdSql.checkRows(1) + tdSql.checkData(0, 1, "CREATE TABLE `tb` (`ts` TIMESTAMP,`c1` INT)") tdSql.error("create table Tb(ts timestamp, c1 int)") tdSql.execute("create table `TB`(ts timestamp, c1 int)") @@ -40,6 +41,7 @@ class TDTestCase: tdSql.checkRows(2) tdSql.query("show create table `TB`") tdSql.checkRows(1) + tdSql.checkData(0, 1, "CREATE TABLE `TB` (`ts` TIMESTAMP,`c1` INT)") tdSql.query("describe tb") tdSql.checkRows(2) @@ -61,7 +63,7 @@ class TDTestCase: tdSql.query("show stables") tdSql.checkRows(1) - tdSql.error("create stable STb(ts timestamp, c1 int) tags(t1 int)") + tdSql.error("crate stable STb(ts timestamp, c1 int) tags(t1 int)") tdSql.error("create stable `stb`(ts timestamp, c1 int) tags(t1 int)") tdSql.execute("create stable `STB`(ts timestamp, c1 int) tags(t1 int)") tdSql.query("show stables") @@ -88,12 +90,15 @@ class TDTestCase: tdSql.query("select tbname from `STB`") tdSql.checkRows(2) - tdSql.execute("alter table stb add column c2 int") + tdSql.execute("alter table stb add column c2 int") tdSql.execute("alter table stb add tag t2 int") tdSql.execute("alter table `STB` add column c2 int") tdSql.execute("alter table `STB` add tag t2 int") tdSql.execute("alter table `TB` add column c2 int") + tdSql.query("show create table `STB`") + tdSql.checkData(0, 1, "CREATE TABLE `STB` (`ts` TIMESTAMP,`c1` INT,`c2` INT) TAGS (`t1` INT,`t2` INT)") + # corner cases tdSql.execute("create table `超级表`(ts timestamp, c1 int) tags(t1 int)") tdSql.execute("create table `子表一` using `超级表` tags(1)") @@ -111,7 +116,9 @@ class TDTestCase: tdSql.query("select * from `普通表`") tdSql.checkRows(1) tdSql.query("show tables") - tdSql.checkRows(8) + tdSql.checkRows(8) + tdSql.query("show create table `普通表`") + tdSql.checkData(0, 0, "CREATE TABLE `普通表` (`ts` TIMESTAMP,`c1` INT)") def stop(self): tdSql.close() -- GitLab From 0811b93a149e6eed3c603ef5505825d7437b1c30 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Mon, 20 Jun 2022 20:37:06 +0800 Subject: [PATCH 053/380] docs: Update 03-docker.md (#14021) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: Update 03-docker.md 增加使用 win 宿主机时,curl 的正确姿势。 * docs: CURL add -L parameters and "" in docker page * docs: CURL add -L parameters and "" in REST page --- docs/zh/14-reference/02-rest-api/02-rest-api.mdx | 14 +++++++------- docs/zh/27-train-faq/03-docker.md | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/zh/14-reference/02-rest-api/02-rest-api.mdx b/docs/zh/14-reference/02-rest-api/02-rest-api.mdx index 43099319b9..a8a92606e4 100644 --- a/docs/zh/14-reference/02-rest-api/02-rest-api.mdx +++ b/docs/zh/14-reference/02-rest-api/02-rest-api.mdx @@ -21,7 +21,7 @@ RESTful 接口不依赖于任何 TDengine 的库,因此客户端不需要安 下面示例是列出所有的数据库,请把 h1.taosdata.com 和 6041(缺省值)替换为实际运行的 TDengine 服务 FQDN 和端口号: ```html -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'show databases;' h1.taosdata.com:6041/rest/sql +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "show databases;" h1.taosdata.com:6041/rest/sql ``` 返回值结果如下表示验证通过: @@ -106,13 +106,13 @@ HTTP 请求的 BODY 里就是一个完整的 SQL 语句,SQL 语句中的数据 使用 `curl` 通过自定义身份认证方式来发起一个 HTTP Request,语法如下: ```bash -curl -H 'Authorization: Basic ' -d '' :/rest/sql/[db_name] +curl -L -H "Authorization: Basic " -d "" :/rest/sql/[db_name] ``` 或者 ```bash -curl -u username:password -d '' :/rest/sql/[db_name] +curl -L -u username:password -d "" :/rest/sql/[db_name] ``` 其中,`TOKEN` 为 `{username}:{password}` 经过 Base64 编码之后的字符串,例如 `root:taosdata` 编码后为 `cm9vdDp0YW9zZGF0YQ==` @@ -192,7 +192,7 @@ curl http://192.168.0.1:6041/rest/login/root/taosdata - 在 demo 库里查询表 d1001 的所有记录: ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001' 192.168.0.1:6041/rest/sql + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.d1001" 192.168.0.1:6041/rest/sql ``` 返回值: @@ -218,7 +218,7 @@ curl http://192.168.0.1:6041/rest/login/root/taosdata - 创建库 demo: ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'create database demo' 192.168.0.1:6041/rest/sql + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "create database demo" 192.168.0.1:6041/rest/sql ``` 返回值: @@ -240,7 +240,7 @@ curl http://192.168.0.1:6041/rest/login/root/taosdata HTTP 请求 URL 采用 `/rest/sqlt` 时,返回结果集的时间戳将采用 Unix 时间戳格式表示,例如 ```bash -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001' 192.168.0.1:6041/rest/sqlt +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.d1001" 192.168.0.1:6041/rest/sqlt ``` 返回结果: @@ -268,7 +268,7 @@ curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001 HTTP 请求 URL 采用 `/rest/sqlutc` 时,返回结果集的时间戳将采用 UTC 时间字符串表示,例如 ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.t1' 192.168.0.1:6041/rest/sqlutc + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.t1" 192.168.0.1:6041/rest/sqlutc ``` 返回值: diff --git a/docs/zh/27-train-faq/03-docker.md b/docs/zh/27-train-faq/03-docker.md index 7791569b25..72b4603dda 100644 --- a/docs/zh/27-train-faq/03-docker.md +++ b/docs/zh/27-train-faq/03-docker.md @@ -108,7 +108,7 @@ taos> 也可以在宿主机使用 curl 通过 RESTful 端口访问 Docker 容器内的 TDengine server。 ``` -curl -u root:taosdata -d 'show databases' 127.0.0.1:6041/rest/sql +curl -L -u root:taosdata -d "show databases" 127.0.0.1:6041/rest/sql ``` 输出示例如下: @@ -148,7 +148,7 @@ docker run -d --name tdengine-taosd -p 6030-6042:6030-6042 -p 6030-6042:6030-604 使用 curl 命令验证 RESTful 接口可以正常工作: ```bash -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'show databases;' 127.0.0.1:6041/rest/sql +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "show databases;" 127.0.0.1:6041/rest/sql ``` 输出示例如下: -- GitLab From 1c7a65ec9d4d67eae24b307dce605c682f4ae9d9 Mon Sep 17 00:00:00 2001 From: tangfangzhi Date: Mon, 20 Jun 2022 20:43:22 +0800 Subject: [PATCH 054/380] fix: force to clone python connector --- Jenkinsfile2 | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index c3b95a166f..e42a13c2fd 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -105,14 +105,9 @@ def sync_source() { ''' sh ''' cd ${WKC} - if [ ! -d src/connector/python/.github ]; then - rm -rf src/connector/python/* || : - rm -rf src/connector/python/.* || : - git clone --depth 1 https://github.com/taosdata/taos-connector-python src/connector/python || echo "failed to clone python connector" - else - cd src/connector/python || echo "src/connector/python not exist" - git pull || : - fi + rm -rf src/connector/python + mkdir -p src/connector/python + git clone --depth 1 https://github.com/taosdata/taos-connector-python src/connector/python || echo "failed to clone python connector" ''' } else if (env.CHANGE_URL =~ /\/TDinternal\//) { sh ''' @@ -124,14 +119,9 @@ def sync_source() { ''' sh ''' cd ${WKC} - if [ ! -d community/src/connector/python/.github ]; then - rm -rf community/src/connector/python/* || : - rm -rf community/src/connector/python/.* || : - git clone --depth 1 https://github.com/taosdata/taos-connector-python community/src/connector/python || echo "failed to clone python connector" - else - cd community/src/connector/python || echo "community/src/connector/python not exist" - git pull || : - fi + rm -rf src/connector/python + mkdir -p src/connector/python + git clone --depth 1 https://github.com/taosdata/taos-connector-python src/connector/python || echo "failed to clone python connector" ''' } else { sh ''' -- GitLab From b3b1372f261bd44f79484316d81f07f9170ae771 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Mon, 20 Jun 2022 20:46:48 +0800 Subject: [PATCH 055/380] docs: Update en 03-docker.md CURL add -L parameters and "" in docker\REST page --- docs/en/14-reference/02-rest-api/02-rest-api.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/en/14-reference/02-rest-api/02-rest-api.mdx b/docs/en/14-reference/02-rest-api/02-rest-api.mdx index 990af86196..fe18349a6d 100644 --- a/docs/en/14-reference/02-rest-api/02-rest-api.mdx +++ b/docs/en/14-reference/02-rest-api/02-rest-api.mdx @@ -21,7 +21,7 @@ The following example is in an Ubuntu environment and uses the `curl` tool to ve The following example lists all databases on the host h1.taosdata.com. To use it in your environment, replace `h1.taosdata.com` and `6041` (the default port) with the actual running TDengine service FQDN and port number. ```html -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'show databases;' h1.taosdata.com:6041/rest/sql +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "show databases;" h1.taosdata.com:6041/rest/sql ``` The following return value results indicate that the verification passed. @@ -106,13 +106,13 @@ The HTTP request's BODY is a complete SQL command, and the data table in the SQL Use `curl` to initiate an HTTP request with a custom authentication method, with the following syntax. ```bash -curl -H 'Authorization: Basic ' -d '' :/rest/sql/[db_name] +curl -L -H "Authorization: Basic " -d "" :/rest/sql/[db_name] ``` Or ```bash -curl -u username:password -d '' :/rest/sql/[db_name] +curl -L -u username:password -d "" :/rest/sql/[db_name] ``` where `TOKEN` is the string after Base64 encoding of `{username}:{password}`, e.g. `root:taosdata` is encoded as `cm9vdDp0YW9zZGF0YQ==`. @@ -192,7 +192,7 @@ Response body: - query all records from table d1001 of database demo ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001' 192.168.0.1:6041/rest/sql + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.d1001" 192.168.0.1:6041/rest/sql ``` Response body: @@ -218,7 +218,7 @@ Response body: - Create database demo: ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'create database demo' 192.168.0.1:6041/rest/sql + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "create database demo" 192.168.0.1:6041/rest/sql ``` Response body: @@ -240,7 +240,7 @@ Response body: When the HTTP request URL uses `/rest/sqlt`, the returned result set's timestamp value will be in Unix timestamp format, for example: ```bash -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001' 192.168.0.1:6041/rest/sqlt +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.d1001" 192.168.0.1:6041/rest/sqlt ``` Response body: @@ -268,7 +268,7 @@ Response body: When the HTTP request URL uses `/rest/sqlutc`, the timestamp of the returned result set will be expressed as a UTC format, for example: ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.t1' 192.168.0.1:6041/rest/sqlutc + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.t1" 192.168.0.1:6041/rest/sqlutc ``` Response body: -- GitLab From 69cd1e111355d02876aaa9f984a1ac1d23c7ef26 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Mon, 20 Jun 2022 20:52:09 +0800 Subject: [PATCH 056/380] docs: Update en 03-docker.md --- docs/en/27-train-faq/03-docker.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/27-train-faq/03-docker.md b/docs/en/27-train-faq/03-docker.md index afee13c137..0378fffb8b 100644 --- a/docs/en/27-train-faq/03-docker.md +++ b/docs/en/27-train-faq/03-docker.md @@ -109,7 +109,7 @@ taos> It's also able to access the REST interface provided by TDengine in container from the host. ``` -curl -u root:taosdata -d 'show databases' 127.0.0.1:6041/rest/sql +curl -L -u root:taosdata -d "show databases" 127.0.0.1:6041/rest/sql ``` Output is like below: @@ -147,7 +147,7 @@ docker run -d --name tdengine-taosd -p 6030-6042:6030-6042 -p 6030-6042:6030-604 - Verify the REST interface: ```bash -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'show databases;' 127.0.0.1:6041/rest/sql +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "show databases;" 127.0.0.1:6041/rest/sql ``` Below is an example output: -- GitLab From 6f7ad2a9aca9a393109d8efdf4f148a05c799d28 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Tue, 21 Jun 2022 09:02:48 +0800 Subject: [PATCH 057/380] fix: remove useless script from makepkg.sh --- packaging/tools/makepkg.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/packaging/tools/makepkg.sh b/packaging/tools/makepkg.sh index 139749e4e6..8c45b0a7d1 100755 --- a/packaging/tools/makepkg.sh +++ b/packaging/tools/makepkg.sh @@ -91,7 +91,6 @@ else ${build_dir}/bin/tarbitrator\ ${script_dir}/remove.sh \ ${script_dir}/set_core.sh \ - ${script_dir}/run_taosd_and_taosadapter.sh \ ${script_dir}/startPre.sh \ ${script_dir}/taosd-dump-cfg.gdb" fi @@ -158,7 +157,6 @@ if [ $adapterName != "taosadapter" ]; then sed -i "s/taosadapter/${adapterName}/g" ${install_dir}/cfg/$adapterName.service # !!! do not change taosadaptor here mv ${install_dir}/bin/taosadapter ${install_dir}/bin/${adapterName} - mv ${install_dir}/bin/run_taosd_and_taosadapter.sh ${install_dir}/bin/run_${serverName}_and_${adapterName}.sh mv ${install_dir}/bin/taosd-dump-cfg.gdb ${install_dir}/bin/${serverName}-dump-cfg.gdb fi -- GitLab From 99f42e93b12a69be36193b6534e5c40839ff8c45 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Tue, 21 Jun 2022 09:11:32 +0800 Subject: [PATCH 058/380] docs: remove useless script --- docs/en/14-reference/12-directory.md | 1 - docs/zh/14-reference/12-directory.md | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/en/14-reference/12-directory.md b/docs/en/14-reference/12-directory.md index 304e3bcb43..d6cffd22e0 100644 --- a/docs/en/14-reference/12-directory.md +++ b/docs/en/14-reference/12-directory.md @@ -26,7 +26,6 @@ All executable files of TDengine are in the _/usr/local/taos/bin_ directory by d - _remove.sh_: script to uninstall TDengine, please execute it carefully, link to the **rmtaos** command in the /usr/bin directory. Will remove the TDengine installation directory `/usr/local/taos`, but will keep `/etc/taos`, `/var/lib/taos`, `/var/log/taos` - _taosadapter_: server-side executable that provides RESTful services and accepts writing requests from a variety of other softwares - _tarbitrator_: provides arbitration for two-node cluster deployments -- _run_taosd_and_taosadapter.sh_: script to start both taosd and taosAdapter - _TDinsight.sh_: script to download TDinsight and install it - _set_core.sh_: script for setting up the system to generate core dump files for easy debugging - _taosd-dump-cfg.gdb_: script to facilitate debugging of taosd's gdb execution. diff --git a/docs/zh/14-reference/12-directory.md b/docs/zh/14-reference/12-directory.md index f8c8cb4a08..0caf7e03c3 100644 --- a/docs/zh/14-reference/12-directory.md +++ b/docs/zh/14-reference/12-directory.md @@ -26,7 +26,6 @@ TDengine 的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下 - _remove.sh_:卸载 TDengine 的脚本,请谨慎执行,链接到/usr/bin 目录下的**rmtaos**命令。会删除 TDengine 的安装目录/usr/local/taos,但会保留/etc/taos、/var/lib/taos、/var/log/taos - _taosadapter_: 提供 RESTful 服务和接受其他多种软件写入请求的服务端可执行文件 - _tarbitrator_: 提供双节点集群部署的仲裁功能 -- _run_taosd_and_taosadapter.sh_:同时启动 taosd 和 taosAdapter 的脚本 - _TDinsight.sh_:用于下载 TDinsight 并安装的脚本 - _set_core.sh_:用于方便调试设置系统生成 core dump 文件的脚本 - _taosd-dump-cfg.gdb_:用于方便调试 taosd 的 gdb 执行脚本。 -- GitLab From d6fdf0b920462ba5e5210e7df71649654c0c1302 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Tue, 21 Jun 2022 11:34:06 +0800 Subject: [PATCH 059/380] test: add test cases for OpenTSDB line and json protocol --- tests/pytest/dbmgmt/dbNameCaseSensitive.py | 2 +- .../pytest/insert/schemalessCaseSensitive.py | 87 ++++++++++++++++++- tests/pytest/table/tbNameCaseSensitive.py | 2 +- 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/tests/pytest/dbmgmt/dbNameCaseSensitive.py b/tests/pytest/dbmgmt/dbNameCaseSensitive.py index dd19a2b25b..065b92c6e2 100644 --- a/tests/pytest/dbmgmt/dbNameCaseSensitive.py +++ b/tests/pytest/dbmgmt/dbNameCaseSensitive.py @@ -52,7 +52,7 @@ class TDTestCase: tdSql.checkRows(0) tdSql.query("show create database `Db`") tdSql.checkRows(1) - tdSql.checkData(0, 1, "CREATE DATABASE `Db` REPLICA 1 QUORUM 1 DAYS 10 KEEP 3650 CACHE 16 BLOCKS 6 MINROWS 100 MAXROWS 4096 WAL 2 FSYNC 1000 COMP 2 CACHELAST 0 PRECISION 'ms' UPDATE 0") + tdSql.checkData(0, 1, "CREATE DATABASE `Db` REPLICA 1 QUORUM 1 DAYS 10 KEEP 3650 CACHE 16 BLOCKS 6 MINROWS 100 MAXROWS 4096 WAL 2 FSYNC 1000 COMP 2 CACHELAST 1 PRECISION 'ms' UPDATE 0") tdSql.execute("drop database db") diff --git a/tests/pytest/insert/schemalessCaseSensitive.py b/tests/pytest/insert/schemalessCaseSensitive.py index c7db1bed1a..bf92624ff1 100644 --- a/tests/pytest/insert/schemalessCaseSensitive.py +++ b/tests/pytest/insert/schemalessCaseSensitive.py @@ -15,6 +15,7 @@ from util.log import * from util.cases import * from util.sql import * from util.types import TDSmlProtocolType, TDSmlTimestampType +import json class TDTestCase: def init(self, conn, logSql): @@ -24,9 +25,19 @@ class TDTestCase: def run(self): - # schemaless - tdSql.execute("create database line_insert precision 'ns' ") - tdSql.execute("use line_insert") + # influxDB Line Protocol + self.influxDBLineProtocol() + + # OpenTSDB Line Protocol + self.openTSDBLineProtocol() + + # OpenTSDB JSON Protocol + self.openTSDBJSONProtocol() + + def influxDBLineProtocol(self): + print("===== influxDB Line Protocol Case Sensitive Test =====\n") + tdSql.execute("create database influxdb precision 'ns' ") + tdSql.execute("use influxdb") lines = [ "St,deviceId=1i voltage=1,phase=\"Test\" 1626006833639000000", "St,DeviceId=3i voltage=2,phase=\"Test\" 1626006833639000000", @@ -41,7 +52,7 @@ class TDTestCase: "超级表,deviceId=\"sensor0\" 电压=3i 1646053743694400035", ] - code = self._conn.schemaless_insert(lines, TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + self._conn.schemaless_insert(lines, TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) tdSql.query("show stables") tdSql.checkRows(3) @@ -60,6 +71,74 @@ class TDTestCase: tdSql.query("select * from `超级表`") tdSql.checkRows(1) + def openTSDBLineProtocol(self): + print("===== OpenTSDB Line Protocol Case Sensitive Test =====\n") + tdSql.execute("create database opentsdbline") + tdSql.execute("use opentsdbline") + + # format: =[ =] + lines = [ + "meters.current 1648432611249 10.3 location=California.SanFrancisco groupid=2", + "meters.Current 1648432611250 12.6 location=California.SanFrancisco groupid=2", + "meters.Current 1648432611249 10.8 Location=California.LosAngeles groupid=3", + "Meters.current 1648432611250 11.3 location=California.LosAngeles Groupid=3", + "电表 1648432611250 11.3 位置=California.LosAngeles Groupid=3" + ] + + self._conn.schemaless_insert(lines, TDSmlProtocolType.TELNET.value, None) + tdSql.query("show stables") + tdSql.checkRows(4) + + tdSql.query("show tables") + tdSql.checkRows(5) + + tdSql.query("describe `meters.Current`") + tdSql.checkRows(5) + tdSql.checkData(2, 0, "groupid") + tdSql.checkData(3, 0, "location") + tdSql.checkData(4, 0, "Location") + + tdSql.query("describe `Meters.current`") + tdSql.checkRows(4) + tdSql.checkData(2, 0, "Groupid") + tdSql.checkData(3, 0, "location") + + tdSql.query("describe `电表`") + tdSql.checkRows(4) + tdSql.checkData(2, 0, "Groupid") + tdSql.checkData(3, 0, "位置") + + def openTSDBJSONProtocol(self): + print("===== OpenTSDB JSON Protocol Case Sensitive Test =====\n") + tdSql.execute("create database opentsdbjson") + tdSql.execute("use opentsdbjson") + + lines = [ + {"metric": "meters.current", "timestamp": 1648432611249, "value": 10.3, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, + {"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219, "tags": {"Location": "California.LosAngeles", "groupid": 1}}, + {"metric": "meters.Current", "timestamp": 1648432611250, "value": 12.6, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, + {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}, + {"metric": "电压", "timestamp": 1648432611250, "value": 221, "tags": {"位置": "California.LosAngeles", "groupid": 1}} + ] + + self._conn.schemaless_insert([json.dumps(lines)], TDSmlProtocolType.JSON.value, None) + tdSql.query("show stables") + tdSql.checkRows(4) + + tdSql.query("show tables") + tdSql.checkRows(5) + + tdSql.query("describe `meters.Current`") + tdSql.checkRows(4) + + tdSql.query("describe `meters.voltage`") + tdSql.checkRows(5) + tdSql.checkData(3, 0, "Location") + tdSql.checkData(4, 0, "location") + + tdSql.query("describe `电压`") + tdSql.checkRows(4) + tdSql.checkData(3, 0, "位置") def stop(self): tdSql.close() diff --git a/tests/pytest/table/tbNameCaseSensitive.py b/tests/pytest/table/tbNameCaseSensitive.py index eafef9fc57..ee6a24d786 100644 --- a/tests/pytest/table/tbNameCaseSensitive.py +++ b/tests/pytest/table/tbNameCaseSensitive.py @@ -118,7 +118,7 @@ class TDTestCase: tdSql.query("show tables") tdSql.checkRows(8) tdSql.query("show create table `普通表`") - tdSql.checkData(0, 0, "CREATE TABLE `普通表` (`ts` TIMESTAMP,`c1` INT)") + tdSql.checkData(0, 1, "CREATE TABLE `普通表` (`ts` TIMESTAMP,`c1` INT)") def stop(self): tdSql.close() -- GitLab From 1890e507dcc320357f259baed3ccc6891047a944 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 21 Jun 2022 13:31:04 +0800 Subject: [PATCH 060/380] fix(query): multi column group by compare key --- src/query/src/qExecutor.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 492bf5241c..fdf8073e28 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1588,6 +1588,8 @@ static bool initGroupbyInfo(const SSDataBlock *pSDataBlock, const SGroupbyExpr * return true; } pInfo->pGroupbyDataInfo = taosArrayInit(pGroupbyExpr->numOfGroupCols, sizeof(SGroupbyDataInfo)); + // head put key length (int32_t type) + pInfo->totalBytes = sizeof(int32_t); for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols; ++k) { SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, k); @@ -1613,7 +1615,6 @@ static bool initGroupbyInfo(const SSDataBlock *pSDataBlock, const SGroupbyExpr * } } } - pInfo->totalBytes += (int32_t)strlen(MULTI_KEY_DELIM) * pGroupbyExpr->numOfGroupCols; return true; } @@ -1624,7 +1625,7 @@ static void buildGroupbyKeyBuf(const SSDataBlock *pSDataBlock, SGroupbyOperatorI *buf = NULL; return; } - *buf = p; + *buf = p; for (int32_t i = 0; i < taosArrayGetSize(pInfo->pGroupbyDataInfo); i++) { SGroupbyDataInfo *pDataInfo = taosArrayGet(pInfo->pGroupbyDataInfo, i); @@ -1642,30 +1643,24 @@ static void buildGroupbyKeyBuf(const SSDataBlock *pSDataBlock, SGroupbyOperatorI memcpy(p, val, pDataInfo->bytes); p += pDataInfo->bytes; } - - memcpy(p, MULTI_KEY_DELIM, strlen(MULTI_KEY_DELIM)); - p += strlen(MULTI_KEY_DELIM); } + + // calc keyLen and save + int32_t keyLen = (p - *buf); + *(int32_t *)(*buf) = keyLen; } static bool isGroupbyKeyEqual(void *a, void *b, void *ext) { SGroupbyOperatorInfo *pInfo = (SGroupbyOperatorInfo *)ext; - if (memcmp(a, b, pInfo->totalBytes) == 0) { - return true; + int32_t len1 = *(int32_t *)a; + int32_t len2 = *(int32_t *)b; + if (len1 != len2) { + return false; } - int32_t offset = 0; - for (int32_t i = 0; i < taosArrayGetSize(pInfo->pGroupbyDataInfo); i++) { - SGroupbyDataInfo *pDataInfo = taosArrayGet(pInfo->pGroupbyDataInfo, i); + char *a1 = (char *)a + sizeof(int32_t); + char *b1 = (char *)b + sizeof(int32_t); - char *k1 = (char *)a + offset; - char *k2 = (char *)b + offset; - if (getComparFunc(pDataInfo->type, 0)(k1, k2) != 0) { - return false; - } - offset += pDataInfo->bytes; - offset += (int32_t)strlen(MULTI_KEY_DELIM); - } - return true; + return memcmp(a1, b1, len1) == 0; } static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { -- GitLab From db2688732c2b0b28391cfb8fc8e7529109397b34 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 21 Jun 2022 13:32:31 +0800 Subject: [PATCH 061/380] fix(query): multi column group by build --- src/query/src/qExecutor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index fdf8073e28..1c81692e50 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1651,7 +1651,6 @@ static void buildGroupbyKeyBuf(const SSDataBlock *pSDataBlock, SGroupbyOperatorI } static bool isGroupbyKeyEqual(void *a, void *b, void *ext) { - SGroupbyOperatorInfo *pInfo = (SGroupbyOperatorInfo *)ext; int32_t len1 = *(int32_t *)a; int32_t len2 = *(int32_t *)b; if (len1 != len2) { -- GitLab From 316f55def8a5d422cc9e9485382d18169ea6d83f Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Tue, 21 Jun 2022 13:38:39 +0800 Subject: [PATCH 062/380] test: update test cases --- tests/pytest/dbmgmt/dbNameCaseSensitive.py | 6 ++++-- tests/pytest/insert/schemalessCaseSensitive.py | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/pytest/dbmgmt/dbNameCaseSensitive.py b/tests/pytest/dbmgmt/dbNameCaseSensitive.py index 065b92c6e2..f28b9fd016 100644 --- a/tests/pytest/dbmgmt/dbNameCaseSensitive.py +++ b/tests/pytest/dbmgmt/dbNameCaseSensitive.py @@ -52,7 +52,8 @@ class TDTestCase: tdSql.checkRows(0) tdSql.query("show create database `Db`") tdSql.checkRows(1) - tdSql.checkData(0, 1, "CREATE DATABASE `Db` REPLICA 1 QUORUM 1 DAYS 10 KEEP 3650 CACHE 16 BLOCKS 6 MINROWS 100 MAXROWS 4096 WAL 2 FSYNC 1000 COMP 2 CACHELAST 1 PRECISION 'ms' UPDATE 0") + sql = tdSql.getData(0, 1) + tdSql.checkEqual(True, sql.startswith("CREATE DATABASE `Db`")) tdSql.execute("drop database db") @@ -69,7 +70,8 @@ class TDTestCase: tdSql.checkRows(1) tdSql.checkData(0, 0, "电力系统") tdSql.query("show create database `电力系统`") - tdSql.checkData(0, 1, "CREATE DATABASE `电力系统` REPLICA 1 QUORUM 1 DAYS 10 KEEP 3650 CACHE 16 BLOCKS 6 MINROWS 100 MAXROWS 4096 WAL 2 FSYNC 1000 COMP 2 CACHELAST 0 PRECISION 'ms' UPDATE 0") + sql = tdSql.getData(0, 1) + tdSql.checkEqual(True, sql.startswith("CREATE DATABASE `电力系统`")) def stop(self): tdSql.close() diff --git a/tests/pytest/insert/schemalessCaseSensitive.py b/tests/pytest/insert/schemalessCaseSensitive.py index bf92624ff1..c9cf133f9d 100644 --- a/tests/pytest/insert/schemalessCaseSensitive.py +++ b/tests/pytest/insert/schemalessCaseSensitive.py @@ -81,6 +81,7 @@ class TDTestCase: "meters.current 1648432611249 10.3 location=California.SanFrancisco groupid=2", "meters.Current 1648432611250 12.6 location=California.SanFrancisco groupid=2", "meters.Current 1648432611249 10.8 Location=California.LosAngeles groupid=3", + "meters.Current 1648432611249 10.8 Location=California.LosAngeles location=California.SanFrancisco groupid=3", "Meters.current 1648432611250 11.3 location=California.LosAngeles Groupid=3", "电表 1648432611250 11.3 位置=California.LosAngeles Groupid=3" ] @@ -90,7 +91,7 @@ class TDTestCase: tdSql.checkRows(4) tdSql.query("show tables") - tdSql.checkRows(5) + tdSql.checkRows(6) tdSql.query("describe `meters.Current`") tdSql.checkRows(5) @@ -118,6 +119,7 @@ class TDTestCase: {"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219, "tags": {"Location": "California.LosAngeles", "groupid": 1}}, {"metric": "meters.Current", "timestamp": 1648432611250, "value": 12.6, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}, + {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "Location": "California.SanFrancisco", "groupid": 2}}, {"metric": "电压", "timestamp": 1648432611250, "value": 221, "tags": {"位置": "California.LosAngeles", "groupid": 1}} ] @@ -126,7 +128,7 @@ class TDTestCase: tdSql.checkRows(4) tdSql.query("show tables") - tdSql.checkRows(5) + tdSql.checkRows(6) tdSql.query("describe `meters.Current`") tdSql.checkRows(4) -- GitLab From b7c4ccff3393b7fbe76f0416f4546e3880cc09ac Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 21 Jun 2022 15:28:56 +0800 Subject: [PATCH 063/380] fix(query): multi group by key add split on each value --- src/query/src/qExecutor.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 1c81692e50..558c82d4d3 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1615,6 +1615,7 @@ static bool initGroupbyInfo(const SSDataBlock *pSDataBlock, const SGroupbyExpr * } } } + pInfo->totalBytes += (int32_t)strlen(MULTI_KEY_DELIM) * pGroupbyExpr->numOfGroupCols return true; } @@ -1643,6 +1644,9 @@ static void buildGroupbyKeyBuf(const SSDataBlock *pSDataBlock, SGroupbyOperatorI memcpy(p, val, pDataInfo->bytes); p += pDataInfo->bytes; } + + memcpy(p, MULTI_KEY_DELIM, strlen(MULTI_KEY_DELIM)); + p += strlen(MULTI_KEY_DELIM); } // calc keyLen and save -- GitLab From 24d5178466becf6a2cd85a111d93db1d70dc49ee Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 21 Jun 2022 15:30:17 +0800 Subject: [PATCH 064/380] fix(query): multi group by key add split on each value1 --- src/query/src/qExecutor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 558c82d4d3..1cd333690f 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1615,7 +1615,7 @@ static bool initGroupbyInfo(const SSDataBlock *pSDataBlock, const SGroupbyExpr * } } } - pInfo->totalBytes += (int32_t)strlen(MULTI_KEY_DELIM) * pGroupbyExpr->numOfGroupCols + pInfo->totalBytes += (int32_t)strlen(MULTI_KEY_DELIM) * pGroupbyExpr->numOfGroupCols; return true; } -- GitLab From 327921fd80398699084b332f1a1928fa7ada9c9d Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 21 Jun 2022 16:14:04 +0800 Subject: [PATCH 065/380] fix: remove unused script in more files (#14060) --- packaging/tools/install.sh | 2 -- packaging/tools/make_install.sh | 3 --- packaging/tools/remove.sh | 1 - 3 files changed, 6 deletions(-) diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index 85280cc509..d74a962210 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -199,7 +199,6 @@ function install_bin() { ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : ${csudo}rm -f ${bin_link_dir}/tarbitrator || : ${csudo}rm -f ${bin_link_dir}/set_core || : - ${csudo}rm -f ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : ${csudo}rm -f ${bin_link_dir}/TDinsight.sh || : ${csudo}cp -r ${script_dir}/bin/* ${install_main_dir}/bin && ${csudo}chmod 0555 ${install_main_dir}/bin/* @@ -214,7 +213,6 @@ function install_bin() { [ -x ${install_main_dir}/bin/TDinsight.sh ] && ${csudo}ln -s ${install_main_dir}/bin/TDinsight.sh ${bin_link_dir}/TDinsight.sh || : [ -x ${install_main_dir}/bin/remove.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/${uninstallScript} || : [ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || : - [ -x ${install_main_dir}/bin/run_${serverName}_and_${adapterName}.sh ] && ${csudo}ln -s ${install_main_dir}/bin/run_${serverName}_and_${adapterName}.sh ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : [ -x ${install_main_dir}/bin/tarbitrator ] && ${csudo}ln -s ${install_main_dir}/bin/tarbitrator ${bin_link_dir}/tarbitrator || : if [ "$verMode" == "cluster" ]; then diff --git a/packaging/tools/make_install.sh b/packaging/tools/make_install.sh index bcb3664c29..c40fe14e3a 100755 --- a/packaging/tools/make_install.sh +++ b/packaging/tools/make_install.sh @@ -178,7 +178,6 @@ function install_bin() { if [ "$osType" != "Darwin" ]; then ${csudo}rm -f ${bin_link_dir}/perfMonitor || : ${csudo}rm -f ${bin_link_dir}/set_core || : - ${csudo}rm -f ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : ${csudo}cp -r ${binary_dir}/build/bin/${clientName} ${install_main_dir}/bin || : @@ -192,7 +191,6 @@ function install_bin() { ${csudo}cp -r ${script_dir}/taosd-dump-cfg.gdb ${install_main_dir}/bin ${csudo}cp -r ${script_dir}/remove.sh ${install_main_dir}/bin ${csudo}cp -r ${script_dir}/set_core.sh ${install_main_dir}/bin - ${csudo}cp -r ${script_dir}/run_${serverName}_and_${adapterName}.sh ${install_main_dir}/bin ${csudo}cp -r ${script_dir}/startPre.sh ${install_main_dir}/bin ${csudo}chmod 0555 ${install_main_dir}/bin/* @@ -204,7 +202,6 @@ function install_bin() { [ -x ${install_main_dir}/bin/${demoName} ] && ${csudo}ln -s ${install_main_dir}/bin/${demoName} ${bin_link_dir}/${demoName} || : [ -x ${install_main_dir}/bin/perfMonitor ] && ${csudo}ln -s ${install_main_dir}/bin/perfMonitor ${bin_link_dir}/perfMonitor || : [ -x ${install_main_dir}/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || : - [ -x ${install_main_dir}/run_${serverName}_and_${adapterName}.sh ] && ${csudo}ln -s ${install_main_dir}/bin/run_${serverName}_and_${adapterName}.sh ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : [ -x ${install_main_dir}/bin/remove.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/${uninstallScript} || : else diff --git a/packaging/tools/remove.sh b/packaging/tools/remove.sh index db8a209747..cb20085125 100755 --- a/packaging/tools/remove.sh +++ b/packaging/tools/remove.sh @@ -81,7 +81,6 @@ function clean_bin() { ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : ${csudo}rm -f ${bin_link_dir}/tarbitrator || : ${csudo}rm -f ${bin_link_dir}/set_core || : - ${csudo}rm -f ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : ${csudo}rm -f ${bin_link_dir}/TDinsight.sh || : } -- GitLab From 14275d9ce13786457731c173ff2d32723c8e2a8c Mon Sep 17 00:00:00 2001 From: Sunshine Chan Date: Tue, 21 Jun 2022 16:25:00 +0800 Subject: [PATCH 066/380] ADD container --- .devcontainer/Dockerfile | 9 +++++++++ .devcontainer/devcontainer.json | 34 +++++++++++++++++++++++++++++++++ .devcontainer/sources.list | 10 ++++++++++ 3 files changed, 53 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/sources.list diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000000..6de78c5b11 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,9 @@ +# [Choice] Ubuntu version (use jammy or bionic on local arm64/Apple Silicon): jammy, focal, bionic +ARG VARIANT="bullseye" +FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT} +# FROM ubuntu:20.04 +# Options for setup script +# ARG INSTALL_ZSH="true" +# ARG UPGRADE_PACKAGES="true" +ADD sources.list /etc/apt/ +RUN apt-get update && apt-get -y install tree vim tmux python3-pip gcc cmake build-essential git gdb \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..7b68e371c9 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,34 @@ +{ + "name": "Ubuntu", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick an Ubuntu version: jammy / ubuntu-22.04, focal / ubuntu-20.04, bionic /ubuntu-18.04 + // Use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon. + "args": { "VARIANT": "ubuntu-20.04" } + }, + "runArgs": [ + "--cap-add=SYS_PTRACE", + "--security-opt", + "seccomp=unconfined" + ], + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "uname -a", + + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "root", + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cmake-tools", + "austin.code-gnu-global", + "visualstudioexptteam.vscodeintel", + "eamodio.gitlens", + "matepek.vscode-catch2-test-adapter", + "spmeesseman.vscode-taskexplorer", + "cschlosser.doxdocgen", + "urosvujosevic.explorer-manager" + ] + +} diff --git a/.devcontainer/sources.list b/.devcontainer/sources.list new file mode 100644 index 0000000000..c48fbd9ac3 --- /dev/null +++ b/.devcontainer/sources.list @@ -0,0 +1,10 @@ +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal universe +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates universe +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal multiverse +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates multiverse +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security universe +deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security multiverse \ No newline at end of file -- GitLab From 3aafd17a7ab7123c4bf8164939bdc57954da370a Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 21 Jun 2022 16:49:21 +0800 Subject: [PATCH 067/380] fix(query): multi group by fixed overwrite context by write head len --- src/query/src/qExecutor.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 1cd333690f..cb0c8527fc 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1627,6 +1627,7 @@ static void buildGroupbyKeyBuf(const SSDataBlock *pSDataBlock, SGroupbyOperatorI return; } *buf = p; + p += sizeof(int32_t); for (int32_t i = 0; i < taosArrayGetSize(pInfo->pGroupbyDataInfo); i++) { SGroupbyDataInfo *pDataInfo = taosArrayGet(pInfo->pGroupbyDataInfo, i); @@ -1650,7 +1651,7 @@ static void buildGroupbyKeyBuf(const SSDataBlock *pSDataBlock, SGroupbyOperatorI } // calc keyLen and save - int32_t keyLen = (p - *buf); + int32_t keyLen = (p - *buf) - sizeof(int32_t); *(int32_t *)(*buf) = keyLen; } @@ -1706,7 +1707,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn setParamForStableStddevByColData(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, pOperator->pExpr, pInfo); } - int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, pInfo->prevData, type, pInfo->totalBytes, item->groupIndex); + int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, pInfo->prevData, type, *(int32_t *)pInfo->prevData, item->groupIndex); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); } -- GitLab From 6cb29ed298a8274e2eeb05d2af1b2b040f664763 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 21 Jun 2022 17:07:30 +0800 Subject: [PATCH 068/380] fix(query): fixed end call calc prekey --- src/query/src/qExecutor.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index cb0c8527fc..e92666ca31 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1707,7 +1707,9 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn setParamForStableStddevByColData(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, pOperator->pExpr, pInfo); } - int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, pInfo->prevData, type, *(int32_t *)pInfo->prevData, item->groupIndex); + char *preKey = pInfo->prevData + sizeof(int32_t); + int32_t keyLen = *(int32_t *)pInfo->prevData; + int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, preKey, type, keyLen, item->groupIndex); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); } @@ -1729,7 +1731,9 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn if (pQueryAttr->stableQuery && pQueryAttr->stabledev && (pRuntimeEnv->prevResult != NULL)) { setParamForStableStddevByColData(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, pOperator->pExpr, pInfo); } - int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, pInfo->prevData, type, pInfo->totalBytes, item->groupIndex); + char *preKey = pInfo->prevData + sizeof(int32_t); + int32_t keyLen = *(int32_t *)pInfo->prevData; + int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, preKey, type, keyLen, item->groupIndex); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); } -- GitLab From 425b4c68077c5bf490c25df9d5210793fe37da4c Mon Sep 17 00:00:00 2001 From: SunShine Chan Date: Tue, 21 Jun 2022 17:28:01 +0800 Subject: [PATCH 069/380] fix[TSDB]: fix extraRow was set but never used --- src/tsdb/src/tsdbRead.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 992b6285d6..05928e60fa 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -986,7 +986,7 @@ static SMemRow getSMemRowInTableMem(STableCheckInfo* pCheckInfo, int32_t order, return rmem; } else { pCheckInfo->chosen = CHECKINFO_CHOSEN_BOTH; - extraRow = rimem; + *extraRow = rimem; return rmem; } } else { -- GitLab From 5a53e2356359c917454ccd9771630094d6a1bb71 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 21 Jun 2022 19:38:39 +0800 Subject: [PATCH 070/380] fix(query): fixed stddev prevData calc value --- src/query/src/qExecutor.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index e92666ca31..7d4b0b7edb 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -4315,14 +4315,15 @@ void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunction // find colid in dataBlock int32_t bytes, offset = 0; char* val = NULL; + char* prevData = pInfo->prevData + sizeof(int32_t); // head is key length (int32_t type) for (int32_t idx = 0; idx < taosArrayGetSize(pInfo->pGroupbyDataInfo); idx++) { SGroupbyDataInfo *pDataInfo = taosArrayGet(pInfo->pGroupbyDataInfo, idx); if (pDataInfo->index == pExpr1->colInfo.colId) { bytes = pDataInfo->bytes; - val = pInfo->prevData + offset; + val = prevData + offset; break; } - offset += pDataInfo->bytes; + offset += pDataInfo->bytes + strlen(MULTI_KEY_DELIM); // multi value split by MULTI_KEY_DELIM } if (val == NULL) { continue; } -- GitLab From 3f30b3c5b4460b00516de7d9dae47ecd0599ad3f Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Tue, 21 Jun 2022 17:38:18 +0800 Subject: [PATCH 071/380] fix: change the default maxDbs of root acct to INT16_MAX --- src/mnode/src/mnodeAcct.c | 2 +- tests/script/unique/account/paras.sim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mnode/src/mnodeAcct.c b/src/mnode/src/mnodeAcct.c index 64cfa28917..0ec330841c 100644 --- a/src/mnode/src/mnodeAcct.c +++ b/src/mnode/src/mnodeAcct.c @@ -215,7 +215,7 @@ static int32_t mnodeCreateRootAcct() { taosEncryptPass((uint8_t *)TSDB_DEFAULT_PASS, strlen(TSDB_DEFAULT_PASS), pAcct->pass); pAcct->cfg = (SAcctCfg){ .maxUsers = 128, - .maxDbs = 128, + .maxDbs = INT16_MAX, .maxTimeSeries = INT32_MAX, .maxConnections = 1024, .maxStreams = 1000, diff --git a/tests/script/unique/account/paras.sim b/tests/script/unique/account/paras.sim index 102f5b6a38..77e010f5bd 100644 --- a/tests/script/unique/account/paras.sim +++ b/tests/script/unique/account/paras.sim @@ -17,7 +17,7 @@ endi if $data02 != 3/128 then return -1 endi -if $data03 != 0/128 then +if $data03 != 0/32767 then return -1 endi if $data04 != 0/2147483647 then @@ -111,4 +111,4 @@ if $data16 != 0.000/10.000 then return -1 endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +system sh/exec.sh -n dnode1 -s stop -x SIGINT -- GitLab From 35a05770b577aff29ecfad791d79c0b8ec2e075e Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 22 Jun 2022 00:27:55 +0800 Subject: [PATCH 072/380] fix: update taos-tools (#14084) for 2.6 [TD-13052] --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 28a49b447f..d3c29fb492 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 28a49b447f71c4f014ebbac858b7215b897d57fd +Subproject commit d3c29fb492514cbaf08cb533976121bff5d94dea -- GitLab From 52f1842e84d2ef7bc413c177c3451ea747c1ec4e Mon Sep 17 00:00:00 2001 From: tangfangzhi Date: Wed, 22 Jun 2022 09:25:52 +0800 Subject: [PATCH 073/380] ci: add make install process in ci --- Jenkinsfile2 | 1 + 1 file changed, 1 insertion(+) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index e42a13c2fd..79954fb969 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -144,6 +144,7 @@ def pre_test() { go env -w GO111MODULE=on cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true > /dev/null make -j8 >/dev/null + make install ''' return 1 } -- GitLab From 798937be4db519bc7c89980f1a25b637e3af1b6e Mon Sep 17 00:00:00 2001 From: dongyanqiong Date: Wed, 22 Jun 2022 11:18:20 +0800 Subject: [PATCH 074/380] build: release script modify #TS-1618 --- packaging/release.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/release.sh b/packaging/release.sh index 354d713e28..d5dcb3330c 100755 --- a/packaging/release.sh +++ b/packaging/release.sh @@ -202,6 +202,7 @@ fi if [[ "$dbName" != "taos" ]]; then source ${enterprise_dir}/packaging/oem/sed_$dbName.sh replace_community_$dbName + replace_output_$dbName fi if [[ "$httpdBuild" == "true" ]]; then @@ -228,6 +229,7 @@ if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" = else if [[ "$dbName" != "taos" ]]; then replace_enterprise_$dbName + replace_output_$dbName fi cmake ../../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} -DBUILD_HTTP=${BUILD_HTTP} -DBUILD_TOOLS=${BUILD_TOOLS} ${allocator_macro} fi -- GitLab From 1dc929fa58d0673e050b5318a07631844b50ccfc Mon Sep 17 00:00:00 2001 From: dingbo Date: Wed, 22 Jun 2022 13:42:44 +0800 Subject: [PATCH 075/380] docs:change master/slave to leader/follower --- docs/en/10-cluster/02-cluster-mgmt.md | 50 ++++++++-------- docs/en/10-cluster/03-ha-and-lb.md | 6 +- .../15146-tdengine-monitor-dashboard.json | 8 +-- .../assets/tdengine-grafana-7.x.json | 8 +-- docs/en/14-reference/07-tdinsight/index.md | 6 +- docs/en/21-tdinternal/01-arch.md | 60 +++++++++---------- 6 files changed, 69 insertions(+), 69 deletions(-) diff --git a/docs/en/10-cluster/02-cluster-mgmt.md b/docs/en/10-cluster/02-cluster-mgmt.md index 674c92e276..bd3386c411 100644 --- a/docs/en/10-cluster/02-cluster-mgmt.md +++ b/docs/en/10-cluster/02-cluster-mgmt.md @@ -54,14 +54,14 @@ Database changed. taos> show vgroups; vgId | tables | status | onlines | v1_dnode | v1_status | compacting | ========================================================================================== - 14 | 38000 | ready | 1 | 1 | master | 0 | - 15 | 38000 | ready | 1 | 1 | master | 0 | - 16 | 38000 | ready | 1 | 1 | master | 0 | - 17 | 38000 | ready | 1 | 1 | master | 0 | - 18 | 37001 | ready | 1 | 1 | master | 0 | - 19 | 37000 | ready | 1 | 1 | master | 0 | - 20 | 37000 | ready | 1 | 1 | master | 0 | - 21 | 37000 | ready | 1 | 1 | master | 0 | + 14 | 38000 | ready | 1 | 1 | leader | 0 | + 15 | 38000 | ready | 1 | 1 | leader | 0 | + 16 | 38000 | ready | 1 | 1 | leader | 0 | + 17 | 38000 | ready | 1 | 1 | leader | 0 | + 18 | 37001 | ready | 1 | 1 | leader | 0 | + 19 | 37000 | ready | 1 | 1 | leader | 0 | + 20 | 37000 | ready | 1 | 1 | leader | 0 | + 21 | 37000 | ready | 1 | 1 | leader | 0 | Query OK, 8 row(s) in set (0.001154s) ``` @@ -161,14 +161,14 @@ First `show vgroups` is executed to show the vgroup distribution. taos> show vgroups; vgId | tables | status | onlines | v1_dnode | v1_status | compacting | ========================================================================================== - 14 | 38000 | ready | 1 | 3 | master | 0 | - 15 | 38000 | ready | 1 | 3 | master | 0 | - 16 | 38000 | ready | 1 | 3 | master | 0 | - 17 | 38000 | ready | 1 | 3 | master | 0 | - 18 | 37001 | ready | 1 | 3 | master | 0 | - 19 | 37000 | ready | 1 | 1 | master | 0 | - 20 | 37000 | ready | 1 | 1 | master | 0 | - 21 | 37000 | ready | 1 | 1 | master | 0 | + 14 | 38000 | ready | 1 | 3 | leader | 0 | + 15 | 38000 | ready | 1 | 3 | leader | 0 | + 16 | 38000 | ready | 1 | 3 | leader | 0 | + 17 | 38000 | ready | 1 | 3 | leader | 0 | + 18 | 37001 | ready | 1 | 3 | leader | 0 | + 19 | 37000 | ready | 1 | 1 | leader | 0 | + 20 | 37000 | ready | 1 | 1 | leader | 0 | + 21 | 37000 | ready | 1 | 1 | leader | 0 | Query OK, 8 row(s) in set (0.001314s) ``` @@ -191,14 +191,14 @@ Query OK, 0 row(s) in set (0.000575s) taos> show vgroups; vgId | tables | status | onlines | v1_dnode | v1_status | v2_dnode | v2_status | compacting | ================================================================================================================= - 14 | 38000 | ready | 1 | 3 | master | 0 | NULL | 0 | - 15 | 38000 | ready | 1 | 3 | master | 0 | NULL | 0 | - 16 | 38000 | ready | 1 | 3 | master | 0 | NULL | 0 | - 17 | 38000 | ready | 1 | 3 | master | 0 | NULL | 0 | - 18 | 37001 | ready | 2 | 1 | slave | 3 | master | 0 | - 19 | 37000 | ready | 1 | 1 | master | 0 | NULL | 0 | - 20 | 37000 | ready | 1 | 1 | master | 0 | NULL | 0 | - 21 | 37000 | ready | 1 | 1 | master | 0 | NULL | 0 | + 14 | 38000 | ready | 1 | 3 | leader | 0 | NULL | 0 | + 15 | 38000 | ready | 1 | 3 | leader | 0 | NULL | 0 | + 16 | 38000 | ready | 1 | 3 | leader | 0 | NULL | 0 | + 17 | 38000 | ready | 1 | 3 | leader | 0 | NULL | 0 | + 18 | 37001 | ready | 2 | 1 | follower | 3 | leader | 0 | + 19 | 37000 | ready | 1 | 1 | leader | 0 | NULL | 0 | + 20 | 37000 | ready | 1 | 1 | leader | 0 | NULL | 0 | + 21 | 37000 | ready | 1 | 1 | leader | 0 | NULL | 0 | Query OK, 8 row(s) in set (0.001242s) ``` @@ -207,7 +207,7 @@ It can be seen from above output that vgId 18 has been moved from dnode 3 to dno :::note - Manual load balancing can only be performed when the automatic load balancing is disabled, i.e. `balance` is set to 0. -- Only a vnode in normal state, i.e. master or slave, can be moved. vnode can't be moved when its in status offline, unsynced or syncing. +- Only a vnode in normal state, i.e. leader or follower, can be moved. vnode can't be moved when its in status offline, unsynced or syncing. - Before moving a vnode, it's necessary to make sure the target dnode has enough resources: CPU, memory and disk. ::: diff --git a/docs/en/10-cluster/03-ha-and-lb.md b/docs/en/10-cluster/03-ha-and-lb.md index bd718eef9f..9780e8f6c6 100644 --- a/docs/en/10-cluster/03-ha-and-lb.md +++ b/docs/en/10-cluster/03-ha-and-lb.md @@ -27,7 +27,7 @@ There may be multiple dnodes in a cluster, but only one mnode can be started in SHOW MNODES; ``` -The end point and role/status (master, slave, unsynced, or offline) of all mnodes can be shown by the above command. When the first dnode is started in a cluster, there must be one mnode in this dnode. Without at least one mnode, the cluster cannot work. If `numOfMNodes` is configured to 2, another mnode will be started when the second dnode is launched. +The end point and role/status (leader, follower, unsynced, or offline) of all mnodes can be shown by the above command. When the first dnode is started in a cluster, there must be one mnode in this dnode. Without at least one mnode, the cluster cannot work. If `numOfMNodes` is configured to 2, another mnode will be started when the second dnode is launched. For the high availability of mnode, `numOfMnodes` needs to be configured to 2 or a higher value. Because the data consistency between mnodes must be guaranteed, the replica confirmation parameter `quorum` is set to 2 automatically if `numOfMNodes` is set to 2 or higher. @@ -58,13 +58,13 @@ When a dnode is offline, it can be detected by the TDengine cluster. There are t - If the dnode has been offline over the threshold configured in `offlineThreshold` in `taos.cfg`, the dnode will be removed from the cluster automatically. A system alert will be generated and automatic load balancing will be triggered if `balance` is set to 1. When the removed dnode is restarted and becomes online, it will not join the cluster automatically. The system administrator has to manually join the dnode to the cluster. :::note -If all the vnodes in a vgroup (or mnodes in mnode group) are in offline or unsynced status, the master node can only be voted on, after all the vnodes or mnodes in the group become online and can exchange status. Following this, the vgroup (or mnode group) is able to provide service. +If all the vnodes in a vgroup (or mnodes in mnode group) are in offline or unsynced status, the leader node can only be voted on, after all the vnodes or mnodes in the group become online and can exchange status. Following this, the vgroup (or mnode group) is able to provide service. ::: ## Arbitrator -The "arbitrator" component is used to address the special case when the number of replicas is set to an even number like 2,4 etc. If half of the vnodes in a vgroup don't work, it is impossible to vote and select a master node. This situation also applies to mnodes if the number of mnodes is set to an even number like 2,4 etc. +The "arbitrator" component is used to address the special case when the number of replicas is set to an even number like 2,4 etc. If half of the vnodes in a vgroup don't work, it is impossible to vote and select a leader node. This situation also applies to mnodes if the number of mnodes is set to an even number like 2,4 etc. To resolve this problem, a new arbitrator component named `tarbitrator`, an abbreviation of TDengine Arbitrator, was introduced. The `tarbitrator` simulates a vnode or mnode but it's only responsible for network communication and doesn't handle any actual data access. As long as more than half of the vnode or mnode, including Arbitrator, are available the vnode group or mnode group can provide data insertion or query services normally. diff --git a/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json b/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json index f651983528..54dc1062d6 100644 --- a/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json +++ b/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json @@ -211,7 +211,7 @@ ], "timeFrom": null, "timeShift": null, - "title": "Master MNode", + "title": "Leader MNode", "transformations": [ { "id": "filterByValue", @@ -221,7 +221,7 @@ "config": { "id": "regex", "options": { - "value": "master" + "value": "leader" } }, "fieldName": "role" @@ -300,7 +300,7 @@ ], "timeFrom": null, "timeShift": null, - "title": "Master MNode Create Time", + "title": "Leader MNode Create Time", "transformations": [ { "id": "filterByValue", @@ -310,7 +310,7 @@ "config": { "id": "regex", "options": { - "value": "master" + "value": "leader" } }, "fieldName": "role" diff --git a/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json b/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json index b4254c428b..1add8522a7 100644 --- a/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json +++ b/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json @@ -153,7 +153,7 @@ ], "timeFrom": null, "timeShift": null, - "title": "Master MNode", + "title": "Leader MNode", "transformations": [ { "id": "filterByValue", @@ -163,7 +163,7 @@ "config": { "id": "regex", "options": { - "value": "master" + "value": "leader" } }, "fieldName": "role" @@ -246,7 +246,7 @@ ], "timeFrom": null, "timeShift": null, - "title": "Master MNode Create Time", + "title": "Leader MNode Create Time", "transformations": [ { "id": "filterByValue", @@ -256,7 +256,7 @@ "config": { "id": "regex", "options": { - "value": "master" + "value": "leader" } }, "fieldName": "role" diff --git a/docs/en/14-reference/07-tdinsight/index.md b/docs/en/14-reference/07-tdinsight/index.md index cebfafa225..e74c9de7b2 100644 --- a/docs/en/14-reference/07-tdinsight/index.md +++ b/docs/en/14-reference/07-tdinsight/index.md @@ -274,8 +274,8 @@ Details of the metrics are as follows. This section contains the current information and status of the cluster, the alert information is also here (from left to right, top to bottom). - **First EP**: the `firstEp` setting in the current TDengine cluster. -- **Version**: TDengine server version (master mnode). -- **Master Uptime**: The time elapsed since the current Master MNode was elected as Master. +- **Version**: TDengine server version (leader mnode). +- **Leader Uptime**: The time elapsed since the current Leader MNode was elected as Leader. - **Expire Time** - Enterprise version expiration time. - **Used Measuring Points** - The number of measuring points used by the Enterprise Edition. - **Databases** - The number of databases. @@ -333,7 +333,7 @@ Data node resource usage display with repeated multiple rows for the variable `$ 2. **Has MNodes?**: whether the current dnode is a mnode. 3. **CPU Cores**: the number of CPU cores. 4. **VNodes Number**: the number of VNodes in the current dnode. -5. **VNodes Masters**: the number of vnodes in the master role. +5. **VNodes Masters**: the number of vnodes in the leader role. 6. **Current CPU Usage of taosd**: CPU usage rate of taosd processes. 7. **Current Memory Usage of taosd**: memory usage of taosd processes. 8. **Disk Used**: The total disk usage percentage of the taosd data directory. diff --git a/docs/en/21-tdinternal/01-arch.md b/docs/en/21-tdinternal/01-arch.md index 4d8bed4d2d..d7d472eb98 100644 --- a/docs/en/21-tdinternal/01-arch.md +++ b/docs/en/21-tdinternal/01-arch.md @@ -22,9 +22,9 @@ A complete TDengine system runs on one or more physical nodes. Logically, it inc **Virtual node (vnode)**: To better support data sharding, load balancing and prevent data from overheating or skewing, data nodes are virtualized into multiple virtual nodes (vnode, V2, V3, V4, etc. in the figure). Each vnode is a relatively independent work unit, which is the basic unit of time-series data storage and has independent running threads, memory space and persistent storage path. A vnode contains a certain number of tables (data collection points). When a new table is created, the system checks whether a new vnode needs to be created. The number of vnodes that can be created on a data node depends on the capacity of the hardware of the physical node where the data node is located. A vnode belongs to only one DB, but a DB can have multiple vnodes. In addition to the stored time-series data, a vnode also stores the schema and tag values of the included tables. A virtual node is uniquely identified in the system by the EP of the data node and the VGroup ID to which it belongs and is created and managed by the management node. -**Management node (mnode)**: A virtual logical unit responsible for monitoring and maintaining the running status of all data nodes and load balancing among nodes (M in the figure). At the same time, the management node is also responsible for the storage and management of metadata (including users, databases, tables, static tags, etc.), so it is also called Meta Node. Multiple (up to 5) mnodes can be configured in a TDengine cluster, and they are automatically constructed into a virtual management node group (M0, M1, M2 in the figure). The master/slave mechanism is adopted for the mnode group and the data synchronization is carried out in a strongly consistent way. Any data update operation can only be executed on the master. The creation of mnode cluster is completed automatically by the system without manual intervention. There is at most one mnode on each dnode, which is uniquely identified by the EP of the data node to which it belongs. Each dnode automatically obtains the EP of the dnode where all mnodes in the whole cluster are located, through internal messaging interaction. +**Management node (mnode)**: A virtual logical unit responsible for monitoring and maintaining the running status of all data nodes and load balancing among nodes (M in the figure). At the same time, the management node is also responsible for the storage and management of metadata (including users, databases, tables, static tags, etc.), so it is also called Meta Node. Multiple (up to 5) mnodes can be configured in a TDengine cluster, and they are automatically constructed into a virtual management node group (M0, M1, M2 in the figure). The leader/follower mechanism is adopted for the mnode group and the data synchronization is carried out in a strongly consistent way. Any data update operation can only be executed on the leader. The creation of mnode cluster is completed automatically by the system without manual intervention. There is at most one mnode on each dnode, which is uniquely identified by the EP of the data node to which it belongs. Each dnode automatically obtains the EP of the dnode where all mnodes in the whole cluster are located, through internal messaging interaction. -**Virtual node group (VGroup)**: Vnodes on different data nodes can form a virtual node group to ensure the high availability of the system. The virtual node group is managed in a master/slave mechanism. Write operations can only be performed on the master vnode, and then replicated to slave vnodes, thus ensuring that one single replica of data is copied on multiple physical nodes. The number of virtual nodes in a vgroup equals the number of data replicas. If the number of replicas of a DB is N, the system must have at least N data nodes. The number of replicas can be specified by the parameter `“replica”` when creating a DB, and the default is 1. Using the multi-replication feature of TDengine, the same high data reliability can be achieved without the need for expensive storage devices such as disk arrays. Virtual node groups are created and managed by the management node, and the management node assigns a system unique ID, aka VGroup ID. If two virtual nodes have the same vnode group ID, it means that they belong to the same group and the data is backed up to each other. The number of virtual nodes in a virtual node group can be dynamically changed, allowing only one, that is, no data replication. VGroup ID is never changed. Even if a virtual node group is deleted, its ID will not be reused. +**Virtual node group (VGroup)**: Vnodes on different data nodes can form a virtual node group to ensure the high availability of the system. The virtual node group is managed in a leader/follower mechanism. Write operations can only be performed on the leader vnode, and then replicated to follower vnodes, thus ensuring that one single replica of data is copied on multiple physical nodes. The number of virtual nodes in a vgroup equals the number of data replicas. If the number of replicas of a DB is N, the system must have at least N data nodes. The number of replicas can be specified by the parameter `“replica”` when creating a DB, and the default is 1. Using the multi-replication feature of TDengine, the same high data reliability can be achieved without the need for expensive storage devices such as disk arrays. Virtual node groups are created and managed by the management node, and the management node assigns a system unique ID, aka VGroup ID. If two virtual nodes have the same vnode group ID, it means that they belong to the same group and the data is backed up to each other. The number of virtual nodes in a virtual node group can be dynamically changed, allowing only one, that is, no data replication. VGroup ID is never changed. Even if a virtual node group is deleted, its ID will not be reused. **TAOSC**: TAOSC is the driver provided by TDengine to applications. It is responsible for dealing with the interaction between application and cluster, and provides the native interface for the C/C++ language. It is also embedded in the JDBC, C #, Python, Go, Node.js language connection libraries. Applications interact with the whole cluster through TAOSC instead of directly connecting to data nodes in the cluster. This module is responsible for obtaining and caching metadata; forwarding requests for insertion, query, etc. to the correct data node; when returning the results to the application, TAOSC also needs to be responsible for the final level of aggregation, sorting, filtering and other operations. For JDBC, C/C++/C#/Python/Go/Node.js interfaces, this module runs on the physical node where the application is located. At the same time, in order to support the fully distributed RESTful interface, TAOSC has a running instance on each dnode of TDengine cluster. @@ -62,13 +62,13 @@ To explain the relationship between vnode, mnode, TAOSC and application and thei 1. Application initiates a request to insert data through JDBC, ODBC, or other APIs. 2. TAOSC checks the cache to see if meta data exists for the table. If it does, it goes straight to Step 4. If not, TAOSC sends a get meta-data request to mnode. 3. Mnode returns the meta-data of the table to TAOSC. Meta-data contains the schema of the table, and also the vgroup information to which the table belongs (the vnode ID and the End Point of the dnode where the table belongs. If the number of replicas is N, there will be N groups of End Points). If TAOSC does not receive a response from the mnode for a long time, and there are multiple mnodes, TAOSC will send a request to the next mnode. -4. TAOSC initiates an insert request to master vnode. +4. TAOSC initiates an insert request to leader vnode. 5. After vnode inserts the data, it gives a reply to TAOSC, indicating that the insertion is successful. If TAOSC doesn't get a response from vnode for a long time, TAOSC will treat this node as offline. In this case, if there are multiple replicas of the inserted database, TAOSC will issue an insert request to the next vnode in vgroup. 6. TAOSC notifies APP that writing is successful. For Step 2 and 3, when TAOSC starts, it does not know the End Point of mnode, so it will directly initiate a request to the configured serving End Point of the cluster. If the dnode that receives the request does not have a mnode configured, it will reply with the mnode EP list, so that TAOSC will re-issue a request to obtain meta-data to the EP of another mnode. -For Step 4 and 5, without caching, TAOSC can't recognize the master in the virtual node group, so assumes that the first vnode is the master and sends a request to it. If this vnode is not the master, it will reply to the actual master as a new target to which TAOSC shall send a request. Once a response of successful insertion is obtained, TAOSC will cache the information of master node. +For Step 4 and 5, without caching, TAOSC can't recognize the leader in the virtual node group, so assumes that the first vnode is the leader and sends a request to it. If this vnode is not the leader, it will reply to the actual leader as a new target to which TAOSC shall send a request. Once a response of successful insertion is obtained, TAOSC will cache the information of leader node. The above describes the process of inserting data. The processes of querying and computing are the same. TAOSC encapsulates and hides all these complicated processes, and it is transparent to applications. @@ -119,65 +119,65 @@ The load balancing process does not require any manual intervention, and it is t ## Data Writing and Replication Process -If a database has N replicas, a virtual node group has N virtual nodes. But only one is the Master and all others are slaves. When the application writes a new record to system, only the Master vnode can accept the writing request. If a slave vnode receives a writing request, the system will notifies TAOSC to redirect. +If a database has N replicas, a virtual node group has N virtual nodes. But only one is the Leader and all others are slaves. When the application writes a new record to system, only the Leader vnode can accept the writing request. If a follower vnode receives a writing request, the system will notifies TAOSC to redirect. -### Master vnode Writing Process +### Leader vnode Writing Process -Master Vnode uses a writing process as follows: +Leader Vnode uses a writing process as follows: -![TDengine Database Master Writing Process](write_master.webp) -
Figure 3: TDengine Master writing process
+![TDengine Database Leader Writing Process](write_master.webp) +
Figure 3: TDengine Leader writing process
-1. Master vnode receives the application data insertion request, verifies, and moves to next step; +1. Leader vnode receives the application data insertion request, verifies, and moves to next step; 2. If the system configuration parameter `“walLevel”` is greater than 0, vnode will write the original request packet into database log file WAL. If walLevel is set to 2 and fsync is set to 0, TDengine will make WAL data written immediately to ensure that even system goes down, all data can be recovered from database log file; -3. If there are multiple replicas, vnode will forward data packet to slave vnodes in the same virtual node group, and the forwarded packet has a version number with data; +3. If there are multiple replicas, vnode will forward data packet to follower vnodes in the same virtual node group, and the forwarded packet has a version number with data; 4. Write into memory and add the record to “skip list”; -5. Master vnode returns a confirmation message to the application, indicating a successful write. +5. Leader vnode returns a confirmation message to the application, indicating a successful write. 6. If any of Step 2, 3 or 4 fails, the error will directly return to the application. -### Slave vnode Writing Process +### Follower vnode Writing Process -For a slave vnode, the write process as follows: +For a follower vnode, the write process as follows: -![TDengine Database Slave Writing Process](write_slave.webp) -
Figure 4: TDengine Slave Writing Process
+![TDengine Database Follower Writing Process](write_slave.webp) +
Figure 4: TDengine Follower Writing Process
-1. Slave vnode receives a data insertion request forwarded by Master vnode; +1. Follower vnode receives a data insertion request forwarded by Leader vnode; 2. If the system configuration parameter `“walLevel”` is greater than 0, vnode will write the original request packet into database log file WAL. If walLevel is set to 2 and fsync is set to 0, TDengine will make WAL data written immediately to ensure that even system goes down, all data can be recovered from database log file; 3. Write into memory and add the record to “skip list”. -Compared with Master vnode, slave vnode has no forwarding or reply confirmation step, means two steps less. But writing into memory and WAL is exactly the same. +Compared with Leader vnode, follower vnode has no forwarding or reply confirmation step, means two steps less. But writing into memory and WAL is exactly the same. ### Remote Disaster Recovery and IDC (Internet Data Center) Migration -As discussed above, TDengine writes using Master and Slave processes. TDengine adopts asynchronous replication for data synchronization. This method can greatly improve write performance, with no obvious impact from network delay. By configuring IDC and rack number for each physical node, it can be ensured that for a virtual node group, virtual nodes are composed of physical nodes from different IDC and different racks, thus implementing remote disaster recovery without other tools. +As discussed above, TDengine writes using Leader and Follower processes. TDengine adopts asynchronous replication for data synchronization. This method can greatly improve write performance, with no obvious impact from network delay. By configuring IDC and rack number for each physical node, it can be ensured that for a virtual node group, virtual nodes are composed of physical nodes from different IDC and different racks, thus implementing remote disaster recovery without other tools. -On the other hand, TDengine supports dynamic modification of the replica number. Once the number of replicas increases, the newly added virtual nodes will immediately enter the data synchronization process. After synchronization is complete, added virtual nodes can provide services. In the synchronization process, master and other synchronized virtual nodes keep serving. With this feature, TDengine can provide IDC migration without service interruption. It is only necessary to add new physical nodes to the existing IDC cluster, and then remove old physical nodes after the data synchronization is completed. +On the other hand, TDengine supports dynamic modification of the replica number. Once the number of replicas increases, the newly added virtual nodes will immediately enter the data synchronization process. After synchronization is complete, added virtual nodes can provide services. In the synchronization process, leader and other synchronized virtual nodes keep serving. With this feature, TDengine can provide IDC migration without service interruption. It is only necessary to add new physical nodes to the existing IDC cluster, and then remove old physical nodes after the data synchronization is completed. However, the asynchronous replication has a very low probability scenario where data may be lost. The specific scenario is as follows: -1. Master vnode has finished its 5-step operations, confirmed the success of writing to APP, and then goes down; -2. Slave vnode receives the write request, then processing fails before writing to the log in Step 2; -3. Slave vnode will become the new master, thus losing one record. +1. Leader vnode has finished its 5-step operations, confirmed the success of writing to APP, and then goes down; +2. Follower vnode receives the write request, then processing fails before writing to the log in Step 2; +3. Follower vnode will become the new leader, thus losing one record. In theory, for asynchronous replication, there is no guarantee to prevent data loss. However, this is an extremely low probability scenario as described above. Note: Remote disaster recovery and no-downtime IDC migration are only supported by Enterprise Edition. **Hint: This function is not available yet** -### Master/slave Selection +### Leader/follower Selection Vnode maintains a version number. When memory data is persisted, the version number will also be persisted. For each data update operation, whether it is time-series data or metadata, this version number will be increased by one. -When a vnode starts, the roles (master, slave) are uncertain, and the data is in an unsynchronized state. It’s necessary to establish TCP connections with other nodes in the virtual node group and exchange status, including version and its own roles. Through the exchange, the system implements a master-selection process. The rules are as follows: +When a vnode starts, the roles (leader, follower) are uncertain, and the data is in an unsynchronized state. It’s necessary to establish TCP connections with other nodes in the virtual node group and exchange status, including version and its own roles. Through the exchange, the system implements a leader-selection process. The rules are as follows: -1. If there’s only one replica, it’s always master -2. When all replicas are online, the one with latest version is master -3. Over half of online nodes are virtual nodes, and some virtual node is slave, it will automatically become master -4. For 2 and 3, if multiple virtual nodes meet the requirement, the first vnode in virtual node group list will be selected as master. +1. If there’s only one replica, it’s always leader +2. When all replicas are online, the one with latest version is leader +3. Over half of online nodes are virtual nodes, and some virtual node is follower, it will automatically become leader +4. For 2 and 3, if multiple virtual nodes meet the requirement, the first vnode in virtual node group list will be selected as leader. ### Synchronous Replication -For scenarios with strong data consistency requirements, asynchronous data replication is not applicable, because there is a small probability of data loss. So, TDengine provides a synchronous replication mechanism for users. When creating a database, in addition to specifying the number of replicas, user also needs to specify a new parameter “quorum”. If quorum is greater than one, it means that every time the Master forwards a message to the replica, it needs to wait for “quorum-1” reply confirms before informing the application that data has been successfully written in slave. If “quorum-1” reply confirms are not received within a certain period of time, the master vnode will return an error to the application. +For scenarios with strong data consistency requirements, asynchronous data replication is not applicable, because there is a small probability of data loss. So, TDengine provides a synchronous replication mechanism for users. When creating a database, in addition to specifying the number of replicas, user also needs to specify a new parameter “quorum”. If quorum is greater than one, it means that every time the Leader forwards a message to the replica, it needs to wait for “quorum-1” reply confirms before informing the application that data has been successfully written in follower. If “quorum-1” reply confirms are not received within a certain period of time, the leader vnode will return an error to the application. With synchronous replication, performance of system will decrease and latency will increase. Because metadata needs strong consistency, the default for data synchronization between mnodes is synchronous replication. -- GitLab From 9065c6784fdd98c3e4ef0476d5a0c49a4403d228 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Wed, 22 Jun 2022 20:25:30 +0800 Subject: [PATCH 076/380] test: update test case --- tests/pytest/functions/function_first.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pytest/functions/function_first.py b/tests/pytest/functions/function_first.py index 6c3a747feb..df9056acfe 100644 --- a/tests/pytest/functions/function_first.py +++ b/tests/pytest/functions/function_first.py @@ -162,7 +162,7 @@ class TDTestCase: text = r.read() r.close() result = float(re.split('\n |\|', text)[3]) - tdSql.query("select first(c1) + last(c1) from tb01") + tdSql.query("select first(c1) - last(c1) from tb01") tdSql.checkData(0, 0, result) -- GitLab From bfde050b2f2c6aa9e138fd9f1015c4092579aa5d Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Tue, 21 Jun 2022 19:04:14 +0800 Subject: [PATCH 077/380] fix: compilation with visual c on win --- src/plugins/monitor/src/monMain.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/monitor/src/monMain.c b/src/plugins/monitor/src/monMain.c index 2cd0139f5b..1ff2f0ef8d 100644 --- a/src/plugins/monitor/src/monMain.c +++ b/src/plugins/monitor/src/monMain.c @@ -719,10 +719,9 @@ static int32_t monBuildMnodesTotalSql(char *sql) { static int32_t monGetVgroupsTotalStats(char *dbName, int32_t *totalVgroups, int32_t *totalVgroupsAlive) { - int bufLen = TSDB_DB_NAME_LEN + 16; - char subsql[bufLen]; + char subsql[TSDB_DB_NAME_LEN + 16]; memset(subsql, 0, sizeof(subsql)); - snprintf(subsql, bufLen - 1, "show `%s`.vgroups", dbName); + snprintf(subsql, sizeof(subsql) - 1, "show `%s`.vgroups", dbName); TAOS_RES *result = taos_query(tsMonitor.conn, subsql); int32_t code = taos_errno(result); if (code != TSDB_CODE_SUCCESS) { -- GitLab From bf041f2177855e3bb5e5777f4a0541be395277f2 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 23 Jun 2022 11:48:34 +0800 Subject: [PATCH 078/380] fix: undo trimming EOL whitespaces or some formatting --- src/client/src/tscLocal.c | 125 +++++++++---------- src/client/src/tscSQLParser.c | 208 ++++++++++++++++---------------- src/client/src/tscUtil.c | 26 ++-- src/kit/shell/src/shellEngine.c | 4 +- src/mnode/src/mnodeTable.c | 14 +-- 5 files changed, 191 insertions(+), 186 deletions(-) diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index 05d8e77a3e..39cbd6789f 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -25,23 +25,23 @@ #include "taos.h" #include "tscSubquery.h" -#define STR_NOCASE_EQUAL(str1, len1, str2, len2) ((len1 == len2) && 0 == strncasecmp(str1, str2, len1)) +#define STR_NOCASE_EQUAL(str1, len1, str2, len2) ((len1 == len2) && 0 == strncasecmp(str1, str2, len1)) typedef enum BuildType { - SCREATE_BUILD_TABLE = 1, - SCREATE_BUILD_DB = 2, -} BuildType; + SCREATE_BUILD_TABLE = 1, + SCREATE_BUILD_DB = 2, +} BuildType; typedef enum Stage { SCREATE_CALLBACK_QUERY = 1, SCREATE_CALLBACK_RETRIEVE = 2, } Stage; -// support 'show create table' +// support 'show create table' typedef struct SCreateBuilder { char sTableName[TSDB_TABLE_FNAME_LEN]; char buf[TSDB_TABLE_FNAME_LEN]; - SSqlObj *pParentSql; + SSqlObj *pParentSql; SSqlObj *pInterSql; int32_t (*fp)(void *para, char* result); Stage callStage; @@ -54,7 +54,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { // one column for each row SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); - + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -121,7 +121,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { // type name pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1); char *type = tDataTypes[pSchema[i].type].name; - + output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i; STR_WITH_MAXSIZE_TO_VARSTR(output, type, pField->bytes); @@ -153,7 +153,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, int32_t noteColLength) { int32_t rowLen = 0; SColumnIndex index = {0}; - + pSql->cmd.numOfCols = numOfCols; SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); @@ -161,48 +161,48 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, TAOS_FIELD f = {.type = TSDB_DATA_TYPE_BINARY, .bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE}; tstrncpy(f.name, "Field", sizeof(f.name)); - + SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false); - + rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE); f.bytes = (int16_t)(typeColLength + VARSTR_HEADER_SIZE); f.type = TSDB_DATA_TYPE_BINARY; tstrncpy(f.name, "Type", sizeof(f.name)); - + pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), -1000, typeColLength, false); - + rowLen += typeColLength + VARSTR_HEADER_SIZE; f.bytes = sizeof(int32_t); f.type = TSDB_DATA_TYPE_INT; tstrncpy(f.name, "Length", sizeof(f.name)); - + pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), -1000, sizeof(int32_t), false); - + rowLen += sizeof(int32_t); f.bytes = (int16_t)(noteColLength + VARSTR_HEADER_SIZE); f.type = TSDB_DATA_TYPE_BINARY; tstrncpy(f.name, "Note", sizeof(f.name)); - + pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), -1000, noteColLength, false); - + rowLen += noteColLength + VARSTR_HEADER_SIZE; return rowLen; } static int32_t tscProcessDescribeTable(SSqlObj *pSql) { SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); - + assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL); const int32_t NUM_OF_DESC_TABLE_COLUMNS = 4; @@ -220,25 +220,25 @@ static int32_t tscGetNthFieldResult(TAOS_ROW row, TAOS_FIELD* fields, int *lengt if (val == NULL) { sprintf(result, "%s", TSDB_DATA_NULL_STR); return -1; - } + } uint8_t type = fields[idx].type; int32_t length = lengths[idx]; switch (type) { - case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_BOOL: sprintf(result, "%s", ((((int32_t)(*((char *)val))) == 1) ? "true" : "false")); break; case TSDB_DATA_TYPE_TINYINT: sprintf(result, "%d", *((int8_t *)val)); break; - case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_SMALLINT: sprintf(result, "%d", *((int16_t *)val)); break; case TSDB_DATA_TYPE_INT: sprintf(result, "%d", *((int32_t *)val)); break; - case TSDB_DATA_TYPE_BIGINT: - sprintf(result, "%" PRId64, *((int64_t *)val)); + case TSDB_DATA_TYPE_BIGINT: + sprintf(result, "%"PRId64, *((int64_t *)val)); break; case TSDB_DATA_TYPE_UTINYINT: sprintf(result, "%u", *((uint8_t *)val)); @@ -253,57 +253,57 @@ static int32_t tscGetNthFieldResult(TAOS_ROW row, TAOS_FIELD* fields, int *lengt sprintf(result, "%"PRIu64, *((uint64_t *)val)); break; case TSDB_DATA_TYPE_FLOAT: - sprintf(result, "%f", GET_FLOAT_VAL(val)); + sprintf(result, "%f", GET_FLOAT_VAL(val)); break; case TSDB_DATA_TYPE_DOUBLE: - sprintf(result, "%f", GET_DOUBLE_VAL(val)); + sprintf(result, "%f", GET_DOUBLE_VAL(val)); break; case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_JSON: - memcpy(result, val, length); + memcpy(result, val, length); break; case TSDB_DATA_TYPE_TIMESTAMP: ///formatTimestamp(buf, *(int64_t*)val, TSDB_TIME_PRECISION_MICRO); //memcpy(result, val, strlen(buf)); - sprintf(result, "%" PRId64, *((int64_t *)val)); + sprintf(result, "%"PRId64, *((int64_t *)val)); break; default: - break; + break; } return 0; -} +} void tscSCreateCallBack(void *param, TAOS_RES *tres, int code) { if (param == NULL || tres == NULL) { return; - } + } SCreateBuilder *builder = (SCreateBuilder *)(param); - SSqlObj *pParentSql = builder->pParentSql; - SSqlObj *pSql = (SSqlObj *)tres; + SSqlObj *pParentSql = builder->pParentSql; + SSqlObj *pSql = (SSqlObj *)tres; SSqlRes *pRes = &pParentSql->res; - pRes->code = taos_errno(pSql); + pRes->code = taos_errno(pSql); if (pRes->code != TSDB_CODE_SUCCESS) { - taos_free_result(pSql); + taos_free_result(pSql); free(builder); tscAsyncResultOnError(pParentSql); return; } if (builder->callStage == SCREATE_CALLBACK_QUERY) { - taos_fetch_rows_a(tres, tscSCreateCallBack, param); + taos_fetch_rows_a(tres, tscSCreateCallBack, param); builder->callStage = SCREATE_CALLBACK_RETRIEVE; } else { char *result = calloc(1, TSDB_MAX_BINARY_LEN); pRes->code = builder->fp(builder, result); - taos_free_result(pSql); + taos_free_result(pSql); free(builder); free(result); if (pRes->code == TSDB_CODE_SUCCESS) { - (*pParentSql->fp)(pParentSql->param, pParentSql, code); + (*pParentSql->fp)(pParentSql->param, pParentSql, code); } else { tscAsyncResultOnError(pParentSql); } @@ -314,16 +314,16 @@ TAOS_ROW tscFetchRow(void *param) { SCreateBuilder *builder = (SCreateBuilder *)param; if (builder == NULL) { return NULL; - } + } SSqlObj *pSql = builder->pInterSql; if (pSql == NULL || pSql->signature != pSql) { terrno = TSDB_CODE_TSC_DISCONNECTED; return NULL; } - + SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; - + if (pRes->qId == 0 || pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pCmd->command == TSDB_SQL_INSERT) { @@ -367,7 +367,7 @@ static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) { return TSDB_CODE_TSC_INVALID_TABLE_NAME; } - int32_t *lengths = taos_fetch_lengths(pSql); + int32_t* lengths = taos_fetch_lengths(pSql); int num_fields = taos_num_fields(pSql); TAOS_FIELD *fields = taos_fetch_fields(pSql); @@ -382,10 +382,10 @@ static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) { if (i == 0) { snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "%s", "("); - } - if ((fields[i].type == TSDB_DATA_TYPE_NCHAR || fields[i].type == TSDB_DATA_TYPE_BINARY || - fields[i].type == TSDB_DATA_TYPE_TIMESTAMP) && - 0 == ret) { + } + if ((fields[i].type == TSDB_DATA_TYPE_NCHAR + || fields[i].type == TSDB_DATA_TYPE_BINARY + || fields[i].type == TSDB_DATA_TYPE_TIMESTAMP) && 0 == ret) { snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "\"%s\",", buf); } else if (fields[i].type == TSDB_DATA_TYPE_JSON) { snprintf(result + strlen(result), TSDB_MAX_BINARY_LEN - strlen(result), "'%s,", buf); @@ -410,17 +410,18 @@ static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) { return TSDB_CODE_SUCCESS; } -// build 'show create table/database' result fields + +// build 'show create table/database' result fields static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const char *ddl) { int32_t rowLen = 0; - int16_t ddlLen = (int16_t)strlen(ddl); + int16_t ddlLen = (int16_t)strlen(ddl); SColumnIndex index = {0}; pSql->cmd.numOfCols = 2; SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); pQueryInfo->order.order = TSDB_ORDER_ASC; - TAOS_FIELD f; + TAOS_FIELD f; if (type == SCREATE_BUILD_TABLE) { f.type = TSDB_DATA_TYPE_BINARY; f.bytes = (TSDB_TABLE_NAME_LEN - 1) + VARSTR_HEADER_SIZE; @@ -429,12 +430,12 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const f.type = TSDB_DATA_TYPE_BINARY; f.bytes = (TSDB_DB_NAME_LEN - 1) + VARSTR_HEADER_SIZE; tstrncpy(f.name, "Database", sizeof(f.name)); - } + } SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); - rowLen += f.bytes; + rowLen += f.bytes; f.bytes = (int16_t)(ddlLen + VARSTR_HEADER_SIZE); f.type = TSDB_DATA_TYPE_BINARY; @@ -639,7 +640,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch param->fp = tscRebuildCreateTableStatement; param->callStage = SCREATE_CALLBACK_QUERY; - char *query = (char *)calloc(1, TSDB_MAX_BINARY_LEN); + char *query = (char *)calloc(1, TSDB_MAX_BINARY_LEN); if (query == NULL) { free(param); free(pInterSql); @@ -649,7 +650,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch char *columns = NULL; int32_t code = tscGetTableTagColumnName(pSql, &columns) ; if (code != TSDB_CODE_SUCCESS) { - free(param); + free(param); free(pInterSql); free(query); return code; @@ -660,7 +661,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch free(query); free(columns); - return TSDB_CODE_TSC_ACTION_IN_PROGRESS; + return TSDB_CODE_TSC_ACTION_IN_PROGRESS; } static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) { @@ -755,7 +756,7 @@ static int32_t tscProcessShowCreateTable(SSqlObj *pSql) { if (code == TSDB_CODE_SUCCESS) { code = tscSCreateBuildResult(pSql, SCREATE_BUILD_TABLE, tableName, result); - } + } free(result); return code; } @@ -765,12 +766,12 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - SSqlObj *pInterSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); + SSqlObj *pInterSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); if (pInterSql == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; - } + } - SCreateBuilder *param = (SCreateBuilder *)calloc(1, sizeof(SCreateBuilder)); + SCreateBuilder *param = (SCreateBuilder *)calloc(1, sizeof(SCreateBuilder)); if (param == NULL) { free(pInterSql); return TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -781,7 +782,7 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { param->pInterSql = pInterSql; param->fp = tscRebuildCreateDBStatement; param->callStage = SCREATE_CALLBACK_QUERY; - + const char *query = "show databases"; doAsyncQuery(pSql->pTscObj, pInterSql, tscSCreateCallBack, param, query, strlen(query)); return TSDB_CODE_TSC_ACTION_IN_PROGRESS; @@ -960,8 +961,8 @@ int tscProcessLocalCmd(SSqlObj *pSql) { if (taosCfgDynamicOptions(pCmd->payload)) { pRes->code = TSDB_CODE_SUCCESS; } else { - pRes->code = TSDB_CODE_COM_INVALID_CFG_MSG; - } + pRes->code = TSDB_CODE_COM_INVALID_CFG_MSG; + } pRes->numOfRows = 0; } else if (pCmd->command == TSDB_SQL_DESCRIBE_TABLE) { pRes->code = (uint8_t)tscProcessDescribeTable(pSql); @@ -973,9 +974,9 @@ int tscProcessLocalCmd(SSqlObj *pSql) { pRes->qId = 0x1; pRes->numOfRows = 0; } else if (pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE || pCmd->command == TSDB_SQL_SHOW_CREATE_STABLE) { - pRes->code = tscProcessShowCreateTable(pSql); + pRes->code = tscProcessShowCreateTable(pSql); } else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) { - pRes->code = tscProcessShowCreateDatabase(pSql); + pRes->code = tscProcessShowCreateDatabase(pSql); } else if (pCmd->command == TSDB_SQL_RESET_CACHE) { taosHashClear(UTIL_GET_TABLEMETA(pSql)); taosCacheEmpty(UTIL_GET_VGROUPLIST(pSql)); diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 866ecb3927..4021fca42f 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1081,7 +1081,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (code != TSDB_CODE_SUCCESS) { return code ; // async load table meta } - + // vgroupInfo if super if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { code = tscGetSTableVgroupInfo(pSql, pQueryInfo); @@ -1117,7 +1117,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { */ static bool isTopBottomUniqueQuery(SQueryInfo* pQueryInfo) { size_t size = tscNumOfExprs(pQueryInfo); - + for (int32_t i = 0; i < size; ++i) { int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId; @@ -1228,7 +1228,7 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS if (interpQuery) { return addPrimaryTsColumnForTimeWindowQuery(pQueryInfo, pCmd); } - + return TSDB_CODE_SUCCESS; } @@ -1344,7 +1344,7 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } } - + tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; taosArrayPush(pGroupExpr->columnInfo, &colIndex); @@ -1515,11 +1515,11 @@ int32_t tscSetTableFullName(SName* pName, SStrToken* pTableName, SSqlObj* pSql, SSqlCmd* pCmd = &pSql->cmd; int32_t code = TSDB_CODE_SUCCESS; int32_t idx = -1; - + if (dbIncluded) { idx = getDelimiterIndex(pTableName); } - + if (idx != -1) { // db has been specified in sql string so we ignore current db path char* acctId = getAccountId(pSql); if (acctId == NULL || strlen(acctId) <= 0) { @@ -1822,10 +1822,10 @@ int32_t validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { // assert(pCmd->numOfClause == 1); STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - + int32_t numOfTags = tscGetNumOfTags(pTableMeta); int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - + // no more max columns if (numOfCols >= TSDB_MAX_COLUMNS || numOfTags + numOfCols >= TSDB_MAX_COLUMNS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -2242,7 +2242,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS const char* msg3 = "not support query expression"; const char* msg4 = "not support distinct mixed with proj/agg func"; const char* msg5 = "invalid function name"; - const char* msg6 = "not support distinct mixed with join"; + const char* msg6 = "not support distinct mixed with join"; const char* msg7 = "not support distinct mixed with groupby"; const char* msg8 = "not support distinct in nest query"; const char* msg9 = "_block_dist not support subquery, only support stable/table"; @@ -2379,11 +2379,11 @@ int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnLi SSchema* pSchema = tscGetTableSchema(pTableMeta); tscColumnListInsert(pQueryInfo->colList, pColList->ids[i].columnIndex, uid, &pSchema[pColList->ids[i].columnIndex]); } - + TAOS_FIELD f = tscCreateField(type, fieldName, bytes); SInternalField* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f); pInfo->pExpr = pSqlExpr; - + return TSDB_CODE_SUCCESS; } @@ -2391,12 +2391,12 @@ SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tab STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex); int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ); SColumnIndex index = {.tableIndex = tableIndex,}; - + if (functionId == TSDB_FUNC_TAGPRJ) { index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta); tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); @@ -2424,7 +2424,7 @@ SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColInd pExpr->base.colInfo.flag = flag; STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); - + if (TSDB_COL_IS_TAG(flag)) { tscColumnListInsert(pTableMetaInfo->tagColList, pIndex->columnIndex, pTableMetaInfo->pTableMeta->id.uid, pColSchema); } @@ -2440,7 +2440,7 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum SSchema* pSchema = tscGetTableSchema(pTableMeta); STableComInfo tinfo = tscGetTableInfo(pTableMeta); - + if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { numOfTotalColumns = tinfo.numOfColumns + tinfo.numOfTags; } else { @@ -2670,7 +2670,7 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS pExpr->base.param[0].i64 = TSDB_ORDER_DESC; pExpr->base.param[0].nType = TSDB_DATA_TYPE_INT; } - + // for all queries, the timestamp column needs to be loaded SSchema s = {.colId = PRIMARYKEY_TIMESTAMP_COL_INDEX, .bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP,}; tscColumnListInsert(pQueryInfo->colList, PRIMARYKEY_TIMESTAMP_COL_INDEX, pExpr->base.uid, &s); @@ -3945,7 +3945,7 @@ static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // create tmp buf to avoid alter orginal sqlstr strncpy(tmpTokenBuf, pToken->z, pToken->n); - + pToken->z = tmpTokenBuf; pToken->n = stringProcess(pToken->z, pToken->n); @@ -4136,7 +4136,7 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (pShowInfo->prefix.n <= 0) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - } + } return TSDB_CODE_SUCCESS; } @@ -4147,7 +4147,7 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { SSqlCmd* pCmd = &pSql->cmd; pCmd->command = pInfo->type; - + SStrToken* idStr = &(pInfo->pMiscInfo->id); if (idStr->n > TSDB_KILL_MSG_LEN) { return TSDB_CODE_TSC_INVALID_OPERATION; @@ -4180,7 +4180,7 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } - + return TSDB_CODE_SUCCESS; } static int32_t setCompactVnodeInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { @@ -4202,7 +4202,7 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { int32_t bytes = 0; int16_t type = 0; int32_t interBytes = 0; - + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t k = 0; k < size; ++k) { SExprInfo* pExpr = tscExprGet(pQueryInfo, k); @@ -4214,7 +4214,7 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { int32_t colIndex = pExpr->base.colInfo.colIndex; SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex); - + if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) || (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_STDDEV_DST) || (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_IRATE) || @@ -4246,16 +4246,16 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { return; } - + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex); - + // the final result size and type in the same as query on single table. // so here, set the flag to be false; int32_t inter = 0; - + int32_t functionId = pExpr->base.functionId; if (functionId < 0) { continue; @@ -4264,7 +4264,7 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) { continue; } - + if (functionId == TSDB_FUNC_FIRST_DST) { functionId = TSDB_FUNC_FIRST; } else if (functionId == TSDB_FUNC_LAST_DST) { @@ -4319,7 +4319,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) return true; } } - + if (tscIsSessionWindowQuery(pQueryInfo)) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return true; @@ -4668,7 +4668,7 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, } if (pExpr->tokenId == TK_IN) { - tVariant* pVal; + tVariant *pVal; if (pRight->tokenId != TK_SET || !serializeExprListToVariant(pRight->Expr.paramList, &pVal, colType, timePrecision)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } @@ -4703,7 +4703,7 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, if (retVal != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); - } + } switch (pExpr->tokenId) { case TK_LE: @@ -4768,7 +4768,7 @@ enum { TSQL_EXPR_TAG = 2, TSQL_EXPR_COLUMN = 4, TSQL_EXPR_TBNAME = 8, - TSQL_EXPR_JOIN = 16, + TSQL_EXPR_JOIN = 16, }; #define GET_MIXED_TYPE(t) (((t) >= TSQL_EXPR_JOIN) || ((t) > TSQL_EXPR_COLUMN && (t) < TSQL_EXPR_TBNAME) || ((t) == (TSQL_EXPR_TS|TSQL_EXPR_TAG))) @@ -4800,7 +4800,7 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); goto _err_ret; } - + if (pSchema->type == TSDB_DATA_TYPE_BOOL) { int32_t t = pExpr->tokenId; if (t != TK_EQ && t != TK_NE && t != TK_NOTNULL && t != TK_ISNULL && t != TK_IN) { @@ -4820,7 +4820,7 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol _err_ret: freeColumnFilterInfo(pColFilter, 1); - + return ret; } @@ -4850,7 +4850,7 @@ static int32_t addAllColumn(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pEx static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr) { int32_t ret = TSDB_CODE_SUCCESS; const char* msg6 = "illegal condition expression"; - + for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { tSqlExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i); if (p1 == NULL) { // no query condition on this table @@ -4859,7 +4859,7 @@ static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlEx tExprNode* p = NULL; - SArray* colList = taosArrayInit(10, sizeof(SColIndex)); + SArray* colList = taosArrayInit(10, sizeof(SColIndex)); ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL); size_t colNum = taosArrayGetSize(colList); for (int32_t k = 0; k < colNum; k++) { @@ -4898,12 +4898,12 @@ static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlEx if (pQueryInfo->colCond == NULL) { pQueryInfo->colCond = taosArrayInit(2, sizeof(STblCond)); } - - taosArrayPush(pQueryInfo->colCond, &cond); + + taosArrayPush(pQueryInfo->colCond, &cond); tSqlExprDestroy(p1); tExprTreeDestroy(p, NULL); - + if (ret) { break; } @@ -5029,7 +5029,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema2); atomic_add_fetch_32(&pTableMetaInfo->joinTagNum, 1); - + if (pTableMetaInfo->joinTagNum > 1) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } @@ -5073,9 +5073,9 @@ static int32_t validateSQLExprItemSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr, int32_t code = TSDB_CODE_SUCCESS; const char* msg1 = "invalid function parameters"; const char* msg2 = "not supported functions in arithmetic expression"; - + int32_t functionId = isValidFunction(pExpr->Expr.operand.z, pExpr->Expr.operand.n); - + pExpr->functionId = functionId; if (pExpr->Expr.paramList != NULL) { size_t numChildren = taosArrayGetSize(pExpr->Expr.paramList); @@ -6041,7 +6041,7 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* *pOut = NULL; return; } - + if (!isLogicalOperator(*pExpr)) { tSqlExpr* pLeft = (*pExpr)->pLeft; @@ -6099,17 +6099,17 @@ int32_t mergeTimeRange(SSqlCmd* pCmd, STimeWindow* res, STimeWindow* win, int32_ #define SET_EMPTY_RANGE(w) do { (w)->skey = INT64_MAX; (w)->ekey = INT64_MIN; } while (0) #define IS_EMPTY_RANGE(w) ((w)->skey == INT64_MAX && (w)->ekey == INT64_MIN) - + if (optr == TSDB_RELATION_AND) { if (res->skey > win->ekey || win->skey > res->ekey) { SET_EMPTY_RANGE(res); return TSDB_CODE_SUCCESS; } - + if (res->skey < win->skey) { res->skey = win->skey; } - + if (res->ekey > win->ekey) { res->ekey = win->ekey; } @@ -6134,7 +6134,7 @@ int32_t mergeTimeRange(SSqlCmd* pCmd, STimeWindow* res, STimeWindow* win, int32_ if (res->skey > win->skey) { res->skey = win->skey; } - + if (res->ekey < win->ekey) { res->ekey = win->ekey; } @@ -6144,7 +6144,7 @@ int32_t mergeTimeRange(SSqlCmd* pCmd, STimeWindow* res, STimeWindow* win, int32_ static int32_t createTimeRangeExpr(tSqlExpr** pExpr, STimeWindow* win, uint32_t tokenId) { *pExpr = calloc(1, sizeof(tSqlExpr)); - + (*pExpr)->type = SQL_NODE_VALUE; (*pExpr)->tokenId = tokenId; (*pExpr)->value.nType = TSDB_DATA_TYPE_VALUE_ARRAY; @@ -6167,6 +6167,7 @@ static int32_t convertTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return TSDB_CODE_SUCCESS; } pQueryInfo->onlyHasTagCond &= false; + if (!tSqlExprIsParentOfLeaf(pExpr)) { code = convertTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pLeft); @@ -6186,7 +6187,7 @@ static int32_t convertTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - + tSqlExpr* pRight = pExpr->pRight; if (getTimeRange(&win, pRight, pExpr->tokenId, tinfo.precision) != TSDB_CODE_SUCCESS) { @@ -6263,7 +6264,7 @@ static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInf SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); - + if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->ColName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (right)", pQueryInfo); } @@ -6369,7 +6370,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE if (pCondExpr->pTagCond == NULL) { return ret; } - + for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { tSqlExpr* p1 = extractExprForSTable(pCmd, &pCondExpr->pTagCond, pQueryInfo, i); if (p1 == NULL) { // no query condition on this table @@ -6377,7 +6378,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE } tExprNode* p = NULL; - + SArray* colList = taosArrayInit(10, sizeof(SColIndex)); ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL); size_t colNum = taosArrayGetSize(colList); @@ -6394,7 +6395,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE //if (ret == TSDB_CODE_SUCCESS) { // ret = filterInitFromTree(p, &pQueryInfo->tagFilter, (int32_t)taosArrayGetSize(colList), NULL); //} - + SBufferWriter bw = tbufInitWriter(NULL, false); TRY(0) { @@ -6409,7 +6410,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); int64_t uid = pTableMetaInfo->pTableMeta->id.uid; int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - + size_t num = taosArrayGetSize(colList); for(int32_t j = 0; j < num; ++j) { SColIndex* pIndex = taosArrayGet(colList, j); @@ -6419,7 +6420,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, &s[pIndex->colIndex]); } - + tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw); tSqlExprCompact(&pCondExpr->pTagCond); @@ -6429,7 +6430,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE tSqlExprDestroy(p1); tExprTreeDestroy(p, NULL); //TODO - + taosArrayDestroy(&colList); if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table"); @@ -6544,13 +6545,13 @@ static int32_t getQueryTimeRange(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr if (*pExpr == NULL) { return ret; } - + //multiple tables's query time range mixed together - + tExprNode* p = NULL; void *filter = NULL; - SArray* colList = taosArrayInit(10, sizeof(SColIndex)); + SArray* colList = taosArrayInit(10, sizeof(SColIndex)); ret = exprTreeFromSqlExpr(pCmd, &p, *pExpr, pQueryInfo, colList, NULL); taosArrayDestroy(&colList); @@ -6807,7 +6808,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo if ((!isTimeWindowQuery(pQueryInfo)) && (!pointInterp)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } - + if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && (!pointInterp)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } @@ -6823,9 +6824,9 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - + size_t numOfFields = tscNumOfFields(pQueryInfo); - + if (pQueryInfo->fillVal == NULL) { pQueryInfo->fillVal = calloc(numOfFields, sizeof(int64_t)); pQueryInfo->numOfFillVal = (int32_t)numOfFields; @@ -6886,7 +6887,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } } - + if ((num < numOfFields) || ((num - 1 < numOfFields) && pointInterp)) { tVariantListItem* lastItem = taosArrayGetLast(pFillToken); @@ -6922,13 +6923,13 @@ int32_t validateRangeNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlN const char *msg0 = "invalid usage of range clause"; const char* msg1 = "invalid timestamp in range"; SSqlCmd* pCmd = &pSql->cmd; - + bool interpQuery = tscIsPointInterpQuery(pQueryInfo); if ((!interpQuery) && (pSqlNode->pRange.start || pSqlNode->pRange.end)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } - + if (pSqlNode->pRange.start == NULL || pSqlNode->pRange.end == NULL) { pQueryInfo->range.skey = INT64_MIN; pQueryInfo->range.ekey = INT64_MIN; @@ -7006,8 +7007,8 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq setDefaultOrderInfo(pQueryInfo); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (pSqlNode->pSortOrder == NULL) { - return TSDB_CODE_SUCCESS; - } + return TSDB_CODE_SUCCESS; + } char* pMsgBuf = tscGetErrorMsgPayload(pCmd); SArray* pSortOrder = pSqlNode->pSortOrder; @@ -7578,12 +7579,12 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { len = varDataTLen(pUpdateMsg->data + schemaLen); if(len > pTagsSchema->bytes) return invalidOperationMsg(pMsg, msg14); } - + pUpdateMsg->tagValLen = htonl(len); // length may be changed after dump data - + int32_t total = sizeof(SUpdateTableTagValMsg) + len + schemaLen; pUpdateMsg->head.contLen = htonl(total); - + } else if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN) { SArray* pFieldList = pAlterSQL->pAddColumns; if (taosArrayGetSize(pFieldList) > 1) { @@ -7596,7 +7597,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (ret != TSDB_CODE_SUCCESS) { return ret; } - + tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p); } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) { if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) { // @@ -7749,7 +7750,7 @@ int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { pQueryInfo->interval.intervalUnit != 'y') { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } - + size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { int32_t functId = tscExprGet(pQueryInfo, i)->base.functionId; @@ -7770,7 +7771,7 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu // multi-output set/ todo refactor size_t size = taosArrayGetSize(pQueryInfo->exprList); - + for (int32_t k = 0; k < size; ++k) { SExprInfo* pExpr = tscExprGet(pQueryInfo, k); @@ -7828,7 +7829,8 @@ typedef struct SDNodeDynConfOption { int32_t len; // name string length } SDNodeDynConfOption; -int32_t validateEp(char* ep) { + +int32_t validateEp(char* ep) { char buf[TSDB_EP_LEN + 1] = {0}; tstrncpy(buf, ep, TSDB_EP_LEN); @@ -8031,10 +8033,10 @@ int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlN pQueryInfo->limit = pSqlNode->limit; pQueryInfo->clauseLimit = pQueryInfo->limit.limit; pQueryInfo->slimit = pSqlNode->slimit; - + tscDebug("0x%"PRIx64" limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql->self, pQueryInfo->limit.limit, pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset); - + if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } @@ -8329,7 +8331,7 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); - + for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); @@ -8337,7 +8339,7 @@ static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { bool qualifiedCol = false; for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j); - + if (pExpr->base.colInfo.colId == pColIndex->colId) { qualifiedCol = true; doLimitOutputNormalColOfGroupby(pExpr); @@ -8377,7 +8379,7 @@ static bool tagColumnInGroupby(SGroupbyExpr* pGroupbyExpr, int16_t columnId, int static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) { bool hasTagPrj = false; bool hasColumnPrj = false; - + size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); @@ -8415,7 +8417,7 @@ static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) { static void updateTagPrjFunction(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); - + for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ) { @@ -8605,7 +8607,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo s = &pSchema[colIndex]; } } - + if (TSDB_COL_IS_TAG(pColIndex->flag)) { int32_t f = TSDB_FUNC_TAG; @@ -8613,7 +8615,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo f = TSDB_FUNC_TAGPRJ; } - int32_t pos = tscGetFirstInvisibleFieldPos(pQueryInfo); + int32_t pos = tscGetFirstInvisibleFieldPos(pQueryInfo); SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; SExprInfo* pExpr = tscExprInsert(pQueryInfo, pos, f, &index, s->type, s->bytes, getNewResColId(pCmd), s->bytes, true); @@ -8803,10 +8805,10 @@ int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) { int32_t numOfExprs = (int32_t)tscNumOfExprs(pQueryInfo); size_t upNum = taosArrayGetSize(pQueryInfo->pUpstream); - + for (int32_t i = 0; i < numOfExprs; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); - + int32_t f = pExpr->base.functionId; if (f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || @@ -8823,7 +8825,7 @@ int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) { return TSDB_CODE_SUCCESS; } } - + return invalidOperationMsg(msg, msg1); } else if (f == TSDB_FUNC_INTERP) { if (pQueryInfo->groupbyExpr.columnInfo) { @@ -8839,7 +8841,7 @@ int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) { if (pUp->groupbyExpr.columnInfo) { return invalidOperationMsg(msg, msg2); } - + if (pUp->order.order == TSDB_ORDER_DESC || (pUp->order.orderColId != INT32_MIN && pUp->order.orderColId != PRIMARYKEY_TIMESTAMP_COL_INDEX)) { return invalidOperationMsg(msg, msg3); } @@ -8860,7 +8862,7 @@ int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) { if (TSDB_QUERY_HAS_TYPE(pUp->type, TSDB_QUERY_TYPE_PROJECTION_QUERY)) { return invalidOperationMsg(msg, msg5); } - + for (int32_t n = 0; n < exprNum; ++n) { expr = taosArrayGetP(pUp->exprList, n); if (expr->functionId == TSDB_FUNC_TOP || @@ -8897,11 +8899,11 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (pExpr->Expr.operand.z == NULL) { //handle 'select 1' if (pExpr->exprToken.n == 1 && 0 == strncasecmp(pExpr->exprToken.z, "1", 1)) { - server_status = true; + server_status = true; } else { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); - } - } + } + } // TODO redefine the function SDNodeDynConfOption functionsInfo[5] = {{"database()", 10}, {"server_version()", 16}, @@ -8935,7 +8937,7 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq pQueryInfo->command = TSDB_SQL_CURRENT_USER;break; default: { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } - + SColumnIndex ind = {0}; SExprInfo* pExpr1 = tscExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT, tDataTypes[TSDB_DATA_TYPE_INT].bytes, getNewResColId(pCmd), tDataTypes[TSDB_DATA_TYPE_INT].bytes, false); @@ -8943,7 +8945,7 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq tSqlExprItem* item = taosArrayGet(pExprList, 0); const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[index].name; tstrncpy(pExpr1->base.aliasName, name, tListLen(pExpr1->base.aliasName)); - + return TSDB_CODE_SUCCESS; } @@ -9104,7 +9106,7 @@ int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* p // if sql specifies db, use it, otherwise use default db SStrToken* pzTableName = &(pCreateTable->name); - + bool dbIncluded = false; if (tscValidateName(pzTableName, true, &dbIncluded) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -9382,7 +9384,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { kvRowCpy(pTag->data, row); free(row); - + bool dbIncluded2 = false; char tmp[TSDB_TABLE_FNAME_LEN] = {0}; SStrToken tbName = taosTokenDup(&pCreateTableInfo->name, tmp, tListLen(tmp)); @@ -9434,7 +9436,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { if (tscValidateName(pName, true, &dbIncluded1) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), STR_INVALID_TABLE_NAME); } - + // check to valid and create to name if(pInfo->pCreateTableInfo->to.n > 0) { bool dbInclude = false; @@ -9909,12 +9911,12 @@ static int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList if (t->type == TK_INTEGER || t->type == TK_FLOAT) { return invalidOperationMsg(msgBuf, STR_INVALID_TABLE_NAME); } - + bool dbIncluded = false; char buf[TSDB_TABLE_FNAME_LEN]; SStrToken sTblToken; sTblToken.z = buf; - + if (validateTableName(t->z, t->n, &sTblToken, &dbIncluded) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(msgBuf, STR_INVALID_TABLE_NAME); } @@ -9943,7 +9945,7 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis if (p->from == NULL) { return TSDB_CODE_TSC_INVALID_OPERATION; } - + if (p->from->type == SQL_NODE_FROM_TABLELIST) { int32_t code = getTableNameFromSqlNode(p, tableNameList, msgBuf, pSql); if (code != TSDB_CODE_SUCCESS) { @@ -10041,7 +10043,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { tNameExtractFullName(pname, name); size_t len = strlen(name); - + if (NULL == taosHashGetCloneExt(UTIL_GET_TABLEMETA(pSql), name, len, NULL, (void **)&pTableMeta, &tableMetaCapacity)) { // not found tfree(pTableMeta); @@ -10054,7 +10056,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { void* pVgroupIdList = NULL; if (pTableMeta->tableType == TSDB_CHILD_TABLE) { code = tscCreateTableMetaFromSTableMeta(pSql, (STableMeta **)(&pTableMeta), name, &tableMetaCapacity, (STableMeta **)(&pSTMeta)); - pSql->pBuf = (void*)pSTMeta; + pSql->pBuf = (void *)pSTMeta; // create the child table meta from super table failed, try load it from mnode if (code != TSDB_CODE_SUCCESS) { @@ -10135,7 +10137,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { } else if (taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) { int32_t usize = (int32_t)taosArrayGetSize(pQueryInfo->pUdfInfo); int32_t exist = 0; - + for (int32_t j = 0; j < usize; ++j) { SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, j); int32_t len = (int32_t)strlen(pUdfInfo->name); @@ -10155,7 +10157,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (taosArrayGetSize(pQueryInfo->pUdfInfo) > 1) { code = tscInvalidOperationMsg(pCmd->payload, "only one udf allowed", NULL); goto _end; - } + } } } } @@ -10813,9 +10815,9 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS *pExpr = calloc(1, sizeof(tExprNode)); (*pExpr)->nodeType = TSQL_NODE_TYPE; (*pExpr)->pType = calloc(1, sizeof(TAOS_FIELD)); - - *(*pExpr)->pType = pSqlExpr->dataType; - + + *(*pExpr)->pType = pSqlExpr->dataType; + return TSDB_CODE_SUCCESS; } else if (pSqlExpr->tokenId == TK_SET) { int32_t colType = -1; diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 13eacfc671..cfcf2f63ee 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -1418,7 +1418,7 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue }; SUdfInfo* pUdfInfo = NULL; - + size_t size = tscNumOfExprs(px); for (int32_t j = 0; j < size; ++j) { SExprInfo* pExprInfo = tscExprGet(px, j); @@ -1429,7 +1429,7 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue pSql->res.code = tscInvalidOperationMsg(pSql->cmd.payload, "only one udf allowed", NULL); return; } - + pUdfInfo = taosArrayGet(px->pUdfInfo, -1 * functionId - 1); int32_t code = initUdfInfo(pUdfInfo); if (code != TSDB_CODE_SUCCESS) { @@ -1537,7 +1537,7 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue px->pQInfo->runtimeEnv.udfIsCopy = true; px->pQInfo->runtimeEnv.pUdfInfo = pUdfInfo; - + tfree(schema); // set the pRuntimeEnv for pSourceOperator @@ -2702,9 +2702,11 @@ int32_t tscExprTopBottomIndex(SQueryInfo* pQueryInfo){ SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr == NULL) continue; - if (pExpr->base.functionId == TSDB_FUNC_TOP || pExpr->base.functionId == TSDB_FUNC_BOTTOM || - pExpr->base.functionId == TSDB_FUNC_SAMPLE || pExpr->base.functionId == TSDB_FUNC_UNIQUE || - pExpr->base.functionId == TSDB_FUNC_TAIL) { + if (pExpr->base.functionId == TSDB_FUNC_TOP + || pExpr->base.functionId == TSDB_FUNC_BOTTOM + || pExpr->base.functionId == TSDB_FUNC_SAMPLE + || pExpr->base.functionId == TSDB_FUNC_UNIQUE + || pExpr->base.functionId == TSDB_FUNC_TAIL) { return i; } } @@ -4195,20 +4197,20 @@ static void tscSubqueryCompleteCallback(void* param, TAOS_RES* tres, int code) { } int32_t doInitSubState(SSqlObj* pSql, int32_t numOfSubqueries) { - // bug fix. Above doInitSubState level, the loop invocation with the same SSqlObj will be fail. - // assert(pSql->subState.numOfSub == 0 && pSql->pSubs == NULL && pSql->subState.states == NULL); + //bug fix. Above doInitSubState level, the loop invocation with the same SSqlObj will be fail. + //assert(pSql->subState.numOfSub == 0 && pSql->pSubs == NULL && pSql->subState.states == NULL); if(pSql->pSubs) { free(pSql->pSubs); pSql->pSubs = NULL; } - + if(pSql->subState.states) { free(pSql->subState.states); pSql->subState.states = NULL; } - + pSql->subState.numOfSub = numOfSubqueries; - + pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES); pSql->subState.states = calloc(pSql->subState.numOfSub, sizeof(int8_t)); @@ -4234,7 +4236,7 @@ void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { (*pSql->fp)(pSql->param, pSql, 0); } return ; - } + } if (pSql->cmd.command == TSDB_SQL_SELECT) { tscAddIntoSqlList(pSql); diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index b8e41655d4..ee82212081 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -136,7 +136,7 @@ void shellInit(SShellArguments *_args) { exit(EXIT_SUCCESS); } #endif - + return; } @@ -1515,7 +1515,7 @@ int wsclient_print_data(int rows, TAOS_FIELD *fields, int cols, int64_t id, int if (*pshowed_rows == DEFAULT_RES_SHOW_NUM) { free(recv_buffer); return 0; - } + } for (int c = 0; c < cols; c++) { pos = start; pos += i * fields[c].bytes; diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c index 1188dc8843..f32d7841d3 100644 --- a/src/mnode/src/mnodeTable.c +++ b/src/mnode/src/mnodeTable.c @@ -1047,7 +1047,7 @@ static int32_t mnodeCreateSuperTableCb(SMnodeMsg *pMsg, int32_t code) { if (code == TSDB_CODE_SUCCESS) { mLInfo("stable:%s, is created in sdb, uid:%" PRIu64, pTable->info.tableId, pTable->uid); if(pMsg->pBatchMasterMsg) - pMsg->pBatchMasterMsg->successed ++; + pMsg->pBatchMasterMsg->successed ++; } else { mError("msg:%p, app:%p stable:%s, failed to create in sdb, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, tstrerror(code)); @@ -1060,7 +1060,7 @@ static int32_t mnodeCreateSuperTableCb(SMnodeMsg *pMsg, int32_t code) { // if super table create by batch msg, check done and send finished to client if(pMsg->pBatchMasterMsg) { if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received >= pMsg->pBatchMasterMsg->expected) - dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code); + dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code); } return code; @@ -3558,7 +3558,7 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pTable->sql, pShow->bytes[cols]); + STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pTable->sql, pShow->bytes[cols]); cols++; numOfRows++; @@ -3593,13 +3593,13 @@ static int32_t mnodeCompactSuperTables() { }; //mInfo("compact super %" PRIu64, pTable->uid); - + sdbInsertCompactRow(&row); } mInfo("end to compact super table..."); - return 0; + return 0; } static int32_t mnodeCompactChildTables() { @@ -3619,13 +3619,13 @@ static int32_t mnodeCompactChildTables() { }; //mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid); - + sdbInsertCompactRow(&row); } mInfo("end to compact child table..."); - return 0; + return 0; } int32_t mnodeCompactTables() { -- GitLab From 702b20a2bcd8c59618e86ae68bb5dbbf3dfdba03 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 23 Jun 2022 15:44:03 +0800 Subject: [PATCH 079/380] feat: taos-tools update for2.6 (#14158) * feat: update taos-tools for 2.6 prepare for 3.0 [TD-13052] * feat: update taos-tools fix -I -s for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index d3c29fb492..a875a057d1 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit d3c29fb492514cbaf08cb533976121bff5d94dea +Subproject commit a875a057d1225d85c6323b9edaccc2b1a9641987 -- GitLab From 976a5e625b6b4055c5269b2db728c97893ab4869 Mon Sep 17 00:00:00 2001 From: tangfangzhi Date: Thu, 23 Jun 2022 16:34:05 +0800 Subject: [PATCH 080/380] ci: add windows build to ci --- Jenkinsfile2 | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index 79954fb969..db26426b93 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -161,6 +161,153 @@ def pre_test_mac() { ''' return 1 } +def pre_test_win(){ + bat ''' + hostname + ipconfig + set + date /t + time /t + taskkill /f /t /im python.exe + taskkill /f /t /im bash.exe + taskkill /f /t /im taosd.exe + rd /s /Q %WIN_INTERNAL_ROOT%\\debug || echo "no debug folder" + echo "clean environment done" + exit 0 + ''' + bat ''' + cd %WIN_INTERNAL_ROOT% + git reset --hard + ''' + bat ''' + cd %WIN_COMMUNITY_ROOT% + git reset --hard + ''' + script { + if (env.CHANGE_TARGET == 'master') { + bat ''' + cd %WIN_INTERNAL_ROOT% + git checkout master + ''' + bat ''' + cd %WIN_COMMUNITY_ROOT% + git checkout master + ''' + } else if (env.CHANGE_TARGET == '2.0') { + bat ''' + cd %WIN_INTERNAL_ROOT% + git checkout 2.0 + ''' + bat ''' + cd %WIN_COMMUNITY_ROOT% + git checkout 2.0 + ''' + } else if (env.CHANGE_TARGET == '2.4') { + bat ''' + cd %WIN_INTERNAL_ROOT% + git checkout 2.4 + ''' + bat ''' + cd %WIN_COMMUNITY_ROOT% + git checkout 2.4 + ''' + } else if (env.CHANGE_TARGET == '2.6') { + bat ''' + cd %WIN_INTERNAL_ROOT% + git checkout 2.6 + ''' + bat ''' + cd %WIN_COMMUNITY_ROOT% + git checkout 2.6 + ''' + } else { + bat ''' + cd %WIN_INTERNAL_ROOT% + git checkout develop + ''' + bat ''' + cd %WIN_COMMUNITY_ROOT% + git checkout develop + ''' + } + } + bat ''' + cd %WIN_INTERNAL_ROOT% + git pull + ''' + bat ''' + cd %WIN_COMMUNITY_ROOT% + git remote prune origin + git pull + ''' + bat ''' + cd %WIN_INTERNAL_ROOT% + git branch + git log -5 + ''' + bat ''' + cd %WIN_COMMUNITY_ROOT% + git branch + git log -5 + ''' + script { + if (env.CHANGE_URL =~ /\/TDengine\//) { + bat ''' + echo "match /TDengine/ repository" + cd %WIN_COMMUNITY_ROOT% + git fetch origin +refs/pull/%CHANGE_ID%/merge + git checkout -qf FETCH_HEAD + git log -5 + ''' + } else if (env.CHANGE_URL =~ /\/TDinternal\//) { + bat ''' + echo "match /TDinternal/ repository" + cd %WIN_INTERNAL_ROOT% + git fetch origin +refs/pull/%CHANGE_ID%/merge + git checkout -qf FETCH_HEAD + git log -5 + ''' + } else { + bat ''' + echo "unmatched reposiotry %CHANGE_URL%" + ''' + } + } + bat ''' + cd %WIN_COMMUNITY_ROOT% + git submodule update --init --recursive + ''' + /*bat ''' + cd %WIN_CONNECTOR_ROOT% + git branch + git reset --hard + git pull + ''' + bat ''' + cd %WIN_CONNECTOR_ROOT% + git log -5 + '''*/ +} +def pre_test_build_win() { + bat ''' + echo "building ..." + time /t + cd %WIN_INTERNAL_ROOT% + mkdir debug + cd debug + time /t + call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat" x64 + set CL=/MP8 + echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cmake" + time /t + cmake .. -G "NMake Makefiles JOM" || exit 7 + echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> jom -j 6" + time /t + jom -j 6 || exit 8 + time /t + ''' + return 1 +} pipeline { agent none options { skipDefaultCheckout() } @@ -207,6 +354,21 @@ pipeline { } } } + stage('build win') { + agent {label " windows10_05 || windows10_06 "} + environment{ + WIN_INTERNAL_ROOT="C:\\workspace\\${env.EXECUTOR_NUMBER}\\TDinternal" + WIN_COMMUNITY_ROOT="C:\\workspace\\${env.EXECUTOR_NUMBER}\\TDinternal\\community" + WIN_SYSTEM_TEST_ROOT="C:\\workspace\\${env.EXECUTOR_NUMBER}\\TDinternal\\community\\tests\\system-test" + WIN_CONNECTOR_ROOT="C:\\workspace\\${env.EXECUTOR_NUMBER}\\taos-connector-python" + } + steps { + timeout(time: 200, unit: 'MINUTES') { + pre_test_win() + pre_test_build_win() + } + } + } stage('run cases') { agent {label " worker01 || worker02 "} steps { -- GitLab From e1d40a5ae2c5df046701d3c07ca4161331aec45a Mon Sep 17 00:00:00 2001 From: tangfangzhi Date: Thu, 23 Jun 2022 17:28:02 +0800 Subject: [PATCH 081/380] fix: a typo --- Jenkinsfile2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index db26426b93..b27622c25d 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -363,7 +363,7 @@ pipeline { WIN_CONNECTOR_ROOT="C:\\workspace\\${env.EXECUTOR_NUMBER}\\taos-connector-python" } steps { - timeout(time: 200, unit: 'MINUTES') { + timeout(time: 20, unit: 'MINUTES') { pre_test_win() pre_test_build_win() } -- GitLab From 7e22a3093f0b0391e604cddf75ab820f8a9cc38a Mon Sep 17 00:00:00 2001 From: Bo Ding Date: Fri, 24 Jun 2022 10:23:21 +0800 Subject: [PATCH 082/380] enh: change master/slave to leader/follower --- src/plugins/monitor/src/monMain.c | 8 ++--- src/sync/src/syncMain.c | 4 +-- tests/pytest/client/client.py | 4 +-- tests/pytest/cluster/changeReplicaTest.py | 12 +++---- .../manualTest/TD-5114/checkClusterStatus.py | 2 +- tests/script/general/db/alter_tables_d2.sim | 10 +++--- tests/script/general/db/alter_tables_v1.sim | 12 +++---- tests/script/general/db/alter_tables_v4.sim | 10 +++--- tests/script/general/db/delete.sim | 2 +- tests/script/general/wal/sync.sim | 6 ++-- tests/script/issue/TD-2677.sim | 6 ++-- tests/script/issue/TD-2680.sim | 2 +- tests/script/issue/TD-2713.sim | 6 ++-- tests/script/issue/TD-3300.sim | 22 ++++++------ tests/script/tmp/mnodes.sim | 6 ++-- .../arbitrator/dn2_mn1_cache_file_sync.sim | 4 +-- .../dn2_mn1_cache_file_sync_second.sim | 2 +- .../arbitrator/dn3_mn1_r2_vnode_delDir.sim | 10 +++--- .../arbitrator/dn3_mn1_r3_vnode_delDir.sim | 14 ++++---- .../arbitrator/dn3_mn1_vnode_change.sim | 8 ++--- .../dn3_mn1_vnode_corruptFile_offline.sim | 8 ++--- .../dn3_mn1_vnode_corruptFile_online.sim | 6 ++-- .../dn3_mn1_vnode_createErrData_online.sim | 6 ++-- .../arbitrator/dn3_mn1_vnode_delDir.sim | 14 ++++---- .../dn3_mn1_vnode_noCorruptFile_offline.sim | 8 ++--- .../arbitrator/dn3_mn1_vnode_nomaster.sim | 2 +- .../unique/arbitrator/dn3_mn2_killDnode.sim | 2 +- .../arbitrator/insert_duplicationTs.sim | 4 +-- .../offline_replica2_alterTable_online.sim | 2 +- .../offline_replica2_alterTag_online.sim | 2 +- .../offline_replica2_createTable_online.sim | 2 +- .../offline_replica2_dropDb_online.sim | 2 +- .../offline_replica2_dropTable_online.sim | 2 +- .../offline_replica3_alterTable_online.sim | 2 +- .../offline_replica3_alterTag_online.sim | 2 +- .../offline_replica3_createTable_online.sim | 2 +- .../offline_replica3_dropDb_online.sim | 2 +- .../offline_replica3_dropTable_online.sim | 2 +- .../replica_changeWithArbitrator.sim | 2 +- .../sync_replica2_alterTable_add.sim | 2 +- .../sync_replica2_alterTable_drop.sim | 2 +- .../arbitrator/sync_replica2_dropDb.sim | 2 +- .../arbitrator/sync_replica2_dropTable.sim | 2 +- .../sync_replica3_alterTable_add.sim | 2 +- .../sync_replica3_alterTable_drop.sim | 2 +- .../arbitrator/sync_replica3_createTable.sim | 2 +- ...ca3_dnodeChang_DropAddAlterTableDropDb.sim | 14 ++++---- .../arbitrator/sync_replica3_dropDb.sim | 2 +- .../arbitrator/sync_replica3_dropTable.sim | 2 +- tests/script/unique/cluster/balance1.sim | 10 +++--- tests/script/unique/cluster/balance2.sim | 16 ++++----- tests/script/unique/cluster/balance3.sim | 22 ++++++------ tests/script/unique/cluster/cache.sim | 4 +-- tests/script/unique/cluster/flowctrl.sim | 6 ++-- tests/script/unique/cluster/vgroup100.sim | 12 +++---- .../unique/clusterSimCase/cluster_main.sim | 22 ++++++------ tests/script/unique/db/commit.sim | 2 +- tests/script/unique/db/delete.sim | 2 +- tests/script/unique/db/replica_add12.sim | 2 +- tests/script/unique/db/replica_add13.sim | 2 +- tests/script/unique/db/replica_add23.sim | 2 +- tests/script/unique/db/replica_part.sim | 2 +- tests/script/unique/db/replica_reduce21.sim | 2 +- tests/script/unique/db/replica_reduce31.sim | 2 +- tests/script/unique/db/replica_reduce32.sim | 2 +- tests/script/unique/dnode/alternativeRole.sim | 4 +-- tests/script/unique/dnode/offline3.sim | 2 +- tests/script/unique/http/admin.sim | 2 +- .../migrate/mn2_vn2_repl2_rmMnodeDir.sim | 12 +++---- .../migrate/mn2_vn2_repl2_rmMnodeVnodeDir.sim | 12 +++---- ..._repl2_rmMnodeVnodeDir_stopAll_starAll.sim | 12 +++---- .../migrate/mn2_vn2_repl2_rmVnodeDir.sim | 12 +++---- tests/script/unique/mnode/mgmt20.sim | 8 ++--- tests/script/unique/mnode/mgmt21.sim | 6 ++-- tests/script/unique/mnode/mgmt22.sim | 20 +++++------ tests/script/unique/mnode/mgmt23.sim | 18 +++++----- tests/script/unique/mnode/mgmt24.sim | 10 +++--- tests/script/unique/mnode/mgmt25.sim | 14 ++++---- tests/script/unique/mnode/mgmt26.sim | 18 +++++----- tests/script/unique/mnode/mgmt30.sim | 8 ++--- tests/script/unique/mnode/mgmt33.sim | 30 ++++++++-------- tests/script/unique/mnode/mgmt34.sim | 36 +++++++++---------- tests/script/unique/mnode/mgmtr2.sim | 6 ++-- tests/script/unique/vnode/many.sim | 2 +- tests/script/unique/vnode/replica2_repeat.sim | 2 +- tests/script/unique/vnode/replica3_basic.sim | 6 ++-- tests/script/unique/vnode/replica3_repeat.sim | 2 +- 87 files changed, 303 insertions(+), 303 deletions(-) diff --git a/src/plugins/monitor/src/monMain.c b/src/plugins/monitor/src/monMain.c index 1ff2f0ef8d..bd0e015205 100644 --- a/src/plugins/monitor/src/monMain.c +++ b/src/plugins/monitor/src/monMain.c @@ -703,8 +703,8 @@ static int32_t monBuildMnodesTotalSql(char *sql) { for (int i = 0; i < num_fields; ++i) { if (strcmp(fields[i].name, "role") == 0) { int32_t charLen = monGetRowElemCharLen(fields[i], (char *)row[i]); - if (strncmp((char *)row[i], "master", charLen) == 0 || - strncmp((char *)row[i], "slave", charLen) == 0) { + if (strncmp((char *)row[i], "leader", charLen) == 0 || + strncmp((char *)row[i], "follower", charLen) == 0) { totalMnodesAlive += 1; } } @@ -794,8 +794,8 @@ static int32_t monGetVnodesTotalStats(char *ep, int32_t *totalVnodes, for (int i = 0; i < num_fields; ++i) { if (strcmp(fields[i].name, "status") == 0) { int32_t charLen = monGetRowElemCharLen(fields[i], (char *)row[i]); - if (strncmp((char *)row[i], "master", charLen) == 0 || - strncmp((char *)row[i], "slave", charLen) == 0) { + if (strncmp((char *)row[i], "leader", charLen) == 0 || + strncmp((char *)row[i], "follower", charLen) == 0) { *totalVnodesAlive += 1; } } diff --git a/src/sync/src/syncMain.c b/src/sync/src/syncMain.c index be35f3aaf9..3f5b2e12e2 100644 --- a/src/sync/src/syncMain.c +++ b/src/sync/src/syncMain.c @@ -68,8 +68,8 @@ char* syncRole[] = { "offline", "unsynced", "syncing", - "slave", - "master" + "follower", + "leader" }; char *syncStatus[] = { diff --git a/tests/pytest/client/client.py b/tests/pytest/client/client.py index 9192f7e6d3..308ffab848 100644 --- a/tests/pytest/client/client.py +++ b/tests/pytest/client/client.py @@ -50,7 +50,7 @@ class TDTestCase: ret = tdSql.query('show mnodes') tdSql.checkRows(1) - tdSql.checkData(0, 2, "master") + tdSql.checkData(0, 2, "leader") role_time = tdSql.getData(0, 3) create_time = tdSql.getData(0, 4) @@ -73,7 +73,7 @@ class TDTestCase: ret = tdSql.query('show vnodes "{}"'.format(dnodeEndpoint)) tdSql.checkRows(1) tdSql.checkData(0, 0, 2) - tdSql.checkData(0, 1, "master") + tdSql.checkData(0, 1, "leader") cmd = "taos -h 127.0.0.1 -s 'show databases'" r = os.popen(cmd) diff --git a/tests/pytest/cluster/changeReplicaTest.py b/tests/pytest/cluster/changeReplicaTest.py index 7fa68edbfe..a7b357cc57 100644 --- a/tests/pytest/cluster/changeReplicaTest.py +++ b/tests/pytest/cluster/changeReplicaTest.py @@ -30,22 +30,22 @@ class ClusterTestcase: tdSql.execute("use %s" % ctest.dbName) tdSql.query("show vgroups") for i in range(10): - tdSql.checkData(i, 5, "master") + tdSql.checkData(i, 5, "leader") tdSql.execute("alter database %s replica 2" % ctest.dbName) tdLog.sleep(30) tdSql.query("show vgroups") for i in range(10): - tdSql.checkData(i, 5, "master") - tdSql.checkData(i, 7, "slave") + tdSql.checkData(i, 5, "leader") + tdSql.checkData(i, 7, "follower") tdSql.execute("alter database %s replica 3" % ctest.dbName) tdLog.sleep(30) tdSql.query("show vgroups") for i in range(10): - tdSql.checkData(i, 5, "master") - tdSql.checkData(i, 7, "slave") - tdSql.checkData(i, 9, "slave") + tdSql.checkData(i, 5, "leader") + tdSql.checkData(i, 7, "follower") + tdSql.checkData(i, 9, "follower") ct = ClusterTestcase() ct.run() \ No newline at end of file diff --git a/tests/pytest/manualTest/TD-5114/checkClusterStatus.py b/tests/pytest/manualTest/TD-5114/checkClusterStatus.py index c6bff305a5..213d6b87ab 100644 --- a/tests/pytest/manualTest/TD-5114/checkClusterStatus.py +++ b/tests/pytest/manualTest/TD-5114/checkClusterStatus.py @@ -53,7 +53,7 @@ class TwoClients: tdSql.query("show mnodes") tdSql.checkRows(3) - roles = "master slave" + roles = "leader follower" for i in range(tdSql.queryRows): if (tdSql.queryResult[i][2] in roles ): ep = tdSql.queryResult[i][1] diff --git a/tests/script/general/db/alter_tables_d2.sim b/tests/script/general/db/alter_tables_d2.sim index f74f98d571..41d72e35d3 100644 --- a/tests/script/general/db/alter_tables_d2.sim +++ b/tests/script/general/db/alter_tables_d2.sim @@ -109,7 +109,7 @@ sql show mnodes -x step1 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step2 endi @@ -186,7 +186,7 @@ sql show mnodes -x step3 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step3 endi @@ -323,7 +323,7 @@ sql show mnodes -x step9 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step9 endi @@ -419,7 +419,7 @@ sql show mnodes -x step10 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step10 endi @@ -482,7 +482,7 @@ sql show mnodes -x step1xx print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1xx endi diff --git a/tests/script/general/db/alter_tables_v1.sim b/tests/script/general/db/alter_tables_v1.sim index 20c4c73363..8708d764e4 100644 --- a/tests/script/general/db/alter_tables_v1.sim +++ b/tests/script/general/db/alter_tables_v1.sim @@ -62,7 +62,7 @@ sql show mnodes -x step2 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step2 endi @@ -115,7 +115,7 @@ sql show mnodes -x step5 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step5 endi @@ -185,7 +185,7 @@ sql show mnodes -x step7 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step7 endi @@ -240,7 +240,7 @@ sql show mnodes -x step9 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step9 endi @@ -314,7 +314,7 @@ sql show mnodes -x step10 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step10 endi @@ -369,7 +369,7 @@ sql show mnodes -x step12 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step12 endi diff --git a/tests/script/general/db/alter_tables_v4.sim b/tests/script/general/db/alter_tables_v4.sim index 10bb4e108b..02816097ed 100644 --- a/tests/script/general/db/alter_tables_v4.sim +++ b/tests/script/general/db/alter_tables_v4.sim @@ -81,7 +81,7 @@ sql show mnodes -x step3 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step3 endi @@ -155,7 +155,7 @@ sql show mnodes -x step5 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step5 endi @@ -287,7 +287,7 @@ sql show mnodes -x step9 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step9 endi @@ -381,7 +381,7 @@ sql show mnodes -x step10 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step10 endi @@ -441,7 +441,7 @@ sql show mnodes -x step12 print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step12 endi diff --git a/tests/script/general/db/delete.sim b/tests/script/general/db/delete.sim index 4384044885..80ec812c74 100644 --- a/tests/script/general/db/delete.sim +++ b/tests/script/general/db/delete.sim @@ -57,7 +57,7 @@ step3: sql show mnodes print dnode1 role $data2_1 -if $data2_1 != master then +if $data2_1 != leader then goto step3 endi diff --git a/tests/script/general/wal/sync.sim b/tests/script/general/wal/sync.sim index 3a89523918..bd9ed574a9 100644 --- a/tests/script/general/wal/sync.sim +++ b/tests/script/general/wal/sync.sim @@ -54,13 +54,13 @@ print mnode2Role $mnode2Role $mnode3Role = $data2_3 print mnode3Role $mnode3Role -if $mnode1Role != master then +if $mnode1Role != leader then goto show1 endi -if $mnode2Role != slave then +if $mnode2Role != follower then goto show1 endi -if $mnode3Role != slave then +if $mnode3Role != follower then goto show1 endi diff --git a/tests/script/issue/TD-2677.sim b/tests/script/issue/TD-2677.sim index 8d2058a385..db61aca811 100644 --- a/tests/script/issue/TD-2677.sim +++ b/tests/script/issue/TD-2677.sim @@ -54,13 +54,13 @@ print mnode2Role $mnode2Role $mnode3Role = $data2_3 print mnode3Role $mnode3Role -if $mnode1Role != master then +if $mnode1Role != leader then goto step1 endi -if $mnode2Role != slave then +if $mnode2Role != follower then goto step1 endi -if $mnode3Role != slave then +if $mnode3Role != follower then goto step1 endi diff --git a/tests/script/issue/TD-2680.sim b/tests/script/issue/TD-2680.sim index 631332160f..4f1bd63dd8 100644 --- a/tests/script/issue/TD-2680.sim +++ b/tests/script/issue/TD-2680.sim @@ -67,7 +67,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi diff --git a/tests/script/issue/TD-2713.sim b/tests/script/issue/TD-2713.sim index b66c55b9b9..f2c0bc9eb5 100644 --- a/tests/script/issue/TD-2713.sim +++ b/tests/script/issue/TD-2713.sim @@ -60,13 +60,13 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi -if $data2_2 != slave then +if $data2_2 != follower then goto step1 endi -if $data2_3 != slave then +if $data2_3 != follower then goto step1 endi diff --git a/tests/script/issue/TD-3300.sim b/tests/script/issue/TD-3300.sim index 0745ceb849..8ff3af5895 100644 --- a/tests/script/issue/TD-3300.sim +++ b/tests/script/issue/TD-3300.sim @@ -76,10 +76,10 @@ endi if $data06 != 2 then return -1 endi -if $data05 != master then +if $data05 != leader then return -1 endi -if $data07 != slave then +if $data07 != follower then return -1 endi @@ -125,10 +125,10 @@ endi if $data06 != 2 then goto step4 endi -if $data05 != master then +if $data05 != leader then goto step4 endi -if $data07 != slave then +if $data07 != follower then goto step4 endi @@ -189,7 +189,7 @@ endi if $data05 != offline then goto step5 endi -if $data07 != master then +if $data07 != leader then goto step5 endi @@ -251,10 +251,10 @@ endi if $data06 != 2 then goto step6 endi -if $data05 != slave then +if $data05 != follower then goto step6 endi -if $data07 != master then +if $data07 != leader then goto step6 endi @@ -337,7 +337,7 @@ endi if $data06 != 2 then goto step7 endi -if $data05 != master then +if $data05 != leader then goto step7 endi if $data07 != offline then @@ -422,10 +422,10 @@ endi if $data06 != 2 then goto step8 endi -if $data05 != master then +if $data05 != leader then goto step8 endi -if $data07 != slave then +if $data07 != follower then goto step8 endi @@ -521,7 +521,7 @@ endi if $data05 != offline then goto step7 endi -if $data07 != master then +if $data07 != leader then goto step7 endi diff --git a/tests/script/tmp/mnodes.sim b/tests/script/tmp/mnodes.sim index 8bca76c38b..e9b03c8447 100644 --- a/tests/script/tmp/mnodes.sim +++ b/tests/script/tmp/mnodes.sim @@ -74,13 +74,13 @@ print mnode2Role $mnode2Role $mnode3Role = $data2_3 print mnode3Role $mnode3Role -if $mnode1Role != master then +if $mnode1Role != leader then goto step1 endi -if $mnode2Role != slave then +if $mnode2Role != follower then goto step1 endi -if $mnode3Role != slave then +if $mnode3Role != follower then goto step1 endi diff --git a/tests/script/unique/arbitrator/dn2_mn1_cache_file_sync.sim b/tests/script/unique/arbitrator/dn2_mn1_cache_file_sync.sim index dbd0e2bd87..f20c92b982 100644 --- a/tests/script/unique/arbitrator/dn2_mn1_cache_file_sync.sim +++ b/tests/script/unique/arbitrator/dn2_mn1_cache_file_sync.sim @@ -1,6 +1,6 @@ # Test case describe: dnode1 is only mnode, dnode2/dnode3 are only vnode # step 1: start dnode1 -# step 2: start dnode2 and dnode3, and all added into cluster (Suppose dnode2 is master-vnode) +# step 2: start dnode2 and dnode3, and all added into cluster (Suppose dnode2 is leader-vnode) # step 2: create db, table, insert data, and Falling disc into file (control only one file, e.g. 1841) # step 3: insert old data(now-20d) and new data(now-40d), control data rows in order to save in cache, not falling disc # step 4: stop dnode2, so date rows falling disc, generate two new files 1840, 1842 in dnode2 @@ -145,7 +145,7 @@ if $dnode2Status != ready then goto wait_dnode3_offline endi -sleep $sleepTimer # waitting for move master vnode of dnode2 to dnode3 +sleep $sleepTimer # waitting for move leader vnode of dnode2 to dnode3 # check using select sql select count(*) from $stb print data00 $data00 diff --git a/tests/script/unique/arbitrator/dn2_mn1_cache_file_sync_second.sim b/tests/script/unique/arbitrator/dn2_mn1_cache_file_sync_second.sim index e15edb3f3d..a7380a8de9 100644 --- a/tests/script/unique/arbitrator/dn2_mn1_cache_file_sync_second.sim +++ b/tests/script/unique/arbitrator/dn2_mn1_cache_file_sync_second.sim @@ -1,6 +1,6 @@ # Test case describe: dnode1 is only mnode, dnode2/dnode3 are only vnode # step 1: start dnode1 -# step 2: start dnode2 and dnode3, and all added into cluster (Suppose dnode2 is master-vnode) +# step 2: start dnode2 and dnode3, and all added into cluster (Suppose dnode2 is leader-vnode) # step 3: create db, table, insert data, and Falling disc into file (control only one file, e.g. 1841) # step 4: insert old data(now-20d) and new data(now-40d), control data rows in order to save in cache, not falling disc # step 5: stop dnode2, so date rows falling disc, generate two new files 1840, 1842 in dnode2 diff --git a/tests/script/unique/arbitrator/dn3_mn1_r2_vnode_delDir.sim b/tests/script/unique/arbitrator/dn3_mn1_r2_vnode_delDir.sim index 96fde9061a..3f5bcc5da9 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_r2_vnode_delDir.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_r2_vnode_delDir.sim @@ -144,7 +144,7 @@ if $dnode3Vtatus != offline then sleep 2000 goto wait_dnode3_vgroup_offline endi -if $dnode2Vtatus != master then +if $dnode2Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_offline endi @@ -209,11 +209,11 @@ $dnode2Vtatus = $data7_2 print dnode2Vtatus: $dnode3Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode3Vtatus != slave then +if $dnode3Vtatus != follower then sleep 2000 goto wait_dnode3_vgroup_slave endi -if $dnode2Vtatus != master then +if $dnode2Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_slave endi @@ -325,11 +325,11 @@ $dnode2Vtatus = $data7_2 print dnode4Vtatus: $dnode4Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode2_vgroup_slave endi -if $dnode2Vtatus != slave then +if $dnode2Vtatus != follower then sleep 2000 goto wait_dnode2_vgroup_slave endi diff --git a/tests/script/unique/arbitrator/dn3_mn1_r3_vnode_delDir.sim b/tests/script/unique/arbitrator/dn3_mn1_r3_vnode_delDir.sim index da76cc467b..f0d2b41ce8 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_r3_vnode_delDir.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_r3_vnode_delDir.sim @@ -146,7 +146,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi @@ -211,11 +211,11 @@ $dnode3Vtatus = $data7_2 print dnode4Vtatus: $dnode4Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode4Vtatus != slave then +if $dnode4Vtatus != follower then sleep 2000 goto wait_dnode4_vgroup_slave endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_slave endi @@ -330,11 +330,11 @@ $dnode3Vtatus = $data7_2 print dnode4Vtatus: $dnode4Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode4Vtatus != master then +if $dnode4Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_master endi -if $dnode3Vtatus != slave then +if $dnode3Vtatus != follower then sleep 2000 goto wait_dnode4_vgroup_master endi @@ -393,11 +393,11 @@ $dnode3Vtatus = $data7_2 print dnode4Vtatus: $dnode4Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode4Vtatus != master then +if $dnode4Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_master_2 endi -if $dnode3Vtatus != slave then +if $dnode3Vtatus != follower then sleep 2000 goto wait_dnode4_vgroup_master_2 endi diff --git a/tests/script/unique/arbitrator/dn3_mn1_vnode_change.sim b/tests/script/unique/arbitrator/dn3_mn1_vnode_change.sim index 6d81effab6..53a1ce04fa 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_vnode_change.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_vnode_change.sim @@ -145,7 +145,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi @@ -218,11 +218,11 @@ $dnode3Vtatus = $data7_2 print dnode4Vtatus: $dnode4Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode4Vtatus != slave then +if $dnode4Vtatus != follower then sleep 2000 goto wait_dnode4_vgroup_slave endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_slave endi @@ -292,7 +292,7 @@ $dnode3Vtatus = $data7_2 print dnode4Vtatus: $dnode4Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode4Vtatus != master then +if $dnode4Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_master endi diff --git a/tests/script/unique/arbitrator/dn3_mn1_vnode_corruptFile_offline.sim b/tests/script/unique/arbitrator/dn3_mn1_vnode_corruptFile_offline.sim index d22aca07cb..ba15bb42d5 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_vnode_corruptFile_offline.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_vnode_corruptFile_offline.sim @@ -151,7 +151,7 @@ if $dnode3Vtatus != offline then sleep 2000 goto wait_dnode3_vgroup_offline endi -if $dnode2Vtatus != master then +if $dnode2Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_offline endi @@ -237,11 +237,11 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode2Vtatus = $data5_2 $dnode3Vtatus = $data7_2 -if $dnode2Vtatus != master then +if $dnode2Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_slave endi -if $dnode3Vtatus != slave then +if $dnode3Vtatus != follower then sleep 2000 goto wait_dnode3_vgroup_slave endi @@ -320,7 +320,7 @@ if $dnode2Vtatus != offline then sleep 2000 goto wait_dnode3_vgroup_master endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_master endi diff --git a/tests/script/unique/arbitrator/dn3_mn1_vnode_corruptFile_online.sim b/tests/script/unique/arbitrator/dn3_mn1_vnode_corruptFile_online.sim index 884a43bce1..119cb418db 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_vnode_corruptFile_online.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_vnode_corruptFile_online.sim @@ -203,7 +203,7 @@ if $dnode2Vtatus != offline then sleep 2000 goto wait_dnode3_vgroup_master endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_master endi @@ -328,11 +328,11 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode2Vtatus = $data7_2 $dnode3Vtatus = $data5_2 -if $dnode2Vtatus != slave then +if $dnode2Vtatus != follower then sleep 2000 goto wait_dnode3_vgroup_master_1 endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_master_1 endi diff --git a/tests/script/unique/arbitrator/dn3_mn1_vnode_createErrData_online.sim b/tests/script/unique/arbitrator/dn3_mn1_vnode_createErrData_online.sim index 3c74de4916..f393e4afba 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_vnode_createErrData_online.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_vnode_createErrData_online.sim @@ -165,7 +165,7 @@ if $dnode2Vtatus != offline then sleep 2000 goto wait_dnode3_vgroup_master endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_master endi @@ -290,11 +290,11 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode2Vtatus = $data7_2 $dnode3Vtatus = $data5_2 -if $dnode2Vtatus != slave then +if $dnode2Vtatus != follower then sleep 2000 goto wait_dnode3_vgroup_master_1 endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_master_1 endi diff --git a/tests/script/unique/arbitrator/dn3_mn1_vnode_delDir.sim b/tests/script/unique/arbitrator/dn3_mn1_vnode_delDir.sim index d0399222f1..00ab574e07 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_vnode_delDir.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_vnode_delDir.sim @@ -148,7 +148,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi @@ -206,11 +206,11 @@ $dnode3Vtatus = $data7_2 print dnode4Vtatus: $dnode4Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode4Vtatus != slave then +if $dnode4Vtatus != follower then sleep 2000 goto wait_dnode4_vgroup_slave endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_slave endi @@ -306,11 +306,11 @@ $dnode3Vtatus = $data7_2 print dnode4Vtatus: $dnode4Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode4Vtatus != master then +if $dnode4Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_slave endi -if $dnode3Vtatus != slave then +if $dnode3Vtatus != follower then sleep 2000 goto wait_dnode3_vgroup_slave endi @@ -422,11 +422,11 @@ $dnode3Vtatus = $data7_2 print dnode4Vtatus: $dnode4Vtatus print dnode3Vtatus: $dnode3Vtatus -if $dnode4Vtatus != master then +if $dnode4Vtatus != leader then sleep 2000 goto wait_dnode2_vgroup_slave endi -if $dnode3Vtatus != slave then +if $dnode3Vtatus != follower then sleep 2000 goto wait_dnode2_vgroup_slave endi diff --git a/tests/script/unique/arbitrator/dn3_mn1_vnode_noCorruptFile_offline.sim b/tests/script/unique/arbitrator/dn3_mn1_vnode_noCorruptFile_offline.sim index 01534f9476..370b19990b 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_vnode_noCorruptFile_offline.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_vnode_noCorruptFile_offline.sim @@ -151,7 +151,7 @@ if $dnode3Vtatus != offline then sleep 2000 goto wait_dnode3_vgroup_offline endi -if $dnode2Vtatus != master then +if $dnode2Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_offline endi @@ -237,11 +237,11 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode2Vtatus = $data7_2 $dnode3Vtatus = $data5_2 -if $dnode2Vtatus != master then +if $dnode2Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_slave endi -if $dnode3Vtatus != slave then +if $dnode3Vtatus != follower then sleep 2000 goto wait_dnode3_vgroup_slave endi @@ -320,7 +320,7 @@ if $dnode2Vtatus != offline then sleep 2000 goto wait_dnode3_vgroup_master endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode3_vgroup_master endi diff --git a/tests/script/unique/arbitrator/dn3_mn1_vnode_nomaster.sim b/tests/script/unique/arbitrator/dn3_mn1_vnode_nomaster.sim index b9ee508f78..35a7bf8966 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_vnode_nomaster.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_vnode_nomaster.sim @@ -268,7 +268,7 @@ if $dnode3Vtatus != offline then sleep 2000 goto wait_dnode2_vgroup_master endi -if $dnode2Vtatus != master then +if $dnode2Vtatus != leader then sleep 2000 goto wait_dnode2_vgroup_master endi diff --git a/tests/script/unique/arbitrator/dn3_mn2_killDnode.sim b/tests/script/unique/arbitrator/dn3_mn2_killDnode.sim index d90853d2e4..d12b5ff3ad 100644 --- a/tests/script/unique/arbitrator/dn3_mn2_killDnode.sim +++ b/tests/script/unique/arbitrator/dn3_mn2_killDnode.sim @@ -104,7 +104,7 @@ $mnode2Status = $data2_2 $mnode3Status = $data2_3 #$mnode4Status = $data2_4 -if $mnode1Status != master then +if $mnode1Status != leader then return -1 endi diff --git a/tests/script/unique/arbitrator/insert_duplicationTs.sim b/tests/script/unique/arbitrator/insert_duplicationTs.sim index 4af47ca336..f10405eaa9 100644 --- a/tests/script/unique/arbitrator/insert_duplicationTs.sim +++ b/tests/script/unique/arbitrator/insert_duplicationTs.sim @@ -1,6 +1,6 @@ # Test case describe: dnode1 is only mnode, dnode2/dnode3 are only vnode # step 1: start dnode1 -# step 2: start dnode2 and dnode3, and all added into cluster (Suppose dnode2 is master-vnode) +# step 2: start dnode2 and dnode3, and all added into cluster (Suppose dnode2 is leader-vnode) # step 3: create db, table, insert data, and Falling disc into file (control only one file, e.g. 1841) # step 4: insert old data(now-15d) and new data(now+15d), control data rows in order to save in cache, not falling disc # step 5: stop dnode2, so date rows falling disc, generate two new files 1840, 1842 in dnode2 @@ -157,7 +157,7 @@ if $dnode3Status != ready then goto wait_dnode2_offline endi -sleep $sleepTimer # waitting for move master vnode of dnode2 to dnode3 +sleep $sleepTimer # waitting for move leader vnode of dnode2 to dnode3 # check using select sql select count(*) from $stb print data00 $data00 diff --git a/tests/script/unique/arbitrator/offline_replica2_alterTable_online.sim b/tests/script/unique/arbitrator/offline_replica2_alterTable_online.sim index 0adb6b4759..f3da076fde 100644 --- a/tests/script/unique/arbitrator/offline_replica2_alterTable_online.sim +++ b/tests/script/unique/arbitrator/offline_replica2_alterTable_online.sim @@ -146,7 +146,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/offline_replica2_alterTag_online.sim b/tests/script/unique/arbitrator/offline_replica2_alterTag_online.sim index a0877ad89c..6a4c92959c 100644 --- a/tests/script/unique/arbitrator/offline_replica2_alterTag_online.sim +++ b/tests/script/unique/arbitrator/offline_replica2_alterTag_online.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/offline_replica2_createTable_online.sim b/tests/script/unique/arbitrator/offline_replica2_createTable_online.sim index 376484a066..d97638b6fc 100644 --- a/tests/script/unique/arbitrator/offline_replica2_createTable_online.sim +++ b/tests/script/unique/arbitrator/offline_replica2_createTable_online.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/offline_replica2_dropDb_online.sim b/tests/script/unique/arbitrator/offline_replica2_dropDb_online.sim index 9f21193400..bb51700196 100644 --- a/tests/script/unique/arbitrator/offline_replica2_dropDb_online.sim +++ b/tests/script/unique/arbitrator/offline_replica2_dropDb_online.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/offline_replica2_dropTable_online.sim b/tests/script/unique/arbitrator/offline_replica2_dropTable_online.sim index cb3bbb3a73..592ad1b136 100644 --- a/tests/script/unique/arbitrator/offline_replica2_dropTable_online.sim +++ b/tests/script/unique/arbitrator/offline_replica2_dropTable_online.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/offline_replica3_alterTable_online.sim b/tests/script/unique/arbitrator/offline_replica3_alterTable_online.sim index 8a9995f891..b75a06874e 100644 --- a/tests/script/unique/arbitrator/offline_replica3_alterTable_online.sim +++ b/tests/script/unique/arbitrator/offline_replica3_alterTable_online.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/offline_replica3_alterTag_online.sim b/tests/script/unique/arbitrator/offline_replica3_alterTag_online.sim index 6eed563bbc..5a06ab4405 100644 --- a/tests/script/unique/arbitrator/offline_replica3_alterTag_online.sim +++ b/tests/script/unique/arbitrator/offline_replica3_alterTag_online.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/offline_replica3_createTable_online.sim b/tests/script/unique/arbitrator/offline_replica3_createTable_online.sim index 2633d822c9..31fe60aaac 100644 --- a/tests/script/unique/arbitrator/offline_replica3_createTable_online.sim +++ b/tests/script/unique/arbitrator/offline_replica3_createTable_online.sim @@ -151,7 +151,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/offline_replica3_dropDb_online.sim b/tests/script/unique/arbitrator/offline_replica3_dropDb_online.sim index 3abfc40161..725ca1b620 100644 --- a/tests/script/unique/arbitrator/offline_replica3_dropDb_online.sim +++ b/tests/script/unique/arbitrator/offline_replica3_dropDb_online.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/offline_replica3_dropTable_online.sim b/tests/script/unique/arbitrator/offline_replica3_dropTable_online.sim index f2acb8b90a..7dea6b24a9 100644 --- a/tests/script/unique/arbitrator/offline_replica3_dropTable_online.sim +++ b/tests/script/unique/arbitrator/offline_replica3_dropTable_online.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/replica_changeWithArbitrator.sim b/tests/script/unique/arbitrator/replica_changeWithArbitrator.sim index 9d0e967f4e..5c8e06fadd 100644 --- a/tests/script/unique/arbitrator/replica_changeWithArbitrator.sim +++ b/tests/script/unique/arbitrator/replica_changeWithArbitrator.sim @@ -224,7 +224,7 @@ if $data2_1 != offline then sleep 2000 goto wait_dnode2_master endi -if $data2_2 != master then +if $data2_2 != leader then sleep 2000 goto wait_dnode2_master endi diff --git a/tests/script/unique/arbitrator/sync_replica2_alterTable_add.sim b/tests/script/unique/arbitrator/sync_replica2_alterTable_add.sim index a8c0e83cc1..7ce878c63a 100644 --- a/tests/script/unique/arbitrator/sync_replica2_alterTable_add.sim +++ b/tests/script/unique/arbitrator/sync_replica2_alterTable_add.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/sync_replica2_alterTable_drop.sim b/tests/script/unique/arbitrator/sync_replica2_alterTable_drop.sim index 951d26635b..83e31ff9ae 100644 --- a/tests/script/unique/arbitrator/sync_replica2_alterTable_drop.sim +++ b/tests/script/unique/arbitrator/sync_replica2_alterTable_drop.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/sync_replica2_dropDb.sim b/tests/script/unique/arbitrator/sync_replica2_dropDb.sim index e4e7f95188..2272e63f04 100644 --- a/tests/script/unique/arbitrator/sync_replica2_dropDb.sim +++ b/tests/script/unique/arbitrator/sync_replica2_dropDb.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/sync_replica2_dropTable.sim b/tests/script/unique/arbitrator/sync_replica2_dropTable.sim index 0049dc6fba..4f7588a43b 100644 --- a/tests/script/unique/arbitrator/sync_replica2_dropTable.sim +++ b/tests/script/unique/arbitrator/sync_replica2_dropTable.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/sync_replica3_alterTable_add.sim b/tests/script/unique/arbitrator/sync_replica3_alterTable_add.sim index 4990899601..fa34a67b93 100644 --- a/tests/script/unique/arbitrator/sync_replica3_alterTable_add.sim +++ b/tests/script/unique/arbitrator/sync_replica3_alterTable_add.sim @@ -148,7 +148,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/sync_replica3_alterTable_drop.sim b/tests/script/unique/arbitrator/sync_replica3_alterTable_drop.sim index 10bd4fc8bd..aefb849527 100644 --- a/tests/script/unique/arbitrator/sync_replica3_alterTable_drop.sim +++ b/tests/script/unique/arbitrator/sync_replica3_alterTable_drop.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/sync_replica3_createTable.sim b/tests/script/unique/arbitrator/sync_replica3_createTable.sim index a0b391dd76..0cea59f799 100644 --- a/tests/script/unique/arbitrator/sync_replica3_createTable.sim +++ b/tests/script/unique/arbitrator/sync_replica3_createTable.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/sync_replica3_dnodeChang_DropAddAlterTableDropDb.sim b/tests/script/unique/arbitrator/sync_replica3_dnodeChang_DropAddAlterTableDropDb.sim index 68c6ecbd6e..2f29dfb472 100644 --- a/tests/script/unique/arbitrator/sync_replica3_dnodeChang_DropAddAlterTableDropDb.sim +++ b/tests/script/unique/arbitrator/sync_replica3_dnodeChang_DropAddAlterTableDropDb.sim @@ -146,7 +146,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi @@ -210,7 +210,7 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode4Vtatus = $data5_2 $dnode3Vtatus = $data7_2 -if $dnode4Vtatus != slave then +if $dnode4Vtatus != follower then sleep 2000 goto wait_dnode4_vgroup_slave endi @@ -243,7 +243,7 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode4Vtatus = $data5_2 $dnode3Vtatus = $data7_2 -if $dnode4Vtatus != master then +if $dnode4Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_master endi @@ -317,7 +317,7 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode4Vtatus = $data5_2 $dnode3Vtatus = $data7_2 -if $dnode4Vtatus != slave then +if $dnode4Vtatus != follower then sleep 2000 goto wait_dnode4_vgroup_slave_2 endi @@ -350,7 +350,7 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode4Vtatus = $data5_2 $dnode3Vtatus = $data7_2 -if $dnode4Vtatus != master then +if $dnode4Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_master_2 endi @@ -440,7 +440,7 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode4Vtatus = $data5_2 $dnode3Vtatus = $data7_2 -if $dnode4Vtatus != slave then +if $dnode4Vtatus != follower then sleep 2000 goto wait_dnode4_vgroup_slave_3 endi @@ -473,7 +473,7 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $dnode4Vtatus = $data5_2 $dnode3Vtatus = $data7_2 -if $dnode4Vtatus != master then +if $dnode4Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_master_3 endi diff --git a/tests/script/unique/arbitrator/sync_replica3_dropDb.sim b/tests/script/unique/arbitrator/sync_replica3_dropDb.sim index 83e53eaeeb..4f61da9d9d 100644 --- a/tests/script/unique/arbitrator/sync_replica3_dropDb.sim +++ b/tests/script/unique/arbitrator/sync_replica3_dropDb.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/arbitrator/sync_replica3_dropTable.sim b/tests/script/unique/arbitrator/sync_replica3_dropTable.sim index 7496541b76..a74364a158 100644 --- a/tests/script/unique/arbitrator/sync_replica3_dropTable.sim +++ b/tests/script/unique/arbitrator/sync_replica3_dropTable.sim @@ -150,7 +150,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != leader then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/cluster/balance1.sim b/tests/script/unique/cluster/balance1.sim index c98687a81c..b686fb8665 100644 --- a/tests/script/unique/cluster/balance1.sim +++ b/tests/script/unique/cluster/balance1.sim @@ -192,10 +192,10 @@ print dnode1 ==> $dnode1Role print dnode3 ==> $dnode3Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi -if $dnode3Role != slave then +if $dnode3Role != follower then return -1 endi @@ -236,7 +236,7 @@ print dnode1 ==> $dnode1Role print dnode3 ==> $dnode3Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi @@ -274,11 +274,11 @@ $dnode4Role = $data2_4 print dnode1 ==> $dnode1Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi -if $dnode4Role != slave then +if $dnode4Role != follower then return -1 endi diff --git a/tests/script/unique/cluster/balance2.sim b/tests/script/unique/cluster/balance2.sim index 0b80acbe6c..789d3787b5 100644 --- a/tests/script/unique/cluster/balance2.sim +++ b/tests/script/unique/cluster/balance2.sim @@ -82,13 +82,13 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi -if $data2_2 != slave then +if $data2_2 != follower then goto step1 endi -if $data2_3 != slave then +if $data2_3 != follower then goto step1 endi @@ -226,17 +226,17 @@ print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi if $dnode2Role != null then return -1 endi -if $dnode3Role != slave then +if $dnode3Role != follower then return -1 endi -if $dnode4Role != slave then +if $dnode4Role != follower then return -1 endi @@ -279,7 +279,7 @@ print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi if $dnode2Role != null then @@ -289,7 +289,7 @@ if $dnode3Role != null then return -1 endi -if $dnode4Role != slave then +if $dnode4Role != follower then return -1 endi diff --git a/tests/script/unique/cluster/balance3.sim b/tests/script/unique/cluster/balance3.sim index c2e9a84514..0f583ed600 100644 --- a/tests/script/unique/cluster/balance3.sim +++ b/tests/script/unique/cluster/balance3.sim @@ -68,13 +68,13 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi -if $data2_2 != slave then +if $data2_2 != follower then goto step1 endi -if $data2_3 != slave then +if $data2_3 != follower then goto step1 endi @@ -240,7 +240,7 @@ print dnode3 ==> $data2_3 print dnode4 ==> $data2_4 print dnode5 ==> $data2_5 -if $data2_4 != slave then +if $data2_4 != follower then goto show4 endi @@ -290,7 +290,7 @@ print dnode5 ==> $data2_5 print dnode6 ==> $data2_6 print dnode7 ==> $data2_7 -if $data2_5 != slave then +if $data2_5 != follower then goto show5 endi @@ -381,7 +381,7 @@ print dnode5 ==> $data2_5 print dnode6 ==> $data2_6 print dnode7 ==> $data2_7 -if $data2_6 != slave then +if $data2_6 != follower then goto show7 endi @@ -451,10 +451,10 @@ print dnode7 ==> $data2_7 if $data2_1 != offline then goto show9 endi -if $data2_5 != master then +if $data2_5 != leader then goto show9 endi -if $data2_6 != slave then +if $data2_6 != follower then goto show9 endi @@ -480,13 +480,13 @@ print dnode7 ==> $data2_7 if $data2_1 != null then goto show10 endi -if $data2_5 != master then +if $data2_5 != leader then goto show10 endi -if $data2_6 != slave then +if $data2_6 != follower then goto show10 endi -if $data2_7 != slave then +if $data2_7 != follower then goto show10 endi diff --git a/tests/script/unique/cluster/cache.sim b/tests/script/unique/cluster/cache.sim index 1b3771353f..f4da8380eb 100644 --- a/tests/script/unique/cluster/cache.sim +++ b/tests/script/unique/cluster/cache.sim @@ -57,9 +57,9 @@ endi #sql create table sys.st as select avg(taosd), avg(system) from sys.cpu interval(30s) sql show log.vgroups -if $data05 != master then +if $data05 != leader then return -1 endi -if $data15 != master then +if $data15 != leader then return -1 endi diff --git a/tests/script/unique/cluster/flowctrl.sim b/tests/script/unique/cluster/flowctrl.sim index 700fa0a3f1..8e04767ffd 100644 --- a/tests/script/unique/cluster/flowctrl.sim +++ b/tests/script/unique/cluster/flowctrl.sim @@ -55,13 +55,13 @@ print mnode2Role $mnode2Role $mnode3Role = $data2_3 print mnode3Role $mnode3Role -if $mnode1Role != master then +if $mnode1Role != leader then goto show1 endi -if $mnode2Role != slave then +if $mnode2Role != follower then goto show1 endi -if $mnode3Role != slave then +if $mnode3Role != follower then goto show1 endi diff --git a/tests/script/unique/cluster/vgroup100.sim b/tests/script/unique/cluster/vgroup100.sim index 656ed2ec44..cfe2765798 100644 --- a/tests/script/unique/cluster/vgroup100.sim +++ b/tests/script/unique/cluster/vgroup100.sim @@ -46,13 +46,13 @@ print $dnode1Role print $dnode2Role print $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then goto show2 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto show2 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto show2 endi @@ -109,13 +109,13 @@ sql show mnodes -x show7 $dnode1Role = $data2_1 $dnode2Role = $data2_2 $dnode3Role = $data2_3 -if $dnode1Role != master then +if $dnode1Role != leader then goto show7 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto show7 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto show7 endi diff --git a/tests/script/unique/clusterSimCase/cluster_main.sim b/tests/script/unique/clusterSimCase/cluster_main.sim index 274ce85974..2ec6ce9b55 100644 --- a/tests/script/unique/clusterSimCase/cluster_main.sim +++ b/tests/script/unique/clusterSimCase/cluster_main.sim @@ -10,17 +10,17 @@ #taos> show vgroups; # vgId | tables | status | onlineVnodes | dnode | vstatus | dnode | vstatus | #====================================================================================================== -# 2 | 1024 | ready | 2 | 3 | master | 2 | slave | -# 3 | 1024 | ready | 2 | 3 | master | 2 | slave | -# 4 | 1024 | ready | 2 | 3 | master | 2 | slave | -# 5 | 718 | ready | 2 | 3 | master | 2 | slave | +# 2 | 1024 | ready | 2 | 3 | leader | 2 | follower | +# 3 | 1024 | ready | 2 | 3 | leader | 2 | follower | +# 4 | 1024 | ready | 2 | 3 | leader | 2 | follower | +# 5 | 718 | ready | 2 | 3 | leader | 2 | follower | #Query OK, 4 row(s) in set (0.002749s) # #taos> show mnodes # -> ; # id | end_point | role | create_time | #===================================================================================== -# 1 | ubuntu-OptiPlex-7060:7100 | master | 2020-07-22 06:25:31.677 | +# 1 | ubuntu-OptiPlex-7060:7100 | leader | 2020-07-22 06:25:31.677 | #Query OK, 1 row(s) in set (0.002126s) @@ -136,7 +136,7 @@ if $vg2Dnode3Status != offline then sleep 2000 goto wait_vgroup_chang_0 endi -if $vg2Dnode2Status != master then +if $vg2Dnode2Status != leader then sleep 2000 goto wait_vgroup_chang_0 endi @@ -165,11 +165,11 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $vg2Dnode3Status = $data5_2 $vg2Dnode2Status = $data7_2 -if $vg2Dnode3Status != slave then +if $vg2Dnode3Status != follower then sleep 2000 goto wait_vgroup_chang_1 endi -if $vg2Dnode2Status != master then +if $vg2Dnode2Status != leader then sleep 2000 goto wait_vgroup_chang_1 endi @@ -197,7 +197,7 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $vg2Dnode3Status = $data5_2 $vg2Dnode2Status = $data7_2 -if $vg2Dnode3Status != master then +if $vg2Dnode3Status != leader then sleep 2000 goto wait_vgroup_chang_2 endi @@ -230,11 +230,11 @@ print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $dat $vg2Dnode3Status = $data5_2 $vg2Dnode2Status = $data7_2 -if $vg2Dnode2Status != slave then +if $vg2Dnode2Status != follower then sleep 2000 goto wait_vgroup_chang_3 endi -if $vg2Dnode3Status != master then +if $vg2Dnode3Status != leader then sleep 2000 goto wait_vgroup_chang_3 endi diff --git a/tests/script/unique/db/commit.sim b/tests/script/unique/db/commit.sim index 661dd4505f..dec78c8e43 100644 --- a/tests/script/unique/db/commit.sim +++ b/tests/script/unique/db/commit.sim @@ -13,7 +13,7 @@ system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 4 system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 4 system sh/cfg.sh -n dnode3 -c mnodeEqualVnodeNum -v 4 -print ========= start dnode1 as master +print ========= start dnode1 as leader system sh/exec.sh -n dnode1 -s start sql connect sleep 2000 diff --git a/tests/script/unique/db/delete.sim b/tests/script/unique/db/delete.sim index c876f23de3..b0ad52e494 100644 --- a/tests/script/unique/db/delete.sim +++ b/tests/script/unique/db/delete.sim @@ -84,7 +84,7 @@ step3: sql show mnodes print dnode1 role $data2_1 -if $data2_1 != master then +if $data2_1 != leader then goto step3 endi diff --git a/tests/script/unique/db/replica_add12.sim b/tests/script/unique/db/replica_add12.sim index d46187e445..6cca6ce4cd 100644 --- a/tests/script/unique/db/replica_add12.sim +++ b/tests/script/unique/db/replica_add12.sim @@ -60,7 +60,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi if $data2_2 != null then diff --git a/tests/script/unique/db/replica_add13.sim b/tests/script/unique/db/replica_add13.sim index 13a5c97832..6bc76615da 100644 --- a/tests/script/unique/db/replica_add13.sim +++ b/tests/script/unique/db/replica_add13.sim @@ -66,7 +66,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi diff --git a/tests/script/unique/db/replica_add23.sim b/tests/script/unique/db/replica_add23.sim index ac0bd6d9d7..ffc62abb8e 100644 --- a/tests/script/unique/db/replica_add23.sim +++ b/tests/script/unique/db/replica_add23.sim @@ -67,7 +67,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi diff --git a/tests/script/unique/db/replica_part.sim b/tests/script/unique/db/replica_part.sim index 9880ec666c..924d544c42 100644 --- a/tests/script/unique/db/replica_part.sim +++ b/tests/script/unique/db/replica_part.sim @@ -54,7 +54,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi diff --git a/tests/script/unique/db/replica_reduce21.sim b/tests/script/unique/db/replica_reduce21.sim index d3a76485f8..0305f3ad09 100644 --- a/tests/script/unique/db/replica_reduce21.sim +++ b/tests/script/unique/db/replica_reduce21.sim @@ -47,7 +47,7 @@ endi sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi diff --git a/tests/script/unique/db/replica_reduce31.sim b/tests/script/unique/db/replica_reduce31.sim index 5350bcc78c..4286ad94ad 100644 --- a/tests/script/unique/db/replica_reduce31.sim +++ b/tests/script/unique/db/replica_reduce31.sim @@ -55,7 +55,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi diff --git a/tests/script/unique/db/replica_reduce32.sim b/tests/script/unique/db/replica_reduce32.sim index ead265d5d5..730661ec02 100644 --- a/tests/script/unique/db/replica_reduce32.sim +++ b/tests/script/unique/db/replica_reduce32.sim @@ -54,7 +54,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi if $data2_2 != null then diff --git a/tests/script/unique/dnode/alternativeRole.sim b/tests/script/unique/dnode/alternativeRole.sim index 7e647925d1..ce13a4a847 100644 --- a/tests/script/unique/dnode/alternativeRole.sim +++ b/tests/script/unique/dnode/alternativeRole.sim @@ -66,13 +66,13 @@ sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 print dnode3 ==> $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto show2 endi if $data2_2 != null then goto show2 endi -if $data2_3 != slave then +if $data2_3 != follower then goto show2 endi diff --git a/tests/script/unique/dnode/offline3.sim b/tests/script/unique/dnode/offline3.sim index 93c75e3b13..de5cc94645 100644 --- a/tests/script/unique/dnode/offline3.sim +++ b/tests/script/unique/dnode/offline3.sim @@ -59,7 +59,7 @@ endi sql show mnodes print mnode1 $data2_1 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi diff --git a/tests/script/unique/http/admin.sim b/tests/script/unique/http/admin.sim index ae206744c4..39138d6db7 100644 --- a/tests/script/unique/http/admin.sim +++ b/tests/script/unique/http/admin.sim @@ -178,7 +178,7 @@ endi print =============== step8 - monitor dbs #system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'show dnodes;show mnodes;' 127.0.0.1:7111/admin/sqls #print 24-> $system_content -#if $system_content != @[{"status":"succ","head":["IP","created time","open vnodes","free vnodes","status","balance state"],"data":[["127.0.0.1","2018-09-04 #11:16:13.985",1,3,"ready","balanced"]],"rows":1},{"status":"succ","head":["IP","created time","status","role"],"data":[["127.0.0.1","2018-09-04 11:16:13.371","serving","master"]],"rows":1}]@ then +#if $system_content != @[{"status":"succ","head":["IP","created time","open vnodes","free vnodes","status","balance state"],"data":[["127.0.0.1","2018-09-04 #11:16:13.985",1,3,"ready","balanced"]],"rows":1},{"status":"succ","head":["IP","created time","status","role"],"data":[["127.0.0.1","2018-09-04 11:16:13.371","serving","leader"]],"rows":1}]@ then # return -1 # endi diff --git a/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeDir.sim b/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeDir.sim index e3623c7c62..fbffc0a69b 100644 --- a/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeDir.sim +++ b/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeDir.sim @@ -195,33 +195,33 @@ print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $dat print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3 print $data0_4 $data1_4 $data2_4 $data3_4 $data4_4 $data5_4 $data6_4 $data7_4 $data8_4 $data9_4 -if $data5_4 != master then +if $data5_4 != leader then print $data5_4 sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data5_3 != slave then +if $data5_3 != follower then print $data5_2 sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data5_2 != master then +if $data5_2 != leader then print $data5_3 sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data7_4 != slave then +if $data7_4 != follower then print $data7_4 sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data7_3 != master then +if $data7_3 != leader then print $data7_3 sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data7_2 != slave then +if $data7_2 != follower then print $data7_2 sleep 2000 goto wait_dnode1_vgroup_slave diff --git a/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir.sim b/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir.sim index c88e26d7eb..b076c4c501 100644 --- a/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir.sim +++ b/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir.sim @@ -197,28 +197,28 @@ print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $dat print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3 print $data0_4 $data1_4 $data2_4 $data3_4 $data4_4 $data5_4 $data6_4 $data7_4 $data8_4 $data9_4 -if $data5_4 != master then +if $data5_4 != leader then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data5_3 != slave then +if $data5_3 != follower then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data5_2 != master then +if $data5_2 != leader then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data7_4 != slave then +if $data7_4 != follower then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data7_3 != master then +if $data7_3 != leader then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data7_2 != slave then +if $data7_2 != follower then sleep 2000 goto wait_dnode1_vgroup_slave endi diff --git a/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim b/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim index 69e83a2c00..9fe8e31db9 100644 --- a/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim +++ b/tests/script/unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim @@ -169,28 +169,28 @@ $d1v2status = $data7_4 $d1v3status = $data7_2 $d1v4status = $data7_3 -if $d2v2status != master then +if $d2v2status != leader then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $d2v3status != master then +if $d2v3status != leader then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $d2v4status != master then +if $d2v4status != leader then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $d1v2status != slave then +if $d1v2status != follower then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $d1v3status != slave then +if $d1v3status != follower then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $d1v4status != slave then +if $d1v4status != follower then sleep 2000 goto wait_dnode1_vgroup_slave endi diff --git a/tests/script/unique/migrate/mn2_vn2_repl2_rmVnodeDir.sim b/tests/script/unique/migrate/mn2_vn2_repl2_rmVnodeDir.sim index ed3f9b8274..f665f551f7 100644 --- a/tests/script/unique/migrate/mn2_vn2_repl2_rmVnodeDir.sim +++ b/tests/script/unique/migrate/mn2_vn2_repl2_rmVnodeDir.sim @@ -195,28 +195,28 @@ print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $dat print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3 print $data0_4 $data1_4 $data2_4 $data3_4 $data4_4 $data5_4 $data6_4 $data7_4 $data8_4 $data9_4 -if $data5_4 != master then +if $data5_4 != leader then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data5_3 != slave then +if $data5_3 != follower then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data5_2 != master then +if $data5_2 != leader then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data7_4 != slave then +if $data7_4 != follower then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data7_3 != master then +if $data7_3 != leader then sleep 2000 goto wait_dnode1_vgroup_slave endi -if $data7_2 != slave then +if $data7_2 != follower then sleep 2000 goto wait_dnode1_vgroup_slave endi diff --git a/tests/script/unique/mnode/mgmt20.sim b/tests/script/unique/mnode/mgmt20.sim index 8945cffab2..710b3aa169 100644 --- a/tests/script/unique/mnode/mgmt20.sim +++ b/tests/script/unique/mnode/mgmt20.sim @@ -27,10 +27,10 @@ show2: sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto show2 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show2 endi @@ -61,10 +61,10 @@ show4: sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto show4 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show4 endi diff --git a/tests/script/unique/mnode/mgmt21.sim b/tests/script/unique/mnode/mgmt21.sim index 8409383309..44000de860 100644 --- a/tests/script/unique/mnode/mgmt21.sim +++ b/tests/script/unique/mnode/mgmt21.sim @@ -15,7 +15,7 @@ sql connect sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then return -1 endi @@ -33,10 +33,10 @@ show2: sql show mnodes -x show2 print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto show2 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show2 endi diff --git a/tests/script/unique/mnode/mgmt22.sim b/tests/script/unique/mnode/mgmt22.sim index 399805312b..415a40c21c 100644 --- a/tests/script/unique/mnode/mgmt22.sim +++ b/tests/script/unique/mnode/mgmt22.sim @@ -14,7 +14,7 @@ sql connect sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then return -1 endi @@ -33,26 +33,26 @@ show2: sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto show2 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show2 endi print ============== step3 sql_error drop dnode $hostname1 -x error1 -print should not drop master +print should not drop leader print ============== step4 system sh/exec.sh -n dnode1 -s stop -x SIGINT sleep 3000 sql_error show mnodes -print error of no master +print error of no leader print ============== step5 sql_error drop dnode $hostname1 -print error of no master +print error of no leader print ============== step6 system sh/exec.sh -n dnode1 -s start @@ -71,10 +71,10 @@ show6: sql show mnodes -x show6 print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto show6 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show6 endi @@ -94,10 +94,10 @@ sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 print dnode3 ==> $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto show7 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show7 endi if $data3_3 != null then diff --git a/tests/script/unique/mnode/mgmt23.sim b/tests/script/unique/mnode/mgmt23.sim index 19c7b4ba76..1145c27188 100644 --- a/tests/script/unique/mnode/mgmt23.sim +++ b/tests/script/unique/mnode/mgmt23.sim @@ -14,7 +14,7 @@ sql connect sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then return -1 endi @@ -33,10 +33,10 @@ show2: sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto show2 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show2 endi @@ -53,10 +53,10 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi -if $dnode2Role != slave then +if $dnode2Role != follower then return -1 endi if $dnode3Role != null then @@ -82,13 +82,13 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step4 endi if $dnode2Role != null then goto step4 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step4 endi @@ -117,13 +117,13 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step5 endi if $dnode2Role != null then goto step5 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step5 endi diff --git a/tests/script/unique/mnode/mgmt24.sim b/tests/script/unique/mnode/mgmt24.sim index a7bcc59ac0..c68a7236f9 100644 --- a/tests/script/unique/mnode/mgmt24.sim +++ b/tests/script/unique/mnode/mgmt24.sim @@ -14,7 +14,7 @@ sql connect sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then return -1 endi @@ -33,10 +33,10 @@ show2: sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto show2 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show2 endi @@ -67,10 +67,10 @@ sql show mnodes -x step5 print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto step5 endi -if $data2_2 != slave then +if $data2_2 != follower then goto step5 endi diff --git a/tests/script/unique/mnode/mgmt25.sim b/tests/script/unique/mnode/mgmt25.sim index 9cca9c8448..f9564f4f1a 100644 --- a/tests/script/unique/mnode/mgmt25.sim +++ b/tests/script/unique/mnode/mgmt25.sim @@ -14,7 +14,7 @@ sql connect sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then return -1 endi @@ -33,10 +33,10 @@ show2: sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto show2 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show2 endi @@ -53,10 +53,10 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi -if $dnode2Role != slave then +if $dnode2Role != follower then return -1 endi if $dnode3Role != null then @@ -75,13 +75,13 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi if $dnode2Role != null then return -1 endi -if $dnode3Role != slave then +if $dnode3Role != follower then return -1 endi diff --git a/tests/script/unique/mnode/mgmt26.sim b/tests/script/unique/mnode/mgmt26.sim index 2816845052..34bd3defba 100644 --- a/tests/script/unique/mnode/mgmt26.sim +++ b/tests/script/unique/mnode/mgmt26.sim @@ -14,7 +14,7 @@ sql connect sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then return -1 endi @@ -33,10 +33,10 @@ show2: sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 -if $data2_1 != master then +if $data2_1 != leader then goto show2 endi -if $data2_2 != slave then +if $data2_2 != follower then goto show2 endi @@ -53,10 +53,10 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi -if $dnode2Role != slave then +if $dnode2Role != follower then return -1 endi if $dnode3Role != null then @@ -76,13 +76,13 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi if $dnode2Role != null then return -1 endi -if $dnode3Role != slave then +if $dnode3Role != follower then return -1 endi @@ -103,13 +103,13 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi if $dnode2Role != null then return -1 endi -if $dnode3Role != slave then +if $dnode3Role != follower then return -1 endi diff --git a/tests/script/unique/mnode/mgmt30.sim b/tests/script/unique/mnode/mgmt30.sim index d0858c0d6c..3a6140539b 100644 --- a/tests/script/unique/mnode/mgmt30.sim +++ b/tests/script/unique/mnode/mgmt30.sim @@ -19,7 +19,7 @@ sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 print dnode3 ==> $data3_3 -if $data2_1 != master then +if $data2_1 != leader then return -1 endi if $data3_2 != null then @@ -53,13 +53,13 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step2 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto step2 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step2 endi diff --git a/tests/script/unique/mnode/mgmt33.sim b/tests/script/unique/mnode/mgmt33.sim index ce7cdce35d..ad05cd4f6b 100644 --- a/tests/script/unique/mnode/mgmt33.sim +++ b/tests/script/unique/mnode/mgmt33.sim @@ -15,7 +15,7 @@ sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 print dnode3 ==> $data3_3 -if $data2_1 != master then +if $data2_1 != leader then return -1 endi if $data3_2 != null then @@ -45,10 +45,10 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step2 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto step2 endi if $dnode3Role != null then @@ -75,13 +75,13 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step3 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto step3 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step3 endi @@ -104,13 +104,13 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step4 endi if $dnode2Role != null then goto step4 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step4 endi @@ -138,13 +138,13 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step5 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto step5 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step5 endi @@ -169,10 +169,10 @@ print dnode3 ==> $dnode3Role if $dnode1Role != offline then goto step6 endi -#if $dnode2Role != master then +#if $dnode2Role != leader then # return -1 #endi -#if $dnode3Role != slave then +#if $dnode3Role != follower then # return -1 #endi @@ -197,10 +197,10 @@ print dnode3 ==> $dnode3Role if $dnode1Role != null then goto step7 endi -#if $dnode2Role != master then +#if $dnode2Role != leader then # return -1 #endi -#if $dnode3Role != slave then +#if $dnode3Role != follower then # return -1 #endi diff --git a/tests/script/unique/mnode/mgmt34.sim b/tests/script/unique/mnode/mgmt34.sim index d8a46b0955..7f62b43fb8 100644 --- a/tests/script/unique/mnode/mgmt34.sim +++ b/tests/script/unique/mnode/mgmt34.sim @@ -18,7 +18,7 @@ sql show mnodes print dnode1 ==> $data2_1 print dnode2 ==> $data2_2 print dnode3 ==> $data3_3 -if $data2_1 != master then +if $data2_1 != leader then return -1 endi if $data3_2 != null then @@ -49,10 +49,10 @@ print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step2 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto step2 endi if $dnode3Role != null then @@ -84,13 +84,13 @@ print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step3 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto step3 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step3 endi if $dnode4Role != null then @@ -119,13 +119,13 @@ print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step4 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto step4 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step4 endi if $dnode4Role != null then @@ -152,16 +152,16 @@ print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step5 endi if $dnode2Role != null then goto step5 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step5 endi -if $dnode4Role != slave then +if $dnode4Role != follower then goto step5 endi @@ -190,16 +190,16 @@ print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role print dnode4 ==> $dnode4Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step6 endi if $dnode2Role != null then goto step6 endi -if $dnode3Role != slave then +if $dnode3Role != follower then goto step6 endi -if $dnode4Role != slave then +if $dnode4Role != follower then goto step6 endi @@ -249,13 +249,13 @@ print dnode4 ==> $dnode4Role if $dnode1Role != null then goto step8 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto step8 endi -#if $dnode3Role != master then +#if $dnode3Role != leader then # return -1 #endi -#if $dnode4Role != slave then +#if $dnode4Role != follower then # return -1 #endi diff --git a/tests/script/unique/mnode/mgmtr2.sim b/tests/script/unique/mnode/mgmtr2.sim index 5afb419058..fee2e405a2 100644 --- a/tests/script/unique/mnode/mgmtr2.sim +++ b/tests/script/unique/mnode/mgmtr2.sim @@ -20,7 +20,7 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then return -1 endi if $dnode2Role != null then @@ -72,10 +72,10 @@ print dnode1 ==> $dnode1Role print dnode2 ==> $dnode2Role print dnode3 ==> $dnode3Role -if $dnode1Role != master then +if $dnode1Role != leader then goto step4 endi -if $dnode2Role != slave then +if $dnode2Role != follower then goto step4 endi if $dnode3Role != null then diff --git a/tests/script/unique/vnode/many.sim b/tests/script/unique/vnode/many.sim index a9298b1cf2..24e2cd60c7 100644 --- a/tests/script/unique/vnode/many.sim +++ b/tests/script/unique/vnode/many.sim @@ -51,7 +51,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi diff --git a/tests/script/unique/vnode/replica2_repeat.sim b/tests/script/unique/vnode/replica2_repeat.sim index ac68d59164..9845ef2d19 100644 --- a/tests/script/unique/vnode/replica2_repeat.sim +++ b/tests/script/unique/vnode/replica2_repeat.sim @@ -52,7 +52,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi diff --git a/tests/script/unique/vnode/replica3_basic.sim b/tests/script/unique/vnode/replica3_basic.sim index 0ff42b523b..edb70b7d4c 100644 --- a/tests/script/unique/vnode/replica3_basic.sim +++ b/tests/script/unique/vnode/replica3_basic.sim @@ -44,13 +44,13 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi -if $data2_2 != slave then +if $data2_2 != follower then goto step1 endi -if $data2_3 != slave then +if $data2_3 != follower then goto step1 endi diff --git a/tests/script/unique/vnode/replica3_repeat.sim b/tests/script/unique/vnode/replica3_repeat.sim index 636bc64f89..cde0c512a5 100644 --- a/tests/script/unique/vnode/replica3_repeat.sim +++ b/tests/script/unique/vnode/replica3_repeat.sim @@ -59,7 +59,7 @@ sql show mnodes print mnode1 $data2_1 print mnode1 $data2_2 print mnode1 $data2_3 -if $data2_1 != master then +if $data2_1 != leader then goto step1 endi -- GitLab From efd2d768cb54ee7663f42c21d9de5aa4b5ffdd5d Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 23 Jun 2022 19:15:04 +0800 Subject: [PATCH 083/380] fix: Uniqueness checking of names of columns and tags --- src/client/src/tscSQLParser.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 4021fca42f..988d2ef38f 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1632,7 +1632,7 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { } // field name must be unique - if (has(pFieldList, i + 1, pField->name) == true) { + if (has(pFieldList, i, pField->name) == true) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return false; } @@ -1691,7 +1691,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC return false; } - if (has(pTagsList, i + 1, p->name) == true) { + if (has(pTagsList, i, p->name) == true) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return false; } @@ -1720,8 +1720,8 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC // field name must be unique for (int32_t i = 0; i < numOfTags; ++i) { TAOS_FIELD* p = taosArrayGet(pTagsList, i); - - if (has(pFieldList, 0, p->name) == true) { + size_t numOfCols = taosArrayGetSize(pFieldList); + if (has(pFieldList, numOfCols, p->name) == true) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return false; } @@ -1867,9 +1867,8 @@ int32_t validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { } /* is contained in pFieldList or not */ -static bool has(SArray* pFieldList, int32_t startIdx, const char* name) { - size_t numOfCols = taosArrayGetSize(pFieldList); - for (int32_t j = startIdx; j < numOfCols; ++j) { +static bool has(SArray* pFieldList, int32_t endIdx, const char* name) { + for (int32_t j = 0; j < endIdx; ++j) { TAOS_FIELD* field = taosArrayGet(pFieldList, j); if (strncmp(name, field->name, sizeof(field->name) - 1) == 0) return true; } -- GitLab From 0e57e872b0398ae8412274ba71937e1bb18dcd4e Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 23 Jun 2022 19:47:08 +0800 Subject: [PATCH 084/380] fix: Nonemptiness checking of names of columns and tags --- src/client/src/tscSQLParser.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 988d2ef38f..750412117c 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -8011,7 +8011,9 @@ int32_t validateColumnName(char* name) { return validateColumnName(token.z); } else if (token.type == TK_ID) { stringProcess(name, token.n); - return TSDB_CODE_SUCCESS; + if (strlen(name) == 0) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } } else { if (isNumber(&token)) { return TSDB_CODE_TSC_INVALID_OPERATION; -- GitLab From 67e0ab21273c5adc05a15947b61987b58ee48742 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 23 Jun 2022 20:17:26 +0800 Subject: [PATCH 085/380] test: Add tests of uniqueness and non-emptiness of col names --- tests/pytest/table/columnNameValidation.py | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/pytest/table/columnNameValidation.py diff --git a/tests/pytest/table/columnNameValidation.py b/tests/pytest/table/columnNameValidation.py new file mode 100644 index 0000000000..a2968a2ea5 --- /dev/null +++ b/tests/pytest/table/columnNameValidation.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- + +import sys +import string +import random +import subprocess +from util.log import * +from util.cases import * +from util.sql import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + tdSql.prepare() + + tdSql.query('show tables') + tdSql.checkRows(0) + + # uniqueness + tdSql.error("create table t (t timestamp, f int, F int)") + tdSql.error("create table t (t timestamp, `f` int, F int)") + tdSql.error("create table t (t timestamp, `f` int, `f` int)") + tdSql.execute("create table t (t timestamp, `f` int, `F` int)") + tdSql.query("show tables") + tdSql.checkRows(1) + tdSql.execute("drop table t") + + tdSql.error("create table t (t timestamp, f int, `F` int) tags (T int)") + tdSql.error("create table t (t timestamp, f int, `F` int) tags (`T` int, `T` int)") + tdSql.execute("create table t (t timestamp, f int, `F` int) tags (`T` int)") + tdSql.query("show stables") + tdSql.checkRows(1) + tdSql.execute("drop table t") + + # non-emptiness + tdSql.error("create table t (t timestamp, `` int)") + tdSql.error("create table t (t timestamp, `f` int) tags (`` int)") + tdSql.query("show tables") + tdSql.checkRows(0) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) -- GitLab From 2e123fe8a2186586673d511d01b03eabdc111271 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Fri, 24 Jun 2022 13:29:08 +0800 Subject: [PATCH 086/380] fix: update parallel_test/cases.task --- tests/parallel_test/cases.task | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 578756d03e..2174437f31 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -810,6 +810,7 @@ 3,,pytest,python3 test.py -f dbmgmt/dbNameCaseSensitive.py 3,,pytest,python3 test.py -f insert/schemalessCaseSensitive.py 3,,pytest,python3 test.py -f table/columnNameCaseSensitive.py +3,,pytest,python3 test.py -f table/columnNameValidation.py 3,,pytest,python3 test.py -f table/tagNameCaseSensitive.py 3,,pytest,python3 test.py -f table/tbNameCaseSensitive.py 3,,develop-test,python3 ./test.py -f 2-query/ts_hidden_column.py -- GitLab From 095f4348717034a2fd2f5d132d3df3a3e7293749 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Fri, 24 Jun 2022 13:30:19 +0800 Subject: [PATCH 087/380] fix: update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 091e1d7361..d1f1dc4ded 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ cmake-build-debug/ cmake-build-release/ cscope.out cscope.files +tags .DS_Store debug/ release/ -- GitLab From b4a4027cba303f1d5b8a7508c0688ffced42f772 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Fri, 24 Jun 2022 15:43:28 +0800 Subject: [PATCH 088/380] test: add test cases --- tests/pytest/dbmgmt/dbNameCaseSensitive.py | 4 ++++ tests/pytest/table/columnNameCaseSensitive.py | 16 +++++++++++++++ tests/pytest/table/tagNameCaseSensitive.py | 20 +++++++++++++++++++ tests/pytest/table/tbNameCaseSensitive.py | 13 ++++++++++++ 4 files changed, 53 insertions(+) diff --git a/tests/pytest/dbmgmt/dbNameCaseSensitive.py b/tests/pytest/dbmgmt/dbNameCaseSensitive.py index f28b9fd016..80d0614c3f 100644 --- a/tests/pytest/dbmgmt/dbNameCaseSensitive.py +++ b/tests/pytest/dbmgmt/dbNameCaseSensitive.py @@ -73,6 +73,10 @@ class TDTestCase: sql = tdSql.getData(0, 1) tdSql.checkEqual(True, sql.startswith("CREATE DATABASE `电力系统`")) + tdSql.error("create database ``") + tdSql.execute("create database ` `") + tdSql.error("create database ` `") + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/table/columnNameCaseSensitive.py b/tests/pytest/table/columnNameCaseSensitive.py index b3ae863a46..cbf69c6bf1 100644 --- a/tests/pytest/table/columnNameCaseSensitive.py +++ b/tests/pytest/table/columnNameCaseSensitive.py @@ -159,6 +159,22 @@ class TDTestCase: tdSql.query("select ts `时间戳` from tt3") tdSql.checkRows(1) + tdSql.error("create table tt4(`` timestamp, c1 int)") + tdSql.error("create table tt4(` ` timestamp, ` ` int)") + tdSql.error("create table tt4(`tb1` timestamp, `tb1` int)") + + ts = 1656040651000 + tdSql.execute("create table `T4`(` ` timestamp, c1 int, `C1` int)") + tdSql.execute("insert into `T4`(` `, `C1`) values(%d, 1)" % ts) + tdSql.query("select * from `T4`") + tdSql.checkRows(1) + tdSql.execute("delete from `T4` where ` ` = '2022-06-24 11:17:31.000'") + tdSql.query("select * from `T4`") + tdSql.checkRows(0) + + tdSql.error("alter table `T4` add column `` double") + + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/table/tagNameCaseSensitive.py b/tests/pytest/table/tagNameCaseSensitive.py index ad0a960eb0..ebd7f55a2d 100644 --- a/tests/pytest/table/tagNameCaseSensitive.py +++ b/tests/pytest/table/tagNameCaseSensitive.py @@ -56,6 +56,26 @@ class TDTestCase: tdSql.query("describe `STB5`") tdSql.checkRows(5) + ts = 1656040651000 + tdSql.error("create table `STB6`(ts timestamp, c1 int) tags(`` int)") + tdSql.error("create table `STB6`(ts timestamp, c1 int) tags(` ` int, ` ` binary(20))") + tdSql.execute("create table `STB6`(ts timestamp, c1 int) tags(` ` int)") + tdSql.execute("insert into tb6 using `STB6` tags(1) values(%d, 1)(%d, 2)(%d, 3)" % (ts, ts + 1000, ts + 2000)) + tdSql.execute("insert into tb7 using `STB6` tags(2) values(%d, 1)(%d, 2)(%d, 3)" % (ts, ts + 1000, ts + 2000)) + tdSql.query("select * from `STB6`") + tdSql.checkRows(6) + + tdSql.execute("delete from `STB6` where ` ` = 1 and ts = '2022-06-24 11:17:31.000'") + tdSql.checkAffectedRows(1) + tdSql.query("select * from `STB6`") + tdSql.checkRows(5) + tdSql.execute("delete from `STB6` where ` ` = 2") + tdSql.checkAffectedRows(3) + tdSql.query("select * from `STB6`") + tdSql.checkRows(2) + + tdSql.error("alter table `STB6` add tag `` nchar(20)") + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/table/tbNameCaseSensitive.py b/tests/pytest/table/tbNameCaseSensitive.py index ee6a24d786..dd3f668eb8 100644 --- a/tests/pytest/table/tbNameCaseSensitive.py +++ b/tests/pytest/table/tbNameCaseSensitive.py @@ -120,6 +120,19 @@ class TDTestCase: tdSql.query("show create table `普通表`") tdSql.checkData(0, 1, "CREATE TABLE `普通表` (`ts` TIMESTAMP,`c1` INT)") + tdSql.error("create table `` (ts timestamp, c1 int)") + tdSql.execute("create table ` ` (ts timestamp, c1 int)") + tdSql.error("create table ` ` (ts timestamp, c1 int)") + + ts = 1656040651000 + tdSql.execute("insert into ` ` values(%d, 1)" % ts) + tdSql.query("select * from ` `") + tdSql.checkRows(1) + tdSql.execute("delete from ` `") + tdSql.checkAffectedRows(1) + tdSql.query("select * from ` `") + tdSql.checkRows(0) + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) -- GitLab From 92f37047e2a7452f59dee9ddc326cd3a7a2f575b Mon Sep 17 00:00:00 2001 From: tangfangzhi Date: Sat, 25 Jun 2022 13:38:48 +0800 Subject: [PATCH 089/380] ci: optimize Jenkins log --- Jenkinsfile2 | 43 ++++++++++--- tests/parallel_test/run.sh | 126 +++++++++++++++++++++++++++---------- 2 files changed, 127 insertions(+), 42 deletions(-) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index b27622c25d..257a13e4bf 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -387,14 +387,41 @@ pipeline { } } catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { - timeout(time: 25, unit: 'MINUTES') { - sh ''' - date - cd ${WKC}/tests/parallel_test - time ./run.sh -m /home/m.json -t cases.task -l ${LOGDIR} -b ${BRANCH_NAME} - date - hostname - ''' + timeout(time: 60, unit: 'MINUTES') { + script { + def extra_param = "" + def log_server_file = "/home/log_server.json" + def timeout_cmd = "" + if (fileExists(log_server_file)) { + def log_server_enabled = sh ( + script: 'jq .enabled ' + log_server_file, + returnStdout: true + ).trim() + def timeout_param = sh ( + script: 'jq .timeout ' + log_server_file, + returnStdout: true + ).trim() + if (timeout_param != "null" && timeout_param != "0") { + timeout_cmd = "timeout " + timeout_param + } + if (log_server_enabled == "1") { + def log_server = sh ( + script: 'jq .server ' + log_server_file + ' | sed "s/\\\"//g"', + returnStdout: true + ).trim() + if (log_server != "null" && log_server != "") { + extra_param = "-w " + log_server + } + } + } + sh ''' + date + cd ${WKC}/tests/parallel_test + ''' + timeout_cmd + ''' time ./run.sh -m /home/m.json -t cases.task -l ${LOGDIR} -b ${BRANCH_NAME} ''' + extra_param + ''' + date + hostname + ''' + } } } } diff --git a/tests/parallel_test/run.sh b/tests/parallel_test/run.sh index 221b70b22a..457e339d89 100755 --- a/tests/parallel_test/run.sh +++ b/tests/parallel_test/run.sh @@ -7,10 +7,11 @@ function usage() { echo -e "\t -b branch" echo -e "\t -l log dir" echo -e "\t -o default timeout value" + echo -e "\t -w log web server" echo -e "\t -h help" } -while getopts "m:t:b:l:o:h" opt; do +while getopts "m:t:b:l:o:w:h" opt; do case $opt in m) config_file=$OPTARG @@ -27,6 +28,9 @@ while getopts "m:t:b:l:o:h" opt; do o) timeout_param="-o $OPTARG" ;; + w) + web_server=$OPTARG + ;; h) usage exit 0 @@ -59,10 +63,11 @@ if [ ! -f $t_file ]; then exit 1 fi date_tag=`date +%Y%m%d-%H%M%S` +test_log_dir=${branch}_${date_tag} if [ -z $log_dir ]; then - log_dir="log/${branch}_${date_tag}" + log_dir="log/${test_log_dir}" else - log_dir="$log_dir/${branch}_${date_tag}" + log_dir="$log_dir/${test_log_dir}" fi hosts=() @@ -134,14 +139,14 @@ function build_src() { echo "$cmd" ${cmd} if [ $? -ne 0 ]; then - flock -x $lock_file -c "echo \"${hosts[index]} TDengine build failed\" >>$log_dir/failed.log" + flock -x $lock_file -c "echo \"${hosts[index]} TDengine build failed\" >>${failed_case_file}" return fi script=". ~/.bashrc;cd ${workdirs[index]}/taos-tools;git submodule update --init --recursive;mkdir -p build;cd build;cmake ..;make -j4" cmd="${ssh_script} sh -c \"$script\"" ${cmd} if [ $? -ne 0 ]; then - flock -x $lock_file -c "echo \"${hosts[index]} taos-tools build failed\" >>$log_dir/failed.log" + flock -x $lock_file -c "echo \"${hosts[index]} taos-tools build failed\" >>${failed_case_file}" return fi script="cp -rf ${workdirs[index]}/taos-tools/build/build/bin/* ${workdirs[index]}/TDinternal/debug/build/bin/;cp -rf ${workdirs[index]}/taos-tools/build/build/lib/* ${workdirs[index]}/TDinternal/debug/build/lib/;cp -rf ${workdirs[index]}/taos-tools/build/build/lib64/* ${workdirs[index]}/TDinternal/debug/build/lib/;cp -rf ${workdirs[index]}/TDinternal/debug/build/bin/taosBenchmark ${workdirs[index]}/TDinternal/debug/build/bin/taosdemo" @@ -191,6 +196,10 @@ function run_thread() { local exec_dir=`echo "$line"|cut -d, -f3` local case_cmd=`echo "$line"|cut -d, -f4` local case_file="" + echo "$case_cmd"|grep -q "\.sh" + if [ $? -eq 0 ]; then + case_file=`echo "$case_cmd"|grep -o ".*\.sh"|awk '{print $NF}'` + fi echo "$case_cmd"|grep -q "^python3" if [ $? -eq 0 ]; then case_file=`echo "$case_cmd"|grep -o ".*\.py"|awk '{print $NF}'` @@ -215,44 +224,54 @@ function run_thread() { # echo "$thread_no $count $cmd" local ret=0 local redo_count=1 + local case_log_file=$log_dir/${case_file}.txt start_time=`date +%s` + local case_index=`flock -x $lock_file -c "sh -c \"echo \\\$(( \\\$( cat $index_file ) + 1 )) | tee $index_file\""` + case_index=`printf "%5d" $case_index` + local case_info=`echo "$line"|cut -d, -f 3,4` while [ ${redo_count} -lt 6 ]; do - if [ -f $log_dir/$case_file.log ]; then - cp $log_dir/$case_file.log $log_dir/$case_file.${redo_count}.redolog + if [ -f $case_log_file ]; then + cp $case_log_file $log_dir/$case_file.${redo_count}.redotxt fi - echo "${hosts[index]}-${thread_no} order:${count}, redo:${redo_count} task:${line}" >$log_dir/$case_file.log - echo -e "\e[33m >>>>> \e[0m ${case_cmd}" - date >>$log_dir/$case_file.log - # $cmd 2>&1 | tee -a $log_dir/$case_file.log + echo "${hosts[index]}-${thread_no} order:${count}, redo:${redo_count} task:${line}" >$case_log_file + local current_time=`date "+%Y-%m-%d %H:%M:%S"` + echo -e "$case_index \e[33m START >>>>> \e[0m ${case_info} \e[33m[$current_time]\e[0m" + echo "$current_time" >>$case_log_file + local real_start_time=`date +%s` + # $cmd 2>&1 | tee -a $case_log_file # ret=${PIPESTATUS[0]} - $cmd >>$log_dir/$case_file.log 2>&1 + $cmd >>$case_log_file 2>&1 ret=$? - echo "${hosts[index]} `date` ret:${ret}" >>$log_dir/$case_file.log + local real_end_time=`date +%s` + local time_elapsed=$(( real_end_time - real_start_time )) + echo "execute time: ${time_elapsed}s" >>$case_log_file + current_time=`date "+%Y-%m-%d %H:%M:%S"` + echo "${hosts[index]} $current_time exit code:${ret}" >>$case_log_file if [ $ret -eq 0 ]; then break fi redo=0 - grep -q "wait too long for taosd start" $log_dir/$case_file.log + grep -q "wait too long for taosd start" $case_log_file if [ $? -eq 0 ]; then redo=1 fi - grep -q "kex_exchange_identification: Connection closed by remote host" $log_dir/$case_file.log + grep -q "kex_exchange_identification: Connection closed by remote host" $case_log_file if [ $? -eq 0 ]; then redo=1 fi - grep -q "ssh_exchange_identification: Connection closed by remote host" $log_dir/$case_file.log + grep -q "ssh_exchange_identification: Connection closed by remote host" $case_log_file if [ $? -eq 0 ]; then redo=1 fi - grep -q "kex_exchange_identification: read: Connection reset by peer" $log_dir/$case_file.log + grep -q "kex_exchange_identification: read: Connection reset by peer" $case_log_file if [ $? -eq 0 ]; then redo=1 fi - grep -q "Database not ready" $log_dir/$case_file.log + grep -q "Database not ready" $case_log_file if [ $? -eq 0 ]; then redo=1 fi - grep -q "Unable to establish connection" $log_dir/$case_file.log + grep -q "Unable to establish connection" $case_log_file if [ $? -eq 0 ]; then redo=1 fi @@ -265,11 +284,18 @@ function run_thread() { redo_count=$(( redo_count + 1 )) done end_time=`date +%s` - echo >>$log_dir/$case_file.log - echo "${hosts[index]} execute time: $(( end_time - start_time ))s" >>$log_dir/$case_file.log + echo >>$case_log_file + total_time=$(( end_time - start_time )) + echo "${hosts[index]} total time: ${total_time}s" >>$case_log_file # echo "$thread_no ${line} DONE" - if [ $ret -ne 0 ]; then - flock -x $lock_file -c "echo \"${hosts[index]} ret:${ret} ${line}\" >>$log_dir/failed.log" + if [ $ret -eq 0 ]; then + echo -e "$case_index \e[34m DONE <<<<< \e[0m ${case_info} \e[34m[${total_time}s]\e[0m \e[32m success\e[0m" + else + if [ ! -z ${web_server} ]; then + flock -x $lock_file -c "echo -e \"${hosts[index]} ret:${ret} ${line}\n ${web_server}/$test_log_dir/${case_file}.txt\" >>${failed_case_file}" + else + flock -x $lock_file -c "echo -e \"${hosts[index]} ret:${ret} ${line}\n log file: ${case_log_file}\" >>${failed_case_file}" + fi mkdir -p $log_dir/${case_file}.coredump local remote_coredump_dir="${workdirs[index]}/tmp/thread_volume/$thread_no/coredump" local scpcmd="sshpass -p ${passwords[index]} scp -o StrictHostKeyChecking=no -r ${usernames[index]}@${hosts[index]}" @@ -278,14 +304,16 @@ function run_thread() { fi cmd="$scpcmd:${remote_coredump_dir}/* $log_dir/${case_file}.coredump/" $cmd # 2>/dev/null - local case_info=`echo "$line"|cut -d, -f 3,4` local corefile=`ls $log_dir/${case_file}.coredump/` - corefile=`find $log_dir/${case_file}.coredump/ -name "core.*"` - echo -e "$case_info \e[31m failed\e[0m" + corefile=`find $log_dir/${case_file}.coredump/ -name "core*"` + echo -e "$case_index \e[34m DONE <<<<< \e[0m ${case_info} \e[34m[${total_time}s]\e[0m \e[31m failed\e[0m" echo "=========================log============================" - cat $log_dir/$case_file.log + cat $case_log_file echo "=====================================================" - echo -e "\e[34m log file: $log_dir/$case_file.log \e[0m" + echo -e "\e[34m log file: $case_log_file \e[0m" + if [ ! -z "${web_server}" ]; then + echo "${web_server}/$test_log_dir/${case_file}.txt" + fi if [ ! -z "$corefile" ]; then echo -e "\e[34m corefiles: $corefile \e[0m" local build_dir=$log_dir/build_${hosts[index]} @@ -320,6 +348,10 @@ mkdir -p $log_dir rm -rf $log_dir/* task_file=$log_dir/$$.task lock_file=$log_dir/$$.lock +index_file=$log_dir/case_index.txt +stat_file=$log_dir/stat.txt +failed_case_file=$log_dir/failed.txt +echo "0" >$index_file i=0 while [ $i -lt ${#hosts[*]} ]; do @@ -328,10 +360,6 @@ while [ $i -lt ${#hosts[*]} ]; do i=$(( i + 1 )) done wait -# if [ -f "$log_dir/failed.log" ]; then -# cat $log_dir/failed.log -# exit 1 -# fi i=0 j=0 @@ -357,15 +385,45 @@ rm -f $lock_file rm -f $task_file # docker ps -a|grep -v CONTAINER|awk '{print $1}'|xargs docker rm -f +echo "=====================================================================" +echo "log dir: $log_dir" +total_cases=`cat $index_file` +failed_cases=0 +if [ -f $failed_case_file ]; then + if [ ! -z "$web_server" ]; then + failed_cases=`grep -v "$web_server" $failed_case_file|wc -l` + else + failed_cases=`grep -v "log file:" $failed_case_file|wc -l` + fi +fi +success_cases=$(( total_cases - failed_cases )) +echo "Total Cases: $total_cases" >$stat_file +echo "Successful: $success_cases" >>$stat_file +echo "Failed: $failed_cases" >>$stat_file +cat $stat_file + RET=0 i=1 -if [ -f "$log_dir/failed.log" ]; then +if [ -f "${failed_case_file}" ]; then echo "=====================================================" while read line; do + if [ ! -z "${web_server}" ]; then + echo "$line"|grep -q "${web_server}" + if [ $? -eq 0 ]; then + echo " $line" + continue + fi + else + echo "$line"|grep -q "log file:" + if [ $? -eq 0 ]; then + echo " $line" + continue + fi + fi line=`echo "$line"|cut -d, -f 3,4` echo -e "$i. $line \e[31m failed\e[0m" >&2 i=$(( i + 1 )) - done <$log_dir/failed.log + done <${failed_case_file} RET=1 fi -- GitLab From 01db91b038064ec83180ab93a861efc5c775a539 Mon Sep 17 00:00:00 2001 From: Yu Chen <74105241+yu285@users.noreply.github.com> Date: Sun, 26 Jun 2022 12:32:51 +0800 Subject: [PATCH 090/380] docs: update mnode description --- docs/en/21-tdinternal/01-arch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/21-tdinternal/01-arch.md b/docs/en/21-tdinternal/01-arch.md index d7d472eb98..44651c0496 100644 --- a/docs/en/21-tdinternal/01-arch.md +++ b/docs/en/21-tdinternal/01-arch.md @@ -22,7 +22,7 @@ A complete TDengine system runs on one or more physical nodes. Logically, it inc **Virtual node (vnode)**: To better support data sharding, load balancing and prevent data from overheating or skewing, data nodes are virtualized into multiple virtual nodes (vnode, V2, V3, V4, etc. in the figure). Each vnode is a relatively independent work unit, which is the basic unit of time-series data storage and has independent running threads, memory space and persistent storage path. A vnode contains a certain number of tables (data collection points). When a new table is created, the system checks whether a new vnode needs to be created. The number of vnodes that can be created on a data node depends on the capacity of the hardware of the physical node where the data node is located. A vnode belongs to only one DB, but a DB can have multiple vnodes. In addition to the stored time-series data, a vnode also stores the schema and tag values of the included tables. A virtual node is uniquely identified in the system by the EP of the data node and the VGroup ID to which it belongs and is created and managed by the management node. -**Management node (mnode)**: A virtual logical unit responsible for monitoring and maintaining the running status of all data nodes and load balancing among nodes (M in the figure). At the same time, the management node is also responsible for the storage and management of metadata (including users, databases, tables, static tags, etc.), so it is also called Meta Node. Multiple (up to 5) mnodes can be configured in a TDengine cluster, and they are automatically constructed into a virtual management node group (M0, M1, M2 in the figure). The leader/follower mechanism is adopted for the mnode group and the data synchronization is carried out in a strongly consistent way. Any data update operation can only be executed on the leader. The creation of mnode cluster is completed automatically by the system without manual intervention. There is at most one mnode on each dnode, which is uniquely identified by the EP of the data node to which it belongs. Each dnode automatically obtains the EP of the dnode where all mnodes in the whole cluster are located, through internal messaging interaction. +**Management node (mnode)**: A virtual logical unit responsible for monitoring and maintaining the running status of all data nodes and load balancing among nodes (M in the figure). At the same time, the management node is also responsible for the storage and management of metadata (including users, databases, tables, static tags, etc.), so it is also called Meta Node. Multiple (up to 3) mnodes can be configured in a TDengine cluster, and they are automatically constructed into a virtual management node group (M0, M1, M2 in the figure). The leader/follower mechanism is adopted for the mnode group and the data synchronization is carried out in a strongly consistent way. Any data update operation can only be executed on the leader. The creation of mnode cluster is completed automatically by the system without manual intervention. There is at most one mnode on each dnode, which is uniquely identified by the EP of the data node to which it belongs. Each dnode automatically obtains the EP of the dnode where all mnodes in the whole cluster are located, through internal messaging interaction. **Virtual node group (VGroup)**: Vnodes on different data nodes can form a virtual node group to ensure the high availability of the system. The virtual node group is managed in a leader/follower mechanism. Write operations can only be performed on the leader vnode, and then replicated to follower vnodes, thus ensuring that one single replica of data is copied on multiple physical nodes. The number of virtual nodes in a vgroup equals the number of data replicas. If the number of replicas of a DB is N, the system must have at least N data nodes. The number of replicas can be specified by the parameter `“replica”` when creating a DB, and the default is 1. Using the multi-replication feature of TDengine, the same high data reliability can be achieved without the need for expensive storage devices such as disk arrays. Virtual node groups are created and managed by the management node, and the management node assigns a system unique ID, aka VGroup ID. If two virtual nodes have the same vnode group ID, it means that they belong to the same group and the data is backed up to each other. The number of virtual nodes in a virtual node group can be dynamically changed, allowing only one, that is, no data replication. VGroup ID is never changed. Even if a virtual node group is deleted, its ID will not be reused. -- GitLab From 9d12558f4c8ef01535764b871af4c2cb5fe6a7d1 Mon Sep 17 00:00:00 2001 From: Yu Chen <74105241+yu285@users.noreply.github.com> Date: Sun, 26 Jun 2022 12:17:52 +0800 Subject: [PATCH 091/380] docs: update docs --- docs/zh/21-tdinternal/01-arch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/21-tdinternal/01-arch.md b/docs/zh/21-tdinternal/01-arch.md index 433cb4808b..507ccea629 100644 --- a/docs/zh/21-tdinternal/01-arch.md +++ b/docs/zh/21-tdinternal/01-arch.md @@ -23,7 +23,7 @@ TDengine 分布式架构的逻辑结构图如下: **虚拟节点(vnode):** 为更好的支持数据分片、负载均衡,防止数据过热或倾斜,数据节点被虚拟化成多个虚拟节点(vnode,图中 V2,V3,V4 等)。每个 vnode 都是一个相对独立的工作单元,是时序数据存储的基本单元,具有独立的运行线程、内存空间与持久化存储的路径。一个 vnode 包含一定数量的表(数据采集点)。当创建一张新表时,系统会检查是否需要创建新的 vnode。一个数据节点上能创建的 vnode 的数量取决于该数据节点所在物理节点的硬件资源。一个 vnode 只属于一个 DB,但一个 DB 可以有多个 vnode。一个 vnode 除存储的时序数据外,也保存有所包含的表的 schema、标签值等。一个虚拟节点由所属的数据节点的 EP,以及所属的 VGroup ID 在系统内唯一标识,由管理节点创建并管理。 -**管理节点(mnode):** 一个虚拟的逻辑单元,负责所有数据节点运行状态的监控和维护,以及节点之间的负载均衡(图中 M)。同时,管理节点也负责元数据(包括用户、数据库、表、静态标签等)的存储和管理,因此也称为 Meta Node。TDengine 集群中可配置多个(开源版最多不超过 3 个)mnode,它们自动构建成为一个虚拟管理节点组(图中 M0,M1,M2)。mnode 间采用 master/slave 的机制进行管理,而且采取强一致方式进行数据同步,任何数据更新操作只能在 Master 上进行。mnode 集群的创建由系统自动完成,无需人工干预。每个 dnode 上至多有一个 mnode,由所属的数据节点的 EP 来唯一标识。每个 dnode 通过内部消息交互自动获取整个集群中所有 mnode 所在的 dnode 的 EP。 +**管理节点(mnode):** 一个虚拟的逻辑单元,负责所有数据节点运行状态的监控和维护,以及节点之间的负载均衡(图中 M)。同时,管理节点也负责元数据(包括用户、数据库、表、静态标签等)的存储和管理,因此也称为 Meta Node。TDengine 集群中可配置多个(最多不超过 3 个)mnode,它们自动构建成为一个虚拟管理节点组(图中 M0,M1,M2)。mnode 间采用 master/slave 的机制进行管理,而且采取强一致方式进行数据同步,任何数据更新操作只能在 Master 上进行。mnode 集群的创建由系统自动完成,无需人工干预。每个 dnode 上至多有一个 mnode,由所属的数据节点的 EP 来唯一标识。每个 dnode 通过内部消息交互自动获取整个集群中所有 mnode 所在的 dnode 的 EP。 **虚拟节点组(VGroup):** 不同数据节点上的 vnode 可以组成一个虚拟节点组(vgroup)来保证系统的高可靠。虚拟节点组内采取 master/slave 的方式进行管理。写操作只能在 master vnode 上进行,系统采用异步复制的方式将数据同步到 slave vnode,这样确保了一份数据在多个物理节点上有拷贝。一个 vgroup 里虚拟节点个数就是数据的副本数。如果一个 DB 的副本数为 N,系统必须有至少 N 数据节点。副本数在创建 DB 时通过参数 replica 可以指定,缺省为 1。使用 TDengine 的多副本特性,可以不再需要昂贵的磁盘阵列等存储设备,就可以获得同样的数据高可靠性。虚拟节点组由管理节点创建、管理,并且由管理节点分配一个系统唯一的 ID,VGroup ID。如果两个虚拟节点的 VGroup ID 相同,说明他们属于同一个组,数据互为备份。虚拟节点组里虚拟节点的个数是可以动态改变的,容许只有一个,也就是没有数据复制。VGroup ID 是永远不变的,即使一个虚拟节点组被删除,它的 ID 也不会被收回重复利用。 -- GitLab From 2858754598d299c0fb0843484bfb195e9f16d4c6 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Mon, 27 Jun 2022 13:01:45 +0800 Subject: [PATCH 092/380] Update 02-2.4.md --- docs/zh/30-release/02-2.4.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/zh/30-release/02-2.4.md b/docs/zh/30-release/02-2.4.md index 62580b327a..9eeb5a10b4 100644 --- a/docs/zh/30-release/02-2.4.md +++ b/docs/zh/30-release/02-2.4.md @@ -2,6 +2,8 @@ title: 2.4 --- +[2.4.0.30](https://github.com/taosdata/TDengine/releases/tag/ver-2.4.0.30) + [2.4.0.26](https://github.com/taosdata/TDengine/releases/tag/ver-2.4.0.26) [2.4.0.25](https://github.com/taosdata/TDengine/releases/tag/ver-2.4.0.25) -- GitLab From c767af5a4c1923ca480816b146ab1dcad5c7b114 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Mon, 27 Jun 2022 13:02:10 +0800 Subject: [PATCH 093/380] Update 01-2.6.md --- docs/zh/30-release/01-2.6.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/zh/30-release/01-2.6.md b/docs/zh/30-release/01-2.6.md index 85b76d9999..c7f46b110c 100644 --- a/docs/zh/30-release/01-2.6.md +++ b/docs/zh/30-release/01-2.6.md @@ -2,6 +2,8 @@ title: 2.6 --- +[2.6.0.6](https://github.com/taosdata/TDengine/releases/tag/ver-2.6.0.6) + [2.6.0.4](https://github.com/taosdata/TDengine/releases/tag/ver-2.6.0.4) [2.6.0.1](https://github.com/taosdata/TDengine/releases/tag/ver-2.6.0.1) -- GitLab From 29f05e25f5be4c3136910a17c76db2e97449ef46 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Mon, 27 Jun 2022 13:03:03 +0800 Subject: [PATCH 094/380] Update 01-2.6.md --- docs/en/30-release/01-2.6.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/30-release/01-2.6.md b/docs/en/30-release/01-2.6.md index 85b76d9999..c7f46b110c 100644 --- a/docs/en/30-release/01-2.6.md +++ b/docs/en/30-release/01-2.6.md @@ -2,6 +2,8 @@ title: 2.6 --- +[2.6.0.6](https://github.com/taosdata/TDengine/releases/tag/ver-2.6.0.6) + [2.6.0.4](https://github.com/taosdata/TDengine/releases/tag/ver-2.6.0.4) [2.6.0.1](https://github.com/taosdata/TDengine/releases/tag/ver-2.6.0.1) -- GitLab From 308481670dffaebabc458f07a58bacd4911464cd Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Mon, 27 Jun 2022 13:03:27 +0800 Subject: [PATCH 095/380] Update 02-2.4.md --- docs/en/30-release/02-2.4.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/30-release/02-2.4.md b/docs/en/30-release/02-2.4.md index 62580b327a..9eeb5a10b4 100644 --- a/docs/en/30-release/02-2.4.md +++ b/docs/en/30-release/02-2.4.md @@ -2,6 +2,8 @@ title: 2.4 --- +[2.4.0.30](https://github.com/taosdata/TDengine/releases/tag/ver-2.4.0.30) + [2.4.0.26](https://github.com/taosdata/TDengine/releases/tag/ver-2.4.0.26) [2.4.0.25](https://github.com/taosdata/TDengine/releases/tag/ver-2.4.0.25) -- GitLab From 68285d2653222a51912d8d2b7c1f1233694739ed Mon Sep 17 00:00:00 2001 From: SunShine Chan Date: Mon, 27 Jun 2022 15:17:56 +0800 Subject: [PATCH 096/380] fix(tsc): add error code TSDB_CODE_TSC_TOO_MANY_SML_LINES --- src/client/src/tscParseLineProtocol.c | 4 ++-- src/inc/taoserror.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index 5a7de5fd5a..66280c32e8 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -1028,7 +1028,7 @@ static int32_t applyDataPointsWithSqlInsert(TAOS* taos, TAOS_SML_DATA_POINT* poi if (info->numBatches >= MAX_SML_SQL_INSERT_BATCHES) { tscError("SML:0x%"PRIx64" Apply points failed. exceeds max sql insert batches", info->id); - code = TSDB_CODE_TSC_OUT_OF_MEMORY; + code = TSDB_CODE_TSC_TOO_MANY_SML_LINES; goto cleanup; } @@ -1047,7 +1047,7 @@ static int32_t applyDataPointsWithSqlInsert(TAOS* taos, TAOS_SML_DATA_POINT* poi tscDebug("SML:0x%"PRIx64" sql: %s" , info->id, batch->sql); if (info->numBatches >= MAX_SML_SQL_INSERT_BATCHES) { tscError("SML:0x%"PRIx64" Apply points failed. exceeds max sql insert batches", info->id); - code = TSDB_CODE_TSC_OUT_OF_MEMORY; + code = TSDB_CODE_TSC_TOO_MANY_SML_LINES; goto cleanup; } bool batchesExecuted[MAX_SML_SQL_INSERT_BATCHES] = {false}; diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 6266926d55..029d3bd40f 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -116,6 +116,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSC_INVALID_PRECISION_TYPE TAOS_DEF_ERROR_CODE(0, 0x0226) //"Invalid timestamp precision type") #define TSDB_CODE_TSC_RES_TOO_MANY TAOS_DEF_ERROR_CODE(0, 0x0227) //"Result set too large to be output") #define TSDB_CODE_TSC_INVALID_SCHEMA_VERSION TAOS_DEF_ERROR_CODE(0, 0x0228) //"invalid table schema version") +#define TSDB_CODE_TSC_TOO_MANY_SML_LINES TAOS_DEF_ERROR_CODE(0, 0x0229) //"too many lines in batch") // mnode #define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed" -- GitLab From dfeb75feb3b5c9280a8de6774fa335acdf874dc9 Mon Sep 17 00:00:00 2001 From: xywang Date: Tue, 28 Jun 2022 10:34:59 +0800 Subject: [PATCH 097/380] feat: added min_row & max_row functions --- src/client/src/tscSQLParser.c | 67 ++++++-- src/query/inc/qAggMain.h | 9 +- src/query/src/qAggMain.c | 279 +++++++++++++++++++++++++++++++++- src/query/src/qExecutor.c | 67 +++++++- 4 files changed, 404 insertions(+), 18 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 750412117c..49ce9398b3 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -2875,6 +2875,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col case TSDB_FUNC_TWA: case TSDB_FUNC_MIN: case TSDB_FUNC_MAX: + case TSDB_FUNC_MIN_ROW: + case TSDB_FUNC_MAX_ROW: case TSDB_FUNC_DIFF: case TSDB_FUNC_DERIVATIVE: case TSDB_FUNC_CSUM: @@ -2961,6 +2963,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); + } else if (!IS_NUMERIC_TYPE(pSchema->type) && (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW)) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } int16_t resultType = 0; @@ -8294,13 +8298,15 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex, SSqlC pInfo->visible = false; } -static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { +static void doUpdateSqlFunctionForColTagPrj(SQueryInfo* pQueryInfo) { int32_t tagLength = 0; size_t size = taosArrayGetSize(pQueryInfo->exprList); -//todo is 0?? + //todo is 0?? STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); + bool isMinRow = false; + bool isMaxRow = false; for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); @@ -8310,6 +8316,22 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { } else if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { pExpr->base.functionId = TSDB_FUNC_TS_DUMMY; // ts_select ts,top(col,2) tagLength += pExpr->base.resBytes; + } else if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW) { + isMinRow = true; + } else if (pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { + isMaxRow = true; + } + } + + if (isMinRow || isMaxRow) { + for (int32_t i = 0; i < size; ++i) { + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW || pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { + continue; + } else if (pExpr->base.functionId == TSDB_FUNC_PRJ) { + pExpr->base.functionId = isMinRow ? TSDB_FUNC_MIN_COL_DUMMY : TSDB_FUNC_MAX_COL_DUMMY; + tagLength += pExpr->base.resBytes; + } } } @@ -8321,8 +8343,9 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { continue; } - if ((pExpr->base.functionId != TSDB_FUNC_TAG_DUMMY && pExpr->base.functionId != TSDB_FUNC_TS_DUMMY) && - !(pExpr->base.functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag))) { + if ((pExpr->base.functionId != TSDB_FUNC_TAG_DUMMY && pExpr->base.functionId != TSDB_FUNC_TS_DUMMY && + pExpr->base.functionId != TSDB_FUNC_MIN_COL_DUMMY && pExpr->base.functionId != TSDB_FUNC_MAX_COL_DUMMY) + && !(pExpr->base.functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag))) { SSchema* pColSchema = &pSchema[pExpr->base.colInfo.colIndex]; getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->base.functionId, (int32_t)pExpr->base.param[0].i64, &pExpr->base.resType, &pExpr->base.resBytes, &pExpr->base.interBytes, tagLength, isSTable, NULL); @@ -8451,10 +8474,14 @@ static bool check_expr_in_groupby_colum(SGroupbyExpr* pGroupbyExpr, SExprInfo* p * 2. if selectivity function and tagprj function both exist, there should be only * one selectivity function exists. */ -static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { +static int32_t checkUpdateColTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { const char* msg1 = "only one selectivity function allowed in presence of tags function"; const char* msg2 = "aggregation function should not be mixed up with projection"; + const char* msg3 = "min_row should not be mixed up with max_row"; + bool isMinRow = false; + bool isMaxRow = false; + bool isMinMaxRow = false; bool tagTsColExists = false; int16_t numOfScalar = 0; int16_t numOfSelectivity = 0; @@ -8471,6 +8498,26 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { tagTsColExists = true; // selectivity + ts/tag column break; } + } else if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW) { + isMinRow = true; + } else if (pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { + isMaxRow = true; + } + } + + if (isMinRow && isMaxRow) { + return invalidOperationMsg(msg, msg3); + } else if (isMinRow || isMaxRow) { + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo *pExpr = taosArrayGetP(pQueryInfo->exprList, i); + if (pExpr->base.functionId != TSDB_FUNC_PRJ) { + continue; + } else { + if (false == check_expr_in_groupby_colum(pGroupbyExpr, pExpr)) { + isMinMaxRow = true; + break; + } + } } } @@ -8512,7 +8559,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { } } - if (tagTsColExists) { // check if the selectivity function exists + if (tagTsColExists || isMinMaxRow) { // check if the selectivity function exists // When the tag projection function on tag column that is not in the group by clause, aggregation function and // selectivity function exist in select clause is not allowed. if (numOfAggregation > 0) { @@ -8523,7 +8570,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { * if numOfSelectivity equals to 0, it is a super table projection query */ if (numOfSelectivity == 1) { - doUpdateSqlFunctionForTagPrj(pQueryInfo); + doUpdateSqlFunctionForColTagPrj(pQueryInfo); int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo); if (code != TSDB_CODE_SUCCESS) { return code; @@ -8553,7 +8600,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { } } - doUpdateSqlFunctionForTagPrj(pQueryInfo); + doUpdateSqlFunctionForColTagPrj(pQueryInfo); int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo); if (code != TSDB_CODE_SUCCESS) { return code; @@ -8777,7 +8824,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* } } - if (checkUpdateTagPrjFunctions(pQueryInfo, msg) != TSDB_CODE_SUCCESS) { + if (checkUpdateColTagPrjFunctions(pQueryInfo, msg) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -8792,7 +8839,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* return TSDB_CODE_SUCCESS; } else { - return checkUpdateTagPrjFunctions(pQueryInfo, msg); + return checkUpdateColTagPrjFunctions(pQueryInfo, msg); } } diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index edd13ea962..23a3f66a8c 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -90,8 +90,12 @@ extern "C" { #define TSDB_FUNC_QSTOP 48 #define TSDB_FUNC_QDURATION 49 #define TSDB_FUNC_HYPERLOGLOG 50 +#define TSDB_FUNC_MIN_ROW 51 +#define TSDB_FUNC_MAX_ROW 52 +#define TSDB_FUNC_MIN_COL_DUMMY 53 +#define TSDB_FUNC_MAX_COL_DUMMY 54 -#define TSDB_FUNC_MAX_NUM 51 +#define TSDB_FUNC_MAX_NUM 55 #define TSDB_FUNCSTATE_SO 0x1u // single output #define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM @@ -217,6 +221,9 @@ typedef struct SQLFunctionCtx { SHashObj **pModeSet; // for mode function STimeWindow qWindow; // for _qstart/_qstop/_qduration column int32_t allocRows; // rows allocated for output buffer + int16_t minRowIndex; + int16_t maxRowIndex; + bool updateIndex; // whether update index after comparation } SQLFunctionCtx; typedef struct SAggFunctionInfo { diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 8d9560f7ec..0ed6d4ee33 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -419,8 +419,8 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI assert(functionId != TSDB_FUNC_SCALAR_EXPR); if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY || - functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ || - functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) + functionId == TSDB_FUNC_MIN_COL_DUMMY || functionId == TSDB_FUNC_MAX_COL_DUMMY || functionId == TSDB_FUNC_DIFF || + functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) { *type = (int16_t)dataType; *bytes = dataBytes; @@ -522,6 +522,12 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI *bytes = (dataBytes + DATA_SET_FLAG_SIZE); *interBytes = *bytes; + return TSDB_CODE_SUCCESS; + } else if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + *type = TSDB_DATA_TYPE_BINARY; + *bytes = (dataBytes + DATA_SET_FLAG_SIZE); + *interBytes = *bytes; + return TSDB_CODE_SUCCESS; } else if (functionId == TSDB_FUNC_SUM) { *type = TSDB_DATA_TYPE_BINARY; @@ -680,6 +686,10 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI *type = (int16_t)dataType; *bytes = dataBytes; *interBytes = dataBytes + DATA_SET_FLAG_SIZE; + } else if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + *type = (int16_t)dataType; + *bytes = dataBytes; + *interBytes = dataBytes + DATA_SET_FLAG_SIZE; } else if (functionId == TSDB_FUNC_FIRST || functionId == TSDB_FUNC_LAST) { *type = (int16_t)dataType; *bytes = dataBytes; @@ -1001,6 +1011,7 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) { #define UPDATE_DATA(ctx, left, right, num, sign, k) \ do { \ if (((left) < (right)) ^ (sign)) { \ + (ctx)->updateIndex = true; \ (left) = (right); \ DO_UPDATE_TAG_COLUMNS(ctx, k); \ (num) += 1; \ @@ -1737,6 +1748,152 @@ static void max_func_merge(SQLFunctionCtx *pCtx) { } } +static bool min_row_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { + if (!function_setup(pCtx, pResultInfo)) { + return false; // not initialized since it has been initialized + } + + GET_TRUE_DATA_TYPE(); + + switch (type) { + case TSDB_DATA_TYPE_TINYINT: + *((int8_t *)pCtx->pOutput) = INT8_MAX; + break; + case TSDB_DATA_TYPE_UTINYINT: + *(uint8_t *) pCtx->pOutput = UINT8_MAX; + break; + case TSDB_DATA_TYPE_SMALLINT: + *((int16_t *)pCtx->pOutput) = INT16_MAX; + break; + case TSDB_DATA_TYPE_USMALLINT: + *((uint16_t *)pCtx->pOutput) = UINT16_MAX; + break; + case TSDB_DATA_TYPE_INT: + *((int32_t *)pCtx->pOutput) = INT32_MAX; + break; + case TSDB_DATA_TYPE_UINT: + *((uint32_t *)pCtx->pOutput) = UINT32_MAX; + break; + case TSDB_DATA_TYPE_BIGINT: + *((int64_t *)pCtx->pOutput) = INT64_MAX; + break; + case TSDB_DATA_TYPE_UBIGINT: + *((uint64_t *)pCtx->pOutput) = UINT64_MAX; + break; + case TSDB_DATA_TYPE_FLOAT: + *((float *)pCtx->pOutput) = FLT_MAX; + break; + case TSDB_DATA_TYPE_DOUBLE: + SET_DOUBLE_VAL(((double *)pCtx->pOutput), DBL_MAX); + break; + default: + qError("illegal data type:%d in min_row query", pCtx->inputType); + } + + return true; +} + +static bool max_row_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { + if (!function_setup(pCtx, pResultInfo)) { + return false; // not initialized since it has been initialized + } + + GET_TRUE_DATA_TYPE(); + + switch (type) { + case TSDB_DATA_TYPE_TINYINT: + *((int8_t *)pCtx->pOutput) = INT8_MIN; + break; + case TSDB_DATA_TYPE_UTINYINT: + *((uint8_t *)pCtx->pOutput) = 0; + break; + case TSDB_DATA_TYPE_SMALLINT: + *((int16_t *)pCtx->pOutput) = INT16_MIN; + break; + case TSDB_DATA_TYPE_USMALLINT: + *((uint16_t *)pCtx->pOutput) = 0; + break; + case TSDB_DATA_TYPE_INT: + *((int32_t *)pCtx->pOutput) = INT32_MIN; + break; + case TSDB_DATA_TYPE_UINT: + *((uint32_t *)pCtx->pOutput) = 0; + break; + case TSDB_DATA_TYPE_BIGINT: + *((int64_t *)pCtx->pOutput) = INT64_MIN; + break; + case TSDB_DATA_TYPE_UBIGINT: + *((uint64_t *)pCtx->pOutput) = 0; + break; + case TSDB_DATA_TYPE_FLOAT: + *((float *)pCtx->pOutput) = -FLT_MAX; + break; + case TSDB_DATA_TYPE_DOUBLE: + SET_DOUBLE_VAL(((double *)pCtx->pOutput), -DBL_MAX); + break; + default: + qError("illegal data type:%d in max_row query", pCtx->inputType); + } + + return true; +} + +static void min_row_function(SQLFunctionCtx *pCtx) { + int32_t notNullElems = 0; + minMax_function(pCtx, pCtx->pOutput, 1, ¬NullElems); + + SET_VAL(pCtx, notNullElems, 1); + + if (notNullElems > 0) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + pResInfo->hasResult = DATA_SET_FLAG; + + // set the flag for super table query + if (pCtx->stableQuery) { + *(pCtx->pOutput + pCtx->inputBytes) = DATA_SET_FLAG; + } + } +} + +static void max_row_function(SQLFunctionCtx *pCtx) { + int32_t notNullElems = 0; + minMax_function(pCtx, pCtx->pOutput, 0, ¬NullElems); + + SET_VAL(pCtx, notNullElems, 1); + + if (notNullElems > 0) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + pResInfo->hasResult = DATA_SET_FLAG; + + // set the flag for super table query + if (pCtx->stableQuery) { + *(pCtx->pOutput + pCtx->inputBytes) = DATA_SET_FLAG; + } + } +} + +static void min_row_func_merge(SQLFunctionCtx *pCtx) { + int32_t notNullElems = minmax_merge_impl(pCtx, pCtx->outputBytes, pCtx->pOutput, 1); + + SET_VAL(pCtx, notNullElems, 1); + + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + if (notNullElems > 0) { + pResInfo->hasResult = DATA_SET_FLAG; + } +} + +static void max_row_func_merge(SQLFunctionCtx *pCtx) { + int32_t numOfElem = minmax_merge_impl(pCtx, pCtx->outputBytes, pCtx->pOutput, 0); + + SET_VAL(pCtx, numOfElem, 1); + + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + if (numOfElem > 0) { + pResInfo->hasResult = DATA_SET_FLAG; + } +} + #define LOOP_STDDEV_IMPL(type, r, d, ctx, delta, _type, num) \ for (int32_t i = 0; i < (ctx)->size; ++i) { \ if ((ctx)->hasNull && isNull((char *)&((type *)d)[i], (_type))) { \ @@ -3411,6 +3568,72 @@ static void copy_function(SQLFunctionCtx *pCtx) { assignVal(pCtx->pOutput, pData, pCtx->inputBytes, pCtx->inputType); } +static char *get_data_by_offset(char *src, int16_t inputType, int32_t inputBytes, int32_t offset) { + char *res = NULL; + + switch (inputType) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_UTINYINT: + res = (char *) ((int8_t *) src + offset); + break; + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_USMALLINT: + res = (char *) ((int16_t *) src + offset); + break; + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_UINT: + res = (char *) ((int32_t *) src + offset); + break; + case TSDB_DATA_TYPE_FLOAT: + res = (char *) ((float *) src + offset); + break; + case TSDB_DATA_TYPE_DOUBLE: + res = (char *) ((double *) src + offset); + break; + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_UBIGINT: + case TSDB_DATA_TYPE_TIMESTAMP: + res = (char *) ((int64_t *) src + offset); + break; + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + res = src + offset * inputBytes; + break; + default: { + res = src; + } + } + + return res; +} + +static void min_row_copy_function(SQLFunctionCtx *pCtx) { + int16_t index = pCtx->minRowIndex; + if (index < 0 || !pCtx->updateIndex) { + return; + } + + SET_VAL(pCtx, pCtx->size, 1); + + char *pData = GET_INPUT_DATA_LIST(pCtx); + pData = get_data_by_offset(pData, pCtx->inputType, pCtx->inputBytes, index); + assignVal(pCtx->pOutput, pData, pCtx->inputBytes, pCtx->inputType); +} + +static void max_row_copy_function(SQLFunctionCtx *pCtx) { + int16_t index = pCtx->maxRowIndex; + if (index < 0 || !pCtx->updateIndex) { + return; + } + + SET_VAL(pCtx, pCtx->size, 1); + + char *pData = GET_INPUT_DATA_LIST(pCtx); + pData = get_data_by_offset(pData, pCtx->inputType, pCtx->inputBytes, index); + assignVal(pCtx->pOutput, pData, pCtx->inputBytes, pCtx->inputType); +} + static void full_copy_function(SQLFunctionCtx *pCtx) { copy_function(pCtx); @@ -6052,8 +6275,8 @@ int32_t functionCompatList[] = { 1, 1, 1, 1, -1, 1, 1, 1, 5, 1, 1, // tid_tag, deriv, csum, mavg, sample, block_info, elapsed, histogram, unique, mode, tail 6, 8, -1, -1, -1, 7, 1, -1, -1, 1, -1, - // stateCount, stateDuration, wstart, wstop, wduration, qstart, qstop, qduration, hyperloglog - 1, 1, 1, 1, 1, 1, 1, 1, 1, + // stateCount, stateDuration, wstart, wstop, wduration, qstart, qstop, qduration, hyperloglog, min_row, max_row + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; SAggFunctionInfo aAggs[TSDB_FUNC_MAX_NUM] = {{ @@ -6670,5 +6893,53 @@ SAggFunctionInfo aAggs[TSDB_FUNC_MAX_NUM] = {{ hll_func_finalizer, hll_func_merge, dataBlockRequired, + }, + { + // 51 + "min_row", + TSDB_FUNC_MIN_ROW, + TSDB_FUNC_MIN_ROW, + TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_SELECTIVITY, + min_row_func_setup, + min_row_function, + function_finalizer, + min_row_func_merge, + dataBlockRequired, + }, + { + // 52 + "max_row", + TSDB_FUNC_MAX_ROW, + TSDB_FUNC_MAX_ROW, + TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_SELECTIVITY, + max_row_func_setup, + max_row_function, + function_finalizer, + max_row_func_merge, + dataBlockRequired, + }, + { + // 53 + "min_col_dummy", + TSDB_FUNC_MIN_COL_DUMMY, + TSDB_FUNC_MIN_COL_DUMMY, + TSDB_BASE_FUNC_SO, + function_setup, + min_row_copy_function, + doFinalizer, + copy_function, + noDataRequired, + }, + { + // 54 + "max_col_dummy", + TSDB_FUNC_MAX_COL_DUMMY, + TSDB_FUNC_MAX_COL_DUMMY, + TSDB_BASE_FUNC_SO, + function_setup, + max_row_copy_function, + doFinalizer, + copy_function, + noDataRequired, } }; diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 7d4b0b7edb..35509bad05 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -413,7 +413,9 @@ static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput continue; } - if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY) { + if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY || + functId == TSDB_FUNC_MIN_COL_DUMMY || functId == TSDB_FUNC_MAX_COL_DUMMY) + { hasTags = true; continue; } @@ -437,7 +439,9 @@ static bool isScalarWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput) { continue; } - if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY) { + if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY || + functId == TSDB_FUNC_MIN_COL_DUMMY || functId == TSDB_FUNC_MAX_COL_DUMMY) + { hasTags = true; continue; } @@ -1233,6 +1237,9 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunctionCtx* pCtx, SSDataBlock* pSDataBlock) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + int16_t minRowIndex = -1, maxRowIndex = -1; + bool updateIndex = false; + int32_t minMaxRowColIndex = -1; for (int32_t k = 0; k < pOperator->numOfOutput; ++k) { if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) { @@ -1243,7 +1250,32 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo; doInvokeUdf(pUdfInfo, &pCtx[k], 0, TSDB_UDF_FUNC_NORMAL); } else if (!TSDB_FUNC_IS_SCALAR(functionId)){ + if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + if (minMaxRowColIndex == -1) { + minMaxRowColIndex = k; + } + + pCtx[k].updateIndex = false; + } else { + pCtx[k].minRowIndex = minRowIndex; + pCtx[k].maxRowIndex = maxRowIndex; + pCtx[k].updateIndex = updateIndex; + } + aAggs[functionId].xFunction(&pCtx[k]); + + if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + updateIndex = pCtx[k].updateIndex; + + // find the minIndex or maxIndex of this column to detemine the index of other columns + if (functionId == TSDB_FUNC_MIN_ROW) { + minRowIndex = pCtx[k].preAggVals.statis.minIndex; + } + + if (functionId == TSDB_FUNC_MAX_ROW) { + maxRowIndex = pCtx[k].preAggVals.statis.maxIndex; + } + } } else { assert(0); } @@ -1254,6 +1286,30 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction } } } + + // update the indices of columns before the one in min_row/max_row + if (updateIndex) { + for (int32_t k = 0; k < minMaxRowColIndex; ++k) { + if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) { + pCtx[k].startTs = startTs; + + int32_t functionId = pCtx[k].functionId; + if (functionId != TSDB_FUNC_MIN_COL_DUMMY && functionId != TSDB_FUNC_MAX_COL_DUMMY) { + continue; + } + + pCtx[k].minRowIndex = minRowIndex; + pCtx[k].maxRowIndex = maxRowIndex; + pCtx[k].updateIndex = updateIndex; + + aAggs[functionId].xFunction(&pCtx[k]); + + pCtx[k].minRowIndex = -1; + pCtx[k].maxRowIndex = -1; + pCtx[k].updateIndex = false; + } + } + } } static void projectApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t numOfOutput) { @@ -1949,7 +2005,9 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { continue; } - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { //ts_select ts,top(col,2) + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY || + functionId == TSDB_FUNC_MIN_COL_DUMMY || functionId == TSDB_FUNC_MAX_COL_DUMMY) + { //ts_select ts,top(col,2) tagLen += pCtx[i].outputBytes; pTagCtx[num++] = &pCtx[i]; } else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) { @@ -2024,6 +2082,9 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr pCtx->end.key = INT64_MIN; pCtx->startTs = INT64_MIN; + pCtx->minRowIndex = -1; + pCtx->maxRowIndex = -1; + pCtx->qWindow = pQueryAttr->window; pCtx->allocRows = numOfRows; -- GitLab From db228a6d823801995b1c40e762c4f48c4b209b29 Mon Sep 17 00:00:00 2001 From: xywang Date: Tue, 28 Jun 2022 10:50:19 +0800 Subject: [PATCH 098/380] fix(tsc): add error code TSDB_CODE_TSC_TOO_MANY_SML_LINES --- src/util/src/terror.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 334207022d..0cc345d60a 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -123,6 +123,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_VALUE_OUT_OF_RANGE, "Value out of range") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_PROTOCOL_TYPE, "Invalid line protocol type") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_PRECISION_TYPE, "Invalid timestamp precision type") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_RES_TOO_MANY, "Result set too large to be output") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_TOO_MANY_SML_LINES, "Too many lines in batch") // mnode TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, "Message not processed") -- GitLab From de9664f93a36c1459db717b427d5ceff9080a02a Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 28 Jun 2022 17:35:25 +0800 Subject: [PATCH 099/380] fix(query): percentile second scan not call cause crash --- src/query/src/qAggMain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 8d9560f7ec..1aecac1b2f 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -2912,7 +2912,8 @@ static void percentile_finalizer(SQLFunctionCtx *pCtx) { tMemBucket * pMemBucket = ppInfo->pMemBucket; if (pMemBucket == NULL || pMemBucket->total == 0) { // check for null - assert(ppInfo->numOfElems == 0); + if (ppInfo->stage > 0) + assert(ppInfo->numOfElems == 0); setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes); } else { SET_DOUBLE_VAL((double *)pCtx->pOutput, getPercentile(pMemBucket, v)); -- GitLab From 76368c2e7b169bd246f4cb6291c0b929465e544a Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Tue, 28 Jun 2022 19:12:15 +0800 Subject: [PATCH 100/380] fix: add Linx and Red Hat support --- packaging/tools/install_arbi.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packaging/tools/install_arbi.sh b/packaging/tools/install_arbi.sh index 6e9be8489b..31a9ce38ac 100755 --- a/packaging/tools/install_arbi.sh +++ b/packaging/tools/install_arbi.sh @@ -76,12 +76,21 @@ elif echo $osinfo | grep -qwi "debian"; then elif echo $osinfo | grep -qwi "Kylin"; then # echo "This is Kylin system" os_type=1 +elif echo $osinfo | grep -qwi "Red"; then + # echo "This is Red Hat system" + os_type=1 elif echo $osinfo | grep -qwi "centos"; then # echo "This is centos system" os_type=2 elif echo $osinfo | grep -qwi "fedora"; then # echo "This is fedora system" os_type=2 +elif echo $osinfo | grep -qwi "Linx"; then + # echo "This is Linx system" + os_type=1 + service_mod=0 + initd_mod=0 + service_config_dir="/etc/systemd/system" else echo " osinfo: ${osinfo}" echo " This is an officially unverified linux system," -- GitLab From 2abc73a7d4de5602f3c016ce4f19d560d61351ed Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Tue, 28 Jun 2022 19:24:45 +0800 Subject: [PATCH 101/380] docs: Update LineProtocolExample.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 看代码的时候发现注释有个小问题,毫秒的英文全称弄错了。 --- .../src/main/java/com/taos/example/LineProtocolExample.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java b/docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java index 990922b7a5..4f3da59fd1 100644 --- a/docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java @@ -26,7 +26,7 @@ public class LineProtocolExample { private static void createDatabase(Connection conn) throws SQLException { try (Statement stmt = conn.createStatement()) { - // the default precision is ms (microsecond), but we use us(microsecond) here. + // the default precision is ms (milliseconds), but we use us(microsecond) here. stmt.execute("CREATE DATABASE IF NOT EXISTS test PRECISION 'us'"); stmt.execute("USE test"); } -- GitLab From fd6690075f493fc7cf33cef671cf8ebd06f17ad3 Mon Sep 17 00:00:00 2001 From: Bo Ding Date: Wed, 29 Jun 2022 08:24:18 +0800 Subject: [PATCH 102/380] docs: typo in LineProtocolExample.java --- .../src/main/java/com/taos/example/LineProtocolExample.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java b/docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java index 4f3da59fd1..09c3078e22 100644 --- a/docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/LineProtocolExample.java @@ -26,7 +26,7 @@ public class LineProtocolExample { private static void createDatabase(Connection conn) throws SQLException { try (Statement stmt = conn.createStatement()) { - // the default precision is ms (milliseconds), but we use us(microsecond) here. + // the default precision is ms (millisecond), but we use us(microsecond) here. stmt.execute("CREATE DATABASE IF NOT EXISTS test PRECISION 'us'"); stmt.execute("USE test"); } -- GitLab From 740f1ab11781ae67b3541faa11f8ab3b33313faf Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 29 Jun 2022 11:26:58 +0800 Subject: [PATCH 103/380] feat: taosdump update for2.6 (#14342) * feat: update taos-tools for 2.6 prepare for 3.0 [TD-13052] * feat: update taos-tools fix -I -s for 2.6 * feat: taosdump support new format prepare for 3.0 for 2.6 branch update taos-tools [TD-13052] --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index a875a057d1..7105027650 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit a875a057d1225d85c6323b9edaccc2b1a9641987 +Subproject commit 7105027650b51e701cfa1dac11b8fb42d447dd01 -- GitLab From 0fa95ede673691dc26d0293271c9f0933cc9a179 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 29 Jun 2022 19:03:33 +0800 Subject: [PATCH 104/380] fix: remove csudo from mkdir debug (#14360) * fix: remove csudo from mkdir debug * fix: remove more csudo from directory maniplation --- packaging/release.sh | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packaging/release.sh b/packaging/release.sh index 354d713e28..cc4f064383 100755 --- a/packaging/release.sh +++ b/packaging/release.sh @@ -182,14 +182,10 @@ cd "${curr_dir}" # 2. cmake executable file compile_dir="${top_dir}/debug" if [ -d ${compile_dir} ]; then - ${csudo}rm -rf ${compile_dir} + rm -rf ${compile_dir} fi -if [ "$osType" != "Darwin" ]; then - ${csudo}mkdir -p ${compile_dir} -else - mkdir -p ${compile_dir} -fi +mkdir -p ${compile_dir} cd ${compile_dir} if [[ "$allocator" == "jemalloc" ]]; then @@ -256,9 +252,9 @@ if [ "$osType" != "Darwin" ]; then echo "====do deb package for the ubuntu system====" output_dir="${top_dir}/debs" if [ -d ${output_dir} ]; then - ${csudo}rm -rf ${output_dir} + rm -rf ${output_dir} fi - ${csudo}mkdir -p ${output_dir} + mkdir -p ${output_dir} cd ${script_dir}/deb ${csudo}./makedeb.sh ${compile_dir} ${output_dir} ${verNumber} ${cpuType} ${osType} ${verMode} ${verType} @@ -281,9 +277,9 @@ if [ "$osType" != "Darwin" ]; then echo "====do rpm package for the centos system====" output_dir="${top_dir}/rpms" if [ -d ${output_dir} ]; then - ${csudo}rm -rf ${output_dir} + rm -rf ${output_dir} fi - ${csudo}mkdir -p ${output_dir} + mkdir -p ${output_dir} cd ${script_dir}/rpm ${csudo}./makerpm.sh ${compile_dir} ${output_dir} ${verNumber} ${cpuType} ${osType} ${verMode} ${verType} -- GitLab From 1c1061fe6d80f67269e4ec7aca5fe12e2244274c Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Wed, 29 Jun 2022 16:44:13 +0800 Subject: [PATCH 105/380] fix: resolve arithmetic issues of first/last/last_row with keepColumnName enabled --- src/client/src/tscSQLParser.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 750412117c..22456782d0 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -2685,7 +2685,8 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS return TSDB_CODE_SUCCESS; } -void setResultColName(char* name, tSqlExprItem* pItem, int32_t functionId, SStrToken* pToken, bool multiCols) { +void setResultColName(char* name, bool finalResult, tSqlExprItem* pItem, int32_t functionId, SStrToken* pToken, + bool multiCols) { if (pItem->aliasName != NULL) { tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN); } else { @@ -2693,7 +2694,7 @@ void setResultColName(char* name, tSqlExprItem* pItem, int32_t functionId, SStrT int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN); tstrncpy(uname, pToken->z, len); - if (tsKeepOriginalColumnName) { // keep the original column name + if (finalResult && tsKeepOriginalColumnName) { // keep the original column name tstrncpy(name, uname, TSDB_COL_NAME_LEN); } else if (multiCols) { if (!TSDB_FUNC_IS_SCALAR(functionId)) { @@ -2710,7 +2711,7 @@ void setResultColName(char* name, tSqlExprItem* pItem, int32_t functionId, SStrT tstrncpy(name, tmp, TSDB_COL_NAME_LEN); } - } else { // use the user-input result column name + } else { // use the user-input result column name len = MIN(pItem->pNode->exprToken.n + 1, TSDB_COL_NAME_LEN); tstrncpy(name, pItem->pNode->exprToken.z, len); } @@ -3183,7 +3184,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) { index.columnIndex = j; SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)}; - setResultColName(name, pItem, cvtFunc.originFuncId, &t, true); + setResultColName(name, finalResult, pItem, cvtFunc.originFuncId, &t, true); if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult, pUdfInfo) != 0) { @@ -3212,7 +3213,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1; - setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->columnName, multiColOutput); + setResultColName(name, finalResult, pItem, cvtFunc.originFuncId, &pParamElem->pNode->columnName, + multiColOutput); if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex++, &index, finalResult, pUdfInfo) != 0) { @@ -3238,7 +3240,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col char name[TSDB_COL_NAME_LEN] = {0}; SStrToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)}; - setResultColName(name, pItem, cvtFunc.originFuncId, &t, true); + setResultColName(name, finalResult, pItem, cvtFunc.originFuncId, &t, true); if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult, pUdfInfo) != 0) { @@ -10950,17 +10952,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS *pExpr = calloc(1, sizeof(tExprNode)); (*pExpr)->nodeType = TSQL_NODE_COL; (*pExpr)->pSchema = calloc(1, sizeof(SSchema)); - if (tsKeepOriginalColumnName && // TD-14196, tsKeepOriginalColumnName params makes logic special - (pSqlExpr->functionId == TSDB_FUNC_FIRST || - pSqlExpr->functionId == TSDB_FUNC_LAST || - pSqlExpr->functionId == TSDB_FUNC_SPREAD || - pSqlExpr->functionId == TSDB_FUNC_LAST_ROW || - pSqlExpr->functionId == TSDB_FUNC_INTERP)) { - tSqlExprItem* pParamElem = taosArrayGet(pSqlExpr->Expr.paramList, 0); - strncpy((*pExpr)->pSchema->name, pParamElem->pNode->columnName.z, pParamElem->pNode->columnName.n); - }else{ - strncpy((*pExpr)->pSchema->name, pSqlExpr->exprToken.z, pSqlExpr->exprToken.n); - } + strncpy((*pExpr)->pSchema->name, pSqlExpr->exprToken.z, pSqlExpr->exprToken.n); // set the input column data byte and type. size_t size = taosArrayGetSize(pQueryInfo->exprList); -- GitLab From 3944fe9233655c5b28bc3ffb37bf719cf850147a Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 29 Jun 2022 21:02:39 +0800 Subject: [PATCH 106/380] fix(query): filter condition filterRmUnitRange can not reset unitIdx pointer when unitNum==0 [TS-1498] --- src/query/src/qFilter.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index a3421c801b..11ace4f7ce 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -2868,17 +2868,22 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t for (uint32_t g = 0; g < info->groupNum; ++g) { SFilterGroup *group = &info->groups[g]; + // first is block unint num for a group, following append unitNum blkUnitIdx for this group *unitNum = group->unitNum; all = 0; empty = 0; - + + // save group idx start pointer + uint32_t * pGroupIdx = unitIdx; for (uint32_t u = 0; u < group->unitNum; ++u) { uint32_t uidx = group->unitIdxs[u]; if (info->blkUnitRes[uidx] == 1) { + // blkUnitRes == 1 is always true, so need not compare every time, delete this unit from group --(*unitNum); all = 1; continue; } else if (info->blkUnitRes[uidx] == -1) { + // blkUnitRes == -1 is alwary false, so in group is alwary false, need delete this group from blkGroupNum *unitNum = 0; empty = 1; break; @@ -2888,6 +2893,9 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t } if (*unitNum == 0) { + // if unit num is zero, reset unitIdx to start on this group + unitIdx = pGroupIdx; + --info->blkGroupNum; assert(empty || all); -- GitLab From fea38333b6c004404dd88c7993fe62ed126949f8 Mon Sep 17 00:00:00 2001 From: xywang Date: Thu, 30 Jun 2022 11:42:15 +0800 Subject: [PATCH 107/380] feat: enhanced min_row & max_row functions --- src/client/src/tscGlobalmerge.c | 4 +- src/client/src/tscSQLParser.c | 61 ++++++++--------- src/query/inc/qAggMain.h | 12 +++- src/query/src/qAggMain.c | 62 ++++++++--------- src/query/src/qExecutor.c | 114 +++++++++++++++++++++++++++++--- 5 files changed, 176 insertions(+), 77 deletions(-) diff --git a/src/client/src/tscGlobalmerge.c b/src/client/src/tscGlobalmerge.c index b8d47022b4..f3f32ba64d 100644 --- a/src/client/src/tscGlobalmerge.c +++ b/src/client/src/tscGlobalmerge.c @@ -603,7 +603,7 @@ static void doMergeResultImpl(SOperatorInfo* pInfo, SQLFunctionCtx *pCtx, int32_ for (int32_t j = 0; j < numOfExpr; ++j) { int32_t functionId = pCtx[j].functionId; - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_COL_DUMMY) { continue; } @@ -625,7 +625,7 @@ static void doMergeResultImpl(SOperatorInfo* pInfo, SQLFunctionCtx *pCtx, int32_ static void doFinalizeResultImpl(SMultiwayMergeInfo* pInfo, SQLFunctionCtx *pCtx, int32_t numOfExpr) { for(int32_t j = 0; j < numOfExpr; ++j) { int32_t functionId = pCtx[j].functionId; - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_COL_DUMMY) { continue; } diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 49ce9398b3..a618f3a578 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -7770,10 +7770,20 @@ int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { bool isProjectionFunction = false; + bool minMaxRowExists = false; const char* msg1 = "functions not compatible with interval"; // multi-output set/ todo refactor size_t size = taosArrayGetSize(pQueryInfo->exprList); + + for (int32_t k = 0; k < size; ++k) { + SExprInfo* pExpr = tscExprGet(pQueryInfo, k); + + if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW || pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { + minMaxRowExists = true; + break; + } + } for (int32_t k = 0; k < size; ++k) { SExprInfo* pExpr = tscExprGet(pQueryInfo, k); @@ -7794,7 +7804,7 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu } // projection query on primary timestamp, the selectivity function needs to be present. - if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (minMaxRowExists || (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { bool hasSelectivity = false; for (int32_t j = 0; j < size; ++j) { SExprInfo* pEx = tscExprGet(pQueryInfo, j); @@ -8305,8 +8315,7 @@ static void doUpdateSqlFunctionForColTagPrj(SQueryInfo* pQueryInfo) { //todo is 0?? STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); - bool isMinRow = false; - bool isMaxRow = false; + bool minMaxRowExists = false; for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); @@ -8316,20 +8325,18 @@ static void doUpdateSqlFunctionForColTagPrj(SQueryInfo* pQueryInfo) { } else if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { pExpr->base.functionId = TSDB_FUNC_TS_DUMMY; // ts_select ts,top(col,2) tagLength += pExpr->base.resBytes; - } else if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW) { - isMinRow = true; - } else if (pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { - isMaxRow = true; + } else if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW || pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { + minMaxRowExists = true; } } - if (isMinRow || isMaxRow) { + if (minMaxRowExists) { for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW || pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { continue; } else if (pExpr->base.functionId == TSDB_FUNC_PRJ) { - pExpr->base.functionId = isMinRow ? TSDB_FUNC_MIN_COL_DUMMY : TSDB_FUNC_MAX_COL_DUMMY; + pExpr->base.functionId = TSDB_FUNC_COL_DUMMY; tagLength += pExpr->base.resBytes; } } @@ -8344,7 +8351,7 @@ static void doUpdateSqlFunctionForColTagPrj(SQueryInfo* pQueryInfo) { } if ((pExpr->base.functionId != TSDB_FUNC_TAG_DUMMY && pExpr->base.functionId != TSDB_FUNC_TS_DUMMY && - pExpr->base.functionId != TSDB_FUNC_MIN_COL_DUMMY && pExpr->base.functionId != TSDB_FUNC_MAX_COL_DUMMY) + pExpr->base.functionId != TSDB_FUNC_COL_DUMMY) && !(pExpr->base.functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag))) { SSchema* pColSchema = &pSchema[pExpr->base.colInfo.colIndex]; getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->base.functionId, (int32_t)pExpr->base.param[0].i64, &pExpr->base.resType, @@ -8478,10 +8485,10 @@ static int32_t checkUpdateColTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) const char* msg1 = "only one selectivity function allowed in presence of tags function"; const char* msg2 = "aggregation function should not be mixed up with projection"; const char* msg3 = "min_row should not be mixed up with max_row"; + const char* msg4 = "only one selectivity function allowed in presence of min_row or max_row function"; - bool isMinRow = false; - bool isMaxRow = false; - bool isMinMaxRow = false; + bool minRowExists = false; + bool maxRowExists = false; bool tagTsColExists = false; int16_t numOfScalar = 0; int16_t numOfSelectivity = 0; @@ -8499,26 +8506,14 @@ static int32_t checkUpdateColTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) break; } } else if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW) { - isMinRow = true; + minRowExists = true; } else if (pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { - isMaxRow = true; + maxRowExists = true; } } - if (isMinRow && isMaxRow) { + if (minRowExists && maxRowExists) { return invalidOperationMsg(msg, msg3); - } else if (isMinRow || isMaxRow) { - for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo *pExpr = taosArrayGetP(pQueryInfo->exprList, i); - if (pExpr->base.functionId != TSDB_FUNC_PRJ) { - continue; - } else { - if (false == check_expr_in_groupby_colum(pGroupbyExpr, pExpr)) { - isMinMaxRow = true; - break; - } - } - } } for (int32_t i = 0; i < numOfExprs; ++i) { @@ -8559,7 +8554,7 @@ static int32_t checkUpdateColTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) } } - if (tagTsColExists || isMinMaxRow) { // check if the selectivity function exists + if (tagTsColExists || minRowExists || maxRowExists) { // check if the selectivity function exists // When the tag projection function on tag column that is not in the group by clause, aggregation function and // selectivity function exist in select clause is not allowed. if (numOfAggregation > 0) { @@ -8596,7 +8591,13 @@ static int32_t checkUpdateColTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) (functionId == TSDB_FUNC_LAST_DST && (pExpr->base.colInfo.flag & TSDB_COL_NULL) != 0)) { // do nothing } else { - return invalidOperationMsg(msg, msg1); + if (tagTsColExists) { + return invalidOperationMsg(msg, msg1); + } + + if (minRowExists || maxRowExists) { + return invalidOperationMsg(msg, msg4); + } } } diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index 23a3f66a8c..5fc940309c 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -92,10 +92,15 @@ extern "C" { #define TSDB_FUNC_HYPERLOGLOG 50 #define TSDB_FUNC_MIN_ROW 51 #define TSDB_FUNC_MAX_ROW 52 -#define TSDB_FUNC_MIN_COL_DUMMY 53 -#define TSDB_FUNC_MAX_COL_DUMMY 54 +#define TSDB_FUNC_COL_DUMMY 53 -#define TSDB_FUNC_MAX_NUM 55 +#define TSDB_FUNC_MAX_NUM 54 + +enum { + FUNC_NOT_VAL, + FUNC_MIN_ROW, + FUNC_MAX_ROW +}; #define TSDB_FUNCSTATE_SO 0x1u // single output #define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM @@ -223,6 +228,7 @@ typedef struct SQLFunctionCtx { int32_t allocRows; // rows allocated for output buffer int16_t minRowIndex; int16_t maxRowIndex; + int16_t minMaxRowType; bool updateIndex; // whether update index after comparation } SQLFunctionCtx; diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 0ed6d4ee33..0968f67554 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -419,8 +419,8 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI assert(functionId != TSDB_FUNC_SCALAR_EXPR); if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY || - functionId == TSDB_FUNC_MIN_COL_DUMMY || functionId == TSDB_FUNC_MAX_COL_DUMMY || functionId == TSDB_FUNC_DIFF || - functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) + functionId == TSDB_FUNC_COL_DUMMY || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || + functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) { *type = (int16_t)dataType; *bytes = dataBytes; @@ -1028,13 +1028,27 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) { } while (0) #define LOOPCHECK_N(val, list, ctx, tsdbType, sign, num) \ + int32_t updateCount = 0; \ for (int32_t i = 0; i < ((ctx)->size); ++i) { \ if ((ctx)->hasNull && isNull((char *)&(list)[i], tsdbType)) { \ continue; \ } \ TSKEY key = (ctx)->ptsList != NULL? GET_TS_DATA(ctx, i):0; \ + (ctx)->updateIndex = false; \ UPDATE_DATA(ctx, val, (list)[i], num, sign, key); \ - } + if (!(ctx)->preAggVals.isSet) { \ + if ((ctx)->updateIndex) { \ + if (sign && (ctx)->preAggVals.statis.minIndex != i) { \ + (ctx)->preAggVals.statis.minIndex = i; \ + } \ + if (!sign && (ctx)->preAggVals.statis.maxIndex != i) { \ + (ctx)->preAggVals.statis.maxIndex = i; \ + } \ + updateCount++; \ + } \ + } \ + } \ + (ctx)->updateIndex = updateCount > 0 ? true : false; \ #define TYPED_LOOPCHECK_N(type, data, list, ctx, tsdbType, sign, notNullElems) \ do { \ @@ -3608,22 +3622,20 @@ static char *get_data_by_offset(char *src, int16_t inputType, int32_t inputBytes return res; } -static void min_row_copy_function(SQLFunctionCtx *pCtx) { - int16_t index = pCtx->minRowIndex; - if (index < 0 || !pCtx->updateIndex) { +static void row_copy_function(SQLFunctionCtx *pCtx) { + int16_t index; + + if (pCtx->minMaxRowType == FUNC_NOT_VAL || !pCtx->updateIndex) { return; } - SET_VAL(pCtx, pCtx->size, 1); - - char *pData = GET_INPUT_DATA_LIST(pCtx); - pData = get_data_by_offset(pData, pCtx->inputType, pCtx->inputBytes, index); - assignVal(pCtx->pOutput, pData, pCtx->inputBytes, pCtx->inputType); -} + if (pCtx->minMaxRowType == FUNC_MIN_ROW) { + index = pCtx->minRowIndex; + } else { + index = pCtx->maxRowIndex; + } -static void max_row_copy_function(SQLFunctionCtx *pCtx) { - int16_t index = pCtx->maxRowIndex; - if (index < 0 || !pCtx->updateIndex) { + if (index < 0) { return; } @@ -6920,24 +6932,12 @@ SAggFunctionInfo aAggs[TSDB_FUNC_MAX_NUM] = {{ }, { // 53 - "min_col_dummy", - TSDB_FUNC_MIN_COL_DUMMY, - TSDB_FUNC_MIN_COL_DUMMY, - TSDB_BASE_FUNC_SO, - function_setup, - min_row_copy_function, - doFinalizer, - copy_function, - noDataRequired, - }, - { - // 54 - "max_col_dummy", - TSDB_FUNC_MAX_COL_DUMMY, - TSDB_FUNC_MAX_COL_DUMMY, + "col_dummy", + TSDB_FUNC_COL_DUMMY, + TSDB_FUNC_COL_DUMMY, TSDB_BASE_FUNC_SO, function_setup, - max_row_copy_function, + row_copy_function, doFinalizer, copy_function, noDataRequired, diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 35509bad05..e78cc632a5 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -413,9 +413,7 @@ static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput continue; } - if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY || - functId == TSDB_FUNC_MIN_COL_DUMMY || functId == TSDB_FUNC_MAX_COL_DUMMY) - { + if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY || functId == TSDB_FUNC_COL_DUMMY) { hasTags = true; continue; } @@ -439,9 +437,7 @@ static bool isScalarWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput) { continue; } - if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY || - functId == TSDB_FUNC_MIN_COL_DUMMY || functId == TSDB_FUNC_MAX_COL_DUMMY) - { + if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY || functId == TSDB_FUNC_COL_DUMMY) { hasTags = true; continue; } @@ -949,6 +945,10 @@ void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset, int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput) { SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + int16_t minRowIndex = -1, maxRowIndex = -1; + bool updateIndex = false; + int32_t minMaxRowColIndex = -1; + int16_t minMaxRowType = FUNC_NOT_VAL; for (int32_t k = 0; k < numOfOutput; ++k) { bool hasAggregates = pCtx[k].preAggVals.isSet; @@ -981,7 +981,39 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo; doInvokeUdf(pUdfInfo, &pCtx[k], 0, TSDB_UDF_FUNC_NORMAL); } else if (!TSDB_FUNC_IS_SCALAR(functionId)){ + if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + if (minMaxRowColIndex == -1) { + minMaxRowColIndex = k; + } + + if (functionId == TSDB_FUNC_MIN_ROW) { + minMaxRowType = FUNC_MIN_ROW; + } else { + minMaxRowType = FUNC_MAX_ROW; + } + + pCtx[k].updateIndex = false; + } else { + pCtx[k].minRowIndex = minRowIndex; + pCtx[k].maxRowIndex = maxRowIndex; + pCtx[k].updateIndex = updateIndex; + pCtx[k].minMaxRowType = minMaxRowType; + } + aAggs[functionId].xFunction(&pCtx[k]); + + if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + updateIndex = pCtx[k].updateIndex; + + // find the minIndex or maxIndex of this column to detemine the index of other columns + if (functionId == TSDB_FUNC_MIN_ROW) { + minRowIndex = pCtx[k].preAggVals.statis.minIndex; + } + + if (functionId == TSDB_FUNC_MAX_ROW) { + maxRowIndex = pCtx[k].preAggVals.statis.maxIndex; + } + } } else { assert(0); } @@ -996,6 +1028,58 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx pCtx[k].preAggVals.isSet = hasAggregates; pCtx[k].pInput = start; } + + // update the indices of columns before the one in min_row/max_row + if (updateIndex) { + for (int32_t k = 0; k < minMaxRowColIndex; ++k) { + bool hasAggregates = pCtx[k].preAggVals.isSet; + + pCtx[k].size = forwardStep; + pCtx[k].startTs = pWin->skey; + pCtx[k].endTs = pWin->ekey; + + // keep it temporarialy + char* start = pCtx[k].pInput; + + int32_t pos = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? offset : offset - (forwardStep - 1); + if (pCtx[k].pInput != NULL) { + pCtx[k].pInput = (char *)pCtx[k].pInput + pos * pCtx[k].inputBytes; + } + + if (tsCol != NULL) { + pCtx[k].ptsList = &tsCol[pos]; + } + + // not a whole block involved in query processing, statistics data can not be used + // NOTE: the original value of isSet have been changed here + if (pCtx[k].preAggVals.isSet && forwardStep < numOfTotal) { + pCtx[k].preAggVals.isSet = false; + } + + if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) { + int32_t functionId = pCtx[k].functionId; + if (functionId != TSDB_FUNC_COL_DUMMY) { + continue; + } + + pCtx[k].minRowIndex = minRowIndex; + pCtx[k].maxRowIndex = maxRowIndex; + pCtx[k].updateIndex = updateIndex; + pCtx[k].minMaxRowType = minMaxRowType; + + aAggs[functionId].xFunction(&pCtx[k]); + + pCtx[k].minRowIndex = -1; + pCtx[k].maxRowIndex = -1; + pCtx[k].updateIndex = false; + pCtx[k].minMaxRowType = FUNC_NOT_VAL; + } + + // restore it + pCtx[k].preAggVals.isSet = hasAggregates; + pCtx[k].pInput = start; + } + } } @@ -1238,8 +1322,9 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunctionCtx* pCtx, SSDataBlock* pSDataBlock) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; int16_t minRowIndex = -1, maxRowIndex = -1; - bool updateIndex = false; + bool updateIndex = false; int32_t minMaxRowColIndex = -1; + int16_t minMaxRowType = FUNC_NOT_VAL; for (int32_t k = 0; k < pOperator->numOfOutput; ++k) { if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) { @@ -1255,11 +1340,18 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction minMaxRowColIndex = k; } + if (functionId == TSDB_FUNC_MIN_ROW) { + minMaxRowType = FUNC_MIN_ROW; + } else { + minMaxRowType = FUNC_MAX_ROW; + } + pCtx[k].updateIndex = false; } else { pCtx[k].minRowIndex = minRowIndex; pCtx[k].maxRowIndex = maxRowIndex; pCtx[k].updateIndex = updateIndex; + pCtx[k].minMaxRowType = minMaxRowType; } aAggs[functionId].xFunction(&pCtx[k]); @@ -1294,19 +1386,21 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction pCtx[k].startTs = startTs; int32_t functionId = pCtx[k].functionId; - if (functionId != TSDB_FUNC_MIN_COL_DUMMY && functionId != TSDB_FUNC_MAX_COL_DUMMY) { + if (functionId != TSDB_FUNC_COL_DUMMY) { continue; } pCtx[k].minRowIndex = minRowIndex; pCtx[k].maxRowIndex = maxRowIndex; pCtx[k].updateIndex = updateIndex; + pCtx[k].minMaxRowType = minMaxRowType; aAggs[functionId].xFunction(&pCtx[k]); pCtx[k].minRowIndex = -1; pCtx[k].maxRowIndex = -1; pCtx[k].updateIndex = false; + pCtx[k].minMaxRowType = FUNC_NOT_VAL; } } } @@ -2005,9 +2099,7 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { continue; } - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY || - functionId == TSDB_FUNC_MIN_COL_DUMMY || functionId == TSDB_FUNC_MAX_COL_DUMMY) - { //ts_select ts,top(col,2) + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_COL_DUMMY) { //ts_select ts,top(col,2) tagLen += pCtx[i].outputBytes; pTagCtx[num++] = &pCtx[i]; } else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) { -- GitLab From b46275f9d220c62451fc166408f75888ee9087a9 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 30 Jun 2022 13:12:31 +0800 Subject: [PATCH 108/380] fix: install script for2.6 (#14381) * fix: remove csudo from mkdir debug * fix: remove more csudo from directory maniplation * fix: packaging/release.sh for 2.6 --- packaging/release.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/release.sh b/packaging/release.sh index cc4f064383..4823c9d10b 100755 --- a/packaging/release.sh +++ b/packaging/release.sh @@ -261,9 +261,9 @@ if [ "$osType" != "Darwin" ]; then if [[ "$pagMode" == "full" ]]; then if [ -d ${top_dir}/src/kit/taos-tools/packaging/deb ]; then cd ${top_dir}/src/kit/taos-tools/packaging/deb + taos_tools_ver=$(git describe --tags | sed -e 's/ver-//g' | awk -F '-' '{print $1}') [ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0" - taos_tools_ver=$(git describe --tags | sed -e 's/ver-//g' | awk -F '-' '{print $1}') ${csudo}./make-taos-tools-deb.sh ${top_dir} \ ${compile_dir} ${output_dir} ${taos_tools_ver} ${cpuType} ${osType} ${verMode} ${verType} fi @@ -286,9 +286,9 @@ if [ "$osType" != "Darwin" ]; then if [[ "$pagMode" == "full" ]]; then if [ -d ${top_dir}/src/kit/taos-tools/packaging/rpm ]; then cd ${top_dir}/src/kit/taos-tools/packaging/rpm + taos_tools_ver=$(git describe --tags | sed -e 's/ver-//g' | awk -F '-' '{print $1}' | sed -e 's/-/_/g') [ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0" - taos_tools_ver=$(git describe --tags | sed -e 's/ver-//g' | awk -F '-' '{print $1}' | sed -e 's/-/_/g') ${csudo}./make-taos-tools-rpm.sh ${top_dir} \ ${compile_dir} ${output_dir} ${taos_tools_ver} ${cpuType} ${osType} ${verMode} ${verType} fi -- GitLab From 503b2453933ec7ac855c1327d3a07fcf052e87eb Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Wed, 29 Jun 2022 11:14:46 +0000 Subject: [PATCH 109/380] test: update functions/function_last.py --- tests/pytest/functions/function_last.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/pytest/functions/function_last.py b/tests/pytest/functions/function_last.py index 991ac96a80..1b89e2f5e4 100644 --- a/tests/pytest/functions/function_last.py +++ b/tests/pytest/functions/function_last.py @@ -127,6 +127,10 @@ class TDTestCase: tdSql.checkRows(1) tdSql.checkData(0, 0, 9.1) + tdSql.query("select last(col6)/10 from test1") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 0.91) + tdSql.query("select last(col7) from test1") tdSql.checkRows(1) tdSql.checkData(0, 0, True) -- GitLab From a14881fb82fcc01bf9ed88ecfaa5f5d822832a70 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Thu, 30 Jun 2022 14:43:21 +0800 Subject: [PATCH 110/380] fix: fix a typo --- src/common/src/tglobal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 616c5fba89..2b8c2bbb66 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -627,7 +627,7 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); - cfg.option = "tcpConnTimout"; + cfg.option = "tcpConnTimeout"; cfg.ptr = &tsTcpConnTimeout; cfg.valType = TAOS_CFG_VTYPE_INT32; cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; -- GitLab From 09c25e8d4cffde52444e549319894ec02df6c727 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 30 Jun 2022 16:25:09 +0800 Subject: [PATCH 111/380] fix(query): tsdb read merge block and memory condition check is not right --- src/tsdb/src/tsdbRead.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 05928e60fa..567b7ab85b 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -1654,7 +1654,9 @@ static int32_t loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SBlock* pBlock, if (asc) { // query ended in/started from current block - if (pQueryHandle->window.ekey < pBlock->keyLast || pCheckInfo->lastKey > pBlock->keyFirst) { + if ((pQueryHandle->window.ekey < pBlock->keyLast || pCheckInfo->lastKey > pBlock->keyFirst ) + && pCheckInfo->lastKey <= pBlock->keyLast) { + // if mem lastKey > block lastKey , should deal with handleDatamergeIfNeed if ((code = doLoadFileDataBlock(pQueryHandle, pBlock, pCheckInfo, cur->slot)) != TSDB_CODE_SUCCESS) { *exists = false; return code; @@ -1670,10 +1672,9 @@ static int32_t loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SBlock* pBlock, cur->pos = 0; } - assert(pCheckInfo->lastKey <= pBlock->keyLast); doMergeTwoLevelData(pQueryHandle, pCheckInfo, pBlock); } else { // the whole block is loaded in to buffer - cur->pos = asc? 0:(pBlock->numOfRows - 1); + cur->pos = 0; code = handleDataMergeIfNeeded(pQueryHandle, pBlock, pCheckInfo); } } else { //desc order, query ended in current block @@ -1693,7 +1694,7 @@ static int32_t loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SBlock* pBlock, assert(pCheckInfo->lastKey >= pBlock->keyFirst); doMergeTwoLevelData(pQueryHandle, pCheckInfo, pBlock); } else { - cur->pos = asc? 0:(pBlock->numOfRows-1); + cur->pos = pBlock->numOfRows - 1; code = handleDataMergeIfNeeded(pQueryHandle, pBlock, pCheckInfo); } } -- GitLab From 5a56adad0b577d0b5db5f360063c4a55c7db9589 Mon Sep 17 00:00:00 2001 From: xywang Date: Thu, 30 Jun 2022 16:39:54 +0800 Subject: [PATCH 112/380] fix: fixed bugs in min_row & max_row functions --- src/query/src/qAggMain.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 0968f67554..0e953b2ca2 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -1431,6 +1431,7 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, #endif if ((*data < val) ^ isMin) { + pCtx->updateIndex = true; *data = (int32_t)val; for (int32_t i = 0; i < (pCtx)->tagInfo.numOfTagCols; ++i) { SQLFunctionCtx *__ctx = pCtx->tagInfo.pTagCtxList[i]; @@ -1490,13 +1491,17 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, } else if (pCtx->inputType == TSDB_DATA_TYPE_INT) { int32_t *pData = p; int32_t *retVal = (int32_t*) pOutput; + int32_t updateCount = 0; for (int32_t i = 0; i < pCtx->size; ++i) { if (pCtx->hasNull && isNull((const char*)&pData[i], pCtx->inputType)) { continue; } + pCtx->updateIndex = false; + if ((*retVal < pData[i]) ^ isMin) { + pCtx->updateIndex = true; *retVal = pData[i]; if(tsList) { TSKEY k = tsList[i]; @@ -1504,7 +1509,21 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, } } *notNullElems += 1; + + if (!pCtx->preAggVals.isSet) { + if (pCtx->updateIndex) { + if (isMin && pCtx->preAggVals.statis.minIndex != i) { + pCtx->preAggVals.statis.minIndex = i; + } + if (!isMin && pCtx->preAggVals.statis.maxIndex != i) { + pCtx->preAggVals.statis.maxIndex = i; + } + updateCount++; + } + } } + + pCtx->updateIndex = updateCount > 0 ? true : false; #if defined(_DEBUG_VIEW) qDebug("max value updated:%d", *retVal); #endif -- GitLab From 228e82d52dda88cd70e6b6feb6f865c50672de04 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 30 Jun 2022 21:07:10 +0800 Subject: [PATCH 113/380] docs: use normal doc style (#14410) --- docs/en/14-reference/04-taosadapter.md | 4 ++-- docs/zh/14-reference/04-taosadapter.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/14-reference/04-taosadapter.md b/docs/en/14-reference/04-taosadapter.md index 3264124655..cad229c32d 100644 --- a/docs/en/14-reference/04-taosadapter.md +++ b/docs/en/14-reference/04-taosadapter.md @@ -206,8 +206,8 @@ Note: InfluxDB token authorization is not supported at present. Only Basic autho You can use any client that supports the http protocol to access the RESTful interface address `http://:6041/` to write data in OpenTSDB compatible format to TDengine. ```text -/opentsdb/v1/put/json/:db -/opentsdb/v1/put/telnet/:db +/opentsdb/v1/put/json/ +/opentsdb/v1/put/telnet/ ``` ### collectd diff --git a/docs/zh/14-reference/04-taosadapter.md b/docs/zh/14-reference/04-taosadapter.md index 6e259391d4..42bc51a6d3 100644 --- a/docs/zh/14-reference/04-taosadapter.md +++ b/docs/zh/14-reference/04-taosadapter.md @@ -207,8 +207,8 @@ AllowWebSockets 您可以使用任何支持 http 协议的客户端访问 Restful 接口地址 `http://:6041/` 来写入 OpenTSDB 兼容格式的数据到 TDengine。EndPoint 如下: ```text -/opentsdb/v1/put/json/:db -/opentsdb/v1/put/telnet/:db +/opentsdb/v1/put/json/ +/opentsdb/v1/put/telnet/ ``` ### collectd -- GitLab From aedb496fed231f6fbec148844b88996b38d86a1a Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 1 Jul 2022 15:50:45 +0800 Subject: [PATCH 114/380] fix: change tools/taosdumpTestNanoSupport.py keep to 36500 (#14427) --- tests/pytest/tools/taosdumpTestNanoSupport.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pytest/tools/taosdumpTestNanoSupport.py b/tests/pytest/tools/taosdumpTestNanoSupport.py index 146beb90e5..7d614543e1 100644 --- a/tests/pytest/tools/taosdumpTestNanoSupport.py +++ b/tests/pytest/tools/taosdumpTestNanoSupport.py @@ -61,7 +61,7 @@ class TDTestCase: def build_db(precision, start_time): tdSql.execute("drop database if exists timedb1") tdSql.execute( - "create database timedb1 days 10 keep 365 blocks 8 precision " + + "create database timedb1 days 10 keep 36500 blocks 8 precision " + "\"" + precision + "\"") -- GitLab From 5cd4b5721aaaff29fefeaf5c6eab13aaa1ca0c66 Mon Sep 17 00:00:00 2001 From: Yang Zhao Date: Fri, 1 Jul 2022 18:51:46 +0800 Subject: [PATCH 115/380] test: change test case (#14435) (#14437) --- .../5-taos-tools/taosbenchmark/insert_alltypes_json.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py b/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py index bcba5d8cc2..5239d1b5fb 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py +++ b/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py @@ -93,8 +93,6 @@ class TDTestCase: tdSql.checkData(27, 1, "SMALLINT UNSIGNED") tdSql.checkData(28, 1, "BINARY") tdSql.checkData(28, 2, 19) - tdSql.query("select count(*) from db.stb where c0 >= 0 and c0 <= 10") - tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from db.stb where c1 >= 0 and c1 <= 10") tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from db.stb where c2 >= 0 and c2 <= 10") -- GitLab From e43f809ef52f742d8b914dd2367e0f2c9048ece2 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 1 Jul 2022 20:04:35 +0800 Subject: [PATCH 116/380] feat: update taos-tools for 2.6 [TD-14141] --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 7105027650..5fdd694621 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 7105027650b51e701cfa1dac11b8fb42d447dd01 +Subproject commit 5fdd694621fbb7bd2d6102ff4feaec92a7001038 -- GitLab From c2d37d0a27c78892791a95764278cf1862ab4f74 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 1 Jul 2022 21:09:05 +0800 Subject: [PATCH 117/380] feat: update taos-tools (#14444) for 2.6 [TD-14141] --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 7105027650..5fdd694621 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 7105027650b51e701cfa1dac11b8fb42d447dd01 +Subproject commit 5fdd694621fbb7bd2d6102ff4feaec92a7001038 -- GitLab From 0d698d9bf6251bcac245d71477a94217eb4ab6d0 Mon Sep 17 00:00:00 2001 From: dingbo Date: Thu, 30 Jun 2022 19:43:13 +0800 Subject: [PATCH 118/380] docs: remove develop from go.mod --- docs/en/14-reference/03-connector/go.mdx | 161 +++++++++++----------- docs/examples/.gitignore | 3 +- docs/examples/.gitignre | 2 - docs/examples/go/go.mod | 2 +- docs/zh/14-reference/03-connector/go.mdx | 166 +++++++++++------------ 5 files changed, 164 insertions(+), 170 deletions(-) delete mode 100644 docs/examples/.gitignre diff --git a/docs/en/14-reference/03-connector/go.mdx b/docs/en/14-reference/03-connector/go.mdx index 8a05f2d841..b641fc0420 100644 --- a/docs/en/14-reference/03-connector/go.mdx +++ b/docs/en/14-reference/03-connector/go.mdx @@ -5,15 +5,15 @@ sidebar_label: Go title: TDengine Go Connector --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; -import Preparation from "./_preparation.mdx" -import GoInsert from "../../07-develop/03-insert-data/_go_sql.mdx" -import GoInfluxLine from "../../07-develop/03-insert-data/_go_line.mdx" -import GoOpenTSDBTelnet from "../../07-develop/03-insert-data/_go_opts_telnet.mdx" -import GoOpenTSDBJson from "../../07-develop/03-insert-data/_go_opts_json.mdx" -import GoQuery from "../../07-develop/04-query-data/_go.mdx" +import Preparation from "./_preparation.mdx"; +import GoInsert from "../../07-develop/03-insert-data/_go_sql.mdx"; +import GoInfluxLine from "../../07-develop/03-insert-data/_go_line.mdx"; +import GoOpenTSDBTelnet from "../../07-develop/03-insert-data/_go_opts_telnet.mdx"; +import GoOpenTSDBJson from "../../07-develop/03-insert-data/_go_opts_json.mdx"; +import GoQuery from "../../07-develop/04-query-data/_go.mdx"; `driver-go` is the official Go language connector for TDengine. It implements the [database/sql](https://golang.org/pkg/database/sql/) package, the generic Go language interface to SQL databases. Go developers can use it to develop applications that access TDengine cluster data. @@ -38,18 +38,18 @@ Please refer to [version support list](/reference/connector#version-support) A "native connection" is established by the connector directly to the TDengine instance via the TDengine client driver (taosc). The supported functional features are: -* Normal queries -* Continuous queries -* Subscriptions -* schemaless interface -* parameter binding interface +- Normal queries +- Continuous queries +- Subscriptions +- schemaless interface +- parameter binding interface ### REST connection A "REST connection" is a connection between the application and the TDengine instance via the REST API provided by the taosAdapter component. The following features are supported: -* General queries -* Continuous queries +- General queries +- Continuous queries ## Installation steps @@ -60,8 +60,8 @@ A "REST connection" is a connection between the application and the TDengine ins Configure the environment variables and check the command. -* `go env` -* `gcc -v` +- `go env` +- `gcc -v` ### Use go get to install @@ -73,31 +73,31 @@ go get -u github.com/taosdata/driver-go/v2@develop 1. Initialize the project with the `go mod` command. - ```text - go mod init taos-demo - ``` +```text +go mod init taos-demo +``` 2. Introduce taosSql - ```go - import ( - "database/sql" - _ "github.com/taosdata/driver-go/v2/taosSql" - ) - ``` +```go +import ( + "database/sql" + _ "github.com/taosdata/driver-go/v2/taosSql" +) +``` 3. Update the dependency packages with `go mod tidy`. - ```text - go mod tidy - ``` +```text +go mod tidy +``` 4. Run the program with `go run taos-demo` or compile the binary with the `go build` command. - ```text - go run taos-demo - go build - ``` +```text +go run taos-demo +go build +``` ## Create a connection @@ -105,7 +105,7 @@ go get -u github.com/taosdata/driver-go/v2@develop Data source names have a standard format, e.g. [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php), but no type prefix (square brackets indicate optionally): -``` text +```text [username[:password]@][protocol[(address)]]/[dbname][?param1=value1&... ¶mN=valueN] ``` @@ -124,7 +124,7 @@ _taosSql_ implements Go's `database/sql/driver` interface via cgo. You can use t Use `taosSql` as `driverName` and use a correct [DSN](#DSN) as `dataSourceName`, DSN supports the following parameters. -* configPath specifies the `taos.cfg` directory +- configPath specifies the `taos.cfg` directory Example. @@ -155,8 +155,8 @@ _taosRestful_ implements Go's `database/sql/driver` interface via `http client`. Use `taosRestful` as `driverName` and use a correct [DSN](#DSN) as `dataSourceName` with the following parameters supported by the DSN. -* `disableCompression` whether to accept compressed data, default is true do not accept compressed data, set to false if transferring data using gzip compression. -* `readBufferSize` The default size of the buffer for reading data is 4K (4096), which can be adjusted upwards when the query result has a lot of data. +- `disableCompression` whether to accept compressed data, default is true do not accept compressed data, set to false if transferring data using gzip compression. +- `readBufferSize` The default size of the buffer for reading data is 4K (4096), which can be adjusted upwards when the query result has a lot of data. Example. @@ -179,6 +179,7 @@ func main() { } } ``` + @@ -208,8 +209,8 @@ func main() { ### More sample programs -* [sample program](https://github.com/taosdata/TDengine/tree/develop/examples/go) -* [Video tutorial](https://www.taosdata.com/blog/2020/11/11/1951.html). +- [sample program](https://github.com/taosdata/TDengine/tree/develop/examples/go) +- [Video tutorial](https://www.taosdata.com/blog/2020/11/11/1951.html). ## Usage limitations @@ -269,56 +270,52 @@ func main() { ## Frequently Asked Questions -1. Cannot find the package `github.com/taosdata/driver-go/v2/taosRestful` - - Change the `github.com/taosdata/driver-go/v2` line in the require block of the `go.mod` file to `github.com/taosdata/driver-go/v2 develop`, then execute `go mod tidy`. - -2. bind interface in database/sql crashes +1. bind interface in database/sql crashes - REST does not support parameter binding related interface. It is recommended to use `db.Exec` and `db.Query`. + REST does not support parameter binding related interface. It is recommended to use `db.Exec` and `db.Query`. -3. error `[0x217] Database not specified or available` after executing other statements with `use db` statement +2. error `[0x217] Database not specified or available` after executing other statements with `use db` statement - The execution of SQL command in the REST interface is not contextual, so using `use db` statement will not work, see the usage restrictions section above. + The execution of SQL command in the REST interface is not contextual, so using `use db` statement will not work, see the usage restrictions section above. -4. use `taosSql` without error but use `taosRestful` with error `[0x217] Database not specified or available` +3. use `taosSql` without error but use `taosRestful` with error `[0x217] Database not specified or available` - Because the REST interface is stateless, using the `use db` statement will not take effect. See the usage restrictions section above. + Because the REST interface is stateless, using the `use db` statement will not take effect. See the usage restrictions section above. -5. Upgrade `github.com/taosdata/driver-go/v2/taosRestful` +4. Upgrade `github.com/taosdata/driver-go/v2/taosRestful` - Change the `github.com/taosdata/driver-go/v2` line in the `go.mod` file to `github.com/taosdata/driver-go/v2 develop`, then execute `go mod tidy`. + Change the `github.com/taosdata/driver-go/v2` line in the `go.mod` file to `github.com/taosdata/driver-go/v2 develop`, then execute `go mod tidy`. -6. `readBufferSize` parameter has no significant effect after being increased +5. `readBufferSize` parameter has no significant effect after being increased - Increasing `readBufferSize` will reduce the number of `syscall` calls when fetching results. If the query result is smaller, modifying this parameter will not improve performance significantly. If you increase the parameter value too much, the bottleneck will be parsing JSON data. If you need to optimize the query speed, you must adjust the value based on the actual situation to achieve the best query performance. + Increasing `readBufferSize` will reduce the number of `syscall` calls when fetching results. If the query result is smaller, modifying this parameter will not improve performance significantly. If you increase the parameter value too much, the bottleneck will be parsing JSON data. If you need to optimize the query speed, you must adjust the value based on the actual situation to achieve the best query performance. -7. `disableCompression` parameter is set to `false` when the query efficiency is reduced +6. `disableCompression` parameter is set to `false` when the query efficiency is reduced - When set `disableCompression` parameter to `false`, the query result will be compressed by `gzip` and then transmitted, so you have to decompress the data by `gzip` after getting it. + When set `disableCompression` parameter to `false`, the query result will be compressed by `gzip` and then transmitted, so you have to decompress the data by `gzip` after getting it. -8. `go get` command can't get the package, or timeout to get the package +7. `go get` command can't get the package, or timeout to get the package - Set Go proxy `go env -w GOPROXY=https://goproxy.cn,direct`. + Set Go proxy `go env -w GOPROXY=https://goproxy.cn,direct`. ## Common APIs ### database/sql API -* `sql.Open(DRIVER_NAME string, dataSourceName string) *DB` +- `sql.Open(DRIVER_NAME string, dataSourceName string) *DB` Use This API to open a DB, returning an object of type \*DB. -:::info -This API is created successfully without checking permissions, but only when you execute a Query or Exec, and check if user/password/host/port is legal. + :::info + This API is created successfully without checking permissions, but only when you execute a Query or Exec, and check if user/password/host/port is legal. -::: + ::: -* `func (db *DB) Exec(query string, args . .interface{}) (Result, error)` +- `func (db *DB) Exec(query string, args . .interface{}) (Result, error)` `sql.Open` built-in method to execute non-query related SQL. -* `func (db *DB) Query(query string, args ... . interface{}) (*Rows, error)` +- `func (db *DB) Query(query string, args ... . interface{}) (*Rows, error)` `sql.Open` Built-in method to execute query statements. @@ -328,85 +325,85 @@ The `af` package encapsulates TDengine advanced functions such as connection man #### Connection management -* `af.Open(host, user, pass, db string, port int) (*Connector, error)` +- `af.Open(host, user, pass, db string, port int) (*Connector, error)` This API creates a connection to taosd via cgo. -* `func (conn *Connector) Close() error` +- `func (conn *Connector) Close() error` Closes the connection. #### Subscribe to -* `func (conn *Connector) Subscribe(restart bool, topic string, sql string, interval time.Duration) (Subscriber, error)` +- `func (conn *Connector) Subscribe(restart bool, topic string, sql string, interval time.Duration) (Subscriber, error)` Subscribe to data. -* `func (s *taosSubscriber) Consume() (driver.Rows, error)` +- `func (s *taosSubscriber) Consume() (driver.Rows, error)` Consume the subscription data, returning the `Rows` structure of the `database/sql/driver` package. -* `func (s *taosSubscriber) Unsubscribe(keepProgress bool)` +- `func (s *taosSubscriber) Unsubscribe(keepProgress bool)` Unsubscribe from data. #### schemaless -* `func (conn *Connector) InfluxDBInsertLines(lines []string, precision string) error` +- `func (conn *Connector) InfluxDBInsertLines(lines []string, precision string) error` Write to influxDB line protocol. -* `func (conn *Connector) OpenTSDBInsertTelnetLines(lines []string) error` +- `func (conn *Connector) OpenTSDBInsertTelnetLines(lines []string) error` Write OpenTDSB telnet protocol data. -* `func (conn *Connector) OpenTSDBInsertJsonPayload(payload string) error` +- `func (conn *Connector) OpenTSDBInsertJsonPayload(payload string) error` Writes OpenTSDB JSON protocol data. #### parameter binding -* `func (conn *Connector) StmtExecute(sql string, params *param.Param) (res driver.Result, err error)` +- `func (conn *Connector) StmtExecute(sql string, params *param.Param) (res driver.Result, err error)` Parameter bound single row insert. -* `func (conn *Connector) StmtQuery(sql string, params *param.Param) (rows driver.Rows, err error)` +- `func (conn *Connector) StmtQuery(sql string, params *param.Param) (rows driver.Rows, err error)` Parameter bound query that returns the `Rows` structure of the `database/sql/driver` package. -* `func (conn *Connector) InsertStmt() *insertstmt. +- `func (conn *Connector) InsertStmt() *insertstmt. Initialize the parameters. -* `func (stmt *InsertStmt) Prepare(sql string) error` +- `func (stmt *InsertStmt) Prepare(sql string) error` Parameter binding preprocessing SQL statement. -* `func (stmt *InsertStmt) SetTableName(name string) error` +- `func (stmt *InsertStmt) SetTableName(name string) error` Bind the set table name parameter. -* `func (stmt *InsertStmt) SetSubTableName(name string) error` +- `func (stmt *InsertStmt) SetSubTableName(name string) error` Parameter binding to set the sub table name. -* `func (stmt *InsertStmt) BindParam(params []*param.Param, bindType *param.ColumnType) error` +- `func (stmt *InsertStmt) BindParam(params []*param.Param, bindType *param.ColumnType) error` Parameter bind multiple rows of data. -* `func (stmt *InsertStmt) AddBatch() error` +- `func (stmt *InsertStmt) AddBatch() error` Add to a parameter-bound batch. -* `func (stmt *InsertStmt) Execute() error` +- `func (stmt *InsertStmt) Execute() error` Execute a parameter binding. -* `func (stmt *InsertStmt) GetAffectedRows() int` +- `func (stmt *InsertStmt) GetAffectedRows() int` Gets the number of affected rows inserted by the parameter binding. -* `func (stmt *InsertStmt) Close() error` +- `func (stmt *InsertStmt) Close() error` Closes the parameter binding. diff --git a/docs/examples/.gitignore b/docs/examples/.gitignore index 7ed6d403bf..b50ab6c63b 100644 --- a/docs/examples/.gitignore +++ b/docs/examples/.gitignore @@ -1,3 +1,4 @@ .vscode *.lock -.idea \ No newline at end of file +.idea +.env \ No newline at end of file diff --git a/docs/examples/.gitignre b/docs/examples/.gitignre deleted file mode 100644 index 0853156c65..0000000000 --- a/docs/examples/.gitignre +++ /dev/null @@ -1,2 +0,0 @@ -.vscode -*.lock \ No newline at end of file diff --git a/docs/examples/go/go.mod b/docs/examples/go/go.mod index 5945e395e9..c754753d59 100644 --- a/docs/examples/go/go.mod +++ b/docs/examples/go/go.mod @@ -2,5 +2,5 @@ module goexample go 1.17 -require github.com/taosdata/driver-go/v2 develop +require github.com/taosdata/driver-go/v2 diff --git a/docs/zh/14-reference/03-connector/go.mdx b/docs/zh/14-reference/03-connector/go.mdx index 88b09aa5d0..b65630d9f7 100644 --- a/docs/zh/14-reference/03-connector/go.mdx +++ b/docs/zh/14-reference/03-connector/go.mdx @@ -5,15 +5,15 @@ sidebar_label: Go title: TDengine Go Connector --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; -import Preparition from "./_preparition.mdx" -import GoInsert from "../../07-develop/03-insert-data/_go_sql.mdx" -import GoInfluxLine from "../../07-develop/03-insert-data/_go_line.mdx" -import GoOpenTSDBTelnet from "../../07-develop/03-insert-data/_go_opts_telnet.mdx" -import GoOpenTSDBJson from "../../07-develop/03-insert-data/_go_opts_json.mdx" -import GoQuery from "../../07-develop/04-query-data/_go.mdx" +import Preparition from "./_preparition.mdx"; +import GoInsert from "../../07-develop/03-insert-data/_go_sql.mdx"; +import GoInfluxLine from "../../07-develop/03-insert-data/_go_line.mdx"; +import GoOpenTSDBTelnet from "../../07-develop/03-insert-data/_go_opts_telnet.mdx"; +import GoOpenTSDBJson from "../../07-develop/03-insert-data/_go_opts_json.mdx"; +import GoQuery from "../../07-develop/04-query-data/_go.mdx"; `driver-go` 是 TDengine 的官方 Go 语言连接器,实现了 Go 语言[ database/sql ](https://golang.org/pkg/database/sql/) 包的接口。Go 开发人员可以通过它开发存取 TDengine 集群数据的应用软件。 @@ -38,30 +38,30 @@ REST 连接支持所有能运行 Go 的平台。 “原生连接”指连接器通过 TDengine 客户端驱动(taosc)直接与 TDengine 运行实例建立的连接。支持的功能特性有: -* 普通查询 -* 连续查询 -* 订阅 -* schemaless 接口 -* 参数绑定接口 +- 普通查询 +- 连续查询 +- 订阅 +- schemaless 接口 +- 参数绑定接口 ### REST 连接 "REST 连接"指连接器通过 taosAdapter 组件提供的 REST API 与 TDengine 运行实例建立的连接。支持的功能特性有: -* 普通查询 -* 连续查询 +- 普通查询 +- 连续查询 ## 安装步骤 ### 安装前准备 -* 安装 Go 开发环境(Go 1.14 及以上,GCC 4.8.5 及以上) -* 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动) +- 安装 Go 开发环境(Go 1.14 及以上,GCC 4.8.5 及以上) +- 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动) 配置好环境变量,检查命令: -* ```go env``` -* ```gcc -v``` +- `go env` +- `gcc -v` ### 使用 go get 安装 @@ -71,31 +71,31 @@ REST 连接支持所有能运行 Go 的平台。 1. 使用 `go mod` 命令初始化项目: - ```text - go mod init taos-demo - ``` +```text +go mod init taos-demo +``` 2. 引入 taosSql : - ```go - import ( - "database/sql" - _ "github.com/taosdata/driver-go/v2/taosSql" - ) - ``` +```go +import ( + "database/sql" + _ "github.com/taosdata/driver-go/v2/taosSql" +) +``` 3. 使用 `go mod tidy` 更新依赖包: - ```text - go mod tidy - ``` +```text +go mod tidy +``` 4. 使用 `go run taos-demo` 运行程序或使用 `go build` 命令编译出二进制文件。 - ```text - go run taos-demo - go build - ``` +```text +go run taos-demo +go build +``` ## 建立连接 @@ -103,7 +103,7 @@ REST 连接支持所有能运行 Go 的平台。 数据源名称具有通用格式,例如 [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php),但没有类型前缀(方括号表示可选): -``` text +```text [username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...¶mN=valueN] ``` @@ -112,6 +112,7 @@ REST 连接支持所有能运行 Go 的平台。 ```text username:password@protocol(address)/dbname?param=value ``` + ### 使用连接器进行连接 @@ -121,7 +122,7 @@ _taosSql_ 通过 cgo 实现了 Go 的 `database/sql/driver` 接口。只需要 使用 `taosSql` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`,DSN 支持的参数: -* configPath 指定 taos.cfg 目录 +- configPath 指定 taos.cfg 目录 示例: @@ -152,8 +153,8 @@ _taosRestful_ 通过 `http client` 实现了 Go 的 `database/sql/driver` 接口 使用 `taosRestful` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`,DSN 支持的参数: -* `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。 -* `readBufferSize` 读取数据的缓存区大小默认为 4K(4096),当查询结果数据量多时可以适当调大该值。 +- `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。 +- `readBufferSize` 读取数据的缓存区大小默认为 4K(4096),当查询结果数据量多时可以适当调大该值。 示例: @@ -176,6 +177,7 @@ func main() { } } ``` + @@ -205,8 +207,8 @@ func main() { ### 更多示例程序 -* [示例程序](https://github.com/taosdata/TDengine/tree/develop/examples/go) -* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。 +- [示例程序](https://github.com/taosdata/TDengine/tree/develop/examples/go) +- [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。 ## 使用限制 @@ -266,55 +268,51 @@ func main() { ## 常见问题 -1. 无法找到包 `github.com/taosdata/driver-go/v2/taosRestful` - - 将 `go.mod` 中 require 块对`github.com/taosdata/driver-go/v2`的引用改为`github.com/taosdata/driver-go/v2 develop`,之后执行 `go mod tidy`。 - -2. database/sql 中 stmt(参数绑定)相关接口崩溃 +1. database/sql 中 stmt(参数绑定)相关接口崩溃 - REST 不支持参数绑定相关接口,建议使用`db.Exec`和`db.Query`。 + REST 不支持参数绑定相关接口,建议使用`db.Exec`和`db.Query`。 -3. 使用 `use db` 语句后执行其他语句报错 `[0x217] Database not specified or available` +2. 使用 `use db` 语句后执行其他语句报错 `[0x217] Database not specified or available` - 在 REST 接口中 SQL 语句的执行无上下文关联,使用 `use db` 语句不会生效,解决办法见上方使用限制章节。 + 在 REST 接口中 SQL 语句的执行无上下文关联,使用 `use db` 语句不会生效,解决办法见上方使用限制章节。 -4. 使用 taosSql 不报错使用 taosRestful 报错 `[0x217] Database not specified or available` +3. 使用 taosSql 不报错使用 taosRestful 报错 `[0x217] Database not specified or available` - 因为 REST 接口无状态,使用 `use db` 语句不会生效,解决办法见上方使用限制章节。 + 因为 REST 接口无状态,使用 `use db` 语句不会生效,解决办法见上方使用限制章节。 -5. 升级 `github.com/taosdata/driver-go/v2/taosRestful` +4. 升级 `github.com/taosdata/driver-go/v2/taosRestful` - 将 `go.mod` 文件中对 `github.com/taosdata/driver-go/v2` 的引用改为 `github.com/taosdata/driver-go/v2 develop`,之后执行 `go mod tidy`。 + 将 `go.mod` 文件中对 `github.com/taosdata/driver-go/v2` 的引用改为 `github.com/taosdata/driver-go/v2 develop`,之后执行 `go mod tidy`。 -6. `readBufferSize` 参数调大后无明显效果 +5. `readBufferSize` 参数调大后无明显效果 - `readBufferSize` 调大后会减少获取结果时 `syscall` 的调用。如果查询结果的数据量不大,修改该参数不会带来明显提升,如果该参数修改过大,瓶颈会在解析 JSON 数据。如果需要优化查询速度,需要根据实际情况调整该值来达到查询效果最优。 + `readBufferSize` 调大后会减少获取结果时 `syscall` 的调用。如果查询结果的数据量不大,修改该参数不会带来明显提升,如果该参数修改过大,瓶颈会在解析 JSON 数据。如果需要优化查询速度,需要根据实际情况调整该值来达到查询效果最优。 -7. `disableCompression` 参数设置为 `false` 时查询效率降低 +6. `disableCompression` 参数设置为 `false` 时查询效率降低 - 当 `disableCompression` 参数设置为 `false` 时查询结果会使用 `gzip` 压缩后传输,拿到数据后要先进行 `gzip` 解压。 + 当 `disableCompression` 参数设置为 `false` 时查询结果会使用 `gzip` 压缩后传输,拿到数据后要先进行 `gzip` 解压。 -8. `go get` 命令无法获取包,或者获取包超时 +7. `go get` 命令无法获取包,或者获取包超时 - 设置 Go 代理 `go env -w GOPROXY=https://goproxy.cn,direct`。 + 设置 Go 代理 `go env -w GOPROXY=https://goproxy.cn,direct`。 ## 常用 API ### database/sql API -* `sql.Open(DRIVER_NAME string, dataSourceName string) *DB` +- `sql.Open(DRIVER_NAME string, dataSourceName string) *DB` 该 API 用来打开 DB,返回一个类型为 \*DB 的对象。 -:::info -该 API 成功创建的时候,并没有做权限等检查,只有在真正执行 Query 或者 Exec 的时候才能真正的去创建连接,并同时检查 user/password/host/port 是不是合法。 -::: + :::info + 该 API 成功创建的时候,并没有做权限等检查,只有在真正执行 Query 或者 Exec 的时候才能真正的去创建连接,并同时检查 user/password/host/port 是不是合法。 + ::: -* `func (db *DB) Exec(query string, args ...interface{}) (Result, error)` +- `func (db *DB) Exec(query string, args ...interface{}) (Result, error)` `sql.Open` 内置的方法,用来执行非查询相关 SQL。 -* `func (db *DB) Query(query string, args ...interface{}) (*Rows, error)` +- `func (db *DB) Query(query string, args ...interface{}) (*Rows, error)` `sql.Open` 内置的方法,用来执行查询语句。 @@ -324,85 +322,85 @@ func main() { #### 连接管理 -* `af.Open(host, user, pass, db string, port int) (*Connector, error)` +- `af.Open(host, user, pass, db string, port int) (*Connector, error)` 该 API 通过 cgo 创建与 taosd 的连接。 -* `func (conn *Connector) Close() error` +- `func (conn *Connector) Close() error` 关闭与 taosd 的连接。 #### 订阅 -* `func (conn *Connector) Subscribe(restart bool, topic string, sql string, interval time.Duration) (Subscriber, error)` +- `func (conn *Connector) Subscribe(restart bool, topic string, sql string, interval time.Duration) (Subscriber, error)` 订阅数据。 -* `func (s *taosSubscriber) Consume() (driver.Rows, error)` +- `func (s *taosSubscriber) Consume() (driver.Rows, error)` 消费订阅数据,返回 `database/sql/driver` 包的 `Rows` 结构。 -* `func (s *taosSubscriber) Unsubscribe(keepProgress bool)` +- `func (s *taosSubscriber) Unsubscribe(keepProgress bool)` 取消订阅数据。 #### schemaless -* `func (conn *Connector) InfluxDBInsertLines(lines []string, precision string) error` +- `func (conn *Connector) InfluxDBInsertLines(lines []string, precision string) error` 写入 influxDB 行协议。 -* `func (conn *Connector) OpenTSDBInsertTelnetLines(lines []string) error` +- `func (conn *Connector) OpenTSDBInsertTelnetLines(lines []string) error` 写入 OpenTDSB telnet 协议数据。 -* `func (conn *Connector) OpenTSDBInsertJsonPayload(payload string) error` +- `func (conn *Connector) OpenTSDBInsertJsonPayload(payload string) error` 写入 OpenTSDB JSON 协议数据。 #### 参数绑定 -* `func (conn *Connector) StmtExecute(sql string, params *param.Param) (res driver.Result, err error)` +- `func (conn *Connector) StmtExecute(sql string, params *param.Param) (res driver.Result, err error)` 参数绑定单行插入。 -* `func (conn *Connector) StmtQuery(sql string, params *param.Param) (rows driver.Rows, err error)` +- `func (conn *Connector) StmtQuery(sql string, params *param.Param) (rows driver.Rows, err error)` 参数绑定查询,返回 `database/sql/driver` 包的 `Rows` 结构。 -* `func (conn *Connector) InsertStmt() *insertstmt.InsertStmt` +- `func (conn *Connector) InsertStmt() *insertstmt.InsertStmt` 初始化参数。 -* `func (stmt *InsertStmt) Prepare(sql string) error` +- `func (stmt *InsertStmt) Prepare(sql string) error` 参数绑定预处理 SQL 语句。 -* `func (stmt *InsertStmt) SetTableName(name string) error` +- `func (stmt *InsertStmt) SetTableName(name string) error` 参数绑定设置表名。 -* `func (stmt *InsertStmt) SetSubTableName(name string) error` +- `func (stmt *InsertStmt) SetSubTableName(name string) error` 参数绑定设置子表名。 -* `func (stmt *InsertStmt) BindParam(params []*param.Param, bindType *param.ColumnType) error` +- `func (stmt *InsertStmt) BindParam(params []*param.Param, bindType *param.ColumnType) error` 参数绑定多行数据。 -* `func (stmt *InsertStmt) AddBatch() error` +- `func (stmt *InsertStmt) AddBatch() error` 添加到参数绑定批处理。 -* `func (stmt *InsertStmt) Execute() error` +- `func (stmt *InsertStmt) Execute() error` 执行参数绑定。 -* `func (stmt *InsertStmt) GetAffectedRows() int` +- `func (stmt *InsertStmt) GetAffectedRows() int` 获取参数绑定插入受影响行数。 -* `func (stmt *InsertStmt) Close() error` +- `func (stmt *InsertStmt) Close() error` 结束参数绑定。 -- GitLab From 394fe954a05e7fc96f9f84ed3fefb2e2230c705d Mon Sep 17 00:00:00 2001 From: dingbo Date: Thu, 30 Jun 2022 20:16:59 +0800 Subject: [PATCH 119/380] docs: go connect --- docs/en/14-reference/03-connector/go.mdx | 2 +- docs/examples/go/go.mod | 3 +-- docs/zh/14-reference/03-connector/go.mdx | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/en/14-reference/03-connector/go.mdx b/docs/en/14-reference/03-connector/go.mdx index b641fc0420..69e1b56f38 100644 --- a/docs/en/14-reference/03-connector/go.mdx +++ b/docs/en/14-reference/03-connector/go.mdx @@ -66,7 +66,7 @@ Configure the environment variables and check the command. ### Use go get to install ``` -go get -u github.com/taosdata/driver-go/v2@develop +go get -u github.com/taosdata/driver-go/v2@latest ``` ### Manage with go mod diff --git a/docs/examples/go/go.mod b/docs/examples/go/go.mod index c754753d59..cb1fec0194 100644 --- a/docs/examples/go/go.mod +++ b/docs/examples/go/go.mod @@ -2,5 +2,4 @@ module goexample go 1.17 -require github.com/taosdata/driver-go/v2 - +require github.com/taosdata/driver-go/v2 v2.0.2 diff --git a/docs/zh/14-reference/03-connector/go.mdx b/docs/zh/14-reference/03-connector/go.mdx index b65630d9f7..79ced6f427 100644 --- a/docs/zh/14-reference/03-connector/go.mdx +++ b/docs/zh/14-reference/03-connector/go.mdx @@ -65,7 +65,7 @@ REST 连接支持所有能运行 Go 的平台。 ### 使用 go get 安装 -`go get -u github.com/taosdata/driver-go/v2@develop` +`go get -u github.com/taosdata/driver-go/v2@latest` ### 使用 go mod 管理 -- GitLab From 86e57c9e327bf3462b27a248cb97d5eb7702d378 Mon Sep 17 00:00:00 2001 From: BoDing Date: Thu, 30 Jun 2022 21:39:36 +0800 Subject: [PATCH 120/380] test: user driver-go v2 latest --- docs/en/07-develop/01-connect/index.md | 6 +----- docs/examples/go/go.mod | 2 +- docs/zh/07-develop/01-connect/index.md | 6 +----- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/docs/en/07-develop/01-connect/index.md b/docs/en/07-develop/01-connect/index.md index 720f8e2384..df793f6d3f 100644 --- a/docs/en/07-develop/01-connect/index.md +++ b/docs/en/07-develop/01-connect/index.md @@ -98,11 +98,7 @@ pip install git+https://github.com/taosdata/taos-connector-python.git Just need to add `driver-go` dependency in `go.mod` . ```go-mod title=go.mod -module goexample - -go 1.17 - -require github.com/taosdata/driver-go/v2 develop +{{#include docs/examples/go/go.mod}} ``` :::note diff --git a/docs/examples/go/go.mod b/docs/examples/go/go.mod index cb1fec0194..b0f6fbcd50 100644 --- a/docs/examples/go/go.mod +++ b/docs/examples/go/go.mod @@ -2,4 +2,4 @@ module goexample go 1.17 -require github.com/taosdata/driver-go/v2 v2.0.2 +require github.com/taosdata/driver-go/v2 latest diff --git a/docs/zh/07-develop/01-connect/index.md b/docs/zh/07-develop/01-connect/index.md index b1857b9739..a56577e2be 100644 --- a/docs/zh/07-develop/01-connect/index.md +++ b/docs/zh/07-develop/01-connect/index.md @@ -99,11 +99,7 @@ pip install git+https://github.com/taosdata/taos-connector-python.git 编辑 `go.mod` 添加 `driver-go` 依赖即可。 ```go-mod title=go.mod -module goexample - -go 1.17 - -require github.com/taosdata/driver-go/v2 develop +{{#include docs/examples/go/go.mod}} ``` :::note -- GitLab From d5c4d5d5f8c34fe751da76732c8c001dbadae5b0 Mon Sep 17 00:00:00 2001 From: Bo Ding Date: Mon, 4 Jul 2022 11:13:13 +0800 Subject: [PATCH 121/380] fix: masters number in log.dnodes_info --- src/plugins/monitor/src/monMain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/monitor/src/monMain.c b/src/plugins/monitor/src/monMain.c index bd0e015205..6af0d2bf0a 100644 --- a/src/plugins/monitor/src/monMain.c +++ b/src/plugins/monitor/src/monMain.c @@ -637,7 +637,7 @@ static int32_t monBuildMasterUptimeSql(char *sql) { for (int i = 0; i < num_fields; ++i) { if (strcmp(fields[i].name, "role") == 0) { int32_t charLen = monGetRowElemCharLen(fields[i], (char *)row[i]); - if (strncmp((char *)row[i], "master", charLen) == 0) { + if (strncmp((char *)row[i], "leader", charLen) == 0) { if (strcmp(fields[i + 1].name, "role_time") == 0) { int64_t now = taosGetTimestamp(TSDB_TIME_PRECISION_MILLI); //master uptime in seconds @@ -957,7 +957,7 @@ static int32_t monBuildDnodeVnodesSql(char *sql) { for (int i = 0; i < num_fields; ++i) { if (strcmp(fields[i].name, "status") == 0) { int32_t charLen = monGetRowElemCharLen(fields[i], (char *)row[i]); - if (strncmp((char *)row[i], "master", charLen) == 0) { + if (strncmp((char *)row[i], "leader", charLen) == 0) { masterNum += 1; } } @@ -992,7 +992,7 @@ static int32_t monBuildDnodeMnodeSql(char *sql) { } } else if (strcmp(fields[i].name, "role") == 0) { charLen = monGetRowElemCharLen(fields[i], (char *)row[i]); - if (strncmp((char *)row[i], "master", charLen) == 0) { + if (strncmp((char *)row[i], "leader", charLen) == 0) { if (has_mnode_row) { monHasMnodeMaster = true; } -- GitLab From a3b7f35496f5fe677762f19643f2206ff524203c Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 4 Jul 2022 20:38:18 +0800 Subject: [PATCH 122/380] chore: update taos tools for2.6 (#14516) * chore(release): make get_os.sh works on mac * chore(tools): update taos-tools for 2.6 * chore: update taos-tools for 2.6 [TD-16450] --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 5fdd694621..1163c0f60a 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 5fdd694621fbb7bd2d6102ff4feaec92a7001038 +Subproject commit 1163c0f60aa65d6cc58283247c8bf8c56ba43b92 -- GitLab From 3d5fcf79495dcca644217b2f8a828a1f200a1aaa Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 6 Jul 2022 18:14:57 +0800 Subject: [PATCH 123/380] chore: update taos-tools (#14563) * chore: update taos-tools for 2.6 * test: change taosbenchmark test cases * fix: outdated test cases * fix: query/nestedQuery/nestedQuery.py * fix: update taos-tools Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- .../taosbenchmark/insert_alltypes_json.py | 4 +- .../taosbenchmark/limit_offset_json.py | 2 - tests/pytest/query/nestedQuery/nestedQuery.py | 4 +- .../TD-5213/insertSigcolumnsNum4096.py | 8 +- .../insert4096columns_not_use_taosdemo.py | 706 ------------------ .../TD-5213/insertSigcolumnsNum4096.csv | 3 - .../TD-5213/insertSigcolumnsNum4096.json | 137 ---- .../TD-5213/insertSigcolumnsNum4096.py | 176 ----- 9 files changed, 8 insertions(+), 1034 deletions(-) delete mode 100644 tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insert4096columns_not_use_taosdemo.py delete mode 100755 tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv delete mode 100755 tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.json delete mode 100755 tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.py diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 1163c0f60a..46a71144a8 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 1163c0f60aa65d6cc58283247c8bf8c56ba43b92 +Subproject commit 46a71144a85e5eed9160304830f235cb28bc4895 diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py b/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py index 5239d1b5fb..c86d5300f5 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py +++ b/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py @@ -117,8 +117,6 @@ class TDTestCase: tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from db.stb where c13 = 'b1' or c13 = 'b2'") tdSql.checkData(0, 0, 160) - tdSql.query("select count(*) from db.stb where t0 >= 0 and t0 <= 10") - tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from db.stb where t1 >= 0 and t1 <= 10") tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from db.stb where t2 >= 0 and t2 <= 10") @@ -326,4 +324,4 @@ class TDTestCase: tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/limit_offset_json.py b/tests/develop-test/5-taos-tools/taosbenchmark/limit_offset_json.py index b7f3fcd826..e2160f3c9c 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/limit_offset_json.py +++ b/tests/develop-test/5-taos-tools/taosbenchmark/limit_offset_json.py @@ -79,8 +79,6 @@ class TDTestCase: tdSql.checkData(0, 0, 8) tdSql.query("select count(*) from db.stb") tdSql.checkData(0, 0, 40) - tdSql.query("select distinct(c1) from db.stb") - tdSql.checkData(0, 0, None) tdSql.query("select distinct(c3) from db.stb") tdSql.checkData(0, 0, None) tdSql.query("select distinct(c4) from db.stb") diff --git a/tests/pytest/query/nestedQuery/nestedQuery.py b/tests/pytest/query/nestedQuery/nestedQuery.py index 89751bb7b8..9f9f56660c 100755 --- a/tests/pytest/query/nestedQuery/nestedQuery.py +++ b/tests/pytest/query/nestedQuery/nestedQuery.py @@ -2233,10 +2233,10 @@ class TDTestCase: sql = "select * from ( select ts , " for i in range(4094): sql += "c%d , " % (i) - sql += "c4094 from d0 " + sql += "c4094 from d0 " sql += " %s )" % random.choice(order_where) sql += " %s ;" % random.choice(order_desc_where) - tdLog.info(len(sql)) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkCols(4096) tdSql.checkRows(1000) diff --git a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py index c047e4b0aa..667b859c8f 100755 --- a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py +++ b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py @@ -56,18 +56,18 @@ class TDTestCase: tdSql.execute("use regular_old") tdSql.query("show tables;") tdSql.checkRows(1) - tdSql.query("select * from d0;") + tdSql.query("select * from meters;") tdSql.checkCols(1024) - tdSql.query("describe d0;") + tdSql.query("describe meters;") tdSql.checkRows(1024) os.system("%s -N -d regular_new -t 1 -n 10 -l 4095 -y" % binPath) tdSql.execute("use regular_new") tdSql.query("show tables;") tdSql.checkRows(1) - tdSql.query("select * from d0;") + tdSql.query("select * from meters;") tdSql.checkCols(4096) - tdSql.query("describe d0;") + tdSql.query("describe meters;") tdSql.checkRows(4096) # super table -d:database name -t:table num -n:rows num per table diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insert4096columns_not_use_taosdemo.py b/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insert4096columns_not_use_taosdemo.py deleted file mode 100644 index ec55acb848..0000000000 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insert4096columns_not_use_taosdemo.py +++ /dev/null @@ -1,706 +0,0 @@ -################################################################### -# 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 -*- - -import random -import string -import os -import time -from util.log import tdLog -from util.cases import tdCases -from util.sql import tdSql -from util.dnodes import tdDnodes - -class TDTestCase: - updatecfgDict={'maxSQLLength':1048576} - def init(self, conn, logSql): - tdLog.debug("start to execute %s" % __file__) - tdSql.init(conn.cursor(), logSql) - - os.system("rm -rf tools/taosdemoAllTest/TD-5213/insert4096columns_not_use_taosdemo.py.sql") - - now = time.time() - self.ts = int(round(now * 1000)) - self.num = 100 - - def get_random_string(self, length): - letters = string.ascii_lowercase - result_str = ''.join(random.choice(letters) for i in range(length)) - return result_str - - def run(self): - tdSql.prepare() - # test case for https://jira.taosdata.com:18080/browse/TD-5213 - - print("==============step1, regular table, 1 ts + 4094 cols + 1 binary==============") - startTime = time.time() - sql = "create table regular_table_1(ts timestamp, " - for i in range(4094): - sql += "col%d int, " % (i + 1) - sql += "col4095 binary(22))" - tdLog.info(len(sql)) - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into regular_table_1 values(%d, " - for j in range(4094): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_1") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from regular_table_1") - tdSql.checkRows(self.num) - tdSql.checkCols(4096) - - endTime = time.time() - print("total time %ds" % (endTime - startTime)) - - #insert in order - tdLog.info('test insert in order') - for i in range(self.num): - sql = "insert into regular_table_1 (ts,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col4095) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 1000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_1") - tdSql.checkData(0, 0, 2*self.num) - tdSql.query("select * from regular_table_1") - tdSql.checkRows(2*self.num) - tdSql.checkCols(4096) - - #insert out of order - tdLog.info('test insert out of order') - for i in range(self.num): - sql = "insert into regular_table_1 (ts,col123,col2213,col331,col41,col523,col236,col71,col813,col912,col1320,col4095) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 2000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_1") - tdSql.checkData(0, 0, 3*self.num) - tdSql.query("select * from regular_table_1") - tdSql.checkRows(3*self.num) - tdSql.checkCols(4096) - - - print("==============step2,regular table error col or value==============") - tdLog.info('test regular table exceeds row num') - # column > 4096 - sql = "create table regular_table_2(ts timestamp, " - for i in range(4095): - sql += "col%d int, " % (i + 1) - sql += "col4096 binary(22))" - tdLog.info(len(sql)) - tdSql.error(sql) - - # column > 4096 - sql = "insert into regular_table_1 values(%d, " - for j in range(4095): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.error(sql) - - # insert column < 4096 - sql = "insert into regular_table_1 values(%d, " - for j in range(4092): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.error(sql) - - # alter column > 4096 - sql = "alter table regular_table_1 add column max int; " - tdSql.error(sql) - - print("==============step3,regular table , mix data type==============") - startTime = time.time() - sql = "create table regular_table_3(ts timestamp, " - for i in range(2000): - sql += "col%d int, " % (i + 1) - for i in range(2000,4094): - sql += "col%d bigint, " % (i + 1) - sql += "col4095 binary(22))" - tdLog.info(len(sql)) - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into regular_table_3 values(%d, " - for j in range(4094): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_3") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from regular_table_3") - tdSql.checkRows(self.num) - tdSql.checkCols(4096) - - endTime = time.time() - print("total time %ds" % (endTime - startTime)) - - sql = "create table regular_table_4(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(4), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(10), " % (i + 1) - for i in range(4090,4094): - sql += "timestamp_%d timestamp, " % (i + 1) - sql += "col4095 binary(22))" - tdLog.info(len(sql)) - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into regular_table_4 values(%d, " - for j in range(500): - str = "'%s', " % random.randint(-2147483647,2147483647) - sql += str - for j in range(500,1000): - str = "'%s', " % random.randint(-32767,32767 ) - sql += str - for j in range(1000,1500): - str = "'%s', " % random.randint(-127,127) - sql += str - for j in range(1500,2000): - str = "'%s', " % random.randint(-922337203685477580700,922337203685477580700) - sql += str - for j in range(2000,2500): - str = "'%s', " % random.randint(-92233720368547758070,92233720368547758070) - sql += str - for j in range(2500,3000): - str = "'%s', " % random.choice(['true','false']) - sql += str - for j in range(3000,3500): - str = "'%s', " % random.randint(-9223372036854775807,9223372036854775807) - sql += str - for j in range(3500,3800): - str = "'%s', " % self.get_random_string(4) - sql += str - for j in range(3800,4090): - str = "'%s', " % self.get_random_string(10) - sql += str - for j in range(4090,4094): - str = "%s, " % (self.ts + j) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_4") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from regular_table_4") - tdSql.checkRows(self.num) - tdSql.checkCols(4096) - tdLog.info("end ,now new one") - - #insert null value - tdLog.info('test insert null value') - for i in range(self.num): - sql = "insert into regular_table_4 values(%d, " - for j in range(2500): - str = "'%s', " % random.choice(['NULL' ,'NULL' ,'NULL' ,1 , 10 ,100 ,-100 ,-10, 88 ,66 ,'NULL' ,'NULL' ,'NULL' ]) - sql += str - for j in range(2500,3000): - str = "'%s', " % random.choice(['true' ,'false']) - sql += str - for j in range(3000,3500): - str = "'%s', " % random.randint(-9223372036854775807,9223372036854775807) - sql += str - for j in range(3500,3800): - str = "'%s', " % self.get_random_string(4) - sql += str - for j in range(3800,4090): - str = "'%s', " % self.get_random_string(10) - sql += str - for j in range(4090,4094): - str = "%s, " % (self.ts + j) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 10000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_4") - tdSql.checkData(0, 0, 2*self.num) - tdSql.query("select * from regular_table_4") - tdSql.checkRows(2*self.num) - tdSql.checkCols(4096) - - #insert in order - tdLog.info('test insert in order') - for i in range(self.num): - sql = "insert into regular_table_4 (ts,int_2,int_22,int_169,smallint_537,smallint_607,tinyint_1030,tinyint_1491,double_1629,double_1808,float_2075,col4095) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,100) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 1000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_4") - tdSql.checkData(0, 0, 3*self.num) - tdSql.query("select * from regular_table_4") - tdSql.checkRows(3*self.num) - tdSql.checkCols(4096) - - #insert out of order - tdLog.info('test insert out of order') - for i in range(self.num): - sql = "insert into regular_table_4 (ts,int_169,float_2075,int_369,tinyint_1491,tinyint_1030,float_2360,smallint_537,double_1808,double_1608,double_1629,col4095) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,100) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 2000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_4") - tdSql.checkData(0, 0, 4*self.num) - tdSql.query("select * from regular_table_4") - tdSql.checkRows(4*self.num) - tdSql.checkCols(4096) - - #define TSDB_MAX_BYTES_PER_ROW 49151[old:1024 && 16384] - #ts:8\int:4\smallint:2\bigint:8\bool:1\float:4\tinyint:1\nchar:4*()+2[offset]\binary:1*()+2[offset] - tdLog.info('test regular_table max bytes per row 49151') - sql = "create table regular_table_5(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(20), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(34), " % (i + 1) - for i in range(4090,4094): - sql += "timestamp_%d timestamp, " % (i + 1) - sql += "col4095 binary(69))" - tdSql.execute(sql) - tdSql.query("select * from regular_table_5") - tdSql.checkCols(4096) - # TD-5324 - sql = "alter table regular_table_5 modify column col4095 binary(70); " - tdSql.error(sql) - - # drop and add - sql = "alter table regular_table_5 drop column col4095; " - tdSql.execute(sql) - sql = "select * from regular_table_5; " - tdSql.query(sql) - tdSql.checkCols(4095) - sql = "alter table regular_table_5 add column col4095 binary(70); " - tdSql.error(sql) - sql = "alter table regular_table_5 add column col4095 binary(69); " - tdSql.execute(sql) - sql = "select * from regular_table_5; " - tdSql.query(sql) - tdSql.checkCols(4096) - - #out TSDB_MAX_BYTES_PER_ROW 49151 - tdLog.info('test regular_table max bytes per row out 49151') - sql = "create table regular_table_6(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(20), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(34), " % (i + 1) - for i in range(4090,4094): - sql += "timestamp_%d timestamp, " % (i + 1) - sql += "col4095 binary(70))" - tdLog.info(len(sql)) - tdSql.error(sql) - - - print("==============step4, super table , 1 ts + 4090 cols + 4 tags ==============") - startTime = time.time() - sql = "create stable stable_1(ts timestamp, " - for i in range(4090): - sql += "col%d int, " % (i + 1) - sql += "col4091 binary(22))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdLog.info(len(sql)) - tdSql.execute(sql) - sql = '''create table table_0 using stable_1 - tags('table_0' , '1' , '2' , '3' );''' - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into table_0 values(%d, " - for j in range(4090): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from table_0") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from table_0") - tdSql.checkRows(self.num) - tdSql.checkCols(4092) - - sql = '''create table table_1 using stable_1 - tags('table_1' , '1' , '2' , '3' );''' - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into table_1 values(%d, " - for j in range(2080): - sql += "'%d', " % random.randint(0,1000) - for j in range(2080,4080): - sql += "'%s', " % 'NULL' - for j in range(4080,4090): - sql += "'%s', " % random.randint(0,10000) - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from table_1") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from table_1") - tdSql.checkRows(self.num) - tdSql.checkCols(4092) - - endTime = time.time() - print("total time %ds" % (endTime - startTime)) - - #insert in order - tdLog.info('test insert in order') - for i in range(self.num): - sql = "insert into table_1 (ts,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col4091) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 1000)) - time.sleep(1) - tdSql.query("select count(*) from table_1") - tdSql.checkData(0, 0, 2*self.num) - tdSql.query("select * from table_1") - tdSql.checkRows(2*self.num) - tdSql.checkCols(4092) - - #insert out of order - tdLog.info('test insert out of order') - for i in range(self.num): - sql = "insert into table_1 (ts,col123,col2213,col331,col41,col523,col236,col71,col813,col912,col1320,col4091) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 2000)) - time.sleep(1) - tdSql.query("select count(*) from table_1") - tdSql.checkData(0, 0, 3*self.num) - tdSql.query("select * from table_1") - tdSql.checkRows(3*self.num) - tdSql.checkCols(4092) - - print("==============step5,stable table , mix data type==============") - sql = "create stable stable_3(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(4), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(10), " % (i + 1) - sql += "col4091 binary(22))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdLog.info(len(sql)) - tdSql.execute(sql) - sql = '''create table table_30 using stable_3 - tags('table_30' , '1' , '2' , '3' );''' - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into table_30 values(%d, " - for j in range(500): - str = "'%s', " % random.randint(-2147483647,2147483647) - sql += str - for j in range(500,1000): - str = "'%s', " % random.randint(-32767,32767 ) - sql += str - for j in range(1000,1500): - str = "'%s', " % random.randint(-127,127) - sql += str - for j in range(1500,2000): - str = "'%s', " % random.randint(-922337203685477580700,922337203685477580700) - sql += str - for j in range(2000,2500): - str = "'%s', " % random.randint(-92233720368547758070,92233720368547758070) - sql += str - for j in range(2500,3000): - str = "'%s', " % random.choice(['true','false']) - sql += str - for j in range(3000,3500): - str = "'%s', " % random.randint(-9223372036854775807,9223372036854775807) - sql += str - for j in range(3500,3800): - str = "'%s', " % self.get_random_string(4) - sql += str - for j in range(3800,4090): - str = "'%s', " % self.get_random_string(10) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from table_30") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from table_30") - tdSql.checkRows(self.num) - tdSql.checkCols(4092) - - #insert null value - tdLog.info('test insert null value') - sql = '''create table table_31 using stable_3 - tags('table_31' , '1' , '2' , '3' );''' - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into table_31 values(%d, " - for j in range(2500): - str = "'%s', " % random.choice(['NULL' ,'NULL' ,'NULL' ,1 , 10 ,100 ,-100 ,-10, 88 ,66 ,'NULL' ,'NULL' ,'NULL' ]) - sql += str - for j in range(2500,3000): - str = "'%s', " % random.choice(['true' ,'false']) - sql += str - for j in range(3000,3500): - str = "'%s', " % random.randint(-9223372036854775807,9223372036854775807) - sql += str - for j in range(3500,3800): - str = "'%s', " % self.get_random_string(4) - sql += str - for j in range(3800,4090): - str = "'%s', " % self.get_random_string(10) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from table_31") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from table_31") - tdSql.checkRows(self.num) - tdSql.checkCols(4092) - - #insert in order - tdLog.info('test insert in order') - for i in range(self.num): - sql = "insert into table_31 (ts,int_2,int_22,int_169,smallint_537,smallint_607,tinyint_1030,tinyint_1491,double_1629,double_1808,float_2075,col4091) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,100) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 1000)) - time.sleep(1) - tdSql.query("select count(*) from table_31") - tdSql.checkData(0, 0, 2*self.num) - tdSql.query("select * from table_31") - tdSql.checkRows(2*self.num) - tdSql.checkCols(4092) - - #insert out of order - tdLog.info('test insert out of order') - for i in range(self.num): - sql = "insert into table_31 (ts,int_169,float_2075,int_369,tinyint_1491,tinyint_1030,float_2360,smallint_537,double_1808,double_1608,double_1629,col4091) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,100) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 2000)) - time.sleep(1) - tdSql.query("select count(*) from table_31") - tdSql.checkData(0, 0, 3*self.num) - tdSql.query("select * from table_31") - tdSql.checkRows(3*self.num) - tdSql.checkCols(4092) - - #define TSDB_MAX_BYTES_PER_ROW 49151 TSDB_MAX_TAGS_LEN 16384 - #ts:8\int:4\smallint:2\bigint:8\bool:1\float:4\tinyint:1\nchar:4*()+2[offset]\binary:1*()+2[offset] - tdLog.info('test super table max bytes per row 49151') - sql = "create table stable_4(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(20), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(34), " % (i + 1) - sql += "col4091 binary(101))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdSql.execute(sql) - sql = '''create table table_40 using stable_4 - tags('table_40' , '1' , '2' , '3' );''' - tdSql.execute(sql) - tdSql.query("select * from table_40") - tdSql.checkCols(4092) - tdSql.query("describe table_40") - tdSql.checkRows(4096) - - tdLog.info('test super table drop and add column or tag') - sql = "alter stable stable_4 drop column col4091; " - tdSql.execute(sql) - sql = "select * from stable_4; " - tdSql.query(sql) - tdSql.checkCols(4095) - sql = "alter table stable_4 add column col4091 binary(102); " - tdSql.error(sql) - sql = "alter table stable_4 add column col4091 binary(101); " - tdSql.execute(sql) - sql = "select * from stable_4; " - tdSql.query(sql) - tdSql.checkCols(4096) - - sql = "alter stable stable_4 drop tag tag_1; " - tdSql.execute(sql) - sql = "select * from stable_4; " - tdSql.query(sql) - tdSql.checkCols(4095) - sql = "alter table stable_4 add tag tag_1 int; " - tdSql.execute(sql) - sql = "select * from stable_4; " - tdSql.query(sql) - tdSql.checkCols(4096) - sql = "alter table stable_4 add tag loc1 nchar(10); " - tdSql.error(sql) - - tdLog.info('test super table max bytes per row 49151') - sql = "create table stable_5(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(20), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(34), " % (i + 1) - sql += "col4091 binary(102))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdSql.error(sql) - - print("==============step6, super table error col ==============") - tdLog.info('test exceeds row num') - # column + tag > 4096 - sql = "create stable stable_2(ts timestamp, " - for i in range(4091): - sql += "col%d int, " % (i + 1) - sql += "col4092 binary(22))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdLog.info(len(sql)) - tdSql.error(sql) - - # column + tag > 4096 - sql = "create stable stable_2(ts timestamp, " - for i in range(4090): - sql += "col%d int, " % (i + 1) - sql += "col4091 binary(22))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int,tag_4 int) " - tdLog.info(len(sql)) - tdSql.error(sql) - - # alter column + tag > 4096 - sql = "alter table stable_1 add column max int; " - tdSql.error(sql) - # TD-5322 - sql = "alter table stable_1 add tag max int; " - tdSql.error(sql) - # TD-5324 - sql = "alter table stable_4 modify column col4091 binary(102); " - tdSql.error(sql) - sql = "alter table stable_4 modify tag loc nchar(20); " - tdSql.query("select * from table_40") - tdSql.checkCols(4092) - tdSql.query("describe table_40") - tdSql.checkRows(4096) - - - - - def stop(self): - tdSql.close() - tdLog.success("%s successfully executed" % __file__) - - -tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv b/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv deleted file mode 100755 index 5b30be5b4c..0000000000 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv +++ /dev/null @@ -1,3 +0,0 @@ -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438, 2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2449, 2450, 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, 2494, 2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2527, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, 2544, 2545, 2546, 2547, 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, 2583, 2584, 2585, 2586, 2587, 2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595, 2596, 2597, 2598, 2599, 2600, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2634, 2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643, 2644, 2645, 2646, 2647, 2648, 2649, 2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, 2715, 2716, 2717, 2718, 2719, 2720, 2721, 2722, 2723, 2724, 2725, 2726, 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734, 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, 2768, 2769, 2770, 2771, 2772, 2773, 2774, 2775, 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826, 2827, 2828, 2829, 2830, 2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887, 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, 2941, 2942, 2943, 2944, 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, 2963, 2964, 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999, 3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043, 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3077, 3078, 3079, 3080, 3081, 3082, 3083, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, 3095, 3096, 3097, 3098, 3099, 3100, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111, 3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, 3143, 3144, 3145, 3146, 3147, 3148, 3149, 3150, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183, 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213, 3214, 3215, 3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, 3238, 3239, 3240, 3241, 3242, 3243, 3244, 3245, 3246, 3247, 3248, 3249, 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3304, 3305, 3306, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357, 3358, 3359, 3360, 3361, 3362, 3363, 3364, 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, 3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438, 3439, 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, 3455, 3456, 3457, 3458, 3459, 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469, 3470, 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3478, 3479, 3480, 3481, 3482, 3483, 3484, 3485, 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494, 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518, 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532, 3533, 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, 3553, 3554, 3555, 3556, 3557, 3558, 3559, 3560, 3561, 3562, 3563, 3564, 3565, 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574, 3575, 3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680, 3681, 3682, 3683, 3684, 3685, 3686, 3687, 3688, 3689, 3690, 3691, 3692, 3693, 3694, 3695, 3696, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, 3705, 3706, 3707, 3708, 3709, 3710, 3711, 3712, 3713, 3714, 3715, 3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723, 3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3744, 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835, 3836, 3837, 3838, 3839, 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894, 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3904, 3905, 3906, 3907, 3908, 3909, 3910, 3911, 3912, 3913, 3914, 3915, 3916, 3917, 3918, 3919, 3920, 3921, 3922, 3923, 3924, 3925, 3926, 3927, 3928, 3929, 3930, 3931, 3932, 3933, 3934, 3935, 3936, 3937, 3938, 3939, 3940, 3941, 3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949, 3950, 3951, 3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, 3970, 3971, 3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979, 3980, 3981, 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, 3990, 3991, 3992, 3993, 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091 -1,2,3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL -1,2,3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,NULL,NULL,5,NULL,NULL,6,NULL,NULL,NULL,7,NULL,NULL,NULL,8,NULL,NULL,NULL,9,NULL,NULL,10 \ No newline at end of file diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.json deleted file mode 100755 index d7225dfd12..0000000000 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "filetype": "insert", - "cfgdir": "/etc/taos", - "host": "127.0.0.1", - "port": 6030, - "user": "root", - "password": "taosdata", - "thread_count": 10, - "thread_count_create_tbl": 10, - "result_file": "./insert_res.txt", - "confirm_parameter_prompt": "no", - "insert_interval": 0, - "interlace_rows": 10, - "num_of_records_per_req": 1, - "max_sql_len": 102400000, - "databases": [{ - "dbinfo": { - "name": "json_test", - "drop": "yes", - "replica": 1, - "days": 10, - "cache": 50, - "blocks": 8, - "precision": "ms", - "keep": 36500, - "minRows": 100, - "maxRows": 4096, - "comp":2, - "walLevel":1, - "cachelast":0, - "quorum":1, - "fsync":3000, - "update": 0 - }, - "super_tables": [{ - "name": "stb_old", - "child_table_exists":"no", - "childtable_count": 2, - "childtable_prefix": "stb_old_", - "auto_create_table": "no", - "batch_create_tbl_num": 5, - "data_source": "rand", - "insert_mode": "taosc", - "insert_rows": 2, - "childtable_limit": 0, - "childtable_offset":0, - "multi_thread_write_one_tbl": "no", - "interlace_rows": 0, - "insert_interval":0, - "max_sql_len": 1024000, - "disorder_ratio": 0, - "disorder_range": 1000, - "timestamp_step": 1, - "start_timestamp": "2020-10-01 00:00:00.000", - "sample_format": "csv", - "sample_file": "./5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv", - "tags_file": "", - "columns": [{"type": "INT","count":1000}, {"type": "BINARY", "len": 16, "count":20}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}] - },{ - "name": "stb_new", - "child_table_exists":"no", - "childtable_count": 2, - "childtable_prefix": "stb_new_", - "auto_create_table": "no", - "batch_create_tbl_num": 5, - "data_source": "rand", - "insert_mode": "taosc", - "insert_rows": 2, - "childtable_limit": 0, - "childtable_offset":0, - "multi_thread_write_one_tbl": "no", - "interlace_rows": 0, - "insert_interval":0, - "max_sql_len": 1024000, - "disorder_ratio": 0, - "disorder_range": 1000, - "timestamp_step": 1, - "start_timestamp": "2020-10-01 00:00:00.000", - "sample_format": "csv", - "sample_file": "./5-taos-tools/taosbenchmark/sample.csv", - "tags_file": "", - "columns": [{"type": "INT","count":4000}, {"type": "BINARY", "len": 16, "count":90}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":3}] - },{ - "name": "stb_mix", - "child_table_exists":"no", - "childtable_count": 2, - "childtable_prefix": "stb_mix_", - "auto_create_table": "no", - "batch_create_tbl_num": 5, - "data_source": "rand", - "insert_mode": "taosc", - "insert_rows": 2, - "childtable_limit": 0, - "childtable_offset":0, - "multi_thread_write_one_tbl": "no", - "interlace_rows": 0, - "insert_interval":0, - "max_sql_len": 1024000, - "disorder_ratio": 0, - "disorder_range": 1000, - "timestamp_step": 1, - "start_timestamp": "2020-10-01 00:00:00.000", - "sample_format": "csv", - "sample_file": "./5-taos-tools/taosbenchmark/sample.csv", - "tags_file": "", - "columns": [{"type": "INT","count":500},{"type": "SMALLINT","count":500},{"type": "TINYINT","count":500},{"type": "DOUBLE","count":500},{"type": "FLOAT","count":500},{"type": "BOOL","count":500},{"type": "BIGINT","count":500},{"type": "NCHAR","len": 20,"count":300},{"type": "BINARY","len": 34,"count":290},{"type": "BINARY","len": 101,"count":1}], - "tags": [{"type": "INT", "count":3}, {"type": "NCHAR", "len": 10, "count":1}] - },{ - "name": "stb_excel", - "child_table_exists":"no", - "childtable_count": 2, - "childtable_prefix": "stb_excel_", - "auto_create_table": "no", - "batch_create_tbl_num": 5, - "data_source": "sample", - "insert_mode": "taosc", - "insert_rows": 2, - "childtable_limit": 0, - "childtable_offset":0, - "multi_thread_write_one_tbl": "no", - "interlace_rows": 0, - "insert_interval":0, - "max_sql_len": 1024000, - "disorder_ratio": 0, - "disorder_range": 1000, - "timestamp_step": 1, - "start_timestamp": "2020-10-01 00:00:00.000", - "sample_format": "csv", - "sample_file": "./5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv", - "tags_file": "", - "columns": [{"type": "INT","count":500},{"type": "SMALLINT","count":500},{"type": "SMALLINT","count":500},{"type": "DOUBLE","count":500},{"type": "FLOAT","count":500},{"type": "BOOL","count":500},{"type": "BIGINT","count":500},{"type": "NCHAR","len": 19,"count":300},{"type": "BINARY","len": 34,"count":290},{"type": "BINARY","len": 101,"count":1}], - "tags": [{"type": "INT", "count":3}, {"type": "NCHAR", "len": 10, "count":1}] - }] - }] -} diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.py b/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.py deleted file mode 100755 index 56b51f5498..0000000000 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.py +++ /dev/null @@ -1,176 +0,0 @@ -################################################################### -# 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 -*- - -import sys -import os -import time -from util.log import * -from util.cases import * -from util.sql import * -from util.dnodes import * - - -class TDTestCase: - def init(self, conn, logSql): - tdLog.debug("start to execute %s" % __file__) - tdSql.init(conn.cursor(), logSql) - - def getBuildPath(self): - selfPath = os.path.dirname(os.path.realpath(__file__)) - - if ("community" in selfPath): - projPath = selfPath[:selfPath.find("community")] - else: - projPath = selfPath[:selfPath.find("tests")] - - for root, dirs, files in os.walk(projPath): - if ("taosd" in files): - rootRealPath = os.path.dirname(os.path.realpath(root)) - if ("packaging" not in rootRealPath): - buildPath = root[:len(root)-len("/build/bin")] - break - return buildPath - - def run(self): - buildPath = self.getBuildPath() - if (buildPath == ""): - tdLog.exit("taosd not found!") - else: - tdLog.info("taosd found in %s" % buildPath) - binPath = buildPath+ "/build/bin/" - - #-N:regular table -d:database name -t:table num -n:rows num per table -l:col num -y:force - #regular old && new - startTime = time.time() - os.system("%staosBenchmark -N -d regular_old -t 1 -n 10 -l 1023 -y" % binPath) - tdSql.execute("use regular_old") - tdSql.query("show tables;") - tdSql.checkRows(1) - tdSql.query("select * from d0;") - tdSql.checkCols(1024) - tdSql.query("describe d0;") - tdSql.checkRows(1024) - - os.system("%staosBenchmark -N -d regular_new -t 1 -n 10 -l 4095 -y" % binPath) - tdSql.execute("use regular_new") - tdSql.query("show tables;") - tdSql.checkRows(1) - tdSql.query("select * from d0;") - tdSql.checkCols(4096) - tdSql.query("describe d0;") - tdSql.checkRows(4096) - - #super table -d:database name -t:table num -n:rows num per table -l:col num -y:force - os.system("%staosBenchmark -d super_old -t 1 -n 10 -l 1021 -y" % binPath) - tdSql.execute("use super_old") - tdSql.query("show tables;") - tdSql.checkRows(1) - tdSql.query("select * from meters;") - tdSql.checkCols(1024) - tdSql.query("select * from d0;") - tdSql.checkCols(1022) - tdSql.query("describe meters;") - tdSql.checkRows(1024) - tdSql.query("describe d0;") - tdSql.checkRows(1024) - - os.system("%staosBenchmark -d super_new -t 1 -n 10 -l 4093 -y" % binPath) - tdSql.execute("use super_new") - tdSql.query("show tables;") - tdSql.checkRows(1) - tdSql.query("select * from meters;") - tdSql.checkCols(4096) - tdSql.query("select * from d0;") - tdSql.checkCols(4094) - tdSql.query("describe meters;") - tdSql.checkRows(4096) - tdSql.query("describe d0;") - tdSql.checkRows(4096) - tdSql.execute("create table stb_new1_1 using meters tags(1,2)") - tdSql.query("select * from stb_new1_1") - tdSql.checkCols(4094) - tdSql.query("describe stb_new1_1;") - tdSql.checkRows(4096) - - # insert: create one or mutiple tables per sql and insert multiple rows per sql - # test case for https://jira.taosdata.com:18080/browse/TD-5213 - os.system("%staosBenchmark -f tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json -y " % binPath) - tdSql.execute("use json_test") - tdSql.query("select count (tbname) from stb_old") - tdSql.checkData(0, 0, 1) - - tdSql.query("select * from stb_old") - tdSql.checkRows(10) - tdSql.checkCols(1024) - - tdSql.query("select count (tbname) from stb_new") - tdSql.checkData(0, 0, 1) - - tdSql.query("select * from stb_new") - tdSql.checkRows(10) - tdSql.checkCols(4096) - tdSql.query("describe stb_new;") - tdSql.checkRows(4096) - tdSql.query("select * from stb_new_0") - tdSql.checkRows(10) - tdSql.checkCols(4091) - tdSql.query("describe stb_new_0;") - tdSql.checkRows(4096) - tdSql.execute("create table stb_new1_1 using stb_new tags(1,2,3,4,5)") - tdSql.query("select * from stb_new1_1") - tdSql.checkCols(4091) - tdSql.query("describe stb_new1_1;") - tdSql.checkRows(4096) - - tdSql.query("select count (tbname) from stb_mix") - tdSql.checkData(0, 0, 1) - - tdSql.query("select * from stb_mix") - tdSql.checkRows(10) - tdSql.checkCols(4096) - tdSql.query("describe stb_mix;") - tdSql.checkRows(4096) - tdSql.query("select * from stb_mix_0") - tdSql.checkRows(10) - tdSql.checkCols(4092) - tdSql.query("describe stb_mix_0;") - tdSql.checkRows(4096) - - tdSql.query("select count (tbname) from stb_excel") - tdSql.checkData(0, 0, 1) - - tdSql.query("select * from stb_excel") - tdSql.checkRows(10) - tdSql.checkCols(4096) - tdSql.query("describe stb_excel;") - tdSql.checkRows(4096) - tdSql.query("select * from stb_excel_0") - tdSql.checkRows(10) - tdSql.checkCols(4092) - tdSql.query("describe stb_excel_0;") - tdSql.checkRows(4096) - endTime = time.time() - print("total time %ds" % (endTime - startTime)) - - - os.system("rm -rf tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py.sql") - - - - def stop(self): - tdSql.close() - tdLog.success("%s successfully executed" % __file__) - - -tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) -- GitLab From 809a9112ddc4f22cf98aa22d69312cff34363131 Mon Sep 17 00:00:00 2001 From: "xywang@taosdata.com" Date: Wed, 6 Jul 2022 19:47:15 +0800 Subject: [PATCH 124/380] fix: fixed compilation errors produced by old gcc version --- deps/TSZ/sz/src/CompressElement.c | 6 +- deps/TSZ/sz/src/Huffman.c | 12 +- deps/TSZ/sz/src/TightDataPointStorageD.c | 46 +- deps/TSZ/sz/src/TightDataPointStorageF.c | 46 +- deps/cJson/src/cJSON.c | 12 +- src/client/src/tscGlobalmerge.c | 10 +- src/client/src/tscLocal.c | 16 +- src/client/src/tscParseInsert.c | 158 +++--- src/client/src/tscParseLineProtocol.c | 56 +- src/client/src/tscParseOpenTSDB.c | 44 +- src/client/src/tscPrepare.c | 116 ++--- src/client/src/tscSQLParser.c | 636 +++++++++++------------ src/client/src/tscServer.c | 32 +- src/client/src/tscSubquery.c | 80 +-- src/client/src/tscSystem.c | 28 +- src/client/src/tscUtil.c | 74 +-- src/common/src/tarithoperator.c | 130 ++--- src/common/src/tdataformat.c | 6 +- src/common/src/tglobal.c | 8 +- src/common/src/tname.c | 16 +- src/common/src/ttypes.c | 16 +- src/dnode/src/dnodeCheck.c | 26 +- src/dnode/src/dnodePeer.c | 48 +- src/dnode/src/dnodeShell.c | 28 +- src/kit/shell/src/shellImport.c | 4 +- src/mnode/src/mnodeCluster.c | 6 +- src/mnode/src/mnodeMnode.c | 36 +- src/mnode/src/mnodeSdb.c | 24 +- src/os/src/detail/osDir.c | 4 +- src/os/src/detail/osFile.c | 12 +- src/os/src/detail/osTime.c | 62 +-- src/os/src/linux/osSystem.c | 4 +- src/query/src/qAggMain.c | 70 +-- src/query/src/qExecutor.c | 88 ++-- src/query/src/qExtbuffer.c | 26 +- src/query/src/qFill.c | 26 +- src/query/src/qFilter.c | 30 +- src/query/src/qHistogram.c | 36 +- src/query/src/qPercentile.c | 62 +-- src/query/src/qPlan.c | 6 +- src/query/src/qSqlParser.c | 12 +- src/query/src/qUtil.c | 6 +- src/query/src/queryMain.c | 6 +- src/rpc/src/rpcCache.c | 24 +- src/rpc/src/rpcTcp.c | 16 +- src/rpc/src/rpcUdp.c | 10 +- src/rpc/test/rclient.c | 48 +- src/rpc/test/rsclient.c | 48 +- src/rpc/test/rserver.c | 34 +- src/sync/src/syncMain.c | 110 ++-- src/sync/src/syncRetrieve.c | 14 +- src/tsdb/src/tsdbCommit.c | 8 +- src/tsdb/src/tsdbFS.c | 8 +- src/tsdb/src/tsdbMain.c | 18 +- src/tsdb/src/tsdbMeta.c | 36 +- src/tsdb/src/tsdbRead.c | 20 +- src/util/src/hash.c | 6 +- src/util/src/tarray.c | 36 +- src/util/src/tcache.c | 8 +- src/util/src/tcompare.c | 4 +- src/util/src/tmempool.c | 12 +- src/util/src/tnettest.c | 30 +- src/util/src/tref.c | 6 +- src/vnode/src/vnodeMain.c | 6 +- src/vnode/src/vnodeSync.c | 4 +- src/wal/test/waltest.c | 8 +- tests/tsim/src/simExe.c | 4 +- tests/tsim/src/simParse.c | 10 +- tests/tsim/src/simSystem.c | 4 +- 69 files changed, 1354 insertions(+), 1348 deletions(-) diff --git a/deps/TSZ/sz/src/CompressElement.c b/deps/TSZ/sz/src/CompressElement.c index b71ff9638e..a215a3aebc 100644 --- a/deps/TSZ/sz/src/CompressElement.c +++ b/deps/TSZ/sz/src/CompressElement.c @@ -7,7 +7,9 @@ * See COPYRIGHT in top-level directory. */ #ifndef WINDOWS +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push +#endif #pragma GCC diagnostic ignored "-Wchar-subscripts" #endif @@ -233,5 +235,7 @@ INLINE void updateLossyCompElement_Float(unsigned char* diffBytes, unsigned char } #ifndef WINDOWS +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop -#endif \ No newline at end of file +#endif +#endif diff --git a/deps/TSZ/sz/src/Huffman.c b/deps/TSZ/sz/src/Huffman.c index 9868f3c0cb..6db8b15d1f 100644 --- a/deps/TSZ/sz/src/Huffman.c +++ b/deps/TSZ/sz/src/Huffman.c @@ -117,7 +117,7 @@ node qremove(HuffmanTree* huffmanTree) /** * @out1 should be set to 0. * @out2 should be 0 as well. - * @index: the index of the byte + * @idx: the idx of the byte * */ void build_code(HuffmanTree *huffmanTree, node n, int len, unsigned long out1, unsigned long out2) { @@ -136,8 +136,8 @@ void build_code(HuffmanTree *huffmanTree, node n, int len, unsigned long out1, u huffmanTree->cout[n->c] = (unsigned char)len; return; } - int index = len >> 6; //=len/64 - if(index == 0) + int idx = len >> 6; //=len/64 + if(idx == 0) { out1 = out1 << 1; out1 = out1 | 0; @@ -164,13 +164,13 @@ void build_code(HuffmanTree *huffmanTree, node n, int len, unsigned long out1, u * */ void init(HuffmanTree* huffmanTree, int *s, size_t length) { - size_t i, index; + size_t i, idx; size_t *freq = (size_t *)malloc(huffmanTree->allNodes*sizeof(size_t)); memset(freq, 0, huffmanTree->allNodes*sizeof(size_t)); for(i = 0;i < length;i++) { - index = s[i]; - freq[index]++; + idx = s[i]; + freq[idx]++; } for (i = 0; i < huffmanTree->allNodes; i++) diff --git a/deps/TSZ/sz/src/TightDataPointStorageD.c b/deps/TSZ/sz/src/TightDataPointStorageD.c index 469a1bdce9..e1a2af9c04 100644 --- a/deps/TSZ/sz/src/TightDataPointStorageD.c +++ b/deps/TSZ/sz/src/TightDataPointStorageD.c @@ -25,9 +25,9 @@ void new_TightDataPointStorageD_Empty(TightDataPointStorageD **this) int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsigned char* flatBytes, size_t flatBytesLength, sz_exedata* pde_exe, sz_params* pde_params) { new_TightDataPointStorageD_Empty(this); - size_t i, index = 0; - unsigned char version = flatBytes[index++]; //3 - unsigned char sameRByte = flatBytes[index++]; //1 + size_t i, idx = 0; + unsigned char version = flatBytes[idx++]; //3 + unsigned char sameRByte = flatBytes[idx++]; //1 // parse data format switch (version) @@ -46,15 +46,15 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi pde_params->accelerate_pw_rel_compression = (sameRByte & 0x08) >> 3; int errorBoundMode = SZ_ABS; - convertBytesToSZParams(&(flatBytes[index]), pde_params, pde_exe); + convertBytesToSZParams(&(flatBytes[idx]), pde_params, pde_exe); - index += MetaDataByteLength_double; + idx += MetaDataByteLength_double; int isRegression = (sameRByte >> 7) & 0x01; unsigned char dsLengthBytes[8]; for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - dsLengthBytes[i] = flatBytes[index++]; + dsLengthBytes[i] = flatBytes[idx++]; (*this)->dataSeriesLength = bytesToSize(dsLengthBytes, pde_exe->SZ_SIZE_TYPE); if((*this)->isLossless==1) @@ -65,7 +65,7 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi else if(same==1) { (*this)->allSameData = 1; - (*this)->exactMidBytes = &(flatBytes[index]); + (*this)->exactMidBytes = &(flatBytes[idx]); return errorBoundMode; } else @@ -74,42 +74,42 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi if(isRegression == 1) { (*this)->raBytes_size = flatBytesLength - 3 - 1 - MetaDataByteLength_double - pde_exe->SZ_SIZE_TYPE; - (*this)->raBytes = &(flatBytes[index]); + (*this)->raBytes = &(flatBytes[idx]); return errorBoundMode; } unsigned char byteBuf[8]; for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; int max_quant_intervals = bytesToInt_bigEndian(byteBuf);// 4 pde_params->maxRangeRadius = max_quant_intervals/2; for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->intervals = bytesToInt_bigEndian(byteBuf);// 4 for (i = 0; i < 8; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->medianValue = bytesToDouble(byteBuf);//8 - (*this)->reqLength = flatBytes[index++]; //1 + (*this)->reqLength = flatBytes[idx++]; //1 for (i = 0; i < 8; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->realPrecision = bytesToDouble(byteBuf);//8 for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->typeArray_size = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE); for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->exactDataNum = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// ST for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->exactMidBytes_size = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// ST size_t logicLeadNumBitsNum = (*this)->exactDataNum * 2; @@ -122,12 +122,12 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi (*this)->leadNumArray_size = (logicLeadNumBitsNum >> 3) + 1; } - (*this)->typeArray = &flatBytes[index]; + (*this)->typeArray = &flatBytes[idx]; //retrieve the number of states (i.e., stateNum) (*this)->allNodes = bytesToInt_bigEndian((*this)->typeArray); //the first 4 bytes store the stateNum (*this)->stateNum = ((*this)->allNodes+1)/2; - index+=(*this)->typeArray_size; + idx+=(*this)->typeArray_size; // todo need check length @@ -135,15 +135,15 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi - pde_exe->SZ_SIZE_TYPE - pde_exe->SZ_SIZE_TYPE - pde_exe->SZ_SIZE_TYPE - (*this)->leadNumArray_size - (*this)->exactMidBytes_size - (*this)->typeArray_size; - (*this)->leadNumArray = &flatBytes[index]; + (*this)->leadNumArray = &flatBytes[idx]; - index+=(*this)->leadNumArray_size; + idx+=(*this)->leadNumArray_size; - (*this)->exactMidBytes = &flatBytes[index]; + (*this)->exactMidBytes = &flatBytes[idx]; - index+=(*this)->exactMidBytes_size; + idx+=(*this)->exactMidBytes_size; - (*this)->residualMidBits = &flatBytes[index]; + (*this)->residualMidBits = &flatBytes[idx]; return errorBoundMode; diff --git a/deps/TSZ/sz/src/TightDataPointStorageF.c b/deps/TSZ/sz/src/TightDataPointStorageF.c index cb1d79b827..16d524b9b4 100644 --- a/deps/TSZ/sz/src/TightDataPointStorageF.c +++ b/deps/TSZ/sz/src/TightDataPointStorageF.c @@ -25,15 +25,15 @@ void new_TightDataPointStorageF_Empty(TightDataPointStorageF **this) int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsigned char* flatBytes, size_t flatBytesLength, sz_exedata* pde_exe, sz_params* pde_params) { new_TightDataPointStorageF_Empty(this); - size_t i, index = 0; + size_t i, idx = 0; // // parse tdps // // 1 version(1) - unsigned char version = flatBytes[index++]; //1 - unsigned char sameRByte = flatBytes[index++]; //1 + unsigned char version = flatBytes[idx++]; //1 + unsigned char sameRByte = flatBytes[idx++]; //1 // parse data format switch (version) @@ -51,12 +51,12 @@ int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsi pde_exe->SZ_SIZE_TYPE = ((sameRByte & 0x40)>>6)==1?8:4; //0100,0000 int errorBoundMode = SZ_ABS; // 3 meta(2) - convertBytesToSZParams(&(flatBytes[index]), pde_params, pde_exe); - index += MetaDataByteLength; + convertBytesToSZParams(&(flatBytes[idx]), pde_params, pde_exe); + idx += MetaDataByteLength; // 4 element count(4) unsigned char dsLengthBytes[8]; for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - dsLengthBytes[i] = flatBytes[index++]; + dsLengthBytes[i] = flatBytes[idx++]; (*this)->dataSeriesLength = bytesToSize(dsLengthBytes, pde_exe->SZ_SIZE_TYPE);// 4 or 8 if((*this)->isLossless==1) { @@ -66,7 +66,7 @@ int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsi else if(same==1) { (*this)->allSameData = 1; - (*this)->exactMidBytes = &(flatBytes[index]); + (*this)->exactMidBytes = &(flatBytes[idx]); return errorBoundMode; } else @@ -76,40 +76,40 @@ int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsi if(isRegression == 1) { (*this)->raBytes_size = flatBytesLength - 1 - 1 - MetaDataByteLength - pde_exe->SZ_SIZE_TYPE; - (*this)->raBytes = &(flatBytes[index]); + (*this)->raBytes = &(flatBytes[idx]); return errorBoundMode; } // 5 quant intervals(4) unsigned char byteBuf[8]; for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; int max_quant_intervals = bytesToInt_bigEndian(byteBuf);// 4 pde_params->maxRangeRadius = max_quant_intervals/2; // 6 intervals for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->intervals = bytesToInt_bigEndian(byteBuf);// 4 // 7 median for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->medianValue = bytesToFloat(byteBuf); //4 // 8 reqLength - (*this)->reqLength = flatBytes[index++]; //1 + (*this)->reqLength = flatBytes[idx++]; //1 // 9 realPrecision(8) for (i = 0; i < 8; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->realPrecision = bytesToDouble(byteBuf);//8 // 10 typeArray_size for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->typeArray_size = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// 4 // 11 exactNum for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->exactDataNum = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// ST // 12 mid size for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->exactMidBytes_size = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// STqq // calc leadNumArray_size @@ -124,20 +124,20 @@ int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsi } // 13 typeArray - (*this)->typeArray = &flatBytes[index]; + (*this)->typeArray = &flatBytes[idx]; //retrieve the number of states (i.e., stateNum) (*this)->allNodes = bytesToInt_bigEndian((*this)->typeArray); //the first 4 bytes store the stateNum (*this)->stateNum = ((*this)->allNodes+1)/2; - index+=(*this)->typeArray_size; + idx+=(*this)->typeArray_size; // 14 leadNumArray - (*this)->leadNumArray = &flatBytes[index]; - index += (*this)->leadNumArray_size; + (*this)->leadNumArray = &flatBytes[idx]; + idx += (*this)->leadNumArray_size; // 15 exactMidBytes - (*this)->exactMidBytes = &flatBytes[index]; - index+=(*this)->exactMidBytes_size; + (*this)->exactMidBytes = &flatBytes[idx]; + idx+=(*this)->exactMidBytes_size; // 16 residualMidBits - (*this)->residualMidBits = &flatBytes[index]; + (*this)->residualMidBits = &flatBytes[idx]; // calc residualMidBits_size (*this)->residualMidBits_size = flatBytesLength - 1 - 1 - MetaDataByteLength - pde_exe->SZ_SIZE_TYPE - 4 - 4 - 4 - 1 - 8 diff --git a/deps/cJson/src/cJSON.c b/deps/cJson/src/cJSON.c index ff93e8730d..53698b5baf 100644 --- a/deps/cJson/src/cJSON.c +++ b/deps/cJson/src/cJSON.c @@ -1683,7 +1683,7 @@ CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) return (int)size; } -static cJSON* get_array_item(const cJSON *array, size_t index) +static cJSON* get_array_item(const cJSON *array, size_t idx) { cJSON *current_child = NULL; @@ -1693,23 +1693,23 @@ static cJSON* get_array_item(const cJSON *array, size_t index) } current_child = array->child; - while ((current_child != NULL) && (index > 0)) + while ((current_child != NULL) && (idx > 0)) { - index--; + idx--; current_child = current_child->next; } return current_child; } -CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int idx) { - if (index < 0) + if (idx < 0) { return NULL; } - return get_array_item(array, (size_t)index); + return get_array_item(array, (size_t)idx); } static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) diff --git a/src/client/src/tscGlobalmerge.c b/src/client/src/tscGlobalmerge.c index b8d47022b4..f5acfb68d1 100644 --- a/src/client/src/tscGlobalmerge.c +++ b/src/client/src/tscGlobalmerge.c @@ -33,12 +33,12 @@ typedef struct SCompareParam { int32_t groupOrderType; } SCompareParam; -static bool needToMerge(SSDataBlock* pBlock, SArray* columnIndexList, int32_t index, char **buf) { +static bool needToMerge(SSDataBlock* pBlock, SArray* columnIndexList, int32_t idx, char **buf) { int32_t ret = 0; size_t size = taosArrayGetSize(columnIndexList); if (size > 0) { - ret = compare_aRv(pBlock, columnIndexList, (int32_t) size, index, buf, TSDB_ORDER_ASC); + ret = compare_aRv(pBlock, columnIndexList, (int32_t) size, idx, buf, TSDB_ORDER_ASC); } // if ret == 0, means the result belongs to the same group @@ -563,9 +563,9 @@ static void savePrevOrderColumns(char** prevRow, SArray* pColumnList, SSDataBloc int32_t size = (int32_t) taosArrayGetSize(pColumnList); for(int32_t i = 0; i < size; ++i) { - SColIndex* index = taosArrayGet(pColumnList, i); - SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, index->colIndex); - assert(index->colId == pColInfo->info.colId); + SColIndex* idx = taosArrayGet(pColumnList, i); + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, idx->colIndex); + assert(idx->colId == pColInfo->info.colId); memcpy(prevRow[i], pColInfo->pData + pColInfo->info.bytes * rowIndex, pColInfo->info.bytes); } diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index 39cbd6789f..cda3b0a50a 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -152,7 +152,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, int32_t typeColLength, int32_t noteColLength) { int32_t rowLen = 0; - SColumnIndex index = {0}; + SColumnIndex idx = {0, 0}; pSql->cmd.numOfCols = numOfCols; @@ -163,7 +163,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Field", sizeof(f.name)); SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false); rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE); @@ -173,7 +173,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Type", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), -1000, typeColLength, false); rowLen += typeColLength + VARSTR_HEADER_SIZE; @@ -183,7 +183,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Length", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_INT, sizeof(int32_t), -1000, sizeof(int32_t), false); rowLen += sizeof(int32_t); @@ -193,7 +193,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Note", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), -1000, noteColLength, false); rowLen += noteColLength + VARSTR_HEADER_SIZE; @@ -415,7 +415,7 @@ static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) { static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const char *ddl) { int32_t rowLen = 0; int16_t ddlLen = (int16_t)strlen(ddl); - SColumnIndex index = {0}; + SColumnIndex idx = {0}; pSql->cmd.numOfCols = 2; SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); @@ -433,7 +433,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); rowLen += f.bytes; @@ -446,7 +446,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, (int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false); rowLen += ddlLen + VARSTR_HEADER_SIZE; diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index ad209839bb..38aee8a678 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -61,8 +61,8 @@ int initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, SParsedDataColIn return TSDB_CODE_SUCCESS; } -int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int16_t timePrec) { - int32_t index = 0; +int tsParseTime(SStrToken *pToken, int64_t *pTime, char **next, char *err, int16_t timePrec) { + int32_t idx = 0; SStrToken sToken; int64_t interval; int64_t useconds = 0; @@ -80,8 +80,8 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 useconds = taosStr2int64(pToken->z); } else { // strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm); - if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { - return tscInvalidOperationMsg(error, "invalid timestamp format", pToken->z); + if (taosParseTime(pToken->z, pTime, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { + return tscInvalidOperationMsg(err, "invalid timestamp format", pToken->z); } return TSDB_CODE_SUCCESS; @@ -91,7 +91,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 if (isspace(pToken->z[k])) continue; if (pToken->z[k] == ',') { *next = pTokenEnd; - *time = useconds; + *pTime = useconds; return 0; } @@ -103,17 +103,17 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 * e.g., now+12a, now-5h */ SStrToken valueToken; - index = 0; - sToken = tStrGetToken(pTokenEnd, &index, false); - pTokenEnd += index; + idx = 0; + sToken = tStrGetToken(pTokenEnd, &idx, false); + pTokenEnd += idx; if (sToken.type == TK_MINUS || sToken.type == TK_PLUS) { - index = 0; - valueToken = tStrGetToken(pTokenEnd, &index, false); - pTokenEnd += index; + idx = 0; + valueToken = tStrGetToken(pTokenEnd, &idx, false); + pTokenEnd += idx; if (valueToken.n < 2) { - return tscInvalidOperationMsg(error, "value expected in timestamp", sToken.z); + return tscInvalidOperationMsg(err, "value expected in timestamp", sToken.z); } char unit = 0; @@ -130,7 +130,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 *next = pTokenEnd; } - *time = useconds; + *pTime = useconds; return TSDB_CODE_SUCCESS; } @@ -433,7 +433,7 @@ int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start) { int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, int32_t *len, char *tmpTokenBuf, SInsertStatementParam *pInsertParam) { - int32_t index = 0; + int32_t idx = 0; SStrToken sToken = {0}; char *row = pDataBlocks->pData + pDataBlocks->size; // skip the SSubmitBlk header @@ -455,9 +455,9 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i SSchema *pSchema = &schema[colIndex]; // get colId here - index = 0; - sToken = tStrGetToken(*str, &index, true); - *str += index; + idx = 0; + sToken = tStrGetToken(*str, &idx, true); + *str += idx; if (sToken.type == TK_QUESTION) { if (!isParseBindParam) { @@ -564,7 +564,7 @@ int32_t boundIdxCompar(const void *lhs, const void *rhs) { int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SInsertStatementParam *pInsertParam, int32_t* numOfRows, char *tmpTokenBuf) { - int32_t index = 0; + int32_t idx = 0; int32_t code = 0; (*numOfRows) = 0; @@ -584,11 +584,11 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SIn pDataBlock->rowBuilder.rowSize = extendedRowSize; while (1) { - index = 0; - sToken = tStrGetToken(*str, &index, false); + idx = 0; + sToken = tStrGetToken(*str, &idx, false); if (sToken.n == 0 || sToken.type != TK_LP) break; - *str += index; + *str += idx; if ((*numOfRows) >= maxRows || pDataBlock->size + extendedRowSize >= pDataBlock->nAllocSize) { int32_t tSize; code = tscAllocateMemIfNeed(pDataBlock, extendedRowSize, &tSize); @@ -609,13 +609,13 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SIn pDataBlock->size += len; - index = 0; - sToken = tStrGetToken(*str, &index, false); + idx = 0; + sToken = tStrGetToken(*str, &idx, false); if (sToken.n == 0 || sToken.type != TK_RP) { return tscSQLSyntaxErrMsg(pInsertParam->msg, ") expected", *str); } - *str += index; + *str += idx; (*numOfRows)++; } @@ -876,7 +876,7 @@ int validateTableName(char *tblName, int len, SStrToken* psTblToken, bool *dbInc static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundColumn) { - int32_t index = 0; + int32_t idx = 0; SStrToken sToken = {0}; SStrToken tableToken = {0}; int32_t code = TSDB_CODE_SUCCESS; @@ -891,14 +891,14 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC char *sql = *sqlstr; // get the token of specified table - index = 0; - tableToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + tableToken = tStrGetToken(sql, &idx, false); + sql += idx; // skip possibly exists column list - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; int32_t numOfColList = 0; @@ -907,8 +907,8 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC *boundColumn = &sToken.z[0]; while (1) { - index = 0; - sToken = tStrGetToken(sql, &index, false); + idx = 0; + sToken = tStrGetToken(sql, &idx, false); if (sToken.type == TK_ILLEGAL) { return tscSQLSyntaxErrMsg(pCmd->payload, "unrecognized token", sToken.z); @@ -918,12 +918,12 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC break; } - sql += index; + sql += idx; ++numOfColList; } - sToken = tStrGetToken(sql, &index, false); - sql += index; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; } if (numOfColList == 0 && (*boundColumn) != NULL) { @@ -933,9 +933,9 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX); if (sToken.type == TK_USING) { // create table if not exists according to the super table - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; if (sToken.type == TK_ILLEGAL) { return tscSQLSyntaxErrMsg(pCmd->payload, NULL, sql); @@ -980,8 +980,8 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC SParsedDataColInfo spd = {0}; tscSetBoundColumnInfo(&spd, pTagSchema, tscGetNumOfTags(pSTableMetaInfo->pTableMeta)); - index = 0; - sToken = tStrGetToken(sql, &index, false); + idx = 0; + sToken = tStrGetToken(sql, &idx, false); if (sToken.type != TK_TAGS && sToken.type != TK_LP) { tscDestroyBoundColumnInfo(&spd); return tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword TAGS expected", sToken.z); @@ -1002,16 +1002,16 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC sql = end; - index = 0; // keywords of "TAGS" - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; // keywords of "TAGS" + sToken = tStrGetToken(sql, &idx, false); + sql += idx; } else { - sql += index; + sql += idx; } - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; if (sToken.type != TK_LP) { tscDestroyBoundColumnInfo(&spd); @@ -1027,9 +1027,9 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC for (int i = 0; i < spd.numOfBound; ++i) { SSchema* pSchema = &pTagSchema[spd.boundedColumns[i]]; - index = 0; - sToken = tStrGetToken(sql, &index, true); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, true); + sql += idx; if (TK_ILLEGAL == sToken.type) { tdDestroyKVRowBuilder(&kvRowBuilder); @@ -1101,9 +1101,9 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC free(row); pInsertParam->tagData.data = pTag; - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; if (sToken.n == 0 || sToken.type != TK_RP) { return tscSQLSyntaxErrMsg(pInsertParam->msg, ") expected", sToken.z); } @@ -1112,9 +1112,9 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC * insert into table_name using super_table(tag_name1, tag_name2) tags(tag_val1, tag_val2) * (normal_col1, normal_col2) values(normal_col1_val, normal_col2_val); * */ - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; int numOfColsAfterTags = 0; if (sToken.type == TK_LP) { if (*boundColumn != NULL) { @@ -1124,18 +1124,18 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } while (1) { - index = 0; - sToken = tStrGetToken(sql, &index, false); + idx = 0; + sToken = tStrGetToken(sql, &idx, false); if (sToken.type == TK_RP) { break; } - if (sToken.n == 0 || sToken.type == TK_SEMI || index == 0) { + if (sToken.n == 0 || sToken.type == TK_SEMI || idx == 0) { return tscSQLSyntaxErrMsg(pCmd->payload, "unexpected token", sql); } - sql += index; + sql += idx; ++numOfColsAfterTags; } @@ -1143,7 +1143,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } - sToken = tStrGetToken(sql, &index, false); + sToken = tStrGetToken(sql, &idx, false); } sql = sToken.z; @@ -1213,9 +1213,9 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat int32_t code = TSDB_CODE_SUCCESS; - int32_t index = 0; - SStrToken sToken = tStrGetToken(str, &index, false); - str += index; + int32_t idx = 0; + SStrToken sToken = tStrGetToken(str, &idx, false); + str += idx; if (sToken.type != TK_LP) { code = tscSQLSyntaxErrMsg(pInsertParam->msg, "( is expected", sToken.z); @@ -1225,9 +1225,9 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat bool isOrdered = true; int32_t lastColIdx = -1; // last column found while (1) { - index = 0; - sToken = tStrGetToken(str, &index, false); - str += index; + idx = 0; + sToken = tStrGetToken(str, &idx, false); + str += idx; char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // used for deleting Escape character backstick(`) strncpy(tmpTokenBuf, sToken.z, sToken.n); @@ -1404,8 +1404,8 @@ int tsParseInsertSql(SSqlObj *pSql) { tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pInsertParam->pTableBlockHashList); while (1) { - int32_t index = 0; - SStrToken sToken = tStrGetToken(str, &index, false); + int32_t idx = 0; + SStrToken sToken = tStrGetToken(str, &idx, false); // no data in the sql string anymore. if (sToken.n == 0) { @@ -1469,9 +1469,9 @@ int tsParseInsertSql(SSqlObj *pSql) { goto _clean; } - index = 0; - sToken = tStrGetToken(str, &index, false); - str += index; + idx = 0; + sToken = tStrGetToken(str, &idx, false); + str += idx; if (sToken.n == 0 || (sToken.type != TK_FILE && sToken.type != TK_VALUES)) { code = tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword VALUES or FILE required", sToken.z); @@ -1484,13 +1484,13 @@ int tsParseInsertSql(SSqlObj *pSql) { goto _clean; } - index = 0; - sToken = tStrGetToken(str, &index, false); + idx = 0; + sToken = tStrGetToken(str, &idx, false); if (sToken.type != TK_STRING && sToken.type != TK_ID) { code = tscSQLSyntaxErrMsg(pInsertParam->msg, "file path is required following keyword FILE", sToken.z); goto _clean; } - str += index; + str += idx; if (sToken.n == 0) { code = tscSQLSyntaxErrMsg(pInsertParam->msg, "file path is required following keyword FILE", sToken.z); goto _clean; @@ -1590,7 +1590,7 @@ int tsInsertInitialCheck(SSqlObj *pSql) { return TSDB_CODE_TSC_NO_WRITE_AUTH; } - int32_t index = 0; + int32_t idx = 0; SSqlCmd *pCmd = &pSql->cmd; pCmd->count = 0; @@ -1600,12 +1600,12 @@ int tsInsertInitialCheck(SSqlObj *pSql) { SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd); TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT); - SStrToken sToken = tStrGetToken(pSql->sqlstr, &index, false); + SStrToken sToken = tStrGetToken(pSql->sqlstr, &idx, false); if (sToken.type != TK_INSERT && sToken.type != TK_IMPORT) { return tscSQLSyntaxErrMsg(pInsertParam->msg, NULL, sToken.z); } - sToken = tStrGetToken(pSql->sqlstr, &index, false); + sToken = tStrGetToken(pSql->sqlstr, &idx, false); if (sToken.type != TK_INTO) { return tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword INTO is expected", sToken.z); } diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index 66280c32e8..8a1eb88e93 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -1966,14 +1966,14 @@ int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value, return TSDB_CODE_SUCCESS; } -static int32_t parseSmlTimeStamp(TAOS_SML_KV **pTS, const char **index, SSmlLinesInfo* info) { +static int32_t parseSmlTimeStamp(TAOS_SML_KV **pTS, const char **idx, SSmlLinesInfo* info) { const char *start, *cur; int32_t ret = TSDB_CODE_SUCCESS; int len = 0; char key[] = "ts"; char *value = NULL; - start = cur = *index; + start = cur = *idx; *pTS = calloc(1, sizeof(TAOS_SML_KV)); while(*cur != '\0') { @@ -2013,8 +2013,8 @@ bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlLinesInfo* info) { return false; } -static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash, SSmlLinesInfo* info) { - const char *cur = *index; +static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **idx, SHashObj *pHash, SSmlLinesInfo* info) { + const char *cur = *idx; char key[TSDB_COL_NAME_LEN + 1]; // +1 to avoid key[len] over write int16_t len = 0; @@ -2048,12 +2048,12 @@ static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash memcpy(pKV->key, key, len + 1); addEscapeCharToString(pKV->key, len); tscDebug("SML:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); - *index = cur + 1; + *idx = cur + 1; return TSDB_CODE_SUCCESS; } -static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, +static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, bool *is_last_kv, SSmlLinesInfo* info, bool isTag) { const char *start, *cur; int32_t ret = TSDB_CODE_SUCCESS; @@ -2077,7 +2077,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, val_rqoute } val_state; - start = cur = *index; + start = cur = *idx; tag_state = tag_common; val_state = val_common; @@ -2100,17 +2100,17 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, } if (*cur == '"') { - if (cur == *index) { + if (cur == *idx) { tag_state = tag_lqoute; } cur += 1; len += 1; break; } else if (*cur == 'L') { - line_len = strlen(*index); + line_len = strlen(*idx); /* common character at the end */ - if (cur + 1 >= *index + line_len) { + if (cur + 1 >= *idx + line_len) { *is_last_kv = true; kv_done = true; break; @@ -2118,7 +2118,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, if (*(cur + 1) == '"') { /* string starts here */ - if (cur + 1 == *index + 1) { + if (cur + 1 == *idx + 1) { tag_state = tag_lqoute; } cur += 2; @@ -2224,7 +2224,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, } if (*cur == '"') { - if (cur == *index) { + if (cur == *idx) { val_state = val_lqoute; } else { if (*(cur - 1) != '\\') { @@ -2238,10 +2238,10 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, len += 1; break; } else if (*cur == 'L') { - line_len = strlen(*index); + line_len = strlen(*idx); /* common character at the end */ - if (cur + 1 >= *index + line_len) { + if (cur + 1 >= *idx + line_len) { *is_last_kv = true; kv_done = true; break; @@ -2249,13 +2249,13 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, if (*(cur + 1) == '"') { /* string starts here */ - if (cur + 1 == *index + 1) { + if (cur + 1 == *idx + 1) { val_state = val_lqoute; cur += 2; len += 2; } else { /* MUST at the end of string */ - if (cur + 2 >= *index + line_len) { + if (cur + 2 >= *idx + line_len) { cur += 2; len += 2; *is_last_kv = true; @@ -2385,7 +2385,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, } free(value); - *index = (*cur == '\0') ? cur : cur + 1; + *idx = (*cur == '\0') ? cur : cur + 1; return ret; error: @@ -2395,9 +2395,9 @@ error: return ret; } -static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index, +static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **idx, uint8_t *has_tags, SSmlLinesInfo* info) { - const char *cur = *index; + const char *cur = *idx; int16_t len = 0; pSml->stableName = calloc(TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE, 1); @@ -2441,7 +2441,7 @@ static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } addEscapeCharToString(pSml->stableName, len); - *index = cur + 1; + *idx = cur + 1; tscDebug("SML:0x%"PRIx64" Stable name in measurement:%s|len:%d", info->id, pSml->stableName, len); return TSDB_CODE_SUCCESS; @@ -2464,10 +2464,10 @@ int32_t isValidChildTableName(const char *pTbName, int16_t len, SSmlLinesInfo* i static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs, - const char **index, bool isField, + const char **idx, bool isField, TAOS_SML_DATA_POINT* smlData, SHashObj *pHash, SSmlLinesInfo* info) { - const char *cur = *index; + const char *cur = *idx; int32_t ret = TSDB_CODE_SUCCESS; TAOS_SML_KV *pkv; bool is_last_kv = false; @@ -2555,7 +2555,7 @@ static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs, error: return ret; done: - *index = cur; + *idx = cur; return ret; } @@ -2575,13 +2575,13 @@ static void moveTimeStampToFirstKv(TAOS_SML_DATA_POINT** smlData, TAOS_SML_KV *t } int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData, SSmlLinesInfo* info) { - const char* index = sql; + const char* idx = sql; int32_t ret = TSDB_CODE_SUCCESS; uint8_t has_tags = 0; TAOS_SML_KV *timestamp = NULL; SHashObj *keyHashTable = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false); - ret = parseSmlMeasurement(smlData, &index, &has_tags, info); + ret = parseSmlMeasurement(smlData, &idx, &has_tags, info); if (ret) { tscError("SML:0x%"PRIx64" Unable to parse measurement", info->id); taosHashCleanup(keyHashTable); @@ -2591,7 +2591,7 @@ int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData, SSmlLinesInf //Parse Tags if (has_tags) { - ret = parseSmlKvPairs(&smlData->tags, &smlData->tagNum, &index, false, smlData, keyHashTable, info); + ret = parseSmlKvPairs(&smlData->tags, &smlData->tagNum, &idx, false, smlData, keyHashTable, info); if (ret) { tscError("SML:0x%"PRIx64" Unable to parse tag", info->id); taosHashCleanup(keyHashTable); @@ -2601,7 +2601,7 @@ int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData, SSmlLinesInf tscDebug("SML:0x%"PRIx64" Parse tags finished, num of tags:%d", info->id, smlData->tagNum); //Parse fields - ret = parseSmlKvPairs(&smlData->fields, &smlData->fieldNum, &index, true, smlData, keyHashTable, info); + ret = parseSmlKvPairs(&smlData->fields, &smlData->fieldNum, &idx, true, smlData, keyHashTable, info); if (ret) { tscError("SML:0x%"PRIx64" Unable to parse field", info->id); taosHashCleanup(keyHashTable); @@ -2611,7 +2611,7 @@ int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData, SSmlLinesInf taosHashCleanup(keyHashTable); //Parse timestamp - ret = parseSmlTimeStamp(×tamp, &index, info); + ret = parseSmlTimeStamp(×tamp, &idx, info); if (ret) { tscError("SML:0x%"PRIx64" Unable to parse timestamp", info->id); return ret; diff --git a/src/client/src/tscParseOpenTSDB.c b/src/client/src/tscParseOpenTSDB.c index 4b2738e567..525bfa4bd3 100644 --- a/src/client/src/tscParseOpenTSDB.c +++ b/src/client/src/tscParseOpenTSDB.c @@ -33,8 +33,8 @@ static uint64_t genUID() { return id; } -static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, SSmlLinesInfo* info) { - const char *cur = *index; +static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **idx, SSmlLinesInfo* info) { + const char *cur = *idx; uint16_t len = 0; pSml->stableName = tcalloc(TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE, 1); @@ -76,13 +76,13 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, } addEscapeCharToString(pSml->stableName, len); - *index = cur + 1; + *idx = cur + 1; tscDebug("OTD:0x%"PRIx64" Stable name in metric:%s|len:%d", info->id, pSml->stableName, len); return TSDB_CODE_SUCCESS; } -static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char **index, SSmlLinesInfo* info) { +static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char **idx, SSmlLinesInfo* info) { //Timestamp must be the first KV to parse assert(*num_kvs == 0); @@ -92,7 +92,7 @@ static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char char key[] = OTD_TIMESTAMP_COLUMN_NAME; char *value = NULL; - start = cur = *index; + start = cur = *idx; //allocate fields for timestamp and value *pTS = tcalloc(OTD_MAX_FIELDS_NUM, sizeof(TAOS_SML_KV)); @@ -130,12 +130,12 @@ static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char addEscapeCharToString((*pTS)->key, (int32_t)strlen(key)); *num_kvs += 1; - *index = cur + 1; + *idx = cur + 1; return ret; } -static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const char **index, SSmlLinesInfo* info) { +static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const char **idx, SSmlLinesInfo* info) { //skip timestamp TAOS_SML_KV *pVal = *pKVs + 1; const char *start, *cur; @@ -145,7 +145,7 @@ static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const ch char key[] = OTD_METRIC_VALUE_COLUMN_NAME; char *value = NULL; - start = cur = *index; + start = cur = *idx; //if metric value is string if (*cur == '"') { @@ -201,12 +201,12 @@ static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const ch addEscapeCharToString(pVal->key, (int32_t)strlen(pVal->key)); *num_kvs += 1; - *index = cur + 1; + *idx = cur + 1; return ret; } -static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash, SSmlLinesInfo* info) { - const char *cur = *index; +static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **idx, SHashObj *pHash, SSmlLinesInfo* info) { + const char *cur = *idx; char key[TSDB_COL_NAME_LEN]; uint16_t len = 0; @@ -244,17 +244,17 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj memcpy(pKV->key, key, len + 1); addEscapeCharToString(pKV->key, len); //tscDebug("OTD:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); - *index = cur + 1; + *idx = cur + 1; return TSDB_CODE_SUCCESS; } -static int32_t parseTelnetTagValue(TAOS_SML_KV *pKV, const char **index, +static int32_t parseTelnetTagValue(TAOS_SML_KV *pKV, const char **idx, bool *is_last_kv, SSmlLinesInfo* info) { const char *start, *cur; char *value = NULL; uint16_t len = 0; - start = cur = *index; + start = cur = *idx; while (1) { // whitespace or '\0' identifies a value @@ -290,14 +290,14 @@ static int32_t parseTelnetTagValue(TAOS_SML_KV *pKV, const char **index, } tfree(value); - *index = (*cur == '\0') ? cur : cur + 1; + *idx = (*cur == '\0') ? cur : cur + 1; return TSDB_CODE_SUCCESS; } static int32_t parseTelnetTagKvs(TAOS_SML_KV **pKVs, int *num_kvs, - const char **index, char **childTableName, + const char **idx, char **childTableName, SHashObj *pHash, SSmlLinesInfo* info) { - const char *cur = *index; + const char *cur = *idx; int32_t ret = TSDB_CODE_SUCCESS; TAOS_SML_KV *pkv; bool is_last_kv = false; @@ -357,11 +357,11 @@ static int32_t parseTelnetTagKvs(TAOS_SML_KV **pKVs, int *num_kvs, } static int32_t tscParseTelnetLine(const char* line, TAOS_SML_DATA_POINT* smlData, SSmlLinesInfo* info) { - const char* index = line; + const char* idx = line; int32_t ret = TSDB_CODE_SUCCESS; //Parse metric - ret = parseTelnetMetric(smlData, &index, info); + ret = parseTelnetMetric(smlData, &idx, info); if (ret) { tscError("OTD:0x%"PRIx64" Unable to parse metric", info->id); return ret; @@ -369,7 +369,7 @@ static int32_t tscParseTelnetLine(const char* line, TAOS_SML_DATA_POINT* smlData tscDebug("OTD:0x%"PRIx64" Parse metric finished", info->id); //Parse timestamp - ret = parseTelnetTimeStamp(&smlData->fields, &smlData->fieldNum, &index, info); + ret = parseTelnetTimeStamp(&smlData->fields, &smlData->fieldNum, &idx, info); if (ret) { tscError("OTD:0x%"PRIx64" Unable to parse timestamp", info->id); return ret; @@ -377,7 +377,7 @@ static int32_t tscParseTelnetLine(const char* line, TAOS_SML_DATA_POINT* smlData tscDebug("OTD:0x%"PRIx64" Parse timestamp finished", info->id); //Parse value - ret = parseTelnetMetricValue(&smlData->fields, &smlData->fieldNum, &index, info); + ret = parseTelnetMetricValue(&smlData->fields, &smlData->fieldNum, &idx, info); if (ret) { tscError("OTD:0x%"PRIx64" Unable to parse metric value", info->id); return ret; @@ -386,7 +386,7 @@ static int32_t tscParseTelnetLine(const char* line, TAOS_SML_DATA_POINT* smlData //Parse tagKVs SHashObj *keyHashTable = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false); - ret = parseTelnetTagKvs(&smlData->tags, &smlData->tagNum, &index, &smlData->childTableName, keyHashTable, info); + ret = parseTelnetTagKvs(&smlData->tags, &smlData->tagNum, &idx, &smlData->childTableName, keyHashTable, info); if (ret) { tscError("OTD:0x%"PRIx64" Unable to parse tags", info->id); taosHashCleanup(keyHashTable); diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index 454f158298..665efa4c6d 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -121,11 +121,11 @@ static int normalStmtAddPart(SNormalStmt* stmt, bool isParam, char* str, uint32_ return TSDB_CODE_SUCCESS; } -static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { +static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* pBind) { SNormalStmt* normal = &stmt->normal; for (uint16_t i = 0; i < normal->numParams; ++i) { - TAOS_BIND* tb = bind + i; + TAOS_BIND* tb = pBind + i; tVariant* var = normal->params + i; tVariantDestroy(var); @@ -383,8 +383,8 @@ int32_t fillTablesColumnsNull(SSqlObj* pSql) { //////////////////////////////////////////////////////////////////////////////// // functions for insertion statement preparation -static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, TAOS_BIND* bind, int32_t colNum) { - if (bind->is_null != NULL && *(bind->is_null)) { +static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, TAOS_BIND* pBind, int32_t colNum) { + if (pBind->is_null != NULL && *(pBind->is_null)) { setNull(data + param->offset, param->type, param->bytes); return TSDB_CODE_SUCCESS; } @@ -772,7 +772,7 @@ static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParam } #endif - if (bind->buffer_type != param->type) { + if (pBind->buffer_type != param->type) { tscError("column type mismatch"); return TSDB_CODE_TSC_INVALID_VALUE; } @@ -782,39 +782,39 @@ static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParam case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_UTINYINT: - *(uint8_t *)(data + param->offset) = *(uint8_t *)bind->buffer; + *(uint8_t *)(data + param->offset) = *(uint8_t *)pBind->buffer; break; case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_USMALLINT: - *(uint16_t *)(data + param->offset) = *(uint16_t *)bind->buffer; + *(uint16_t *)(data + param->offset) = *(uint16_t *)pBind->buffer; break; case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_UINT: case TSDB_DATA_TYPE_FLOAT: - *(uint32_t *)(data + param->offset) = *(uint32_t *)bind->buffer; + *(uint32_t *)(data + param->offset) = *(uint32_t *)pBind->buffer; break; case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_UBIGINT: case TSDB_DATA_TYPE_DOUBLE: case TSDB_DATA_TYPE_TIMESTAMP: - *(uint64_t *)(data + param->offset) = *(uint64_t *)bind->buffer; + *(uint64_t *)(data + param->offset) = *(uint64_t *)pBind->buffer; break; case TSDB_DATA_TYPE_BINARY: - if ((*bind->length) > (uintptr_t)param->bytes) { + if ((*pBind->length) > (uintptr_t)param->bytes) { tscError("column length is too big"); return TSDB_CODE_TSC_INVALID_VALUE; } - size = (short)*bind->length; - STR_WITH_SIZE_TO_VARSTR(data + param->offset, bind->buffer, size); + size = (short)*pBind->length; + STR_WITH_SIZE_TO_VARSTR(data + param->offset, pBind->buffer, size); return TSDB_CODE_SUCCESS; case TSDB_DATA_TYPE_NCHAR: { int32_t output = 0; - if (!taosMbsToUcs4(bind->buffer, *bind->length, varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { + if (!taosMbsToUcs4(pBind->buffer, *pBind->length, varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { tscError("convert nchar failed"); return TSDB_CODE_TSC_INVALID_VALUE; } @@ -889,27 +889,27 @@ static int32_t insertStmtGenBlock(STscStmt* pStmt, STableDataBlocks** pBlock, ST } -static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* bind, int32_t rowNum) { - if (bind->buffer_type != param->type || !isValidDataType(param->type)) { +static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* pBind, int32_t rowNum) { + if (pBind->buffer_type != param->type || !isValidDataType(param->type)) { tscError("column mismatch or invalid"); return TSDB_CODE_TSC_INVALID_VALUE; } - if (IS_VAR_DATA_TYPE(param->type) && bind->length == NULL) { + if (IS_VAR_DATA_TYPE(param->type) && pBind->length == NULL) { tscError("BINARY/NCHAR no length"); return TSDB_CODE_TSC_INVALID_VALUE; } - for (int i = 0; i < bind->num; ++i) { + for (int i = 0; i < pBind->num; ++i) { char* data = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * (rowNum + i); - if (bind->is_null != NULL && bind->is_null[i]) { + if (pBind->is_null != NULL && pBind->is_null[i]) { setNull(data + param->offset, param->type, param->bytes); continue; } if (!IS_VAR_DATA_TYPE(param->type)) { - memcpy(data + param->offset, (char *)bind->buffer + bind->buffer_length * i, tDataTypes[param->type].bytes); + memcpy(data + param->offset, (char *)pBind->buffer + pBind->buffer_length * i, tDataTypes[param->type].bytes); if (param->offset == 0) { if (tsCheckTimestamp(pBlock, data + param->offset) != TSDB_CODE_SUCCESS) { @@ -918,21 +918,21 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU } } } else if (param->type == TSDB_DATA_TYPE_BINARY) { - if (bind->length[i] > (uintptr_t)param->bytes) { - tscError("binary length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)bind->length[i]); + if (pBind->length[i] > (uintptr_t)param->bytes) { + tscError("binary length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)pBind->length[i]); return TSDB_CODE_TSC_INVALID_VALUE; } - int16_t bsize = (short)bind->length[i]; - STR_WITH_SIZE_TO_VARSTR(data + param->offset, (char *)bind->buffer + bind->buffer_length * i, bsize); + int16_t bsize = (short)pBind->length[i]; + STR_WITH_SIZE_TO_VARSTR(data + param->offset, (char *)pBind->buffer + pBind->buffer_length * i, bsize); } else if (param->type == TSDB_DATA_TYPE_NCHAR) { - if (bind->length[i] > (uintptr_t)param->bytes) { - tscError("nchar string length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)bind->length[i]); + if (pBind->length[i] > (uintptr_t)param->bytes) { + tscError("nchar string length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)pBind->length[i]); return TSDB_CODE_TSC_INVALID_VALUE; } int32_t output = 0; - if (!taosMbsToUcs4((char *)bind->buffer + bind->buffer_length * i, bind->length[i], varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { - tscError("convert nchar string to UCS4_LE failed:%s", (char*)((char *)bind->buffer + bind->buffer_length * i)); + if (!taosMbsToUcs4((char *)pBind->buffer + pBind->buffer_length * i, pBind->length[i], varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { + tscError("convert nchar string to UCS4_LE failed:%s", (char*)((char *)pBind->buffer + pBind->buffer_length * i)); return TSDB_CODE_TSC_INVALID_VALUE; } @@ -943,7 +943,7 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU return TSDB_CODE_SUCCESS; } -static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { +static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* pBind) { SSqlCmd* pCmd = &stmt->pSql->cmd; STscStmt* pStmt = (STscStmt*)stmt; @@ -995,7 +995,7 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { for (uint32_t j = 0; j < pBlock->numOfParams; ++j) { SParamInfo* param = &pBlock->params[j]; - int code = doBindParam(pBlock, data, param, &bind[param->idx], 1); + int code = doBindParam(pBlock, data, param, &pBind[param->idx], 1); if (code != TSDB_CODE_SUCCESS) { tscDebug("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind column type mismatch or invalid"); @@ -1006,10 +1006,10 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { } -static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int colIdx) { +static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* pBind, int colIdx) { SSqlCmd* pCmd = &stmt->pSql->cmd; STscStmt* pStmt = (STscStmt*)stmt; - int rowNum = bind->num; + int rowNum = pBind->num; STableDataBlocks* pBlock = NULL; @@ -1063,12 +1063,12 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c if (colIdx == -1) { for (uint32_t j = 0; j < pBlock->numOfParams; ++j) { SParamInfo* param = &pBlock->params[j]; - if (bind[param->idx].num != rowNum) { - tscError("0x%"PRIx64" param %d: num[%d:%d] not match", pStmt->pSql->self, param->idx, rowNum, bind[param->idx].num); + if (pBind[param->idx].num != rowNum) { + tscError("0x%"PRIx64" param %d: num[%d:%d] not match", pStmt->pSql->self, param->idx, rowNum, pBind[param->idx].num); return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind row num mismatch"); } - int code = doBindBatchParam(pBlock, param, &bind[param->idx], pCmd->batchSize); + int code = doBindBatchParam(pBlock, param, &pBind[param->idx], pCmd->batchSize); if (code != TSDB_CODE_SUCCESS) { tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind column type mismatch or invalid"); @@ -1079,7 +1079,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c } else { SParamInfo* param = &pBlock->params[colIdx]; - int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize); + int code = doBindBatchParam(pBlock, param, pBind, pCmd->batchSize); if (code != TSDB_CODE_SUCCESS) { tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind column type mismatch or invalid"); @@ -1312,8 +1312,8 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { return ret; } - int32_t index = 0; - SStrToken sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + int32_t idx = 0; + SStrToken sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n == 0) { tscError("table is is expected, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "table name is expected", pCmd->insertParam.sql); @@ -1333,7 +1333,7 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { pStmt->mtb.tagSet = true; - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n > 0 && (sToken.type == TK_VALUES || sToken.type == TK_LP)) { return TSDB_CODE_SUCCESS; } @@ -1343,14 +1343,14 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { return tscSQLSyntaxErrMsg(pCmd->payload, "keywords USING is expected", sToken.z ? sToken.z : pCmd->insertParam.sql); } - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) { tscError("invalid token, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z ? sToken.z : pCmd->insertParam.sql); } pStmt->mtb.stbname = sToken; - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || ((sToken.type != TK_TAGS) && (sToken.type != TK_LP))) { tscError("invalid token, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z ? sToken.z : pCmd->insertParam.sql); @@ -1361,9 +1361,9 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { if (sToken.type == TK_LP) { pStmt->mtb.tagColSet = true; pStmt->mtb.tagCols = sToken; - int32_t tagColsStart = index; + int32_t tagColsStart = idx; while (1) { - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.type == TK_ILLEGAL) { return tscSQLSyntaxErrMsg(pCmd->payload, "unrecognized token", sToken.z); } @@ -1378,16 +1378,16 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { tscError("tag column list expected, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "tag column list expected", pCmd->insertParam.sql); } - pStmt->mtb.tagCols.n = index - tagColsStart + 1; + pStmt->mtb.tagCols.n = idx - tagColsStart + 1; - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || sToken.type != TK_TAGS) { tscError("keyword TAGS expected, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z ? sToken.z : pCmd->insertParam.sql); } } - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || sToken.type != TK_LP) { tscError("( expected, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "( expected", sToken.z ? sToken.z : pCmd->insertParam.sql); @@ -1398,7 +1398,7 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { int32_t loopCont = 1; while (loopCont) { - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0) { tscError("unexpected sql end, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "unexpected sql end", pCmd->insertParam.sql); @@ -1429,7 +1429,7 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { return tscSQLSyntaxErrMsg(pCmd->payload, "not match tags", pCmd->insertParam.sql); } - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || (sToken.type != TK_VALUES && sToken.type != TK_LP)) { tscError("sql error, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "sql error", sToken.z ? sToken.z : pCmd->insertParam.sql); @@ -1944,7 +1944,7 @@ int taos_stmt_close(TAOS_STMT* stmt) { STMT_RET(TSDB_CODE_SUCCESS); } -int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) { +int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* pBind) { STscStmt* pStmt = (STscStmt*)stmt; STMT_CHECK @@ -1965,18 +1965,18 @@ int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) { tscDebug("tableId:%" PRIu64 ", try to bind one row", pStmt->mtb.currentUid); - STMT_RET(insertStmtBindParam(pStmt, bind)); + STMT_RET(insertStmtBindParam(pStmt, pBind)); } else { - STMT_RET(normalStmtBindParam(pStmt, bind)); + STMT_RET(normalStmtBindParam(pStmt, pBind)); } } -int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) { +int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* pBind) { STscStmt* pStmt = (STscStmt*)stmt; STMT_CHECK - if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) { + if (pBind == NULL || pBind->num <= 0 || pBind->num > INT16_MAX) { tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self); STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "invalid bind param")); } @@ -2000,21 +2000,21 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) { pStmt->last = STMT_BIND; - STMT_RET(insertStmtBindParamBatch(pStmt, bind, -1)); + STMT_RET(insertStmtBindParamBatch(pStmt, pBind, -1)); } -int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int colIdx) { +int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* pBind, int colIdx) { STscStmt* pStmt = (STscStmt*)stmt; STMT_CHECK - if (bind == NULL) { + if (pBind == NULL) { tscError("0x%" PRIx64 " invalid parameter: bind is NULL", pStmt->pSql->self); STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "invalid bind param: bind is NULL")); } - if (bind->num <= 0 || bind->num > INT16_MAX) { + if (pBind->num <= 0 || pBind->num > INT16_MAX) { char errMsg[128]; - sprintf(errMsg, "invalid parameter: bind->num:%d out of range [0, %d)", bind->num, INT16_MAX); + sprintf(errMsg, "invalid parameter: bind->num:%d out of range [0, %d)", pBind->num, INT16_MAX); tscError("0x%" PRIx64 " %s", pStmt->pSql->self, errMsg); STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), errMsg)); } @@ -2045,7 +2045,7 @@ int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, in pStmt->last = STMT_BIND_COL; - STMT_RET(insertStmtBindParamBatch(pStmt, bind, colIdx)); + STMT_RET(insertStmtBindParamBatch(pStmt, pBind, colIdx)); } int taos_stmt_add_batch(TAOS_STMT* stmt) { diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 22456782d0..61e62535d1 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -47,11 +47,11 @@ #define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey)) -// -1 is tbname column index, so here use the -2 as the initial value +// -1 is tbname column idx, so here use the -2 as the initial value #define COLUMN_INDEX_INITIAL_VAL (-2) #define COLUMN_INDEX_INITIALIZER \ { COLUMN_INDEX_INITIAL_VAL, COLUMN_INDEX_INITIAL_VAL } -#define COLUMN_INDEX_VALID(index) (((index).tableIndex >= 0) && ((index).columnIndex >= TSDB_MIN_VALID_COLUMN_INDEX)) +#define COLUMN_INDEX_VALID(idx) (((idx).tableIndex >= 0) && ((idx).columnIndex >= TSDB_MIN_VALID_COLUMN_INDEX)) #define TBNAME_LIST_SEP "," typedef struct SColumnList { // todo refactor @@ -335,21 +335,21 @@ static int32_t invalidOperationMsg(char* dstBuffer, const char* errMsg) { } static int convertTimestampStrToInt64(tVariant *pVar, int32_t precision) { - int64_t time = 0; + int64_t t = 0; stringProcess(pVar->pz, pVar->nLen); char* seg = strnchr(pVar->pz, '-', pVar->nLen, false); if (seg != NULL) { - if (taosParseTime(pVar->pz, &time, pVar->nLen, precision, tsDaylight) != TSDB_CODE_SUCCESS) { + if (taosParseTime(pVar->pz, &t, pVar->nLen, precision, tsDaylight) != TSDB_CODE_SUCCESS) { return -1; } } else { - if (tVariantDump(pVar, (char*)&time, TSDB_DATA_TYPE_BIGINT, true)) { + if (tVariantDump(pVar, (char*)&t, TSDB_DATA_TYPE_BIGINT, true)) { return -1; } } tVariantDestroy(pVar); - tVariantCreateFromBinary(pVar, (char*)&time, 0, TSDB_DATA_TYPE_BIGINT); + tVariantCreateFromBinary(pVar, (char*)&t, 0, TSDB_DATA_TYPE_BIGINT); return 0; } static int setColumnFilterInfoForTimestamp(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tVariant* pVar) { @@ -1155,8 +1155,8 @@ static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo, SSql tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name)); } - SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL, 0); + SColumnIndex idx = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &idx, &s, TSDB_COL_NORMAL, 0); return TSDB_CODE_SUCCESS; } @@ -1303,17 +1303,17 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(col, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(col, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); - } else if (index.columnIndex >= numOfCols) { + } else if (idx.columnIndex >= numOfCols) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } @@ -1322,7 +1322,7 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex)); } - SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE || pSchema->type == TSDB_DATA_TYPE_NCHAR || pSchema->type == TSDB_DATA_TYPE_BINARY) { @@ -1345,8 +1345,8 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS } } - tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); - SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; + tscColumnListInsert(pQueryInfo->colList, idx.columnIndex, pTableMeta->id.uid, pSchema); + SColIndex colIndex = { .colIndex = idx.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; taosArrayPush(pGroupExpr->columnInfo, &colIndex); pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC; pQueryInfo->stateWindow = true; @@ -1386,11 +1386,11 @@ int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pS return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(col, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(col, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } @@ -1947,8 +1947,8 @@ static int32_t handleScalarTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = {.tableIndex = tableIndex}; - SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_SCALAR_EXPR, &index, pNode->resultType, pNode->resultBytes, + SColumnIndex idx = {.tableIndex = tableIndex}; + SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_SCALAR_EXPR, &idx, pNode->resultType, pNode->resultBytes, getNewResColId(pCmd), 0, false); // set the colId to the result column id pExpr->base.colInfo.colId = pExpr->base.resColId; @@ -2130,9 +2130,9 @@ static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) { SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, PRIMARYKEY_TIMESTAMP_COL_INDEX); // add the timestamp column into the output columns - SColumnIndex index = {0}; // primary timestamp column info + SColumnIndex idx = {0}; // primary timestamp column info int32_t numOfCols = (int32_t)tscNumOfFields(pQueryInfo); - tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &idx, pSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); SInternalField* pSupInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfCols); pSupInfo->visible = false; @@ -2394,16 +2394,16 @@ SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tab SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex); int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ); - SColumnIndex index = {.tableIndex = tableIndex,}; + SColumnIndex idx = {.tableIndex = tableIndex,}; if (functionId == TSDB_FUNC_TAGPRJ) { - index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); + idx.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta); + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMeta->id.uid, pSchema); } else { - index.columnIndex = colIndex; + idx.columnIndex = colIndex; } - return tscExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes, colId, 0, + return tscExprAppend(pQueryInfo, functionId, &idx, pSchema->type, pSchema->bytes, colId, 0, (functionId == TSDB_FUNC_TAGPRJ)); } @@ -2476,41 +2476,41 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t if (tokenId == TK_ALL) { // project on all fields TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY); - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getTableIndexByName(&pItem->pNode->columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getTableIndexByName(&pItem->pNode->columnName, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } // all meters columns are required - if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) { // all table columns are required. + if (idx.tableIndex == COLUMN_INDEX_INITIAL_VAL) { // all table columns are required. for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - index.tableIndex = i; - int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos, pCmd); + idx.tableIndex = i; + int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &idx, startPos, pCmd); startPos += inc; } } else { - doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos, pCmd); + doAddProjectionExprAndResultFields(pQueryInfo, &idx, startPos, pCmd); } // add the primary timestamp column even though it is not required by user - STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[index.tableIndex]->pTableMeta; + STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[idx.tableIndex]->pTableMeta; if (pTableMeta->tableType != TSDB_TEMP_TABLE) { tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMeta->id.uid); } } else if (tokenId == TK_STRING || tokenId == TK_INTEGER || tokenId == TK_FLOAT || tokenId == TK_BOOL) { // simple column projection query - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; // user-specified constant value as a new result column - index.columnIndex = (pQueryInfo->udColumnId--); - index.tableIndex = 0; + idx.columnIndex = (pQueryInfo->udColumnId--); + idx.tableIndex = 0; SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->value, &pItem->pNode->exprToken, pItem->aliasName); - SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC, + SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &idx, &colSchema, TSDB_COL_UDC, getNewResColId(pCmd)); tVariantAssign(&pExpr->base.param[pExpr->base.numOfParams++], &pItem->pNode->value); }else if (tokenId == TK_ID || tokenId == TK_ARROW) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; SStrToken* pToken = NULL; if (tokenId == TK_ARROW){ @@ -2530,35 +2530,35 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t pToken = &pItem->pNode->columnName; } - if (getColumnIndexByName(pToken, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } //for tbname and other pseudo columns - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || TSDB_COL_IS_TSWIN_COL(index.columnIndex)) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX || TSDB_COL_IS_TSWIN_COL(idx.columnIndex)) { if (outerQuery) { - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); bool existed = false; SSchema* pSchema = pTableMetaInfo->pTableMeta->schema; for (int32_t i = 0; i < numOfCols; ++i) { if ((strncasecmp(pSchema[i].name, TSQL_TBNAME_L, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) || + idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_TSWIN_START, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_TSWIN_START_COLUMN_INDEX) || + idx.columnIndex == TSDB_TSWIN_START_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_TSWIN_STOP, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_TSWIN_STOP_COLUMN_INDEX) || + idx.columnIndex == TSDB_TSWIN_STOP_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_TSWIN_DURATION, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_TSWIN_DURATION_COLUMN_INDEX) || + idx.columnIndex == TSDB_TSWIN_DURATION_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_QUERY_START, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_QUERY_START_COLUMN_INDEX) || + idx.columnIndex == TSDB_QUERY_START_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_QUERY_STOP, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_QUERY_STOP_COLUMN_INDEX) || + idx.columnIndex == TSDB_QUERY_STOP_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_QUERY_DURATION, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_QUERY_DURATION_COLUMN_INDEX)) { + idx.columnIndex == TSDB_QUERY_DURATION_COLUMN_INDEX)) { existed = true; - index.columnIndex = i; + idx.columnIndex = i; break; } } @@ -2567,47 +2567,47 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - SSchema colSchema = pSchema[index.columnIndex]; + SSchema colSchema = pSchema[idx.columnIndex]; char name[TSDB_COL_NAME_LEN] = {0}; getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1); tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN); - /*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, + /*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &idx, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); } else { SSchema colSchema; int16_t functionId, colType; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { colSchema = *tGetTbnameColumnSchema(); functionId = TSDB_FUNC_TAGPRJ; colType = TSDB_COL_TAG; } else { - if (!timeWindowQuery && (index.columnIndex == TSDB_TSWIN_START_COLUMN_INDEX || - index.columnIndex == TSDB_TSWIN_STOP_COLUMN_INDEX || - index.columnIndex == TSDB_TSWIN_DURATION_COLUMN_INDEX)) { + if (!timeWindowQuery && (idx.columnIndex == TSDB_TSWIN_START_COLUMN_INDEX || + idx.columnIndex == TSDB_TSWIN_STOP_COLUMN_INDEX || + idx.columnIndex == TSDB_TSWIN_DURATION_COLUMN_INDEX)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } - colSchema = *tGetTimeWindowColumnSchema(index.columnIndex); - functionId = getTimeWindowFunctionID(index.columnIndex); + colSchema = *tGetTimeWindowColumnSchema(idx.columnIndex); + functionId = getTimeWindowFunctionID(idx.columnIndex); colType = TSDB_COL_NORMAL; } char name[TSDB_COL_NAME_LEN] = {0}; getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1); tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN); - /*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, functionId, &index, &colSchema, + /*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, functionId, &idx, &colSchema, colType, getNewResColId(pCmd)); } pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; } else { - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { + if (idx.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); if (tokenId == TK_ARROW && pSchema->type != TSDB_DATA_TYPE_JSON) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } @@ -2615,12 +2615,12 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - addProjectQueryCol(pQueryInfo, startPos, &index, pItem, getNewResColId(pCmd)); + addProjectQueryCol(pQueryInfo, startPos, &idx, pItem, getNewResColId(pCmd)); pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; } // add the primary timestamp column even though it is not required by user - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); if (!UTIL_TABLE_IS_TMP_TABLE(pTableMetaInfo)) { tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); } @@ -2690,24 +2690,24 @@ void setResultColName(char* name, bool finalResult, tSqlExprItem* pItem, int32_t if (pItem->aliasName != NULL) { tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN); } else { - char uname[TSDB_COL_NAME_LEN] = {0}; + char colName[TSDB_COL_NAME_LEN] = {0}; int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN); - tstrncpy(uname, pToken->z, len); + tstrncpy(colName, pToken->z, len); if (finalResult && tsKeepOriginalColumnName) { // keep the original column name - tstrncpy(name, uname, TSDB_COL_NAME_LEN); + tstrncpy(name, colName, TSDB_COL_NAME_LEN); } else if (multiCols) { if (!TSDB_FUNC_IS_SCALAR(functionId)) { int32_t size = TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].name) + 2 + 1; char tmp[TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].name) + 2 + 1] = {0}; - snprintf(tmp, size, "%s(%s)", aAggs[functionId].name, uname); + snprintf(tmp, size, "%s(%s)", aAggs[functionId].name, colName); tstrncpy(name, tmp, TSDB_COL_NAME_LEN); } else { - int32_t index = TSDB_FUNC_SCALAR_INDEX(functionId); - int32_t size = TSDB_COL_NAME_LEN + tListLen(aScalarFunctions[index].name) + 2 + 1; - char tmp[TSDB_COL_NAME_LEN + tListLen(aScalarFunctions[index].name) + 2 + 1] = {0}; - snprintf(tmp, size, "%s(%s)", aScalarFunctions[index].name, uname); + int32_t idx = TSDB_FUNC_SCALAR_INDEX(functionId); + int32_t size = TSDB_COL_NAME_LEN + tListLen(aScalarFunctions[idx].name) + 2 + 1; + char tmp[TSDB_COL_NAME_LEN + tListLen(aScalarFunctions[idx].name) + 2 + 1] = {0}; + snprintf(tmp, size, "%s(%s)", aScalarFunctions[idx].name, colName); tstrncpy(name, tmp, TSDB_COL_NAME_LEN); } @@ -2793,7 +2793,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } SExprInfo* pExpr = NULL; - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; if (pItem->pNode->Expr.paramList != NULL) { tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0); @@ -2808,47 +2808,47 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // check if the table name is valid or not SStrToken tmpToken = pParamElem->pNode->columnName; - if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + if (getTableIndexByName(&tmpToken, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + idx = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, false); } else { // count the number of table created according to the super table - if (getColumnIndexByName(pToken, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); // count tag is equalled to count(tbname) bool isTag = false; - if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || - index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { - index.columnIndex = TSDB_TBNAME_COLUMN_INDEX; + if (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || + idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + idx.columnIndex = TSDB_TBNAME_COLUMN_INDEX; isTag = true; } int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, isTag); } } else { // count(*) is equalled to count(primary_timestamp_key) - index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + idx = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, false); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); - SColumnList list = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList list = createColumnList(1, idx.tableIndex, idx.columnIndex); if (finalResult) { int32_t numOfOutput = tscNumOfFields(pQueryInfo); insertResultField(pQueryInfo, numOfOutput, &list, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, pExpr->base.aliasName, @@ -2862,7 +2862,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // the time stamp may be always needed - if (index.tableIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { + if (idx.tableIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); } @@ -2908,18 +2908,18 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pColumnSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pColumnSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); // elapsed only can be applied to primary key if (functionId == TSDB_FUNC_ELAPSED) { - if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX || + if (idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX || pColumnSchema->colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "elapsed only can be applied to primary key"); } @@ -2945,13 +2945,13 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col STableComInfo info = tscGetTableInfo(pTableMetaInfo->pTableMeta); // functions can not be applied to tags - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || - (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta))) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX || + (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta))) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } // 2. check if sql function can be applied on this column data type - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); if (functionId == TSDB_FUNC_MODE && pColumnSchema->colId == PRIMARYKEY_TIMESTAMP_COL_INDEX && pColumnSchema->type == TSDB_DATA_TYPE_TIMESTAMP){ @@ -2975,7 +2975,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // set the first column ts for diff query if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE || functionId == TSDB_FUNC_CSUM) { - SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; + SColumnIndex indexTS = {.tableIndex = idx.tableIndex, .columnIndex = 0}; SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0, TSDB_KEYSIZE, false); tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS_DUMMY].name, sizeof(pExpr->base.aliasName)); @@ -2986,7 +2986,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } if (functionId == TSDB_FUNC_STATE_COUNT || functionId == TSDB_FUNC_STATE_DURATION) { - SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; + SColumnIndex indexTS = {.tableIndex = idx.tableIndex, .columnIndex = 0}; SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_PRJ, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0, TSDB_KEYSIZE, false); tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS_DUMMY].name, sizeof(pExpr->base.aliasName)); @@ -2995,15 +2995,15 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col insertResultField(pQueryInfo, colIndex, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].name, pExpr); - pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_PRJ, &index, pSchema->type, + pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_PRJ, &idx, pSchema->type, pSchema->bytes, getNewResColId(pCmd), 0, false); tstrncpy(pExpr->base.aliasName, pParamElem->pNode->columnName.z, pParamElem->pNode->columnName.n+1); - ids = createColumnList(1, index.tableIndex, index.columnIndex); + ids = createColumnList(1, idx.tableIndex, idx.columnIndex); insertResultField(pQueryInfo, colIndex + 1, &ids, pExpr->base.resBytes, (int32_t)pExpr->base.resType, pExpr->base.aliasName, pExpr); } - SExprInfo* pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), + SExprInfo* pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), intermediateResSize, false); if (functionId == TSDB_FUNC_LEASTSQR) { // set the leastsquares parameters @@ -3118,7 +3118,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } } - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); @@ -3168,55 +3168,55 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; if (pParamElem->pNode->tokenId == TK_ALL) { // select table.* SStrToken tmpToken = pParamElem->pNode->columnName; - if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + if (getTableIndexByName(&tmpToken, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); char name[TSDB_COL_NAME_LEN] = {0}; for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) { - index.columnIndex = j; + idx.columnIndex = j; SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)}; setResultColName(name, finalResult, pItem, cvtFunc.originFuncId, &t, true); - if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult, + if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &idx, finalResult, pUdfInfo) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } } } else { - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); if (pParamElem->pNode->columnName.z == NULL) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } // functions can not be applied to tags - if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) { + if ((idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (idx.columnIndex < 0)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } char name[TSDB_COL_NAME_LEN] = {0}; - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1; setResultColName(name, finalResult, pItem, cvtFunc.originFuncId, &pParamElem->pNode->columnName, multiColOutput); - if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex++, &index, finalResult, + if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex++, &idx, finalResult, pUdfInfo) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -3236,13 +3236,13 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) { - SColumnIndex index = {.tableIndex = j, .columnIndex = i}; + SColumnIndex idx = {.tableIndex = j, .columnIndex = i}; char name[TSDB_COL_NAME_LEN] = {0}; SStrToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)}; setResultColName(name, finalResult, pItem, cvtFunc.originFuncId, &t, true); - if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, + if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[idx.columnIndex], cvtFunc, name, colIndex, &idx, finalResult, pUdfInfo) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -3284,26 +3284,26 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); - if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX && pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && + if (idx.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX && pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && (functionId == TSDB_FUNC_UNIQUE || functionId == TSDB_FUNC_TAIL)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg29); } // functions can not be applied to tags - if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { + if (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } @@ -3352,7 +3352,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); colIndex += 1; // the first column is ts - pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), interResult, false); tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); @@ -3398,12 +3398,12 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // todo REFACTOR // set the first column ts for top/bottom query int32_t tsFuncId = (functionId == TSDB_FUNC_MAVG) ? TSDB_FUNC_TS_DUMMY : TSDB_FUNC_TS; - SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + SColumnIndex index1 = {idx.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; pExpr = tscExprAppend(pQueryInfo, tsFuncId, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0, 0, false); tstrncpy(pExpr->base.aliasName, aAggs[tsFuncId].name, sizeof(pExpr->base.aliasName)); const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX; - SColumnList ids = createColumnList(1, index.tableIndex, TS_COLUMN_INDEX); + SColumnList ids = createColumnList(1, idx.tableIndex, TS_COLUMN_INDEX); insertResultField(pQueryInfo, colIndex, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[tsFuncId].name, pExpr); @@ -3411,7 +3411,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col getResultDataInfo(pSchema->type, pSchema->bytes, functionId, (int32_t)numRowsSelected, &resultType, &resultSize, &interResult, 0, false, pUdfInfo); - pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), interResult, false); tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); } else { @@ -3427,19 +3427,19 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // todo REFACTOR // set the first column ts for top/bottom query - SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + SColumnIndex index1 = {idx.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0, 0, false); tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->base.aliasName)); const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX; - SColumnList ids = createColumnList(1, index.tableIndex, TS_COLUMN_INDEX); + SColumnList ids = createColumnList(1, idx.tableIndex, TS_COLUMN_INDEX); insertResultField(pQueryInfo, colIndex, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].name, pExpr); colIndex += 1; // the first column is ts getResultDataInfo(pSchema->type, pSchema->bytes, functionId, (int32_t)numRowsSelected, &resultType, &resultSize, &interResult, 0, false, pUdfInfo); - pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), interResult, false); if (functionId == TSDB_FUNC_TAIL){ int64_t offset = 0; @@ -3466,7 +3466,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); // todo refactor: tscColumnListInsert part - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); if (finalResult) { insertResultField(pQueryInfo, colIndex, &ids, resultSize, (int8_t)resultType, pExpr->base.aliasName, pExpr); @@ -3492,46 +3492,46 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col tSqlExprItem* pParamItem = taosArrayGet(pItem->pNode->Expr.paramList, 0); tSqlExpr* pParam = pParamItem->pNode; - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pParam->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pParam->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); // functions can not be applied to normal columns int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex < numOfCols && idx.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - if (index.columnIndex > 0) { - index.columnIndex -= numOfCols; + if (idx.columnIndex > 0) { + idx.columnIndex -= numOfCols; } // 2. valid the column type int16_t colType = 0; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { colType = TSDB_DATA_TYPE_BINARY; } else { - colType = pSchema[index.columnIndex].type; + colType = pSchema[idx.columnIndex].type; } if (colType == TSDB_DATA_TYPE_BOOL) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, - &pSchema[index.columnIndex]); + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMetaInfo->pTableMeta->id.uid, + &pSchema[idx.columnIndex]); SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); SSchema s = {0}; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { s = *tGetTbnameColumnSchema(); } else { - s = pTagSchema[index.columnIndex]; + s = pTagSchema[idx.columnIndex]; } int32_t bytes = 0; @@ -3545,7 +3545,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col s.bytes = bytes; TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY); - tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TID_TAG, &index, &s, TSDB_COL_TAG, getNewResColId(pCmd)); + tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TID_TAG, &idx, &s, TSDB_COL_TAG, getNewResColId(pCmd)); return TSDB_CODE_SUCCESS; } @@ -3556,11 +3556,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = { + SColumnIndex idx = { .tableIndex = 0, .columnIndex = 0, }; - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); int32_t inter = 0; int16_t resType = 0; @@ -3571,10 +3571,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SSchema s = {.name = "block_dist", .type = TSDB_DATA_TYPE_BINARY, .bytes = bytes}; SExprInfo* pExpr = - tscExprInsert(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, resType, bytes, getNewResColId(pCmd), bytes, 0); + tscExprInsert(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &idx, resType, bytes, getNewResColId(pCmd), bytes, 0); tstrncpy(pExpr->base.aliasName, s.name, sizeof(pExpr->base.aliasName)); - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); insertResultField(pQueryInfo, 0, &ids, bytes, s.type, s.name, pExpr); pExpr->base.numOfParams = 1; @@ -3595,18 +3595,18 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); if (!IS_NUMERIC_TYPE(pSchema->type)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -3768,7 +3768,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col getResultDataInfo(pSchema->type, pSchema->bytes, functionId, counter, &resultType, &resultSize, &interResult, 0, false, pUdfInfo); SExprInfo* pExpr = NULL; - pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), interResult, + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), interResult, false); numOutput = numBins - 1; tscExprAddParams(&pExpr->base, (char*)&numOutput, TSDB_DATA_TYPE_INT, sizeof(int32_t)); @@ -3796,7 +3796,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); // todo refactor: tscColumnListInsert part - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); if (finalResult) { insertResultField(pQueryInfo, colIndex, &ids, resultSize, (int8_t)resultType, pExpr->base.aliasName, pExpr); @@ -3826,20 +3826,20 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); // functions can not be applied to tags - if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { + if (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } @@ -3849,21 +3849,21 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, false, pUdfInfo); SExprInfo* pExpr = - tscExprAppend(pQueryInfo, functionId, &index, resType, bytes, getNewResColId(pCmd), inter, false); + tscExprAppend(pQueryInfo, functionId, &idx, resType, bytes, getNewResColId(pCmd), inter, false); memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); if (finalResult) { insertResultField(pQueryInfo, colIndex, &ids, pUdfInfo->resBytes, pUdfInfo->resType, pExpr->base.aliasName, pExpr); } else { for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, index.columnIndex, uid, pSchema); + tscColumnListInsert(pQueryInfo->colList, idx.columnIndex, uid, pSchema); } } tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); @@ -3880,9 +3880,9 @@ static SColumnList createColumnList(int32_t num, int16_t tableIndex, int32_t col SColumnList columnList = {0}; columnList.num = num; - int32_t index = num - 1; - columnList.ids[index].tableIndex = tableIndex; - columnList.ids[index].columnIndex = columnIndex; + int32_t idx = num - 1; + columnList.ids[idx].tableIndex = tableIndex; + columnList.ids[idx].columnIndex = columnIndex; return columnList; } @@ -3936,8 +3936,8 @@ static bool isTimeWindowToken(SStrToken* token, int16_t *columnIndex) { } } -static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken* pToken) { - STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index)->pTableMeta; +static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t idx, SStrToken* pToken) { + STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, idx)->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta); SSchema* pSchema = tscGetTableSchema(pTableMeta); @@ -3981,7 +3981,7 @@ int32_t doGetColumnIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColum } else if (isTimeWindowToken(pToken, &tsWinColumnIndex)) { pIndex->columnIndex = tsWinColumnIndex; } else { - // not specify the table name, try to locate the table index by column name + // not specify the table name, try to locate the table idx by column name if (pIndex->tableIndex == COLUMN_INDEX_INITIAL_VAL) { for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) { int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken); @@ -3995,7 +3995,7 @@ int32_t doGetColumnIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColum } } } - } else { // table index is valid, get the column index + } else { // table idx is valid, get the column idx int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken); if (colIndex != COLUMN_INDEX_INITIAL_VAL) { pIndex->columnIndex = colIndex; @@ -4535,24 +4535,24 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd } } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&token, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&token, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } if (tableIndex == COLUMN_INDEX_INITIAL_VAL) { - tableIndex = index.tableIndex; - } else if (tableIndex != index.tableIndex) { + tableIndex = idx.tableIndex; + } else if (tableIndex != idx.tableIndex) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { pSchema = tGetTbnameColumnSchema(); } else { - pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); } if (pSchema->type == TSDB_DATA_TYPE_JSON && !pItem->isJsonExp){ @@ -4563,15 +4563,15 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd } int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - bool groupTag = (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols); + bool groupTag = (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX || idx.columnIndex >= numOfCols); if (groupTag) { if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - int32_t relIndex = index.columnIndex; - if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { + int32_t relIndex = idx.columnIndex; + if (idx.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { relIndex -= numOfCols; } @@ -4587,17 +4587,17 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd taosArrayPush(pGroupExpr->columnInfo, &colIndex); - index.columnIndex = relIndex; - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); + idx.columnIndex = relIndex; + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMeta->id.uid, pSchema); } else { // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by if (pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } - tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); + tscColumnListInsert(pQueryInfo->colList, idx.columnIndex, pTableMeta->id.uid, pSchema); - SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; + SColIndex colIndex = { .colIndex = idx.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; strncpy(colIndex.name, pSchema->name, tListLen(colIndex.name)); taosArrayPush(pGroupExpr->columnInfo, &colIndex); @@ -4929,9 +4929,9 @@ static int32_t checkColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return checkColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->tokenId); } else { // handle leaf node - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - addAllColumn(pCmd, pQueryInfo, pExpr, pExpr->tokenId, &index); - return checkColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr); + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + addAllColumn(pCmd, pQueryInfo, pExpr, pExpr->tokenId, &idx); + return checkColumnFilterInfo(pCmd, pQueryInfo, &idx, pExpr, relOptr); } return TSDB_CODE_SUCCESS; } @@ -4965,17 +4965,17 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS pRight = pRight->pLeft; } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pTagSchema1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pTagSchema1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); - assert(index.tableIndex >= 0 && index.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); + assert(idx.tableIndex >= 0 && idx.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); - SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; + SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[idx.tableIndex]; if (*leftNode == NULL) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -4989,9 +4989,9 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + idx.columnIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); if (tscColumnExists(pTableMetaInfo->tagColList, pTagSchema1->colId, pTableMetaInfo->pTableMeta->id.uid) < 0) { - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema1); + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMeta->id.uid, pTagSchema1); atomic_add_fetch_32(&pTableMetaInfo->joinTagNum, 1); if (pTableMetaInfo->joinTagNum > 1) { @@ -5000,19 +5000,19 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS } } - int16_t leftIdx = index.tableIndex; + int16_t leftIdx = idx.tableIndex; - index = (SColumnIndex)COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pRight->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + idx = (SColumnIndex)COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pRight->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pTagSchema2 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pTagSchema2 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); - assert(index.tableIndex >= 0 && index.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); + assert(idx.tableIndex >= 0 && idx.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); - SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; + SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[idx.tableIndex]; if (*rightNode == NULL) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -5025,10 +5025,10 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMeta); + idx.columnIndex = idx.columnIndex - tscGetNumOfColumns(pTableMeta); if (tscColumnExists(pTableMetaInfo->tagColList, pTagSchema2->colId, pTableMeta->id.uid) < 0) { - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema2); + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMeta->id.uid, pTagSchema2); atomic_add_fetch_32(&pTableMetaInfo->joinTagNum, 1); if (pTableMetaInfo->joinTagNum > 1) { @@ -5037,7 +5037,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS } } - int16_t rightIdx = index.tableIndex; + int16_t rightIdx = idx.tableIndex; if (pTagSchema1->type != pTagSchema2->type) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); @@ -5290,14 +5290,14 @@ static int32_t validateSQLExprItem(SSqlCmd* pCmd, tSqlExpr* pExpr, return ret; } } else if (pExpr->type == SQL_NODE_TABLE_COLUMN) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - pList->ids[pList->num++] = index; + pList->ids[pList->num++] = idx; *type = SQLEXPR_TYPE_SCALAR; } else if (pExpr->type == SQL_NODE_DATA_TYPE) { if (pExpr->dataType.type < 0 || pExpr->dataType.bytes <= 0) { @@ -5493,17 +5493,17 @@ static int32_t setNormalExprToCond(tSqlExpr** parent, tSqlExpr* pExpr, int32_t p } -static int32_t validateNullExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t index, char* msgBuf) { +static int32_t validateNullExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t idx, char* msgBuf) { const char* msg = "only support is [not] null"; tSqlExpr* pRight = pExpr->pRight; SSchema* pSchema = tscGetTableSchema(pTableMeta); - if (pRight->tokenId == TK_NULL && pSchema[index].type != TSDB_DATA_TYPE_JSON && (!(pExpr->tokenId == TK_ISNULL || pExpr->tokenId == TK_NOTNULL))) { + if (pRight->tokenId == TK_NULL && pSchema[idx].type != TSDB_DATA_TYPE_JSON && (!(pExpr->tokenId == TK_ISNULL || pExpr->tokenId == TK_NOTNULL))) { return invalidOperationMsg(msgBuf, msg); } if (pRight->tokenId == TK_STRING) { - if (IS_VAR_DATA_TYPE(pSchema[index].type) || pSchema[index].type == TSDB_DATA_TYPE_JSON) { + if (IS_VAR_DATA_TYPE(pSchema[idx].type) || pSchema[idx].type == TSDB_DATA_TYPE_JSON) { return TSDB_CODE_SUCCESS; } @@ -5526,7 +5526,7 @@ static int32_t validateNullExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t } // check for like expression -static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t index, char* msgBuf) { +static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t idx, char* msgBuf) { const char* msg1 = "wildcard string should be less than %d characters"; const char* msg2 = "illegal column type for like"; @@ -5541,7 +5541,7 @@ static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t } SSchema* pSchema = tscGetTableSchema(pTableMeta); - if ((pLeft->tokenId != TK_ARROW) && (!isTablenameToken(&pLeft->columnName)) && !IS_VAR_DATA_TYPE(pSchema[index].type)) { + if ((pLeft->tokenId != TK_ARROW) && (!isTablenameToken(&pLeft->columnName)) && !IS_VAR_DATA_TYPE(pSchema[idx].type)) { return invalidOperationMsg(msgBuf, msg2); } } @@ -5601,7 +5601,7 @@ static int32_t validateJsonTagExpr(tSqlExpr* pExpr, char* msgBuf) { } // check for match expression -static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t index, char* msgBuf) { +static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t idx, char* msgBuf) { const char* msg1 = "regular expression string should be less than %d characters"; const char* msg3 = "invalid regular expression"; @@ -5676,7 +5676,7 @@ void convertWhereStringCharset(tSqlExpr* pRight){ free(newData); } -static int32_t handleColumnInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SColumnIndex* index) { +static int32_t handleColumnInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SColumnIndex* idx) { const char* msg2 = "illegal column name"; int32_t ret = TSDB_CODE_SUCCESS; if (pExpr == NULL) { @@ -5685,11 +5685,11 @@ static int32_t handleColumnInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (isComparisonOperator(pExpr)) { return TSDB_CODE_TSC_INVALID_OPERATION; } - ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pLeft, index); + ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pLeft, idx); if( ret != TSDB_CODE_SUCCESS) { return ret; } - ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pRight, index); + ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pRight, idx); return ret; } @@ -5701,7 +5701,7 @@ static int32_t handleColumnInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS } if (colName) { - if (getColumnIndexByName(colName, pQueryInfo, index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(colName, pQueryInfo, idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } @@ -5729,51 +5729,51 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql int32_t ret = TSDB_CODE_SUCCESS; - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; if (!tSqlExprIsParentOfLeaf(*pExpr)) { - ret = handleColumnInQueryCond(pCmd, pQueryInfo, pLeft, &index); + ret = handleColumnInQueryCond(pCmd, pQueryInfo, pLeft, &idx); if (ret != TSDB_CODE_SUCCESS) { return ret; } - ret = handleColumnInQueryCond(pCmd, pQueryInfo, pRight, &index); + ret = handleColumnInQueryCond(pCmd, pQueryInfo, pRight, &idx); if (ret != TSDB_CODE_SUCCESS) { return ret; } } else { - if (getColumnIndexByName(colName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(colName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } - *tbIdx = index.tableIndex; + *tbIdx = idx.tableIndex; - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); // delete where condition check , column must ts or tag if (delData) { if (!((pSchema->colId == PRIMARYKEY_TIMESTAMP_COL_INDEX && pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || - index.columnIndex >= tscGetNumOfColumns(pTableMeta) || - index.columnIndex == TSDB_TBNAME_COLUMN_INDEX)) { + idx.columnIndex >= tscGetNumOfColumns(pTableMeta) || + idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } } // validate the null expression - int32_t code = validateNullExpr(*pExpr, pTableMeta, index.columnIndex, tscGetErrorMsgPayload(pCmd)); + int32_t code = validateNullExpr(*pExpr, pTableMeta, idx.columnIndex, tscGetErrorMsgPayload(pCmd)); if (code != TSDB_CODE_SUCCESS) { return code; } // validate the like expression - code = validateLikeExpr(*pExpr, pTableMeta, index.columnIndex, tscGetErrorMsgPayload(pCmd)); + code = validateLikeExpr(*pExpr, pTableMeta, idx.columnIndex, tscGetErrorMsgPayload(pCmd)); if (code != TSDB_CODE_SUCCESS) { return code; } // validate the match expression - code = validateMatchExpr(*pExpr, pTableMeta, index.columnIndex, tscGetErrorMsgPayload(pCmd)); + code = validateMatchExpr(*pExpr, pTableMeta, idx.columnIndex, tscGetErrorMsgPayload(pCmd)); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -5782,8 +5782,8 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql convertWhereStringCharset(pRight); } - if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // query on time range - if (!tSqlExprIsParentOfLeaf(*pExpr) || !validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) { + if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && idx.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // query on time range + if (!tSqlExprIsParentOfLeaf(*pExpr) || !validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &idx)) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -5792,8 +5792,8 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY); pCondExpr->tsJoin = true; - assert(index.tableIndex >= 0 && index.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); - SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; + assert(idx.tableIndex >= 0 && idx.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); + SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[idx.tableIndex]; if (*leftNode == NULL) { *leftNode = calloc(1, sizeof(SJoinNode)); if (*leftNode == NULL) { @@ -5801,17 +5801,17 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } } - int16_t leftIdx = index.tableIndex; + int16_t leftIdx = idx.tableIndex; - if (getColumnIndexByName(&pRight->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&pRight->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - if (index.tableIndex < 0 || index.tableIndex >= TSDB_MAX_JOIN_TABLE_NUM) { + if (idx.tableIndex < 0 || idx.tableIndex >= TSDB_MAX_JOIN_TABLE_NUM) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; + SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[idx.tableIndex]; if (*rightNode == NULL) { *rightNode = calloc(1, sizeof(SJoinNode)); if (*rightNode == NULL) { @@ -5819,7 +5819,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } } - int16_t rightIdx = index.tableIndex; + int16_t rightIdx = idx.tableIndex; if ((*leftNode)->tsJoin == NULL) { (*leftNode)->tsJoin = taosArrayInit(2, sizeof(int16_t)); @@ -5855,7 +5855,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } *pExpr = NULL; // remove this expression - } else if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + } else if (idx.columnIndex >= tscGetNumOfColumns(pTableMeta) || idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { // query on tags, check for tag query condition if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -5870,7 +5870,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } if (joinQuery && pRight != NULL && (pRight->tokenId == TK_ID || pRight->tokenId == TK_ARROW)) { // join on tag columns for stable query - if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) { + if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &idx)) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -6047,15 +6047,15 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* tSqlExpr* pLeft = (*pExpr)->pLeft; if (pLeft->tokenId == TK_ARROW || pLeft->tokenId == TK_ID) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; if(pLeft->tokenId == TK_ARROW) { pLeft = pLeft->pLeft; } - if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return; } - if (index.tableIndex != tableIndex) { + if (idx.tableIndex != tableIndex) { return; } } @@ -6181,12 +6181,12 @@ static int32_t convertTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return code; } } else { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pExpr->pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pExpr->pLeft->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); tSqlExpr* pRight = pExpr->pRight; @@ -6254,27 +6254,27 @@ static void cleanQueryExpr(SCondExpr* pCondExpr) { static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->ColName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->ColName, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (left)", pQueryInfo); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + idx.columnIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); + tscColumnListInsert(pTableMetaInfo->tagColList, &idx, &pSchema[idx.columnIndex]); - if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->ColName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->ColName, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (right)", pQueryInfo); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + idx.columnIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); + tscColumnListInsert(pTableMetaInfo->tagColList, &idx, &pSchema[idx.columnIndex]); } } */ @@ -6415,10 +6415,10 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE size_t num = taosArrayGetSize(colList); for(int32_t j = 0; j < num; ++j) { SColIndex* pIndex = taosArrayGet(colList, j); - SColumnIndex index = {.tableIndex = i, .columnIndex = pIndex->colIndex - numOfCols}; + SColumnIndex idx = {.tableIndex = i, .columnIndex = pIndex->colIndex - numOfCols}; SSchema* s = tscGetTableSchema(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMetaInfo->pTableMeta->id.uid, &s[pIndex->colIndex]); } @@ -7057,7 +7057,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq columnName.z = pVar->pz; } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; bool udf = false; if (pQueryInfo->pUdfInfo && taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) { @@ -7073,7 +7073,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // super table query - if (getColumnIndexByName(&columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsgBuf, msg1); } @@ -7081,8 +7081,8 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq bool orderByTS = false; bool orderByGroupbyCol = false; - if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { // order by tag1 - int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + if (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { // order by tag1 + int32_t relTagIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); // it is a tag column if (pQueryInfo->groupbyExpr.columnInfo == NULL) { @@ -7106,7 +7106,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq orderByTags = true; } } - } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { // order by tbname + } else if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { // order by tbname // it is a tag column if (pQueryInfo->groupbyExpr.columnInfo == NULL) { return invalidOperationMsg(pMsgBuf, msg4); @@ -7115,13 +7115,13 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (TSDB_TBNAME_COLUMN_INDEX == pColIndex->colIndex) { orderByTags = true; } - }else if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // order by ts + }else if (idx.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // order by ts orderByTS = true; }else{ // order by normal column SArray *columnInfo = pQueryInfo->groupbyExpr.columnInfo; if (columnInfo != NULL && taosArrayGetSize(columnInfo) > 0) { SColIndex* pColIndex = taosArrayGet(columnInfo, 0); - if (pColIndex->colIndex == index.columnIndex) { + if (pColIndex->colIndex == idx.columnIndex) { orderByGroupbyCol = true; } } @@ -7135,7 +7135,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (tscIsDiffDerivLikeQuery(pQueryInfo)) { return invalidOperationMsg(pMsgBuf, msg12); } - //pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + //pQueryInfo->groupbyExpr.orderIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); pQueryInfo->groupbyExpr.orderType = pItem->sortOrder; } else if (orderByGroupbyCol) { @@ -7154,12 +7154,12 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq pExpr = tscExprGet(pQueryInfo, pos); - if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colIndex != idx.columnIndex && idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(pMsgBuf, msg5); } pQueryInfo->order.order = pItem->sortOrder; - pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; + pQueryInfo->order.orderColId = pSchema[idx.columnIndex].colId; } else { if (udf) { return invalidOperationMsg(pMsgBuf, msg11); @@ -7185,27 +7185,27 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq cname.type = pVar->nType; cname.z = pVar->pz; } - if (getColumnIndexByName(&cname, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&cname, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsgBuf, msg1); } - if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(pMsgBuf, msg6); } pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; } } else if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo) || UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) { // check order by clause for normal table & temp table - if (getColumnIndexByName(&columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&columnName, pQueryInfo, &idx, pMsgBuf) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsgBuf, msg1); } - if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomUniqueQuery(pQueryInfo)){ + if (idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomUniqueQuery(pQueryInfo)){ bool validOrder = false; SArray *columnInfo = pQueryInfo->groupbyExpr.columnInfo; if (columnInfo != NULL && taosArrayGetSize(columnInfo) > 0) { SColIndex* pColIndex = taosArrayGet(columnInfo, 0); - validOrder = (pColIndex->colIndex == index.columnIndex); + validOrder = (pColIndex->colIndex == idx.columnIndex); } if (!validOrder) { @@ -7217,7 +7217,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (columnInfo != NULL && taosArrayGetSize(columnInfo) > 0) { /*SColIndex* pColIndex = taosArrayGet(columnInfo, 0); - if (pColIndex->colIndex != index.columnIndex) { + if (pColIndex->colIndex != idx.columnIndex) { return invalidOperationMsg(pMsgBuf, msg8); }*/ } else { @@ -7228,12 +7228,12 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq pExpr = tscExprGet(pQueryInfo, pos); - if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colIndex != idx.columnIndex && idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(pMsgBuf, msg5); } } pQueryInfo->order.order = pItem->sortOrder; - pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; + pQueryInfo->order.orderColId = pSchema[idx.columnIndex].colId; }else{ pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; @@ -7247,11 +7247,11 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq // inner subquery. assert(UTIL_TABLE_IS_TMP_TABLE(pTableMetaInfo) && taosArrayGetSize(pSqlNode->pSortOrder) == 1); - if (getColumnIndexByName(&columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&columnName, pQueryInfo, &idx, pMsgBuf) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsgBuf, msg1); } - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(pMsgBuf, msg1); } @@ -7263,7 +7263,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq bool found = false; for (int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); - if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == pSchema[index.columnIndex].colId) { + if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == pSchema[idx.columnIndex].colId) { found = true; break; } @@ -7271,7 +7271,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (!found) { int32_t numOfCols = (int32_t)tscNumOfFields(pQueryInfo); - tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &idx, pSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); SInternalField* pSupInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfCols); pSupInfo->visible = false; @@ -7281,7 +7281,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } pQueryInfo->order.order = pItem->sortOrder; - pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; + pQueryInfo->order.orderColId = pSchema[idx.columnIndex].colId; } return TSDB_CODE_SUCCESS; @@ -7394,17 +7394,17 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { return invalidOperationMsg(pMsg, msg9); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; SStrToken name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen}; - if (getColumnIndexByName(&name, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&name, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - if (index.columnIndex < numOfCols) { + if (idx.columnIndex < numOfCols) { return invalidOperationMsg(pMsg, msg10); - } else if (index.columnIndex == numOfCols) { + } else if (idx.columnIndex == numOfCols) { return invalidOperationMsg(pMsg, msg11); } @@ -8244,20 +8244,20 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau SSchema* pTagSchema = tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, colId); int16_t colIndex = tscGetTagColIndexById(pTableMetaInfo->pTableMeta, colId); - SColumnIndex index = {.tableIndex = 0, .columnIndex = colIndex}; + SColumnIndex idx = {.tableIndex = 0, .columnIndex = colIndex}; char* name = pTagSchema->name; int16_t type = pTagSchema->type; int16_t bytes = pTagSchema->bytes; - pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(&pSql->cmd), bytes, true); + pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TAG, &idx, type, bytes, getNewResColId(&pSql->cmd), bytes, true); pExpr->base.colInfo.flag = TSDB_COL_TAG; // NOTE: tag column does not add to source column list SColumnList ids = {0}; insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr); - int32_t relIndex = index.columnIndex; + int32_t relIndex = idx.columnIndex; pExpr->base.colInfo.colIndex = relIndex; SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0); @@ -8620,8 +8620,8 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo int32_t pos = tscGetFirstInvisibleFieldPos(pQueryInfo); - SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; - SExprInfo* pExpr = tscExprInsert(pQueryInfo, pos, f, &index, s->type, s->bytes, getNewResColId(pCmd), s->bytes, true); + SColumnIndex idx = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; + SExprInfo* pExpr = tscExprInsert(pQueryInfo, pos, f, &idx, s->type, s->bytes, getNewResColId(pCmd), s->bytes, true); // NOTE: tag column does not add to source column list SColumnList ids = createColumnList(1, 0, pColIndex->colIndex); insertResultField(pQueryInfo, pos, &ids, s->bytes, (int8_t)s->type, pColIndex->name, pExpr); @@ -8914,20 +8914,20 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq {"client_version()", 16}, {"current_user()", 14}}; - int32_t index = -1; + int32_t idx = -1; if (server_status == true) { - index = 2; + idx = 2; } else { for (int32_t i = 0; i < tListLen(functionsInfo); ++i) { if (strncasecmp(functionsInfo[i].name, pExpr->exprToken.z, functionsInfo[i].len) == 0 && functionsInfo[i].len == pExpr->exprToken.n) { - index = i; + idx = i; break; } } } - switch (index) { + switch (idx) { case 0: pQueryInfo->command = TSDB_SQL_CURRENT_DB;break; case 1: @@ -8946,7 +8946,7 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq tDataTypes[TSDB_DATA_TYPE_INT].bytes, getNewResColId(pCmd), tDataTypes[TSDB_DATA_TYPE_INT].bytes, false); tSqlExprItem* item = taosArrayGet(pExprList, 0); - const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[index].name; + const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[idx].name; tstrncpy(pExpr1->base.aliasName, name, tListLen(pExpr1->base.aliasName)); return TSDB_CODE_SUCCESS; @@ -9616,10 +9616,10 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect pParam = taosArrayGet(pSqlExpr->Expr.paramList, 0); SStrToken* pToken = &pParam->pNode->columnName; - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - getColumnIndexByName(pToken, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)); - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - schema = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + schema = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); } else { schema = (SSchema) {.colId = PRIMARYKEY_TIMESTAMP_COL_INDEX, .type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE}; } @@ -9639,15 +9639,15 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect // // if (tSqlExprCompare(pItem->pNode, pSqlExpr) == 0) { // exists, not added it, // -// SColumnIndex index = COLUMN_INDEX_INITIALIZER; +// SColumnIndex idx = COLUMN_INDEX_INITIALIZER; // int32_t functionId = pSqlExpr->functionId; // if (pSqlExpr->Expr.paramList == NULL) { -// index.columnIndex = 0; -// index.tableIndex = 0; +// idx.columnIndex = 0; +// idx.tableIndex = 0; // } else { // tSqlExprItem* pParamElem = taosArrayGet(pSqlExpr->Expr.paramList, 0); // SStrToken* pToken = &pParamElem->pNode->columnName; -// getColumnIndexByName(pToken, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)); +// getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)); // } // // size_t numOfNodeInSel = tscNumOfExprs(pQueryInfo); @@ -9658,7 +9658,7 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect // continue; // } // -// if (pExpr1->base.colInfo.colIndex != index.columnIndex) { +// if (pExpr1->base.colInfo.colIndex != idx.columnIndex) { // continue; // } // @@ -9847,16 +9847,16 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNode } if (pExpr1->tokenId == TK_ID) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if ((getColumnIndexByName(&pExpr1->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS)) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if ((getColumnIndexByName(&pExpr1->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - if (index.columnIndex <= 0 || - index.columnIndex >= tscGetNumOfColumns(pTableMeta)) { + if (idx.columnIndex <= 0 || + idx.columnIndex >= tscGetNumOfColumns(pTableMeta)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -10318,8 +10318,8 @@ static STableMeta* extractTempTableMetaFromSubquery(SQueryInfo* pUpstream) { return meta; } -static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SSqlObj* pSql, SQueryInfo* pQueryInfo, char* msgBuf) { - SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, index); +static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t idx, SSqlObj* pSql, SQueryInfo* pQueryInfo, char* msgBuf) { + SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, idx); // union all is not supported currently SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0); @@ -10776,15 +10776,15 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS } return ret; } else if (pSqlExpr->type == SQL_NODE_TABLE_COLUMN) { // column name, normal column arithmetic expression - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; - int32_t ret = getColumnIndexByName(&pSqlExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)); + int32_t ret = getColumnIndexByName(&pSqlExpr->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)); if (ret != TSDB_CODE_SUCCESS) { return ret; } - pQueryInfo->curTableIdx = index.tableIndex; - STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta; + pQueryInfo->curTableIdx = idx.tableIndex; + STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, idx.tableIndex)->pTableMeta; int32_t numOfColumns = tscGetNumOfColumns(pTableMeta); *pExpr = calloc(1, sizeof(tExprNode)); @@ -10793,14 +10793,14 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS SSchema* pSchema = NULL; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { pSchema = (*pExpr)->pSchema; strcpy(pSchema->name, tGetTbnameColumnSchema()->name); pSchema->type = tGetTbnameColumnSchema()->type; pSchema->colId = tGetTbnameColumnSchema()->colId; pSchema->bytes = tGetTbnameColumnSchema()->bytes; } else { - pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); *(*pExpr)->pSchema = *pSchema; } @@ -10808,8 +10808,8 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS SColIndex colIndex = {0}; tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name)); colIndex.colId = pSchema->colId; - colIndex.colIndex = index.columnIndex; - colIndex.flag = (index.columnIndex >= numOfColumns) ? 1 : 0; + colIndex.colIndex = idx.columnIndex; + colIndex.flag = (idx.columnIndex >= numOfColumns) ? 1 : 0; taosArrayPush(pCols, &colIndex); } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index e42f73fb32..c952bc2eb3 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -748,13 +748,13 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab int32_t vgId = -1; if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - int32_t index = pTableMetaInfo->vgroupIndex; - assert(index >= 0); + int32_t idx = pTableMetaInfo->vgroupIndex; + assert(idx >= 0); SVgroupMsg* pVgroupInfo = NULL; if (pTableMetaInfo->vgroupList && pTableMetaInfo->vgroupList->numOfVgroups > 0) { - assert(index < pTableMetaInfo->vgroupList->numOfVgroups); - pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[index]; + assert(idx < pTableMetaInfo->vgroupList->numOfVgroups); + pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[idx]; } else { tscError("0x%"PRIx64" No vgroup info found", pSql->self); @@ -764,7 +764,7 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab vgId = pVgroupInfo->vgId; tscSetDnodeEpSet(&pSql->epSet, pVgroupInfo); - tscDebug("0x%"PRIx64" query on stable, vgIndex:%d, numOfVgroups:%d", pSql->self, index, pTableMetaInfo->vgroupList->numOfVgroups); + tscDebug("0x%"PRIx64" query on stable, vgIndex:%d, numOfVgroups:%d", pSql->self, idx, pTableMetaInfo->vgroupList->numOfVgroups); } else { vgId = pTableMeta->vgId; @@ -786,11 +786,11 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab pQueryMsg->numOfTables = htonl(1); // set the number of tables pMsg += sizeof(STableIdInfo); } else { // it is a subquery of the super table query, this EP info is acquired from vgroupInfo - int32_t index = pTableMetaInfo->vgroupIndex; + int32_t idx = pTableMetaInfo->vgroupIndex; int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables); - assert(index >= 0 && index < numOfVgroups); + assert(idx >= 0 && idx < numOfVgroups); - SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, index); + SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, idx); // set the vgroup info tscSetDnodeEpSet(&pSql->epSet, &pTableIdList->vgInfo); @@ -800,7 +800,7 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab pQueryMsg->numOfTables = htonl(numOfTables); // set the number of tables tscDebug("0x%"PRIx64" query on stable, vgId:%d, numOfTables:%d, vgIndex:%d, numOfVgroups:%d", pSql->self, - pTableIdList->vgInfo.vgId, numOfTables, index, numOfVgroups); + pTableIdList->vgInfo.vgId, numOfTables, idx, numOfVgroups); // serialize each table id info for(int32_t i = 0; i < numOfTables; ++i) { @@ -1113,7 +1113,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pQueryMsg->tsBuf.tsOffset = htonl((int32_t)(pMsg - pCmd->payload)); if (pQueryInfo->tsBuf != NULL) { - // note: here used the index instead of actual vnode id. + // note: here used the idx instead of actual vnode id. int32_t vnodeIndex = pTableMetaInfo->vgroupIndex; code = dumpFileBlockByGroupId(pQueryInfo->tsBuf, vnodeIndex, pMsg, &pQueryMsg->tsBuf.tsLen, &pQueryMsg->tsBuf.tsNumOfBlocks); if (code != TSDB_CODE_SUCCESS) { @@ -1258,10 +1258,10 @@ int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } static bool tscIsAlterCommand(char* sqlstr) { - int32_t index = 0; + int32_t idx = 0; do { - SStrToken t0 = tStrGetToken(sqlstr, &index, false); + SStrToken t0 = tStrGetToken(sqlstr, &idx, false); if (t0.type != TK_LP) { return t0.type == TK_ALTER; } @@ -2643,18 +2643,18 @@ int tscProcessShowRsp(SSqlObj *pSql) { SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo; - SColumnIndex index = {0}; + SColumnIndex idx = {0}; pSchema = pMetaMsg->schema; uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; for (int16_t i = 0; i < pMetaMsg->numOfColumns; ++i, ++pSchema) { - index.columnIndex = i; + idx.columnIndex = i; tscColumnListInsert(pQueryInfo->colList, i, uid, pSchema); TAOS_FIELD f = tscCreateField(pSchema->type, pSchema->name, pSchema->bytes); SInternalField* pInfo = tscFieldInfoAppend(pFieldInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, pTableSchema[i].type, pTableSchema[i].bytes, getNewResColId(pCmd), pTableSchema[i].bytes, false); } @@ -3481,4 +3481,4 @@ void tscInitMsgsFp() { tscKeepConn[TSDB_SQL_SELECT] = 1; tscKeepConn[TSDB_SQL_FETCH] = 1; tscKeepConn[TSDB_SQL_HB] = 1; -} \ No newline at end of file +} diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 3fadc7abaf..5f1d996b54 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -30,7 +30,7 @@ typedef struct SInsertSupporter { SSqlObj* pSql; - int32_t index; + int32_t idx; } SInsertSupporter; static void freeJoinSubqueryObj(SSqlObj* pSql); @@ -84,14 +84,14 @@ static bool allSubqueryDone(SSqlObj *pParentSql) { for (int i = 0; i < subState->numOfSub; i++) { SSqlObj* pSub = pParentSql->pSubs[i]; if (0 == subState->states[i]) { - tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index: %d NOT finished yet", pParentSql->self, pSub->self, i); + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", idx: %d NOT finished yet", pParentSql->self, pSub->self, i); done = false; break; } else { if (pSub != NULL) { - tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index: %d finished", pParentSql->self, pSub->self, i); + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", idx: %d finished", pParentSql->self, pSub->self, i); } else { - tscDebug("0x%"PRIx64" subquery:%p, index: %d finished", pParentSql->self, pSub, i); + tscDebug("0x%"PRIx64" subquery:%p, idx: %d finished", pParentSql->self, pSub, i); } } } @@ -105,7 +105,7 @@ bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx) { pthread_mutex_lock(&subState->mutex); - tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index:%d state set to 1", pParentSql->self, pSql->self, idx); + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", idx:%d state set to 1", pParentSql->self, pSql->self, idx); subState->states[idx] = 1; bool done = allSubqueryDone(pParentSql); @@ -383,7 +383,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { // todo handle failed to create sub query -SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { +SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t idx) { SJoinSupporter* pSupporter = calloc(1, sizeof(SJoinSupporter)); if (pSupporter == NULL) { return NULL; @@ -391,7 +391,7 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { pSupporter->pObj = pSql->self; - pSupporter->subqueryIndex = index; + pSupporter->subqueryIndex = idx; SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); memcpy(&pSupporter->interval, &pQueryInfo->interval, sizeof(pSupporter->interval)); @@ -403,7 +403,7 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { pSupporter->numOfFillVal = pQueryInfo->numOfFillVal; } - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, index); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, idx); pSupporter->uid = pTableMetaInfo->pTableMeta->id.uid; assert (pSupporter->uid != 0); @@ -614,7 +614,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { * during the timestamp intersection. */ pSupporter->limit = pQueryInfo->limit; - SColumnIndex index = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; + SColumnIndex idx = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; SSchema* s = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, 0); SExprInfo* pExpr = tscExprGet(pQueryInfo, 0); @@ -626,7 +626,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { int16_t functionId = tscIsProjectionQuery(pQueryInfo)? TSDB_FUNC_PRJ : TSDB_FUNC_TS; - tscAddFuncInSelectClause(pQueryInfo, 0, functionId, &index, s, TSDB_COL_NORMAL, getNewResColId(&pNew->cmd)); + tscAddFuncInSelectClause(pQueryInfo, 0, functionId, &idx, s, TSDB_COL_NORMAL, getNewResColId(&pNew->cmd)); tscPrintSelNodeList(pNew, 0); tscFieldInfoUpdateOffset(pQueryInfo); @@ -836,8 +836,8 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = 1}; - SColumnIndex index = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - SExprInfo *pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &index, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + SColumnIndex idx = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + SExprInfo *pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &idx, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); // set the tags value for ts_comp function if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { @@ -1280,7 +1280,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow // todo retry if other subqueries are not failed assert(numOfRows < 0 && numOfRows == taos_errno(pSql)); - tscError("0x%"PRIx64" sub query failed, code:%s, index:%d", pSql->self, tstrerror(numOfRows), pSupporter->subqueryIndex); + tscError("0x%"PRIx64" sub query failed, code:%s, idx:%d", pSql->self, tstrerror(numOfRows), pSupporter->subqueryIndex); pParentSql->res.code = numOfRows; if (quitAllSubquery(pSql, pParentSql, pSupporter)) { @@ -1336,7 +1336,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow pTableMetaInfo->vgroupIndex += 1; assert(pTableMetaInfo->vgroupIndex < totalVgroups); - tscDebug("0x%"PRIx64" tid_tag from vgroup index:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%d", + tscDebug("0x%"PRIx64" tid_tag from vgroup idx:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%d", pSql->self, pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pSupporter->num); pCmd->command = TSDB_SQL_SELECT; @@ -1447,7 +1447,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow if (taos_errno(pSql) != TSDB_CODE_SUCCESS) { // todo retry if other subqueries are not failed yet assert(numOfRows < 0 && numOfRows == taos_errno(pSql)); - tscError("0x%"PRIx64" sub query failed, code:%s, index:%d", pSql->self, tstrerror(numOfRows), pSupporter->subqueryIndex); + tscError("0x%"PRIx64" sub query failed, code:%s, idx:%d", pSql->self, tstrerror(numOfRows), pSupporter->subqueryIndex); pParentSql->res.code = numOfRows; if (quitAllSubquery(pSql, pParentSql, pSupporter)){ @@ -1525,7 +1525,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow pTableMetaInfo->vgroupIndex += 1; assert(pTableMetaInfo->vgroupIndex < totalVgroups); - tscDebug("0x%"PRIx64" results from vgroup index:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%" PRId64, + tscDebug("0x%"PRIx64" results from vgroup idx:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%" PRId64, pSql->self, pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pRes->numOfClauseTotal); @@ -1610,7 +1610,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR assert(numOfRows == taos_errno(pSql)); pParentSql->res.code = numOfRows; - tscError("0x%"PRIx64" retrieve failed, index:%d, code:%s", pSql->self, pSupporter->subqueryIndex, tstrerror(numOfRows)); + tscError("0x%"PRIx64" retrieve failed, idx:%d, code:%s", pSql->self, pSupporter->subqueryIndex, tstrerror(numOfRows)); tscAsyncResultOnError(pParentSql); goto _return; @@ -1670,7 +1670,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR pParentSql->res.precision = pRes1->precision; if (pRes1->row > 0 && pRes1->numOfRows > 0) { - tscDebug("0x%"PRIx64" sub:0x%"PRIx64" index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql->self, + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" idx:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql->self, pParentSql->pSubs[i]->self, i, pRes1->numOfRows, pRes1->numOfTotal); assert(pRes1->row < pRes1->numOfRows || (pRes1->row == pRes1->numOfRows && pRes1->completed)); } else { @@ -1678,7 +1678,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR pRes1->numOfClauseTotal += pRes1->numOfRows; } - tscDebug("0x%"PRIx64" sub:0x%"PRIx64" index:%d numOfRows:%d total:%"PRId64, pParentSql->self, + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" idx:%d numOfRows:%d total:%"PRId64, pParentSql->self, pParentSql->pSubs[i]->self, i, pRes1->numOfRows, pRes1->numOfTotal); } } @@ -1879,7 +1879,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { } } -// all subqueries return, set the result output index +// all subqueries return, set the result output idx void tscSetupOutputColumnIndex(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; @@ -2567,7 +2567,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { int32_t numOfExprs = (int32_t) tscNumOfExprs(pQueryInfo); - int32_t index = 0; + int32_t idx = 0; for(int32_t i = 0; i < numOfExprs; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_TS && pQueryInfo->interval.interval > 0) { @@ -2576,7 +2576,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); - SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TS, &colIndex, schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, idx++, TSDB_FUNC_TS, &colIndex, schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); p->base.resColId = pExpr->base.resColId; // update the result column id } else if (pExpr->base.functionId == TSDB_FUNC_STDDEV_DST) { taosArrayPush(pSup->pColsInfo, &pExpr->base.resColId); @@ -2585,7 +2585,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { SSchema schema = {.type = TSDB_DATA_TYPE_DOUBLE, .bytes = sizeof(double)}; tstrncpy(schema.name, pExpr->base.aliasName, tListLen(schema.name)); - SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_AVG, &colIndex, &schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, idx++, TSDB_FUNC_AVG, &colIndex, &schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); p->base.resColId = pExpr->base.resColId; // update the result column id } else if (pExpr->base.functionId == TSDB_FUNC_TAG) { pSup->tagLen += pExpr->base.resBytes; @@ -2598,7 +2598,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { schema = tGetTbnameColumnSchema(); } - SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG, getNewResColId(pCmd)); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, idx++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG, getNewResColId(pCmd)); if (schema->type == TSDB_DATA_TYPE_JSON){ p->base.numOfParams = pExpr->base.numOfParams; tVariantAssign(&p->base.param[0], &pExpr->base.param[0]); @@ -2616,7 +2616,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); //doLimitOutputNormalColOfGroupby - SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_PRJ, &colIndex, schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, idx++, TSDB_FUNC_PRJ, &colIndex, schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); p->base.numOfParams = 1; p->base.param[0].i64 = 1; p->base.param[0].nType = TSDB_DATA_TYPE_INT; @@ -2658,7 +2658,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { "0x%"PRIx64" first round subquery:0x%"PRIx64" tableIndex:%d, vgroupIndex:%d, numOfVgroups:%d, type:%d, query to retrieve timestamps, " "numOfExpr:%" PRIzu ", colList:%d, numOfOutputFields:%d, name:%s", pSql->self, pNew->self, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pNewQueryInfo->type, - tscNumOfExprs(pNewQueryInfo), index+1, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); + tscNumOfExprs(pNewQueryInfo), idx+1, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); pSql->pSubs = calloc(1, POINTER_BYTES); if (pSql->pSubs == NULL) { @@ -3281,7 +3281,7 @@ SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsupport, SSq assert(trsupport->subqueryIndex < pSql->subState.numOfSub); - // launch subquery for each vnode, so the subquery index equals to the vgroupIndex. + // launch subquery for each vnode, so the subquery idx equals to the vgroupIndex. STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, table_index); pTableMetaInfo->vgroupIndex = trsupport->subqueryIndex; @@ -3411,7 +3411,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) } } - if (!subAndCheckDone(tres, pParentObj, pSupporter->index)) { + if (!subAndCheckDone(tres, pParentObj, pSupporter->idx)) { // concurrency problem, other thread already release pParentObj //tscDebug("0x%"PRIx64" insert:%p,%d completed, total:%d", pParentObj->self, tres, suppIdx, pParentObj->subState.numOfSub); return; @@ -3495,9 +3495,9 @@ int32_t tscHandleInsertRetry(SSqlObj* pParent, SSqlObj* pSql) { SSqlRes* pRes = &pSql->res; SInsertSupporter* pSupporter = (SInsertSupporter*) pSql->param; - assert(pSupporter->index < pSupporter->pSql->subState.numOfSub); + assert(pSupporter->idx < pSupporter->pSql->subState.numOfSub); - STableDataBlocks* pTableDataBlock = taosArrayGetP(pParent->cmd.insertParam.pDataBlocks, pSupporter->index); + STableDataBlocks* pTableDataBlock = taosArrayGetP(pParent->cmd.insertParam.pDataBlocks, pSupporter->idx); int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock); if ((pRes->code = code)!= TSDB_CODE_SUCCESS) { @@ -3524,7 +3524,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) { SSqlObj* pSub = pSql->pSubs[i]; SInsertSupporter* pSup = calloc(1, sizeof(SInsertSupporter)); - pSup->index = i; + pSup->idx = i; pSup->pSql = pSql; pSub->param = pSup; @@ -3572,7 +3572,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { } pSupporter->pSql = pSql; - pSupporter->index = numOfSub; + pSupporter->idx = numOfSub; SSqlObj *pNew = createSimpleSubObj(pSql, multiVnodeInsertFinalize, pSupporter, TSDB_SQL_INSERT); if (pNew == NULL) { @@ -3763,19 +3763,19 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { char * getScalarExprInputSrc(void *param, const char *name, int32_t colId) { SScalarExprSupport*pSupport = (SScalarExprSupport*) param; - int32_t index = -1; + int32_t idx = -1; SExprInfo* pExpr = NULL; for (int32_t i = 0; i < pSupport->numOfCols; ++i) { pExpr = taosArrayGetP(pSupport->exprList, i); if (strncmp(name, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1) == 0) { - index = i; + idx = i; break; } } - assert(index >= 0 && index < pSupport->numOfCols); - return pSupport->data[index] + pSupport->offset * pExpr->base.resBytes; + assert(idx >= 0 && idx < pSupport->numOfCols); + return pSupport->data[idx] + pSupport->offset * pExpr->base.resBytes; } TAOS_ROW doSetResultRowData(SSqlObj *pSql) { @@ -3815,7 +3815,7 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql) { j += 1; } - pRes->row++; // index increase one-step + pRes->row++; // idx increase one-step return pRes->tsrow; } @@ -3959,7 +3959,7 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr pthread_mutex_init(&pQInfo->lock, NULL); tsem_init(&pQInfo->ready, 0, 0); - int32_t index = 0; + int32_t idx = 0; for(int32_t i = 0; i < numOfGroups; ++i) { SArray* pa = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); @@ -3976,7 +3976,7 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr STableKeyInfo* info = taosArrayGet(pa, j); window.skey = info->lastKey; - void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo); + void* buf = (char*) pQInfo->pBuf + idx * sizeof(STableQueryInfo); STableQueryInfo* item = createTableQueryInfo(pQueryAttr, info->pTable, pQueryAttr->groupbyColumn, window, buf); if (item == NULL) { goto _cleanup; @@ -3987,7 +3987,7 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr STableId id = {.tid = 0, .uid = 0}; taosHashPut(pRuntimeEnv->tableqinfoGroupInfo.map, &id.tid, sizeof(id.tid), &item, POINTER_BYTES); - index += 1; + idx += 1; } } diff --git a/src/client/src/tscSystem.c b/src/client/src/tscSystem.c index d5369e38f0..d2dcf041fb 100644 --- a/src/client/src/tscSystem.c +++ b/src/client/src/tscSystem.c @@ -87,24 +87,24 @@ int32_t tscAcquireRpc(const char *key, const char *user, const char *secretEncry return 0; } - SRpcInit rpcInit; - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = 0; - rpcInit.label = "TSC"; - rpcInit.numOfThreads = tscNumOfThreads; - rpcInit.cfp = tscProcessMsgFromServer; - rpcInit.sessions = tsMaxConnections; - rpcInit.connType = TAOS_CONN_CLIENT; - rpcInit.user = (char *)user; - rpcInit.idleTime = tsShellActivityTimer * 1000; - rpcInit.ckey = "key"; - rpcInit.spi = 1; - rpcInit.secret = (char *)secretEncrypt; + SRpcInit rpcInitial; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = 0; + rpcInitial.label = "TSC"; + rpcInitial.numOfThreads = tscNumOfThreads; + rpcInitial.cfp = tscProcessMsgFromServer; + rpcInitial.sessions = tsMaxConnections; + rpcInitial.connType = TAOS_CONN_CLIENT; + rpcInitial.user = (char *)user; + rpcInitial.idleTime = tsShellActivityTimer * 1000; + rpcInitial.ckey = "key"; + rpcInitial.spi = 1; + rpcInitial.secret = (char *)secretEncrypt; SRpcObj rpcObj; memset(&rpcObj, 0, sizeof(rpcObj)); tstrncpy(rpcObj.key, key, sizeof(rpcObj.key)); - rpcObj.pDnodeConn = rpcOpen(&rpcInit); + rpcObj.pDnodeConn = rpcOpen(&rpcInitial); if (rpcObj.pDnodeConn == NULL) { pthread_mutex_unlock(&rpcObjMutex); tscError("failed to init connection to server"); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index cfcf2f63ee..01691249c1 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -2305,10 +2305,10 @@ void tscCloseTscObj(void *param) { } bool tscIsInsertData(char* sqlstr) { - int32_t index = 0; + int32_t idx = 0; do { - SStrToken t0 = tStrGetToken(sqlstr, &index, false); + SStrToken t0 = tStrGetToken(sqlstr, &idx, false); if (t0.type != TK_LP) { return t0.type == TK_INSERT || t0.type == TK_IMPORT; } @@ -2378,12 +2378,12 @@ SInternalField* tscFieldInfoAppend(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) { return taosArrayPush(pFieldInfo->internalField, &info); } -SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIELD* field) { +SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t idx, TAOS_FIELD* field) { pFieldInfo->numOfOutput++; struct SInternalField info = { .pExpr = NULL, .visible = true }; info.field = *field; - return taosArrayInsert(pFieldInfo->internalField, index, &info); + return taosArrayInsert(pFieldInfo->internalField, idx, &info); } void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo) { @@ -2398,18 +2398,18 @@ void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo) { } } -SInternalField* tscFieldInfoGetInternalField(SFieldInfo* pFieldInfo, int32_t index) { - assert(index < pFieldInfo->numOfOutput); - return TARRAY_GET_ELEM(pFieldInfo->internalField, index); +SInternalField* tscFieldInfoGetInternalField(SFieldInfo* pFieldInfo, int32_t idx) { + assert(idx < pFieldInfo->numOfOutput); + return TARRAY_GET_ELEM(pFieldInfo->internalField, idx); } -TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) { - assert(index < pFieldInfo->numOfOutput); - return &((SInternalField*)TARRAY_GET_ELEM(pFieldInfo->internalField, index))->field; +TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t idx) { + assert(idx < pFieldInfo->numOfOutput); + return &((SInternalField*)TARRAY_GET_ELEM(pFieldInfo->internalField, idx))->field; } -int32_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) { - SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, index); +int32_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t idx) { + SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, idx); assert(pInfo != NULL && pInfo->pExpr->pExpr == NULL); return pInfo->pExpr->base.offset; @@ -2635,16 +2635,16 @@ SExprInfo* tscExprCreate(STableMetaInfo* pTableMetaInfo, int16_t functionId, SCo return pExpr; } -SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t idx, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int32_t interSize, bool isTagCol) { int32_t num = (int32_t)taosArrayGetSize(pQueryInfo->exprList); - if (index == num) { + if (idx == num) { return tscExprAppend(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pColIndex->tableIndex); SExprInfo* pExpr = tscExprCreate(pTableMetaInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); - taosArrayInsert(pQueryInfo->exprList, index, &pExpr); + taosArrayInsert(pQueryInfo->exprList, idx, &pExpr); return pExpr; } @@ -2656,10 +2656,10 @@ SExprInfo* tscExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnInde return pExpr; } -SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, +SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t idx, int16_t functionId, int16_t srcColumnIndex, int16_t type, int32_t size) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - SExprInfo* pExpr = tscExprGet(pQueryInfo, index); + SExprInfo* pExpr = tscExprGet(pQueryInfo, idx); if (pExpr == NULL) { return NULL; } @@ -2676,8 +2676,8 @@ SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t function return pExpr; } -bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t index) { - if (!UTIL_TABLE_IS_SUPER_TABLE(pQueryInfo->pTableMetaInfo[index])) { +bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t idx) { + if (!UTIL_TABLE_IS_SUPER_TABLE(pQueryInfo->pTableMetaInfo[idx])) { return false; } @@ -2725,8 +2725,8 @@ void tscExprAddParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t byt assert(pExpr->numOfParams <= 3); } -SExprInfo* tscExprGet(SQueryInfo* pQueryInfo, int32_t index) { - return taosArrayGetP(pQueryInfo->exprList, index); +SExprInfo* tscExprGet(SQueryInfo* pQueryInfo, int32_t idx) { + return taosArrayGetP(pQueryInfo->exprList, idx); } /* @@ -3297,8 +3297,8 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) { if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - int16_t index = pExpr->base.colInfo.colIndex; - pColInfo[i].type = (index != -1) ? pTagSchema[index].type : TSDB_DATA_TYPE_BINARY; + int16_t idx = pExpr->base.colInfo.colIndex; + pColInfo[i].type = (idx != -1) ? pTagSchema[idx].type : TSDB_DATA_TYPE_BINARY; } else { pColInfo[i].type = pSchema[pExpr->base.colInfo.colIndex].type; } @@ -3381,7 +3381,7 @@ SQueryInfo* tscGetQueryInfoS(SSqlCmd* pCmd) { return pQueryInfo; } -STableMetaInfo* tscGetTableMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, int32_t* index) { +STableMetaInfo* tscGetTableMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, int32_t* idx) { int32_t k = -1; for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { @@ -3391,8 +3391,8 @@ STableMetaInfo* tscGetTableMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, i } } - if (index != NULL) { - *index = k; + if (idx != NULL) { + *idx = k; } assert(k != -1); @@ -3615,19 +3615,19 @@ void tscFreeVgroupTableInfo(SArray* pVgroupTables) { taosArrayDestroy(&pVgroupTables); } -void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index) { - assert(pVgroupTable != NULL && index >= 0); +void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t idx) { + assert(pVgroupTable != NULL && idx >= 0); size_t size = taosArrayGetSize(pVgroupTable); - assert(size > index); + assert(size > idx); - SVgroupTableInfo* pInfo = taosArrayGet(pVgroupTable, index); + SVgroupTableInfo* pInfo = taosArrayGet(pVgroupTable, idx); // for(int32_t j = 0; j < pInfo->vgInfo.numOfEps; ++j) { // tfree(pInfo->vgInfo.epAddr[j].fqdn); // } taosArrayDestroy(&pInfo->itemList); - taosArrayRemove(pVgroupTable, index); + taosArrayRemove(pVgroupTable, idx); } void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo) { @@ -4102,15 +4102,15 @@ static void tscSubqueryRetrieveCallback(void* param, TAOS_RES* tres, int code) { SSqlObj* pParentSql = ps->pParentSql; SSqlObj* pSql = tres; - int32_t index = ps->subqueryIndex; - bool ret = subAndCheckDone(pSql, pParentSql, index); + int32_t idx = ps->subqueryIndex; + bool ret = subAndCheckDone(pSql, pParentSql, idx); // TODO refactor tfree(ps); pSql->param = NULL; if (!ret) { - tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, index); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, idx); return; } @@ -4131,13 +4131,13 @@ static void tscSubqueryCompleteCallback(void* param, TAOS_RES* tres, int code) { if (pSql->res.code != TSDB_CODE_SUCCESS) { SSqlObj* pParentSql = ps->pParentSql; - int32_t index = ps->subqueryIndex; - bool ret = subAndCheckDone(pSql, pParentSql, index); + int32_t idx = ps->subqueryIndex; + bool ret = subAndCheckDone(pSql, pParentSql, idx); tscFreeRetrieveSup(&pSql->param); if (!ret) { - tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, index); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, idx); return; } diff --git a/src/common/src/tarithoperator.c b/src/common/src/tarithoperator.c index ca5d247dd6..71702e1249 100644 --- a/src/common/src/tarithoperator.c +++ b/src/common/src/tarithoperator.c @@ -60,40 +60,40 @@ void calc_i32_i32_add(void *left, void *right, int32_t numLeft, int32_t numRight } } -typedef double (*_arithmetic_getVectorDoubleValue_fn_t)(void *src, int32_t index); +typedef double (*_arithmetic_getVectorDoubleValue_fn_t)(void *src, int32_t idx); -double getVectorDoubleValue_TINYINT(void *src, int32_t index) { - return (double)*((int8_t *)src + index); +double getVectorDoubleValue_TINYINT(void *src, int32_t idx) { + return (double)*((int8_t *)src + idx); } -double getVectorDoubleValue_UTINYINT(void *src, int32_t index) { - return (double)*((uint8_t *)src + index); +double getVectorDoubleValue_UTINYINT(void *src, int32_t idx) { + return (double)*((uint8_t *)src + idx); } -double getVectorDoubleValue_SMALLINT(void *src, int32_t index) { - return (double)*((int16_t *)src + index); +double getVectorDoubleValue_SMALLINT(void *src, int32_t idx) { + return (double)*((int16_t *)src + idx); } -double getVectorDoubleValue_USMALLINT(void *src, int32_t index) { - return (double)*((uint16_t *)src + index); +double getVectorDoubleValue_USMALLINT(void *src, int32_t idx) { + return (double)*((uint16_t *)src + idx); } -double getVectorDoubleValue_INT(void *src, int32_t index) { - return (double)*((int32_t *)src + index); +double getVectorDoubleValue_INT(void *src, int32_t idx) { + return (double)*((int32_t *)src + idx); } -double getVectorDoubleValue_UINT(void *src, int32_t index) { - return (double)*((uint32_t *)src + index); +double getVectorDoubleValue_UINT(void *src, int32_t idx) { + return (double)*((uint32_t *)src + idx); } -double getVectorDoubleValue_BIGINT(void *src, int32_t index) { - return (double)*((int64_t *)src + index); +double getVectorDoubleValue_BIGINT(void *src, int32_t idx) { + return (double)*((int64_t *)src + idx); } -double getVectorDoubleValue_UBIGINT(void *src, int32_t index) { - return (double)*((uint64_t *)src + index); +double getVectorDoubleValue_UBIGINT(void *src, int32_t idx) { + return (double)*((uint64_t *)src + idx); } -double getVectorDoubleValue_FLOAT(void *src, int32_t index) { - return (double)*((float *)src + index); +double getVectorDoubleValue_FLOAT(void *src, int32_t idx) { + return (double)*((float *)src + idx); } -double getVectorDoubleValue_DOUBLE(void *src, int32_t index) { - return (double)*((double *)src + index); +double getVectorDoubleValue_DOUBLE(void *src, int32_t idx) { + return (double)*((double *)src + idx); } -int64_t getVectorTimestampValue(void *src, int32_t index) { - return (int64_t)*((int64_t *)src + index); +int64_t getVectorTimestampValue(void *src, int32_t idx) { + return (int64_t)*((int64_t *)src + idx); } _arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) { _arithmetic_getVectorDoubleValue_fn_t p = NULL; @@ -124,40 +124,40 @@ _arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) { } -typedef void* (*_arithmetic_getVectorValueAddr_fn_t)(void *src, int32_t index); +typedef void* (*_arithmetic_getVectorValueAddr_fn_t)(void *src, int32_t idx); -void* getVectorValueAddr_BOOL(void *src, int32_t index) { - return (void*)((bool *)src + index); +void* getVectorValueAddr_BOOL(void *src, int32_t idx) { + return (void*)((bool *)src + idx); } -void* getVectorValueAddr_TINYINT(void *src, int32_t index) { - return (void*)((int8_t *)src + index); +void* getVectorValueAddr_TINYINT(void *src, int32_t idx) { + return (void*)((int8_t *)src + idx); } -void* getVectorValueAddr_UTINYINT(void *src, int32_t index) { - return (void*)((uint8_t *)src + index); +void* getVectorValueAddr_UTINYINT(void *src, int32_t idx) { + return (void*)((uint8_t *)src + idx); } -void* getVectorValueAddr_SMALLINT(void *src, int32_t index) { - return (void*)((int16_t *)src + index); +void* getVectorValueAddr_SMALLINT(void *src, int32_t idx) { + return (void*)((int16_t *)src + idx); } -void* getVectorValueAddr_USMALLINT(void *src, int32_t index) { - return (void*)((uint16_t *)src + index); +void* getVectorValueAddr_USMALLINT(void *src, int32_t idx) { + return (void*)((uint16_t *)src + idx); } -void* getVectorValueAddr_INT(void *src, int32_t index) { - return (void*)((int32_t *)src + index); +void* getVectorValueAddr_INT(void *src, int32_t idx) { + return (void*)((int32_t *)src + idx); } -void* getVectorValueAddr_UINT(void *src, int32_t index) { - return (void*)((uint32_t *)src + index); +void* getVectorValueAddr_UINT(void *src, int32_t idx) { + return (void*)((uint32_t *)src + idx); } -void* getVectorValueAddr_BIGINT(void *src, int32_t index) { - return (void*)((int64_t *)src + index); +void* getVectorValueAddr_BIGINT(void *src, int32_t idx) { + return (void*)((int64_t *)src + idx); } -void* getVectorValueAddr_UBIGINT(void *src, int32_t index) { - return (void*)((uint64_t *)src + index); +void* getVectorValueAddr_UBIGINT(void *src, int32_t idx) { + return (void*)((uint64_t *)src + idx); } -void* getVectorValueAddr_FLOAT(void *src, int32_t index) { - return (void*)((float *)src + index); +void* getVectorValueAddr_FLOAT(void *src, int32_t idx) { + return (void*)((float *)src + idx); } -void* getVectorValueAddr_DOUBLE(void *src, int32_t index) { - return (void*)((double *)src + index); +void* getVectorValueAddr_DOUBLE(void *src, int32_t idx) { + return (void*)((double *)src + idx); } _arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) { @@ -474,34 +474,34 @@ void vectorRemainder(void *left, int32_t len1, int32_t _left_type, void *right, } } -typedef int64_t (*_arithmetic_getVectorBigintValue_fn_t)(void *src, int32_t index); +typedef int64_t (*_arithmetic_getVectorBigintValue_fn_t)(void *src, int32_t idx); -int64_t getVectorBigintValue_BOOL(void *src, int32_t index) { - return (int64_t)*((bool *)src + index); +int64_t getVectorBigintValue_BOOL(void *src, int32_t idx) { + return (int64_t)*((bool *)src + idx); } -int64_t getVectorBigintValue_TINYINT(void *src, int32_t index) { - return (int64_t)*((int8_t *)src + index); +int64_t getVectorBigintValue_TINYINT(void *src, int32_t idx) { + return (int64_t)*((int8_t *)src + idx); } -int64_t getVectorBigintValue_UTINYINT(void *src, int32_t index) { - return (int64_t)*((uint8_t *)src + index); +int64_t getVectorBigintValue_UTINYINT(void *src, int32_t idx) { + return (int64_t)*((uint8_t *)src + idx); } -int64_t getVectorBigintValue_SMALLINT(void *src, int32_t index) { - return (int64_t)*((int16_t *)src + index); +int64_t getVectorBigintValue_SMALLINT(void *src, int32_t idx) { + return (int64_t)*((int16_t *)src + idx); } -int64_t getVectorBigintValue_USMALLINT(void *src, int32_t index) { - return (int64_t)*((uint16_t *)src + index); +int64_t getVectorBigintValue_USMALLINT(void *src, int32_t idx) { + return (int64_t)*((uint16_t *)src + idx); } -int64_t getVectorBigintValue_INT(void *src, int32_t index) { - return (int64_t)*((int32_t *)src + index); +int64_t getVectorBigintValue_INT(void *src, int32_t idx) { + return (int64_t)*((int32_t *)src + idx); } -int64_t getVectorBigintValue_UINT(void *src, int32_t index) { - return (int64_t)*((uint32_t *)src + index); +int64_t getVectorBigintValue_UINT(void *src, int32_t idx) { + return (int64_t)*((uint32_t *)src + idx); } -int64_t getVectorBigintValue_BIGINT(void *src, int32_t index) { - return (int64_t)*((int64_t *)src + index); +int64_t getVectorBigintValue_BIGINT(void *src, int32_t idx) { + return (int64_t)*((int64_t *)src + idx); } -int64_t getVectorBigintValue_UBIGINT(void *src, int32_t index) { - return (int64_t)*((uint64_t *)src + index); +int64_t getVectorBigintValue_UBIGINT(void *src, int32_t idx) { + return (int64_t)*((uint64_t *)src + idx); } _arithmetic_getVectorBigintValue_fn_t getVectorBigintValueFn(int32_t srcType) { diff --git a/src/common/src/tdataformat.c b/src/common/src/tdataformat.c index 55afd4c620..4786700f97 100644 --- a/src/common/src/tdataformat.c +++ b/src/common/src/tdataformat.c @@ -304,14 +304,14 @@ bool isNEleNull(SDataCol *pCol, int nEle) { return true; } -static FORCE_INLINE void dataColSetNullAt(SDataCol *pCol, int index) { +static FORCE_INLINE void dataColSetNullAt(SDataCol *pCol, int idx) { if (IS_VAR_DATA_TYPE(pCol->type)) { - pCol->dataOff[index] = pCol->len; + pCol->dataOff[idx] = pCol->len; char *ptr = POINTER_SHIFT(pCol->pData, pCol->len); setVardataNull(ptr, pCol->type); pCol->len += varDataTLen(ptr); } else { - setNull(POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * index), pCol->type, pCol->bytes); + setNull(POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * idx), pCol->type, pCol->bytes); pCol->len += TYPE_BYTES[pCol->type]; } } diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 2b8c2bbb66..44a53efd8c 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -397,10 +397,10 @@ bool taosCfgDynamicOptions(char *msg) { return false; } -void taosAddDataDir(int index, char *v1, int level, int primary) { - tstrncpy(tsDiskCfg[index].dir, v1, TSDB_FILENAME_LEN); - tsDiskCfg[index].level = level; - tsDiskCfg[index].primary = primary; +void taosAddDataDir(int idx, char *v1, int level, int primary) { + tstrncpy(tsDiskCfg[idx].dir, v1, TSDB_FILENAME_LEN); + tsDiskCfg[idx].level = level; + tsDiskCfg[idx].primary = primary; uTrace("dataDir:%s, level:%d primary:%d is configured", v1, level, primary); } diff --git a/src/common/src/tname.c b/src/common/src/tname.c index 521dcffa6c..7653df3879 100644 --- a/src/common/src/tname.c +++ b/src/common/src/tname.c @@ -442,29 +442,29 @@ void tNameAssign(SName* dst, const SName* src) { memcpy(dst, src, sizeof(SName)); } -int32_t tNameSetDbName(SName* dst, const char* acct, SStrToken* dbToken) { - assert(dst != NULL && dbToken != NULL && acct != NULL); +int32_t tNameSetDbName(SName* dst, const char* accnt, SStrToken* dbToken) { + assert(dst != NULL && dbToken != NULL && accnt != NULL); // too long account id or too long db name - if (strlen(acct) >= tListLen(dst->acctId) || dbToken->n >= tListLen(dst->dbname)) { + if (strlen(accnt) >= tListLen(dst->acctId) || dbToken->n >= tListLen(dst->dbname)) { return -1; } dst->type = TSDB_DB_NAME_T; - tstrncpy(dst->acctId, acct, tListLen(dst->acctId)); + tstrncpy(dst->acctId, accnt, tListLen(dst->acctId)); tstrncpy(dst->dbname, dbToken->z, dbToken->n + 1); return 0; } -int32_t tNameSetAcctId(SName* dst, const char* acct) { - assert(dst != NULL && acct != NULL); +int32_t tNameSetAcctId(SName* dst, const char* accnt) { + assert(dst != NULL && accnt != NULL); // too long account id or too long db name - if (strlen(acct) >= tListLen(dst->acctId)) { + if (strlen(accnt) >= tListLen(dst->acctId)) { return -1; } - tstrncpy(dst->acctId, acct, tListLen(dst->acctId)); + tstrncpy(dst->acctId, accnt, tListLen(dst->acctId)); assert(strlen(dst->acctId) > 0); diff --git a/src/common/src/ttypes.c b/src/common/src/ttypes.c index 81bc9c7275..fa4126350c 100644 --- a/src/common/src/ttypes.c +++ b/src/common/src/ttypes.c @@ -259,8 +259,8 @@ static void getStatics_u64(const void *pData, int32_t numOfRow, int64_t *min, in static void getStatics_f(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max, int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) { float *data = (float *)pData; - float fmin = FLT_MAX; - float fmax = -FLT_MAX; + float flmin = FLT_MAX; + float flmax = -FLT_MAX; double dsum = 0; *minIndex = 0; *maxIndex = 0; @@ -276,20 +276,20 @@ static void getStatics_f(const void *pData, int32_t numOfRow, int64_t *min, int6 float fv = GET_FLOAT_VAL((const char*)&(data[i])); dsum += fv; - if (fmin > fv) { - fmin = fv; + if (flmin > fv) { + flmin = fv; *minIndex = i; } - if (fmax < fv) { - fmax = fv; + if (flmax < fv) { + flmax = fv; *maxIndex = i; } } SET_DOUBLE_VAL(sum, dsum); - SET_DOUBLE_VAL(max, fmax); - SET_DOUBLE_VAL(min, fmin); + SET_DOUBLE_VAL(max, flmax); + SET_DOUBLE_VAL(min, flmin); } static void getStatics_d(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max, diff --git a/src/dnode/src/dnodeCheck.c b/src/dnode/src/dnodeCheck.c index 87baff3067..f0218fdba9 100644 --- a/src/dnode/src/dnodeCheck.c +++ b/src/dnode/src/dnodeCheck.c @@ -229,12 +229,12 @@ static void dnodeAllocCheckItem() { } void dnodeCleanupCheck() { - for (ECheckItemType index = 0; index < TSDB_CHECK_ITEM_MAX; ++index) { - if (tsCheckItem[index].enable && tsCheckItem[index].stopFp) { - (*tsCheckItem[index].stopFp)(); + for (ECheckItemType idx = 0; idx < TSDB_CHECK_ITEM_MAX; ++idx) { + if (tsCheckItem[idx].enable && tsCheckItem[idx].stopFp) { + (*tsCheckItem[idx].stopFp)(); } - if (tsCheckItem[index].cleanUpFp) { - (*tsCheckItem[index].cleanUpFp)(); + if (tsCheckItem[idx].cleanUpFp) { + (*tsCheckItem[idx].cleanUpFp)(); } } } @@ -242,19 +242,19 @@ void dnodeCleanupCheck() { int32_t dnodeInitCheck() { dnodeAllocCheckItem(); - for (ECheckItemType index = 0; index < TSDB_CHECK_ITEM_MAX; ++index) { - if (tsCheckItem[index].initFp) { - if ((*tsCheckItem[index].initFp)() != 0) { - dError("failed to init check item:%s", tsCheckItem[index].name); + for (ECheckItemType idx = 0; idx < TSDB_CHECK_ITEM_MAX; ++idx) { + if (tsCheckItem[idx].initFp) { + if ((*tsCheckItem[idx].initFp)() != 0) { + dError("failed to init check item:%s", tsCheckItem[idx].name); return -1; } } } - for (ECheckItemType index = 0; index < TSDB_CHECK_ITEM_MAX; ++index) { - if (tsCheckItem[index].enable && tsCheckItem[index].startFp) { - if ((*tsCheckItem[index].startFp)() != 0) { - dError("failed to check item:%s", tsCheckItem[index].name); + for (ECheckItemType idx = 0; idx < TSDB_CHECK_ITEM_MAX; ++idx) { + if (tsCheckItem[idx].enable && tsCheckItem[idx].startFp) { + if ((*tsCheckItem[idx].startFp)() != 0) { + dError("failed to check item:%s", tsCheckItem[idx].name); exit(-1); } } diff --git a/src/dnode/src/dnodePeer.c b/src/dnode/src/dnodePeer.c index 08269c0bf6..cc1b1c98aa 100644 --- a/src/dnode/src/dnodePeer.c +++ b/src/dnode/src/dnodePeer.c @@ -56,17 +56,17 @@ int32_t dnodeInitServer() { dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_GRANT] = dnodeDispatchToMPeerQueue; dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_STATUS] = dnodeDispatchToMPeerQueue; - SRpcInit rpcInit; - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = tsDnodeDnodePort; - rpcInit.label = "DND-S"; - rpcInit.numOfThreads = 1; - rpcInit.cfp = dnodeProcessReqMsgFromDnode; - rpcInit.sessions = TSDB_MAX_VNODES << 4; - rpcInit.connType = TAOS_CONN_SERVER; - rpcInit.idleTime = tsShellActivityTimer * 1000; - - tsServerRpc = rpcOpen(&rpcInit); + SRpcInit rpcInitial; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = tsDnodeDnodePort; + rpcInitial.label = "DND-S"; + rpcInitial.numOfThreads = 1; + rpcInitial.cfp = dnodeProcessReqMsgFromDnode; + rpcInitial.sessions = TSDB_MAX_VNODES << 4; + rpcInitial.connType = TAOS_CONN_SERVER; + rpcInitial.idleTime = tsShellActivityTimer * 1000; + + tsServerRpc = rpcOpen(&rpcInitial); if (tsServerRpc == NULL) { dError("failed to init inter-dnodes RPC server"); return -1; @@ -123,19 +123,19 @@ static void dnodeProcessReqMsgFromDnode(SRpcMsg *pMsg, SRpcEpSet *pEpSet) { int32_t dnodeInitClient() { char secret[TSDB_KEY_LEN] = "secret"; - SRpcInit rpcInit; - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.label = "DND-C"; - rpcInit.numOfThreads = 1; - rpcInit.cfp = dnodeProcessRspFromDnode; - rpcInit.sessions = TSDB_MAX_VNODES << 4; - rpcInit.connType = TAOS_CONN_CLIENT; - rpcInit.idleTime = tsShellActivityTimer * 1000; - rpcInit.user = "t"; - rpcInit.ckey = "key"; - rpcInit.secret = secret; - - tsClientRpc = rpcOpen(&rpcInit); + SRpcInit rpcInitial; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.label = "DND-C"; + rpcInitial.numOfThreads = 1; + rpcInitial.cfp = dnodeProcessRspFromDnode; + rpcInitial.sessions = TSDB_MAX_VNODES << 4; + rpcInitial.connType = TAOS_CONN_CLIENT; + rpcInitial.idleTime = tsShellActivityTimer * 1000; + rpcInitial.user = "t"; + rpcInitial.ckey = "key"; + rpcInitial.secret = secret; + + tsClientRpc = rpcOpen(&rpcInitial); if (tsClientRpc == NULL) { dError("failed to init mnode rpc client"); return -1; diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c index 7676343b37..26a2fc9651 100644 --- a/src/dnode/src/dnodeShell.c +++ b/src/dnode/src/dnodeShell.c @@ -83,18 +83,18 @@ int32_t dnodeInitShell() { numOfThreads = 1; } - SRpcInit rpcInit; - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = tsDnodeShellPort; - rpcInit.label = "SHELL"; - rpcInit.numOfThreads = numOfThreads; - rpcInit.cfp = dnodeProcessMsgFromShell; - rpcInit.sessions = tsMaxShellConns; - rpcInit.connType = TAOS_CONN_SERVER; - rpcInit.idleTime = tsShellActivityTimer * 1000; - rpcInit.afp = dnodeRetrieveUserAuthInfo; - - tsShellRpc = rpcOpen(&rpcInit); + SRpcInit rpcInitial; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = tsDnodeShellPort; + rpcInitial.label = "SHELL"; + rpcInitial.numOfThreads = numOfThreads; + rpcInitial.cfp = dnodeProcessMsgFromShell; + rpcInitial.sessions = tsMaxShellConns; + rpcInitial.connType = TAOS_CONN_SERVER; + rpcInitial.idleTime = tsShellActivityTimer * 1000; + rpcInitial.afp = dnodeRetrieveUserAuthInfo; + + tsShellRpc = rpcOpen(&rpcInitial); if (tsShellRpc == NULL) { dError("failed to init shell rpc server"); return -1; @@ -258,10 +258,10 @@ SDnodeStatisInfo dnodeGetStatisInfo() { return info; } -int32_t dnodeGetHttpStatusInfo(int32_t index) { +int32_t dnodeGetHttpStatusInfo(int32_t idx) { int32_t httpStatus = 0; #ifdef HTTP_EMBEDDED - httpStatus = httpGetStatusCodeCount(index); + httpStatus = httpGetStatusCodeCount(idx); #endif return httpStatus; } diff --git a/src/kit/shell/src/shellImport.c b/src/kit/shell/src/shellImport.c index b3a07b257c..e74c31729f 100644 --- a/src/kit/shell/src/shellImport.c +++ b/src/kit/shell/src/shellImport.c @@ -93,8 +93,8 @@ static void shellCheckTablesSQLFile(const char *directoryName) { sprintf(shellTablesSQLFile, "%s/tables.sql", directoryName); - struct stat fstat; - if (stat(shellTablesSQLFile, &fstat) < 0) { + struct stat status; + if (stat(shellTablesSQLFile, &status) < 0) { shellTablesSQLFile[0] = 0; } } diff --git a/src/mnode/src/mnodeCluster.c b/src/mnode/src/mnodeCluster.c index 553e8446ab..e8f7484fd1 100644 --- a/src/mnode/src/mnodeCluster.c +++ b/src/mnode/src/mnodeCluster.c @@ -145,8 +145,8 @@ static int32_t mnodeCreateCluster() { SClusterObj *pCluster = malloc(sizeof(SClusterObj)); memset(pCluster, 0, sizeof(SClusterObj)); pCluster->createdTime = taosGetTimestampMs(); - bool getuid = taosGetSystemUid(pCluster->uid); - if (!getuid) { + bool bGetuid = taosGetSystemUid(pCluster->uid); + if (!bGetuid) { strcpy(pCluster->uid, "tdengine2.0"); mError("failed to get uid from system, set to default val %s", pCluster->uid); } else { @@ -260,4 +260,4 @@ int32_t mnodeCompactCluster() { mInfo("end to compact cluster table..."); return 0; -} \ No newline at end of file +} diff --git a/src/mnode/src/mnodeMnode.c b/src/mnode/src/mnodeMnode.c index 13dd06bcac..491d2e4b36 100644 --- a/src/mnode/src/mnodeMnode.c +++ b/src/mnode/src/mnodeMnode.c @@ -210,7 +210,7 @@ void mnodeUpdateMnodeEpSet(SMInfos *pMinfos) { mInfos = *pMinfos; } else { mInfo("vgId:1, update mnodes epSet, numOfMnodes:%d", mnodeGetMnodesNum()); - int32_t index = 0; + int32_t idx = 0; void * pIter = NULL; while (1) { SMnodeObj *pMnode = NULL; @@ -220,10 +220,10 @@ void mnodeUpdateMnodeEpSet(SMInfos *pMinfos) { SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId); if (pDnode != NULL) { set = true; - mInfos.mnodeInfos[index].mnodeId = pMnode->mnodeId; - strcpy(mInfos.mnodeInfos[index].mnodeEp, pDnode->dnodeEp); - if (pMnode->role == TAOS_SYNC_ROLE_MASTER) mInfos.inUse = index; - index++; + mInfos.mnodeInfos[idx].mnodeId = pMnode->mnodeId; + strcpy(mInfos.mnodeInfos[idx].mnodeEp, pDnode->dnodeEp); + if (pMnode->role == TAOS_SYNC_ROLE_MASTER) mInfos.inUse = idx; + idx++; } else { set = false; } @@ -232,7 +232,7 @@ void mnodeUpdateMnodeEpSet(SMInfos *pMinfos) { mnodeDecMnodeRef(pMnode); } - mInfos.mnodeNum = index; + mInfos.mnodeNum = idx; if (mInfos.mnodeNum < sdbGetReplicaNum()) { set = false; mDebug("vgId:1, mnodes info not synced, current:%d syncCfgNum:%d", mInfos.mnodeNum, sdbGetReplicaNum()); @@ -251,23 +251,23 @@ void mnodeUpdateMnodeEpSet(SMInfos *pMinfos) { tsMEpForPeer.numOfEps = tsMInfos.mnodeNum; mInfo("vgId:1, mnodes epSet is set, num:%d inUse:%d", tsMInfos.mnodeNum, tsMInfos.inUse); - for (int index = 0; index < mInfos.mnodeNum; ++index) { - SMInfo *pInfo = &tsMInfos.mnodeInfos[index]; - taosGetFqdnPortFromEp(pInfo->mnodeEp, tsMEpForShell.fqdn[index], &tsMEpForShell.port[index]); - taosGetFqdnPortFromEp(pInfo->mnodeEp, tsMEpForPeer.fqdn[index], &tsMEpForPeer.port[index]); - tsMEpForPeer.port[index] = tsMEpForPeer.port[index] + TSDB_PORT_DNODEDNODE; + for (int idx = 0; idx < mInfos.mnodeNum; ++idx) { + SMInfo *pInfo = &tsMInfos.mnodeInfos[idx]; + taosGetFqdnPortFromEp(pInfo->mnodeEp, tsMEpForShell.fqdn[idx], &tsMEpForShell.port[idx]); + taosGetFqdnPortFromEp(pInfo->mnodeEp, tsMEpForPeer.fqdn[idx], &tsMEpForPeer.port[idx]); + tsMEpForPeer.port[idx] = tsMEpForPeer.port[idx] + TSDB_PORT_DNODEDNODE; - mInfo("vgId:1, mnode:%d, fqdn:%s shell:%u peer:%u", pInfo->mnodeId, tsMEpForShell.fqdn[index], - tsMEpForShell.port[index], tsMEpForPeer.port[index]); + mInfo("vgId:1, mnode:%d, fqdn:%s shell:%u peer:%u", pInfo->mnodeId, tsMEpForShell.fqdn[idx], + tsMEpForShell.port[idx], tsMEpForPeer.port[idx]); - tsMEpForShell.port[index] = htons(tsMEpForShell.port[index]); - tsMEpForPeer.port[index] = htons(tsMEpForPeer.port[index]); + tsMEpForShell.port[idx] = htons(tsMEpForShell.port[idx]); + tsMEpForPeer.port[idx] = htons(tsMEpForPeer.port[idx]); pInfo->mnodeId = htonl(pInfo->mnodeId); } } else { mInfo("vgId:1, mnodes epSet not set, num:%d inUse:%d", tsMInfos.mnodeNum, tsMInfos.inUse); - for (int index = 0; index < tsMInfos.mnodeNum; ++index) { - mInfo("vgId:1, index:%d, ep:%s:%u", index, tsMEpForShell.fqdn[index], htons(tsMEpForShell.port[index])); + for (int idx = 0; idx < tsMInfos.mnodeNum; ++idx) { + mInfo("vgId:1, index:%d, ep:%s:%u", idx, tsMEpForShell.fqdn[idx], htons(tsMEpForShell.port[idx])); } } @@ -603,4 +603,4 @@ int32_t mnodeCompactMnodes() { mInfo("end to compact mnodes table..."); return 0; -} \ No newline at end of file +} diff --git a/src/mnode/src/mnodeSdb.c b/src/mnode/src/mnodeSdb.c index 1e3057f270..cb39c2ae2b 100644 --- a/src/mnode/src/mnodeSdb.c +++ b/src/mnode/src/mnodeSdb.c @@ -331,7 +331,7 @@ int32_t sdbUpdateSync(void *pMnodes) { mDebug("vgId:1, update sync config, pMnodes:%p", pMnodes); SSyncCfg syncCfg = {0}; - int32_t index = 0; + int32_t idx = 0; if (pMinfos == NULL) { mDebug("vgId:1, mInfos not input, use mInfos in sdb, numOfMnodes:%d", syncCfg.replica); @@ -342,29 +342,29 @@ int32_t sdbUpdateSync(void *pMnodes) { pIter = mnodeGetNextMnode(pIter, &pMnode); if (pMnode == NULL) break; - syncCfg.nodeInfo[index].nodeId = pMnode->mnodeId; + syncCfg.nodeInfo[idx].nodeId = pMnode->mnodeId; SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId); if (pDnode != NULL) { - syncCfg.nodeInfo[index].nodePort = pDnode->dnodePort + TSDB_PORT_SYNC; - tstrncpy(syncCfg.nodeInfo[index].nodeFqdn, pDnode->dnodeFqdn, TSDB_FQDN_LEN); - index++; + syncCfg.nodeInfo[idx].nodePort = pDnode->dnodePort + TSDB_PORT_SYNC; + tstrncpy(syncCfg.nodeInfo[idx].nodeFqdn, pDnode->dnodeFqdn, TSDB_FQDN_LEN); + idx++; } mnodeDecDnodeRef(pDnode); mnodeDecMnodeRef(pMnode); } - syncCfg.replica = index; + syncCfg.replica = idx; } else { mDebug("vgId:1, mInfos input, numOfMnodes:%d", pMinfos->mnodeNum); - for (index = 0; index < pMinfos->mnodeNum; ++index) { - SMInfo *node = &pMinfos->mnodeInfos[index]; - syncCfg.nodeInfo[index].nodeId = node->mnodeId; - taosGetFqdnPortFromEp(node->mnodeEp, syncCfg.nodeInfo[index].nodeFqdn, &syncCfg.nodeInfo[index].nodePort); - syncCfg.nodeInfo[index].nodePort += TSDB_PORT_SYNC; + for (idx = 0; idx < pMinfos->mnodeNum; ++idx) { + SMInfo *node = &pMinfos->mnodeInfos[idx]; + syncCfg.nodeInfo[idx].nodeId = node->mnodeId; + taosGetFqdnPortFromEp(node->mnodeEp, syncCfg.nodeInfo[idx].nodeFqdn, &syncCfg.nodeInfo[idx].nodePort); + syncCfg.nodeInfo[idx].nodePort += TSDB_PORT_SYNC; } - syncCfg.replica = index; + syncCfg.replica = idx; mnodeUpdateMnodeEpSet(pMnodes); } diff --git a/src/os/src/detail/osDir.c b/src/os/src/detail/osDir.c index 17c844ed86..d867c80af4 100644 --- a/src/os/src/detail/osDir.c +++ b/src/os/src/detail/osDir.c @@ -45,8 +45,8 @@ void taosRemoveDir(char *rootDir) { uInfo("dir:%s is removed", rootDir); } -bool taosDirExist(const char* dirname) { - return access(dirname, F_OK) == 0; +bool taosDirExist(const char* dir) { + return access(dir, F_OK) == 0; } int32_t taosMkdirP(const char *dir, int keepLast) { diff --git a/src/os/src/detail/osFile.c b/src/os/src/detail/osFile.c index 910e6f15be..6adcd1dae3 100644 --- a/src/os/src/detail/osFile.c +++ b/src/os/src/detail/osFile.c @@ -44,11 +44,11 @@ void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) { strcat(tmpPath, "-%d-%s"); } - char rand[32] = {0}; + char rand_num[32] = {0}; - sprintf(rand, "%" PRIu64, atomic_add_fetch_64(&seqId, 1)); + sprintf(rand_num, "%" PRIu64, atomic_add_fetch_64(&seqId, 1)); - snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand); + snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand_num); } #else @@ -71,11 +71,11 @@ void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) { strcat(tmpPath, "-%d-%s"); } - char rand[32] = {0}; + char rand_num[32] = {0}; - sprintf(rand, "%" PRIu64, atomic_add_fetch_64(&seqId, 1)); + sprintf(rand_num, "%" PRIu64, atomic_add_fetch_64(&seqId, 1)); - snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand); + snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand_num); } #endif diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 1575b3100f..3590703695 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -82,26 +82,26 @@ void deltaToUtcInitOnce() { } static int64_t parseFraction(char* str, char** end, int32_t timePrec); -static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim); -static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim, bool withDST); +static int32_t parseTimeWithTz(char* timestr, int64_t* pTime, int32_t timePrec, char delim); +static int32_t parseLocaltime(char* timestr, int64_t* pTime, int32_t timePrec, char delim, bool withDST); static char* forwardToTimeStringEnd(char* str); static bool checkTzPresent(char *str, int32_t len); int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } -int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { +int32_t taosParseTime(char* timestr, int64_t* pTime, int32_t len, int32_t timePrec, int8_t day_light) { /* parse datatime string in with tz */ if (strnchr(timestr, 'T', len, false) != NULL) { if (checkTzPresent(timestr, len)) { - return parseTimeWithTz(timestr, time, timePrec, 'T'); + return parseTimeWithTz(timestr, pTime, timePrec, 'T'); } else { - return parseLocaltime(timestr, time, timePrec, 'T', day_light); + return parseLocaltime(timestr, pTime, timePrec, 'T', day_light); } } else { if (checkTzPresent(timestr, len)) { - return parseTimeWithTz(timestr, time, timePrec, 0); + return parseTimeWithTz(timestr, pTime, timePrec, 0); } else { - return parseLocaltime(timestr, time, timePrec, 0, day_light); + return parseLocaltime(timestr, pTime, timePrec, 0, day_light); } } } @@ -121,8 +121,8 @@ bool checkTzPresent(char *str, int32_t len) { } -FORCE_INLINE int32_t taos_parse_time(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { - return taosParseTime(timestr, time, len, timePrec, day_light); +FORCE_INLINE int32_t taos_parse_time(char* timestr, int64_t* pTime, int32_t len, int32_t timePrec, int8_t day_light) { + return taosParseTime(timestr, pTime, len, timePrec, day_light); } char* forwardToTimeStringEnd(char* str) { @@ -243,7 +243,7 @@ int32_t parseTimezone(char* str, int64_t* tzOffset) { * 2013-04-12T15:52:01+0800 * 2013-04-12T15:52:01.123+0800 */ -int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim) { +int32_t parseTimeWithTz(char* timestr, int64_t* pTime, int32_t timePrec, char delim) { int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 : (timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000); @@ -277,14 +277,14 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del if ((str[0] == 'Z' || str[0] == 'z') && str[1] == '\0') { /* utc time, no millisecond, return directly*/ - *time = seconds * factor; + *pTime = seconds * factor; } else if (str[0] == '.') { str += 1; if ((fraction = parseFraction(str, &str, timePrec)) < 0) { return -1; } - *time = seconds * factor + fraction; + *pTime = seconds * factor + fraction; char seg = str[0]; if (seg != 'Z' && seg != 'z' && seg != '+' && seg != '-') { @@ -297,18 +297,18 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del return -1; } - *time += tzOffset * factor; + *pTime += tzOffset * factor; } } else if (str[0] == '+' || str[0] == '-') { - *time = seconds * factor + fraction; + *pTime = seconds * factor + fraction; // parse the timezone if (parseTimezone(str, &tzOffset) == -1) { return -1; } - *time += tzOffset * factor; + *pTime += tzOffset * factor; } else { return -1; } @@ -316,8 +316,8 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del return 0; } -int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim, bool withDST) { - *time = 0; +int32_t parseLocaltime(char* timestr, int64_t* pTime, int32_t timePrec, char delim, bool withDST) { + *pTime = 0; struct tm tm = {0}; if (withDST) { tm.tm_isdst = -1; @@ -365,65 +365,65 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char deli int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 : (timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000); - *time = factor * seconds + fraction; + *pTime = factor * seconds + fraction; return 0; } -int64_t convertTimePrecision(int64_t time, int32_t fromPrecision, int32_t toPrecision) { +int64_t convertTimePrecision(int64_t timeStamp, int32_t fromPrecision, int32_t toPrecision) { assert(fromPrecision == TSDB_TIME_PRECISION_MILLI || fromPrecision == TSDB_TIME_PRECISION_MICRO || fromPrecision == TSDB_TIME_PRECISION_NANO); assert(toPrecision == TSDB_TIME_PRECISION_MILLI || toPrecision == TSDB_TIME_PRECISION_MICRO || toPrecision == TSDB_TIME_PRECISION_NANO); - double tempResult = (double)time; + double tempResult = (double)timeStamp; switch(fromPrecision) { case TSDB_TIME_PRECISION_MILLI: { switch (toPrecision) { case TSDB_TIME_PRECISION_MILLI: - return time; + return timeStamp; case TSDB_TIME_PRECISION_MICRO: tempResult *= 1000; - time *= 1000; + timeStamp *= 1000; goto end_; case TSDB_TIME_PRECISION_NANO: tempResult *= 1000000; - time *= 1000000; + timeStamp *= 1000000; goto end_; } } // end from milli case TSDB_TIME_PRECISION_MICRO: { switch (toPrecision) { case TSDB_TIME_PRECISION_MILLI: - return time / 1000; + return timeStamp / 1000; case TSDB_TIME_PRECISION_MICRO: - return time; + return timeStamp; case TSDB_TIME_PRECISION_NANO: tempResult *= 1000; - time *= 1000; + timeStamp *= 1000; goto end_; } } //end from micro case TSDB_TIME_PRECISION_NANO: { switch (toPrecision) { case TSDB_TIME_PRECISION_MILLI: - return time / 1000000; + return timeStamp / 1000000; case TSDB_TIME_PRECISION_MICRO: - return time / 1000; + return timeStamp / 1000; case TSDB_TIME_PRECISION_NANO: - return time; + return timeStamp; } } //end from nano default: { assert(0); - return time; // only to pass windows compilation + return timeStamp; // only to pass windows compilation } } //end switch fromPrecision end_: if (tempResult >= (double)INT64_MAX) return INT64_MAX; if (tempResult <= (double)INT64_MIN) return INT64_MIN + 1; // INT64_MIN means NULL - return time; + return timeStamp; } static int32_t getDuration(int64_t val, char unit, int64_t* result, int32_t timePrecision) { diff --git a/src/os/src/linux/osSystem.c b/src/os/src/linux/osSystem.c index a82149dccb..d2d9d6d76c 100644 --- a/src/os/src/linux/osSystem.c +++ b/src/os/src/linux/osSystem.c @@ -33,9 +33,9 @@ void* taosLoadDll(const char *filename) { void* taosLoadSym(void* handle, char* name) { void* sym = dlsym(handle, name); - char* error = NULL; + char* err = NULL; - if ((error = dlerror()) != NULL) { + if ((err = dlerror()) != NULL) { uWarn("load sym:%s failed, error:%s", name, dlerror()); return NULL; } diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 1aecac1b2f..44cf11d723 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -352,7 +352,7 @@ static uint64_t hllCountCnt(uint8_t *buckets) { static uint8_t hllCountNum(void *ele, int32_t elesize, int32_t *buk) { uint64_t hash = MurmurHash3_64(ele,elesize); - int32_t index = hash & HLL_BUCKET_MASK; + int32_t idx = hash & HLL_BUCKET_MASK; hash >>= HLL_BUCKET_BITS; hash |= ((uint64_t)1<buckets[index]; + int32_t idx = 0; + uint8_t count = hllCountNum(val,elesize,&idx); + uint8_t oldcount = pHLLInfo->buckets[idx]; if (count > oldcount) { - pHLLInfo->buckets[index] = count; + pHLLInfo->buckets[idx] = count; } } GET_RES_INFO(pCtx)->numOfRes = 1; @@ -1363,14 +1363,14 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, } void* tval = NULL; - int16_t index = 0; + int16_t idx = 0; if (isMin) { tval = &pCtx->preAggVals.statis.min; - index = pCtx->preAggVals.statis.minIndex; + idx = pCtx->preAggVals.statis.minIndex; } else { tval = &pCtx->preAggVals.statis.max; - index = pCtx->preAggVals.statis.maxIndex; + idx = pCtx->preAggVals.statis.maxIndex; } TSKEY key = TSKEY_INITIAL_VAL; @@ -1381,12 +1381,12 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, * * The following codes of 3 lines will be removed later. */ -// if (index < 0 || index >= pCtx->size + pCtx->startOffset) { -// index = 0; +// if (idx < 0 || idx >= pCtx->size + pCtx->startOffset) { +// idx = 0; // } - // the index is the original position, not the relative position - key = pCtx->ptsList[index]; + // the idx is the original position, not the relative position + key = pCtx->ptsList[idx]; } if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) { @@ -2065,15 +2065,15 @@ static void first_function(SQLFunctionCtx *pCtx) { SET_VAL(pCtx, notNullElems, 1); } -static void first_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t index) { +static void first_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t idx) { int64_t *timestamp = GET_TS_LIST(pCtx); SFirstLastInfo *pInfo = (SFirstLastInfo *)(pCtx->pOutput + pCtx->inputBytes); - if (pInfo->hasResult != DATA_SET_FLAG || timestamp[index] < pInfo->ts) { + if (pInfo->hasResult != DATA_SET_FLAG || timestamp[idx] < pInfo->ts) { memcpy(pCtx->pOutput, pData, pCtx->inputBytes); pInfo->hasResult = DATA_SET_FLAG; - pInfo->ts = timestamp[index]; + pInfo->ts = timestamp[idx]; DO_UPDATE_TAG_COLUMNS(pCtx, pInfo->ts); } @@ -2203,19 +2203,19 @@ static void last_function(SQLFunctionCtx *pCtx) { SET_VAL(pCtx, notNullElems, 1); } -static void last_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t index) { +static void last_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t idx) { int64_t *timestamp = GET_TS_LIST(pCtx); SFirstLastInfo *pInfo = (SFirstLastInfo *)(pCtx->pOutput + pCtx->inputBytes); - if (pInfo->hasResult != DATA_SET_FLAG || pInfo->ts < timestamp[index]) { + if (pInfo->hasResult != DATA_SET_FLAG || pInfo->ts < timestamp[idx]) { #if defined(_DEBUG_VIEW) - qDebug("assign index:%d, ts:%" PRId64 ", val:%d, ", index, timestamp[index], *(int32_t *)pData); + qDebug("assign index:%d, ts:%" PRId64 ", val:%d, ", idx, timestamp[idx], *(int32_t *)pData); #endif memcpy(pCtx->pOutput, pData, pCtx->inputBytes); pInfo->hasResult = DATA_SET_FLAG; - pInfo->ts = timestamp[index]; + pInfo->ts = timestamp[idx]; DO_UPDATE_TAG_COLUMNS(pCtx, pInfo->ts); } @@ -3188,12 +3188,12 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo return true; } -#define LEASTSQR_CAL(p, x, y, index, step) \ +#define LEASTSQR_CAL(p, x, y, idx, step) \ do { \ (p)[0][0] += (double)(x) * (x); \ (p)[0][1] += (double)(x); \ - (p)[0][2] += (double)(x) * (y)[index]; \ - (p)[1][2] += (y)[index]; \ + (p)[0][2] += (double)(x) * (y)[idx]; \ + (p)[1][2] += (y)[idx]; \ (x) += step; \ } while (0) @@ -3831,16 +3831,16 @@ static void diff_function(SQLFunctionCtx *pCtx) { char *getScalarExprColumnData(void *param, const char* name, int32_t colId) { SScalarExprSupport *pSupport = (SScalarExprSupport *)param; - int32_t index = -1; + int32_t idx = -1; for (int32_t i = 0; i < pSupport->numOfCols; ++i) { if (colId == pSupport->colList[i].colId) { - index = i; + idx = i; break; } } - assert(index >= 0); - return pSupport->data[index] + pSupport->offset * pSupport->colList[index].bytes; + assert(idx >= 0); + return pSupport->data[idx] + pSupport->offset * pSupport->colList[idx].bytes; } static void scalar_expr_function(SQLFunctionCtx *pCtx) { @@ -4049,14 +4049,14 @@ static double twa_get_area(SPoint1 s, SPoint1 e) { return val; } -static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t size) { +static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t idx, int32_t size) { int32_t notNullElems = 0; SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); TSKEY *tsList = GET_TS_LIST(pCtx); - int32_t i = index; + int32_t i = idx; int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order); SPoint1* last = &pInfo->p; @@ -4067,7 +4067,7 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si assert(last->key == INT64_MIN); last->key = tsList[i]; - GET_TYPED_DATA(last->val, double, pCtx->inputType, GET_INPUT_DATA(pCtx, index)); + GET_TYPED_DATA(last->val, double, pCtx->inputType, GET_INPUT_DATA(pCtx, idx)); pInfo->dOutput += twa_get_area(pCtx->start, *last); @@ -4077,7 +4077,7 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si i += step; } else if (pInfo->p.key == INT64_MIN) { last->key = tsList[i]; - GET_TYPED_DATA(last->val, double, pCtx->inputType, GET_INPUT_DATA(pCtx, index)); + GET_TYPED_DATA(last->val, double, pCtx->inputType, GET_INPUT_DATA(pCtx, idx)); pInfo->hasResult = DATA_SET_FLAG; pInfo->win.skey = last->key; @@ -5016,13 +5016,13 @@ static void mavg_function(SQLFunctionCtx *pCtx) { ////////////////////////////////////////////////////////////////////////////////// // Sample function with reservoir sampling algorithm -static void assignResultSample(SQLFunctionCtx *pCtx, SSampleFuncInfo *pInfo, int32_t index, int64_t ts, void *pData, uint16_t type, int16_t bytes, char *inputTags) { - assignVal(pInfo->values + index*bytes, pData, bytes, type); - *(pInfo->timeStamps + index) = ts; +static void assignResultSample(SQLFunctionCtx *pCtx, SSampleFuncInfo *pInfo, int32_t idx, int64_t ts, void *pData, uint16_t type, int16_t bytes, char *inputTags) { + assignVal(pInfo->values + idx*bytes, pData, bytes, type); + *(pInfo->timeStamps + idx) = ts; SExtTagsInfo* pTagInfo = &pCtx->tagInfo; int32_t posTag = 0; - char* tags = pInfo->taglists + index*pTagInfo->tagsLen; + char* tags = pInfo->taglists + idx*pTagInfo->tagsLen; if (pCtx->currentStage == MERGE_STAGE) { assert(inputTags != NULL); memcpy(tags, inputTags, (size_t)pTagInfo->tagsLen); diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 7d4b0b7edb..14b7b11475 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -519,9 +519,9 @@ static SResultRow* doSetResultOutBufByKey(SQueryRuntimeEnv* pRuntimeEnv, SResult pResultRowInfo->curPos = 0; } else { // check if current pResultRowInfo contains the existed pResultRow SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, tid, pResultRowInfo); - int64_t* index = taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes)); - if (index != NULL) { - pResultRowInfo->curPos = (int32_t) *index; + int64_t* idx = taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes)); + if (idx != NULL) { + pResultRowInfo->curPos = (int32_t) *idx; existed = true; } else { existed = false; @@ -557,9 +557,9 @@ static SResultRow* doSetResultOutBufByKey(SQueryRuntimeEnv* pRuntimeEnv, SResult pResultRowInfo->curPos = pResultRowInfo->size; pResultRowInfo->pResult[pResultRowInfo->size++] = pResult; - int64_t index = pResultRowInfo->curPos; + int64_t idx = pResultRowInfo->curPos; SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, tid, pResultRowInfo); - taosHashPut(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes), &index, POINTER_BYTES); + taosHashPut(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes), &idx, POINTER_BYTES); } // too many time window in query @@ -633,7 +633,7 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t /* * query border check, skey should not be bounded by the query time range, since the value skey will - * be used as the time window index value. So we only change ekey of time window accordingly. + * be used as the time window idx value. So we only change ekey of time window accordingly. */ if (w.ekey > pQueryAttr->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) { w.ekey = pQueryAttr->window.ekey; @@ -1293,8 +1293,8 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, } SColIndex * pColIndex = &pExpr[k].base.colInfo; - int16_t index = pColIndex->colIndex; - SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, index); + int16_t idx = pColIndex->colIndex; + SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, idx); assert(pColInfo->info.colId <= TSDB_RES_COL_ID || (pColInfo->info.colId >= 0 && pColInfo->info.colId == pColIndex->colId)); double v1 = 0, v2 = 0, v = 0; @@ -1302,7 +1302,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, if (functionId == TSDB_FUNC_INTERP) { if (type == RESULT_ROW_START_INTERP) { if (prevRowIndex == -1) { - COPY_DATA(&pCtx[k].start.val, (char *)pRuntimeEnv->prevRow[index]); + COPY_DATA(&pCtx[k].start.val, (char *)pRuntimeEnv->prevRow[idx]); } else { COPY_DATA(&pCtx[k].start.val, (char *)pColInfo->pData + prevRowIndex * pColInfo->info.bytes); } @@ -1311,7 +1311,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) { if (prevRowIndex == -1) { - pCtx[k].start.ptr = (char *)pRuntimeEnv->prevRow[index]; + pCtx[k].start.ptr = (char *)pRuntimeEnv->prevRow[idx]; } else { pCtx[k].start.ptr = (char *)pColInfo->pData + prevRowIndex * pColInfo->info.bytes; } @@ -1319,7 +1319,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, } else { if (curRowIndex == -1) { - COPY_DATA(&pCtx[k].end.val, pRuntimeEnv->prevRow[index]); + COPY_DATA(&pCtx[k].end.val, pRuntimeEnv->prevRow[idx]); } else { COPY_DATA(&pCtx[k].end.val, (char *)pColInfo->pData + curRowIndex * pColInfo->info.bytes); } @@ -1334,7 +1334,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, assert(curTs != windowKey); if (prevRowIndex == -1) { - GET_TYPED_DATA(v1, double, pColInfo->info.type, (char *)pRuntimeEnv->prevRow[index]); + GET_TYPED_DATA(v1, double, pColInfo->info.type, (char *)pRuntimeEnv->prevRow[idx]); } else { GET_TYPED_DATA(v1, double, pColInfo->info.type, (char *)pColInfo->pData + prevRowIndex * pColInfo->info.bytes); } @@ -3504,7 +3504,7 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt continue; } - // todo use tag column index to optimize performance + // todo use tag column idx to optimize performance GET_JSON_KEY(pLocalExprInfo) doSetTagValueInParam(pTable, param, paramLen, pLocalExprInfo->base.colInfo.colId, &pCtx[idx].tag, pLocalExprInfo->base.resType, pLocalExprInfo->base.resBytes); @@ -3522,7 +3522,7 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt offset += pLocalExprInfo->base.resBytes; } - //todo : use index to avoid iterator all possible output columns + //todo : use idx to avoid iterator all possible output columns if (pQueryAttr->stableQuery && pQueryAttr->stabledev && (pRuntimeEnv->prevResult != NULL)) { setParamForStableStddev(pRuntimeEnv, pCtx, numOfOutput, pExprInfo); } @@ -4834,10 +4834,10 @@ void queryCostStatis(SQInfo *pQInfo) { // TSKEY key = pTableQueryInfo->win.skey; // // pWindowResInfo->prevSKey = tw.skey; -// int32_t index = pRuntimeEnv->resultRowInfo.curIndex; +// int32_t idx = pRuntimeEnv->resultRowInfo.curIndex; // // int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock); -// pRuntimeEnv->resultRowInfo.curIndex = index; // restore the window index +// pRuntimeEnv->resultRowInfo.curIndex = idx; // restore the window idx // // qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%" PRId64, // GET_QID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, @@ -5643,15 +5643,15 @@ SArray* getOrderCheckColumns(SQueryAttr* pQuery) { { numOfCols = (int32_t) taosArrayGetSize(pOrderColumns); for(int32_t i = 0; i < numOfCols; ++i) { - SColIndex* index = taosArrayGet(pOrderColumns, i); + SColIndex* idx = taosArrayGet(pOrderColumns, i); for(int32_t j = 0; j < pQuery->numOfOutput; ++j) { SSqlExpr* pExpr = &pQuery->pExpr1[j].base; int32_t functionId = pExpr->functionId; - if (index->colId == pExpr->colInfo.colId && + if (idx->colId == pExpr->colInfo.colId && (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS)) { - index->colIndex = j; - index->colId = pExpr->resColId; + idx->colIndex = j; + idx->colId = pExpr->resColId; } } } @@ -5675,24 +5675,24 @@ SArray* getResultGroupCheckColumns(SQueryAttr* pQuery) { } for (int32_t i = 0; i < numOfCols; ++i) { - SColIndex* index = taosArrayGet(pOrderColumns, i); + SColIndex* idx = taosArrayGet(pOrderColumns, i); bool found = false; for(int32_t j = 0; j < pQuery->numOfOutput; ++j) { SSqlExpr* pExpr = &pQuery->pExpr1[j].base; // TSDB_FUNC_TAG_DUMMY function needs to be ignored - if (index->colId == pExpr->colInfo.colId && + if (idx->colId == pExpr->colInfo.colId && ((TSDB_COL_IS_TAG(pExpr->colInfo.flag) && ((pExpr->functionId == TSDB_FUNC_TAG) || (pExpr->functionId == TSDB_FUNC_TAGPRJ))) || (TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && pExpr->functionId == TSDB_FUNC_PRJ))) { - index->colIndex = j; - index->colId = pExpr->resColId; + idx->colIndex = j; + idx->colId = pExpr->resColId; found = true; break; } } - assert(found && index->colIndex >= 0 && index->colIndex < pQuery->numOfOutput); + assert(found && idx->colIndex >= 0 && idx->colIndex < pQuery->numOfOutput); } return pOrderColumns; @@ -5774,8 +5774,8 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, for(int32_t i = 0; i < numOfCols; ++i) { pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; - SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); - offset += pExpr[index->colIndex].base.resBytes; + SColIndex* idx = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[idx->colIndex].base.resBytes; } numOfCols = (pInfo->groupColumnList != NULL)? (int32_t)taosArrayGetSize(pInfo->groupColumnList):0; @@ -5789,8 +5789,8 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, for(int32_t i = 0; i < numOfCols; ++i) { pInfo->currentGroupColData[i] = (char*)pInfo->currentGroupColData + offset; - SColIndex* index = taosArrayGet(pInfo->groupColumnList, i); - offset += pExpr[index->colIndex].base.resBytes; + SColIndex* idx = taosArrayGet(pInfo->groupColumnList, i); + offset += pExpr[idx->colIndex].base.resBytes; } initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); @@ -5857,8 +5857,8 @@ SOperatorInfo *createMultiwaySortOperatorInfo(SQueryRuntimeEnv *pRuntimeEnv, SEx for(int32_t i = 0; i < numOfCols; ++i) { pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; - SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); - offset += pExpr[index->colIndex].base.colBytes; + SColIndex* idx = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[idx->colIndex].base.colBytes; } } @@ -6496,7 +6496,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo STimeEveryOperatorInfo* pEveryInfo = (STimeEveryOperatorInfo*)pOperatorInfo->info; SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); - int32_t gidx = pRuntimeEnv->current->groupIndex; + int32_t gindex = pRuntimeEnv->current->groupIndex; SQLFunctionCtx* pCtx = NULL; *needApply = false; @@ -6702,7 +6702,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo group_finished_exit: - qDebug("group idx[%d] interp finished", gidx); + qDebug("group index[%d] interp finished", gindex); if (pQueryAttr->needReverseScan) { pQueryAttr->range.skey = INT64_MIN; @@ -8132,8 +8132,8 @@ SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperator for(int32_t i = 0; i < numOfCols; ++i) { pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; - SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); - offset += pExpr[index->colIndex].base.resBytes; + SColIndex* idx = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[idx->colIndex].base.resBytes; } pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); @@ -8888,7 +8888,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pMsg += tListLen(param->pGroupColIndex[i].name); } - //pQueryMsg->orderByIdx = htons(pQueryMsg->orderByIdx); + //pQueryMsg->orderByIndex = htons(pQueryMsg->orderByIndex); pQueryMsg->groupOrderType = htons(pQueryMsg->groupOrderType); } @@ -9441,11 +9441,11 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t nu pExprs[i].base.resType = pExprs[i].pExpr->resultType; pExprs[i].base.interBytes = 0; } else { - int32_t index = pExprs[i].base.colInfo.colIndex; - assert(prevExpr[index].base.resColId == pExprs[i].base.colInfo.colId); + int32_t idx = pExprs[i].base.colInfo.colIndex; + assert(prevExpr[idx].base.resColId == pExprs[i].base.colInfo.colId); - type = prevExpr[index].base.resType; - bytes = prevExpr[index].base.resBytes; + type = prevExpr[idx].base.resType; + bytes = prevExpr[idx].base.resBytes; int32_t param = (int32_t)pExprs[i].base.param[0].i64; if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, @@ -9476,7 +9476,7 @@ SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pCo pGroupbyExpr->numOfGroupCols = pQueryMsg->numOfGroupCols; pGroupbyExpr->orderType = pQueryMsg->groupOrderType; - //pGroupbyExpr->orderIndex = pQueryMsg->orderByIdx; + //pGroupbyExpr->orderIndex = pQueryMsg->orderByIndex; pGroupbyExpr->columnInfo = taosArrayInit(pQueryMsg->numOfGroupCols, sizeof(SColIndex)); for(int32_t i = 0; i < pQueryMsg->numOfGroupCols; ++i) { @@ -9786,7 +9786,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; STimeWindow window = pQueryAttr->window; - int32_t index = 0; + int32_t idx = 0; for(int32_t i = 0; i < numOfGroups; ++i) { SArray* pa = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); @@ -9802,7 +9802,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S STableKeyInfo* info = taosArrayGet(pa, j); window.skey = info->lastKey; - void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo); + void* buf = (char*) pQInfo->pBuf + idx * sizeof(STableQueryInfo); STableQueryInfo* item = createTableQueryInfo(pQueryAttr, info->pTable, pQueryAttr->groupbyColumn, window, buf); if (item == NULL) { goto _cleanup; @@ -9813,7 +9813,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S STableId* id = TSDB_TABLEID(info->pTable); taosHashPut(pRuntimeEnv->tableqinfoGroupInfo.map, &id->tid, sizeof(id->tid), &item, POINTER_BYTES); - index += 1; + idx += 1; } } diff --git a/src/query/src/qExtbuffer.c b/src/query/src/qExtbuffer.c index 4a4ae3ca42..e2c649e99c 100644 --- a/src/query/src/qExtbuffer.c +++ b/src/query/src/qExtbuffer.c @@ -485,9 +485,9 @@ int32_t compare_a(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1, int32_t compare_aRv(SSDataBlock* pBlock, SArray* colIndex, int32_t numOfCols, int32_t rowIndex, char** buffer, int32_t order) { for (int32_t i = 0; i < numOfCols; ++i) { SColIndex* pColIndex = taosArrayGet(colIndex, i); - int32_t index = pColIndex->colIndex; + int32_t idx = pColIndex->colIndex; - SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, index); + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, idx); assert(pColIndex->colId == pColInfo->info.colId); char* data = pColInfo->pData + rowIndex * pColInfo->info.bytes; @@ -1176,14 +1176,14 @@ void tColModelCompact(SColumnModel *pModel, tFilePage *inputBuffer, int32_t maxE } } -SSchema1* getColumnModelSchema(SColumnModel *pColumnModel, int32_t index) { - assert(pColumnModel != NULL && index >= 0 && index < pColumnModel->numOfCols); - return &pColumnModel->pFields[index].field; +SSchema1* getColumnModelSchema(SColumnModel *pColumnModel, int32_t idx) { + assert(pColumnModel != NULL && idx >= 0 && idx < pColumnModel->numOfCols); + return &pColumnModel->pFields[idx].field; } -int16_t getColumnModelOffset(SColumnModel *pColumnModel, int32_t index) { - assert(pColumnModel != NULL && index >= 0 && index < pColumnModel->numOfCols); - return pColumnModel->pFields[index].offset; +int16_t getColumnModelOffset(SColumnModel *pColumnModel, int32_t idx) { + assert(pColumnModel != NULL && idx >= 0 && idx < pColumnModel->numOfCols); + return pColumnModel->pFields[idx].offset; } void tColModelErase(SColumnModel *pModel, tFilePage *inputBuffer, int32_t blockCapacity, int32_t s, int32_t e) { @@ -1257,17 +1257,17 @@ void tOrderDescDestroy(tOrderDescriptor *pDesc) { tfree(pDesc); } -void taoscQSort(void** pCols, SSchema* pSchema, int32_t numOfCols, int32_t numOfRows, int32_t index, __compar_fn_t compareFn) { - assert(numOfRows > 0 && numOfCols > 0 && index >= 0 && index < numOfCols); +void taoscQSort(void** pCols, SSchema* pSchema, int32_t numOfCols, int32_t numOfRows, int32_t idx, __compar_fn_t compareFn) { + assert(numOfRows > 0 && numOfCols > 0 && idx >= 0 && idx < numOfCols); - int32_t bytes = pSchema[index].bytes; + int32_t bytes = pSchema[idx].bytes; int32_t size = bytes + sizeof(int32_t); char* buf = calloc(1, size * numOfRows); for(int32_t i = 0; i < numOfRows; ++i) { char* dest = buf + size * i; - memcpy(dest, ((char*) pCols[index]) + bytes * i, bytes); + memcpy(dest, ((char*) pCols[idx]) + bytes * i, bytes); *(int32_t*)(dest+bytes) = i; } @@ -1279,7 +1279,7 @@ void taoscQSort(void** pCols, SSchema* pSchema, int32_t numOfCols, int32_t numOf for(int32_t i = 0; i < numOfCols; ++i) { int32_t bytes1 = pSchema[i].bytes; - if (i == index) { + if (i == idx) { for(int32_t j = 0; j < numOfRows; ++j){ char* src = buf + (j * size); char* dest = ((char*)pCols[i]) + (j * bytes1); diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index d83620c78f..1f4bbed831 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -63,8 +63,8 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData int32_t step = GET_FORWARD_DIRECTION_FACTOR(pFillInfo->order); // set the primary timestamp column value - int32_t index = pFillInfo->numOfCurrent; - char* val = elePtrAt(data[0], TSDB_KEYSIZE, index); + int32_t idx = pFillInfo->numOfCurrent; + char* val = elePtrAt(data[0], TSDB_KEYSIZE, idx); *(TSKEY*) val = pFillInfo->currentKey; // set the other values @@ -78,11 +78,11 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData continue; } - char* output = elePtrAt(data[i], pCol->col.bytes, index); + char* output = elePtrAt(data[i], pCol->col.bytes, idx); assignVal(output, p + pCol->col.offset, pCol->col.bytes, pCol->col.type); } } else { // no prev value yet, set the value for NULL - setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, index); + setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, idx); } } else if (pFillInfo->type == TSDB_FILL_NEXT) { char* p = next; @@ -94,11 +94,11 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData continue; } - char* output = elePtrAt(data[i], pCol->col.bytes, index); + char* output = elePtrAt(data[i], pCol->col.bytes, idx); assignVal(output, p + pCol->col.offset, pCol->col.bytes, pCol->col.type); } } else { // no prev value yet, set the value for NULL - setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, index); + setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, idx); } } else if (pFillInfo->type == TSDB_FILL_LINEAR) { if (prev != NULL && !outOfBound) { @@ -111,7 +111,7 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData int16_t type = pCol->col.type; int16_t bytes = pCol->col.bytes; - char *val1 = elePtrAt(data[i], pCol->col.bytes, index); + char *val1 = elePtrAt(data[i], pCol->col.bytes, idx); if (type == TSDB_DATA_TYPE_BINARY|| type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BOOL) { setNull(val1, pCol->col.type, bytes); continue; @@ -128,7 +128,7 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData taosGetLinearInterpolationVal(&point, type, &point1, &point2, type, &exceedMax, &exceedMin); } } else { - setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, index); + setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, idx); } } else { // fill the default value */ for (int32_t i = 1; i < pFillInfo->numOfCols; ++i) { @@ -137,12 +137,12 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData continue; } - char* val1 = elePtrAt(data[i], pCol->col.bytes, index); + char* val1 = elePtrAt(data[i], pCol->col.bytes, idx); assignVal(val1, (char*)&pCol->fillVal.i, pCol->col.bytes, pCol->col.type); } } - setTagsValue(pFillInfo, data, index); + setTagsValue(pFillInfo, data, idx); pFillInfo->currentKey = taosTimeAdd(pFillInfo->currentKey, pFillInfo->interval.sliding * step, pFillInfo->interval.slidingUnit, pFillInfo->precision); pFillInfo->numOfCurrent++; } @@ -303,11 +303,11 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t numOfTags += 1; bool exists = false; - int32_t index = -1; + int32_t idx = -1; for (int32_t j = 0; j < k; ++j) { if (pFillInfo->pTags[j].col.colId == pColInfo->col.colId) { exists = true; - index = j; + idx = j; break; } } @@ -323,7 +323,7 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t k += 1; } else { - pColInfo->tagIndex = index; + pColInfo->tagIndex = idx; } } diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index 11ace4f7ce..0d9fdb814a 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -975,7 +975,7 @@ int32_t filterAddUnitToGroup(SFilterGroup *group, uint32_t unitIdx) { return TSDB_CODE_SUCCESS; } -int32_t filterConvertSetFromBinary(void **q, const char *buf, int32_t len, uint32_t tType, bool tolower) { +int32_t filterConvertSetFromBinary(void **q, const char *buf, int32_t len, uint32_t tType, bool bTolower) { SBufferReader br = tbufInitReader(buf, len, false); uint32_t sType = tbufReadUint32(&br); SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(tType), true, false); @@ -1158,7 +1158,7 @@ int32_t filterConvertSetFromBinary(void **q, const char *buf, int32_t len, uint3 t = varDataLen(tmp); pvar = varDataVal(tmp); - if (tolower) { + if (bTolower) { strntolower_s(pvar, pvar, (int32_t)t); } break; @@ -2746,7 +2746,7 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t memset(info->blkUnitRes, 0, sizeof(*info->blkUnitRes) * info->unitNum); for (uint32_t k = 0; k < info->unitNum; ++k) { - int32_t index = -1; + int32_t idx = -1; SFilterComUnit *cunit = &info->cunits[k]; if (FILTER_NO_MERGE_DATA_TYPE(cunit->dataType)) { @@ -2755,16 +2755,16 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t for(int32_t i = 0; i < numOfCols; ++i) { if (pDataStatis[i].colId == cunit->colId) { - index = i; + idx = i; break; } } - if (index == -1) { + if (idx == -1) { continue; } - if (pDataStatis[index].numOfNull <= 0) { + if (pDataStatis[idx].numOfNull <= 0) { if (cunit->optr == TSDB_RELATION_ISNULL) { info->blkUnitRes[k] = -1; rmUnit = 1; @@ -2777,7 +2777,7 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t continue; } } else { - if (pDataStatis[index].numOfNull == numOfRows) { + if (pDataStatis[idx].numOfNull == numOfRows) { if (cunit->optr == TSDB_RELATION_ISNULL) { info->blkUnitRes[k] = 1; rmUnit = 1; @@ -2796,7 +2796,7 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t continue; } - SDataStatis* pDataBlockst = &pDataStatis[index]; + SDataStatis* pDataBlockst = &pDataStatis[idx]; void *minVal, *maxVal; float minv = 0; float maxv = 0; @@ -3586,17 +3586,17 @@ bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t num void *minVal, *maxVal; for (uint32_t k = 0; k < info->colRangeNum; ++k) { - int32_t index = -1; + int32_t idx = -1; SFilterRangeCtx *ctx = info->colRange[k]; for(int32_t i = 0; i < numOfCols; ++i) { if (pDataStatis[i].colId == ctx->colId) { - index = i; + idx = i; break; } } // no statistics data, load the true data block - if (index == -1) { + if (idx == -1) { break; } @@ -3605,13 +3605,13 @@ bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t num break; } - if (pDataStatis[index].numOfNull <= 0) { + if (pDataStatis[idx].numOfNull <= 0) { if (ctx->isnull && !ctx->notnull && !ctx->isrange) { ret = false; break; } - } else if (pDataStatis[index].numOfNull > 0) { - if (pDataStatis[index].numOfNull == numOfRows) { + } else if (pDataStatis[idx].numOfNull > 0) { + if (pDataStatis[idx].numOfNull == numOfRows) { if ((ctx->notnull || ctx->isrange) && (!ctx->isnull)) { ret = false; break; @@ -3625,7 +3625,7 @@ bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t num } } - SDataStatis* pDataBlockst = &pDataStatis[index]; + SDataStatis* pDataBlockst = &pDataStatis[idx]; SFilterRangeNode *r = ctx->rs; float minv = 0; diff --git a/src/query/src/qHistogram.c b/src/query/src/qHistogram.c index 8544224a64..752c7b96a5 100644 --- a/src/query/src/qHistogram.c +++ b/src/query/src/qHistogram.c @@ -45,15 +45,15 @@ //} // ////min heap -// void tHeapAdjust(SHeapEntry* pEntry, int32_t index, int32_t len) { +// void tHeapAdjust(SHeapEntry* pEntry, int32_t idx, int32_t len) { // SHeapEntry* ptr = NULL; // // int32_t end = len - 1; // -// SHeapEntry p1 = pEntry[index]; -// int32_t next = index; +// SHeapEntry p1 = pEntry[idx]; +// int32_t next = idx; // -// for(int32_t i=index; i<=(end-1)/2; ) { +// for(int32_t i=idx; i<=(end-1)/2; ) { // int32_t lc = (i<<1) + 1; // int32_t rc = (i+1) << 1; // @@ -119,7 +119,7 @@ // } //} -static int32_t histogramCreateBin(SHistogramInfo* pHisto, int32_t index, double val); +static int32_t histogramCreateBin(SHistogramInfo* pHisto, int32_t idx, double val); SHistogramInfo* tHistogramCreate(int32_t numOfEntries) { /* need one redundant slot */ @@ -191,7 +191,7 @@ int32_t tHistogramAdd(SHistogramInfo** pHisto, double val) { tSkipListNode* pResNode = SSkipListPut((*pHisto)->pList, entry, &key, 0); SHistBin* pEntry1 = (SHistBin*)pResNode->pData; - pEntry1->index = -1; + pEntry1->idx = -1; tSkipListNode* pLast = NULL; @@ -209,7 +209,7 @@ int32_t tHistogramAdd(SHistogramInfo** pHisto, double val) { SLoserTreeInfo* pTree = (*pHisto)->pLoserTree; (*pHisto)->pLoserTree->pNode[lastIndex + pTree->numOfEntries].pData = pResNode; - pEntry1->index = (*pHisto)->pLoserTree->pNode[lastIndex + pTree->numOfEntries].index; + pEntry1->idx = (*pHisto)->pLoserTree->pNode[lastIndex + pTree->numOfEntries].index; // update the loser tree if ((*pHisto)->ordered) { @@ -390,39 +390,39 @@ static void histogramMergeImpl(SHistBin* pHistBin, int32_t* size) { int32_t oldSize = *size; double delta = DBL_MAX; - int32_t index = -1; + int32_t idx = -1; for (int32_t i = 1; i < oldSize; ++i) { double d = pHistBin[i].val - pHistBin[i - 1].val; if (d < delta) { delta = d; - index = i - 1; + idx = i - 1; } } - SHistBin* s1 = &pHistBin[index]; - SHistBin* s2 = &pHistBin[index + 1]; + SHistBin* s1 = &pHistBin[idx]; + SHistBin* s2 = &pHistBin[idx + 1]; double newVal = (s1->val * s1->num + s2->val * s2->num) / (s1->num + s2->num); s1->val = newVal; s1->num = s1->num + s2->num; - memmove(&pHistBin[index + 1], &pHistBin[index + 2], (oldSize - index - 2) * sizeof(SHistBin)); + memmove(&pHistBin[idx + 1], &pHistBin[idx + 2], (oldSize - idx - 2) * sizeof(SHistBin)); (*size) -= 1; #endif } /* optimize this procedure */ -int32_t histogramCreateBin(SHistogramInfo* pHisto, int32_t index, double val) { +int32_t histogramCreateBin(SHistogramInfo* pHisto, int32_t idx, double val) { #if defined(USE_ARRAYLIST) - int32_t remain = pHisto->numOfEntries - index; + int32_t remain = pHisto->numOfEntries - idx; if (remain > 0) { - memmove(&pHisto->elems[index + 1], &pHisto->elems[index], sizeof(SHistBin) * remain); + memmove(&pHisto->elems[idx + 1], &pHisto->elems[idx], sizeof(SHistBin) * remain); } - assert(index >= 0 && index <= pHisto->maxEntries); + assert(idx >= 0 && idx <= pHisto->maxEntries); - pHisto->elems[index].num = 1; - pHisto->elems[index].val = val; + pHisto->elems[idx].num = 1; + pHisto->elems[idx].val = val; pHisto->numOfEntries += 1; /* we need to merge the slot */ diff --git a/src/query/src/qPercentile.c b/src/query/src/qPercentile.c index 8428c339f4..0210888b17 100644 --- a/src/query/src/qPercentile.c +++ b/src/query/src/qPercentile.c @@ -122,54 +122,54 @@ int32_t tBucketIntHash(tMemBucket *pBucket, const void *value) { int64_t v = 0; GET_TYPED_DATA(v, int64_t, pBucket->type, value); - int32_t index = -1; + int32_t idx = -1; if (v > pBucket->range.i64MaxVal || v < pBucket->range.i64MinVal) { - return index; + return idx; } // divide the value range into 1024 buckets uint64_t span = pBucket->range.i64MaxVal - pBucket->range.i64MinVal; if (span < pBucket->numOfSlots) { int64_t delta = v - pBucket->range.i64MinVal; - index = (delta % pBucket->numOfSlots); + idx = (delta % pBucket->numOfSlots); } else { double slotSpan = (double)span / pBucket->numOfSlots; - index = (int32_t)(((double)v - pBucket->range.i64MinVal) / slotSpan); - if (index == pBucket->numOfSlots) { - index -= 1; + idx = (int32_t)(((double)v - pBucket->range.i64MinVal) / slotSpan); + if (idx == pBucket->numOfSlots) { + idx -= 1; } } - assert(index >= 0 && index < pBucket->numOfSlots); - return index; + assert(idx >= 0 && idx < pBucket->numOfSlots); + return idx; } int32_t tBucketUintHash(tMemBucket *pBucket, const void *value) { uint64_t v = 0; GET_TYPED_DATA(v, uint64_t, pBucket->type, value); - int32_t index = -1; + int32_t idx = -1; if (v > pBucket->range.u64MaxVal || v < pBucket->range.u64MinVal) { - return index; + return idx; } // divide the value range into 1024 buckets uint64_t span = pBucket->range.u64MaxVal - pBucket->range.u64MinVal; if (span < pBucket->numOfSlots) { int64_t delta = v - pBucket->range.u64MinVal; - index = (int32_t) (delta % pBucket->numOfSlots); + idx = (int32_t) (delta % pBucket->numOfSlots); } else { double slotSpan = (double)span / pBucket->numOfSlots; - index = (int32_t)(((double)v - pBucket->range.u64MinVal) / slotSpan); - if (index == pBucket->numOfSlots) { - index -= 1; + idx = (int32_t)(((double)v - pBucket->range.u64MinVal) / slotSpan); + if (idx == pBucket->numOfSlots) { + idx -= 1; } } - assert(index >= 0 && index < pBucket->numOfSlots); - return index; + assert(idx >= 0 && idx < pBucket->numOfSlots); + return idx; } int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) { @@ -180,27 +180,27 @@ int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) { v = GET_DOUBLE_VAL(value); } - int32_t index = -1; + int32_t idx = -1; if (v > pBucket->range.dMaxVal || v < pBucket->range.dMinVal) { - return index; + return idx; } // divide a range of [dMinVal, dMaxVal] into 1024 buckets double span = pBucket->range.dMaxVal - pBucket->range.dMinVal; if (span < pBucket->numOfSlots) { int32_t delta = (int32_t)(v - pBucket->range.dMinVal); - index = (delta % pBucket->numOfSlots); + idx = (delta % pBucket->numOfSlots); } else { double slotSpan = span / pBucket->numOfSlots; - index = (int32_t)((v - pBucket->range.dMinVal) / slotSpan); - if (index == pBucket->numOfSlots) { - index -= 1; + idx = (int32_t)((v - pBucket->range.dMinVal) / slotSpan); + if (idx == pBucket->numOfSlots) { + idx -= 1; } } - assert(index >= 0 && index < pBucket->numOfSlots); - return index; + assert(idx >= 0 && idx < pBucket->numOfSlots); + return idx; } static __perc_hash_func_t getHashFunc(int32_t type) { @@ -332,18 +332,18 @@ int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size) { for (int32_t i = 0; i < size; ++i) { char *d = (char *) data + i * bytes; - int32_t index = (pBucket->hashFunc)(pBucket, d); - if (index < 0) { + int32_t idx = (pBucket->hashFunc)(pBucket, d); + if (idx < 0) { continue; } count += 1; - tMemBucketSlot *pSlot = &pBucket->pSlots[index]; + tMemBucketSlot *pSlot = &pBucket->pSlots[idx]; tMemBucketUpdateBoundingBox(&pSlot->range, d, pBucket->type); // ensure available memory pages to allocate - int32_t groupId = getGroupId(pBucket->numOfSlots, index, pBucket->times); + int32_t groupId = getGroupId(pBucket->numOfSlots, idx, pBucket->times); int32_t pageId = -1; if (pSlot->info.data == NULL || pSlot->info.data->num >= pBucket->elemPerPage) { @@ -387,7 +387,7 @@ static MinMaxEntry getMinMaxEntryOfNextSlotWithData(tMemBucket *pMemBucket, int3 return pMemBucket->pSlots[j].range; } -static bool isIdenticalData(tMemBucket *pMemBucket, int32_t index); +static bool isIdenticalData(tMemBucket *pMemBucket, int32_t idx); static double getIdenticalDataVal(tMemBucket* pMemBucket, int32_t slotIndex) { assert(isIdenticalData(pMemBucket, slotIndex)); @@ -532,8 +532,8 @@ double getPercentile(tMemBucket *pMemBucket, double percent) { /* * check if data in one slot are all identical only need to compare with the bounding box */ -bool isIdenticalData(tMemBucket *pMemBucket, int32_t index) { - tMemBucketSlot *pSeg = &pMemBucket->pSlots[index]; +bool isIdenticalData(tMemBucket *pMemBucket, int32_t idx) { + tMemBucketSlot *pSeg = &pMemBucket->pSlots[idx]; if (IS_FLOAT_TYPE(pMemBucket->type)) { return fabs(pSeg->range.dMaxVal - pSeg->range.dMinVal) < DBL_EPSILON; diff --git a/src/query/src/qPlan.c b/src/query/src/qPlan.c index 95c7f81ed6..eda920063f 100644 --- a/src/query/src/qPlan.c +++ b/src/query/src/qPlan.c @@ -126,9 +126,9 @@ static SQueryNode* doAddTableColumnNode(SQueryInfo* pQueryInfo, STableMetaInfo* for (int32_t i = 0; i < numOfCols; ++i) { SColumn* pCol = taosArrayGetP(tableCols, i); - SColumnIndex index = {.tableIndex = 0, .columnIndex = pCol->columnIndex}; - STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SExprInfo* p = tscExprCreate(pTableMetaInfo1, TSDB_FUNC_PRJ, &index, pCol->info.type, pCol->info.bytes, + SColumnIndex idx = {.tableIndex = 0, .columnIndex = pCol->columnIndex}; + STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SExprInfo* p = tscExprCreate(pTableMetaInfo1, TSDB_FUNC_PRJ, &idx, pCol->info.type, pCol->info.bytes, pCol->info.colId, 0, TSDB_COL_NORMAL); strncpy(p->base.aliasName, pSchema[pCol->columnIndex].name, tListLen(p->base.aliasName)); diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index cee5130651..28cc1c10a2 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -857,8 +857,8 @@ SArray *tVariantListAppend(SArray *pList, tVariant *pVar, uint8_t sortOrder) { return pList; } -SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int32_t index) { - if (pList == NULL || pVar == NULL || index >= taosArrayGetSize(pList)) { +SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int32_t idx) { + if (pList == NULL || pVar == NULL || idx >= taosArrayGetSize(pList)) { return tVariantListAppend(NULL, pVar, sortOrder); } @@ -867,7 +867,7 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int item.pVar = *pVar; item.sortOrder = sortOrder; - taosArrayInsert(pList, index, &item); + taosArrayInsert(pList, idx, &item); return pList; } @@ -878,7 +878,8 @@ SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, } pRelationInfo->type = SQL_NODE_FROM_TABLELIST; - SRelElementPair p = {.tableName = *pName}; + SRelElementPair p; + p.tableName = *pName; if (pAlias != NULL) { p.aliasName = *pAlias; } else { @@ -917,7 +918,8 @@ SRelationInfo* addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrT pRelationInfo->type = SQL_NODE_FROM_SUBQUERY; - SRelElementPair p = {.pSubquery = pSub}; + SRelElementPair p; + p.pSubquery = pSub; if (pAlias != NULL) { p.aliasName = *pAlias; } else { diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index 1628c2d511..60ae900eb7 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -183,9 +183,9 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16 } // TODO refactor: use macro -SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset) { - assert(index >= 0 && offset != NULL); - return (SResultRowCellInfo*)((char*) pRow->pCellInfo + offset[index]); +SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t idx, int32_t* offset) { + assert(idx >= 0 && offset != NULL); + return (SResultRowCellInfo*)((char*) pRow->pCellInfo + offset[idx]); } size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv) { diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index b2941a8fe0..ee3245dd57 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -597,7 +597,7 @@ void** qReleaseQInfo(void* pMgmt, void* pQInfo, bool freeHandle) { //kill by qid int32_t qKillQueryByQId(void* pMgmt, int64_t qId, int32_t waitMs, int32_t waitCount) { - int32_t error = TSDB_CODE_SUCCESS; + int32_t err = TSDB_CODE_SUCCESS; void** handle = qAcquireQInfo(pMgmt, qId); if(handle == NULL) return terrno; @@ -613,13 +613,13 @@ int32_t qKillQueryByQId(void* pMgmt, int64_t qId, int32_t waitMs, int32_t waitCo while (pQInfo->owner != 0) { taosMsleep(waitMs); if(loop++ > waitCount){ - error = TSDB_CODE_FAILED; + err = TSDB_CODE_FAILED; break; } } qReleaseQInfo(pMgmt, (void **)&handle, true); - return error; + return err; } // local struct diff --git a/src/rpc/src/rpcCache.c b/src/rpc/src/rpcCache.c index 60a12c26b7..d18aa12c13 100644 --- a/src/rpc/src/rpcCache.c +++ b/src/rpc/src/rpcCache.c @@ -49,7 +49,7 @@ static int rpcHashConn(void *handle, char *fqdn, uint16_t port, int8_t connType static void rpcLockCache(int64_t *lockedBy); static void rpcUnlockCache(int64_t *lockedBy); static void rpcCleanConnCache(void *handle, void *tmrId); -static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t time); +static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t timeStamp); void *rpcOpenConnCache(int maxSessions, void (*cleanFp)(void *), void *tmrCtrl, int64_t keepTimer) { SConnHash **connHashList; @@ -118,7 +118,7 @@ void rpcAddConnIntoCache(void *handle, void *data, char *fqdn, uint16_t port, in SConnHash * pNode; SConnCache *pCache; - uint64_t time = taosGetTimestampMs(); + uint64_t timeStamp = taosGetTimestampMs(); pCache = (SConnCache *)handle; assert(pCache); @@ -131,7 +131,7 @@ void rpcAddConnIntoCache(void *handle, void *data, char *fqdn, uint16_t port, in pNode->connType = connType; pNode->data = data; pNode->prev = NULL; - pNode->time = time; + pNode->time = timeStamp; rpcLockCache(pCache->lockedBy+hash); @@ -140,7 +140,7 @@ void rpcAddConnIntoCache(void *handle, void *data, char *fqdn, uint16_t port, in pCache->connHashList[hash] = pNode; pCache->count[hash]++; - rpcRemoveExpiredNodes(pCache, pNode->next, hash, time); + rpcRemoveExpiredNodes(pCache, pNode->next, hash, timeStamp); rpcUnlockCache(pCache->lockedBy+hash); @@ -159,15 +159,15 @@ void *rpcGetConnFromCache(void *handle, char *fqdn, uint16_t port, int8_t connTy pCache = (SConnCache *)handle; assert(pCache); - uint64_t time = taosGetTimestampMs(); + uint64_t timeStamp = taosGetTimestampMs(); hash = rpcHashConn(pCache, fqdn, port, connType); rpcLockCache(pCache->lockedBy+hash); pNode = pCache->connHashList[hash]; while (pNode) { - if (time >= pCache->keepTimer + pNode->time) { - rpcRemoveExpiredNodes(pCache, pNode, hash, time); + if (timeStamp >= pCache->keepTimer + pNode->time) { + rpcRemoveExpiredNodes(pCache, pNode, hash, timeStamp); pNode = NULL; break; } @@ -178,7 +178,7 @@ void *rpcGetConnFromCache(void *handle, char *fqdn, uint16_t port, int8_t connTy } if (pNode) { - rpcRemoveExpiredNodes(pCache, pNode->next, hash, time); + rpcRemoveExpiredNodes(pCache, pNode->next, hash, timeStamp); if (pNode->prev) { pNode->prev->next = pNode->next; @@ -217,12 +217,12 @@ static void rpcCleanConnCache(void *handle, void *tmrId) { if (pCache->pTimer != tmrId) return; pthread_mutex_lock(&pCache->mutex); - uint64_t time = taosGetTimestampMs(); + uint64_t timeStamp = taosGetTimestampMs(); for (hash = 0; hash < pCache->maxSessions; ++hash) { rpcLockCache(pCache->lockedBy+hash); pNode = pCache->connHashList[hash]; - rpcRemoveExpiredNodes(pCache, pNode, hash, time); + rpcRemoveExpiredNodes(pCache, pNode, hash, timeStamp); rpcUnlockCache(pCache->lockedBy+hash); } @@ -231,8 +231,8 @@ static void rpcCleanConnCache(void *handle, void *tmrId) { pthread_mutex_unlock(&pCache->mutex); } -static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t time) { - if (pNode == NULL || (time < pCache->keepTimer + pNode->time) ) return; +static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t timeStamp) { + if (pNode == NULL || (timeStamp < pCache->keepTimer + pNode->time) ) return; SConnHash *pPrev = pNode->prev, *pNext; diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index 740a1e2b7d..44686fa9e0 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -392,9 +392,9 @@ void taosCleanUpTcpClient(void *chandle) { void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uint16_t port) { SClientObj * pClientObj = shandle; - int32_t index = atomic_load_32(&pClientObj->index) % pClientObj->numOfThreads; - atomic_store_32(&pClientObj->index, index + 1); - SThreadObj *pThreadObj = pClientObj->pThreadObj[index]; + int32_t idx = atomic_load_32(&pClientObj->index) % pClientObj->numOfThreads; + atomic_store_32(&pClientObj->index, idx + 1); + SThreadObj *pThreadObj = pClientObj->pThreadObj[idx]; SOCKET fd = taosOpenTcpClientSocket(ip, port, pThreadObj->ip); #if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) @@ -403,12 +403,12 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin if (fd <= 0) return NULL; #endif - struct sockaddr_in sin; + struct sockaddr_in sockin; uint16_t localPort = 0; - unsigned int addrlen = sizeof(sin); - if (getsockname(fd, (struct sockaddr *)&sin, &addrlen) == 0 && - sin.sin_family == AF_INET && addrlen == sizeof(sin)) { - localPort = (uint16_t)ntohs(sin.sin_port); + unsigned int addrlen = sizeof(sockin); + if (getsockname(fd, (struct sockaddr *)&sockin, &addrlen) == 0 && + sockin.sin_family == AF_INET && addrlen == sizeof(sockin)) { + localPort = (uint16_t)ntohs(sockin.sin_port); } SFdObj *pFdObj = taosMallocFdObj(pThreadObj, fd); diff --git a/src/rpc/src/rpcUdp.c b/src/rpc/src/rpcUdp.c index 46313543d8..7b0f27a3d6 100644 --- a/src/rpc/src/rpcUdp.c +++ b/src/rpc/src/rpcUdp.c @@ -97,11 +97,11 @@ void *taosInitUdpConnection(uint32_t ip, uint16_t port, char *label, int threads break; } - struct sockaddr_in sin; - unsigned int addrlen = sizeof(sin); - if (getsockname(pConn->fd, (struct sockaddr *)&sin, &addrlen) == 0 && - sin.sin_family == AF_INET && addrlen == sizeof(sin)) { - pConn->localPort = (uint16_t)ntohs(sin.sin_port); + struct sockaddr_in sockin; + unsigned int addrlen = sizeof(sockin); + if (getsockname(pConn->fd, (struct sockaddr *)&sockin, &addrlen) == 0 && + sockin.sin_family == AF_INET && addrlen == sizeof(sockin)) { + pConn->localPort = (uint16_t)ntohs(sockin.sin_port); } tstrncpy(pConn->label, label, sizeof(pConn->label)); diff --git a/src/rpc/test/rclient.c b/src/rpc/test/rclient.c index 2f4433f1bb..42b77e624e 100644 --- a/src/rpc/test/rclient.c +++ b/src/rpc/test/rclient.c @@ -70,7 +70,7 @@ static void *sendRequest(void *param) { } int main(int argc, char *argv[]) { - SRpcInit rpcInit; + SRpcInit rpcInitial; SRpcEpSet epSet; int msgSize = 128; int numOfReqs = 0; @@ -90,18 +90,18 @@ int main(int argc, char *argv[]) { strcpy(epSet.fqdn[1], "192.168.0.1"); // client info - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = 0; - rpcInit.label = "APP"; - rpcInit.numOfThreads = 1; - rpcInit.cfp = processResponse; - rpcInit.sessions = 100; - rpcInit.idleTime = tsShellActivityTimer*1000; - rpcInit.user = "michael"; - rpcInit.secret = secret; - rpcInit.ckey = "key"; - rpcInit.spi = 1; - rpcInit.connType = TAOS_CONN_CLIENT; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = 0; + rpcInitial.label = "APP"; + rpcInitial.numOfThreads = 1; + rpcInitial.cfp = processResponse; + rpcInitial.sessions = 100; + rpcInitial.idleTime = tsShellActivityTimer*1000; + rpcInitial.user = "michael"; + rpcInitial.secret = secret; + rpcInitial.ckey = "key"; + rpcInitial.spi = 1; + rpcInitial.connType = TAOS_CONN_CLIENT; for (int i=1; ireplica; ++index) { - const SNodeInfo *pNodeInfo = pCfg->nodeInfo + index; - pNode->peerInfo[index] = syncAddPeer(pNode, pNodeInfo); - if (pNode->peerInfo[index] == NULL) { + for (int32_t idx = 0; idx < pCfg->replica; ++idx) { + const SNodeInfo *pNodeInfo = pCfg->nodeInfo + idx; + pNode->peerInfo[idx] = syncAddPeer(pNode, pNodeInfo); + if (pNode->peerInfo[idx] == NULL) { sError("vgId:%d, node:%d fqdn:%s port:%u is not configured, stop taosd", pNode->vgId, pNodeInfo->nodeId, pNodeInfo->nodeFqdn, pNodeInfo->nodePort); syncStop(pNode->rid); @@ -210,7 +210,7 @@ int64_t syncStart(const SSyncInfo *pInfo) { } if ((strcmp(pNodeInfo->nodeFqdn, tsNodeFqdn) == 0) && (pNodeInfo->nodePort == tsSyncPort)) { - pNode->selfIndex = index; + pNode->selfIndex = idx; } } @@ -256,8 +256,8 @@ int64_t syncStart(const SSyncInfo *pInfo) { } syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb - for (int32_t index = 0; index < pNode->replica; ++index) { - syncStartCheckPeerConn(pNode->peerInfo[index]); + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + syncStartCheckPeerConn(pNode->peerInfo[idx]); } return pNode->rid; @@ -277,8 +277,8 @@ void syncStop(int64_t rid) { if (pNode->pFwdTimer) taosTmrStop(pNode->pFwdTimer); if (pNode->pRoleTimer) taosTmrStop(pNode->pRoleTimer); - for (int32_t index = 0; index < pNode->replica; ++index) { - pPeer = pNode->peerInfo[index]; + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + pPeer = pNode->peerInfo[idx]; if (pPeer) syncRemovePeer(pPeer); } @@ -303,8 +303,8 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) { pthread_mutex_lock(&pNode->mutex); syncStopCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb - for (int32_t index = 0; index < pNode->replica; ++index) { - syncStopCheckPeerConn(pNode->peerInfo[index]); + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + syncStopCheckPeerConn(pNode->peerInfo[idx]); } for (i = 0; i < pNode->replica; ++i) { @@ -364,8 +364,8 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) { } syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb - for (int32_t index = 0; index < pNode->replica; ++index) { - syncStartCheckPeerConn(pNode->peerInfo[index]); + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + syncStartCheckPeerConn(pNode->peerInfo[idx]); } pthread_mutex_unlock(&pNode->mutex); @@ -629,16 +629,16 @@ static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) { } void syncBroadcastStatus(SSyncNode *pNode) { - for (int32_t index = 0; index < pNode->replica; ++index) { - if (index == pNode->selfIndex) continue; - SSyncPeer *pPeer = pNode->peerInfo[index]; + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + if (idx == pNode->selfIndex) continue; + SSyncPeer *pPeer = pNode->peerInfo[idx]; syncSendPeersStatusMsgToPeer(pPeer, 1, SYNC_STATUS_BROADCAST, syncGenTranId()); } } static void syncResetFlowCtrl(SSyncNode *pNode) { - for (int32_t index = 0; index < pNode->replica; ++index) { - pNode->peerInfo[index]->numOfRetrieves = 0; + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + pNode->peerInfo[idx]->numOfRetrieves = 0; } if (pNode->notifyFlowCtrlFp) { @@ -649,7 +649,7 @@ static void syncResetFlowCtrl(SSyncNode *pNode) { static void syncChooseMaster(SSyncNode *pNode) { SSyncPeer *pPeer; int32_t onlineNum = 0; - int32_t index = -1; + int32_t idx = -1; int32_t replica = pNode->replica; for (int32_t i = 0; i < pNode->replica; ++i) { @@ -660,13 +660,13 @@ static void syncChooseMaster(SSyncNode *pNode) { if (onlineNum == pNode->replica) { // if all peers are online, peer with highest version shall be master - index = 0; + idx = 0; for (int32_t i = 1; i < pNode->replica; ++i) { - if (pNode->peerInfo[i]->version > pNode->peerInfo[index]->version) { - index = i; + if (pNode->peerInfo[i]->version > pNode->peerInfo[idx]->version) { + idx = i; } } - sDebug("vgId:%d, master:%s may be choosed, index:%d", pNode->vgId, pNode->peerInfo[index]->id, index); + sDebug("vgId:%d, master:%s may be choosed, index:%d", pNode->vgId, pNode->peerInfo[idx]->id, idx); } else { sDebug("vgId:%d, no master election since onlineNum:%d replica:%d", pNode->vgId, onlineNum, pNode->replica); } @@ -683,26 +683,26 @@ static void syncChooseMaster(SSyncNode *pNode) { } } - if (index < 0 && onlineNum > replica / 2.0) { + if (idx < 0 && onlineNum > replica / 2.0) { // over half of nodes are online for (int32_t i = 0; i < pNode->replica; ++i) { // slave with highest version shall be master pPeer = pNode->peerInfo[i]; if (pPeer->role == TAOS_SYNC_ROLE_SLAVE || pPeer->role == TAOS_SYNC_ROLE_MASTER) { - if (index < 0 || pPeer->version > pNode->peerInfo[index]->version) { - index = i; + if (idx < 0 || pPeer->version > pNode->peerInfo[idx]->version) { + idx = i; } } } - if (index >= 0) { + if (idx >= 0) { sDebug("vgId:%d, master:%s may be choosed, index:%d onlineNum(arb):%d replica:%d", pNode->vgId, - pNode->peerInfo[index]->id, index, onlineNum, replica); + pNode->peerInfo[idx]->id, idx, onlineNum, replica); } } - if (index >= 0) { - if (index == pNode->selfIndex) { + if (idx >= 0) { + if (idx == pNode->selfIndex) { sInfo("vgId:%d, start to work as master", pNode->vgId); nodeRole = TAOS_SYNC_ROLE_MASTER; @@ -712,7 +712,7 @@ static void syncChooseMaster(SSyncNode *pNode) { syncResetFlowCtrl(pNode); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole); } else { - pPeer = pNode->peerInfo[index]; + pPeer = pNode->peerInfo[idx]; sInfo("%s, it shall work as master", pPeer->id); } } else { @@ -725,8 +725,8 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { int32_t masterIndex = -1; int32_t replica = pNode->replica; - for (int32_t index = 0; index < pNode->replica; ++index) { - if (pNode->peerInfo[index]->role != TAOS_SYNC_ROLE_OFFLINE) { + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + if (pNode->peerInfo[idx]->role != TAOS_SYNC_ROLE_OFFLINE) { onlineNum++; } } @@ -751,19 +751,19 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { (*pNode->notifyRoleFp)(pNode->vgId, nodeRole); } } else { - for (int32_t index = 0; index < pNode->replica; ++index) { - SSyncPeer *pTemp = pNode->peerInfo[index]; + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + SSyncPeer *pTemp = pNode->peerInfo[idx]; if (pTemp->role != TAOS_SYNC_ROLE_MASTER) continue; if (masterIndex < 0) { - masterIndex = index; - sDebug("vgId:%d, peer:%s is master, index:%d", pNode->vgId, pTemp->id, index); + masterIndex = idx; + sDebug("vgId:%d, peer:%s is master, index:%d", pNode->vgId, pTemp->id, idx); } else { // multiple masters, it shall not happen if (masterIndex == pNode->selfIndex) { sError("%s, peer is master, work as slave instead", pTemp->id); nodeRole = TAOS_SYNC_ROLE_SLAVE; (*pNode->notifyRoleFp)(pNode->vgId, nodeRole); } else { - sError("vgId:%d, peer:%s is master too, masterIndex:%d index:%d", pNode->vgId, pTemp->id, masterIndex, index); + sError("vgId:%d, peer:%s is master too, masterIndex:%d index:%d", pNode->vgId, pTemp->id, masterIndex, idx); } } } @@ -783,9 +783,9 @@ static int32_t syncValidateMaster(SSyncPeer *pPeer) { (*pNode->notifyRoleFp)(pNode->vgId, nodeRole); code = -1; - for (int32_t index = 0; index < pNode->replica; ++index) { - if (index == pNode->selfIndex) continue; - syncRestartPeer(pNode->peerInfo[index]); + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + if (idx == pNode->selfIndex) continue; + syncRestartPeer(pNode->peerInfo[idx]); } } @@ -825,15 +825,15 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus* peersStatus, int8_t new } else { // master not there, if all peer's state and version are consistent, choose the master int32_t consistent = 0; - int32_t index = 0; + int32_t idx = 0; if (peersStatus != NULL) { - for (index = 0; index < pNode->replica; ++index) { - SSyncPeer *pTemp = pNode->peerInfo[index]; - if (pTemp->role != peersStatus[index].role) break; - if ((pTemp->role != TAOS_SYNC_ROLE_OFFLINE) && (pTemp->version != peersStatus[index].version)) break; + for (idx = 0; idx < pNode->replica; ++idx) { + SSyncPeer *pTemp = pNode->peerInfo[idx]; + if (pTemp->role != peersStatus[idx].role) break; + if ((pTemp->role != TAOS_SYNC_ROLE_OFFLINE) && (pTemp->version != peersStatus[idx].version)) break; } - if (index >= pNode->replica) consistent = 1; + if (idx >= pNode->replica) consistent = 1; } else { if (pNode->replica == 2) consistent = 1; } @@ -1331,7 +1331,7 @@ static void syncProcessBrokenLink(int64_t rid, int32_t closedByApp) { static int32_t syncSaveFwdInfo(SSyncNode *pNode, uint64_t _version, void *mhandle) { SSyncFwds *pSyncFwds = pNode->pSyncFwds; - int64_t time = taosGetTimestampMs(); + int64_t lastTime = taosGetTimestampMs(); if (pSyncFwds->fwds >= SYNC_MAX_FWDS) { // pSyncFwds->first = (pSyncFwds->first + 1) % SYNC_MAX_FWDS; @@ -1348,7 +1348,7 @@ static int32_t syncSaveFwdInfo(SSyncNode *pNode, uint64_t _version, void *mhandl memset(pFwdInfo, 0, sizeof(SFwdInfo)); pFwdInfo->version = _version; pFwdInfo->mhandle = mhandle; - pFwdInfo->time = time; + pFwdInfo->time = lastTime; pSyncFwds->fwds++; sTrace("vgId:%d, fwd info is saved, hver:%" PRIu64 " fwds:%d ", pNode->vgId, _version, pSyncFwds->fwds); @@ -1400,10 +1400,10 @@ static void syncMonitorNodeRole(void *param, void *tmrId) { SSyncNode *pNode = syncAcquireNode(rid); if (pNode == NULL) return; - for (int32_t index = 0; index < pNode->replica; index++) { - if (index == pNode->selfIndex) continue; + for (int32_t idx = 0; idx < pNode->replica; idx++) { + if (idx == pNode->selfIndex) continue; - SSyncPeer *pPeer = pNode->peerInfo[index]; + SSyncPeer *pPeer = pNode->peerInfo[idx]; if (/*pPeer->role > TAOS_SYNC_ROLE_UNSYNCED && */ nodeRole > TAOS_SYNC_ROLE_UNSYNCED) continue; if (/*pPeer->sstatus > TAOS_SYNC_STATUS_INIT || */ nodeSStatus > TAOS_SYNC_STATUS_INIT) continue; @@ -1425,16 +1425,16 @@ static void syncMonitorFwdInfos(void *param, void *tmrId) { SSyncFwds *pSyncFwds = pNode->pSyncFwds; if (pSyncFwds) { - int64_t time = taosGetTimestampMs(); + int64_t lastTime = taosGetTimestampMs(); if (pSyncFwds->fwds > 0) { pthread_mutex_lock(&pNode->mutex); for (int32_t i = 0; i < pSyncFwds->fwds; ++i) { SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + (pSyncFwds->first + i) % SYNC_MAX_FWDS; - if (ABS(time - pFwdInfo->time) < 10000) break; + if (ABS(lastTime - pFwdInfo->time) < 10000) break; sDebug("vgId:%d, forward info expired, hver:%" PRIu64 " curtime:%" PRIu64 " savetime:%" PRIu64, pNode->vgId, - pFwdInfo->version, time, pFwdInfo->time); + pFwdInfo->version, lastTime, pFwdInfo->time); syncProcessFwdAck(pNode, pFwdInfo, TSDB_CODE_SYN_CONFIRM_EXPIRED); } diff --git a/src/sync/src/syncRetrieve.c b/src/sync/src/syncRetrieve.c index 623d6e3cc0..f0fcf6d6dd 100644 --- a/src/sync/src/syncRetrieve.c +++ b/src/sync/src/syncRetrieve.c @@ -228,7 +228,7 @@ static int64_t syncRetrieveLastWal(SSyncPeer *pPeer, char *name, uint64_t fversi return code; } -static int64_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t index) { +static int64_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t idx) { SSyncNode *pNode = pPeer->pSyncNode; int32_t once = 0; // last WAL has once ever been processed int64_t offset = 0; @@ -290,12 +290,12 @@ static int64_t syncRetrieveWal(SSyncPeer *pPeer) { char wname[TSDB_FILENAME_LEN * 2]; int32_t size; int64_t code = -1; - int64_t index = 0; + int64_t idx = 0; while (1) { // retrieve wal info wname[0] = 0; - code = (*pNode->getWalInfoFp)(pNode->vgId, wname, &index); + code = (*pNode->getWalInfoFp)(pNode->vgId, wname, &idx); if (code < 0) { sError("%s, failed to get wal info since:%s, code:0x%" PRIx64, pPeer->id, strerror(errno), code); break; @@ -308,7 +308,7 @@ static int64_t syncRetrieveWal(SSyncPeer *pPeer) { } if (code == 0) { // last wal - code = syncProcessLastWal(pPeer, wname, index); + code = syncProcessLastWal(pPeer, wname, idx); sInfo("%s, last wal processed, code:%" PRId64, pPeer->id, code); break; } @@ -317,14 +317,14 @@ static int64_t syncRetrieveWal(SSyncPeer *pPeer) { snprintf(fname, sizeof(fname), "%s/%s", pNode->path, wname); // send wal file, old wal file won't be modified, even remove is ok - struct stat fstat; - if (stat(fname, &fstat) < 0) { + struct stat fstatus; + if (stat(fname, &fstatus) < 0) { code = -1; sInfo("%s, failed to stat wal:%s for retrieve since %s, code:0x%" PRIx64, pPeer->id, fname, strerror(errno), code); break; } - size = fstat.st_size; + size = fstatus.st_size; sInfo("%s, retrieve wal:%s size:%d", pPeer->id, fname, size); int32_t sfd = open(fname, O_RDONLY | O_BINARY); diff --git a/src/tsdb/src/tsdbCommit.c b/src/tsdb/src/tsdbCommit.c index 6b19fdf3c1..3abc3e9acc 100644 --- a/src/tsdb/src/tsdbCommit.c +++ b/src/tsdb/src/tsdbCommit.c @@ -275,7 +275,7 @@ int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf) { // =================== Commit Meta Data -static int tsdbInitCommitMetaFile(STsdbRepo *pRepo, SMFile* pMf, bool open) { +static int tsdbInitCommitMetaFile(STsdbRepo *pRepo, SMFile* pMf, bool bOpen) { STsdbFS * pfs = REPO_FS(pRepo); SMFile * pOMFile = pfs->cstatus->pmf; SDiskID did; @@ -287,7 +287,7 @@ static int tsdbInitCommitMetaFile(STsdbRepo *pRepo, SMFile* pMf, bool open) { did.id = TFS_PRIMARY_ID; tsdbInitMFile(pMf, did, REPO_ID(pRepo), FS_TXN_VERSION(REPO_FS(pRepo))); - if (open && tsdbCreateMFile(pMf, true) < 0) { + if (bOpen && tsdbCreateMFile(pMf, true) < 0) { tsdbError("vgId:%d failed to create META file since %s", REPO_ID(pRepo), tstrerror(terrno)); return -1; } @@ -295,7 +295,7 @@ static int tsdbInitCommitMetaFile(STsdbRepo *pRepo, SMFile* pMf, bool open) { tsdbInfo("vgId:%d meta file %s is created to commit", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMf)); } else { tsdbInitMFileEx(pMf, pOMFile); - if (open && tsdbOpenMFile(pMf, O_WRONLY) < 0) { + if (bOpen && tsdbOpenMFile(pMf, O_WRONLY) < 0) { tsdbError("vgId:%d failed to open META file since %s", REPO_ID(pRepo), tstrerror(terrno)); return -1; } @@ -1813,4 +1813,4 @@ int tsdbCommitControl(STsdbRepo* pRepo, SControlDataInfo* pCtlDataInfo) { tsem_post(&pRepo->readyToCommit); return ret; -} \ No newline at end of file +} diff --git a/src/tsdb/src/tsdbFS.c b/src/tsdb/src/tsdbFS.c index b3d52e8fad..bfeb61e4f1 100644 --- a/src/tsdb/src/tsdbFS.c +++ b/src/tsdb/src/tsdbFS.c @@ -1217,13 +1217,13 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { bool isOneFSetFinish = true; int lastFType = -1; // one fileset ends when (1) the array ends or (2) encounter different fid - for (size_t index = 0; index < fArraySize; ++index) { + for (size_t idx = 0; idx < fArraySize; ++idx) { int tvid = -1, tfid = -1; TSDB_FILE_T ttype = TSDB_FILE_MAX; uint32_t tversion = -1; char bname[TSDB_FILENAME_LEN] = "\0"; - pf = taosArrayGet(fArray, index); + pf = taosArrayGet(fArray, idx); tfsbasename(pf, bname); tsdbParseDFilename(bname, &tvid, &tfid, &ttype, &tversion); ASSERT(tvid == REPO_ID(pRepo)); @@ -1237,7 +1237,7 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { lastFType = ttype; - if (index == 0) { + if (idx == 0) { memset(&fset, 0, sizeof(SDFileSet)); TSDB_FSET_SET_CLOSED(&fset); nDFiles = 1; @@ -1249,7 +1249,7 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { ++nDFiles; pDFile->f = *pf; // (1) the array ends - if (index == fArraySize - 1) { + if (idx == fArraySize - 1) { if (tsdbIsDFileSetValid(nDFiles)) { tsdbInfo("vgId:%d DFileSet %d is fetched, nDFiles=%" PRIu8, REPO_ID(pRepo), fset.fid, nDFiles); isOneFSetFinish = true; diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c index 2ae215ad36..5392fc075b 100644 --- a/src/tsdb/src/tsdbMain.c +++ b/src/tsdb/src/tsdbMain.c @@ -344,7 +344,7 @@ int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg) { #endif } -uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t eindex, int64_t *size) { +uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *idx, uint32_t eindex, int64_t *size) { // TODO return 0; #if 0 @@ -356,16 +356,16 @@ uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t struct stat fState; - tsdbDebug("vgId:%d name:%s index:%d eindex:%d", pRepo->config.tsdbId, name, *index, eindex); - ASSERT(*index <= eindex); + tsdbDebug("vgId:%d name:%s index:%d eindex:%d", pRepo->config.tsdbId, name, *idx, eindex); + ASSERT(*idx <= eindex); if (name[0] == 0) { // get the file from index or after, but not larger than eindex - int fid = (*index) / TSDB_FILE_TYPE_MAX; + int fid = (*idx) / TSDB_FILE_TYPE_MAX; if (pFileH->nFGroups == 0 || fid > pFileH->pFGroup[pFileH->nFGroups - 1].fileId) { - if (*index <= TSDB_META_FILE_INDEX && TSDB_META_FILE_INDEX <= eindex) { + if (*idx <= TSDB_META_FILE_INDEX && TSDB_META_FILE_INDEX <= eindex) { fname = tsdbGetMetaFileName(pRepo->rootDir); - *index = TSDB_META_FILE_INDEX; + *idx = TSDB_META_FILE_INDEX; magic = TSDB_META_FILE_MAGIC(pRepo->tsdbMeta); sprintf(name, "tsdb/%s", TSDB_META_FILE_NAME); } else { @@ -375,7 +375,7 @@ uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t SFileGroup *pFGroup = taosbsearch(&fid, pFileH->pFGroup, pFileH->nFGroups, sizeof(SFileGroup), keyFGroupCompFunc, TD_GE); if (pFGroup->fileId == fid) { - SFile *pFile = &pFGroup->files[(*index) % TSDB_FILE_TYPE_MAX]; + SFile *pFile = &pFGroup->files[(*idx) % TSDB_FILE_TYPE_MAX]; fname = strdup(TSDB_FILE_NAME(pFile)); magic = pFile->info.magic; char *tfname = strdup(fname); @@ -385,7 +385,7 @@ uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t if ((pFGroup->fileId + 1) * TSDB_FILE_TYPE_MAX - 1 < (int)eindex) { SFile *pFile = &pFGroup->files[0]; fname = strdup(TSDB_FILE_NAME(pFile)); - *index = pFGroup->fileId * TSDB_FILE_TYPE_MAX; + *idx = pFGroup->fileId * TSDB_FILE_TYPE_MAX; magic = pFile->info.magic; char *tfname = strdup(fname); sprintf(name, "tsdb/%s/%s", TSDB_DATA_DIR_NAME, basename(tfname)); @@ -402,7 +402,7 @@ uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t tfree(fname); return 0; } - if (*index == TSDB_META_FILE_INDEX) { // get meta file + if (*idx == TSDB_META_FILE_INDEX) { // get meta file tsdbGetStoreInfo(fname, &magic, size); } else { char tfname[TSDB_FILENAME_LEN] = "\0"; diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c index a095bff61e..a7aa310152 100644 --- a/src/tsdb/src/tsdbMeta.c +++ b/src/tsdb/src/tsdbMeta.c @@ -28,13 +28,13 @@ static void tsdbRemoveTableFromMeta(STsdbRepo *pRepo, STable *pTable, bool rm static int tsdbAddTableIntoIndex(STsdbMeta *pMeta, STable *pTable, bool refSuper); static int tsdbRemoveTableFromIndex(STsdbMeta *pMeta, STable *pTable); static int tsdbInitTableCfg(STableCfg *config, ETableType type, uint64_t uid, int32_t tid); -static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool dup); -static int tsdbTableSetName(STableCfg *config, char *name, bool dup); -static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool dup); -static int tsdbTableSetSName(STableCfg *config, char *sname, bool dup); +static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool duplicate); +static int tsdbTableSetName(STableCfg *config, char *name, bool duplicate); +static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool duplicate); +static int tsdbTableSetSName(STableCfg *config, char *sname, bool duplicate); static int tsdbTableSetSuperUid(STableCfg *config, uint64_t uid); -static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool dup); -static int tsdbTableSetStreamSql(STableCfg *config, char *sql, bool dup); +static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool duplicate); +static int tsdbTableSetStreamSql(STableCfg *config, char *sql, bool duplicate); static int tsdbEncodeTableName(void **buf, tstr *name); static void * tsdbDecodeTableName(void *buf, tstr **name); static int tsdbEncodeTable(void **buf, STable *pTable); @@ -1236,8 +1236,8 @@ static int tsdbInitTableCfg(STableCfg *config, ETableType type, uint64_t uid, in return 0; } -static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool dup) { - if (dup) { +static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool duplicate) { + if (duplicate) { config->schema = tdDupSchema(pSchema); if (config->schema == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1249,8 +1249,8 @@ static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool dup) { return 0; } -static int tsdbTableSetName(STableCfg *config, char *name, bool dup) { - if (dup) { +static int tsdbTableSetName(STableCfg *config, char *name, bool duplicate) { + if (duplicate) { config->name = strdup(name); if (config->name == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1263,13 +1263,13 @@ static int tsdbTableSetName(STableCfg *config, char *name, bool dup) { return 0; } -static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool dup) { +static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool duplicate) { if (config->type != TSDB_CHILD_TABLE) { terrno = TSDB_CODE_TDB_INVALID_CREATE_TB_MSG; return -1; } - if (dup) { + if (duplicate) { config->tagSchema = tdDupSchema(pSchema); if (config->tagSchema == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1281,13 +1281,13 @@ static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool dup) return 0; } -static int tsdbTableSetSName(STableCfg *config, char *sname, bool dup) { +static int tsdbTableSetSName(STableCfg *config, char *sname, bool duplicate) { if (config->type != TSDB_CHILD_TABLE) { terrno = TSDB_CODE_TDB_INVALID_CREATE_TB_MSG; return -1; } - if (dup) { + if (duplicate) { config->sname = strdup(sname); if (config->sname == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1309,13 +1309,13 @@ static int tsdbTableSetSuperUid(STableCfg *config, uint64_t uid) { return 0; } -static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool dup) { +static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool duplicate) { if (config->type != TSDB_CHILD_TABLE) { terrno = TSDB_CODE_TDB_INVALID_CREATE_TB_MSG; return -1; } - if (dup) { + if (duplicate) { config->tagValues = tdKVRowDup(row); if (config->tagValues == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1328,13 +1328,13 @@ static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool dup) { return 0; } -static int tsdbTableSetStreamSql(STableCfg *config, char *sql, bool dup) { +static int tsdbTableSetStreamSql(STableCfg *config, char *sql, bool duplicate) { if (config->type != TSDB_STREAM_TABLE) { terrno = TSDB_CODE_TDB_INVALID_CREATE_TB_MSG; return -1; } - if (dup) { + if (duplicate) { config->sql = strdup(sql); if (config->sql == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 567b7ab85b..c2fd51414b 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -2589,10 +2589,10 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO while (numOfTotal < cnt) { int32_t pos = pTree->pNode[0].index; - int32_t index = sup.blockIndexArray[pos]++; + int32_t idx = sup.blockIndexArray[pos]++; STableBlockInfo* pBlocksInfo = sup.pDataBlockInfo[pos]; - pQueryHandle->pDataBlockInfo[numOfTotal++] = pBlocksInfo[index]; + pQueryHandle->pDataBlockInfo[numOfTotal++] = pBlocksInfo[idx]; // set data block index overflow, in order to disable the offset comparator if (sup.blockIndexArray[pos] >= sup.numOfBlocksPerTable[pos]) { @@ -3331,7 +3331,7 @@ static bool loadDataBlockFromTableSeq(STsdbQueryHandle* pQueryHandle) { size_t numOfTables = taosArrayGetSize(pQueryHandle->pTableCheckInfo); assert(numOfTables > 0); - int64_t stime = taosGetTimestampUs(); + int64_t lastTime = taosGetTimestampUs(); while(pQueryHandle->activeIndex < numOfTables) { if (loadBlockOfActiveTable(pQueryHandle)) { @@ -3349,7 +3349,7 @@ static bool loadDataBlockFromTableSeq(STsdbQueryHandle* pQueryHandle) { terrno = TSDB_CODE_SUCCESS; - int64_t elapsedTime = taosGetTimestampUs() - stime; + int64_t elapsedTime = taosGetTimestampUs() - lastTime; pQueryHandle->cost.checkForNextTime += elapsedTime; } @@ -3368,8 +3368,8 @@ bool tsdbNextDataBlock(TsdbQueryHandleT pHandle) { return false; } - int64_t stime = taosGetTimestampUs(); - int64_t elapsedTime = stime; + int64_t lastTime = taosGetTimestampUs(); + int64_t elapsedTime = lastTime; // TODO refactor: remove "type" if (pQueryHandle->type == TSDB_QUERY_TYPE_LAST) { @@ -3396,7 +3396,7 @@ bool tsdbNextDataBlock(TsdbQueryHandleT pHandle) { } if (exists) { - pQueryHandle->cost.checkForNextTime += (taosGetTimestampUs() - stime); + pQueryHandle->cost.checkForNextTime += (taosGetTimestampUs() - lastTime); return exists; } @@ -3408,7 +3408,7 @@ bool tsdbNextDataBlock(TsdbQueryHandleT pHandle) { bool ret = doHasDataInBuffer(pQueryHandle); terrno = TSDB_CODE_SUCCESS; - elapsedTime = taosGetTimestampUs() - stime; + elapsedTime = taosGetTimestampUs() - lastTime; pQueryHandle->cost.checkForNextTime += elapsedTime; return ret; } @@ -3757,7 +3757,7 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta return TSDB_CODE_SUCCESS; } - int64_t stime = taosGetTimestampUs(); + int64_t lastTime = taosGetTimestampUs(); int statisStatus = tsdbLoadBlockStatis(&pHandle->rhelper, pBlockInfo->compBlock); if (statisStatus < TSDB_STATIS_OK) { return terrno; @@ -3791,7 +3791,7 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta } } - int64_t elapsed = taosGetTimestampUs() - stime; + int64_t elapsed = taosGetTimestampUs() - lastTime; pHandle->cost.statisInfoLoadTime += elapsed; *pBlockStatis = pHandle->statis; diff --git a/src/util/src/hash.c b/src/util/src/hash.c index e2fd37fdc4..d4d4297615 100644 --- a/src/util/src/hash.c +++ b/src/util/src/hash.c @@ -47,7 +47,7 @@ typedef struct SHashEntry { SHashNode *next; } SHashEntry; -typedef struct SHashObj { +struct SHashObj { SHashEntry **hashList; size_t capacity; // number of slots size_t size; // number of elements in hash table @@ -58,7 +58,7 @@ typedef struct SHashObj { SHashLockTypeE type; // lock type bool enableUpdate; // enable update SArray *pMemBlock; // memory block allocated for SHashEntry -} SHashObj; +}; /* * Function definition @@ -303,7 +303,7 @@ int32_t taosHashGetSize(const SHashObj *pHashObj) { if (pHashObj == NULL) { return 0; } - return (int32_t)atomic_load_64(&pHashObj->size); + return (int32_t)atomic_load_64((int32_t *) &pHashObj->size); } static FORCE_INLINE bool taosHashTableEmpty(const SHashObj *pHashObj) { diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c index 20f6d5b250..efccf7dff8 100644 --- a/src/util/src/tarray.c +++ b/src/util/src/tarray.c @@ -180,15 +180,15 @@ void* taosArrayPop(SArray* pArray) { return TARRAY_GET_ELEM(pArray, pArray->size); } -void* taosArrayGet(const SArray* pArray, size_t index) { - assert(index < pArray->size); - return TARRAY_GET_ELEM(pArray, index); +void* taosArrayGet(const SArray* pArray, size_t idx) { + assert(idx < pArray->size); + return TARRAY_GET_ELEM(pArray, idx); } -void* taosArrayGetP(const SArray* pArray, size_t index) { - assert(index < pArray->size); +void* taosArrayGetP(const SArray* pArray, size_t idx) { + assert(idx < pArray->size); - void* d = TARRAY_GET_ELEM(pArray, index); + void* d = TARRAY_GET_ELEM(pArray, idx); return *(void**)d; } @@ -204,12 +204,12 @@ void taosArraySetSize(SArray* pArray, size_t size) { pArray->size = size; } -void* taosArrayInsert(SArray* pArray, size_t index, void* pData) { +void* taosArrayInsert(SArray* pArray, size_t idx, void* pData) { if (pArray == NULL || pData == NULL) { return NULL; } - if (index >= pArray->size) { + if (idx >= pArray->size) { return taosArrayPush(pArray, pData); } @@ -221,9 +221,9 @@ void* taosArrayInsert(SArray* pArray, size_t index, void* pData) { } } - void* dst = TARRAY_GET_ELEM(pArray, index); + void* dst = TARRAY_GET_ELEM(pArray, idx); - int32_t remain = (int32_t)(pArray->size - index); + int32_t remain = (int32_t)(pArray->size - idx); memmove((char*)dst + pArray->elemSize, (char*)dst, pArray->elemSize * remain); memcpy(dst, pData, pArray->elemSize); @@ -232,21 +232,21 @@ void* taosArrayInsert(SArray* pArray, size_t index, void* pData) { return dst; } -void taosArraySet(SArray* pArray, size_t index, void* pData) { - assert(index < pArray->size); - memcpy(TARRAY_GET_ELEM(pArray, index), pData, pArray->elemSize); +void taosArraySet(SArray* pArray, size_t idx, void* pData) { + assert(idx < pArray->size); + memcpy(TARRAY_GET_ELEM(pArray, idx), pData, pArray->elemSize); } -void taosArrayRemove(SArray* pArray, size_t index) { - assert(index < pArray->size); +void taosArrayRemove(SArray* pArray, size_t idx) { + assert(idx < pArray->size); - if (index == pArray->size - 1) { + if (idx == pArray->size - 1) { taosArrayPop(pArray); return; } - size_t remain = pArray->size - index - 1; - memmove((char*)pArray->pData + index * pArray->elemSize, (char*)pArray->pData + (index + 1) * pArray->elemSize, remain * pArray->elemSize); + size_t remain = pArray->size - idx - 1; + memmove((char*)pArray->pData + idx * pArray->elemSize, (char*)pArray->pData + (idx + 1) * pArray->elemSize, remain * pArray->elemSize); pArray->size -= 1; } diff --git a/src/util/src/tcache.c b/src/util/src/tcache.c index 39b674fe4f..6fac32e22d 100644 --- a/src/util/src/tcache.c +++ b/src/util/src/tcache.c @@ -624,9 +624,9 @@ void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) { return; } - const char* stat[] = {"false", "true"}; + const char* status[] = {"false", "true"}; uDebug("cache:%s start to cleanup trashcan, numOfElem in trashcan:%d, free:%s", pCacheObj->name, - pCacheObj->numOfElemsInTrash, (force? stat[1]:stat[0])); + pCacheObj->numOfElemsInTrash, (force? status[1]:status[0])); STrashElem *pElem = pCacheObj->pTrash; while (pElem) { @@ -683,10 +683,10 @@ bool travHashTableFn(void* param, void* data) { return true; } -static void doCacheRefresh(SCacheObj* pCacheObj, int64_t time, __cache_trav_fn_t fp, void* param1) { +static void doCacheRefresh(SCacheObj* pCacheObj, int64_t timeStamp, __cache_trav_fn_t fp, void* param1) { assert(pCacheObj != NULL); - SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = fp, .time = time, .param1 = param1}; + SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = fp, .time = timeStamp, .param1 = param1}; taosHashCondTraverse(pCacheObj->pHashTable, travHashTableFn, &sup); } diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 2ab5ddbbe0..565878f3e1 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -436,9 +436,9 @@ int WCSPatternMatch(const uint32_t *patterStr, const uint32_t *str, size_t size, return TSDB_PATTERN_MATCH; } - uint32_t accept[3] = {towupper(c), towlower(c), 0}; + uint32_t accept_array[3] = {towupper(c), towlower(c), 0}; while (1) { - size_t n = taosWcscspn(str, accept); + size_t n = taosWcscspn(str, accept_array); str += n; if (str[0] == 0 || (n >= size)) { diff --git a/src/util/src/tmempool.c b/src/util/src/tmempool.c index 678c965eb1..b580f9d9ab 100644 --- a/src/util/src/tmempool.c +++ b/src/util/src/tmempool.c @@ -89,19 +89,19 @@ char *taosMemPoolMalloc(mpool_h handle) { } void taosMemPoolFree(mpool_h handle, char *pMem) { - int index; + int idx; pool_t *pool_p = (pool_t *)handle; if (pMem == NULL) return; - index = (int)(pMem - pool_p->pool) % pool_p->blockSize; - if (index != 0) { + idx = (int)(pMem - pool_p->pool) % pool_p->blockSize; + if (idx != 0) { uError("invalid free address:%p\n", pMem); return; } - index = (int)((pMem - pool_p->pool) / pool_p->blockSize); - if (index < 0 || index >= pool_p->numOfBlock) { + idx = (int)((pMem - pool_p->pool) / pool_p->blockSize); + if (idx < 0 || idx >= pool_p->numOfBlock) { uError("mempool: error, invalid address:%p\n", pMem); return; } @@ -110,7 +110,7 @@ void taosMemPoolFree(mpool_h handle, char *pMem) { pthread_mutex_lock(&pool_p->mutex); - pool_p->freeList[(pool_p->first + pool_p->numOfFree) % pool_p->numOfBlock] = index; + pool_p->freeList[(pool_p->first + pool_p->numOfFree) % pool_p->numOfBlock] = idx; pool_p->numOfFree++; pthread_mutex_unlock(&pool_p->mutex); diff --git a/src/util/src/tnettest.c b/src/util/src/tnettest.c index 2094c3d4be..407884759a 100644 --- a/src/util/src/tnettest.c +++ b/src/util/src/tnettest.c @@ -314,27 +314,27 @@ static void taosNetCheckPort(uint32_t hostIp, int32_t startPort, int32_t endPort } void *taosNetInitRpc(char *secretEncrypt, char spi) { - SRpcInit rpcInit; + SRpcInit rpcInitial; void * pRpcConn = NULL; char user[] = "nettestinternal"; char pass[] = "nettestinternal"; taosEncryptPass((uint8_t *)pass, strlen(pass), secretEncrypt); - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = 0; - rpcInit.label = "NT"; - rpcInit.numOfThreads = 1; // every DB connection has only one thread - rpcInit.cfp = NULL; - rpcInit.sessions = 16; - rpcInit.connType = TAOS_CONN_CLIENT; - rpcInit.user = user; - rpcInit.idleTime = 2000; - rpcInit.ckey = "key"; - rpcInit.spi = spi; - rpcInit.secret = secretEncrypt; - - pRpcConn = rpcOpen(&rpcInit); + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = 0; + rpcInitial.label = "NT"; + rpcInitial.numOfThreads = 1; // every DB connection has only one thread + rpcInitial.cfp = NULL; + rpcInitial.sessions = 16; + rpcInitial.connType = TAOS_CONN_CLIENT; + rpcInitial.user = user; + rpcInitial.idleTime = 2000; + rpcInitial.ckey = "key"; + rpcInitial.spi = spi; + rpcInitial.secret = secretEncrypt; + + pRpcConn = rpcOpen(&rpcInitial); return pRpcConn; } diff --git a/src/util/src/tref.c b/src/util/src/tref.c index 33323889c6..bff8b12aae 100644 --- a/src/util/src/tref.c +++ b/src/util/src/tref.c @@ -54,7 +54,7 @@ static void taosLockList(int64_t *lockedBy); static void taosUnlockList(int64_t *lockedBy); static void taosIncRsetCount(SRefSet *pSet); static void taosDecRsetCount(SRefSet *pSet); -static int taosDecRefCount(int rsetId, int64_t rid, int remove); +static int taosDecRefCount(int rsetId, int64_t rid, int rm); int taosOpenRef(int max, void (*fp)(void *)) { @@ -389,7 +389,7 @@ int taosListRef() { return num; } -static int taosDecRefCount(int rsetId, int64_t rid, int remove) { +static int taosDecRefCount(int rsetId, int64_t rid, int rm) { int hash; SRefSet *pSet; SRefNode *pNode; @@ -428,7 +428,7 @@ static int taosDecRefCount(int rsetId, int64_t rid, int remove) { if (pNode) { pNode->count--; - if (remove) pNode->removed = 1; + if (rm) pNode->removed = 1; if (pNode->count <= 0) { if (pNode->prev) { diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c index 81ab56ccea..23181981e0 100644 --- a/src/vnode/src/vnodeMain.c +++ b/src/vnode/src/vnodeMain.c @@ -586,9 +586,9 @@ void vnodeCleanUp(SVnodeObj *pVnode) { // stop replication module if (pVnode->sync > 0) { - int64_t sync = pVnode->sync; + int64_t syncRid = pVnode->sync; pVnode->sync = -1; - syncStop(sync); + syncStop(syncRid); } vDebug("vgId:%d, vnode is cleaned, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode); @@ -692,4 +692,4 @@ bool vnodeWaitTooMany(void* vparam) { tsem_t* vnodeSemWait(void* vparam) { SVnodeObj* pVnode = (SVnodeObj* )vparam; return &pVnode->semWait; -} \ No newline at end of file +} diff --git a/src/vnode/src/vnodeSync.c b/src/vnode/src/vnodeSync.c index 2bdfd2ead3..6edcadcf71 100644 --- a/src/vnode/src/vnodeSync.c +++ b/src/vnode/src/vnodeSync.c @@ -22,7 +22,7 @@ #include "vnodeMain.h" #include "vnodeStatus.h" -uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fver) { +uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *idx, uint32_t eindex, int64_t *size, uint64_t *fver) { SVnodeObj *pVnode = vnodeAcquire(vgId); if (pVnode == NULL) { vError("vgId:%d, vnode not found while get file info", vgId); @@ -30,7 +30,7 @@ uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t ei } *fver = pVnode->fversion; - uint32_t ret = tsdbGetFileInfo(pVnode->tsdb, name, index, eindex, size); + uint32_t ret = tsdbGetFileInfo(pVnode->tsdb, name, idx, eindex, size); vnodeRelease(pVnode); return ret; diff --git a/src/wal/test/waltest.c b/src/wal/test/waltest.c index 505728fbe4..ffb9767bb4 100644 --- a/src/wal/test/waltest.c +++ b/src/wal/test/waltest.c @@ -113,17 +113,17 @@ int main(int argc, char *argv[]) { printf("%d wal files are written\n", total); - int64_t index = 0; + int64_t idx = 0; char name[256]; while (1) { - int code = walGetWalFile(pWal, name, &index); + int code = walGetWalFile(pWal, name, &idx); if (code == -1) { - printf("failed to get wal file, index:%" PRId64 "\n", index); + printf("failed to get wal file, index:%" PRId64 "\n", idx); break; } - printf("index:%" PRId64 " wal:%s\n", index, name); + printf("index:%" PRId64 " wal:%s\n", idx, name); if (code == 0) break; } diff --git a/tests/tsim/src/simExe.c b/tests/tsim/src/simExe.c index e880f1e446..d1288213c5 100644 --- a/tests/tsim/src/simExe.c +++ b/tests/tsim/src/simExe.c @@ -143,13 +143,13 @@ char *simGetVariable(SScript *script, char *varName, int32_t varLen) { return var->varValue; } -int32_t simExecuteExpression(SScript *script, char *exp) { +int32_t simExecuteExpression(SScript *script, char *expr) { char * op1, *op2, *var1, *var2, *var3, *rest; int32_t op1Len, op2Len, var1Len, var2Len, var3Len, val0, val1; char t0[1024], t1[1024], t2[1024], t3[2048]; int32_t result; - rest = paGetToken(exp, &var1, &var1Len); + rest = paGetToken(expr, &var1, &var1Len); rest = paGetToken(rest, &op1, &op1Len); rest = paGetToken(rest, &var2, &var2Len); rest = paGetToken(rest, &op2, &op2Len); diff --git a/tests/tsim/src/simParse.c b/tests/tsim/src/simParse.c index 1acdcd2ac6..7de2630006 100644 --- a/tests/tsim/src/simParse.c +++ b/tests/tsim/src/simParse.c @@ -251,11 +251,11 @@ SScript *simParseScript(char *fileName) { return script; } -int32_t simCheckExpression(char *exp) { +int32_t simCheckExpression(char *expr) { char * op1, *op2, *op, *rest; int32_t op1Len, op2Len, opLen; - rest = paGetToken(exp, &op1, &op1Len); + rest = paGetToken(expr, &op1, &op1Len); if (op1Len == 0) { sprintf(parseErr, "expression is required"); return -1; @@ -295,10 +295,10 @@ int32_t simCheckExpression(char *exp) { rest = paGetToken(rest, &op, &opLen); - if (opLen == 0) return (int32_t)(rest - exp); + if (opLen == 0) return (int32_t)(rest - expr); /* if it is key word "then" */ - if (strncmp(op, "then", 4) == 0) return (int32_t)(op - exp); + if (strncmp(op, "then", 4) == 0) return (int32_t)(op - expr); rest = paGetToken(rest, &op2, &op2Len); if (op2Len == 0) { @@ -312,7 +312,7 @@ int32_t simCheckExpression(char *exp) { } if (op[0] == '+' || op[0] == '-' || op[0] == '*' || op[0] == '/' || op[0] == '.') { - return (int32_t)(rest - exp); + return (int32_t)(rest - expr); } return -1; diff --git a/tests/tsim/src/simSystem.c b/tests/tsim/src/simSystem.c index 0879e371ef..7569d3fc7d 100644 --- a/tests/tsim/src/simSystem.c +++ b/tests/tsim/src/simSystem.c @@ -43,9 +43,9 @@ char *simParseArbitratorName(char *varName) { char *simParseHostName(char *varName) { static char hostName[140]; - int32_t index = atoi(varName + 8); + int32_t idx = atoi(varName + 8); int32_t port = 7100; - switch (index) { + switch (idx) { case 1: port = 7100; break; -- GitLab From 504929cfa969bfc5499e3388d5110c3c2410b4cc Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 6 Jul 2022 20:49:30 +0800 Subject: [PATCH 125/380] chore: upate taos-tools for2.6 (#14617) * chore: update taos-tools for 2.6 * test: change taosbenchmark test cases * fix: outdated test cases * fix: query/nestedQuery/nestedQuery.py * fix: update taos-tools * chore: update taos-tools for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 46a71144a8..c9308b0481 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 46a71144a85e5eed9160304830f235cb28bc4895 +Subproject commit c9308b04810faa653548db5f07c753a9d00990eb -- GitLab From b8552bca825aa15546492305d9f08a39d432c7fd Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Wed, 6 Jul 2022 21:27:16 +0800 Subject: [PATCH 126/380] test: add test case --- tests/pytest/query/queryBase.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/pytest/query/queryBase.py b/tests/pytest/query/queryBase.py index 4544fab3ad..9be950df49 100644 --- a/tests/pytest/query/queryBase.py +++ b/tests/pytest/query/queryBase.py @@ -171,6 +171,11 @@ class TDTestCase: tdSql.waitedQuery(sql, 1, WAITS) tdSql.checkData(0, 1, 229400) + # TS-1664 + tdSql.error("create database string") + tdSql.error("create table string(ts timestamp, c1 int)") + tdSql.error("select * from string") + # # add case with filename # -- GitLab From d814cfb51004e708435ca8604fcb83f3d296412d Mon Sep 17 00:00:00 2001 From: xiaolei li <85657333+xleili@users.noreply.github.com> Date: Thu, 7 Jul 2022 10:04:30 +0800 Subject: [PATCH 127/380] fix(test):change C# ci example targetframe work to net5 in 2.6 branch (#14523) * fix(test):C# example ineffective in CI under TDegnine/example (#14472) * fix(test):C# example ineffective in CI under tdegnine/example * fix(test):C# examples add into CI cases.task * test(fix):update C# CI example target framework to NET 6.0 * fix(test):C# example in CI, path incorrect * fix(test):C# example CI ineffective * fix(test):C# example CI taosdemo realese path incorrect * fix(test):change C# ci example targetframe work to net5 in 2.6 branch --- examples/C#/C#checker/C#checker.cs | 2 +- examples/C#/insertCn/lib/ResultSetUtils.cs | 43 +++ examples/C#/insertCn/lib/Utils.cs | 418 +++++++++++++++++++++ examples/C#/jsonTag/JsonTag.cs | 2 +- examples/C#/jsonTag/Util.cs | 4 +- examples/C#/jsonTag/jsonTag.csproj | 4 +- examples/C#/schemaless/schemaless.csproj | 4 +- examples/C#/schemaless/schemalessSample.cs | 2 +- examples/C#/stmt/StmtDemo.cs | 2 +- tests/develop-test/3-connectors/c#/test.sh | 34 +- tests/parallel_test/cases.task | 1 + 11 files changed, 499 insertions(+), 17 deletions(-) create mode 100644 examples/C#/insertCn/lib/ResultSetUtils.cs create mode 100644 examples/C#/insertCn/lib/Utils.cs diff --git a/examples/C#/C#checker/C#checker.cs b/examples/C#/C#checker/C#checker.cs index 7d0b6a50b6..f49fda88cd 100644 --- a/examples/C#/C#checker/C#checker.cs +++ b/examples/C#/C#checker/C#checker.cs @@ -389,7 +389,7 @@ namespace TDengineDriver static void ExitProgram() { - System.Environment.Exit(0); + System.Environment.Exit(1); } public void cleanup() diff --git a/examples/C#/insertCn/lib/ResultSetUtils.cs b/examples/C#/insertCn/lib/ResultSetUtils.cs new file mode 100644 index 0000000000..7d299411ee --- /dev/null +++ b/examples/C#/insertCn/lib/ResultSetUtils.cs @@ -0,0 +1,43 @@ +using System; +using TDengineDriver; +using System.Runtime.InteropServices; +using System.Text; +using System.Collections.Generic; +namespace Test.UtilsTools.ResultSet +{ + public class ResultSet + { + private List resultMeta; + private List resultData; + // private bool isValidResult = false; + public ResultSet(IntPtr res) + { + + resultMeta = UtilsTools.GetResField(res); + resultData = UtilsTools.GetResData(res); + } + + public ResultSet(List metas, List datas) + { + resultMeta = metas; + resultData = datas; + } + + public List GetResultData() + { + return resultData; + } + + public List GetResultMeta() + { + return resultMeta; + } + + public int GetFieldsNum() + { + return resultMeta.Count; + } + } + + +} diff --git a/examples/C#/insertCn/lib/Utils.cs b/examples/C#/insertCn/lib/Utils.cs new file mode 100644 index 0000000000..6107ecab57 --- /dev/null +++ b/examples/C#/insertCn/lib/Utils.cs @@ -0,0 +1,418 @@ +using System; +using TDengineDriver; +using System.Runtime.InteropServices; +using System.Text; +using System.Collections.Generic; +namespace Test.UtilsTools +{ + public class UtilsTools + { + + static string ip = "127.0.0.1"; + static string user = "root"; + static string password = "taosdata"; + static string db = ""; + static short port = 0; + //get a tdengine connection + public static IntPtr TDConnection() + { + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, GetConfigPath()); + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60"); + TDengine.Init(); + IntPtr conn = TDengine.Connect(ip, user, password, db, port); + return conn; + } + //get taos.cfg file based on different os + public static string GetConfigPath() + { + string configDir = "" ; + if(OperatingSystem.IsOSPlatform("Windows")) + { + configDir = "C:/TDengine/cfg"; + } + else if(OperatingSystem.IsOSPlatform("Linux")) + { + configDir = "/etc/taos"; + } + else if(OperatingSystem.IsOSPlatform("macOS")) + { + configDir = "/etc/taos"; + } + return configDir; + } + + public static IntPtr ExecuteQuery(IntPtr conn, String sql) + { + IntPtr res = TDengine.Query(conn, sql); + if (!IsValidResult(res)) + { + Console.Write(sql.ToString() + " failure, "); + ExitProgram(); + } + else + { + Console.WriteLine(sql.ToString() + " success"); + } + return res; + } + + public static IntPtr ExecuteErrorQuery(IntPtr conn, String sql) + { + IntPtr res = TDengine.Query(conn, sql); + if (!IsValidResult(res)) + { + Console.Write(sql.ToString() + " failure, "); + ExitProgram(); + } + else + { + Console.WriteLine(sql.ToString() + " success"); + + } + return res; + } + + public static void ExecuteUpdate(IntPtr conn, String sql) + { + IntPtr res = TDengine.Query(conn, sql); + if (!IsValidResult(res)) + { + Console.Write(sql.ToString() + " failure, "); + ExitProgram(); + } + else + { + Console.WriteLine(sql.ToString() + " success"); + + } + TDengine.FreeResult(res); + } + + + public static bool IsValidResult(IntPtr res) + { + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) + { + if (res != IntPtr.Zero) + { + Console.Write("reason: " + TDengine.Error(res)); + return false; + } + Console.WriteLine(""); + return false; + } + return true; + } + public static void CloseConnection(IntPtr conn) + { + if (conn != IntPtr.Zero) + { + if (TDengine.Close(conn) == 0) + { + Console.WriteLine("close connection sucess"); + } + else + { + Console.WriteLine("close Connection failed"); + } + } + TDengine.Cleanup(); + } + public static List GetResField(IntPtr res) + { + List metas = TDengine.FetchFields(res); + return metas; + } + public static void AssertEqual(string expectVal, string actualVal) + { + if (expectVal == actualVal) + { + Console.WriteLine("{0}=={1} pass", expectVal, actualVal); + } + else + { + Console.WriteLine("{0}=={1} failed", expectVal, actualVal); + ExitProgram(); + } + } + public static void ExitProgram() + { + TDengine.Cleanup(); + System.Environment.Exit(1); + } + public static List GetResData(IntPtr res) + { + List dataRaw = new List(); + if (!IsValidResult(res)) + { + ExitProgram(); + } + List metas = GetResField(res); + dataRaw = QueryRes(res, metas); + return dataRaw; + } + + public static TDengineMeta ConstructTDengineMeta(string name, string type) + { + + TDengineMeta _meta = new TDengineMeta(); + _meta.name = name; + char[] separators = new char[] { '(', ')' }; + string[] subs = type.Split(separators, StringSplitOptions.RemoveEmptyEntries); + + switch (subs[0].ToUpper()) + { + case "BOOL": + _meta.type = 1; + _meta.size = 1; + break; + case "TINYINT": + _meta.type = 2; + _meta.size = 1; + break; + case "SMALLINT": + _meta.type = 3; + _meta.size = 2; + break; + case "INT": + _meta.type = 4; + _meta.size = 4; + break; + case "BIGINT": + _meta.type = 5; + _meta.size = 8; + break; + case "TINYINT UNSIGNED": + _meta.type = 11; + _meta.size = 1; + break; + case "SMALLINT UNSIGNED": + _meta.type = 12; + _meta.size = 2; + break; + case "INT UNSIGNED": + _meta.type = 13; + _meta.size = 4; + break; + case "BIGINT UNSIGNED": + _meta.type = 14; + _meta.size = 8; + break; + case "FLOAT": + _meta.type = 6; + _meta.size = 4; + break; + case "DOUBLE": + _meta.type = 7; + _meta.size = 8; + break; + case "BINARY": + _meta.type = 8; + _meta.size = short.Parse(subs[1]); + break; + case "TIMESTAMP": + _meta.type = 9; + _meta.size = 8; + break; + case "NCHAR": + _meta.type = 10; + _meta.size = short.Parse(subs[1]); + break; + case "JSON": + _meta.type = 15; + _meta.size = 4096; + break; + default: + _meta.type = byte.MaxValue; + _meta.size = 0; + break; + } + return _meta; + } + + private static List QueryRes(IntPtr res, List metas) + { + IntPtr rowdata; + long queryRows = 0; + List dataRaw = new List(); + int fieldCount = metas.Count; + while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero) + { + queryRows++; + IntPtr colLengthPtr = TDengine.FetchLengths(res); + int[] colLengthArr = new int[fieldCount]; + Marshal.Copy(colLengthPtr, colLengthArr, 0, fieldCount); + + for (int fields = 0; fields < fieldCount; ++fields) + { + TDengineMeta meta = metas[fields]; + int offset = IntPtr.Size * fields; + IntPtr data = Marshal.ReadIntPtr(rowdata, offset); + + if (data == IntPtr.Zero) + { + dataRaw.Add("NULL"); + continue; + } + + switch ((TDengineDataType)meta.type) + { + case TDengineDataType.TSDB_DATA_TYPE_BOOL: + bool v1 = Marshal.ReadByte(data) == 0 ? false : true; + dataRaw.Add(v1); + break; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + sbyte v2 = (sbyte)Marshal.ReadByte(data); + dataRaw.Add(v2); + break; + case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: + short v3 = Marshal.ReadInt16(data); + dataRaw.Add(v3); + break; + case TDengineDataType.TSDB_DATA_TYPE_INT: + int v4 = Marshal.ReadInt32(data); + dataRaw.Add(v4); + break; + case TDengineDataType.TSDB_DATA_TYPE_BIGINT: + long v5 = Marshal.ReadInt64(data); + dataRaw.Add(v5); + break; + case TDengineDataType.TSDB_DATA_TYPE_FLOAT: + float v6 = (float)Marshal.PtrToStructure(data, typeof(float)); + dataRaw.Add(v6); + break; + case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: + double v7 = (double)Marshal.PtrToStructure(data, typeof(double)); + dataRaw.Add(v7); + break; + case TDengineDataType.TSDB_DATA_TYPE_BINARY: + // string v8 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]); + string v8 = Marshal.PtrToStringUTF8(data, colLengthArr[fields]); + dataRaw.Add(v8); + break; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + long v9 = Marshal.ReadInt64(data); + dataRaw.Add(v9); + break; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + // string v10 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]); + string v10 = Marshal.PtrToStringUTF8(data, colLengthArr[fields]); + dataRaw.Add(v10); + break; + case TDengineDataType.TSDB_DATA_TYPE_UTINYINT: + byte v12 = Marshal.ReadByte(data); + dataRaw.Add(v12); + break; + case TDengineDataType.TSDB_DATA_TYPE_USMALLINT: + ushort v13 = (ushort)Marshal.ReadInt16(data); + dataRaw.Add(v13); + break; + case TDengineDataType.TSDB_DATA_TYPE_UINT: + uint v14 = (uint)Marshal.ReadInt32(data); + dataRaw.Add(v14); + break; + case TDengineDataType.TSDB_DATA_TYPE_UBIGINT: + ulong v15 = (ulong)Marshal.ReadInt64(data); + dataRaw.Add(v15); + break; + default: + dataRaw.Add("unknown value"); + break; + } + } + + } + if (TDengine.ErrorNo(res) != 0) + { + Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res)); + } + TDengine.FreeResult(res); + Console.WriteLine(""); + return dataRaw; + } + + // Generate insert sql for the with the coldata and tag data + public static string ConstructInsertSql(string table,string stable,List colData,List tagData,int numOfRows) + { + int numofFileds = colData.Count / numOfRows; + StringBuilder insertSql; + + if (stable == "") + { + insertSql = new StringBuilder($"insert into {table} values("); + } + else + { + insertSql = new StringBuilder($"insert into {table} using {stable} tags("); + + for (int j = 0; j < tagData.Count; j++) + { + if (tagData[j] is String) + { + insertSql.Append('\''); + insertSql.Append(tagData[j]); + insertSql.Append('\''); + } + else + { + insertSql.Append(tagData[j]); + } + if (j + 1 != tagData.Count) + { + insertSql.Append(','); + } + } + + insertSql.Append(")values("); + } + for (int i = 0; i < colData.Count; i++) + { + + if (colData[i] is String) + { + insertSql.Append('\''); + insertSql.Append(colData[i]); + insertSql.Append('\''); + } + else + { + insertSql.Append(colData[i]); + } + + if ((i + 1) % numofFileds == 0 && (i + 1) != colData.Count) + { + insertSql.Append(")("); + } + else if ((i + 1) == colData.Count) + { + insertSql.Append(')'); + } + else + { + insertSql.Append(','); + } + } + insertSql.Append(';'); + //Console.WriteLine(insertSql.ToString()); + + return insertSql.ToString(); + } + + public static List CombineColAndTagData(List colData,List tagData, int numOfRows) + { + var list = new List(); + for (int i = 0; i < colData.Count; i++) + { + list.Add(colData[i]); + if ((i + 1) % (colData.Count / numOfRows) == 0) + { + for (int j = 0; j < tagData.Count; j++) + { + list.Add(tagData[j]); + } + } + } + return list; + } + } +} diff --git a/examples/C#/jsonTag/JsonTag.cs b/examples/C#/jsonTag/JsonTag.cs index 453e54eabd..5c94df8b5a 100644 --- a/examples/C#/jsonTag/JsonTag.cs +++ b/examples/C#/jsonTag/JsonTag.cs @@ -11,7 +11,7 @@ namespace Cases IntPtr conn = IntPtr.Zero; Console.WriteLine("===================JsonTagTest===================="); conn = conn = UtilsTools.TDConnection("127.0.0.1", "root", "taosdata", "", 0); - UtilsTools.ExecuteUpdate(conn, "create database if not exists csharp_sample keep 3650"); + UtilsTools.ExecuteUpdate(conn, "create database if not exists csharp keep 3650"); UtilsTools.ExecuteUpdate(conn, "use csharp"); JsonTagSample jsonTagSample = new JsonTagSample(); jsonTagSample.Test(conn); diff --git a/examples/C#/jsonTag/Util.cs b/examples/C#/jsonTag/Util.cs index 5138938df6..7446378fc7 100644 --- a/examples/C#/jsonTag/Util.cs +++ b/examples/C#/jsonTag/Util.cs @@ -217,10 +217,10 @@ namespace Utils } } } - public static void ExitProgram() + public static void ExitProgram(int i = 1) { TDengine.Cleanup(); - System.Environment.Exit(0); + System.Environment.Exit(i); } } } \ No newline at end of file diff --git a/examples/C#/jsonTag/jsonTag.csproj b/examples/C#/jsonTag/jsonTag.csproj index ed3af6e806..eb33d899ac 100644 --- a/examples/C#/jsonTag/jsonTag.csproj +++ b/examples/C#/jsonTag/jsonTag.csproj @@ -5,8 +5,8 @@ net5.0 - - + + diff --git a/examples/C#/schemaless/schemaless.csproj b/examples/C#/schemaless/schemaless.csproj index d132e34589..c2369f3e8e 100644 --- a/examples/C#/schemaless/schemaless.csproj +++ b/examples/C#/schemaless/schemaless.csproj @@ -5,8 +5,8 @@ net5.0 - - + + diff --git a/examples/C#/schemaless/schemalessSample.cs b/examples/C#/schemaless/schemalessSample.cs index f27ac352a6..8d0b7f60d0 100644 --- a/examples/C#/schemaless/schemalessSample.cs +++ b/examples/C#/schemaless/schemalessSample.cs @@ -289,7 +289,7 @@ namespace TDengineDriver static void ExitProgram() { - System.Environment.Exit(0); + System.Environment.Exit(1); } public void cleanup() diff --git a/examples/C#/stmt/StmtDemo.cs b/examples/C#/stmt/StmtDemo.cs index fdd647fdb5..56a5aa20f3 100644 --- a/examples/C#/stmt/StmtDemo.cs +++ b/examples/C#/stmt/StmtDemo.cs @@ -543,7 +543,7 @@ namespace TDengineDriver public static void ExitProgram() { TDengine.Cleanup(); - System.Environment.Exit(0); + System.Environment.Exit(1); } } } diff --git a/tests/develop-test/3-connectors/c#/test.sh b/tests/develop-test/3-connectors/c#/test.sh index 8cfb3fe4fc..f77536c1fd 100755 --- a/tests/develop-test/3-connectors/c#/test.sh +++ b/tests/develop-test/3-connectors/c#/test.sh @@ -15,25 +15,45 @@ rm -rf /var/lib/taos/* rm -rf /var/log/taos/* nohup taosd -c /etc/taos/ > /dev/null 2>&1 & sleep 10 + +# define fun to check if execute correct. +check(){ +if [ $1 -eq 0 ] +then + echo "===================$2 succeed===================" +else + echo "===================$2 failed===================" + exit 1 +fi +} + cd ../../ WKC=`pwd` -cd ${WKC}/src/connector/C# -dotnet test -# run example under Driver -cd ${WKC}/src/connector/C#/examples -dotnet run - -#dotnet run --project src/test/Cases/Cases.csproj +echo "WKC:${WKC}" # run example with neuget package cd ${WKC}/tests/examples/C# + dotnet run --project C#checker/C#checker.csproj +check $? C#checker.csproj + dotnet run --project TDengineTest/TDengineTest.csproj +check $? TDengineTest.csproj + dotnet run --project schemaless/schemaless.csproj +check $? schemaless.csproj + dotnet run --project jsonTag/jsonTag.csproj +check $? jsonTag.csproj + dotnet run --project stmt/stmt.csproj +check $? stmt.csproj + +dotnet run --project insertCn/insertCn.csproj +check $? insertCn.csproj cd ${WKC}/tests/examples/C#/taosdemo dotnet build -c Release tree | true ./bin/Release/net5.0/taosdemo -c /etc/taos -y +check $? taosdemo diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 2174437f31..365823d227 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -236,6 +236,7 @@ 30,,script,./test.sh -f general/import/commit.sim 30,,script,./test.sh -f general/compute/diff2.sim 30,,develop-test,bash 3-connectors/R/test.sh +30,,develop-test,bash 3-connectors/c#/test.sh 29,,system-test,python3 ./test.py -f 0-others/create_col_tag.py 29,,script,./test.sh -f unique/arbitrator/dn3_mn1_full_createTableFail.sim 29,,script,./test.sh -f general/wal/maxtables.sim -- GitLab From 8b944e218d37d076249b8780d512d74a22c1245f Mon Sep 17 00:00:00 2001 From: xywang Date: Thu, 7 Jul 2022 15:00:52 +0800 Subject: [PATCH 128/380] fix: table name which is a key word led to a crash --- src/client/src/tscSQLParser.c | 10 ++++++++++ src/client/src/tscUtil.c | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 22456782d0..e36a81b387 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1511,6 +1511,7 @@ int32_t tscSetTableFullName(SName* pName, SStrToken* pTableName, SSqlObj* pSql, const char* msg4 = "db name too long"; const char* msg5 = "table name too long"; const char* msg6 = "table name empty"; + const char* msg7 = "invalid table name"; SSqlCmd* pCmd = &pSql->cmd; int32_t code = TSDB_CODE_SUCCESS; @@ -1575,6 +1576,15 @@ int32_t tscSetTableFullName(SName* pName, SStrToken* pTableName, SSqlObj* pSql, } } + if (code != 0) { + return code; + } + + bool ret = taosIsKeyWordToken(pName->tname, (int32_t) strlen(pName->tname)); + if (ret) { + code = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); + } + return code; } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index cfcf2f63ee..c27ceac50c 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -3014,6 +3014,10 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded) // single token, validate it if (len == pToken->n) { + if (strncmp(pToken->z, "string", len) == 0) { + return TSDB_CODE_SUCCESS; + } + return validateQuoteToken(pToken, escapeEnabled, NULL); } else { sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true); -- GitLab From 7f3204ce062abf17dbd873b5d6f26f633c6f1096 Mon Sep 17 00:00:00 2001 From: xywang Date: Thu, 7 Jul 2022 15:48:27 +0800 Subject: [PATCH 129/380] fix: database name which is a key word should not permitted --- src/client/src/tscSQLParser.c | 10 ---------- src/client/src/tscUtil.c | 4 ++-- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index e36a81b387..22456782d0 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1511,7 +1511,6 @@ int32_t tscSetTableFullName(SName* pName, SStrToken* pTableName, SSqlObj* pSql, const char* msg4 = "db name too long"; const char* msg5 = "table name too long"; const char* msg6 = "table name empty"; - const char* msg7 = "invalid table name"; SSqlCmd* pCmd = &pSql->cmd; int32_t code = TSDB_CODE_SUCCESS; @@ -1576,15 +1575,6 @@ int32_t tscSetTableFullName(SName* pName, SStrToken* pTableName, SSqlObj* pSql, } } - if (code != 0) { - return code; - } - - bool ret = taosIsKeyWordToken(pName->tname, (int32_t) strlen(pName->tname)); - if (ret) { - code = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); - } - return code; } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index c27ceac50c..5c6fb2dc75 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -3014,8 +3014,8 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded) // single token, validate it if (len == pToken->n) { - if (strncmp(pToken->z, "string", len) == 0) { - return TSDB_CODE_SUCCESS; + if (taosIsKeyWordToken(pToken->z, (int32_t) pToken->n)) { + return TSDB_CODE_TSC_INVALID_OPERATION; } return validateQuoteToken(pToken, escapeEnabled, NULL); -- GitLab From 6ba5063b4ebdab0d2540cfdf6f4f90836c36cc2d Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Fri, 8 Jul 2022 12:04:33 +0800 Subject: [PATCH 130/380] docs: Update 03-immigrate.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 存储资源估算的计算公式有误 --- docs/zh/25-application/03-immigrate.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh/25-application/03-immigrate.md b/docs/zh/25-application/03-immigrate.md index 9d8946bc4a..d1c9caea09 100644 --- a/docs/zh/25-application/03-immigrate.md +++ b/docs/zh/25-application/03-immigrate.md @@ -367,10 +367,10 @@ WHERE ts>=1510560000 AND ts<=1515000009 ### 存储资源估算 -假设产生数据并需要存储的传感器设备数量为 `n`,数据生成的频率为`t`条/秒,每条记录的长度为 `L` bytes,则每天产生的数据规模为 `n×t×L` bytes。假设压缩比为 C,则每日产生数据规模为 `(n×t×L)/C` bytes。存储资源预估为能够容纳 1.5 年的数据规模,生产环境下 TDengine 的压缩比 C 一般在 5 ~ 7 之间,同时为最后结果增加 20% 的冗余,可计算得到需要存储资源: +假设产生数据并需要存储的传感器设备数量为 `n`,数据生成的频率为`t`条/秒,每条记录的长度为 `L` bytes,则每天产生的数据规模为 `86400×n×t×L` bytes。假设压缩比为 C,则每日产生数据规模为 `(86400×n×t×L)/C` bytes。存储资源预估为能够容纳 1.5 年的数据规模,生产环境下 TDengine 的压缩比 C 一般在 5 ~ 7 之间,同时为最后结果增加 20% 的冗余,可计算得到需要存储资源: ```matlab -(n×t×L)×(365×1.5)×(1+20%)/C +(86400×n×t×L)×(365×1.5)×(1+20%)/C ``` 结合以上的计算公式,将参数带入计算公式,在不考虑标签信息的情况下,每年产生的原始数据规模是 11.8TB。需要注意的是,由于标签信息在 TDengine 中关联到每个时间线,并不是每条记录。所以需要记录的数据量规模相对于产生的数据有一定的降低,而这部分标签数据整体上可以忽略不记。假设压缩比为 5,则保留的数据规模最终为 2.56 TB。 -- GitLab From c2cdd2affcaff217cc19ef010b11fd1d165f3793 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Fri, 8 Jul 2022 12:07:21 +0800 Subject: [PATCH 131/380] Update 03-immigrate.md --- docs/en/25-application/03-immigrate.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/25-application/03-immigrate.md b/docs/en/25-application/03-immigrate.md index 4d47aec1d7..fe67f97389 100644 --- a/docs/en/25-application/03-immigrate.md +++ b/docs/en/25-application/03-immigrate.md @@ -379,11 +379,11 @@ We still use the hypothetical environment from Chapter 4. There are three measur ### Storage resource estimation -Assuming that the number of sensor devices that generate data and need to be stored is `n`, the frequency of data generation is `t` per second, and the length of each record is `L` bytes, the scale of data generated per day is `n * t * L` bytes. Assuming the compression ratio is `C`, the daily data size is `(n * t * L)/C` bytes. The storage resources are estimated to accommodate the data scale for 1.5 years. In the production environment, the compression ratio C of TDengine is generally between 5 and 7. +Assuming that the number of sensor devices that generate data and need to be stored is `n`, the frequency of data generation is `t` per second, and the length of each record is `L` bytes, the scale of data generated per day is `86400 * n * t * L` bytes. Assuming the compression ratio is `C`, the daily data size is `(86400 * n * t * L)/C` bytes. The storage resources are estimated to accommodate the data scale for 1.5 years. In the production environment, the compression ratio C of TDengine is generally between 5 and 7. With additional 20% redundancy, you can calculate the required storage resources: ```matlab -(n * t * L) * (365 * 1.5) * (1+20%)/C +(86400 * n * t * L) * (365 * 1.5) * (1+20%)/C ```` Substituting in the above formula, the raw data generated every year is 11.8TB without considering the label information. Note that tag information is associated with each timeline in TDengine, not every record. The amount of data to be recorded is somewhat reduced relative to the generated data, and label data can be ignored as a whole. Assuming a compression ratio of 5, the size of the retained data ends up being 2.56 TB. -- GitLab From 03d82f9baa2c717c9e0d09bb08cce498e7854ea1 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 8 Jul 2022 18:51:47 +0800 Subject: [PATCH 132/380] chore: update taos-tools for 2.6 (#14694) * chore: update taos-tools for 2.6 * test: change taosbenchmark test cases * fix: outdated test cases * fix: query/nestedQuery/nestedQuery.py * fix: update taos-tools * chore: update taos-tools for 2.6 * chore: update taos-tools for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index c9308b0481..9cb71e3c4c 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit c9308b04810faa653548db5f07c753a9d00990eb +Subproject commit 9cb71e3c4c0474553aa961cbe19795541c29b5c7 -- GitLab From 267352fe8964a93e07ae8e620f972078634ccffe Mon Sep 17 00:00:00 2001 From: Yu Chen <74105241+yu285@users.noreply.github.com> Date: Sat, 9 Jul 2022 23:15:00 +0800 Subject: [PATCH 133/380] docs/Update taos sql --- docs/zh/12-taos-sql/16-json.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/zh/12-taos-sql/16-json.md b/docs/zh/12-taos-sql/16-json.md index 4a4a8cca73..d1f7b3300b 100644 --- a/docs/zh/12-taos-sql/16-json.md +++ b/docs/zh/12-taos-sql/16-json.md @@ -55,8 +55,17 @@ title: JSON 类型使用说明 4. 标签操作 支持修改 json 标签值(全量覆盖) + + + ``` + alter table s1_1 set tag info = '{"k1": "v2"}'; + ``` 支持修改 json 标签名 + + ``` + alter stable s1 change tag info info2 ; + ``` 不支持添加 json 标签、删除 json 标签、修改 json 标签列宽 -- GitLab From 261d9c389852e444466754c25e482bfcd0fb5290 Mon Sep 17 00:00:00 2001 From: Yu Chen <74105241+yu285@users.noreply.github.com> Date: Sun, 10 Jul 2022 10:49:39 +0800 Subject: [PATCH 134/380] docs\ update json tag --- docs/en/12-taos-sql/16-json.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/en/12-taos-sql/16-json.md b/docs/en/12-taos-sql/16-json.md index 7460a5e0ba..61c473d120 100644 --- a/docs/en/12-taos-sql/16-json.md +++ b/docs/en/12-taos-sql/16-json.md @@ -52,9 +52,20 @@ title: JSON Type 4. Tag Operations - The value of a JSON tag can be altered. Please note that the full JSON will be overriden when doing this. + The value of a JSON tag can be altered. Please note that the full JSON will be overriden when doing this: + + ```sql + alter table s1_1 set tag info = '{"k1": "v2"}'; + ``` + + The name of a JSON tag can be altered: + + ```sql + alter stable s1 change tag info info2 ; + ``` + + A tag of JSON type can't be added or removed. The column length of a JSON tag can't be changed. - The name of a JSON tag can be altered. A tag of JSON type can't be added or removed. The column length of a JSON tag can't be changed. ## Other Restrictions -- GitLab From c8c7350ea0d5436b67612589fa6a1b3a8f9fdf32 Mon Sep 17 00:00:00 2001 From: huolibo Date: Fri, 8 Jul 2022 18:20:56 +0800 Subject: [PATCH 135/380] docs: add col length of example --- docs/zh/14-reference/03-connector/java.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/14-reference/03-connector/java.mdx b/docs/zh/14-reference/03-connector/java.mdx index ddab9e5f24..836bf49ce3 100644 --- a/docs/zh/14-reference/03-connector/java.mdx +++ b/docs/zh/14-reference/03-connector/java.mdx @@ -368,7 +368,7 @@ public class ParameterBindingDemo { private static final String host = "127.0.0.1"; private static final Random random = new Random(System.currentTimeMillis()); - private static final int BINARY_COLUMN_SIZE = 20; + private static final int BINARY_COLUMN_SIZE = 30; private static final String[] schemaList = { "create table stable1(ts timestamp, f1 tinyint, f2 smallint, f3 int, f4 bigint) tags(t1 tinyint, t2 smallint, t3 int, t4 bigint)", "create table stable2(ts timestamp, f1 float, f2 double) tags(t1 float, t2 double)", -- GitLab From f2c9f34be007f94638156b71449b73de5aa84f1b Mon Sep 17 00:00:00 2001 From: xiaolei li <85657333+xleili@users.noreply.github.com> Date: Mon, 11 Jul 2022 13:07:37 +0800 Subject: [PATCH 136/380] test(driver):update 2.6 R CI checkout JDBC from main to 2.0 (#14751) --- tests/develop-test/3-connectors/R/test.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/develop-test/3-connectors/R/test.sh b/tests/develop-test/3-connectors/R/test.sh index 90b9489365..dd4577a356 100644 --- a/tests/develop-test/3-connectors/R/test.sh +++ b/tests/develop-test/3-connectors/R/test.sh @@ -22,7 +22,9 @@ cd ../../ WKC=`pwd` #echo "WKC:${WKC}" -JDBC_PATH=${WKC}'/src/connector/jdbc/' +git clone git@github.com:taosdata/taos-connector-jdbc.git --branch 2.0 --single-branch --depth 1 + +JDBC_PATH=${WKC}'/taos-connector-jdbc/' CASE_PATH=${WKC}'/tests/examples/R/' cd ${JDBC_PATH} #echo "JDBC_PATH:${JDBC_PATH}" -- GitLab From 36b07f985ac1ed391e12f318b29f09417b3eccfa Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Mon, 11 Jul 2022 17:18:41 +0800 Subject: [PATCH 137/380] docs: remove maxVgroupsPerDb from database config --- docs/zh/12-taos-sql/02-database.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/zh/12-taos-sql/02-database.md b/docs/zh/12-taos-sql/02-database.md index 566fec3241..e3a0aa7c87 100644 --- a/docs/zh/12-taos-sql/02-database.md +++ b/docs/zh/12-taos-sql/02-database.md @@ -32,7 +32,6 @@ CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1]; - cacheLast: [详细说明](/reference/config/#cachelast) - replica: [详细说明](/reference/config/#replica) - quorum: [详细说明](/reference/config/#quorum) - - maxVgroupsPerDb: [详细说明](/reference/config/#maxvgroupsperdb) - comp: [详细说明](/reference/config/#comp) - precision: [详细说明](/reference/config/#precision) 6. 请注意上面列出的所有参数都可以配置在配置文件 `taosd.cfg` 中作为创建数据库时使用的默认配置, `create database` 的参数中明确指定的会覆盖配置文件中的设置。 -- GitLab From ac5236f012121e7af50a5da624b1de90b09ce3d9 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Mon, 11 Jul 2022 17:19:52 +0800 Subject: [PATCH 138/380] Update 02-database.md --- docs/en/12-taos-sql/02-database.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/en/12-taos-sql/02-database.md b/docs/en/12-taos-sql/02-database.md index 80581b2f1b..c2961d6241 100644 --- a/docs/en/12-taos-sql/02-database.md +++ b/docs/en/12-taos-sql/02-database.md @@ -32,7 +32,6 @@ CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1]; - cacheLast: [Description](/reference/config/#cachelast) - replica: [Description](/reference/config/#replica) - quorum: [Description](/reference/config/#quorum) - - maxVgroupsPerDb: [Description](/reference/config/#maxvgroupsperdb) - comp: [Description](/reference/config/#comp) - precision: [Description](/reference/config/#precision) 6. Please note that all of the parameters mentioned in this section are configured in configuration file `taos.cfg` on the TDengine server. If not specified in the `create database` statement, the values from taos.cfg are used by default. To override default parameters, they must be specified in the `create database` statement. -- GitLab From 7fbf8cbfc709c6669cb404dad4ea39108cdfb32f Mon Sep 17 00:00:00 2001 From: dingbo Date: Wed, 13 Jul 2022 12:13:47 +0800 Subject: [PATCH 139/380] docs: add high-volume.md --- docs/examples/java/pom.xml | 41 +++ .../example/highvolume/FastWriteExample.java | 114 ++++++ .../com/taos/example/highvolume/ReadTask.java | 111 ++++++ .../taos/example/highvolume/SQLWriter.java | 199 ++++++++++ .../taos/example/highvolume/WriteTask.java | 60 +++ .../python/highvolume_faster_queue.py | 205 +++++++++++ docs/examples/python/sql_writer.py | 81 +++++ .../03-insert-data/05-high-volume.md | 341 ++++++++++++++++++ .../07-develop/03-insert-data/highvolume.webp | Bin 0 -> 6746 bytes 9 files changed, 1152 insertions(+) create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java create mode 100644 docs/examples/python/highvolume_faster_queue.py create mode 100644 docs/examples/python/sql_writer.py create mode 100644 docs/zh/07-develop/03-insert-data/05-high-volume.md create mode 100644 docs/zh/07-develop/03-insert-data/highvolume.webp diff --git a/docs/examples/java/pom.xml b/docs/examples/java/pom.xml index a48ba398da..77c6a3ad60 100644 --- a/docs/examples/java/pom.xml +++ b/docs/examples/java/pom.xml @@ -24,6 +24,16 @@ 2.0.38 + + org.slf4j + slf4j-api + 1.7.36 + + + ch.qos.logback + logback-classic + 1.2.11 + junit junit @@ -31,5 +41,36 @@ test + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.5 + + true + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/lib + false + false + true + + + + + + diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java new file mode 100644 index 0000000000..e8af1a68ea --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java @@ -0,0 +1,114 @@ +package com.taos.example.highvolume; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +/** + * Prepare target database. + * Count total records in database periodically so that we can estimate the writing speed. + */ +class DataBaseMonitor { + private Connection conn; + private Statement stmt; + + public DataBaseMonitor init() throws SQLException { + if (conn == null) { + String jdbcURL = System.getenv("TDENGINE_JDBC_URL"); + conn = DriverManager.getConnection(jdbcURL); + stmt = conn.createStatement(); + } + return this; + } + + public void close() { + try { + stmt.close(); + } catch (SQLException e) { + } + try { + conn.close(); + } catch (SQLException e) { + } + } + + public void prepareDatabase() throws SQLException { + stmt.execute("DROP DATABASE IF EXISTS test"); + stmt.execute("CREATE DATABASE test"); + stmt.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"); + } + + public Long count() throws SQLException { + if (!stmt.isClosed()) { + ResultSet result = stmt.executeQuery("SELECT count(*) from test.meters"); + result.next(); + return result.getLong(1); + } + return null; + } +} + +// ANCHOR: main +public class FastWriteExample { + final static Logger logger = LoggerFactory.getLogger(FastWriteExample.class); + + final static int taskQueueCapacity = 10000000; + final static List> taskQueues = new ArrayList<>(); + final static List readTasks = new ArrayList<>(); + final static List writeTasks = new ArrayList<>(); + final static DataBaseMonitor databaseMonitor = new DataBaseMonitor(); + + public static void stopAll() { + logger.info("shutting down"); + readTasks.forEach(task -> task.stop()); + writeTasks.forEach(task -> task.stop()); + databaseMonitor.close(); + } + + public static void main(String[] args) throws InterruptedException, SQLException { + int readTaskCount = args.length > 0 ? Integer.parseInt(args[0]) : 1; + int writeTaskCount = args.length > 1 ? Integer.parseInt(args[1]) : 3; + int tableCount = args.length > 2 ? Integer.parseInt(args[2]) : 1000; + int maxBatchSize = args.length > 3 ? Integer.parseInt(args[3]) : 3000; + + logger.info("readTaskCount={}, writeTaskCount={} tableCount={} maxBatchSize={}", + readTaskCount, writeTaskCount, tableCount, maxBatchSize); + + databaseMonitor.init().prepareDatabase(); + + // Create task queues, whiting tasks and start writing threads. + for (int i = 0; i < writeTaskCount; ++i) { + BlockingQueue queue = new ArrayBlockingQueue<>(taskQueueCapacity); + taskQueues.add(queue); + WriteTask task = new WriteTask(queue, maxBatchSize); + Thread t = new Thread(task); + t.setName("WriteThread-" + i); + t.start(); + } + + // create reading tasks and start reading threads + int tableCountPerTask = tableCount / readTaskCount; + for (int i = 0; i < readTaskCount; ++i) { + ReadTask task = new ReadTask(i, taskQueues, tableCountPerTask); + Thread t = new Thread(task); + t.setName("ReadThread-" + i); + t.start(); + } + + Runtime.getRuntime().addShutdownHook(new Thread(FastWriteExample::stopAll)); + + long lastCount = 0; + while (true) { + Thread.sleep(10000); + long count = databaseMonitor.count(); + logger.info("count={} speed={}", count, (count - lastCount) / 10); + lastCount = count; + } + } +} +// ANCHOR_END: main \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java new file mode 100644 index 0000000000..94cde899f4 --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java @@ -0,0 +1,111 @@ +package com.taos.example.highvolume; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.BlockingQueue; + +/** + * Generate test data + */ +class MockDataSource implements Iterator { + private String tbNamePrefix; + private int tableCount; + private long maxRowsPerTable = 1000000000L; + + // 100 milliseconds between two neighbouring rows. + long startMs = System.currentTimeMillis() - maxRowsPerTable * 100; + private int currentRow = 0; + private int currentTbId = -1; + + // mock values + String[] location = {"LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"}; + float[] current = {8.8f, 10.7f, 9.9f, 8.9f, 9.4f}; + int[] voltage = {119, 116, 111, 113, 118}; + float[] phase = {0.32f, 0.34f, 0.33f, 0.329f, 0.141f}; + + public MockDataSource(String tbNamePrefix, int tableCount) { + this.tbNamePrefix = tbNamePrefix; + this.tableCount = tableCount; + } + + @Override + public boolean hasNext() { + currentTbId += 1; + if (currentTbId == tableCount) { + currentTbId = 0; + currentRow += 1; + } + return currentRow < maxRowsPerTable; + } + + @Override + public String next() { + long ts = startMs + 100 * currentRow; + int groupId = currentTbId % 5 == 0 ? currentTbId / 5 : currentTbId / 5 + 1; + StringBuilder sb = new StringBuilder(tbNamePrefix + "_" + currentTbId + ","); // tbName + sb.append(ts).append(','); // ts + sb.append(current[currentRow % 5]).append(','); // current + sb.append(voltage[currentRow % 5]).append(','); // voltage + sb.append(phase[currentRow % 5]).append(','); // phase + sb.append(location[currentRow % 5]).append(','); // location + sb.append(groupId); // groupID + + return sb.toString(); + } +} + +// ANCHOR: ReadTask +class ReadTask implements Runnable { + private final static Logger logger = LoggerFactory.getLogger(ReadTask.class); + private final int taskId; + private final List> taskQueues; + private final int queueCount; + private final int tableCount; + private boolean active = true; + + public ReadTask(int readTaskId, List> queues, int tableCount) { + this.taskId = readTaskId; + this.taskQueues = queues; + this.queueCount = queues.size(); + this.tableCount = tableCount; + } + + /** + * Assign data received to different queues. + * Here we use the suffix number in table name. + * You are expected to define your own rule in practice. + * + * @param line record received + * @return which queue to use + */ + public int getQueueId(String line) { + String tbName = line.substring(0, line.indexOf(',')); // For example: tb1_101 + String suffixNumber = tbName.split("_")[1]; + return Integer.parseInt(suffixNumber) % this.queueCount; + } + + @Override + public void run() { + logger.info("started"); + Iterator it = new MockDataSource("tb" + this.taskId, tableCount); + try { + while (it.hasNext() && active) { + String line = it.next(); + int queueId = getQueueId(line); + taskQueues.get(queueId).put(line); + } + } catch (Exception e) { + logger.error("Read Task Error", e); + } + } + + public void stop() { + logger.info("stop"); + this.active = false; + } +} + +// ANCHOR_END: ReadTask \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java new file mode 100644 index 0000000000..b13d6c363c --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java @@ -0,0 +1,199 @@ +package com.taos.example.highvolume; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.util.HashMap; +import java.util.Map; + +// ANCHOR: SQLWriter + +/** + * A helper class encapsulate the logic of writing using SQL. + *

+ * The main interfaces are two methods: + *

    + *
  1. {@link SQLWriter#processLine}, which receive raw lines from WriteTask and group them by table names.
  2. + *
  3. {@link SQLWriter#flush}, which assemble INSERT statement and execute it.
  4. + *
+ *

+ * There is a technical skill worth mentioning: we create table as needed when "table does not exist" error occur instead of creating table automatically using syntax "INSET INTO tb USING stb". + * This ensure that checking table existence is a one-time-only operation. + *

+ * + *

+ */ +public class SQLWriter { + final static Logger logger = LoggerFactory.getLogger(SQLWriter.class); + + private Connection conn; + private Statement stmt; + + /** + * current number of buffered records + */ + private int bufferedCount = 0; + /** + * Maximum number of buffered records. + * Flush action will be triggered if bufferedCount reached this value, + */ + private int maxBatchSize; + + + /** + * Maximum SQL length. + */ + private int maxSQLLength; + + /** + * Map from table name to column values. For example: + * "tb001" -> "(1648432611249,2.1,114,0.09) (1648432611250,2.2,135,0.2)" + */ + private Map tbValues = new HashMap<>(); + + /** + * Map from table name to tag values in the same order as creating stable. + * Used for creating table. + */ + private Map tbTags = new HashMap<>(); + + public SQLWriter(int maxBatchSize) { + this.maxBatchSize = maxBatchSize; + } + + + /** + * Get Database Connection + * + * @return Connection + * @throws SQLException + */ + private static Connection getConnection() throws SQLException { + String jdbcURL = System.getenv("TDENGINE_JDBC_URL"); + return DriverManager.getConnection(jdbcURL); + } + + /** + * Create Connection and Statement + * + * @throws SQLException + */ + public void init() throws SQLException { + conn = getConnection(); + stmt = conn.createStatement(); + stmt.execute("use test"); + ResultSet rs = stmt.executeQuery("show variables"); + while (rs.next()) { + String configName = rs.getString(1); + if ("maxSQLLength".equals(configName)) { + maxSQLLength = Integer.parseInt(rs.getString(2)); + logger.info("maxSQLLength={}", maxSQLLength); + } + } + } + + /** + * Convert raw data to SQL fragments, group them by table name and cache them in a HashMap. + * Trigger writing when number of buffered records reached maxBachSize. + * + * @param line raw data get from task queue in format: tbName,ts,current,voltage,phase,location,groupId + */ + public void processLine(String line) throws SQLException { + bufferedCount += 1; + int firstComma = line.indexOf(','); + String tbName = line.substring(0, firstComma); + int lastComma = line.lastIndexOf(','); + int secondLastComma = line.lastIndexOf(',', lastComma - 1); + String value = "(" + line.substring(firstComma + 1, secondLastComma) + ") "; + if (tbValues.containsKey(tbName)) { + tbValues.put(tbName, tbValues.get(tbName) + value); + } else { + tbValues.put(tbName, value); + } + if (!tbTags.containsKey(tbName)) { + String location = line.substring(secondLastComma + 1, lastComma); + String groupId = line.substring(lastComma + 1); + String tagValues = "('" + location + "'," + groupId + ')'; + tbTags.put(tbName, tagValues); + } + if (bufferedCount == maxBatchSize) { + flush(); + } + } + + + /** + * Assemble INSERT statement using buffered SQL fragments in Map {@link SQLWriter#tbValues} and execute it. + * In case of "Table does not exit" exception, create all tables in the sql and retry the sql. + */ + public void flush() throws SQLException { + StringBuilder sb = new StringBuilder("INSERT INTO "); + for (Map.Entry entry : tbValues.entrySet()) { + String tableName = entry.getKey(); + String values = entry.getValue(); + String q = tableName + " values " + values + " "; + if (sb.length() + q.length() > maxSQLLength) { + executeSQL(sb.toString()); + logger.warn("increase maxSQLLength or decrease maxBatchSize to gain better performance"); + sb = new StringBuilder("INSERT INTO "); + } + sb.append(q); + } + executeSQL(sb.toString()); + tbValues.clear(); + bufferedCount = 0; + } + + private void executeSQL(String sql) throws SQLException { + try { + stmt.executeUpdate(sql); + } catch (SQLException e) { + // convert to error code defined in taoserror.h + int errorCode = e.getErrorCode() & 0xffff; + if (errorCode == 0x362 || errorCode == 0x218) { + // Table does not exist + createTables(); + stmt.executeUpdate(sql); + } else { + throw e; + } + } + } + + /** + * Create tables in batch using syntax: + *

+ * CREATE TABLE [IF NOT EXISTS] tb_name1 USING stb_name TAGS (tag_value1, ...) [IF NOT EXISTS] tb_name2 USING stb_name TAGS (tag_value2, ...) ...; + *

+ */ + private void createTables() throws SQLException { + StringBuilder sb = new StringBuilder("CREATE TABLE "); + for (String tbName : tbValues.keySet()) { + String tagValues = tbTags.get(tbName); + sb.append("IF NOT EXISTS ").append(tbName).append(" USING meters TAGS ").append(tagValues).append(" "); + } + String sql = sb.toString(); + stmt.executeUpdate(sql); + } + + public boolean hasBufferedValues() { + return bufferedCount > 0; + } + + public int getBufferedCount() { + return bufferedCount; + } + + public void close() { + try { + stmt.close(); + } catch (SQLException e) { + } + try { + conn.close(); + } catch (SQLException e) { + } + } +} +// ANCHOR_END: SQLWriter diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java new file mode 100644 index 0000000000..bbe9cb0770 --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java @@ -0,0 +1,60 @@ +package com.taos.example.highvolume; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.BlockingQueue; + +// ANCHOR: WriteTask +class WriteTask implements Runnable { + private final static Logger logger = LoggerFactory.getLogger(WriteTask.class); + private final int maxBatchSize; + + // the queue from which this writing task get raw data. + private final BlockingQueue queue; + + // A flag indicate whether to continue. + private boolean active = true; + + public WriteTask(BlockingQueue taskQueue, int maxBatchSize) { + this.queue = taskQueue; + this.maxBatchSize = maxBatchSize; + } + + @Override + public void run() { + logger.info("started"); + String line = null; // data getting from the queue just now. + SQLWriter writer = new SQLWriter(maxBatchSize); + try { + writer.init(); + while (active) { + line = queue.poll(); + if (line != null) { + // parse raw data and buffer the data. + writer.processLine(line); + } else if (writer.hasBufferedValues()) { + // write data immediately if no more data in the queue + writer.flush(); + } else { + // sleep a while to avoid high CPU usage if no more data in the queue and no buffered records, . + Thread.sleep(100); + } + } + if (writer.hasBufferedValues()) { + writer.flush(); + } + } catch (Exception e) { + String msg = String.format("line=%s, bufferedCount=%s", line, writer.getBufferedCount()); + logger.error(msg, e); + } finally { + writer.close(); + } + } + + public void stop() { + logger.info("stop"); + this.active = false; + } +} +// ANCHOR_END: WriteTask \ No newline at end of file diff --git a/docs/examples/python/highvolume_faster_queue.py b/docs/examples/python/highvolume_faster_queue.py new file mode 100644 index 0000000000..14aebc67ee --- /dev/null +++ b/docs/examples/python/highvolume_faster_queue.py @@ -0,0 +1,205 @@ +# install dependencies: +# recommend python >= 3.8 +# pip3 install faster-fifo +# + +import logging +import sys +import time +import os +from multiprocessing import Process +from faster_fifo import Queue +from queue import Empty +from typing import List + +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format="%(asctime)s [%(name)s] - %(message)s") + +READ_TASK_COUNT = 1 +WRITE_TASK_COUNT = 1 +TABLE_COUNT = 1000 +QUEUE_SIZE = 1000000 +MAX_BATCH_SIZE = 3000 + +read_processes = [] +write_processes = [] + + +def get_connection(): + """ + If variable TDENGINE_FIRST_EP is provided then it will be used. If not, firstEP in /etc/taos/taos.cfg will be used. + You can also override the default username and password by supply variable TDENGINE_USER and TDENGINE_PASSWORD + """ + import taos + firstEP = os.environ.get("TDENGINE_FIRST_EP") + if firstEP: + host, port = firstEP.split(":") + else: + host, port = None, 0 + user = os.environ.get("TDENGINE_USER", "root") + password = os.environ.get("TDENGINE_PASSWORD", "taosdata") + return taos.connect(host=host, port=int(port), user=user, password=password) + + +# ANCHOR: MockDataSource +class MockDataSource: + location = ["LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"] + current = [8.8, 10.7, 9.9, 8.9, 9.4] + voltage = [119, 116, 111, 113, 118] + phase = [0.32, 0.34, 0.33, 0.329, 0.141] + max_rows_per_table = 10 ** 9 + + def __init__(self, tb_name_prefix, table_count): + self.table_name_prefix = tb_name_prefix + self.table_count = table_count + self.start_ms = round(time.time() * 1000) - self.max_rows_per_table * 100 + + def __iter__(self): + self.row = 0 + self.table_id = -1 + return self + + def __next__(self): + """ + next 100 rows of current table + """ + self.table_id += 1 + if self.table_id == self.table_count: + self.table_id = 0 + if self.row >= self.max_rows_per_table: + raise StopIteration + rows = [] + + while len(rows) < 100: + self.row += 1 + ts = self.start_ms + 100 * self.row + group_id = self.table_id % 5 if self.table_id % 5 == 0 else self.table_id % 5 + 1 + tb_name = self.table_name_prefix + '_' + str(self.table_id) + ri = self.row % 5 + rows.append(f"{tb_name},{ts},{self.current[ri]},{self.voltage[ri]},{self.phase[ri]},{self.location[ri]},{group_id}") + return self.table_id, rows + + +# ANCHOR_END: MockDataSource + +# ANCHOR: read +def run_read_task(task_id: int, task_queues: List[Queue]): + table_count_per_task = TABLE_COUNT // READ_TASK_COUNT + data_source = MockDataSource(f"tb{task_id}", table_count_per_task) + try: + for table_id, rows in data_source: + # hash data to different queue + i = table_id % len(task_queues) + # block putting forever when the queue is full + task_queues[i].put_many(rows, block=True, timeout=-1) + except KeyboardInterrupt: + pass + + +# ANCHOR_END: read + +# ANCHOR: write +def run_write_task(task_id: int, queue: Queue): + from sql_writer import SQLWriter + log = logging.getLogger(f"WriteTask-{task_id}") + writer = SQLWriter(get_connection) + lines = None + try: + while True: + try: + # get as many as possible + lines = queue.get_many(block=False, max_messages_to_get=MAX_BATCH_SIZE) + writer.process_lines(lines) + except Empty: + time.sleep(0.01) + except KeyboardInterrupt: + pass + except BaseException as e: + log.debug(f"lines={lines}") + raise e + + +# ANCHOR_END: write + +def set_global_config(): + argc = len(sys.argv) + if argc > 1: + global READ_TASK_COUNT + READ_TASK_COUNT = int(sys.argv[1]) + if argc > 2: + global WRITE_TASK_COUNT + WRITE_TASK_COUNT = int(sys.argv[2]) + if argc > 3: + global TABLE_COUNT + TABLE_COUNT = int(sys.argv[3]) + if argc > 4: + global QUEUE_SIZE + QUEUE_SIZE = int(sys.argv[4]) + if argc > 5: + global MAX_BATCH_SIZE + MAX_BATCH_SIZE = int(sys.argv[5]) + + +# ANCHOR: monitor +def run_monitor_process(): + import taos + log = logging.getLogger("DataBaseMonitor") + conn = get_connection() + conn.execute("DROP DATABASE IF EXISTS test") + conn.execute("CREATE DATABASE test") + conn.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) " + "TAGS (location BINARY(64), groupId INT)") + + def get_count(): + res = conn.query("SELECT count(*) FROM test.meters") + rows = res.fetch_all() + return rows[0][0] if rows else 0 + + last_count = 0 + while True: + time.sleep(10) + count = get_count() + log.info(f"count={count} speed={(count - last_count) / 10}") + last_count = count + + +# ANCHOR_END: monitor +# ANCHOR: main +def main(): + set_global_config() + logging.info(f"READ_TASK_COUNT={READ_TASK_COUNT}, WRITE_TASK_COUNT={WRITE_TASK_COUNT}, " + f"TABLE_COUNT={TABLE_COUNT}, QUEUE_SIZE={QUEUE_SIZE}, MAX_BATCH_SIZE={MAX_BATCH_SIZE}") + + monitor_process = Process(target=run_monitor_process) + monitor_process.start() + time.sleep(3) # waiting for database ready. + + task_queues: List[Queue] = [] + # create task queues + for i in range(WRITE_TASK_COUNT): + queue = Queue(max_size_bytes=QUEUE_SIZE) + task_queues.append(queue) + # create write processes + for i in range(WRITE_TASK_COUNT): + p = Process(target=run_write_task, args=(i, task_queues[i])) + p.start() + logging.debug(f"WriteTask-{i} started with pid {p.pid}") + write_processes.append(p) + # create read processes + for i in range(READ_TASK_COUNT): + p = Process(target=run_read_task, args=(i, task_queues)) + p.start() + logging.debug(f"ReadTask-{i} started with pid {p.pid}") + read_processes.append(p) + + try: + monitor_process.join() + except KeyboardInterrupt: + monitor_process.terminate() + [p.terminate() for p in read_processes] + [p.terminate() for p in write_processes] + [q.close() for q in task_queues] + + +if __name__ == '__main__': + main() +# ANCHOR_END: main diff --git a/docs/examples/python/sql_writer.py b/docs/examples/python/sql_writer.py new file mode 100644 index 0000000000..ad5653f0ec --- /dev/null +++ b/docs/examples/python/sql_writer.py @@ -0,0 +1,81 @@ +import logging +import taos + + +class SQLWriter: + log = logging.getLogger("SQLWriter") + + def __init__(self, get_connection_func): + self._tb_values = {} + self._tb_tags = {} + self._conn = get_connection_func() + self._max_sql_length = self.get_max_sql_length() + self._conn.execute("USE test") + + def get_max_sql_length(self): + rows = self._conn.query("SHOW variables").fetch_all() + for r in rows: + name = r[0] + if name == "maxSQLLength": + return int(r[1]) + + def process_lines(self, lines: str): + """ + :param lines: [[tbName,ts,current,voltage,phase,location,groupId]] + """ + for line in lines: + ps = line.split(",") + table_name = ps[0] + value = '(' + ",".join(ps[1:-2]) + ') ' + if table_name in self._tb_values: + self._tb_values[table_name] += value + else: + self._tb_values[table_name] = value + + if table_name not in self._tb_tags: + location = ps[-2] + group_id = ps[-1] + tag_value = f"('{location}',{group_id})" + self._tb_tags[table_name] = tag_value + self.flush() + + def flush(self): + """ + Assemble INSERT statement and execute it. + When the sql length grows close to MAX_SQL_LENGTH, the sql will be executed immediately, and a new INSERT statement will be created. + In case of "Table does not exit" exception, tables in the sql will be created and the sql will be re-executed. + """ + sql = "INSERT INTO " + sql_len = len(sql) + buf = [] + for tb_name, values in self._tb_values.items(): + q = tb_name + " VALUES " + values + if sql_len + len(q) >= self._max_sql_length: + sql += " ".join(buf) + self.execute_sql(sql) + sql = "INSERT INTO " + sql_len = len(sql) + buf = [] + buf.append(q) + sql_len += len(q) + sql += " ".join(buf) + self.execute_sql(sql) + self._tb_values.clear() + + def execute_sql(self, sql): + try: + self._conn.execute(sql) + except taos.Error as e: + error_code = e.errno & 0xffff + # Table does not exit + if error_code == 0x362 or error_code == 0x218: + self.create_tables() + else: + raise e + + def create_tables(self): + sql = "CREATE TABLE " + for tb in self._tb_values.keys(): + tag_values = self._tb_tags[tb] + sql += "IF NOT EXISTS " + tb + " USING meters TAGS " + tag_values + " " + self._conn.execute(sql) diff --git a/docs/zh/07-develop/03-insert-data/05-high-volume.md b/docs/zh/07-develop/03-insert-data/05-high-volume.md new file mode 100644 index 0000000000..731cf2c188 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/05-high-volume.md @@ -0,0 +1,341 @@ +--- +title: 高效写入 +--- + +## 高效写入原理 {#principle} + +本节介绍如何高效地向 TDengine 写入数据。高效写入数据要考虑几个因素:数据在不同表(或子表)之间的分布,即要写入数据的相邻性;单次写入的数据量;并发连接数。一般来说,每批次只向同一张表(或子表)写入数据比向多张表(或子表)写入数据要更高效;每批次写入的数据量越大越高效(但超过一定阈值其优势会消失;同时写入数据的并发连接数越多写入越高效(但超过一定阈值反而会下降,取决于服务端处理能力)。 + +为了更高效地向 TDengine 写入数据,客户端程序要充分且恰当地利用以上几个因素。在单次写入中尽量只向同一张表(或子表)写入数据,每批次写入的数据量经过测试和调优设定为一个最适合当前系统处理能力的数值,并发写入的连接数同样经过测试和调优后设定为一个最适合当前系统处理能力的数值,以实现在当前系统中的最佳写入速度。同时,TDengine 还提供了独特的参数绑定写入,这也是一个有助于实现高效写入的方法。 + +为了使写入最高效,除了客户端程序的设计,服务端的配置也很重要。如果无论怎么调节客户端程序,taosd 进程的 CPU 使用率都很低,那很可能需要增加 vgroup 的数量。比如:数据库总表数是 1000 且 minTablesPerVnode 设置的也是 1000,那么这个数据至多有一个 vgroup。此时如果将 minTablesPerVnode 和 tablelncStepPerVnode 都设置成 100, 则这个数据库有可能用到 10 个 vgroup。更多性能调优参数请参考[配置参考](../../reference/config)性能调优部分。 + +## 高效写入方案 {#scenario} + +下面的示例程序展示了如何高效写入数据: + +- TDengine 客户端程序从消息队列或者其它数据源不断读入数据,在示例程序中采用生成模拟数据的方式来模拟读取数据源 +- 单个连接向 TDengine 写入的速度无法与读数据的速度相匹配,因此客户端程序启动多个线程,每个线程都建立了与 TDengine 的连接,每个线程都有一个独占的固定大小的消息队列 +- 客户端程序将接收到的数据根据所属的表名(或子表名)HASH 到不同的线程,即写入该线程所对应的消息队列,以此确保属于某个表(或子表)的数据一定会被一个固定的线程处理 +- 各个子线程在将所关联的消息队列中的数据读空后或者读取数据量达到一个预定的阈值后将该批数据写入 TDengine,并继续处理后面接收到的数据 + +![TDengine 高效写入线程模型](highvolume.webp) + +:::note +上图所示架构,每个写任务只负责写特定的表,体现了数据的相邻性原则。但是读任务所读的表,我们假设是随机的。这样一个队列有多个写入线程(或进程),队列内部可能产生锁的消耗。实际场景,如果能做到一个读任务对应一个写任务是最好的。 +::: + +## Java 示例程序 {#java-demo} + +在 Java 示例程序中采用拼接 SQL 的写入方式。 + +### 主程序 {#java-demo-main} + +主程序负责: + +1. 创建消息队列 +2. 启动写线程 +3. 启动读线程 +4. 每隔 10 秒统计一次写入速度 + +主程序默认暴露了 4 个参数,每次启动程序都可调节,用于测试和调优: + +1. 读线程个数。默认为 1。 +2. 写线程个数。默认为 3。 +3. 模拟生成的总表数。默认为 1000。将会平分给各个读线程。 +4. 每批最多写入记录数量。默认为 3000。 + +
+主程序 + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java:main}} +``` + +
+ + +队列容量(taskQueueCapacity)也是与性能有关的参数,可通过修改程序调节。一般来讲,队列容量越大,入队被阻塞的概率越小,队列的吞吐量越大,但是内存占用也会越大。 + +### 读任务的实现 {#java-demo-read} + +读任务负责从数据源读数据。每个读任务都关联了一个模拟数据源。每个模拟数据源可生成一点数量表的数据。不同的模拟数据源生成不同表的数据。 + +读任务采用阻塞的方式写消息队列。也就是说,一旦队列满了,写操作就会阻塞。 + +
+读任务的实现 + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java:ReadTask}} +``` + +
+ +### 写任务的实现 {#java-demo-write} + +
+写任务的实现 + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java:WriteTask}} +``` + +
+ +### SQLWriter 类的实现 {#java-demo-sql-writer} + +SQLWriter 类封装了拼 SQL 和写数据的逻辑。注意,所有的表都没有提前创建,而是写入出错的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。 + +
+SQLWriter 类的实现 + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java:SQLWriter}} +``` + +
+ +### 执行示例程序 {#run-java-demo} + +
+执行 Java 示例程序 + + +执行程序前需配置环境变量 `TDENGINE_JDBC_URL`。如果 TDengine Server 部署在本机,且用户名、密码和端口都是默认值,那么可配置: + +``` +TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" +``` + +#### 本地集成开发环境执行示例程序 {#java-demo-local-run} + +1. clone TDengine 仓库 + ``` + git clone git@github.com:taosdata/TDengine.git --depth 1 + ``` +2. 用集成开发环境打开 `docs/examples/java` 目录。 +3. 在开发环境中配置环境变量 `TDENGINE_JDBC_URL`。如果已配置了全局的环境变量 `TDENGINE_JDBC_URL` 可跳过这一步。 +4. 运行类 `com.taos.example.highvolume.FastWriteExample`。 + +#### 远程服务器上执行示例程序 {#java-demo-remote-run} + +若要在服务器上执行示例程序,可按照下面的步骤操作: + +1. 打包示例代码。在目录 TDengine/docs/examples/java 下执行: + ``` + mvn package + ``` +2. 远程服务器上创建 examples 目录: + ``` + mkdir -p examples/java + ``` +3. 复制依赖到服务器指定目录: + - 复制依赖包,只用复制一次 + ``` + scp -r .\target\lib @:~/examples/java + ``` + + - 复制本程序的 jar 包,每次更新代码都需要复制 + ``` + scp -r .\target\javaexample-1.0.jar @:~/examples/java + ``` +4. 配置环境变量。 + 编辑 `~/.bash_profile` 或 `~/.bashrc` 添加如下内容例如: + ``` + export TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" + ``` + 以上使用的是本地部署 TDengine Server 时默认的 JDBC URL。你需要根据自己的实际情况更改。 + +5. 用 java 命令启动示例程序,命令模板: + + ``` + java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample + ``` + +6. 结束测试程序。测试程序不会自动结束,在获取到当前配置下稳定的写入速度后,按 CTRL + C 结束程序。 + 下面是一次实际运行的截图: + + ``` + [testuser@vm95 java]$ java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample 1 9 1000 2000 + 17:01:01.131 [main] INFO c.t.e.highvolume.FastWriteExample - readTaskCount=1, writeTaskCount=9 tableCount=1000 maxBatchSize=2000 + 17:01:01.286 [WriteThread-0] INFO c.taos.example.highvolume.WriteTask - started + 17:01:01.354 [WriteThread-1] INFO c.taos.example.highvolume.WriteTask - started + 17:01:01.360 [WriteThread-2] INFO c.taos.example.highvolume.WriteTask - started + 17:01:01.366 [WriteThread-3] INFO c.taos.example.highvolume.WriteTask - started + 17:01:01.433 [WriteThread-4] INFO c.taos.example.highvolume.WriteTask - started + 17:01:01.438 [WriteThread-5] INFO c.taos.example.highvolume.WriteTask - started + 17:01:01.443 [WriteThread-6] INFO c.taos.example.highvolume.WriteTask - started + 17:01:01.448 [WriteThread-7] INFO c.taos.example.highvolume.WriteTask - started + 17:01:01.454 [WriteThread-8] INFO c.taos.example.highvolume.WriteTask - started + 17:01:01.454 [ReadThread-0] INFO com.taos.example.highvolume.ReadTask - started + 17:01:11.615 [main] INFO c.t.e.highvolume.FastWriteExample - count=18766442 speed=1876644 + 17:01:21.775 [main] INFO c.t.e.highvolume.FastWriteExample - count=38947464 speed=2018102 + 17:01:32.428 [main] INFO c.t.e.highvolume.FastWriteExample - count=58649571 speed=1970210 + 17:01:42.577 [main] INFO c.t.e.highvolume.FastWriteExample - count=79264890 speed=2061531 + 17:01:53.265 [main] INFO c.t.e.highvolume.FastWriteExample - count=99097476 speed=1983258 + 17:02:04.209 [main] INFO c.t.e.highvolume.FastWriteExample - count=119546779 speed=2044930 + 17:02:14.935 [main] INFO c.t.e.highvolume.FastWriteExample - count=141078914 speed=2153213 + 17:02:25.617 [main] INFO c.t.e.highvolume.FastWriteExample - count=162183457 speed=2110454 + 17:02:36.718 [main] INFO c.t.e.highvolume.FastWriteExample - count=182735614 speed=2055215 + 17:02:46.988 [main] INFO c.t.e.highvolume.FastWriteExample - count=202895614 speed=2016000 + ``` + +
+ +## Python 示例程序 {#python-demo} + +该 Python 示例程序中采用了多进程的架构,并使用了跨进程的队列通信。写任务采用拼装 SQL 的方式写入。 +### main 函数 {#python-demo-main} + +main 函数负责创建消息队列和启动子进程,子进程有 3 类: + +1. 1 个监控进程,负责数据库初始化和统计写入速度 +2. n 个读进程,负责从其它数据系统读数据 +3. m 个写进程,负责写数据库 + +main 函数可以接收 5 个启动参数,依次是: + +1. 读任务(进程)数, 默认为 1 +2. 写任务(进程)数, 默认为 1 +3. 模拟生成的总表数,默认为 1000 +4. 队列大小(单位字节),默认为 1000000 +5. 每批最多写入记录数量, 默认为 3000 + +
+ +main 函数 + +```python +{{#include docs/examples/python/highvolume_faster_queue.py:main}} +``` + +
+ +### 监控进程 + +监控进程负责初始化数据库,并监控当前的写入速度。 + +
+Monitor Process + +```python +{{#include docs/examples/python/highvolume_faster_queue.py:monitor}} +``` + +
+ +### 读进程 {#python-read-process} + +#### 读进程主要逻辑 {#python-run-read-task} + +读进程,负责从其它数据系统读数据,并分发数据到各个写进程。 + +
+ +run_read_task 函数 + +```python +{{#include docs/examples/python/highvolume_faster_queue.py:read}} +``` + +
+ +#### 模拟数据源 {#python-mock-data-source} + +以下是模拟数据源的实现,我们假设数据源生成的每一条数据都带有目标表名信息。实际中你可能需要一定的规则确定目标表名。 + +
+MockDataSource + +```python +{{#include docs/examples/python/highvolume_faster_queue.py:MockDataSource}} +``` + +
+ +### 写进程 {#python-write-process} + +写进程每次从队列中取出尽量多的数据,并批量写入。 + +
+run_write_task 函数 + +```python +{{#include docs/examples/python/highvolume_faster_queue.py:write}} +``` +
+ +### SQLWriter 类的实现 {#python-sql-writer} + +SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提前创建,而是写入出错的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。这个类也对 SQL 是否超过最大长度限制做了检查,如果接近 SQL 最大长度限制(maxSQLLength),将会立即执行 SQL。为了减少 SQL 此时,建议将 maxSQLLength 适当调大。 + +
+ +SQLWriter + +```python +{{#include docs/examples/python/sql_writer.py}} +``` + +
+ +### 执行示例程序 {#run-python-demo} + +
+ +执行 Python 示例程序 + +1. 前提条件 + - 已安装 TDengine 客户端驱动 + - 已安装 Python3, 推荐版本 >= 3.8 + - 已安装 taospy + +2. 安装 faster-fifo 代替 python 内置的 multiprocessing.Queue + ``` + pip3 install faster-fifo + ``` + +3. 点击上面的“查看源码”链接复制 `highvolume_faster_queue.py` 和 `sql_writer.py` 两个文件。 + +4. 执行示例程序 + + ``` + python3 highvolume_faster_queue.py + ``` + +下面是一次实际运行的输出: + +``` +[testuser@vm95 python]$ python3.6 highvolume_faster_queue.py 9 9 1000 5000000 3000 +2022-07-13 10:05:50,504 [root] - READ_TASK_COUNT=9, WRITE_TASK_COUNT=9, TABLE_COUNT=1000, QUEUE_SIZE=5000000, MAX_BATCH_SIZE=3000 +2022-07-13 10:05:53,542 [root] - WriteTask-0 started with pid 5475 +2022-07-13 10:05:53,542 [root] - WriteTask-1 started with pid 5476 +2022-07-13 10:05:53,543 [root] - WriteTask-2 started with pid 5477 +2022-07-13 10:05:53,543 [root] - WriteTask-3 started with pid 5478 +2022-07-13 10:05:53,544 [root] - WriteTask-4 started with pid 5479 +2022-07-13 10:05:53,544 [root] - WriteTask-5 started with pid 5480 +2022-07-13 10:05:53,545 [root] - WriteTask-6 started with pid 5481 +2022-07-13 10:05:53,546 [root] - WriteTask-7 started with pid 5482 +2022-07-13 10:05:53,546 [root] - WriteTask-8 started with pid 5483 +2022-07-13 10:05:53,547 [root] - ReadTask-0 started with pid 5484 +2022-07-13 10:05:53,548 [root] - ReadTask-1 started with pid 5485 +2022-07-13 10:05:53,549 [root] - ReadTask-2 started with pid 5486 +2022-07-13 10:05:53,550 [root] - ReadTask-3 started with pid 5487 +2022-07-13 10:05:53,551 [root] - ReadTask-4 started with pid 5488 +2022-07-13 10:05:53,552 [root] - ReadTask-5 started with pid 5489 +2022-07-13 10:05:53,552 [root] - ReadTask-6 started with pid 5490 +2022-07-13 10:05:53,553 [root] - ReadTask-7 started with pid 5491 +2022-07-13 10:05:53,554 [root] - ReadTask-8 started with pid 5492 +2022-07-13 10:06:00,842 [DataBaseMonitor] - count=6612939 speed=661293.9 +2022-07-13 10:06:11,151 [DataBaseMonitor] - count=14765739 speed=815280.0 +2022-07-13 10:06:21,677 [DataBaseMonitor] - count=23282163 speed=851642.4 +2022-07-13 10:06:31,985 [DataBaseMonitor] - count=31673139 speed=839097.6 +2022-07-13 10:06:42,343 [DataBaseMonitor] - count=39819439 speed=814630.0 +2022-07-13 10:06:52,830 [DataBaseMonitor] - count=48146339 speed=832690.0 +2022-07-13 10:07:03,396 [DataBaseMonitor] - count=56385039 speed=823870.0 +2022-07-13 10:07:14,341 [DataBaseMonitor] - count=64848739 speed=846370.0 +2022-07-13 10:07:24,877 [DataBaseMonitor] - count=73654566 speed=880582.7 +``` + +
\ No newline at end of file diff --git a/docs/zh/07-develop/03-insert-data/highvolume.webp b/docs/zh/07-develop/03-insert-data/highvolume.webp new file mode 100644 index 0000000000000000000000000000000000000000..9f8c9a9cc161e382728750bdfcc93ee086d62aea GIT binary patch literal 6746 zcmV-g8l~k@Nk&Fe8UO%SMM6+kP&iCR8UO$CyO#QS9WVGMWL42`pl&ux?cKFR}Ie{7On)TcT`BO+qP}nwr$(C zZQHhOTQfZ~-M{|Lbnox?$8J)#ZQC}!x!RL!&t+`e+SuBvI5|~waa7SKwr$(C9VdrkEMKJux%0)RvfOGBYzXLk&%aY%w!4v#ieiMMRdW zLKT%_W(J$dV`lwQ%&fJR$4g*MvKBM5CFn6~ae7^A^!b%wYb(O08Y`^z7P4hYx6h8T4hx_4?B#YFM)pLu^%VZF zTC{HAQcO-WA8f%+BUSe3P0=?ww^0n9*pYJP@TDUv`?vx44da!imw%5-IBNOIL&*dGXtBhm1;V+_B+aiJTUOBe!b*9-?6 z!*?wD*^M;C2YLd_Y8Vq40k^6Ll#fFvE^*-i@XqwHgC3g_%kN?2dEy>KL|uOT$Q;A> zajG|Kv|I!gG;JCPG}j1N*N9F>lu+sC37V$}27*Y;n=%<2pHiSg-0JYbd6Uq6GiHvE z7J!b&v$-z5Ha(|=Ka zWV{pTu5aqCz(>$XGZfGy5FJ(&4chRyk>c)GILYbN)T>hMD|*N#5D-skI^yw{ah+or zM7gOZ5>w^1f{u^?<}5xn+N*(ewRen4u(PCKqZUsR45WP7&?%0yn4tSdDZ8MuVe*DBe(9M~^#`TwdP2eLihou0LK+N(u2gQ-hF?<6T zdIwou%|SQ4Az;M|JQnplz%kyII?ckB>a=z$WpJ1PzlLAq(QV~eUe{!Hane#sEjsY* z;jtdC*HV#US?r_*h!h7Lyc+aSAD`LuQPdwDFNx`62jNW~_G;j-+~$%Y$c3$`p$hg@ z4Kl2e)42}rBf4=TKfpy_m)U{p#T+zzJn!a7*yF6xUnMKS7qwi(A)n_N>Oz!yLz?^A zRWHP3kOpLPzyZGQriP~{@wc1)o4E%a*e)`lV_(lp=&MY1JQIizx(Atr9Z&A#x5viE zG-~Z3bzry$+q4-7h#*J6PqheQqv3xhab3akzkN7vh)aA3_Btq{lP6bEnh8>dM#5ivM2K3@1X4)i89%Y5uG z-DXMoo_EzG0b5(J9GmPX36LgHslyB#Yt4Hcu-8G6oxGxAG>#Kh`UFP7yA9yr!4vmj zYPenZP~!sW(Pj8d&YlXm;p0*xk)98I-{6<2;p_O@WBHG`beB-+0NDiyINwca=RzAF zq-{VJnoF(ui0Cjb05P!(93M0Rh>mrDG%#EU^f5#NEzjh{m$TO9_CCf* zZkGBeb>-wEkH^x}mBz)URRdrIzeRm7=>ub(S>Hz~eP5k-1oqeR{@QZ|gY&WAPiQc= z_bv`FH01kIiskqy52*lj4PEG)=<=ZM+fa+HnZp>XeMGn!07fU7H+m4|??mnl$dD4L zkq&XYj!UiSzKw`rxbV2w1;iEolwpI?@2h_`xSk3%6IgTQf4HyTAP4WsnIII zz!-1Wyl70YG3c~*IN+=4;tX{`L=`84Sj@8VVL9Xoc54XE_e>5GD)gl~l3*|HE0+JoFq*B zEa(VRzHAt`_$nB|PjmNRE?t;vA~8$K_fHTEe7F+Sl+y6=6wff`($!g#u(9&qlWZ{E zd+bdEj5*m~(X~!e(hR1CnD%-7i!m6tzn5q(8Qv1{& z?C0cHJ84|wx6&Yp~?PG?JIFzZY9x&+63=U?h`ZV%{d7_f+%Xp^%HM@-kz2cFVbrqkv-TWY>d@KhK%PC_O62qxdbSVBDej06f>l4f(~)CmX^BnTl=whs5T?r~tCw`&<_< zmOB zd5x_QuB()UP88dz_NcG)v+xTYK5vp(X@45c+sl2$`|)T z;pxWb?A;P=k)#f-y=o;XdK zg4^v)SSdly&uv+t3yFR67h}n%4PE6L8`DM651>_ciaAkx3S|q8*sEsLI zc;01yCVFC9)-(l`iC1yL$J(@R+eHXi1VRC=5De_15VjLC+s8V;7Evl9yFDX`KN9m6 zP358^w$*{=pi+UCv387itYeX@8q_KVC7`WlBsLBcF=6&W6vVc=&=OPv5Iz;78IM*e z8tdA&O`u=323-s(KxAUujTCEJ{b-xO6anM_5sPj0q6{4U4I~QPa%EcBu5CG>8)D@bkO#0?+m^ti{4|sI-5nAER%=^c=!J!{12O^4 zYulj!Pt^y@Wd)=MdDW@fJ1Vw@LMCXLy8OmgeJuBXt-+v zrtt}KX##26DMl4h14|n%6&(OODLdcwOk#g+%P*s`(E$Sk5eoI1Ww$+;%~99nmdSHyySC+;vB-oZ=pTqpY+r|)@r#d$5Gqqi6|l5X(Xqqe zx5tJ{s`nv;L?~VYxtSvSFk`#078u%~R!SP^jatX1*T_1pUT2B%ZNF@l4txhW z@NQ2)jN0o|f|8)cAxA*=B+NYkS3zk|GeDLw zHXB_(Jb?NjDtpR?ngG%S3{7%m0swA;@}Wk6L;-yfAGrYV5>yQNL#lwT2+Je@A3^2N zv5+jFE$DQBhoEYxb|76qlhFHs{y_~;%|Luo9@!l@Nqk<_TjBZnApH!`JE#S!9tcpX z2aVIjrx*cm_!`fugc<|TH>d+zL5Nz-YbRu?Axn5J$^XB&StR~7u9X3`2B2qfBUOeN zwVJn%P1-BVY0+s;tN;9(3440669N5#d#NHssnxvNlvazf1ZO2FWiPL>Uo&I5b4Bj} zdIeFaJcOy$yesU3h31i0HKwJnnX}AEn!y3|3HGD15U5u3RyPxNEz0_bxE!-Y9a`IC zJZ6%SIU{XG2hbyE7CK$1TFtxSUb`ByPJ7p%1+?#5o*#a?$&+6*Z38oDHUQ8epn0PT zR;zjI*kn5)^O_UOBS%0xsJYdytJC@{gkhEzgu2Xfb>W5d?!{51kJY@62+GCGX^X%V ziS^ZW3#7vJWM~Q6kTEYRXSuQy$QzU`2-*H`4$ZOv;2@AUU^n`lQ5+vt5y%?w zG9Af`u8D;_005PNbiqywLPqSOoaIVGAY;I?5m}oFJ+n~u0D#6oqF}cLA&XhAzRVf` zU=YX>?6)A)KFd|2WR7)~D@K7-0Yj5K88bc_@p)!W#Vl8P1wI~`aSif6{c|p8V-PNx zW>f$`zhE1WAz00$N*nQxFXz*9S}L-D{;!wpS`fxaiPc5~0CWuE;yaJ)u$rg0WfQ%G zADOlN(5v=gEmbwIEvOVU%yN|)|5VI!rDt#z(Vjns@)8b-#v#+w^lAMHCw8&L(XkvYM)zS0xlh4eQOBBm)3T=^Vrgk@e1X zTg_t{ECyTVljT#@JSHs&$0Ktd=m+RuyZHJk?+n3eo>G4q$#Xw*wdGUQJT@%|v*t@4 zX1Q`F$6{oySHG)2{x<@vc}m0oOy_)wW4vASq7_xuygZ1D-f%d}RnKs7|Ei6IBuY0T zw{B?wR`af$WB838_gX$x&12GnFc;!r7as0Ygosih2VQP~$ZkWhn)imuM|v>j%Z3mj zte>jpv1mbf$ogHw#W5Aj+jIF=^EguhhW=IRGznK$RaNr_CULUHmV5}$iKfG9-dO{6 z&f&Ol&5KG|R#naWscj3w%}(tI(_uC5tXBwNX8c;}qm;6)s+xDjuZuxB%T;^mdZe;L z4($OOjKpeQ_qn97-j5DZESCkA)x4IVasY}X5N)CJj|>qJ`Tj0LqF2c59{~noHSe3%3rJ+0fR|c>X$QLz z53^kPhs008sUBF6Csy-HgQ!_J_~2_{uDPsq09*`8DWS;))FhS`ggP@K)srlgI592w zL#j|7)F_G;gnDw;3_*!N$@I#yMD#MG3KgOJ|Cj>_(I2|e2pK{5)WtXe89=Wt3#r0i zs2*VD1xpJ;ea`#cD{d%1BHQ$yH~>%Pm!yoMyJy zf-rt^hA~^$%)FE(P2-@)piJR82eVwA^&L~^5Nj91V&9d3gKK8vflT2oTETG(LS{5U zrUW1rYQu5+Ynj50^cNK^2rGfj7EQCCKnp|#AaC%eiUFX*G=fp{f=-y7QA0w3V>Qq4 z*pZ^CZ9%AwF*xW`$_#eXiwhj9c}54Rp5>}cG+hIY8Gn1nViz-P5hHS}<{2E#LU$=X zBBs*_zUHPBd2VYkERkb1&)8U;N#}JVT>R0x<(LF$#{R5q#kfXV5EAz^p`&)jUJvMZZE}*n$w3EODOS z3@rP93LvX_2G`^)6q_+g6i`NG6rm$e1qP*lOB zlnX0E9#vPw!Xd0$5a!Qj6bEI~FOW#J_H6$H6UOKBNhx6(1X8Jf`tHMEL7&{Ue$2wS zjy@N67?KC--bs*enY`A+^h`Aj2T&o@EW!>W@<81;iL&T;Xl6K8ND|7CmVu(K+c&DH z!+< z@pzz)@w**P(Kc1!1#v(H(FqPem=`kO`VU1MhU0;H82*_$!=mZxFzili-S#V0AFZVY zp?Je^JW!87TBO8~XxkY>wp^?F#Gn&)7j77i2kMokNsd8*TDs=xphV;!4z~n!)Phj3 zVK^SB*L&p|A5A-B&^R{kRP+x)gGuPuHf!cgs&bYqpK^&C`l3UixtfBmlsII~mwljq zXAEoxdHe&_g0vxf;-weV?2Mr%=B1O_S--fAqDUHc_w4~SJ7WmJcO}4dw6g7}Riq4g zu;*EDMB`)%rAqCv_AENXVx1yk_~UuEINTXSe9!_KcE+x)1)+3d+0eY_aAyn&u&GW{ z8ZY|H#*&3eg3~_scgAo%Wk!=guUhGz9Y#Z{@N{6NvcEHiP`thibgYZkx?QGVcb2Qy z7Nr!KS?_w3QyArZlwk>?}3_;L+>*=Tx@2!>Xnk&#;+*40X)@z z>2t@3dJohIL>Kd3)Ici{Jz*VVgK`7uoP;(A4LuF76ob&+YO6!2bx{jjS ze?qi-pyoZGavs&3my{Od`xvkN$~Lp#f>6MFpyoYH9GL%p8}8qr444>PmHHNhLf!*4 z@8Nhns+t|*`gHcZxE(lV9QHZpLuD-HJy3`FcyOJz&P%RTG;3)=DC#{>^B*Qo^e;{V zZ7m2zzX$3hqGNj28sEWL;V2l0eGk+OX{N>z0nUTAp?`>e57a(}1Mfjhx>90v8{|It z1I;Wi;6JDeiXts=f}l+3J6VA<1T%cpDUt%G2=e66-jEZp4|HomC?#MLMAe^_?pf_z z8G(}oPpoyjjDTgJdkaDdfzt%<`4x?Pza@Z7R5AkT`pufI;5E8Z9AUnKKhVs= z2on~3O*@Jr%vf*%eJ6-8H-YvRgd-q$FlWK#zP+M!0VQ}aLxF}Cgl_T?JD8+EZ3{ww z@)tXpwV(^W%nINcdRXjW+JZYGv4DptGzQ>-y63Wbdc#7l{00UQHHn&QKRgs|=VevJ7Atj_wjf0)5Jcox072AKiz;w0fX^@DdGk`kAtzMHVlRD@a*M5cJg%e{#@Ic+PDjd3DlmI6EHB@q12Wobq zVr2o2JW%huZ^!@x@IYO4=oP^LV*2M5*-B>XK%J0@UHI}qok}dSu9vRg19hd*nOTys zpXJJLVA^NcX%;TCb)W|NTsgorc%bH$f_l0aE3{lBuXUjI;3$a{U@kmRGw%*vA)|Gm zrsV@HiJvl4dK5%f>p<-zy0WlfHat+bsU91&?AH*~))!%IjIX^yQtLoX%W`D3RuYTH=+r|9Jb4xBtW#02MKwtpET3 literal 0 HcmV?d00001 -- GitLab From f57c2d8708dae3b8e9716a06c6828e102bf5d662 Mon Sep 17 00:00:00 2001 From: Bo Ding Date: Wed, 13 Jul 2022 13:14:01 +0800 Subject: [PATCH 140/380] Update 05-high-volume.md --- docs/zh/07-develop/03-insert-data/05-high-volume.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh/07-develop/03-insert-data/05-high-volume.md b/docs/zh/07-develop/03-insert-data/05-high-volume.md index 731cf2c188..ed8b137358 100644 --- a/docs/zh/07-develop/03-insert-data/05-high-volume.md +++ b/docs/zh/07-develop/03-insert-data/05-high-volume.md @@ -268,7 +268,7 @@ main 函数可以接收 5 个启动参数,依次是: ### SQLWriter 类的实现 {#python-sql-writer} -SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提前创建,而是写入出错的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。这个类也对 SQL 是否超过最大长度限制做了检查,如果接近 SQL 最大长度限制(maxSQLLength),将会立即执行 SQL。为了减少 SQL 此时,建议将 maxSQLLength 适当调大。 +SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提前创建,而是写入出错的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。这个类也对 SQL 是否超过最大长度限制做了检查,如果接近 SQL 最大长度限制(maxSQLLength),将会立即执行 SQL。为了减少 SQL 执行次数,建议将 maxSQLLength 适当调大。
@@ -338,4 +338,4 @@ SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提 2022-07-13 10:07:24,877 [DataBaseMonitor] - count=73654566 speed=880582.7 ``` -
\ No newline at end of file + -- GitLab From 7b72757e015c5050df28572f7d0017cc1cc582c9 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 13 Jul 2022 14:59:23 +0800 Subject: [PATCH 141/380] test: fix tools/taosdumpTest3.py (#14848) --- tests/pytest/tools/taosdumpTest.py | 7 +++++++ tests/pytest/tools/taosdumpTest3.py | 3 +++ 2 files changed, 10 insertions(+) diff --git a/tests/pytest/tools/taosdumpTest.py b/tests/pytest/tools/taosdumpTest.py index 2155556776..95ed69b917 100644 --- a/tests/pytest/tools/taosdumpTest.py +++ b/tests/pytest/tools/taosdumpTest.py @@ -60,6 +60,13 @@ class TDTestCase: else: print("directory exists") + for i in range(1, 9): + if not os.path.exists("./taosdumptest/tmp%d" % i): + os.makedirs("./taosdumptest/tmp%d" % i) + else: + os.system("rm -rf ./taosdumptest/tmp%d" % i) + os.makedirs("./taosdumptest/tmp%d" % i) + if not os.path.exists("./taosdumptest/tmp2"): os.makedirs("./taosdumptest/tmp2") tdSql.execute("drop database if exists db") diff --git a/tests/pytest/tools/taosdumpTest3.py b/tests/pytest/tools/taosdumpTest3.py index 3994ad0323..e8fb46f3a8 100644 --- a/tests/pytest/tools/taosdumpTest3.py +++ b/tests/pytest/tools/taosdumpTest3.py @@ -57,6 +57,9 @@ class TDTestCase: def run(self): if not os.path.exists("./taosdumptest"): os.makedirs("./taosdumptest") + else: + print("directory exists") + for i in range(1, 9): if not os.path.exists("./taosdumptest/tmp%d" % i): os.makedirs("./taosdumptest/tmp%d" % i) -- GitLab From a8bbf3423f81f3403929c1ce44441c826bdb95fa Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 13 Jul 2022 18:08:08 +0800 Subject: [PATCH 142/380] fix(rpc): probe connection already alive --- src/client/inc/tsclient.h | 3 ++ src/client/src/tscServer.c | 70 +++++++++++++++++++++++++++++++ src/dnode/inc/dnodeVRead.h | 2 + src/dnode/src/dnodeShell.c | 2 + src/dnode/src/dnodeVRead.c | 7 ++++ src/inc/taosmsg.h | 3 ++ src/inc/trpc.h | 1 + src/rpc/inc/rpcTcp.h | 2 + src/rpc/src/rpcMain.c | 84 +++++++++++++++++++++++++++++++++++++- src/rpc/src/rpcTcp.c | 9 ++++ 10 files changed, 181 insertions(+), 2 deletions(-) diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 2ada7b32e8..f26739a337 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -397,6 +397,9 @@ typedef struct SSqlObj { int32_t retryReason; // previous error code struct SSqlObj *prev, *next; int64_t self; + // connect alive + int64_t lastUpdate; + char noAckCnt; // no recevie ack from sever count } SSqlObj; typedef struct SSqlStream { diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index e42f73fb32..9e49c09550 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -281,6 +281,52 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { } } +// pSql connection link is broken +bool dealConnBroken(SSqlObj * pSql) { + return true; +} + +// if return true, send probe connection msg to sever ok +bool sendProbeConnMsg(SSqlObj* pSql) { + pSql->noAckCnt++; + tscDebug("0x%"PRIx64" sendProbeConnMsg noAckCnt:%d", pSql->self, pSql->noAckCnt); + + // send + pSql->rpcRid + + + + + return true; +} + +// check have broken link queries than killed +void checkBrokenQueries(STscObj *pTscObj) { + // + SSqlObj *pSql = pTscObj->sqlList; + while (pSql) { + int32_t numOfSub = pSql->subState.numOfSub; + if (numOfSub == 0) { + // no sub sql + if(!sendProbeConnMsg(pSql)) { + // send failed , connect already broken + dealConnBroken(pSql); + } + + return ; + } + + // have sub sql + for (int i = 0; i < numOfSub; i++) { + SSqlObj *pSubSql = pSql->pSubs[i]; + if(!sendProbeConnMsg(pSubSql)) { + // send failed , connect already broken + dealConnBroken(pSubSql); + } + } + } +} + void tscProcessActivityTimer(void *handle, void *tmrId) { int64_t rid = (int64_t) handle; STscObj *pObj = taosAcquireRef(tscRefId, rid); @@ -296,6 +342,20 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { assert(pHB->self == pObj->hbrid); + // check queries already death + static int activetyTimerCnt = 0; + if (++activetyTimerCnt > 10) { // 1.5s * 10 = 15s interval call + activetyTimerCnt = 0; + + // call check if have query doing + if(pObj->sqlList && pObj->sqlList->next) { + // have queries executing + checkBrokenQueies(); + } + } + + + // send self connetion and queries pHB->retry = 0; int32_t code = tscBuildAndSendRequest(pHB, NULL); taosReleaseRef(tscObjRef, pObj->hbrid); @@ -417,6 +477,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; + + pSql->rpcRid = -1; if (pObj->signature != pObj) { tscDebug("0x%"PRIx64" DB connection is closed, cmd:%d pObj:%p signature:%p", pSql->self, pCmd->command, pObj, pObj->signature); @@ -427,6 +489,14 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { return; } + // check msgtype + if(rpcMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { + pSql->noAckCnt = 0; + pSql->lastUpdate = taosGetTimestampMs(); + tscInfo(" recv sql probe msg. sql=%s", pSql->sqlstr); + return ; + } + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); if (pQueryInfo != NULL && pQueryInfo->type == TSDB_QUERY_TYPE_FREE_RESOURCE) { tscDebug("0x%"PRIx64" sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p", diff --git a/src/dnode/inc/dnodeVRead.h b/src/dnode/inc/dnodeVRead.h index 9c88886f88..9171026f21 100644 --- a/src/dnode/inc/dnodeVRead.h +++ b/src/dnode/inc/dnodeVRead.h @@ -29,6 +29,8 @@ void * dnodeAllocVFetchQueue(void *pVnode); void dnodeFreeVQueryQueue(void *pQqueue); void dnodeFreeVFetchQueue(void *pFqueue); + + #ifdef __cplusplus } #endif diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c index 7676343b37..bea325c053 100644 --- a/src/dnode/src/dnodeShell.c +++ b/src/dnode/src/dnodeShell.c @@ -78,6 +78,8 @@ int32_t dnodeInitShell() { dnodeProcessShellMsgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dnodeSendStartupStep; + dnodeProcessShellMsgFp[TSDB_MSG_TYPE_PROBE_CONN] = dnodeDispatchToVReadQueue; + int32_t numOfThreads = (int32_t)((tsNumOfCores * tsNumOfThreadsPerCore) / 2.0); if (numOfThreads < 1) { numOfThreads = 1; diff --git a/src/dnode/src/dnodeVRead.c b/src/dnode/src/dnodeVRead.c index c404ab1a55..8eab67209a 100644 --- a/src/dnode/src/dnodeVRead.c +++ b/src/dnode/src/dnodeVRead.c @@ -57,6 +57,13 @@ void dnodeDispatchToVReadQueue(SRpcMsg *pMsg) { int32_t code = TSDB_CODE_VND_INVALID_VGROUP_ID; char * pCont = pMsg->pCont; + // check probe conn msg + if(pMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN) { + SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = 0, .msgType = TSDB_MSG_TYPE_PROBE_CONN_RSP}; + rpcSendResponse(&rpcRsp); + return ; + } + while (leftLen > 0) { SMsgHead *pHead = (SMsgHead *)pCont; pHead->vgId = htonl(pHead->vgId); diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index 1a8907efab..280747afed 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -123,6 +123,9 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_TP, "alter-tp" ) // delete TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DELDATA, "delete-data" ) +// syn -> ack probe connection msg +TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_PROBE_CONN, "probe-connection-alive" ) + #ifndef TAOS_MESSAGE_C TSDB_MSG_TYPE_MAX // 105 diff --git a/src/inc/trpc.h b/src/inc/trpc.h index 5e3fbd571e..c23959a0cc 100644 --- a/src/inc/trpc.h +++ b/src/inc/trpc.h @@ -94,6 +94,7 @@ int rpcReportProgress(void *pConn, char *pCont, int contLen); void rpcCancelRequest(int64_t rid); int32_t rpcUnusedSession(void * rpcInfo, bool bLock); + #ifdef __cplusplus } #endif diff --git a/src/rpc/inc/rpcTcp.h b/src/rpc/inc/rpcTcp.h index 6ef8fc2d92..20ebec4fec 100644 --- a/src/rpc/inc/rpcTcp.h +++ b/src/rpc/inc/rpcTcp.h @@ -32,6 +32,8 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin void taosCloseTcpConnection(void *chandle); int taosSendTcpData(uint32_t ip, uint16_t port, void *data, int len, void *chandle); +int32_t taosGetFdID(void *chandle); + #ifdef __cplusplus } #endif diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 95931fcbc6..3203dc4a73 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -196,7 +196,7 @@ static SRpcConn *rpcGetConnObj(SRpcInfo *pRpc, int sid, SRecvInfo *pRecv); static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext); static void rpcSendQuickRsp(SRpcConn *pConn, int32_t code); static void rpcSendErrorMsgToPeer(SRecvInfo *pRecv, int32_t code); -static void rpcSendMsgToPeer(SRpcConn *pConn, void *data, int dataLen); +static bool rpcSendMsgToPeer(SRpcConn *pConn, void *data, int dataLen); static void rpcSendReqHead(SRpcConn *pConn); static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv); @@ -1349,9 +1349,10 @@ static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { rpcUnlockConn(pConn); } -static void rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) { +static bool rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) { int writtenLen = 0; SRpcHead *pHead = (SRpcHead *)msg; + bool ret = true; msgLen = rpcAddAuthPart(pConn, msg, msgLen); @@ -1371,9 +1372,11 @@ static void rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) { if (writtenLen != msgLen) { tError("%s, failed to send, msgLen:%d written:%d, reason:%s", pConn->info, msgLen, writtenLen, strerror(errno)); + ret = false; } tDump(msg, msgLen); + return ret; } static void rpcProcessConnError(void *param, void *id) { @@ -1683,4 +1686,81 @@ int32_t rpcUnusedSession(void * rpcInfo, bool bLock) { if(info == NULL) return 0; return taosIdPoolNumOfFree(info->idPool, bLock); +} + + +static void doRpcSendProbe(SRpcConn *pConn) { + char msg[RPC_MSG_OVERHEAD]; + SRpcHead *pHead; + + // set msg header + memset(msg, 0, sizeof(SRpcHead)); + pHead = (SRpcHead *)msg; + pHead->version = 1; + pHead->msgType = TSDB_MSG_TYPE_PROBE_CONN; + pHead->spi = pConn->spi; + pHead->encrypt = 0; + pHead->tranId = pConn->inTranId; + pHead->sourceId = pConn->ownId; + pHead->destId = pConn->peerId; + pHead->linkUid = pConn->linkUid; + pHead->ahandle = (uint64_t)pConn->ahandle; + memcpy(pHead->user, pConn->user, tListLen(pHead->user)); + pHead->code = htonl(code); + + rpcSendMsgToPeer(pConn, msg, sizeof(SRpcHead)); + pConn->secured = 1; // connection shall be secured +} + +// send server syn +bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPrevFdObj, int32_t prevFd) { + bool ret = false; + if(rpcRid < 0) { + tError("ACK rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); + return false; + } + + // get req content + SRpcReqContext *pContext = taosAcquireRef(tsRpcRefId, rpcRid); + if (pContext == NULL) { + tError("ACK rpcRid=%" PRId64 " get context NULL.", rpcRid); + return false; + } + + // context same + if(pContext != pPrevContext) { + tError("ACK rpcRid=%" PRId64 " context diff. pContext=%p pPreContent=%p", rpcRid, pContext, pPrevContext); + goto _END; + } + + // conn same + if (pContext->pConn != pPrevConn) { + tError("ACK rpcRid=%" PRId64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pPrevConn); + goto _END; + } + + // fdObj same + if (pContext->pConn->chandle != pPrevFdObj) { + tError("ACK rpcRid=%" PRId64 " connect fdObj diff. pContext->pConn->chandle=%p pPrevFdObj=%p", rpcRid, pContext->pConn->chandle, pPrevFdObj); + goto _END; + } + + // fd same + int32_t fd = taosGetFdID(pContext->pConn->chandle); + if (fd != prevFd) { + tError("ACK rpcRid=%" PRId64 " connect fd diff.fd=%d prevFd=%p", rpcRid, fd, prevFd); + goto _END; + } + + // send syn + ret = doRpcSendProbe(pContext->pConn); + +_END: + // put back req context + taosReleaseRef(tsRpcRefId, rpcRid); + return ret; +} + +bool saveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd) { + } \ No newline at end of file diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index 740a1e2b7d..001c50ee5d 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -674,3 +674,12 @@ static void taosFreeFdObj(SFdObj *pFdObj) { tfree(pFdObj); } + +int32_t taosGetFdID(void *chandle) { + SFdObj * pFdObj = chandle; + if(pFdObj == NULL) + return -1; + if (pFdObj->signature != pFdObj) + return -1; + return pFdObj->fd; +} \ No newline at end of file -- GitLab From 44b031b2fc4662e95f09042809252cce7671087b Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 13 Jul 2022 19:16:17 +0800 Subject: [PATCH 143/380] fix(rpc): build error --- src/rpc/src/rpcMain.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 3203dc4a73..fbb5c328f9 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1688,10 +1688,10 @@ int32_t rpcUnusedSession(void * rpcInfo, bool bLock) { return taosIdPoolNumOfFree(info->idPool, bLock); } - -static void doRpcSendProbe(SRpcConn *pConn) { +bool doRpcSendProbe(SRpcConn *pConn) { char msg[RPC_MSG_OVERHEAD]; SRpcHead *pHead; + int code = 0; // set msg header memset(msg, 0, sizeof(SRpcHead)); @@ -1708,8 +1708,10 @@ static void doRpcSendProbe(SRpcConn *pConn) { memcpy(pHead->user, pConn->user, tListLen(pHead->user)); pHead->code = htonl(code); - rpcSendMsgToPeer(pConn, msg, sizeof(SRpcHead)); + bool ret = rpcSendMsgToPeer(pConn, msg, sizeof(SRpcHead)); pConn->secured = 1; // connection shall be secured + + return ret; } // send server syn @@ -1748,7 +1750,7 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPr // fd same int32_t fd = taosGetFdID(pContext->pConn->chandle); if (fd != prevFd) { - tError("ACK rpcRid=%" PRId64 " connect fd diff.fd=%d prevFd=%p", rpcRid, fd, prevFd); + tError("ACK rpcRid=%" PRId64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, prevFd); goto _END; } @@ -1761,6 +1763,7 @@ _END: return ret; } -bool saveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd) { -} \ No newline at end of file +bool saveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd) { + return true; +} -- GitLab From f7fcd05af4dfcbba224703fcf1bcb4e68ffb2fd6 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Wed, 13 Jul 2022 18:26:25 +0800 Subject: [PATCH 144/380] fix: remove redundant -I header dir from makefile of examples/c --- examples/c/makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/c/makefile b/examples/c/makefile index 4d6cfc1f5f..6f0ab8880a 100644 --- a/examples/c/makefile +++ b/examples/c/makefile @@ -7,7 +7,6 @@ LFLAGS = '-Wl,-rpath,/usr/local/taos/driver/' -ltaos -lpthread -lm -lrt CFLAGS = -O3 -g -Wall -Wno-deprecated -fPIC -Wno-unused-result -Wconversion \ -Wno-char-subscripts -D_REENTRANT -Wno-format -D_REENTRANT -DLINUX \ -Wno-unused-function -D_M_X64 -I/usr/local/taos/include -std=gnu99 \ - -I../../../deps/cJson/inc \ -Wno-unused-function -D_M_X64 -I/usr/local/taos/include -std=gnu99 \ -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment -- GitLab From e22afede4e54553cff85cd634d1a133f7a62569e Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Wed, 13 Jul 2022 19:13:39 +0800 Subject: [PATCH 145/380] fix: resolve memory leak on select interp... where range... --- src/query/inc/qSqlparser.h | 6 ++++-- src/query/src/qSqlParser.c | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/query/inc/qSqlparser.h b/src/query/inc/qSqlparser.h index 8091a300b3..2a75d4d992 100644 --- a/src/query/inc/qSqlparser.h +++ b/src/query/inc/qSqlparser.h @@ -97,9 +97,11 @@ typedef struct SIntervalVal { SStrToken offset; } SIntervalVal; +typedef struct tSqlExpr tSqlExprTimestamp; + typedef struct SRangeVal { - void *start; - void *end; + tSqlExprTimestamp *start; + tSqlExprTimestamp *end; } SRangeVal; typedef struct SSessionWindowVal { diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index 28cc1c10a2..fe459ee460 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -1183,6 +1183,10 @@ void destroySqlNode(SSqlNode *pSqlNode) { pSqlNode->fillType = NULL; tSqlExprDestroy(pSqlNode->pHaving); + + tSqlExprDestroy(pSqlNode->pRange.start); + tSqlExprDestroy(pSqlNode->pRange.end); + free(pSqlNode); } -- GitLab From c172979ae458db5aacdc3ca92f0f0472e59ac671 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 13 Jul 2022 20:52:48 +0800 Subject: [PATCH 146/380] fix(query): check probe in timer --- src/client/inc/tsclient.h | 8 ++++++- src/client/src/tscServer.c | 44 ++++++++++++++++++++++++++++---------- src/inc/trpc.h | 7 ++++-- src/rpc/src/rpcMain.c | 38 +++++++++++++++++++++++++------- 4 files changed, 75 insertions(+), 22 deletions(-) diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index f26739a337..a8d5cff1d6 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -397,9 +397,15 @@ typedef struct SSqlObj { int32_t retryReason; // previous error code struct SSqlObj *prev, *next; int64_t self; + // connect alive - int64_t lastUpdate; + int64_t lastProbe; + int64_t lastAlive; char noAckCnt; // no recevie ack from sever count + void * pPrevContext; + void * pPrevConn; + void * pPrevFdObj; + int32_t prevFd; } SSqlObj; typedef struct SSqlStream { diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 9e49c09550..3ef3b0db23 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -283,21 +283,40 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { // pSql connection link is broken bool dealConnBroken(SSqlObj * pSql) { + // TODO + return true; } // if return true, send probe connection msg to sever ok bool sendProbeConnMsg(SSqlObj* pSql) { - pSql->noAckCnt++; - tscDebug("0x%"PRIx64" sendProbeConnMsg noAckCnt:%d", pSql->self, pSql->noAckCnt); + // check time out + int32_t probeTimeout = 60*1000; // over this value send probe msg + int32_t killTimeout = 3*60*1000; // over this value query can be killed + int64_t stime = MAX(pSql->stime, pSql->lastAlive); + int32_t diff = (int32_t)(taosGetTimestampMs() - stime); + if (diff < probeTimeout) { + // exec time short , need not probe alive + return true; + } - // send - pSql->rpcRid + if (diff > killTimeout) { + // need kill query + tscDebug("PROBE 0x%"PRIx64" need killed, noAckCnt:%d diff=%d", pSql->self, pSql->noAckCnt, diff); + return false; + } - - + if (pSql->pPrevContext == NULL || pSql->pPrevConn == NULL || pSql->pPrevFdObj == NULL || pSql->prevFd <= 0) { + // last connect info save uncompletely, so can't probe + return true; + } - return true; + // It's long time from lastAlive, so need probe + pSql->noAckCnt++; + pSql->lastProbe = taosGetTimestampMs(); + tscDebug("0x%"PRIx64" sendProbeConnMsg noAckCnt:%d diff=%d", pSql->self, pSql->noAckCnt, diff); + + return rpcSendProbe(pSql->rpcRid, pSql->pPrevContext, pSql->pPrevConn, pSql->pPrevFdObj, pSql->prevFd); } // check have broken link queries than killed @@ -350,11 +369,10 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { // call check if have query doing if(pObj->sqlList && pObj->sqlList->next) { // have queries executing - checkBrokenQueies(); + checkBrokenQueies(pObj); } } - // send self connetion and queries pHB->retry = 0; int32_t code = tscBuildAndSendRequest(pHB, NULL); @@ -398,8 +416,12 @@ int tscSendMsgToServer(SSqlObj *pSql) { return TSDB_CODE_FAILED; } - rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid); - return TSDB_CODE_SUCCESS; + if(rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid)) { + saveSendInfo(pSql->rpcRid, &pSql->pPrevContext, &pSql->pPrevConn, &pSql->pPrevFdObj, &pSql->prevFd); + return TSDB_CODE_SUCCESS; + } + + return TSDB_CODE_FAILED; } // handle three situation diff --git a/src/inc/trpc.h b/src/inc/trpc.h index c23959a0cc..95b84d66eb 100644 --- a/src/inc/trpc.h +++ b/src/inc/trpc.h @@ -85,7 +85,7 @@ void rpcClose(void *); void *rpcMallocCont(int contLen); void rpcFreeCont(void *pCont); void *rpcReallocCont(void *ptr, int contLen); -void rpcSendRequest(void *thandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *rid); +bool rpcSendRequest(void *thandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *rid); void rpcSendResponse(const SRpcMsg *pMsg); void rpcSendRedirectRsp(void *pConn, const SRpcEpSet *pEpSet); int rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo); @@ -93,7 +93,10 @@ void rpcSendRecv(void *shandle, SRpcEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp int rpcReportProgress(void *pConn, char *pCont, int contLen); void rpcCancelRequest(int64_t rid); int32_t rpcUnusedSession(void * rpcInfo, bool bLock); - +// send rpc Refid connection probe alive message +bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPrevFdObj, int32_t prevFd); +// after sql request send , save conn info +bool saveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd); #ifdef __cplusplus } diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index fbb5c328f9..801f745dbe 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -193,7 +193,7 @@ static SRpcConn *rpcAllocateClientConn(SRpcInfo *pRpc); static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, SRecvInfo *pRecv); static SRpcConn *rpcGetConnObj(SRpcInfo *pRpc, int sid, SRecvInfo *pRecv); -static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext); +static bool rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext); static void rpcSendQuickRsp(SRpcConn *pConn, int32_t code); static void rpcSendErrorMsgToPeer(SRecvInfo *pRecv, int32_t code); static bool rpcSendMsgToPeer(SRpcConn *pConn, void *data, int dataLen); @@ -385,7 +385,7 @@ void *rpcReallocCont(void *ptr, int contLen) { return start + sizeof(SRpcReqContext) + sizeof(SRpcHead); } -void rpcSendRequest(void *shandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *pRid) { +bool rpcSendRequest(void *shandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *pRid) { SRpcInfo *pRpc = (SRpcInfo *)shandle; SRpcReqContext *pContext; @@ -415,7 +415,7 @@ void rpcSendRequest(void *shandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64 pContext->rid = taosAddRef(tsRpcRefId, pContext); if (pRid) *pRid = pContext->rid; - rpcSendReqToServer(pRpc, pContext); + return rpcSendReqToServer(pRpc, pContext); } void rpcSendResponse(const SRpcMsg *pRsp) { @@ -1302,7 +1302,7 @@ static void rpcSendErrorMsgToPeer(SRecvInfo *pRecv, int32_t code) { return; } -static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { +static bool rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { SRpcHead *pHead = rpcHeadFromCont(pContext->pCont); char *msg = (char *)pHead; int msgLen = rpcMsgLenFromCont(pContext->contLen); @@ -1313,7 +1313,7 @@ static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { if (pConn == NULL) { pContext->code = terrno; taosTmrStart(rpcProcessConnError, 1, pContext, pRpc->tmrCtrl); - return; + return false; } pContext->pConn = pConn; @@ -1342,11 +1342,12 @@ static void rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { pConn->reqMsgLen = msgLen; pConn->pContext = pContext; - rpcSendMsgToPeer(pConn, msg, msgLen); + bool ret = rpcSendMsgToPeer(pConn, msg, msgLen); if (pConn->connType != RPC_CONN_TCPC) taosTmrReset(rpcProcessRetryTimer, tsRpcTimer, pConn, pRpc->tmrCtrl, &pConn->pTimer); rpcUnlockConn(pConn); + return ret; } static bool rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) { @@ -1763,7 +1764,28 @@ _END: return ret; } - +// after sql request send , save conn info bool saveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd) { - return true; + if(rpcRid < 0) { + tError("ACK saveSendInfo rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); + return false; + } + // get req content + SRpcReqContext *pContext = taosAcquireRef(tsRpcRefId, rpcRid); + if (pContext == NULL) { + tError("ACK rpcRid=%" PRId64 " get context NULL.", rpcRid); + return false; + } + + if (ppContext) + *ppContext = pContext; + if (ppConn) + *ppConn = pContext->pConn; + if (ppFdObj) + *ppFdObj = pContext->pConn->chandle; + if (pFd) + *pFd = taosGetFdID(pContext->pConn->chandle); + + taosReleaseRef(tsRpcRefId, rpcRid); + return true; } -- GitLab From 8b693ada80260fb7ebb6b19ea8b3691a6de43ce2 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 13 Jul 2022 20:56:10 +0800 Subject: [PATCH 147/380] fix(query): check probe in timer1 --- src/client/src/tscServer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 3ef3b0db23..0e256e7bc3 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -369,7 +369,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { // call check if have query doing if(pObj->sqlList && pObj->sqlList->next) { // have queries executing - checkBrokenQueies(pObj); + checkBrokenQueries(pObj); } } -- GitLab From 3601b77e523c3485696f1dc49d9b21007d6ce4fb Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 13 Jul 2022 20:56:58 +0800 Subject: [PATCH 148/380] fix(query): check probe in timer2 --- src/client/src/tscServer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 0e256e7bc3..1f4db1c03e 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -513,8 +513,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { // check msgtype if(rpcMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { - pSql->noAckCnt = 0; - pSql->lastUpdate = taosGetTimestampMs(); + pSql->noAckCnt = 0; + pSql->lastAlive = taosGetTimestampMs(); tscInfo(" recv sql probe msg. sql=%s", pSql->sqlstr); return ; } -- GitLab From b167ff81b739832a552d051fc8e3e07b81a3be81 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 14 Jul 2022 10:21:44 +0800 Subject: [PATCH 149/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 9cb71e3c4c..bd496f76b6 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 9cb71e3c4c0474553aa961cbe19795541c29b5c7 +Subproject commit bd496f76b64931c66da2f8b0f24143a98a881cde -- GitLab From 18b76d30edbe34e82c48168758383557e71b24a1 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 14 Jul 2022 11:03:24 +0800 Subject: [PATCH 150/380] feat: update taostools for2.6 (#14883) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 9cb71e3c4c..bd496f76b6 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 9cb71e3c4c0474553aa961cbe19795541c29b5c7 +Subproject commit bd496f76b64931c66da2f8b0f24143a98a881cde -- GitLab From 3c6158d443d7970ebfcdcea39f2d16fc83d70ce1 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 14 Jul 2022 13:53:03 +0800 Subject: [PATCH 151/380] fix(rpc): probe alive connection --- src/rpc/src/rpcMain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 801f745dbe..a950bea15c 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1781,9 +1781,9 @@ bool saveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdOb *ppContext = pContext; if (ppConn) *ppConn = pContext->pConn; - if (ppFdObj) + if (ppFdObj && pContext->pConn) *ppFdObj = pContext->pConn->chandle; - if (pFd) + if (pFd && pContext->pConn && pContext->pConn->chandle) *pFd = taosGetFdID(pContext->pConn->chandle); taosReleaseRef(tsRpcRefId, rpcRid); -- GitLab From 2652d782567d967d75141b77a43e8d7b558f0c55 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 14 Jul 2022 14:09:17 +0800 Subject: [PATCH 152/380] fix(rpc): send probe msg loop move next --- src/client/src/tscServer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 1f4db1c03e..79f8e94835 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -343,6 +343,9 @@ void checkBrokenQueries(STscObj *pTscObj) { dealConnBroken(pSubSql); } } + + // move next + pSql = pSql->next; } } @@ -363,11 +366,11 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { // check queries already death static int activetyTimerCnt = 0; - if (++activetyTimerCnt > 10) { // 1.5s * 10 = 15s interval call + if (++activetyTimerCnt > 5) { // 1.5s * 10 = 15s interval call activetyTimerCnt = 0; // call check if have query doing - if(pObj->sqlList && pObj->sqlList->next) { + if(pObj->sqlList) { // have queries executing checkBrokenQueries(pObj); } -- GitLab From 0775971fb43a9a9489ccdf862ccb838aa0a2f0b5 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 14 Jul 2022 14:50:21 +0800 Subject: [PATCH 153/380] fix(rpc): send probe check send condition --- src/client/src/tscServer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 79f8e94835..404b074f66 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -293,6 +293,11 @@ bool sendProbeConnMsg(SSqlObj* pSql) { // check time out int32_t probeTimeout = 60*1000; // over this value send probe msg int32_t killTimeout = 3*60*1000; // over this value query can be killed + if(pSql->stime == 0) { + // not start , no need probe + return true; + } + int64_t stime = MAX(pSql->stime, pSql->lastAlive); int32_t diff = (int32_t)(taosGetTimestampMs() - stime); if (diff < probeTimeout) { @@ -311,6 +316,11 @@ bool sendProbeConnMsg(SSqlObj* pSql) { return true; } + if(pSql->rpcRid == -1) { + // cancel or reponse ok from server, so need not probe + return true; + } + // It's long time from lastAlive, so need probe pSql->noAckCnt++; pSql->lastProbe = taosGetTimestampMs(); -- GitLab From 6ecc4abc8e3ddbe74e2125318e3174e4bcbe10c1 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 14 Jul 2022 17:29:29 +0800 Subject: [PATCH 154/380] fix(rpc): probe alive test --- src/client/src/tscServer.c | 5 +++-- src/dnode/inc/dnodeVRead.h | 2 ++ src/dnode/src/dnodeShell.c | 2 +- src/dnode/src/dnodeVRead.c | 16 +++++++++++++++- src/inc/trpc.h | 2 +- src/rpc/src/rpcMain.c | 3 ++- src/vnode/src/vnodeRead.c | 3 ++- 7 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 404b074f66..de57f62fbe 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -291,7 +291,7 @@ bool dealConnBroken(SSqlObj * pSql) { // if return true, send probe connection msg to sever ok bool sendProbeConnMsg(SSqlObj* pSql) { // check time out - int32_t probeTimeout = 60*1000; // over this value send probe msg + int32_t probeTimeout = 1*1000; // over this value send probe msg int32_t killTimeout = 3*60*1000; // over this value query can be killed if(pSql->stime == 0) { // not start , no need probe @@ -430,7 +430,8 @@ int tscSendMsgToServer(SSqlObj *pSql) { } if(rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid)) { - saveSendInfo(pSql->rpcRid, &pSql->pPrevContext, &pSql->pPrevConn, &pSql->pPrevFdObj, &pSql->prevFd); + if(pSql->cmd.command != TSDB_SQL_HB) + rpcSaveSendInfo(pSql->rpcRid, &pSql->pPrevContext, &pSql->pPrevConn, &pSql->pPrevFdObj, &pSql->prevFd); return TSDB_CODE_SUCCESS; } diff --git a/src/dnode/inc/dnodeVRead.h b/src/dnode/inc/dnodeVRead.h index 9171026f21..b467e93885 100644 --- a/src/dnode/inc/dnodeVRead.h +++ b/src/dnode/inc/dnodeVRead.h @@ -28,6 +28,8 @@ void * dnodeAllocVQueryQueue(void *pVnode); void * dnodeAllocVFetchQueue(void *pVnode); void dnodeFreeVQueryQueue(void *pQqueue); void dnodeFreeVFetchQueue(void *pFqueue); +// reponse probe connection msg +void dnodeResponseProbeMsg(SRpcMsg *pMsg); diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c index bea325c053..0f536a84cc 100644 --- a/src/dnode/src/dnodeShell.c +++ b/src/dnode/src/dnodeShell.c @@ -78,7 +78,7 @@ int32_t dnodeInitShell() { dnodeProcessShellMsgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dnodeSendStartupStep; - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_PROBE_CONN] = dnodeDispatchToVReadQueue; + dnodeProcessShellMsgFp[TSDB_MSG_TYPE_PROBE_CONN] = dnodeResponseProbeMsg; int32_t numOfThreads = (int32_t)((tsNumOfCores * tsNumOfThreadsPerCore) / 2.0); if (numOfThreads < 1) { diff --git a/src/dnode/src/dnodeVRead.c b/src/dnode/src/dnodeVRead.c index 8eab67209a..544961adfc 100644 --- a/src/dnode/src/dnodeVRead.c +++ b/src/dnode/src/dnodeVRead.c @@ -143,7 +143,11 @@ static void *dnodeProcessReadQueue(void *wparam) { int32_t code = vnodeProcessRead(pVnode, pRead); - if (qtype == TAOS_QTYPE_RPC && code != TSDB_CODE_QRY_NOT_READY) { + if(code == 9999) { + dInfo(" ******* doNotRsp Test **** msg:%p, app:%p type:%s will be processed in vquery queue, qtype:%d", pRead, pRead->rpcAhandle,taosMsg[pRead->msgType], qtype); + printf(" ******* doNotRsp Test **** msg:%p, app:%p type:%s will be processed in vquery queue, qtype:%d", pRead, pRead->rpcAhandle,taosMsg[pRead->msgType], qtype); + + } else if (qtype == TAOS_QTYPE_RPC && code != TSDB_CODE_QRY_NOT_READY) { dnodeSendRpcVReadRsp(pVnode, pRead, code); } else { if (code == TSDB_CODE_QRY_HAS_RSP) { @@ -159,3 +163,13 @@ static void *dnodeProcessReadQueue(void *wparam) { return NULL; } + +// reponse probe connection msg +void dnodeResponseProbeMsg(SRpcMsg *pMsg) { + // check probe conn msg + if(pMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN) { + SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = 0, .msgType = TSDB_MSG_TYPE_PROBE_CONN_RSP}; + rpcSendResponse(&rpcRsp); + return ; + } +} diff --git a/src/inc/trpc.h b/src/inc/trpc.h index 95b84d66eb..3e1edc2c0a 100644 --- a/src/inc/trpc.h +++ b/src/inc/trpc.h @@ -96,7 +96,7 @@ int32_t rpcUnusedSession(void * rpcInfo, bool bLock); // send rpc Refid connection probe alive message bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPrevFdObj, int32_t prevFd); // after sql request send , save conn info -bool saveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd); +bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd); #ifdef __cplusplus } diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index a950bea15c..a8cd533e36 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1698,6 +1698,7 @@ bool doRpcSendProbe(SRpcConn *pConn) { memset(msg, 0, sizeof(SRpcHead)); pHead = (SRpcHead *)msg; pHead->version = 1; + pHead->msgVer = htonl(tsVersion >> 8); pHead->msgType = TSDB_MSG_TYPE_PROBE_CONN; pHead->spi = pConn->spi; pHead->encrypt = 0; @@ -1765,7 +1766,7 @@ _END: } // after sql request send , save conn info -bool saveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd) { +bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd) { if(rpcRid < 0) { tError("ACK saveSendInfo rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); return false; diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index e8495cac6d..8f3c7a399a 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -339,8 +339,9 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, freehandle); } - } + // TEST CODE + //code = 9999; } return code; -- GitLab From aaae42307c1420b14b21d0cd243784f949dd864a Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Thu, 14 Jul 2022 18:42:12 +0800 Subject: [PATCH 155/380] test: add test cases for max_row/min_row function --- tests/parallel_test/cases.task | 2 + tests/pytest/functions/function_max_row.py | 84 ++++++++++++++++++++++ tests/pytest/functions/function_min_row.py | 84 ++++++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 tests/pytest/functions/function_max_row.py create mode 100644 tests/pytest/functions/function_min_row.py diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 365823d227..36c57cdf95 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -814,6 +814,8 @@ 3,,pytest,python3 test.py -f table/columnNameValidation.py 3,,pytest,python3 test.py -f table/tagNameCaseSensitive.py 3,,pytest,python3 test.py -f table/tbNameCaseSensitive.py +3,,pytest,python3 test.py -f functions/function_max_row.py +3,,pytest,python3 test.py -f functions/function_min_row.py 3,,develop-test,python3 ./test.py -f 2-query/ts_hidden_column.py 3,,develop-test,python3 ./test.py -f 2-query/ts_shortcut.py 3,,develop-test,python3 ./test.py -f 2-query/nchar_funcs.py diff --git a/tests/pytest/functions/function_max_row.py b/tests/pytest/functions/function_max_row.py new file mode 100644 index 0000000000..7ffa9858b9 --- /dev/null +++ b/tests/pytest/functions/function_max_row.py @@ -0,0 +1,84 @@ +################################################################### +# 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 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +import numpy as np + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + self.rowNum = 10 + self.tables = 10 + self.ts = 1537146000000 + + def run(self): + tdSql.prepare() + + intData = [] + floatData = [] + + tdSql.execute("create table stb (ts timestamp, c1 int, c2 double, c3 float) tags(t1 int)") + for i in range(self.tables): + tdSql.execute("create table tb%d using stb tags(%d)" % (i, i)) + sql = "insert into tb%d values" % i + for j in range(self.rowNum): + sql += "(%d, %d, %f, %f)" % (self.ts + j * 3000, j, j + 0.1, j + 0.1) + intData.append(j) + floatData.append(j + 0.1) + tdSql.execute(sql) + + tdSql.error("select max_row(ts) from stb") + tdSql.error("select max_row(t1) from stb") + + tdSql.query("select max_row(c1) from stb") + tdSql.checkData(0, 0, np.max(intData)) + + tdSql.query("select max_row(c1), * from stb") + tdSql.checkData(0, 0, np.max(intData)) + tdSql.checkData(0, 2, np.max(intData)) + tdSql.checkData(0, 3, np.max(floatData)) + tdSql.checkData(0, 4, np.max(floatData)) + + tdSql.query("select max_row(c1), * from stb group by tbname") + for i in range(self.tables): + tdSql.checkData(i, 0, np.max(intData)) + tdSql.checkData(i, 2, np.max(intData)) + tdSql.checkData(i, 3, np.max(floatData)) + tdSql.checkData(i, 4, np.max(floatData)) + + tdSql.query("select max_row(c1), * from stb interval(6s)") + tdSql.checkRows(5) + + tdSql.query("select max_row(c1), * from tb1 interval(6s)") + tdSql.checkRows(5) + + tdSql.query("select max_row(c1), * from stb interval(6s) group by tbname") + tdSql.checkRows(50) + + tdSql.query("select max_row(c1), * from (select min_row(c1) c1, * from stb group by tbname)") + tdSql.checkData(0, 0, np.min(intData)) + tdSql.checkRows(1) + + 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 diff --git a/tests/pytest/functions/function_min_row.py b/tests/pytest/functions/function_min_row.py new file mode 100644 index 0000000000..9acc0eee5b --- /dev/null +++ b/tests/pytest/functions/function_min_row.py @@ -0,0 +1,84 @@ +################################################################### +# 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 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +import numpy as np + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + self.rowNum = 10 + self.tables = 10 + self.ts = 1537146000000 + + def run(self): + tdSql.prepare() + + intData = [] + floatData = [] + + tdSql.execute("create table stb (ts timestamp, c1 int, c2 double, c3 float) tags(t1 int)") + for i in range(self.tables): + tdSql.execute("create table tb%d using stb tags(%d)" % (i, i)) + sql = "insert into tb%d values" % i + for j in range(self.rowNum): + sql += "(%d, %d, %f, %f)" % (self.ts + j * 3000, j, j + 0.1, j + 0.1) + intData.append(j) + floatData.append(j + 0.1) + tdSql.execute(sql) + + tdSql.error("select min_row(ts) from stb") + tdSql.error("select min_row(t1) from stb") + + tdSql.query("select min_row(c1) from stb") + tdSql.checkData(0, 0, np.min(intData)) + + tdSql.query("select min_row(c1), * from stb") + tdSql.checkData(0, 0, np.min(intData)) + tdSql.checkData(0, 2, np.min(intData)) + tdSql.checkData(0, 3, np.min(floatData)) + tdSql.checkData(0, 4, np.min(floatData)) + + tdSql.query("select min_row(c1), * from stb group by tbname") + for i in range(self.tables): + tdSql.checkData(i, 0, np.min(intData)) + tdSql.checkData(i, 2, np.min(intData)) + tdSql.checkData(i, 3, np.min(floatData)) + tdSql.checkData(i, 4, np.min(floatData)) + + tdSql.query("select min_row(c1), * from stb interval(6s)") + tdSql.checkRows(5) + + tdSql.query("select min_row(c1), * from tb1 interval(6s)") + tdSql.checkRows(5) + + tdSql.query("select min_row(c1), * from stb interval(6s) group by tbname") + tdSql.checkRows(50) + + tdSql.query("select min_row(c1), * from (select max_row(c1) c1, * from stb group by tbname)") + tdSql.checkData(0, 0, np.max(intData)) + tdSql.checkRows(1) + + 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 -- GitLab From 1180912bf5c18089378920d1ab9d653544cf4501 Mon Sep 17 00:00:00 2001 From: dingbo Date: Fri, 15 Jul 2022 09:37:05 +0800 Subject: [PATCH 156/380] docs: update high-volume.md --- .../com/taos/example/TestTableNotExits.java | 26 ++ .../example/highvolume/DataBaseMonitor.java | 47 +++ .../example/highvolume/FastWriteExample.java | 47 +-- .../example/highvolume/MockDataSource.java | 53 +++ .../com/taos/example/highvolume/ReadTask.java | 55 +-- .../taos/example/highvolume/SQLWriter.java | 18 +- .../taos/example/highvolume/StmtWriter.java | 4 + .../taos/example/highvolume/WriteTask.java | 4 +- .../java/src/main/resources/highvolume.drawio | 72 ++++ .../src/main/resources/highvolume2.drawio | 76 ++++ .../java/src/main/resources/logback.xml | 14 + docs/examples/python/fast_write_example.py | 180 +++++++++ docs/examples/python/highvolume_mp_queue.py | 193 +++++++++ docs/examples/python/mockdatasource.py | 49 +++ docs/examples/python/sql_writer.py | 11 +- docs/examples/python/stmt_writer.py | 2 + .../03-insert-data/05-high-volume.md | 367 +++++++++++------- .../07-develop/03-insert-data/highvolume.webp | Bin 6746 -> 7308 bytes 18 files changed, 970 insertions(+), 248 deletions(-) create mode 100644 docs/examples/java/src/main/java/com/taos/example/TestTableNotExits.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/StmtWriter.java create mode 100644 docs/examples/java/src/main/resources/highvolume.drawio create mode 100644 docs/examples/java/src/main/resources/highvolume2.drawio create mode 100644 docs/examples/java/src/main/resources/logback.xml create mode 100644 docs/examples/python/fast_write_example.py create mode 100644 docs/examples/python/highvolume_mp_queue.py create mode 100644 docs/examples/python/mockdatasource.py create mode 100644 docs/examples/python/stmt_writer.py diff --git a/docs/examples/java/src/main/java/com/taos/example/TestTableNotExits.java b/docs/examples/java/src/main/java/com/taos/example/TestTableNotExits.java new file mode 100644 index 0000000000..89fa8eaed5 --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/TestTableNotExits.java @@ -0,0 +1,26 @@ +package com.taos.example; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +public class TestTableNotExits { + private static Connection getConnection() throws SQLException { + String jdbcUrl = "jdbc:TAOS://localhost:6030?user=root&password=taosdata"; + return DriverManager.getConnection(jdbcUrl); + } + public static void main(String[] args) throws SQLException { + try(Connection conn = getConnection()) { + try(Statement stmt = conn.createStatement()) { + try { + stmt.executeUpdate("insert into test.t1 values(1, 2) test.t2 values(3, 4)"); + } catch (SQLException e) { + System.out.println(e.getErrorCode()); + System.out.println(Integer.toHexString(e.getErrorCode())); + System.out.println(e); + } + } + } + } +} diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java new file mode 100644 index 0000000000..5c513ec282 --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java @@ -0,0 +1,47 @@ +package com.taos.example.highvolume; + +import java.sql.*; + +/** + * Prepare target database. + * Count total records in database periodically so that we can estimate the writing speed. + */ +public class DataBaseMonitor { + private Connection conn; + private Statement stmt; + + public DataBaseMonitor init() throws SQLException { + if (conn == null) { + String jdbcURL = System.getenv("TDENGINE_JDBC_URL"); + conn = DriverManager.getConnection(jdbcURL); + stmt = conn.createStatement(); + } + return this; + } + + public void close() { + try { + stmt.close(); + } catch (SQLException e) { + } + try { + conn.close(); + } catch (SQLException e) { + } + } + + public void prepareDatabase() throws SQLException { + stmt.execute("DROP DATABASE IF EXISTS test"); + stmt.execute("CREATE DATABASE test"); + stmt.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"); + } + + public Long count() throws SQLException { + if (!stmt.isClosed()) { + ResultSet result = stmt.executeQuery("SELECT count(*) from test.meters"); + result.next(); + return result.getLong(1); + } + return null; + } +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java index e8af1a68ea..15672dddd9 100644 --- a/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java @@ -9,51 +9,7 @@ import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; -/** - * Prepare target database. - * Count total records in database periodically so that we can estimate the writing speed. - */ -class DataBaseMonitor { - private Connection conn; - private Statement stmt; - public DataBaseMonitor init() throws SQLException { - if (conn == null) { - String jdbcURL = System.getenv("TDENGINE_JDBC_URL"); - conn = DriverManager.getConnection(jdbcURL); - stmt = conn.createStatement(); - } - return this; - } - - public void close() { - try { - stmt.close(); - } catch (SQLException e) { - } - try { - conn.close(); - } catch (SQLException e) { - } - } - - public void prepareDatabase() throws SQLException { - stmt.execute("DROP DATABASE IF EXISTS test"); - stmt.execute("CREATE DATABASE test"); - stmt.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"); - } - - public Long count() throws SQLException { - if (!stmt.isClosed()) { - ResultSet result = stmt.executeQuery("SELECT count(*) from test.meters"); - result.next(); - return result.getLong(1); - } - return null; - } -} - -// ANCHOR: main public class FastWriteExample { final static Logger logger = LoggerFactory.getLogger(FastWriteExample.class); @@ -110,5 +66,4 @@ public class FastWriteExample { lastCount = count; } } -} -// ANCHOR_END: main \ No newline at end of file +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java new file mode 100644 index 0000000000..6fe83f002e --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java @@ -0,0 +1,53 @@ +package com.taos.example.highvolume; + +import java.util.Iterator; + +/** + * Generate test data + */ +class MockDataSource implements Iterator { + private String tbNamePrefix; + private int tableCount; + private long maxRowsPerTable = 1000000000L; + + // 100 milliseconds between two neighbouring rows. + long startMs = System.currentTimeMillis() - maxRowsPerTable * 100; + private int currentRow = 0; + private int currentTbId = -1; + + // mock values + String[] location = {"LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"}; + float[] current = {8.8f, 10.7f, 9.9f, 8.9f, 9.4f}; + int[] voltage = {119, 116, 111, 113, 118}; + float[] phase = {0.32f, 0.34f, 0.33f, 0.329f, 0.141f}; + + public MockDataSource(String tbNamePrefix, int tableCount) { + this.tbNamePrefix = tbNamePrefix; + this.tableCount = tableCount; + } + + @Override + public boolean hasNext() { + currentTbId += 1; + if (currentTbId == tableCount) { + currentTbId = 0; + currentRow += 1; + } + return currentRow < maxRowsPerTable; + } + + @Override + public String next() { + long ts = startMs + 100 * currentRow; + int groupId = currentTbId % 5 == 0 ? currentTbId / 5 : currentTbId / 5 + 1; + StringBuilder sb = new StringBuilder(tbNamePrefix + "_" + currentTbId + ","); // tbName + sb.append(ts).append(','); // ts + sb.append(current[currentRow % 5]).append(','); // current + sb.append(voltage[currentRow % 5]).append(','); // voltage + sb.append(phase[currentRow % 5]).append(','); // phase + sb.append(location[currentRow % 5]).append(','); // location + sb.append(groupId); // groupID + + return sb.toString(); + } +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java index 94cde899f4..a6fcfed1d2 100644 --- a/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java @@ -7,57 +7,6 @@ import java.util.Iterator; import java.util.List; import java.util.concurrent.BlockingQueue; -/** - * Generate test data - */ -class MockDataSource implements Iterator { - private String tbNamePrefix; - private int tableCount; - private long maxRowsPerTable = 1000000000L; - - // 100 milliseconds between two neighbouring rows. - long startMs = System.currentTimeMillis() - maxRowsPerTable * 100; - private int currentRow = 0; - private int currentTbId = -1; - - // mock values - String[] location = {"LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"}; - float[] current = {8.8f, 10.7f, 9.9f, 8.9f, 9.4f}; - int[] voltage = {119, 116, 111, 113, 118}; - float[] phase = {0.32f, 0.34f, 0.33f, 0.329f, 0.141f}; - - public MockDataSource(String tbNamePrefix, int tableCount) { - this.tbNamePrefix = tbNamePrefix; - this.tableCount = tableCount; - } - - @Override - public boolean hasNext() { - currentTbId += 1; - if (currentTbId == tableCount) { - currentTbId = 0; - currentRow += 1; - } - return currentRow < maxRowsPerTable; - } - - @Override - public String next() { - long ts = startMs + 100 * currentRow; - int groupId = currentTbId % 5 == 0 ? currentTbId / 5 : currentTbId / 5 + 1; - StringBuilder sb = new StringBuilder(tbNamePrefix + "_" + currentTbId + ","); // tbName - sb.append(ts).append(','); // ts - sb.append(current[currentRow % 5]).append(','); // current - sb.append(voltage[currentRow % 5]).append(','); // voltage - sb.append(phase[currentRow % 5]).append(','); // phase - sb.append(location[currentRow % 5]).append(','); // location - sb.append(groupId); // groupID - - return sb.toString(); - } -} - -// ANCHOR: ReadTask class ReadTask implements Runnable { private final static Logger logger = LoggerFactory.getLogger(ReadTask.class); private final int taskId; @@ -106,6 +55,4 @@ class ReadTask implements Runnable { logger.info("stop"); this.active = false; } -} - -// ANCHOR_END: ReadTask \ No newline at end of file +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java index b13d6c363c..c2989acdbe 100644 --- a/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java @@ -7,8 +7,6 @@ import java.sql.*; import java.util.HashMap; import java.util.Map; -// ANCHOR: SQLWriter - /** * A helper class encapsulate the logic of writing using SQL. *

@@ -154,10 +152,14 @@ public class SQLWriter { if (errorCode == 0x362 || errorCode == 0x218) { // Table does not exist createTables(); - stmt.executeUpdate(sql); + executeSQL(sql); } else { + logger.error("Execute SQL: {}", sql); throw e; } + } catch (Throwable throwable) { + logger.error("Execute SQL: {}", sql); + throw throwable; } } @@ -174,7 +176,12 @@ public class SQLWriter { sb.append("IF NOT EXISTS ").append(tbName).append(" USING meters TAGS ").append(tagValues).append(" "); } String sql = sb.toString(); - stmt.executeUpdate(sql); + try { + stmt.executeUpdate(sql); + } catch (Throwable throwable) { + logger.error("Execute SQL: {}", sql); + throw throwable; + } } public boolean hasBufferedValues() { @@ -195,5 +202,4 @@ public class SQLWriter { } catch (SQLException e) { } } -} -// ANCHOR_END: SQLWriter +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/StmtWriter.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/StmtWriter.java new file mode 100644 index 0000000000..8ade06625d --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/StmtWriter.java @@ -0,0 +1,4 @@ +package com.taos.example.highvolume; + +public class StmtWriter { +} diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java index bbe9cb0770..de9e5463d7 100644 --- a/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java @@ -5,7 +5,6 @@ import org.slf4j.LoggerFactory; import java.util.concurrent.BlockingQueue; -// ANCHOR: WriteTask class WriteTask implements Runnable { private final static Logger logger = LoggerFactory.getLogger(WriteTask.class); private final int maxBatchSize; @@ -56,5 +55,4 @@ class WriteTask implements Runnable { logger.info("stop"); this.active = false; } -} -// ANCHOR_END: WriteTask \ No newline at end of file +} \ No newline at end of file diff --git a/docs/examples/java/src/main/resources/highvolume.drawio b/docs/examples/java/src/main/resources/highvolume.drawio new file mode 100644 index 0000000000..4102160618 --- /dev/null +++ b/docs/examples/java/src/main/resources/highvolume.drawio @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/examples/java/src/main/resources/highvolume2.drawio b/docs/examples/java/src/main/resources/highvolume2.drawio new file mode 100644 index 0000000000..8c9ae09007 --- /dev/null +++ b/docs/examples/java/src/main/resources/highvolume2.drawio @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/examples/java/src/main/resources/logback.xml b/docs/examples/java/src/main/resources/logback.xml new file mode 100644 index 0000000000..898887fe6a --- /dev/null +++ b/docs/examples/java/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/docs/examples/python/fast_write_example.py b/docs/examples/python/fast_write_example.py new file mode 100644 index 0000000000..c9d606388f --- /dev/null +++ b/docs/examples/python/fast_write_example.py @@ -0,0 +1,180 @@ +# install dependencies: +# recommend python >= 3.8 +# pip3 install faster-fifo +# + +import logging +import math +import sys +import time +import os +from multiprocessing import Process +from faster_fifo import Queue +from mockdatasource import MockDataSource +from queue import Empty +from typing import List + +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format="%(asctime)s [%(name)s] - %(message)s") + +READ_TASK_COUNT = 1 +WRITE_TASK_COUNT = 1 +TABLE_COUNT = 1000 +QUEUE_SIZE = 1000000 +MAX_BATCH_SIZE = 3000 + +read_processes = [] +write_processes = [] + + +def get_connection(): + """ + If variable TDENGINE_FIRST_EP is provided then it will be used. If not, firstEP in /etc/taos/taos.cfg will be used. + You can also override the default username and password by supply variable TDENGINE_USER and TDENGINE_PASSWORD + """ + import taos + firstEP = os.environ.get("TDENGINE_FIRST_EP") + if firstEP: + host, port = firstEP.split(":") + else: + host, port = None, 0 + user = os.environ.get("TDENGINE_USER", "root") + password = os.environ.get("TDENGINE_PASSWORD", "taosdata") + return taos.connect(host=host, port=int(port), user=user, password=password) + + +# ANCHOR: read + +def run_read_task(task_id: int, task_queues: List[Queue]): + table_count_per_task = TABLE_COUNT // READ_TASK_COUNT + data_source = MockDataSource(f"tb{task_id}", table_count_per_task) + try: + for batch in data_source: + for table_id, rows in batch: + # hash data to different queue + i = table_id % len(task_queues) + # block putting forever when the queue is full + task_queues[i].put_many(rows, block=True, timeout=-1) + except KeyboardInterrupt: + pass + + +# ANCHOR_END: read + +# ANCHOR: write +def run_write_task(task_id: int, queue: Queue): + from sql_writer import SQLWriter + log = logging.getLogger(f"WriteTask-{task_id}") + writer = SQLWriter(get_connection) + lines = None + try: + while True: + try: + # get as many as possible + lines = queue.get_many(block=False, max_messages_to_get=MAX_BATCH_SIZE) + writer.process_lines(lines) + except Empty: + time.sleep(0.01) + except KeyboardInterrupt: + pass + except BaseException as e: + log.debug(f"lines={lines}") + raise e + + +# ANCHOR_END: write + +def set_global_config(): + argc = len(sys.argv) + if argc > 1: + global READ_TASK_COUNT + READ_TASK_COUNT = int(sys.argv[1]) + if argc > 2: + global WRITE_TASK_COUNT + WRITE_TASK_COUNT = int(sys.argv[2]) + if argc > 3: + global TABLE_COUNT + TABLE_COUNT = int(sys.argv[3]) + if argc > 4: + global QUEUE_SIZE + QUEUE_SIZE = int(sys.argv[4]) + if argc > 5: + global MAX_BATCH_SIZE + MAX_BATCH_SIZE = int(sys.argv[5]) + + +# ANCHOR: monitor +def run_monitor_process(): + log = logging.getLogger("DataBaseMonitor") + conn = get_connection() + conn.execute("DROP DATABASE IF EXISTS test") + conn.execute("CREATE DATABASE test") + conn.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) " + "TAGS (location BINARY(64), groupId INT)") + + def get_count(): + res = conn.query("SELECT count(*) FROM test.meters") + rows = res.fetch_all() + return rows[0][0] if rows else 0 + + last_count = 0 + while True: + time.sleep(10) + count = get_count() + log.info(f"count={count} speed={(count - last_count) / 10}") + last_count = count + + +# ANCHOR_END: monitor +# ANCHOR: main +def main(): + set_global_config() + logging.info(f"READ_TASK_COUNT={READ_TASK_COUNT}, WRITE_TASK_COUNT={WRITE_TASK_COUNT}, " + f"TABLE_COUNT={TABLE_COUNT}, QUEUE_SIZE={QUEUE_SIZE}, MAX_BATCH_SIZE={MAX_BATCH_SIZE}") + + monitor_process = Process(target=run_monitor_process) + monitor_process.start() + time.sleep(3) # waiting for database ready. + + task_queues: List[Queue] = [] + # create task queues + for i in range(WRITE_TASK_COUNT): + queue = Queue(max_size_bytes=QUEUE_SIZE) + task_queues.append(queue) + + # create write processes + for i in range(WRITE_TASK_COUNT): + p = Process(target=run_write_task, args=(i, task_queues[i])) + p.start() + logging.debug(f"WriteTask-{i} started with pid {p.pid}") + write_processes.append(p) + + # create read processes + for i in range(READ_TASK_COUNT): + queues = assign_queues(i, task_queues) + p = Process(target=run_read_task, args=(i, queues)) + p.start() + logging.debug(f"ReadTask-{i} started with pid {p.pid}") + read_processes.append(p) + + try: + monitor_process.join() + except KeyboardInterrupt: + monitor_process.terminate() + [p.terminate() for p in read_processes] + [p.terminate() for p in write_processes] + [q.close() for q in task_queues] + + +def assign_queues(read_task_id, task_queues): + """ + Compute target queues for a specific read task. + """ + ratio = WRITE_TASK_COUNT / READ_TASK_COUNT + from_index = math.floor(read_task_id * ratio) + end_index = math.ceil((read_task_id + 1) * ratio) + return task_queues[from_index:end_index] + + +if __name__ == '__main__': + main() +# ANCHOR_END: main diff --git a/docs/examples/python/highvolume_mp_queue.py b/docs/examples/python/highvolume_mp_queue.py new file mode 100644 index 0000000000..f6605adb0f --- /dev/null +++ b/docs/examples/python/highvolume_mp_queue.py @@ -0,0 +1,193 @@ +# import logging +# import sys +# import time +# from multiprocessing import Queue, Process +# from queue import Empty +# from typing import List +# +# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format="%(asctime)s [%(name)s] - %(message)s") +# +# READ_TASK_COUNT = 1 +# WRITE_TASK_COUNT = 1 +# QUEUE_SIZE = 1000 +# TABLE_COUNT = 1000 +# MAX_BATCH_SIZE = 3000 +# +# read_processes = [] +# write_processes = [] +# +# +# # ANCHOR: DataBaseMonitor +# class DataBaseMonitor: +# """ +# Start a thread. +# Prepare database and stable. +# Statistic writing speed and print it every 10 seconds. +# """ +# +# def __init__(self): +# self.process = Process(target=self.run) +# self.process.start() +# +# def get_connection(self): +# import taos +# return taos.connect(host="localhost", user="root", password="taosdata", port=6030) +# +# def prepare_database(self, conn): +# conn.execute("DROP DATABASE IF EXISTS test") +# conn.execute("CREATE DATABASE test") +# conn.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)") +# +# def get_count(self, conn): +# res = conn.query("SELECT count(*) FROM test.meters") +# rows = res.fetch_all() +# return rows[0][0] if rows else 0 +# +# def run(self): +# log = logging.getLogger("DataBaseMonitor") +# conn = self.get_connection() +# self.prepare_database(conn) +# last_count = 0 +# while True: +# time.sleep(10) +# count = self.get_count(conn) +# log.info(f"count={count} speed={(count - last_count) / 10}") +# last_count = count +# +# def join(self): +# self.process.join() +# +# def stop(self): +# self.process.terminate() +# +# +# # ANCHOR_END: DataBaseMonitor +# +# # ANCHOR: MockDataSource +# class MockDataSource: +# location = ["LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"] +# current = [8.8, 10.7, 9.9, 8.9, 9.4] +# voltage = [119, 116, 111, 113, 118] +# phase = [0.32, 0.34, 0.33, 0.329, 0.141] +# max_rows_per_table = 10 ** 9 +# +# def __init__(self, tb_name_prefix, table_count): +# self.table_name_prefix = tb_name_prefix +# self.table_count = table_count +# self.start_ms = round(time.time() * 1000) - self.max_rows_per_table * 100 +# +# def __iter__(self): +# self.row = 0 +# self.table_id = -1 +# return self +# +# def __next__(self): +# self.table_id += 1 +# if self.table_id == self.table_count: +# self.table_id = 0 +# self.row += 1 +# if self.row < self.max_rows_per_table: +# ts = self.start_ms + 100 * self.row +# group_id = self.table_id % 5 if self.table_id % 5 == 0 else self.table_id % 5 + 1 +# tb_name = self.table_name_prefix + '_' + str(self.table_id) +# ri = self.row % 5 +# return self.table_id, f"{tb_name},{ts},{self.current[ri]},{self.voltage[ri]},{self.phase[ri]},{self.location[ri]},{group_id}" +# else: +# raise StopIteration +# +# +# # ANCHOR_END: MockDataSource +# +# # ANCHOR: read +# def run_read_task(task_id: int, task_queues: List[Queue]): +# table_count_per_task = TABLE_COUNT // READ_TASK_COUNT +# data_source = MockDataSource(f"tb{task_id}", table_count_per_task) +# try: +# for table_id, line in data_source: +# i = table_id % len(task_queues) +# task_queues[i].put(line, block=True) +# except KeyboardInterrupt: +# pass +# +# +# # ANCHOR_END: read +# +# # ANCHOR: write +# def run_write_task(task_id: int, queue: Queue): +# from sql_writer import SQLWriter +# log = logging.getLogger(f"WriteTask-{task_id}") +# writer = SQLWriter(MAX_BATCH_SIZE) +# try: +# while True: +# try: +# line = queue.get(block=False) +# writer.process_line(line) +# except Empty: +# if writer.buffered_count > 0: +# writer.flush() +# else: +# time.sleep(0.01) +# except KeyboardInterrupt: +# pass +# except BaseException as e: +# msg = f"line={line}, buffer_count={writer.buffered_count}" +# log.debug(msg) +# raise e +# +# +# # ANCHOR_END: write +# +# def set_global_config(): +# argc = len(sys.argv) +# if argc > 1: +# global READ_TASK_COUNT +# READ_TASK_COUNT = int(sys.argv[1]) +# if argc > 2: +# global WRITE_TASK_COUNT +# WRITE_TASK_COUNT = int(sys.argv[2]) +# if argc > 3: +# global QUEUE_SIZE +# QUEUE_SIZE = int(sys.argv[3]) +# if argc > 4: +# global TABLE_COUNT +# TABLE_COUNT = int(sys.argv[4]) +# if argc > 5: +# global MAX_BATCH_SIZE +# MAX_BATCH_SIZE = int(sys.argv[5]) +# +# +# # ANCHOR: main +# def main(): +# set_global_config() +# logging.info(f"READ_TASK_COUNT={READ_TASK_COUNT}, WRITE_TASK_COUNT={WRITE_TASK_COUNT}, QUEUE_SIZE={QUEUE_SIZE}, TABLE_COUNT={TABLE_COUNT}, MAX_BATCH_SIZE={MAX_BATCH_SIZE}") +# +# database_monitor = DataBaseMonitor() +# time.sleep(3) # wait for database ready +# +# task_queues: List[Queue] = [] +# +# for i in range(WRITE_TASK_COUNT): +# queue = Queue(maxsize=QUEUE_SIZE) +# task_queues.append(queue) +# p = Process(target=run_write_task, args=(i, queue)) +# p.start() +# logging.debug(f"WriteTask-{i} started with pid {p.pid}") +# write_processes.append(p) +# +# for i in range(READ_TASK_COUNT): +# p = Process(target=run_read_task, args=(i, task_queues)) +# p.start() +# logging.debug(f"ReadTask-{i} started with pid {p.pid}") +# read_processes.append(p) +# +# try: +# database_monitor.join() +# except KeyboardInterrupt: +# database_monitor.stop() +# [p.terminate() for p in read_processes] +# [p.terminate() for p in write_processes] +# +# +# if __name__ == '__main__': +# main() +# # ANCHOR_END: main diff --git a/docs/examples/python/mockdatasource.py b/docs/examples/python/mockdatasource.py new file mode 100644 index 0000000000..852860aec0 --- /dev/null +++ b/docs/examples/python/mockdatasource.py @@ -0,0 +1,49 @@ +import time + + +class MockDataSource: + samples = [ + "8.8,119,0.32,LosAngeles,0", + "10.7,116,0.34,SanDiego,1", + "9.9,111,0.33,Hollywood,2", + "8.9,113,0.329,Compton,3", + "9.4,118,0.141,San Francisco,4" + ] + + def __init__(self, tb_name_prefix, table_count): + self.table_name_prefix = tb_name_prefix + "_" + self.table_count = table_count + self.max_rows = 10000000 + self.current_ts = round(time.time() * 1000) - self.max_rows * 100 + # [(tableId, tableName, values),] + self.data = self._init_data() + + def _init_data(self): + lines = self.samples * (self.table_count // 5 + 1) + data = [] + for i in range(self.table_count): + table_name = self.table_name_prefix + str(i) + data.append((i, table_name, lines[i])) # tableId, row + return data + + def __iter__(self): + self.row = 0 + return self + + def __next__(self): + """ + next 1000 rows for each table. + return: {tableId:[row,...]} + """ + # generate 1000 timestamps + ts = [] + for _ in range(1000): + self.current_ts += 100 + ts.append(str(self.current_ts)) + # add timestamp to each row + # [(tableId, ["tableName,ts,current,voltage,phase,location,groupId"])] + result = [] + for table_id, table_name, values in self.data: + rows = [table_name + ',' + t + ',' + values for t in ts] + result.append((table_id, rows)) + return result diff --git a/docs/examples/python/sql_writer.py b/docs/examples/python/sql_writer.py index ad5653f0ec..cb04f85c23 100644 --- a/docs/examples/python/sql_writer.py +++ b/docs/examples/python/sql_writer.py @@ -18,6 +18,7 @@ class SQLWriter: name = r[0] if name == "maxSQLLength": return int(r[1]) + return 1024 * 1024 def process_lines(self, lines: str): """ @@ -71,11 +72,19 @@ class SQLWriter: if error_code == 0x362 or error_code == 0x218: self.create_tables() else: + self.log.error("Execute SQL: %s", sql) raise e + except BaseException as baseException: + self.log.error("Execute SQL: %s", sql) + raise baseException def create_tables(self): sql = "CREATE TABLE " for tb in self._tb_values.keys(): tag_values = self._tb_tags[tb] sql += "IF NOT EXISTS " + tb + " USING meters TAGS " + tag_values + " " - self._conn.execute(sql) + try: + self._conn.execute(sql) + except BaseException as e: + self.log.error("Execute SQL: %s", sql) + raise e diff --git a/docs/examples/python/stmt_writer.py b/docs/examples/python/stmt_writer.py new file mode 100644 index 0000000000..60846b5a64 --- /dev/null +++ b/docs/examples/python/stmt_writer.py @@ -0,0 +1,2 @@ +class StmtWriter: + pass diff --git a/docs/zh/07-develop/03-insert-data/05-high-volume.md b/docs/zh/07-develop/03-insert-data/05-high-volume.md index ed8b137358..24b57cee67 100644 --- a/docs/zh/07-develop/03-insert-data/05-high-volume.md +++ b/docs/zh/07-develop/03-insert-data/05-high-volume.md @@ -1,36 +1,88 @@ ---- -title: 高效写入 ---- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +# 高效写入 + +本节介绍如何高效地向 TDengine 写入数据。 ## 高效写入原理 {#principle} -本节介绍如何高效地向 TDengine 写入数据。高效写入数据要考虑几个因素:数据在不同表(或子表)之间的分布,即要写入数据的相邻性;单次写入的数据量;并发连接数。一般来说,每批次只向同一张表(或子表)写入数据比向多张表(或子表)写入数据要更高效;每批次写入的数据量越大越高效(但超过一定阈值其优势会消失;同时写入数据的并发连接数越多写入越高效(但超过一定阈值反而会下降,取决于服务端处理能力)。 +### 客户端程序的角度 {#application-view} + +从客户端程序的角度来说,高效写入数据要考虑以下几个因素: + +1. 单次写入的数据量。一般来讲,每批次写入的数据量越大越高效(但超过一定阈值其优势会消失)。使用 SQL 写入 TDengine 时,尽量在一条 SQL 中拼接更多数据。目前,TDengine 支持的一条 SQL 的最大长度为 1,048,576(1M)个字符。可通过配置客户端参数 maxSQLLength(默认值为 65480)进行修改。 +2. 并发连接数。一般来讲,同时写入数据的并发连接数越多写入越高效(但超过一定阈值反而会下降,取决于服务端处理能力)。 +3. 数据在不同表(或子表)之间的分布,即要写入数据的相邻性。一般来说,每批次只向同一张表(或子表)写入数据比向多张表(或子表)写入数据要更高效; +4. 写入方式。一般来讲: + - 参数绑定写入比 SQL 写入更高效。因参数绑定方式避免了 SQL 解析。(但增加了 C 接口的调用次数,对于连接器也有性能损耗)。 + - SQL 写入不自动建表比自动建表更高效。因自动建表要频繁检查表是否存在 + - SQL 写入比无模式写入更高效。因无模式写入会自动建表且支持动态更改表结构 + +客户端程序要充分且恰当地利用以上几个因素。在单次写入中尽量只向同一张表(或子表)写入数据,每批次写入的数据量经过测试和调优设定为一个最适合当前系统处理能力的数值,并发写入的连接数同样经过测试和调优后设定为一个最适合当前系统处理能力的数值,以实现在当前系统中的最佳写入速度。 + +### 数据源的角度 {#datasource-view} + +客户端程序通常需要从数据源读数据再写入 TDengine。从数据源角度来说,以下几种情况需要在读线程和写线程之间增加队列: + +1. 有多个数据源,单个数据源生成数据的速度远小于单线程写入的速度,但数据量整体比较大。此时队列的作用是把多个数据源的数据汇聚到一起,增加单次写入的数据量。 +2. 单个数据源生成数据的速度远大于单线程写入的速度。此时队列的作用是增加写入的并发度。 +3. 单张表的数据分散在多个数据源。此时队列的作用是将同一张表的数据提前汇聚到一起,提高写入时数据的相邻性。 + +如果写应用的数据源是 Kafka, 写应用本身即 Kafka 的消费者,则可利用 Kafka 的特性实现高效写入。比如: + +1. 将同一张表的数据写到同一个 Topic 的同一个 Partition,增加数据的相邻性 +2. 通过订阅多个 Topic 实现数据汇聚 +3. 通过增加 Consumer 线程数增加写入的并发度 +4. 通过增加每次 fetch 的最大数据量来增加单次写入的最大数据量 + +### 服务器配置的角度 {#setting-view} -为了更高效地向 TDengine 写入数据,客户端程序要充分且恰当地利用以上几个因素。在单次写入中尽量只向同一张表(或子表)写入数据,每批次写入的数据量经过测试和调优设定为一个最适合当前系统处理能力的数值,并发写入的连接数同样经过测试和调优后设定为一个最适合当前系统处理能力的数值,以实现在当前系统中的最佳写入速度。同时,TDengine 还提供了独特的参数绑定写入,这也是一个有助于实现高效写入的方法。 +从服务器配置的角度来说,也有很多优化写入性能的方法。 -为了使写入最高效,除了客户端程序的设计,服务端的配置也很重要。如果无论怎么调节客户端程序,taosd 进程的 CPU 使用率都很低,那很可能需要增加 vgroup 的数量。比如:数据库总表数是 1000 且 minTablesPerVnode 设置的也是 1000,那么这个数据至多有一个 vgroup。此时如果将 minTablesPerVnode 和 tablelncStepPerVnode 都设置成 100, 则这个数据库有可能用到 10 个 vgroup。更多性能调优参数请参考[配置参考](../../reference/config)性能调优部分。 +如果无论怎么调节客户端程序,taosd 进程的 CPU 使用率都很低,那很可能需要增加 vgroup 的数量。比如:数据库总表数是 1000 且 minTablesPerVnode 设置的也是 1000,那么这个数据至多有一个 vgroup。此时如果将 minTablesPerVnode 和 tablelncStepPerVnode 都设置成 100, 则这个数据库可能用到 10 个 vgroup。 -## 高效写入方案 {#scenario} +更多调优参数,请参考[性能优化](../../operation/optimize)和[配置参考](../../reference/config)部分。 -下面的示例程序展示了如何高效写入数据: +## 高效写入示例 {#sample-code} -- TDengine 客户端程序从消息队列或者其它数据源不断读入数据,在示例程序中采用生成模拟数据的方式来模拟读取数据源 +### 场景设计 {#scenario} + +下面的示例程序展示了如何高效写入数据,场景设计如下: + +- TDengine 客户端程序从其它数据源不断读入数据,在示例程序中采用生成模拟数据的方式来模拟读取数据源 - 单个连接向 TDengine 写入的速度无法与读数据的速度相匹配,因此客户端程序启动多个线程,每个线程都建立了与 TDengine 的连接,每个线程都有一个独占的固定大小的消息队列 - 客户端程序将接收到的数据根据所属的表名(或子表名)HASH 到不同的线程,即写入该线程所对应的消息队列,以此确保属于某个表(或子表)的数据一定会被一个固定的线程处理 - 各个子线程在将所关联的消息队列中的数据读空后或者读取数据量达到一个预定的阈值后将该批数据写入 TDengine,并继续处理后面接收到的数据 -![TDengine 高效写入线程模型](highvolume.webp) +![TDengine 高效写入示例场景的线程模型](highvolume.webp) + +### 示例代码 {#code} + +这一部分是针对以上场景的示例代码。对于其它场景高效写入原理相同,不过代码需要适当修改。 + +本示例代码假设源数据属于同一张超级表(meters)的不同子表。程序在开始写入数据之前已经在 test 库创建了这个超级表。对于子表,将根据收到的数据,由应用程序自动创建。如果实际场景是多个超级表,只需修改写任务自动建表的代码。 + + + -:::note -上图所示架构,每个写任务只负责写特定的表,体现了数据的相邻性原则。但是读任务所读的表,我们假设是随机的。这样一个队列有多个写入线程(或进程),队列内部可能产生锁的消耗。实际场景,如果能做到一个读任务对应一个写任务是最好的。 -::: +**程序清单** -## Java 示例程序 {#java-demo} +| 类名 | 功能说明 | +| ---------------- | --------------------------------------------------------------------------- | +| FastWriteExample | 主程序 | +| ReadTask | 从模拟源中读取数据,将表名经过 hash 后得到 Queue 的 index,写入对应的 Queue | +| WriteTask | 从 Queue 中获取数据,组成一个 Batch,写入 TDengine | +| MockDataSource | 模拟生成一定数量 meters 子表的数据 | +| SQLWriter | WriteTask 依赖这个类完成 SQL 拼接、自动建表、 SQL 写入、SQL 长度检查 | +| StmtWriter | 实现参数绑定方式批量写入(暂未完成) | +| DataBaseMonitor | 统计写入速度,并每隔 10 秒把当前写入速度打印到控制台 | -在 Java 示例程序中采用拼接 SQL 的写入方式。 -### 主程序 {#java-demo-main} +以下是各类的完整代码和更详细的功能说明。 +

+FastWriteExample 主程序负责: 1. 创建消息队列 @@ -45,70 +97,80 @@ title: 高效写入 3. 模拟生成的总表数。默认为 1000。将会平分给各个读线程。 4. 每批最多写入记录数量。默认为 3000。 -
-主程序 +队列容量(taskQueueCapacity)也是与性能有关的参数,可通过修改程序调节。一般来讲,队列容量越大,入队被阻塞的概率越小,队列的吞吐量越大,但是内存占用也会越大。 示例程序默认值已经设置地足够大。 ```java -{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java:main}} +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java}} ```
- -队列容量(taskQueueCapacity)也是与性能有关的参数,可通过修改程序调节。一般来讲,队列容量越大,入队被阻塞的概率越小,队列的吞吐量越大,但是内存占用也会越大。 - -### 读任务的实现 {#java-demo-read} +
+ReadTask 读任务负责从数据源读数据。每个读任务都关联了一个模拟数据源。每个模拟数据源可生成一点数量表的数据。不同的模拟数据源生成不同表的数据。 读任务采用阻塞的方式写消息队列。也就是说,一旦队列满了,写操作就会阻塞。 +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java}} +``` + +
+
-读任务的实现 +WriteTask ```java -{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java:ReadTask}} +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java}} ```
-### 写任务的实现 {#java-demo-write} -
-写任务的实现 + +MockDataSource ```java -{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java:WriteTask}} +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java}} ```
-### SQLWriter 类的实现 {#java-demo-sql-writer} +
+ +SQLWriter -SQLWriter 类封装了拼 SQL 和写数据的逻辑。注意,所有的表都没有提前创建,而是写入出错的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。 +SQLWriter 类封装了拼 SQL 和写数据的逻辑。注意,所有的表都没有提前创建,而是在 catch 到表不存在异常的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。对于其它异常,这里简单地记录当时执行的 SQL 语句到日志中,你也可以记录更多线索到日志,已便排查错误和故障恢复。 + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java}} +``` + +
-SQLWriter 类的实现 + +DataBaseMonitor ```java -{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java:SQLWriter}} +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java}} ```
-### 执行示例程序 {#run-java-demo} +**执行步骤**
执行 Java 示例程序 - 执行程序前需配置环境变量 `TDENGINE_JDBC_URL`。如果 TDengine Server 部署在本机,且用户名、密码和端口都是默认值,那么可配置: ``` TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" ``` -#### 本地集成开发环境执行示例程序 {#java-demo-local-run} +**本地集成开发环境执行示例程序** 1. clone TDengine 仓库 ``` @@ -118,7 +180,7 @@ TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" 3. 在开发环境中配置环境变量 `TDENGINE_JDBC_URL`。如果已配置了全局的环境变量 `TDENGINE_JDBC_URL` 可跳过这一步。 4. 运行类 `com.taos.example.highvolume.FastWriteExample`。 -#### 远程服务器上执行示例程序 {#java-demo-remote-run} +**远程服务器上执行示例程序** 若要在服务器上执行示例程序,可按照下面的步骤操作: @@ -132,61 +194,93 @@ TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" ``` 3. 复制依赖到服务器指定目录: - 复制依赖包,只用复制一次 - ``` - scp -r .\target\lib @:~/examples/java - ``` - + ``` + scp -r .\target\lib @:~/examples/java + ``` - 复制本程序的 jar 包,每次更新代码都需要复制 - ``` - scp -r .\target\javaexample-1.0.jar @:~/examples/java - ``` + ``` + scp -r .\target\javaexample-1.0.jar @:~/examples/java + ``` 4. 配置环境变量。 编辑 `~/.bash_profile` 或 `~/.bashrc` 添加如下内容例如: + ``` export TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" ``` + 以上使用的是本地部署 TDengine Server 时默认的 JDBC URL。你需要根据自己的实际情况更改。 5. 用 java 命令启动示例程序,命令模板: - + ``` java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample ``` 6. 结束测试程序。测试程序不会自动结束,在获取到当前配置下稳定的写入速度后,按 CTRL + C 结束程序。 - 下面是一次实际运行的截图: + 下面是一次实际运行的日志输出,机器配置 16核 + 64G + 固态硬盘。 ``` - [testuser@vm95 java]$ java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample 1 9 1000 2000 - 17:01:01.131 [main] INFO c.t.e.highvolume.FastWriteExample - readTaskCount=1, writeTaskCount=9 tableCount=1000 maxBatchSize=2000 - 17:01:01.286 [WriteThread-0] INFO c.taos.example.highvolume.WriteTask - started - 17:01:01.354 [WriteThread-1] INFO c.taos.example.highvolume.WriteTask - started - 17:01:01.360 [WriteThread-2] INFO c.taos.example.highvolume.WriteTask - started - 17:01:01.366 [WriteThread-3] INFO c.taos.example.highvolume.WriteTask - started - 17:01:01.433 [WriteThread-4] INFO c.taos.example.highvolume.WriteTask - started - 17:01:01.438 [WriteThread-5] INFO c.taos.example.highvolume.WriteTask - started - 17:01:01.443 [WriteThread-6] INFO c.taos.example.highvolume.WriteTask - started - 17:01:01.448 [WriteThread-7] INFO c.taos.example.highvolume.WriteTask - started - 17:01:01.454 [WriteThread-8] INFO c.taos.example.highvolume.WriteTask - started - 17:01:01.454 [ReadThread-0] INFO com.taos.example.highvolume.ReadTask - started - 17:01:11.615 [main] INFO c.t.e.highvolume.FastWriteExample - count=18766442 speed=1876644 - 17:01:21.775 [main] INFO c.t.e.highvolume.FastWriteExample - count=38947464 speed=2018102 - 17:01:32.428 [main] INFO c.t.e.highvolume.FastWriteExample - count=58649571 speed=1970210 - 17:01:42.577 [main] INFO c.t.e.highvolume.FastWriteExample - count=79264890 speed=2061531 - 17:01:53.265 [main] INFO c.t.e.highvolume.FastWriteExample - count=99097476 speed=1983258 - 17:02:04.209 [main] INFO c.t.e.highvolume.FastWriteExample - count=119546779 speed=2044930 - 17:02:14.935 [main] INFO c.t.e.highvolume.FastWriteExample - count=141078914 speed=2153213 - 17:02:25.617 [main] INFO c.t.e.highvolume.FastWriteExample - count=162183457 speed=2110454 - 17:02:36.718 [main] INFO c.t.e.highvolume.FastWriteExample - count=182735614 speed=2055215 - 17:02:46.988 [main] INFO c.t.e.highvolume.FastWriteExample - count=202895614 speed=2016000 + root@vm85$ java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample 2 12 + 18:56:35.896 [main] INFO c.t.e.highvolume.FastWriteExample - readTaskCount=2, writeTaskCount=12 tableCount=1000 maxBatchSize=3000 + 18:56:36.011 [WriteThread-0] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.015 [WriteThread-0] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.021 [WriteThread-1] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.022 [WriteThread-1] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.031 [WriteThread-2] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.032 [WriteThread-2] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.041 [WriteThread-3] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.042 [WriteThread-3] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.093 [WriteThread-4] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.094 [WriteThread-4] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.099 [WriteThread-5] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.100 [WriteThread-5] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.100 [WriteThread-6] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.101 [WriteThread-6] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.103 [WriteThread-7] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.104 [WriteThread-7] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.105 [WriteThread-8] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.107 [WriteThread-8] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.108 [WriteThread-9] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.109 [WriteThread-9] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.156 [WriteThread-10] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.157 [WriteThread-11] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.158 [WriteThread-10] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.158 [ReadThread-0] INFO com.taos.example.highvolume.ReadTask - started + 18:56:36.158 [ReadThread-1] INFO com.taos.example.highvolume.ReadTask - started + 18:56:36.158 [WriteThread-11] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:46.369 [main] INFO c.t.e.highvolume.FastWriteExample - count=18554448 speed=1855444 + 18:56:56.946 [main] INFO c.t.e.highvolume.FastWriteExample - count=39059660 speed=2050521 + 18:57:07.322 [main] INFO c.t.e.highvolume.FastWriteExample - count=59403604 speed=2034394 + 18:57:18.032 [main] INFO c.t.e.highvolume.FastWriteExample - count=80262938 speed=2085933 + 18:57:28.432 [main] INFO c.t.e.highvolume.FastWriteExample - count=101139906 speed=2087696 + 18:57:38.921 [main] INFO c.t.e.highvolume.FastWriteExample - count=121807202 speed=2066729 + 18:57:49.375 [main] INFO c.t.e.highvolume.FastWriteExample - count=142952417 speed=2114521 + 18:58:00.689 [main] INFO c.t.e.highvolume.FastWriteExample - count=163650306 speed=2069788 + 18:58:11.646 [main] INFO c.t.e.highvolume.FastWriteExample - count=185019808 speed=2136950 ```
-## Python 示例程序 {#python-demo} + + -该 Python 示例程序中采用了多进程的架构,并使用了跨进程的队列通信。写任务采用拼装 SQL 的方式写入。 -### main 函数 {#python-demo-main} +**程序清单** + +Python 示例程序中采用了多进程的架构,并使用了跨进程的消息队列。 + +| 函数或类 | 功能说明 | +| ------------------------ | -------------------------------------------------------------------- | +| main 函数 | 程序入口, 创建各个子进程和消息队列 | +| run_monitor_process 函数 | 创建数据库,超级表,统计写入速度并定时打印到控制台 | +| run_read_task 函数 | 读进程主要逻辑,负责从其它数据系统读数据,并分发数据到为之分配的队列 | +| MockDataSource 类 | 模拟数据源, 实现迭代器接口,每次批量返回每张表的接下来 1000 条数据 | +| run_write_task 函数 | 写进程主要逻辑。每次从队列中取出尽量多的数据,并批量写入 | +| SQLWriter类 | SQL 写入和自动建表 | +| StmtWriter 类 | 实现参数绑定方式批量写入(暂未完成) | + + +
+main 函数 main 函数负责创建消息队列和启动子进程,子进程有 3 类: @@ -202,76 +296,62 @@ main 函数可以接收 5 个启动参数,依次是: 4. 队列大小(单位字节),默认为 1000000 5. 每批最多写入记录数量, 默认为 3000 -
- -main 函数 - ```python -{{#include docs/examples/python/highvolume_faster_queue.py:main}} +{{#include docs/examples/python/fast_write_example.py:main}} ```
-### 监控进程 +
+run_monitor_process 监控进程负责初始化数据库,并监控当前的写入速度。 -
-Monitor Process - ```python -{{#include docs/examples/python/highvolume_faster_queue.py:monitor}} +{{#include docs/examples/python/fast_write_example.py:monitor}} ```
-### 读进程 {#python-read-process} - -#### 读进程主要逻辑 {#python-run-read-task} - -读进程,负责从其它数据系统读数据,并分发数据到各个写进程。 -
run_read_task 函数 +读进程,负责从其它数据系统读数据,并分发数据到为之分配的队列。 + ```python -{{#include docs/examples/python/highvolume_faster_queue.py:read}} +{{#include docs/examples/python/fast_write_example.py:read}} ```
-#### 模拟数据源 {#python-mock-data-source} - -以下是模拟数据源的实现,我们假设数据源生成的每一条数据都带有目标表名信息。实际中你可能需要一定的规则确定目标表名。 -
+ MockDataSource +以下是模拟数据源的实现,我们假设数据源生成的每一条数据都带有目标表名信息。实际中你可能需要一定的规则确定目标表名。 + ```python -{{#include docs/examples/python/highvolume_faster_queue.py:MockDataSource}} +{{#include docs/examples/python/mockdatasource.py}} ```
-### 写进程 {#python-write-process} - -写进程每次从队列中取出尽量多的数据,并批量写入。 -
run_write_task 函数 +写进程每次从队列中取出尽量多的数据,并批量写入。 + ```python -{{#include docs/examples/python/highvolume_faster_queue.py:write}} +{{#include docs/examples/python/fast_write_example.py:write}} ``` -
- -### SQLWriter 类的实现 {#python-sql-writer} -SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提前创建,而是写入出错的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。这个类也对 SQL 是否超过最大长度限制做了检查,如果接近 SQL 最大长度限制(maxSQLLength),将会立即执行 SQL。为了减少 SQL 执行次数,建议将 maxSQLLength 适当调大。 +
+SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提前创建,而是在发生表不存在错误的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。对于其它错误会记录当时执行的 SQL, 以便排查错误和故障恢复。这个类也对 SQL 是否超过最大长度限制做了检查,如果接近 SQL 最大长度限制(maxSQLLength),将会立即执行 SQL。为了减少 SQL 此时,建议将 maxSQLLength 适当调大。 + SQLWriter ```python @@ -280,62 +360,73 @@ SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提
-### 执行示例程序 {#run-python-demo} +**执行步骤**
执行 Python 示例程序 1. 前提条件 + - 已安装 TDengine 客户端驱动 - 已安装 Python3, 推荐版本 >= 3.8 - 已安装 taospy 2. 安装 faster-fifo 代替 python 内置的 multiprocessing.Queue + ``` pip3 install faster-fifo ``` -3. 点击上面的“查看源码”链接复制 `highvolume_faster_queue.py` 和 `sql_writer.py` 两个文件。 +3. 点击上面的“查看源码”链接复制 `fast_write_example.py` 、 `sql_writer.py` 和 `mockdatasource.py` 三个文件。 4. 执行示例程序 - + ``` - python3 highvolume_faster_queue.py + python3 fast_write_example.py ``` -下面是一次实际运行的输出: + 下面是一次实际运行的输出: -``` -[testuser@vm95 python]$ python3.6 highvolume_faster_queue.py 9 9 1000 5000000 3000 -2022-07-13 10:05:50,504 [root] - READ_TASK_COUNT=9, WRITE_TASK_COUNT=9, TABLE_COUNT=1000, QUEUE_SIZE=5000000, MAX_BATCH_SIZE=3000 -2022-07-13 10:05:53,542 [root] - WriteTask-0 started with pid 5475 -2022-07-13 10:05:53,542 [root] - WriteTask-1 started with pid 5476 -2022-07-13 10:05:53,543 [root] - WriteTask-2 started with pid 5477 -2022-07-13 10:05:53,543 [root] - WriteTask-3 started with pid 5478 -2022-07-13 10:05:53,544 [root] - WriteTask-4 started with pid 5479 -2022-07-13 10:05:53,544 [root] - WriteTask-5 started with pid 5480 -2022-07-13 10:05:53,545 [root] - WriteTask-6 started with pid 5481 -2022-07-13 10:05:53,546 [root] - WriteTask-7 started with pid 5482 -2022-07-13 10:05:53,546 [root] - WriteTask-8 started with pid 5483 -2022-07-13 10:05:53,547 [root] - ReadTask-0 started with pid 5484 -2022-07-13 10:05:53,548 [root] - ReadTask-1 started with pid 5485 -2022-07-13 10:05:53,549 [root] - ReadTask-2 started with pid 5486 -2022-07-13 10:05:53,550 [root] - ReadTask-3 started with pid 5487 -2022-07-13 10:05:53,551 [root] - ReadTask-4 started with pid 5488 -2022-07-13 10:05:53,552 [root] - ReadTask-5 started with pid 5489 -2022-07-13 10:05:53,552 [root] - ReadTask-6 started with pid 5490 -2022-07-13 10:05:53,553 [root] - ReadTask-7 started with pid 5491 -2022-07-13 10:05:53,554 [root] - ReadTask-8 started with pid 5492 -2022-07-13 10:06:00,842 [DataBaseMonitor] - count=6612939 speed=661293.9 -2022-07-13 10:06:11,151 [DataBaseMonitor] - count=14765739 speed=815280.0 -2022-07-13 10:06:21,677 [DataBaseMonitor] - count=23282163 speed=851642.4 -2022-07-13 10:06:31,985 [DataBaseMonitor] - count=31673139 speed=839097.6 -2022-07-13 10:06:42,343 [DataBaseMonitor] - count=39819439 speed=814630.0 -2022-07-13 10:06:52,830 [DataBaseMonitor] - count=48146339 speed=832690.0 -2022-07-13 10:07:03,396 [DataBaseMonitor] - count=56385039 speed=823870.0 -2022-07-13 10:07:14,341 [DataBaseMonitor] - count=64848739 speed=846370.0 -2022-07-13 10:07:24,877 [DataBaseMonitor] - count=73654566 speed=880582.7 -``` + ``` + root@vm85$ python3 fast_write_example.py 8 8 + 2022-07-14 19:13:45,869 [root] - READ_TASK_COUNT=8, WRITE_TASK_COUNT=8, TABLE_COUNT=1000, QUEUE_SIZE=1000000, MAX_BATCH_SIZE=3000 + 2022-07-14 19:13:48,882 [root] - WriteTask-0 started with pid 718347 + 2022-07-14 19:13:48,883 [root] - WriteTask-1 started with pid 718348 + 2022-07-14 19:13:48,884 [root] - WriteTask-2 started with pid 718349 + 2022-07-14 19:13:48,884 [root] - WriteTask-3 started with pid 718350 + 2022-07-14 19:13:48,885 [root] - WriteTask-4 started with pid 718351 + 2022-07-14 19:13:48,885 [root] - WriteTask-5 started with pid 718352 + 2022-07-14 19:13:48,886 [root] - WriteTask-6 started with pid 718353 + 2022-07-14 19:13:48,886 [root] - WriteTask-7 started with pid 718354 + 2022-07-14 19:13:48,887 [root] - ReadTask-0 started with pid 718355 + 2022-07-14 19:13:48,888 [root] - ReadTask-1 started with pid 718356 + 2022-07-14 19:13:48,889 [root] - ReadTask-2 started with pid 718357 + 2022-07-14 19:13:48,889 [root] - ReadTask-3 started with pid 718358 + 2022-07-14 19:13:48,890 [root] - ReadTask-4 started with pid 718359 + 2022-07-14 19:13:48,891 [root] - ReadTask-5 started with pid 718361 + 2022-07-14 19:13:48,892 [root] - ReadTask-6 started with pid 718364 + 2022-07-14 19:13:48,893 [root] - ReadTask-7 started with pid 718365 + 2022-07-14 19:13:56,042 [DataBaseMonitor] - count=6676310 speed=667631.0 + 2022-07-14 19:14:06,196 [DataBaseMonitor] - count=20004310 speed=1332800.0 + 2022-07-14 19:14:16,366 [DataBaseMonitor] - count=32290310 speed=1228600.0 + 2022-07-14 19:14:26,527 [DataBaseMonitor] - count=44438310 speed=1214800.0 + 2022-07-14 19:14:36,673 [DataBaseMonitor] - count=56608310 speed=1217000.0 + 2022-07-14 19:14:46,834 [DataBaseMonitor] - count=68757310 speed=1214900.0 + 2022-07-14 19:14:57,280 [DataBaseMonitor] - count=80992310 speed=1223500.0 + 2022-07-14 19:15:07,689 [DataBaseMonitor] - count=93805310 speed=1281300.0 + 2022-07-14 19:15:18,020 [DataBaseMonitor] - count=106111310 speed=1230600.0 + 2022-07-14 19:15:28,356 [DataBaseMonitor] - count=118394310 speed=1228300.0 + 2022-07-14 19:15:38,690 [DataBaseMonitor] - count=130742310 speed=1234800.0 + 2022-07-14 19:15:49,000 [DataBaseMonitor] - count=143051310 speed=1230900.0 + 2022-07-14 19:15:59,323 [DataBaseMonitor] - count=155276310 speed=1222500.0 + 2022-07-14 19:16:09,649 [DataBaseMonitor] - count=167603310 speed=1232700.0 + 2022-07-14 19:16:19,995 [DataBaseMonitor] - count=179976310 speed=1237300.0 + ```
+ + + + + diff --git a/docs/zh/07-develop/03-insert-data/highvolume.webp b/docs/zh/07-develop/03-insert-data/highvolume.webp index 9f8c9a9cc161e382728750bdfcc93ee086d62aea..46dfc74ae3b0043c591ff930c62251da49cae7ad 100644 GIT binary patch literal 7308 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 literal 6746 zcmV-g8l~k@Nk&Fe8UO%SMM6+kP&iCR8UO$CyO#QS9WVGMWL42`pl&ux?cKFR}Ie{7On)TcT`BO+qP}nwr$(C zZQHhOTQfZ~-M{|Lbnox?$8J)#ZQC}!x!RL!&t+`e+SuBvI5|~waa7SKwr$(C9VdrkEMKJux%0)RvfOGBYzXLk&%aY%w!4v#ieiMMRdW zLKT%_W(J$dV`lwQ%&fJR$4g*MvKBM5CFn6~ae7^A^!b%wYb(O08Y`^z7P4hYx6h8T4hx_4?B#YFM)pLu^%VZF zTC{HAQcO-WA8f%+BUSe3P0=?ww^0n9*pYJP@TDUv`?vx44da!imw%5-IBNOIL&*dGXtBhm1;V+_B+aiJTUOBe!b*9-?6 z!*?wD*^M;C2YLd_Y8Vq40k^6Ll#fFvE^*-i@XqwHgC3g_%kN?2dEy>KL|uOT$Q;A> zajG|Kv|I!gG;JCPG}j1N*N9F>lu+sC37V$}27*Y;n=%<2pHiSg-0JYbd6Uq6GiHvE z7J!b&v$-z5Ha(|=Ka zWV{pTu5aqCz(>$XGZfGy5FJ(&4chRyk>c)GILYbN)T>hMD|*N#5D-skI^yw{ah+or zM7gOZ5>w^1f{u^?<}5xn+N*(ewRen4u(PCKqZUsR45WP7&?%0yn4tSdDZ8MuVe*DBe(9M~^#`TwdP2eLihou0LK+N(u2gQ-hF?<6T zdIwou%|SQ4Az;M|JQnplz%kyII?ckB>a=z$WpJ1PzlLAq(QV~eUe{!Hane#sEjsY* z;jtdC*HV#US?r_*h!h7Lyc+aSAD`LuQPdwDFNx`62jNW~_G;j-+~$%Y$c3$`p$hg@ z4Kl2e)42}rBf4=TKfpy_m)U{p#T+zzJn!a7*yF6xUnMKS7qwi(A)n_N>Oz!yLz?^A zRWHP3kOpLPzyZGQriP~{@wc1)o4E%a*e)`lV_(lp=&MY1JQIizx(Atr9Z&A#x5viE zG-~Z3bzry$+q4-7h#*J6PqheQqv3xhab3akzkN7vh)aA3_Btq{lP6bEnh8>dM#5ivM2K3@1X4)i89%Y5uG z-DXMoo_EzG0b5(J9GmPX36LgHslyB#Yt4Hcu-8G6oxGxAG>#Kh`UFP7yA9yr!4vmj zYPenZP~!sW(Pj8d&YlXm;p0*xk)98I-{6<2;p_O@WBHG`beB-+0NDiyINwca=RzAF zq-{VJnoF(ui0Cjb05P!(93M0Rh>mrDG%#EU^f5#NEzjh{m$TO9_CCf* zZkGBeb>-wEkH^x}mBz)URRdrIzeRm7=>ub(S>Hz~eP5k-1oqeR{@QZ|gY&WAPiQc= z_bv`FH01kIiskqy52*lj4PEG)=<=ZM+fa+HnZp>XeMGn!07fU7H+m4|??mnl$dD4L zkq&XYj!UiSzKw`rxbV2w1;iEolwpI?@2h_`xSk3%6IgTQf4HyTAP4WsnIII zz!-1Wyl70YG3c~*IN+=4;tX{`L=`84Sj@8VVL9Xoc54XE_e>5GD)gl~l3*|HE0+JoFq*B zEa(VRzHAt`_$nB|PjmNRE?t;vA~8$K_fHTEe7F+Sl+y6=6wff`($!g#u(9&qlWZ{E zd+bdEj5*m~(X~!e(hR1CnD%-7i!m6tzn5q(8Qv1{& z?C0cHJ84|wx6&Yp~?PG?JIFzZY9x&+63=U?h`ZV%{d7_f+%Xp^%HM@-kz2cFVbrqkv-TWY>d@KhK%PC_O62qxdbSVBDej06f>l4f(~)CmX^BnTl=whs5T?r~tCw`&<_< zmOB zd5x_QuB()UP88dz_NcG)v+xTYK5vp(X@45c+sl2$`|)T z;pxWb?A;P=k)#f-y=o;XdK zg4^v)SSdly&uv+t3yFR67h}n%4PE6L8`DM651>_ciaAkx3S|q8*sEsLI zc;01yCVFC9)-(l`iC1yL$J(@R+eHXi1VRC=5De_15VjLC+s8V;7Evl9yFDX`KN9m6 zP358^w$*{=pi+UCv387itYeX@8q_KVC7`WlBsLBcF=6&W6vVc=&=OPv5Iz;78IM*e z8tdA&O`u=323-s(KxAUujTCEJ{b-xO6anM_5sPj0q6{4U4I~QPa%EcBu5CG>8)D@bkO#0?+m^ti{4|sI-5nAER%=^c=!J!{12O^4 zYulj!Pt^y@Wd)=MdDW@fJ1Vw@LMCXLy8OmgeJuBXt-+v zrtt}KX##26DMl4h14|n%6&(OODLdcwOk#g+%P*s`(E$Sk5eoI1Ww$+;%~99nmdSHyySC+;vB-oZ=pTqpY+r|)@r#d$5Gqqi6|l5X(Xqqe zx5tJ{s`nv;L?~VYxtSvSFk`#078u%~R!SP^jatX1*T_1pUT2B%ZNF@l4txhW z@NQ2)jN0o|f|8)cAxA*=B+NYkS3zk|GeDLw zHXB_(Jb?NjDtpR?ngG%S3{7%m0swA;@}Wk6L;-yfAGrYV5>yQNL#lwT2+Je@A3^2N zv5+jFE$DQBhoEYxb|76qlhFHs{y_~;%|Luo9@!l@Nqk<_TjBZnApH!`JE#S!9tcpX z2aVIjrx*cm_!`fugc<|TH>d+zL5Nz-YbRu?Axn5J$^XB&StR~7u9X3`2B2qfBUOeN zwVJn%P1-BVY0+s;tN;9(3440669N5#d#NHssnxvNlvazf1ZO2FWiPL>Uo&I5b4Bj} zdIeFaJcOy$yesU3h31i0HKwJnnX}AEn!y3|3HGD15U5u3RyPxNEz0_bxE!-Y9a`IC zJZ6%SIU{XG2hbyE7CK$1TFtxSUb`ByPJ7p%1+?#5o*#a?$&+6*Z38oDHUQ8epn0PT zR;zjI*kn5)^O_UOBS%0xsJYdytJC@{gkhEzgu2Xfb>W5d?!{51kJY@62+GCGX^X%V ziS^ZW3#7vJWM~Q6kTEYRXSuQy$QzU`2-*H`4$ZOv;2@AUU^n`lQ5+vt5y%?w zG9Af`u8D;_005PNbiqywLPqSOoaIVGAY;I?5m}oFJ+n~u0D#6oqF}cLA&XhAzRVf` zU=YX>?6)A)KFd|2WR7)~D@K7-0Yj5K88bc_@p)!W#Vl8P1wI~`aSif6{c|p8V-PNx zW>f$`zhE1WAz00$N*nQxFXz*9S}L-D{;!wpS`fxaiPc5~0CWuE;yaJ)u$rg0WfQ%G zADOlN(5v=gEmbwIEvOVU%yN|)|5VI!rDt#z(Vjns@)8b-#v#+w^lAMHCw8&L(XkvYM)zS0xlh4eQOBBm)3T=^Vrgk@e1X zTg_t{ECyTVljT#@JSHs&$0Ktd=m+RuyZHJk?+n3eo>G4q$#Xw*wdGUQJT@%|v*t@4 zX1Q`F$6{oySHG)2{x<@vc}m0oOy_)wW4vASq7_xuygZ1D-f%d}RnKs7|Ei6IBuY0T zw{B?wR`af$WB838_gX$x&12GnFc;!r7as0Ygosih2VQP~$ZkWhn)imuM|v>j%Z3mj zte>jpv1mbf$ogHw#W5Aj+jIF=^EguhhW=IRGznK$RaNr_CULUHmV5}$iKfG9-dO{6 z&f&Ol&5KG|R#naWscj3w%}(tI(_uC5tXBwNX8c;}qm;6)s+xDjuZuxB%T;^mdZe;L z4($OOjKpeQ_qn97-j5DZESCkA)x4IVasY}X5N)CJj|>qJ`Tj0LqF2c59{~noHSe3%3rJ+0fR|c>X$QLz z53^kPhs008sUBF6Csy-HgQ!_J_~2_{uDPsq09*`8DWS;))FhS`ggP@K)srlgI592w zL#j|7)F_G;gnDw;3_*!N$@I#yMD#MG3KgOJ|Cj>_(I2|e2pK{5)WtXe89=Wt3#r0i zs2*VD1xpJ;ea`#cD{d%1BHQ$yH~>%Pm!yoMyJy zf-rt^hA~^$%)FE(P2-@)piJR82eVwA^&L~^5Nj91V&9d3gKK8vflT2oTETG(LS{5U zrUW1rYQu5+Ynj50^cNK^2rGfj7EQCCKnp|#AaC%eiUFX*G=fp{f=-y7QA0w3V>Qq4 z*pZ^CZ9%AwF*xW`$_#eXiwhj9c}54Rp5>}cG+hIY8Gn1nViz-P5hHS}<{2E#LU$=X zBBs*_zUHPBd2VYkERkb1&)8U;N#}JVT>R0x<(LF$#{R5q#kfXV5EAz^p`&)jUJvMZZE}*n$w3EODOS z3@rP93LvX_2G`^)6q_+g6i`NG6rm$e1qP*lOB zlnX0E9#vPw!Xd0$5a!Qj6bEI~FOW#J_H6$H6UOKBNhx6(1X8Jf`tHMEL7&{Ue$2wS zjy@N67?KC--bs*enY`A+^h`Aj2T&o@EW!>W@<81;iL&T;Xl6K8ND|7CmVu(K+c&DH z!+< z@pzz)@w**P(Kc1!1#v(H(FqPem=`kO`VU1MhU0;H82*_$!=mZxFzili-S#V0AFZVY zp?Je^JW!87TBO8~XxkY>wp^?F#Gn&)7j77i2kMokNsd8*TDs=xphV;!4z~n!)Phj3 zVK^SB*L&p|A5A-B&^R{kRP+x)gGuPuHf!cgs&bYqpK^&C`l3UixtfBmlsII~mwljq zXAEoxdHe&_g0vxf;-weV?2Mr%=B1O_S--fAqDUHc_w4~SJ7WmJcO}4dw6g7}Riq4g zu;*EDMB`)%rAqCv_AENXVx1yk_~UuEINTXSe9!_KcE+x)1)+3d+0eY_aAyn&u&GW{ z8ZY|H#*&3eg3~_scgAo%Wk!=guUhGz9Y#Z{@N{6NvcEHiP`thibgYZkx?QGVcb2Qy z7Nr!KS?_w3QyArZlwk>?}3_;L+>*=Tx@2!>Xnk&#;+*40X)@z z>2t@3dJohIL>Kd3)Ici{Jz*VVgK`7uoP;(A4LuF76ob&+YO6!2bx{jjS ze?qi-pyoZGavs&3my{Od`xvkN$~Lp#f>6MFpyoYH9GL%p8}8qr444>PmHHNhLf!*4 z@8Nhns+t|*`gHcZxE(lV9QHZpLuD-HJy3`FcyOJz&P%RTG;3)=DC#{>^B*Qo^e;{V zZ7m2zzX$3hqGNj28sEWL;V2l0eGk+OX{N>z0nUTAp?`>e57a(}1Mfjhx>90v8{|It z1I;Wi;6JDeiXts=f}l+3J6VA<1T%cpDUt%G2=e66-jEZp4|HomC?#MLMAe^_?pf_z z8G(}oPpoyjjDTgJdkaDdfzt%<`4x?Pza@Z7R5AkT`pufI;5E8Z9AUnKKhVs= z2on~3O*@Jr%vf*%eJ6-8H-YvRgd-q$FlWK#zP+M!0VQ}aLxF}Cgl_T?JD8+EZ3{ww z@)tXpwV(^W%nINcdRXjW+JZYGv4DptGzQ>-y63Wbdc#7l{00UQHHn&QKRgs|=VevJ7Atj_wjf0)5Jcox072AKiz;w0fX^@DdGk`kAtzMHVlRD@a*M5cJg%e{#@Ic+PDjd3DlmI6EHB@q12Wobq zVr2o2JW%huZ^!@x@IYO4=oP^LV*2M5*-B>XK%J0@UHI}qok}dSu9vRg19hd*nOTys zpXJJLVA^NcX%;TCb)W|NTsgorc%bH$f_l0aE3{lBuXUjI;3$a{U@kmRGw%*vA)|Gm zrsV@HiJvl4dK5%f>p<-zy0WlfHat+bsU91&?AH*~))!%IjIX^yQtLoX%W`D3RuYTH=+r|9Jb4xBtW#02MKwtpET3 -- GitLab From 3581dc3d879a693561aa258cce688e539f501257 Mon Sep 17 00:00:00 2001 From: dingbo Date: Fri, 15 Jul 2022 09:41:45 +0800 Subject: [PATCH 157/380] docs: delete highvolume_mp_queue.py --- docs/examples/python/highvolume_mp_queue.py | 193 -------------------- 1 file changed, 193 deletions(-) delete mode 100644 docs/examples/python/highvolume_mp_queue.py diff --git a/docs/examples/python/highvolume_mp_queue.py b/docs/examples/python/highvolume_mp_queue.py deleted file mode 100644 index f6605adb0f..0000000000 --- a/docs/examples/python/highvolume_mp_queue.py +++ /dev/null @@ -1,193 +0,0 @@ -# import logging -# import sys -# import time -# from multiprocessing import Queue, Process -# from queue import Empty -# from typing import List -# -# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format="%(asctime)s [%(name)s] - %(message)s") -# -# READ_TASK_COUNT = 1 -# WRITE_TASK_COUNT = 1 -# QUEUE_SIZE = 1000 -# TABLE_COUNT = 1000 -# MAX_BATCH_SIZE = 3000 -# -# read_processes = [] -# write_processes = [] -# -# -# # ANCHOR: DataBaseMonitor -# class DataBaseMonitor: -# """ -# Start a thread. -# Prepare database and stable. -# Statistic writing speed and print it every 10 seconds. -# """ -# -# def __init__(self): -# self.process = Process(target=self.run) -# self.process.start() -# -# def get_connection(self): -# import taos -# return taos.connect(host="localhost", user="root", password="taosdata", port=6030) -# -# def prepare_database(self, conn): -# conn.execute("DROP DATABASE IF EXISTS test") -# conn.execute("CREATE DATABASE test") -# conn.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)") -# -# def get_count(self, conn): -# res = conn.query("SELECT count(*) FROM test.meters") -# rows = res.fetch_all() -# return rows[0][0] if rows else 0 -# -# def run(self): -# log = logging.getLogger("DataBaseMonitor") -# conn = self.get_connection() -# self.prepare_database(conn) -# last_count = 0 -# while True: -# time.sleep(10) -# count = self.get_count(conn) -# log.info(f"count={count} speed={(count - last_count) / 10}") -# last_count = count -# -# def join(self): -# self.process.join() -# -# def stop(self): -# self.process.terminate() -# -# -# # ANCHOR_END: DataBaseMonitor -# -# # ANCHOR: MockDataSource -# class MockDataSource: -# location = ["LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"] -# current = [8.8, 10.7, 9.9, 8.9, 9.4] -# voltage = [119, 116, 111, 113, 118] -# phase = [0.32, 0.34, 0.33, 0.329, 0.141] -# max_rows_per_table = 10 ** 9 -# -# def __init__(self, tb_name_prefix, table_count): -# self.table_name_prefix = tb_name_prefix -# self.table_count = table_count -# self.start_ms = round(time.time() * 1000) - self.max_rows_per_table * 100 -# -# def __iter__(self): -# self.row = 0 -# self.table_id = -1 -# return self -# -# def __next__(self): -# self.table_id += 1 -# if self.table_id == self.table_count: -# self.table_id = 0 -# self.row += 1 -# if self.row < self.max_rows_per_table: -# ts = self.start_ms + 100 * self.row -# group_id = self.table_id % 5 if self.table_id % 5 == 0 else self.table_id % 5 + 1 -# tb_name = self.table_name_prefix + '_' + str(self.table_id) -# ri = self.row % 5 -# return self.table_id, f"{tb_name},{ts},{self.current[ri]},{self.voltage[ri]},{self.phase[ri]},{self.location[ri]},{group_id}" -# else: -# raise StopIteration -# -# -# # ANCHOR_END: MockDataSource -# -# # ANCHOR: read -# def run_read_task(task_id: int, task_queues: List[Queue]): -# table_count_per_task = TABLE_COUNT // READ_TASK_COUNT -# data_source = MockDataSource(f"tb{task_id}", table_count_per_task) -# try: -# for table_id, line in data_source: -# i = table_id % len(task_queues) -# task_queues[i].put(line, block=True) -# except KeyboardInterrupt: -# pass -# -# -# # ANCHOR_END: read -# -# # ANCHOR: write -# def run_write_task(task_id: int, queue: Queue): -# from sql_writer import SQLWriter -# log = logging.getLogger(f"WriteTask-{task_id}") -# writer = SQLWriter(MAX_BATCH_SIZE) -# try: -# while True: -# try: -# line = queue.get(block=False) -# writer.process_line(line) -# except Empty: -# if writer.buffered_count > 0: -# writer.flush() -# else: -# time.sleep(0.01) -# except KeyboardInterrupt: -# pass -# except BaseException as e: -# msg = f"line={line}, buffer_count={writer.buffered_count}" -# log.debug(msg) -# raise e -# -# -# # ANCHOR_END: write -# -# def set_global_config(): -# argc = len(sys.argv) -# if argc > 1: -# global READ_TASK_COUNT -# READ_TASK_COUNT = int(sys.argv[1]) -# if argc > 2: -# global WRITE_TASK_COUNT -# WRITE_TASK_COUNT = int(sys.argv[2]) -# if argc > 3: -# global QUEUE_SIZE -# QUEUE_SIZE = int(sys.argv[3]) -# if argc > 4: -# global TABLE_COUNT -# TABLE_COUNT = int(sys.argv[4]) -# if argc > 5: -# global MAX_BATCH_SIZE -# MAX_BATCH_SIZE = int(sys.argv[5]) -# -# -# # ANCHOR: main -# def main(): -# set_global_config() -# logging.info(f"READ_TASK_COUNT={READ_TASK_COUNT}, WRITE_TASK_COUNT={WRITE_TASK_COUNT}, QUEUE_SIZE={QUEUE_SIZE}, TABLE_COUNT={TABLE_COUNT}, MAX_BATCH_SIZE={MAX_BATCH_SIZE}") -# -# database_monitor = DataBaseMonitor() -# time.sleep(3) # wait for database ready -# -# task_queues: List[Queue] = [] -# -# for i in range(WRITE_TASK_COUNT): -# queue = Queue(maxsize=QUEUE_SIZE) -# task_queues.append(queue) -# p = Process(target=run_write_task, args=(i, queue)) -# p.start() -# logging.debug(f"WriteTask-{i} started with pid {p.pid}") -# write_processes.append(p) -# -# for i in range(READ_TASK_COUNT): -# p = Process(target=run_read_task, args=(i, task_queues)) -# p.start() -# logging.debug(f"ReadTask-{i} started with pid {p.pid}") -# read_processes.append(p) -# -# try: -# database_monitor.join() -# except KeyboardInterrupt: -# database_monitor.stop() -# [p.terminate() for p in read_processes] -# [p.terminate() for p in write_processes] -# -# -# if __name__ == '__main__': -# main() -# # ANCHOR_END: main -- GitLab From 60a8970a84d294e6d8d0188bd012e7b34612ca3a Mon Sep 17 00:00:00 2001 From: dingbo Date: Fri, 15 Jul 2022 09:44:55 +0800 Subject: [PATCH 158/380] docs: update high-volume.md --- docs/zh/07-develop/03-insert-data/05-high-volume.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/07-develop/03-insert-data/05-high-volume.md b/docs/zh/07-develop/03-insert-data/05-high-volume.md index 24b57cee67..e43b225d77 100644 --- a/docs/zh/07-develop/03-insert-data/05-high-volume.md +++ b/docs/zh/07-develop/03-insert-data/05-high-volume.md @@ -386,7 +386,7 @@ SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提 python3 fast_write_example.py ``` - 下面是一次实际运行的输出: + 下面是一次实际运行的输出, 机器配置 16核 + 64G + 固态硬盘。 ``` root@vm85$ python3 fast_write_example.py 8 8 -- GitLab From 1b343540606b7906b9892e28bcf3e272e2621747 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 15 Jul 2022 13:42:31 +0800 Subject: [PATCH 159/380] chore: change upx download location for2.6 (#14936) * chore: update taosadapter for 2.6 * chore: change upx download location --- src/plugins/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index aeb7f538ce..6733b604fa 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -63,7 +63,7 @@ ELSE () COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../inc CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -ldflags "-s -w -X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}" COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../inc CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -o taosadapter-debug -ldflags "-X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}" INSTALL_COMMAND - COMMAND curl -sL https://github.com/upx/upx/releases/download/v3.96/upx-3.96-${PLATFORM_ARCH_STR}_linux.tar.xz -o upx.tar.xz && tar -xvJf upx.tar.xz -C ${CMAKE_BINARY_DIR} --strip-components 1 > /dev/null && ${CMAKE_BINARY_DIR}/upx taosadapter || : + COMMAND wget -c https://github.com/upx/upx/releases/download/v3.96/upx-3.96-${PLATFORM_ARCH_STR}_linux.tar.xz -O ${CMAKE_CURRENT_SOURCE_DIR}/upx.tar.xz && tar -xvJf ${CMAKE_CURRENT_SOURCE_DIR}/upx.tar.xz -C ${CMAKE_CURRENT_SOURCE_DIR} --strip-components 1 > /dev/null && ${CMAKE_CURRENT_SOURCE_DIR}/upx taosadapter || : COMMAND cmake -E copy taosadapter ${CMAKE_BINARY_DIR}/build/bin COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/test/cfg/ COMMAND cmake -E copy ./example/config/taosadapter.toml ${CMAKE_BINARY_DIR}/test/cfg/ -- GitLab From 72ecefbbb7ec6c3616fee67f340eecefecbe1c37 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 15 Jul 2022 17:57:46 +0800 Subject: [PATCH 160/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index bd496f76b6..d807c3ffa6 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit bd496f76b64931c66da2f8b0f24143a98a881cde +Subproject commit d807c3ffa6f750f7765e102917d1328cadf21c13 -- GitLab From 141eefb38ec51f83024de508fe533cd04bfaa502 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 15 Jul 2022 18:41:30 +0800 Subject: [PATCH 161/380] feat: update taostools for2.6 (#14962) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index bd496f76b6..d807c3ffa6 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit bd496f76b64931c66da2f8b0f24143a98a881cde +Subproject commit d807c3ffa6f750f7765e102917d1328cadf21c13 -- GitLab From ef242d0a8721685138fd5a784c3652ef233b5d92 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 16 Jul 2022 16:20:34 +0800 Subject: [PATCH 162/380] feat(shell): autotab push to 2.6 branch --- src/kit/shell/inc/shellAuto.h | 37 + src/kit/shell/inc/shellCommand.h | 2 + src/kit/shell/inc/tire.h | 92 ++ src/kit/shell/src/shellAuto.c | 1744 ++++++++++++++++++++++++++++++ src/kit/shell/src/shellCommand.c | 17 +- src/kit/shell/src/shellEngine.c | 491 +++++---- src/kit/shell/src/shellLinux.c | 18 +- src/kit/shell/src/shellMain.c | 22 +- src/kit/shell/src/tire.c | 434 ++++++++ src/tsdb/src/tsdbMain.c | 2 +- src/util/inc/tthread.h | 2 +- src/util/src/tthread.c | 2 +- src/vnode/src/vnodeMain.c | 2 +- 13 files changed, 2623 insertions(+), 242 deletions(-) create mode 100644 src/kit/shell/inc/shellAuto.h create mode 100644 src/kit/shell/inc/tire.h create mode 100644 src/kit/shell/src/shellAuto.c create mode 100644 src/kit/shell/src/tire.c diff --git a/src/kit/shell/inc/shellAuto.h b/src/kit/shell/inc/shellAuto.h new file mode 100644 index 0000000000..0bd6bdf403 --- /dev/null +++ b/src/kit/shell/inc/shellAuto.h @@ -0,0 +1,37 @@ +/* + * 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 __SHELL_AUTO__ +#define __SHELL_AUTO__ + +#define TAB_KEY 0x09 + +// press tab key +void pressTabKey(TAOS * con, Command * cmd); + +// press othr key +void pressOtherKey(char c); + +// init shell auto funciton , shell start call once +bool shellAutoInit(); + +// exit shell auto funciton, shell exit call once +void shellAutoExit(); + +// callback autotab module +void callbackAutoTab(char* sqlstr, TAOS* pSql, bool usedb); + + +#endif diff --git a/src/kit/shell/inc/shellCommand.h b/src/kit/shell/inc/shellCommand.h index 6e4d3e382e..47ef6b30a9 100644 --- a/src/kit/shell/inc/shellCommand.h +++ b/src/kit/shell/inc/shellCommand.h @@ -41,6 +41,7 @@ extern void deleteChar(Command *cmd); extern void moveCursorLeft(Command *cmd); extern void moveCursorRight(Command *cmd); extern void positionCursorHome(Command *cmd); +extern void positionCursorMiddle(Command *cmd); extern void positionCursorEnd(Command *cmd); extern void showOnScreen(Command *cmd); extern void updateBuffer(Command *cmd); @@ -51,5 +52,6 @@ int countPrefixOnes(unsigned char c); void clearScreen(int ecmd_pos, int cursor_pos); void printChar(char c, int times); void positionCursor(int step, int direction); +void getPrevCharSize(const char *str, int pos, int *size, int *width); #endif diff --git a/src/kit/shell/inc/tire.h b/src/kit/shell/inc/tire.h new file mode 100644 index 0000000000..88bae54809 --- /dev/null +++ b/src/kit/shell/inc/tire.h @@ -0,0 +1,92 @@ +/* + * 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 __TRIE__ +#define __TRIE__ + +// +// The prefix search tree is a efficient storage words and search words tree, it support 95 visible ascii code character +// +#define FIRST_ASCII 40 // first visiable char is '0' +#define LAST_ASCII 122 // last visilbe char is 'z' + +// capacity save char is 95 +#define CHAR_CNT (LAST_ASCII - FIRST_ASCII + 1) +#define MAX_WORD_LEN 256 // max insert word length + +// define STire +#define TIRE_TREE 0 +#define TIRE_LIST 1 + +typedef struct STireNode { + struct STireNode** d; + bool end; // record end flag +}STireNode; + +typedef struct StrName { + char * name; + struct StrName * next; +}StrName; + + +typedef struct STire { + char type; // see define TIRE_ + STireNode root; + + StrName * head; + StrName * tail; + + int count; // all count + int ref; +}STire; + +typedef struct SMatchNode { + char* word; + struct SMatchNode* next; +}SMatchNode; + + +typedef struct SMatch { + SMatchNode* head; + SMatchNode* tail; // append node to tail + int count; + char pre[MAX_WORD_LEN]; +}SMatch; + + +// ----------- interface ------------- + +// create prefix search tree, return value call freeTire to free +STire* createTire(char type); + +// destroy prefix search tree +void freeTire(STire* tire); + +// add a new word +bool insertWord(STire* tire, char* word); + +// add a new word +bool deleteWord(STire* tire, char* word); + +// match prefix words, if match is not NULL , put all item to match and return match +SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match); + +// get all items from tires tree +SMatch* enumAll(STire* tire); + +// free match result +void freeMatch(SMatch* match); + +#endif diff --git a/src/kit/shell/src/shellAuto.c b/src/kit/shell/src/shellAuto.c new file mode 100644 index 0000000000..265bda2262 --- /dev/null +++ b/src/kit/shell/src/shellAuto.c @@ -0,0 +1,1744 @@ +/* + * 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 . + */ + +#define __USE_XOPEN +#include "os.h" +#include "tglobal.h" +#include "shell.h" +#include "shellCommand.h" +#include "tkey.h" +#include "tulog.h" +#include "shellAuto.h" +#include "tire.h" +#include "tthread.h" + +// +// ------------- define area --------------- +// +#define UNION_ALL " union all " + + +// extern function +void insertChar(Command *cmd, char *c, int size); + + +typedef struct SAutoPtr { + STire* p; + int ref; +}SAutoPtr; + +typedef struct SWord{ + int type ; // word type , see WT_ define + char * word; + int32_t len; + struct SWord * next; + bool free; // if true need free +}SWord; + +typedef struct { + char * source; + int32_t source_len; // valid data length in source + int32_t count; + SWord* head; + // matched information + int32_t matchIndex; // matched word index in words + int32_t matchLen; // matched length at matched word +}SWords; + + +SWords shellCommands[] = { + {"alter database ", 0, 0, NULL}, + {"alter dnode balance ", 0, 0, NULL}, + {"alter dnode resetlog;", 0, 0, NULL}, + {"alter dnode debugFlag 141;", 0, 0, NULL}, + {"alter dnode monitor 1;", 0, 0, NULL}, + {"alter table ", 0, 0, NULL}, + {"alter table modify column", 0, 0, NULL}, + {"alter topic", 0, 0, NULL}, + {"alter user pass", 0, 0, NULL}, + {"alter user privilege read", 0, 0, NULL}, + {"alter user privilege write", 0, 0, NULL}, + {"create table using tags(", 0, 0, NULL}, + {"create database ", 0, 0, NULL}, + {"create table as ", 0, 0, NULL}, + {"create dnode ", 0, 0, NULL}, + {"create topic", 0, 0, NULL}, + {"create function ", 0, 0, NULL}, + {"create user pass", 0, 0, NULL}, + {"compact vnode in", 0, 0, NULL}, + {"describe ", 0, 0, NULL}, +#ifdef TD_ENTERPRISE + {"delete from where", 0, 0, NULL}, +#endif + {"drop database ", 0, 0, NULL}, + {"drop dnode ", 0, 0, NULL}, + {"drop function", 0, 0, NULL}, + {"drop topic", 0, 0, NULL}, + {"drop table ;", 0, 0, NULL}, + {"drop user ;", 0, 0, NULL}, + {"kill connection", 0, 0, NULL}, + {"kill query", 0, 0, NULL}, + {"kill stream", 0, 0, NULL}, + {"select * from where ", 0, 0, NULL}, + {"select _block_dist() from \\G;", 0, 0, NULL}, + {"select client_version();", 0, 0, NULL}, + {"select current_user();", 0, 0, NULL}, + {"select database;", 0, 0, NULL}, + {"select server_version();", 0, 0, NULL}, + {"set max_binary_display_width ", 0, 0, NULL}, + {"show create database \\G;", 0, 0, NULL}, + {"show create stable \\G;", 0, 0, NULL}, + {"show create table \\G;", 0, 0, NULL}, + {"show connections;", 0, 0, NULL}, + {"show databases;", 0, 0, NULL}, + {"show dnodes;", 0, 0, NULL}, + {"show functions;", 0, 0, NULL}, + {"show modules;", 0, 0, NULL}, + {"show mnodes;", 0, 0, NULL}, + {"show queries;", 0, 0, NULL}, + {"show stables;", 0, 0, NULL}, + {"show stables like ", 0, 0, NULL}, + {"show streams;", 0, 0, NULL}, + {"show scores;", 0, 0, NULL}, + {"show tables;", 0, 0, NULL}, + {"show tables like", 0, 0, NULL}, + {"show users;", 0, 0, NULL}, + {"show variables;", 0, 0, NULL}, + {"show vgroups;", 0, 0, NULL}, + {"insert into values(", 0, 0, NULL}, + {"use ", 0, 0, NULL} +}; + +char * keywords[] = { + "and ", + "asc ", + "desc ", + "from ", + "fill(", + "limit ", + "where ", + "interval(", + "order by ", + "order by ", + "offset ", + "or ", + "group by ", + "now()", + "session(", + "sliding ", + "slimit ", + "soffset ", + "state_window(", + "today() ", + "union all select ", +}; + +char * functions[] = { + "count(", + "sum(", + "avg(", + "last(", + "last_row(", + "top(", + "interp(", + "max(", + "min(", + "now()", + "today()", + "percentile(", + "tail(", + "pow(", + "abs(", + "atan(", + "acos(", + "asin(", + "apercentile(", + "bottom(", + "cast(", + "ceil(", + "char_length(", + "cos(", + "concat(", + "concat_ws(", + "csum(", + "diff(", + "derivative(", + "elapsed(", + "first(", + "floor(", + "hyperloglog(", + "histogram(", + "irate(", + "leastsquares(", + "length(", + "log(", + "lower(", + "ltrim(", + "mavg(", + "mode(", + "tan(", + "round(", + "rtrim(", + "sample(", + "sin(", + "spread(", + "substr(", + "statecount(", + "stateduration(", + "stddev(", + "sqrt(", + "timediff(", + "timezone(", + "timetruncate(", + "twa(", + "to_unixtimestamp(", + "unique(", + "upper(", +}; + +char * tb_actions[] = { + "add column", + "modify column", + "drop column", + "change tag", +}; + +char * db_options[] = { + "blocks", + "cachelast", + "comp", + "keep", + "replica", + "quorum", +}; + +char * data_types[] = { + "timestamp", + "int", + "bigint", + "float", + "double", + "binary", + "smallint", + "tinyint", + "bool", + "nchar", + "json" +}; + +char * key_tags[] = { + "tags(" +}; + + +// +// ------- gobal variant define --------- +// +int32_t firstMatchIndex = -1; // first match shellCommands index +int32_t lastMatchIndex = -1; // last match shellCommands index +int32_t curMatchIndex = -1; // current match shellCommands index +int32_t lastWordBytes = -1; // printShow last word length +bool waitAutoFill = false; + + +// +// ----------- global var array define ----------- +// +#define WT_VAR_DBNAME 0 +#define WT_VAR_STABLE 1 +#define WT_VAR_TABLE 2 +#define WT_VAR_DNODEID 3 +#define WT_VAR_USERNAME 4 +#define WT_VAR_ALLTABLE 5 +#define WT_VAR_FUNC 6 +#define WT_VAR_KEYWORD 7 +#define WT_VAR_TBACTION 8 +#define WT_VAR_DBOPTION 9 +#define WT_VAR_DATATYPE 10 +#define WT_VAR_KEYTAGS 11 +#define WT_VAR_ANYWORD 12 +#define WT_VAR_CNT 13 + +#define WT_FROM_DB_MAX 4 // max get content from db +#define WT_FROM_DB_CNT (WT_FROM_DB_MAX + 1) + +#define WT_TEXT 0xFF + +char dbName[256] = ""; // save use database name; +// tire array +STire* tires[WT_VAR_CNT]; +pthread_mutex_t tiresMutex; +//save thread handle obtain var name from db server +pthread_t* threads[WT_FROM_DB_CNT]; +// obtain var name with sql from server +char varTypes[WT_VAR_CNT][64] = { + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" +}; + +char varSqls[WT_FROM_DB_CNT][64] = { + "show databases;", + "show stables;", + "show tables;", + "show dnodes;", + "show users;" +}; + + +// var words current cursor, if user press any one key except tab, cursorVar can be reset to -1 +int cursorVar = -1; +bool varMode = false; // enter var names list mode + + +TAOS* varCon = NULL; +Command* varCmd = NULL; +SMatch* lastMatch = NULL; // save last match result +int cntDel = 0; // delete byte count after next press tab + + +// show auto tab introduction +void printfIntroduction() { + printf(" **************************** SUPPORT TAB KEY ************************************\n"); + printf(" * Taos shell support press TAB key to complete word. You can try it. *\n"); + printf(" * Anywhere press SPACE key following TAB key, You'll get surprise. *\n"); + printf(" * SUPPORT SHORTCUT: *\n"); + printf(" * [ Ctrl + A ] ...... move cursor to line [A]head *\n"); + printf(" * [ Ctrl + M ] ...... move cursor to line [M]iddle *\n"); + printf(" * [ Ctrl + E ] ...... move cursor to line [E]nd *\n"); + printf(" * [ Ctrl + L ] ...... clean screen *\n"); + printf(" * [ Ctrl + K ] ...... clean after cursor *\n"); + printf(" * [ Ctrl + U ] ...... clean before cursor *\n"); + printf(" * *\n"); + printf(" **********************************************************************************\n\n"); +} + +void showHelp() { + printf("\nThe following are supported commands for Taos shell:"); + printf("\n\ + ----- A ----- \n\ + alter database \n\ + alter dnode balance \n\ + alter dnode resetlog;\n\ + alter dnode debugFlag 141;\n\ + alter dnode monitor 1;\n\ + alter table ADD COLUMN ; \n\ + alter table DROP COLUMN ; \n\ + alter table MODIFY COLUMN ;\n\ + alter topic \n\ + alter user pass\n\ + alter user privilege read ;\n\ + alter user privilege write ;\n\ + ----- C ----- \n\ + create table using tags ...\n\ + create database ;\n\ + create table as ...\n\ + create dnode \n\ + create topic \n\ + create function \n\ + create user pass ;\n\ + compact vnode in (vgid,vgid,vgid);\n\ + ----- D ----- \n\ + describe ;\n\ + delete from where ... \n\ + drop database ;\n\ + drop dnode ;\n\ + drop function ;\n\ + drop topic ;\n\ + drop table ;\n\ + drop user ;\n\ + ----- K ----- \n\ + kill connection ; \n\ + kill query ; \n\ + kill stream ; \n\ + ----- S ----- \n\ + select * from where ... \n\ + select _block_dist() from ;\n\ + select client_version();\n\ + select current_user();\n\ + select database;\n\ + select server_version();\n\ + set max_binary_display_width ; \n\ + show create database ;\n\ + show create stable ;\n\ + show create table ;\n\ + show connections;\n\ + show databases;\n\ + show dnodes;\n\ + show functions;\n\ + show modules;\n\ + show mnodes;\n\ + show queries;\n\ + show stables;\n\ + show stables like ''; note: regular expression only support '_' and '%%' match.\n\ + show streams;\n\ + show scores;\n\ + show tables;\n\ + show tables like ''; \n\ + show users;\n\ + show variables;\n\ + show vgroups;\n\ + ----- I ----- \n\ + insert into values(...) ;\n\ + ----- U ----- \n\ + use ;"); + + printf("\n\n"); + + //define in getDuration() function + printf("\ + Timestamp expression Format:\n\ + b - nanosecond \n\ + u - microsecond \n\ + a - millisecond \n\ + s - second \n\ + m - minute \n\ + h - hour \n\ + d - day \n\ + w - week \n\ + now - current time \n\ + Example : \n\ + select * from t1 where ts > now - 2w + 3d and ts <= now - 1w -2h ;\n"); + printf("\n"); +} + +// +// ------------------- parse words -------------------------- +// + +#define SHELL_COMMAND_COUNT() (sizeof(shellCommands) / sizeof(SWords)) + +// get at +SWord * atWord(SWords * command, int32_t index) { + SWord * word = command->head; + for (int32_t i = 0; i < index; i++) { + if (word == NULL) + return NULL; + word = word->next; + } + + return word; +} + +#define MATCH_WORD(x) atWord(x, x->matchIndex) + +int wordType(const char* p, int32_t len) { + for (int i = 0; i < WT_VAR_CNT; i++) { + if (strncmp(p, varTypes[i], len) == 0) + return i; + } + return WT_TEXT; +} + +// add word +SWord * addWord(const char* p, int32_t len, bool pattern) { + SWord* word = (SWord *) malloc(sizeof(SWord)); + memset(word, 0, sizeof(SWord)); + word->word = (char* )p; + word->len = len; + + // check format + if (pattern) { + word->type = wordType(p, len); + } else { + word->type = WT_TEXT; + } + + return word; +} + +// parse one command +void parseCommand(SWords * command, bool pattern) { + char * p = command->source; + int32_t start = 0; + int32_t size = command->source_len > 0 ? command->source_len : strlen(p); + + bool lastBlank = false; + for (int i = 0; i <= size; i++) { + if (p[i] == ' ' || i == size) { + // check continue blank like ' ' + if (p[i] == ' ') { + if (lastBlank) { + start ++; + continue; + } + if (i == 0) { // first blank + lastBlank = true; + start ++; + continue; + } + lastBlank = true; + } + + // found split or string end , append word + if (command->head == NULL) { + command->head = addWord(p + start, i - start, pattern); + command->count = 1; + } else { + SWord * word = command->head; + while (word->next) { + word = word->next; + } + word->next = addWord(p + start, i - start, pattern); + command->count ++; + } + start = i + 1; + } else { + lastBlank = false; + } + } +} + +// free Command +void freeCommand(SWords * command) { + SWord * word = command->head; + if (word == NULL) { + return ; + } + + // loop + while (word->next) { + SWord * tmp = word; + word = word->next; + // if malloc need free + if(tmp->free && tmp->word) + free(tmp->word); + free(tmp); + } + + // if malloc need free + if(word->free && word->word) + free(word->word); + free(word); +} + +void GenerateVarType(int type, char** p, int count) { + STire* tire = createTire(TIRE_LIST); + for (int i = 0; i < count; i++) { + insertWord(tire, p[i]); + } + + pthread_mutex_lock(&tiresMutex); + tires[type] = tire; + pthread_mutex_unlock(&tiresMutex); +} + +// +// -------------------- shell auto ---------------- +// + + +// init shell auto funciton , shell start call once +bool shellAutoInit() { + // command + int32_t count = SHELL_COMMAND_COUNT(); + for (int32_t i = 0; i < count; i ++) { + parseCommand(shellCommands + i, true); + } + + // tires + memset(tires, 0, sizeof(STire*) * WT_VAR_CNT); + pthread_mutex_init(&tiresMutex, NULL); + + // threads + memset(threads, 0, sizeof(pthread_t*) * WT_VAR_CNT); + + // generate varType + GenerateVarType(WT_VAR_FUNC, functions, sizeof(functions) /sizeof(char *)); + GenerateVarType(WT_VAR_KEYWORD, keywords, sizeof(keywords) /sizeof(char *)); + GenerateVarType(WT_VAR_DBOPTION, db_options, sizeof(db_options) /sizeof(char *)); + GenerateVarType(WT_VAR_TBACTION, tb_actions, sizeof(tb_actions) /sizeof(char *)); + GenerateVarType(WT_VAR_DATATYPE, data_types, sizeof(data_types) /sizeof(char *)); + GenerateVarType(WT_VAR_KEYTAGS, key_tags, sizeof(key_tags) /sizeof(char *)); + + printfIntroduction(); + + return true; +} + +// exit shell auto funciton, shell exit call once +void shellAutoExit() { + // free command + int32_t count = SHELL_COMMAND_COUNT(); + for (int32_t i = 0; i < count; i ++) { + freeCommand(shellCommands + i); + } + + // free tires + pthread_mutex_lock(&tiresMutex); + for (int32_t i = 0; i < WT_VAR_CNT; i++) { + if (tires[i]) { + freeTire(tires[i]); + tires[i] = NULL; + } + } + pthread_mutex_unlock(&tiresMutex); + // destory + pthread_mutex_destroy(&tiresMutex); + + // free threads + for (int32_t i = 0; i < WT_VAR_CNT; i++) { + if (threads[i]) { + taosDestroyThread(threads[i]); + threads[i] = NULL; + } + } + + // free lastMatch + if (lastMatch) { + freeMatch(lastMatch); + lastMatch = NULL; + } +} + +// +// ------------------- auto ptr for tires -------------------------- +// +bool setNewAuotPtr(int type, STire* pNew) { + if (pNew == NULL) + return false; + + pthread_mutex_lock(&tiresMutex); + STire* pOld = tires[type]; + if (pOld != NULL) { + // previous have value, release self ref count + if (--pOld->ref == 0) { + freeTire(pOld); + } + } + + // set new + tires[type] = pNew; + tires[type]->ref = 1; + pthread_mutex_unlock(&tiresMutex); + + return true; +} + +// get ptr +STire* getAutoPtr(int type) { + if (tires[type] == NULL) { + return NULL; + } + + pthread_mutex_lock(&tiresMutex); + tires[type]->ref++; + pthread_mutex_unlock(&tiresMutex); + + return tires[type]; +} + +// put back tire to tires[type], if tire not equal tires[type].p, need free tire +void putBackAutoPtr(int type, STire* tire) { + if (tire == NULL) { + return ; + } + + pthread_mutex_lock(&tiresMutex); + if (tires[type] != tire) { + //update by out, can't put back , so free + if (--tire->ref == 1) { + // support multi thread getAuotPtr + freeTire(tire); + } + + } else { + tires[type]->ref--; + assert(tires[type]->ref > 0); + } + pthread_mutex_unlock(&tiresMutex); + + return ; +} + + + +// +// ------------------- var Word -------------------------- +// + +#define MAX_CACHED_CNT 100000 // max cached rows 10w +// write sql result to var name, return write rows cnt +int writeVarNames(int type, TAOS_RES* tres) { + // fetch row + TAOS_ROW row = taos_fetch_row(tres); + if (row == NULL) { + return 0; + } + + TAOS_FIELD *fields = taos_fetch_fields(tres); + // create new tires + char tireType = type == WT_VAR_TABLE ? TIRE_TREE : TIRE_LIST; + STire* tire = createTire(tireType); + + // enum rows + char name[1024]; + int numOfRows = 0; + do { + int32_t* lengths = taos_fetch_lengths(tres); + int32_t bytes = lengths[0]; + if(fields[0].type == TSDB_DATA_TYPE_SMALLINT) { + sprintf(name,"%d", *(int16_t*)row[0]); + } else { + memcpy(name, row[0], bytes); + } + + name[bytes] = 0; //set string end + // insert to tire + insertWord(tire, name); + + if (++numOfRows > MAX_CACHED_CNT ) { + break; + } + + row = taos_fetch_row(tres); + } while (row != NULL); + + // replace old tire + setNewAuotPtr(type, tire); + + return numOfRows; +} + +bool firstMatchCommand(TAOS * con, Command * cmd); +// +// thread obtain var thread from db server +// +void* varObtainThread(void* param) { + int type = *(int* )param; + free(param); + + if (varCon == NULL || type > WT_FROM_DB_MAX) { + return NULL; + } + + TAOS_RES* pSql = taos_query_h(varCon, varSqls[type], NULL); + if (taos_errno(pSql)) { + taos_free_result(pSql); + return NULL; + } + + // write var names from pSql + int cnt = writeVarNames(type, pSql); + + // free sql + taos_free_result(pSql); + + // check need call auto tab + if (cnt > 0 && waitAutoFill) { + // press tab key by program + firstMatchCommand(varCon, varCmd); + } + + return NULL; +} + +// only match next one word from all match words, return valuue must free by caller +char* matchNextPrefix(STire* tire, char* pre) { + SMatch* match = NULL; + + // re-use last result + if (lastMatch) { + if (strcmp(pre, lastMatch->pre) == 0) { + // same pre + match = lastMatch; + } + } + + if (match == NULL) { + // not same with last result + if (pre[0] == 0) { + // EMPTY PRE + match = enumAll(tire); + } else { + // NOT EMPTY + match = matchPrefix(tire, pre, NULL); + } + + // save to lastMatch + if (match) { + if (lastMatch) + freeMatch(lastMatch); + lastMatch = match; + } + } + + // check valid + if (match == NULL || match->head == NULL) { + // no one matched + return false; + } + + if (cursorVar == -1) { + // first + cursorVar = 0; + return strdup(match->head->word); + } + + // according to cursorVar , calculate next one + int i = 0; + SMatchNode* item = match->head; + while (item) { + if (i == cursorVar + 1) { + // found next position ok + if (item->next == NULL) { + // match last item, reset cursorVar to head + cursorVar = -1; + } else { + cursorVar = i; + } + + return strdup(item->word); + } + + // check end item + if (item->next == NULL) { + // if cursorVar > var list count, return last and reset cursorVar + cursorVar = -1; + + return strdup(item->word); + } + + // move next + item = item->next; + i++; + } + + return NULL; +} + +// search pre word from tire tree, return value must free by caller +char* tireSearchWord(int type, char* pre) { + if (type == WT_TEXT) { + return NULL; + } + + if(type > WT_FROM_DB_MAX) { + // NOT FROM DB , tires[type] alwary not null + STire* tire = tires[type]; + if (tire == NULL) + return NULL; + return matchNextPrefix(tire, pre); + } + + // TYPE CONTEXT GET FROM DB + pthread_mutex_lock(&tiresMutex); + + // check need obtain from server + if (tires[type] == NULL) { + waitAutoFill = true; + // need async obtain var names from db sever + if (threads[type] != NULL) { + if (taosThreadRunning(threads[type])) { + // thread running , need not obtain again, return + pthread_mutex_unlock(&tiresMutex); + return NULL; + } + // destroy previous thread handle for new create thread handle + taosDestroyThread(threads[type]); + threads[type] = NULL; + } + + // create new + void * param = malloc(sizeof(int)); + *((int* )param) = type; + threads[type] = taosCreateThread(varObtainThread, param); + pthread_mutex_unlock(&tiresMutex); + return NULL; + } + pthread_mutex_unlock(&tiresMutex); + + // can obtain var names from local + STire* tire = getAutoPtr(type); + if (tire == NULL) { + return NULL; + } + + char* str = matchNextPrefix(tire, pre); + // used finish, put back pointer to autoptr array + putBackAutoPtr(type, tire); + + return str; +} + +// match var word, word1 is pattern , word2 is input from shell +bool matchVarWord(SWord* word1, SWord* word2) { + // search input word from tire tree + char pre[512]; + memcpy(pre, word2->word, word2->len); + pre[word2->len] = 0; + + char* str = NULL; + if (word1->type == WT_VAR_ALLTABLE) { + // ALL_TABLE + str = tireSearchWord(WT_VAR_STABLE, pre); + if (str == NULL) { + str = tireSearchWord(WT_VAR_TABLE, pre); + if(str == NULL) + return false; + } + } else { + // OTHER + str = tireSearchWord(word1->type, pre); + if (str == NULL) { + // not found or word1->type variable list not obtain from server, return not match + return false; + } + } + + // free previous malloc + if(word1->free && word1->word) { + free(word1->word); + } + + // save + word1->word = str; + word1->len = strlen(str); + word1->free = true; // need free + + return true; +} + +// +// ------------------- match words -------------------------- +// + + +// compare command cmd1 come from shellCommands , cmd2 come from user input +int32_t compareCommand(SWords * cmd1, SWords * cmd2) { + SWord * word1 = cmd1->head; + SWord * word2 = cmd2->head; + + if (word1 == NULL || word2 == NULL) { + return -1; + } + + for (int32_t i = 0; i < cmd1->count; i++) { + if (word1->type == WT_TEXT) { + // WT_TEXT match + if (word1->len == word2->len) { + if (strncasecmp(word1->word, word2->word, word1->len) != 0) + return -1; + } else if (word1->len < word2->len) { + return -1; + } else { + // word1->len > word2->len + if (strncasecmp(word1->word, word2->word, word2->len) == 0) { + cmd1->matchIndex = i; + cmd1->matchLen = word2->len; + return i; + } else { + return -1; + } + } + } else { + // WT_VAR auto match any one word + if (word2->next == NULL) { // input words last one + if (matchVarWord(word1, word2)) { + cmd1->matchIndex = i; + cmd1->matchLen = word2->len; + varMode = true; + return i; + } + return -1; + } + } + + // move next + word1 = word1->next; + word2 = word2->next; + if (word1 == NULL || word2 == NULL) { + return -1; + } + } + + return -1; +} + +// match command +SWords * matchCommand(SWords * input, bool continueSearch) { + int32_t count = SHELL_COMMAND_COUNT(); + for (int32_t i = 0; i < count; i ++) { + SWords * shellCommand = shellCommands + i; + if (continueSearch && lastMatchIndex != -1 && i <= lastMatchIndex) { + // new match must greate than lastMatchIndex + if (varMode && i == lastMatchIndex) { + // do nothing, var match on lastMatchIndex + } else { + continue; + } + } + + // command is large + if (input->count > shellCommand->count ) { + continue; + } + + // compare + int32_t index = compareCommand(shellCommand, input); + if (index != -1) { + if (firstMatchIndex == -1) + firstMatchIndex = i; + curMatchIndex = i; + return &shellCommands[i]; + } + } + + // not match + return NULL; +} + +// +// ------------------- print screen -------------------------- +// + +// delete char count +void deleteCount(Command * cmd, int count) { + int size = 0; + int width = 0; + clearScreen(cmd->endOffset + prompt_size, cmd->screenOffset + prompt_size); + + // loop delete + while (--count >= 0 && cmd->cursorOffset > 0) { + getPrevCharSize(cmd->command, cmd->cursorOffset, &size, &width); + memmove(cmd->command + cmd->cursorOffset - size, cmd->command + cmd->cursorOffset, + cmd->commandSize - cmd->cursorOffset); + cmd->commandSize -= size; + cmd->cursorOffset -= size; + cmd->screenOffset -= width; + cmd->endOffset -= width; + } +} + +// show screen +void printScreen(TAOS * con, Command * cmd, SWords * match) { + // modify Command + if (firstMatchIndex == -1 || curMatchIndex == -1) { + // no match + return ; + } + + // first tab press + const char * str = NULL; + int strLen = 0; + + if (firstMatchIndex == curMatchIndex && lastWordBytes == -1) { + // first press tab + SWord * word = MATCH_WORD(match); + str = word->word + match->matchLen; + strLen = word->len - match->matchLen; + lastMatchIndex = firstMatchIndex; + lastWordBytes = word->len; + } else { + if (lastWordBytes == -1) + return ; + deleteCount(cmd, lastWordBytes); + + SWord * word = MATCH_WORD(match); + str = word->word; + strLen = word->len; + // set current to last + lastMatchIndex = curMatchIndex; + lastWordBytes = word->len; + } + + // insert new + insertChar(cmd, (char *)str, strLen); +} + + +// main key press tab , matched return true else false +bool firstMatchCommand(TAOS * con, Command * cmd) { + // parse command + SWords* input = (SWords *)malloc(sizeof(SWords)); + memset(input, 0, sizeof(SWords)); + input->source = cmd->command; + input->source_len = cmd->commandSize; + parseCommand(input, false); + + // if have many , default match first, if press tab again , switch to next + curMatchIndex = -1; + lastMatchIndex = -1; + SWords * match = matchCommand(input, true); + if (match == NULL) { + // not match , nothing to do + freeCommand(input); + return false; + } + + // print to screen + printScreen(con, cmd, match); + freeCommand(input); + return true; +} + +// create input source +void createInputFromFirst(SWords* input, SWords * firstMatch) { + // + // if next pressTabKey , input context come from firstMatch, set matched length with source_len + // + input->source = (char*)malloc(1024); + memset((void* )input->source, 0, 1024); + + SWord * word = firstMatch->head; + + // source_len = full match word->len + half match with firstMatch->matchLen + for (int i = 0; i < firstMatch->matchIndex && word; i++) { + // combine source from each word + strncpy(input->source + input->source_len, word->word, word->len); + strcat(input->source, " "); // append blank splite + input->source_len += word->len + 1; // 1 is blank length + // move next + word = word->next; + } + // appand half matched word for last + if (word) { + strncpy(input->source + input->source_len, word->word, firstMatch->matchLen); + input->source_len += firstMatch->matchLen; + } +} + +// user press Tabkey again is named next , matched return true else false +bool nextMatchCommand(TAOS * con, Command * cmd, SWords * firstMatch) { + if (firstMatch == NULL || firstMatch->head == NULL) { + return false; + } + SWords* input = (SWords *)malloc(sizeof(SWords)); + memset(input, 0, sizeof(SWords)); + + // create input from firstMatch + createInputFromFirst(input, firstMatch); + + // parse input + parseCommand(input, false); + + // if have many , default match first, if press tab again , switch to next + SWords * match = matchCommand(input, true); + if (match == NULL) { + // if not match , reset all index + firstMatchIndex = -1; + curMatchIndex = -1; + match = matchCommand(input, false); + if (match == NULL) { + freeCommand(input); + return false; + } + } + + // print to screen + printScreen(con, cmd, match); + + // free + if (input->source) { + free(input->source); + input->source = NULL; + } + freeCommand(input); + + return true; +} + +// fill with type +bool fillWithType(TAOS * con, Command * cmd, char* pre, int type) { + // get type + STire* tire = tires[type]; + char* str = matchNextPrefix(tire, pre); + if (str == NULL) { + return false; + } + + // need insert part string + char * part = str + strlen(pre); + + // show + int count = strlen(part); + insertChar(cmd, part, count); + cntDel = count; // next press tab delete current append count + + free(str); + return true; +} + +// fill with type +bool fillTableName(TAOS * con, Command * cmd, char* pre) { + // search stable and table + char * str = tireSearchWord(WT_VAR_STABLE, pre); + if (str == NULL) { + str = tireSearchWord(WT_VAR_TABLE, pre); + if(str == NULL) + return false; + } + + // need insert part string + char * part = str + strlen(pre); + + // delete autofill count last append + if(cntDel > 0) { + deleteCount(cmd, cntDel); + cntDel = 0; + } + + // show + int count = strlen(part); + insertChar(cmd, part, count); + cntDel = count; // next press tab delete current append count + + free(str); + return true; +} + +// +// find last word from sql select clause +// example : +// 1 select cou -> press tab select count( +// 2 select count(*),su -> select count(*), sum( +// 3 select count(*), su -> select count(*), sum( +// +char * lastWord(char * p) { + // get near from end revert find ' ' and ',' + char * p1 = strrchr(p, ' '); + char * p2 = strrchr(p, ','); + + if (p1 && p2) { + return MAX(p1, p2) + 1; + } else if (p1) { + return p1 + 1; + } else if(p2) { + return p2 + 1; + } else { + return p; + } +} + +bool fieldsInputEnd(char* sql) { + // not in '()' + char* p1 = strrchr(sql, '('); + char* p2 = strrchr(sql, ')'); + if (p1 && p2 == NULL) { + // like select count( ' ' + return false; + } else if (p1 && p2 && p1 > p2) { + // like select sum(age), count( ' ' + return false; + } + + // not in ',' + char * p = strrchr(sql, ','); + // like select ts, age,' ' + if (p) { + ++p; + bool allBlank = true; + int cnt = 0; // blank count , continue many blank is one blank + char * plast = NULL; + while(*p) { + if (*p != ' ') { + allBlank = false; + plast = NULL; + } else { + if(plast == NULL) { + plast = p; + cnt ++; + } + } + ++p; + } + + // any one word is not blank + if(allBlank) { + return false; + } + + // if last char not ' ', then not end field, like select count(*), su + tab can fill sum( + if(sql[strlen(sql)-1] != ' ' && cnt <= 1) { + return false; + } + } + + char * p3 = strrchr(sql, ' '); + if(p3 == NULL) { + // only one word + return false; + } + + return true; +} + +// need insert from +bool needInsertFrom(char * sql, int len) { + // last is blank + if(sql[len-1] != ' ') { + // insert from keyword + return false; + } + + // select fields input is end + if (!fieldsInputEnd(sql)) { + return false; + } + + // can insert from keyword + return true; +} + +bool matchSelectQuery(TAOS * con, Command * cmd) { + // if continue press Tab , delete bytes by previous autofill + if (cntDel > 0) { + deleteCount(cmd, cntDel); + cntDel = 0; + } + + // match select ... + int len = cmd->commandSize; + char * p = cmd->command; + + // remove prefix blank + while (p[0] == ' ' && len > 0) { + p++; + len--; + } + + // special range + if(len < 7 || len > 512) { + return false; + } + + // select and from + if(strncasecmp(p, "select ", 7) != 0) { + // not select query clause + return false; + } + p += 7; + len -= 7; + + char* ps = p = strndup(p, len); + + // union all + char * p1; + do { + p1 = strstr(p, UNION_ALL); + if(p1) { + p = p1 + strlen(UNION_ALL); + } + } while (p1); + + char * from = strstr(p, " from "); + //last word , maybe empty string or some letters of a string + char * last = lastWord(p); + bool ret = false; + if (from == NULL) { + bool fieldEnd = fieldsInputEnd(p); + // cheeck fields input end then insert from keyword + if (fieldEnd && p[len-1] == ' ') { + insertChar(cmd, "from", 4); + free(ps); + return true; + } + + // fill funciton + if(fieldEnd) { + // fields is end , need match keyword + ret = fillWithType(con, cmd, last, WT_VAR_KEYWORD); + } else { + ret = fillWithType(con, cmd, last, WT_VAR_FUNC); + } + + free(ps); + return ret; + } + + // have from + char * blank = strstr(from + 6, " "); + if (blank == NULL) { + // no table name, need fill + ret = fillTableName(con, cmd, last); + } else { + ret = fillWithType(con, cmd, last, WT_VAR_KEYWORD); + } + + free(ps); + return ret; +} + +// if is input create fields or tags area, return true +bool isCreateFieldsArea(char * p) { + char * left = strrchr(p, '('); + if (left == NULL) { + // like 'create table st' + return false; + } + + char * right = strrchr(p, ')'); + if(right == NULL) { + // like 'create table st( ' + return true; + } + + if (left > right) { + // like 'create table st( ts timestamp, age int) tags(area ' + return true; + } + + return false; +} + +bool matchCreateTable(TAOS * con, Command * cmd) { + // if continue press Tab , delete bytes by previous autofill + if (cntDel > 0) { + deleteCount(cmd, cntDel); + cntDel = 0; + } + + // match select ... + int len = cmd->commandSize; + char * p = cmd->command; + + // remove prefix blank + while (p[0] == ' ' && len > 0) { + p++; + len--; + } + + // special range + if(len < 7 || len > 1024) { + return false; + } + + // select and from + if(strncasecmp(p, "create table ", 13) != 0) { + // not select query clause + return false; + } + p += 13; + len -= 13; + + char* ps = strndup(p, len); + bool ret = false; + char * last = lastWord(ps); + + // check in create fields or tags input area + if (isCreateFieldsArea(ps)) { + ret = fillWithType(con, cmd, last, WT_VAR_DATATYPE); + } + + // tags + if (!ret) { + // find only one ')' , can insert tags + char * p1 = strchr(ps, ')'); + if (p1) { + if(strchr(p1 + 1, ')') == NULL && strstr(p1 + 1, "tags") == NULL) { + // can insert tags keyword + ret = fillWithType(con, cmd, last, WT_VAR_KEYTAGS); + } + } + } + + free(ps); + return ret; +} + +bool matchOther(TAOS * con, Command * cmd) { + int len = cmd->commandSize; + char* p = cmd->command; + + if (p[len - 1] == '\\') { + // append '\G' + char a[] = "G;"; + insertChar(cmd, a, 2); + return true; + } + + return false; +} + + +// main key press tab +void pressTabKey(TAOS * con, Command * cmd) { + // check + if (cmd->commandSize == 0) { + // empty + showHelp(); + showOnScreen(cmd); + return ; + } + + // save connection to global + varCon = con; + varCmd = cmd; + bool matched = false; + + // manual match like create table st( ... + matched = matchCreateTable(con, cmd); + if (matched) + return ; + + // shellCommands match + if (firstMatchIndex == -1) { + matched = firstMatchCommand(con, cmd); + } else { + matched = nextMatchCommand(con, cmd, &shellCommands[firstMatchIndex]); + } + if (matched) + return ; + + // NOT MATCHED ANYONE + // match other like '\G' ... + matched = matchOther(con, cmd); + if (matched) + return ; + + // manual match like select * from ... + matched = matchSelectQuery(con, cmd); + if (matched) + return ; + + return ; +} + +// press othr key +void pressOtherKey(char c) { + // reset global variant + firstMatchIndex = -1; + lastMatchIndex = -1; + curMatchIndex = -1; + lastWordBytes = -1; + + // var names + cursorVar = -1; + varMode = false; + waitAutoFill = false; + cntDel = 0; + + if (lastMatch) { + freeMatch(lastMatch); + lastMatch = NULL; + } + + //printf(" -> %d <-\n", c); + +} + +// put name into name, return name length +int getWordName(char* p, char * name, int nameLen) { + //remove prefix blank + while (*p == ' ') { + p++; + } + + // get databases name; + int i = 0; + while(p[i] != 0 && i < nameLen - 1) { + name[i] = p[i]; + i++; + if(p[i] == ' ' || p[i] == ';'|| p[i] == '(') { + // name end + break; + } + } + name[i] = 0; + + return i; +} + +// deal use db, if have 'use' return true +bool dealUseDB(char * sql) { + // check use keyword + if(strncasecmp(sql, "use ", 4) != 0) { + return false; + } + + char db[256]; + char *p = sql + 4; + if (getWordName(p, db, sizeof(db)) == 0) { + // no name , return + return true; + } + + // dbName is previous use open db name + if (strcasecmp(db, dbName) == 0) { + // same , no need switch + return true; + } + + // switch new db + pthread_mutex_lock(&tiresMutex); + // STABLE set null + STire* tire = tires[WT_VAR_STABLE]; + tires[WT_VAR_STABLE] = NULL; + if(tire) { + freeTire(tire); + } + // TABLE set null + tire = tires[WT_VAR_TABLE]; + tires[WT_VAR_TABLE] = NULL; + if(tire) { + freeTire(tire); + } + // save + strcpy(dbName, db); + pthread_mutex_unlock(&tiresMutex); + + return true; +} + +// deal create, if have 'create' return true +bool dealCreateCommand(char * sql) { + // check keyword + if(strncasecmp(sql, "create ", 7) != 0) { + return false; + } + + char name[1024]; + char *p = sql + 7; + if (getWordName(p, name, sizeof(name)) == 0) { + // no name , return + return true; + } + + int type = -1; + // dbName is previous use open db name + if (strcasecmp(name, "database") == 0) { + type = WT_VAR_DBNAME; + } else if (strcasecmp(name, "table") == 0) { + if(strstr(sql, " tags") != NULL && strstr(sql, " using ") == NULL) + type = WT_VAR_STABLE; + else + type = WT_VAR_TABLE; + } else if (strcasecmp(name, "user") == 0) { + type = WT_VAR_USERNAME; + } else { + // no match , return + return true; + } + + // move next + p += strlen(name); + + // get next word , that is table name + if (getWordName(p, name, sizeof(name)) == 0) { + // no name , return + return true; + } + + // switch new db + pthread_mutex_lock(&tiresMutex); + // STABLE set null + STire* tire = tires[type]; + if(tire) { + insertWord(tire, name); + } + pthread_mutex_unlock(&tiresMutex); + + return true; +} + +// deal create, if have 'drop' return true +bool dealDropCommand(char * sql) { + // check keyword + if(strncasecmp(sql, "drop ", 5) != 0) { + return false; + } + + char name[1024]; + char *p = sql + 5; + if (getWordName(p, name, sizeof(name)) == 0) { + // no name , return + return true; + } + + int type = -1; + // dbName is previous use open db name + if (strcasecmp(name, "database") == 0) { + type = WT_VAR_DBNAME; + } else if (strcasecmp(name, "table") == 0) { + type = WT_VAR_ALLTABLE; + } else if (strcasecmp(name, "dnode") == 0) { + type = WT_VAR_DNODEID; + } else if (strcasecmp(name, "user") == 0) { + type = WT_VAR_USERNAME; + } else { + // no match , return + return true; + } + + // move next + p += strlen(name); + + // get next word , that is table name + if (getWordName(p, name, sizeof(name)) == 0) { + // no name , return + return true; + } + + // switch new db + pthread_mutex_lock(&tiresMutex); + // STABLE set null + if(type == WT_VAR_ALLTABLE) { + bool del = false; + // del in stable + STire* tire = tires[WT_VAR_STABLE]; + if(tire) + del = deleteWord(tire, name); + // del in table + if(!del) { + tire = tires[WT_VAR_TABLE]; + if(tire) + del = deleteWord(tire, name); + } + } else { + // OTHER TYPE + STire* tire = tires[type]; + if(tire) + deleteWord(tire, name); + } + pthread_mutex_unlock(&tiresMutex); + + return true; +} + +// callback autotab module after shell sql execute +void callbackAutoTab(char* sqlstr, TAOS* pSql, bool usedb) { + char * sql = sqlstr; + // remove prefix blank + while (*sql == ' ') { + sql++; + } + + if(dealUseDB(sql)) { + // change to new db + return ; + } + + // create command add name to autotab + if(dealCreateCommand(sql)) { + return ; + } + + // drop command remove name from autotab + if(dealDropCommand(sql)) { + return ; + } + + return ; +} diff --git a/src/kit/shell/src/shellCommand.c b/src/kit/shell/src/shellCommand.c index d78e152dbd..9bbf19571e 100644 --- a/src/kit/shell/src/shellCommand.c +++ b/src/kit/shell/src/shellCommand.c @@ -79,8 +79,11 @@ void insertChar(Command *cmd, char *c, int size) { /* update the values */ cmd->commandSize += size; cmd->cursorOffset += size; - cmd->screenOffset += wcwidth(wc); - cmd->endOffset += wcwidth(wc); + for (int i = 0; i < size; i++) { + mbtowc(&wc, c + i, size); + cmd->screenOffset += wcwidth(wc); + cmd->endOffset += wcwidth(wc); + } showOnScreen(cmd); } @@ -179,6 +182,16 @@ void positionCursorHome(Command *cmd) { } } +void positionCursorMiddle(Command *cmd) { + if (cmd->endOffset > 0) { + clearScreen(cmd->endOffset + prompt_size, cmd->screenOffset + prompt_size); + cmd->cursorOffset = cmd->commandSize/2; + cmd->screenOffset = cmd->endOffset/2; + showOnScreen(cmd); + } +} + + void positionCursorEnd(Command *cmd) { assert(cmd->cursorOffset <= cmd->commandSize && cmd->endOffset >= cmd->screenOffset); diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index ee82212081..5ac17c6a9d 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -27,6 +27,7 @@ #include "tglobal.h" #include "tsclient.h" #include "cJSON.h" +#include "shellAuto.h" #include @@ -136,7 +137,7 @@ void shellInit(SShellArguments *_args) { exit(EXIT_SUCCESS); } #endif - + return; } @@ -261,41 +262,22 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { int64_t st, et; wordexp_t full_path; char * sptr = NULL; - char * tmp = NULL; char * cptr = NULL; char * fname = NULL; bool printMode = false; - int match; - - sptr = command; - while ((sptr = tstrstr(sptr, ">>", true)) != NULL) { - // find the last ">>" if any - tmp = sptr; - sptr += 2; - } - - sptr = tmp; - - if (sptr != NULL) { - // select ... where col >> n op m ...; - match = regex_match(sptr + 2, "^\\s*.{1,}\\s*[\\>|\\<|\\<=|\\>=|=|!=]\\s*.{1,};\\s*$", REG_EXTENDED | REG_ICASE); - if (match == 0) { - // select col >> n from ...; - match = regex_match(sptr + 2, "^\\s*.{1,}\\s{1,}.{1,};\\s*$", REG_EXTENDED | REG_ICASE); - if (match == 0) { - cptr = tstrstr(command, ";", true); - if (cptr != NULL) { - *cptr = '\0'; - } - if (wordexp(sptr + 2, &full_path, 0) != 0) { - fprintf(stderr, "ERROR: invalid filename: %s\n", sptr + 2); - return; - } - *sptr = '\0'; - fname = full_path.we_wordv[0]; - } + if ((sptr = tstrstr(command, ">>", true)) != NULL) { + cptr = tstrstr(command, ";", true); + if (cptr != NULL) { + *cptr = '\0'; } + + if (wordexp(sptr + 2, &full_path, 0) != 0) { + fprintf(stderr, "ERROR: invalid filename: %s\n", sptr + 2); + return; + } + *sptr = '\0'; + fname = full_path.we_wordv[0]; } if ((sptr = tstrstr(command, "\\G", true)) != NULL) { @@ -323,10 +305,13 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { int64_t oresult = atomic_load_64(&result); - if (regex_match(command, "^\\s*use\\s+([a-zA-Z0-9_]+|`.+`)\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) { + if (regex_match(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) { fprintf(stdout, "Database changed.\n\n"); fflush(stdout); + // call back auto tab module + callbackAutoTab(command, pSql, true); + atomic_store_64(&result, 0); freeResultWithRid(oresult); return; @@ -361,10 +346,14 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { } else { printf("Query interrupted (%s), %d row(s) in set (%.6fs)\n", taos_errstr(pSql), numOfRows, (et - st) / 1E6); } + } else { int num_rows_affacted = taos_affected_rows(pSql); et = taosGetTimestampUs(); printf("Query OK, %d of %d row(s) in database (%.6fs)\n", num_rows_affacted, num_rows_affacted, (et - st) / 1E6); + + // call auto tab + callbackAutoTab(command, pSql, false); } printf("\n"); @@ -1155,7 +1144,7 @@ int taos_base64_encode(unsigned char *source, size_t sourcelen, char *target, si int parse_cloud_dsn() { if (args.cloudDsn == NULL) { fprintf(stderr, "Cannot read cloud service info\n"); - return 1; + return -1; } else { char *start = strstr(args.cloudDsn, "http://"); if (start != NULL) { @@ -1171,7 +1160,7 @@ int parse_cloud_dsn() { char *port = strstr(args.cloudHost, ":"); if ((port == NULL) || (port + strlen(":")) == NULL) { fprintf(stderr, "Invalid format in TDengine cloud dsn: %s\n", args.cloudDsn); - return 1; + return -1; } char *token = strstr(port + strlen(":"), "?token="); if ((token == NULL) || (token + strlen("?token=")) == NULL || @@ -1229,12 +1218,11 @@ int wsclient_handshake() { return 0; } -int wsclient_send(char *strdata) { +int wsclient_send(char *strdata, WebSocketFrameType frame) { struct timeval tv; unsigned char mask[4]; unsigned int mask_int; unsigned long long payload_len; - unsigned char finNopcode; unsigned int payload_len_small; unsigned int payload_offset = 6; unsigned int len_size; @@ -1248,7 +1236,6 @@ int wsclient_send(char *strdata) { mask_int = rand(); memcpy(mask, &mask_int, 4); payload_len = strlen(strdata); - finNopcode = 0x81; if (payload_len <= 125) { frame_size = 6 + payload_len; payload_len_small = payload_len; @@ -1266,7 +1253,7 @@ int wsclient_send(char *strdata) { } data = (char *)malloc(frame_size); memset(data, 0, frame_size); - *data = finNopcode; + *data = frame; *(data + 1) = payload_len_small | 0x80; if (payload_len_small == 126) { payload_len &= 0xffff; @@ -1293,13 +1280,16 @@ int wsclient_send(char *strdata) { sent += i; } if (i < 0) { - fprintf(stderr, "websocket send data error\n"); + fprintf(stderr, "websocket send data error, please check the server\n"); + free(data); + return -1; } free(data); return 0; } -int wsclient_send_sql(char *command, WS_ACTION_TYPE type, int id) { +int wsclient_send_sql(char *command, WS_ACTION_TYPE type, int64_t id) { + int code = 1; cJSON *json = cJSON_CreateObject(); cJSON *_args = cJSON_CreateObject(); cJSON_AddNumberToObject(_args, "req_id", 1); @@ -1323,15 +1313,22 @@ int wsclient_send_sql(char *command, WS_ACTION_TYPE type, int id) { cJSON_AddStringToObject(json, "action", "fetch_block"); cJSON_AddNumberToObject(_args, "id", id); break; + case WS_CLOSE: + cJSON_AddStringToObject(json, "action", "close"); + cJSON_AddNumberToObject(_args, "id", id); + break; } cJSON_AddItemToObject(json, "args", _args); char *strdata = NULL; strdata = cJSON_Print(json); - if (wsclient_send(strdata)) { - free(strdata); - return -1; - } - return 0; + if (wsclient_send(strdata, TEXT_FRAME)) { + goto OVER; + } + code = 0; +OVER: + free(strdata); + cJSON_Delete(json); + return code; } int wsclient_conn() { @@ -1366,7 +1363,6 @@ int wsclient_conn() { } else { fprintf(stdout, "Successfully connect to %s:%d in restful mode\n\n", args.host, args.port); } - return 0; } else { cJSON *message = cJSON_GetObjectItem(root, "message"); @@ -1381,143 +1377,135 @@ int wsclient_conn() { return -1; } -cJSON *wsclient_parse_response() { - char *recv_buffer = calloc(1, 4096); - int start = 0; - bool found = false; - int received = 0; - int bytes; - int recv_length = 4095; - do { - bytes = recv(args.socket, recv_buffer + received, recv_length - received, 0); - if (bytes == -1) { - free(recv_buffer); - fprintf(stderr, "websocket recv failed with bytes: %d\n", bytes); - return NULL; +void wsclient_parse_frame(SWSParser * parser, uint8_t * recv_buffer) { + unsigned char msg_opcode = recv_buffer[0] & 0x0F; + unsigned char msg_masked = (recv_buffer[1] >> 7) & 0x01; + int payload_length = 0; + int pos = 2; + int length_field = recv_buffer[1] &(~0x80); + unsigned int mask = 0; + if (length_field <= 125) { + payload_length = length_field; + } else if (length_field == 126) { + payload_length = recv_buffer[2]; + for (int i = 0; i < 1; i++) { + payload_length = (payload_length << 8) + recv_buffer[3 + i]; } - - if (!found) { - for (; start < recv_length - received; start++) { - if ((recv_buffer + start)[0] == '{') { - found = true; - break; - } - } - } - if (NULL != strstr(recv_buffer + start, "}")) { - break; + pos += 2; + } else if (length_field == 127) { + payload_length = recv_buffer[2]; + for (int i = 0; i < 7; i++) { + payload_length = (payload_length << 8) + recv_buffer[3 + i]; } - received += bytes; - if (received >= recv_length) { - recv_length += 4096; - recv_buffer = realloc(recv_buffer + start, recv_length); + pos += 8; + } + if (msg_masked) { + mask = *((unsigned int *) (recv_buffer + pos)); + pos += 4; + const uint8_t *c = recv_buffer + pos; + for (int i = 0; i < payload_length; i++) { + recv_buffer[i] = c[i] ^ ((unsigned char *) (&mask))[i % 4]; } - } while (1); - cJSON *res = cJSON_Parse(recv_buffer + start); - if (res == NULL) { - fprintf(stderr, "fail to parse response into json: %s\n", recv_buffer + start); - free(recv_buffer); - return NULL; } - return res; + if (msg_opcode == 0x9) { + parser->frame = PING_FRAME; + } + parser->offset = pos; + parser->payload_length = payload_length; } -TAOS_FIELD *wsclient_print_header(cJSON *query, int *pcols, int *pprecison) { - TAOS_FIELD *fields = NULL; - cJSON *fields_count = cJSON_GetObjectItem(query, "fields_count"); - if (cJSON_IsNumber(fields_count)) { - *pcols = (int)fields_count->valueint; - fields = calloc((int)fields_count->valueint, sizeof(TAOS_FIELD)); - cJSON *fields_names = cJSON_GetObjectItem(query, "fields_names"); - cJSON *fields_types = cJSON_GetObjectItem(query, "fields_types"); - cJSON *fields_lengths = cJSON_GetObjectItem(query, "fields_lengths"); - if (cJSON_IsArray(fields_names) && cJSON_IsArray(fields_types) && cJSON_IsArray(fields_lengths)) { - for (int i = 0; i < (int)fields_count->valueint; i++) { - strncpy(fields[i].name, cJSON_GetArrayItem(fields_names, i)->valuestring, 65); - fields[i].type = (uint8_t)cJSON_GetArrayItem(fields_types, i)->valueint; - fields[i].bytes = (int16_t)cJSON_GetArrayItem(fields_lengths, i)->valueint; - } - cJSON *precision = cJSON_GetObjectItem(query, "precision"); - if (cJSON_IsNumber(precision)) { - *pprecison = (int)precision->valueint; - int width[TSDB_MAX_COLUMNS]; - for (int col = 0; col < (int)fields_count->valueint; col++) { - width[col] = calcColWidth(fields + col, (int)precision->valueint); - } - printHeader(fields, width, (int)fields_count->valueint); - return fields; - } else { - fprintf(stderr, "Invalid precision key in json\n"); - } - } else { - fprintf(stderr, "Invalid fields_names/fields_types/fields_lengths key in json\n"); +char *wsclient_get_response() { + uint8_t recv_buffer[TEMP_RECV_BUF]= {0}; + int received = 0; + SWSParser parser; + int bytes = recv(args.socket, recv_buffer + received, TEMP_RECV_BUF - 1, 0); + if (bytes <= 0) { + fprintf(stderr, "websocket recv failed with bytes: %d\n", bytes); + return NULL; + } + wsclient_parse_frame(&parser, recv_buffer); + if (parser.frame == PING_FRAME) { + if (wsclient_send("pong", PONG_FRAME)) { + return NULL; } - } else { - fprintf(stderr, "Invalid fields_count key in json\n"); + return wsclient_get_response(); + } + char* response = calloc(1, parser.payload_length + 1); + int pos = bytes - parser.offset; + memcpy(response, recv_buffer + parser.offset, pos); + while (pos < parser.payload_length) { + bytes = recv(args.socket, response + pos, parser.payload_length - pos, 0); + pos += bytes; } - if (fields != NULL) { - free(fields); + response[pos] = '\0'; + return response; +} + +int wsclient_fetch_fields(cJSON *query, TAOS_FIELD * fields, int cols) { + cJSON *fields_names = cJSON_GetObjectItem(query, "fields_names"); + cJSON *fields_types = cJSON_GetObjectItem(query, "fields_types"); + cJSON *fields_lengths = cJSON_GetObjectItem(query, "fields_lengths"); + if (!cJSON_IsArray(fields_names) || !cJSON_IsArray(fields_types) || !cJSON_IsArray(fields_lengths)) { + fprintf(stderr, "Invalid or miss 'fields_names'/'fields_types'/'fields_lengths' key in response\n"); + return -1; + } + for (int i = 0; i < cols; i++) { + cJSON* field_name = cJSON_GetArrayItem(fields_names, i); + cJSON* field_type = cJSON_GetArrayItem(fields_types, i); + cJSON* field_length = cJSON_GetArrayItem(fields_lengths, i); + if (!cJSON_IsString(field_name) || !cJSON_IsNumber(field_type) || !cJSON_IsNumber(field_length)) { + fprintf(stderr, "Invalid or miss 'field_name'/'field_type'/'field_length' in query response"); + return -1; + } + strncpy(fields[i].name, field_name->valuestring, 65); + fields[i].type = (uint8_t)field_type->valueint; + fields[i].bytes = (int16_t)field_length->valueint; } - return NULL; + return 0; } int wsclient_check(cJSON *root, int64_t st, int64_t et) { cJSON *code = cJSON_GetObjectItem(root, "code"); - if (cJSON_IsNumber(code)) { - if (code->valueint == 0) { - return 0; - } else { - cJSON *message = cJSON_GetObjectItem(root, "message"); - if (cJSON_IsString(message)) { - fprintf(stderr, "\nDB error: %s (%.6fs)\n", message->valuestring, (et - st) / 1E6); - } else { - fprintf(stderr, "Invalid message key in json\n"); - } - } - } else { - fprintf(stderr, "Invalid code key in json\n"); + cJSON *message = cJSON_GetObjectItem(root, "message"); + if (!cJSON_IsNumber(code) || !cJSON_IsString(message)) { + fprintf(stderr, "Invalid or miss 'code'/'message' in response\n"); + return -1; } - return -1; + if (code->valueint != 0) { + fprintf(stderr, "\nDB error: %s (%.6fs)\n", message->valuestring, (et - st) / 1E6); + return -1; + } + return 0; } int wsclient_print_data(int rows, TAOS_FIELD *fields, int cols, int64_t id, int precision, int* pshowed_rows) { - char *recv_buffer = calloc(1, 4096); - int col_length = 0; - for (int i = 0; i < cols; i++) { - col_length += fields[i].bytes; + char* response = wsclient_get_response(); + if (response == NULL) { + return -1; } - int total_recv_len = col_length * rows + 12; - int received = 0; - int recv_length = 4095; - int start = 0; - int pos; - do { - int bytes = recv(args.socket, recv_buffer + received, recv_length - received, 0); - received += bytes; - if (received >= recv_length) { - recv_length += 4096; - recv_buffer = realloc(recv_buffer, recv_length); - } - } while (received < total_recv_len); - while (1) { - if (*(int64_t *)(recv_buffer + start) == id) { - break; - } - start++; + if (*(int64_t *)response != id) { + fprintf(stderr, "Mismatch id with %"PRId64" expect %"PRId64"\n", *(int64_t *)response, id); + free(response); + return -1; } - start += 8; + int pos; int width[TSDB_MAX_COLUMNS]; for (int c = 0; c < cols; c++) { width[c] = calcColWidth(fields + c, precision); } for (int i = 0; i < rows; i++) { if (*pshowed_rows == DEFAULT_RES_SHOW_NUM) { - free(recv_buffer); + printf("\n"); + printf(" Notice: The result shows only the first %d rows.\n", DEFAULT_RES_SHOW_NUM); + printf("\n"); + printf(" You can use Ctrl+C to stop the underway fetching.\n"); + printf("\n"); + free(response); return 0; - } + } for (int c = 0; c < cols; c++) { - pos = start; + pos = 8; pos += i * fields[c].bytes; for (int j = 0; j < c; j++) { pos += fields[j].bytes * rows; @@ -1526,17 +1514,17 @@ int wsclient_print_data(int rows, TAOS_FIELD *fields, int cols, int64_t id, int int16_t length = 0; if (fields[c].type == TSDB_DATA_TYPE_NCHAR || fields[c].type == TSDB_DATA_TYPE_BINARY || fields[c].type == TSDB_DATA_TYPE_JSON) { - length = *(int16_t *)(recv_buffer + pos); + length = *(int16_t *)(response + pos); pos += 2; } - printField((const char *)(recv_buffer + pos), fields + c, width[c], (int32_t)length, precision); + printField((const char *)(response + pos), fields + c, width[c], (int32_t)length, precision); putchar(' '); putchar('|'); } putchar('\n'); *pshowed_rows += 1; } - free(recv_buffer); + free(response); return 0; } @@ -1546,90 +1534,129 @@ void wsclient_query(char *command) { if (wsclient_send_sql(command, WS_QUERY, 0)) { return; } - - et = taosGetTimestampUs(); - cJSON *query = wsclient_parse_response(); + char *query_buffer = wsclient_get_response(); + if (query_buffer == NULL) { + return; + } + cJSON* query = cJSON_Parse(query_buffer); if (query == NULL) { + fprintf(stderr, "Failed to parse response into json: %s\n", query_buffer); + free(query_buffer); return; } - + free(query_buffer); + et = taosGetTimestampUs(); if (wsclient_check(query, st, et)) { + cJSON_Delete(query); return; } cJSON *is_update = cJSON_GetObjectItem(query, "is_update"); - if (cJSON_IsBool(is_update)) { - if (is_update->valueint) { - cJSON *affected_rows = cJSON_GetObjectItem(query, "affected_rows"); - if (cJSON_IsNumber(affected_rows)) { - printf("Update OK, %d row(s) in set (%.6fs)\n\n", (int)affected_rows->valueint, (et - st) / 1E6); - } else { - fprintf(stderr, "Invalid affected_rows key in json\n"); - } + cJSON *fields_count = cJSON_GetObjectItem(query, "fields_count"); + cJSON *precisionObj = cJSON_GetObjectItem(query, "precision"); + cJSON *id = cJSON_GetObjectItem(query, "id"); + if (!cJSON_IsBool(is_update) || + !cJSON_IsNumber(fields_count) || + !cJSON_IsNumber(precisionObj) || + !cJSON_IsNumber(id)) { + fprintf(stderr, "Invalid or miss 'is_update'/'fields_count'/'precision'/'id' in query response\n"); + cJSON_Delete(query); + return; + } + if (is_update->valueint) { + cJSON *affected_rows = cJSON_GetObjectItem(query, "affected_rows"); + if (cJSON_IsNumber(affected_rows)) { + et = taosGetTimestampUs(); + printf("Update OK, %d row(s) in set (%.6fs)\n\n", (int)affected_rows->valueint, (et - st) / 1E6); } else { - int cols = 0; - int precision = 0; - int64_t total_rows = 0; - int showed_rows = 0; - TAOS_FIELD *fields = wsclient_print_header(query, &cols, &precision); - if (fields != NULL) { - cJSON *id = cJSON_GetObjectItem(query, "id"); - if (cJSON_IsNumber(id)) { - bool completed = false; - while (!completed) { - if (wsclient_send_sql(NULL, WS_FETCH, (int)id->valueint) == 0) { - cJSON *fetch = wsclient_parse_response(); - if (fetch != NULL) { - if (wsclient_check(fetch, st, et) == 0) { - cJSON *_completed = cJSON_GetObjectItem(fetch, "completed"); - if (cJSON_IsBool(_completed)) { - if (_completed->valueint) { - completed = true; - continue; - } - cJSON *rows = cJSON_GetObjectItem(fetch, "rows"); - if (cJSON_IsNumber(rows)) { - total_rows += rows->valueint; - cJSON *lengths = cJSON_GetObjectItem(fetch, "lengths"); - if (cJSON_IsArray(lengths)) { - for (int i = 0; i < cols; i++) { - fields[i].bytes = (int16_t)(cJSON_GetArrayItem(lengths, i)->valueint); - } - if (showed_rows < DEFAULT_RES_SHOW_NUM) { - if (wsclient_send_sql(NULL, WS_FETCH_BLOCK, (int)id->valueint) == 0) { - wsclient_print_data((int)rows->valueint, fields, cols, id->valueint, precision, &showed_rows); - } - } - continue; - } else { - fprintf(stderr, "Invalid lengths key in json\n"); - } - } else { - fprintf(stderr, "Invalid rows key in json\n"); - } - } else { - fprintf(stderr, "Invalid completed key in json\n"); - } - } - } - } - fprintf(stderr, "err occured in fetch/fetch_block ws actions\n"); - break; - } - if (showed_rows == DEFAULT_RES_SHOW_NUM) { - printf("\n"); - printf(" Notice: The result shows only the first %d rows.\n", DEFAULT_RES_SHOW_NUM); - printf("\n"); - } - printf("Query OK, %" PRId64 " row(s) in set (%.6fs)\n\n", total_rows, (et - st) / 1E6); - } else { - fprintf(stderr, "Invalid id key in json\n"); - } - free(fields); + fprintf(stderr, "Invalid or miss 'affected_rows' key in response\n"); + } + cJSON_Delete(query); + return; + } + ws_id = id->valueint; + int cols = (int)fields_count->valueint; + int precision = (int)precisionObj->valueint; + int64_t total_rows = 0; + int showed_rows = 0; + bool completed = false; + TAOS_FIELD fields[TSDB_MAX_COLUMNS]; + if (wsclient_fetch_fields(query, fields, cols)) { + cJSON_Delete(query); + return; + } + int width[TSDB_MAX_COLUMNS]; + for (int i = 0; i < cols; ++i) { + width[i] = calcColWidth(fields + i, precision); + } + printHeader(fields, width, cols); + + cJSON_Delete(query); + + while (!completed && !stop_fetch) { + if (wsclient_send_sql(NULL, WS_FETCH, ws_id)) { + return; + } + char *fetch_buffer = wsclient_get_response(); + if (fetch_buffer == NULL) { + return; + } + cJSON *fetch = cJSON_Parse(fetch_buffer); + if (fetch == NULL) { + fprintf(stderr, "failed to parse response into json: %s\n", fetch_buffer); + free(fetch_buffer); + return; + } + free(fetch_buffer); + if (wsclient_check(fetch, st, et)) { + cJSON_Delete(fetch); + return; + } + cJSON *completedObj = cJSON_GetObjectItem(fetch, "completed"); + cJSON *rows = cJSON_GetObjectItem(fetch, "rows"); + cJSON *lengths = cJSON_GetObjectItem(fetch, "lengths"); + if (!cJSON_IsBool(completedObj) || !cJSON_IsNumber(rows)) { + fprintf(stderr, "Invalid or miss 'completed'/'rows' in fetch response\n"); + cJSON_Delete(fetch); + return; + } + if (completedObj->valueint) { + cJSON_Delete(fetch); + completed = true; + continue; + } + total_rows += rows->valueint; + if (!cJSON_IsArray(lengths)) { + fprintf(stderr, "Invalid or miss 'lengths' in fetch response\n"); + cJSON_Delete(fetch); + return; + } + for (int i = 0; i < cols; i++) { + cJSON* length = cJSON_GetArrayItem(lengths, i); + if (!cJSON_IsNumber(length)) { + fprintf(stderr, "Invalid or miss 'lengths' key in fetch response\n"); + cJSON_Delete(fetch); + return; + } + fields[i].bytes = (int16_t)(length->valueint); + } + if (showed_rows < DEFAULT_RES_SHOW_NUM) { + if (wsclient_send_sql(NULL, WS_FETCH_BLOCK, ws_id)) { + cJSON_Delete(fetch); + return; + } + if (wsclient_print_data((int)rows->valueint, fields, cols, ws_id, precision, &showed_rows)) { + cJSON_Delete(fetch); + return; } + cJSON_Delete(fetch); + continue; } + } + et = taosGetTimestampUs(); + if (stop_fetch) { + printf("Query interrupted, %" PRId64 " row(s) in set (%.6fs)\n\n", total_rows, (et - st) / 1E6); + stop_fetch = false; } else { - fprintf(stderr, "Invalid is_update key in json\n"); + printf("Query OK, %" PRId64 " row(s) in set (%.6fs)\n\n", total_rows, (et - st) / 1E6); } - cJSON_Delete(query); - return; } \ No newline at end of file diff --git a/src/kit/shell/src/shellLinux.c b/src/kit/shell/src/shellLinux.c index 863da2e1a7..5bf8ada862 100644 --- a/src/kit/shell/src/shellLinux.c +++ b/src/kit/shell/src/shellLinux.c @@ -20,6 +20,7 @@ #include "shellCommand.h" #include "tkey.h" #include "tulog.h" +#include "shellAuto.h" #define OPT_ABORT 1 /* �Cabort */ @@ -283,7 +284,12 @@ int32_t shellReadCommand(TAOS *con, char *command) { utf8_array[k] = c; } insertChar(&cmd, utf8_array, count); + pressOtherKey(c); + } else if (c == TAB_KEY) { + // press TAB key + pressTabKey(con, &cmd); } else if (c < '\033') { + pressOtherKey(c); // Ctrl keys. TODO: Implement ctrl combinations switch (c) { case 1: // ctrl A @@ -329,8 +335,12 @@ int32_t shellReadCommand(TAOS *con, char *command) { case 21: // Ctrl + U; clearLineBefore(&cmd); break; + case 23: // Ctrl + W; + positionCursorMiddle(&cmd); + break; } } else if (c == '\033') { + pressOtherKey(c); c = (char)getchar(); switch (c) { case '[': @@ -405,9 +415,11 @@ int32_t shellReadCommand(TAOS *con, char *command) { break; } } else if (c == 0x7f) { + pressOtherKey(c); // press delete key backspaceChar(&cmd); } else { + pressOtherKey(c); insertChar(&cmd, &c, 1); } } @@ -556,14 +568,14 @@ void showOnScreen(Command *cmd) { /* assert(size >= 0); */ int width = wcwidth(wc); if (remain_column > width) { - printf("%lc", wc); + fprintf(stdout, "%lc", wc); remain_column -= width; } else { if (remain_column == width) { - printf("%lc\n\r", wc); + fprintf(stdout, "%lc\n\r", wc); remain_column = w.ws_col; } else { - printf("\n\r%lc", wc); + fprintf(stdout, "\n\r%lc", wc); remain_column = w.ws_col - width; } } diff --git a/src/kit/shell/src/shellMain.c b/src/kit/shell/src/shellMain.c index 149afc503e..c0b0b2b525 100644 --- a/src/kit/shell/src/shellMain.c +++ b/src/kit/shell/src/shellMain.c @@ -17,14 +17,20 @@ #include "shell.h" #include "tconfig.h" #include "tnettest.h" +#include "shellCommand.h" +#include "shellAuto.h" pthread_t pid; static tsem_t cancelSem; +bool stop_fetch = false; +int64_t ws_id = 0; void shellQueryInterruptHandler(int32_t signum, void *sigInfo, void *context) { tsem_post(&cancelSem); } +void shellRestfulSendInterruptHandler(int32_t signum, void *sigInfo, void *context) {} + void *cancelHandler(void *arg) { setThreadName("cancelHandler"); @@ -33,7 +39,12 @@ void *cancelHandler(void *arg) { taosMsleep(10); continue; } - + if (args.restful || args.cloud) { + stop_fetch = true; + if (wsclient_send_sql(NULL, WS_CLOSE, ws_id)) { + exit(EXIT_FAILURE); + } + } #ifdef LINUX int64_t rid = atomic_val_compare_exchange_64(&result, result, 0); SSqlObj* pSql = taosAcquireRef(tscObjRef, rid); @@ -87,6 +98,7 @@ SShellArguments args = {.host = NULL, .pktNum = 100, .pktType = "TCP", .netTestRole = NULL, + .cloudDsn = NULL, .cloud = true, .cloudHost = NULL, .cloudPort = NULL, @@ -159,13 +171,21 @@ int main(int argc, char* argv[]) { taosSetSignal(SIGINT, shellQueryInterruptHandler); taosSetSignal(SIGHUP, shellQueryInterruptHandler); taosSetSignal(SIGABRT, shellQueryInterruptHandler); + if (args.restful || args.cloud) { +#ifdef LINUX + taosSetSignal(SIGPIPE, shellRestfulSendInterruptHandler); +#endif + } /* Get grant information */ shellGetGrantInfo(args.con); + shellAutoInit(); /* Loop to query the input. */ while (1) { pthread_create(&pid, NULL, shellLoopQuery, args.con); pthread_join(pid, NULL); } + + shellAutoExit(); } diff --git a/src/kit/shell/src/tire.c b/src/kit/shell/src/tire.c new file mode 100644 index 0000000000..1ea27f5b9b --- /dev/null +++ b/src/kit/shell/src/tire.c @@ -0,0 +1,434 @@ +/* + * 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 . + */ + +#define __USE_XOPEN + +#include "os.h" +#include "tire.h" + +// ----------- interface ------------- + +// create prefix search tree +STire* createTire(char type) { + STire* tire = malloc(sizeof(STire)); + memset(tire, 0, sizeof(STire)); + tire->ref = 1; // init is 1 + tire->type = type; + tire->root.d = (STireNode **)calloc(CHAR_CNT, sizeof(STireNode *)); + return tire; +} + +// free tire node +void freeTireNode(STireNode* node) { + if (node == NULL) + return ; + + // nest free sub node on array d + if(node->d) { + for (int i = 0; i < CHAR_CNT; i++) { + freeTireNode(node->d[i]); + } + tfree(node->d); + } + + // free self + tfree(node); +} + +// destroy prefix search tree +void freeTire(STire* tire) { + // free nodes + for (int i = 0; i < CHAR_CNT; i++) { + freeTireNode(tire->root.d[i]); + } + tfree(tire->root.d); + + // free from list + StrName * item = tire->head; + while (item) { + // free string + tfree(item->name); + // free node + tfree(item); + + // move next + item = item->next; + } + tire->head = tire->tail = NULL; + + // free tire + tfree(tire); +} + +// insert a new word to list +bool insertToList(STire* tire, char* word) { + StrName * p = (StrName *)malloc(sizeof(StrName)); + p->name = strdup(word); + p->next = NULL; + + if(tire->head == NULL) { + tire->head = p; + tire->tail = p; + }else { + tire->tail->next = p; + tire->tail = p; + } + + return true; +} + +// insert a new word to tree +bool insertToTree(STire* tire, char* word, int len) { + int m = 0; + STireNode ** nodes = tire->root.d; + for (int i = 0; i < len; i++) { + m = word[i] - FIRST_ASCII; + if (m < 0 || m > CHAR_CNT) { + return false; + } + + if (nodes[m] == NULL) { + // no pointer + STireNode* p = (STireNode* )tmalloc(sizeof(STireNode)); + memset(p, 0, sizeof(STireNode)); + nodes[m] = p; + if (i == len - 1) { + // is end + p->end = true; + break; + } + } + + if (nodes[m]->d == NULL) { + // malloc d + nodes[m]->d = (STireNode **)calloc(CHAR_CNT, sizeof(STireNode *)); + } + + // move to next node + nodes = nodes[m]->d; + } + + // add count + tire->count += 1; + return true; +} + +// insert a new word +bool insertWord(STire* tire, char* word) { + int len = strlen(word); + if (len >= MAX_WORD_LEN) { + return false; + } + + switch (tire->type) { + case TIRE_TREE: + return insertToTree(tire, word, len); + case TIRE_LIST: + return insertToList(tire, word); + default: + break; + } + return false; +} + +// delete one word from list +bool deleteFromList(STire* tire, char* word) { + StrName * item = tire->head; + while (item) { + if (strcmp(item->name, word) == 0) { + // found, reset empty to delete + item->name[0] = 0; + } + + // move next + item = item->next; + } + return true; +} + +// delete one word from tree +bool deleteFromTree(STire* tire, char* word, int len) { + int m = 0; + bool del = false; + + STireNode** nodes = tire->root.d; + for (int i = 0; i < len; i++) { + m = word[i] - FIRST_ASCII; + if (m < 0 || m >= CHAR_CNT) { + return false; + } + + if (nodes[m] == NULL) { + // no found + return false; + } else { + // not null + if(i == len - 1) { + // this is last, only set end false , not free node + nodes[m]->end = false; + del = true; + break; + } + } + + if(nodes[m]->d == NULL) + break; + // move to next node + nodes = nodes[m]->d; + } + + // reduce count + if (del) { + tire->count -= 1; + } + + return del; +} + +// insert a new word +bool deleteWord(STire* tire, char* word) { + int len = strlen(word); + if (len >= MAX_WORD_LEN) { + return false; + } + + switch (tire->type) { + case TIRE_TREE: + return deleteFromTree(tire, word, len); + case TIRE_LIST: + return deleteFromList(tire, word); + default: + break; + } + return false; +} + +void addWordToMatch(SMatch* match, char* word){ + // malloc new + SMatchNode* node = (SMatchNode* )tmalloc(sizeof(SMatchNode)); + memset(node, 0, sizeof(SMatchNode)); + node->word = strdup(word); + + // append to match + if (match->head == NULL) { + match->head = match->tail = node; + } else { + match->tail->next = node; + match->tail = node; + } + match->count += 1; +} + +// enum all words from node +void enumAllWords(STireNode** nodes, char* prefix, SMatch* match) { + STireNode * c; + char word[MAX_WORD_LEN]; + int len = strlen(prefix); + for (int i = 0; i < CHAR_CNT; i++) { + c = nodes[i]; + + if (c == NULL) { + // chain end node + continue; + } else { + // combine word string + memset(word, 0, sizeof(word)); + strcpy(word, prefix); + word[len] = FIRST_ASCII + i; // append current char + + // chain middle node + if (c->end) { + // have end flag + addWordToMatch(match, word); + } + // nested call next layer + if (c->d) + enumAllWords(c->d, word, match); + } + } +} + +// match prefix from list +void matchPrefixFromList(STire* tire, char* prefix, SMatch* match) { + StrName * item = tire->head; + int len = strlen(prefix); + while (item) { + if ( strncmp(item->name, prefix, len) == 0) { + // prefix matched + addWordToMatch(match, item->name); + } + + // move next + item = item->next; + } +} + +// match prefix words, if match is not NULL , put all item to match and return match +void matchPrefixFromTree(STire* tire, char* prefix, SMatch* match) { + SMatch* root = match; + int m = 0; + STireNode* c = 0; + int len = strlen(prefix); + if (len >= MAX_WORD_LEN) { + return; + } + + STireNode** nodes = tire->root.d; + for (int i = 0; i < len; i++) { + m = prefix[i] - FIRST_ASCII; + if (m < 0 || m > CHAR_CNT) { + return; + } + + // match + c = nodes[m]; + if (c == NULL) { + // arrive end + break; + } + + // previous items already matched + if (i == len - 1) { + // malloc match if not pass by param match + if (root == NULL) { + root = (SMatch* )tmalloc(sizeof(SMatch)); + memset(root, 0, sizeof(SMatch)); + strcpy(root->pre, prefix); + } + + // prefix is match to end char + if (c->d) + enumAllWords(c->d, prefix, root); + } else { + // move to next node continue match + if(c->d == NULL) + break; + nodes = c->d; + } + } + + // return + return ; +} + +SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match) { + if(match == NULL) { + match = (SMatch* )tmalloc(sizeof(SMatch)); + memset(match, 0, sizeof(SMatch)); + } + + switch (tire->type) { + case TIRE_TREE: + matchPrefixFromTree(tire, prefix, match); + case TIRE_LIST: + matchPrefixFromList(tire, prefix, match); + default: + break; + } + + // return if need + if (match->count == 0) { + freeMatch(match); + match = NULL; + } + + return match; +} + + +// get all items from tires tree +void enumFromList(STire* tire, SMatch* match) { + StrName * item = tire->head; + while (item) { + if (item->name[0] != 0) { + // not delete + addWordToMatch(match, item->name); + } + + // move next + item = item->next; + } +} + +// get all items from tires tree +void enumFromTree(STire* tire, SMatch* match) { + char pre[2] ={0, 0}; + STireNode* c; + + // enum first layer + for (int i = 0; i < CHAR_CNT; i++) { + pre[0] = FIRST_ASCII + i; + + // each node + c = tire->root.d[i]; + if (c == NULL) { + // this branch no data + continue; + } + + // this branch have data + if(c->end) + addWordToMatch(match, pre); + else + matchPrefix(tire, pre, match); + } +} + +// get all items from tires tree +SMatch* enumAll(STire* tire) { + SMatch* match = (SMatch* )tmalloc(sizeof(SMatch)); + memset(match, 0, sizeof(SMatch)); + + switch (tire->type) { + case TIRE_TREE: + enumFromTree(tire, match); + case TIRE_LIST: + enumFromList(tire, match); + default: + break; + } + + // return if need + if (match->count == 0) { + freeMatch(match); + match = NULL; + } + + return match; +} + + +// free match result +void freeMatchNode(SMatchNode* node) { + // first free next + if (node->next) + freeMatchNode(node->next); + + // second free self + if (node->word) + free(node->word); + free(node); +} + +// free match result +void freeMatch(SMatch* match) { + // first free next + if (match->head) { + freeMatchNode(match->head); + } + + // second free self + free(match); +} diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c index 5392fc075b..63ea4ab6df 100644 --- a/src/tsdb/src/tsdbMain.c +++ b/src/tsdb/src/tsdbMain.c @@ -128,7 +128,7 @@ int tsdbCloseRepo(STsdbRepo *repo, int toCommit) { tsdbStopStream(pRepo); if(pRepo->pthread){ - taosDestoryThread(pRepo->pthread); + taosDestroyThread(pRepo->pthread); pRepo->pthread = NULL; } diff --git a/src/util/inc/tthread.h b/src/util/inc/tthread.h index 7443ad706d..9ef1c23035 100644 --- a/src/util/inc/tthread.h +++ b/src/util/inc/tthread.h @@ -26,7 +26,7 @@ extern "C" { // create new thread pthread_t* taosCreateThread( void *(*__start_routine) (void *), void* param); // destory thread -bool taosDestoryThread(pthread_t* pthread); +bool taosDestroyThread(pthread_t* pthread); // thread running return true bool taosThreadRunning(pthread_t* pthread); diff --git a/src/util/src/tthread.c b/src/util/src/tthread.c index 043b2de2f2..f77dea592e 100644 --- a/src/util/src/tthread.c +++ b/src/util/src/tthread.c @@ -38,7 +38,7 @@ pthread_t* taosCreateThread( void *(*__start_routine) (void *), void* param) { } // destory thread -bool taosDestoryThread(pthread_t* pthread) { +bool taosDestroyThread(pthread_t* pthread) { if(pthread == NULL) return false; if(taosThreadRunning(pthread)) { pthread_cancel(*pthread); diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c index 23181981e0..f215453f74 100644 --- a/src/vnode/src/vnodeMain.c +++ b/src/vnode/src/vnodeMain.c @@ -461,7 +461,7 @@ void vnodeStopWaitingThread(SVnodeObj* pVnode) { if(loop == 0) { vInfo("vgId:%d :SDEL force kill thread to quit. pthread=%p pWrite=%p", pVnode->vgId, pWaitThread->pthread, pWaitThread->param); // thread not stop , so need kill - taosDestoryThread(pWaitThread->pthread); + taosDestroyThread(pWaitThread->pthread); // write msg need remove from queue SVWriteMsg* pWrite = (SVWriteMsg* )pWaitThread->param; if (pWrite) -- GitLab From da484b7ab53922d86ebec79df948f0faae331581 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 16 Jul 2022 16:28:58 +0800 Subject: [PATCH 163/380] fix(query): rpc add context len --- src/client/src/tscServer.c | 2 +- src/rpc/src/rpcMain.c | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index de57f62fbe..435a6d7214 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -376,7 +376,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { // check queries already death static int activetyTimerCnt = 0; - if (++activetyTimerCnt > 5) { // 1.5s * 10 = 15s interval call + if (++activetyTimerCnt > 3) { // 1.5s * 10 = 15s interval call activetyTimerCnt = 0; // call check if have query doing diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index a8cd533e36..c4c2232e6b 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1710,7 +1710,7 @@ bool doRpcSendProbe(SRpcConn *pConn) { memcpy(pHead->user, pConn->user, tListLen(pHead->user)); pHead->code = htonl(code); - bool ret = rpcSendMsgToPeer(pConn, msg, sizeof(SRpcHead)); + bool ret = rpcSendMsgToPeer(pConn, msg, sizeof(SRpcHead) + sizeof(int32_t)); pConn->secured = 1; // connection shall be secured return ret; @@ -1778,13 +1778,17 @@ bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppF return false; } + if (pContext->pConn == NULL || pContext->pConn->chandle == NULL) { + return false; + } + if (ppContext) *ppContext = pContext; if (ppConn) *ppConn = pContext->pConn; - if (ppFdObj && pContext->pConn) + if (ppFdObj) *ppFdObj = pContext->pConn->chandle; - if (pFd && pContext->pConn && pContext->pConn->chandle) + if (pFd) *pFd = taosGetFdID(pContext->pConn->chandle); taosReleaseRef(tsRpcRefId, rpcRid); -- GitLab From 6fc5933ba142248e625d7441fc1a4a80efcd6f21 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 16 Jul 2022 16:37:28 +0800 Subject: [PATCH 164/380] feat(shell): autotab reset shellEngine.c --- src/kit/shell/src/shellEngine.c | 490 +++++++++++++++----------------- 1 file changed, 235 insertions(+), 255 deletions(-) diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index 5ac17c6a9d..681e7b90e6 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -137,7 +137,7 @@ void shellInit(SShellArguments *_args) { exit(EXIT_SUCCESS); } #endif - + return; } @@ -262,22 +262,41 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { int64_t st, et; wordexp_t full_path; char * sptr = NULL; + char * tmp = NULL; char * cptr = NULL; char * fname = NULL; bool printMode = false; + int match; + + sptr = command; + while ((sptr = tstrstr(sptr, ">>", true)) != NULL) { + // find the last ">>" if any + tmp = sptr; + sptr += 2; + } + + sptr = tmp; + + if (sptr != NULL) { + // select ... where col >> n op m ...; + match = regex_match(sptr + 2, "^\\s*.{1,}\\s*[\\>|\\<|\\<=|\\>=|=|!=]\\s*.{1,};\\s*$", REG_EXTENDED | REG_ICASE); + if (match == 0) { + // select col >> n from ...; + match = regex_match(sptr + 2, "^\\s*.{1,}\\s{1,}.{1,};\\s*$", REG_EXTENDED | REG_ICASE); + if (match == 0) { + cptr = tstrstr(command, ";", true); + if (cptr != NULL) { + *cptr = '\0'; + } - if ((sptr = tstrstr(command, ">>", true)) != NULL) { - cptr = tstrstr(command, ";", true); - if (cptr != NULL) { - *cptr = '\0'; - } - - if (wordexp(sptr + 2, &full_path, 0) != 0) { - fprintf(stderr, "ERROR: invalid filename: %s\n", sptr + 2); - return; + if (wordexp(sptr + 2, &full_path, 0) != 0) { + fprintf(stderr, "ERROR: invalid filename: %s\n", sptr + 2); + return; + } + *sptr = '\0'; + fname = full_path.we_wordv[0]; + } } - *sptr = '\0'; - fname = full_path.we_wordv[0]; } if ((sptr = tstrstr(command, "\\G", true)) != NULL) { @@ -305,12 +324,12 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { int64_t oresult = atomic_load_64(&result); - if (regex_match(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) { + if (regex_match(command, "^\\s*use\\s+([a-zA-Z0-9_]+|`.+`)\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) { fprintf(stdout, "Database changed.\n\n"); fflush(stdout); // call back auto tab module - callbackAutoTab(command, pSql, true); + callbackAutoTab(command, pSql, true); atomic_store_64(&result, 0); freeResultWithRid(oresult); @@ -346,14 +365,13 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { } else { printf("Query interrupted (%s), %d row(s) in set (%.6fs)\n", taos_errstr(pSql), numOfRows, (et - st) / 1E6); } - } else { int num_rows_affacted = taos_affected_rows(pSql); et = taosGetTimestampUs(); printf("Query OK, %d of %d row(s) in database (%.6fs)\n", num_rows_affacted, num_rows_affacted, (et - st) / 1E6); - + // call auto tab - callbackAutoTab(command, pSql, false); + callbackAutoTab(command, pSql, false); } printf("\n"); @@ -1144,7 +1162,7 @@ int taos_base64_encode(unsigned char *source, size_t sourcelen, char *target, si int parse_cloud_dsn() { if (args.cloudDsn == NULL) { fprintf(stderr, "Cannot read cloud service info\n"); - return -1; + return 1; } else { char *start = strstr(args.cloudDsn, "http://"); if (start != NULL) { @@ -1160,7 +1178,7 @@ int parse_cloud_dsn() { char *port = strstr(args.cloudHost, ":"); if ((port == NULL) || (port + strlen(":")) == NULL) { fprintf(stderr, "Invalid format in TDengine cloud dsn: %s\n", args.cloudDsn); - return -1; + return 1; } char *token = strstr(port + strlen(":"), "?token="); if ((token == NULL) || (token + strlen("?token=")) == NULL || @@ -1218,11 +1236,12 @@ int wsclient_handshake() { return 0; } -int wsclient_send(char *strdata, WebSocketFrameType frame) { +int wsclient_send(char *strdata) { struct timeval tv; unsigned char mask[4]; unsigned int mask_int; unsigned long long payload_len; + unsigned char finNopcode; unsigned int payload_len_small; unsigned int payload_offset = 6; unsigned int len_size; @@ -1236,6 +1255,7 @@ int wsclient_send(char *strdata, WebSocketFrameType frame) { mask_int = rand(); memcpy(mask, &mask_int, 4); payload_len = strlen(strdata); + finNopcode = 0x81; if (payload_len <= 125) { frame_size = 6 + payload_len; payload_len_small = payload_len; @@ -1253,7 +1273,7 @@ int wsclient_send(char *strdata, WebSocketFrameType frame) { } data = (char *)malloc(frame_size); memset(data, 0, frame_size); - *data = frame; + *data = finNopcode; *(data + 1) = payload_len_small | 0x80; if (payload_len_small == 126) { payload_len &= 0xffff; @@ -1280,16 +1300,13 @@ int wsclient_send(char *strdata, WebSocketFrameType frame) { sent += i; } if (i < 0) { - fprintf(stderr, "websocket send data error, please check the server\n"); - free(data); - return -1; + fprintf(stderr, "websocket send data error\n"); } free(data); return 0; } -int wsclient_send_sql(char *command, WS_ACTION_TYPE type, int64_t id) { - int code = 1; +int wsclient_send_sql(char *command, WS_ACTION_TYPE type, int id) { cJSON *json = cJSON_CreateObject(); cJSON *_args = cJSON_CreateObject(); cJSON_AddNumberToObject(_args, "req_id", 1); @@ -1313,22 +1330,15 @@ int wsclient_send_sql(char *command, WS_ACTION_TYPE type, int64_t id) { cJSON_AddStringToObject(json, "action", "fetch_block"); cJSON_AddNumberToObject(_args, "id", id); break; - case WS_CLOSE: - cJSON_AddStringToObject(json, "action", "close"); - cJSON_AddNumberToObject(_args, "id", id); - break; } cJSON_AddItemToObject(json, "args", _args); char *strdata = NULL; strdata = cJSON_Print(json); - if (wsclient_send(strdata, TEXT_FRAME)) { - goto OVER; - } - code = 0; -OVER: - free(strdata); - cJSON_Delete(json); - return code; + if (wsclient_send(strdata)) { + free(strdata); + return -1; + } + return 0; } int wsclient_conn() { @@ -1363,6 +1373,7 @@ int wsclient_conn() { } else { fprintf(stdout, "Successfully connect to %s:%d in restful mode\n\n", args.host, args.port); } + return 0; } else { cJSON *message = cJSON_GetObjectItem(root, "message"); @@ -1377,135 +1388,143 @@ int wsclient_conn() { return -1; } -void wsclient_parse_frame(SWSParser * parser, uint8_t * recv_buffer) { - unsigned char msg_opcode = recv_buffer[0] & 0x0F; - unsigned char msg_masked = (recv_buffer[1] >> 7) & 0x01; - int payload_length = 0; - int pos = 2; - int length_field = recv_buffer[1] &(~0x80); - unsigned int mask = 0; - if (length_field <= 125) { - payload_length = length_field; - } else if (length_field == 126) { - payload_length = recv_buffer[2]; - for (int i = 0; i < 1; i++) { - payload_length = (payload_length << 8) + recv_buffer[3 + i]; +cJSON *wsclient_parse_response() { + char *recv_buffer = calloc(1, 4096); + int start = 0; + bool found = false; + int received = 0; + int bytes; + int recv_length = 4095; + do { + bytes = recv(args.socket, recv_buffer + received, recv_length - received, 0); + if (bytes == -1) { + free(recv_buffer); + fprintf(stderr, "websocket recv failed with bytes: %d\n", bytes); + return NULL; } - pos += 2; - } else if (length_field == 127) { - payload_length = recv_buffer[2]; - for (int i = 0; i < 7; i++) { - payload_length = (payload_length << 8) + recv_buffer[3 + i]; + + if (!found) { + for (; start < recv_length - received; start++) { + if ((recv_buffer + start)[0] == '{') { + found = true; + break; + } + } } - pos += 8; - } - if (msg_masked) { - mask = *((unsigned int *) (recv_buffer + pos)); - pos += 4; - const uint8_t *c = recv_buffer + pos; - for (int i = 0; i < payload_length; i++) { - recv_buffer[i] = c[i] ^ ((unsigned char *) (&mask))[i % 4]; + if (NULL != strstr(recv_buffer + start, "}")) { + break; } - } - if (msg_opcode == 0x9) { - parser->frame = PING_FRAME; - } - parser->offset = pos; - parser->payload_length = payload_length; -} - -char *wsclient_get_response() { - uint8_t recv_buffer[TEMP_RECV_BUF]= {0}; - int received = 0; - SWSParser parser; - int bytes = recv(args.socket, recv_buffer + received, TEMP_RECV_BUF - 1, 0); - if (bytes <= 0) { - fprintf(stderr, "websocket recv failed with bytes: %d\n", bytes); - return NULL; - } - wsclient_parse_frame(&parser, recv_buffer); - if (parser.frame == PING_FRAME) { - if (wsclient_send("pong", PONG_FRAME)) { - return NULL; + received += bytes; + if (received >= recv_length) { + recv_length += 4096; + recv_buffer = realloc(recv_buffer + start, recv_length); } - return wsclient_get_response(); - } - char* response = calloc(1, parser.payload_length + 1); - int pos = bytes - parser.offset; - memcpy(response, recv_buffer + parser.offset, pos); - while (pos < parser.payload_length) { - bytes = recv(args.socket, response + pos, parser.payload_length - pos, 0); - pos += bytes; + } while (1); + cJSON *res = cJSON_Parse(recv_buffer + start); + if (res == NULL) { + fprintf(stderr, "fail to parse response into json: %s\n", recv_buffer + start); + free(recv_buffer); + return NULL; } - response[pos] = '\0'; - return response; + return res; } -int wsclient_fetch_fields(cJSON *query, TAOS_FIELD * fields, int cols) { - cJSON *fields_names = cJSON_GetObjectItem(query, "fields_names"); - cJSON *fields_types = cJSON_GetObjectItem(query, "fields_types"); - cJSON *fields_lengths = cJSON_GetObjectItem(query, "fields_lengths"); - if (!cJSON_IsArray(fields_names) || !cJSON_IsArray(fields_types) || !cJSON_IsArray(fields_lengths)) { - fprintf(stderr, "Invalid or miss 'fields_names'/'fields_types'/'fields_lengths' key in response\n"); - return -1; - } - for (int i = 0; i < cols; i++) { - cJSON* field_name = cJSON_GetArrayItem(fields_names, i); - cJSON* field_type = cJSON_GetArrayItem(fields_types, i); - cJSON* field_length = cJSON_GetArrayItem(fields_lengths, i); - if (!cJSON_IsString(field_name) || !cJSON_IsNumber(field_type) || !cJSON_IsNumber(field_length)) { - fprintf(stderr, "Invalid or miss 'field_name'/'field_type'/'field_length' in query response"); - return -1; +TAOS_FIELD *wsclient_print_header(cJSON *query, int *pcols, int *pprecison) { + TAOS_FIELD *fields = NULL; + cJSON *fields_count = cJSON_GetObjectItem(query, "fields_count"); + if (cJSON_IsNumber(fields_count)) { + *pcols = (int)fields_count->valueint; + fields = calloc((int)fields_count->valueint, sizeof(TAOS_FIELD)); + cJSON *fields_names = cJSON_GetObjectItem(query, "fields_names"); + cJSON *fields_types = cJSON_GetObjectItem(query, "fields_types"); + cJSON *fields_lengths = cJSON_GetObjectItem(query, "fields_lengths"); + if (cJSON_IsArray(fields_names) && cJSON_IsArray(fields_types) && cJSON_IsArray(fields_lengths)) { + for (int i = 0; i < (int)fields_count->valueint; i++) { + strncpy(fields[i].name, cJSON_GetArrayItem(fields_names, i)->valuestring, 65); + fields[i].type = (uint8_t)cJSON_GetArrayItem(fields_types, i)->valueint; + fields[i].bytes = (int16_t)cJSON_GetArrayItem(fields_lengths, i)->valueint; + } + cJSON *precision = cJSON_GetObjectItem(query, "precision"); + if (cJSON_IsNumber(precision)) { + *pprecison = (int)precision->valueint; + int width[TSDB_MAX_COLUMNS]; + for (int col = 0; col < (int)fields_count->valueint; col++) { + width[col] = calcColWidth(fields + col, (int)precision->valueint); + } + printHeader(fields, width, (int)fields_count->valueint); + return fields; + } else { + fprintf(stderr, "Invalid precision key in json\n"); + } + } else { + fprintf(stderr, "Invalid fields_names/fields_types/fields_lengths key in json\n"); } - strncpy(fields[i].name, field_name->valuestring, 65); - fields[i].type = (uint8_t)field_type->valueint; - fields[i].bytes = (int16_t)field_length->valueint; + } else { + fprintf(stderr, "Invalid fields_count key in json\n"); } - return 0; + if (fields != NULL) { + free(fields); + } + return NULL; } int wsclient_check(cJSON *root, int64_t st, int64_t et) { cJSON *code = cJSON_GetObjectItem(root, "code"); - cJSON *message = cJSON_GetObjectItem(root, "message"); - if (!cJSON_IsNumber(code) || !cJSON_IsString(message)) { - fprintf(stderr, "Invalid or miss 'code'/'message' in response\n"); - return -1; - } - if (code->valueint != 0) { - fprintf(stderr, "\nDB error: %s (%.6fs)\n", message->valuestring, (et - st) / 1E6); - return -1; + if (cJSON_IsNumber(code)) { + if (code->valueint == 0) { + return 0; + } else { + cJSON *message = cJSON_GetObjectItem(root, "message"); + if (cJSON_IsString(message)) { + fprintf(stderr, "\nDB error: %s (%.6fs)\n", message->valuestring, (et - st) / 1E6); + } else { + fprintf(stderr, "Invalid message key in json\n"); + } + } + } else { + fprintf(stderr, "Invalid code key in json\n"); } - return 0; + return -1; } int wsclient_print_data(int rows, TAOS_FIELD *fields, int cols, int64_t id, int precision, int* pshowed_rows) { - char* response = wsclient_get_response(); - if (response == NULL) { - return -1; + char *recv_buffer = calloc(1, 4096); + int col_length = 0; + for (int i = 0; i < cols; i++) { + col_length += fields[i].bytes; } + int total_recv_len = col_length * rows + 12; + int received = 0; + int recv_length = 4095; + int start = 0; + int pos; + do { + int bytes = recv(args.socket, recv_buffer + received, recv_length - received, 0); + received += bytes; + if (received >= recv_length) { + recv_length += 4096; + recv_buffer = realloc(recv_buffer, recv_length); + } + } while (received < total_recv_len); - if (*(int64_t *)response != id) { - fprintf(stderr, "Mismatch id with %"PRId64" expect %"PRId64"\n", *(int64_t *)response, id); - free(response); - return -1; + while (1) { + if (*(int64_t *)(recv_buffer + start) == id) { + break; + } + start++; } - int pos; + start += 8; int width[TSDB_MAX_COLUMNS]; for (int c = 0; c < cols; c++) { width[c] = calcColWidth(fields + c, precision); } for (int i = 0; i < rows; i++) { if (*pshowed_rows == DEFAULT_RES_SHOW_NUM) { - printf("\n"); - printf(" Notice: The result shows only the first %d rows.\n", DEFAULT_RES_SHOW_NUM); - printf("\n"); - printf(" You can use Ctrl+C to stop the underway fetching.\n"); - printf("\n"); - free(response); + free(recv_buffer); return 0; - } + } for (int c = 0; c < cols; c++) { - pos = 8; + pos = start; pos += i * fields[c].bytes; for (int j = 0; j < c; j++) { pos += fields[j].bytes * rows; @@ -1514,17 +1533,17 @@ int wsclient_print_data(int rows, TAOS_FIELD *fields, int cols, int64_t id, int int16_t length = 0; if (fields[c].type == TSDB_DATA_TYPE_NCHAR || fields[c].type == TSDB_DATA_TYPE_BINARY || fields[c].type == TSDB_DATA_TYPE_JSON) { - length = *(int16_t *)(response + pos); + length = *(int16_t *)(recv_buffer + pos); pos += 2; } - printField((const char *)(response + pos), fields + c, width[c], (int32_t)length, precision); + printField((const char *)(recv_buffer + pos), fields + c, width[c], (int32_t)length, precision); putchar(' '); putchar('|'); } putchar('\n'); *pshowed_rows += 1; } - free(response); + free(recv_buffer); return 0; } @@ -1534,129 +1553,90 @@ void wsclient_query(char *command) { if (wsclient_send_sql(command, WS_QUERY, 0)) { return; } - char *query_buffer = wsclient_get_response(); - if (query_buffer == NULL) { - return; - } - cJSON* query = cJSON_Parse(query_buffer); + + et = taosGetTimestampUs(); + cJSON *query = wsclient_parse_response(); if (query == NULL) { - fprintf(stderr, "Failed to parse response into json: %s\n", query_buffer); - free(query_buffer); return; } - free(query_buffer); - et = taosGetTimestampUs(); + if (wsclient_check(query, st, et)) { - cJSON_Delete(query); return; } cJSON *is_update = cJSON_GetObjectItem(query, "is_update"); - cJSON *fields_count = cJSON_GetObjectItem(query, "fields_count"); - cJSON *precisionObj = cJSON_GetObjectItem(query, "precision"); - cJSON *id = cJSON_GetObjectItem(query, "id"); - if (!cJSON_IsBool(is_update) || - !cJSON_IsNumber(fields_count) || - !cJSON_IsNumber(precisionObj) || - !cJSON_IsNumber(id)) { - fprintf(stderr, "Invalid or miss 'is_update'/'fields_count'/'precision'/'id' in query response\n"); - cJSON_Delete(query); - return; - } - if (is_update->valueint) { - cJSON *affected_rows = cJSON_GetObjectItem(query, "affected_rows"); - if (cJSON_IsNumber(affected_rows)) { - et = taosGetTimestampUs(); - printf("Update OK, %d row(s) in set (%.6fs)\n\n", (int)affected_rows->valueint, (et - st) / 1E6); - } else { - fprintf(stderr, "Invalid or miss 'affected_rows' key in response\n"); - } - cJSON_Delete(query); - return; - } - ws_id = id->valueint; - int cols = (int)fields_count->valueint; - int precision = (int)precisionObj->valueint; - int64_t total_rows = 0; - int showed_rows = 0; - bool completed = false; - TAOS_FIELD fields[TSDB_MAX_COLUMNS]; - if (wsclient_fetch_fields(query, fields, cols)) { - cJSON_Delete(query); - return; - } - int width[TSDB_MAX_COLUMNS]; - for (int i = 0; i < cols; ++i) { - width[i] = calcColWidth(fields + i, precision); - } - printHeader(fields, width, cols); - - cJSON_Delete(query); - - while (!completed && !stop_fetch) { - if (wsclient_send_sql(NULL, WS_FETCH, ws_id)) { - return; - } - char *fetch_buffer = wsclient_get_response(); - if (fetch_buffer == NULL) { - return; - } - cJSON *fetch = cJSON_Parse(fetch_buffer); - if (fetch == NULL) { - fprintf(stderr, "failed to parse response into json: %s\n", fetch_buffer); - free(fetch_buffer); - return; - } - free(fetch_buffer); - if (wsclient_check(fetch, st, et)) { - cJSON_Delete(fetch); - return; - } - cJSON *completedObj = cJSON_GetObjectItem(fetch, "completed"); - cJSON *rows = cJSON_GetObjectItem(fetch, "rows"); - cJSON *lengths = cJSON_GetObjectItem(fetch, "lengths"); - if (!cJSON_IsBool(completedObj) || !cJSON_IsNumber(rows)) { - fprintf(stderr, "Invalid or miss 'completed'/'rows' in fetch response\n"); - cJSON_Delete(fetch); - return; - } - if (completedObj->valueint) { - cJSON_Delete(fetch); - completed = true; - continue; - } - total_rows += rows->valueint; - if (!cJSON_IsArray(lengths)) { - fprintf(stderr, "Invalid or miss 'lengths' in fetch response\n"); - cJSON_Delete(fetch); - return; - } - for (int i = 0; i < cols; i++) { - cJSON* length = cJSON_GetArrayItem(lengths, i); - if (!cJSON_IsNumber(length)) { - fprintf(stderr, "Invalid or miss 'lengths' key in fetch response\n"); - cJSON_Delete(fetch); - return; - } - fields[i].bytes = (int16_t)(length->valueint); - } - if (showed_rows < DEFAULT_RES_SHOW_NUM) { - if (wsclient_send_sql(NULL, WS_FETCH_BLOCK, ws_id)) { - cJSON_Delete(fetch); - return; + if (cJSON_IsBool(is_update)) { + if (is_update->valueint) { + cJSON *affected_rows = cJSON_GetObjectItem(query, "affected_rows"); + if (cJSON_IsNumber(affected_rows)) { + printf("Update OK, %d row(s) in set (%.6fs)\n\n", (int)affected_rows->valueint, (et - st) / 1E6); + } else { + fprintf(stderr, "Invalid affected_rows key in json\n"); } - if (wsclient_print_data((int)rows->valueint, fields, cols, ws_id, precision, &showed_rows)) { - cJSON_Delete(fetch); - return; + } else { + int cols = 0; + int precision = 0; + int64_t total_rows = 0; + int showed_rows = 0; + TAOS_FIELD *fields = wsclient_print_header(query, &cols, &precision); + if (fields != NULL) { + cJSON *id = cJSON_GetObjectItem(query, "id"); + if (cJSON_IsNumber(id)) { + bool completed = false; + while (!completed) { + if (wsclient_send_sql(NULL, WS_FETCH, (int)id->valueint) == 0) { + cJSON *fetch = wsclient_parse_response(); + if (fetch != NULL) { + if (wsclient_check(fetch, st, et) == 0) { + cJSON *_completed = cJSON_GetObjectItem(fetch, "completed"); + if (cJSON_IsBool(_completed)) { + if (_completed->valueint) { + completed = true; + continue; + } + cJSON *rows = cJSON_GetObjectItem(fetch, "rows"); + if (cJSON_IsNumber(rows)) { + total_rows += rows->valueint; + cJSON *lengths = cJSON_GetObjectItem(fetch, "lengths"); + if (cJSON_IsArray(lengths)) { + for (int i = 0; i < cols; i++) { + fields[i].bytes = (int16_t)(cJSON_GetArrayItem(lengths, i)->valueint); + } + if (showed_rows < DEFAULT_RES_SHOW_NUM) { + if (wsclient_send_sql(NULL, WS_FETCH_BLOCK, (int)id->valueint) == 0) { + wsclient_print_data((int)rows->valueint, fields, cols, id->valueint, precision, &showed_rows); + } + } + continue; + } else { + fprintf(stderr, "Invalid lengths key in json\n"); + } + } else { + fprintf(stderr, "Invalid rows key in json\n"); + } + } else { + fprintf(stderr, "Invalid completed key in json\n"); + } + } + } + } + fprintf(stderr, "err occured in fetch/fetch_block ws actions\n"); + break; + } + if (showed_rows == DEFAULT_RES_SHOW_NUM) { + printf("\n"); + printf(" Notice: The result shows only the first %d rows.\n", DEFAULT_RES_SHOW_NUM); + printf("\n"); + } + printf("Query OK, %" PRId64 " row(s) in set (%.6fs)\n\n", total_rows, (et - st) / 1E6); + } else { + fprintf(stderr, "Invalid id key in json\n"); + } + free(fields); } - cJSON_Delete(fetch); - continue; } - } - et = taosGetTimestampUs(); - if (stop_fetch) { - printf("Query interrupted, %" PRId64 " row(s) in set (%.6fs)\n\n", total_rows, (et - st) / 1E6); - stop_fetch = false; } else { - printf("Query OK, %" PRId64 " row(s) in set (%.6fs)\n\n", total_rows, (et - st) / 1E6); + fprintf(stderr, "Invalid is_update key in json\n"); } + cJSON_Delete(query); + return; } \ No newline at end of file -- GitLab From 5cb0fa774156cf75b8baf3ec1fd4c6e276e29d29 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 16 Jul 2022 16:43:12 +0800 Subject: [PATCH 165/380] feat(shell): autotab reset shellMain.c --- src/kit/shell/src/shellMain.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/kit/shell/src/shellMain.c b/src/kit/shell/src/shellMain.c index c0b0b2b525..3e84332834 100644 --- a/src/kit/shell/src/shellMain.c +++ b/src/kit/shell/src/shellMain.c @@ -22,15 +22,11 @@ pthread_t pid; static tsem_t cancelSem; -bool stop_fetch = false; -int64_t ws_id = 0; void shellQueryInterruptHandler(int32_t signum, void *sigInfo, void *context) { tsem_post(&cancelSem); } -void shellRestfulSendInterruptHandler(int32_t signum, void *sigInfo, void *context) {} - void *cancelHandler(void *arg) { setThreadName("cancelHandler"); @@ -39,12 +35,7 @@ void *cancelHandler(void *arg) { taosMsleep(10); continue; } - if (args.restful || args.cloud) { - stop_fetch = true; - if (wsclient_send_sql(NULL, WS_CLOSE, ws_id)) { - exit(EXIT_FAILURE); - } - } + #ifdef LINUX int64_t rid = atomic_val_compare_exchange_64(&result, result, 0); SSqlObj* pSql = taosAcquireRef(tscObjRef, rid); @@ -98,7 +89,6 @@ SShellArguments args = {.host = NULL, .pktNum = 100, .pktType = "TCP", .netTestRole = NULL, - .cloudDsn = NULL, .cloud = true, .cloudHost = NULL, .cloudPort = NULL, @@ -171,11 +161,6 @@ int main(int argc, char* argv[]) { taosSetSignal(SIGINT, shellQueryInterruptHandler); taosSetSignal(SIGHUP, shellQueryInterruptHandler); taosSetSignal(SIGABRT, shellQueryInterruptHandler); - if (args.restful || args.cloud) { -#ifdef LINUX - taosSetSignal(SIGPIPE, shellRestfulSendInterruptHandler); -#endif - } /* Get grant information */ shellGetGrantInfo(args.con); -- GitLab From 199dbab9dca8108d71df1af1eed67de47ad67b45 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 16 Jul 2022 17:05:41 +0800 Subject: [PATCH 166/380] feat(shell): modify tab help info --- src/kit/shell/src/shellAuto.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/kit/shell/src/shellAuto.c b/src/kit/shell/src/shellAuto.c index 265bda2262..7ac120156c 100644 --- a/src/kit/shell/src/shellAuto.c +++ b/src/kit/shell/src/shellAuto.c @@ -323,8 +323,9 @@ int cntDel = 0; // delete byte count after next press tab void printfIntroduction() { printf(" **************************** SUPPORT TAB KEY ************************************\n"); printf(" * Taos shell support press TAB key to complete word. You can try it. *\n"); - printf(" * Anywhere press SPACE key following TAB key, You'll get surprise. *\n"); - printf(" * SUPPORT SHORTCUT: *\n"); + printf(" * Press TAB key anywhere, You'll get surprise. *\n"); + printf(" * SUPPORT KEYBOARD SHORTCUT: *\n"); + printf(" * [ TAB ] ...... if prefix nothing show help else complete word *\n"); printf(" * [ Ctrl + A ] ...... move cursor to line [A]head *\n"); printf(" * [ Ctrl + M ] ...... move cursor to line [M]iddle *\n"); printf(" * [ Ctrl + E ] ...... move cursor to line [E]nd *\n"); -- GitLab From 881d814882cd1e1bd8454ef6150308a3585e35f6 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 16 Jul 2022 17:09:10 +0800 Subject: [PATCH 167/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index d807c3ffa6..b7b922268c 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit d807c3ffa6f750f7765e102917d1328cadf21c13 +Subproject commit b7b922268c4a06d9db77ffdfde0726f3d9900b72 -- GitLab From f373823197258f135fc66a754ba7a0f1aaae956f Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 16 Jul 2022 17:45:14 +0800 Subject: [PATCH 168/380] feat: update taostools for2.6 (#14996) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index d807c3ffa6..b7b922268c 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit d807c3ffa6f750f7765e102917d1328cadf21c13 +Subproject commit b7b922268c4a06d9db77ffdfde0726f3d9900b72 -- GitLab From a6dda144bcb9e7e7426ca5a36a1a65d98a07a3c2 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 16 Jul 2022 18:00:56 +0800 Subject: [PATCH 169/380] feat(shell): support maxos autotab --- src/kit/shell/CMakeLists.txt | 2 ++ src/kit/shell/src/shellAuto.c | 12 +++++------- src/kit/shell/src/shellDarwin.c | 14 +++++++++++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/kit/shell/CMakeLists.txt b/src/kit/shell/CMakeLists.txt index b311361c43..614fa328ba 100644 --- a/src/kit/shell/CMakeLists.txt +++ b/src/kit/shell/CMakeLists.txt @@ -46,6 +46,8 @@ ELSEIF (TD_DARWIN) LIST(APPEND SRC ./src/shellCommand.c) LIST(APPEND SRC ./src/shellImport.c) LIST(APPEND SRC ./src/shellCheck.c) + LIST(APPEND SRC ./src/shellAuto.c) + LIST(APPEND SRC ./src/tire.c) ADD_EXECUTABLE(shell ${SRC}) # linking with dylib TARGET_LINK_LIBRARIES(shell taos cJson) diff --git a/src/kit/shell/src/shellAuto.c b/src/kit/shell/src/shellAuto.c index 7ac120156c..8b69566329 100644 --- a/src/kit/shell/src/shellAuto.c +++ b/src/kit/shell/src/shellAuto.c @@ -118,6 +118,7 @@ SWords shellCommands[] = { {"show variables;", 0, 0, NULL}, {"show vgroups;", 0, 0, NULL}, {"insert into values(", 0, 0, NULL}, + {"insert into using tags(", 0, 0, NULL}, {"use ", 0, 0, NULL} }; @@ -227,14 +228,14 @@ char * db_options[] = { char * data_types[] = { "timestamp", "int", - "bigint", "float", "double", - "binary", + "binary(16)", + "nchar(16)", + "bigint", "smallint", "tinyint", "bool", - "nchar", "json" }; @@ -564,7 +565,7 @@ bool shellAutoInit() { pthread_mutex_init(&tiresMutex, NULL); // threads - memset(threads, 0, sizeof(pthread_t*) * WT_VAR_CNT); + memset(threads, 0, sizeof(pthread_t*) * WT_FROM_DB_CNT); // generate varType GenerateVarType(WT_VAR_FUNC, functions, sizeof(functions) /sizeof(char *)); @@ -1535,9 +1536,6 @@ void pressOtherKey(char c) { freeMatch(lastMatch); lastMatch = NULL; } - - //printf(" -> %d <-\n", c); - } // put name into name, return name length diff --git a/src/kit/shell/src/shellDarwin.c b/src/kit/shell/src/shellDarwin.c index 7803113a0f..fa3afd131a 100644 --- a/src/kit/shell/src/shellDarwin.c +++ b/src/kit/shell/src/shellDarwin.c @@ -22,6 +22,7 @@ #include "tkey.h" #include "tscLog.h" +#include "shellAuto.h" #define OPT_ABORT 1 /* �Cabort */ @@ -255,7 +256,12 @@ int32_t shellReadCommand(TAOS *con, char *command) { utf8_array[k] = c; } insertChar(&cmd, utf8_array, count); + pressOtherKey(c); + } else if (c == TAB_KEY) { + // press TAB key + pressTabKey(con, &cmd); } else if (c < '\033') { + pressOtherKey(c); // Ctrl keys. TODO: Implement ctrl combinations switch (c) { case 1: // ctrl A @@ -377,9 +383,11 @@ int32_t shellReadCommand(TAOS *con, char *command) { break; } } else if (c == 0x7f) { + pressOtherKey(c); // press delete key backspaceChar(&cmd); } else { + pressOtherKey(c); insertChar(&cmd, &c, 1); } } @@ -528,14 +536,14 @@ void showOnScreen(Command *cmd) { /* assert(size >= 0); */ int width = wcwidth(wc); if (remain_column > width) { - printf("%lc", wc); + fprintf(stdout, "%lc", wc); remain_column -= width; } else { if (remain_column == width) { - printf("%lc\n\r", wc); + fprintf(stdout, "%lc\n\r", wc); remain_column = w.ws_col; } else { - printf("\n\r%lc", wc); + fprintf(stdout, "\n\r%lc", wc); remain_column = w.ws_col - width; } } -- GitLab From 6ed6f0fc8cd16d213548ddb06fef3267927944ce Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 16 Jul 2022 20:03:38 +0800 Subject: [PATCH 170/380] feat(shell): -DMEMORY_SANITIZER=true check memory leak and fix --- src/kit/shell/src/shellAuto.c | 43 +++++++++++++++++++++-------------- src/kit/shell/src/tire.c | 3 ++- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/kit/shell/src/shellAuto.c b/src/kit/shell/src/shellAuto.c index 8b69566329..916ce1fa49 100644 --- a/src/kit/shell/src/shellAuto.c +++ b/src/kit/shell/src/shellAuto.c @@ -83,11 +83,11 @@ SWords shellCommands[] = { {"delete from where", 0, 0, NULL}, #endif {"drop database ", 0, 0, NULL}, + {"drop table ", 0, 0, NULL}, {"drop dnode ", 0, 0, NULL}, + {"drop user ;", 0, 0, NULL}, {"drop function", 0, 0, NULL}, {"drop topic", 0, 0, NULL}, - {"drop table ;", 0, 0, NULL}, - {"drop user ;", 0, 0, NULL}, {"kill connection", 0, 0, NULL}, {"kill query", 0, 0, NULL}, {"kill stream", 0, 0, NULL}, @@ -366,10 +366,10 @@ void showHelp() { describe ;\n\ delete from where ... \n\ drop database ;\n\ + drop table ;\n\ drop dnode ;\n\ drop function ;\n\ drop topic ;\n\ - drop table ;\n\ drop user ;\n\ ----- K ----- \n\ kill connection ; \n\ @@ -1087,12 +1087,14 @@ bool firstMatchCommand(TAOS * con, Command * cmd) { if (match == NULL) { // not match , nothing to do freeCommand(input); + free(input); return false; } // print to screen printScreen(con, cmd, match); freeCommand(input); + free(input); return true; } @@ -1145,6 +1147,9 @@ bool nextMatchCommand(TAOS * con, Command * cmd, SWords * firstMatch) { match = matchCommand(input, false); if (match == NULL) { freeCommand(input); + if (input->source) + free(input->source); + free(input); return false; } } @@ -1158,6 +1163,7 @@ bool nextMatchCommand(TAOS * con, Command * cmd, SWords * firstMatch) { input->source = NULL; } freeCommand(input); + free(input); return true; } @@ -1247,22 +1253,20 @@ bool fieldsInputEnd(char* sql) { } // not in ',' - char * p = strrchr(sql, ','); + char * p3 = strrchr(sql, ','); + char * p = p3; // like select ts, age,' ' if (p) { ++p; - bool allBlank = true; - int cnt = 0; // blank count , continue many blank is one blank - char * plast = NULL; + bool allBlank = true; // after last ',' all char is blank + int cnt = 0; // blank count , like ' ' as one blank + char * plast = NULL; // last blank position while(*p) { - if (*p != ' ') { - allBlank = false; - plast = NULL; + if (*p == ' ') { + plast = p; + cnt ++; } else { - if(plast == NULL) { - plast = p; - cnt ++; - } + allBlank = false; } ++p; } @@ -1272,14 +1276,19 @@ bool fieldsInputEnd(char* sql) { return false; } - // if last char not ' ', then not end field, like select count(*), su + tab can fill sum( + // like 'select count(*),sum(age) fr' need return true + if (plast && plast > p3 && p2 > p1 && plast > p2 && p1 > p3) { + return true; + } + + // if last char not ' ', then not end field, like 'select count(*), su' can fill sum( if(sql[strlen(sql)-1] != ' ' && cnt <= 1) { return false; } } - char * p3 = strrchr(sql, ' '); - if(p3 == NULL) { + char * p4 = strrchr(sql, ' '); + if(p4 == NULL) { // only one word return false; } diff --git a/src/kit/shell/src/tire.c b/src/kit/shell/src/tire.c index 1ea27f5b9b..b4dc7976bd 100644 --- a/src/kit/shell/src/tire.c +++ b/src/kit/shell/src/tire.c @@ -58,13 +58,14 @@ void freeTire(STire* tire) { // free from list StrName * item = tire->head; while (item) { + StrName * next = item->next; // free string tfree(item->name); // free node tfree(item); // move next - item = item->next; + item = next; } tire->head = tire->tail = NULL; -- GitLab From dd1774eb562514ba6e5ddc5d631dd4d1bc2a3f0d Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Sun, 17 Jul 2022 22:38:10 +0800 Subject: [PATCH 171/380] docs: Update 2.6 faq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增三个常见问题 --- docs/zh/27-train-faq/01-faq.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/zh/27-train-faq/01-faq.md b/docs/zh/27-train-faq/01-faq.md index e8a106d5d6..bb92c69c3f 100644 --- a/docs/zh/27-train-faq/01-faq.md +++ b/docs/zh/27-train-faq/01-faq.md @@ -239,3 +239,25 @@ taosAdapter 从 TDengine 2.4.0.0 版本开始成为 TDengine 服务端软件的 OOM 是操作系统的保护机制,当操作系统内存(包括 SWAP )不足时,会杀掉某些进程,从而保证操作系统的稳定运行。通常内存不足主要是如下两个原因导致,一是剩余内存小于 vm.min_free_kbytes ;二是程序请求的内存大于剩余内存。还有一种情况是内存充足但程序占用了特殊的内存地址,也会触发 OOM 。 TDengine 会预先为每个 VNode 分配好内存,每个 Database 的 VNode 个数受 maxVgroupsPerDb 影响,每个 VNode 占用的内存大小受 Blocks 和 Cache 影响。要防止 OOM,需要在项目建设之初合理规划内存,并合理设置 SWAP ,除此之外查询过量的数据也有可能导致内存暴涨,这取决于具体的查询语句。TDengine 企业版对内存管理做了优化,采用了新的内存分配器,对稳定性有更高要求的用户可以考虑选择企业版。 + +### 26. 为何批量写入数据时,时间戳使用 NOW 函数拼接会导致数据丢失? + +首先需要强调一个概念,TDengine 作为一个时序数据库(Time-Series Database),首个时间戳字段起到主键的作用,内存索引的构建、磁盘数据的存储与其密切相关,不能有重复的时间戳。 + +NOW 函数(以及 NOW 关键字)返回客户端当前时间。当执行批量写入时,若首列时间戳给的值都是 NOW,在数据库默认毫秒的时间级别下是区分不开的(建库时可选择更高的时间精度),后续写入的重复时间戳将会丢失或更新,处理重复时间戳的具体逻辑由在 TDengine 中建库时的 Update 参数决定。 + +### 27. 扩容集群后,DNode 状态为 Offline 怎么办? + +新的节点正常加入集群后,数据节点列表中会显示该节点处于 Ready 状态。若该节点状态为 Offline,可按照如下内容进行排查: + +1. 查看该节点 taosd 是否已启动、防火墙是否关闭; +2. 确认新增节点的数据文件夹是否清空; +3. 检查所有节点 /etc/hosts 域名解析是否完整、有效(需要有所有节点的解析,包括 arbitrator); +4. 该节点 firstEP、fqdn 参数是否正确配置。 + +### 28. 能提供 TDengine 的建模实例吗? + +在社区支持的过程中,能发现很多新手小伙伴在部署 TDengine 后不知道如何进一步体验,我们的建议是跑一跑官网文档的语句。文档内容较多,为了方便新手小伙伴快速上手,我们将官网文档的示例模型浓缩、汇总了一下,希望尽可能快的让大家了解 TDengine 建模方法:[建模入门](https://github.com/taosdata/tdengine-modeling-and-querying-101/blob/main/cases/001-electricity-meter-monitoring.zh-hans.md) + +同时也欢迎社区的用户们为仓库 [tdengine-modeling-and-querying-101](https://github.com/taosdata/tdengine-modeling-and-querying-101) 提交 PR,展现 TDengine 在各行各业的建模实例。 + -- GitLab From 4898978be48a4645bfb10aa2eb83d5ffe9d71651 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Mon, 18 Jul 2022 10:37:45 +0800 Subject: [PATCH 172/380] test: add test case --- tests/pytest/table/tagNameCaseSensitive.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/pytest/table/tagNameCaseSensitive.py b/tests/pytest/table/tagNameCaseSensitive.py index ebd7f55a2d..c71dcacabb 100644 --- a/tests/pytest/table/tagNameCaseSensitive.py +++ b/tests/pytest/table/tagNameCaseSensitive.py @@ -74,6 +74,10 @@ class TDTestCase: tdSql.query("select * from `STB6`") tdSql.checkRows(2) + tdSql.execute("alter table `STB6` add tag `1` int") + tdSql.execute("create table t1 using `STB6`(`1`) tags(1)") + tdSql.error("alter table t1 set tag 1=2222") + tdSql.error("alter table `STB6` add tag `` nchar(20)") def stop(self): -- GitLab From daa8852ef6d7736d6bf787c46f1b12a92a32326b Mon Sep 17 00:00:00 2001 From: xywang Date: Mon, 18 Jul 2022 11:32:54 +0800 Subject: [PATCH 173/380] fix: fixed OEM bugs on Windows --- src/client/src/tscSystem.c | 2 +- src/kit/shell/src/shellWindows.c | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/client/src/tscSystem.c b/src/client/src/tscSystem.c index d2dcf041fb..944b85e996 100644 --- a/src/client/src/tscSystem.c +++ b/src/client/src/tscSystem.c @@ -47,7 +47,7 @@ int32_t tscNumOfObj = 0; // number of sqlObj in current process. static void *tscCheckDiskUsageTmr; void *tscRpcCache; // cache to keep rpc obj int32_t tscNumOfThreads = 1; // num of rpc threads -char tscLogFileName[12] = "taoslog"; +char tscLogFileName[] = "taoslog"; int tscLogFileNum = 10; static pthread_mutex_t rpcObjMutex; // mutex to protect open the rpc obj concurrently diff --git a/src/kit/shell/src/shellWindows.c b/src/kit/shell/src/shellWindows.c index 9aab9f49cd..0133caf997 100644 --- a/src/kit/shell/src/shellWindows.c +++ b/src/kit/shell/src/shellWindows.c @@ -250,14 +250,15 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { if (args.cloudDsn == NULL) { if (args.cloud) { args.cloudDsn = getenv("TDENGINE_CLOUD_DSN"); - if (args.cloudDsn[strlen(args.cloudDsn) - 1] == '\"') { - args.cloudDsn[strlen(args.cloudDsn) - 1] = '\0'; - } - if (args.cloudDsn[0] == '\"') { - args.cloudDsn += 1; - } if (args.cloudDsn == NULL) { args.cloud = false; + } else { + if (args.cloudDsn[strlen(args.cloudDsn) - 1] == '\"') { + args.cloudDsn[strlen(args.cloudDsn) - 1] = '\0'; + } + if (args.cloudDsn[0] == '\"') { + args.cloudDsn += 1; + } } } } else { @@ -434,4 +435,4 @@ int tcpConnect(char* host, int iport) { return 1; } return 0; -} \ No newline at end of file +} -- GitLab From 5d3fe43a91528171848df9463332118888facc94 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 18 Jul 2022 13:16:17 +0800 Subject: [PATCH 174/380] docs: update hivemq to reflect current version 4.8 (#15045) [TD-17476] --- docs/en/20-third-party/10-hive-mq-broker.md | 2 +- docs/zh/20-third-party/10-hive-mq-broker.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/20-third-party/10-hive-mq-broker.md b/docs/en/20-third-party/10-hive-mq-broker.md index 333e00fa0e..64404bd63f 100644 --- a/docs/en/20-third-party/10-hive-mq-broker.md +++ b/docs/en/20-third-party/10-hive-mq-broker.md @@ -3,4 +3,4 @@ sidebar_label: HiveMQ Broker title: HiveMQ Broker writing --- -[HiveMQ](https://www.hivemq.com/) is an MQTT broker that provides community and enterprise editions. HiveMQ is mainly for enterprise emerging machine-to-machine M2M communication and internal transport, meeting scalability, ease of management, and security features. HiveMQ provides an open-source plug-in development kit. MQTT data can be saved to TDengine via TDengine extension for HiveMQ. Please refer to the [HiveMQ extension - TDengine documentation](https://github.com/huskar-t/hivemq-tdengine-extension/blob/b62a26ecc164a310104df57691691b237e091c89/README_EN.md) for details on how to use it. \ No newline at end of file +[HiveMQ](https://www.hivemq.com/) is an MQTT broker that provides community and enterprise editions. HiveMQ is mainly for enterprise emerging machine-to-machine M2M communication and internal transport, meeting scalability, ease of management, and security features. HiveMQ provides an open-source plug-in development kit. MQTT data can be saved to TDengine via TDengine extension for HiveMQ. Please refer to the [HiveMQ extension - TDengine documentation](https://github.com/taosdata/hivemq-tdengine-extension/blob/master/README_EN.md) for details on how to use it. diff --git a/docs/zh/20-third-party/10-hive-mq-broker.md b/docs/zh/20-third-party/10-hive-mq-broker.md index f75ed793d6..1944b97cb0 100644 --- a/docs/zh/20-third-party/10-hive-mq-broker.md +++ b/docs/zh/20-third-party/10-hive-mq-broker.md @@ -3,4 +3,4 @@ sidebar_label: HiveMQ Broker title: HiveMQ Broker 写入 --- -[HiveMQ](https://www.hivemq.com/) 是一个提供免费个人版和企业版的 MQTT 代理,主要用于企业和新兴的机器到机器 M2M 通讯和内部传输,满足可伸缩性、易管理和安全特性。HiveMQ 提供了开源的插件开发包。可以通过 HiveMQ extension - TDengine 保存数据到 TDengine。详细使用方法请参考 [HiveMQ extension - TDengine 说明文档](https://github.com/huskar-t/hivemq-tdengine-extension/blob/b62a26ecc164a310104df57691691b237e091c89/README.md)。 +[HiveMQ](https://www.hivemq.com/) 是一个提供免费个人版和企业版的 MQTT 代理,主要用于企业和新兴的机器到机器 M2M 通讯和内部传输,满足可伸缩性、易管理和安全特性。HiveMQ 提供了开源的插件开发包。可以通过 HiveMQ extension - TDengine 保存数据到 TDengine。详细使用方法请参考 [HiveMQ extension - TDengine 说明文档](https://github.com/taosdata/hivemq-tdengine-extension/blob/master/README.md)。 -- GitLab From ee84ebd7c40ca9be5eb9904167d3081496c0c8cc Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 18 Jul 2022 14:59:09 +0800 Subject: [PATCH 175/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index b7b922268c..0b8a3373bb 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit b7b922268c4a06d9db77ffdfde0726f3d9900b72 +Subproject commit 0b8a3373bb7548f8106d13e7d3b0a988d3c4d48a -- GitLab From 181d1569d95b4e419e1029f9822e283b7ca52da5 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 18 Jul 2022 15:23:10 +0800 Subject: [PATCH 176/380] feat: update taostools for2.6 (#15058) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index b7b922268c..0b8a3373bb 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit b7b922268c4a06d9db77ffdfde0726f3d9900b72 +Subproject commit 0b8a3373bb7548f8106d13e7d3b0a988d3c4d48a -- GitLab From 5536c3c90ca972b9849bbd312a04a1efc6302c5d Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Mon, 18 Jul 2022 15:33:47 +0800 Subject: [PATCH 177/380] feat(rpc): ack connection alive --- src/client/src/tscServer.c | 2 +- src/dnode/src/dnodeVRead.c | 7 ------- src/rpc/src/rpcMain.c | 11 +++++++++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 435a6d7214..e6d5a94f04 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -308,7 +308,7 @@ bool sendProbeConnMsg(SSqlObj* pSql) { if (diff > killTimeout) { // need kill query tscDebug("PROBE 0x%"PRIx64" need killed, noAckCnt:%d diff=%d", pSql->self, pSql->noAckCnt, diff); - return false; + //return false; } if (pSql->pPrevContext == NULL || pSql->pPrevConn == NULL || pSql->pPrevFdObj == NULL || pSql->prevFd <= 0) { diff --git a/src/dnode/src/dnodeVRead.c b/src/dnode/src/dnodeVRead.c index 544961adfc..8a9cca4f5f 100644 --- a/src/dnode/src/dnodeVRead.c +++ b/src/dnode/src/dnodeVRead.c @@ -57,13 +57,6 @@ void dnodeDispatchToVReadQueue(SRpcMsg *pMsg) { int32_t code = TSDB_CODE_VND_INVALID_VGROUP_ID; char * pCont = pMsg->pCont; - // check probe conn msg - if(pMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN) { - SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = 0, .msgType = TSDB_MSG_TYPE_PROBE_CONN_RSP}; - rpcSendResponse(&rpcRsp); - return ; - } - while (leftLen > 0) { SMsgHead *pHead = (SMsgHead *)pCont; pHead->vgId = htonl(pHead->vgId); diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index c4c2232e6b..10b729eddb 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -993,6 +993,16 @@ static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv, SRpcReqCont pConn->peerPort = pRecv->port; if (pHead->port) pConn->peerPort = htons(pHead->port); + // probe msg + if(pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN) { + pConn->inType = pHead->msgType; + rpcSendQuickRsp(pConn, TSDB_CODE_SUCCESS); + rpcUnlockConn(pConn); + rpcFreeMsg(pRecv->msg); + pRecv->msg = NULL; + return pConn; + } + terrno = rpcCheckAuthentication(pConn, (char *)pHead, pRecv->msgLen); // code can be transformed only after authentication @@ -1710,6 +1720,7 @@ bool doRpcSendProbe(SRpcConn *pConn) { memcpy(pHead->user, pConn->user, tListLen(pHead->user)); pHead->code = htonl(code); + pConn->outType = pHead->msgType; bool ret = rpcSendMsgToPeer(pConn, msg, sizeof(SRpcHead) + sizeof(int32_t)); pConn->secured = 1; // connection shall be secured -- GitLab From f4685dc1eb06a4dfb82b7cf3f4f62b1e13dc023e Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 18 Jul 2022 15:50:28 +0800 Subject: [PATCH 178/380] fix: gcc 12 compile error for 2.6 (#15062) --- deps/lua/src/ldump.c | 2 +- src/kit/shell/src/shellEngine.c | 6 +++--- src/rpc/src/rpcMain.c | 6 +++--- src/util/src/tqueue.c | 3 +-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/deps/lua/src/ldump.c b/deps/lua/src/ldump.c index f08277d3ac..4b20591488 100644 --- a/deps/lua/src/ldump.c +++ b/deps/lua/src/ldump.c @@ -60,7 +60,7 @@ static void DumpVector(const void* b, int n, size_t size, DumpState* D) static void DumpString(const TString* s, DumpState* D) { - if (s==NULL || getstr(s)==NULL) + if (s==NULL) { size_t size=0; DumpVar(size,D); diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index ee82212081..e1e443413a 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -1169,12 +1169,12 @@ int parse_cloud_dsn() { } } char *port = strstr(args.cloudHost, ":"); - if ((port == NULL) || (port + strlen(":")) == NULL) { + if (port == NULL) { fprintf(stderr, "Invalid format in TDengine cloud dsn: %s\n", args.cloudDsn); return 1; } char *token = strstr(port + strlen(":"), "?token="); - if ((token == NULL) || (token + strlen("?token=")) == NULL || + if ((token == NULL) || (strlen(token + strlen("?token=")) == 0)) { fprintf(stderr, "Invalid format in TDengine cloud dsn: %s\n", args.cloudDsn); return -1; @@ -1632,4 +1632,4 @@ void wsclient_query(char *command) { } cJSON_Delete(query); return; -} \ No newline at end of file +} diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 95931fcbc6..4f67c6088d 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -361,8 +361,8 @@ void *rpcMallocCont(int contLen) { void rpcFreeCont(void *cont) { if (cont) { char *temp = ((char *)cont) - sizeof(SRpcHead) - sizeof(SRpcReqContext); - free(temp); tTrace("free mem: %p", temp); + free(temp); } } @@ -573,8 +573,8 @@ void rpcCancelRequest(int64_t rid) { static void rpcFreeMsg(void *msg) { if ( msg ) { char *temp = (char *)msg - sizeof(SRpcReqContext); - free(temp); tTrace("free mem: %p", temp); + free(temp); } } @@ -1683,4 +1683,4 @@ int32_t rpcUnusedSession(void * rpcInfo, bool bLock) { if(info == NULL) return 0; return taosIdPoolNumOfFree(info->idPool, bLock); -} \ No newline at end of file +} diff --git a/src/util/src/tqueue.c b/src/util/src/tqueue.c index 1ffa94b0df..7b23b708b1 100644 --- a/src/util/src/tqueue.c +++ b/src/util/src/tqueue.c @@ -86,9 +86,8 @@ void taosCloseQueue(taos_queue param) { } pthread_mutex_destroy(&queue->mutex); - free(queue); - uTrace("queue:%p is closed", queue); + free(queue); } void *taosAllocateQitem(int size) { -- GitLab From dc9d941a373bc14271765e876713a598765a27a5 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Mon, 18 Jul 2022 19:12:26 +0800 Subject: [PATCH 179/380] fix: resolve a segmenation fault issue of taos when alter table... set tag with a number as key --- src/client/src/tscSQLParser.c | 9 +++++---- tests/pytest/table/tagNameCaseSensitive.py | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index cc2a1fed78..c0f9720fe4 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -3972,10 +3972,6 @@ int32_t doGetColumnIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColum const char* msg0 = "ambiguous column name"; const char* msg1 = "invalid column name"; - if (pToken->n == 0) { - return TSDB_CODE_TSC_INVALID_OPERATION; - } - int16_t tsWinColumnIndex; if (isTablenameToken(pToken)) { pIndex->columnIndex = TSDB_TBNAME_COLUMN_INDEX; @@ -4061,6 +4057,11 @@ int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIn } int32_t getColumnIndexByName(const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex, char* msg) { + const char* msg0 = "invalid column name"; + + if (pToken->n == 0) { + return invalidOperationMsg(msg, msg0); + } if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } diff --git a/tests/pytest/table/tagNameCaseSensitive.py b/tests/pytest/table/tagNameCaseSensitive.py index c71dcacabb..c9ee64fa24 100644 --- a/tests/pytest/table/tagNameCaseSensitive.py +++ b/tests/pytest/table/tagNameCaseSensitive.py @@ -65,7 +65,7 @@ class TDTestCase: tdSql.query("select * from `STB6`") tdSql.checkRows(6) - tdSql.execute("delete from `STB6` where ` ` = 1 and ts = '2022-06-24 11:17:31.000'") + tdSql.execute("delete from `STB6` where ` ` = 1 and ts = 1656040651000") tdSql.checkAffectedRows(1) tdSql.query("select * from `STB6`") tdSql.checkRows(5) @@ -86,4 +86,4 @@ class TDTestCase: tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file +tdCases.addLinux(__file__, TDTestCase()) -- GitLab From 419924833df27a31802f89e86e8ecd6d8f86b7c0 Mon Sep 17 00:00:00 2001 From: dingbo Date: Tue, 19 Jul 2022 11:23:06 +0800 Subject: [PATCH 180/380] docs: enhance high-volume.md for large quantity of tables --- docs/examples/java/src/main/resources/logback.xml | 8 ++++++++ docs/zh/07-develop/03-insert-data/05-high-volume.md | 6 ++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/examples/java/src/main/resources/logback.xml b/docs/examples/java/src/main/resources/logback.xml index 898887fe6a..15c6d77de7 100644 --- a/docs/examples/java/src/main/resources/logback.xml +++ b/docs/examples/java/src/main/resources/logback.xml @@ -7,8 +7,16 @@ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + demo.log + true + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + \ No newline at end of file diff --git a/docs/zh/07-develop/03-insert-data/05-high-volume.md b/docs/zh/07-develop/03-insert-data/05-high-volume.md index e43b225d77..3d522f8aa5 100644 --- a/docs/zh/07-develop/03-insert-data/05-high-volume.md +++ b/docs/zh/07-develop/03-insert-data/05-high-volume.md @@ -40,7 +40,9 @@ import TabItem from "@theme/TabItem"; 从服务器配置的角度来说,也有很多优化写入性能的方法。 -如果无论怎么调节客户端程序,taosd 进程的 CPU 使用率都很低,那很可能需要增加 vgroup 的数量。比如:数据库总表数是 1000 且 minTablesPerVnode 设置的也是 1000,那么这个数据至多有一个 vgroup。此时如果将 minTablesPerVnode 和 tablelncStepPerVnode 都设置成 100, 则这个数据库可能用到 10 个 vgroup。 +如果总表数不多(远小于核数乘以1000), 且无论怎么调节客户端程序,taosd 进程的 CPU 使用率都很低,那么很可能是因为表在各个 vgroup 分布不均。比如:数据库总表数是 1000 且 minTablesPerVnode 设置的也是 1000,那么所有的表都会分布在 1 个 vgroup 上。此时如果将 minTablesPerVnode 和 tablelncStepPerVnode 都设置成 100, 则可将表分布至 10 个 vgroup。(假设 maxVgroupsPerDb 大于等于 10)。 + +如果总表数比较大(比如大于500万),适当增加 maxVgroupsPerDb 也能显著提高建表的速度。maxVgroupsPerDb 默认值为 0, 自动配置为 CPU 的核数。 如果表的数量巨大,也建议调节 maxTablesPerVnode 参数,以免超过单个 vnode 建表的上限。 更多调优参数,请参考[性能优化](../../operation/optimize)和[配置参考](../../reference/config)部分。 @@ -94,7 +96,7 @@ import TabItem from "@theme/TabItem"; 1. 读线程个数。默认为 1。 2. 写线程个数。默认为 3。 -3. 模拟生成的总表数。默认为 1000。将会平分给各个读线程。 +3. 模拟生成的总表数。默认为 1000。将会平分给各个读线程。如果总表数较大,建表需要花费较长,开始统计的写入速度可能较慢。 4. 每批最多写入记录数量。默认为 3000。 队列容量(taskQueueCapacity)也是与性能有关的参数,可通过修改程序调节。一般来讲,队列容量越大,入队被阻塞的概率越小,队列的吞吐量越大,但是内存占用也会越大。 示例程序默认值已经设置地足够大。 -- GitLab From 5b864c8a000c4069c5d89155bdb3c62d0d807fb0 Mon Sep 17 00:00:00 2001 From: huolibo Date: Tue, 19 Jul 2022 10:01:56 +0800 Subject: [PATCH 181/380] docs(driver): release jdbc 2.0.40 --- docs/en/14-reference/03-connector/java.mdx | 23 +++++++++++++++------- docs/zh/14-reference/03-connector/java.mdx | 11 ++++++++++- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/docs/en/14-reference/03-connector/java.mdx b/docs/en/14-reference/03-connector/java.mdx index ff15acf1a9..625ffc2698 100644 --- a/docs/en/14-reference/03-connector/java.mdx +++ b/docs/en/14-reference/03-connector/java.mdx @@ -202,6 +202,10 @@ The configuration parameters in the URL are as follows. - batchfetch: true: pull the result set in batch when executing the query; false: pull the result set row by row. The default value is false. batchfetch uses HTTP for data transfer. The JDBC REST connection supports bulk data pulling function in taos-jdbcdriver-2.0.38 and TDengine 2.4.0.12 and later versions. taos-jdbcdriver and TDengine transfer data via WebSocket connection. Compared with HTTP, WebSocket enables JDBC REST connection to support large data volume querying and improve query performance. - charset: specify the charset to parse the string, this parameter is valid only when set batchfetch to true. - batchErrorIgnore: true: when executing executeBatch of Statement, if one SQL execution fails in the middle, continue to execute the following SQL. false: no longer execute any statement after the failed SQL. The default value is: false. +- httpConnectTimeout: REST connection timeout in milliseconds, the default value is 5000 ms. +- httpSocketTimeout: socket timeout in milliseconds, the default value is 5000 ms. only takes effect when batchfetch is false. +- messageWaitTimeout: message transmission timeout in milliseconds, the default value is 3000 ms. only takes effect when batchfetch is true. +- useSSL: connecting Securely Using SSL. true: using SSL conneciton, false: not using SSL connection. **Note**: Some configuration items (e.g., locale, timezone) do not work in the REST connection. @@ -257,14 +261,18 @@ In the above example, a connection is established to `taosdemo.com`, port is 603 The configuration parameters in properties are as follows. -- TSDBDriver.PROPERTY_KEY_USER: Login TDengine user name, default value 'root'. +- TSDBDriver.PROPERTY_KEY_USER: login TDengine user name, default value 'root'. - TSDBDriver.PROPERTY_KEY_PASSWORD: user login password, default value 'taosdata'. - TSDBDriver.PROPERTY_KEY_BATCH_LOAD: true: pull the result set in batch when executing query; false: pull the result set row by row. The default value is: false. - TSDBDriver.PROPERTY_KEY_BATCH_ERROR_IGNORE: true: when executing executeBatch of Statement, if there is a SQL execution failure in the middle, continue to execute the following sq. false: no longer execute any statement after the failed SQL. The default value is: false. -- TSDBDriver.PROPERTY_KEY_CONFIG_DIR: Only works when using JDBC native connection. Client configuration file directory path, default value `/etc/taos` on Linux OS, default value `C:/TDengine/cfg` on Windows OS. +- TSDBDriver.PROPERTY_KEY_CONFIG_DIR: only works when using JDBC native connection. Client configuration file directory path, default value `/etc/taos` on Linux OS, default value `C:/TDengine/cfg` on Windows OS. - TSDBDriver.PROPERTY_KEY_CHARSET: In the character set used by the client, the default value is the system character set. - TSDBDriver.PROPERTY_KEY_LOCALE: this only takes effect when using JDBC native connection. Client language environment, the default value is system current locale. - TSDBDriver.PROPERTY_KEY_TIME_ZONE: only takes effect when using JDBC native connection. In the time zone used by the client, the default value is the system's current time zone. +- TSDBDriver.HTTP_CONNECT_TIMEOUT: REST connection timeout in milliseconds, the default value is 5000 ms. only takes effect when using JDBC REST connection. +- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket timeout in milliseconds, the default value is 5000 ms. only takes effect when using JDBC REST connection and batchfetch is false. +- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: message transmission timeout in milliseconds, the default value is 3000 ms. only takes effect when using JDBC REST connection and batchfetch is true. +- TSDBDriver.PROPERTY_KEY_USE_SSL: connecting Securely Using SSL. true: using SSL conneciton, false: not using SSL connection. only takes effect when using using JDBC REST connection. For JDBC native connections, you can specify other parameters, such as log level, SQL length, etc., by specifying URL and Properties. For more detailed configuration, please refer to [Client Configuration](/reference/config/#Client-Only). ### Priority of configuration parameters @@ -812,11 +820,12 @@ Please refer to: [JDBC example](https://github.com/taosdata/TDengine/tree/develo ## Recent update logs -| taos-jdbcdriver version | major changes | -| :---------------------: | :------------------------------------------: | -| 2.0.38 | JDBC REST connections add bulk pull function | -| 2.0.37 | Added support for json tags | -| 2.0.36 | Add support for schemaless writing | +| taos-jdbcdriver version | major changes | +| :---------------------: | :--------------------------------------------: | +| 2.0.39 - 2.0.40 | Add REST connection/request timeout parameters | +| 2.0.38 | JDBC REST connections add bulk pull function | +| 2.0.37 | Support json tags | +| 2.0.36 | Support schemaless writing | ## Frequently Asked Questions diff --git a/docs/zh/14-reference/03-connector/java.mdx b/docs/zh/14-reference/03-connector/java.mdx index 836bf49ce3..46b23c0a64 100644 --- a/docs/zh/14-reference/03-connector/java.mdx +++ b/docs/zh/14-reference/03-connector/java.mdx @@ -201,6 +201,10 @@ url 中的配置参数如下: - batchfetch: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:false。逐行拉取结果集使用 HTTP 方式进行数据传输。从 taos-jdbcdriver-2.0.38 和 TDengine 2.4.0.12 版本开始,JDBC REST 连接增加批量拉取数据功能。taos-jdbcdriver 与 TDengine 之间通过 WebSocket 连接进行数据传输。相较于 HTTP,WebSocket 可以使 JDBC REST 连接支持大数据量查询,并提升查询性能。 - charset: 当开启批量拉取数据时,指定解析字符串数据的字符集。 - batchErrorIgnore:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL 了。false:不再执行失败 SQL 后的任何语句。默认值为:false。 +- httpConnectTimeout: 连接超时时间,单位 ms, 默认值为 5000。 +- httpSocketTimeout: socket 超时时间,单位 ms,默认值为 5000。仅在 batchfetch 设置为 false 时生效。 +- messageWaitTimeout: 消息超时时间, 单位 ms, 默认值为 3000。 仅在 batchfetch 设置为 true 时生效。 +- useSSL: 连接中是否使用 SSL。 **注意**:部分配置项(比如:locale、timezone)在 REST 连接中不生效。 @@ -264,7 +268,11 @@ properties 中的配置参数如下: - TSDBDriver.PROPERTY_KEY_CHARSET:客户端使用的字符集,默认值为系统字符集。 - TSDBDriver.PROPERTY_KEY_LOCALE:仅在使用 JDBC 原生连接时生效。 客户端语言环境,默认值系统当前 locale。 - TSDBDriver.PROPERTY_KEY_TIME_ZONE:仅在使用 JDBC 原生连接时生效。 客户端使用的时区,默认值为系统当前时区。 -- 此外对 JDBC 原生连接,通过指定 URL 和 Properties 还可以指定其他参数,比如日志级别、SQL 长度等。更多详细配置请参考[客户端配置](/reference/config/#仅客户端适用)。 +- TSDBDriver.HTTP_CONNECT_TIMEOUT: 连接超时时间,单位 ms, 默认值为 5000。仅在 REST 连接时生效。 +- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket 超时时间,单位 ms,默认值为 5000。仅在 REST 连接且 batchfetch 设置为 false 时生效。 +- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: 消息超时时间, 单位 ms, 默认值为 3000。 仅在 REST 连接且 batchfetch 设置为 true 时生效。 +- TSDBDriver.PROPERTY_KEY_USE_SSL: 连接中是否使用 SSL。仅在 REST 连接时生效。 + 此外对 JDBC 原生连接,通过指定 URL 和 Properties 还可以指定其他参数,比如日志级别、SQL 长度等。更多详细配置请参考[客户端配置](/reference/config/#仅客户端适用)。 ### 配置参数的优先级 @@ -809,6 +817,7 @@ Query OK, 1 row(s) in set (0.000141s) | taos-jdbcdriver 版本 | 主要变化 | | :------------------: | :----------------------------: | +| 2.0.39 - 2.0.40 | 增加 REST 连接/请求 超时设置 | | 2.0.38 | JDBC REST 连接增加批量拉取功能 | | 2.0.37 | 增加对 json tag 支持 | | 2.0.36 | 增加对 schemaless 写入支持 | -- GitLab From 98c7292854e718ca163e5b0200a6cf5aa6b9710f Mon Sep 17 00:00:00 2001 From: huolibo Date: Tue, 19 Jul 2022 14:27:17 +0800 Subject: [PATCH 182/380] docs(driver): improve description --- docs/en/14-reference/03-connector/java.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/en/14-reference/03-connector/java.mdx b/docs/en/14-reference/03-connector/java.mdx index 625ffc2698..310e0a15c6 100644 --- a/docs/en/14-reference/03-connector/java.mdx +++ b/docs/en/14-reference/03-connector/java.mdx @@ -203,8 +203,8 @@ The configuration parameters in the URL are as follows. - charset: specify the charset to parse the string, this parameter is valid only when set batchfetch to true. - batchErrorIgnore: true: when executing executeBatch of Statement, if one SQL execution fails in the middle, continue to execute the following SQL. false: no longer execute any statement after the failed SQL. The default value is: false. - httpConnectTimeout: REST connection timeout in milliseconds, the default value is 5000 ms. -- httpSocketTimeout: socket timeout in milliseconds, the default value is 5000 ms. only takes effect when batchfetch is false. -- messageWaitTimeout: message transmission timeout in milliseconds, the default value is 3000 ms. only takes effect when batchfetch is true. +- httpSocketTimeout: socket timeout in milliseconds, the default value is 5000 ms. It only takes effect when batchfetch is false. +- messageWaitTimeout: message transmission timeout in milliseconds, the default value is 3000 ms. It only takes effect when batchfetch is true. - useSSL: connecting Securely Using SSL. true: using SSL conneciton, false: not using SSL connection. **Note**: Some configuration items (e.g., locale, timezone) do not work in the REST connection. @@ -269,10 +269,10 @@ The configuration parameters in properties are as follows. - TSDBDriver.PROPERTY_KEY_CHARSET: In the character set used by the client, the default value is the system character set. - TSDBDriver.PROPERTY_KEY_LOCALE: this only takes effect when using JDBC native connection. Client language environment, the default value is system current locale. - TSDBDriver.PROPERTY_KEY_TIME_ZONE: only takes effect when using JDBC native connection. In the time zone used by the client, the default value is the system's current time zone. -- TSDBDriver.HTTP_CONNECT_TIMEOUT: REST connection timeout in milliseconds, the default value is 5000 ms. only takes effect when using JDBC REST connection. -- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket timeout in milliseconds, the default value is 5000 ms. only takes effect when using JDBC REST connection and batchfetch is false. -- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: message transmission timeout in milliseconds, the default value is 3000 ms. only takes effect when using JDBC REST connection and batchfetch is true. -- TSDBDriver.PROPERTY_KEY_USE_SSL: connecting Securely Using SSL. true: using SSL conneciton, false: not using SSL connection. only takes effect when using using JDBC REST connection. +- TSDBDriver.HTTP_CONNECT_TIMEOUT: REST connection timeout in milliseconds, the default value is 5000 ms. It only takes effect when using JDBC REST connection. +- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket timeout in milliseconds, the default value is 5000 ms. It only takes effect when using JDBC REST connection and batchfetch is false. +- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: message transmission timeout in milliseconds, the default value is 3000 ms. It only takes effect when using JDBC REST connection and batchfetch is true. +- TSDBDriver.PROPERTY_KEY_USE_SSL: connecting Securely Using SSL. true: using SSL conneciton, false: not using SSL connection. It only takes effect when using using JDBC REST connection. For JDBC native connections, you can specify other parameters, such as log level, SQL length, etc., by specifying URL and Properties. For more detailed configuration, please refer to [Client Configuration](/reference/config/#Client-Only). ### Priority of configuration parameters -- GitLab From 755619b6cbf537a48e384a542b3509bd17f7be27 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Tue, 19 Jul 2022 18:32:45 +0800 Subject: [PATCH 183/380] docs: 21-tdinternal Query mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除了没有文档链接的《TDengine 2.0 数据查询模块设计》 --- docs/zh/21-tdinternal/03-taosd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/21-tdinternal/03-taosd.md b/docs/zh/21-tdinternal/03-taosd.md index 0cf0a1aaa2..9470311f94 100644 --- a/docs/zh/21-tdinternal/03-taosd.md +++ b/docs/zh/21-tdinternal/03-taosd.md @@ -88,7 +88,7 @@ TSDB 中存储的元数据包含属于其所在的 vnode 中表的类型,schem ## Query 模块 -该模块负责整体系统的查询处理。客户端调用该该模块进行 SQL 语法解析,并将查询或写入请求发送到 vnode ,同时负责针对超级表的查询进行二阶段的聚合操作。在 vnode 端,该模块调用 TSDB 模块读取系统中存储的数据进行查询处理。query 模块还定义了系统能够支持的全部查询函数,查询函数的实现机制与查询框架无耦合,可以在不修改查询流程的情况下动态增加查询函数。详细的设计请参见《TDengine 2.0 查询模块设计》。 +该模块负责整体系统的查询处理。客户端调用该该模块进行 SQL 语法解析,并将查询或写入请求发送到 vnode ,同时负责针对超级表的查询进行二阶段的聚合操作。在 vnode 端,该模块调用 TSDB 模块读取系统中存储的数据进行查询处理。query 模块还定义了系统能够支持的全部查询函数,查询函数的实现机制与查询框架无耦合,可以在不修改查询流程的情况下动态增加查询函数。 ## SYNC 模块 -- GitLab From abec9542e8ed0c5ff03b70e52d25d995bb23227e Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Tue, 19 Jul 2022 18:46:46 +0800 Subject: [PATCH 184/380] fix: resolve a potential nullptr dereferencing on extraRow with update=2 --- src/tsdb/src/tsdbRead.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index c2fd51414b..3d72a7bde3 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -986,7 +986,9 @@ static SMemRow getSMemRowInTableMem(STableCheckInfo* pCheckInfo, int32_t order, return rmem; } else { pCheckInfo->chosen = CHECKINFO_CHOSEN_BOTH; - *extraRow = rimem; + if (extraRow) { + *extraRow = rimem; + } return rmem; } } else { -- GitLab From f014ea7790b68f68507816b95be94772498daded Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 19 Jul 2022 19:20:18 +0800 Subject: [PATCH 185/380] feat: updaete taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 0b8a3373bb..2b75339b8b 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 0b8a3373bb7548f8106d13e7d3b0a988d3c4d48a +Subproject commit 2b75339b8b5c239619d1f09970d03075c58140dd -- GitLab From 7c405b98cd157e2d2a32cdc1b307736939777676 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 19 Jul 2022 20:02:08 +0800 Subject: [PATCH 186/380] feat: update taostools for2.6 (#15147) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 0b8a3373bb..2b75339b8b 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 0b8a3373bb7548f8106d13e7d3b0a988d3c4d48a +Subproject commit 2b75339b8b5c239619d1f09970d03075c58140dd -- GitLab From c562eac94dd4bd49d69d0156dd915c4ca2363a39 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Tue, 19 Jul 2022 20:16:23 +0800 Subject: [PATCH 187/380] fix: check retcode of getColumnIndexByName in tscGetExprFilters --- src/client/src/tscSQLParser.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index c0f9720fe4..3c52c32f0d 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -4062,6 +4062,7 @@ int32_t getColumnIndexByName(const SStrToken* pToken, SQueryInfo* pQueryInfo, SC if (pToken->n == 0) { return invalidOperationMsg(msg, msg0); } + if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -9666,7 +9667,9 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect SStrToken* pToken = &pParam->pNode->columnName; SColumnIndex idx = COLUMN_INDEX_INITIALIZER; - getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)); + if (getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); schema = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); } else { -- GitLab From 382d090cfe436c34680f83c7fb682e614686b4a2 Mon Sep 17 00:00:00 2001 From: Jeff Tao Date: Tue, 19 Jul 2022 20:20:13 +0800 Subject: [PATCH 188/380] Update 01-index.md --- docs/en/01-index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/01-index.md b/docs/en/01-index.md index d76c12e10f..1f2f88d47d 100644 --- a/docs/en/01-index.md +++ b/docs/en/01-index.md @@ -6,7 +6,7 @@ slug: / TDengine is a [high-performance](https://tdengine.com/fast), [scalable](https://tdengine.com/scalable) time series database with [SQL support](https://tdengine.com/sql-support). This document is the TDengine user manual. It introduces the basic, as well as novel concepts, in TDengine, and also talks in detail about installation, features, SQL, APIs, operation, maintenance, kernel design and other topics. It’s written mainly for architects, developers and system administrators. -To get a global view about TDengine, like feature list, benchmarks, and competitive advantages, please browse through section [Introduction](./intro). +To get a global view about TDengine, like feature list, benchmarks, and competitive advantages, please browse through section [Introduction](./intro). If you want to get some basics about time-series databases, please check [here](https://tdengine.com/tsdb). TDengine greatly improves the efficiency of data ingestion, querying and storage by exploiting the characteristics of time series data, introducing the novel concepts of "one table for one data collection point" and "super table", and designing an innovative storage engine. To understand the new concepts in TDengine and make full use of the features and capabilities of TDengine, please read [“Concepts”](./concept) thoroughly. -- GitLab From 86980811dd00411d14adad058a3e9048881b6558 Mon Sep 17 00:00:00 2001 From: Jeff Tao Date: Tue, 19 Jul 2022 20:22:11 +0800 Subject: [PATCH 189/380] Update index.md --- docs/en/02-intro/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index 52b25bf949..23cf1203b2 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -110,4 +110,6 @@ As a high-performance, scalable and SQL supported time-series database, TDengine - [TDengine vs InfluxDB、OpenTSDB、Cassandra、MySQL、ClickHouse](https://www.tdengine.com/downloads/TDengine_Testing_Report_en.pdf) - [TDengine vs OpenTSDB](https://tdengine.com/2019/09/12/710.html) - [TDengine vs Cassandra](https://tdengine.com/2019/09/12/708.html) -- [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html) \ No newline at end of file +- [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html) + +If you want to learn some basics about time-series databases, please check [here](https://tdengine.com/tsdb). -- GitLab From 8fa05f52566f0ec393eea2b9aecdd6502ff3db5a Mon Sep 17 00:00:00 2001 From: Jeff Tao Date: Tue, 19 Jul 2022 20:47:02 +0800 Subject: [PATCH 190/380] Update index.md --- docs/en/02-intro/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index 52b25bf949..5543aae6de 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -3,7 +3,7 @@ title: Introduction toc_max_heading_level: 2 --- -TDengine is a high-performance, scalable time-series database with SQL support. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](/develop/cache), [stream processing](/develop/continuous-query), [data subscription](/develop/subscribe) and other functionalities to reduce the complexity and cost of development and operation. +TDengine is a high-performance, scalable [time-series database](https://tdengine.com/tsdb) with SQL support. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](/develop/cache), [stream processing](/develop/continuous-query), [data subscription](/develop/subscribe) and other functionalities to reduce the complexity and cost of development and operation. This section introduces the major features, competitive advantages, typical use-cases and benchmarks to help you get a high level overview of TDengine. @@ -110,4 +110,4 @@ As a high-performance, scalable and SQL supported time-series database, TDengine - [TDengine vs InfluxDB、OpenTSDB、Cassandra、MySQL、ClickHouse](https://www.tdengine.com/downloads/TDengine_Testing_Report_en.pdf) - [TDengine vs OpenTSDB](https://tdengine.com/2019/09/12/710.html) - [TDengine vs Cassandra](https://tdengine.com/2019/09/12/708.html) -- [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html) \ No newline at end of file +- [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html) -- GitLab From 82988f8299e0b068d92b98eed8bbc3b21158ddea Mon Sep 17 00:00:00 2001 From: Bo Ding Date: Wed, 20 Jul 2022 11:20:24 +0800 Subject: [PATCH 191/380] docs: fast write example for java and python (#15171) * docs: monitor numberOfTable in FaskWriteExample.java * docs: add note to python example --- .../taos/example/highvolume/DataBaseMonitor.java | 16 ++++++++++++++++ .../example/highvolume/FastWriteExample.java | 5 +++-- .../07-develop/03-insert-data/05-high-volume.md | 6 ++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java index 5c513ec282..04b149a4b9 100644 --- a/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java @@ -44,4 +44,20 @@ public class DataBaseMonitor { } return null; } + + /** + * show test.stables; + * + * name | created_time | columns | tags | tables | + * ============================================================================================ + * meters | 2022-07-20 08:39:30.902 | 4 | 2 | 620000 | + */ + public Long getTableCount() throws SQLException { + if (!stmt.isClosed()) { + ResultSet result = stmt.executeQuery("show test.stables"); + result.next(); + return result.getLong(5); + } + return null; + } } \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java index 15672dddd9..41b59551ca 100644 --- a/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java @@ -13,7 +13,7 @@ import java.util.concurrent.BlockingQueue; public class FastWriteExample { final static Logger logger = LoggerFactory.getLogger(FastWriteExample.class); - final static int taskQueueCapacity = 10000000; + final static int taskQueueCapacity = 1000000; final static List> taskQueues = new ArrayList<>(); final static List readTasks = new ArrayList<>(); final static List writeTasks = new ArrayList<>(); @@ -61,8 +61,9 @@ public class FastWriteExample { long lastCount = 0; while (true) { Thread.sleep(10000); + long numberOfTable = databaseMonitor.getTableCount(); long count = databaseMonitor.count(); - logger.info("count={} speed={}", count, (count - lastCount) / 10); + logger.info("numberOfTable={} count={} speed={}", numberOfTable, count, (count - lastCount) / 10); lastCount = count; } } diff --git a/docs/zh/07-develop/03-insert-data/05-high-volume.md b/docs/zh/07-develop/03-insert-data/05-high-volume.md index 3d522f8aa5..6c60fd6e24 100644 --- a/docs/zh/07-develop/03-insert-data/05-high-volume.md +++ b/docs/zh/07-develop/03-insert-data/05-high-volume.md @@ -428,6 +428,12 @@ SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提
+:::note +使用 Python 连接器多进程连接 TDengine 的时候,有一个限制:不能在父进程中建立连接,所有连接只能在子进程中创建。 +如果在父进程中创建连接,子进程再创建连接就会一直阻塞。这是个已知问题。 + +::: +
-- GitLab From 813edbe25a596cd996c0cc1caab95357d5f30805 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 20 Jul 2022 14:43:51 +0800 Subject: [PATCH 192/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 2b75339b8b..51118d42a2 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 2b75339b8b5c239619d1f09970d03075c58140dd +Subproject commit 51118d42a2279d9619e073974fcf8f001b92090a -- GitLab From 9d41a3ccafb6779c942315c20b84cf025e803af9 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 20 Jul 2022 15:06:54 +0800 Subject: [PATCH 193/380] feat: update taostools for2.6 (#15187) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 2b75339b8b..51118d42a2 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 2b75339b8b5c239619d1f09970d03075c58140dd +Subproject commit 51118d42a2279d9619e073974fcf8f001b92090a -- GitLab From 0eddae7259bd987d8414a4db7ccd9616008204f6 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 20 Jul 2022 16:18:31 +0800 Subject: [PATCH 194/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 51118d42a2..f84cb6e515 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 51118d42a2279d9619e073974fcf8f001b92090a +Subproject commit f84cb6e51556d8030585128c2b252aa2a6453328 -- GitLab From bd3834dfe9ddd1977f6f895958be45cb3f16618f Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 20 Jul 2022 17:29:22 +0800 Subject: [PATCH 195/380] feat: update taostools for2.6 (#15197) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 51118d42a2..f84cb6e515 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 51118d42a2279d9619e073974fcf8f001b92090a +Subproject commit f84cb6e51556d8030585128c2b252aa2a6453328 -- GitLab From bee1e40b7d3ff623c28379a924c42929283007d9 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 21 Jul 2022 14:57:52 +0800 Subject: [PATCH 196/380] fix: check type of tVariant as a column/tag name when alter table... --- src/client/src/tscSQLParser.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 3c52c32f0d..bb31b752a1 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -7401,6 +7401,9 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { } SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { + return invalidOperationMsg(pMsg, msg17); + } SStrToken name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen}; if (getColumnIndexByName(&name, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { @@ -7474,6 +7477,9 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { int16_t numOfTags = tscGetNumOfTags(pTableMeta); SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER; + if (item->pVar.nType != TSDB_DATA_TYPE_BINARY) { + return invalidOperationMsg(pMsg, msg17); + } SStrToken name = {.z = item->pVar.pz, .n = item->pVar.nLen}; if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; @@ -7619,6 +7625,9 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { tVariantListItem* pItem = taosArrayGet(pAlterSQL->varList, 0); SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER; + if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { + return invalidOperationMsg(pMsg, msg17); + } SStrToken name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen}; if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { -- GitLab From 1a9dff273a015754740a162225731c4910d88621 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Thu, 21 Jul 2022 20:04:08 +0800 Subject: [PATCH 197/380] docs: Create 12-IDEA.mdx for 2.6 Create 12-IDEA.mdx for 2.6 --- docs/zh/20-third-party/12-IDEA.mdx | 84 ++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/zh/20-third-party/12-IDEA.mdx diff --git a/docs/zh/20-third-party/12-IDEA.mdx b/docs/zh/20-third-party/12-IDEA.mdx new file mode 100644 index 0000000000..5ec8eb3340 --- /dev/null +++ b/docs/zh/20-third-party/12-IDEA.mdx @@ -0,0 +1,84 @@ +--- +sidebar_label: IDEA +title: 通过 IDEA 数据库管理工具连接 TDengine +--- + +IDEA 全称 IntelliJ IDEA,是 Java 语言开发的集成环境,被公认为最友好且使用范围最广的 Java 开发工具之一。 + +IDEA Ultimate 版自带数据库管理工具,类似于一个小型 Navicat。这个工具让我们能在 IDEA 上对数据库做简单操作,不需要再切换到其他工具上。对于 TDengine 来说,用户可以通过 JDBC 驱动建立与 IDEA 的连接,不需要再到命令行去写 SQL 语句,直接在 IDEA 中执行即可。 + +此处以 2.0.40 版本的 JDBC Connector 为例,给大家介绍如何使用源码编译、打包,以及如何使用 IDEA 数据库工具连接 TDengine。 + +## 前置条件 + +要让 IDEA 能正常连接 TDengine ,需要以下几方面的准备工作。 + +- TDengine 集群已经部署并正常运行。 +- 若使用 TSDBDriver 驱动类连接请在本地安装 TDengine 客户端。 +- 若使用 RestfulDriver 驱动类连接 TDengine,请确保 taosAdapter 已经正常运行。 + +## 配置步骤 + +### 源码编译 JDBC-Connector + +去各大仓库下载 [dist-jar 包](https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver)或者通过源码编译,此处介绍源码编译方法。 + +- 首先从 GitHub 仓库克隆 JDBC 连接器的源码,`git clone https://github.com/taosdata/taos-connector-jdbc.git -b 2.0.40`(此处推荐 -b 指定发布了的 Tags 版本),也可以在 IDEA 上操作: + +![image](https://user-images.githubusercontent.com/70138133/180187698-395762d1-fcac-4cea-b44f-cc8cd07ea0c8.png) + +- 克隆完源码后,若是编译 2.0.40 及以下版本的 JDBC-Connector 需要修改 taos-connector-jdbc 目录下 pom.xml 文件,将 下的 commons-logging 依赖包的 值由 test 改为 compile,否则编译完后导入 IDEA database 管理工具可能提醒缺少此驱动类。 + +![image](https://user-images.githubusercontent.com/70138133/180206650-561f9e24-ebb9-4cd2-8868-6f1cede54803.png) + +- 在 taos-connector-jdbc 目录下执行:`mvn clean package -Dmaven.test.skip=true` + +![image](https://user-images.githubusercontent.com/70138133/180187879-486e24a7-3b20-4447-bff8-c0b651ab39b1.png) + +![image](https://user-images.githubusercontent.com/70138133/180187811-4e73b9fc-8787-4634-bd83-f1197b7699d9.png) + +- 此时 taos-connector-jdbc 目录的 target 文件夹内产生了 taos-jdbcdriver-2.0.40-dist.jar 等驱动包。 + +### 使用 IDEA database 工具连接 TDengine + +- 打开 IDEA database 工具,新建驱动,驱动程序文件选择 target 文件夹下的 taos-jdbcdriver-2.0.40-dist.jar。 + +- 选择 RESTful 方式进行连接(注意:若使用 com.taosdata.jdbc.TSDBDriver 驱动类需要安装 TDengine 客户端)。 + +![image](https://user-images.githubusercontent.com/70138133/180208261-34e7ed91-217f-46b5-80f9-f65f67d67662.png) + +- 然后通过驱动创建数据源。TDengine 的 JDBC URL 规范为: +`jdbc:[TAOS|TAOS-RS]://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]` + +- 此处使用 RESTful 连接,URL 示例为:jdbc:TAOS-RS://VM-24-8-centos:6041/log(需要在 Hosts 文件内添加域名解析;URL 内的 locale、timezone 参数在 RESTful 连接中不生效) + +![image](https://user-images.githubusercontent.com/70138133/180197188-4ead4635-e479-4498-8252-c84041c1770e.png) + +- 点击测试连接,出现黄色感叹号不影响使用。 + +![image](https://user-images.githubusercontent.com/70138133/180197251-98764434-bb7b-4e3a-9674-0620ab6d8bad.png) + + +## 验证 + +- 配置完后进行验证,点击刷新后再点击显示所有数据库: + +![image](https://user-images.githubusercontent.com/70138133/180202803-6e277132-44bd-4b22-8921-a54d16190d2b.png) + + +- 右击数据源,新建查询控制台测试能否查询。需要注意的是,RESTful 请求是无状态的,查询、写入需要在表名前带上数据库名。 + +- 2.X 版本中默认带 log 库,我们可以使用 `SHOW log.stables` 查看包含哪些超级表后对特定表进行查询、调试: + +![image](https://user-images.githubusercontent.com/70138133/180202329-6734c874-d4f5-40a3-be7d-c4fabbe73a19.png) + +- 可以看到有个超级表叫做 vgroups_info,执行 `DESCRIBE log.vgroups_info` 查看表结构: + +![image](https://user-images.githubusercontent.com/70138133/180204391-36fd0806-8cd6-43b8-97eb-1e7ff235846a.png) + + +- 再执行`SELECT last_row(*) FROM log.vgroups_info GROUP BY vgroup_id`通过 vgroup_id 分组能查看各 VgroupId 下的最新一条数据。 + +![image](https://user-images.githubusercontent.com/70138133/180205161-7f0314eb-cdaa-442c-acb5-d33931c32648.png) + + -- GitLab From 4e816aa5706f45d134ab2881983bca6527716171 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Thu, 21 Jul 2022 20:07:42 +0800 Subject: [PATCH 198/380] Update 12-IDEA.mdx --- docs/zh/20-third-party/12-IDEA.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/20-third-party/12-IDEA.mdx b/docs/zh/20-third-party/12-IDEA.mdx index 5ec8eb3340..68dff461b2 100644 --- a/docs/zh/20-third-party/12-IDEA.mdx +++ b/docs/zh/20-third-party/12-IDEA.mdx @@ -27,7 +27,7 @@ IDEA Ultimate 版自带数据库管理工具,类似于一个小型 Navicat。 ![image](https://user-images.githubusercontent.com/70138133/180187698-395762d1-fcac-4cea-b44f-cc8cd07ea0c8.png) -- 克隆完源码后,若是编译 2.0.40 及以下版本的 JDBC-Connector 需要修改 taos-connector-jdbc 目录下 pom.xml 文件,将 下的 commons-logging 依赖包的 值由 test 改为 compile,否则编译完后导入 IDEA database 管理工具可能提醒缺少此驱动类。 +- 克隆完源码后,若是编译 2.0.40 及以下版本的 JDBC-Connector 需要修改 taos-connector-jdbc 目录下 pom.xml 文件,将 dependencies 下的 commons-logging 依赖包的 scope 值由 test 改为 compile,否则编译完后导入 IDEA database 管理工具可能提醒缺少此驱动类。 ![image](https://user-images.githubusercontent.com/70138133/180206650-561f9e24-ebb9-4cd2-8868-6f1cede54803.png) -- GitLab From 81e252da58b35077974cb10e0af93c010584b5c0 Mon Sep 17 00:00:00 2001 From: 841866574 <44917562+841866574@users.noreply.github.com> Date: Fri, 22 Jul 2022 10:40:43 +0800 Subject: [PATCH 199/380] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E2=80=9D=E4=BA=A7?= =?UTF-8?q?=E5=93=81=E7=AE=80=E4=BB=8B=E2=80=9C=E9=A1=B5=E9=9D=A2=E7=9A=84?= =?UTF-8?q?=E9=94=99=E5=88=AB=E5=AD=97#15278?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh/02-intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/02-intro.md b/docs/zh/02-intro.md index 673c2e96b6..191e1cbcc2 100644 --- a/docs/zh/02-intro.md +++ b/docs/zh/02-intro.md @@ -52,7 +52,7 @@ TDengine的主要功能如下: 采用 TDengine,可将典型的物联网、车联网、工业互联网大数据平台的总拥有成本大幅降低。表现在几个方面: 1. 由于其超强性能,它能将系统需要的计算资源和存储资源大幅降低 -2. 因为采用 SQL 接口,能与众多第三放软件无缝集成,学习迁移成本大幅下降 +2. 因为采用 SQL 接口,能与众多第三方软件无缝集成,学习迁移成本大幅下降 3. 因为其 All In One 的特性,系统复杂度降低,能降研发成本 4. 因为运维维护简单,运营维护成本能大幅降低 -- GitLab From 1457183efbf157b23a966c10a49219e82910f291 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Fri, 22 Jul 2022 10:41:47 +0800 Subject: [PATCH 200/380] docs: Update 02-intro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update 02-intro 有个错别字 --- docs/zh/02-intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/02-intro.md b/docs/zh/02-intro.md index 673c2e96b6..191e1cbcc2 100644 --- a/docs/zh/02-intro.md +++ b/docs/zh/02-intro.md @@ -52,7 +52,7 @@ TDengine的主要功能如下: 采用 TDengine,可将典型的物联网、车联网、工业互联网大数据平台的总拥有成本大幅降低。表现在几个方面: 1. 由于其超强性能,它能将系统需要的计算资源和存储资源大幅降低 -2. 因为采用 SQL 接口,能与众多第三放软件无缝集成,学习迁移成本大幅下降 +2. 因为采用 SQL 接口,能与众多第三方软件无缝集成,学习迁移成本大幅下降 3. 因为其 All In One 的特性,系统复杂度降低,能降研发成本 4. 因为运维维护简单,运营维护成本能大幅降低 -- GitLab From ac5c41b7b76cdada723b78672d67d1f0c9249570 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Fri, 22 Jul 2022 11:07:16 +0800 Subject: [PATCH 201/380] Update 12-IDEA.mdx --- docs/zh/20-third-party/12-IDEA.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zh/20-third-party/12-IDEA.mdx b/docs/zh/20-third-party/12-IDEA.mdx index 68dff461b2..3862d634bb 100644 --- a/docs/zh/20-third-party/12-IDEA.mdx +++ b/docs/zh/20-third-party/12-IDEA.mdx @@ -33,9 +33,9 @@ IDEA Ultimate 版自带数据库管理工具,类似于一个小型 Navicat。 - 在 taos-connector-jdbc 目录下执行:`mvn clean package -Dmaven.test.skip=true` -![image](https://user-images.githubusercontent.com/70138133/180187879-486e24a7-3b20-4447-bff8-c0b651ab39b1.png) +![image](https://user-images.githubusercontent.com/70138133/180353366-f515a6ae-904d-42d6-9967-1c298112fe88.png) -![image](https://user-images.githubusercontent.com/70138133/180187811-4e73b9fc-8787-4634-bd83-f1197b7699d9.png) +![image](https://user-images.githubusercontent.com/70138133/180353831-cb0b2c5e-b9a3-4182-ba78-58abfa81e1b4.png) - 此时 taos-connector-jdbc 目录的 target 文件夹内产生了 taos-jdbcdriver-2.0.40-dist.jar 等驱动包。 @@ -77,7 +77,7 @@ IDEA Ultimate 版自带数据库管理工具,类似于一个小型 Navicat。 ![image](https://user-images.githubusercontent.com/70138133/180204391-36fd0806-8cd6-43b8-97eb-1e7ff235846a.png) -- 再执行`SELECT last_row(*) FROM log.vgroups_info GROUP BY vgroup_id`通过 vgroup_id 分组能查看各 VgroupId 下的最新一条数据。 +- 再执行`SELECT last_row(*) FROM log.vgroups_info GROUP BY vgroup_id`通过 vgroup_id 分组能查看各 VgroupId 下的最新一条数据: ![image](https://user-images.githubusercontent.com/70138133/180205161-7f0314eb-cdaa-442c-acb5-d33931c32648.png) -- GitLab From 1bb055755be6f51c3ff662a9f0bc30d8827800e1 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Fri, 22 Jul 2022 11:10:36 +0800 Subject: [PATCH 202/380] Update 12-IDEA.mdx --- docs/zh/20-third-party/12-IDEA.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/20-third-party/12-IDEA.mdx b/docs/zh/20-third-party/12-IDEA.mdx index 3862d634bb..2dd682f199 100644 --- a/docs/zh/20-third-party/12-IDEA.mdx +++ b/docs/zh/20-third-party/12-IDEA.mdx @@ -52,7 +52,7 @@ IDEA Ultimate 版自带数据库管理工具,类似于一个小型 Navicat。 - 此处使用 RESTful 连接,URL 示例为:jdbc:TAOS-RS://VM-24-8-centos:6041/log(需要在 Hosts 文件内添加域名解析;URL 内的 locale、timezone 参数在 RESTful 连接中不生效) -![image](https://user-images.githubusercontent.com/70138133/180197188-4ead4635-e479-4498-8252-c84041c1770e.png) +![image](https://user-images.githubusercontent.com/70138133/180354534-7d73fe33-c4d3-400d-922b-28b20aadfb1b.png) - 点击测试连接,出现黄色感叹号不影响使用。 -- GitLab From fdc6cbf48c66ff93e2c80741d12dec411f6a0ccd Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Fri, 22 Jul 2022 14:06:47 +0800 Subject: [PATCH 203/380] test: add test case for TS-1705 --- tests/pytest/insert/line_insert.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/pytest/insert/line_insert.py b/tests/pytest/insert/line_insert.py index 4c873ec4a4..79c318c344 100644 --- a/tests/pytest/insert/line_insert.py +++ b/tests/pytest/insert/line_insert.py @@ -196,12 +196,19 @@ class TDTestCase: self._conn.schemaless_insert([ "sts,t1=abc,t2=ab\"c,t3=ab\\,c,t4=ab\\=c,t5=ab\\ c c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64,c6=\"abc\" 1626006833640000000", - "sts,t1=abc c1=3i64,c2=false,c3=L\"{\\\"date\\\":\\\"2020-01-01 08:00:00.000\\\",\\\"temperature\\\":20}\",c6=\"ab\\\\c\" 1626006833640000000" + "sts,t1=abc c1=3i64,c2=false,c3=L\"{\\\"date\\\":\\\"2020-01-01 08:00:00.000\\\",\\\"temperature\\\":20}\",c6=\"ab\\\\c\" 1626006833640000000", + "type_json5,__deviceId__=10 index=0,jsonAttri$j=\"{\\\"jsonC\\\":\\\"0\\\"}\" 1626006833640000001" ], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) tdSql.query('select tbname from sts') tdSql.checkRows(2) + tdSql.query("select * from sts") + tdSql.checkData(1, 2, '''{"date":"2020-01-01 08:00:00.000","temperature":20}''') + + tdSql.query("select * from type_json5") + tdSql.checkData(0, 2, '''{"jsonC":"0"}''') + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) -- GitLab From f3ba8897fdb0d1df57b69447311a065cc1cd7921 Mon Sep 17 00:00:00 2001 From: huolibo Date: Mon, 11 Jul 2022 11:04:37 +0800 Subject: [PATCH 204/380] docs: TDengine 2.* document checkout jdbc 2.0 branch --- docs/en/14-reference/03-connector/java.mdx | 46 +++++++++++----------- docs/zh/14-reference/03-connector/java.mdx | 2 +- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/en/14-reference/03-connector/java.mdx b/docs/en/14-reference/03-connector/java.mdx index 310e0a15c6..22f99bb9ae 100644 --- a/docs/en/14-reference/03-connector/java.mdx +++ b/docs/en/14-reference/03-connector/java.mdx @@ -91,7 +91,7 @@ Add following dependency in the `pom.xml` file of your Maven project: You can build Java connector from source code after cloning the TDengine project: ``` -git clone https://github.com/taosdata/taos-connector-jdbc.git +git clone https://github.com/taosdata/taos-connector-jdbc.git --branch 2.0 cd taos-connector-jdbc mvn clean install -Dmaven.test.skip=true ``` @@ -140,34 +140,34 @@ When you use a JDBC native connection to connect to a TDengine cluster, you can 1. Do not specify hostname and port in Java applications. - ```java - public Connection getConn() throws Exception{ - Class.forName("com.taosdata.jdbc.TSDBDriver"); - String jdbcUrl = "jdbc:TAOS://:/test?user=root&password=taosdata"; - Properties connProps = new Properties(); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); - Connection conn = DriverManager.getConnection(jdbcUrl, connProps); - return conn; - } - ``` + ```java + public Connection getConn() throws Exception{ + Class.forName("com.taosdata.jdbc.TSDBDriver"); + String jdbcUrl = "jdbc:TAOS://:/test?user=root&password=taosdata"; + Properties connProps = new Properties(); + connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + Connection conn = DriverManager.getConnection(jdbcUrl, connProps); + return conn; + } + ``` 2. specify the firstEp and the secondEp in the configuration file taos.cfg - ```shell - # first fully qualified domain name (FQDN) for TDengine system - firstEp cluster_node1:6030 + ```shell + # first fully qualified domain name (FQDN) for TDengine system + firstEp cluster_node1:6030 - # second fully qualified domain name (FQDN) for TDengine system, for cluster only - secondEp cluster_node2:6030 + # second fully qualified domain name (FQDN) for TDengine system, for cluster only + secondEp cluster_node2:6030 - # default system charset - # charset UTF-8 + # default system charset + # charset UTF-8 - # system locale - # locale en_US.UTF-8 - ``` + # system locale + # locale en_US.UTF-8 + ``` In the above example, JDBC uses the client's configuration file to establish a connection to a hostname `cluster_node1`, port 6030, and a database named `test`. When the firstEp node in the cluster fails, JDBC attempts to connect to the cluster using secondEp. diff --git a/docs/zh/14-reference/03-connector/java.mdx b/docs/zh/14-reference/03-connector/java.mdx index 46b23c0a64..f7bd540088 100644 --- a/docs/zh/14-reference/03-connector/java.mdx +++ b/docs/zh/14-reference/03-connector/java.mdx @@ -93,7 +93,7 @@ Maven 项目中,在 pom.xml 中添加以下依赖: 可以通过下载 TDengine 的源码,自己编译最新版本的 Java connector ```shell -git clone https://github.com/taosdata/taos-connector-jdbc.git +git clone https://github.com/taosdata/taos-connector-jdbc.git --branch 2.0 cd taos-connector-jdbc mvn clean install -Dmaven.test.skip=true ``` -- GitLab From 420f532dba6424861214a8bdf92e09d10f2c4347 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 23 Jul 2022 11:47:02 +0800 Subject: [PATCH 205/380] feat(shell): finish autotab and submit PR --- src/kit/shell/src/shellAuto.c | 8 +++++++- src/kit/shell/src/shellDarwin.c | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/kit/shell/src/shellAuto.c b/src/kit/shell/src/shellAuto.c index 916ce1fa49..a9710de0d4 100644 --- a/src/kit/shell/src/shellAuto.c +++ b/src/kit/shell/src/shellAuto.c @@ -66,6 +66,12 @@ SWords shellCommands[] = { {"alter dnode monitor 1;", 0, 0, NULL}, {"alter table ", 0, 0, NULL}, {"alter table modify column", 0, 0, NULL}, + {"alter local resetlog;", 0, 0, NULL}, + {"alter local DebugFlag 143;", 0, 0, NULL}, + {"alter local cDebugFlag 143;", 0, 0, NULL}, + {"alter local uDebugFlag 143;", 0, 0, NULL}, + {"alter local rpcDebugFlag 143;", 0, 0, NULL}, + {"alter local tmrDebugFlag 143;", 0, 0, NULL}, {"alter topic", 0, 0, NULL}, {"alter user pass", 0, 0, NULL}, {"alter user privilege read", 0, 0, NULL}, @@ -328,8 +334,8 @@ void printfIntroduction() { printf(" * SUPPORT KEYBOARD SHORTCUT: *\n"); printf(" * [ TAB ] ...... if prefix nothing show help else complete word *\n"); printf(" * [ Ctrl + A ] ...... move cursor to line [A]head *\n"); - printf(" * [ Ctrl + M ] ...... move cursor to line [M]iddle *\n"); printf(" * [ Ctrl + E ] ...... move cursor to line [E]nd *\n"); + printf(" * [ Ctrl + W ] ...... move cursor to line middle *\n"); printf(" * [ Ctrl + L ] ...... clean screen *\n"); printf(" * [ Ctrl + K ] ...... clean after cursor *\n"); printf(" * [ Ctrl + U ] ...... clean before cursor *\n"); diff --git a/src/kit/shell/src/shellDarwin.c b/src/kit/shell/src/shellDarwin.c index fa3afd131a..cc3a0fc705 100644 --- a/src/kit/shell/src/shellDarwin.c +++ b/src/kit/shell/src/shellDarwin.c @@ -307,6 +307,9 @@ int32_t shellReadCommand(TAOS *con, char *command) { case 21: // Ctrl + U clearLineBefore(&cmd); break; + case 23: // Ctrl + W; + positionCursorMiddle(&cmd); + break; } } else if (c == '\033') { c = getchar(); -- GitLab From 7cae8adfa6b8ee2bee5ce9ff31d583d26456d275 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 23 Jul 2022 11:48:21 +0800 Subject: [PATCH 206/380] feat(shell): finish autotab and submit PR1 --- src/kit/shell/src/shellAuto.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kit/shell/src/shellAuto.c b/src/kit/shell/src/shellAuto.c index a9710de0d4..d9f805b687 100644 --- a/src/kit/shell/src/shellAuto.c +++ b/src/kit/shell/src/shellAuto.c @@ -125,7 +125,8 @@ SWords shellCommands[] = { {"show vgroups;", 0, 0, NULL}, {"insert into values(", 0, 0, NULL}, {"insert into using tags(", 0, 0, NULL}, - {"use ", 0, 0, NULL} + {"use ", 0, 0, NULL}, + {"quit", 0, 0, NULL} }; char * keywords[] = { -- GitLab From d63c872fb3620eb2464e507d5001cedc1016b22d Mon Sep 17 00:00:00 2001 From: Colin678 <1020084984@qq.com> Date: Sat, 23 Jul 2022 14:23:17 +0800 Subject: [PATCH 207/380] Update index.md (#15336) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove redundant "与" --- docs/zh/04-concept/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/04-concept/index.md b/docs/zh/04-concept/index.md index 8e97d4a2f4..0a0e4a3a2f 100644 --- a/docs/zh/04-concept/index.md +++ b/docs/zh/04-concept/index.md @@ -148,7 +148,7 @@ TDengine 建议用数据采集点的名字(如上表中的 D1001)来做表 3. 子表一定属于一张超级表,但普通表不属于任何超级表 4. 普通表无法转为子表,子表也无法转为普通表。 -超级表与与基于超级表建立的子表之间的关系表现在: +超级表与基于超级表建立的子表之间的关系表现在: 1. 一张超级表包含有多张子表,这些子表具有相同的采集量 schema,但带有不同的标签值。 2. 不能通过子表调整数据或标签的模式,对于超级表的数据模式修改立即对所有的子表生效。 -- GitLab From 4d9fd409e66bbf74462175ac3fb924ebd12ef77f Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 23 Jul 2022 15:09:04 +0800 Subject: [PATCH 208/380] feat(shell): autotab window build --- src/kit/shell/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/kit/shell/CMakeLists.txt b/src/kit/shell/CMakeLists.txt index 614fa328ba..bfe714a70c 100644 --- a/src/kit/shell/CMakeLists.txt +++ b/src/kit/shell/CMakeLists.txt @@ -31,6 +31,8 @@ ELSEIF (TD_WINDOWS) LIST(APPEND SRC ./src/shellEngine.c) LIST(APPEND SRC ./src/shellMain.c) LIST(APPEND SRC ./src/shellWindows.c) + LIST(APPEND SRC ./src/shellAuto.c) + LIST(APPEND SRC ./src/tire.c) ADD_EXECUTABLE(shell ${SRC}) IF (TD_LINUX_64 AND JEMALLOC_ENABLED) ADD_DEPENDENCIES(shell jemalloc) -- GitLab From db821689d9cc04f8709150d6a2e7f154f9782582 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Sat, 23 Jul 2022 15:11:48 +0800 Subject: [PATCH 209/380] doc: english version of high throughput writing --- .../03-insert-data/05-high-volume.md | 441 ++++++++++++++++++ 1 file changed, 441 insertions(+) create mode 100644 docs/en/07-develop/03-insert-data/05-high-volume.md diff --git a/docs/en/07-develop/03-insert-data/05-high-volume.md b/docs/en/07-develop/03-insert-data/05-high-volume.md new file mode 100644 index 0000000000..cc13a2d0ac --- /dev/null +++ b/docs/en/07-develop/03-insert-data/05-high-volume.md @@ -0,0 +1,441 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +# High Performance Data Writing + +This chapter introduces how to write data into TDengine with high throughput. + +## How to Achieve high performance data writing + +To achieve high performance writing, there are a few aspects to consider. In the following sections we will describe these important factors in achieving high performance writing. + +### Application Program + +From the perspective of application program, you need to consider: + +1. The data size of each single write, also known as batch size. Generally speaking, higher batch size generates better writing performance. However, once the batch size is over a specific value, you will not get any additional benefit anymore. When using SQL to write into TDengine, it's better to put as much as possible data in single SQL. The maximum SQL length supported by TDengine is 1,048,576 bytes, i.e. 1 MB. It can be configured by parameter `maxSQLLength` on client side, and the default value is 65,480. + +2. The number of concurrent connections. Normally more connections can get better result. However, once the number of connections exceeds the processing ability of the server side, the performance may downgrade. + +3. The distribution of data to be written across tables or sub-tables. Writing to single table in one batch is more efficient than writing to multiple tables in one batch. + +4. Data Writing Protocol. + - Prameter binding mode is more efficient than SQL because it doesn't have the cost of parsing SQL. + - Writing to known existing tables is more efficient than wirting to uncertain tables in automatic creating mode because the later needs to check whether the table exists or not before actually writing data into it + - Writing in SQL is more efficient than wirting in schemaless mode because schemaless writing creats table automatically and may alter table schema + +Application programs need to take care of the above factors and try to take advantage of them. The application progam should write to single table in each write batch. The batch size needs to be tuned to a proper value on a specific system. The number of concurrent connections needs to be tuned to a proper value too to achieve the best writing throughput. + +### Data Source + +Application programs need to read data from data source then write into TDengine. If you meet one or more of below situations, you need to setup message queues between the threads for reading from data source and the threads for writing into TDengine. + +1. There are multiple data sources, the data generation speed of each data source is much slower than the speed of single writing thread. In this case, the purpose of message queues is to consolidate the data from multiple data sources together to increase the batch size of single write. +2. The speed of data generation from single data source is much higher than the speed of single writing thread. The purpose of message queue in this case is to provide buffer so that data is not lost and multiple writing threads can get data from the buffer. +3. The data for single table are from multiple data source. In this case the purpose of message queues is to combine the data for single table together to improve the write efficiency. + +If the data source is Kafka, then the appication program is a consumer of Kafka, you can benefit from some kafka features to achieve high performance writing: + +1. Put the data for a table in single partition of single topic so that it's easier to put the data for each table together and write in batch +2. Subscribe multiple topics to accumulate data toger. +3. Add more consumers to increase the speed of data generation, thenincrease the number of wirting thredads to get higher writing speed. +4. Incrase the size of single fetch to increase the size of write batch. + +### Tune TDengine + +TDengine is a distributed and high performance time series database, there are also some ways to tune TDengine to get better writing performance. + +1. Set proper number of `vgroups` according to available CPU cores. Normally, we recommend 2 \* number_of_cores as a starting point. If the verification result shows this is not enough to utilize CPU resources, you can use a higher value. +2. Set proper `minTablesPerVnode`, `tableIncStepPerVnode`, and `maxVgroupsPerDb` according to the number of tables so that tables are distributed even across vgroups. Thhe purpose is to balance the work load among all vnodes so that system resources can be utilized better to get higher performance. + +For more performance tuning tips, please refer to [Performance Optimization](../../operation/optimize) and [Configuration Parameters](../../reference/config). + +## Sample Programs + +This section will introduce the sample programs to demonstrate how to write into TDengine with high performance. + +### Scenario + +Below are the scenario for the sample programs of high performance wrting. + +- Application program reads data from data source, the sample program simulates a data source by generating data +- The speed of single writing thread is much slower than the speed of generating data, so the program starts multiple writing threads while each thread establish a connection to TDengine and each thread has a message queue of fixed size. +- Application program maps the received data to different writing threads based on table name to make sure all the data for each table is always processed by a specific writing thread. +- Each writing thread writes the received data into TDengine once the message queue becomes empty or the read data meets a threshold. + +![Thread Model of High Performance Writing into TDengine](highvolume.webp) + +### Sample Programs + +The sample programs listed in this section are based on the scenario described previously. If your scenarios is different, please try to adjust the code based on the principles described in this chapter. + +The sample programs assume the source data is for all the different sub tables in same super table (meters). The super table has been created before the sample program starts to writing data. Sub tables are created automatically according to received data. If there are multiple super tables in your case, please try to adjust the part of creating table automatically. + + + + +**Program Inventory** + +| Class | Description | +| ---------------- | ----------------------------------------------------------------------------------------------------- | +| FastWriteExample | Main Program | +| ReadTask | Read data from simulated data source and put into a queue according to the hash value of table name | +| WriteTask | Read data from Queue, compose a wirte batch and write into TDengine | +| MockDataSource | Generate data for some sub tables of super table meters | +| SQLWriter | WriteTask uses this class to compose SQL, create table automatically, check SQL length and write data | +| StmtWriter | Write in Parameter binding mode (Not finished yet) | +| DataBaseMonitor | Calculate the writing speed and output on console every 10 seconds | + +Below is the list of complete code of the classes in above table and more detailed description. + +
+FastWriteExample +The main Program is responsible for: + +1. Create message queues +2. Start writing threads +3. Start reading threads +4. Otuput writing speed every 10 seconds + +The main program provides 4 parameters for tuning: + +1. The number of reading threads, default value is 1 +2. The number of writing threads, default alue is 2 +3. The total number of tables in the generated data, default value is 1000. These tables are distributed evenly across all writing threads. If the number of tables is very big, it will cost much time to firstly create these tables. +4. The batch size of single write, default value is 3,000 + +The capacity of message queue also impacts performance and can be tuned by modifying program. Normally it's always better to have a larger message queue. A larger message queue means lower possibility of being blocked when enqueueing and higher throughput. But a larger message queue consumes more memory space. The default value used in the sample programs is already big enoug. + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java}} +``` + +
+ +
+ReadTask + +ReadTask reads data from data source. Each ReadTask is associated with a simulated data source, each data source generates data for a group of specific tables, and the data of any table is only generated from a single specific data source. + +ReadTask puts data in message queue in blocking mode. That means, the putting operation is blocked if the message queue is full. + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java}} +``` + +
+ +
+WriteTask + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java}} +``` + +
+ +
+ +MockDataSource + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java}} +``` + +
+ +
+ +SQLWriter + +SQLWriter class encapsulates the logic of composing SQL and writing data. Please be noted that the tables have not been created before writing, but are created automatically when catching the exception of table doesn't exist. For other exceptions caught, the SQL which caused the exception are logged for you to debug. + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java}} +``` + +
+ +
+ +DataBaseMonitor + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java}} +``` + +
+ +**Steps to Launch** + +
+Launch Java Sample Program + +You need to set environment variable `TDENGINE_JDBC_URL` before launching the program. If TDengine Server is setup on localhost, then the default value for user name, password and port can be used, like below: + +``` +TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" +``` + +**Launch in IDE** + +1. Clone TDengine repolitory + ``` + git clone git@github.com:taosdata/TDengine.git --depth 1 + ``` +2. Use IDE to open `docs/examples/java` directory +3. Configure environment variable `TDENGINE_JDBC_URL`, you can also configure it before launching the IDE, if so you can skip this step. +4. Run class `com.taos.example.highvolume.FastWriteExample` + +**Launch on server** + +If you want to launch the sample program on a remote server, please follow below steps: + +1. Package the sample programs. Execute below command under directory `TDengine/docs/examples/java` : + ``` + mvn package + ``` +2. Create `examples/java` directory on the server + ``` + mkdir -p examples/java + ``` +3. Copy dependencies (below commands assume you are working on a local Windows host and try to launch on a remote Linux host) + - Copy dependent packages + ``` + scp -r .\target\lib @:~/examples/java + ``` + - Copy the jar of sample programs + ``` + scp -r .\target\javaexample-1.0.jar @:~/examples/java + ``` +4. Configure environment variable + Edit `~/.bash_profile` or `~/.bashrc` and add below: + + ``` + export TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" + ``` + + If your TDengine server is not deployed on localhost or doesn't use default port, you need to change the above URL to correct value in your environment. + +5. Launch the sample program + + ``` + java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample + ``` + +6. The sample program doesn't exit unless you press CTRL + C to terminate it. + Below is the output of running on a server of 16 cores, 64GB memory and SSD hard disk. + + ``` + root@vm85$ java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample 2 12 + 18:56:35.896 [main] INFO c.t.e.highvolume.FastWriteExample - readTaskCount=2, writeTaskCount=12 tableCount=1000 maxBatchSize=3000 + 18:56:36.011 [WriteThread-0] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.015 [WriteThread-0] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.021 [WriteThread-1] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.022 [WriteThread-1] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.031 [WriteThread-2] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.032 [WriteThread-2] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.041 [WriteThread-3] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.042 [WriteThread-3] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.093 [WriteThread-4] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.094 [WriteThread-4] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.099 [WriteThread-5] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.100 [WriteThread-5] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.100 [WriteThread-6] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.101 [WriteThread-6] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.103 [WriteThread-7] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.104 [WriteThread-7] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.105 [WriteThread-8] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.107 [WriteThread-8] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.108 [WriteThread-9] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.109 [WriteThread-9] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.156 [WriteThread-10] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.157 [WriteThread-11] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.158 [WriteThread-10] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.158 [ReadThread-0] INFO com.taos.example.highvolume.ReadTask - started + 18:56:36.158 [ReadThread-1] INFO com.taos.example.highvolume.ReadTask - started + 18:56:36.158 [WriteThread-11] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:46.369 [main] INFO c.t.e.highvolume.FastWriteExample - count=18554448 speed=1855444 + 18:56:56.946 [main] INFO c.t.e.highvolume.FastWriteExample - count=39059660 speed=2050521 + 18:57:07.322 [main] INFO c.t.e.highvolume.FastWriteExample - count=59403604 speed=2034394 + 18:57:18.032 [main] INFO c.t.e.highvolume.FastWriteExample - count=80262938 speed=2085933 + 18:57:28.432 [main] INFO c.t.e.highvolume.FastWriteExample - count=101139906 speed=2087696 + 18:57:38.921 [main] INFO c.t.e.highvolume.FastWriteExample - count=121807202 speed=2066729 + 18:57:49.375 [main] INFO c.t.e.highvolume.FastWriteExample - count=142952417 speed=2114521 + 18:58:00.689 [main] INFO c.t.e.highvolume.FastWriteExample - count=163650306 speed=2069788 + 18:58:11.646 [main] INFO c.t.e.highvolume.FastWriteExample - count=185019808 speed=2136950 + ``` + +
+ +
+ + +**Program Inventory** + +Sample programs in Python uses multi-process and cross-process message queues. + +| Function/CLass | Description | +| ---------------------------- | --------------------------------------------------------------------------- | +| main Function | Program entry point, create child processes and message queues | +| run_monitor_process Function | Create database, super table, calculate writing speed and output to console | +| run_read_task Function | Read data and distribute to message queues | +| MockDataSource Class | Simulate data source, return next 1,000 rows of each table | +| run_write_task Function | Read as much as possible data from message queue and write in batch | +| SQLWriter Class | Write in SQL and create table utomatically | +| StmtWriter Class | Write in parameter binding mode (not finished yet) | + +
+main function + +`main` function is responsible for creating message queues and fork child processes, there are 3 kinds of child processes: + +1. Monitoring process, initializes database and calculating writing speed +2. Reading process (n), reads data from data source +3. Writing process (m), wirtes data into TDengine + +`main` function provides 5 parameters: + +1. The number of reading tasks, default value is 1 +2. The number of writing tasks, default value is 1 +3. The number of tables, default value is 1,000 +4. The capacity of message queue, default value is 1,000,000 bytes +5. The batch size in single write, default value is 3000 + +```python +{{#include docs/examples/python/fast_write_example.py:main}} +``` + +
+ +
+run_monitor_process + +Monitoring process initilizes database and monitoring writing speed. + +```python +{{#include docs/examples/python/fast_write_example.py:monitor}} +``` + +
+ +
+ +run_read_task function + +Reading process reads data from other data system and distributes to the message queue allocated for it. + +```python +{{#include docs/examples/python/fast_write_example.py:read}} +``` + +
+ +
+ +MockDataSource + +Below is the simulated data source, we assume table name exists in each generated data. + +```python +{{#include docs/examples/python/mockdatasource.py}} +``` + +
+ +
+run_write_task function + +Writing process tries to read as much as possible data from message queue and writes in batch. + +```python +{{#include docs/examples/python/fast_write_example.py:write}} +``` + +
+ +
+ +SQLWriter class encapsulates the logic of composing SQL and writing data. Please be noted that the tables have not been created before writing, but are created automatically when catching the exception of table doesn't exist. For other exceptions caught, the SQL which caused the exception are logged for you to debug. This class also checks the SQL length, if the SQL length is closed to `maxSQLLength` the SQL will be executed immediately. To improve writing efficiency, it's better to increase `maxSQLLength` properly. + +SQLWriter + +```python +{{#include docs/examples/python/sql_writer.py}} +``` + +
+ +**Steps to Launch** + +
+ +Launch Sample Program in Python + +1. Prerequisities + + - TDengine client driver has been installed + - Python3 has been installed, the the version >= 3.8 + - TDengine Python connector `taospy` has been installed + +2. Install faster-fifo to replace python builtin multiprocessing.Queue + + ``` + pip3 install faster-fifo + ``` + +3. Click the "Copy" in the above sample programs to copy `fast_write_example.py` 、 `sql_writer.py` and `mockdatasource.py`. + +4. Execute the program + + ``` + python3 fast_write_example.py + ``` + + Below is the output of running on a server of 16 cores, 64GB memory and SSD hard disk. + + ``` + root@vm85$ python3 fast_write_example.py 8 8 + 2022-07-14 19:13:45,869 [root] - READ_TASK_COUNT=8, WRITE_TASK_COUNT=8, TABLE_COUNT=1000, QUEUE_SIZE=1000000, MAX_BATCH_SIZE=3000 + 2022-07-14 19:13:48,882 [root] - WriteTask-0 started with pid 718347 + 2022-07-14 19:13:48,883 [root] - WriteTask-1 started with pid 718348 + 2022-07-14 19:13:48,884 [root] - WriteTask-2 started with pid 718349 + 2022-07-14 19:13:48,884 [root] - WriteTask-3 started with pid 718350 + 2022-07-14 19:13:48,885 [root] - WriteTask-4 started with pid 718351 + 2022-07-14 19:13:48,885 [root] - WriteTask-5 started with pid 718352 + 2022-07-14 19:13:48,886 [root] - WriteTask-6 started with pid 718353 + 2022-07-14 19:13:48,886 [root] - WriteTask-7 started with pid 718354 + 2022-07-14 19:13:48,887 [root] - ReadTask-0 started with pid 718355 + 2022-07-14 19:13:48,888 [root] - ReadTask-1 started with pid 718356 + 2022-07-14 19:13:48,889 [root] - ReadTask-2 started with pid 718357 + 2022-07-14 19:13:48,889 [root] - ReadTask-3 started with pid 718358 + 2022-07-14 19:13:48,890 [root] - ReadTask-4 started with pid 718359 + 2022-07-14 19:13:48,891 [root] - ReadTask-5 started with pid 718361 + 2022-07-14 19:13:48,892 [root] - ReadTask-6 started with pid 718364 + 2022-07-14 19:13:48,893 [root] - ReadTask-7 started with pid 718365 + 2022-07-14 19:13:56,042 [DataBaseMonitor] - count=6676310 speed=667631.0 + 2022-07-14 19:14:06,196 [DataBaseMonitor] - count=20004310 speed=1332800.0 + 2022-07-14 19:14:16,366 [DataBaseMonitor] - count=32290310 speed=1228600.0 + 2022-07-14 19:14:26,527 [DataBaseMonitor] - count=44438310 speed=1214800.0 + 2022-07-14 19:14:36,673 [DataBaseMonitor] - count=56608310 speed=1217000.0 + 2022-07-14 19:14:46,834 [DataBaseMonitor] - count=68757310 speed=1214900.0 + 2022-07-14 19:14:57,280 [DataBaseMonitor] - count=80992310 speed=1223500.0 + 2022-07-14 19:15:07,689 [DataBaseMonitor] - count=93805310 speed=1281300.0 + 2022-07-14 19:15:18,020 [DataBaseMonitor] - count=106111310 speed=1230600.0 + 2022-07-14 19:15:28,356 [DataBaseMonitor] - count=118394310 speed=1228300.0 + 2022-07-14 19:15:38,690 [DataBaseMonitor] - count=130742310 speed=1234800.0 + 2022-07-14 19:15:49,000 [DataBaseMonitor] - count=143051310 speed=1230900.0 + 2022-07-14 19:15:59,323 [DataBaseMonitor] - count=155276310 speed=1222500.0 + 2022-07-14 19:16:09,649 [DataBaseMonitor] - count=167603310 speed=1232700.0 + 2022-07-14 19:16:19,995 [DataBaseMonitor] - count=179976310 speed=1237300.0 + ``` + +
+ +:::note +Don't establish connection to TDengine in the parent process if using Python connector in multi-process way, otherwise all the connections in child processes are blocked always. This is a known issue. + +::: + +
+
-- GitLab From a3505504b1b012fd917199aba088def3c386a9a6 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 23 Jul 2022 15:21:07 +0800 Subject: [PATCH 210/380] feat(shell): autotab window build --- src/kit/shell/CMakeLists.txt | 2 -- src/kit/shell/src/shellMain.c | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/kit/shell/CMakeLists.txt b/src/kit/shell/CMakeLists.txt index bfe714a70c..614fa328ba 100644 --- a/src/kit/shell/CMakeLists.txt +++ b/src/kit/shell/CMakeLists.txt @@ -31,8 +31,6 @@ ELSEIF (TD_WINDOWS) LIST(APPEND SRC ./src/shellEngine.c) LIST(APPEND SRC ./src/shellMain.c) LIST(APPEND SRC ./src/shellWindows.c) - LIST(APPEND SRC ./src/shellAuto.c) - LIST(APPEND SRC ./src/tire.c) ADD_EXECUTABLE(shell ${SRC}) IF (TD_LINUX_64 AND JEMALLOC_ENABLED) ADD_DEPENDENCIES(shell jemalloc) diff --git a/src/kit/shell/src/shellMain.c b/src/kit/shell/src/shellMain.c index 3e84332834..2dcf105216 100644 --- a/src/kit/shell/src/shellMain.c +++ b/src/kit/shell/src/shellMain.c @@ -164,13 +164,16 @@ int main(int argc, char* argv[]) { /* Get grant information */ shellGetGrantInfo(args.con); +#ifndef WINDOWS shellAutoInit(); +#endif /* Loop to query the input. */ while (1) { pthread_create(&pid, NULL, shellLoopQuery, args.con); pthread_join(pid, NULL); } - +#ifndef WINDOWS shellAutoExit(); +#endif } -- GitLab From 38ddac45c30ac3d94527d8c106f36cfab7cc0d2d Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Sat, 23 Jul 2022 15:29:07 +0800 Subject: [PATCH 211/380] doc: fix broken link to picture --- docs/en/07-develop/03-insert-data/05-high-volume.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/en/07-develop/03-insert-data/05-high-volume.md b/docs/en/07-develop/03-insert-data/05-high-volume.md index cc13a2d0ac..f8849a74b3 100644 --- a/docs/en/07-develop/03-insert-data/05-high-volume.md +++ b/docs/en/07-develop/03-insert-data/05-high-volume.md @@ -1,8 +1,11 @@ +--- +sidebar_label: High Performance Writing +title: High Performance Writing +--- + import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -# High Performance Data Writing - This chapter introduces how to write data into TDengine with high throughput. ## How to Achieve high performance data writing @@ -63,7 +66,7 @@ Below are the scenario for the sample programs of high performance wrting. - Application program maps the received data to different writing threads based on table name to make sure all the data for each table is always processed by a specific writing thread. - Each writing thread writes the received data into TDengine once the message queue becomes empty or the read data meets a threshold. -![Thread Model of High Performance Writing into TDengine](highvolume.webp) +![Thread Model of High Performance Writing into TDengine](../../../zh/07-develop/03-insert-data/highvolume.webp) ### Sample Programs -- GitLab From c0daa2d357c72b3633a5c11c179d9730423ab4cd Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 23 Jul 2022 15:43:27 +0800 Subject: [PATCH 212/380] feat(shell): autotab window build1 --- src/kit/shell/src/shellEngine.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index 681e7b90e6..38921bfd10 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -328,8 +328,11 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { fprintf(stdout, "Database changed.\n\n"); fflush(stdout); +#ifndef WINDOWS // call back auto tab module - callbackAutoTab(command, pSql, true); + callbackAutoTab(command, pSql, true); +#endif + atomic_store_64(&result, 0); freeResultWithRid(oresult); @@ -370,8 +373,10 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { et = taosGetTimestampUs(); printf("Query OK, %d of %d row(s) in database (%.6fs)\n", num_rows_affacted, num_rows_affacted, (et - st) / 1E6); +#ifndef WINDOWS // call auto tab - callbackAutoTab(command, pSql, false); + callbackAutoTab(command, pSql, false); +#endif } printf("\n"); -- GitLab From 219f33d5b4de73caff5404c3459f6ac9d8c62b0b Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Sat, 23 Jul 2022 16:06:12 +0800 Subject: [PATCH 213/380] doc: fix picture broken link --- docs/en/07-develop/03-insert-data/05-high-volume.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/07-develop/03-insert-data/05-high-volume.md b/docs/en/07-develop/03-insert-data/05-high-volume.md index f8849a74b3..29a2c82fc7 100644 --- a/docs/en/07-develop/03-insert-data/05-high-volume.md +++ b/docs/en/07-develop/03-insert-data/05-high-volume.md @@ -66,7 +66,7 @@ Below are the scenario for the sample programs of high performance wrting. - Application program maps the received data to different writing threads based on table name to make sure all the data for each table is always processed by a specific writing thread. - Each writing thread writes the received data into TDengine once the message queue becomes empty or the read data meets a threshold. -![Thread Model of High Performance Writing into TDengine](../../../zh/07-develop/03-insert-data/highvolume.webp) +![Thread Model of High Performance Writing into TDengine](highvolume.webp) ### Sample Programs -- GitLab From f1d23caf9b74dd4d69a688f1b9a47887ce8c925f Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Sat, 23 Jul 2022 16:13:46 +0800 Subject: [PATCH 214/380] doc: add picture file --- .../en/07-develop/03-insert-data/highvolume.webp | Bin 0 -> 7308 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/en/07-develop/03-insert-data/highvolume.webp diff --git a/docs/en/07-develop/03-insert-data/highvolume.webp b/docs/en/07-develop/03-insert-data/highvolume.webp new file mode 100644 index 0000000000000000000000000000000000000000..46dfc74ae3b0043c591ff930c62251da49cae7ad GIT binary patch literal 7308 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 literal 0 HcmV?d00001 -- GitLab From 82337317269c0e9006e14849248a2a743ff44d8f Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 23 Jul 2022 16:34:54 +0800 Subject: [PATCH 215/380] feat(shell): autotab modify english word --- src/kit/shell/src/shellAuto.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/kit/shell/src/shellAuto.c b/src/kit/shell/src/shellAuto.c index d9f805b687..8622b201a6 100644 --- a/src/kit/shell/src/shellAuto.c +++ b/src/kit/shell/src/shellAuto.c @@ -329,14 +329,14 @@ int cntDel = 0; // delete byte count after next press tab // show auto tab introduction void printfIntroduction() { - printf(" **************************** SUPPORT TAB KEY ************************************\n"); - printf(" * Taos shell support press TAB key to complete word. You can try it. *\n"); + printf(" ********************* How to Use TAB in TAOS Shell ******************************\n"); + printf(" * Taos shell supports pressing TAB key to complete word. You can try it. *\n"); printf(" * Press TAB key anywhere, You'll get surprise. *\n"); - printf(" * SUPPORT KEYBOARD SHORTCUT: *\n"); - printf(" * [ TAB ] ...... if prefix nothing show help else complete word *\n"); - printf(" * [ Ctrl + A ] ...... move cursor to line [A]head *\n"); - printf(" * [ Ctrl + E ] ...... move cursor to line [E]nd *\n"); - printf(" * [ Ctrl + W ] ...... move cursor to line middle *\n"); + printf(" * KEYBOARD SHORTCUT: *\n"); + printf(" * [ TAB ] ...... Complete the word or show help if no input *\n"); + printf(" * [ Ctrl + A ] ...... move cursor to [A]head of line *\n"); + printf(" * [ Ctrl + E ] ...... move cursor to [E]nd of line *\n"); + printf(" * [ Ctrl + W ] ...... move cursor to line of middle *\n"); printf(" * [ Ctrl + L ] ...... clean screen *\n"); printf(" * [ Ctrl + K ] ...... clean after cursor *\n"); printf(" * [ Ctrl + U ] ...... clean before cursor *\n"); @@ -351,11 +351,13 @@ void showHelp() { alter database \n\ alter dnode balance \n\ alter dnode resetlog;\n\ - alter dnode debugFlag 141;\n\ + alter dnode DebugFlag 143;\n\ alter dnode monitor 1;\n\ alter table ADD COLUMN ; \n\ alter table DROP COLUMN ; \n\ alter table MODIFY COLUMN ;\n\ + alter local resetlog; \n\ + alter local DebugFlag 143; \n\ alter topic \n\ alter user pass\n\ alter user privilege read ;\n\ -- GitLab From 286984f315c9b34145b6101df1d8d1dcec7669d7 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 23 Jul 2022 16:48:36 +0800 Subject: [PATCH 216/380] feat(shell): autotab show on screen reset to old --- src/kit/shell/src/shellCommand.c | 7 ++----- src/kit/shell/src/shellDarwin.c | 6 +++--- src/kit/shell/src/shellLinux.c | 6 +++--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/kit/shell/src/shellCommand.c b/src/kit/shell/src/shellCommand.c index 9bbf19571e..d40edacbf0 100644 --- a/src/kit/shell/src/shellCommand.c +++ b/src/kit/shell/src/shellCommand.c @@ -79,11 +79,8 @@ void insertChar(Command *cmd, char *c, int size) { /* update the values */ cmd->commandSize += size; cmd->cursorOffset += size; - for (int i = 0; i < size; i++) { - mbtowc(&wc, c + i, size); - cmd->screenOffset += wcwidth(wc); - cmd->endOffset += wcwidth(wc); - } + cmd->screenOffset += wcwidth(wc); + cmd->endOffset += wcwidth(wc); showOnScreen(cmd); } diff --git a/src/kit/shell/src/shellDarwin.c b/src/kit/shell/src/shellDarwin.c index cc3a0fc705..0108d92e8f 100644 --- a/src/kit/shell/src/shellDarwin.c +++ b/src/kit/shell/src/shellDarwin.c @@ -539,14 +539,14 @@ void showOnScreen(Command *cmd) { /* assert(size >= 0); */ int width = wcwidth(wc); if (remain_column > width) { - fprintf(stdout, "%lc", wc); + printf("%lc", wc); remain_column -= width; } else { if (remain_column == width) { - fprintf(stdout, "%lc\n\r", wc); + printf("%lc\n\r", wc); remain_column = w.ws_col; } else { - fprintf(stdout, "\n\r%lc", wc); + printf("\n\r%lc", wc); remain_column = w.ws_col - width; } } diff --git a/src/kit/shell/src/shellLinux.c b/src/kit/shell/src/shellLinux.c index 5bf8ada862..fd24a61c7d 100644 --- a/src/kit/shell/src/shellLinux.c +++ b/src/kit/shell/src/shellLinux.c @@ -568,14 +568,14 @@ void showOnScreen(Command *cmd) { /* assert(size >= 0); */ int width = wcwidth(wc); if (remain_column > width) { - fprintf(stdout, "%lc", wc); + printf("%lc", wc); remain_column -= width; } else { if (remain_column == width) { - fprintf(stdout, "%lc\n\r", wc); + printf("%lc\n\r", wc); remain_column = w.ws_col; } else { - fprintf(stdout, "\n\r%lc", wc); + printf("\n\r%lc", wc); remain_column = w.ws_col - width; } } -- GitLab From 6171efdb3569aff5457a2ab115a288414b0571cb Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 23 Jul 2022 16:54:27 +0800 Subject: [PATCH 217/380] feat(shell): autotab calc position changed --- src/kit/shell/src/shellCommand.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/kit/shell/src/shellCommand.c b/src/kit/shell/src/shellCommand.c index d40edacbf0..2fe09691e3 100644 --- a/src/kit/shell/src/shellCommand.c +++ b/src/kit/shell/src/shellCommand.c @@ -79,8 +79,11 @@ void insertChar(Command *cmd, char *c, int size) { /* update the values */ cmd->commandSize += size; cmd->cursorOffset += size; - cmd->screenOffset += wcwidth(wc); - cmd->endOffset += wcwidth(wc); + for (int i = 0; i < size; i++) { + mbtowc(&wc, c + i, size); + cmd->screenOffset += wcwidth(wc); + cmd->endOffset += wcwidth(wc); + } showOnScreen(cmd); } -- GitLab From 5f667416ce6aeb31e528d31963ee0abc80eb6a74 Mon Sep 17 00:00:00 2001 From: Jeff Tao Date: Sat, 23 Jul 2022 17:03:54 +0800 Subject: [PATCH 218/380] Update 05-high-volume.md --- docs/en/07-develop/03-insert-data/05-high-volume.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/en/07-develop/03-insert-data/05-high-volume.md b/docs/en/07-develop/03-insert-data/05-high-volume.md index 29a2c82fc7..fc4f071997 100644 --- a/docs/en/07-develop/03-insert-data/05-high-volume.md +++ b/docs/en/07-develop/03-insert-data/05-high-volume.md @@ -8,7 +8,7 @@ import TabItem from "@theme/TabItem"; This chapter introduces how to write data into TDengine with high throughput. -## How to Achieve high performance data writing +## How to achieve high performance data writing To achieve high performance writing, there are a few aspects to consider. In the following sections we will describe these important factors in achieving high performance writing. @@ -25,7 +25,7 @@ From the perspective of application program, you need to consider: 4. Data Writing Protocol. - Prameter binding mode is more efficient than SQL because it doesn't have the cost of parsing SQL. - Writing to known existing tables is more efficient than wirting to uncertain tables in automatic creating mode because the later needs to check whether the table exists or not before actually writing data into it - - Writing in SQL is more efficient than wirting in schemaless mode because schemaless writing creats table automatically and may alter table schema + - Writing in SQL is more efficient than writing in schemaless mode because schemaless writing creats table automatically and may alter table schema Application programs need to take care of the above factors and try to take advantage of them. The application progam should write to single table in each write batch. The batch size needs to be tuned to a proper value on a specific system. The number of concurrent connections needs to be tuned to a proper value too to achieve the best writing throughput. @@ -40,8 +40,8 @@ Application programs need to read data from data source then write into TDengine If the data source is Kafka, then the appication program is a consumer of Kafka, you can benefit from some kafka features to achieve high performance writing: 1. Put the data for a table in single partition of single topic so that it's easier to put the data for each table together and write in batch -2. Subscribe multiple topics to accumulate data toger. -3. Add more consumers to increase the speed of data generation, thenincrease the number of wirting thredads to get higher writing speed. +2. Subscribe multiple topics to accumulate data together. +3. Add more consumers to gain more concurrency and throughput. 4. Incrase the size of single fetch to increase the size of write batch. ### Tune TDengine @@ -49,7 +49,7 @@ If the data source is Kafka, then the appication program is a consumer of Kafka, TDengine is a distributed and high performance time series database, there are also some ways to tune TDengine to get better writing performance. 1. Set proper number of `vgroups` according to available CPU cores. Normally, we recommend 2 \* number_of_cores as a starting point. If the verification result shows this is not enough to utilize CPU resources, you can use a higher value. -2. Set proper `minTablesPerVnode`, `tableIncStepPerVnode`, and `maxVgroupsPerDb` according to the number of tables so that tables are distributed even across vgroups. Thhe purpose is to balance the work load among all vnodes so that system resources can be utilized better to get higher performance. +2. Set proper `minTablesPerVnode`, `tableIncStepPerVnode`, and `maxVgroupsPerDb` according to the number of tables so that tables are distributed even across vgroups. The purpose is to balance the workload among all vnodes so that system resources can be utilized better to get higher performance. For more performance tuning tips, please refer to [Performance Optimization](../../operation/optimize) and [Configuration Parameters](../../reference/config). -- GitLab From 21e1e36d38112fc9654af97d2fa1cd12a6efc2de Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Sat, 23 Jul 2022 18:44:12 +0800 Subject: [PATCH 219/380] fix: adjust cases.task to start test_node.sh to first case because its time is uncertain --- tests/parallel_test/cases.task | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 36c57cdf95..c2c462324e 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -1,4 +1,5 @@ # 20,,pytest,python3 insert/retentionpolicy.py change date time +500,,docs-examples-test,./test_node.sh 299,,pytest,python3 test.py -f update/merge_commit_data-0.py 290,,pytest,python3 test.py -f update/merge_commit_data.py 241,,pytest,python3 test.py -f update/merge_commit_data2.py @@ -593,7 +594,6 @@ 8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py 8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py 8,,pytest,python3 test.py -f update/update2.py -7,,docs-examples-test,./test_node.sh 7,,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonSml-otherPara.py 7,,pytest,python3 test.py -f tools/taosdumpTest2.py 7,,pytest,python3 test.py -f tools/taosdemoTestdatatype.py -- GitLab From f3134e5a122cdba3c66d7f70ebfe1c4c1ae47daf Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sat, 23 Jul 2022 20:13:51 +0800 Subject: [PATCH 220/380] fix(query): sync from 2.6 --- deps/TSZ/sz/src/CompressElement.c | 6 +- deps/TSZ/sz/src/Huffman.c | 12 +- deps/TSZ/sz/src/TightDataPointStorageD.c | 46 +- deps/TSZ/sz/src/TightDataPointStorageF.c | 46 +- deps/cJson/src/cJSON.c | 12 +- deps/lua/src/ldump.c | 2 +- docs/en/01-index.md | 2 +- docs/en/02-intro/index.md | 4 +- .../03-insert-data/05-high-volume.md | 444 +++++ .../07-develop/03-insert-data/highvolume.webp | Bin 0 -> 7308 bytes docs/en/12-taos-sql/02-database.md | 1 - docs/en/14-reference/03-connector/java.mdx | 69 +- docs/en/20-third-party/10-hive-mq-broker.md | 2 +- docs/en/25-application/03-immigrate.md | 4 +- docs/examples/java/pom.xml | 41 + .../com/taos/example/TestTableNotExits.java | 26 + .../example/highvolume/DataBaseMonitor.java | 63 + .../example/highvolume/FastWriteExample.java | 70 + .../example/highvolume/MockDataSource.java | 53 + .../com/taos/example/highvolume/ReadTask.java | 58 + .../taos/example/highvolume/SQLWriter.java | 205 ++ .../taos/example/highvolume/StmtWriter.java | 4 + .../taos/example/highvolume/WriteTask.java | 58 + .../java/src/main/resources/highvolume.drawio | 72 + .../src/main/resources/highvolume2.drawio | 76 + .../java/src/main/resources/logback.xml | 22 + docs/examples/python/fast_write_example.py | 180 ++ .../python/highvolume_faster_queue.py | 205 ++ docs/examples/python/mockdatasource.py | 49 + docs/examples/python/sql_writer.py | 90 + docs/examples/python/stmt_writer.py | 2 + docs/zh/02-intro.md | 2 +- docs/zh/04-concept/index.md | 2 +- .../03-insert-data/05-high-volume.md | 440 ++++ .../07-develop/03-insert-data/highvolume.webp | Bin 0 -> 7308 bytes docs/zh/12-taos-sql/02-database.md | 1 - docs/zh/14-reference/03-connector/java.mdx | 15 +- docs/zh/20-third-party/10-hive-mq-broker.md | 2 +- docs/zh/21-tdinternal/03-taosd.md | 2 +- docs/zh/25-application/03-immigrate.md | 4 +- docs/zh/27-train-faq/01-faq.md | 22 + examples/C#/C#checker/C#checker.cs | 2 +- examples/C#/insertCn/lib/ResultSetUtils.cs | 43 + examples/C#/insertCn/lib/Utils.cs | 418 ++++ examples/C#/jsonTag/JsonTag.cs | 2 +- examples/C#/jsonTag/Util.cs | 4 +- examples/C#/jsonTag/jsonTag.csproj | 4 +- examples/C#/schemaless/schemaless.csproj | 4 +- examples/C#/schemaless/schemalessSample.cs | 2 +- examples/C#/stmt/StmtDemo.cs | 2 +- examples/c/makefile | 1 - packaging/release.sh | 2 + packaging/tools/install_arbi.sh | 9 + src/client/src/tscGlobalmerge.c | 14 +- src/client/src/tscLocal.c | 16 +- src/client/src/tscParseInsert.c | 158 +- src/client/src/tscParseLineProtocol.c | 56 +- src/client/src/tscParseOpenTSDB.c | 44 +- src/client/src/tscPrepare.c | 116 +- src/client/src/tscSQLParser.c | 729 +++---- src/client/src/tscServer.c | 32 +- src/client/src/tscSubquery.c | 80 +- src/client/src/tscSystem.c | 30 +- src/client/src/tscUtil.c | 78 +- src/common/src/tarithoperator.c | 130 +- src/common/src/tdataformat.c | 6 +- src/common/src/tglobal.c | 8 +- src/common/src/tname.c | 16 +- src/common/src/ttypes.c | 16 +- src/dnode/src/dnodeCheck.c | 26 +- src/dnode/src/dnodePeer.c | 48 +- src/dnode/src/dnodeShell.c | 28 +- src/kit/shell/CMakeLists.txt | 2 + src/kit/shell/inc/shellAuto.h | 37 + src/kit/shell/inc/shellCommand.h | 2 + src/kit/shell/inc/tire.h | 92 + src/kit/shell/src/shellAuto.c | 1761 +++++++++++++++++ src/kit/shell/src/shellCommand.c | 17 +- src/kit/shell/src/shellDarwin.c | 11 + src/kit/shell/src/shellEngine.c | 18 +- src/kit/shell/src/shellImport.c | 4 +- src/kit/shell/src/shellLinux.c | 12 + src/kit/shell/src/shellMain.c | 8 + src/kit/shell/src/shellWindows.c | 15 +- src/kit/shell/src/tire.c | 435 ++++ src/kit/taos-tools | 2 +- src/mnode/src/mnodeAcct.c | 2 +- src/mnode/src/mnodeCluster.c | 6 +- src/mnode/src/mnodeMnode.c | 36 +- src/mnode/src/mnodeSdb.c | 24 +- src/os/src/detail/osDir.c | 4 +- src/os/src/detail/osFile.c | 12 +- src/os/src/detail/osTime.c | 62 +- src/os/src/linux/osSystem.c | 4 +- src/plugins/CMakeLists.txt | 2 +- src/plugins/monitor/src/monMain.c | 6 +- src/query/inc/qAggMain.h | 15 +- src/query/inc/qSqlparser.h | 6 +- src/query/src/qAggMain.c | 370 +++- src/query/src/qExecutor.c | 247 ++- src/query/src/qExtbuffer.c | 26 +- src/query/src/qFill.c | 26 +- src/query/src/qFilter.c | 30 +- src/query/src/qHistogram.c | 36 +- src/query/src/qPercentile.c | 62 +- src/query/src/qPlan.c | 6 +- src/query/src/qSqlParser.c | 16 +- src/query/src/qUtil.c | 6 +- src/query/src/queryMain.c | 6 +- src/rpc/src/rpcCache.c | 24 +- src/rpc/src/rpcMain.c | 4 +- src/rpc/src/rpcTcp.c | 16 +- src/rpc/src/rpcUdp.c | 10 +- src/rpc/test/rclient.c | 48 +- src/rpc/test/rsclient.c | 48 +- src/rpc/test/rserver.c | 34 +- src/sync/src/syncMain.c | 110 +- src/sync/src/syncRetrieve.c | 14 +- src/tsdb/src/tsdbCommit.c | 8 +- src/tsdb/src/tsdbFS.c | 8 +- src/tsdb/src/tsdbMain.c | 20 +- src/tsdb/src/tsdbMeta.c | 36 +- src/tsdb/src/tsdbRead.c | 24 +- src/util/inc/tthread.h | 2 +- src/util/src/hash.c | 6 +- src/util/src/tarray.c | 36 +- src/util/src/tcache.c | 8 +- src/util/src/tcompare.c | 4 +- src/util/src/tmempool.c | 12 +- src/util/src/tnettest.c | 30 +- src/util/src/tqueue.c | 3 +- src/util/src/tref.c | 6 +- src/util/src/tthread.c | 2 +- src/vnode/src/vnodeMain.c | 8 +- src/vnode/src/vnodeSync.c | 4 +- src/wal/test/waltest.c | 8 +- tests/develop-test/3-connectors/R/test.sh | 4 +- tests/develop-test/3-connectors/c#/test.sh | 34 +- .../taosbenchmark/insert_alltypes_json.py | 4 +- .../taosbenchmark/limit_offset_json.py | 2 - tests/parallel_test/cases.task | 5 +- tests/pytest/functions/function_max_row.py | 84 + tests/pytest/functions/function_min_row.py | 84 + tests/pytest/query/nestedQuery/nestedQuery.py | 4 +- tests/pytest/query/queryBase.py | 5 + tests/pytest/query/queryError.py | 10 + tests/pytest/table/tagNameCaseSensitive.py | 8 +- .../TD-5213/insertSigcolumnsNum4096.py | 8 +- tests/pytest/tools/taosdumpTest.py | 7 + tests/pytest/tools/taosdumpTest3.py | 3 + tests/script/unique/account/paras.sim | 4 +- .../insert4096columns_not_use_taosdemo.py | 706 ------- .../TD-5213/insertSigcolumnsNum4096.csv | 3 - .../TD-5213/insertSigcolumnsNum4096.json | 137 -- .../TD-5213/insertSigcolumnsNum4096.py | 176 -- tests/tsim/src/simExe.c | 4 +- tests/tsim/src/simParse.c | 10 +- tests/tsim/src/simSystem.c | 4 +- 158 files changed, 7294 insertions(+), 2509 deletions(-) create mode 100644 docs/en/07-develop/03-insert-data/05-high-volume.md create mode 100644 docs/en/07-develop/03-insert-data/highvolume.webp create mode 100644 docs/examples/java/src/main/java/com/taos/example/TestTableNotExits.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/StmtWriter.java create mode 100644 docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java create mode 100644 docs/examples/java/src/main/resources/highvolume.drawio create mode 100644 docs/examples/java/src/main/resources/highvolume2.drawio create mode 100644 docs/examples/java/src/main/resources/logback.xml create mode 100644 docs/examples/python/fast_write_example.py create mode 100644 docs/examples/python/highvolume_faster_queue.py create mode 100644 docs/examples/python/mockdatasource.py create mode 100644 docs/examples/python/sql_writer.py create mode 100644 docs/examples/python/stmt_writer.py create mode 100644 docs/zh/07-develop/03-insert-data/05-high-volume.md create mode 100644 docs/zh/07-develop/03-insert-data/highvolume.webp create mode 100644 examples/C#/insertCn/lib/ResultSetUtils.cs create mode 100644 examples/C#/insertCn/lib/Utils.cs create mode 100644 src/kit/shell/inc/shellAuto.h create mode 100644 src/kit/shell/inc/tire.h create mode 100644 src/kit/shell/src/shellAuto.c create mode 100644 src/kit/shell/src/tire.c create mode 100644 tests/pytest/functions/function_max_row.py create mode 100644 tests/pytest/functions/function_min_row.py delete mode 100644 tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insert4096columns_not_use_taosdemo.py delete mode 100755 tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv delete mode 100755 tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.json delete mode 100755 tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.py diff --git a/deps/TSZ/sz/src/CompressElement.c b/deps/TSZ/sz/src/CompressElement.c index b71ff9638e..a215a3aebc 100644 --- a/deps/TSZ/sz/src/CompressElement.c +++ b/deps/TSZ/sz/src/CompressElement.c @@ -7,7 +7,9 @@ * See COPYRIGHT in top-level directory. */ #ifndef WINDOWS +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push +#endif #pragma GCC diagnostic ignored "-Wchar-subscripts" #endif @@ -233,5 +235,7 @@ INLINE void updateLossyCompElement_Float(unsigned char* diffBytes, unsigned char } #ifndef WINDOWS +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop -#endif \ No newline at end of file +#endif +#endif diff --git a/deps/TSZ/sz/src/Huffman.c b/deps/TSZ/sz/src/Huffman.c index 9868f3c0cb..6db8b15d1f 100644 --- a/deps/TSZ/sz/src/Huffman.c +++ b/deps/TSZ/sz/src/Huffman.c @@ -117,7 +117,7 @@ node qremove(HuffmanTree* huffmanTree) /** * @out1 should be set to 0. * @out2 should be 0 as well. - * @index: the index of the byte + * @idx: the idx of the byte * */ void build_code(HuffmanTree *huffmanTree, node n, int len, unsigned long out1, unsigned long out2) { @@ -136,8 +136,8 @@ void build_code(HuffmanTree *huffmanTree, node n, int len, unsigned long out1, u huffmanTree->cout[n->c] = (unsigned char)len; return; } - int index = len >> 6; //=len/64 - if(index == 0) + int idx = len >> 6; //=len/64 + if(idx == 0) { out1 = out1 << 1; out1 = out1 | 0; @@ -164,13 +164,13 @@ void build_code(HuffmanTree *huffmanTree, node n, int len, unsigned long out1, u * */ void init(HuffmanTree* huffmanTree, int *s, size_t length) { - size_t i, index; + size_t i, idx; size_t *freq = (size_t *)malloc(huffmanTree->allNodes*sizeof(size_t)); memset(freq, 0, huffmanTree->allNodes*sizeof(size_t)); for(i = 0;i < length;i++) { - index = s[i]; - freq[index]++; + idx = s[i]; + freq[idx]++; } for (i = 0; i < huffmanTree->allNodes; i++) diff --git a/deps/TSZ/sz/src/TightDataPointStorageD.c b/deps/TSZ/sz/src/TightDataPointStorageD.c index 469a1bdce9..e1a2af9c04 100644 --- a/deps/TSZ/sz/src/TightDataPointStorageD.c +++ b/deps/TSZ/sz/src/TightDataPointStorageD.c @@ -25,9 +25,9 @@ void new_TightDataPointStorageD_Empty(TightDataPointStorageD **this) int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsigned char* flatBytes, size_t flatBytesLength, sz_exedata* pde_exe, sz_params* pde_params) { new_TightDataPointStorageD_Empty(this); - size_t i, index = 0; - unsigned char version = flatBytes[index++]; //3 - unsigned char sameRByte = flatBytes[index++]; //1 + size_t i, idx = 0; + unsigned char version = flatBytes[idx++]; //3 + unsigned char sameRByte = flatBytes[idx++]; //1 // parse data format switch (version) @@ -46,15 +46,15 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi pde_params->accelerate_pw_rel_compression = (sameRByte & 0x08) >> 3; int errorBoundMode = SZ_ABS; - convertBytesToSZParams(&(flatBytes[index]), pde_params, pde_exe); + convertBytesToSZParams(&(flatBytes[idx]), pde_params, pde_exe); - index += MetaDataByteLength_double; + idx += MetaDataByteLength_double; int isRegression = (sameRByte >> 7) & 0x01; unsigned char dsLengthBytes[8]; for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - dsLengthBytes[i] = flatBytes[index++]; + dsLengthBytes[i] = flatBytes[idx++]; (*this)->dataSeriesLength = bytesToSize(dsLengthBytes, pde_exe->SZ_SIZE_TYPE); if((*this)->isLossless==1) @@ -65,7 +65,7 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi else if(same==1) { (*this)->allSameData = 1; - (*this)->exactMidBytes = &(flatBytes[index]); + (*this)->exactMidBytes = &(flatBytes[idx]); return errorBoundMode; } else @@ -74,42 +74,42 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi if(isRegression == 1) { (*this)->raBytes_size = flatBytesLength - 3 - 1 - MetaDataByteLength_double - pde_exe->SZ_SIZE_TYPE; - (*this)->raBytes = &(flatBytes[index]); + (*this)->raBytes = &(flatBytes[idx]); return errorBoundMode; } unsigned char byteBuf[8]; for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; int max_quant_intervals = bytesToInt_bigEndian(byteBuf);// 4 pde_params->maxRangeRadius = max_quant_intervals/2; for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->intervals = bytesToInt_bigEndian(byteBuf);// 4 for (i = 0; i < 8; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->medianValue = bytesToDouble(byteBuf);//8 - (*this)->reqLength = flatBytes[index++]; //1 + (*this)->reqLength = flatBytes[idx++]; //1 for (i = 0; i < 8; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->realPrecision = bytesToDouble(byteBuf);//8 for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->typeArray_size = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE); for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->exactDataNum = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// ST for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->exactMidBytes_size = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// ST size_t logicLeadNumBitsNum = (*this)->exactDataNum * 2; @@ -122,12 +122,12 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi (*this)->leadNumArray_size = (logicLeadNumBitsNum >> 3) + 1; } - (*this)->typeArray = &flatBytes[index]; + (*this)->typeArray = &flatBytes[idx]; //retrieve the number of states (i.e., stateNum) (*this)->allNodes = bytesToInt_bigEndian((*this)->typeArray); //the first 4 bytes store the stateNum (*this)->stateNum = ((*this)->allNodes+1)/2; - index+=(*this)->typeArray_size; + idx+=(*this)->typeArray_size; // todo need check length @@ -135,15 +135,15 @@ int new_TightDataPointStorageD_fromFlatBytes(TightDataPointStorageD **this, unsi - pde_exe->SZ_SIZE_TYPE - pde_exe->SZ_SIZE_TYPE - pde_exe->SZ_SIZE_TYPE - (*this)->leadNumArray_size - (*this)->exactMidBytes_size - (*this)->typeArray_size; - (*this)->leadNumArray = &flatBytes[index]; + (*this)->leadNumArray = &flatBytes[idx]; - index+=(*this)->leadNumArray_size; + idx+=(*this)->leadNumArray_size; - (*this)->exactMidBytes = &flatBytes[index]; + (*this)->exactMidBytes = &flatBytes[idx]; - index+=(*this)->exactMidBytes_size; + idx+=(*this)->exactMidBytes_size; - (*this)->residualMidBits = &flatBytes[index]; + (*this)->residualMidBits = &flatBytes[idx]; return errorBoundMode; diff --git a/deps/TSZ/sz/src/TightDataPointStorageF.c b/deps/TSZ/sz/src/TightDataPointStorageF.c index cb1d79b827..16d524b9b4 100644 --- a/deps/TSZ/sz/src/TightDataPointStorageF.c +++ b/deps/TSZ/sz/src/TightDataPointStorageF.c @@ -25,15 +25,15 @@ void new_TightDataPointStorageF_Empty(TightDataPointStorageF **this) int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsigned char* flatBytes, size_t flatBytesLength, sz_exedata* pde_exe, sz_params* pde_params) { new_TightDataPointStorageF_Empty(this); - size_t i, index = 0; + size_t i, idx = 0; // // parse tdps // // 1 version(1) - unsigned char version = flatBytes[index++]; //1 - unsigned char sameRByte = flatBytes[index++]; //1 + unsigned char version = flatBytes[idx++]; //1 + unsigned char sameRByte = flatBytes[idx++]; //1 // parse data format switch (version) @@ -51,12 +51,12 @@ int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsi pde_exe->SZ_SIZE_TYPE = ((sameRByte & 0x40)>>6)==1?8:4; //0100,0000 int errorBoundMode = SZ_ABS; // 3 meta(2) - convertBytesToSZParams(&(flatBytes[index]), pde_params, pde_exe); - index += MetaDataByteLength; + convertBytesToSZParams(&(flatBytes[idx]), pde_params, pde_exe); + idx += MetaDataByteLength; // 4 element count(4) unsigned char dsLengthBytes[8]; for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - dsLengthBytes[i] = flatBytes[index++]; + dsLengthBytes[i] = flatBytes[idx++]; (*this)->dataSeriesLength = bytesToSize(dsLengthBytes, pde_exe->SZ_SIZE_TYPE);// 4 or 8 if((*this)->isLossless==1) { @@ -66,7 +66,7 @@ int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsi else if(same==1) { (*this)->allSameData = 1; - (*this)->exactMidBytes = &(flatBytes[index]); + (*this)->exactMidBytes = &(flatBytes[idx]); return errorBoundMode; } else @@ -76,40 +76,40 @@ int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsi if(isRegression == 1) { (*this)->raBytes_size = flatBytesLength - 1 - 1 - MetaDataByteLength - pde_exe->SZ_SIZE_TYPE; - (*this)->raBytes = &(flatBytes[index]); + (*this)->raBytes = &(flatBytes[idx]); return errorBoundMode; } // 5 quant intervals(4) unsigned char byteBuf[8]; for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; int max_quant_intervals = bytesToInt_bigEndian(byteBuf);// 4 pde_params->maxRangeRadius = max_quant_intervals/2; // 6 intervals for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->intervals = bytesToInt_bigEndian(byteBuf);// 4 // 7 median for (i = 0; i < 4; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->medianValue = bytesToFloat(byteBuf); //4 // 8 reqLength - (*this)->reqLength = flatBytes[index++]; //1 + (*this)->reqLength = flatBytes[idx++]; //1 // 9 realPrecision(8) for (i = 0; i < 8; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->realPrecision = bytesToDouble(byteBuf);//8 // 10 typeArray_size for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->typeArray_size = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// 4 // 11 exactNum for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->exactDataNum = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// ST // 12 mid size for (i = 0; i < pde_exe->SZ_SIZE_TYPE; i++) - byteBuf[i] = flatBytes[index++]; + byteBuf[i] = flatBytes[idx++]; (*this)->exactMidBytes_size = bytesToSize(byteBuf, pde_exe->SZ_SIZE_TYPE);// STqq // calc leadNumArray_size @@ -124,20 +124,20 @@ int new_TightDataPointStorageF_fromFlatBytes(TightDataPointStorageF **this, unsi } // 13 typeArray - (*this)->typeArray = &flatBytes[index]; + (*this)->typeArray = &flatBytes[idx]; //retrieve the number of states (i.e., stateNum) (*this)->allNodes = bytesToInt_bigEndian((*this)->typeArray); //the first 4 bytes store the stateNum (*this)->stateNum = ((*this)->allNodes+1)/2; - index+=(*this)->typeArray_size; + idx+=(*this)->typeArray_size; // 14 leadNumArray - (*this)->leadNumArray = &flatBytes[index]; - index += (*this)->leadNumArray_size; + (*this)->leadNumArray = &flatBytes[idx]; + idx += (*this)->leadNumArray_size; // 15 exactMidBytes - (*this)->exactMidBytes = &flatBytes[index]; - index+=(*this)->exactMidBytes_size; + (*this)->exactMidBytes = &flatBytes[idx]; + idx+=(*this)->exactMidBytes_size; // 16 residualMidBits - (*this)->residualMidBits = &flatBytes[index]; + (*this)->residualMidBits = &flatBytes[idx]; // calc residualMidBits_size (*this)->residualMidBits_size = flatBytesLength - 1 - 1 - MetaDataByteLength - pde_exe->SZ_SIZE_TYPE - 4 - 4 - 4 - 1 - 8 diff --git a/deps/cJson/src/cJSON.c b/deps/cJson/src/cJSON.c index ff93e8730d..53698b5baf 100644 --- a/deps/cJson/src/cJSON.c +++ b/deps/cJson/src/cJSON.c @@ -1683,7 +1683,7 @@ CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) return (int)size; } -static cJSON* get_array_item(const cJSON *array, size_t index) +static cJSON* get_array_item(const cJSON *array, size_t idx) { cJSON *current_child = NULL; @@ -1693,23 +1693,23 @@ static cJSON* get_array_item(const cJSON *array, size_t index) } current_child = array->child; - while ((current_child != NULL) && (index > 0)) + while ((current_child != NULL) && (idx > 0)) { - index--; + idx--; current_child = current_child->next; } return current_child; } -CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int idx) { - if (index < 0) + if (idx < 0) { return NULL; } - return get_array_item(array, (size_t)index); + return get_array_item(array, (size_t)idx); } static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) diff --git a/deps/lua/src/ldump.c b/deps/lua/src/ldump.c index f08277d3ac..4b20591488 100644 --- a/deps/lua/src/ldump.c +++ b/deps/lua/src/ldump.c @@ -60,7 +60,7 @@ static void DumpVector(const void* b, int n, size_t size, DumpState* D) static void DumpString(const TString* s, DumpState* D) { - if (s==NULL || getstr(s)==NULL) + if (s==NULL) { size_t size=0; DumpVar(size,D); diff --git a/docs/en/01-index.md b/docs/en/01-index.md index d76c12e10f..1f2f88d47d 100644 --- a/docs/en/01-index.md +++ b/docs/en/01-index.md @@ -6,7 +6,7 @@ slug: / TDengine is a [high-performance](https://tdengine.com/fast), [scalable](https://tdengine.com/scalable) time series database with [SQL support](https://tdengine.com/sql-support). This document is the TDengine user manual. It introduces the basic, as well as novel concepts, in TDengine, and also talks in detail about installation, features, SQL, APIs, operation, maintenance, kernel design and other topics. It’s written mainly for architects, developers and system administrators. -To get a global view about TDengine, like feature list, benchmarks, and competitive advantages, please browse through section [Introduction](./intro). +To get a global view about TDengine, like feature list, benchmarks, and competitive advantages, please browse through section [Introduction](./intro). If you want to get some basics about time-series databases, please check [here](https://tdengine.com/tsdb). TDengine greatly improves the efficiency of data ingestion, querying and storage by exploiting the characteristics of time series data, introducing the novel concepts of "one table for one data collection point" and "super table", and designing an innovative storage engine. To understand the new concepts in TDengine and make full use of the features and capabilities of TDengine, please read [“Concepts”](./concept) thoroughly. diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index 52b25bf949..23cf1203b2 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -110,4 +110,6 @@ As a high-performance, scalable and SQL supported time-series database, TDengine - [TDengine vs InfluxDB、OpenTSDB、Cassandra、MySQL、ClickHouse](https://www.tdengine.com/downloads/TDengine_Testing_Report_en.pdf) - [TDengine vs OpenTSDB](https://tdengine.com/2019/09/12/710.html) - [TDengine vs Cassandra](https://tdengine.com/2019/09/12/708.html) -- [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html) \ No newline at end of file +- [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html) + +If you want to learn some basics about time-series databases, please check [here](https://tdengine.com/tsdb). diff --git a/docs/en/07-develop/03-insert-data/05-high-volume.md b/docs/en/07-develop/03-insert-data/05-high-volume.md new file mode 100644 index 0000000000..fc4f071997 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/05-high-volume.md @@ -0,0 +1,444 @@ +--- +sidebar_label: High Performance Writing +title: High Performance Writing +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +This chapter introduces how to write data into TDengine with high throughput. + +## How to achieve high performance data writing + +To achieve high performance writing, there are a few aspects to consider. In the following sections we will describe these important factors in achieving high performance writing. + +### Application Program + +From the perspective of application program, you need to consider: + +1. The data size of each single write, also known as batch size. Generally speaking, higher batch size generates better writing performance. However, once the batch size is over a specific value, you will not get any additional benefit anymore. When using SQL to write into TDengine, it's better to put as much as possible data in single SQL. The maximum SQL length supported by TDengine is 1,048,576 bytes, i.e. 1 MB. It can be configured by parameter `maxSQLLength` on client side, and the default value is 65,480. + +2. The number of concurrent connections. Normally more connections can get better result. However, once the number of connections exceeds the processing ability of the server side, the performance may downgrade. + +3. The distribution of data to be written across tables or sub-tables. Writing to single table in one batch is more efficient than writing to multiple tables in one batch. + +4. Data Writing Protocol. + - Prameter binding mode is more efficient than SQL because it doesn't have the cost of parsing SQL. + - Writing to known existing tables is more efficient than wirting to uncertain tables in automatic creating mode because the later needs to check whether the table exists or not before actually writing data into it + - Writing in SQL is more efficient than writing in schemaless mode because schemaless writing creats table automatically and may alter table schema + +Application programs need to take care of the above factors and try to take advantage of them. The application progam should write to single table in each write batch. The batch size needs to be tuned to a proper value on a specific system. The number of concurrent connections needs to be tuned to a proper value too to achieve the best writing throughput. + +### Data Source + +Application programs need to read data from data source then write into TDengine. If you meet one or more of below situations, you need to setup message queues between the threads for reading from data source and the threads for writing into TDengine. + +1. There are multiple data sources, the data generation speed of each data source is much slower than the speed of single writing thread. In this case, the purpose of message queues is to consolidate the data from multiple data sources together to increase the batch size of single write. +2. The speed of data generation from single data source is much higher than the speed of single writing thread. The purpose of message queue in this case is to provide buffer so that data is not lost and multiple writing threads can get data from the buffer. +3. The data for single table are from multiple data source. In this case the purpose of message queues is to combine the data for single table together to improve the write efficiency. + +If the data source is Kafka, then the appication program is a consumer of Kafka, you can benefit from some kafka features to achieve high performance writing: + +1. Put the data for a table in single partition of single topic so that it's easier to put the data for each table together and write in batch +2. Subscribe multiple topics to accumulate data together. +3. Add more consumers to gain more concurrency and throughput. +4. Incrase the size of single fetch to increase the size of write batch. + +### Tune TDengine + +TDengine is a distributed and high performance time series database, there are also some ways to tune TDengine to get better writing performance. + +1. Set proper number of `vgroups` according to available CPU cores. Normally, we recommend 2 \* number_of_cores as a starting point. If the verification result shows this is not enough to utilize CPU resources, you can use a higher value. +2. Set proper `minTablesPerVnode`, `tableIncStepPerVnode`, and `maxVgroupsPerDb` according to the number of tables so that tables are distributed even across vgroups. The purpose is to balance the workload among all vnodes so that system resources can be utilized better to get higher performance. + +For more performance tuning tips, please refer to [Performance Optimization](../../operation/optimize) and [Configuration Parameters](../../reference/config). + +## Sample Programs + +This section will introduce the sample programs to demonstrate how to write into TDengine with high performance. + +### Scenario + +Below are the scenario for the sample programs of high performance wrting. + +- Application program reads data from data source, the sample program simulates a data source by generating data +- The speed of single writing thread is much slower than the speed of generating data, so the program starts multiple writing threads while each thread establish a connection to TDengine and each thread has a message queue of fixed size. +- Application program maps the received data to different writing threads based on table name to make sure all the data for each table is always processed by a specific writing thread. +- Each writing thread writes the received data into TDengine once the message queue becomes empty or the read data meets a threshold. + +![Thread Model of High Performance Writing into TDengine](highvolume.webp) + +### Sample Programs + +The sample programs listed in this section are based on the scenario described previously. If your scenarios is different, please try to adjust the code based on the principles described in this chapter. + +The sample programs assume the source data is for all the different sub tables in same super table (meters). The super table has been created before the sample program starts to writing data. Sub tables are created automatically according to received data. If there are multiple super tables in your case, please try to adjust the part of creating table automatically. + + + + +**Program Inventory** + +| Class | Description | +| ---------------- | ----------------------------------------------------------------------------------------------------- | +| FastWriteExample | Main Program | +| ReadTask | Read data from simulated data source and put into a queue according to the hash value of table name | +| WriteTask | Read data from Queue, compose a wirte batch and write into TDengine | +| MockDataSource | Generate data for some sub tables of super table meters | +| SQLWriter | WriteTask uses this class to compose SQL, create table automatically, check SQL length and write data | +| StmtWriter | Write in Parameter binding mode (Not finished yet) | +| DataBaseMonitor | Calculate the writing speed and output on console every 10 seconds | + +Below is the list of complete code of the classes in above table and more detailed description. + +
+FastWriteExample +The main Program is responsible for: + +1. Create message queues +2. Start writing threads +3. Start reading threads +4. Otuput writing speed every 10 seconds + +The main program provides 4 parameters for tuning: + +1. The number of reading threads, default value is 1 +2. The number of writing threads, default alue is 2 +3. The total number of tables in the generated data, default value is 1000. These tables are distributed evenly across all writing threads. If the number of tables is very big, it will cost much time to firstly create these tables. +4. The batch size of single write, default value is 3,000 + +The capacity of message queue also impacts performance and can be tuned by modifying program. Normally it's always better to have a larger message queue. A larger message queue means lower possibility of being blocked when enqueueing and higher throughput. But a larger message queue consumes more memory space. The default value used in the sample programs is already big enoug. + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java}} +``` + +
+ +
+ReadTask + +ReadTask reads data from data source. Each ReadTask is associated with a simulated data source, each data source generates data for a group of specific tables, and the data of any table is only generated from a single specific data source. + +ReadTask puts data in message queue in blocking mode. That means, the putting operation is blocked if the message queue is full. + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java}} +``` + +
+ +
+WriteTask + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java}} +``` + +
+ +
+ +MockDataSource + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java}} +``` + +
+ +
+ +SQLWriter + +SQLWriter class encapsulates the logic of composing SQL and writing data. Please be noted that the tables have not been created before writing, but are created automatically when catching the exception of table doesn't exist. For other exceptions caught, the SQL which caused the exception are logged for you to debug. + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java}} +``` + +
+ +
+ +DataBaseMonitor + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java}} +``` + +
+ +**Steps to Launch** + +
+Launch Java Sample Program + +You need to set environment variable `TDENGINE_JDBC_URL` before launching the program. If TDengine Server is setup on localhost, then the default value for user name, password and port can be used, like below: + +``` +TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" +``` + +**Launch in IDE** + +1. Clone TDengine repolitory + ``` + git clone git@github.com:taosdata/TDengine.git --depth 1 + ``` +2. Use IDE to open `docs/examples/java` directory +3. Configure environment variable `TDENGINE_JDBC_URL`, you can also configure it before launching the IDE, if so you can skip this step. +4. Run class `com.taos.example.highvolume.FastWriteExample` + +**Launch on server** + +If you want to launch the sample program on a remote server, please follow below steps: + +1. Package the sample programs. Execute below command under directory `TDengine/docs/examples/java` : + ``` + mvn package + ``` +2. Create `examples/java` directory on the server + ``` + mkdir -p examples/java + ``` +3. Copy dependencies (below commands assume you are working on a local Windows host and try to launch on a remote Linux host) + - Copy dependent packages + ``` + scp -r .\target\lib @:~/examples/java + ``` + - Copy the jar of sample programs + ``` + scp -r .\target\javaexample-1.0.jar @:~/examples/java + ``` +4. Configure environment variable + Edit `~/.bash_profile` or `~/.bashrc` and add below: + + ``` + export TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" + ``` + + If your TDengine server is not deployed on localhost or doesn't use default port, you need to change the above URL to correct value in your environment. + +5. Launch the sample program + + ``` + java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample + ``` + +6. The sample program doesn't exit unless you press CTRL + C to terminate it. + Below is the output of running on a server of 16 cores, 64GB memory and SSD hard disk. + + ``` + root@vm85$ java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample 2 12 + 18:56:35.896 [main] INFO c.t.e.highvolume.FastWriteExample - readTaskCount=2, writeTaskCount=12 tableCount=1000 maxBatchSize=3000 + 18:56:36.011 [WriteThread-0] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.015 [WriteThread-0] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.021 [WriteThread-1] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.022 [WriteThread-1] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.031 [WriteThread-2] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.032 [WriteThread-2] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.041 [WriteThread-3] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.042 [WriteThread-3] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.093 [WriteThread-4] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.094 [WriteThread-4] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.099 [WriteThread-5] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.100 [WriteThread-5] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.100 [WriteThread-6] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.101 [WriteThread-6] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.103 [WriteThread-7] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.104 [WriteThread-7] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.105 [WriteThread-8] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.107 [WriteThread-8] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.108 [WriteThread-9] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.109 [WriteThread-9] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.156 [WriteThread-10] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.157 [WriteThread-11] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.158 [WriteThread-10] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.158 [ReadThread-0] INFO com.taos.example.highvolume.ReadTask - started + 18:56:36.158 [ReadThread-1] INFO com.taos.example.highvolume.ReadTask - started + 18:56:36.158 [WriteThread-11] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:46.369 [main] INFO c.t.e.highvolume.FastWriteExample - count=18554448 speed=1855444 + 18:56:56.946 [main] INFO c.t.e.highvolume.FastWriteExample - count=39059660 speed=2050521 + 18:57:07.322 [main] INFO c.t.e.highvolume.FastWriteExample - count=59403604 speed=2034394 + 18:57:18.032 [main] INFO c.t.e.highvolume.FastWriteExample - count=80262938 speed=2085933 + 18:57:28.432 [main] INFO c.t.e.highvolume.FastWriteExample - count=101139906 speed=2087696 + 18:57:38.921 [main] INFO c.t.e.highvolume.FastWriteExample - count=121807202 speed=2066729 + 18:57:49.375 [main] INFO c.t.e.highvolume.FastWriteExample - count=142952417 speed=2114521 + 18:58:00.689 [main] INFO c.t.e.highvolume.FastWriteExample - count=163650306 speed=2069788 + 18:58:11.646 [main] INFO c.t.e.highvolume.FastWriteExample - count=185019808 speed=2136950 + ``` + +
+ +
+ + +**Program Inventory** + +Sample programs in Python uses multi-process and cross-process message queues. + +| Function/CLass | Description | +| ---------------------------- | --------------------------------------------------------------------------- | +| main Function | Program entry point, create child processes and message queues | +| run_monitor_process Function | Create database, super table, calculate writing speed and output to console | +| run_read_task Function | Read data and distribute to message queues | +| MockDataSource Class | Simulate data source, return next 1,000 rows of each table | +| run_write_task Function | Read as much as possible data from message queue and write in batch | +| SQLWriter Class | Write in SQL and create table utomatically | +| StmtWriter Class | Write in parameter binding mode (not finished yet) | + +
+main function + +`main` function is responsible for creating message queues and fork child processes, there are 3 kinds of child processes: + +1. Monitoring process, initializes database and calculating writing speed +2. Reading process (n), reads data from data source +3. Writing process (m), wirtes data into TDengine + +`main` function provides 5 parameters: + +1. The number of reading tasks, default value is 1 +2. The number of writing tasks, default value is 1 +3. The number of tables, default value is 1,000 +4. The capacity of message queue, default value is 1,000,000 bytes +5. The batch size in single write, default value is 3000 + +```python +{{#include docs/examples/python/fast_write_example.py:main}} +``` + +
+ +
+run_monitor_process + +Monitoring process initilizes database and monitoring writing speed. + +```python +{{#include docs/examples/python/fast_write_example.py:monitor}} +``` + +
+ +
+ +run_read_task function + +Reading process reads data from other data system and distributes to the message queue allocated for it. + +```python +{{#include docs/examples/python/fast_write_example.py:read}} +``` + +
+ +
+ +MockDataSource + +Below is the simulated data source, we assume table name exists in each generated data. + +```python +{{#include docs/examples/python/mockdatasource.py}} +``` + +
+ +
+run_write_task function + +Writing process tries to read as much as possible data from message queue and writes in batch. + +```python +{{#include docs/examples/python/fast_write_example.py:write}} +``` + +
+ +
+ +SQLWriter class encapsulates the logic of composing SQL and writing data. Please be noted that the tables have not been created before writing, but are created automatically when catching the exception of table doesn't exist. For other exceptions caught, the SQL which caused the exception are logged for you to debug. This class also checks the SQL length, if the SQL length is closed to `maxSQLLength` the SQL will be executed immediately. To improve writing efficiency, it's better to increase `maxSQLLength` properly. + +SQLWriter + +```python +{{#include docs/examples/python/sql_writer.py}} +``` + +
+ +**Steps to Launch** + +
+ +Launch Sample Program in Python + +1. Prerequisities + + - TDengine client driver has been installed + - Python3 has been installed, the the version >= 3.8 + - TDengine Python connector `taospy` has been installed + +2. Install faster-fifo to replace python builtin multiprocessing.Queue + + ``` + pip3 install faster-fifo + ``` + +3. Click the "Copy" in the above sample programs to copy `fast_write_example.py` 、 `sql_writer.py` and `mockdatasource.py`. + +4. Execute the program + + ``` + python3 fast_write_example.py + ``` + + Below is the output of running on a server of 16 cores, 64GB memory and SSD hard disk. + + ``` + root@vm85$ python3 fast_write_example.py 8 8 + 2022-07-14 19:13:45,869 [root] - READ_TASK_COUNT=8, WRITE_TASK_COUNT=8, TABLE_COUNT=1000, QUEUE_SIZE=1000000, MAX_BATCH_SIZE=3000 + 2022-07-14 19:13:48,882 [root] - WriteTask-0 started with pid 718347 + 2022-07-14 19:13:48,883 [root] - WriteTask-1 started with pid 718348 + 2022-07-14 19:13:48,884 [root] - WriteTask-2 started with pid 718349 + 2022-07-14 19:13:48,884 [root] - WriteTask-3 started with pid 718350 + 2022-07-14 19:13:48,885 [root] - WriteTask-4 started with pid 718351 + 2022-07-14 19:13:48,885 [root] - WriteTask-5 started with pid 718352 + 2022-07-14 19:13:48,886 [root] - WriteTask-6 started with pid 718353 + 2022-07-14 19:13:48,886 [root] - WriteTask-7 started with pid 718354 + 2022-07-14 19:13:48,887 [root] - ReadTask-0 started with pid 718355 + 2022-07-14 19:13:48,888 [root] - ReadTask-1 started with pid 718356 + 2022-07-14 19:13:48,889 [root] - ReadTask-2 started with pid 718357 + 2022-07-14 19:13:48,889 [root] - ReadTask-3 started with pid 718358 + 2022-07-14 19:13:48,890 [root] - ReadTask-4 started with pid 718359 + 2022-07-14 19:13:48,891 [root] - ReadTask-5 started with pid 718361 + 2022-07-14 19:13:48,892 [root] - ReadTask-6 started with pid 718364 + 2022-07-14 19:13:48,893 [root] - ReadTask-7 started with pid 718365 + 2022-07-14 19:13:56,042 [DataBaseMonitor] - count=6676310 speed=667631.0 + 2022-07-14 19:14:06,196 [DataBaseMonitor] - count=20004310 speed=1332800.0 + 2022-07-14 19:14:16,366 [DataBaseMonitor] - count=32290310 speed=1228600.0 + 2022-07-14 19:14:26,527 [DataBaseMonitor] - count=44438310 speed=1214800.0 + 2022-07-14 19:14:36,673 [DataBaseMonitor] - count=56608310 speed=1217000.0 + 2022-07-14 19:14:46,834 [DataBaseMonitor] - count=68757310 speed=1214900.0 + 2022-07-14 19:14:57,280 [DataBaseMonitor] - count=80992310 speed=1223500.0 + 2022-07-14 19:15:07,689 [DataBaseMonitor] - count=93805310 speed=1281300.0 + 2022-07-14 19:15:18,020 [DataBaseMonitor] - count=106111310 speed=1230600.0 + 2022-07-14 19:15:28,356 [DataBaseMonitor] - count=118394310 speed=1228300.0 + 2022-07-14 19:15:38,690 [DataBaseMonitor] - count=130742310 speed=1234800.0 + 2022-07-14 19:15:49,000 [DataBaseMonitor] - count=143051310 speed=1230900.0 + 2022-07-14 19:15:59,323 [DataBaseMonitor] - count=155276310 speed=1222500.0 + 2022-07-14 19:16:09,649 [DataBaseMonitor] - count=167603310 speed=1232700.0 + 2022-07-14 19:16:19,995 [DataBaseMonitor] - count=179976310 speed=1237300.0 + ``` + +
+ +:::note +Don't establish connection to TDengine in the parent process if using Python connector in multi-process way, otherwise all the connections in child processes are blocked always. This is a known issue. + +::: + +
+
diff --git a/docs/en/07-develop/03-insert-data/highvolume.webp b/docs/en/07-develop/03-insert-data/highvolume.webp new file mode 100644 index 0000000000000000000000000000000000000000..46dfc74ae3b0043c591ff930c62251da49cae7ad GIT binary patch literal 7308 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 literal 0 HcmV?d00001 diff --git a/docs/en/12-taos-sql/02-database.md b/docs/en/12-taos-sql/02-database.md index 80581b2f1b..c2961d6241 100644 --- a/docs/en/12-taos-sql/02-database.md +++ b/docs/en/12-taos-sql/02-database.md @@ -32,7 +32,6 @@ CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1]; - cacheLast: [Description](/reference/config/#cachelast) - replica: [Description](/reference/config/#replica) - quorum: [Description](/reference/config/#quorum) - - maxVgroupsPerDb: [Description](/reference/config/#maxvgroupsperdb) - comp: [Description](/reference/config/#comp) - precision: [Description](/reference/config/#precision) 6. Please note that all of the parameters mentioned in this section are configured in configuration file `taos.cfg` on the TDengine server. If not specified in the `create database` statement, the values from taos.cfg are used by default. To override default parameters, they must be specified in the `create database` statement. diff --git a/docs/en/14-reference/03-connector/java.mdx b/docs/en/14-reference/03-connector/java.mdx index ff15acf1a9..22f99bb9ae 100644 --- a/docs/en/14-reference/03-connector/java.mdx +++ b/docs/en/14-reference/03-connector/java.mdx @@ -91,7 +91,7 @@ Add following dependency in the `pom.xml` file of your Maven project: You can build Java connector from source code after cloning the TDengine project: ``` -git clone https://github.com/taosdata/taos-connector-jdbc.git +git clone https://github.com/taosdata/taos-connector-jdbc.git --branch 2.0 cd taos-connector-jdbc mvn clean install -Dmaven.test.skip=true ``` @@ -140,34 +140,34 @@ When you use a JDBC native connection to connect to a TDengine cluster, you can 1. Do not specify hostname and port in Java applications. - ```java - public Connection getConn() throws Exception{ - Class.forName("com.taosdata.jdbc.TSDBDriver"); - String jdbcUrl = "jdbc:TAOS://:/test?user=root&password=taosdata"; - Properties connProps = new Properties(); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); - Connection conn = DriverManager.getConnection(jdbcUrl, connProps); - return conn; - } - ``` + ```java + public Connection getConn() throws Exception{ + Class.forName("com.taosdata.jdbc.TSDBDriver"); + String jdbcUrl = "jdbc:TAOS://:/test?user=root&password=taosdata"; + Properties connProps = new Properties(); + connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + Connection conn = DriverManager.getConnection(jdbcUrl, connProps); + return conn; + } + ``` 2. specify the firstEp and the secondEp in the configuration file taos.cfg - ```shell - # first fully qualified domain name (FQDN) for TDengine system - firstEp cluster_node1:6030 + ```shell + # first fully qualified domain name (FQDN) for TDengine system + firstEp cluster_node1:6030 - # second fully qualified domain name (FQDN) for TDengine system, for cluster only - secondEp cluster_node2:6030 + # second fully qualified domain name (FQDN) for TDengine system, for cluster only + secondEp cluster_node2:6030 - # default system charset - # charset UTF-8 + # default system charset + # charset UTF-8 - # system locale - # locale en_US.UTF-8 - ``` + # system locale + # locale en_US.UTF-8 + ``` In the above example, JDBC uses the client's configuration file to establish a connection to a hostname `cluster_node1`, port 6030, and a database named `test`. When the firstEp node in the cluster fails, JDBC attempts to connect to the cluster using secondEp. @@ -202,6 +202,10 @@ The configuration parameters in the URL are as follows. - batchfetch: true: pull the result set in batch when executing the query; false: pull the result set row by row. The default value is false. batchfetch uses HTTP for data transfer. The JDBC REST connection supports bulk data pulling function in taos-jdbcdriver-2.0.38 and TDengine 2.4.0.12 and later versions. taos-jdbcdriver and TDengine transfer data via WebSocket connection. Compared with HTTP, WebSocket enables JDBC REST connection to support large data volume querying and improve query performance. - charset: specify the charset to parse the string, this parameter is valid only when set batchfetch to true. - batchErrorIgnore: true: when executing executeBatch of Statement, if one SQL execution fails in the middle, continue to execute the following SQL. false: no longer execute any statement after the failed SQL. The default value is: false. +- httpConnectTimeout: REST connection timeout in milliseconds, the default value is 5000 ms. +- httpSocketTimeout: socket timeout in milliseconds, the default value is 5000 ms. It only takes effect when batchfetch is false. +- messageWaitTimeout: message transmission timeout in milliseconds, the default value is 3000 ms. It only takes effect when batchfetch is true. +- useSSL: connecting Securely Using SSL. true: using SSL conneciton, false: not using SSL connection. **Note**: Some configuration items (e.g., locale, timezone) do not work in the REST connection. @@ -257,14 +261,18 @@ In the above example, a connection is established to `taosdemo.com`, port is 603 The configuration parameters in properties are as follows. -- TSDBDriver.PROPERTY_KEY_USER: Login TDengine user name, default value 'root'. +- TSDBDriver.PROPERTY_KEY_USER: login TDengine user name, default value 'root'. - TSDBDriver.PROPERTY_KEY_PASSWORD: user login password, default value 'taosdata'. - TSDBDriver.PROPERTY_KEY_BATCH_LOAD: true: pull the result set in batch when executing query; false: pull the result set row by row. The default value is: false. - TSDBDriver.PROPERTY_KEY_BATCH_ERROR_IGNORE: true: when executing executeBatch of Statement, if there is a SQL execution failure in the middle, continue to execute the following sq. false: no longer execute any statement after the failed SQL. The default value is: false. -- TSDBDriver.PROPERTY_KEY_CONFIG_DIR: Only works when using JDBC native connection. Client configuration file directory path, default value `/etc/taos` on Linux OS, default value `C:/TDengine/cfg` on Windows OS. +- TSDBDriver.PROPERTY_KEY_CONFIG_DIR: only works when using JDBC native connection. Client configuration file directory path, default value `/etc/taos` on Linux OS, default value `C:/TDengine/cfg` on Windows OS. - TSDBDriver.PROPERTY_KEY_CHARSET: In the character set used by the client, the default value is the system character set. - TSDBDriver.PROPERTY_KEY_LOCALE: this only takes effect when using JDBC native connection. Client language environment, the default value is system current locale. - TSDBDriver.PROPERTY_KEY_TIME_ZONE: only takes effect when using JDBC native connection. In the time zone used by the client, the default value is the system's current time zone. +- TSDBDriver.HTTP_CONNECT_TIMEOUT: REST connection timeout in milliseconds, the default value is 5000 ms. It only takes effect when using JDBC REST connection. +- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket timeout in milliseconds, the default value is 5000 ms. It only takes effect when using JDBC REST connection and batchfetch is false. +- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: message transmission timeout in milliseconds, the default value is 3000 ms. It only takes effect when using JDBC REST connection and batchfetch is true. +- TSDBDriver.PROPERTY_KEY_USE_SSL: connecting Securely Using SSL. true: using SSL conneciton, false: not using SSL connection. It only takes effect when using using JDBC REST connection. For JDBC native connections, you can specify other parameters, such as log level, SQL length, etc., by specifying URL and Properties. For more detailed configuration, please refer to [Client Configuration](/reference/config/#Client-Only). ### Priority of configuration parameters @@ -812,11 +820,12 @@ Please refer to: [JDBC example](https://github.com/taosdata/TDengine/tree/develo ## Recent update logs -| taos-jdbcdriver version | major changes | -| :---------------------: | :------------------------------------------: | -| 2.0.38 | JDBC REST connections add bulk pull function | -| 2.0.37 | Added support for json tags | -| 2.0.36 | Add support for schemaless writing | +| taos-jdbcdriver version | major changes | +| :---------------------: | :--------------------------------------------: | +| 2.0.39 - 2.0.40 | Add REST connection/request timeout parameters | +| 2.0.38 | JDBC REST connections add bulk pull function | +| 2.0.37 | Support json tags | +| 2.0.36 | Support schemaless writing | ## Frequently Asked Questions diff --git a/docs/en/20-third-party/10-hive-mq-broker.md b/docs/en/20-third-party/10-hive-mq-broker.md index 333e00fa0e..64404bd63f 100644 --- a/docs/en/20-third-party/10-hive-mq-broker.md +++ b/docs/en/20-third-party/10-hive-mq-broker.md @@ -3,4 +3,4 @@ sidebar_label: HiveMQ Broker title: HiveMQ Broker writing --- -[HiveMQ](https://www.hivemq.com/) is an MQTT broker that provides community and enterprise editions. HiveMQ is mainly for enterprise emerging machine-to-machine M2M communication and internal transport, meeting scalability, ease of management, and security features. HiveMQ provides an open-source plug-in development kit. MQTT data can be saved to TDengine via TDengine extension for HiveMQ. Please refer to the [HiveMQ extension - TDengine documentation](https://github.com/huskar-t/hivemq-tdengine-extension/blob/b62a26ecc164a310104df57691691b237e091c89/README_EN.md) for details on how to use it. \ No newline at end of file +[HiveMQ](https://www.hivemq.com/) is an MQTT broker that provides community and enterprise editions. HiveMQ is mainly for enterprise emerging machine-to-machine M2M communication and internal transport, meeting scalability, ease of management, and security features. HiveMQ provides an open-source plug-in development kit. MQTT data can be saved to TDengine via TDengine extension for HiveMQ. Please refer to the [HiveMQ extension - TDengine documentation](https://github.com/taosdata/hivemq-tdengine-extension/blob/master/README_EN.md) for details on how to use it. diff --git a/docs/en/25-application/03-immigrate.md b/docs/en/25-application/03-immigrate.md index 4d47aec1d7..fe67f97389 100644 --- a/docs/en/25-application/03-immigrate.md +++ b/docs/en/25-application/03-immigrate.md @@ -379,11 +379,11 @@ We still use the hypothetical environment from Chapter 4. There are three measur ### Storage resource estimation -Assuming that the number of sensor devices that generate data and need to be stored is `n`, the frequency of data generation is `t` per second, and the length of each record is `L` bytes, the scale of data generated per day is `n * t * L` bytes. Assuming the compression ratio is `C`, the daily data size is `(n * t * L)/C` bytes. The storage resources are estimated to accommodate the data scale for 1.5 years. In the production environment, the compression ratio C of TDengine is generally between 5 and 7. +Assuming that the number of sensor devices that generate data and need to be stored is `n`, the frequency of data generation is `t` per second, and the length of each record is `L` bytes, the scale of data generated per day is `86400 * n * t * L` bytes. Assuming the compression ratio is `C`, the daily data size is `(86400 * n * t * L)/C` bytes. The storage resources are estimated to accommodate the data scale for 1.5 years. In the production environment, the compression ratio C of TDengine is generally between 5 and 7. With additional 20% redundancy, you can calculate the required storage resources: ```matlab -(n * t * L) * (365 * 1.5) * (1+20%)/C +(86400 * n * t * L) * (365 * 1.5) * (1+20%)/C ```` Substituting in the above formula, the raw data generated every year is 11.8TB without considering the label information. Note that tag information is associated with each timeline in TDengine, not every record. The amount of data to be recorded is somewhat reduced relative to the generated data, and label data can be ignored as a whole. Assuming a compression ratio of 5, the size of the retained data ends up being 2.56 TB. diff --git a/docs/examples/java/pom.xml b/docs/examples/java/pom.xml index a48ba398da..77c6a3ad60 100644 --- a/docs/examples/java/pom.xml +++ b/docs/examples/java/pom.xml @@ -24,6 +24,16 @@ 2.0.38 + + org.slf4j + slf4j-api + 1.7.36 + + + ch.qos.logback + logback-classic + 1.2.11 + junit junit @@ -31,5 +41,36 @@ test
+ + + + org.apache.maven.plugins + maven-surefire-plugin + 2.5 + + true + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/lib + false + false + true + + + + + + diff --git a/docs/examples/java/src/main/java/com/taos/example/TestTableNotExits.java b/docs/examples/java/src/main/java/com/taos/example/TestTableNotExits.java new file mode 100644 index 0000000000..89fa8eaed5 --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/TestTableNotExits.java @@ -0,0 +1,26 @@ +package com.taos.example; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +public class TestTableNotExits { + private static Connection getConnection() throws SQLException { + String jdbcUrl = "jdbc:TAOS://localhost:6030?user=root&password=taosdata"; + return DriverManager.getConnection(jdbcUrl); + } + public static void main(String[] args) throws SQLException { + try(Connection conn = getConnection()) { + try(Statement stmt = conn.createStatement()) { + try { + stmt.executeUpdate("insert into test.t1 values(1, 2) test.t2 values(3, 4)"); + } catch (SQLException e) { + System.out.println(e.getErrorCode()); + System.out.println(Integer.toHexString(e.getErrorCode())); + System.out.println(e); + } + } + } + } +} diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java new file mode 100644 index 0000000000..04b149a4b9 --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java @@ -0,0 +1,63 @@ +package com.taos.example.highvolume; + +import java.sql.*; + +/** + * Prepare target database. + * Count total records in database periodically so that we can estimate the writing speed. + */ +public class DataBaseMonitor { + private Connection conn; + private Statement stmt; + + public DataBaseMonitor init() throws SQLException { + if (conn == null) { + String jdbcURL = System.getenv("TDENGINE_JDBC_URL"); + conn = DriverManager.getConnection(jdbcURL); + stmt = conn.createStatement(); + } + return this; + } + + public void close() { + try { + stmt.close(); + } catch (SQLException e) { + } + try { + conn.close(); + } catch (SQLException e) { + } + } + + public void prepareDatabase() throws SQLException { + stmt.execute("DROP DATABASE IF EXISTS test"); + stmt.execute("CREATE DATABASE test"); + stmt.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"); + } + + public Long count() throws SQLException { + if (!stmt.isClosed()) { + ResultSet result = stmt.executeQuery("SELECT count(*) from test.meters"); + result.next(); + return result.getLong(1); + } + return null; + } + + /** + * show test.stables; + * + * name | created_time | columns | tags | tables | + * ============================================================================================ + * meters | 2022-07-20 08:39:30.902 | 4 | 2 | 620000 | + */ + public Long getTableCount() throws SQLException { + if (!stmt.isClosed()) { + ResultSet result = stmt.executeQuery("show test.stables"); + result.next(); + return result.getLong(5); + } + return null; + } +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java new file mode 100644 index 0000000000..41b59551ca --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java @@ -0,0 +1,70 @@ +package com.taos.example.highvolume; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + + +public class FastWriteExample { + final static Logger logger = LoggerFactory.getLogger(FastWriteExample.class); + + final static int taskQueueCapacity = 1000000; + final static List> taskQueues = new ArrayList<>(); + final static List readTasks = new ArrayList<>(); + final static List writeTasks = new ArrayList<>(); + final static DataBaseMonitor databaseMonitor = new DataBaseMonitor(); + + public static void stopAll() { + logger.info("shutting down"); + readTasks.forEach(task -> task.stop()); + writeTasks.forEach(task -> task.stop()); + databaseMonitor.close(); + } + + public static void main(String[] args) throws InterruptedException, SQLException { + int readTaskCount = args.length > 0 ? Integer.parseInt(args[0]) : 1; + int writeTaskCount = args.length > 1 ? Integer.parseInt(args[1]) : 3; + int tableCount = args.length > 2 ? Integer.parseInt(args[2]) : 1000; + int maxBatchSize = args.length > 3 ? Integer.parseInt(args[3]) : 3000; + + logger.info("readTaskCount={}, writeTaskCount={} tableCount={} maxBatchSize={}", + readTaskCount, writeTaskCount, tableCount, maxBatchSize); + + databaseMonitor.init().prepareDatabase(); + + // Create task queues, whiting tasks and start writing threads. + for (int i = 0; i < writeTaskCount; ++i) { + BlockingQueue queue = new ArrayBlockingQueue<>(taskQueueCapacity); + taskQueues.add(queue); + WriteTask task = new WriteTask(queue, maxBatchSize); + Thread t = new Thread(task); + t.setName("WriteThread-" + i); + t.start(); + } + + // create reading tasks and start reading threads + int tableCountPerTask = tableCount / readTaskCount; + for (int i = 0; i < readTaskCount; ++i) { + ReadTask task = new ReadTask(i, taskQueues, tableCountPerTask); + Thread t = new Thread(task); + t.setName("ReadThread-" + i); + t.start(); + } + + Runtime.getRuntime().addShutdownHook(new Thread(FastWriteExample::stopAll)); + + long lastCount = 0; + while (true) { + Thread.sleep(10000); + long numberOfTable = databaseMonitor.getTableCount(); + long count = databaseMonitor.count(); + logger.info("numberOfTable={} count={} speed={}", numberOfTable, count, (count - lastCount) / 10); + lastCount = count; + } + } +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java new file mode 100644 index 0000000000..6fe83f002e --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java @@ -0,0 +1,53 @@ +package com.taos.example.highvolume; + +import java.util.Iterator; + +/** + * Generate test data + */ +class MockDataSource implements Iterator { + private String tbNamePrefix; + private int tableCount; + private long maxRowsPerTable = 1000000000L; + + // 100 milliseconds between two neighbouring rows. + long startMs = System.currentTimeMillis() - maxRowsPerTable * 100; + private int currentRow = 0; + private int currentTbId = -1; + + // mock values + String[] location = {"LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"}; + float[] current = {8.8f, 10.7f, 9.9f, 8.9f, 9.4f}; + int[] voltage = {119, 116, 111, 113, 118}; + float[] phase = {0.32f, 0.34f, 0.33f, 0.329f, 0.141f}; + + public MockDataSource(String tbNamePrefix, int tableCount) { + this.tbNamePrefix = tbNamePrefix; + this.tableCount = tableCount; + } + + @Override + public boolean hasNext() { + currentTbId += 1; + if (currentTbId == tableCount) { + currentTbId = 0; + currentRow += 1; + } + return currentRow < maxRowsPerTable; + } + + @Override + public String next() { + long ts = startMs + 100 * currentRow; + int groupId = currentTbId % 5 == 0 ? currentTbId / 5 : currentTbId / 5 + 1; + StringBuilder sb = new StringBuilder(tbNamePrefix + "_" + currentTbId + ","); // tbName + sb.append(ts).append(','); // ts + sb.append(current[currentRow % 5]).append(','); // current + sb.append(voltage[currentRow % 5]).append(','); // voltage + sb.append(phase[currentRow % 5]).append(','); // phase + sb.append(location[currentRow % 5]).append(','); // location + sb.append(groupId); // groupID + + return sb.toString(); + } +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java new file mode 100644 index 0000000000..a6fcfed1d2 --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java @@ -0,0 +1,58 @@ +package com.taos.example.highvolume; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.BlockingQueue; + +class ReadTask implements Runnable { + private final static Logger logger = LoggerFactory.getLogger(ReadTask.class); + private final int taskId; + private final List> taskQueues; + private final int queueCount; + private final int tableCount; + private boolean active = true; + + public ReadTask(int readTaskId, List> queues, int tableCount) { + this.taskId = readTaskId; + this.taskQueues = queues; + this.queueCount = queues.size(); + this.tableCount = tableCount; + } + + /** + * Assign data received to different queues. + * Here we use the suffix number in table name. + * You are expected to define your own rule in practice. + * + * @param line record received + * @return which queue to use + */ + public int getQueueId(String line) { + String tbName = line.substring(0, line.indexOf(',')); // For example: tb1_101 + String suffixNumber = tbName.split("_")[1]; + return Integer.parseInt(suffixNumber) % this.queueCount; + } + + @Override + public void run() { + logger.info("started"); + Iterator it = new MockDataSource("tb" + this.taskId, tableCount); + try { + while (it.hasNext() && active) { + String line = it.next(); + int queueId = getQueueId(line); + taskQueues.get(queueId).put(line); + } + } catch (Exception e) { + logger.error("Read Task Error", e); + } + } + + public void stop() { + logger.info("stop"); + this.active = false; + } +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java new file mode 100644 index 0000000000..c2989acdbe --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java @@ -0,0 +1,205 @@ +package com.taos.example.highvolume; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.util.HashMap; +import java.util.Map; + +/** + * A helper class encapsulate the logic of writing using SQL. + *

+ * The main interfaces are two methods: + *

    + *
  1. {@link SQLWriter#processLine}, which receive raw lines from WriteTask and group them by table names.
  2. + *
  3. {@link SQLWriter#flush}, which assemble INSERT statement and execute it.
  4. + *
+ *

+ * There is a technical skill worth mentioning: we create table as needed when "table does not exist" error occur instead of creating table automatically using syntax "INSET INTO tb USING stb". + * This ensure that checking table existence is a one-time-only operation. + *

+ * + *

+ */ +public class SQLWriter { + final static Logger logger = LoggerFactory.getLogger(SQLWriter.class); + + private Connection conn; + private Statement stmt; + + /** + * current number of buffered records + */ + private int bufferedCount = 0; + /** + * Maximum number of buffered records. + * Flush action will be triggered if bufferedCount reached this value, + */ + private int maxBatchSize; + + + /** + * Maximum SQL length. + */ + private int maxSQLLength; + + /** + * Map from table name to column values. For example: + * "tb001" -> "(1648432611249,2.1,114,0.09) (1648432611250,2.2,135,0.2)" + */ + private Map tbValues = new HashMap<>(); + + /** + * Map from table name to tag values in the same order as creating stable. + * Used for creating table. + */ + private Map tbTags = new HashMap<>(); + + public SQLWriter(int maxBatchSize) { + this.maxBatchSize = maxBatchSize; + } + + + /** + * Get Database Connection + * + * @return Connection + * @throws SQLException + */ + private static Connection getConnection() throws SQLException { + String jdbcURL = System.getenv("TDENGINE_JDBC_URL"); + return DriverManager.getConnection(jdbcURL); + } + + /** + * Create Connection and Statement + * + * @throws SQLException + */ + public void init() throws SQLException { + conn = getConnection(); + stmt = conn.createStatement(); + stmt.execute("use test"); + ResultSet rs = stmt.executeQuery("show variables"); + while (rs.next()) { + String configName = rs.getString(1); + if ("maxSQLLength".equals(configName)) { + maxSQLLength = Integer.parseInt(rs.getString(2)); + logger.info("maxSQLLength={}", maxSQLLength); + } + } + } + + /** + * Convert raw data to SQL fragments, group them by table name and cache them in a HashMap. + * Trigger writing when number of buffered records reached maxBachSize. + * + * @param line raw data get from task queue in format: tbName,ts,current,voltage,phase,location,groupId + */ + public void processLine(String line) throws SQLException { + bufferedCount += 1; + int firstComma = line.indexOf(','); + String tbName = line.substring(0, firstComma); + int lastComma = line.lastIndexOf(','); + int secondLastComma = line.lastIndexOf(',', lastComma - 1); + String value = "(" + line.substring(firstComma + 1, secondLastComma) + ") "; + if (tbValues.containsKey(tbName)) { + tbValues.put(tbName, tbValues.get(tbName) + value); + } else { + tbValues.put(tbName, value); + } + if (!tbTags.containsKey(tbName)) { + String location = line.substring(secondLastComma + 1, lastComma); + String groupId = line.substring(lastComma + 1); + String tagValues = "('" + location + "'," + groupId + ')'; + tbTags.put(tbName, tagValues); + } + if (bufferedCount == maxBatchSize) { + flush(); + } + } + + + /** + * Assemble INSERT statement using buffered SQL fragments in Map {@link SQLWriter#tbValues} and execute it. + * In case of "Table does not exit" exception, create all tables in the sql and retry the sql. + */ + public void flush() throws SQLException { + StringBuilder sb = new StringBuilder("INSERT INTO "); + for (Map.Entry entry : tbValues.entrySet()) { + String tableName = entry.getKey(); + String values = entry.getValue(); + String q = tableName + " values " + values + " "; + if (sb.length() + q.length() > maxSQLLength) { + executeSQL(sb.toString()); + logger.warn("increase maxSQLLength or decrease maxBatchSize to gain better performance"); + sb = new StringBuilder("INSERT INTO "); + } + sb.append(q); + } + executeSQL(sb.toString()); + tbValues.clear(); + bufferedCount = 0; + } + + private void executeSQL(String sql) throws SQLException { + try { + stmt.executeUpdate(sql); + } catch (SQLException e) { + // convert to error code defined in taoserror.h + int errorCode = e.getErrorCode() & 0xffff; + if (errorCode == 0x362 || errorCode == 0x218) { + // Table does not exist + createTables(); + executeSQL(sql); + } else { + logger.error("Execute SQL: {}", sql); + throw e; + } + } catch (Throwable throwable) { + logger.error("Execute SQL: {}", sql); + throw throwable; + } + } + + /** + * Create tables in batch using syntax: + *

+ * CREATE TABLE [IF NOT EXISTS] tb_name1 USING stb_name TAGS (tag_value1, ...) [IF NOT EXISTS] tb_name2 USING stb_name TAGS (tag_value2, ...) ...; + *

+ */ + private void createTables() throws SQLException { + StringBuilder sb = new StringBuilder("CREATE TABLE "); + for (String tbName : tbValues.keySet()) { + String tagValues = tbTags.get(tbName); + sb.append("IF NOT EXISTS ").append(tbName).append(" USING meters TAGS ").append(tagValues).append(" "); + } + String sql = sb.toString(); + try { + stmt.executeUpdate(sql); + } catch (Throwable throwable) { + logger.error("Execute SQL: {}", sql); + throw throwable; + } + } + + public boolean hasBufferedValues() { + return bufferedCount > 0; + } + + public int getBufferedCount() { + return bufferedCount; + } + + public void close() { + try { + stmt.close(); + } catch (SQLException e) { + } + try { + conn.close(); + } catch (SQLException e) { + } + } +} \ No newline at end of file diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/StmtWriter.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/StmtWriter.java new file mode 100644 index 0000000000..8ade06625d --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/StmtWriter.java @@ -0,0 +1,4 @@ +package com.taos.example.highvolume; + +public class StmtWriter { +} diff --git a/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java b/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java new file mode 100644 index 0000000000..de9e5463d7 --- /dev/null +++ b/docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java @@ -0,0 +1,58 @@ +package com.taos.example.highvolume; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.BlockingQueue; + +class WriteTask implements Runnable { + private final static Logger logger = LoggerFactory.getLogger(WriteTask.class); + private final int maxBatchSize; + + // the queue from which this writing task get raw data. + private final BlockingQueue queue; + + // A flag indicate whether to continue. + private boolean active = true; + + public WriteTask(BlockingQueue taskQueue, int maxBatchSize) { + this.queue = taskQueue; + this.maxBatchSize = maxBatchSize; + } + + @Override + public void run() { + logger.info("started"); + String line = null; // data getting from the queue just now. + SQLWriter writer = new SQLWriter(maxBatchSize); + try { + writer.init(); + while (active) { + line = queue.poll(); + if (line != null) { + // parse raw data and buffer the data. + writer.processLine(line); + } else if (writer.hasBufferedValues()) { + // write data immediately if no more data in the queue + writer.flush(); + } else { + // sleep a while to avoid high CPU usage if no more data in the queue and no buffered records, . + Thread.sleep(100); + } + } + if (writer.hasBufferedValues()) { + writer.flush(); + } + } catch (Exception e) { + String msg = String.format("line=%s, bufferedCount=%s", line, writer.getBufferedCount()); + logger.error(msg, e); + } finally { + writer.close(); + } + } + + public void stop() { + logger.info("stop"); + this.active = false; + } +} \ No newline at end of file diff --git a/docs/examples/java/src/main/resources/highvolume.drawio b/docs/examples/java/src/main/resources/highvolume.drawio new file mode 100644 index 0000000000..4102160618 --- /dev/null +++ b/docs/examples/java/src/main/resources/highvolume.drawio @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/examples/java/src/main/resources/highvolume2.drawio b/docs/examples/java/src/main/resources/highvolume2.drawio new file mode 100644 index 0000000000..8c9ae09007 --- /dev/null +++ b/docs/examples/java/src/main/resources/highvolume2.drawio @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/examples/java/src/main/resources/logback.xml b/docs/examples/java/src/main/resources/logback.xml new file mode 100644 index 0000000000..15c6d77de7 --- /dev/null +++ b/docs/examples/java/src/main/resources/logback.xml @@ -0,0 +1,22 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + demo.log + true + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/docs/examples/python/fast_write_example.py b/docs/examples/python/fast_write_example.py new file mode 100644 index 0000000000..c9d606388f --- /dev/null +++ b/docs/examples/python/fast_write_example.py @@ -0,0 +1,180 @@ +# install dependencies: +# recommend python >= 3.8 +# pip3 install faster-fifo +# + +import logging +import math +import sys +import time +import os +from multiprocessing import Process +from faster_fifo import Queue +from mockdatasource import MockDataSource +from queue import Empty +from typing import List + +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format="%(asctime)s [%(name)s] - %(message)s") + +READ_TASK_COUNT = 1 +WRITE_TASK_COUNT = 1 +TABLE_COUNT = 1000 +QUEUE_SIZE = 1000000 +MAX_BATCH_SIZE = 3000 + +read_processes = [] +write_processes = [] + + +def get_connection(): + """ + If variable TDENGINE_FIRST_EP is provided then it will be used. If not, firstEP in /etc/taos/taos.cfg will be used. + You can also override the default username and password by supply variable TDENGINE_USER and TDENGINE_PASSWORD + """ + import taos + firstEP = os.environ.get("TDENGINE_FIRST_EP") + if firstEP: + host, port = firstEP.split(":") + else: + host, port = None, 0 + user = os.environ.get("TDENGINE_USER", "root") + password = os.environ.get("TDENGINE_PASSWORD", "taosdata") + return taos.connect(host=host, port=int(port), user=user, password=password) + + +# ANCHOR: read + +def run_read_task(task_id: int, task_queues: List[Queue]): + table_count_per_task = TABLE_COUNT // READ_TASK_COUNT + data_source = MockDataSource(f"tb{task_id}", table_count_per_task) + try: + for batch in data_source: + for table_id, rows in batch: + # hash data to different queue + i = table_id % len(task_queues) + # block putting forever when the queue is full + task_queues[i].put_many(rows, block=True, timeout=-1) + except KeyboardInterrupt: + pass + + +# ANCHOR_END: read + +# ANCHOR: write +def run_write_task(task_id: int, queue: Queue): + from sql_writer import SQLWriter + log = logging.getLogger(f"WriteTask-{task_id}") + writer = SQLWriter(get_connection) + lines = None + try: + while True: + try: + # get as many as possible + lines = queue.get_many(block=False, max_messages_to_get=MAX_BATCH_SIZE) + writer.process_lines(lines) + except Empty: + time.sleep(0.01) + except KeyboardInterrupt: + pass + except BaseException as e: + log.debug(f"lines={lines}") + raise e + + +# ANCHOR_END: write + +def set_global_config(): + argc = len(sys.argv) + if argc > 1: + global READ_TASK_COUNT + READ_TASK_COUNT = int(sys.argv[1]) + if argc > 2: + global WRITE_TASK_COUNT + WRITE_TASK_COUNT = int(sys.argv[2]) + if argc > 3: + global TABLE_COUNT + TABLE_COUNT = int(sys.argv[3]) + if argc > 4: + global QUEUE_SIZE + QUEUE_SIZE = int(sys.argv[4]) + if argc > 5: + global MAX_BATCH_SIZE + MAX_BATCH_SIZE = int(sys.argv[5]) + + +# ANCHOR: monitor +def run_monitor_process(): + log = logging.getLogger("DataBaseMonitor") + conn = get_connection() + conn.execute("DROP DATABASE IF EXISTS test") + conn.execute("CREATE DATABASE test") + conn.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) " + "TAGS (location BINARY(64), groupId INT)") + + def get_count(): + res = conn.query("SELECT count(*) FROM test.meters") + rows = res.fetch_all() + return rows[0][0] if rows else 0 + + last_count = 0 + while True: + time.sleep(10) + count = get_count() + log.info(f"count={count} speed={(count - last_count) / 10}") + last_count = count + + +# ANCHOR_END: monitor +# ANCHOR: main +def main(): + set_global_config() + logging.info(f"READ_TASK_COUNT={READ_TASK_COUNT}, WRITE_TASK_COUNT={WRITE_TASK_COUNT}, " + f"TABLE_COUNT={TABLE_COUNT}, QUEUE_SIZE={QUEUE_SIZE}, MAX_BATCH_SIZE={MAX_BATCH_SIZE}") + + monitor_process = Process(target=run_monitor_process) + monitor_process.start() + time.sleep(3) # waiting for database ready. + + task_queues: List[Queue] = [] + # create task queues + for i in range(WRITE_TASK_COUNT): + queue = Queue(max_size_bytes=QUEUE_SIZE) + task_queues.append(queue) + + # create write processes + for i in range(WRITE_TASK_COUNT): + p = Process(target=run_write_task, args=(i, task_queues[i])) + p.start() + logging.debug(f"WriteTask-{i} started with pid {p.pid}") + write_processes.append(p) + + # create read processes + for i in range(READ_TASK_COUNT): + queues = assign_queues(i, task_queues) + p = Process(target=run_read_task, args=(i, queues)) + p.start() + logging.debug(f"ReadTask-{i} started with pid {p.pid}") + read_processes.append(p) + + try: + monitor_process.join() + except KeyboardInterrupt: + monitor_process.terminate() + [p.terminate() for p in read_processes] + [p.terminate() for p in write_processes] + [q.close() for q in task_queues] + + +def assign_queues(read_task_id, task_queues): + """ + Compute target queues for a specific read task. + """ + ratio = WRITE_TASK_COUNT / READ_TASK_COUNT + from_index = math.floor(read_task_id * ratio) + end_index = math.ceil((read_task_id + 1) * ratio) + return task_queues[from_index:end_index] + + +if __name__ == '__main__': + main() +# ANCHOR_END: main diff --git a/docs/examples/python/highvolume_faster_queue.py b/docs/examples/python/highvolume_faster_queue.py new file mode 100644 index 0000000000..14aebc67ee --- /dev/null +++ b/docs/examples/python/highvolume_faster_queue.py @@ -0,0 +1,205 @@ +# install dependencies: +# recommend python >= 3.8 +# pip3 install faster-fifo +# + +import logging +import sys +import time +import os +from multiprocessing import Process +from faster_fifo import Queue +from queue import Empty +from typing import List + +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format="%(asctime)s [%(name)s] - %(message)s") + +READ_TASK_COUNT = 1 +WRITE_TASK_COUNT = 1 +TABLE_COUNT = 1000 +QUEUE_SIZE = 1000000 +MAX_BATCH_SIZE = 3000 + +read_processes = [] +write_processes = [] + + +def get_connection(): + """ + If variable TDENGINE_FIRST_EP is provided then it will be used. If not, firstEP in /etc/taos/taos.cfg will be used. + You can also override the default username and password by supply variable TDENGINE_USER and TDENGINE_PASSWORD + """ + import taos + firstEP = os.environ.get("TDENGINE_FIRST_EP") + if firstEP: + host, port = firstEP.split(":") + else: + host, port = None, 0 + user = os.environ.get("TDENGINE_USER", "root") + password = os.environ.get("TDENGINE_PASSWORD", "taosdata") + return taos.connect(host=host, port=int(port), user=user, password=password) + + +# ANCHOR: MockDataSource +class MockDataSource: + location = ["LosAngeles", "SanDiego", "Hollywood", "Compton", "San Francisco"] + current = [8.8, 10.7, 9.9, 8.9, 9.4] + voltage = [119, 116, 111, 113, 118] + phase = [0.32, 0.34, 0.33, 0.329, 0.141] + max_rows_per_table = 10 ** 9 + + def __init__(self, tb_name_prefix, table_count): + self.table_name_prefix = tb_name_prefix + self.table_count = table_count + self.start_ms = round(time.time() * 1000) - self.max_rows_per_table * 100 + + def __iter__(self): + self.row = 0 + self.table_id = -1 + return self + + def __next__(self): + """ + next 100 rows of current table + """ + self.table_id += 1 + if self.table_id == self.table_count: + self.table_id = 0 + if self.row >= self.max_rows_per_table: + raise StopIteration + rows = [] + + while len(rows) < 100: + self.row += 1 + ts = self.start_ms + 100 * self.row + group_id = self.table_id % 5 if self.table_id % 5 == 0 else self.table_id % 5 + 1 + tb_name = self.table_name_prefix + '_' + str(self.table_id) + ri = self.row % 5 + rows.append(f"{tb_name},{ts},{self.current[ri]},{self.voltage[ri]},{self.phase[ri]},{self.location[ri]},{group_id}") + return self.table_id, rows + + +# ANCHOR_END: MockDataSource + +# ANCHOR: read +def run_read_task(task_id: int, task_queues: List[Queue]): + table_count_per_task = TABLE_COUNT // READ_TASK_COUNT + data_source = MockDataSource(f"tb{task_id}", table_count_per_task) + try: + for table_id, rows in data_source: + # hash data to different queue + i = table_id % len(task_queues) + # block putting forever when the queue is full + task_queues[i].put_many(rows, block=True, timeout=-1) + except KeyboardInterrupt: + pass + + +# ANCHOR_END: read + +# ANCHOR: write +def run_write_task(task_id: int, queue: Queue): + from sql_writer import SQLWriter + log = logging.getLogger(f"WriteTask-{task_id}") + writer = SQLWriter(get_connection) + lines = None + try: + while True: + try: + # get as many as possible + lines = queue.get_many(block=False, max_messages_to_get=MAX_BATCH_SIZE) + writer.process_lines(lines) + except Empty: + time.sleep(0.01) + except KeyboardInterrupt: + pass + except BaseException as e: + log.debug(f"lines={lines}") + raise e + + +# ANCHOR_END: write + +def set_global_config(): + argc = len(sys.argv) + if argc > 1: + global READ_TASK_COUNT + READ_TASK_COUNT = int(sys.argv[1]) + if argc > 2: + global WRITE_TASK_COUNT + WRITE_TASK_COUNT = int(sys.argv[2]) + if argc > 3: + global TABLE_COUNT + TABLE_COUNT = int(sys.argv[3]) + if argc > 4: + global QUEUE_SIZE + QUEUE_SIZE = int(sys.argv[4]) + if argc > 5: + global MAX_BATCH_SIZE + MAX_BATCH_SIZE = int(sys.argv[5]) + + +# ANCHOR: monitor +def run_monitor_process(): + import taos + log = logging.getLogger("DataBaseMonitor") + conn = get_connection() + conn.execute("DROP DATABASE IF EXISTS test") + conn.execute("CREATE DATABASE test") + conn.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) " + "TAGS (location BINARY(64), groupId INT)") + + def get_count(): + res = conn.query("SELECT count(*) FROM test.meters") + rows = res.fetch_all() + return rows[0][0] if rows else 0 + + last_count = 0 + while True: + time.sleep(10) + count = get_count() + log.info(f"count={count} speed={(count - last_count) / 10}") + last_count = count + + +# ANCHOR_END: monitor +# ANCHOR: main +def main(): + set_global_config() + logging.info(f"READ_TASK_COUNT={READ_TASK_COUNT}, WRITE_TASK_COUNT={WRITE_TASK_COUNT}, " + f"TABLE_COUNT={TABLE_COUNT}, QUEUE_SIZE={QUEUE_SIZE}, MAX_BATCH_SIZE={MAX_BATCH_SIZE}") + + monitor_process = Process(target=run_monitor_process) + monitor_process.start() + time.sleep(3) # waiting for database ready. + + task_queues: List[Queue] = [] + # create task queues + for i in range(WRITE_TASK_COUNT): + queue = Queue(max_size_bytes=QUEUE_SIZE) + task_queues.append(queue) + # create write processes + for i in range(WRITE_TASK_COUNT): + p = Process(target=run_write_task, args=(i, task_queues[i])) + p.start() + logging.debug(f"WriteTask-{i} started with pid {p.pid}") + write_processes.append(p) + # create read processes + for i in range(READ_TASK_COUNT): + p = Process(target=run_read_task, args=(i, task_queues)) + p.start() + logging.debug(f"ReadTask-{i} started with pid {p.pid}") + read_processes.append(p) + + try: + monitor_process.join() + except KeyboardInterrupt: + monitor_process.terminate() + [p.terminate() for p in read_processes] + [p.terminate() for p in write_processes] + [q.close() for q in task_queues] + + +if __name__ == '__main__': + main() +# ANCHOR_END: main diff --git a/docs/examples/python/mockdatasource.py b/docs/examples/python/mockdatasource.py new file mode 100644 index 0000000000..852860aec0 --- /dev/null +++ b/docs/examples/python/mockdatasource.py @@ -0,0 +1,49 @@ +import time + + +class MockDataSource: + samples = [ + "8.8,119,0.32,LosAngeles,0", + "10.7,116,0.34,SanDiego,1", + "9.9,111,0.33,Hollywood,2", + "8.9,113,0.329,Compton,3", + "9.4,118,0.141,San Francisco,4" + ] + + def __init__(self, tb_name_prefix, table_count): + self.table_name_prefix = tb_name_prefix + "_" + self.table_count = table_count + self.max_rows = 10000000 + self.current_ts = round(time.time() * 1000) - self.max_rows * 100 + # [(tableId, tableName, values),] + self.data = self._init_data() + + def _init_data(self): + lines = self.samples * (self.table_count // 5 + 1) + data = [] + for i in range(self.table_count): + table_name = self.table_name_prefix + str(i) + data.append((i, table_name, lines[i])) # tableId, row + return data + + def __iter__(self): + self.row = 0 + return self + + def __next__(self): + """ + next 1000 rows for each table. + return: {tableId:[row,...]} + """ + # generate 1000 timestamps + ts = [] + for _ in range(1000): + self.current_ts += 100 + ts.append(str(self.current_ts)) + # add timestamp to each row + # [(tableId, ["tableName,ts,current,voltage,phase,location,groupId"])] + result = [] + for table_id, table_name, values in self.data: + rows = [table_name + ',' + t + ',' + values for t in ts] + result.append((table_id, rows)) + return result diff --git a/docs/examples/python/sql_writer.py b/docs/examples/python/sql_writer.py new file mode 100644 index 0000000000..cb04f85c23 --- /dev/null +++ b/docs/examples/python/sql_writer.py @@ -0,0 +1,90 @@ +import logging +import taos + + +class SQLWriter: + log = logging.getLogger("SQLWriter") + + def __init__(self, get_connection_func): + self._tb_values = {} + self._tb_tags = {} + self._conn = get_connection_func() + self._max_sql_length = self.get_max_sql_length() + self._conn.execute("USE test") + + def get_max_sql_length(self): + rows = self._conn.query("SHOW variables").fetch_all() + for r in rows: + name = r[0] + if name == "maxSQLLength": + return int(r[1]) + return 1024 * 1024 + + def process_lines(self, lines: str): + """ + :param lines: [[tbName,ts,current,voltage,phase,location,groupId]] + """ + for line in lines: + ps = line.split(",") + table_name = ps[0] + value = '(' + ",".join(ps[1:-2]) + ') ' + if table_name in self._tb_values: + self._tb_values[table_name] += value + else: + self._tb_values[table_name] = value + + if table_name not in self._tb_tags: + location = ps[-2] + group_id = ps[-1] + tag_value = f"('{location}',{group_id})" + self._tb_tags[table_name] = tag_value + self.flush() + + def flush(self): + """ + Assemble INSERT statement and execute it. + When the sql length grows close to MAX_SQL_LENGTH, the sql will be executed immediately, and a new INSERT statement will be created. + In case of "Table does not exit" exception, tables in the sql will be created and the sql will be re-executed. + """ + sql = "INSERT INTO " + sql_len = len(sql) + buf = [] + for tb_name, values in self._tb_values.items(): + q = tb_name + " VALUES " + values + if sql_len + len(q) >= self._max_sql_length: + sql += " ".join(buf) + self.execute_sql(sql) + sql = "INSERT INTO " + sql_len = len(sql) + buf = [] + buf.append(q) + sql_len += len(q) + sql += " ".join(buf) + self.execute_sql(sql) + self._tb_values.clear() + + def execute_sql(self, sql): + try: + self._conn.execute(sql) + except taos.Error as e: + error_code = e.errno & 0xffff + # Table does not exit + if error_code == 0x362 or error_code == 0x218: + self.create_tables() + else: + self.log.error("Execute SQL: %s", sql) + raise e + except BaseException as baseException: + self.log.error("Execute SQL: %s", sql) + raise baseException + + def create_tables(self): + sql = "CREATE TABLE " + for tb in self._tb_values.keys(): + tag_values = self._tb_tags[tb] + sql += "IF NOT EXISTS " + tb + " USING meters TAGS " + tag_values + " " + try: + self._conn.execute(sql) + except BaseException as e: + self.log.error("Execute SQL: %s", sql) + raise e diff --git a/docs/examples/python/stmt_writer.py b/docs/examples/python/stmt_writer.py new file mode 100644 index 0000000000..60846b5a64 --- /dev/null +++ b/docs/examples/python/stmt_writer.py @@ -0,0 +1,2 @@ +class StmtWriter: + pass diff --git a/docs/zh/02-intro.md b/docs/zh/02-intro.md index 673c2e96b6..191e1cbcc2 100644 --- a/docs/zh/02-intro.md +++ b/docs/zh/02-intro.md @@ -52,7 +52,7 @@ TDengine的主要功能如下: 采用 TDengine,可将典型的物联网、车联网、工业互联网大数据平台的总拥有成本大幅降低。表现在几个方面: 1. 由于其超强性能,它能将系统需要的计算资源和存储资源大幅降低 -2. 因为采用 SQL 接口,能与众多第三放软件无缝集成,学习迁移成本大幅下降 +2. 因为采用 SQL 接口,能与众多第三方软件无缝集成,学习迁移成本大幅下降 3. 因为其 All In One 的特性,系统复杂度降低,能降研发成本 4. 因为运维维护简单,运营维护成本能大幅降低 diff --git a/docs/zh/04-concept/index.md b/docs/zh/04-concept/index.md index 8e97d4a2f4..0a0e4a3a2f 100644 --- a/docs/zh/04-concept/index.md +++ b/docs/zh/04-concept/index.md @@ -148,7 +148,7 @@ TDengine 建议用数据采集点的名字(如上表中的 D1001)来做表 3. 子表一定属于一张超级表,但普通表不属于任何超级表 4. 普通表无法转为子表,子表也无法转为普通表。 -超级表与与基于超级表建立的子表之间的关系表现在: +超级表与基于超级表建立的子表之间的关系表现在: 1. 一张超级表包含有多张子表,这些子表具有相同的采集量 schema,但带有不同的标签值。 2. 不能通过子表调整数据或标签的模式,对于超级表的数据模式修改立即对所有的子表生效。 diff --git a/docs/zh/07-develop/03-insert-data/05-high-volume.md b/docs/zh/07-develop/03-insert-data/05-high-volume.md new file mode 100644 index 0000000000..6c60fd6e24 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/05-high-volume.md @@ -0,0 +1,440 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +# 高效写入 + +本节介绍如何高效地向 TDengine 写入数据。 + +## 高效写入原理 {#principle} + +### 客户端程序的角度 {#application-view} + +从客户端程序的角度来说,高效写入数据要考虑以下几个因素: + +1. 单次写入的数据量。一般来讲,每批次写入的数据量越大越高效(但超过一定阈值其优势会消失)。使用 SQL 写入 TDengine 时,尽量在一条 SQL 中拼接更多数据。目前,TDengine 支持的一条 SQL 的最大长度为 1,048,576(1M)个字符。可通过配置客户端参数 maxSQLLength(默认值为 65480)进行修改。 +2. 并发连接数。一般来讲,同时写入数据的并发连接数越多写入越高效(但超过一定阈值反而会下降,取决于服务端处理能力)。 +3. 数据在不同表(或子表)之间的分布,即要写入数据的相邻性。一般来说,每批次只向同一张表(或子表)写入数据比向多张表(或子表)写入数据要更高效; +4. 写入方式。一般来讲: + - 参数绑定写入比 SQL 写入更高效。因参数绑定方式避免了 SQL 解析。(但增加了 C 接口的调用次数,对于连接器也有性能损耗)。 + - SQL 写入不自动建表比自动建表更高效。因自动建表要频繁检查表是否存在 + - SQL 写入比无模式写入更高效。因无模式写入会自动建表且支持动态更改表结构 + +客户端程序要充分且恰当地利用以上几个因素。在单次写入中尽量只向同一张表(或子表)写入数据,每批次写入的数据量经过测试和调优设定为一个最适合当前系统处理能力的数值,并发写入的连接数同样经过测试和调优后设定为一个最适合当前系统处理能力的数值,以实现在当前系统中的最佳写入速度。 + +### 数据源的角度 {#datasource-view} + +客户端程序通常需要从数据源读数据再写入 TDengine。从数据源角度来说,以下几种情况需要在读线程和写线程之间增加队列: + +1. 有多个数据源,单个数据源生成数据的速度远小于单线程写入的速度,但数据量整体比较大。此时队列的作用是把多个数据源的数据汇聚到一起,增加单次写入的数据量。 +2. 单个数据源生成数据的速度远大于单线程写入的速度。此时队列的作用是增加写入的并发度。 +3. 单张表的数据分散在多个数据源。此时队列的作用是将同一张表的数据提前汇聚到一起,提高写入时数据的相邻性。 + +如果写应用的数据源是 Kafka, 写应用本身即 Kafka 的消费者,则可利用 Kafka 的特性实现高效写入。比如: + +1. 将同一张表的数据写到同一个 Topic 的同一个 Partition,增加数据的相邻性 +2. 通过订阅多个 Topic 实现数据汇聚 +3. 通过增加 Consumer 线程数增加写入的并发度 +4. 通过增加每次 fetch 的最大数据量来增加单次写入的最大数据量 + +### 服务器配置的角度 {#setting-view} + +从服务器配置的角度来说,也有很多优化写入性能的方法。 + +如果总表数不多(远小于核数乘以1000), 且无论怎么调节客户端程序,taosd 进程的 CPU 使用率都很低,那么很可能是因为表在各个 vgroup 分布不均。比如:数据库总表数是 1000 且 minTablesPerVnode 设置的也是 1000,那么所有的表都会分布在 1 个 vgroup 上。此时如果将 minTablesPerVnode 和 tablelncStepPerVnode 都设置成 100, 则可将表分布至 10 个 vgroup。(假设 maxVgroupsPerDb 大于等于 10)。 + +如果总表数比较大(比如大于500万),适当增加 maxVgroupsPerDb 也能显著提高建表的速度。maxVgroupsPerDb 默认值为 0, 自动配置为 CPU 的核数。 如果表的数量巨大,也建议调节 maxTablesPerVnode 参数,以免超过单个 vnode 建表的上限。 + +更多调优参数,请参考[性能优化](../../operation/optimize)和[配置参考](../../reference/config)部分。 + +## 高效写入示例 {#sample-code} + +### 场景设计 {#scenario} + +下面的示例程序展示了如何高效写入数据,场景设计如下: + +- TDengine 客户端程序从其它数据源不断读入数据,在示例程序中采用生成模拟数据的方式来模拟读取数据源 +- 单个连接向 TDengine 写入的速度无法与读数据的速度相匹配,因此客户端程序启动多个线程,每个线程都建立了与 TDengine 的连接,每个线程都有一个独占的固定大小的消息队列 +- 客户端程序将接收到的数据根据所属的表名(或子表名)HASH 到不同的线程,即写入该线程所对应的消息队列,以此确保属于某个表(或子表)的数据一定会被一个固定的线程处理 +- 各个子线程在将所关联的消息队列中的数据读空后或者读取数据量达到一个预定的阈值后将该批数据写入 TDengine,并继续处理后面接收到的数据 + +![TDengine 高效写入示例场景的线程模型](highvolume.webp) + +### 示例代码 {#code} + +这一部分是针对以上场景的示例代码。对于其它场景高效写入原理相同,不过代码需要适当修改。 + +本示例代码假设源数据属于同一张超级表(meters)的不同子表。程序在开始写入数据之前已经在 test 库创建了这个超级表。对于子表,将根据收到的数据,由应用程序自动创建。如果实际场景是多个超级表,只需修改写任务自动建表的代码。 + + + + +**程序清单** + +| 类名 | 功能说明 | +| ---------------- | --------------------------------------------------------------------------- | +| FastWriteExample | 主程序 | +| ReadTask | 从模拟源中读取数据,将表名经过 hash 后得到 Queue 的 index,写入对应的 Queue | +| WriteTask | 从 Queue 中获取数据,组成一个 Batch,写入 TDengine | +| MockDataSource | 模拟生成一定数量 meters 子表的数据 | +| SQLWriter | WriteTask 依赖这个类完成 SQL 拼接、自动建表、 SQL 写入、SQL 长度检查 | +| StmtWriter | 实现参数绑定方式批量写入(暂未完成) | +| DataBaseMonitor | 统计写入速度,并每隔 10 秒把当前写入速度打印到控制台 | + + +以下是各类的完整代码和更详细的功能说明。 + +
+FastWriteExample +主程序负责: + +1. 创建消息队列 +2. 启动写线程 +3. 启动读线程 +4. 每隔 10 秒统计一次写入速度 + +主程序默认暴露了 4 个参数,每次启动程序都可调节,用于测试和调优: + +1. 读线程个数。默认为 1。 +2. 写线程个数。默认为 3。 +3. 模拟生成的总表数。默认为 1000。将会平分给各个读线程。如果总表数较大,建表需要花费较长,开始统计的写入速度可能较慢。 +4. 每批最多写入记录数量。默认为 3000。 + +队列容量(taskQueueCapacity)也是与性能有关的参数,可通过修改程序调节。一般来讲,队列容量越大,入队被阻塞的概率越小,队列的吞吐量越大,但是内存占用也会越大。 示例程序默认值已经设置地足够大。 + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/FastWriteExample.java}} +``` + +
+ +
+ReadTask + +读任务负责从数据源读数据。每个读任务都关联了一个模拟数据源。每个模拟数据源可生成一点数量表的数据。不同的模拟数据源生成不同表的数据。 + +读任务采用阻塞的方式写消息队列。也就是说,一旦队列满了,写操作就会阻塞。 + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/ReadTask.java}} +``` + +
+ +
+WriteTask + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/WriteTask.java}} +``` + +
+ +
+ +MockDataSource + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/MockDataSource.java}} +``` + +
+ +
+ +SQLWriter + +SQLWriter 类封装了拼 SQL 和写数据的逻辑。注意,所有的表都没有提前创建,而是在 catch 到表不存在异常的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。对于其它异常,这里简单地记录当时执行的 SQL 语句到日志中,你也可以记录更多线索到日志,已便排查错误和故障恢复。 + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/SQLWriter.java}} +``` + +
+ +
+ +DataBaseMonitor + +```java +{{#include docs/examples/java/src/main/java/com/taos/example/highvolume/DataBaseMonitor.java}} +``` + +
+ +**执行步骤** + +
+执行 Java 示例程序 + +执行程序前需配置环境变量 `TDENGINE_JDBC_URL`。如果 TDengine Server 部署在本机,且用户名、密码和端口都是默认值,那么可配置: + +``` +TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" +``` + +**本地集成开发环境执行示例程序** + +1. clone TDengine 仓库 + ``` + git clone git@github.com:taosdata/TDengine.git --depth 1 + ``` +2. 用集成开发环境打开 `docs/examples/java` 目录。 +3. 在开发环境中配置环境变量 `TDENGINE_JDBC_URL`。如果已配置了全局的环境变量 `TDENGINE_JDBC_URL` 可跳过这一步。 +4. 运行类 `com.taos.example.highvolume.FastWriteExample`。 + +**远程服务器上执行示例程序** + +若要在服务器上执行示例程序,可按照下面的步骤操作: + +1. 打包示例代码。在目录 TDengine/docs/examples/java 下执行: + ``` + mvn package + ``` +2. 远程服务器上创建 examples 目录: + ``` + mkdir -p examples/java + ``` +3. 复制依赖到服务器指定目录: + - 复制依赖包,只用复制一次 + ``` + scp -r .\target\lib @:~/examples/java + ``` + - 复制本程序的 jar 包,每次更新代码都需要复制 + ``` + scp -r .\target\javaexample-1.0.jar @:~/examples/java + ``` +4. 配置环境变量。 + 编辑 `~/.bash_profile` 或 `~/.bashrc` 添加如下内容例如: + + ``` + export TDENGINE_JDBC_URL="jdbc:TAOS://localhost:6030?user=root&password=taosdata" + ``` + + 以上使用的是本地部署 TDengine Server 时默认的 JDBC URL。你需要根据自己的实际情况更改。 + +5. 用 java 命令启动示例程序,命令模板: + + ``` + java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample + ``` + +6. 结束测试程序。测试程序不会自动结束,在获取到当前配置下稳定的写入速度后,按 CTRL + C 结束程序。 + 下面是一次实际运行的日志输出,机器配置 16核 + 64G + 固态硬盘。 + + ``` + root@vm85$ java -classpath lib/*:javaexample-1.0.jar com.taos.example.highvolume.FastWriteExample 2 12 + 18:56:35.896 [main] INFO c.t.e.highvolume.FastWriteExample - readTaskCount=2, writeTaskCount=12 tableCount=1000 maxBatchSize=3000 + 18:56:36.011 [WriteThread-0] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.015 [WriteThread-0] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.021 [WriteThread-1] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.022 [WriteThread-1] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.031 [WriteThread-2] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.032 [WriteThread-2] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.041 [WriteThread-3] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.042 [WriteThread-3] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.093 [WriteThread-4] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.094 [WriteThread-4] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.099 [WriteThread-5] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.100 [WriteThread-5] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.100 [WriteThread-6] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.101 [WriteThread-6] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.103 [WriteThread-7] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.104 [WriteThread-7] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.105 [WriteThread-8] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.107 [WriteThread-8] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.108 [WriteThread-9] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.109 [WriteThread-9] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.156 [WriteThread-10] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.157 [WriteThread-11] INFO c.taos.example.highvolume.WriteTask - started + 18:56:36.158 [WriteThread-10] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:36.158 [ReadThread-0] INFO com.taos.example.highvolume.ReadTask - started + 18:56:36.158 [ReadThread-1] INFO com.taos.example.highvolume.ReadTask - started + 18:56:36.158 [WriteThread-11] INFO c.taos.example.highvolume.SQLWriter - maxSQLLength=1048576 + 18:56:46.369 [main] INFO c.t.e.highvolume.FastWriteExample - count=18554448 speed=1855444 + 18:56:56.946 [main] INFO c.t.e.highvolume.FastWriteExample - count=39059660 speed=2050521 + 18:57:07.322 [main] INFO c.t.e.highvolume.FastWriteExample - count=59403604 speed=2034394 + 18:57:18.032 [main] INFO c.t.e.highvolume.FastWriteExample - count=80262938 speed=2085933 + 18:57:28.432 [main] INFO c.t.e.highvolume.FastWriteExample - count=101139906 speed=2087696 + 18:57:38.921 [main] INFO c.t.e.highvolume.FastWriteExample - count=121807202 speed=2066729 + 18:57:49.375 [main] INFO c.t.e.highvolume.FastWriteExample - count=142952417 speed=2114521 + 18:58:00.689 [main] INFO c.t.e.highvolume.FastWriteExample - count=163650306 speed=2069788 + 18:58:11.646 [main] INFO c.t.e.highvolume.FastWriteExample - count=185019808 speed=2136950 + ``` + +
+ +
+ + +**程序清单** + +Python 示例程序中采用了多进程的架构,并使用了跨进程的消息队列。 + +| 函数或类 | 功能说明 | +| ------------------------ | -------------------------------------------------------------------- | +| main 函数 | 程序入口, 创建各个子进程和消息队列 | +| run_monitor_process 函数 | 创建数据库,超级表,统计写入速度并定时打印到控制台 | +| run_read_task 函数 | 读进程主要逻辑,负责从其它数据系统读数据,并分发数据到为之分配的队列 | +| MockDataSource 类 | 模拟数据源, 实现迭代器接口,每次批量返回每张表的接下来 1000 条数据 | +| run_write_task 函数 | 写进程主要逻辑。每次从队列中取出尽量多的数据,并批量写入 | +| SQLWriter类 | SQL 写入和自动建表 | +| StmtWriter 类 | 实现参数绑定方式批量写入(暂未完成) | + + +
+main 函数 + +main 函数负责创建消息队列和启动子进程,子进程有 3 类: + +1. 1 个监控进程,负责数据库初始化和统计写入速度 +2. n 个读进程,负责从其它数据系统读数据 +3. m 个写进程,负责写数据库 + +main 函数可以接收 5 个启动参数,依次是: + +1. 读任务(进程)数, 默认为 1 +2. 写任务(进程)数, 默认为 1 +3. 模拟生成的总表数,默认为 1000 +4. 队列大小(单位字节),默认为 1000000 +5. 每批最多写入记录数量, 默认为 3000 + +```python +{{#include docs/examples/python/fast_write_example.py:main}} +``` + +
+ +
+run_monitor_process + +监控进程负责初始化数据库,并监控当前的写入速度。 + +```python +{{#include docs/examples/python/fast_write_example.py:monitor}} +``` + +
+ +
+ +run_read_task 函数 + +读进程,负责从其它数据系统读数据,并分发数据到为之分配的队列。 + +```python +{{#include docs/examples/python/fast_write_example.py:read}} +``` + +
+ +
+ +MockDataSource + +以下是模拟数据源的实现,我们假设数据源生成的每一条数据都带有目标表名信息。实际中你可能需要一定的规则确定目标表名。 + +```python +{{#include docs/examples/python/mockdatasource.py}} +``` + +
+ +
+run_write_task 函数 + +写进程每次从队列中取出尽量多的数据,并批量写入。 + +```python +{{#include docs/examples/python/fast_write_example.py:write}} +``` + +
+ +
+ +SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提前创建,而是在发生表不存在错误的时候,再以超级表为模板批量建表,然后重新执行 INSERT 语句。对于其它错误会记录当时执行的 SQL, 以便排查错误和故障恢复。这个类也对 SQL 是否超过最大长度限制做了检查,如果接近 SQL 最大长度限制(maxSQLLength),将会立即执行 SQL。为了减少 SQL 此时,建议将 maxSQLLength 适当调大。 + +SQLWriter + +```python +{{#include docs/examples/python/sql_writer.py}} +``` + +
+ +**执行步骤** + +
+ +执行 Python 示例程序 + +1. 前提条件 + + - 已安装 TDengine 客户端驱动 + - 已安装 Python3, 推荐版本 >= 3.8 + - 已安装 taospy + +2. 安装 faster-fifo 代替 python 内置的 multiprocessing.Queue + + ``` + pip3 install faster-fifo + ``` + +3. 点击上面的“查看源码”链接复制 `fast_write_example.py` 、 `sql_writer.py` 和 `mockdatasource.py` 三个文件。 + +4. 执行示例程序 + + ``` + python3 fast_write_example.py + ``` + + 下面是一次实际运行的输出, 机器配置 16核 + 64G + 固态硬盘。 + + ``` + root@vm85$ python3 fast_write_example.py 8 8 + 2022-07-14 19:13:45,869 [root] - READ_TASK_COUNT=8, WRITE_TASK_COUNT=8, TABLE_COUNT=1000, QUEUE_SIZE=1000000, MAX_BATCH_SIZE=3000 + 2022-07-14 19:13:48,882 [root] - WriteTask-0 started with pid 718347 + 2022-07-14 19:13:48,883 [root] - WriteTask-1 started with pid 718348 + 2022-07-14 19:13:48,884 [root] - WriteTask-2 started with pid 718349 + 2022-07-14 19:13:48,884 [root] - WriteTask-3 started with pid 718350 + 2022-07-14 19:13:48,885 [root] - WriteTask-4 started with pid 718351 + 2022-07-14 19:13:48,885 [root] - WriteTask-5 started with pid 718352 + 2022-07-14 19:13:48,886 [root] - WriteTask-6 started with pid 718353 + 2022-07-14 19:13:48,886 [root] - WriteTask-7 started with pid 718354 + 2022-07-14 19:13:48,887 [root] - ReadTask-0 started with pid 718355 + 2022-07-14 19:13:48,888 [root] - ReadTask-1 started with pid 718356 + 2022-07-14 19:13:48,889 [root] - ReadTask-2 started with pid 718357 + 2022-07-14 19:13:48,889 [root] - ReadTask-3 started with pid 718358 + 2022-07-14 19:13:48,890 [root] - ReadTask-4 started with pid 718359 + 2022-07-14 19:13:48,891 [root] - ReadTask-5 started with pid 718361 + 2022-07-14 19:13:48,892 [root] - ReadTask-6 started with pid 718364 + 2022-07-14 19:13:48,893 [root] - ReadTask-7 started with pid 718365 + 2022-07-14 19:13:56,042 [DataBaseMonitor] - count=6676310 speed=667631.0 + 2022-07-14 19:14:06,196 [DataBaseMonitor] - count=20004310 speed=1332800.0 + 2022-07-14 19:14:16,366 [DataBaseMonitor] - count=32290310 speed=1228600.0 + 2022-07-14 19:14:26,527 [DataBaseMonitor] - count=44438310 speed=1214800.0 + 2022-07-14 19:14:36,673 [DataBaseMonitor] - count=56608310 speed=1217000.0 + 2022-07-14 19:14:46,834 [DataBaseMonitor] - count=68757310 speed=1214900.0 + 2022-07-14 19:14:57,280 [DataBaseMonitor] - count=80992310 speed=1223500.0 + 2022-07-14 19:15:07,689 [DataBaseMonitor] - count=93805310 speed=1281300.0 + 2022-07-14 19:15:18,020 [DataBaseMonitor] - count=106111310 speed=1230600.0 + 2022-07-14 19:15:28,356 [DataBaseMonitor] - count=118394310 speed=1228300.0 + 2022-07-14 19:15:38,690 [DataBaseMonitor] - count=130742310 speed=1234800.0 + 2022-07-14 19:15:49,000 [DataBaseMonitor] - count=143051310 speed=1230900.0 + 2022-07-14 19:15:59,323 [DataBaseMonitor] - count=155276310 speed=1222500.0 + 2022-07-14 19:16:09,649 [DataBaseMonitor] - count=167603310 speed=1232700.0 + 2022-07-14 19:16:19,995 [DataBaseMonitor] - count=179976310 speed=1237300.0 + ``` + +
+ +:::note +使用 Python 连接器多进程连接 TDengine 的时候,有一个限制:不能在父进程中建立连接,所有连接只能在子进程中创建。 +如果在父进程中创建连接,子进程再创建连接就会一直阻塞。这是个已知问题。 + +::: + +
+
+ + diff --git a/docs/zh/07-develop/03-insert-data/highvolume.webp b/docs/zh/07-develop/03-insert-data/highvolume.webp new file mode 100644 index 0000000000000000000000000000000000000000..46dfc74ae3b0043c591ff930c62251da49cae7ad GIT binary patch literal 7308 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 literal 0 HcmV?d00001 diff --git a/docs/zh/12-taos-sql/02-database.md b/docs/zh/12-taos-sql/02-database.md index 566fec3241..e3a0aa7c87 100644 --- a/docs/zh/12-taos-sql/02-database.md +++ b/docs/zh/12-taos-sql/02-database.md @@ -32,7 +32,6 @@ CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1]; - cacheLast: [详细说明](/reference/config/#cachelast) - replica: [详细说明](/reference/config/#replica) - quorum: [详细说明](/reference/config/#quorum) - - maxVgroupsPerDb: [详细说明](/reference/config/#maxvgroupsperdb) - comp: [详细说明](/reference/config/#comp) - precision: [详细说明](/reference/config/#precision) 6. 请注意上面列出的所有参数都可以配置在配置文件 `taosd.cfg` 中作为创建数据库时使用的默认配置, `create database` 的参数中明确指定的会覆盖配置文件中的设置。 diff --git a/docs/zh/14-reference/03-connector/java.mdx b/docs/zh/14-reference/03-connector/java.mdx index ddab9e5f24..f7bd540088 100644 --- a/docs/zh/14-reference/03-connector/java.mdx +++ b/docs/zh/14-reference/03-connector/java.mdx @@ -93,7 +93,7 @@ Maven 项目中,在 pom.xml 中添加以下依赖: 可以通过下载 TDengine 的源码,自己编译最新版本的 Java connector ```shell -git clone https://github.com/taosdata/taos-connector-jdbc.git +git clone https://github.com/taosdata/taos-connector-jdbc.git --branch 2.0 cd taos-connector-jdbc mvn clean install -Dmaven.test.skip=true ``` @@ -201,6 +201,10 @@ url 中的配置参数如下: - batchfetch: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:false。逐行拉取结果集使用 HTTP 方式进行数据传输。从 taos-jdbcdriver-2.0.38 和 TDengine 2.4.0.12 版本开始,JDBC REST 连接增加批量拉取数据功能。taos-jdbcdriver 与 TDengine 之间通过 WebSocket 连接进行数据传输。相较于 HTTP,WebSocket 可以使 JDBC REST 连接支持大数据量查询,并提升查询性能。 - charset: 当开启批量拉取数据时,指定解析字符串数据的字符集。 - batchErrorIgnore:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL 了。false:不再执行失败 SQL 后的任何语句。默认值为:false。 +- httpConnectTimeout: 连接超时时间,单位 ms, 默认值为 5000。 +- httpSocketTimeout: socket 超时时间,单位 ms,默认值为 5000。仅在 batchfetch 设置为 false 时生效。 +- messageWaitTimeout: 消息超时时间, 单位 ms, 默认值为 3000。 仅在 batchfetch 设置为 true 时生效。 +- useSSL: 连接中是否使用 SSL。 **注意**:部分配置项(比如:locale、timezone)在 REST 连接中不生效。 @@ -264,7 +268,11 @@ properties 中的配置参数如下: - TSDBDriver.PROPERTY_KEY_CHARSET:客户端使用的字符集,默认值为系统字符集。 - TSDBDriver.PROPERTY_KEY_LOCALE:仅在使用 JDBC 原生连接时生效。 客户端语言环境,默认值系统当前 locale。 - TSDBDriver.PROPERTY_KEY_TIME_ZONE:仅在使用 JDBC 原生连接时生效。 客户端使用的时区,默认值为系统当前时区。 -- 此外对 JDBC 原生连接,通过指定 URL 和 Properties 还可以指定其他参数,比如日志级别、SQL 长度等。更多详细配置请参考[客户端配置](/reference/config/#仅客户端适用)。 +- TSDBDriver.HTTP_CONNECT_TIMEOUT: 连接超时时间,单位 ms, 默认值为 5000。仅在 REST 连接时生效。 +- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket 超时时间,单位 ms,默认值为 5000。仅在 REST 连接且 batchfetch 设置为 false 时生效。 +- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: 消息超时时间, 单位 ms, 默认值为 3000。 仅在 REST 连接且 batchfetch 设置为 true 时生效。 +- TSDBDriver.PROPERTY_KEY_USE_SSL: 连接中是否使用 SSL。仅在 REST 连接时生效。 + 此外对 JDBC 原生连接,通过指定 URL 和 Properties 还可以指定其他参数,比如日志级别、SQL 长度等。更多详细配置请参考[客户端配置](/reference/config/#仅客户端适用)。 ### 配置参数的优先级 @@ -368,7 +376,7 @@ public class ParameterBindingDemo { private static final String host = "127.0.0.1"; private static final Random random = new Random(System.currentTimeMillis()); - private static final int BINARY_COLUMN_SIZE = 20; + private static final int BINARY_COLUMN_SIZE = 30; private static final String[] schemaList = { "create table stable1(ts timestamp, f1 tinyint, f2 smallint, f3 int, f4 bigint) tags(t1 tinyint, t2 smallint, t3 int, t4 bigint)", "create table stable2(ts timestamp, f1 float, f2 double) tags(t1 float, t2 double)", @@ -809,6 +817,7 @@ Query OK, 1 row(s) in set (0.000141s) | taos-jdbcdriver 版本 | 主要变化 | | :------------------: | :----------------------------: | +| 2.0.39 - 2.0.40 | 增加 REST 连接/请求 超时设置 | | 2.0.38 | JDBC REST 连接增加批量拉取功能 | | 2.0.37 | 增加对 json tag 支持 | | 2.0.36 | 增加对 schemaless 写入支持 | diff --git a/docs/zh/20-third-party/10-hive-mq-broker.md b/docs/zh/20-third-party/10-hive-mq-broker.md index f75ed793d6..1944b97cb0 100644 --- a/docs/zh/20-third-party/10-hive-mq-broker.md +++ b/docs/zh/20-third-party/10-hive-mq-broker.md @@ -3,4 +3,4 @@ sidebar_label: HiveMQ Broker title: HiveMQ Broker 写入 --- -[HiveMQ](https://www.hivemq.com/) 是一个提供免费个人版和企业版的 MQTT 代理,主要用于企业和新兴的机器到机器 M2M 通讯和内部传输,满足可伸缩性、易管理和安全特性。HiveMQ 提供了开源的插件开发包。可以通过 HiveMQ extension - TDengine 保存数据到 TDengine。详细使用方法请参考 [HiveMQ extension - TDengine 说明文档](https://github.com/huskar-t/hivemq-tdengine-extension/blob/b62a26ecc164a310104df57691691b237e091c89/README.md)。 +[HiveMQ](https://www.hivemq.com/) 是一个提供免费个人版和企业版的 MQTT 代理,主要用于企业和新兴的机器到机器 M2M 通讯和内部传输,满足可伸缩性、易管理和安全特性。HiveMQ 提供了开源的插件开发包。可以通过 HiveMQ extension - TDengine 保存数据到 TDengine。详细使用方法请参考 [HiveMQ extension - TDengine 说明文档](https://github.com/taosdata/hivemq-tdengine-extension/blob/master/README.md)。 diff --git a/docs/zh/21-tdinternal/03-taosd.md b/docs/zh/21-tdinternal/03-taosd.md index 0cf0a1aaa2..9470311f94 100644 --- a/docs/zh/21-tdinternal/03-taosd.md +++ b/docs/zh/21-tdinternal/03-taosd.md @@ -88,7 +88,7 @@ TSDB 中存储的元数据包含属于其所在的 vnode 中表的类型,schem ## Query 模块 -该模块负责整体系统的查询处理。客户端调用该该模块进行 SQL 语法解析,并将查询或写入请求发送到 vnode ,同时负责针对超级表的查询进行二阶段的聚合操作。在 vnode 端,该模块调用 TSDB 模块读取系统中存储的数据进行查询处理。query 模块还定义了系统能够支持的全部查询函数,查询函数的实现机制与查询框架无耦合,可以在不修改查询流程的情况下动态增加查询函数。详细的设计请参见《TDengine 2.0 查询模块设计》。 +该模块负责整体系统的查询处理。客户端调用该该模块进行 SQL 语法解析,并将查询或写入请求发送到 vnode ,同时负责针对超级表的查询进行二阶段的聚合操作。在 vnode 端,该模块调用 TSDB 模块读取系统中存储的数据进行查询处理。query 模块还定义了系统能够支持的全部查询函数,查询函数的实现机制与查询框架无耦合,可以在不修改查询流程的情况下动态增加查询函数。 ## SYNC 模块 diff --git a/docs/zh/25-application/03-immigrate.md b/docs/zh/25-application/03-immigrate.md index 9d8946bc4a..d1c9caea09 100644 --- a/docs/zh/25-application/03-immigrate.md +++ b/docs/zh/25-application/03-immigrate.md @@ -367,10 +367,10 @@ WHERE ts>=1510560000 AND ts<=1515000009 ### 存储资源估算 -假设产生数据并需要存储的传感器设备数量为 `n`,数据生成的频率为`t`条/秒,每条记录的长度为 `L` bytes,则每天产生的数据规模为 `n×t×L` bytes。假设压缩比为 C,则每日产生数据规模为 `(n×t×L)/C` bytes。存储资源预估为能够容纳 1.5 年的数据规模,生产环境下 TDengine 的压缩比 C 一般在 5 ~ 7 之间,同时为最后结果增加 20% 的冗余,可计算得到需要存储资源: +假设产生数据并需要存储的传感器设备数量为 `n`,数据生成的频率为`t`条/秒,每条记录的长度为 `L` bytes,则每天产生的数据规模为 `86400×n×t×L` bytes。假设压缩比为 C,则每日产生数据规模为 `(86400×n×t×L)/C` bytes。存储资源预估为能够容纳 1.5 年的数据规模,生产环境下 TDengine 的压缩比 C 一般在 5 ~ 7 之间,同时为最后结果增加 20% 的冗余,可计算得到需要存储资源: ```matlab -(n×t×L)×(365×1.5)×(1+20%)/C +(86400×n×t×L)×(365×1.5)×(1+20%)/C ``` 结合以上的计算公式,将参数带入计算公式,在不考虑标签信息的情况下,每年产生的原始数据规模是 11.8TB。需要注意的是,由于标签信息在 TDengine 中关联到每个时间线,并不是每条记录。所以需要记录的数据量规模相对于产生的数据有一定的降低,而这部分标签数据整体上可以忽略不记。假设压缩比为 5,则保留的数据规模最终为 2.56 TB。 diff --git a/docs/zh/27-train-faq/01-faq.md b/docs/zh/27-train-faq/01-faq.md index e8a106d5d6..bb92c69c3f 100644 --- a/docs/zh/27-train-faq/01-faq.md +++ b/docs/zh/27-train-faq/01-faq.md @@ -239,3 +239,25 @@ taosAdapter 从 TDengine 2.4.0.0 版本开始成为 TDengine 服务端软件的 OOM 是操作系统的保护机制,当操作系统内存(包括 SWAP )不足时,会杀掉某些进程,从而保证操作系统的稳定运行。通常内存不足主要是如下两个原因导致,一是剩余内存小于 vm.min_free_kbytes ;二是程序请求的内存大于剩余内存。还有一种情况是内存充足但程序占用了特殊的内存地址,也会触发 OOM 。 TDengine 会预先为每个 VNode 分配好内存,每个 Database 的 VNode 个数受 maxVgroupsPerDb 影响,每个 VNode 占用的内存大小受 Blocks 和 Cache 影响。要防止 OOM,需要在项目建设之初合理规划内存,并合理设置 SWAP ,除此之外查询过量的数据也有可能导致内存暴涨,这取决于具体的查询语句。TDengine 企业版对内存管理做了优化,采用了新的内存分配器,对稳定性有更高要求的用户可以考虑选择企业版。 + +### 26. 为何批量写入数据时,时间戳使用 NOW 函数拼接会导致数据丢失? + +首先需要强调一个概念,TDengine 作为一个时序数据库(Time-Series Database),首个时间戳字段起到主键的作用,内存索引的构建、磁盘数据的存储与其密切相关,不能有重复的时间戳。 + +NOW 函数(以及 NOW 关键字)返回客户端当前时间。当执行批量写入时,若首列时间戳给的值都是 NOW,在数据库默认毫秒的时间级别下是区分不开的(建库时可选择更高的时间精度),后续写入的重复时间戳将会丢失或更新,处理重复时间戳的具体逻辑由在 TDengine 中建库时的 Update 参数决定。 + +### 27. 扩容集群后,DNode 状态为 Offline 怎么办? + +新的节点正常加入集群后,数据节点列表中会显示该节点处于 Ready 状态。若该节点状态为 Offline,可按照如下内容进行排查: + +1. 查看该节点 taosd 是否已启动、防火墙是否关闭; +2. 确认新增节点的数据文件夹是否清空; +3. 检查所有节点 /etc/hosts 域名解析是否完整、有效(需要有所有节点的解析,包括 arbitrator); +4. 该节点 firstEP、fqdn 参数是否正确配置。 + +### 28. 能提供 TDengine 的建模实例吗? + +在社区支持的过程中,能发现很多新手小伙伴在部署 TDengine 后不知道如何进一步体验,我们的建议是跑一跑官网文档的语句。文档内容较多,为了方便新手小伙伴快速上手,我们将官网文档的示例模型浓缩、汇总了一下,希望尽可能快的让大家了解 TDengine 建模方法:[建模入门](https://github.com/taosdata/tdengine-modeling-and-querying-101/blob/main/cases/001-electricity-meter-monitoring.zh-hans.md) + +同时也欢迎社区的用户们为仓库 [tdengine-modeling-and-querying-101](https://github.com/taosdata/tdengine-modeling-and-querying-101) 提交 PR,展现 TDengine 在各行各业的建模实例。 + diff --git a/examples/C#/C#checker/C#checker.cs b/examples/C#/C#checker/C#checker.cs index 7d0b6a50b6..f49fda88cd 100644 --- a/examples/C#/C#checker/C#checker.cs +++ b/examples/C#/C#checker/C#checker.cs @@ -389,7 +389,7 @@ namespace TDengineDriver static void ExitProgram() { - System.Environment.Exit(0); + System.Environment.Exit(1); } public void cleanup() diff --git a/examples/C#/insertCn/lib/ResultSetUtils.cs b/examples/C#/insertCn/lib/ResultSetUtils.cs new file mode 100644 index 0000000000..7d299411ee --- /dev/null +++ b/examples/C#/insertCn/lib/ResultSetUtils.cs @@ -0,0 +1,43 @@ +using System; +using TDengineDriver; +using System.Runtime.InteropServices; +using System.Text; +using System.Collections.Generic; +namespace Test.UtilsTools.ResultSet +{ + public class ResultSet + { + private List resultMeta; + private List resultData; + // private bool isValidResult = false; + public ResultSet(IntPtr res) + { + + resultMeta = UtilsTools.GetResField(res); + resultData = UtilsTools.GetResData(res); + } + + public ResultSet(List metas, List datas) + { + resultMeta = metas; + resultData = datas; + } + + public List GetResultData() + { + return resultData; + } + + public List GetResultMeta() + { + return resultMeta; + } + + public int GetFieldsNum() + { + return resultMeta.Count; + } + } + + +} diff --git a/examples/C#/insertCn/lib/Utils.cs b/examples/C#/insertCn/lib/Utils.cs new file mode 100644 index 0000000000..6107ecab57 --- /dev/null +++ b/examples/C#/insertCn/lib/Utils.cs @@ -0,0 +1,418 @@ +using System; +using TDengineDriver; +using System.Runtime.InteropServices; +using System.Text; +using System.Collections.Generic; +namespace Test.UtilsTools +{ + public class UtilsTools + { + + static string ip = "127.0.0.1"; + static string user = "root"; + static string password = "taosdata"; + static string db = ""; + static short port = 0; + //get a tdengine connection + public static IntPtr TDConnection() + { + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, GetConfigPath()); + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60"); + TDengine.Init(); + IntPtr conn = TDengine.Connect(ip, user, password, db, port); + return conn; + } + //get taos.cfg file based on different os + public static string GetConfigPath() + { + string configDir = "" ; + if(OperatingSystem.IsOSPlatform("Windows")) + { + configDir = "C:/TDengine/cfg"; + } + else if(OperatingSystem.IsOSPlatform("Linux")) + { + configDir = "/etc/taos"; + } + else if(OperatingSystem.IsOSPlatform("macOS")) + { + configDir = "/etc/taos"; + } + return configDir; + } + + public static IntPtr ExecuteQuery(IntPtr conn, String sql) + { + IntPtr res = TDengine.Query(conn, sql); + if (!IsValidResult(res)) + { + Console.Write(sql.ToString() + " failure, "); + ExitProgram(); + } + else + { + Console.WriteLine(sql.ToString() + " success"); + } + return res; + } + + public static IntPtr ExecuteErrorQuery(IntPtr conn, String sql) + { + IntPtr res = TDengine.Query(conn, sql); + if (!IsValidResult(res)) + { + Console.Write(sql.ToString() + " failure, "); + ExitProgram(); + } + else + { + Console.WriteLine(sql.ToString() + " success"); + + } + return res; + } + + public static void ExecuteUpdate(IntPtr conn, String sql) + { + IntPtr res = TDengine.Query(conn, sql); + if (!IsValidResult(res)) + { + Console.Write(sql.ToString() + " failure, "); + ExitProgram(); + } + else + { + Console.WriteLine(sql.ToString() + " success"); + + } + TDengine.FreeResult(res); + } + + + public static bool IsValidResult(IntPtr res) + { + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) + { + if (res != IntPtr.Zero) + { + Console.Write("reason: " + TDengine.Error(res)); + return false; + } + Console.WriteLine(""); + return false; + } + return true; + } + public static void CloseConnection(IntPtr conn) + { + if (conn != IntPtr.Zero) + { + if (TDengine.Close(conn) == 0) + { + Console.WriteLine("close connection sucess"); + } + else + { + Console.WriteLine("close Connection failed"); + } + } + TDengine.Cleanup(); + } + public static List GetResField(IntPtr res) + { + List metas = TDengine.FetchFields(res); + return metas; + } + public static void AssertEqual(string expectVal, string actualVal) + { + if (expectVal == actualVal) + { + Console.WriteLine("{0}=={1} pass", expectVal, actualVal); + } + else + { + Console.WriteLine("{0}=={1} failed", expectVal, actualVal); + ExitProgram(); + } + } + public static void ExitProgram() + { + TDengine.Cleanup(); + System.Environment.Exit(1); + } + public static List GetResData(IntPtr res) + { + List dataRaw = new List(); + if (!IsValidResult(res)) + { + ExitProgram(); + } + List metas = GetResField(res); + dataRaw = QueryRes(res, metas); + return dataRaw; + } + + public static TDengineMeta ConstructTDengineMeta(string name, string type) + { + + TDengineMeta _meta = new TDengineMeta(); + _meta.name = name; + char[] separators = new char[] { '(', ')' }; + string[] subs = type.Split(separators, StringSplitOptions.RemoveEmptyEntries); + + switch (subs[0].ToUpper()) + { + case "BOOL": + _meta.type = 1; + _meta.size = 1; + break; + case "TINYINT": + _meta.type = 2; + _meta.size = 1; + break; + case "SMALLINT": + _meta.type = 3; + _meta.size = 2; + break; + case "INT": + _meta.type = 4; + _meta.size = 4; + break; + case "BIGINT": + _meta.type = 5; + _meta.size = 8; + break; + case "TINYINT UNSIGNED": + _meta.type = 11; + _meta.size = 1; + break; + case "SMALLINT UNSIGNED": + _meta.type = 12; + _meta.size = 2; + break; + case "INT UNSIGNED": + _meta.type = 13; + _meta.size = 4; + break; + case "BIGINT UNSIGNED": + _meta.type = 14; + _meta.size = 8; + break; + case "FLOAT": + _meta.type = 6; + _meta.size = 4; + break; + case "DOUBLE": + _meta.type = 7; + _meta.size = 8; + break; + case "BINARY": + _meta.type = 8; + _meta.size = short.Parse(subs[1]); + break; + case "TIMESTAMP": + _meta.type = 9; + _meta.size = 8; + break; + case "NCHAR": + _meta.type = 10; + _meta.size = short.Parse(subs[1]); + break; + case "JSON": + _meta.type = 15; + _meta.size = 4096; + break; + default: + _meta.type = byte.MaxValue; + _meta.size = 0; + break; + } + return _meta; + } + + private static List QueryRes(IntPtr res, List metas) + { + IntPtr rowdata; + long queryRows = 0; + List dataRaw = new List(); + int fieldCount = metas.Count; + while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero) + { + queryRows++; + IntPtr colLengthPtr = TDengine.FetchLengths(res); + int[] colLengthArr = new int[fieldCount]; + Marshal.Copy(colLengthPtr, colLengthArr, 0, fieldCount); + + for (int fields = 0; fields < fieldCount; ++fields) + { + TDengineMeta meta = metas[fields]; + int offset = IntPtr.Size * fields; + IntPtr data = Marshal.ReadIntPtr(rowdata, offset); + + if (data == IntPtr.Zero) + { + dataRaw.Add("NULL"); + continue; + } + + switch ((TDengineDataType)meta.type) + { + case TDengineDataType.TSDB_DATA_TYPE_BOOL: + bool v1 = Marshal.ReadByte(data) == 0 ? false : true; + dataRaw.Add(v1); + break; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + sbyte v2 = (sbyte)Marshal.ReadByte(data); + dataRaw.Add(v2); + break; + case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: + short v3 = Marshal.ReadInt16(data); + dataRaw.Add(v3); + break; + case TDengineDataType.TSDB_DATA_TYPE_INT: + int v4 = Marshal.ReadInt32(data); + dataRaw.Add(v4); + break; + case TDengineDataType.TSDB_DATA_TYPE_BIGINT: + long v5 = Marshal.ReadInt64(data); + dataRaw.Add(v5); + break; + case TDengineDataType.TSDB_DATA_TYPE_FLOAT: + float v6 = (float)Marshal.PtrToStructure(data, typeof(float)); + dataRaw.Add(v6); + break; + case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: + double v7 = (double)Marshal.PtrToStructure(data, typeof(double)); + dataRaw.Add(v7); + break; + case TDengineDataType.TSDB_DATA_TYPE_BINARY: + // string v8 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]); + string v8 = Marshal.PtrToStringUTF8(data, colLengthArr[fields]); + dataRaw.Add(v8); + break; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + long v9 = Marshal.ReadInt64(data); + dataRaw.Add(v9); + break; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + // string v10 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]); + string v10 = Marshal.PtrToStringUTF8(data, colLengthArr[fields]); + dataRaw.Add(v10); + break; + case TDengineDataType.TSDB_DATA_TYPE_UTINYINT: + byte v12 = Marshal.ReadByte(data); + dataRaw.Add(v12); + break; + case TDengineDataType.TSDB_DATA_TYPE_USMALLINT: + ushort v13 = (ushort)Marshal.ReadInt16(data); + dataRaw.Add(v13); + break; + case TDengineDataType.TSDB_DATA_TYPE_UINT: + uint v14 = (uint)Marshal.ReadInt32(data); + dataRaw.Add(v14); + break; + case TDengineDataType.TSDB_DATA_TYPE_UBIGINT: + ulong v15 = (ulong)Marshal.ReadInt64(data); + dataRaw.Add(v15); + break; + default: + dataRaw.Add("unknown value"); + break; + } + } + + } + if (TDengine.ErrorNo(res) != 0) + { + Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res)); + } + TDengine.FreeResult(res); + Console.WriteLine(""); + return dataRaw; + } + + // Generate insert sql for the with the coldata and tag data + public static string ConstructInsertSql(string table,string stable,List colData,List tagData,int numOfRows) + { + int numofFileds = colData.Count / numOfRows; + StringBuilder insertSql; + + if (stable == "") + { + insertSql = new StringBuilder($"insert into {table} values("); + } + else + { + insertSql = new StringBuilder($"insert into {table} using {stable} tags("); + + for (int j = 0; j < tagData.Count; j++) + { + if (tagData[j] is String) + { + insertSql.Append('\''); + insertSql.Append(tagData[j]); + insertSql.Append('\''); + } + else + { + insertSql.Append(tagData[j]); + } + if (j + 1 != tagData.Count) + { + insertSql.Append(','); + } + } + + insertSql.Append(")values("); + } + for (int i = 0; i < colData.Count; i++) + { + + if (colData[i] is String) + { + insertSql.Append('\''); + insertSql.Append(colData[i]); + insertSql.Append('\''); + } + else + { + insertSql.Append(colData[i]); + } + + if ((i + 1) % numofFileds == 0 && (i + 1) != colData.Count) + { + insertSql.Append(")("); + } + else if ((i + 1) == colData.Count) + { + insertSql.Append(')'); + } + else + { + insertSql.Append(','); + } + } + insertSql.Append(';'); + //Console.WriteLine(insertSql.ToString()); + + return insertSql.ToString(); + } + + public static List CombineColAndTagData(List colData,List tagData, int numOfRows) + { + var list = new List(); + for (int i = 0; i < colData.Count; i++) + { + list.Add(colData[i]); + if ((i + 1) % (colData.Count / numOfRows) == 0) + { + for (int j = 0; j < tagData.Count; j++) + { + list.Add(tagData[j]); + } + } + } + return list; + } + } +} diff --git a/examples/C#/jsonTag/JsonTag.cs b/examples/C#/jsonTag/JsonTag.cs index 453e54eabd..5c94df8b5a 100644 --- a/examples/C#/jsonTag/JsonTag.cs +++ b/examples/C#/jsonTag/JsonTag.cs @@ -11,7 +11,7 @@ namespace Cases IntPtr conn = IntPtr.Zero; Console.WriteLine("===================JsonTagTest===================="); conn = conn = UtilsTools.TDConnection("127.0.0.1", "root", "taosdata", "", 0); - UtilsTools.ExecuteUpdate(conn, "create database if not exists csharp_sample keep 3650"); + UtilsTools.ExecuteUpdate(conn, "create database if not exists csharp keep 3650"); UtilsTools.ExecuteUpdate(conn, "use csharp"); JsonTagSample jsonTagSample = new JsonTagSample(); jsonTagSample.Test(conn); diff --git a/examples/C#/jsonTag/Util.cs b/examples/C#/jsonTag/Util.cs index 5138938df6..7446378fc7 100644 --- a/examples/C#/jsonTag/Util.cs +++ b/examples/C#/jsonTag/Util.cs @@ -217,10 +217,10 @@ namespace Utils } } } - public static void ExitProgram() + public static void ExitProgram(int i = 1) { TDengine.Cleanup(); - System.Environment.Exit(0); + System.Environment.Exit(i); } } } \ No newline at end of file diff --git a/examples/C#/jsonTag/jsonTag.csproj b/examples/C#/jsonTag/jsonTag.csproj index ed3af6e806..eb33d899ac 100644 --- a/examples/C#/jsonTag/jsonTag.csproj +++ b/examples/C#/jsonTag/jsonTag.csproj @@ -5,8 +5,8 @@ net5.0 - - + + diff --git a/examples/C#/schemaless/schemaless.csproj b/examples/C#/schemaless/schemaless.csproj index d132e34589..c2369f3e8e 100644 --- a/examples/C#/schemaless/schemaless.csproj +++ b/examples/C#/schemaless/schemaless.csproj @@ -5,8 +5,8 @@ net5.0 - - + + diff --git a/examples/C#/schemaless/schemalessSample.cs b/examples/C#/schemaless/schemalessSample.cs index f27ac352a6..8d0b7f60d0 100644 --- a/examples/C#/schemaless/schemalessSample.cs +++ b/examples/C#/schemaless/schemalessSample.cs @@ -289,7 +289,7 @@ namespace TDengineDriver static void ExitProgram() { - System.Environment.Exit(0); + System.Environment.Exit(1); } public void cleanup() diff --git a/examples/C#/stmt/StmtDemo.cs b/examples/C#/stmt/StmtDemo.cs index fdd647fdb5..56a5aa20f3 100644 --- a/examples/C#/stmt/StmtDemo.cs +++ b/examples/C#/stmt/StmtDemo.cs @@ -543,7 +543,7 @@ namespace TDengineDriver public static void ExitProgram() { TDengine.Cleanup(); - System.Environment.Exit(0); + System.Environment.Exit(1); } } } diff --git a/examples/c/makefile b/examples/c/makefile index 4d6cfc1f5f..6f0ab8880a 100644 --- a/examples/c/makefile +++ b/examples/c/makefile @@ -7,7 +7,6 @@ LFLAGS = '-Wl,-rpath,/usr/local/taos/driver/' -ltaos -lpthread -lm -lrt CFLAGS = -O3 -g -Wall -Wno-deprecated -fPIC -Wno-unused-result -Wconversion \ -Wno-char-subscripts -D_REENTRANT -Wno-format -D_REENTRANT -DLINUX \ -Wno-unused-function -D_M_X64 -I/usr/local/taos/include -std=gnu99 \ - -I../../../deps/cJson/inc \ -Wno-unused-function -D_M_X64 -I/usr/local/taos/include -std=gnu99 \ -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment diff --git a/packaging/release.sh b/packaging/release.sh index 4823c9d10b..0ad8d9b1bf 100755 --- a/packaging/release.sh +++ b/packaging/release.sh @@ -198,6 +198,7 @@ fi if [[ "$dbName" != "taos" ]]; then source ${enterprise_dir}/packaging/oem/sed_$dbName.sh replace_community_$dbName + replace_output_$dbName fi if [[ "$httpdBuild" == "true" ]]; then @@ -224,6 +225,7 @@ if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" = else if [[ "$dbName" != "taos" ]]; then replace_enterprise_$dbName + replace_output_$dbName fi cmake ../../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} -DBUILD_HTTP=${BUILD_HTTP} -DBUILD_TOOLS=${BUILD_TOOLS} ${allocator_macro} fi diff --git a/packaging/tools/install_arbi.sh b/packaging/tools/install_arbi.sh index 6e9be8489b..31a9ce38ac 100755 --- a/packaging/tools/install_arbi.sh +++ b/packaging/tools/install_arbi.sh @@ -76,12 +76,21 @@ elif echo $osinfo | grep -qwi "debian"; then elif echo $osinfo | grep -qwi "Kylin"; then # echo "This is Kylin system" os_type=1 +elif echo $osinfo | grep -qwi "Red"; then + # echo "This is Red Hat system" + os_type=1 elif echo $osinfo | grep -qwi "centos"; then # echo "This is centos system" os_type=2 elif echo $osinfo | grep -qwi "fedora"; then # echo "This is fedora system" os_type=2 +elif echo $osinfo | grep -qwi "Linx"; then + # echo "This is Linx system" + os_type=1 + service_mod=0 + initd_mod=0 + service_config_dir="/etc/systemd/system" else echo " osinfo: ${osinfo}" echo " This is an officially unverified linux system," diff --git a/src/client/src/tscGlobalmerge.c b/src/client/src/tscGlobalmerge.c index b8d47022b4..82f08fc81d 100644 --- a/src/client/src/tscGlobalmerge.c +++ b/src/client/src/tscGlobalmerge.c @@ -33,12 +33,12 @@ typedef struct SCompareParam { int32_t groupOrderType; } SCompareParam; -static bool needToMerge(SSDataBlock* pBlock, SArray* columnIndexList, int32_t index, char **buf) { +static bool needToMerge(SSDataBlock* pBlock, SArray* columnIndexList, int32_t idx, char **buf) { int32_t ret = 0; size_t size = taosArrayGetSize(columnIndexList); if (size > 0) { - ret = compare_aRv(pBlock, columnIndexList, (int32_t) size, index, buf, TSDB_ORDER_ASC); + ret = compare_aRv(pBlock, columnIndexList, (int32_t) size, idx, buf, TSDB_ORDER_ASC); } // if ret == 0, means the result belongs to the same group @@ -563,9 +563,9 @@ static void savePrevOrderColumns(char** prevRow, SArray* pColumnList, SSDataBloc int32_t size = (int32_t) taosArrayGetSize(pColumnList); for(int32_t i = 0; i < size; ++i) { - SColIndex* index = taosArrayGet(pColumnList, i); - SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, index->colIndex); - assert(index->colId == pColInfo->info.colId); + SColIndex* idx = taosArrayGet(pColumnList, i); + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, idx->colIndex); + assert(idx->colId == pColInfo->info.colId); memcpy(prevRow[i], pColInfo->pData + pColInfo->info.bytes * rowIndex, pColInfo->info.bytes); } @@ -603,7 +603,7 @@ static void doMergeResultImpl(SOperatorInfo* pInfo, SQLFunctionCtx *pCtx, int32_ for (int32_t j = 0; j < numOfExpr; ++j) { int32_t functionId = pCtx[j].functionId; - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_COL_DUMMY) { continue; } @@ -625,7 +625,7 @@ static void doMergeResultImpl(SOperatorInfo* pInfo, SQLFunctionCtx *pCtx, int32_ static void doFinalizeResultImpl(SMultiwayMergeInfo* pInfo, SQLFunctionCtx *pCtx, int32_t numOfExpr) { for(int32_t j = 0; j < numOfExpr; ++j) { int32_t functionId = pCtx[j].functionId; - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_COL_DUMMY) { continue; } diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index 39cbd6789f..cda3b0a50a 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -152,7 +152,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, int32_t typeColLength, int32_t noteColLength) { int32_t rowLen = 0; - SColumnIndex index = {0}; + SColumnIndex idx = {0, 0}; pSql->cmd.numOfCols = numOfCols; @@ -163,7 +163,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Field", sizeof(f.name)); SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false); rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE); @@ -173,7 +173,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Type", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), -1000, typeColLength, false); rowLen += typeColLength + VARSTR_HEADER_SIZE; @@ -183,7 +183,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Length", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_INT, sizeof(int32_t), -1000, sizeof(int32_t), false); rowLen += sizeof(int32_t); @@ -193,7 +193,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Note", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), -1000, noteColLength, false); rowLen += noteColLength + VARSTR_HEADER_SIZE; @@ -415,7 +415,7 @@ static int32_t tscGetTableTagValue(SCreateBuilder *builder, char *result) { static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const char *ddl) { int32_t rowLen = 0; int16_t ddlLen = (int16_t)strlen(ddl); - SColumnIndex index = {0}; + SColumnIndex idx = {0}; pSql->cmd.numOfCols = 2; SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); @@ -433,7 +433,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); rowLen += f.bytes; @@ -446,7 +446,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, TSDB_DATA_TYPE_BINARY, (int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false); rowLen += ddlLen + VARSTR_HEADER_SIZE; diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index ad209839bb..38aee8a678 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -61,8 +61,8 @@ int initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, SParsedDataColIn return TSDB_CODE_SUCCESS; } -int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int16_t timePrec) { - int32_t index = 0; +int tsParseTime(SStrToken *pToken, int64_t *pTime, char **next, char *err, int16_t timePrec) { + int32_t idx = 0; SStrToken sToken; int64_t interval; int64_t useconds = 0; @@ -80,8 +80,8 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 useconds = taosStr2int64(pToken->z); } else { // strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm); - if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { - return tscInvalidOperationMsg(error, "invalid timestamp format", pToken->z); + if (taosParseTime(pToken->z, pTime, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { + return tscInvalidOperationMsg(err, "invalid timestamp format", pToken->z); } return TSDB_CODE_SUCCESS; @@ -91,7 +91,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 if (isspace(pToken->z[k])) continue; if (pToken->z[k] == ',') { *next = pTokenEnd; - *time = useconds; + *pTime = useconds; return 0; } @@ -103,17 +103,17 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 * e.g., now+12a, now-5h */ SStrToken valueToken; - index = 0; - sToken = tStrGetToken(pTokenEnd, &index, false); - pTokenEnd += index; + idx = 0; + sToken = tStrGetToken(pTokenEnd, &idx, false); + pTokenEnd += idx; if (sToken.type == TK_MINUS || sToken.type == TK_PLUS) { - index = 0; - valueToken = tStrGetToken(pTokenEnd, &index, false); - pTokenEnd += index; + idx = 0; + valueToken = tStrGetToken(pTokenEnd, &idx, false); + pTokenEnd += idx; if (valueToken.n < 2) { - return tscInvalidOperationMsg(error, "value expected in timestamp", sToken.z); + return tscInvalidOperationMsg(err, "value expected in timestamp", sToken.z); } char unit = 0; @@ -130,7 +130,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 *next = pTokenEnd; } - *time = useconds; + *pTime = useconds; return TSDB_CODE_SUCCESS; } @@ -433,7 +433,7 @@ int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start) { int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, int32_t *len, char *tmpTokenBuf, SInsertStatementParam *pInsertParam) { - int32_t index = 0; + int32_t idx = 0; SStrToken sToken = {0}; char *row = pDataBlocks->pData + pDataBlocks->size; // skip the SSubmitBlk header @@ -455,9 +455,9 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i SSchema *pSchema = &schema[colIndex]; // get colId here - index = 0; - sToken = tStrGetToken(*str, &index, true); - *str += index; + idx = 0; + sToken = tStrGetToken(*str, &idx, true); + *str += idx; if (sToken.type == TK_QUESTION) { if (!isParseBindParam) { @@ -564,7 +564,7 @@ int32_t boundIdxCompar(const void *lhs, const void *rhs) { int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SInsertStatementParam *pInsertParam, int32_t* numOfRows, char *tmpTokenBuf) { - int32_t index = 0; + int32_t idx = 0; int32_t code = 0; (*numOfRows) = 0; @@ -584,11 +584,11 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SIn pDataBlock->rowBuilder.rowSize = extendedRowSize; while (1) { - index = 0; - sToken = tStrGetToken(*str, &index, false); + idx = 0; + sToken = tStrGetToken(*str, &idx, false); if (sToken.n == 0 || sToken.type != TK_LP) break; - *str += index; + *str += idx; if ((*numOfRows) >= maxRows || pDataBlock->size + extendedRowSize >= pDataBlock->nAllocSize) { int32_t tSize; code = tscAllocateMemIfNeed(pDataBlock, extendedRowSize, &tSize); @@ -609,13 +609,13 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SIn pDataBlock->size += len; - index = 0; - sToken = tStrGetToken(*str, &index, false); + idx = 0; + sToken = tStrGetToken(*str, &idx, false); if (sToken.n == 0 || sToken.type != TK_RP) { return tscSQLSyntaxErrMsg(pInsertParam->msg, ") expected", *str); } - *str += index; + *str += idx; (*numOfRows)++; } @@ -876,7 +876,7 @@ int validateTableName(char *tblName, int len, SStrToken* psTblToken, bool *dbInc static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundColumn) { - int32_t index = 0; + int32_t idx = 0; SStrToken sToken = {0}; SStrToken tableToken = {0}; int32_t code = TSDB_CODE_SUCCESS; @@ -891,14 +891,14 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC char *sql = *sqlstr; // get the token of specified table - index = 0; - tableToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + tableToken = tStrGetToken(sql, &idx, false); + sql += idx; // skip possibly exists column list - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; int32_t numOfColList = 0; @@ -907,8 +907,8 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC *boundColumn = &sToken.z[0]; while (1) { - index = 0; - sToken = tStrGetToken(sql, &index, false); + idx = 0; + sToken = tStrGetToken(sql, &idx, false); if (sToken.type == TK_ILLEGAL) { return tscSQLSyntaxErrMsg(pCmd->payload, "unrecognized token", sToken.z); @@ -918,12 +918,12 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC break; } - sql += index; + sql += idx; ++numOfColList; } - sToken = tStrGetToken(sql, &index, false); - sql += index; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; } if (numOfColList == 0 && (*boundColumn) != NULL) { @@ -933,9 +933,9 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX); if (sToken.type == TK_USING) { // create table if not exists according to the super table - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; if (sToken.type == TK_ILLEGAL) { return tscSQLSyntaxErrMsg(pCmd->payload, NULL, sql); @@ -980,8 +980,8 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC SParsedDataColInfo spd = {0}; tscSetBoundColumnInfo(&spd, pTagSchema, tscGetNumOfTags(pSTableMetaInfo->pTableMeta)); - index = 0; - sToken = tStrGetToken(sql, &index, false); + idx = 0; + sToken = tStrGetToken(sql, &idx, false); if (sToken.type != TK_TAGS && sToken.type != TK_LP) { tscDestroyBoundColumnInfo(&spd); return tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword TAGS expected", sToken.z); @@ -1002,16 +1002,16 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC sql = end; - index = 0; // keywords of "TAGS" - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; // keywords of "TAGS" + sToken = tStrGetToken(sql, &idx, false); + sql += idx; } else { - sql += index; + sql += idx; } - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; if (sToken.type != TK_LP) { tscDestroyBoundColumnInfo(&spd); @@ -1027,9 +1027,9 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC for (int i = 0; i < spd.numOfBound; ++i) { SSchema* pSchema = &pTagSchema[spd.boundedColumns[i]]; - index = 0; - sToken = tStrGetToken(sql, &index, true); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, true); + sql += idx; if (TK_ILLEGAL == sToken.type) { tdDestroyKVRowBuilder(&kvRowBuilder); @@ -1101,9 +1101,9 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC free(row); pInsertParam->tagData.data = pTag; - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; if (sToken.n == 0 || sToken.type != TK_RP) { return tscSQLSyntaxErrMsg(pInsertParam->msg, ") expected", sToken.z); } @@ -1112,9 +1112,9 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC * insert into table_name using super_table(tag_name1, tag_name2) tags(tag_val1, tag_val2) * (normal_col1, normal_col2) values(normal_col1_val, normal_col2_val); * */ - index = 0; - sToken = tStrGetToken(sql, &index, false); - sql += index; + idx = 0; + sToken = tStrGetToken(sql, &idx, false); + sql += idx; int numOfColsAfterTags = 0; if (sToken.type == TK_LP) { if (*boundColumn != NULL) { @@ -1124,18 +1124,18 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } while (1) { - index = 0; - sToken = tStrGetToken(sql, &index, false); + idx = 0; + sToken = tStrGetToken(sql, &idx, false); if (sToken.type == TK_RP) { break; } - if (sToken.n == 0 || sToken.type == TK_SEMI || index == 0) { + if (sToken.n == 0 || sToken.type == TK_SEMI || idx == 0) { return tscSQLSyntaxErrMsg(pCmd->payload, "unexpected token", sql); } - sql += index; + sql += idx; ++numOfColsAfterTags; } @@ -1143,7 +1143,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } - sToken = tStrGetToken(sql, &index, false); + sToken = tStrGetToken(sql, &idx, false); } sql = sToken.z; @@ -1213,9 +1213,9 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat int32_t code = TSDB_CODE_SUCCESS; - int32_t index = 0; - SStrToken sToken = tStrGetToken(str, &index, false); - str += index; + int32_t idx = 0; + SStrToken sToken = tStrGetToken(str, &idx, false); + str += idx; if (sToken.type != TK_LP) { code = tscSQLSyntaxErrMsg(pInsertParam->msg, "( is expected", sToken.z); @@ -1225,9 +1225,9 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat bool isOrdered = true; int32_t lastColIdx = -1; // last column found while (1) { - index = 0; - sToken = tStrGetToken(str, &index, false); - str += index; + idx = 0; + sToken = tStrGetToken(str, &idx, false); + str += idx; char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // used for deleting Escape character backstick(`) strncpy(tmpTokenBuf, sToken.z, sToken.n); @@ -1404,8 +1404,8 @@ int tsParseInsertSql(SSqlObj *pSql) { tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pInsertParam->pTableBlockHashList); while (1) { - int32_t index = 0; - SStrToken sToken = tStrGetToken(str, &index, false); + int32_t idx = 0; + SStrToken sToken = tStrGetToken(str, &idx, false); // no data in the sql string anymore. if (sToken.n == 0) { @@ -1469,9 +1469,9 @@ int tsParseInsertSql(SSqlObj *pSql) { goto _clean; } - index = 0; - sToken = tStrGetToken(str, &index, false); - str += index; + idx = 0; + sToken = tStrGetToken(str, &idx, false); + str += idx; if (sToken.n == 0 || (sToken.type != TK_FILE && sToken.type != TK_VALUES)) { code = tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword VALUES or FILE required", sToken.z); @@ -1484,13 +1484,13 @@ int tsParseInsertSql(SSqlObj *pSql) { goto _clean; } - index = 0; - sToken = tStrGetToken(str, &index, false); + idx = 0; + sToken = tStrGetToken(str, &idx, false); if (sToken.type != TK_STRING && sToken.type != TK_ID) { code = tscSQLSyntaxErrMsg(pInsertParam->msg, "file path is required following keyword FILE", sToken.z); goto _clean; } - str += index; + str += idx; if (sToken.n == 0) { code = tscSQLSyntaxErrMsg(pInsertParam->msg, "file path is required following keyword FILE", sToken.z); goto _clean; @@ -1590,7 +1590,7 @@ int tsInsertInitialCheck(SSqlObj *pSql) { return TSDB_CODE_TSC_NO_WRITE_AUTH; } - int32_t index = 0; + int32_t idx = 0; SSqlCmd *pCmd = &pSql->cmd; pCmd->count = 0; @@ -1600,12 +1600,12 @@ int tsInsertInitialCheck(SSqlObj *pSql) { SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd); TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT); - SStrToken sToken = tStrGetToken(pSql->sqlstr, &index, false); + SStrToken sToken = tStrGetToken(pSql->sqlstr, &idx, false); if (sToken.type != TK_INSERT && sToken.type != TK_IMPORT) { return tscSQLSyntaxErrMsg(pInsertParam->msg, NULL, sToken.z); } - sToken = tStrGetToken(pSql->sqlstr, &index, false); + sToken = tStrGetToken(pSql->sqlstr, &idx, false); if (sToken.type != TK_INTO) { return tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword INTO is expected", sToken.z); } diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index 66280c32e8..8a1eb88e93 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -1966,14 +1966,14 @@ int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value, return TSDB_CODE_SUCCESS; } -static int32_t parseSmlTimeStamp(TAOS_SML_KV **pTS, const char **index, SSmlLinesInfo* info) { +static int32_t parseSmlTimeStamp(TAOS_SML_KV **pTS, const char **idx, SSmlLinesInfo* info) { const char *start, *cur; int32_t ret = TSDB_CODE_SUCCESS; int len = 0; char key[] = "ts"; char *value = NULL; - start = cur = *index; + start = cur = *idx; *pTS = calloc(1, sizeof(TAOS_SML_KV)); while(*cur != '\0') { @@ -2013,8 +2013,8 @@ bool checkDuplicateKey(char *key, SHashObj *pHash, SSmlLinesInfo* info) { return false; } -static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash, SSmlLinesInfo* info) { - const char *cur = *index; +static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **idx, SHashObj *pHash, SSmlLinesInfo* info) { + const char *cur = *idx; char key[TSDB_COL_NAME_LEN + 1]; // +1 to avoid key[len] over write int16_t len = 0; @@ -2048,12 +2048,12 @@ static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash memcpy(pKV->key, key, len + 1); addEscapeCharToString(pKV->key, len); tscDebug("SML:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); - *index = cur + 1; + *idx = cur + 1; return TSDB_CODE_SUCCESS; } -static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, +static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, bool *is_last_kv, SSmlLinesInfo* info, bool isTag) { const char *start, *cur; int32_t ret = TSDB_CODE_SUCCESS; @@ -2077,7 +2077,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, val_rqoute } val_state; - start = cur = *index; + start = cur = *idx; tag_state = tag_common; val_state = val_common; @@ -2100,17 +2100,17 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, } if (*cur == '"') { - if (cur == *index) { + if (cur == *idx) { tag_state = tag_lqoute; } cur += 1; len += 1; break; } else if (*cur == 'L') { - line_len = strlen(*index); + line_len = strlen(*idx); /* common character at the end */ - if (cur + 1 >= *index + line_len) { + if (cur + 1 >= *idx + line_len) { *is_last_kv = true; kv_done = true; break; @@ -2118,7 +2118,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, if (*(cur + 1) == '"') { /* string starts here */ - if (cur + 1 == *index + 1) { + if (cur + 1 == *idx + 1) { tag_state = tag_lqoute; } cur += 2; @@ -2224,7 +2224,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, } if (*cur == '"') { - if (cur == *index) { + if (cur == *idx) { val_state = val_lqoute; } else { if (*(cur - 1) != '\\') { @@ -2238,10 +2238,10 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, len += 1; break; } else if (*cur == 'L') { - line_len = strlen(*index); + line_len = strlen(*idx); /* common character at the end */ - if (cur + 1 >= *index + line_len) { + if (cur + 1 >= *idx + line_len) { *is_last_kv = true; kv_done = true; break; @@ -2249,13 +2249,13 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, if (*(cur + 1) == '"') { /* string starts here */ - if (cur + 1 == *index + 1) { + if (cur + 1 == *idx + 1) { val_state = val_lqoute; cur += 2; len += 2; } else { /* MUST at the end of string */ - if (cur + 2 >= *index + line_len) { + if (cur + 2 >= *idx + line_len) { cur += 2; len += 2; *is_last_kv = true; @@ -2385,7 +2385,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index, } free(value); - *index = (*cur == '\0') ? cur : cur + 1; + *idx = (*cur == '\0') ? cur : cur + 1; return ret; error: @@ -2395,9 +2395,9 @@ error: return ret; } -static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index, +static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **idx, uint8_t *has_tags, SSmlLinesInfo* info) { - const char *cur = *index; + const char *cur = *idx; int16_t len = 0; pSml->stableName = calloc(TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE, 1); @@ -2441,7 +2441,7 @@ static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } addEscapeCharToString(pSml->stableName, len); - *index = cur + 1; + *idx = cur + 1; tscDebug("SML:0x%"PRIx64" Stable name in measurement:%s|len:%d", info->id, pSml->stableName, len); return TSDB_CODE_SUCCESS; @@ -2464,10 +2464,10 @@ int32_t isValidChildTableName(const char *pTbName, int16_t len, SSmlLinesInfo* i static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs, - const char **index, bool isField, + const char **idx, bool isField, TAOS_SML_DATA_POINT* smlData, SHashObj *pHash, SSmlLinesInfo* info) { - const char *cur = *index; + const char *cur = *idx; int32_t ret = TSDB_CODE_SUCCESS; TAOS_SML_KV *pkv; bool is_last_kv = false; @@ -2555,7 +2555,7 @@ static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs, error: return ret; done: - *index = cur; + *idx = cur; return ret; } @@ -2575,13 +2575,13 @@ static void moveTimeStampToFirstKv(TAOS_SML_DATA_POINT** smlData, TAOS_SML_KV *t } int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData, SSmlLinesInfo* info) { - const char* index = sql; + const char* idx = sql; int32_t ret = TSDB_CODE_SUCCESS; uint8_t has_tags = 0; TAOS_SML_KV *timestamp = NULL; SHashObj *keyHashTable = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false); - ret = parseSmlMeasurement(smlData, &index, &has_tags, info); + ret = parseSmlMeasurement(smlData, &idx, &has_tags, info); if (ret) { tscError("SML:0x%"PRIx64" Unable to parse measurement", info->id); taosHashCleanup(keyHashTable); @@ -2591,7 +2591,7 @@ int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData, SSmlLinesInf //Parse Tags if (has_tags) { - ret = parseSmlKvPairs(&smlData->tags, &smlData->tagNum, &index, false, smlData, keyHashTable, info); + ret = parseSmlKvPairs(&smlData->tags, &smlData->tagNum, &idx, false, smlData, keyHashTable, info); if (ret) { tscError("SML:0x%"PRIx64" Unable to parse tag", info->id); taosHashCleanup(keyHashTable); @@ -2601,7 +2601,7 @@ int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData, SSmlLinesInf tscDebug("SML:0x%"PRIx64" Parse tags finished, num of tags:%d", info->id, smlData->tagNum); //Parse fields - ret = parseSmlKvPairs(&smlData->fields, &smlData->fieldNum, &index, true, smlData, keyHashTable, info); + ret = parseSmlKvPairs(&smlData->fields, &smlData->fieldNum, &idx, true, smlData, keyHashTable, info); if (ret) { tscError("SML:0x%"PRIx64" Unable to parse field", info->id); taosHashCleanup(keyHashTable); @@ -2611,7 +2611,7 @@ int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData, SSmlLinesInf taosHashCleanup(keyHashTable); //Parse timestamp - ret = parseSmlTimeStamp(×tamp, &index, info); + ret = parseSmlTimeStamp(×tamp, &idx, info); if (ret) { tscError("SML:0x%"PRIx64" Unable to parse timestamp", info->id); return ret; diff --git a/src/client/src/tscParseOpenTSDB.c b/src/client/src/tscParseOpenTSDB.c index 4b2738e567..525bfa4bd3 100644 --- a/src/client/src/tscParseOpenTSDB.c +++ b/src/client/src/tscParseOpenTSDB.c @@ -33,8 +33,8 @@ static uint64_t genUID() { return id; } -static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, SSmlLinesInfo* info) { - const char *cur = *index; +static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **idx, SSmlLinesInfo* info) { + const char *cur = *idx; uint16_t len = 0; pSml->stableName = tcalloc(TSDB_TABLE_NAME_LEN + TS_BACKQUOTE_CHAR_SIZE, 1); @@ -76,13 +76,13 @@ static int32_t parseTelnetMetric(TAOS_SML_DATA_POINT *pSml, const char **index, } addEscapeCharToString(pSml->stableName, len); - *index = cur + 1; + *idx = cur + 1; tscDebug("OTD:0x%"PRIx64" Stable name in metric:%s|len:%d", info->id, pSml->stableName, len); return TSDB_CODE_SUCCESS; } -static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char **index, SSmlLinesInfo* info) { +static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char **idx, SSmlLinesInfo* info) { //Timestamp must be the first KV to parse assert(*num_kvs == 0); @@ -92,7 +92,7 @@ static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char char key[] = OTD_TIMESTAMP_COLUMN_NAME; char *value = NULL; - start = cur = *index; + start = cur = *idx; //allocate fields for timestamp and value *pTS = tcalloc(OTD_MAX_FIELDS_NUM, sizeof(TAOS_SML_KV)); @@ -130,12 +130,12 @@ static int32_t parseTelnetTimeStamp(TAOS_SML_KV **pTS, int *num_kvs, const char addEscapeCharToString((*pTS)->key, (int32_t)strlen(key)); *num_kvs += 1; - *index = cur + 1; + *idx = cur + 1; return ret; } -static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const char **index, SSmlLinesInfo* info) { +static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const char **idx, SSmlLinesInfo* info) { //skip timestamp TAOS_SML_KV *pVal = *pKVs + 1; const char *start, *cur; @@ -145,7 +145,7 @@ static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const ch char key[] = OTD_METRIC_VALUE_COLUMN_NAME; char *value = NULL; - start = cur = *index; + start = cur = *idx; //if metric value is string if (*cur == '"') { @@ -201,12 +201,12 @@ static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const ch addEscapeCharToString(pVal->key, (int32_t)strlen(pVal->key)); *num_kvs += 1; - *index = cur + 1; + *idx = cur + 1; return ret; } -static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash, SSmlLinesInfo* info) { - const char *cur = *index; +static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **idx, SHashObj *pHash, SSmlLinesInfo* info) { + const char *cur = *idx; char key[TSDB_COL_NAME_LEN]; uint16_t len = 0; @@ -244,17 +244,17 @@ static int32_t parseTelnetTagKey(TAOS_SML_KV *pKV, const char **index, SHashObj memcpy(pKV->key, key, len + 1); addEscapeCharToString(pKV->key, len); //tscDebug("OTD:0x%"PRIx64" Key:%s|len:%d", info->id, pKV->key, len); - *index = cur + 1; + *idx = cur + 1; return TSDB_CODE_SUCCESS; } -static int32_t parseTelnetTagValue(TAOS_SML_KV *pKV, const char **index, +static int32_t parseTelnetTagValue(TAOS_SML_KV *pKV, const char **idx, bool *is_last_kv, SSmlLinesInfo* info) { const char *start, *cur; char *value = NULL; uint16_t len = 0; - start = cur = *index; + start = cur = *idx; while (1) { // whitespace or '\0' identifies a value @@ -290,14 +290,14 @@ static int32_t parseTelnetTagValue(TAOS_SML_KV *pKV, const char **index, } tfree(value); - *index = (*cur == '\0') ? cur : cur + 1; + *idx = (*cur == '\0') ? cur : cur + 1; return TSDB_CODE_SUCCESS; } static int32_t parseTelnetTagKvs(TAOS_SML_KV **pKVs, int *num_kvs, - const char **index, char **childTableName, + const char **idx, char **childTableName, SHashObj *pHash, SSmlLinesInfo* info) { - const char *cur = *index; + const char *cur = *idx; int32_t ret = TSDB_CODE_SUCCESS; TAOS_SML_KV *pkv; bool is_last_kv = false; @@ -357,11 +357,11 @@ static int32_t parseTelnetTagKvs(TAOS_SML_KV **pKVs, int *num_kvs, } static int32_t tscParseTelnetLine(const char* line, TAOS_SML_DATA_POINT* smlData, SSmlLinesInfo* info) { - const char* index = line; + const char* idx = line; int32_t ret = TSDB_CODE_SUCCESS; //Parse metric - ret = parseTelnetMetric(smlData, &index, info); + ret = parseTelnetMetric(smlData, &idx, info); if (ret) { tscError("OTD:0x%"PRIx64" Unable to parse metric", info->id); return ret; @@ -369,7 +369,7 @@ static int32_t tscParseTelnetLine(const char* line, TAOS_SML_DATA_POINT* smlData tscDebug("OTD:0x%"PRIx64" Parse metric finished", info->id); //Parse timestamp - ret = parseTelnetTimeStamp(&smlData->fields, &smlData->fieldNum, &index, info); + ret = parseTelnetTimeStamp(&smlData->fields, &smlData->fieldNum, &idx, info); if (ret) { tscError("OTD:0x%"PRIx64" Unable to parse timestamp", info->id); return ret; @@ -377,7 +377,7 @@ static int32_t tscParseTelnetLine(const char* line, TAOS_SML_DATA_POINT* smlData tscDebug("OTD:0x%"PRIx64" Parse timestamp finished", info->id); //Parse value - ret = parseTelnetMetricValue(&smlData->fields, &smlData->fieldNum, &index, info); + ret = parseTelnetMetricValue(&smlData->fields, &smlData->fieldNum, &idx, info); if (ret) { tscError("OTD:0x%"PRIx64" Unable to parse metric value", info->id); return ret; @@ -386,7 +386,7 @@ static int32_t tscParseTelnetLine(const char* line, TAOS_SML_DATA_POINT* smlData //Parse tagKVs SHashObj *keyHashTable = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false); - ret = parseTelnetTagKvs(&smlData->tags, &smlData->tagNum, &index, &smlData->childTableName, keyHashTable, info); + ret = parseTelnetTagKvs(&smlData->tags, &smlData->tagNum, &idx, &smlData->childTableName, keyHashTable, info); if (ret) { tscError("OTD:0x%"PRIx64" Unable to parse tags", info->id); taosHashCleanup(keyHashTable); diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index 454f158298..665efa4c6d 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -121,11 +121,11 @@ static int normalStmtAddPart(SNormalStmt* stmt, bool isParam, char* str, uint32_ return TSDB_CODE_SUCCESS; } -static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { +static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* pBind) { SNormalStmt* normal = &stmt->normal; for (uint16_t i = 0; i < normal->numParams; ++i) { - TAOS_BIND* tb = bind + i; + TAOS_BIND* tb = pBind + i; tVariant* var = normal->params + i; tVariantDestroy(var); @@ -383,8 +383,8 @@ int32_t fillTablesColumnsNull(SSqlObj* pSql) { //////////////////////////////////////////////////////////////////////////////// // functions for insertion statement preparation -static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, TAOS_BIND* bind, int32_t colNum) { - if (bind->is_null != NULL && *(bind->is_null)) { +static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, TAOS_BIND* pBind, int32_t colNum) { + if (pBind->is_null != NULL && *(pBind->is_null)) { setNull(data + param->offset, param->type, param->bytes); return TSDB_CODE_SUCCESS; } @@ -772,7 +772,7 @@ static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParam } #endif - if (bind->buffer_type != param->type) { + if (pBind->buffer_type != param->type) { tscError("column type mismatch"); return TSDB_CODE_TSC_INVALID_VALUE; } @@ -782,39 +782,39 @@ static FORCE_INLINE int doBindParam(STableDataBlocks* pBlock, char* data, SParam case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_UTINYINT: - *(uint8_t *)(data + param->offset) = *(uint8_t *)bind->buffer; + *(uint8_t *)(data + param->offset) = *(uint8_t *)pBind->buffer; break; case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_USMALLINT: - *(uint16_t *)(data + param->offset) = *(uint16_t *)bind->buffer; + *(uint16_t *)(data + param->offset) = *(uint16_t *)pBind->buffer; break; case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_UINT: case TSDB_DATA_TYPE_FLOAT: - *(uint32_t *)(data + param->offset) = *(uint32_t *)bind->buffer; + *(uint32_t *)(data + param->offset) = *(uint32_t *)pBind->buffer; break; case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_UBIGINT: case TSDB_DATA_TYPE_DOUBLE: case TSDB_DATA_TYPE_TIMESTAMP: - *(uint64_t *)(data + param->offset) = *(uint64_t *)bind->buffer; + *(uint64_t *)(data + param->offset) = *(uint64_t *)pBind->buffer; break; case TSDB_DATA_TYPE_BINARY: - if ((*bind->length) > (uintptr_t)param->bytes) { + if ((*pBind->length) > (uintptr_t)param->bytes) { tscError("column length is too big"); return TSDB_CODE_TSC_INVALID_VALUE; } - size = (short)*bind->length; - STR_WITH_SIZE_TO_VARSTR(data + param->offset, bind->buffer, size); + size = (short)*pBind->length; + STR_WITH_SIZE_TO_VARSTR(data + param->offset, pBind->buffer, size); return TSDB_CODE_SUCCESS; case TSDB_DATA_TYPE_NCHAR: { int32_t output = 0; - if (!taosMbsToUcs4(bind->buffer, *bind->length, varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { + if (!taosMbsToUcs4(pBind->buffer, *pBind->length, varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { tscError("convert nchar failed"); return TSDB_CODE_TSC_INVALID_VALUE; } @@ -889,27 +889,27 @@ static int32_t insertStmtGenBlock(STscStmt* pStmt, STableDataBlocks** pBlock, ST } -static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* bind, int32_t rowNum) { - if (bind->buffer_type != param->type || !isValidDataType(param->type)) { +static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* pBind, int32_t rowNum) { + if (pBind->buffer_type != param->type || !isValidDataType(param->type)) { tscError("column mismatch or invalid"); return TSDB_CODE_TSC_INVALID_VALUE; } - if (IS_VAR_DATA_TYPE(param->type) && bind->length == NULL) { + if (IS_VAR_DATA_TYPE(param->type) && pBind->length == NULL) { tscError("BINARY/NCHAR no length"); return TSDB_CODE_TSC_INVALID_VALUE; } - for (int i = 0; i < bind->num; ++i) { + for (int i = 0; i < pBind->num; ++i) { char* data = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * (rowNum + i); - if (bind->is_null != NULL && bind->is_null[i]) { + if (pBind->is_null != NULL && pBind->is_null[i]) { setNull(data + param->offset, param->type, param->bytes); continue; } if (!IS_VAR_DATA_TYPE(param->type)) { - memcpy(data + param->offset, (char *)bind->buffer + bind->buffer_length * i, tDataTypes[param->type].bytes); + memcpy(data + param->offset, (char *)pBind->buffer + pBind->buffer_length * i, tDataTypes[param->type].bytes); if (param->offset == 0) { if (tsCheckTimestamp(pBlock, data + param->offset) != TSDB_CODE_SUCCESS) { @@ -918,21 +918,21 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU } } } else if (param->type == TSDB_DATA_TYPE_BINARY) { - if (bind->length[i] > (uintptr_t)param->bytes) { - tscError("binary length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)bind->length[i]); + if (pBind->length[i] > (uintptr_t)param->bytes) { + tscError("binary length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)pBind->length[i]); return TSDB_CODE_TSC_INVALID_VALUE; } - int16_t bsize = (short)bind->length[i]; - STR_WITH_SIZE_TO_VARSTR(data + param->offset, (char *)bind->buffer + bind->buffer_length * i, bsize); + int16_t bsize = (short)pBind->length[i]; + STR_WITH_SIZE_TO_VARSTR(data + param->offset, (char *)pBind->buffer + pBind->buffer_length * i, bsize); } else if (param->type == TSDB_DATA_TYPE_NCHAR) { - if (bind->length[i] > (uintptr_t)param->bytes) { - tscError("nchar string length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)bind->length[i]); + if (pBind->length[i] > (uintptr_t)param->bytes) { + tscError("nchar string length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)pBind->length[i]); return TSDB_CODE_TSC_INVALID_VALUE; } int32_t output = 0; - if (!taosMbsToUcs4((char *)bind->buffer + bind->buffer_length * i, bind->length[i], varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { - tscError("convert nchar string to UCS4_LE failed:%s", (char*)((char *)bind->buffer + bind->buffer_length * i)); + if (!taosMbsToUcs4((char *)pBind->buffer + pBind->buffer_length * i, pBind->length[i], varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { + tscError("convert nchar string to UCS4_LE failed:%s", (char*)((char *)pBind->buffer + pBind->buffer_length * i)); return TSDB_CODE_TSC_INVALID_VALUE; } @@ -943,7 +943,7 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU return TSDB_CODE_SUCCESS; } -static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { +static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* pBind) { SSqlCmd* pCmd = &stmt->pSql->cmd; STscStmt* pStmt = (STscStmt*)stmt; @@ -995,7 +995,7 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { for (uint32_t j = 0; j < pBlock->numOfParams; ++j) { SParamInfo* param = &pBlock->params[j]; - int code = doBindParam(pBlock, data, param, &bind[param->idx], 1); + int code = doBindParam(pBlock, data, param, &pBind[param->idx], 1); if (code != TSDB_CODE_SUCCESS) { tscDebug("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind column type mismatch or invalid"); @@ -1006,10 +1006,10 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { } -static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int colIdx) { +static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* pBind, int colIdx) { SSqlCmd* pCmd = &stmt->pSql->cmd; STscStmt* pStmt = (STscStmt*)stmt; - int rowNum = bind->num; + int rowNum = pBind->num; STableDataBlocks* pBlock = NULL; @@ -1063,12 +1063,12 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c if (colIdx == -1) { for (uint32_t j = 0; j < pBlock->numOfParams; ++j) { SParamInfo* param = &pBlock->params[j]; - if (bind[param->idx].num != rowNum) { - tscError("0x%"PRIx64" param %d: num[%d:%d] not match", pStmt->pSql->self, param->idx, rowNum, bind[param->idx].num); + if (pBind[param->idx].num != rowNum) { + tscError("0x%"PRIx64" param %d: num[%d:%d] not match", pStmt->pSql->self, param->idx, rowNum, pBind[param->idx].num); return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind row num mismatch"); } - int code = doBindBatchParam(pBlock, param, &bind[param->idx], pCmd->batchSize); + int code = doBindBatchParam(pBlock, param, &pBind[param->idx], pCmd->batchSize); if (code != TSDB_CODE_SUCCESS) { tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind column type mismatch or invalid"); @@ -1079,7 +1079,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c } else { SParamInfo* param = &pBlock->params[colIdx]; - int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize); + int code = doBindBatchParam(pBlock, param, pBind, pCmd->batchSize); if (code != TSDB_CODE_SUCCESS) { tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); return invalidOperationMsg(tscGetErrorMsgPayload(&stmt->pSql->cmd), "bind column type mismatch or invalid"); @@ -1312,8 +1312,8 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { return ret; } - int32_t index = 0; - SStrToken sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + int32_t idx = 0; + SStrToken sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n == 0) { tscError("table is is expected, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "table name is expected", pCmd->insertParam.sql); @@ -1333,7 +1333,7 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { pStmt->mtb.tagSet = true; - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n > 0 && (sToken.type == TK_VALUES || sToken.type == TK_LP)) { return TSDB_CODE_SUCCESS; } @@ -1343,14 +1343,14 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { return tscSQLSyntaxErrMsg(pCmd->payload, "keywords USING is expected", sToken.z ? sToken.z : pCmd->insertParam.sql); } - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) { tscError("invalid token, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z ? sToken.z : pCmd->insertParam.sql); } pStmt->mtb.stbname = sToken; - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || ((sToken.type != TK_TAGS) && (sToken.type != TK_LP))) { tscError("invalid token, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z ? sToken.z : pCmd->insertParam.sql); @@ -1361,9 +1361,9 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { if (sToken.type == TK_LP) { pStmt->mtb.tagColSet = true; pStmt->mtb.tagCols = sToken; - int32_t tagColsStart = index; + int32_t tagColsStart = idx; while (1) { - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.type == TK_ILLEGAL) { return tscSQLSyntaxErrMsg(pCmd->payload, "unrecognized token", sToken.z); } @@ -1378,16 +1378,16 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { tscError("tag column list expected, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "tag column list expected", pCmd->insertParam.sql); } - pStmt->mtb.tagCols.n = index - tagColsStart + 1; + pStmt->mtb.tagCols.n = idx - tagColsStart + 1; - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || sToken.type != TK_TAGS) { tscError("keyword TAGS expected, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z ? sToken.z : pCmd->insertParam.sql); } } - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || sToken.type != TK_LP) { tscError("( expected, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "( expected", sToken.z ? sToken.z : pCmd->insertParam.sql); @@ -1398,7 +1398,7 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { int32_t loopCont = 1; while (loopCont) { - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0) { tscError("unexpected sql end, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "unexpected sql end", pCmd->insertParam.sql); @@ -1429,7 +1429,7 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { return tscSQLSyntaxErrMsg(pCmd->payload, "not match tags", pCmd->insertParam.sql); } - sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + sToken = tStrGetToken(pCmd->insertParam.sql, &idx, false); if (sToken.n <= 0 || (sToken.type != TK_VALUES && sToken.type != TK_LP)) { tscError("sql error, sql:%s", pCmd->insertParam.sql); return tscSQLSyntaxErrMsg(pCmd->payload, "sql error", sToken.z ? sToken.z : pCmd->insertParam.sql); @@ -1944,7 +1944,7 @@ int taos_stmt_close(TAOS_STMT* stmt) { STMT_RET(TSDB_CODE_SUCCESS); } -int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) { +int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* pBind) { STscStmt* pStmt = (STscStmt*)stmt; STMT_CHECK @@ -1965,18 +1965,18 @@ int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) { tscDebug("tableId:%" PRIu64 ", try to bind one row", pStmt->mtb.currentUid); - STMT_RET(insertStmtBindParam(pStmt, bind)); + STMT_RET(insertStmtBindParam(pStmt, pBind)); } else { - STMT_RET(normalStmtBindParam(pStmt, bind)); + STMT_RET(normalStmtBindParam(pStmt, pBind)); } } -int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) { +int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* pBind) { STscStmt* pStmt = (STscStmt*)stmt; STMT_CHECK - if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) { + if (pBind == NULL || pBind->num <= 0 || pBind->num > INT16_MAX) { tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self); STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "invalid bind param")); } @@ -2000,21 +2000,21 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) { pStmt->last = STMT_BIND; - STMT_RET(insertStmtBindParamBatch(pStmt, bind, -1)); + STMT_RET(insertStmtBindParamBatch(pStmt, pBind, -1)); } -int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int colIdx) { +int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* pBind, int colIdx) { STscStmt* pStmt = (STscStmt*)stmt; STMT_CHECK - if (bind == NULL) { + if (pBind == NULL) { tscError("0x%" PRIx64 " invalid parameter: bind is NULL", pStmt->pSql->self); STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), "invalid bind param: bind is NULL")); } - if (bind->num <= 0 || bind->num > INT16_MAX) { + if (pBind->num <= 0 || pBind->num > INT16_MAX) { char errMsg[128]; - sprintf(errMsg, "invalid parameter: bind->num:%d out of range [0, %d)", bind->num, INT16_MAX); + sprintf(errMsg, "invalid parameter: bind->num:%d out of range [0, %d)", pBind->num, INT16_MAX); tscError("0x%" PRIx64 " %s", pStmt->pSql->self, errMsg); STMT_RET(invalidOperationMsg(tscGetErrorMsgPayload(&pStmt->pSql->cmd), errMsg)); } @@ -2045,7 +2045,7 @@ int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, in pStmt->last = STMT_BIND_COL; - STMT_RET(insertStmtBindParamBatch(pStmt, bind, colIdx)); + STMT_RET(insertStmtBindParamBatch(pStmt, pBind, colIdx)); } int taos_stmt_add_batch(TAOS_STMT* stmt) { diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 22456782d0..bb31b752a1 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -47,11 +47,11 @@ #define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey)) -// -1 is tbname column index, so here use the -2 as the initial value +// -1 is tbname column idx, so here use the -2 as the initial value #define COLUMN_INDEX_INITIAL_VAL (-2) #define COLUMN_INDEX_INITIALIZER \ { COLUMN_INDEX_INITIAL_VAL, COLUMN_INDEX_INITIAL_VAL } -#define COLUMN_INDEX_VALID(index) (((index).tableIndex >= 0) && ((index).columnIndex >= TSDB_MIN_VALID_COLUMN_INDEX)) +#define COLUMN_INDEX_VALID(idx) (((idx).tableIndex >= 0) && ((idx).columnIndex >= TSDB_MIN_VALID_COLUMN_INDEX)) #define TBNAME_LIST_SEP "," typedef struct SColumnList { // todo refactor @@ -335,21 +335,21 @@ static int32_t invalidOperationMsg(char* dstBuffer, const char* errMsg) { } static int convertTimestampStrToInt64(tVariant *pVar, int32_t precision) { - int64_t time = 0; + int64_t t = 0; stringProcess(pVar->pz, pVar->nLen); char* seg = strnchr(pVar->pz, '-', pVar->nLen, false); if (seg != NULL) { - if (taosParseTime(pVar->pz, &time, pVar->nLen, precision, tsDaylight) != TSDB_CODE_SUCCESS) { + if (taosParseTime(pVar->pz, &t, pVar->nLen, precision, tsDaylight) != TSDB_CODE_SUCCESS) { return -1; } } else { - if (tVariantDump(pVar, (char*)&time, TSDB_DATA_TYPE_BIGINT, true)) { + if (tVariantDump(pVar, (char*)&t, TSDB_DATA_TYPE_BIGINT, true)) { return -1; } } tVariantDestroy(pVar); - tVariantCreateFromBinary(pVar, (char*)&time, 0, TSDB_DATA_TYPE_BIGINT); + tVariantCreateFromBinary(pVar, (char*)&t, 0, TSDB_DATA_TYPE_BIGINT); return 0; } static int setColumnFilterInfoForTimestamp(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tVariant* pVar) { @@ -1155,8 +1155,8 @@ static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo, SSql tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name)); } - SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL, 0); + SColumnIndex idx = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &idx, &s, TSDB_COL_NORMAL, 0); return TSDB_CODE_SUCCESS; } @@ -1303,17 +1303,17 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(col, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(col, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); - } else if (index.columnIndex >= numOfCols) { + } else if (idx.columnIndex >= numOfCols) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } @@ -1322,7 +1322,7 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex)); } - SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE || pSchema->type == TSDB_DATA_TYPE_NCHAR || pSchema->type == TSDB_DATA_TYPE_BINARY) { @@ -1345,8 +1345,8 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS } } - tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); - SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; + tscColumnListInsert(pQueryInfo->colList, idx.columnIndex, pTableMeta->id.uid, pSchema); + SColIndex colIndex = { .colIndex = idx.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; taosArrayPush(pGroupExpr->columnInfo, &colIndex); pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC; pQueryInfo->stateWindow = true; @@ -1386,11 +1386,11 @@ int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pS return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(col, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(col, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } @@ -1947,8 +1947,8 @@ static int32_t handleScalarTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = {.tableIndex = tableIndex}; - SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_SCALAR_EXPR, &index, pNode->resultType, pNode->resultBytes, + SColumnIndex idx = {.tableIndex = tableIndex}; + SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_SCALAR_EXPR, &idx, pNode->resultType, pNode->resultBytes, getNewResColId(pCmd), 0, false); // set the colId to the result column id pExpr->base.colInfo.colId = pExpr->base.resColId; @@ -2130,9 +2130,9 @@ static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) { SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, PRIMARYKEY_TIMESTAMP_COL_INDEX); // add the timestamp column into the output columns - SColumnIndex index = {0}; // primary timestamp column info + SColumnIndex idx = {0}; // primary timestamp column info int32_t numOfCols = (int32_t)tscNumOfFields(pQueryInfo); - tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &idx, pSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); SInternalField* pSupInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfCols); pSupInfo->visible = false; @@ -2394,16 +2394,16 @@ SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tab SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex); int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ); - SColumnIndex index = {.tableIndex = tableIndex,}; + SColumnIndex idx = {.tableIndex = tableIndex,}; if (functionId == TSDB_FUNC_TAGPRJ) { - index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); + idx.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta); + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMeta->id.uid, pSchema); } else { - index.columnIndex = colIndex; + idx.columnIndex = colIndex; } - return tscExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes, colId, 0, + return tscExprAppend(pQueryInfo, functionId, &idx, pSchema->type, pSchema->bytes, colId, 0, (functionId == TSDB_FUNC_TAGPRJ)); } @@ -2476,41 +2476,41 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t if (tokenId == TK_ALL) { // project on all fields TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY); - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getTableIndexByName(&pItem->pNode->columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getTableIndexByName(&pItem->pNode->columnName, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } // all meters columns are required - if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) { // all table columns are required. + if (idx.tableIndex == COLUMN_INDEX_INITIAL_VAL) { // all table columns are required. for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - index.tableIndex = i; - int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos, pCmd); + idx.tableIndex = i; + int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &idx, startPos, pCmd); startPos += inc; } } else { - doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos, pCmd); + doAddProjectionExprAndResultFields(pQueryInfo, &idx, startPos, pCmd); } // add the primary timestamp column even though it is not required by user - STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[index.tableIndex]->pTableMeta; + STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[idx.tableIndex]->pTableMeta; if (pTableMeta->tableType != TSDB_TEMP_TABLE) { tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMeta->id.uid); } } else if (tokenId == TK_STRING || tokenId == TK_INTEGER || tokenId == TK_FLOAT || tokenId == TK_BOOL) { // simple column projection query - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; // user-specified constant value as a new result column - index.columnIndex = (pQueryInfo->udColumnId--); - index.tableIndex = 0; + idx.columnIndex = (pQueryInfo->udColumnId--); + idx.tableIndex = 0; SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->value, &pItem->pNode->exprToken, pItem->aliasName); - SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC, + SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &idx, &colSchema, TSDB_COL_UDC, getNewResColId(pCmd)); tVariantAssign(&pExpr->base.param[pExpr->base.numOfParams++], &pItem->pNode->value); }else if (tokenId == TK_ID || tokenId == TK_ARROW) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; SStrToken* pToken = NULL; if (tokenId == TK_ARROW){ @@ -2530,35 +2530,35 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t pToken = &pItem->pNode->columnName; } - if (getColumnIndexByName(pToken, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } //for tbname and other pseudo columns - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || TSDB_COL_IS_TSWIN_COL(index.columnIndex)) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX || TSDB_COL_IS_TSWIN_COL(idx.columnIndex)) { if (outerQuery) { - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); bool existed = false; SSchema* pSchema = pTableMetaInfo->pTableMeta->schema; for (int32_t i = 0; i < numOfCols; ++i) { if ((strncasecmp(pSchema[i].name, TSQL_TBNAME_L, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) || + idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_TSWIN_START, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_TSWIN_START_COLUMN_INDEX) || + idx.columnIndex == TSDB_TSWIN_START_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_TSWIN_STOP, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_TSWIN_STOP_COLUMN_INDEX) || + idx.columnIndex == TSDB_TSWIN_STOP_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_TSWIN_DURATION, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_TSWIN_DURATION_COLUMN_INDEX) || + idx.columnIndex == TSDB_TSWIN_DURATION_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_QUERY_START, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_QUERY_START_COLUMN_INDEX) || + idx.columnIndex == TSDB_QUERY_START_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_QUERY_STOP, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_QUERY_STOP_COLUMN_INDEX) || + idx.columnIndex == TSDB_QUERY_STOP_COLUMN_INDEX) || (strncasecmp(pSchema[i].name, TSQL_QUERY_DURATION, tListLen(pSchema[i].name)) == 0 && - index.columnIndex == TSDB_QUERY_DURATION_COLUMN_INDEX)) { + idx.columnIndex == TSDB_QUERY_DURATION_COLUMN_INDEX)) { existed = true; - index.columnIndex = i; + idx.columnIndex = i; break; } } @@ -2567,47 +2567,47 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - SSchema colSchema = pSchema[index.columnIndex]; + SSchema colSchema = pSchema[idx.columnIndex]; char name[TSDB_COL_NAME_LEN] = {0}; getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1); tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN); - /*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, + /*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &idx, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); } else { SSchema colSchema; int16_t functionId, colType; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { colSchema = *tGetTbnameColumnSchema(); functionId = TSDB_FUNC_TAGPRJ; colType = TSDB_COL_TAG; } else { - if (!timeWindowQuery && (index.columnIndex == TSDB_TSWIN_START_COLUMN_INDEX || - index.columnIndex == TSDB_TSWIN_STOP_COLUMN_INDEX || - index.columnIndex == TSDB_TSWIN_DURATION_COLUMN_INDEX)) { + if (!timeWindowQuery && (idx.columnIndex == TSDB_TSWIN_START_COLUMN_INDEX || + idx.columnIndex == TSDB_TSWIN_STOP_COLUMN_INDEX || + idx.columnIndex == TSDB_TSWIN_DURATION_COLUMN_INDEX)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } - colSchema = *tGetTimeWindowColumnSchema(index.columnIndex); - functionId = getTimeWindowFunctionID(index.columnIndex); + colSchema = *tGetTimeWindowColumnSchema(idx.columnIndex); + functionId = getTimeWindowFunctionID(idx.columnIndex); colType = TSDB_COL_NORMAL; } char name[TSDB_COL_NAME_LEN] = {0}; getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1); tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN); - /*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, functionId, &index, &colSchema, + /*SExprInfo* pExpr = */ tscAddFuncInSelectClause(pQueryInfo, startPos, functionId, &idx, &colSchema, colType, getNewResColId(pCmd)); } pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; } else { - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { + if (idx.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); if (tokenId == TK_ARROW && pSchema->type != TSDB_DATA_TYPE_JSON) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } @@ -2615,12 +2615,12 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - addProjectQueryCol(pQueryInfo, startPos, &index, pItem, getNewResColId(pCmd)); + addProjectQueryCol(pQueryInfo, startPos, &idx, pItem, getNewResColId(pCmd)); pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; } // add the primary timestamp column even though it is not required by user - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); if (!UTIL_TABLE_IS_TMP_TABLE(pTableMetaInfo)) { tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); } @@ -2690,24 +2690,24 @@ void setResultColName(char* name, bool finalResult, tSqlExprItem* pItem, int32_t if (pItem->aliasName != NULL) { tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN); } else { - char uname[TSDB_COL_NAME_LEN] = {0}; + char colName[TSDB_COL_NAME_LEN] = {0}; int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN); - tstrncpy(uname, pToken->z, len); + tstrncpy(colName, pToken->z, len); if (finalResult && tsKeepOriginalColumnName) { // keep the original column name - tstrncpy(name, uname, TSDB_COL_NAME_LEN); + tstrncpy(name, colName, TSDB_COL_NAME_LEN); } else if (multiCols) { if (!TSDB_FUNC_IS_SCALAR(functionId)) { int32_t size = TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].name) + 2 + 1; char tmp[TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].name) + 2 + 1] = {0}; - snprintf(tmp, size, "%s(%s)", aAggs[functionId].name, uname); + snprintf(tmp, size, "%s(%s)", aAggs[functionId].name, colName); tstrncpy(name, tmp, TSDB_COL_NAME_LEN); } else { - int32_t index = TSDB_FUNC_SCALAR_INDEX(functionId); - int32_t size = TSDB_COL_NAME_LEN + tListLen(aScalarFunctions[index].name) + 2 + 1; - char tmp[TSDB_COL_NAME_LEN + tListLen(aScalarFunctions[index].name) + 2 + 1] = {0}; - snprintf(tmp, size, "%s(%s)", aScalarFunctions[index].name, uname); + int32_t idx = TSDB_FUNC_SCALAR_INDEX(functionId); + int32_t size = TSDB_COL_NAME_LEN + tListLen(aScalarFunctions[idx].name) + 2 + 1; + char tmp[TSDB_COL_NAME_LEN + tListLen(aScalarFunctions[idx].name) + 2 + 1] = {0}; + snprintf(tmp, size, "%s(%s)", aScalarFunctions[idx].name, colName); tstrncpy(name, tmp, TSDB_COL_NAME_LEN); } @@ -2793,7 +2793,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } SExprInfo* pExpr = NULL; - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; if (pItem->pNode->Expr.paramList != NULL) { tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0); @@ -2808,47 +2808,47 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // check if the table name is valid or not SStrToken tmpToken = pParamElem->pNode->columnName; - if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + if (getTableIndexByName(&tmpToken, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + idx = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, false); } else { // count the number of table created according to the super table - if (getColumnIndexByName(pToken, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); // count tag is equalled to count(tbname) bool isTag = false; - if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || - index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { - index.columnIndex = TSDB_TBNAME_COLUMN_INDEX; + if (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta) || + idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + idx.columnIndex = TSDB_TBNAME_COLUMN_INDEX; isTag = true; } int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, isTag); } } else { // count(*) is equalled to count(primary_timestamp_key) - index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + idx = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, false); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); - SColumnList list = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList list = createColumnList(1, idx.tableIndex, idx.columnIndex); if (finalResult) { int32_t numOfOutput = tscNumOfFields(pQueryInfo); insertResultField(pQueryInfo, numOfOutput, &list, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, pExpr->base.aliasName, @@ -2862,7 +2862,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // the time stamp may be always needed - if (index.tableIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { + if (idx.tableIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); } @@ -2876,6 +2876,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col case TSDB_FUNC_TWA: case TSDB_FUNC_MIN: case TSDB_FUNC_MAX: + case TSDB_FUNC_MIN_ROW: + case TSDB_FUNC_MAX_ROW: case TSDB_FUNC_DIFF: case TSDB_FUNC_DERIVATIVE: case TSDB_FUNC_CSUM: @@ -2908,18 +2910,18 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pColumnSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pColumnSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); // elapsed only can be applied to primary key if (functionId == TSDB_FUNC_ELAPSED) { - if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX || + if (idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX || pColumnSchema->colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "elapsed only can be applied to primary key"); } @@ -2945,13 +2947,13 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col STableComInfo info = tscGetTableInfo(pTableMetaInfo->pTableMeta); // functions can not be applied to tags - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || - (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta))) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX || + (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta))) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } // 2. check if sql function can be applied on this column data type - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); if (functionId == TSDB_FUNC_MODE && pColumnSchema->colId == PRIMARYKEY_TIMESTAMP_COL_INDEX && pColumnSchema->type == TSDB_DATA_TYPE_TIMESTAMP){ @@ -2962,6 +2964,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); + } else if (!IS_NUMERIC_TYPE(pSchema->type) && (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW)) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } int16_t resultType = 0; @@ -2975,7 +2979,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // set the first column ts for diff query if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE || functionId == TSDB_FUNC_CSUM) { - SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; + SColumnIndex indexTS = {.tableIndex = idx.tableIndex, .columnIndex = 0}; SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0, TSDB_KEYSIZE, false); tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS_DUMMY].name, sizeof(pExpr->base.aliasName)); @@ -2986,7 +2990,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } if (functionId == TSDB_FUNC_STATE_COUNT || functionId == TSDB_FUNC_STATE_DURATION) { - SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; + SColumnIndex indexTS = {.tableIndex = idx.tableIndex, .columnIndex = 0}; SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_PRJ, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0, TSDB_KEYSIZE, false); tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS_DUMMY].name, sizeof(pExpr->base.aliasName)); @@ -2995,15 +2999,15 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col insertResultField(pQueryInfo, colIndex, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].name, pExpr); - pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_PRJ, &index, pSchema->type, + pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_PRJ, &idx, pSchema->type, pSchema->bytes, getNewResColId(pCmd), 0, false); tstrncpy(pExpr->base.aliasName, pParamElem->pNode->columnName.z, pParamElem->pNode->columnName.n+1); - ids = createColumnList(1, index.tableIndex, index.columnIndex); + ids = createColumnList(1, idx.tableIndex, idx.columnIndex); insertResultField(pQueryInfo, colIndex + 1, &ids, pExpr->base.resBytes, (int32_t)pExpr->base.resType, pExpr->base.aliasName, pExpr); } - SExprInfo* pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), + SExprInfo* pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), intermediateResSize, false); if (functionId == TSDB_FUNC_LEASTSQR) { // set the leastsquares parameters @@ -3118,7 +3122,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } } - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); @@ -3168,55 +3172,55 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; if (pParamElem->pNode->tokenId == TK_ALL) { // select table.* SStrToken tmpToken = pParamElem->pNode->columnName; - if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + if (getTableIndexByName(&tmpToken, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); char name[TSDB_COL_NAME_LEN] = {0}; for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) { - index.columnIndex = j; + idx.columnIndex = j; SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)}; setResultColName(name, finalResult, pItem, cvtFunc.originFuncId, &t, true); - if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult, + if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &idx, finalResult, pUdfInfo) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } } } else { - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); if (pParamElem->pNode->columnName.z == NULL) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } // functions can not be applied to tags - if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) { + if ((idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (idx.columnIndex < 0)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } char name[TSDB_COL_NAME_LEN] = {0}; - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1; setResultColName(name, finalResult, pItem, cvtFunc.originFuncId, &pParamElem->pNode->columnName, multiColOutput); - if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex++, &index, finalResult, + if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex++, &idx, finalResult, pUdfInfo) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -3236,13 +3240,13 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) { - SColumnIndex index = {.tableIndex = j, .columnIndex = i}; + SColumnIndex idx = {.tableIndex = j, .columnIndex = i}; char name[TSDB_COL_NAME_LEN] = {0}; SStrToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)}; setResultColName(name, finalResult, pItem, cvtFunc.originFuncId, &t, true); - if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, + if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[idx.columnIndex], cvtFunc, name, colIndex, &idx, finalResult, pUdfInfo) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -3284,26 +3288,26 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); - if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX && pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && + if (idx.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX && pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && (functionId == TSDB_FUNC_UNIQUE || functionId == TSDB_FUNC_TAIL)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg29); } // functions can not be applied to tags - if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { + if (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } @@ -3352,7 +3356,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); colIndex += 1; // the first column is ts - pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), interResult, false); tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); @@ -3398,12 +3402,12 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // todo REFACTOR // set the first column ts for top/bottom query int32_t tsFuncId = (functionId == TSDB_FUNC_MAVG) ? TSDB_FUNC_TS_DUMMY : TSDB_FUNC_TS; - SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + SColumnIndex index1 = {idx.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; pExpr = tscExprAppend(pQueryInfo, tsFuncId, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0, 0, false); tstrncpy(pExpr->base.aliasName, aAggs[tsFuncId].name, sizeof(pExpr->base.aliasName)); const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX; - SColumnList ids = createColumnList(1, index.tableIndex, TS_COLUMN_INDEX); + SColumnList ids = createColumnList(1, idx.tableIndex, TS_COLUMN_INDEX); insertResultField(pQueryInfo, colIndex, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[tsFuncId].name, pExpr); @@ -3411,7 +3415,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col getResultDataInfo(pSchema->type, pSchema->bytes, functionId, (int32_t)numRowsSelected, &resultType, &resultSize, &interResult, 0, false, pUdfInfo); - pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), interResult, false); tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); } else { @@ -3427,19 +3431,19 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // todo REFACTOR // set the first column ts for top/bottom query - SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + SColumnIndex index1 = {idx.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0, 0, false); tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->base.aliasName)); const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX; - SColumnList ids = createColumnList(1, index.tableIndex, TS_COLUMN_INDEX); + SColumnList ids = createColumnList(1, idx.tableIndex, TS_COLUMN_INDEX); insertResultField(pQueryInfo, colIndex, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].name, pExpr); colIndex += 1; // the first column is ts getResultDataInfo(pSchema->type, pSchema->bytes, functionId, (int32_t)numRowsSelected, &resultType, &resultSize, &interResult, 0, false, pUdfInfo); - pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), interResult, false); if (functionId == TSDB_FUNC_TAIL){ int64_t offset = 0; @@ -3466,7 +3470,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); // todo refactor: tscColumnListInsert part - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); if (finalResult) { insertResultField(pQueryInfo, colIndex, &ids, resultSize, (int8_t)resultType, pExpr->base.aliasName, pExpr); @@ -3492,46 +3496,46 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col tSqlExprItem* pParamItem = taosArrayGet(pItem->pNode->Expr.paramList, 0); tSqlExpr* pParam = pParamItem->pNode; - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pParam->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pParam->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); // functions can not be applied to normal columns int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex < numOfCols && idx.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - if (index.columnIndex > 0) { - index.columnIndex -= numOfCols; + if (idx.columnIndex > 0) { + idx.columnIndex -= numOfCols; } // 2. valid the column type int16_t colType = 0; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { colType = TSDB_DATA_TYPE_BINARY; } else { - colType = pSchema[index.columnIndex].type; + colType = pSchema[idx.columnIndex].type; } if (colType == TSDB_DATA_TYPE_BOOL) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, - &pSchema[index.columnIndex]); + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMetaInfo->pTableMeta->id.uid, + &pSchema[idx.columnIndex]); SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); SSchema s = {0}; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { s = *tGetTbnameColumnSchema(); } else { - s = pTagSchema[index.columnIndex]; + s = pTagSchema[idx.columnIndex]; } int32_t bytes = 0; @@ -3545,7 +3549,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col s.bytes = bytes; TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY); - tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TID_TAG, &index, &s, TSDB_COL_TAG, getNewResColId(pCmd)); + tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TID_TAG, &idx, &s, TSDB_COL_TAG, getNewResColId(pCmd)); return TSDB_CODE_SUCCESS; } @@ -3556,11 +3560,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = { + SColumnIndex idx = { .tableIndex = 0, .columnIndex = 0, }; - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); int32_t inter = 0; int16_t resType = 0; @@ -3571,10 +3575,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SSchema s = {.name = "block_dist", .type = TSDB_DATA_TYPE_BINARY, .bytes = bytes}; SExprInfo* pExpr = - tscExprInsert(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, resType, bytes, getNewResColId(pCmd), bytes, 0); + tscExprInsert(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &idx, resType, bytes, getNewResColId(pCmd), bytes, 0); tstrncpy(pExpr->base.aliasName, s.name, sizeof(pExpr->base.aliasName)); - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); insertResultField(pQueryInfo, 0, &ids, bytes, s.type, s.name, pExpr); pExpr->base.numOfParams = 1; @@ -3595,18 +3599,18 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); if (!IS_NUMERIC_TYPE(pSchema->type)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -3768,7 +3772,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col getResultDataInfo(pSchema->type, pSchema->bytes, functionId, counter, &resultType, &resultSize, &interResult, 0, false, pUdfInfo); SExprInfo* pExpr = NULL; - pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), interResult, + pExpr = tscExprAppend(pQueryInfo, functionId, &idx, resultType, resultSize, getNewResColId(pCmd), interResult, false); numOutput = numBins - 1; tscExprAddParams(&pExpr->base, (char*)&numOutput, TSDB_DATA_TYPE_INT, sizeof(int32_t)); @@ -3796,7 +3800,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); // todo refactor: tscColumnListInsert part - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); if (finalResult) { insertResultField(pQueryInfo, colIndex, &ids, resultSize, (int8_t)resultType, pExpr->base.aliasName, pExpr); @@ -3826,20 +3830,20 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); // functions can not be applied to tags - if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { + if (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } @@ -3849,21 +3853,21 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, false, pUdfInfo); SExprInfo* pExpr = - tscExprAppend(pQueryInfo, functionId, &index, resType, bytes, getNewResColId(pCmd), inter, false); + tscExprAppend(pQueryInfo, functionId, &idx, resType, bytes, getNewResColId(pCmd), inter, false); memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token, sizeof(pExpr->base.aliasName) - 1); - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; - SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + SColumnList ids = createColumnList(1, idx.tableIndex, idx.columnIndex); if (finalResult) { insertResultField(pQueryInfo, colIndex, &ids, pUdfInfo->resBytes, pUdfInfo->resType, pExpr->base.aliasName, pExpr); } else { for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, index.columnIndex, uid, pSchema); + tscColumnListInsert(pQueryInfo->colList, idx.columnIndex, uid, pSchema); } } tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); @@ -3880,9 +3884,9 @@ static SColumnList createColumnList(int32_t num, int16_t tableIndex, int32_t col SColumnList columnList = {0}; columnList.num = num; - int32_t index = num - 1; - columnList.ids[index].tableIndex = tableIndex; - columnList.ids[index].columnIndex = columnIndex; + int32_t idx = num - 1; + columnList.ids[idx].tableIndex = tableIndex; + columnList.ids[idx].columnIndex = columnIndex; return columnList; } @@ -3936,8 +3940,8 @@ static bool isTimeWindowToken(SStrToken* token, int16_t *columnIndex) { } } -static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken* pToken) { - STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index)->pTableMeta; +static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t idx, SStrToken* pToken) { + STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, idx)->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta) + tscGetNumOfTags(pTableMeta); SSchema* pSchema = tscGetTableSchema(pTableMeta); @@ -3968,10 +3972,6 @@ int32_t doGetColumnIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColum const char* msg0 = "ambiguous column name"; const char* msg1 = "invalid column name"; - if (pToken->n == 0) { - return TSDB_CODE_TSC_INVALID_OPERATION; - } - int16_t tsWinColumnIndex; if (isTablenameToken(pToken)) { pIndex->columnIndex = TSDB_TBNAME_COLUMN_INDEX; @@ -3981,7 +3981,7 @@ int32_t doGetColumnIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColum } else if (isTimeWindowToken(pToken, &tsWinColumnIndex)) { pIndex->columnIndex = tsWinColumnIndex; } else { - // not specify the table name, try to locate the table index by column name + // not specify the table name, try to locate the table idx by column name if (pIndex->tableIndex == COLUMN_INDEX_INITIAL_VAL) { for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) { int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken); @@ -3995,7 +3995,7 @@ int32_t doGetColumnIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColum } } } - } else { // table index is valid, get the column index + } else { // table idx is valid, get the column idx int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken); if (colIndex != COLUMN_INDEX_INITIAL_VAL) { pIndex->columnIndex = colIndex; @@ -4057,6 +4057,12 @@ int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIn } int32_t getColumnIndexByName(const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex, char* msg) { + const char* msg0 = "invalid column name"; + + if (pToken->n == 0) { + return invalidOperationMsg(msg, msg0); + } + if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -4535,24 +4541,24 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd } } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&token, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&token, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } if (tableIndex == COLUMN_INDEX_INITIAL_VAL) { - tableIndex = index.tableIndex; - } else if (tableIndex != index.tableIndex) { + tableIndex = idx.tableIndex; + } else if (tableIndex != idx.tableIndex) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { pSchema = tGetTbnameColumnSchema(); } else { - pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); } if (pSchema->type == TSDB_DATA_TYPE_JSON && !pItem->isJsonExp){ @@ -4563,15 +4569,15 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd } int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - bool groupTag = (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols); + bool groupTag = (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX || idx.columnIndex >= numOfCols); if (groupTag) { if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - int32_t relIndex = index.columnIndex; - if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { + int32_t relIndex = idx.columnIndex; + if (idx.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { relIndex -= numOfCols; } @@ -4587,17 +4593,17 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd taosArrayPush(pGroupExpr->columnInfo, &colIndex); - index.columnIndex = relIndex; - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); + idx.columnIndex = relIndex; + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMeta->id.uid, pSchema); } else { // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by if (pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } - tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); + tscColumnListInsert(pQueryInfo->colList, idx.columnIndex, pTableMeta->id.uid, pSchema); - SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; + SColIndex colIndex = { .colIndex = idx.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; strncpy(colIndex.name, pSchema->name, tListLen(colIndex.name)); taosArrayPush(pGroupExpr->columnInfo, &colIndex); @@ -4929,9 +4935,9 @@ static int32_t checkColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return checkColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->tokenId); } else { // handle leaf node - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - addAllColumn(pCmd, pQueryInfo, pExpr, pExpr->tokenId, &index); - return checkColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr); + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + addAllColumn(pCmd, pQueryInfo, pExpr, pExpr->tokenId, &idx); + return checkColumnFilterInfo(pCmd, pQueryInfo, &idx, pExpr, relOptr); } return TSDB_CODE_SUCCESS; } @@ -4965,17 +4971,17 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS pRight = pRight->pLeft; } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pTagSchema1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pTagSchema1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); - assert(index.tableIndex >= 0 && index.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); + assert(idx.tableIndex >= 0 && idx.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); - SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; + SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[idx.tableIndex]; if (*leftNode == NULL) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -4989,9 +4995,9 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + idx.columnIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); if (tscColumnExists(pTableMetaInfo->tagColList, pTagSchema1->colId, pTableMetaInfo->pTableMeta->id.uid) < 0) { - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema1); + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMeta->id.uid, pTagSchema1); atomic_add_fetch_32(&pTableMetaInfo->joinTagNum, 1); if (pTableMetaInfo->joinTagNum > 1) { @@ -5000,19 +5006,19 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS } } - int16_t leftIdx = index.tableIndex; + int16_t leftIdx = idx.tableIndex; - index = (SColumnIndex)COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pRight->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + idx = (SColumnIndex)COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pRight->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pTagSchema2 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SSchema* pTagSchema2 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); - assert(index.tableIndex >= 0 && index.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); + assert(idx.tableIndex >= 0 && idx.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); - SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; + SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[idx.tableIndex]; if (*rightNode == NULL) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -5025,10 +5031,10 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMeta); + idx.columnIndex = idx.columnIndex - tscGetNumOfColumns(pTableMeta); if (tscColumnExists(pTableMetaInfo->tagColList, pTagSchema2->colId, pTableMeta->id.uid) < 0) { - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema2); + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMeta->id.uid, pTagSchema2); atomic_add_fetch_32(&pTableMetaInfo->joinTagNum, 1); if (pTableMetaInfo->joinTagNum > 1) { @@ -5037,7 +5043,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS } } - int16_t rightIdx = index.tableIndex; + int16_t rightIdx = idx.tableIndex; if (pTagSchema1->type != pTagSchema2->type) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); @@ -5290,14 +5296,14 @@ static int32_t validateSQLExprItem(SSqlCmd* pCmd, tSqlExpr* pExpr, return ret; } } else if (pExpr->type == SQL_NODE_TABLE_COLUMN) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != + if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - pList->ids[pList->num++] = index; + pList->ids[pList->num++] = idx; *type = SQLEXPR_TYPE_SCALAR; } else if (pExpr->type == SQL_NODE_DATA_TYPE) { if (pExpr->dataType.type < 0 || pExpr->dataType.bytes <= 0) { @@ -5493,17 +5499,17 @@ static int32_t setNormalExprToCond(tSqlExpr** parent, tSqlExpr* pExpr, int32_t p } -static int32_t validateNullExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t index, char* msgBuf) { +static int32_t validateNullExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t idx, char* msgBuf) { const char* msg = "only support is [not] null"; tSqlExpr* pRight = pExpr->pRight; SSchema* pSchema = tscGetTableSchema(pTableMeta); - if (pRight->tokenId == TK_NULL && pSchema[index].type != TSDB_DATA_TYPE_JSON && (!(pExpr->tokenId == TK_ISNULL || pExpr->tokenId == TK_NOTNULL))) { + if (pRight->tokenId == TK_NULL && pSchema[idx].type != TSDB_DATA_TYPE_JSON && (!(pExpr->tokenId == TK_ISNULL || pExpr->tokenId == TK_NOTNULL))) { return invalidOperationMsg(msgBuf, msg); } if (pRight->tokenId == TK_STRING) { - if (IS_VAR_DATA_TYPE(pSchema[index].type) || pSchema[index].type == TSDB_DATA_TYPE_JSON) { + if (IS_VAR_DATA_TYPE(pSchema[idx].type) || pSchema[idx].type == TSDB_DATA_TYPE_JSON) { return TSDB_CODE_SUCCESS; } @@ -5526,7 +5532,7 @@ static int32_t validateNullExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t } // check for like expression -static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t index, char* msgBuf) { +static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t idx, char* msgBuf) { const char* msg1 = "wildcard string should be less than %d characters"; const char* msg2 = "illegal column type for like"; @@ -5541,7 +5547,7 @@ static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t } SSchema* pSchema = tscGetTableSchema(pTableMeta); - if ((pLeft->tokenId != TK_ARROW) && (!isTablenameToken(&pLeft->columnName)) && !IS_VAR_DATA_TYPE(pSchema[index].type)) { + if ((pLeft->tokenId != TK_ARROW) && (!isTablenameToken(&pLeft->columnName)) && !IS_VAR_DATA_TYPE(pSchema[idx].type)) { return invalidOperationMsg(msgBuf, msg2); } } @@ -5601,7 +5607,7 @@ static int32_t validateJsonTagExpr(tSqlExpr* pExpr, char* msgBuf) { } // check for match expression -static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t index, char* msgBuf) { +static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t idx, char* msgBuf) { const char* msg1 = "regular expression string should be less than %d characters"; const char* msg3 = "invalid regular expression"; @@ -5676,7 +5682,7 @@ void convertWhereStringCharset(tSqlExpr* pRight){ free(newData); } -static int32_t handleColumnInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SColumnIndex* index) { +static int32_t handleColumnInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SColumnIndex* idx) { const char* msg2 = "illegal column name"; int32_t ret = TSDB_CODE_SUCCESS; if (pExpr == NULL) { @@ -5685,11 +5691,11 @@ static int32_t handleColumnInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (isComparisonOperator(pExpr)) { return TSDB_CODE_TSC_INVALID_OPERATION; } - ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pLeft, index); + ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pLeft, idx); if( ret != TSDB_CODE_SUCCESS) { return ret; } - ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pRight, index); + ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pRight, idx); return ret; } @@ -5701,7 +5707,7 @@ static int32_t handleColumnInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS } if (colName) { - if (getColumnIndexByName(colName, pQueryInfo, index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(colName, pQueryInfo, idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } @@ -5729,51 +5735,51 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql int32_t ret = TSDB_CODE_SUCCESS; - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; if (!tSqlExprIsParentOfLeaf(*pExpr)) { - ret = handleColumnInQueryCond(pCmd, pQueryInfo, pLeft, &index); + ret = handleColumnInQueryCond(pCmd, pQueryInfo, pLeft, &idx); if (ret != TSDB_CODE_SUCCESS) { return ret; } - ret = handleColumnInQueryCond(pCmd, pQueryInfo, pRight, &index); + ret = handleColumnInQueryCond(pCmd, pQueryInfo, pRight, &idx); if (ret != TSDB_CODE_SUCCESS) { return ret; } } else { - if (getColumnIndexByName(colName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(colName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } - *tbIdx = index.tableIndex; + *tbIdx = idx.tableIndex; - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); // delete where condition check , column must ts or tag if (delData) { if (!((pSchema->colId == PRIMARYKEY_TIMESTAMP_COL_INDEX && pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || - index.columnIndex >= tscGetNumOfColumns(pTableMeta) || - index.columnIndex == TSDB_TBNAME_COLUMN_INDEX)) { + idx.columnIndex >= tscGetNumOfColumns(pTableMeta) || + idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } } // validate the null expression - int32_t code = validateNullExpr(*pExpr, pTableMeta, index.columnIndex, tscGetErrorMsgPayload(pCmd)); + int32_t code = validateNullExpr(*pExpr, pTableMeta, idx.columnIndex, tscGetErrorMsgPayload(pCmd)); if (code != TSDB_CODE_SUCCESS) { return code; } // validate the like expression - code = validateLikeExpr(*pExpr, pTableMeta, index.columnIndex, tscGetErrorMsgPayload(pCmd)); + code = validateLikeExpr(*pExpr, pTableMeta, idx.columnIndex, tscGetErrorMsgPayload(pCmd)); if (code != TSDB_CODE_SUCCESS) { return code; } // validate the match expression - code = validateMatchExpr(*pExpr, pTableMeta, index.columnIndex, tscGetErrorMsgPayload(pCmd)); + code = validateMatchExpr(*pExpr, pTableMeta, idx.columnIndex, tscGetErrorMsgPayload(pCmd)); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -5782,8 +5788,8 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql convertWhereStringCharset(pRight); } - if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // query on time range - if (!tSqlExprIsParentOfLeaf(*pExpr) || !validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) { + if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && idx.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // query on time range + if (!tSqlExprIsParentOfLeaf(*pExpr) || !validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &idx)) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -5792,8 +5798,8 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY); pCondExpr->tsJoin = true; - assert(index.tableIndex >= 0 && index.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); - SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; + assert(idx.tableIndex >= 0 && idx.tableIndex < TSDB_MAX_JOIN_TABLE_NUM); + SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[idx.tableIndex]; if (*leftNode == NULL) { *leftNode = calloc(1, sizeof(SJoinNode)); if (*leftNode == NULL) { @@ -5801,17 +5807,17 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } } - int16_t leftIdx = index.tableIndex; + int16_t leftIdx = idx.tableIndex; - if (getColumnIndexByName(&pRight->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&pRight->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - if (index.tableIndex < 0 || index.tableIndex >= TSDB_MAX_JOIN_TABLE_NUM) { + if (idx.tableIndex < 0 || idx.tableIndex >= TSDB_MAX_JOIN_TABLE_NUM) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; + SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[idx.tableIndex]; if (*rightNode == NULL) { *rightNode = calloc(1, sizeof(SJoinNode)); if (*rightNode == NULL) { @@ -5819,7 +5825,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } } - int16_t rightIdx = index.tableIndex; + int16_t rightIdx = idx.tableIndex; if ((*leftNode)->tsJoin == NULL) { (*leftNode)->tsJoin = taosArrayInit(2, sizeof(int16_t)); @@ -5855,7 +5861,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } *pExpr = NULL; // remove this expression - } else if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + } else if (idx.columnIndex >= tscGetNumOfColumns(pTableMeta) || idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { // query on tags, check for tag query condition if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -5870,7 +5876,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } if (joinQuery && pRight != NULL && (pRight->tokenId == TK_ID || pRight->tokenId == TK_ARROW)) { // join on tag columns for stable query - if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) { + if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &idx)) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -6047,15 +6053,15 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* tSqlExpr* pLeft = (*pExpr)->pLeft; if (pLeft->tokenId == TK_ARROW || pLeft->tokenId == TK_ID) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; if(pLeft->tokenId == TK_ARROW) { pLeft = pLeft->pLeft; } - if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return; } - if (index.tableIndex != tableIndex) { + if (idx.tableIndex != tableIndex) { return; } } @@ -6181,12 +6187,12 @@ static int32_t convertTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return code; } } else { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pExpr->pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(&pExpr->pLeft->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); tSqlExpr* pRight = pExpr->pRight; @@ -6254,27 +6260,27 @@ static void cleanQueryExpr(SCondExpr* pCondExpr) { static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->ColName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->ColName, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (left)", pQueryInfo); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + idx.columnIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); + tscColumnListInsert(pTableMetaInfo->tagColList, &idx, &pSchema[idx.columnIndex]); - if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->ColName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->ColName, pQueryInfo, &idx) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (right)", pQueryInfo); } - pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + idx.columnIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); + tscColumnListInsert(pTableMetaInfo->tagColList, &idx, &pSchema[idx.columnIndex]); } } */ @@ -6415,10 +6421,10 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE size_t num = taosArrayGetSize(colList); for(int32_t j = 0; j < num; ++j) { SColIndex* pIndex = taosArrayGet(colList, j); - SColumnIndex index = {.tableIndex = i, .columnIndex = pIndex->colIndex - numOfCols}; + SColumnIndex idx = {.tableIndex = i, .columnIndex = pIndex->colIndex - numOfCols}; SSchema* s = tscGetTableSchema(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, + tscColumnListInsert(pTableMetaInfo->tagColList, idx.columnIndex, pTableMetaInfo->pTableMeta->id.uid, &s[pIndex->colIndex]); } @@ -7057,7 +7063,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq columnName.z = pVar->pz; } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; bool udf = false; if (pQueryInfo->pUdfInfo && taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) { @@ -7073,7 +7079,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // super table query - if (getColumnIndexByName(&columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsgBuf, msg1); } @@ -7081,8 +7087,8 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq bool orderByTS = false; bool orderByGroupbyCol = false; - if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { // order by tag1 - int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + if (idx.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { // order by tag1 + int32_t relTagIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); // it is a tag column if (pQueryInfo->groupbyExpr.columnInfo == NULL) { @@ -7106,7 +7112,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq orderByTags = true; } } - } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { // order by tbname + } else if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { // order by tbname // it is a tag column if (pQueryInfo->groupbyExpr.columnInfo == NULL) { return invalidOperationMsg(pMsgBuf, msg4); @@ -7115,13 +7121,13 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (TSDB_TBNAME_COLUMN_INDEX == pColIndex->colIndex) { orderByTags = true; } - }else if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // order by ts + }else if (idx.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // order by ts orderByTS = true; }else{ // order by normal column SArray *columnInfo = pQueryInfo->groupbyExpr.columnInfo; if (columnInfo != NULL && taosArrayGetSize(columnInfo) > 0) { SColIndex* pColIndex = taosArrayGet(columnInfo, 0); - if (pColIndex->colIndex == index.columnIndex) { + if (pColIndex->colIndex == idx.columnIndex) { orderByGroupbyCol = true; } } @@ -7135,7 +7141,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (tscIsDiffDerivLikeQuery(pQueryInfo)) { return invalidOperationMsg(pMsgBuf, msg12); } - //pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); + //pQueryInfo->groupbyExpr.orderIndex = idx.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); pQueryInfo->groupbyExpr.orderType = pItem->sortOrder; } else if (orderByGroupbyCol) { @@ -7154,12 +7160,12 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq pExpr = tscExprGet(pQueryInfo, pos); - if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colIndex != idx.columnIndex && idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(pMsgBuf, msg5); } pQueryInfo->order.order = pItem->sortOrder; - pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; + pQueryInfo->order.orderColId = pSchema[idx.columnIndex].colId; } else { if (udf) { return invalidOperationMsg(pMsgBuf, msg11); @@ -7185,27 +7191,27 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq cname.type = pVar->nType; cname.z = pVar->pz; } - if (getColumnIndexByName(&cname, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&cname, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsgBuf, msg1); } - if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(pMsgBuf, msg6); } pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; } } else if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo) || UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) { // check order by clause for normal table & temp table - if (getColumnIndexByName(&columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&columnName, pQueryInfo, &idx, pMsgBuf) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsgBuf, msg1); } - if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomUniqueQuery(pQueryInfo)){ + if (idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomUniqueQuery(pQueryInfo)){ bool validOrder = false; SArray *columnInfo = pQueryInfo->groupbyExpr.columnInfo; if (columnInfo != NULL && taosArrayGetSize(columnInfo) > 0) { SColIndex* pColIndex = taosArrayGet(columnInfo, 0); - validOrder = (pColIndex->colIndex == index.columnIndex); + validOrder = (pColIndex->colIndex == idx.columnIndex); } if (!validOrder) { @@ -7217,7 +7223,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (columnInfo != NULL && taosArrayGetSize(columnInfo) > 0) { /*SColIndex* pColIndex = taosArrayGet(columnInfo, 0); - if (pColIndex->colIndex != index.columnIndex) { + if (pColIndex->colIndex != idx.columnIndex) { return invalidOperationMsg(pMsgBuf, msg8); }*/ } else { @@ -7228,12 +7234,12 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq pExpr = tscExprGet(pQueryInfo, pos); - if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colIndex != idx.columnIndex && idx.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(pMsgBuf, msg5); } } pQueryInfo->order.order = pItem->sortOrder; - pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; + pQueryInfo->order.orderColId = pSchema[idx.columnIndex].colId; }else{ pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; @@ -7247,11 +7253,11 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq // inner subquery. assert(UTIL_TABLE_IS_TMP_TABLE(pTableMetaInfo) && taosArrayGetSize(pSqlNode->pSortOrder) == 1); - if (getColumnIndexByName(&columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&columnName, pQueryInfo, &idx, pMsgBuf) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsgBuf, msg1); } - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidOperationMsg(pMsgBuf, msg1); } @@ -7263,7 +7269,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq bool found = false; for (int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); - if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == pSchema[index.columnIndex].colId) { + if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == pSchema[idx.columnIndex].colId) { found = true; break; } @@ -7271,7 +7277,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (!found) { int32_t numOfCols = (int32_t)tscNumOfFields(pQueryInfo); - tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &idx, pSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); SInternalField* pSupInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfCols); pSupInfo->visible = false; @@ -7281,7 +7287,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } pQueryInfo->order.order = pItem->sortOrder; - pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; + pQueryInfo->order.orderColId = pSchema[idx.columnIndex].colId; } return TSDB_CODE_SUCCESS; @@ -7394,17 +7400,20 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { return invalidOperationMsg(pMsg, msg9); } - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { + return invalidOperationMsg(pMsg, msg17); + } SStrToken name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen}; - if (getColumnIndexByName(&name, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&name, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t numOfCols = tscGetNumOfColumns(pTableMeta); - if (index.columnIndex < numOfCols) { + if (idx.columnIndex < numOfCols) { return invalidOperationMsg(pMsg, msg10); - } else if (index.columnIndex == numOfCols) { + } else if (idx.columnIndex == numOfCols) { return invalidOperationMsg(pMsg, msg11); } @@ -7468,6 +7477,9 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { int16_t numOfTags = tscGetNumOfTags(pTableMeta); SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER; + if (item->pVar.nType != TSDB_DATA_TYPE_BINARY) { + return invalidOperationMsg(pMsg, msg17); + } SStrToken name = {.z = item->pVar.pz, .n = item->pVar.nLen}; if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; @@ -7613,6 +7625,9 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { tVariantListItem* pItem = taosArrayGet(pAlterSQL->varList, 0); SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER; + if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { + return invalidOperationMsg(pMsg, msg17); + } SStrToken name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen}; if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { @@ -7768,10 +7783,20 @@ int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { bool isProjectionFunction = false; + bool minMaxRowExists = false; const char* msg1 = "functions not compatible with interval"; // multi-output set/ todo refactor size_t size = taosArrayGetSize(pQueryInfo->exprList); + + for (int32_t k = 0; k < size; ++k) { + SExprInfo* pExpr = tscExprGet(pQueryInfo, k); + + if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW || pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { + minMaxRowExists = true; + break; + } + } for (int32_t k = 0; k < size; ++k) { SExprInfo* pExpr = tscExprGet(pQueryInfo, k); @@ -7792,7 +7817,7 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu } // projection query on primary timestamp, the selectivity function needs to be present. - if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (minMaxRowExists || (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { bool hasSelectivity = false; for (int32_t j = 0; j < size; ++j) { SExprInfo* pEx = tscExprGet(pQueryInfo, j); @@ -8244,20 +8269,20 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau SSchema* pTagSchema = tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, colId); int16_t colIndex = tscGetTagColIndexById(pTableMetaInfo->pTableMeta, colId); - SColumnIndex index = {.tableIndex = 0, .columnIndex = colIndex}; + SColumnIndex idx = {.tableIndex = 0, .columnIndex = colIndex}; char* name = pTagSchema->name; int16_t type = pTagSchema->type; int16_t bytes = pTagSchema->bytes; - pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(&pSql->cmd), bytes, true); + pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TAG, &idx, type, bytes, getNewResColId(&pSql->cmd), bytes, true); pExpr->base.colInfo.flag = TSDB_COL_TAG; // NOTE: tag column does not add to source column list SColumnList ids = {0}; insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr); - int32_t relIndex = index.columnIndex; + int32_t relIndex = idx.columnIndex; pExpr->base.colInfo.colIndex = relIndex; SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0); @@ -8296,13 +8321,14 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex, SSqlC pInfo->visible = false; } -static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { +static void doUpdateSqlFunctionForColTagPrj(SQueryInfo* pQueryInfo) { int32_t tagLength = 0; size_t size = taosArrayGetSize(pQueryInfo->exprList); -//todo is 0?? + //todo is 0?? STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); + bool minMaxRowExists = false; for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); @@ -8312,6 +8338,20 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { } else if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { pExpr->base.functionId = TSDB_FUNC_TS_DUMMY; // ts_select ts,top(col,2) tagLength += pExpr->base.resBytes; + } else if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW || pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { + minMaxRowExists = true; + } + } + + if (minMaxRowExists) { + for (int32_t i = 0; i < size; ++i) { + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW || pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { + continue; + } else if (pExpr->base.functionId == TSDB_FUNC_PRJ) { + pExpr->base.functionId = TSDB_FUNC_COL_DUMMY; + tagLength += pExpr->base.resBytes; + } } } @@ -8323,8 +8363,9 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { continue; } - if ((pExpr->base.functionId != TSDB_FUNC_TAG_DUMMY && pExpr->base.functionId != TSDB_FUNC_TS_DUMMY) && - !(pExpr->base.functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag))) { + if ((pExpr->base.functionId != TSDB_FUNC_TAG_DUMMY && pExpr->base.functionId != TSDB_FUNC_TS_DUMMY && + pExpr->base.functionId != TSDB_FUNC_COL_DUMMY) + && !(pExpr->base.functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag))) { SSchema* pColSchema = &pSchema[pExpr->base.colInfo.colIndex]; getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->base.functionId, (int32_t)pExpr->base.param[0].i64, &pExpr->base.resType, &pExpr->base.resBytes, &pExpr->base.interBytes, tagLength, isSTable, NULL); @@ -8453,10 +8494,14 @@ static bool check_expr_in_groupby_colum(SGroupbyExpr* pGroupbyExpr, SExprInfo* p * 2. if selectivity function and tagprj function both exist, there should be only * one selectivity function exists. */ -static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { +static int32_t checkUpdateColTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { const char* msg1 = "only one selectivity function allowed in presence of tags function"; const char* msg2 = "aggregation function should not be mixed up with projection"; + const char* msg3 = "min_row should not be mixed up with max_row"; + const char* msg4 = "only one selectivity function allowed in presence of min_row or max_row function"; + bool minRowExists = false; + bool maxRowExists = false; bool tagTsColExists = false; int16_t numOfScalar = 0; int16_t numOfSelectivity = 0; @@ -8473,9 +8518,17 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { tagTsColExists = true; // selectivity + ts/tag column break; } + } else if (pExpr->base.functionId == TSDB_FUNC_MIN_ROW) { + minRowExists = true; + } else if (pExpr->base.functionId == TSDB_FUNC_MAX_ROW) { + maxRowExists = true; } } + if (minRowExists && maxRowExists) { + return invalidOperationMsg(msg, msg3); + } + for (int32_t i = 0; i < numOfExprs; ++i) { SExprInfo* pExpr = taosArrayGetP(pQueryInfo->exprList, i); @@ -8514,7 +8567,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { } } - if (tagTsColExists) { // check if the selectivity function exists + if (tagTsColExists || minRowExists || maxRowExists) { // check if the selectivity function exists // When the tag projection function on tag column that is not in the group by clause, aggregation function and // selectivity function exist in select clause is not allowed. if (numOfAggregation > 0) { @@ -8525,7 +8578,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { * if numOfSelectivity equals to 0, it is a super table projection query */ if (numOfSelectivity == 1) { - doUpdateSqlFunctionForTagPrj(pQueryInfo); + doUpdateSqlFunctionForColTagPrj(pQueryInfo); int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo); if (code != TSDB_CODE_SUCCESS) { return code; @@ -8551,11 +8604,17 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { (functionId == TSDB_FUNC_LAST_DST && (pExpr->base.colInfo.flag & TSDB_COL_NULL) != 0)) { // do nothing } else { - return invalidOperationMsg(msg, msg1); + if (tagTsColExists) { + return invalidOperationMsg(msg, msg1); + } + + if (minRowExists || maxRowExists) { + return invalidOperationMsg(msg, msg4); + } } } - doUpdateSqlFunctionForTagPrj(pQueryInfo); + doUpdateSqlFunctionForColTagPrj(pQueryInfo); int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo); if (code != TSDB_CODE_SUCCESS) { return code; @@ -8620,8 +8679,8 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo int32_t pos = tscGetFirstInvisibleFieldPos(pQueryInfo); - SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; - SExprInfo* pExpr = tscExprInsert(pQueryInfo, pos, f, &index, s->type, s->bytes, getNewResColId(pCmd), s->bytes, true); + SColumnIndex idx = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; + SExprInfo* pExpr = tscExprInsert(pQueryInfo, pos, f, &idx, s->type, s->bytes, getNewResColId(pCmd), s->bytes, true); // NOTE: tag column does not add to source column list SColumnList ids = createColumnList(1, 0, pColIndex->colIndex); insertResultField(pQueryInfo, pos, &ids, s->bytes, (int8_t)s->type, pColIndex->name, pExpr); @@ -8779,7 +8838,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* } } - if (checkUpdateTagPrjFunctions(pQueryInfo, msg) != TSDB_CODE_SUCCESS) { + if (checkUpdateColTagPrjFunctions(pQueryInfo, msg) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -8794,7 +8853,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* return TSDB_CODE_SUCCESS; } else { - return checkUpdateTagPrjFunctions(pQueryInfo, msg); + return checkUpdateColTagPrjFunctions(pQueryInfo, msg); } } @@ -8914,20 +8973,20 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq {"client_version()", 16}, {"current_user()", 14}}; - int32_t index = -1; + int32_t idx = -1; if (server_status == true) { - index = 2; + idx = 2; } else { for (int32_t i = 0; i < tListLen(functionsInfo); ++i) { if (strncasecmp(functionsInfo[i].name, pExpr->exprToken.z, functionsInfo[i].len) == 0 && functionsInfo[i].len == pExpr->exprToken.n) { - index = i; + idx = i; break; } } } - switch (index) { + switch (idx) { case 0: pQueryInfo->command = TSDB_SQL_CURRENT_DB;break; case 1: @@ -8946,7 +9005,7 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq tDataTypes[TSDB_DATA_TYPE_INT].bytes, getNewResColId(pCmd), tDataTypes[TSDB_DATA_TYPE_INT].bytes, false); tSqlExprItem* item = taosArrayGet(pExprList, 0); - const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[index].name; + const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[idx].name; tstrncpy(pExpr1->base.aliasName, name, tListLen(pExpr1->base.aliasName)); return TSDB_CODE_SUCCESS; @@ -9616,10 +9675,12 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect pParam = taosArrayGet(pSqlExpr->Expr.paramList, 0); SStrToken* pToken = &pParam->pNode->columnName; - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - getColumnIndexByName(pToken, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)); - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - schema = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + schema = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex); } else { schema = (SSchema) {.colId = PRIMARYKEY_TIMESTAMP_COL_INDEX, .type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE}; } @@ -9639,15 +9700,15 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect // // if (tSqlExprCompare(pItem->pNode, pSqlExpr) == 0) { // exists, not added it, // -// SColumnIndex index = COLUMN_INDEX_INITIALIZER; +// SColumnIndex idx = COLUMN_INDEX_INITIALIZER; // int32_t functionId = pSqlExpr->functionId; // if (pSqlExpr->Expr.paramList == NULL) { -// index.columnIndex = 0; -// index.tableIndex = 0; +// idx.columnIndex = 0; +// idx.tableIndex = 0; // } else { // tSqlExprItem* pParamElem = taosArrayGet(pSqlExpr->Expr.paramList, 0); // SStrToken* pToken = &pParamElem->pNode->columnName; -// getColumnIndexByName(pToken, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)); +// getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)); // } // // size_t numOfNodeInSel = tscNumOfExprs(pQueryInfo); @@ -9658,7 +9719,7 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect // continue; // } // -// if (pExpr1->base.colInfo.colIndex != index.columnIndex) { +// if (pExpr1->base.colInfo.colIndex != idx.columnIndex) { // continue; // } // @@ -9847,16 +9908,16 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNode } if (pExpr1->tokenId == TK_ID) { - SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if ((getColumnIndexByName(&pExpr1->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS)) { + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; + if ((getColumnIndexByName(&pExpr1->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - if (index.columnIndex <= 0 || - index.columnIndex >= tscGetNumOfColumns(pTableMeta)) { + if (idx.columnIndex <= 0 || + idx.columnIndex >= tscGetNumOfColumns(pTableMeta)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -10318,8 +10379,8 @@ static STableMeta* extractTempTableMetaFromSubquery(SQueryInfo* pUpstream) { return meta; } -static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SSqlObj* pSql, SQueryInfo* pQueryInfo, char* msgBuf) { - SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, index); +static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t idx, SSqlObj* pSql, SQueryInfo* pQueryInfo, char* msgBuf) { + SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, idx); // union all is not supported currently SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0); @@ -10776,15 +10837,15 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS } return ret; } else if (pSqlExpr->type == SQL_NODE_TABLE_COLUMN) { // column name, normal column arithmetic expression - SColumnIndex index = COLUMN_INDEX_INITIALIZER; + SColumnIndex idx = COLUMN_INDEX_INITIALIZER; - int32_t ret = getColumnIndexByName(&pSqlExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)); + int32_t ret = getColumnIndexByName(&pSqlExpr->columnName, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)); if (ret != TSDB_CODE_SUCCESS) { return ret; } - pQueryInfo->curTableIdx = index.tableIndex; - STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta; + pQueryInfo->curTableIdx = idx.tableIndex; + STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, idx.tableIndex)->pTableMeta; int32_t numOfColumns = tscGetNumOfColumns(pTableMeta); *pExpr = calloc(1, sizeof(tExprNode)); @@ -10793,14 +10854,14 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS SSchema* pSchema = NULL; - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (idx.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { pSchema = (*pExpr)->pSchema; strcpy(pSchema->name, tGetTbnameColumnSchema()->name); pSchema->type = tGetTbnameColumnSchema()->type; pSchema->colId = tGetTbnameColumnSchema()->colId; pSchema->bytes = tGetTbnameColumnSchema()->bytes; } else { - pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + pSchema = tscGetTableColumnSchema(pTableMeta, idx.columnIndex); *(*pExpr)->pSchema = *pSchema; } @@ -10808,8 +10869,8 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS SColIndex colIndex = {0}; tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name)); colIndex.colId = pSchema->colId; - colIndex.colIndex = index.columnIndex; - colIndex.flag = (index.columnIndex >= numOfColumns) ? 1 : 0; + colIndex.colIndex = idx.columnIndex; + colIndex.flag = (idx.columnIndex >= numOfColumns) ? 1 : 0; taosArrayPush(pCols, &colIndex); } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index e6d5a94f04..b626a5355e 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -854,13 +854,13 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab int32_t vgId = -1; if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - int32_t index = pTableMetaInfo->vgroupIndex; - assert(index >= 0); + int32_t idx = pTableMetaInfo->vgroupIndex; + assert(idx >= 0); SVgroupMsg* pVgroupInfo = NULL; if (pTableMetaInfo->vgroupList && pTableMetaInfo->vgroupList->numOfVgroups > 0) { - assert(index < pTableMetaInfo->vgroupList->numOfVgroups); - pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[index]; + assert(idx < pTableMetaInfo->vgroupList->numOfVgroups); + pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[idx]; } else { tscError("0x%"PRIx64" No vgroup info found", pSql->self); @@ -870,7 +870,7 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab vgId = pVgroupInfo->vgId; tscSetDnodeEpSet(&pSql->epSet, pVgroupInfo); - tscDebug("0x%"PRIx64" query on stable, vgIndex:%d, numOfVgroups:%d", pSql->self, index, pTableMetaInfo->vgroupList->numOfVgroups); + tscDebug("0x%"PRIx64" query on stable, vgIndex:%d, numOfVgroups:%d", pSql->self, idx, pTableMetaInfo->vgroupList->numOfVgroups); } else { vgId = pTableMeta->vgId; @@ -892,11 +892,11 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab pQueryMsg->numOfTables = htonl(1); // set the number of tables pMsg += sizeof(STableIdInfo); } else { // it is a subquery of the super table query, this EP info is acquired from vgroupInfo - int32_t index = pTableMetaInfo->vgroupIndex; + int32_t idx = pTableMetaInfo->vgroupIndex; int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables); - assert(index >= 0 && index < numOfVgroups); + assert(idx >= 0 && idx < numOfVgroups); - SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, index); + SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, idx); // set the vgroup info tscSetDnodeEpSet(&pSql->epSet, &pTableIdList->vgInfo); @@ -906,7 +906,7 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab pQueryMsg->numOfTables = htonl(numOfTables); // set the number of tables tscDebug("0x%"PRIx64" query on stable, vgId:%d, numOfTables:%d, vgIndex:%d, numOfVgroups:%d", pSql->self, - pTableIdList->vgInfo.vgId, numOfTables, index, numOfVgroups); + pTableIdList->vgInfo.vgId, numOfTables, idx, numOfVgroups); // serialize each table id info for(int32_t i = 0; i < numOfTables; ++i) { @@ -1219,7 +1219,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pQueryMsg->tsBuf.tsOffset = htonl((int32_t)(pMsg - pCmd->payload)); if (pQueryInfo->tsBuf != NULL) { - // note: here used the index instead of actual vnode id. + // note: here used the idx instead of actual vnode id. int32_t vnodeIndex = pTableMetaInfo->vgroupIndex; code = dumpFileBlockByGroupId(pQueryInfo->tsBuf, vnodeIndex, pMsg, &pQueryMsg->tsBuf.tsLen, &pQueryMsg->tsBuf.tsNumOfBlocks); if (code != TSDB_CODE_SUCCESS) { @@ -1364,10 +1364,10 @@ int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } static bool tscIsAlterCommand(char* sqlstr) { - int32_t index = 0; + int32_t idx = 0; do { - SStrToken t0 = tStrGetToken(sqlstr, &index, false); + SStrToken t0 = tStrGetToken(sqlstr, &idx, false); if (t0.type != TK_LP) { return t0.type == TK_ALTER; } @@ -2749,18 +2749,18 @@ int tscProcessShowRsp(SSqlObj *pSql) { SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo; - SColumnIndex index = {0}; + SColumnIndex idx = {0}; pSchema = pMetaMsg->schema; uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; for (int16_t i = 0; i < pMetaMsg->numOfColumns; ++i, ++pSchema) { - index.columnIndex = i; + idx.columnIndex = i; tscColumnListInsert(pQueryInfo->colList, i, uid, pSchema); TAOS_FIELD f = tscCreateField(pSchema->type, pSchema->name, pSchema->bytes); SInternalField* pInfo = tscFieldInfoAppend(pFieldInfo, &f); - pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &idx, pTableSchema[i].type, pTableSchema[i].bytes, getNewResColId(pCmd), pTableSchema[i].bytes, false); } @@ -3587,4 +3587,4 @@ void tscInitMsgsFp() { tscKeepConn[TSDB_SQL_SELECT] = 1; tscKeepConn[TSDB_SQL_FETCH] = 1; tscKeepConn[TSDB_SQL_HB] = 1; -} \ No newline at end of file +} diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 3fadc7abaf..5f1d996b54 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -30,7 +30,7 @@ typedef struct SInsertSupporter { SSqlObj* pSql; - int32_t index; + int32_t idx; } SInsertSupporter; static void freeJoinSubqueryObj(SSqlObj* pSql); @@ -84,14 +84,14 @@ static bool allSubqueryDone(SSqlObj *pParentSql) { for (int i = 0; i < subState->numOfSub; i++) { SSqlObj* pSub = pParentSql->pSubs[i]; if (0 == subState->states[i]) { - tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index: %d NOT finished yet", pParentSql->self, pSub->self, i); + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", idx: %d NOT finished yet", pParentSql->self, pSub->self, i); done = false; break; } else { if (pSub != NULL) { - tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index: %d finished", pParentSql->self, pSub->self, i); + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", idx: %d finished", pParentSql->self, pSub->self, i); } else { - tscDebug("0x%"PRIx64" subquery:%p, index: %d finished", pParentSql->self, pSub, i); + tscDebug("0x%"PRIx64" subquery:%p, idx: %d finished", pParentSql->self, pSub, i); } } } @@ -105,7 +105,7 @@ bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx) { pthread_mutex_lock(&subState->mutex); - tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index:%d state set to 1", pParentSql->self, pSql->self, idx); + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", idx:%d state set to 1", pParentSql->self, pSql->self, idx); subState->states[idx] = 1; bool done = allSubqueryDone(pParentSql); @@ -383,7 +383,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { // todo handle failed to create sub query -SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { +SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t idx) { SJoinSupporter* pSupporter = calloc(1, sizeof(SJoinSupporter)); if (pSupporter == NULL) { return NULL; @@ -391,7 +391,7 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { pSupporter->pObj = pSql->self; - pSupporter->subqueryIndex = index; + pSupporter->subqueryIndex = idx; SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); memcpy(&pSupporter->interval, &pQueryInfo->interval, sizeof(pSupporter->interval)); @@ -403,7 +403,7 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { pSupporter->numOfFillVal = pQueryInfo->numOfFillVal; } - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, index); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, idx); pSupporter->uid = pTableMetaInfo->pTableMeta->id.uid; assert (pSupporter->uid != 0); @@ -614,7 +614,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { * during the timestamp intersection. */ pSupporter->limit = pQueryInfo->limit; - SColumnIndex index = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; + SColumnIndex idx = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; SSchema* s = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, 0); SExprInfo* pExpr = tscExprGet(pQueryInfo, 0); @@ -626,7 +626,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { int16_t functionId = tscIsProjectionQuery(pQueryInfo)? TSDB_FUNC_PRJ : TSDB_FUNC_TS; - tscAddFuncInSelectClause(pQueryInfo, 0, functionId, &index, s, TSDB_COL_NORMAL, getNewResColId(&pNew->cmd)); + tscAddFuncInSelectClause(pQueryInfo, 0, functionId, &idx, s, TSDB_COL_NORMAL, getNewResColId(&pNew->cmd)); tscPrintSelNodeList(pNew, 0); tscFieldInfoUpdateOffset(pQueryInfo); @@ -836,8 +836,8 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = 1}; - SColumnIndex index = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - SExprInfo *pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &index, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + SColumnIndex idx = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + SExprInfo *pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &idx, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); // set the tags value for ts_comp function if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { @@ -1280,7 +1280,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow // todo retry if other subqueries are not failed assert(numOfRows < 0 && numOfRows == taos_errno(pSql)); - tscError("0x%"PRIx64" sub query failed, code:%s, index:%d", pSql->self, tstrerror(numOfRows), pSupporter->subqueryIndex); + tscError("0x%"PRIx64" sub query failed, code:%s, idx:%d", pSql->self, tstrerror(numOfRows), pSupporter->subqueryIndex); pParentSql->res.code = numOfRows; if (quitAllSubquery(pSql, pParentSql, pSupporter)) { @@ -1336,7 +1336,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow pTableMetaInfo->vgroupIndex += 1; assert(pTableMetaInfo->vgroupIndex < totalVgroups); - tscDebug("0x%"PRIx64" tid_tag from vgroup index:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%d", + tscDebug("0x%"PRIx64" tid_tag from vgroup idx:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%d", pSql->self, pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pSupporter->num); pCmd->command = TSDB_SQL_SELECT; @@ -1447,7 +1447,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow if (taos_errno(pSql) != TSDB_CODE_SUCCESS) { // todo retry if other subqueries are not failed yet assert(numOfRows < 0 && numOfRows == taos_errno(pSql)); - tscError("0x%"PRIx64" sub query failed, code:%s, index:%d", pSql->self, tstrerror(numOfRows), pSupporter->subqueryIndex); + tscError("0x%"PRIx64" sub query failed, code:%s, idx:%d", pSql->self, tstrerror(numOfRows), pSupporter->subqueryIndex); pParentSql->res.code = numOfRows; if (quitAllSubquery(pSql, pParentSql, pSupporter)){ @@ -1525,7 +1525,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow pTableMetaInfo->vgroupIndex += 1; assert(pTableMetaInfo->vgroupIndex < totalVgroups); - tscDebug("0x%"PRIx64" results from vgroup index:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%" PRId64, + tscDebug("0x%"PRIx64" results from vgroup idx:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%" PRId64, pSql->self, pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pRes->numOfClauseTotal); @@ -1610,7 +1610,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR assert(numOfRows == taos_errno(pSql)); pParentSql->res.code = numOfRows; - tscError("0x%"PRIx64" retrieve failed, index:%d, code:%s", pSql->self, pSupporter->subqueryIndex, tstrerror(numOfRows)); + tscError("0x%"PRIx64" retrieve failed, idx:%d, code:%s", pSql->self, pSupporter->subqueryIndex, tstrerror(numOfRows)); tscAsyncResultOnError(pParentSql); goto _return; @@ -1670,7 +1670,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR pParentSql->res.precision = pRes1->precision; if (pRes1->row > 0 && pRes1->numOfRows > 0) { - tscDebug("0x%"PRIx64" sub:0x%"PRIx64" index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql->self, + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" idx:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql->self, pParentSql->pSubs[i]->self, i, pRes1->numOfRows, pRes1->numOfTotal); assert(pRes1->row < pRes1->numOfRows || (pRes1->row == pRes1->numOfRows && pRes1->completed)); } else { @@ -1678,7 +1678,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR pRes1->numOfClauseTotal += pRes1->numOfRows; } - tscDebug("0x%"PRIx64" sub:0x%"PRIx64" index:%d numOfRows:%d total:%"PRId64, pParentSql->self, + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" idx:%d numOfRows:%d total:%"PRId64, pParentSql->self, pParentSql->pSubs[i]->self, i, pRes1->numOfRows, pRes1->numOfTotal); } } @@ -1879,7 +1879,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { } } -// all subqueries return, set the result output index +// all subqueries return, set the result output idx void tscSetupOutputColumnIndex(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; @@ -2567,7 +2567,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { int32_t numOfExprs = (int32_t) tscNumOfExprs(pQueryInfo); - int32_t index = 0; + int32_t idx = 0; for(int32_t i = 0; i < numOfExprs; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_TS && pQueryInfo->interval.interval > 0) { @@ -2576,7 +2576,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); - SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TS, &colIndex, schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, idx++, TSDB_FUNC_TS, &colIndex, schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); p->base.resColId = pExpr->base.resColId; // update the result column id } else if (pExpr->base.functionId == TSDB_FUNC_STDDEV_DST) { taosArrayPush(pSup->pColsInfo, &pExpr->base.resColId); @@ -2585,7 +2585,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { SSchema schema = {.type = TSDB_DATA_TYPE_DOUBLE, .bytes = sizeof(double)}; tstrncpy(schema.name, pExpr->base.aliasName, tListLen(schema.name)); - SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_AVG, &colIndex, &schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, idx++, TSDB_FUNC_AVG, &colIndex, &schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); p->base.resColId = pExpr->base.resColId; // update the result column id } else if (pExpr->base.functionId == TSDB_FUNC_TAG) { pSup->tagLen += pExpr->base.resBytes; @@ -2598,7 +2598,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { schema = tGetTbnameColumnSchema(); } - SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG, getNewResColId(pCmd)); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, idx++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG, getNewResColId(pCmd)); if (schema->type == TSDB_DATA_TYPE_JSON){ p->base.numOfParams = pExpr->base.numOfParams; tVariantAssign(&p->base.param[0], &pExpr->base.param[0]); @@ -2616,7 +2616,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); //doLimitOutputNormalColOfGroupby - SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_PRJ, &colIndex, schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, idx++, TSDB_FUNC_PRJ, &colIndex, schema, TSDB_COL_NORMAL, getNewResColId(pCmd)); p->base.numOfParams = 1; p->base.param[0].i64 = 1; p->base.param[0].nType = TSDB_DATA_TYPE_INT; @@ -2658,7 +2658,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { "0x%"PRIx64" first round subquery:0x%"PRIx64" tableIndex:%d, vgroupIndex:%d, numOfVgroups:%d, type:%d, query to retrieve timestamps, " "numOfExpr:%" PRIzu ", colList:%d, numOfOutputFields:%d, name:%s", pSql->self, pNew->self, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pNewQueryInfo->type, - tscNumOfExprs(pNewQueryInfo), index+1, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); + tscNumOfExprs(pNewQueryInfo), idx+1, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); pSql->pSubs = calloc(1, POINTER_BYTES); if (pSql->pSubs == NULL) { @@ -3281,7 +3281,7 @@ SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsupport, SSq assert(trsupport->subqueryIndex < pSql->subState.numOfSub); - // launch subquery for each vnode, so the subquery index equals to the vgroupIndex. + // launch subquery for each vnode, so the subquery idx equals to the vgroupIndex. STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, table_index); pTableMetaInfo->vgroupIndex = trsupport->subqueryIndex; @@ -3411,7 +3411,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) } } - if (!subAndCheckDone(tres, pParentObj, pSupporter->index)) { + if (!subAndCheckDone(tres, pParentObj, pSupporter->idx)) { // concurrency problem, other thread already release pParentObj //tscDebug("0x%"PRIx64" insert:%p,%d completed, total:%d", pParentObj->self, tres, suppIdx, pParentObj->subState.numOfSub); return; @@ -3495,9 +3495,9 @@ int32_t tscHandleInsertRetry(SSqlObj* pParent, SSqlObj* pSql) { SSqlRes* pRes = &pSql->res; SInsertSupporter* pSupporter = (SInsertSupporter*) pSql->param; - assert(pSupporter->index < pSupporter->pSql->subState.numOfSub); + assert(pSupporter->idx < pSupporter->pSql->subState.numOfSub); - STableDataBlocks* pTableDataBlock = taosArrayGetP(pParent->cmd.insertParam.pDataBlocks, pSupporter->index); + STableDataBlocks* pTableDataBlock = taosArrayGetP(pParent->cmd.insertParam.pDataBlocks, pSupporter->idx); int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock); if ((pRes->code = code)!= TSDB_CODE_SUCCESS) { @@ -3524,7 +3524,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) { SSqlObj* pSub = pSql->pSubs[i]; SInsertSupporter* pSup = calloc(1, sizeof(SInsertSupporter)); - pSup->index = i; + pSup->idx = i; pSup->pSql = pSql; pSub->param = pSup; @@ -3572,7 +3572,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { } pSupporter->pSql = pSql; - pSupporter->index = numOfSub; + pSupporter->idx = numOfSub; SSqlObj *pNew = createSimpleSubObj(pSql, multiVnodeInsertFinalize, pSupporter, TSDB_SQL_INSERT); if (pNew == NULL) { @@ -3763,19 +3763,19 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { char * getScalarExprInputSrc(void *param, const char *name, int32_t colId) { SScalarExprSupport*pSupport = (SScalarExprSupport*) param; - int32_t index = -1; + int32_t idx = -1; SExprInfo* pExpr = NULL; for (int32_t i = 0; i < pSupport->numOfCols; ++i) { pExpr = taosArrayGetP(pSupport->exprList, i); if (strncmp(name, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1) == 0) { - index = i; + idx = i; break; } } - assert(index >= 0 && index < pSupport->numOfCols); - return pSupport->data[index] + pSupport->offset * pExpr->base.resBytes; + assert(idx >= 0 && idx < pSupport->numOfCols); + return pSupport->data[idx] + pSupport->offset * pExpr->base.resBytes; } TAOS_ROW doSetResultRowData(SSqlObj *pSql) { @@ -3815,7 +3815,7 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql) { j += 1; } - pRes->row++; // index increase one-step + pRes->row++; // idx increase one-step return pRes->tsrow; } @@ -3959,7 +3959,7 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr pthread_mutex_init(&pQInfo->lock, NULL); tsem_init(&pQInfo->ready, 0, 0); - int32_t index = 0; + int32_t idx = 0; for(int32_t i = 0; i < numOfGroups; ++i) { SArray* pa = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); @@ -3976,7 +3976,7 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr STableKeyInfo* info = taosArrayGet(pa, j); window.skey = info->lastKey; - void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo); + void* buf = (char*) pQInfo->pBuf + idx * sizeof(STableQueryInfo); STableQueryInfo* item = createTableQueryInfo(pQueryAttr, info->pTable, pQueryAttr->groupbyColumn, window, buf); if (item == NULL) { goto _cleanup; @@ -3987,7 +3987,7 @@ void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGr STableId id = {.tid = 0, .uid = 0}; taosHashPut(pRuntimeEnv->tableqinfoGroupInfo.map, &id.tid, sizeof(id.tid), &item, POINTER_BYTES); - index += 1; + idx += 1; } } diff --git a/src/client/src/tscSystem.c b/src/client/src/tscSystem.c index d5369e38f0..944b85e996 100644 --- a/src/client/src/tscSystem.c +++ b/src/client/src/tscSystem.c @@ -47,7 +47,7 @@ int32_t tscNumOfObj = 0; // number of sqlObj in current process. static void *tscCheckDiskUsageTmr; void *tscRpcCache; // cache to keep rpc obj int32_t tscNumOfThreads = 1; // num of rpc threads -char tscLogFileName[12] = "taoslog"; +char tscLogFileName[] = "taoslog"; int tscLogFileNum = 10; static pthread_mutex_t rpcObjMutex; // mutex to protect open the rpc obj concurrently @@ -87,24 +87,24 @@ int32_t tscAcquireRpc(const char *key, const char *user, const char *secretEncry return 0; } - SRpcInit rpcInit; - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = 0; - rpcInit.label = "TSC"; - rpcInit.numOfThreads = tscNumOfThreads; - rpcInit.cfp = tscProcessMsgFromServer; - rpcInit.sessions = tsMaxConnections; - rpcInit.connType = TAOS_CONN_CLIENT; - rpcInit.user = (char *)user; - rpcInit.idleTime = tsShellActivityTimer * 1000; - rpcInit.ckey = "key"; - rpcInit.spi = 1; - rpcInit.secret = (char *)secretEncrypt; + SRpcInit rpcInitial; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = 0; + rpcInitial.label = "TSC"; + rpcInitial.numOfThreads = tscNumOfThreads; + rpcInitial.cfp = tscProcessMsgFromServer; + rpcInitial.sessions = tsMaxConnections; + rpcInitial.connType = TAOS_CONN_CLIENT; + rpcInitial.user = (char *)user; + rpcInitial.idleTime = tsShellActivityTimer * 1000; + rpcInitial.ckey = "key"; + rpcInitial.spi = 1; + rpcInitial.secret = (char *)secretEncrypt; SRpcObj rpcObj; memset(&rpcObj, 0, sizeof(rpcObj)); tstrncpy(rpcObj.key, key, sizeof(rpcObj.key)); - rpcObj.pDnodeConn = rpcOpen(&rpcInit); + rpcObj.pDnodeConn = rpcOpen(&rpcInitial); if (rpcObj.pDnodeConn == NULL) { pthread_mutex_unlock(&rpcObjMutex); tscError("failed to init connection to server"); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index cfcf2f63ee..c431a731c0 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -2305,10 +2305,10 @@ void tscCloseTscObj(void *param) { } bool tscIsInsertData(char* sqlstr) { - int32_t index = 0; + int32_t idx = 0; do { - SStrToken t0 = tStrGetToken(sqlstr, &index, false); + SStrToken t0 = tStrGetToken(sqlstr, &idx, false); if (t0.type != TK_LP) { return t0.type == TK_INSERT || t0.type == TK_IMPORT; } @@ -2378,12 +2378,12 @@ SInternalField* tscFieldInfoAppend(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) { return taosArrayPush(pFieldInfo->internalField, &info); } -SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIELD* field) { +SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t idx, TAOS_FIELD* field) { pFieldInfo->numOfOutput++; struct SInternalField info = { .pExpr = NULL, .visible = true }; info.field = *field; - return taosArrayInsert(pFieldInfo->internalField, index, &info); + return taosArrayInsert(pFieldInfo->internalField, idx, &info); } void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo) { @@ -2398,18 +2398,18 @@ void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo) { } } -SInternalField* tscFieldInfoGetInternalField(SFieldInfo* pFieldInfo, int32_t index) { - assert(index < pFieldInfo->numOfOutput); - return TARRAY_GET_ELEM(pFieldInfo->internalField, index); +SInternalField* tscFieldInfoGetInternalField(SFieldInfo* pFieldInfo, int32_t idx) { + assert(idx < pFieldInfo->numOfOutput); + return TARRAY_GET_ELEM(pFieldInfo->internalField, idx); } -TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) { - assert(index < pFieldInfo->numOfOutput); - return &((SInternalField*)TARRAY_GET_ELEM(pFieldInfo->internalField, index))->field; +TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t idx) { + assert(idx < pFieldInfo->numOfOutput); + return &((SInternalField*)TARRAY_GET_ELEM(pFieldInfo->internalField, idx))->field; } -int32_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) { - SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, index); +int32_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t idx) { + SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, idx); assert(pInfo != NULL && pInfo->pExpr->pExpr == NULL); return pInfo->pExpr->base.offset; @@ -2635,16 +2635,16 @@ SExprInfo* tscExprCreate(STableMetaInfo* pTableMetaInfo, int16_t functionId, SCo return pExpr; } -SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t idx, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int32_t interSize, bool isTagCol) { int32_t num = (int32_t)taosArrayGetSize(pQueryInfo->exprList); - if (index == num) { + if (idx == num) { return tscExprAppend(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pColIndex->tableIndex); SExprInfo* pExpr = tscExprCreate(pTableMetaInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); - taosArrayInsert(pQueryInfo->exprList, index, &pExpr); + taosArrayInsert(pQueryInfo->exprList, idx, &pExpr); return pExpr; } @@ -2656,10 +2656,10 @@ SExprInfo* tscExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnInde return pExpr; } -SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, +SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t idx, int16_t functionId, int16_t srcColumnIndex, int16_t type, int32_t size) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - SExprInfo* pExpr = tscExprGet(pQueryInfo, index); + SExprInfo* pExpr = tscExprGet(pQueryInfo, idx); if (pExpr == NULL) { return NULL; } @@ -2676,8 +2676,8 @@ SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t function return pExpr; } -bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t index) { - if (!UTIL_TABLE_IS_SUPER_TABLE(pQueryInfo->pTableMetaInfo[index])) { +bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t idx) { + if (!UTIL_TABLE_IS_SUPER_TABLE(pQueryInfo->pTableMetaInfo[idx])) { return false; } @@ -2725,8 +2725,8 @@ void tscExprAddParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t byt assert(pExpr->numOfParams <= 3); } -SExprInfo* tscExprGet(SQueryInfo* pQueryInfo, int32_t index) { - return taosArrayGetP(pQueryInfo->exprList, index); +SExprInfo* tscExprGet(SQueryInfo* pQueryInfo, int32_t idx) { + return taosArrayGetP(pQueryInfo->exprList, idx); } /* @@ -3014,6 +3014,10 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded) // single token, validate it if (len == pToken->n) { + if (taosIsKeyWordToken(pToken->z, (int32_t) pToken->n)) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + return validateQuoteToken(pToken, escapeEnabled, NULL); } else { sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true); @@ -3297,8 +3301,8 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) { if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - int16_t index = pExpr->base.colInfo.colIndex; - pColInfo[i].type = (index != -1) ? pTagSchema[index].type : TSDB_DATA_TYPE_BINARY; + int16_t idx = pExpr->base.colInfo.colIndex; + pColInfo[i].type = (idx != -1) ? pTagSchema[idx].type : TSDB_DATA_TYPE_BINARY; } else { pColInfo[i].type = pSchema[pExpr->base.colInfo.colIndex].type; } @@ -3381,7 +3385,7 @@ SQueryInfo* tscGetQueryInfoS(SSqlCmd* pCmd) { return pQueryInfo; } -STableMetaInfo* tscGetTableMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, int32_t* index) { +STableMetaInfo* tscGetTableMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, int32_t* idx) { int32_t k = -1; for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { @@ -3391,8 +3395,8 @@ STableMetaInfo* tscGetTableMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, i } } - if (index != NULL) { - *index = k; + if (idx != NULL) { + *idx = k; } assert(k != -1); @@ -3615,19 +3619,19 @@ void tscFreeVgroupTableInfo(SArray* pVgroupTables) { taosArrayDestroy(&pVgroupTables); } -void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index) { - assert(pVgroupTable != NULL && index >= 0); +void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t idx) { + assert(pVgroupTable != NULL && idx >= 0); size_t size = taosArrayGetSize(pVgroupTable); - assert(size > index); + assert(size > idx); - SVgroupTableInfo* pInfo = taosArrayGet(pVgroupTable, index); + SVgroupTableInfo* pInfo = taosArrayGet(pVgroupTable, idx); // for(int32_t j = 0; j < pInfo->vgInfo.numOfEps; ++j) { // tfree(pInfo->vgInfo.epAddr[j].fqdn); // } taosArrayDestroy(&pInfo->itemList); - taosArrayRemove(pVgroupTable, index); + taosArrayRemove(pVgroupTable, idx); } void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo) { @@ -4102,15 +4106,15 @@ static void tscSubqueryRetrieveCallback(void* param, TAOS_RES* tres, int code) { SSqlObj* pParentSql = ps->pParentSql; SSqlObj* pSql = tres; - int32_t index = ps->subqueryIndex; - bool ret = subAndCheckDone(pSql, pParentSql, index); + int32_t idx = ps->subqueryIndex; + bool ret = subAndCheckDone(pSql, pParentSql, idx); // TODO refactor tfree(ps); pSql->param = NULL; if (!ret) { - tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, index); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, idx); return; } @@ -4131,13 +4135,13 @@ static void tscSubqueryCompleteCallback(void* param, TAOS_RES* tres, int code) { if (pSql->res.code != TSDB_CODE_SUCCESS) { SSqlObj* pParentSql = ps->pParentSql; - int32_t index = ps->subqueryIndex; - bool ret = subAndCheckDone(pSql, pParentSql, index); + int32_t idx = ps->subqueryIndex; + bool ret = subAndCheckDone(pSql, pParentSql, idx); tscFreeRetrieveSup(&pSql->param); if (!ret) { - tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, index); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, idx); return; } diff --git a/src/common/src/tarithoperator.c b/src/common/src/tarithoperator.c index ca5d247dd6..71702e1249 100644 --- a/src/common/src/tarithoperator.c +++ b/src/common/src/tarithoperator.c @@ -60,40 +60,40 @@ void calc_i32_i32_add(void *left, void *right, int32_t numLeft, int32_t numRight } } -typedef double (*_arithmetic_getVectorDoubleValue_fn_t)(void *src, int32_t index); +typedef double (*_arithmetic_getVectorDoubleValue_fn_t)(void *src, int32_t idx); -double getVectorDoubleValue_TINYINT(void *src, int32_t index) { - return (double)*((int8_t *)src + index); +double getVectorDoubleValue_TINYINT(void *src, int32_t idx) { + return (double)*((int8_t *)src + idx); } -double getVectorDoubleValue_UTINYINT(void *src, int32_t index) { - return (double)*((uint8_t *)src + index); +double getVectorDoubleValue_UTINYINT(void *src, int32_t idx) { + return (double)*((uint8_t *)src + idx); } -double getVectorDoubleValue_SMALLINT(void *src, int32_t index) { - return (double)*((int16_t *)src + index); +double getVectorDoubleValue_SMALLINT(void *src, int32_t idx) { + return (double)*((int16_t *)src + idx); } -double getVectorDoubleValue_USMALLINT(void *src, int32_t index) { - return (double)*((uint16_t *)src + index); +double getVectorDoubleValue_USMALLINT(void *src, int32_t idx) { + return (double)*((uint16_t *)src + idx); } -double getVectorDoubleValue_INT(void *src, int32_t index) { - return (double)*((int32_t *)src + index); +double getVectorDoubleValue_INT(void *src, int32_t idx) { + return (double)*((int32_t *)src + idx); } -double getVectorDoubleValue_UINT(void *src, int32_t index) { - return (double)*((uint32_t *)src + index); +double getVectorDoubleValue_UINT(void *src, int32_t idx) { + return (double)*((uint32_t *)src + idx); } -double getVectorDoubleValue_BIGINT(void *src, int32_t index) { - return (double)*((int64_t *)src + index); +double getVectorDoubleValue_BIGINT(void *src, int32_t idx) { + return (double)*((int64_t *)src + idx); } -double getVectorDoubleValue_UBIGINT(void *src, int32_t index) { - return (double)*((uint64_t *)src + index); +double getVectorDoubleValue_UBIGINT(void *src, int32_t idx) { + return (double)*((uint64_t *)src + idx); } -double getVectorDoubleValue_FLOAT(void *src, int32_t index) { - return (double)*((float *)src + index); +double getVectorDoubleValue_FLOAT(void *src, int32_t idx) { + return (double)*((float *)src + idx); } -double getVectorDoubleValue_DOUBLE(void *src, int32_t index) { - return (double)*((double *)src + index); +double getVectorDoubleValue_DOUBLE(void *src, int32_t idx) { + return (double)*((double *)src + idx); } -int64_t getVectorTimestampValue(void *src, int32_t index) { - return (int64_t)*((int64_t *)src + index); +int64_t getVectorTimestampValue(void *src, int32_t idx) { + return (int64_t)*((int64_t *)src + idx); } _arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) { _arithmetic_getVectorDoubleValue_fn_t p = NULL; @@ -124,40 +124,40 @@ _arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) { } -typedef void* (*_arithmetic_getVectorValueAddr_fn_t)(void *src, int32_t index); +typedef void* (*_arithmetic_getVectorValueAddr_fn_t)(void *src, int32_t idx); -void* getVectorValueAddr_BOOL(void *src, int32_t index) { - return (void*)((bool *)src + index); +void* getVectorValueAddr_BOOL(void *src, int32_t idx) { + return (void*)((bool *)src + idx); } -void* getVectorValueAddr_TINYINT(void *src, int32_t index) { - return (void*)((int8_t *)src + index); +void* getVectorValueAddr_TINYINT(void *src, int32_t idx) { + return (void*)((int8_t *)src + idx); } -void* getVectorValueAddr_UTINYINT(void *src, int32_t index) { - return (void*)((uint8_t *)src + index); +void* getVectorValueAddr_UTINYINT(void *src, int32_t idx) { + return (void*)((uint8_t *)src + idx); } -void* getVectorValueAddr_SMALLINT(void *src, int32_t index) { - return (void*)((int16_t *)src + index); +void* getVectorValueAddr_SMALLINT(void *src, int32_t idx) { + return (void*)((int16_t *)src + idx); } -void* getVectorValueAddr_USMALLINT(void *src, int32_t index) { - return (void*)((uint16_t *)src + index); +void* getVectorValueAddr_USMALLINT(void *src, int32_t idx) { + return (void*)((uint16_t *)src + idx); } -void* getVectorValueAddr_INT(void *src, int32_t index) { - return (void*)((int32_t *)src + index); +void* getVectorValueAddr_INT(void *src, int32_t idx) { + return (void*)((int32_t *)src + idx); } -void* getVectorValueAddr_UINT(void *src, int32_t index) { - return (void*)((uint32_t *)src + index); +void* getVectorValueAddr_UINT(void *src, int32_t idx) { + return (void*)((uint32_t *)src + idx); } -void* getVectorValueAddr_BIGINT(void *src, int32_t index) { - return (void*)((int64_t *)src + index); +void* getVectorValueAddr_BIGINT(void *src, int32_t idx) { + return (void*)((int64_t *)src + idx); } -void* getVectorValueAddr_UBIGINT(void *src, int32_t index) { - return (void*)((uint64_t *)src + index); +void* getVectorValueAddr_UBIGINT(void *src, int32_t idx) { + return (void*)((uint64_t *)src + idx); } -void* getVectorValueAddr_FLOAT(void *src, int32_t index) { - return (void*)((float *)src + index); +void* getVectorValueAddr_FLOAT(void *src, int32_t idx) { + return (void*)((float *)src + idx); } -void* getVectorValueAddr_DOUBLE(void *src, int32_t index) { - return (void*)((double *)src + index); +void* getVectorValueAddr_DOUBLE(void *src, int32_t idx) { + return (void*)((double *)src + idx); } _arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) { @@ -474,34 +474,34 @@ void vectorRemainder(void *left, int32_t len1, int32_t _left_type, void *right, } } -typedef int64_t (*_arithmetic_getVectorBigintValue_fn_t)(void *src, int32_t index); +typedef int64_t (*_arithmetic_getVectorBigintValue_fn_t)(void *src, int32_t idx); -int64_t getVectorBigintValue_BOOL(void *src, int32_t index) { - return (int64_t)*((bool *)src + index); +int64_t getVectorBigintValue_BOOL(void *src, int32_t idx) { + return (int64_t)*((bool *)src + idx); } -int64_t getVectorBigintValue_TINYINT(void *src, int32_t index) { - return (int64_t)*((int8_t *)src + index); +int64_t getVectorBigintValue_TINYINT(void *src, int32_t idx) { + return (int64_t)*((int8_t *)src + idx); } -int64_t getVectorBigintValue_UTINYINT(void *src, int32_t index) { - return (int64_t)*((uint8_t *)src + index); +int64_t getVectorBigintValue_UTINYINT(void *src, int32_t idx) { + return (int64_t)*((uint8_t *)src + idx); } -int64_t getVectorBigintValue_SMALLINT(void *src, int32_t index) { - return (int64_t)*((int16_t *)src + index); +int64_t getVectorBigintValue_SMALLINT(void *src, int32_t idx) { + return (int64_t)*((int16_t *)src + idx); } -int64_t getVectorBigintValue_USMALLINT(void *src, int32_t index) { - return (int64_t)*((uint16_t *)src + index); +int64_t getVectorBigintValue_USMALLINT(void *src, int32_t idx) { + return (int64_t)*((uint16_t *)src + idx); } -int64_t getVectorBigintValue_INT(void *src, int32_t index) { - return (int64_t)*((int32_t *)src + index); +int64_t getVectorBigintValue_INT(void *src, int32_t idx) { + return (int64_t)*((int32_t *)src + idx); } -int64_t getVectorBigintValue_UINT(void *src, int32_t index) { - return (int64_t)*((uint32_t *)src + index); +int64_t getVectorBigintValue_UINT(void *src, int32_t idx) { + return (int64_t)*((uint32_t *)src + idx); } -int64_t getVectorBigintValue_BIGINT(void *src, int32_t index) { - return (int64_t)*((int64_t *)src + index); +int64_t getVectorBigintValue_BIGINT(void *src, int32_t idx) { + return (int64_t)*((int64_t *)src + idx); } -int64_t getVectorBigintValue_UBIGINT(void *src, int32_t index) { - return (int64_t)*((uint64_t *)src + index); +int64_t getVectorBigintValue_UBIGINT(void *src, int32_t idx) { + return (int64_t)*((uint64_t *)src + idx); } _arithmetic_getVectorBigintValue_fn_t getVectorBigintValueFn(int32_t srcType) { diff --git a/src/common/src/tdataformat.c b/src/common/src/tdataformat.c index 55afd4c620..4786700f97 100644 --- a/src/common/src/tdataformat.c +++ b/src/common/src/tdataformat.c @@ -304,14 +304,14 @@ bool isNEleNull(SDataCol *pCol, int nEle) { return true; } -static FORCE_INLINE void dataColSetNullAt(SDataCol *pCol, int index) { +static FORCE_INLINE void dataColSetNullAt(SDataCol *pCol, int idx) { if (IS_VAR_DATA_TYPE(pCol->type)) { - pCol->dataOff[index] = pCol->len; + pCol->dataOff[idx] = pCol->len; char *ptr = POINTER_SHIFT(pCol->pData, pCol->len); setVardataNull(ptr, pCol->type); pCol->len += varDataTLen(ptr); } else { - setNull(POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * index), pCol->type, pCol->bytes); + setNull(POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * idx), pCol->type, pCol->bytes); pCol->len += TYPE_BYTES[pCol->type]; } } diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 2b8c2bbb66..44a53efd8c 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -397,10 +397,10 @@ bool taosCfgDynamicOptions(char *msg) { return false; } -void taosAddDataDir(int index, char *v1, int level, int primary) { - tstrncpy(tsDiskCfg[index].dir, v1, TSDB_FILENAME_LEN); - tsDiskCfg[index].level = level; - tsDiskCfg[index].primary = primary; +void taosAddDataDir(int idx, char *v1, int level, int primary) { + tstrncpy(tsDiskCfg[idx].dir, v1, TSDB_FILENAME_LEN); + tsDiskCfg[idx].level = level; + tsDiskCfg[idx].primary = primary; uTrace("dataDir:%s, level:%d primary:%d is configured", v1, level, primary); } diff --git a/src/common/src/tname.c b/src/common/src/tname.c index 521dcffa6c..7653df3879 100644 --- a/src/common/src/tname.c +++ b/src/common/src/tname.c @@ -442,29 +442,29 @@ void tNameAssign(SName* dst, const SName* src) { memcpy(dst, src, sizeof(SName)); } -int32_t tNameSetDbName(SName* dst, const char* acct, SStrToken* dbToken) { - assert(dst != NULL && dbToken != NULL && acct != NULL); +int32_t tNameSetDbName(SName* dst, const char* accnt, SStrToken* dbToken) { + assert(dst != NULL && dbToken != NULL && accnt != NULL); // too long account id or too long db name - if (strlen(acct) >= tListLen(dst->acctId) || dbToken->n >= tListLen(dst->dbname)) { + if (strlen(accnt) >= tListLen(dst->acctId) || dbToken->n >= tListLen(dst->dbname)) { return -1; } dst->type = TSDB_DB_NAME_T; - tstrncpy(dst->acctId, acct, tListLen(dst->acctId)); + tstrncpy(dst->acctId, accnt, tListLen(dst->acctId)); tstrncpy(dst->dbname, dbToken->z, dbToken->n + 1); return 0; } -int32_t tNameSetAcctId(SName* dst, const char* acct) { - assert(dst != NULL && acct != NULL); +int32_t tNameSetAcctId(SName* dst, const char* accnt) { + assert(dst != NULL && accnt != NULL); // too long account id or too long db name - if (strlen(acct) >= tListLen(dst->acctId)) { + if (strlen(accnt) >= tListLen(dst->acctId)) { return -1; } - tstrncpy(dst->acctId, acct, tListLen(dst->acctId)); + tstrncpy(dst->acctId, accnt, tListLen(dst->acctId)); assert(strlen(dst->acctId) > 0); diff --git a/src/common/src/ttypes.c b/src/common/src/ttypes.c index 81bc9c7275..fa4126350c 100644 --- a/src/common/src/ttypes.c +++ b/src/common/src/ttypes.c @@ -259,8 +259,8 @@ static void getStatics_u64(const void *pData, int32_t numOfRow, int64_t *min, in static void getStatics_f(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max, int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) { float *data = (float *)pData; - float fmin = FLT_MAX; - float fmax = -FLT_MAX; + float flmin = FLT_MAX; + float flmax = -FLT_MAX; double dsum = 0; *minIndex = 0; *maxIndex = 0; @@ -276,20 +276,20 @@ static void getStatics_f(const void *pData, int32_t numOfRow, int64_t *min, int6 float fv = GET_FLOAT_VAL((const char*)&(data[i])); dsum += fv; - if (fmin > fv) { - fmin = fv; + if (flmin > fv) { + flmin = fv; *minIndex = i; } - if (fmax < fv) { - fmax = fv; + if (flmax < fv) { + flmax = fv; *maxIndex = i; } } SET_DOUBLE_VAL(sum, dsum); - SET_DOUBLE_VAL(max, fmax); - SET_DOUBLE_VAL(min, fmin); + SET_DOUBLE_VAL(max, flmax); + SET_DOUBLE_VAL(min, flmin); } static void getStatics_d(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max, diff --git a/src/dnode/src/dnodeCheck.c b/src/dnode/src/dnodeCheck.c index 87baff3067..f0218fdba9 100644 --- a/src/dnode/src/dnodeCheck.c +++ b/src/dnode/src/dnodeCheck.c @@ -229,12 +229,12 @@ static void dnodeAllocCheckItem() { } void dnodeCleanupCheck() { - for (ECheckItemType index = 0; index < TSDB_CHECK_ITEM_MAX; ++index) { - if (tsCheckItem[index].enable && tsCheckItem[index].stopFp) { - (*tsCheckItem[index].stopFp)(); + for (ECheckItemType idx = 0; idx < TSDB_CHECK_ITEM_MAX; ++idx) { + if (tsCheckItem[idx].enable && tsCheckItem[idx].stopFp) { + (*tsCheckItem[idx].stopFp)(); } - if (tsCheckItem[index].cleanUpFp) { - (*tsCheckItem[index].cleanUpFp)(); + if (tsCheckItem[idx].cleanUpFp) { + (*tsCheckItem[idx].cleanUpFp)(); } } } @@ -242,19 +242,19 @@ void dnodeCleanupCheck() { int32_t dnodeInitCheck() { dnodeAllocCheckItem(); - for (ECheckItemType index = 0; index < TSDB_CHECK_ITEM_MAX; ++index) { - if (tsCheckItem[index].initFp) { - if ((*tsCheckItem[index].initFp)() != 0) { - dError("failed to init check item:%s", tsCheckItem[index].name); + for (ECheckItemType idx = 0; idx < TSDB_CHECK_ITEM_MAX; ++idx) { + if (tsCheckItem[idx].initFp) { + if ((*tsCheckItem[idx].initFp)() != 0) { + dError("failed to init check item:%s", tsCheckItem[idx].name); return -1; } } } - for (ECheckItemType index = 0; index < TSDB_CHECK_ITEM_MAX; ++index) { - if (tsCheckItem[index].enable && tsCheckItem[index].startFp) { - if ((*tsCheckItem[index].startFp)() != 0) { - dError("failed to check item:%s", tsCheckItem[index].name); + for (ECheckItemType idx = 0; idx < TSDB_CHECK_ITEM_MAX; ++idx) { + if (tsCheckItem[idx].enable && tsCheckItem[idx].startFp) { + if ((*tsCheckItem[idx].startFp)() != 0) { + dError("failed to check item:%s", tsCheckItem[idx].name); exit(-1); } } diff --git a/src/dnode/src/dnodePeer.c b/src/dnode/src/dnodePeer.c index 08269c0bf6..cc1b1c98aa 100644 --- a/src/dnode/src/dnodePeer.c +++ b/src/dnode/src/dnodePeer.c @@ -56,17 +56,17 @@ int32_t dnodeInitServer() { dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_GRANT] = dnodeDispatchToMPeerQueue; dnodeProcessReqMsgFp[TSDB_MSG_TYPE_DM_STATUS] = dnodeDispatchToMPeerQueue; - SRpcInit rpcInit; - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = tsDnodeDnodePort; - rpcInit.label = "DND-S"; - rpcInit.numOfThreads = 1; - rpcInit.cfp = dnodeProcessReqMsgFromDnode; - rpcInit.sessions = TSDB_MAX_VNODES << 4; - rpcInit.connType = TAOS_CONN_SERVER; - rpcInit.idleTime = tsShellActivityTimer * 1000; - - tsServerRpc = rpcOpen(&rpcInit); + SRpcInit rpcInitial; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = tsDnodeDnodePort; + rpcInitial.label = "DND-S"; + rpcInitial.numOfThreads = 1; + rpcInitial.cfp = dnodeProcessReqMsgFromDnode; + rpcInitial.sessions = TSDB_MAX_VNODES << 4; + rpcInitial.connType = TAOS_CONN_SERVER; + rpcInitial.idleTime = tsShellActivityTimer * 1000; + + tsServerRpc = rpcOpen(&rpcInitial); if (tsServerRpc == NULL) { dError("failed to init inter-dnodes RPC server"); return -1; @@ -123,19 +123,19 @@ static void dnodeProcessReqMsgFromDnode(SRpcMsg *pMsg, SRpcEpSet *pEpSet) { int32_t dnodeInitClient() { char secret[TSDB_KEY_LEN] = "secret"; - SRpcInit rpcInit; - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.label = "DND-C"; - rpcInit.numOfThreads = 1; - rpcInit.cfp = dnodeProcessRspFromDnode; - rpcInit.sessions = TSDB_MAX_VNODES << 4; - rpcInit.connType = TAOS_CONN_CLIENT; - rpcInit.idleTime = tsShellActivityTimer * 1000; - rpcInit.user = "t"; - rpcInit.ckey = "key"; - rpcInit.secret = secret; - - tsClientRpc = rpcOpen(&rpcInit); + SRpcInit rpcInitial; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.label = "DND-C"; + rpcInitial.numOfThreads = 1; + rpcInitial.cfp = dnodeProcessRspFromDnode; + rpcInitial.sessions = TSDB_MAX_VNODES << 4; + rpcInitial.connType = TAOS_CONN_CLIENT; + rpcInitial.idleTime = tsShellActivityTimer * 1000; + rpcInitial.user = "t"; + rpcInitial.ckey = "key"; + rpcInitial.secret = secret; + + tsClientRpc = rpcOpen(&rpcInitial); if (tsClientRpc == NULL) { dError("failed to init mnode rpc client"); return -1; diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c index 0f536a84cc..2bf67f9a5c 100644 --- a/src/dnode/src/dnodeShell.c +++ b/src/dnode/src/dnodeShell.c @@ -85,18 +85,18 @@ int32_t dnodeInitShell() { numOfThreads = 1; } - SRpcInit rpcInit; - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = tsDnodeShellPort; - rpcInit.label = "SHELL"; - rpcInit.numOfThreads = numOfThreads; - rpcInit.cfp = dnodeProcessMsgFromShell; - rpcInit.sessions = tsMaxShellConns; - rpcInit.connType = TAOS_CONN_SERVER; - rpcInit.idleTime = tsShellActivityTimer * 1000; - rpcInit.afp = dnodeRetrieveUserAuthInfo; - - tsShellRpc = rpcOpen(&rpcInit); + SRpcInit rpcInitial; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = tsDnodeShellPort; + rpcInitial.label = "SHELL"; + rpcInitial.numOfThreads = numOfThreads; + rpcInitial.cfp = dnodeProcessMsgFromShell; + rpcInitial.sessions = tsMaxShellConns; + rpcInitial.connType = TAOS_CONN_SERVER; + rpcInitial.idleTime = tsShellActivityTimer * 1000; + rpcInitial.afp = dnodeRetrieveUserAuthInfo; + + tsShellRpc = rpcOpen(&rpcInitial); if (tsShellRpc == NULL) { dError("failed to init shell rpc server"); return -1; @@ -260,10 +260,10 @@ SDnodeStatisInfo dnodeGetStatisInfo() { return info; } -int32_t dnodeGetHttpStatusInfo(int32_t index) { +int32_t dnodeGetHttpStatusInfo(int32_t idx) { int32_t httpStatus = 0; #ifdef HTTP_EMBEDDED - httpStatus = httpGetStatusCodeCount(index); + httpStatus = httpGetStatusCodeCount(idx); #endif return httpStatus; } diff --git a/src/kit/shell/CMakeLists.txt b/src/kit/shell/CMakeLists.txt index b311361c43..614fa328ba 100644 --- a/src/kit/shell/CMakeLists.txt +++ b/src/kit/shell/CMakeLists.txt @@ -46,6 +46,8 @@ ELSEIF (TD_DARWIN) LIST(APPEND SRC ./src/shellCommand.c) LIST(APPEND SRC ./src/shellImport.c) LIST(APPEND SRC ./src/shellCheck.c) + LIST(APPEND SRC ./src/shellAuto.c) + LIST(APPEND SRC ./src/tire.c) ADD_EXECUTABLE(shell ${SRC}) # linking with dylib TARGET_LINK_LIBRARIES(shell taos cJson) diff --git a/src/kit/shell/inc/shellAuto.h b/src/kit/shell/inc/shellAuto.h new file mode 100644 index 0000000000..0bd6bdf403 --- /dev/null +++ b/src/kit/shell/inc/shellAuto.h @@ -0,0 +1,37 @@ +/* + * 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 __SHELL_AUTO__ +#define __SHELL_AUTO__ + +#define TAB_KEY 0x09 + +// press tab key +void pressTabKey(TAOS * con, Command * cmd); + +// press othr key +void pressOtherKey(char c); + +// init shell auto funciton , shell start call once +bool shellAutoInit(); + +// exit shell auto funciton, shell exit call once +void shellAutoExit(); + +// callback autotab module +void callbackAutoTab(char* sqlstr, TAOS* pSql, bool usedb); + + +#endif diff --git a/src/kit/shell/inc/shellCommand.h b/src/kit/shell/inc/shellCommand.h index 6e4d3e382e..47ef6b30a9 100644 --- a/src/kit/shell/inc/shellCommand.h +++ b/src/kit/shell/inc/shellCommand.h @@ -41,6 +41,7 @@ extern void deleteChar(Command *cmd); extern void moveCursorLeft(Command *cmd); extern void moveCursorRight(Command *cmd); extern void positionCursorHome(Command *cmd); +extern void positionCursorMiddle(Command *cmd); extern void positionCursorEnd(Command *cmd); extern void showOnScreen(Command *cmd); extern void updateBuffer(Command *cmd); @@ -51,5 +52,6 @@ int countPrefixOnes(unsigned char c); void clearScreen(int ecmd_pos, int cursor_pos); void printChar(char c, int times); void positionCursor(int step, int direction); +void getPrevCharSize(const char *str, int pos, int *size, int *width); #endif diff --git a/src/kit/shell/inc/tire.h b/src/kit/shell/inc/tire.h new file mode 100644 index 0000000000..88bae54809 --- /dev/null +++ b/src/kit/shell/inc/tire.h @@ -0,0 +1,92 @@ +/* + * 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 __TRIE__ +#define __TRIE__ + +// +// The prefix search tree is a efficient storage words and search words tree, it support 95 visible ascii code character +// +#define FIRST_ASCII 40 // first visiable char is '0' +#define LAST_ASCII 122 // last visilbe char is 'z' + +// capacity save char is 95 +#define CHAR_CNT (LAST_ASCII - FIRST_ASCII + 1) +#define MAX_WORD_LEN 256 // max insert word length + +// define STire +#define TIRE_TREE 0 +#define TIRE_LIST 1 + +typedef struct STireNode { + struct STireNode** d; + bool end; // record end flag +}STireNode; + +typedef struct StrName { + char * name; + struct StrName * next; +}StrName; + + +typedef struct STire { + char type; // see define TIRE_ + STireNode root; + + StrName * head; + StrName * tail; + + int count; // all count + int ref; +}STire; + +typedef struct SMatchNode { + char* word; + struct SMatchNode* next; +}SMatchNode; + + +typedef struct SMatch { + SMatchNode* head; + SMatchNode* tail; // append node to tail + int count; + char pre[MAX_WORD_LEN]; +}SMatch; + + +// ----------- interface ------------- + +// create prefix search tree, return value call freeTire to free +STire* createTire(char type); + +// destroy prefix search tree +void freeTire(STire* tire); + +// add a new word +bool insertWord(STire* tire, char* word); + +// add a new word +bool deleteWord(STire* tire, char* word); + +// match prefix words, if match is not NULL , put all item to match and return match +SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match); + +// get all items from tires tree +SMatch* enumAll(STire* tire); + +// free match result +void freeMatch(SMatch* match); + +#endif diff --git a/src/kit/shell/src/shellAuto.c b/src/kit/shell/src/shellAuto.c new file mode 100644 index 0000000000..8622b201a6 --- /dev/null +++ b/src/kit/shell/src/shellAuto.c @@ -0,0 +1,1761 @@ +/* + * 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 . + */ + +#define __USE_XOPEN +#include "os.h" +#include "tglobal.h" +#include "shell.h" +#include "shellCommand.h" +#include "tkey.h" +#include "tulog.h" +#include "shellAuto.h" +#include "tire.h" +#include "tthread.h" + +// +// ------------- define area --------------- +// +#define UNION_ALL " union all " + + +// extern function +void insertChar(Command *cmd, char *c, int size); + + +typedef struct SAutoPtr { + STire* p; + int ref; +}SAutoPtr; + +typedef struct SWord{ + int type ; // word type , see WT_ define + char * word; + int32_t len; + struct SWord * next; + bool free; // if true need free +}SWord; + +typedef struct { + char * source; + int32_t source_len; // valid data length in source + int32_t count; + SWord* head; + // matched information + int32_t matchIndex; // matched word index in words + int32_t matchLen; // matched length at matched word +}SWords; + + +SWords shellCommands[] = { + {"alter database ", 0, 0, NULL}, + {"alter dnode balance ", 0, 0, NULL}, + {"alter dnode resetlog;", 0, 0, NULL}, + {"alter dnode debugFlag 141;", 0, 0, NULL}, + {"alter dnode monitor 1;", 0, 0, NULL}, + {"alter table ", 0, 0, NULL}, + {"alter table modify column", 0, 0, NULL}, + {"alter local resetlog;", 0, 0, NULL}, + {"alter local DebugFlag 143;", 0, 0, NULL}, + {"alter local cDebugFlag 143;", 0, 0, NULL}, + {"alter local uDebugFlag 143;", 0, 0, NULL}, + {"alter local rpcDebugFlag 143;", 0, 0, NULL}, + {"alter local tmrDebugFlag 143;", 0, 0, NULL}, + {"alter topic", 0, 0, NULL}, + {"alter user pass", 0, 0, NULL}, + {"alter user privilege read", 0, 0, NULL}, + {"alter user privilege write", 0, 0, NULL}, + {"create table using tags(", 0, 0, NULL}, + {"create database ", 0, 0, NULL}, + {"create table as ", 0, 0, NULL}, + {"create dnode ", 0, 0, NULL}, + {"create topic", 0, 0, NULL}, + {"create function ", 0, 0, NULL}, + {"create user pass", 0, 0, NULL}, + {"compact vnode in", 0, 0, NULL}, + {"describe ", 0, 0, NULL}, +#ifdef TD_ENTERPRISE + {"delete from where", 0, 0, NULL}, +#endif + {"drop database ", 0, 0, NULL}, + {"drop table ", 0, 0, NULL}, + {"drop dnode ", 0, 0, NULL}, + {"drop user ;", 0, 0, NULL}, + {"drop function", 0, 0, NULL}, + {"drop topic", 0, 0, NULL}, + {"kill connection", 0, 0, NULL}, + {"kill query", 0, 0, NULL}, + {"kill stream", 0, 0, NULL}, + {"select * from where ", 0, 0, NULL}, + {"select _block_dist() from \\G;", 0, 0, NULL}, + {"select client_version();", 0, 0, NULL}, + {"select current_user();", 0, 0, NULL}, + {"select database;", 0, 0, NULL}, + {"select server_version();", 0, 0, NULL}, + {"set max_binary_display_width ", 0, 0, NULL}, + {"show create database \\G;", 0, 0, NULL}, + {"show create stable \\G;", 0, 0, NULL}, + {"show create table \\G;", 0, 0, NULL}, + {"show connections;", 0, 0, NULL}, + {"show databases;", 0, 0, NULL}, + {"show dnodes;", 0, 0, NULL}, + {"show functions;", 0, 0, NULL}, + {"show modules;", 0, 0, NULL}, + {"show mnodes;", 0, 0, NULL}, + {"show queries;", 0, 0, NULL}, + {"show stables;", 0, 0, NULL}, + {"show stables like ", 0, 0, NULL}, + {"show streams;", 0, 0, NULL}, + {"show scores;", 0, 0, NULL}, + {"show tables;", 0, 0, NULL}, + {"show tables like", 0, 0, NULL}, + {"show users;", 0, 0, NULL}, + {"show variables;", 0, 0, NULL}, + {"show vgroups;", 0, 0, NULL}, + {"insert into values(", 0, 0, NULL}, + {"insert into using tags(", 0, 0, NULL}, + {"use ", 0, 0, NULL}, + {"quit", 0, 0, NULL} +}; + +char * keywords[] = { + "and ", + "asc ", + "desc ", + "from ", + "fill(", + "limit ", + "where ", + "interval(", + "order by ", + "order by ", + "offset ", + "or ", + "group by ", + "now()", + "session(", + "sliding ", + "slimit ", + "soffset ", + "state_window(", + "today() ", + "union all select ", +}; + +char * functions[] = { + "count(", + "sum(", + "avg(", + "last(", + "last_row(", + "top(", + "interp(", + "max(", + "min(", + "now()", + "today()", + "percentile(", + "tail(", + "pow(", + "abs(", + "atan(", + "acos(", + "asin(", + "apercentile(", + "bottom(", + "cast(", + "ceil(", + "char_length(", + "cos(", + "concat(", + "concat_ws(", + "csum(", + "diff(", + "derivative(", + "elapsed(", + "first(", + "floor(", + "hyperloglog(", + "histogram(", + "irate(", + "leastsquares(", + "length(", + "log(", + "lower(", + "ltrim(", + "mavg(", + "mode(", + "tan(", + "round(", + "rtrim(", + "sample(", + "sin(", + "spread(", + "substr(", + "statecount(", + "stateduration(", + "stddev(", + "sqrt(", + "timediff(", + "timezone(", + "timetruncate(", + "twa(", + "to_unixtimestamp(", + "unique(", + "upper(", +}; + +char * tb_actions[] = { + "add column", + "modify column", + "drop column", + "change tag", +}; + +char * db_options[] = { + "blocks", + "cachelast", + "comp", + "keep", + "replica", + "quorum", +}; + +char * data_types[] = { + "timestamp", + "int", + "float", + "double", + "binary(16)", + "nchar(16)", + "bigint", + "smallint", + "tinyint", + "bool", + "json" +}; + +char * key_tags[] = { + "tags(" +}; + + +// +// ------- gobal variant define --------- +// +int32_t firstMatchIndex = -1; // first match shellCommands index +int32_t lastMatchIndex = -1; // last match shellCommands index +int32_t curMatchIndex = -1; // current match shellCommands index +int32_t lastWordBytes = -1; // printShow last word length +bool waitAutoFill = false; + + +// +// ----------- global var array define ----------- +// +#define WT_VAR_DBNAME 0 +#define WT_VAR_STABLE 1 +#define WT_VAR_TABLE 2 +#define WT_VAR_DNODEID 3 +#define WT_VAR_USERNAME 4 +#define WT_VAR_ALLTABLE 5 +#define WT_VAR_FUNC 6 +#define WT_VAR_KEYWORD 7 +#define WT_VAR_TBACTION 8 +#define WT_VAR_DBOPTION 9 +#define WT_VAR_DATATYPE 10 +#define WT_VAR_KEYTAGS 11 +#define WT_VAR_ANYWORD 12 +#define WT_VAR_CNT 13 + +#define WT_FROM_DB_MAX 4 // max get content from db +#define WT_FROM_DB_CNT (WT_FROM_DB_MAX + 1) + +#define WT_TEXT 0xFF + +char dbName[256] = ""; // save use database name; +// tire array +STire* tires[WT_VAR_CNT]; +pthread_mutex_t tiresMutex; +//save thread handle obtain var name from db server +pthread_t* threads[WT_FROM_DB_CNT]; +// obtain var name with sql from server +char varTypes[WT_VAR_CNT][64] = { + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" +}; + +char varSqls[WT_FROM_DB_CNT][64] = { + "show databases;", + "show stables;", + "show tables;", + "show dnodes;", + "show users;" +}; + + +// var words current cursor, if user press any one key except tab, cursorVar can be reset to -1 +int cursorVar = -1; +bool varMode = false; // enter var names list mode + + +TAOS* varCon = NULL; +Command* varCmd = NULL; +SMatch* lastMatch = NULL; // save last match result +int cntDel = 0; // delete byte count after next press tab + + +// show auto tab introduction +void printfIntroduction() { + printf(" ********************* How to Use TAB in TAOS Shell ******************************\n"); + printf(" * Taos shell supports pressing TAB key to complete word. You can try it. *\n"); + printf(" * Press TAB key anywhere, You'll get surprise. *\n"); + printf(" * KEYBOARD SHORTCUT: *\n"); + printf(" * [ TAB ] ...... Complete the word or show help if no input *\n"); + printf(" * [ Ctrl + A ] ...... move cursor to [A]head of line *\n"); + printf(" * [ Ctrl + E ] ...... move cursor to [E]nd of line *\n"); + printf(" * [ Ctrl + W ] ...... move cursor to line of middle *\n"); + printf(" * [ Ctrl + L ] ...... clean screen *\n"); + printf(" * [ Ctrl + K ] ...... clean after cursor *\n"); + printf(" * [ Ctrl + U ] ...... clean before cursor *\n"); + printf(" * *\n"); + printf(" **********************************************************************************\n\n"); +} + +void showHelp() { + printf("\nThe following are supported commands for Taos shell:"); + printf("\n\ + ----- A ----- \n\ + alter database \n\ + alter dnode balance \n\ + alter dnode resetlog;\n\ + alter dnode DebugFlag 143;\n\ + alter dnode monitor 1;\n\ + alter table ADD COLUMN ; \n\ + alter table DROP COLUMN ; \n\ + alter table MODIFY COLUMN ;\n\ + alter local resetlog; \n\ + alter local DebugFlag 143; \n\ + alter topic \n\ + alter user pass\n\ + alter user privilege read ;\n\ + alter user privilege write ;\n\ + ----- C ----- \n\ + create table using tags ...\n\ + create database ;\n\ + create table as ...\n\ + create dnode \n\ + create topic \n\ + create function \n\ + create user pass ;\n\ + compact vnode in (vgid,vgid,vgid);\n\ + ----- D ----- \n\ + describe ;\n\ + delete from where ... \n\ + drop database ;\n\ + drop table ;\n\ + drop dnode ;\n\ + drop function ;\n\ + drop topic ;\n\ + drop user ;\n\ + ----- K ----- \n\ + kill connection ; \n\ + kill query ; \n\ + kill stream ; \n\ + ----- S ----- \n\ + select * from where ... \n\ + select _block_dist() from ;\n\ + select client_version();\n\ + select current_user();\n\ + select database;\n\ + select server_version();\n\ + set max_binary_display_width ; \n\ + show create database ;\n\ + show create stable ;\n\ + show create table ;\n\ + show connections;\n\ + show databases;\n\ + show dnodes;\n\ + show functions;\n\ + show modules;\n\ + show mnodes;\n\ + show queries;\n\ + show stables;\n\ + show stables like ''; note: regular expression only support '_' and '%%' match.\n\ + show streams;\n\ + show scores;\n\ + show tables;\n\ + show tables like ''; \n\ + show users;\n\ + show variables;\n\ + show vgroups;\n\ + ----- I ----- \n\ + insert into values(...) ;\n\ + ----- U ----- \n\ + use ;"); + + printf("\n\n"); + + //define in getDuration() function + printf("\ + Timestamp expression Format:\n\ + b - nanosecond \n\ + u - microsecond \n\ + a - millisecond \n\ + s - second \n\ + m - minute \n\ + h - hour \n\ + d - day \n\ + w - week \n\ + now - current time \n\ + Example : \n\ + select * from t1 where ts > now - 2w + 3d and ts <= now - 1w -2h ;\n"); + printf("\n"); +} + +// +// ------------------- parse words -------------------------- +// + +#define SHELL_COMMAND_COUNT() (sizeof(shellCommands) / sizeof(SWords)) + +// get at +SWord * atWord(SWords * command, int32_t index) { + SWord * word = command->head; + for (int32_t i = 0; i < index; i++) { + if (word == NULL) + return NULL; + word = word->next; + } + + return word; +} + +#define MATCH_WORD(x) atWord(x, x->matchIndex) + +int wordType(const char* p, int32_t len) { + for (int i = 0; i < WT_VAR_CNT; i++) { + if (strncmp(p, varTypes[i], len) == 0) + return i; + } + return WT_TEXT; +} + +// add word +SWord * addWord(const char* p, int32_t len, bool pattern) { + SWord* word = (SWord *) malloc(sizeof(SWord)); + memset(word, 0, sizeof(SWord)); + word->word = (char* )p; + word->len = len; + + // check format + if (pattern) { + word->type = wordType(p, len); + } else { + word->type = WT_TEXT; + } + + return word; +} + +// parse one command +void parseCommand(SWords * command, bool pattern) { + char * p = command->source; + int32_t start = 0; + int32_t size = command->source_len > 0 ? command->source_len : strlen(p); + + bool lastBlank = false; + for (int i = 0; i <= size; i++) { + if (p[i] == ' ' || i == size) { + // check continue blank like ' ' + if (p[i] == ' ') { + if (lastBlank) { + start ++; + continue; + } + if (i == 0) { // first blank + lastBlank = true; + start ++; + continue; + } + lastBlank = true; + } + + // found split or string end , append word + if (command->head == NULL) { + command->head = addWord(p + start, i - start, pattern); + command->count = 1; + } else { + SWord * word = command->head; + while (word->next) { + word = word->next; + } + word->next = addWord(p + start, i - start, pattern); + command->count ++; + } + start = i + 1; + } else { + lastBlank = false; + } + } +} + +// free Command +void freeCommand(SWords * command) { + SWord * word = command->head; + if (word == NULL) { + return ; + } + + // loop + while (word->next) { + SWord * tmp = word; + word = word->next; + // if malloc need free + if(tmp->free && tmp->word) + free(tmp->word); + free(tmp); + } + + // if malloc need free + if(word->free && word->word) + free(word->word); + free(word); +} + +void GenerateVarType(int type, char** p, int count) { + STire* tire = createTire(TIRE_LIST); + for (int i = 0; i < count; i++) { + insertWord(tire, p[i]); + } + + pthread_mutex_lock(&tiresMutex); + tires[type] = tire; + pthread_mutex_unlock(&tiresMutex); +} + +// +// -------------------- shell auto ---------------- +// + + +// init shell auto funciton , shell start call once +bool shellAutoInit() { + // command + int32_t count = SHELL_COMMAND_COUNT(); + for (int32_t i = 0; i < count; i ++) { + parseCommand(shellCommands + i, true); + } + + // tires + memset(tires, 0, sizeof(STire*) * WT_VAR_CNT); + pthread_mutex_init(&tiresMutex, NULL); + + // threads + memset(threads, 0, sizeof(pthread_t*) * WT_FROM_DB_CNT); + + // generate varType + GenerateVarType(WT_VAR_FUNC, functions, sizeof(functions) /sizeof(char *)); + GenerateVarType(WT_VAR_KEYWORD, keywords, sizeof(keywords) /sizeof(char *)); + GenerateVarType(WT_VAR_DBOPTION, db_options, sizeof(db_options) /sizeof(char *)); + GenerateVarType(WT_VAR_TBACTION, tb_actions, sizeof(tb_actions) /sizeof(char *)); + GenerateVarType(WT_VAR_DATATYPE, data_types, sizeof(data_types) /sizeof(char *)); + GenerateVarType(WT_VAR_KEYTAGS, key_tags, sizeof(key_tags) /sizeof(char *)); + + printfIntroduction(); + + return true; +} + +// exit shell auto funciton, shell exit call once +void shellAutoExit() { + // free command + int32_t count = SHELL_COMMAND_COUNT(); + for (int32_t i = 0; i < count; i ++) { + freeCommand(shellCommands + i); + } + + // free tires + pthread_mutex_lock(&tiresMutex); + for (int32_t i = 0; i < WT_VAR_CNT; i++) { + if (tires[i]) { + freeTire(tires[i]); + tires[i] = NULL; + } + } + pthread_mutex_unlock(&tiresMutex); + // destory + pthread_mutex_destroy(&tiresMutex); + + // free threads + for (int32_t i = 0; i < WT_VAR_CNT; i++) { + if (threads[i]) { + taosDestroyThread(threads[i]); + threads[i] = NULL; + } + } + + // free lastMatch + if (lastMatch) { + freeMatch(lastMatch); + lastMatch = NULL; + } +} + +// +// ------------------- auto ptr for tires -------------------------- +// +bool setNewAuotPtr(int type, STire* pNew) { + if (pNew == NULL) + return false; + + pthread_mutex_lock(&tiresMutex); + STire* pOld = tires[type]; + if (pOld != NULL) { + // previous have value, release self ref count + if (--pOld->ref == 0) { + freeTire(pOld); + } + } + + // set new + tires[type] = pNew; + tires[type]->ref = 1; + pthread_mutex_unlock(&tiresMutex); + + return true; +} + +// get ptr +STire* getAutoPtr(int type) { + if (tires[type] == NULL) { + return NULL; + } + + pthread_mutex_lock(&tiresMutex); + tires[type]->ref++; + pthread_mutex_unlock(&tiresMutex); + + return tires[type]; +} + +// put back tire to tires[type], if tire not equal tires[type].p, need free tire +void putBackAutoPtr(int type, STire* tire) { + if (tire == NULL) { + return ; + } + + pthread_mutex_lock(&tiresMutex); + if (tires[type] != tire) { + //update by out, can't put back , so free + if (--tire->ref == 1) { + // support multi thread getAuotPtr + freeTire(tire); + } + + } else { + tires[type]->ref--; + assert(tires[type]->ref > 0); + } + pthread_mutex_unlock(&tiresMutex); + + return ; +} + + + +// +// ------------------- var Word -------------------------- +// + +#define MAX_CACHED_CNT 100000 // max cached rows 10w +// write sql result to var name, return write rows cnt +int writeVarNames(int type, TAOS_RES* tres) { + // fetch row + TAOS_ROW row = taos_fetch_row(tres); + if (row == NULL) { + return 0; + } + + TAOS_FIELD *fields = taos_fetch_fields(tres); + // create new tires + char tireType = type == WT_VAR_TABLE ? TIRE_TREE : TIRE_LIST; + STire* tire = createTire(tireType); + + // enum rows + char name[1024]; + int numOfRows = 0; + do { + int32_t* lengths = taos_fetch_lengths(tres); + int32_t bytes = lengths[0]; + if(fields[0].type == TSDB_DATA_TYPE_SMALLINT) { + sprintf(name,"%d", *(int16_t*)row[0]); + } else { + memcpy(name, row[0], bytes); + } + + name[bytes] = 0; //set string end + // insert to tire + insertWord(tire, name); + + if (++numOfRows > MAX_CACHED_CNT ) { + break; + } + + row = taos_fetch_row(tres); + } while (row != NULL); + + // replace old tire + setNewAuotPtr(type, tire); + + return numOfRows; +} + +bool firstMatchCommand(TAOS * con, Command * cmd); +// +// thread obtain var thread from db server +// +void* varObtainThread(void* param) { + int type = *(int* )param; + free(param); + + if (varCon == NULL || type > WT_FROM_DB_MAX) { + return NULL; + } + + TAOS_RES* pSql = taos_query_h(varCon, varSqls[type], NULL); + if (taos_errno(pSql)) { + taos_free_result(pSql); + return NULL; + } + + // write var names from pSql + int cnt = writeVarNames(type, pSql); + + // free sql + taos_free_result(pSql); + + // check need call auto tab + if (cnt > 0 && waitAutoFill) { + // press tab key by program + firstMatchCommand(varCon, varCmd); + } + + return NULL; +} + +// only match next one word from all match words, return valuue must free by caller +char* matchNextPrefix(STire* tire, char* pre) { + SMatch* match = NULL; + + // re-use last result + if (lastMatch) { + if (strcmp(pre, lastMatch->pre) == 0) { + // same pre + match = lastMatch; + } + } + + if (match == NULL) { + // not same with last result + if (pre[0] == 0) { + // EMPTY PRE + match = enumAll(tire); + } else { + // NOT EMPTY + match = matchPrefix(tire, pre, NULL); + } + + // save to lastMatch + if (match) { + if (lastMatch) + freeMatch(lastMatch); + lastMatch = match; + } + } + + // check valid + if (match == NULL || match->head == NULL) { + // no one matched + return false; + } + + if (cursorVar == -1) { + // first + cursorVar = 0; + return strdup(match->head->word); + } + + // according to cursorVar , calculate next one + int i = 0; + SMatchNode* item = match->head; + while (item) { + if (i == cursorVar + 1) { + // found next position ok + if (item->next == NULL) { + // match last item, reset cursorVar to head + cursorVar = -1; + } else { + cursorVar = i; + } + + return strdup(item->word); + } + + // check end item + if (item->next == NULL) { + // if cursorVar > var list count, return last and reset cursorVar + cursorVar = -1; + + return strdup(item->word); + } + + // move next + item = item->next; + i++; + } + + return NULL; +} + +// search pre word from tire tree, return value must free by caller +char* tireSearchWord(int type, char* pre) { + if (type == WT_TEXT) { + return NULL; + } + + if(type > WT_FROM_DB_MAX) { + // NOT FROM DB , tires[type] alwary not null + STire* tire = tires[type]; + if (tire == NULL) + return NULL; + return matchNextPrefix(tire, pre); + } + + // TYPE CONTEXT GET FROM DB + pthread_mutex_lock(&tiresMutex); + + // check need obtain from server + if (tires[type] == NULL) { + waitAutoFill = true; + // need async obtain var names from db sever + if (threads[type] != NULL) { + if (taosThreadRunning(threads[type])) { + // thread running , need not obtain again, return + pthread_mutex_unlock(&tiresMutex); + return NULL; + } + // destroy previous thread handle for new create thread handle + taosDestroyThread(threads[type]); + threads[type] = NULL; + } + + // create new + void * param = malloc(sizeof(int)); + *((int* )param) = type; + threads[type] = taosCreateThread(varObtainThread, param); + pthread_mutex_unlock(&tiresMutex); + return NULL; + } + pthread_mutex_unlock(&tiresMutex); + + // can obtain var names from local + STire* tire = getAutoPtr(type); + if (tire == NULL) { + return NULL; + } + + char* str = matchNextPrefix(tire, pre); + // used finish, put back pointer to autoptr array + putBackAutoPtr(type, tire); + + return str; +} + +// match var word, word1 is pattern , word2 is input from shell +bool matchVarWord(SWord* word1, SWord* word2) { + // search input word from tire tree + char pre[512]; + memcpy(pre, word2->word, word2->len); + pre[word2->len] = 0; + + char* str = NULL; + if (word1->type == WT_VAR_ALLTABLE) { + // ALL_TABLE + str = tireSearchWord(WT_VAR_STABLE, pre); + if (str == NULL) { + str = tireSearchWord(WT_VAR_TABLE, pre); + if(str == NULL) + return false; + } + } else { + // OTHER + str = tireSearchWord(word1->type, pre); + if (str == NULL) { + // not found or word1->type variable list not obtain from server, return not match + return false; + } + } + + // free previous malloc + if(word1->free && word1->word) { + free(word1->word); + } + + // save + word1->word = str; + word1->len = strlen(str); + word1->free = true; // need free + + return true; +} + +// +// ------------------- match words -------------------------- +// + + +// compare command cmd1 come from shellCommands , cmd2 come from user input +int32_t compareCommand(SWords * cmd1, SWords * cmd2) { + SWord * word1 = cmd1->head; + SWord * word2 = cmd2->head; + + if (word1 == NULL || word2 == NULL) { + return -1; + } + + for (int32_t i = 0; i < cmd1->count; i++) { + if (word1->type == WT_TEXT) { + // WT_TEXT match + if (word1->len == word2->len) { + if (strncasecmp(word1->word, word2->word, word1->len) != 0) + return -1; + } else if (word1->len < word2->len) { + return -1; + } else { + // word1->len > word2->len + if (strncasecmp(word1->word, word2->word, word2->len) == 0) { + cmd1->matchIndex = i; + cmd1->matchLen = word2->len; + return i; + } else { + return -1; + } + } + } else { + // WT_VAR auto match any one word + if (word2->next == NULL) { // input words last one + if (matchVarWord(word1, word2)) { + cmd1->matchIndex = i; + cmd1->matchLen = word2->len; + varMode = true; + return i; + } + return -1; + } + } + + // move next + word1 = word1->next; + word2 = word2->next; + if (word1 == NULL || word2 == NULL) { + return -1; + } + } + + return -1; +} + +// match command +SWords * matchCommand(SWords * input, bool continueSearch) { + int32_t count = SHELL_COMMAND_COUNT(); + for (int32_t i = 0; i < count; i ++) { + SWords * shellCommand = shellCommands + i; + if (continueSearch && lastMatchIndex != -1 && i <= lastMatchIndex) { + // new match must greate than lastMatchIndex + if (varMode && i == lastMatchIndex) { + // do nothing, var match on lastMatchIndex + } else { + continue; + } + } + + // command is large + if (input->count > shellCommand->count ) { + continue; + } + + // compare + int32_t index = compareCommand(shellCommand, input); + if (index != -1) { + if (firstMatchIndex == -1) + firstMatchIndex = i; + curMatchIndex = i; + return &shellCommands[i]; + } + } + + // not match + return NULL; +} + +// +// ------------------- print screen -------------------------- +// + +// delete char count +void deleteCount(Command * cmd, int count) { + int size = 0; + int width = 0; + clearScreen(cmd->endOffset + prompt_size, cmd->screenOffset + prompt_size); + + // loop delete + while (--count >= 0 && cmd->cursorOffset > 0) { + getPrevCharSize(cmd->command, cmd->cursorOffset, &size, &width); + memmove(cmd->command + cmd->cursorOffset - size, cmd->command + cmd->cursorOffset, + cmd->commandSize - cmd->cursorOffset); + cmd->commandSize -= size; + cmd->cursorOffset -= size; + cmd->screenOffset -= width; + cmd->endOffset -= width; + } +} + +// show screen +void printScreen(TAOS * con, Command * cmd, SWords * match) { + // modify Command + if (firstMatchIndex == -1 || curMatchIndex == -1) { + // no match + return ; + } + + // first tab press + const char * str = NULL; + int strLen = 0; + + if (firstMatchIndex == curMatchIndex && lastWordBytes == -1) { + // first press tab + SWord * word = MATCH_WORD(match); + str = word->word + match->matchLen; + strLen = word->len - match->matchLen; + lastMatchIndex = firstMatchIndex; + lastWordBytes = word->len; + } else { + if (lastWordBytes == -1) + return ; + deleteCount(cmd, lastWordBytes); + + SWord * word = MATCH_WORD(match); + str = word->word; + strLen = word->len; + // set current to last + lastMatchIndex = curMatchIndex; + lastWordBytes = word->len; + } + + // insert new + insertChar(cmd, (char *)str, strLen); +} + + +// main key press tab , matched return true else false +bool firstMatchCommand(TAOS * con, Command * cmd) { + // parse command + SWords* input = (SWords *)malloc(sizeof(SWords)); + memset(input, 0, sizeof(SWords)); + input->source = cmd->command; + input->source_len = cmd->commandSize; + parseCommand(input, false); + + // if have many , default match first, if press tab again , switch to next + curMatchIndex = -1; + lastMatchIndex = -1; + SWords * match = matchCommand(input, true); + if (match == NULL) { + // not match , nothing to do + freeCommand(input); + free(input); + return false; + } + + // print to screen + printScreen(con, cmd, match); + freeCommand(input); + free(input); + return true; +} + +// create input source +void createInputFromFirst(SWords* input, SWords * firstMatch) { + // + // if next pressTabKey , input context come from firstMatch, set matched length with source_len + // + input->source = (char*)malloc(1024); + memset((void* )input->source, 0, 1024); + + SWord * word = firstMatch->head; + + // source_len = full match word->len + half match with firstMatch->matchLen + for (int i = 0; i < firstMatch->matchIndex && word; i++) { + // combine source from each word + strncpy(input->source + input->source_len, word->word, word->len); + strcat(input->source, " "); // append blank splite + input->source_len += word->len + 1; // 1 is blank length + // move next + word = word->next; + } + // appand half matched word for last + if (word) { + strncpy(input->source + input->source_len, word->word, firstMatch->matchLen); + input->source_len += firstMatch->matchLen; + } +} + +// user press Tabkey again is named next , matched return true else false +bool nextMatchCommand(TAOS * con, Command * cmd, SWords * firstMatch) { + if (firstMatch == NULL || firstMatch->head == NULL) { + return false; + } + SWords* input = (SWords *)malloc(sizeof(SWords)); + memset(input, 0, sizeof(SWords)); + + // create input from firstMatch + createInputFromFirst(input, firstMatch); + + // parse input + parseCommand(input, false); + + // if have many , default match first, if press tab again , switch to next + SWords * match = matchCommand(input, true); + if (match == NULL) { + // if not match , reset all index + firstMatchIndex = -1; + curMatchIndex = -1; + match = matchCommand(input, false); + if (match == NULL) { + freeCommand(input); + if (input->source) + free(input->source); + free(input); + return false; + } + } + + // print to screen + printScreen(con, cmd, match); + + // free + if (input->source) { + free(input->source); + input->source = NULL; + } + freeCommand(input); + free(input); + + return true; +} + +// fill with type +bool fillWithType(TAOS * con, Command * cmd, char* pre, int type) { + // get type + STire* tire = tires[type]; + char* str = matchNextPrefix(tire, pre); + if (str == NULL) { + return false; + } + + // need insert part string + char * part = str + strlen(pre); + + // show + int count = strlen(part); + insertChar(cmd, part, count); + cntDel = count; // next press tab delete current append count + + free(str); + return true; +} + +// fill with type +bool fillTableName(TAOS * con, Command * cmd, char* pre) { + // search stable and table + char * str = tireSearchWord(WT_VAR_STABLE, pre); + if (str == NULL) { + str = tireSearchWord(WT_VAR_TABLE, pre); + if(str == NULL) + return false; + } + + // need insert part string + char * part = str + strlen(pre); + + // delete autofill count last append + if(cntDel > 0) { + deleteCount(cmd, cntDel); + cntDel = 0; + } + + // show + int count = strlen(part); + insertChar(cmd, part, count); + cntDel = count; // next press tab delete current append count + + free(str); + return true; +} + +// +// find last word from sql select clause +// example : +// 1 select cou -> press tab select count( +// 2 select count(*),su -> select count(*), sum( +// 3 select count(*), su -> select count(*), sum( +// +char * lastWord(char * p) { + // get near from end revert find ' ' and ',' + char * p1 = strrchr(p, ' '); + char * p2 = strrchr(p, ','); + + if (p1 && p2) { + return MAX(p1, p2) + 1; + } else if (p1) { + return p1 + 1; + } else if(p2) { + return p2 + 1; + } else { + return p; + } +} + +bool fieldsInputEnd(char* sql) { + // not in '()' + char* p1 = strrchr(sql, '('); + char* p2 = strrchr(sql, ')'); + if (p1 && p2 == NULL) { + // like select count( ' ' + return false; + } else if (p1 && p2 && p1 > p2) { + // like select sum(age), count( ' ' + return false; + } + + // not in ',' + char * p3 = strrchr(sql, ','); + char * p = p3; + // like select ts, age,' ' + if (p) { + ++p; + bool allBlank = true; // after last ',' all char is blank + int cnt = 0; // blank count , like ' ' as one blank + char * plast = NULL; // last blank position + while(*p) { + if (*p == ' ') { + plast = p; + cnt ++; + } else { + allBlank = false; + } + ++p; + } + + // any one word is not blank + if(allBlank) { + return false; + } + + // like 'select count(*),sum(age) fr' need return true + if (plast && plast > p3 && p2 > p1 && plast > p2 && p1 > p3) { + return true; + } + + // if last char not ' ', then not end field, like 'select count(*), su' can fill sum( + if(sql[strlen(sql)-1] != ' ' && cnt <= 1) { + return false; + } + } + + char * p4 = strrchr(sql, ' '); + if(p4 == NULL) { + // only one word + return false; + } + + return true; +} + +// need insert from +bool needInsertFrom(char * sql, int len) { + // last is blank + if(sql[len-1] != ' ') { + // insert from keyword + return false; + } + + // select fields input is end + if (!fieldsInputEnd(sql)) { + return false; + } + + // can insert from keyword + return true; +} + +bool matchSelectQuery(TAOS * con, Command * cmd) { + // if continue press Tab , delete bytes by previous autofill + if (cntDel > 0) { + deleteCount(cmd, cntDel); + cntDel = 0; + } + + // match select ... + int len = cmd->commandSize; + char * p = cmd->command; + + // remove prefix blank + while (p[0] == ' ' && len > 0) { + p++; + len--; + } + + // special range + if(len < 7 || len > 512) { + return false; + } + + // select and from + if(strncasecmp(p, "select ", 7) != 0) { + // not select query clause + return false; + } + p += 7; + len -= 7; + + char* ps = p = strndup(p, len); + + // union all + char * p1; + do { + p1 = strstr(p, UNION_ALL); + if(p1) { + p = p1 + strlen(UNION_ALL); + } + } while (p1); + + char * from = strstr(p, " from "); + //last word , maybe empty string or some letters of a string + char * last = lastWord(p); + bool ret = false; + if (from == NULL) { + bool fieldEnd = fieldsInputEnd(p); + // cheeck fields input end then insert from keyword + if (fieldEnd && p[len-1] == ' ') { + insertChar(cmd, "from", 4); + free(ps); + return true; + } + + // fill funciton + if(fieldEnd) { + // fields is end , need match keyword + ret = fillWithType(con, cmd, last, WT_VAR_KEYWORD); + } else { + ret = fillWithType(con, cmd, last, WT_VAR_FUNC); + } + + free(ps); + return ret; + } + + // have from + char * blank = strstr(from + 6, " "); + if (blank == NULL) { + // no table name, need fill + ret = fillTableName(con, cmd, last); + } else { + ret = fillWithType(con, cmd, last, WT_VAR_KEYWORD); + } + + free(ps); + return ret; +} + +// if is input create fields or tags area, return true +bool isCreateFieldsArea(char * p) { + char * left = strrchr(p, '('); + if (left == NULL) { + // like 'create table st' + return false; + } + + char * right = strrchr(p, ')'); + if(right == NULL) { + // like 'create table st( ' + return true; + } + + if (left > right) { + // like 'create table st( ts timestamp, age int) tags(area ' + return true; + } + + return false; +} + +bool matchCreateTable(TAOS * con, Command * cmd) { + // if continue press Tab , delete bytes by previous autofill + if (cntDel > 0) { + deleteCount(cmd, cntDel); + cntDel = 0; + } + + // match select ... + int len = cmd->commandSize; + char * p = cmd->command; + + // remove prefix blank + while (p[0] == ' ' && len > 0) { + p++; + len--; + } + + // special range + if(len < 7 || len > 1024) { + return false; + } + + // select and from + if(strncasecmp(p, "create table ", 13) != 0) { + // not select query clause + return false; + } + p += 13; + len -= 13; + + char* ps = strndup(p, len); + bool ret = false; + char * last = lastWord(ps); + + // check in create fields or tags input area + if (isCreateFieldsArea(ps)) { + ret = fillWithType(con, cmd, last, WT_VAR_DATATYPE); + } + + // tags + if (!ret) { + // find only one ')' , can insert tags + char * p1 = strchr(ps, ')'); + if (p1) { + if(strchr(p1 + 1, ')') == NULL && strstr(p1 + 1, "tags") == NULL) { + // can insert tags keyword + ret = fillWithType(con, cmd, last, WT_VAR_KEYTAGS); + } + } + } + + free(ps); + return ret; +} + +bool matchOther(TAOS * con, Command * cmd) { + int len = cmd->commandSize; + char* p = cmd->command; + + if (p[len - 1] == '\\') { + // append '\G' + char a[] = "G;"; + insertChar(cmd, a, 2); + return true; + } + + return false; +} + + +// main key press tab +void pressTabKey(TAOS * con, Command * cmd) { + // check + if (cmd->commandSize == 0) { + // empty + showHelp(); + showOnScreen(cmd); + return ; + } + + // save connection to global + varCon = con; + varCmd = cmd; + bool matched = false; + + // manual match like create table st( ... + matched = matchCreateTable(con, cmd); + if (matched) + return ; + + // shellCommands match + if (firstMatchIndex == -1) { + matched = firstMatchCommand(con, cmd); + } else { + matched = nextMatchCommand(con, cmd, &shellCommands[firstMatchIndex]); + } + if (matched) + return ; + + // NOT MATCHED ANYONE + // match other like '\G' ... + matched = matchOther(con, cmd); + if (matched) + return ; + + // manual match like select * from ... + matched = matchSelectQuery(con, cmd); + if (matched) + return ; + + return ; +} + +// press othr key +void pressOtherKey(char c) { + // reset global variant + firstMatchIndex = -1; + lastMatchIndex = -1; + curMatchIndex = -1; + lastWordBytes = -1; + + // var names + cursorVar = -1; + varMode = false; + waitAutoFill = false; + cntDel = 0; + + if (lastMatch) { + freeMatch(lastMatch); + lastMatch = NULL; + } +} + +// put name into name, return name length +int getWordName(char* p, char * name, int nameLen) { + //remove prefix blank + while (*p == ' ') { + p++; + } + + // get databases name; + int i = 0; + while(p[i] != 0 && i < nameLen - 1) { + name[i] = p[i]; + i++; + if(p[i] == ' ' || p[i] == ';'|| p[i] == '(') { + // name end + break; + } + } + name[i] = 0; + + return i; +} + +// deal use db, if have 'use' return true +bool dealUseDB(char * sql) { + // check use keyword + if(strncasecmp(sql, "use ", 4) != 0) { + return false; + } + + char db[256]; + char *p = sql + 4; + if (getWordName(p, db, sizeof(db)) == 0) { + // no name , return + return true; + } + + // dbName is previous use open db name + if (strcasecmp(db, dbName) == 0) { + // same , no need switch + return true; + } + + // switch new db + pthread_mutex_lock(&tiresMutex); + // STABLE set null + STire* tire = tires[WT_VAR_STABLE]; + tires[WT_VAR_STABLE] = NULL; + if(tire) { + freeTire(tire); + } + // TABLE set null + tire = tires[WT_VAR_TABLE]; + tires[WT_VAR_TABLE] = NULL; + if(tire) { + freeTire(tire); + } + // save + strcpy(dbName, db); + pthread_mutex_unlock(&tiresMutex); + + return true; +} + +// deal create, if have 'create' return true +bool dealCreateCommand(char * sql) { + // check keyword + if(strncasecmp(sql, "create ", 7) != 0) { + return false; + } + + char name[1024]; + char *p = sql + 7; + if (getWordName(p, name, sizeof(name)) == 0) { + // no name , return + return true; + } + + int type = -1; + // dbName is previous use open db name + if (strcasecmp(name, "database") == 0) { + type = WT_VAR_DBNAME; + } else if (strcasecmp(name, "table") == 0) { + if(strstr(sql, " tags") != NULL && strstr(sql, " using ") == NULL) + type = WT_VAR_STABLE; + else + type = WT_VAR_TABLE; + } else if (strcasecmp(name, "user") == 0) { + type = WT_VAR_USERNAME; + } else { + // no match , return + return true; + } + + // move next + p += strlen(name); + + // get next word , that is table name + if (getWordName(p, name, sizeof(name)) == 0) { + // no name , return + return true; + } + + // switch new db + pthread_mutex_lock(&tiresMutex); + // STABLE set null + STire* tire = tires[type]; + if(tire) { + insertWord(tire, name); + } + pthread_mutex_unlock(&tiresMutex); + + return true; +} + +// deal create, if have 'drop' return true +bool dealDropCommand(char * sql) { + // check keyword + if(strncasecmp(sql, "drop ", 5) != 0) { + return false; + } + + char name[1024]; + char *p = sql + 5; + if (getWordName(p, name, sizeof(name)) == 0) { + // no name , return + return true; + } + + int type = -1; + // dbName is previous use open db name + if (strcasecmp(name, "database") == 0) { + type = WT_VAR_DBNAME; + } else if (strcasecmp(name, "table") == 0) { + type = WT_VAR_ALLTABLE; + } else if (strcasecmp(name, "dnode") == 0) { + type = WT_VAR_DNODEID; + } else if (strcasecmp(name, "user") == 0) { + type = WT_VAR_USERNAME; + } else { + // no match , return + return true; + } + + // move next + p += strlen(name); + + // get next word , that is table name + if (getWordName(p, name, sizeof(name)) == 0) { + // no name , return + return true; + } + + // switch new db + pthread_mutex_lock(&tiresMutex); + // STABLE set null + if(type == WT_VAR_ALLTABLE) { + bool del = false; + // del in stable + STire* tire = tires[WT_VAR_STABLE]; + if(tire) + del = deleteWord(tire, name); + // del in table + if(!del) { + tire = tires[WT_VAR_TABLE]; + if(tire) + del = deleteWord(tire, name); + } + } else { + // OTHER TYPE + STire* tire = tires[type]; + if(tire) + deleteWord(tire, name); + } + pthread_mutex_unlock(&tiresMutex); + + return true; +} + +// callback autotab module after shell sql execute +void callbackAutoTab(char* sqlstr, TAOS* pSql, bool usedb) { + char * sql = sqlstr; + // remove prefix blank + while (*sql == ' ') { + sql++; + } + + if(dealUseDB(sql)) { + // change to new db + return ; + } + + // create command add name to autotab + if(dealCreateCommand(sql)) { + return ; + } + + // drop command remove name from autotab + if(dealDropCommand(sql)) { + return ; + } + + return ; +} diff --git a/src/kit/shell/src/shellCommand.c b/src/kit/shell/src/shellCommand.c index d78e152dbd..2fe09691e3 100644 --- a/src/kit/shell/src/shellCommand.c +++ b/src/kit/shell/src/shellCommand.c @@ -79,8 +79,11 @@ void insertChar(Command *cmd, char *c, int size) { /* update the values */ cmd->commandSize += size; cmd->cursorOffset += size; - cmd->screenOffset += wcwidth(wc); - cmd->endOffset += wcwidth(wc); + for (int i = 0; i < size; i++) { + mbtowc(&wc, c + i, size); + cmd->screenOffset += wcwidth(wc); + cmd->endOffset += wcwidth(wc); + } showOnScreen(cmd); } @@ -179,6 +182,16 @@ void positionCursorHome(Command *cmd) { } } +void positionCursorMiddle(Command *cmd) { + if (cmd->endOffset > 0) { + clearScreen(cmd->endOffset + prompt_size, cmd->screenOffset + prompt_size); + cmd->cursorOffset = cmd->commandSize/2; + cmd->screenOffset = cmd->endOffset/2; + showOnScreen(cmd); + } +} + + void positionCursorEnd(Command *cmd) { assert(cmd->cursorOffset <= cmd->commandSize && cmd->endOffset >= cmd->screenOffset); diff --git a/src/kit/shell/src/shellDarwin.c b/src/kit/shell/src/shellDarwin.c index 7803113a0f..0108d92e8f 100644 --- a/src/kit/shell/src/shellDarwin.c +++ b/src/kit/shell/src/shellDarwin.c @@ -22,6 +22,7 @@ #include "tkey.h" #include "tscLog.h" +#include "shellAuto.h" #define OPT_ABORT 1 /* �Cabort */ @@ -255,7 +256,12 @@ int32_t shellReadCommand(TAOS *con, char *command) { utf8_array[k] = c; } insertChar(&cmd, utf8_array, count); + pressOtherKey(c); + } else if (c == TAB_KEY) { + // press TAB key + pressTabKey(con, &cmd); } else if (c < '\033') { + pressOtherKey(c); // Ctrl keys. TODO: Implement ctrl combinations switch (c) { case 1: // ctrl A @@ -301,6 +307,9 @@ int32_t shellReadCommand(TAOS *con, char *command) { case 21: // Ctrl + U clearLineBefore(&cmd); break; + case 23: // Ctrl + W; + positionCursorMiddle(&cmd); + break; } } else if (c == '\033') { c = getchar(); @@ -377,9 +386,11 @@ int32_t shellReadCommand(TAOS *con, char *command) { break; } } else if (c == 0x7f) { + pressOtherKey(c); // press delete key backspaceChar(&cmd); } else { + pressOtherKey(c); insertChar(&cmd, &c, 1); } } diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index ee82212081..b0c3f4934d 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -27,6 +27,7 @@ #include "tglobal.h" #include "tsclient.h" #include "cJSON.h" +#include "shellAuto.h" #include @@ -327,6 +328,12 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { fprintf(stdout, "Database changed.\n\n"); fflush(stdout); +#ifndef WINDOWS + // call back auto tab module + callbackAutoTab(command, pSql, true); +#endif + + atomic_store_64(&result, 0); freeResultWithRid(oresult); return; @@ -365,6 +372,11 @@ void shellRunCommandOnServer(TAOS *con, char command[]) { int num_rows_affacted = taos_affected_rows(pSql); et = taosGetTimestampUs(); printf("Query OK, %d of %d row(s) in database (%.6fs)\n", num_rows_affacted, num_rows_affacted, (et - st) / 1E6); + +#ifndef WINDOWS + // call auto tab + callbackAutoTab(command, pSql, false); +#endif } printf("\n"); @@ -1169,12 +1181,12 @@ int parse_cloud_dsn() { } } char *port = strstr(args.cloudHost, ":"); - if ((port == NULL) || (port + strlen(":")) == NULL) { + if (port == NULL) { fprintf(stderr, "Invalid format in TDengine cloud dsn: %s\n", args.cloudDsn); return 1; } char *token = strstr(port + strlen(":"), "?token="); - if ((token == NULL) || (token + strlen("?token=")) == NULL || + if ((token == NULL) || (strlen(token + strlen("?token=")) == 0)) { fprintf(stderr, "Invalid format in TDengine cloud dsn: %s\n", args.cloudDsn); return -1; @@ -1632,4 +1644,4 @@ void wsclient_query(char *command) { } cJSON_Delete(query); return; -} \ No newline at end of file +} diff --git a/src/kit/shell/src/shellImport.c b/src/kit/shell/src/shellImport.c index b3a07b257c..e74c31729f 100644 --- a/src/kit/shell/src/shellImport.c +++ b/src/kit/shell/src/shellImport.c @@ -93,8 +93,8 @@ static void shellCheckTablesSQLFile(const char *directoryName) { sprintf(shellTablesSQLFile, "%s/tables.sql", directoryName); - struct stat fstat; - if (stat(shellTablesSQLFile, &fstat) < 0) { + struct stat status; + if (stat(shellTablesSQLFile, &status) < 0) { shellTablesSQLFile[0] = 0; } } diff --git a/src/kit/shell/src/shellLinux.c b/src/kit/shell/src/shellLinux.c index 863da2e1a7..fd24a61c7d 100644 --- a/src/kit/shell/src/shellLinux.c +++ b/src/kit/shell/src/shellLinux.c @@ -20,6 +20,7 @@ #include "shellCommand.h" #include "tkey.h" #include "tulog.h" +#include "shellAuto.h" #define OPT_ABORT 1 /* �Cabort */ @@ -283,7 +284,12 @@ int32_t shellReadCommand(TAOS *con, char *command) { utf8_array[k] = c; } insertChar(&cmd, utf8_array, count); + pressOtherKey(c); + } else if (c == TAB_KEY) { + // press TAB key + pressTabKey(con, &cmd); } else if (c < '\033') { + pressOtherKey(c); // Ctrl keys. TODO: Implement ctrl combinations switch (c) { case 1: // ctrl A @@ -329,8 +335,12 @@ int32_t shellReadCommand(TAOS *con, char *command) { case 21: // Ctrl + U; clearLineBefore(&cmd); break; + case 23: // Ctrl + W; + positionCursorMiddle(&cmd); + break; } } else if (c == '\033') { + pressOtherKey(c); c = (char)getchar(); switch (c) { case '[': @@ -405,9 +415,11 @@ int32_t shellReadCommand(TAOS *con, char *command) { break; } } else if (c == 0x7f) { + pressOtherKey(c); // press delete key backspaceChar(&cmd); } else { + pressOtherKey(c); insertChar(&cmd, &c, 1); } } diff --git a/src/kit/shell/src/shellMain.c b/src/kit/shell/src/shellMain.c index 149afc503e..2dcf105216 100644 --- a/src/kit/shell/src/shellMain.c +++ b/src/kit/shell/src/shellMain.c @@ -17,6 +17,8 @@ #include "shell.h" #include "tconfig.h" #include "tnettest.h" +#include "shellCommand.h" +#include "shellAuto.h" pthread_t pid; static tsem_t cancelSem; @@ -162,10 +164,16 @@ int main(int argc, char* argv[]) { /* Get grant information */ shellGetGrantInfo(args.con); +#ifndef WINDOWS + shellAutoInit(); +#endif /* Loop to query the input. */ while (1) { pthread_create(&pid, NULL, shellLoopQuery, args.con); pthread_join(pid, NULL); } +#ifndef WINDOWS + shellAutoExit(); +#endif } diff --git a/src/kit/shell/src/shellWindows.c b/src/kit/shell/src/shellWindows.c index 9aab9f49cd..0133caf997 100644 --- a/src/kit/shell/src/shellWindows.c +++ b/src/kit/shell/src/shellWindows.c @@ -250,14 +250,15 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) { if (args.cloudDsn == NULL) { if (args.cloud) { args.cloudDsn = getenv("TDENGINE_CLOUD_DSN"); - if (args.cloudDsn[strlen(args.cloudDsn) - 1] == '\"') { - args.cloudDsn[strlen(args.cloudDsn) - 1] = '\0'; - } - if (args.cloudDsn[0] == '\"') { - args.cloudDsn += 1; - } if (args.cloudDsn == NULL) { args.cloud = false; + } else { + if (args.cloudDsn[strlen(args.cloudDsn) - 1] == '\"') { + args.cloudDsn[strlen(args.cloudDsn) - 1] = '\0'; + } + if (args.cloudDsn[0] == '\"') { + args.cloudDsn += 1; + } } } } else { @@ -434,4 +435,4 @@ int tcpConnect(char* host, int iport) { return 1; } return 0; -} \ No newline at end of file +} diff --git a/src/kit/shell/src/tire.c b/src/kit/shell/src/tire.c new file mode 100644 index 0000000000..b4dc7976bd --- /dev/null +++ b/src/kit/shell/src/tire.c @@ -0,0 +1,435 @@ +/* + * 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 . + */ + +#define __USE_XOPEN + +#include "os.h" +#include "tire.h" + +// ----------- interface ------------- + +// create prefix search tree +STire* createTire(char type) { + STire* tire = malloc(sizeof(STire)); + memset(tire, 0, sizeof(STire)); + tire->ref = 1; // init is 1 + tire->type = type; + tire->root.d = (STireNode **)calloc(CHAR_CNT, sizeof(STireNode *)); + return tire; +} + +// free tire node +void freeTireNode(STireNode* node) { + if (node == NULL) + return ; + + // nest free sub node on array d + if(node->d) { + for (int i = 0; i < CHAR_CNT; i++) { + freeTireNode(node->d[i]); + } + tfree(node->d); + } + + // free self + tfree(node); +} + +// destroy prefix search tree +void freeTire(STire* tire) { + // free nodes + for (int i = 0; i < CHAR_CNT; i++) { + freeTireNode(tire->root.d[i]); + } + tfree(tire->root.d); + + // free from list + StrName * item = tire->head; + while (item) { + StrName * next = item->next; + // free string + tfree(item->name); + // free node + tfree(item); + + // move next + item = next; + } + tire->head = tire->tail = NULL; + + // free tire + tfree(tire); +} + +// insert a new word to list +bool insertToList(STire* tire, char* word) { + StrName * p = (StrName *)malloc(sizeof(StrName)); + p->name = strdup(word); + p->next = NULL; + + if(tire->head == NULL) { + tire->head = p; + tire->tail = p; + }else { + tire->tail->next = p; + tire->tail = p; + } + + return true; +} + +// insert a new word to tree +bool insertToTree(STire* tire, char* word, int len) { + int m = 0; + STireNode ** nodes = tire->root.d; + for (int i = 0; i < len; i++) { + m = word[i] - FIRST_ASCII; + if (m < 0 || m > CHAR_CNT) { + return false; + } + + if (nodes[m] == NULL) { + // no pointer + STireNode* p = (STireNode* )tmalloc(sizeof(STireNode)); + memset(p, 0, sizeof(STireNode)); + nodes[m] = p; + if (i == len - 1) { + // is end + p->end = true; + break; + } + } + + if (nodes[m]->d == NULL) { + // malloc d + nodes[m]->d = (STireNode **)calloc(CHAR_CNT, sizeof(STireNode *)); + } + + // move to next node + nodes = nodes[m]->d; + } + + // add count + tire->count += 1; + return true; +} + +// insert a new word +bool insertWord(STire* tire, char* word) { + int len = strlen(word); + if (len >= MAX_WORD_LEN) { + return false; + } + + switch (tire->type) { + case TIRE_TREE: + return insertToTree(tire, word, len); + case TIRE_LIST: + return insertToList(tire, word); + default: + break; + } + return false; +} + +// delete one word from list +bool deleteFromList(STire* tire, char* word) { + StrName * item = tire->head; + while (item) { + if (strcmp(item->name, word) == 0) { + // found, reset empty to delete + item->name[0] = 0; + } + + // move next + item = item->next; + } + return true; +} + +// delete one word from tree +bool deleteFromTree(STire* tire, char* word, int len) { + int m = 0; + bool del = false; + + STireNode** nodes = tire->root.d; + for (int i = 0; i < len; i++) { + m = word[i] - FIRST_ASCII; + if (m < 0 || m >= CHAR_CNT) { + return false; + } + + if (nodes[m] == NULL) { + // no found + return false; + } else { + // not null + if(i == len - 1) { + // this is last, only set end false , not free node + nodes[m]->end = false; + del = true; + break; + } + } + + if(nodes[m]->d == NULL) + break; + // move to next node + nodes = nodes[m]->d; + } + + // reduce count + if (del) { + tire->count -= 1; + } + + return del; +} + +// insert a new word +bool deleteWord(STire* tire, char* word) { + int len = strlen(word); + if (len >= MAX_WORD_LEN) { + return false; + } + + switch (tire->type) { + case TIRE_TREE: + return deleteFromTree(tire, word, len); + case TIRE_LIST: + return deleteFromList(tire, word); + default: + break; + } + return false; +} + +void addWordToMatch(SMatch* match, char* word){ + // malloc new + SMatchNode* node = (SMatchNode* )tmalloc(sizeof(SMatchNode)); + memset(node, 0, sizeof(SMatchNode)); + node->word = strdup(word); + + // append to match + if (match->head == NULL) { + match->head = match->tail = node; + } else { + match->tail->next = node; + match->tail = node; + } + match->count += 1; +} + +// enum all words from node +void enumAllWords(STireNode** nodes, char* prefix, SMatch* match) { + STireNode * c; + char word[MAX_WORD_LEN]; + int len = strlen(prefix); + for (int i = 0; i < CHAR_CNT; i++) { + c = nodes[i]; + + if (c == NULL) { + // chain end node + continue; + } else { + // combine word string + memset(word, 0, sizeof(word)); + strcpy(word, prefix); + word[len] = FIRST_ASCII + i; // append current char + + // chain middle node + if (c->end) { + // have end flag + addWordToMatch(match, word); + } + // nested call next layer + if (c->d) + enumAllWords(c->d, word, match); + } + } +} + +// match prefix from list +void matchPrefixFromList(STire* tire, char* prefix, SMatch* match) { + StrName * item = tire->head; + int len = strlen(prefix); + while (item) { + if ( strncmp(item->name, prefix, len) == 0) { + // prefix matched + addWordToMatch(match, item->name); + } + + // move next + item = item->next; + } +} + +// match prefix words, if match is not NULL , put all item to match and return match +void matchPrefixFromTree(STire* tire, char* prefix, SMatch* match) { + SMatch* root = match; + int m = 0; + STireNode* c = 0; + int len = strlen(prefix); + if (len >= MAX_WORD_LEN) { + return; + } + + STireNode** nodes = tire->root.d; + for (int i = 0; i < len; i++) { + m = prefix[i] - FIRST_ASCII; + if (m < 0 || m > CHAR_CNT) { + return; + } + + // match + c = nodes[m]; + if (c == NULL) { + // arrive end + break; + } + + // previous items already matched + if (i == len - 1) { + // malloc match if not pass by param match + if (root == NULL) { + root = (SMatch* )tmalloc(sizeof(SMatch)); + memset(root, 0, sizeof(SMatch)); + strcpy(root->pre, prefix); + } + + // prefix is match to end char + if (c->d) + enumAllWords(c->d, prefix, root); + } else { + // move to next node continue match + if(c->d == NULL) + break; + nodes = c->d; + } + } + + // return + return ; +} + +SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match) { + if(match == NULL) { + match = (SMatch* )tmalloc(sizeof(SMatch)); + memset(match, 0, sizeof(SMatch)); + } + + switch (tire->type) { + case TIRE_TREE: + matchPrefixFromTree(tire, prefix, match); + case TIRE_LIST: + matchPrefixFromList(tire, prefix, match); + default: + break; + } + + // return if need + if (match->count == 0) { + freeMatch(match); + match = NULL; + } + + return match; +} + + +// get all items from tires tree +void enumFromList(STire* tire, SMatch* match) { + StrName * item = tire->head; + while (item) { + if (item->name[0] != 0) { + // not delete + addWordToMatch(match, item->name); + } + + // move next + item = item->next; + } +} + +// get all items from tires tree +void enumFromTree(STire* tire, SMatch* match) { + char pre[2] ={0, 0}; + STireNode* c; + + // enum first layer + for (int i = 0; i < CHAR_CNT; i++) { + pre[0] = FIRST_ASCII + i; + + // each node + c = tire->root.d[i]; + if (c == NULL) { + // this branch no data + continue; + } + + // this branch have data + if(c->end) + addWordToMatch(match, pre); + else + matchPrefix(tire, pre, match); + } +} + +// get all items from tires tree +SMatch* enumAll(STire* tire) { + SMatch* match = (SMatch* )tmalloc(sizeof(SMatch)); + memset(match, 0, sizeof(SMatch)); + + switch (tire->type) { + case TIRE_TREE: + enumFromTree(tire, match); + case TIRE_LIST: + enumFromList(tire, match); + default: + break; + } + + // return if need + if (match->count == 0) { + freeMatch(match); + match = NULL; + } + + return match; +} + + +// free match result +void freeMatchNode(SMatchNode* node) { + // first free next + if (node->next) + freeMatchNode(node->next); + + // second free self + if (node->word) + free(node->word); + free(node); +} + +// free match result +void freeMatch(SMatch* match) { + // first free next + if (match->head) { + freeMatchNode(match->head); + } + + // second free self + free(match); +} diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 5fdd694621..f84cb6e515 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 5fdd694621fbb7bd2d6102ff4feaec92a7001038 +Subproject commit f84cb6e51556d8030585128c2b252aa2a6453328 diff --git a/src/mnode/src/mnodeAcct.c b/src/mnode/src/mnodeAcct.c index 64cfa28917..0ec330841c 100644 --- a/src/mnode/src/mnodeAcct.c +++ b/src/mnode/src/mnodeAcct.c @@ -215,7 +215,7 @@ static int32_t mnodeCreateRootAcct() { taosEncryptPass((uint8_t *)TSDB_DEFAULT_PASS, strlen(TSDB_DEFAULT_PASS), pAcct->pass); pAcct->cfg = (SAcctCfg){ .maxUsers = 128, - .maxDbs = 128, + .maxDbs = INT16_MAX, .maxTimeSeries = INT32_MAX, .maxConnections = 1024, .maxStreams = 1000, diff --git a/src/mnode/src/mnodeCluster.c b/src/mnode/src/mnodeCluster.c index 553e8446ab..e8f7484fd1 100644 --- a/src/mnode/src/mnodeCluster.c +++ b/src/mnode/src/mnodeCluster.c @@ -145,8 +145,8 @@ static int32_t mnodeCreateCluster() { SClusterObj *pCluster = malloc(sizeof(SClusterObj)); memset(pCluster, 0, sizeof(SClusterObj)); pCluster->createdTime = taosGetTimestampMs(); - bool getuid = taosGetSystemUid(pCluster->uid); - if (!getuid) { + bool bGetuid = taosGetSystemUid(pCluster->uid); + if (!bGetuid) { strcpy(pCluster->uid, "tdengine2.0"); mError("failed to get uid from system, set to default val %s", pCluster->uid); } else { @@ -260,4 +260,4 @@ int32_t mnodeCompactCluster() { mInfo("end to compact cluster table..."); return 0; -} \ No newline at end of file +} diff --git a/src/mnode/src/mnodeMnode.c b/src/mnode/src/mnodeMnode.c index 13dd06bcac..491d2e4b36 100644 --- a/src/mnode/src/mnodeMnode.c +++ b/src/mnode/src/mnodeMnode.c @@ -210,7 +210,7 @@ void mnodeUpdateMnodeEpSet(SMInfos *pMinfos) { mInfos = *pMinfos; } else { mInfo("vgId:1, update mnodes epSet, numOfMnodes:%d", mnodeGetMnodesNum()); - int32_t index = 0; + int32_t idx = 0; void * pIter = NULL; while (1) { SMnodeObj *pMnode = NULL; @@ -220,10 +220,10 @@ void mnodeUpdateMnodeEpSet(SMInfos *pMinfos) { SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId); if (pDnode != NULL) { set = true; - mInfos.mnodeInfos[index].mnodeId = pMnode->mnodeId; - strcpy(mInfos.mnodeInfos[index].mnodeEp, pDnode->dnodeEp); - if (pMnode->role == TAOS_SYNC_ROLE_MASTER) mInfos.inUse = index; - index++; + mInfos.mnodeInfos[idx].mnodeId = pMnode->mnodeId; + strcpy(mInfos.mnodeInfos[idx].mnodeEp, pDnode->dnodeEp); + if (pMnode->role == TAOS_SYNC_ROLE_MASTER) mInfos.inUse = idx; + idx++; } else { set = false; } @@ -232,7 +232,7 @@ void mnodeUpdateMnodeEpSet(SMInfos *pMinfos) { mnodeDecMnodeRef(pMnode); } - mInfos.mnodeNum = index; + mInfos.mnodeNum = idx; if (mInfos.mnodeNum < sdbGetReplicaNum()) { set = false; mDebug("vgId:1, mnodes info not synced, current:%d syncCfgNum:%d", mInfos.mnodeNum, sdbGetReplicaNum()); @@ -251,23 +251,23 @@ void mnodeUpdateMnodeEpSet(SMInfos *pMinfos) { tsMEpForPeer.numOfEps = tsMInfos.mnodeNum; mInfo("vgId:1, mnodes epSet is set, num:%d inUse:%d", tsMInfos.mnodeNum, tsMInfos.inUse); - for (int index = 0; index < mInfos.mnodeNum; ++index) { - SMInfo *pInfo = &tsMInfos.mnodeInfos[index]; - taosGetFqdnPortFromEp(pInfo->mnodeEp, tsMEpForShell.fqdn[index], &tsMEpForShell.port[index]); - taosGetFqdnPortFromEp(pInfo->mnodeEp, tsMEpForPeer.fqdn[index], &tsMEpForPeer.port[index]); - tsMEpForPeer.port[index] = tsMEpForPeer.port[index] + TSDB_PORT_DNODEDNODE; + for (int idx = 0; idx < mInfos.mnodeNum; ++idx) { + SMInfo *pInfo = &tsMInfos.mnodeInfos[idx]; + taosGetFqdnPortFromEp(pInfo->mnodeEp, tsMEpForShell.fqdn[idx], &tsMEpForShell.port[idx]); + taosGetFqdnPortFromEp(pInfo->mnodeEp, tsMEpForPeer.fqdn[idx], &tsMEpForPeer.port[idx]); + tsMEpForPeer.port[idx] = tsMEpForPeer.port[idx] + TSDB_PORT_DNODEDNODE; - mInfo("vgId:1, mnode:%d, fqdn:%s shell:%u peer:%u", pInfo->mnodeId, tsMEpForShell.fqdn[index], - tsMEpForShell.port[index], tsMEpForPeer.port[index]); + mInfo("vgId:1, mnode:%d, fqdn:%s shell:%u peer:%u", pInfo->mnodeId, tsMEpForShell.fqdn[idx], + tsMEpForShell.port[idx], tsMEpForPeer.port[idx]); - tsMEpForShell.port[index] = htons(tsMEpForShell.port[index]); - tsMEpForPeer.port[index] = htons(tsMEpForPeer.port[index]); + tsMEpForShell.port[idx] = htons(tsMEpForShell.port[idx]); + tsMEpForPeer.port[idx] = htons(tsMEpForPeer.port[idx]); pInfo->mnodeId = htonl(pInfo->mnodeId); } } else { mInfo("vgId:1, mnodes epSet not set, num:%d inUse:%d", tsMInfos.mnodeNum, tsMInfos.inUse); - for (int index = 0; index < tsMInfos.mnodeNum; ++index) { - mInfo("vgId:1, index:%d, ep:%s:%u", index, tsMEpForShell.fqdn[index], htons(tsMEpForShell.port[index])); + for (int idx = 0; idx < tsMInfos.mnodeNum; ++idx) { + mInfo("vgId:1, index:%d, ep:%s:%u", idx, tsMEpForShell.fqdn[idx], htons(tsMEpForShell.port[idx])); } } @@ -603,4 +603,4 @@ int32_t mnodeCompactMnodes() { mInfo("end to compact mnodes table..."); return 0; -} \ No newline at end of file +} diff --git a/src/mnode/src/mnodeSdb.c b/src/mnode/src/mnodeSdb.c index 1e3057f270..cb39c2ae2b 100644 --- a/src/mnode/src/mnodeSdb.c +++ b/src/mnode/src/mnodeSdb.c @@ -331,7 +331,7 @@ int32_t sdbUpdateSync(void *pMnodes) { mDebug("vgId:1, update sync config, pMnodes:%p", pMnodes); SSyncCfg syncCfg = {0}; - int32_t index = 0; + int32_t idx = 0; if (pMinfos == NULL) { mDebug("vgId:1, mInfos not input, use mInfos in sdb, numOfMnodes:%d", syncCfg.replica); @@ -342,29 +342,29 @@ int32_t sdbUpdateSync(void *pMnodes) { pIter = mnodeGetNextMnode(pIter, &pMnode); if (pMnode == NULL) break; - syncCfg.nodeInfo[index].nodeId = pMnode->mnodeId; + syncCfg.nodeInfo[idx].nodeId = pMnode->mnodeId; SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId); if (pDnode != NULL) { - syncCfg.nodeInfo[index].nodePort = pDnode->dnodePort + TSDB_PORT_SYNC; - tstrncpy(syncCfg.nodeInfo[index].nodeFqdn, pDnode->dnodeFqdn, TSDB_FQDN_LEN); - index++; + syncCfg.nodeInfo[idx].nodePort = pDnode->dnodePort + TSDB_PORT_SYNC; + tstrncpy(syncCfg.nodeInfo[idx].nodeFqdn, pDnode->dnodeFqdn, TSDB_FQDN_LEN); + idx++; } mnodeDecDnodeRef(pDnode); mnodeDecMnodeRef(pMnode); } - syncCfg.replica = index; + syncCfg.replica = idx; } else { mDebug("vgId:1, mInfos input, numOfMnodes:%d", pMinfos->mnodeNum); - for (index = 0; index < pMinfos->mnodeNum; ++index) { - SMInfo *node = &pMinfos->mnodeInfos[index]; - syncCfg.nodeInfo[index].nodeId = node->mnodeId; - taosGetFqdnPortFromEp(node->mnodeEp, syncCfg.nodeInfo[index].nodeFqdn, &syncCfg.nodeInfo[index].nodePort); - syncCfg.nodeInfo[index].nodePort += TSDB_PORT_SYNC; + for (idx = 0; idx < pMinfos->mnodeNum; ++idx) { + SMInfo *node = &pMinfos->mnodeInfos[idx]; + syncCfg.nodeInfo[idx].nodeId = node->mnodeId; + taosGetFqdnPortFromEp(node->mnodeEp, syncCfg.nodeInfo[idx].nodeFqdn, &syncCfg.nodeInfo[idx].nodePort); + syncCfg.nodeInfo[idx].nodePort += TSDB_PORT_SYNC; } - syncCfg.replica = index; + syncCfg.replica = idx; mnodeUpdateMnodeEpSet(pMnodes); } diff --git a/src/os/src/detail/osDir.c b/src/os/src/detail/osDir.c index 17c844ed86..d867c80af4 100644 --- a/src/os/src/detail/osDir.c +++ b/src/os/src/detail/osDir.c @@ -45,8 +45,8 @@ void taosRemoveDir(char *rootDir) { uInfo("dir:%s is removed", rootDir); } -bool taosDirExist(const char* dirname) { - return access(dirname, F_OK) == 0; +bool taosDirExist(const char* dir) { + return access(dir, F_OK) == 0; } int32_t taosMkdirP(const char *dir, int keepLast) { diff --git a/src/os/src/detail/osFile.c b/src/os/src/detail/osFile.c index 910e6f15be..6adcd1dae3 100644 --- a/src/os/src/detail/osFile.c +++ b/src/os/src/detail/osFile.c @@ -44,11 +44,11 @@ void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) { strcat(tmpPath, "-%d-%s"); } - char rand[32] = {0}; + char rand_num[32] = {0}; - sprintf(rand, "%" PRIu64, atomic_add_fetch_64(&seqId, 1)); + sprintf(rand_num, "%" PRIu64, atomic_add_fetch_64(&seqId, 1)); - snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand); + snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand_num); } #else @@ -71,11 +71,11 @@ void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) { strcat(tmpPath, "-%d-%s"); } - char rand[32] = {0}; + char rand_num[32] = {0}; - sprintf(rand, "%" PRIu64, atomic_add_fetch_64(&seqId, 1)); + sprintf(rand_num, "%" PRIu64, atomic_add_fetch_64(&seqId, 1)); - snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand); + snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand_num); } #endif diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 1575b3100f..3590703695 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -82,26 +82,26 @@ void deltaToUtcInitOnce() { } static int64_t parseFraction(char* str, char** end, int32_t timePrec); -static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim); -static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim, bool withDST); +static int32_t parseTimeWithTz(char* timestr, int64_t* pTime, int32_t timePrec, char delim); +static int32_t parseLocaltime(char* timestr, int64_t* pTime, int32_t timePrec, char delim, bool withDST); static char* forwardToTimeStringEnd(char* str); static bool checkTzPresent(char *str, int32_t len); int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } -int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { +int32_t taosParseTime(char* timestr, int64_t* pTime, int32_t len, int32_t timePrec, int8_t day_light) { /* parse datatime string in with tz */ if (strnchr(timestr, 'T', len, false) != NULL) { if (checkTzPresent(timestr, len)) { - return parseTimeWithTz(timestr, time, timePrec, 'T'); + return parseTimeWithTz(timestr, pTime, timePrec, 'T'); } else { - return parseLocaltime(timestr, time, timePrec, 'T', day_light); + return parseLocaltime(timestr, pTime, timePrec, 'T', day_light); } } else { if (checkTzPresent(timestr, len)) { - return parseTimeWithTz(timestr, time, timePrec, 0); + return parseTimeWithTz(timestr, pTime, timePrec, 0); } else { - return parseLocaltime(timestr, time, timePrec, 0, day_light); + return parseLocaltime(timestr, pTime, timePrec, 0, day_light); } } } @@ -121,8 +121,8 @@ bool checkTzPresent(char *str, int32_t len) { } -FORCE_INLINE int32_t taos_parse_time(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { - return taosParseTime(timestr, time, len, timePrec, day_light); +FORCE_INLINE int32_t taos_parse_time(char* timestr, int64_t* pTime, int32_t len, int32_t timePrec, int8_t day_light) { + return taosParseTime(timestr, pTime, len, timePrec, day_light); } char* forwardToTimeStringEnd(char* str) { @@ -243,7 +243,7 @@ int32_t parseTimezone(char* str, int64_t* tzOffset) { * 2013-04-12T15:52:01+0800 * 2013-04-12T15:52:01.123+0800 */ -int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim) { +int32_t parseTimeWithTz(char* timestr, int64_t* pTime, int32_t timePrec, char delim) { int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 : (timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000); @@ -277,14 +277,14 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del if ((str[0] == 'Z' || str[0] == 'z') && str[1] == '\0') { /* utc time, no millisecond, return directly*/ - *time = seconds * factor; + *pTime = seconds * factor; } else if (str[0] == '.') { str += 1; if ((fraction = parseFraction(str, &str, timePrec)) < 0) { return -1; } - *time = seconds * factor + fraction; + *pTime = seconds * factor + fraction; char seg = str[0]; if (seg != 'Z' && seg != 'z' && seg != '+' && seg != '-') { @@ -297,18 +297,18 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del return -1; } - *time += tzOffset * factor; + *pTime += tzOffset * factor; } } else if (str[0] == '+' || str[0] == '-') { - *time = seconds * factor + fraction; + *pTime = seconds * factor + fraction; // parse the timezone if (parseTimezone(str, &tzOffset) == -1) { return -1; } - *time += tzOffset * factor; + *pTime += tzOffset * factor; } else { return -1; } @@ -316,8 +316,8 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del return 0; } -int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim, bool withDST) { - *time = 0; +int32_t parseLocaltime(char* timestr, int64_t* pTime, int32_t timePrec, char delim, bool withDST) { + *pTime = 0; struct tm tm = {0}; if (withDST) { tm.tm_isdst = -1; @@ -365,65 +365,65 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char deli int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 : (timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000); - *time = factor * seconds + fraction; + *pTime = factor * seconds + fraction; return 0; } -int64_t convertTimePrecision(int64_t time, int32_t fromPrecision, int32_t toPrecision) { +int64_t convertTimePrecision(int64_t timeStamp, int32_t fromPrecision, int32_t toPrecision) { assert(fromPrecision == TSDB_TIME_PRECISION_MILLI || fromPrecision == TSDB_TIME_PRECISION_MICRO || fromPrecision == TSDB_TIME_PRECISION_NANO); assert(toPrecision == TSDB_TIME_PRECISION_MILLI || toPrecision == TSDB_TIME_PRECISION_MICRO || toPrecision == TSDB_TIME_PRECISION_NANO); - double tempResult = (double)time; + double tempResult = (double)timeStamp; switch(fromPrecision) { case TSDB_TIME_PRECISION_MILLI: { switch (toPrecision) { case TSDB_TIME_PRECISION_MILLI: - return time; + return timeStamp; case TSDB_TIME_PRECISION_MICRO: tempResult *= 1000; - time *= 1000; + timeStamp *= 1000; goto end_; case TSDB_TIME_PRECISION_NANO: tempResult *= 1000000; - time *= 1000000; + timeStamp *= 1000000; goto end_; } } // end from milli case TSDB_TIME_PRECISION_MICRO: { switch (toPrecision) { case TSDB_TIME_PRECISION_MILLI: - return time / 1000; + return timeStamp / 1000; case TSDB_TIME_PRECISION_MICRO: - return time; + return timeStamp; case TSDB_TIME_PRECISION_NANO: tempResult *= 1000; - time *= 1000; + timeStamp *= 1000; goto end_; } } //end from micro case TSDB_TIME_PRECISION_NANO: { switch (toPrecision) { case TSDB_TIME_PRECISION_MILLI: - return time / 1000000; + return timeStamp / 1000000; case TSDB_TIME_PRECISION_MICRO: - return time / 1000; + return timeStamp / 1000; case TSDB_TIME_PRECISION_NANO: - return time; + return timeStamp; } } //end from nano default: { assert(0); - return time; // only to pass windows compilation + return timeStamp; // only to pass windows compilation } } //end switch fromPrecision end_: if (tempResult >= (double)INT64_MAX) return INT64_MAX; if (tempResult <= (double)INT64_MIN) return INT64_MIN + 1; // INT64_MIN means NULL - return time; + return timeStamp; } static int32_t getDuration(int64_t val, char unit, int64_t* result, int32_t timePrecision) { diff --git a/src/os/src/linux/osSystem.c b/src/os/src/linux/osSystem.c index a82149dccb..d2d9d6d76c 100644 --- a/src/os/src/linux/osSystem.c +++ b/src/os/src/linux/osSystem.c @@ -33,9 +33,9 @@ void* taosLoadDll(const char *filename) { void* taosLoadSym(void* handle, char* name) { void* sym = dlsym(handle, name); - char* error = NULL; + char* err = NULL; - if ((error = dlerror()) != NULL) { + if ((err = dlerror()) != NULL) { uWarn("load sym:%s failed, error:%s", name, dlerror()); return NULL; } diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index aeb7f538ce..6733b604fa 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -63,7 +63,7 @@ ELSE () COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../inc CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -ldflags "-s -w -X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}" COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../inc CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -o taosadapter-debug -ldflags "-X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}" INSTALL_COMMAND - COMMAND curl -sL https://github.com/upx/upx/releases/download/v3.96/upx-3.96-${PLATFORM_ARCH_STR}_linux.tar.xz -o upx.tar.xz && tar -xvJf upx.tar.xz -C ${CMAKE_BINARY_DIR} --strip-components 1 > /dev/null && ${CMAKE_BINARY_DIR}/upx taosadapter || : + COMMAND wget -c https://github.com/upx/upx/releases/download/v3.96/upx-3.96-${PLATFORM_ARCH_STR}_linux.tar.xz -O ${CMAKE_CURRENT_SOURCE_DIR}/upx.tar.xz && tar -xvJf ${CMAKE_CURRENT_SOURCE_DIR}/upx.tar.xz -C ${CMAKE_CURRENT_SOURCE_DIR} --strip-components 1 > /dev/null && ${CMAKE_CURRENT_SOURCE_DIR}/upx taosadapter || : COMMAND cmake -E copy taosadapter ${CMAKE_BINARY_DIR}/build/bin COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/test/cfg/ COMMAND cmake -E copy ./example/config/taosadapter.toml ${CMAKE_BINARY_DIR}/test/cfg/ diff --git a/src/plugins/monitor/src/monMain.c b/src/plugins/monitor/src/monMain.c index bd0e015205..6af0d2bf0a 100644 --- a/src/plugins/monitor/src/monMain.c +++ b/src/plugins/monitor/src/monMain.c @@ -637,7 +637,7 @@ static int32_t monBuildMasterUptimeSql(char *sql) { for (int i = 0; i < num_fields; ++i) { if (strcmp(fields[i].name, "role") == 0) { int32_t charLen = monGetRowElemCharLen(fields[i], (char *)row[i]); - if (strncmp((char *)row[i], "master", charLen) == 0) { + if (strncmp((char *)row[i], "leader", charLen) == 0) { if (strcmp(fields[i + 1].name, "role_time") == 0) { int64_t now = taosGetTimestamp(TSDB_TIME_PRECISION_MILLI); //master uptime in seconds @@ -957,7 +957,7 @@ static int32_t monBuildDnodeVnodesSql(char *sql) { for (int i = 0; i < num_fields; ++i) { if (strcmp(fields[i].name, "status") == 0) { int32_t charLen = monGetRowElemCharLen(fields[i], (char *)row[i]); - if (strncmp((char *)row[i], "master", charLen) == 0) { + if (strncmp((char *)row[i], "leader", charLen) == 0) { masterNum += 1; } } @@ -992,7 +992,7 @@ static int32_t monBuildDnodeMnodeSql(char *sql) { } } else if (strcmp(fields[i].name, "role") == 0) { charLen = monGetRowElemCharLen(fields[i], (char *)row[i]); - if (strncmp((char *)row[i], "master", charLen) == 0) { + if (strncmp((char *)row[i], "leader", charLen) == 0) { if (has_mnode_row) { monHasMnodeMaster = true; } diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index edd13ea962..5fc940309c 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -90,8 +90,17 @@ extern "C" { #define TSDB_FUNC_QSTOP 48 #define TSDB_FUNC_QDURATION 49 #define TSDB_FUNC_HYPERLOGLOG 50 +#define TSDB_FUNC_MIN_ROW 51 +#define TSDB_FUNC_MAX_ROW 52 +#define TSDB_FUNC_COL_DUMMY 53 -#define TSDB_FUNC_MAX_NUM 51 +#define TSDB_FUNC_MAX_NUM 54 + +enum { + FUNC_NOT_VAL, + FUNC_MIN_ROW, + FUNC_MAX_ROW +}; #define TSDB_FUNCSTATE_SO 0x1u // single output #define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM @@ -217,6 +226,10 @@ typedef struct SQLFunctionCtx { SHashObj **pModeSet; // for mode function STimeWindow qWindow; // for _qstart/_qstop/_qduration column int32_t allocRows; // rows allocated for output buffer + int16_t minRowIndex; + int16_t maxRowIndex; + int16_t minMaxRowType; + bool updateIndex; // whether update index after comparation } SQLFunctionCtx; typedef struct SAggFunctionInfo { diff --git a/src/query/inc/qSqlparser.h b/src/query/inc/qSqlparser.h index 8091a300b3..2a75d4d992 100644 --- a/src/query/inc/qSqlparser.h +++ b/src/query/inc/qSqlparser.h @@ -97,9 +97,11 @@ typedef struct SIntervalVal { SStrToken offset; } SIntervalVal; +typedef struct tSqlExpr tSqlExprTimestamp; + typedef struct SRangeVal { - void *start; - void *end; + tSqlExprTimestamp *start; + tSqlExprTimestamp *end; } SRangeVal; typedef struct SSessionWindowVal { diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 1aecac1b2f..d12bb28ab8 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -352,7 +352,7 @@ static uint64_t hllCountCnt(uint8_t *buckets) { static uint8_t hllCountNum(void *ele, int32_t elesize, int32_t *buk) { uint64_t hash = MurmurHash3_64(ele,elesize); - int32_t index = hash & HLL_BUCKET_MASK; + int32_t idx = hash & HLL_BUCKET_MASK; hash >>= HLL_BUCKET_BITS; hash |= ((uint64_t)1<buckets[index]; + int32_t idx = 0; + uint8_t count = hllCountNum(val,elesize,&idx); + uint8_t oldcount = pHLLInfo->buckets[idx]; if (count > oldcount) { - pHLLInfo->buckets[index] = count; + pHLLInfo->buckets[idx] = count; } } GET_RES_INFO(pCtx)->numOfRes = 1; @@ -419,8 +419,8 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI assert(functionId != TSDB_FUNC_SCALAR_EXPR); if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY || - functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ || - functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) + functionId == TSDB_FUNC_COL_DUMMY || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || + functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) { *type = (int16_t)dataType; *bytes = dataBytes; @@ -522,6 +522,12 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI *bytes = (dataBytes + DATA_SET_FLAG_SIZE); *interBytes = *bytes; + return TSDB_CODE_SUCCESS; + } else if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + *type = TSDB_DATA_TYPE_BINARY; + *bytes = (dataBytes + DATA_SET_FLAG_SIZE); + *interBytes = *bytes; + return TSDB_CODE_SUCCESS; } else if (functionId == TSDB_FUNC_SUM) { *type = TSDB_DATA_TYPE_BINARY; @@ -680,6 +686,10 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI *type = (int16_t)dataType; *bytes = dataBytes; *interBytes = dataBytes + DATA_SET_FLAG_SIZE; + } else if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + *type = (int16_t)dataType; + *bytes = dataBytes; + *interBytes = dataBytes + DATA_SET_FLAG_SIZE; } else if (functionId == TSDB_FUNC_FIRST || functionId == TSDB_FUNC_LAST) { *type = (int16_t)dataType; *bytes = dataBytes; @@ -1001,6 +1011,7 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) { #define UPDATE_DATA(ctx, left, right, num, sign, k) \ do { \ if (((left) < (right)) ^ (sign)) { \ + (ctx)->updateIndex = true; \ (left) = (right); \ DO_UPDATE_TAG_COLUMNS(ctx, k); \ (num) += 1; \ @@ -1017,13 +1028,27 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) { } while (0) #define LOOPCHECK_N(val, list, ctx, tsdbType, sign, num) \ + int32_t updateCount = 0; \ for (int32_t i = 0; i < ((ctx)->size); ++i) { \ if ((ctx)->hasNull && isNull((char *)&(list)[i], tsdbType)) { \ continue; \ } \ TSKEY key = (ctx)->ptsList != NULL? GET_TS_DATA(ctx, i):0; \ + (ctx)->updateIndex = false; \ UPDATE_DATA(ctx, val, (list)[i], num, sign, key); \ - } + if (!(ctx)->preAggVals.isSet) { \ + if ((ctx)->updateIndex) { \ + if (sign && (ctx)->preAggVals.statis.minIndex != i) { \ + (ctx)->preAggVals.statis.minIndex = i; \ + } \ + if (!sign && (ctx)->preAggVals.statis.maxIndex != i) { \ + (ctx)->preAggVals.statis.maxIndex = i; \ + } \ + updateCount++; \ + } \ + } \ + } \ + (ctx)->updateIndex = updateCount > 0 ? true : false; \ #define TYPED_LOOPCHECK_N(type, data, list, ctx, tsdbType, sign, notNullElems) \ do { \ @@ -1363,14 +1388,14 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, } void* tval = NULL; - int16_t index = 0; + int16_t idx = 0; if (isMin) { tval = &pCtx->preAggVals.statis.min; - index = pCtx->preAggVals.statis.minIndex; + idx = pCtx->preAggVals.statis.minIndex; } else { tval = &pCtx->preAggVals.statis.max; - index = pCtx->preAggVals.statis.maxIndex; + idx = pCtx->preAggVals.statis.maxIndex; } TSKEY key = TSKEY_INITIAL_VAL; @@ -1381,12 +1406,12 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, * * The following codes of 3 lines will be removed later. */ -// if (index < 0 || index >= pCtx->size + pCtx->startOffset) { -// index = 0; +// if (idx < 0 || idx >= pCtx->size + pCtx->startOffset) { +// idx = 0; // } - // the index is the original position, not the relative position - key = pCtx->ptsList[index]; + // the idx is the original position, not the relative position + key = pCtx->ptsList[idx]; } if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) { @@ -1406,6 +1431,7 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, #endif if ((*data < val) ^ isMin) { + pCtx->updateIndex = true; *data = (int32_t)val; for (int32_t i = 0; i < (pCtx)->tagInfo.numOfTagCols; ++i) { SQLFunctionCtx *__ctx = pCtx->tagInfo.pTagCtxList[i]; @@ -1465,13 +1491,17 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, } else if (pCtx->inputType == TSDB_DATA_TYPE_INT) { int32_t *pData = p; int32_t *retVal = (int32_t*) pOutput; + int32_t updateCount = 0; for (int32_t i = 0; i < pCtx->size; ++i) { if (pCtx->hasNull && isNull((const char*)&pData[i], pCtx->inputType)) { continue; } + pCtx->updateIndex = false; + if ((*retVal < pData[i]) ^ isMin) { + pCtx->updateIndex = true; *retVal = pData[i]; if(tsList) { TSKEY k = tsList[i]; @@ -1479,7 +1509,21 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, } } *notNullElems += 1; + + if (!pCtx->preAggVals.isSet) { + if (pCtx->updateIndex) { + if (isMin && pCtx->preAggVals.statis.minIndex != i) { + pCtx->preAggVals.statis.minIndex = i; + } + if (!isMin && pCtx->preAggVals.statis.maxIndex != i) { + pCtx->preAggVals.statis.maxIndex = i; + } + updateCount++; + } + } } + + pCtx->updateIndex = updateCount > 0 ? true : false; #if defined(_DEBUG_VIEW) qDebug("max value updated:%d", *retVal); #endif @@ -1737,6 +1781,152 @@ static void max_func_merge(SQLFunctionCtx *pCtx) { } } +static bool min_row_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { + if (!function_setup(pCtx, pResultInfo)) { + return false; // not initialized since it has been initialized + } + + GET_TRUE_DATA_TYPE(); + + switch (type) { + case TSDB_DATA_TYPE_TINYINT: + *((int8_t *)pCtx->pOutput) = INT8_MAX; + break; + case TSDB_DATA_TYPE_UTINYINT: + *(uint8_t *) pCtx->pOutput = UINT8_MAX; + break; + case TSDB_DATA_TYPE_SMALLINT: + *((int16_t *)pCtx->pOutput) = INT16_MAX; + break; + case TSDB_DATA_TYPE_USMALLINT: + *((uint16_t *)pCtx->pOutput) = UINT16_MAX; + break; + case TSDB_DATA_TYPE_INT: + *((int32_t *)pCtx->pOutput) = INT32_MAX; + break; + case TSDB_DATA_TYPE_UINT: + *((uint32_t *)pCtx->pOutput) = UINT32_MAX; + break; + case TSDB_DATA_TYPE_BIGINT: + *((int64_t *)pCtx->pOutput) = INT64_MAX; + break; + case TSDB_DATA_TYPE_UBIGINT: + *((uint64_t *)pCtx->pOutput) = UINT64_MAX; + break; + case TSDB_DATA_TYPE_FLOAT: + *((float *)pCtx->pOutput) = FLT_MAX; + break; + case TSDB_DATA_TYPE_DOUBLE: + SET_DOUBLE_VAL(((double *)pCtx->pOutput), DBL_MAX); + break; + default: + qError("illegal data type:%d in min_row query", pCtx->inputType); + } + + return true; +} + +static bool max_row_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { + if (!function_setup(pCtx, pResultInfo)) { + return false; // not initialized since it has been initialized + } + + GET_TRUE_DATA_TYPE(); + + switch (type) { + case TSDB_DATA_TYPE_TINYINT: + *((int8_t *)pCtx->pOutput) = INT8_MIN; + break; + case TSDB_DATA_TYPE_UTINYINT: + *((uint8_t *)pCtx->pOutput) = 0; + break; + case TSDB_DATA_TYPE_SMALLINT: + *((int16_t *)pCtx->pOutput) = INT16_MIN; + break; + case TSDB_DATA_TYPE_USMALLINT: + *((uint16_t *)pCtx->pOutput) = 0; + break; + case TSDB_DATA_TYPE_INT: + *((int32_t *)pCtx->pOutput) = INT32_MIN; + break; + case TSDB_DATA_TYPE_UINT: + *((uint32_t *)pCtx->pOutput) = 0; + break; + case TSDB_DATA_TYPE_BIGINT: + *((int64_t *)pCtx->pOutput) = INT64_MIN; + break; + case TSDB_DATA_TYPE_UBIGINT: + *((uint64_t *)pCtx->pOutput) = 0; + break; + case TSDB_DATA_TYPE_FLOAT: + *((float *)pCtx->pOutput) = -FLT_MAX; + break; + case TSDB_DATA_TYPE_DOUBLE: + SET_DOUBLE_VAL(((double *)pCtx->pOutput), -DBL_MAX); + break; + default: + qError("illegal data type:%d in max_row query", pCtx->inputType); + } + + return true; +} + +static void min_row_function(SQLFunctionCtx *pCtx) { + int32_t notNullElems = 0; + minMax_function(pCtx, pCtx->pOutput, 1, ¬NullElems); + + SET_VAL(pCtx, notNullElems, 1); + + if (notNullElems > 0) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + pResInfo->hasResult = DATA_SET_FLAG; + + // set the flag for super table query + if (pCtx->stableQuery) { + *(pCtx->pOutput + pCtx->inputBytes) = DATA_SET_FLAG; + } + } +} + +static void max_row_function(SQLFunctionCtx *pCtx) { + int32_t notNullElems = 0; + minMax_function(pCtx, pCtx->pOutput, 0, ¬NullElems); + + SET_VAL(pCtx, notNullElems, 1); + + if (notNullElems > 0) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + pResInfo->hasResult = DATA_SET_FLAG; + + // set the flag for super table query + if (pCtx->stableQuery) { + *(pCtx->pOutput + pCtx->inputBytes) = DATA_SET_FLAG; + } + } +} + +static void min_row_func_merge(SQLFunctionCtx *pCtx) { + int32_t notNullElems = minmax_merge_impl(pCtx, pCtx->outputBytes, pCtx->pOutput, 1); + + SET_VAL(pCtx, notNullElems, 1); + + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + if (notNullElems > 0) { + pResInfo->hasResult = DATA_SET_FLAG; + } +} + +static void max_row_func_merge(SQLFunctionCtx *pCtx) { + int32_t numOfElem = minmax_merge_impl(pCtx, pCtx->outputBytes, pCtx->pOutput, 0); + + SET_VAL(pCtx, numOfElem, 1); + + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + if (numOfElem > 0) { + pResInfo->hasResult = DATA_SET_FLAG; + } +} + #define LOOP_STDDEV_IMPL(type, r, d, ctx, delta, _type, num) \ for (int32_t i = 0; i < (ctx)->size; ++i) { \ if ((ctx)->hasNull && isNull((char *)&((type *)d)[i], (_type))) { \ @@ -2065,15 +2255,15 @@ static void first_function(SQLFunctionCtx *pCtx) { SET_VAL(pCtx, notNullElems, 1); } -static void first_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t index) { +static void first_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t idx) { int64_t *timestamp = GET_TS_LIST(pCtx); SFirstLastInfo *pInfo = (SFirstLastInfo *)(pCtx->pOutput + pCtx->inputBytes); - if (pInfo->hasResult != DATA_SET_FLAG || timestamp[index] < pInfo->ts) { + if (pInfo->hasResult != DATA_SET_FLAG || timestamp[idx] < pInfo->ts) { memcpy(pCtx->pOutput, pData, pCtx->inputBytes); pInfo->hasResult = DATA_SET_FLAG; - pInfo->ts = timestamp[index]; + pInfo->ts = timestamp[idx]; DO_UPDATE_TAG_COLUMNS(pCtx, pInfo->ts); } @@ -2203,19 +2393,19 @@ static void last_function(SQLFunctionCtx *pCtx) { SET_VAL(pCtx, notNullElems, 1); } -static void last_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t index) { +static void last_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t idx) { int64_t *timestamp = GET_TS_LIST(pCtx); SFirstLastInfo *pInfo = (SFirstLastInfo *)(pCtx->pOutput + pCtx->inputBytes); - if (pInfo->hasResult != DATA_SET_FLAG || pInfo->ts < timestamp[index]) { + if (pInfo->hasResult != DATA_SET_FLAG || pInfo->ts < timestamp[idx]) { #if defined(_DEBUG_VIEW) - qDebug("assign index:%d, ts:%" PRId64 ", val:%d, ", index, timestamp[index], *(int32_t *)pData); + qDebug("assign index:%d, ts:%" PRId64 ", val:%d, ", idx, timestamp[idx], *(int32_t *)pData); #endif memcpy(pCtx->pOutput, pData, pCtx->inputBytes); pInfo->hasResult = DATA_SET_FLAG; - pInfo->ts = timestamp[index]; + pInfo->ts = timestamp[idx]; DO_UPDATE_TAG_COLUMNS(pCtx, pInfo->ts); } @@ -3188,12 +3378,12 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo return true; } -#define LEASTSQR_CAL(p, x, y, index, step) \ +#define LEASTSQR_CAL(p, x, y, idx, step) \ do { \ (p)[0][0] += (double)(x) * (x); \ (p)[0][1] += (double)(x); \ - (p)[0][2] += (double)(x) * (y)[index]; \ - (p)[1][2] += (y)[index]; \ + (p)[0][2] += (double)(x) * (y)[idx]; \ + (p)[1][2] += (y)[idx]; \ (x) += step; \ } while (0) @@ -3412,6 +3602,70 @@ static void copy_function(SQLFunctionCtx *pCtx) { assignVal(pCtx->pOutput, pData, pCtx->inputBytes, pCtx->inputType); } +static char *get_data_by_offset(char *src, int16_t inputType, int32_t inputBytes, int32_t offset) { + char *res = NULL; + + switch (inputType) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_UTINYINT: + res = (char *) ((int8_t *) src + offset); + break; + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_USMALLINT: + res = (char *) ((int16_t *) src + offset); + break; + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_UINT: + res = (char *) ((int32_t *) src + offset); + break; + case TSDB_DATA_TYPE_FLOAT: + res = (char *) ((float *) src + offset); + break; + case TSDB_DATA_TYPE_DOUBLE: + res = (char *) ((double *) src + offset); + break; + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_UBIGINT: + case TSDB_DATA_TYPE_TIMESTAMP: + res = (char *) ((int64_t *) src + offset); + break; + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + res = src + offset * inputBytes; + break; + default: { + res = src; + } + } + + return res; +} + +static void row_copy_function(SQLFunctionCtx *pCtx) { + int16_t index; + + if (pCtx->minMaxRowType == FUNC_NOT_VAL || !pCtx->updateIndex) { + return; + } + + if (pCtx->minMaxRowType == FUNC_MIN_ROW) { + index = pCtx->minRowIndex; + } else { + index = pCtx->maxRowIndex; + } + + if (index < 0) { + return; + } + + SET_VAL(pCtx, pCtx->size, 1); + + char *pData = GET_INPUT_DATA_LIST(pCtx); + pData = get_data_by_offset(pData, pCtx->inputType, pCtx->inputBytes, index); + assignVal(pCtx->pOutput, pData, pCtx->inputBytes, pCtx->inputType); +} + static void full_copy_function(SQLFunctionCtx *pCtx) { copy_function(pCtx); @@ -3831,16 +4085,16 @@ static void diff_function(SQLFunctionCtx *pCtx) { char *getScalarExprColumnData(void *param, const char* name, int32_t colId) { SScalarExprSupport *pSupport = (SScalarExprSupport *)param; - int32_t index = -1; + int32_t idx = -1; for (int32_t i = 0; i < pSupport->numOfCols; ++i) { if (colId == pSupport->colList[i].colId) { - index = i; + idx = i; break; } } - assert(index >= 0); - return pSupport->data[index] + pSupport->offset * pSupport->colList[index].bytes; + assert(idx >= 0); + return pSupport->data[idx] + pSupport->offset * pSupport->colList[idx].bytes; } static void scalar_expr_function(SQLFunctionCtx *pCtx) { @@ -4049,14 +4303,14 @@ static double twa_get_area(SPoint1 s, SPoint1 e) { return val; } -static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t size) { +static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t idx, int32_t size) { int32_t notNullElems = 0; SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); TSKEY *tsList = GET_TS_LIST(pCtx); - int32_t i = index; + int32_t i = idx; int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order); SPoint1* last = &pInfo->p; @@ -4067,7 +4321,7 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si assert(last->key == INT64_MIN); last->key = tsList[i]; - GET_TYPED_DATA(last->val, double, pCtx->inputType, GET_INPUT_DATA(pCtx, index)); + GET_TYPED_DATA(last->val, double, pCtx->inputType, GET_INPUT_DATA(pCtx, idx)); pInfo->dOutput += twa_get_area(pCtx->start, *last); @@ -4077,7 +4331,7 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si i += step; } else if (pInfo->p.key == INT64_MIN) { last->key = tsList[i]; - GET_TYPED_DATA(last->val, double, pCtx->inputType, GET_INPUT_DATA(pCtx, index)); + GET_TYPED_DATA(last->val, double, pCtx->inputType, GET_INPUT_DATA(pCtx, idx)); pInfo->hasResult = DATA_SET_FLAG; pInfo->win.skey = last->key; @@ -5016,13 +5270,13 @@ static void mavg_function(SQLFunctionCtx *pCtx) { ////////////////////////////////////////////////////////////////////////////////// // Sample function with reservoir sampling algorithm -static void assignResultSample(SQLFunctionCtx *pCtx, SSampleFuncInfo *pInfo, int32_t index, int64_t ts, void *pData, uint16_t type, int16_t bytes, char *inputTags) { - assignVal(pInfo->values + index*bytes, pData, bytes, type); - *(pInfo->timeStamps + index) = ts; +static void assignResultSample(SQLFunctionCtx *pCtx, SSampleFuncInfo *pInfo, int32_t idx, int64_t ts, void *pData, uint16_t type, int16_t bytes, char *inputTags) { + assignVal(pInfo->values + idx*bytes, pData, bytes, type); + *(pInfo->timeStamps + idx) = ts; SExtTagsInfo* pTagInfo = &pCtx->tagInfo; int32_t posTag = 0; - char* tags = pInfo->taglists + index*pTagInfo->tagsLen; + char* tags = pInfo->taglists + idx*pTagInfo->tagsLen; if (pCtx->currentStage == MERGE_STAGE) { assert(inputTags != NULL); memcpy(tags, inputTags, (size_t)pTagInfo->tagsLen); @@ -6053,8 +6307,8 @@ int32_t functionCompatList[] = { 1, 1, 1, 1, -1, 1, 1, 1, 5, 1, 1, // tid_tag, deriv, csum, mavg, sample, block_info, elapsed, histogram, unique, mode, tail 6, 8, -1, -1, -1, 7, 1, -1, -1, 1, -1, - // stateCount, stateDuration, wstart, wstop, wduration, qstart, qstop, qduration, hyperloglog - 1, 1, 1, 1, 1, 1, 1, 1, 1, + // stateCount, stateDuration, wstart, wstop, wduration, qstart, qstop, qduration, hyperloglog, min_row, max_row + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; SAggFunctionInfo aAggs[TSDB_FUNC_MAX_NUM] = {{ @@ -6671,5 +6925,41 @@ SAggFunctionInfo aAggs[TSDB_FUNC_MAX_NUM] = {{ hll_func_finalizer, hll_func_merge, dataBlockRequired, + }, + { + // 51 + "min_row", + TSDB_FUNC_MIN_ROW, + TSDB_FUNC_MIN_ROW, + TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_SELECTIVITY, + min_row_func_setup, + min_row_function, + function_finalizer, + min_row_func_merge, + dataBlockRequired, + }, + { + // 52 + "max_row", + TSDB_FUNC_MAX_ROW, + TSDB_FUNC_MAX_ROW, + TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_SELECTIVITY, + max_row_func_setup, + max_row_function, + function_finalizer, + max_row_func_merge, + dataBlockRequired, + }, + { + // 53 + "col_dummy", + TSDB_FUNC_COL_DUMMY, + TSDB_FUNC_COL_DUMMY, + TSDB_BASE_FUNC_SO, + function_setup, + row_copy_function, + doFinalizer, + copy_function, + noDataRequired, } }; diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 7d4b0b7edb..d12cf8d03f 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -413,7 +413,7 @@ static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput continue; } - if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY) { + if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY || functId == TSDB_FUNC_COL_DUMMY) { hasTags = true; continue; } @@ -437,7 +437,7 @@ static bool isScalarWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput) { continue; } - if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY) { + if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY || functId == TSDB_FUNC_COL_DUMMY) { hasTags = true; continue; } @@ -519,9 +519,9 @@ static SResultRow* doSetResultOutBufByKey(SQueryRuntimeEnv* pRuntimeEnv, SResult pResultRowInfo->curPos = 0; } else { // check if current pResultRowInfo contains the existed pResultRow SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, tid, pResultRowInfo); - int64_t* index = taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes)); - if (index != NULL) { - pResultRowInfo->curPos = (int32_t) *index; + int64_t* idx = taosHashGet(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes)); + if (idx != NULL) { + pResultRowInfo->curPos = (int32_t) *idx; existed = true; } else { existed = false; @@ -557,9 +557,9 @@ static SResultRow* doSetResultOutBufByKey(SQueryRuntimeEnv* pRuntimeEnv, SResult pResultRowInfo->curPos = pResultRowInfo->size; pResultRowInfo->pResult[pResultRowInfo->size++] = pResult; - int64_t index = pResultRowInfo->curPos; + int64_t idx = pResultRowInfo->curPos; SET_RES_EXT_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, tid, pResultRowInfo); - taosHashPut(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes), &index, POINTER_BYTES); + taosHashPut(pRuntimeEnv->pResultRowListSet, pRuntimeEnv->keyBuf, GET_RES_EXT_WINDOW_KEY_LEN(bytes), &idx, POINTER_BYTES); } // too many time window in query @@ -633,7 +633,7 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t /* * query border check, skey should not be bounded by the query time range, since the value skey will - * be used as the time window index value. So we only change ekey of time window accordingly. + * be used as the time window idx value. So we only change ekey of time window accordingly. */ if (w.ekey > pQueryAttr->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) { w.ekey = pQueryAttr->window.ekey; @@ -945,6 +945,10 @@ void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset, int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput) { SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + int16_t minRowIndex = -1, maxRowIndex = -1; + bool updateIndex = false; + int32_t minMaxRowColIndex = -1; + int16_t minMaxRowType = FUNC_NOT_VAL; for (int32_t k = 0; k < numOfOutput; ++k) { bool hasAggregates = pCtx[k].preAggVals.isSet; @@ -977,7 +981,39 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo; doInvokeUdf(pUdfInfo, &pCtx[k], 0, TSDB_UDF_FUNC_NORMAL); } else if (!TSDB_FUNC_IS_SCALAR(functionId)){ + if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + if (minMaxRowColIndex == -1) { + minMaxRowColIndex = k; + } + + if (functionId == TSDB_FUNC_MIN_ROW) { + minMaxRowType = FUNC_MIN_ROW; + } else { + minMaxRowType = FUNC_MAX_ROW; + } + + pCtx[k].updateIndex = false; + } else { + pCtx[k].minRowIndex = minRowIndex; + pCtx[k].maxRowIndex = maxRowIndex; + pCtx[k].updateIndex = updateIndex; + pCtx[k].minMaxRowType = minMaxRowType; + } + aAggs[functionId].xFunction(&pCtx[k]); + + if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + updateIndex = pCtx[k].updateIndex; + + // find the minIndex or maxIndex of this column to detemine the index of other columns + if (functionId == TSDB_FUNC_MIN_ROW) { + minRowIndex = pCtx[k].preAggVals.statis.minIndex; + } + + if (functionId == TSDB_FUNC_MAX_ROW) { + maxRowIndex = pCtx[k].preAggVals.statis.maxIndex; + } + } } else { assert(0); } @@ -992,6 +1028,58 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx pCtx[k].preAggVals.isSet = hasAggregates; pCtx[k].pInput = start; } + + // update the indices of columns before the one in min_row/max_row + if (updateIndex) { + for (int32_t k = 0; k < minMaxRowColIndex; ++k) { + bool hasAggregates = pCtx[k].preAggVals.isSet; + + pCtx[k].size = forwardStep; + pCtx[k].startTs = pWin->skey; + pCtx[k].endTs = pWin->ekey; + + // keep it temporarialy + char* start = pCtx[k].pInput; + + int32_t pos = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? offset : offset - (forwardStep - 1); + if (pCtx[k].pInput != NULL) { + pCtx[k].pInput = (char *)pCtx[k].pInput + pos * pCtx[k].inputBytes; + } + + if (tsCol != NULL) { + pCtx[k].ptsList = &tsCol[pos]; + } + + // not a whole block involved in query processing, statistics data can not be used + // NOTE: the original value of isSet have been changed here + if (pCtx[k].preAggVals.isSet && forwardStep < numOfTotal) { + pCtx[k].preAggVals.isSet = false; + } + + if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) { + int32_t functionId = pCtx[k].functionId; + if (functionId != TSDB_FUNC_COL_DUMMY) { + continue; + } + + pCtx[k].minRowIndex = minRowIndex; + pCtx[k].maxRowIndex = maxRowIndex; + pCtx[k].updateIndex = updateIndex; + pCtx[k].minMaxRowType = minMaxRowType; + + aAggs[functionId].xFunction(&pCtx[k]); + + pCtx[k].minRowIndex = -1; + pCtx[k].maxRowIndex = -1; + pCtx[k].updateIndex = false; + pCtx[k].minMaxRowType = FUNC_NOT_VAL; + } + + // restore it + pCtx[k].preAggVals.isSet = hasAggregates; + pCtx[k].pInput = start; + } + } } @@ -1233,6 +1321,10 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunctionCtx* pCtx, SSDataBlock* pSDataBlock) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + int16_t minRowIndex = -1, maxRowIndex = -1; + bool updateIndex = false; + int32_t minMaxRowColIndex = -1; + int16_t minMaxRowType = FUNC_NOT_VAL; for (int32_t k = 0; k < pOperator->numOfOutput; ++k) { if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) { @@ -1243,7 +1335,39 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo; doInvokeUdf(pUdfInfo, &pCtx[k], 0, TSDB_UDF_FUNC_NORMAL); } else if (!TSDB_FUNC_IS_SCALAR(functionId)){ + if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + if (minMaxRowColIndex == -1) { + minMaxRowColIndex = k; + } + + if (functionId == TSDB_FUNC_MIN_ROW) { + minMaxRowType = FUNC_MIN_ROW; + } else { + minMaxRowType = FUNC_MAX_ROW; + } + + pCtx[k].updateIndex = false; + } else { + pCtx[k].minRowIndex = minRowIndex; + pCtx[k].maxRowIndex = maxRowIndex; + pCtx[k].updateIndex = updateIndex; + pCtx[k].minMaxRowType = minMaxRowType; + } + aAggs[functionId].xFunction(&pCtx[k]); + + if (functionId == TSDB_FUNC_MIN_ROW || functionId == TSDB_FUNC_MAX_ROW) { + updateIndex = pCtx[k].updateIndex; + + // find the minIndex or maxIndex of this column to detemine the index of other columns + if (functionId == TSDB_FUNC_MIN_ROW) { + minRowIndex = pCtx[k].preAggVals.statis.minIndex; + } + + if (functionId == TSDB_FUNC_MAX_ROW) { + maxRowIndex = pCtx[k].preAggVals.statis.maxIndex; + } + } } else { assert(0); } @@ -1254,6 +1378,32 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction } } } + + // update the indices of columns before the one in min_row/max_row + if (updateIndex) { + for (int32_t k = 0; k < minMaxRowColIndex; ++k) { + if (functionNeedToExecute(pRuntimeEnv, &pCtx[k])) { + pCtx[k].startTs = startTs; + + int32_t functionId = pCtx[k].functionId; + if (functionId != TSDB_FUNC_COL_DUMMY) { + continue; + } + + pCtx[k].minRowIndex = minRowIndex; + pCtx[k].maxRowIndex = maxRowIndex; + pCtx[k].updateIndex = updateIndex; + pCtx[k].minMaxRowType = minMaxRowType; + + aAggs[functionId].xFunction(&pCtx[k]); + + pCtx[k].minRowIndex = -1; + pCtx[k].maxRowIndex = -1; + pCtx[k].updateIndex = false; + pCtx[k].minMaxRowType = FUNC_NOT_VAL; + } + } + } } static void projectApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t numOfOutput) { @@ -1293,8 +1443,8 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, } SColIndex * pColIndex = &pExpr[k].base.colInfo; - int16_t index = pColIndex->colIndex; - SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, index); + int16_t idx = pColIndex->colIndex; + SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, idx); assert(pColInfo->info.colId <= TSDB_RES_COL_ID || (pColInfo->info.colId >= 0 && pColInfo->info.colId == pColIndex->colId)); double v1 = 0, v2 = 0, v = 0; @@ -1302,7 +1452,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, if (functionId == TSDB_FUNC_INTERP) { if (type == RESULT_ROW_START_INTERP) { if (prevRowIndex == -1) { - COPY_DATA(&pCtx[k].start.val, (char *)pRuntimeEnv->prevRow[index]); + COPY_DATA(&pCtx[k].start.val, (char *)pRuntimeEnv->prevRow[idx]); } else { COPY_DATA(&pCtx[k].start.val, (char *)pColInfo->pData + prevRowIndex * pColInfo->info.bytes); } @@ -1311,7 +1461,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) { if (prevRowIndex == -1) { - pCtx[k].start.ptr = (char *)pRuntimeEnv->prevRow[index]; + pCtx[k].start.ptr = (char *)pRuntimeEnv->prevRow[idx]; } else { pCtx[k].start.ptr = (char *)pColInfo->pData + prevRowIndex * pColInfo->info.bytes; } @@ -1319,7 +1469,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, } else { if (curRowIndex == -1) { - COPY_DATA(&pCtx[k].end.val, pRuntimeEnv->prevRow[index]); + COPY_DATA(&pCtx[k].end.val, pRuntimeEnv->prevRow[idx]); } else { COPY_DATA(&pCtx[k].end.val, (char *)pColInfo->pData + curRowIndex * pColInfo->info.bytes); } @@ -1334,7 +1484,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, assert(curTs != windowKey); if (prevRowIndex == -1) { - GET_TYPED_DATA(v1, double, pColInfo->info.type, (char *)pRuntimeEnv->prevRow[index]); + GET_TYPED_DATA(v1, double, pColInfo->info.type, (char *)pRuntimeEnv->prevRow[idx]); } else { GET_TYPED_DATA(v1, double, pColInfo->info.type, (char *)pColInfo->pData + prevRowIndex * pColInfo->info.bytes); } @@ -1949,7 +2099,7 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { continue; } - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { //ts_select ts,top(col,2) + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_COL_DUMMY) { //ts_select ts,top(col,2) tagLen += pCtx[i].outputBytes; pTagCtx[num++] = &pCtx[i]; } else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) { @@ -2024,6 +2174,9 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr pCtx->end.key = INT64_MIN; pCtx->startTs = INT64_MIN; + pCtx->minRowIndex = -1; + pCtx->maxRowIndex = -1; + pCtx->qWindow = pQueryAttr->window; pCtx->allocRows = numOfRows; @@ -3504,7 +3657,7 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt continue; } - // todo use tag column index to optimize performance + // todo use tag column idx to optimize performance GET_JSON_KEY(pLocalExprInfo) doSetTagValueInParam(pTable, param, paramLen, pLocalExprInfo->base.colInfo.colId, &pCtx[idx].tag, pLocalExprInfo->base.resType, pLocalExprInfo->base.resBytes); @@ -3522,7 +3675,7 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt offset += pLocalExprInfo->base.resBytes; } - //todo : use index to avoid iterator all possible output columns + //todo : use idx to avoid iterator all possible output columns if (pQueryAttr->stableQuery && pQueryAttr->stabledev && (pRuntimeEnv->prevResult != NULL)) { setParamForStableStddev(pRuntimeEnv, pCtx, numOfOutput, pExprInfo); } @@ -4834,10 +4987,10 @@ void queryCostStatis(SQInfo *pQInfo) { // TSKEY key = pTableQueryInfo->win.skey; // // pWindowResInfo->prevSKey = tw.skey; -// int32_t index = pRuntimeEnv->resultRowInfo.curIndex; +// int32_t idx = pRuntimeEnv->resultRowInfo.curIndex; // // int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock); -// pRuntimeEnv->resultRowInfo.curIndex = index; // restore the window index +// pRuntimeEnv->resultRowInfo.curIndex = idx; // restore the window idx // // qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%" PRId64, // GET_QID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, @@ -5643,15 +5796,15 @@ SArray* getOrderCheckColumns(SQueryAttr* pQuery) { { numOfCols = (int32_t) taosArrayGetSize(pOrderColumns); for(int32_t i = 0; i < numOfCols; ++i) { - SColIndex* index = taosArrayGet(pOrderColumns, i); + SColIndex* idx = taosArrayGet(pOrderColumns, i); for(int32_t j = 0; j < pQuery->numOfOutput; ++j) { SSqlExpr* pExpr = &pQuery->pExpr1[j].base; int32_t functionId = pExpr->functionId; - if (index->colId == pExpr->colInfo.colId && + if (idx->colId == pExpr->colInfo.colId && (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS)) { - index->colIndex = j; - index->colId = pExpr->resColId; + idx->colIndex = j; + idx->colId = pExpr->resColId; } } } @@ -5675,24 +5828,24 @@ SArray* getResultGroupCheckColumns(SQueryAttr* pQuery) { } for (int32_t i = 0; i < numOfCols; ++i) { - SColIndex* index = taosArrayGet(pOrderColumns, i); + SColIndex* idx = taosArrayGet(pOrderColumns, i); bool found = false; for(int32_t j = 0; j < pQuery->numOfOutput; ++j) { SSqlExpr* pExpr = &pQuery->pExpr1[j].base; // TSDB_FUNC_TAG_DUMMY function needs to be ignored - if (index->colId == pExpr->colInfo.colId && + if (idx->colId == pExpr->colInfo.colId && ((TSDB_COL_IS_TAG(pExpr->colInfo.flag) && ((pExpr->functionId == TSDB_FUNC_TAG) || (pExpr->functionId == TSDB_FUNC_TAGPRJ))) || (TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && pExpr->functionId == TSDB_FUNC_PRJ))) { - index->colIndex = j; - index->colId = pExpr->resColId; + idx->colIndex = j; + idx->colId = pExpr->resColId; found = true; break; } } - assert(found && index->colIndex >= 0 && index->colIndex < pQuery->numOfOutput); + assert(found && idx->colIndex >= 0 && idx->colIndex < pQuery->numOfOutput); } return pOrderColumns; @@ -5774,8 +5927,8 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, for(int32_t i = 0; i < numOfCols; ++i) { pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; - SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); - offset += pExpr[index->colIndex].base.resBytes; + SColIndex* idx = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[idx->colIndex].base.resBytes; } numOfCols = (pInfo->groupColumnList != NULL)? (int32_t)taosArrayGetSize(pInfo->groupColumnList):0; @@ -5789,8 +5942,8 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, for(int32_t i = 0; i < numOfCols; ++i) { pInfo->currentGroupColData[i] = (char*)pInfo->currentGroupColData + offset; - SColIndex* index = taosArrayGet(pInfo->groupColumnList, i); - offset += pExpr[index->colIndex].base.resBytes; + SColIndex* idx = taosArrayGet(pInfo->groupColumnList, i); + offset += pExpr[idx->colIndex].base.resBytes; } initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); @@ -5857,8 +6010,8 @@ SOperatorInfo *createMultiwaySortOperatorInfo(SQueryRuntimeEnv *pRuntimeEnv, SEx for(int32_t i = 0; i < numOfCols; ++i) { pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; - SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); - offset += pExpr[index->colIndex].base.colBytes; + SColIndex* idx = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[idx->colIndex].base.colBytes; } } @@ -6496,7 +6649,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo STimeEveryOperatorInfo* pEveryInfo = (STimeEveryOperatorInfo*)pOperatorInfo->info; SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); - int32_t gidx = pRuntimeEnv->current->groupIndex; + int32_t gindex = pRuntimeEnv->current->groupIndex; SQLFunctionCtx* pCtx = NULL; *needApply = false; @@ -6702,7 +6855,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo group_finished_exit: - qDebug("group idx[%d] interp finished", gidx); + qDebug("group index[%d] interp finished", gindex); if (pQueryAttr->needReverseScan) { pQueryAttr->range.skey = INT64_MIN; @@ -8132,8 +8285,8 @@ SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperator for(int32_t i = 0; i < numOfCols; ++i) { pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; - SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); - offset += pExpr[index->colIndex].base.resBytes; + SColIndex* idx = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[idx->colIndex].base.resBytes; } pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); @@ -8888,7 +9041,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pMsg += tListLen(param->pGroupColIndex[i].name); } - //pQueryMsg->orderByIdx = htons(pQueryMsg->orderByIdx); + //pQueryMsg->orderByIndex = htons(pQueryMsg->orderByIndex); pQueryMsg->groupOrderType = htons(pQueryMsg->groupOrderType); } @@ -9441,11 +9594,11 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t nu pExprs[i].base.resType = pExprs[i].pExpr->resultType; pExprs[i].base.interBytes = 0; } else { - int32_t index = pExprs[i].base.colInfo.colIndex; - assert(prevExpr[index].base.resColId == pExprs[i].base.colInfo.colId); + int32_t idx = pExprs[i].base.colInfo.colIndex; + assert(prevExpr[idx].base.resColId == pExprs[i].base.colInfo.colId); - type = prevExpr[index].base.resType; - bytes = prevExpr[index].base.resBytes; + type = prevExpr[idx].base.resType; + bytes = prevExpr[idx].base.resBytes; int32_t param = (int32_t)pExprs[i].base.param[0].i64; if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, @@ -9476,7 +9629,7 @@ SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pCo pGroupbyExpr->numOfGroupCols = pQueryMsg->numOfGroupCols; pGroupbyExpr->orderType = pQueryMsg->groupOrderType; - //pGroupbyExpr->orderIndex = pQueryMsg->orderByIdx; + //pGroupbyExpr->orderIndex = pQueryMsg->orderByIndex; pGroupbyExpr->columnInfo = taosArrayInit(pQueryMsg->numOfGroupCols, sizeof(SColIndex)); for(int32_t i = 0; i < pQueryMsg->numOfGroupCols; ++i) { @@ -9786,7 +9939,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; STimeWindow window = pQueryAttr->window; - int32_t index = 0; + int32_t idx = 0; for(int32_t i = 0; i < numOfGroups; ++i) { SArray* pa = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); @@ -9802,7 +9955,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S STableKeyInfo* info = taosArrayGet(pa, j); window.skey = info->lastKey; - void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo); + void* buf = (char*) pQInfo->pBuf + idx * sizeof(STableQueryInfo); STableQueryInfo* item = createTableQueryInfo(pQueryAttr, info->pTable, pQueryAttr->groupbyColumn, window, buf); if (item == NULL) { goto _cleanup; @@ -9813,7 +9966,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S STableId* id = TSDB_TABLEID(info->pTable); taosHashPut(pRuntimeEnv->tableqinfoGroupInfo.map, &id->tid, sizeof(id->tid), &item, POINTER_BYTES); - index += 1; + idx += 1; } } diff --git a/src/query/src/qExtbuffer.c b/src/query/src/qExtbuffer.c index 4a4ae3ca42..e2c649e99c 100644 --- a/src/query/src/qExtbuffer.c +++ b/src/query/src/qExtbuffer.c @@ -485,9 +485,9 @@ int32_t compare_a(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1, int32_t compare_aRv(SSDataBlock* pBlock, SArray* colIndex, int32_t numOfCols, int32_t rowIndex, char** buffer, int32_t order) { for (int32_t i = 0; i < numOfCols; ++i) { SColIndex* pColIndex = taosArrayGet(colIndex, i); - int32_t index = pColIndex->colIndex; + int32_t idx = pColIndex->colIndex; - SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, index); + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, idx); assert(pColIndex->colId == pColInfo->info.colId); char* data = pColInfo->pData + rowIndex * pColInfo->info.bytes; @@ -1176,14 +1176,14 @@ void tColModelCompact(SColumnModel *pModel, tFilePage *inputBuffer, int32_t maxE } } -SSchema1* getColumnModelSchema(SColumnModel *pColumnModel, int32_t index) { - assert(pColumnModel != NULL && index >= 0 && index < pColumnModel->numOfCols); - return &pColumnModel->pFields[index].field; +SSchema1* getColumnModelSchema(SColumnModel *pColumnModel, int32_t idx) { + assert(pColumnModel != NULL && idx >= 0 && idx < pColumnModel->numOfCols); + return &pColumnModel->pFields[idx].field; } -int16_t getColumnModelOffset(SColumnModel *pColumnModel, int32_t index) { - assert(pColumnModel != NULL && index >= 0 && index < pColumnModel->numOfCols); - return pColumnModel->pFields[index].offset; +int16_t getColumnModelOffset(SColumnModel *pColumnModel, int32_t idx) { + assert(pColumnModel != NULL && idx >= 0 && idx < pColumnModel->numOfCols); + return pColumnModel->pFields[idx].offset; } void tColModelErase(SColumnModel *pModel, tFilePage *inputBuffer, int32_t blockCapacity, int32_t s, int32_t e) { @@ -1257,17 +1257,17 @@ void tOrderDescDestroy(tOrderDescriptor *pDesc) { tfree(pDesc); } -void taoscQSort(void** pCols, SSchema* pSchema, int32_t numOfCols, int32_t numOfRows, int32_t index, __compar_fn_t compareFn) { - assert(numOfRows > 0 && numOfCols > 0 && index >= 0 && index < numOfCols); +void taoscQSort(void** pCols, SSchema* pSchema, int32_t numOfCols, int32_t numOfRows, int32_t idx, __compar_fn_t compareFn) { + assert(numOfRows > 0 && numOfCols > 0 && idx >= 0 && idx < numOfCols); - int32_t bytes = pSchema[index].bytes; + int32_t bytes = pSchema[idx].bytes; int32_t size = bytes + sizeof(int32_t); char* buf = calloc(1, size * numOfRows); for(int32_t i = 0; i < numOfRows; ++i) { char* dest = buf + size * i; - memcpy(dest, ((char*) pCols[index]) + bytes * i, bytes); + memcpy(dest, ((char*) pCols[idx]) + bytes * i, bytes); *(int32_t*)(dest+bytes) = i; } @@ -1279,7 +1279,7 @@ void taoscQSort(void** pCols, SSchema* pSchema, int32_t numOfCols, int32_t numOf for(int32_t i = 0; i < numOfCols; ++i) { int32_t bytes1 = pSchema[i].bytes; - if (i == index) { + if (i == idx) { for(int32_t j = 0; j < numOfRows; ++j){ char* src = buf + (j * size); char* dest = ((char*)pCols[i]) + (j * bytes1); diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index d83620c78f..1f4bbed831 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -63,8 +63,8 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData int32_t step = GET_FORWARD_DIRECTION_FACTOR(pFillInfo->order); // set the primary timestamp column value - int32_t index = pFillInfo->numOfCurrent; - char* val = elePtrAt(data[0], TSDB_KEYSIZE, index); + int32_t idx = pFillInfo->numOfCurrent; + char* val = elePtrAt(data[0], TSDB_KEYSIZE, idx); *(TSKEY*) val = pFillInfo->currentKey; // set the other values @@ -78,11 +78,11 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData continue; } - char* output = elePtrAt(data[i], pCol->col.bytes, index); + char* output = elePtrAt(data[i], pCol->col.bytes, idx); assignVal(output, p + pCol->col.offset, pCol->col.bytes, pCol->col.type); } } else { // no prev value yet, set the value for NULL - setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, index); + setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, idx); } } else if (pFillInfo->type == TSDB_FILL_NEXT) { char* p = next; @@ -94,11 +94,11 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData continue; } - char* output = elePtrAt(data[i], pCol->col.bytes, index); + char* output = elePtrAt(data[i], pCol->col.bytes, idx); assignVal(output, p + pCol->col.offset, pCol->col.bytes, pCol->col.type); } } else { // no prev value yet, set the value for NULL - setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, index); + setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, idx); } } else if (pFillInfo->type == TSDB_FILL_LINEAR) { if (prev != NULL && !outOfBound) { @@ -111,7 +111,7 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData int16_t type = pCol->col.type; int16_t bytes = pCol->col.bytes; - char *val1 = elePtrAt(data[i], pCol->col.bytes, index); + char *val1 = elePtrAt(data[i], pCol->col.bytes, idx); if (type == TSDB_DATA_TYPE_BINARY|| type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BOOL) { setNull(val1, pCol->col.type, bytes); continue; @@ -128,7 +128,7 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData taosGetLinearInterpolationVal(&point, type, &point1, &point2, type, &exceedMax, &exceedMin); } } else { - setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, index); + setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, idx); } } else { // fill the default value */ for (int32_t i = 1; i < pFillInfo->numOfCols; ++i) { @@ -137,12 +137,12 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData continue; } - char* val1 = elePtrAt(data[i], pCol->col.bytes, index); + char* val1 = elePtrAt(data[i], pCol->col.bytes, idx); assignVal(val1, (char*)&pCol->fillVal.i, pCol->col.bytes, pCol->col.type); } } - setTagsValue(pFillInfo, data, index); + setTagsValue(pFillInfo, data, idx); pFillInfo->currentKey = taosTimeAdd(pFillInfo->currentKey, pFillInfo->interval.sliding * step, pFillInfo->interval.slidingUnit, pFillInfo->precision); pFillInfo->numOfCurrent++; } @@ -303,11 +303,11 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t numOfTags += 1; bool exists = false; - int32_t index = -1; + int32_t idx = -1; for (int32_t j = 0; j < k; ++j) { if (pFillInfo->pTags[j].col.colId == pColInfo->col.colId) { exists = true; - index = j; + idx = j; break; } } @@ -323,7 +323,7 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t k += 1; } else { - pColInfo->tagIndex = index; + pColInfo->tagIndex = idx; } } diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index 11ace4f7ce..0d9fdb814a 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -975,7 +975,7 @@ int32_t filterAddUnitToGroup(SFilterGroup *group, uint32_t unitIdx) { return TSDB_CODE_SUCCESS; } -int32_t filterConvertSetFromBinary(void **q, const char *buf, int32_t len, uint32_t tType, bool tolower) { +int32_t filterConvertSetFromBinary(void **q, const char *buf, int32_t len, uint32_t tType, bool bTolower) { SBufferReader br = tbufInitReader(buf, len, false); uint32_t sType = tbufReadUint32(&br); SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(tType), true, false); @@ -1158,7 +1158,7 @@ int32_t filterConvertSetFromBinary(void **q, const char *buf, int32_t len, uint3 t = varDataLen(tmp); pvar = varDataVal(tmp); - if (tolower) { + if (bTolower) { strntolower_s(pvar, pvar, (int32_t)t); } break; @@ -2746,7 +2746,7 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t memset(info->blkUnitRes, 0, sizeof(*info->blkUnitRes) * info->unitNum); for (uint32_t k = 0; k < info->unitNum; ++k) { - int32_t index = -1; + int32_t idx = -1; SFilterComUnit *cunit = &info->cunits[k]; if (FILTER_NO_MERGE_DATA_TYPE(cunit->dataType)) { @@ -2755,16 +2755,16 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t for(int32_t i = 0; i < numOfCols; ++i) { if (pDataStatis[i].colId == cunit->colId) { - index = i; + idx = i; break; } } - if (index == -1) { + if (idx == -1) { continue; } - if (pDataStatis[index].numOfNull <= 0) { + if (pDataStatis[idx].numOfNull <= 0) { if (cunit->optr == TSDB_RELATION_ISNULL) { info->blkUnitRes[k] = -1; rmUnit = 1; @@ -2777,7 +2777,7 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t continue; } } else { - if (pDataStatis[index].numOfNull == numOfRows) { + if (pDataStatis[idx].numOfNull == numOfRows) { if (cunit->optr == TSDB_RELATION_ISNULL) { info->blkUnitRes[k] = 1; rmUnit = 1; @@ -2796,7 +2796,7 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t continue; } - SDataStatis* pDataBlockst = &pDataStatis[index]; + SDataStatis* pDataBlockst = &pDataStatis[idx]; void *minVal, *maxVal; float minv = 0; float maxv = 0; @@ -3586,17 +3586,17 @@ bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t num void *minVal, *maxVal; for (uint32_t k = 0; k < info->colRangeNum; ++k) { - int32_t index = -1; + int32_t idx = -1; SFilterRangeCtx *ctx = info->colRange[k]; for(int32_t i = 0; i < numOfCols; ++i) { if (pDataStatis[i].colId == ctx->colId) { - index = i; + idx = i; break; } } // no statistics data, load the true data block - if (index == -1) { + if (idx == -1) { break; } @@ -3605,13 +3605,13 @@ bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t num break; } - if (pDataStatis[index].numOfNull <= 0) { + if (pDataStatis[idx].numOfNull <= 0) { if (ctx->isnull && !ctx->notnull && !ctx->isrange) { ret = false; break; } - } else if (pDataStatis[index].numOfNull > 0) { - if (pDataStatis[index].numOfNull == numOfRows) { + } else if (pDataStatis[idx].numOfNull > 0) { + if (pDataStatis[idx].numOfNull == numOfRows) { if ((ctx->notnull || ctx->isrange) && (!ctx->isnull)) { ret = false; break; @@ -3625,7 +3625,7 @@ bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t num } } - SDataStatis* pDataBlockst = &pDataStatis[index]; + SDataStatis* pDataBlockst = &pDataStatis[idx]; SFilterRangeNode *r = ctx->rs; float minv = 0; diff --git a/src/query/src/qHistogram.c b/src/query/src/qHistogram.c index 8544224a64..752c7b96a5 100644 --- a/src/query/src/qHistogram.c +++ b/src/query/src/qHistogram.c @@ -45,15 +45,15 @@ //} // ////min heap -// void tHeapAdjust(SHeapEntry* pEntry, int32_t index, int32_t len) { +// void tHeapAdjust(SHeapEntry* pEntry, int32_t idx, int32_t len) { // SHeapEntry* ptr = NULL; // // int32_t end = len - 1; // -// SHeapEntry p1 = pEntry[index]; -// int32_t next = index; +// SHeapEntry p1 = pEntry[idx]; +// int32_t next = idx; // -// for(int32_t i=index; i<=(end-1)/2; ) { +// for(int32_t i=idx; i<=(end-1)/2; ) { // int32_t lc = (i<<1) + 1; // int32_t rc = (i+1) << 1; // @@ -119,7 +119,7 @@ // } //} -static int32_t histogramCreateBin(SHistogramInfo* pHisto, int32_t index, double val); +static int32_t histogramCreateBin(SHistogramInfo* pHisto, int32_t idx, double val); SHistogramInfo* tHistogramCreate(int32_t numOfEntries) { /* need one redundant slot */ @@ -191,7 +191,7 @@ int32_t tHistogramAdd(SHistogramInfo** pHisto, double val) { tSkipListNode* pResNode = SSkipListPut((*pHisto)->pList, entry, &key, 0); SHistBin* pEntry1 = (SHistBin*)pResNode->pData; - pEntry1->index = -1; + pEntry1->idx = -1; tSkipListNode* pLast = NULL; @@ -209,7 +209,7 @@ int32_t tHistogramAdd(SHistogramInfo** pHisto, double val) { SLoserTreeInfo* pTree = (*pHisto)->pLoserTree; (*pHisto)->pLoserTree->pNode[lastIndex + pTree->numOfEntries].pData = pResNode; - pEntry1->index = (*pHisto)->pLoserTree->pNode[lastIndex + pTree->numOfEntries].index; + pEntry1->idx = (*pHisto)->pLoserTree->pNode[lastIndex + pTree->numOfEntries].index; // update the loser tree if ((*pHisto)->ordered) { @@ -390,39 +390,39 @@ static void histogramMergeImpl(SHistBin* pHistBin, int32_t* size) { int32_t oldSize = *size; double delta = DBL_MAX; - int32_t index = -1; + int32_t idx = -1; for (int32_t i = 1; i < oldSize; ++i) { double d = pHistBin[i].val - pHistBin[i - 1].val; if (d < delta) { delta = d; - index = i - 1; + idx = i - 1; } } - SHistBin* s1 = &pHistBin[index]; - SHistBin* s2 = &pHistBin[index + 1]; + SHistBin* s1 = &pHistBin[idx]; + SHistBin* s2 = &pHistBin[idx + 1]; double newVal = (s1->val * s1->num + s2->val * s2->num) / (s1->num + s2->num); s1->val = newVal; s1->num = s1->num + s2->num; - memmove(&pHistBin[index + 1], &pHistBin[index + 2], (oldSize - index - 2) * sizeof(SHistBin)); + memmove(&pHistBin[idx + 1], &pHistBin[idx + 2], (oldSize - idx - 2) * sizeof(SHistBin)); (*size) -= 1; #endif } /* optimize this procedure */ -int32_t histogramCreateBin(SHistogramInfo* pHisto, int32_t index, double val) { +int32_t histogramCreateBin(SHistogramInfo* pHisto, int32_t idx, double val) { #if defined(USE_ARRAYLIST) - int32_t remain = pHisto->numOfEntries - index; + int32_t remain = pHisto->numOfEntries - idx; if (remain > 0) { - memmove(&pHisto->elems[index + 1], &pHisto->elems[index], sizeof(SHistBin) * remain); + memmove(&pHisto->elems[idx + 1], &pHisto->elems[idx], sizeof(SHistBin) * remain); } - assert(index >= 0 && index <= pHisto->maxEntries); + assert(idx >= 0 && idx <= pHisto->maxEntries); - pHisto->elems[index].num = 1; - pHisto->elems[index].val = val; + pHisto->elems[idx].num = 1; + pHisto->elems[idx].val = val; pHisto->numOfEntries += 1; /* we need to merge the slot */ diff --git a/src/query/src/qPercentile.c b/src/query/src/qPercentile.c index 8428c339f4..0210888b17 100644 --- a/src/query/src/qPercentile.c +++ b/src/query/src/qPercentile.c @@ -122,54 +122,54 @@ int32_t tBucketIntHash(tMemBucket *pBucket, const void *value) { int64_t v = 0; GET_TYPED_DATA(v, int64_t, pBucket->type, value); - int32_t index = -1; + int32_t idx = -1; if (v > pBucket->range.i64MaxVal || v < pBucket->range.i64MinVal) { - return index; + return idx; } // divide the value range into 1024 buckets uint64_t span = pBucket->range.i64MaxVal - pBucket->range.i64MinVal; if (span < pBucket->numOfSlots) { int64_t delta = v - pBucket->range.i64MinVal; - index = (delta % pBucket->numOfSlots); + idx = (delta % pBucket->numOfSlots); } else { double slotSpan = (double)span / pBucket->numOfSlots; - index = (int32_t)(((double)v - pBucket->range.i64MinVal) / slotSpan); - if (index == pBucket->numOfSlots) { - index -= 1; + idx = (int32_t)(((double)v - pBucket->range.i64MinVal) / slotSpan); + if (idx == pBucket->numOfSlots) { + idx -= 1; } } - assert(index >= 0 && index < pBucket->numOfSlots); - return index; + assert(idx >= 0 && idx < pBucket->numOfSlots); + return idx; } int32_t tBucketUintHash(tMemBucket *pBucket, const void *value) { uint64_t v = 0; GET_TYPED_DATA(v, uint64_t, pBucket->type, value); - int32_t index = -1; + int32_t idx = -1; if (v > pBucket->range.u64MaxVal || v < pBucket->range.u64MinVal) { - return index; + return idx; } // divide the value range into 1024 buckets uint64_t span = pBucket->range.u64MaxVal - pBucket->range.u64MinVal; if (span < pBucket->numOfSlots) { int64_t delta = v - pBucket->range.u64MinVal; - index = (int32_t) (delta % pBucket->numOfSlots); + idx = (int32_t) (delta % pBucket->numOfSlots); } else { double slotSpan = (double)span / pBucket->numOfSlots; - index = (int32_t)(((double)v - pBucket->range.u64MinVal) / slotSpan); - if (index == pBucket->numOfSlots) { - index -= 1; + idx = (int32_t)(((double)v - pBucket->range.u64MinVal) / slotSpan); + if (idx == pBucket->numOfSlots) { + idx -= 1; } } - assert(index >= 0 && index < pBucket->numOfSlots); - return index; + assert(idx >= 0 && idx < pBucket->numOfSlots); + return idx; } int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) { @@ -180,27 +180,27 @@ int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) { v = GET_DOUBLE_VAL(value); } - int32_t index = -1; + int32_t idx = -1; if (v > pBucket->range.dMaxVal || v < pBucket->range.dMinVal) { - return index; + return idx; } // divide a range of [dMinVal, dMaxVal] into 1024 buckets double span = pBucket->range.dMaxVal - pBucket->range.dMinVal; if (span < pBucket->numOfSlots) { int32_t delta = (int32_t)(v - pBucket->range.dMinVal); - index = (delta % pBucket->numOfSlots); + idx = (delta % pBucket->numOfSlots); } else { double slotSpan = span / pBucket->numOfSlots; - index = (int32_t)((v - pBucket->range.dMinVal) / slotSpan); - if (index == pBucket->numOfSlots) { - index -= 1; + idx = (int32_t)((v - pBucket->range.dMinVal) / slotSpan); + if (idx == pBucket->numOfSlots) { + idx -= 1; } } - assert(index >= 0 && index < pBucket->numOfSlots); - return index; + assert(idx >= 0 && idx < pBucket->numOfSlots); + return idx; } static __perc_hash_func_t getHashFunc(int32_t type) { @@ -332,18 +332,18 @@ int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size) { for (int32_t i = 0; i < size; ++i) { char *d = (char *) data + i * bytes; - int32_t index = (pBucket->hashFunc)(pBucket, d); - if (index < 0) { + int32_t idx = (pBucket->hashFunc)(pBucket, d); + if (idx < 0) { continue; } count += 1; - tMemBucketSlot *pSlot = &pBucket->pSlots[index]; + tMemBucketSlot *pSlot = &pBucket->pSlots[idx]; tMemBucketUpdateBoundingBox(&pSlot->range, d, pBucket->type); // ensure available memory pages to allocate - int32_t groupId = getGroupId(pBucket->numOfSlots, index, pBucket->times); + int32_t groupId = getGroupId(pBucket->numOfSlots, idx, pBucket->times); int32_t pageId = -1; if (pSlot->info.data == NULL || pSlot->info.data->num >= pBucket->elemPerPage) { @@ -387,7 +387,7 @@ static MinMaxEntry getMinMaxEntryOfNextSlotWithData(tMemBucket *pMemBucket, int3 return pMemBucket->pSlots[j].range; } -static bool isIdenticalData(tMemBucket *pMemBucket, int32_t index); +static bool isIdenticalData(tMemBucket *pMemBucket, int32_t idx); static double getIdenticalDataVal(tMemBucket* pMemBucket, int32_t slotIndex) { assert(isIdenticalData(pMemBucket, slotIndex)); @@ -532,8 +532,8 @@ double getPercentile(tMemBucket *pMemBucket, double percent) { /* * check if data in one slot are all identical only need to compare with the bounding box */ -bool isIdenticalData(tMemBucket *pMemBucket, int32_t index) { - tMemBucketSlot *pSeg = &pMemBucket->pSlots[index]; +bool isIdenticalData(tMemBucket *pMemBucket, int32_t idx) { + tMemBucketSlot *pSeg = &pMemBucket->pSlots[idx]; if (IS_FLOAT_TYPE(pMemBucket->type)) { return fabs(pSeg->range.dMaxVal - pSeg->range.dMinVal) < DBL_EPSILON; diff --git a/src/query/src/qPlan.c b/src/query/src/qPlan.c index 95c7f81ed6..eda920063f 100644 --- a/src/query/src/qPlan.c +++ b/src/query/src/qPlan.c @@ -126,9 +126,9 @@ static SQueryNode* doAddTableColumnNode(SQueryInfo* pQueryInfo, STableMetaInfo* for (int32_t i = 0; i < numOfCols; ++i) { SColumn* pCol = taosArrayGetP(tableCols, i); - SColumnIndex index = {.tableIndex = 0, .columnIndex = pCol->columnIndex}; - STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SExprInfo* p = tscExprCreate(pTableMetaInfo1, TSDB_FUNC_PRJ, &index, pCol->info.type, pCol->info.bytes, + SColumnIndex idx = {.tableIndex = 0, .columnIndex = pCol->columnIndex}; + STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, idx.tableIndex); + SExprInfo* p = tscExprCreate(pTableMetaInfo1, TSDB_FUNC_PRJ, &idx, pCol->info.type, pCol->info.bytes, pCol->info.colId, 0, TSDB_COL_NORMAL); strncpy(p->base.aliasName, pSchema[pCol->columnIndex].name, tListLen(p->base.aliasName)); diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index cee5130651..fe459ee460 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -857,8 +857,8 @@ SArray *tVariantListAppend(SArray *pList, tVariant *pVar, uint8_t sortOrder) { return pList; } -SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int32_t index) { - if (pList == NULL || pVar == NULL || index >= taosArrayGetSize(pList)) { +SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int32_t idx) { + if (pList == NULL || pVar == NULL || idx >= taosArrayGetSize(pList)) { return tVariantListAppend(NULL, pVar, sortOrder); } @@ -867,7 +867,7 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int item.pVar = *pVar; item.sortOrder = sortOrder; - taosArrayInsert(pList, index, &item); + taosArrayInsert(pList, idx, &item); return pList; } @@ -878,7 +878,8 @@ SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, } pRelationInfo->type = SQL_NODE_FROM_TABLELIST; - SRelElementPair p = {.tableName = *pName}; + SRelElementPair p; + p.tableName = *pName; if (pAlias != NULL) { p.aliasName = *pAlias; } else { @@ -917,7 +918,8 @@ SRelationInfo* addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrT pRelationInfo->type = SQL_NODE_FROM_SUBQUERY; - SRelElementPair p = {.pSubquery = pSub}; + SRelElementPair p; + p.pSubquery = pSub; if (pAlias != NULL) { p.aliasName = *pAlias; } else { @@ -1181,6 +1183,10 @@ void destroySqlNode(SSqlNode *pSqlNode) { pSqlNode->fillType = NULL; tSqlExprDestroy(pSqlNode->pHaving); + + tSqlExprDestroy(pSqlNode->pRange.start); + tSqlExprDestroy(pSqlNode->pRange.end); + free(pSqlNode); } diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index 1628c2d511..60ae900eb7 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -183,9 +183,9 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16 } // TODO refactor: use macro -SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset) { - assert(index >= 0 && offset != NULL); - return (SResultRowCellInfo*)((char*) pRow->pCellInfo + offset[index]); +SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t idx, int32_t* offset) { + assert(idx >= 0 && offset != NULL); + return (SResultRowCellInfo*)((char*) pRow->pCellInfo + offset[idx]); } size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv) { diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index b2941a8fe0..ee3245dd57 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -597,7 +597,7 @@ void** qReleaseQInfo(void* pMgmt, void* pQInfo, bool freeHandle) { //kill by qid int32_t qKillQueryByQId(void* pMgmt, int64_t qId, int32_t waitMs, int32_t waitCount) { - int32_t error = TSDB_CODE_SUCCESS; + int32_t err = TSDB_CODE_SUCCESS; void** handle = qAcquireQInfo(pMgmt, qId); if(handle == NULL) return terrno; @@ -613,13 +613,13 @@ int32_t qKillQueryByQId(void* pMgmt, int64_t qId, int32_t waitMs, int32_t waitCo while (pQInfo->owner != 0) { taosMsleep(waitMs); if(loop++ > waitCount){ - error = TSDB_CODE_FAILED; + err = TSDB_CODE_FAILED; break; } } qReleaseQInfo(pMgmt, (void **)&handle, true); - return error; + return err; } // local struct diff --git a/src/rpc/src/rpcCache.c b/src/rpc/src/rpcCache.c index 60a12c26b7..d18aa12c13 100644 --- a/src/rpc/src/rpcCache.c +++ b/src/rpc/src/rpcCache.c @@ -49,7 +49,7 @@ static int rpcHashConn(void *handle, char *fqdn, uint16_t port, int8_t connType static void rpcLockCache(int64_t *lockedBy); static void rpcUnlockCache(int64_t *lockedBy); static void rpcCleanConnCache(void *handle, void *tmrId); -static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t time); +static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t timeStamp); void *rpcOpenConnCache(int maxSessions, void (*cleanFp)(void *), void *tmrCtrl, int64_t keepTimer) { SConnHash **connHashList; @@ -118,7 +118,7 @@ void rpcAddConnIntoCache(void *handle, void *data, char *fqdn, uint16_t port, in SConnHash * pNode; SConnCache *pCache; - uint64_t time = taosGetTimestampMs(); + uint64_t timeStamp = taosGetTimestampMs(); pCache = (SConnCache *)handle; assert(pCache); @@ -131,7 +131,7 @@ void rpcAddConnIntoCache(void *handle, void *data, char *fqdn, uint16_t port, in pNode->connType = connType; pNode->data = data; pNode->prev = NULL; - pNode->time = time; + pNode->time = timeStamp; rpcLockCache(pCache->lockedBy+hash); @@ -140,7 +140,7 @@ void rpcAddConnIntoCache(void *handle, void *data, char *fqdn, uint16_t port, in pCache->connHashList[hash] = pNode; pCache->count[hash]++; - rpcRemoveExpiredNodes(pCache, pNode->next, hash, time); + rpcRemoveExpiredNodes(pCache, pNode->next, hash, timeStamp); rpcUnlockCache(pCache->lockedBy+hash); @@ -159,15 +159,15 @@ void *rpcGetConnFromCache(void *handle, char *fqdn, uint16_t port, int8_t connTy pCache = (SConnCache *)handle; assert(pCache); - uint64_t time = taosGetTimestampMs(); + uint64_t timeStamp = taosGetTimestampMs(); hash = rpcHashConn(pCache, fqdn, port, connType); rpcLockCache(pCache->lockedBy+hash); pNode = pCache->connHashList[hash]; while (pNode) { - if (time >= pCache->keepTimer + pNode->time) { - rpcRemoveExpiredNodes(pCache, pNode, hash, time); + if (timeStamp >= pCache->keepTimer + pNode->time) { + rpcRemoveExpiredNodes(pCache, pNode, hash, timeStamp); pNode = NULL; break; } @@ -178,7 +178,7 @@ void *rpcGetConnFromCache(void *handle, char *fqdn, uint16_t port, int8_t connTy } if (pNode) { - rpcRemoveExpiredNodes(pCache, pNode->next, hash, time); + rpcRemoveExpiredNodes(pCache, pNode->next, hash, timeStamp); if (pNode->prev) { pNode->prev->next = pNode->next; @@ -217,12 +217,12 @@ static void rpcCleanConnCache(void *handle, void *tmrId) { if (pCache->pTimer != tmrId) return; pthread_mutex_lock(&pCache->mutex); - uint64_t time = taosGetTimestampMs(); + uint64_t timeStamp = taosGetTimestampMs(); for (hash = 0; hash < pCache->maxSessions; ++hash) { rpcLockCache(pCache->lockedBy+hash); pNode = pCache->connHashList[hash]; - rpcRemoveExpiredNodes(pCache, pNode, hash, time); + rpcRemoveExpiredNodes(pCache, pNode, hash, timeStamp); rpcUnlockCache(pCache->lockedBy+hash); } @@ -231,8 +231,8 @@ static void rpcCleanConnCache(void *handle, void *tmrId) { pthread_mutex_unlock(&pCache->mutex); } -static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t time) { - if (pNode == NULL || (time < pCache->keepTimer + pNode->time) ) return; +static void rpcRemoveExpiredNodes(SConnCache *pCache, SConnHash *pNode, int hash, uint64_t timeStamp) { + if (pNode == NULL || (timeStamp < pCache->keepTimer + pNode->time) ) return; SConnHash *pPrev = pNode->prev, *pNext; diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 10b729eddb..da08c924a5 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -361,8 +361,8 @@ void *rpcMallocCont(int contLen) { void rpcFreeCont(void *cont) { if (cont) { char *temp = ((char *)cont) - sizeof(SRpcHead) - sizeof(SRpcReqContext); - free(temp); tTrace("free mem: %p", temp); + free(temp); } } @@ -573,8 +573,8 @@ void rpcCancelRequest(int64_t rid) { static void rpcFreeMsg(void *msg) { if ( msg ) { char *temp = (char *)msg - sizeof(SRpcReqContext); - free(temp); tTrace("free mem: %p", temp); + free(temp); } } diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index 001c50ee5d..aa13179af1 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -392,9 +392,9 @@ void taosCleanUpTcpClient(void *chandle) { void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uint16_t port) { SClientObj * pClientObj = shandle; - int32_t index = atomic_load_32(&pClientObj->index) % pClientObj->numOfThreads; - atomic_store_32(&pClientObj->index, index + 1); - SThreadObj *pThreadObj = pClientObj->pThreadObj[index]; + int32_t idx = atomic_load_32(&pClientObj->index) % pClientObj->numOfThreads; + atomic_store_32(&pClientObj->index, idx + 1); + SThreadObj *pThreadObj = pClientObj->pThreadObj[idx]; SOCKET fd = taosOpenTcpClientSocket(ip, port, pThreadObj->ip); #if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) @@ -403,12 +403,12 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin if (fd <= 0) return NULL; #endif - struct sockaddr_in sin; + struct sockaddr_in sockin; uint16_t localPort = 0; - unsigned int addrlen = sizeof(sin); - if (getsockname(fd, (struct sockaddr *)&sin, &addrlen) == 0 && - sin.sin_family == AF_INET && addrlen == sizeof(sin)) { - localPort = (uint16_t)ntohs(sin.sin_port); + unsigned int addrlen = sizeof(sockin); + if (getsockname(fd, (struct sockaddr *)&sockin, &addrlen) == 0 && + sockin.sin_family == AF_INET && addrlen == sizeof(sockin)) { + localPort = (uint16_t)ntohs(sockin.sin_port); } SFdObj *pFdObj = taosMallocFdObj(pThreadObj, fd); diff --git a/src/rpc/src/rpcUdp.c b/src/rpc/src/rpcUdp.c index 46313543d8..7b0f27a3d6 100644 --- a/src/rpc/src/rpcUdp.c +++ b/src/rpc/src/rpcUdp.c @@ -97,11 +97,11 @@ void *taosInitUdpConnection(uint32_t ip, uint16_t port, char *label, int threads break; } - struct sockaddr_in sin; - unsigned int addrlen = sizeof(sin); - if (getsockname(pConn->fd, (struct sockaddr *)&sin, &addrlen) == 0 && - sin.sin_family == AF_INET && addrlen == sizeof(sin)) { - pConn->localPort = (uint16_t)ntohs(sin.sin_port); + struct sockaddr_in sockin; + unsigned int addrlen = sizeof(sockin); + if (getsockname(pConn->fd, (struct sockaddr *)&sockin, &addrlen) == 0 && + sockin.sin_family == AF_INET && addrlen == sizeof(sockin)) { + pConn->localPort = (uint16_t)ntohs(sockin.sin_port); } tstrncpy(pConn->label, label, sizeof(pConn->label)); diff --git a/src/rpc/test/rclient.c b/src/rpc/test/rclient.c index 2f4433f1bb..42b77e624e 100644 --- a/src/rpc/test/rclient.c +++ b/src/rpc/test/rclient.c @@ -70,7 +70,7 @@ static void *sendRequest(void *param) { } int main(int argc, char *argv[]) { - SRpcInit rpcInit; + SRpcInit rpcInitial; SRpcEpSet epSet; int msgSize = 128; int numOfReqs = 0; @@ -90,18 +90,18 @@ int main(int argc, char *argv[]) { strcpy(epSet.fqdn[1], "192.168.0.1"); // client info - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = 0; - rpcInit.label = "APP"; - rpcInit.numOfThreads = 1; - rpcInit.cfp = processResponse; - rpcInit.sessions = 100; - rpcInit.idleTime = tsShellActivityTimer*1000; - rpcInit.user = "michael"; - rpcInit.secret = secret; - rpcInit.ckey = "key"; - rpcInit.spi = 1; - rpcInit.connType = TAOS_CONN_CLIENT; + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = 0; + rpcInitial.label = "APP"; + rpcInitial.numOfThreads = 1; + rpcInitial.cfp = processResponse; + rpcInitial.sessions = 100; + rpcInitial.idleTime = tsShellActivityTimer*1000; + rpcInitial.user = "michael"; + rpcInitial.secret = secret; + rpcInitial.ckey = "key"; + rpcInitial.spi = 1; + rpcInitial.connType = TAOS_CONN_CLIENT; for (int i=1; ireplica; ++index) { - const SNodeInfo *pNodeInfo = pCfg->nodeInfo + index; - pNode->peerInfo[index] = syncAddPeer(pNode, pNodeInfo); - if (pNode->peerInfo[index] == NULL) { + for (int32_t idx = 0; idx < pCfg->replica; ++idx) { + const SNodeInfo *pNodeInfo = pCfg->nodeInfo + idx; + pNode->peerInfo[idx] = syncAddPeer(pNode, pNodeInfo); + if (pNode->peerInfo[idx] == NULL) { sError("vgId:%d, node:%d fqdn:%s port:%u is not configured, stop taosd", pNode->vgId, pNodeInfo->nodeId, pNodeInfo->nodeFqdn, pNodeInfo->nodePort); syncStop(pNode->rid); @@ -210,7 +210,7 @@ int64_t syncStart(const SSyncInfo *pInfo) { } if ((strcmp(pNodeInfo->nodeFqdn, tsNodeFqdn) == 0) && (pNodeInfo->nodePort == tsSyncPort)) { - pNode->selfIndex = index; + pNode->selfIndex = idx; } } @@ -256,8 +256,8 @@ int64_t syncStart(const SSyncInfo *pInfo) { } syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb - for (int32_t index = 0; index < pNode->replica; ++index) { - syncStartCheckPeerConn(pNode->peerInfo[index]); + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + syncStartCheckPeerConn(pNode->peerInfo[idx]); } return pNode->rid; @@ -277,8 +277,8 @@ void syncStop(int64_t rid) { if (pNode->pFwdTimer) taosTmrStop(pNode->pFwdTimer); if (pNode->pRoleTimer) taosTmrStop(pNode->pRoleTimer); - for (int32_t index = 0; index < pNode->replica; ++index) { - pPeer = pNode->peerInfo[index]; + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + pPeer = pNode->peerInfo[idx]; if (pPeer) syncRemovePeer(pPeer); } @@ -303,8 +303,8 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) { pthread_mutex_lock(&pNode->mutex); syncStopCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb - for (int32_t index = 0; index < pNode->replica; ++index) { - syncStopCheckPeerConn(pNode->peerInfo[index]); + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + syncStopCheckPeerConn(pNode->peerInfo[idx]); } for (i = 0; i < pNode->replica; ++i) { @@ -364,8 +364,8 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) { } syncStartCheckPeerConn(pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]); // arb - for (int32_t index = 0; index < pNode->replica; ++index) { - syncStartCheckPeerConn(pNode->peerInfo[index]); + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + syncStartCheckPeerConn(pNode->peerInfo[idx]); } pthread_mutex_unlock(&pNode->mutex); @@ -629,16 +629,16 @@ static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) { } void syncBroadcastStatus(SSyncNode *pNode) { - for (int32_t index = 0; index < pNode->replica; ++index) { - if (index == pNode->selfIndex) continue; - SSyncPeer *pPeer = pNode->peerInfo[index]; + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + if (idx == pNode->selfIndex) continue; + SSyncPeer *pPeer = pNode->peerInfo[idx]; syncSendPeersStatusMsgToPeer(pPeer, 1, SYNC_STATUS_BROADCAST, syncGenTranId()); } } static void syncResetFlowCtrl(SSyncNode *pNode) { - for (int32_t index = 0; index < pNode->replica; ++index) { - pNode->peerInfo[index]->numOfRetrieves = 0; + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + pNode->peerInfo[idx]->numOfRetrieves = 0; } if (pNode->notifyFlowCtrlFp) { @@ -649,7 +649,7 @@ static void syncResetFlowCtrl(SSyncNode *pNode) { static void syncChooseMaster(SSyncNode *pNode) { SSyncPeer *pPeer; int32_t onlineNum = 0; - int32_t index = -1; + int32_t idx = -1; int32_t replica = pNode->replica; for (int32_t i = 0; i < pNode->replica; ++i) { @@ -660,13 +660,13 @@ static void syncChooseMaster(SSyncNode *pNode) { if (onlineNum == pNode->replica) { // if all peers are online, peer with highest version shall be master - index = 0; + idx = 0; for (int32_t i = 1; i < pNode->replica; ++i) { - if (pNode->peerInfo[i]->version > pNode->peerInfo[index]->version) { - index = i; + if (pNode->peerInfo[i]->version > pNode->peerInfo[idx]->version) { + idx = i; } } - sDebug("vgId:%d, master:%s may be choosed, index:%d", pNode->vgId, pNode->peerInfo[index]->id, index); + sDebug("vgId:%d, master:%s may be choosed, index:%d", pNode->vgId, pNode->peerInfo[idx]->id, idx); } else { sDebug("vgId:%d, no master election since onlineNum:%d replica:%d", pNode->vgId, onlineNum, pNode->replica); } @@ -683,26 +683,26 @@ static void syncChooseMaster(SSyncNode *pNode) { } } - if (index < 0 && onlineNum > replica / 2.0) { + if (idx < 0 && onlineNum > replica / 2.0) { // over half of nodes are online for (int32_t i = 0; i < pNode->replica; ++i) { // slave with highest version shall be master pPeer = pNode->peerInfo[i]; if (pPeer->role == TAOS_SYNC_ROLE_SLAVE || pPeer->role == TAOS_SYNC_ROLE_MASTER) { - if (index < 0 || pPeer->version > pNode->peerInfo[index]->version) { - index = i; + if (idx < 0 || pPeer->version > pNode->peerInfo[idx]->version) { + idx = i; } } } - if (index >= 0) { + if (idx >= 0) { sDebug("vgId:%d, master:%s may be choosed, index:%d onlineNum(arb):%d replica:%d", pNode->vgId, - pNode->peerInfo[index]->id, index, onlineNum, replica); + pNode->peerInfo[idx]->id, idx, onlineNum, replica); } } - if (index >= 0) { - if (index == pNode->selfIndex) { + if (idx >= 0) { + if (idx == pNode->selfIndex) { sInfo("vgId:%d, start to work as master", pNode->vgId); nodeRole = TAOS_SYNC_ROLE_MASTER; @@ -712,7 +712,7 @@ static void syncChooseMaster(SSyncNode *pNode) { syncResetFlowCtrl(pNode); (*pNode->notifyRoleFp)(pNode->vgId, nodeRole); } else { - pPeer = pNode->peerInfo[index]; + pPeer = pNode->peerInfo[idx]; sInfo("%s, it shall work as master", pPeer->id); } } else { @@ -725,8 +725,8 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { int32_t masterIndex = -1; int32_t replica = pNode->replica; - for (int32_t index = 0; index < pNode->replica; ++index) { - if (pNode->peerInfo[index]->role != TAOS_SYNC_ROLE_OFFLINE) { + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + if (pNode->peerInfo[idx]->role != TAOS_SYNC_ROLE_OFFLINE) { onlineNum++; } } @@ -751,19 +751,19 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { (*pNode->notifyRoleFp)(pNode->vgId, nodeRole); } } else { - for (int32_t index = 0; index < pNode->replica; ++index) { - SSyncPeer *pTemp = pNode->peerInfo[index]; + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + SSyncPeer *pTemp = pNode->peerInfo[idx]; if (pTemp->role != TAOS_SYNC_ROLE_MASTER) continue; if (masterIndex < 0) { - masterIndex = index; - sDebug("vgId:%d, peer:%s is master, index:%d", pNode->vgId, pTemp->id, index); + masterIndex = idx; + sDebug("vgId:%d, peer:%s is master, index:%d", pNode->vgId, pTemp->id, idx); } else { // multiple masters, it shall not happen if (masterIndex == pNode->selfIndex) { sError("%s, peer is master, work as slave instead", pTemp->id); nodeRole = TAOS_SYNC_ROLE_SLAVE; (*pNode->notifyRoleFp)(pNode->vgId, nodeRole); } else { - sError("vgId:%d, peer:%s is master too, masterIndex:%d index:%d", pNode->vgId, pTemp->id, masterIndex, index); + sError("vgId:%d, peer:%s is master too, masterIndex:%d index:%d", pNode->vgId, pTemp->id, masterIndex, idx); } } } @@ -783,9 +783,9 @@ static int32_t syncValidateMaster(SSyncPeer *pPeer) { (*pNode->notifyRoleFp)(pNode->vgId, nodeRole); code = -1; - for (int32_t index = 0; index < pNode->replica; ++index) { - if (index == pNode->selfIndex) continue; - syncRestartPeer(pNode->peerInfo[index]); + for (int32_t idx = 0; idx < pNode->replica; ++idx) { + if (idx == pNode->selfIndex) continue; + syncRestartPeer(pNode->peerInfo[idx]); } } @@ -825,15 +825,15 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus* peersStatus, int8_t new } else { // master not there, if all peer's state and version are consistent, choose the master int32_t consistent = 0; - int32_t index = 0; + int32_t idx = 0; if (peersStatus != NULL) { - for (index = 0; index < pNode->replica; ++index) { - SSyncPeer *pTemp = pNode->peerInfo[index]; - if (pTemp->role != peersStatus[index].role) break; - if ((pTemp->role != TAOS_SYNC_ROLE_OFFLINE) && (pTemp->version != peersStatus[index].version)) break; + for (idx = 0; idx < pNode->replica; ++idx) { + SSyncPeer *pTemp = pNode->peerInfo[idx]; + if (pTemp->role != peersStatus[idx].role) break; + if ((pTemp->role != TAOS_SYNC_ROLE_OFFLINE) && (pTemp->version != peersStatus[idx].version)) break; } - if (index >= pNode->replica) consistent = 1; + if (idx >= pNode->replica) consistent = 1; } else { if (pNode->replica == 2) consistent = 1; } @@ -1331,7 +1331,7 @@ static void syncProcessBrokenLink(int64_t rid, int32_t closedByApp) { static int32_t syncSaveFwdInfo(SSyncNode *pNode, uint64_t _version, void *mhandle) { SSyncFwds *pSyncFwds = pNode->pSyncFwds; - int64_t time = taosGetTimestampMs(); + int64_t lastTime = taosGetTimestampMs(); if (pSyncFwds->fwds >= SYNC_MAX_FWDS) { // pSyncFwds->first = (pSyncFwds->first + 1) % SYNC_MAX_FWDS; @@ -1348,7 +1348,7 @@ static int32_t syncSaveFwdInfo(SSyncNode *pNode, uint64_t _version, void *mhandl memset(pFwdInfo, 0, sizeof(SFwdInfo)); pFwdInfo->version = _version; pFwdInfo->mhandle = mhandle; - pFwdInfo->time = time; + pFwdInfo->time = lastTime; pSyncFwds->fwds++; sTrace("vgId:%d, fwd info is saved, hver:%" PRIu64 " fwds:%d ", pNode->vgId, _version, pSyncFwds->fwds); @@ -1400,10 +1400,10 @@ static void syncMonitorNodeRole(void *param, void *tmrId) { SSyncNode *pNode = syncAcquireNode(rid); if (pNode == NULL) return; - for (int32_t index = 0; index < pNode->replica; index++) { - if (index == pNode->selfIndex) continue; + for (int32_t idx = 0; idx < pNode->replica; idx++) { + if (idx == pNode->selfIndex) continue; - SSyncPeer *pPeer = pNode->peerInfo[index]; + SSyncPeer *pPeer = pNode->peerInfo[idx]; if (/*pPeer->role > TAOS_SYNC_ROLE_UNSYNCED && */ nodeRole > TAOS_SYNC_ROLE_UNSYNCED) continue; if (/*pPeer->sstatus > TAOS_SYNC_STATUS_INIT || */ nodeSStatus > TAOS_SYNC_STATUS_INIT) continue; @@ -1425,16 +1425,16 @@ static void syncMonitorFwdInfos(void *param, void *tmrId) { SSyncFwds *pSyncFwds = pNode->pSyncFwds; if (pSyncFwds) { - int64_t time = taosGetTimestampMs(); + int64_t lastTime = taosGetTimestampMs(); if (pSyncFwds->fwds > 0) { pthread_mutex_lock(&pNode->mutex); for (int32_t i = 0; i < pSyncFwds->fwds; ++i) { SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + (pSyncFwds->first + i) % SYNC_MAX_FWDS; - if (ABS(time - pFwdInfo->time) < 10000) break; + if (ABS(lastTime - pFwdInfo->time) < 10000) break; sDebug("vgId:%d, forward info expired, hver:%" PRIu64 " curtime:%" PRIu64 " savetime:%" PRIu64, pNode->vgId, - pFwdInfo->version, time, pFwdInfo->time); + pFwdInfo->version, lastTime, pFwdInfo->time); syncProcessFwdAck(pNode, pFwdInfo, TSDB_CODE_SYN_CONFIRM_EXPIRED); } diff --git a/src/sync/src/syncRetrieve.c b/src/sync/src/syncRetrieve.c index 623d6e3cc0..f0fcf6d6dd 100644 --- a/src/sync/src/syncRetrieve.c +++ b/src/sync/src/syncRetrieve.c @@ -228,7 +228,7 @@ static int64_t syncRetrieveLastWal(SSyncPeer *pPeer, char *name, uint64_t fversi return code; } -static int64_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t index) { +static int64_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t idx) { SSyncNode *pNode = pPeer->pSyncNode; int32_t once = 0; // last WAL has once ever been processed int64_t offset = 0; @@ -290,12 +290,12 @@ static int64_t syncRetrieveWal(SSyncPeer *pPeer) { char wname[TSDB_FILENAME_LEN * 2]; int32_t size; int64_t code = -1; - int64_t index = 0; + int64_t idx = 0; while (1) { // retrieve wal info wname[0] = 0; - code = (*pNode->getWalInfoFp)(pNode->vgId, wname, &index); + code = (*pNode->getWalInfoFp)(pNode->vgId, wname, &idx); if (code < 0) { sError("%s, failed to get wal info since:%s, code:0x%" PRIx64, pPeer->id, strerror(errno), code); break; @@ -308,7 +308,7 @@ static int64_t syncRetrieveWal(SSyncPeer *pPeer) { } if (code == 0) { // last wal - code = syncProcessLastWal(pPeer, wname, index); + code = syncProcessLastWal(pPeer, wname, idx); sInfo("%s, last wal processed, code:%" PRId64, pPeer->id, code); break; } @@ -317,14 +317,14 @@ static int64_t syncRetrieveWal(SSyncPeer *pPeer) { snprintf(fname, sizeof(fname), "%s/%s", pNode->path, wname); // send wal file, old wal file won't be modified, even remove is ok - struct stat fstat; - if (stat(fname, &fstat) < 0) { + struct stat fstatus; + if (stat(fname, &fstatus) < 0) { code = -1; sInfo("%s, failed to stat wal:%s for retrieve since %s, code:0x%" PRIx64, pPeer->id, fname, strerror(errno), code); break; } - size = fstat.st_size; + size = fstatus.st_size; sInfo("%s, retrieve wal:%s size:%d", pPeer->id, fname, size); int32_t sfd = open(fname, O_RDONLY | O_BINARY); diff --git a/src/tsdb/src/tsdbCommit.c b/src/tsdb/src/tsdbCommit.c index 6b19fdf3c1..3abc3e9acc 100644 --- a/src/tsdb/src/tsdbCommit.c +++ b/src/tsdb/src/tsdbCommit.c @@ -275,7 +275,7 @@ int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf) { // =================== Commit Meta Data -static int tsdbInitCommitMetaFile(STsdbRepo *pRepo, SMFile* pMf, bool open) { +static int tsdbInitCommitMetaFile(STsdbRepo *pRepo, SMFile* pMf, bool bOpen) { STsdbFS * pfs = REPO_FS(pRepo); SMFile * pOMFile = pfs->cstatus->pmf; SDiskID did; @@ -287,7 +287,7 @@ static int tsdbInitCommitMetaFile(STsdbRepo *pRepo, SMFile* pMf, bool open) { did.id = TFS_PRIMARY_ID; tsdbInitMFile(pMf, did, REPO_ID(pRepo), FS_TXN_VERSION(REPO_FS(pRepo))); - if (open && tsdbCreateMFile(pMf, true) < 0) { + if (bOpen && tsdbCreateMFile(pMf, true) < 0) { tsdbError("vgId:%d failed to create META file since %s", REPO_ID(pRepo), tstrerror(terrno)); return -1; } @@ -295,7 +295,7 @@ static int tsdbInitCommitMetaFile(STsdbRepo *pRepo, SMFile* pMf, bool open) { tsdbInfo("vgId:%d meta file %s is created to commit", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMf)); } else { tsdbInitMFileEx(pMf, pOMFile); - if (open && tsdbOpenMFile(pMf, O_WRONLY) < 0) { + if (bOpen && tsdbOpenMFile(pMf, O_WRONLY) < 0) { tsdbError("vgId:%d failed to open META file since %s", REPO_ID(pRepo), tstrerror(terrno)); return -1; } @@ -1813,4 +1813,4 @@ int tsdbCommitControl(STsdbRepo* pRepo, SControlDataInfo* pCtlDataInfo) { tsem_post(&pRepo->readyToCommit); return ret; -} \ No newline at end of file +} diff --git a/src/tsdb/src/tsdbFS.c b/src/tsdb/src/tsdbFS.c index b3d52e8fad..bfeb61e4f1 100644 --- a/src/tsdb/src/tsdbFS.c +++ b/src/tsdb/src/tsdbFS.c @@ -1217,13 +1217,13 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { bool isOneFSetFinish = true; int lastFType = -1; // one fileset ends when (1) the array ends or (2) encounter different fid - for (size_t index = 0; index < fArraySize; ++index) { + for (size_t idx = 0; idx < fArraySize; ++idx) { int tvid = -1, tfid = -1; TSDB_FILE_T ttype = TSDB_FILE_MAX; uint32_t tversion = -1; char bname[TSDB_FILENAME_LEN] = "\0"; - pf = taosArrayGet(fArray, index); + pf = taosArrayGet(fArray, idx); tfsbasename(pf, bname); tsdbParseDFilename(bname, &tvid, &tfid, &ttype, &tversion); ASSERT(tvid == REPO_ID(pRepo)); @@ -1237,7 +1237,7 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { lastFType = ttype; - if (index == 0) { + if (idx == 0) { memset(&fset, 0, sizeof(SDFileSet)); TSDB_FSET_SET_CLOSED(&fset); nDFiles = 1; @@ -1249,7 +1249,7 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { ++nDFiles; pDFile->f = *pf; // (1) the array ends - if (index == fArraySize - 1) { + if (idx == fArraySize - 1) { if (tsdbIsDFileSetValid(nDFiles)) { tsdbInfo("vgId:%d DFileSet %d is fetched, nDFiles=%" PRIu8, REPO_ID(pRepo), fset.fid, nDFiles); isOneFSetFinish = true; diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c index 2ae215ad36..63ea4ab6df 100644 --- a/src/tsdb/src/tsdbMain.c +++ b/src/tsdb/src/tsdbMain.c @@ -128,7 +128,7 @@ int tsdbCloseRepo(STsdbRepo *repo, int toCommit) { tsdbStopStream(pRepo); if(pRepo->pthread){ - taosDestoryThread(pRepo->pthread); + taosDestroyThread(pRepo->pthread); pRepo->pthread = NULL; } @@ -344,7 +344,7 @@ int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg) { #endif } -uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t eindex, int64_t *size) { +uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *idx, uint32_t eindex, int64_t *size) { // TODO return 0; #if 0 @@ -356,16 +356,16 @@ uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t struct stat fState; - tsdbDebug("vgId:%d name:%s index:%d eindex:%d", pRepo->config.tsdbId, name, *index, eindex); - ASSERT(*index <= eindex); + tsdbDebug("vgId:%d name:%s index:%d eindex:%d", pRepo->config.tsdbId, name, *idx, eindex); + ASSERT(*idx <= eindex); if (name[0] == 0) { // get the file from index or after, but not larger than eindex - int fid = (*index) / TSDB_FILE_TYPE_MAX; + int fid = (*idx) / TSDB_FILE_TYPE_MAX; if (pFileH->nFGroups == 0 || fid > pFileH->pFGroup[pFileH->nFGroups - 1].fileId) { - if (*index <= TSDB_META_FILE_INDEX && TSDB_META_FILE_INDEX <= eindex) { + if (*idx <= TSDB_META_FILE_INDEX && TSDB_META_FILE_INDEX <= eindex) { fname = tsdbGetMetaFileName(pRepo->rootDir); - *index = TSDB_META_FILE_INDEX; + *idx = TSDB_META_FILE_INDEX; magic = TSDB_META_FILE_MAGIC(pRepo->tsdbMeta); sprintf(name, "tsdb/%s", TSDB_META_FILE_NAME); } else { @@ -375,7 +375,7 @@ uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t SFileGroup *pFGroup = taosbsearch(&fid, pFileH->pFGroup, pFileH->nFGroups, sizeof(SFileGroup), keyFGroupCompFunc, TD_GE); if (pFGroup->fileId == fid) { - SFile *pFile = &pFGroup->files[(*index) % TSDB_FILE_TYPE_MAX]; + SFile *pFile = &pFGroup->files[(*idx) % TSDB_FILE_TYPE_MAX]; fname = strdup(TSDB_FILE_NAME(pFile)); magic = pFile->info.magic; char *tfname = strdup(fname); @@ -385,7 +385,7 @@ uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t if ((pFGroup->fileId + 1) * TSDB_FILE_TYPE_MAX - 1 < (int)eindex) { SFile *pFile = &pFGroup->files[0]; fname = strdup(TSDB_FILE_NAME(pFile)); - *index = pFGroup->fileId * TSDB_FILE_TYPE_MAX; + *idx = pFGroup->fileId * TSDB_FILE_TYPE_MAX; magic = pFile->info.magic; char *tfname = strdup(fname); sprintf(name, "tsdb/%s/%s", TSDB_DATA_DIR_NAME, basename(tfname)); @@ -402,7 +402,7 @@ uint32_t tsdbGetFileInfo(STsdbRepo *repo, char *name, uint32_t *index, uint32_t tfree(fname); return 0; } - if (*index == TSDB_META_FILE_INDEX) { // get meta file + if (*idx == TSDB_META_FILE_INDEX) { // get meta file tsdbGetStoreInfo(fname, &magic, size); } else { char tfname[TSDB_FILENAME_LEN] = "\0"; diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c index a095bff61e..a7aa310152 100644 --- a/src/tsdb/src/tsdbMeta.c +++ b/src/tsdb/src/tsdbMeta.c @@ -28,13 +28,13 @@ static void tsdbRemoveTableFromMeta(STsdbRepo *pRepo, STable *pTable, bool rm static int tsdbAddTableIntoIndex(STsdbMeta *pMeta, STable *pTable, bool refSuper); static int tsdbRemoveTableFromIndex(STsdbMeta *pMeta, STable *pTable); static int tsdbInitTableCfg(STableCfg *config, ETableType type, uint64_t uid, int32_t tid); -static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool dup); -static int tsdbTableSetName(STableCfg *config, char *name, bool dup); -static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool dup); -static int tsdbTableSetSName(STableCfg *config, char *sname, bool dup); +static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool duplicate); +static int tsdbTableSetName(STableCfg *config, char *name, bool duplicate); +static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool duplicate); +static int tsdbTableSetSName(STableCfg *config, char *sname, bool duplicate); static int tsdbTableSetSuperUid(STableCfg *config, uint64_t uid); -static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool dup); -static int tsdbTableSetStreamSql(STableCfg *config, char *sql, bool dup); +static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool duplicate); +static int tsdbTableSetStreamSql(STableCfg *config, char *sql, bool duplicate); static int tsdbEncodeTableName(void **buf, tstr *name); static void * tsdbDecodeTableName(void *buf, tstr **name); static int tsdbEncodeTable(void **buf, STable *pTable); @@ -1236,8 +1236,8 @@ static int tsdbInitTableCfg(STableCfg *config, ETableType type, uint64_t uid, in return 0; } -static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool dup) { - if (dup) { +static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool duplicate) { + if (duplicate) { config->schema = tdDupSchema(pSchema); if (config->schema == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1249,8 +1249,8 @@ static int tsdbTableSetSchema(STableCfg *config, STSchema *pSchema, bool dup) { return 0; } -static int tsdbTableSetName(STableCfg *config, char *name, bool dup) { - if (dup) { +static int tsdbTableSetName(STableCfg *config, char *name, bool duplicate) { + if (duplicate) { config->name = strdup(name); if (config->name == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1263,13 +1263,13 @@ static int tsdbTableSetName(STableCfg *config, char *name, bool dup) { return 0; } -static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool dup) { +static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool duplicate) { if (config->type != TSDB_CHILD_TABLE) { terrno = TSDB_CODE_TDB_INVALID_CREATE_TB_MSG; return -1; } - if (dup) { + if (duplicate) { config->tagSchema = tdDupSchema(pSchema); if (config->tagSchema == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1281,13 +1281,13 @@ static int tsdbTableSetTagSchema(STableCfg *config, STSchema *pSchema, bool dup) return 0; } -static int tsdbTableSetSName(STableCfg *config, char *sname, bool dup) { +static int tsdbTableSetSName(STableCfg *config, char *sname, bool duplicate) { if (config->type != TSDB_CHILD_TABLE) { terrno = TSDB_CODE_TDB_INVALID_CREATE_TB_MSG; return -1; } - if (dup) { + if (duplicate) { config->sname = strdup(sname); if (config->sname == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1309,13 +1309,13 @@ static int tsdbTableSetSuperUid(STableCfg *config, uint64_t uid) { return 0; } -static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool dup) { +static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool duplicate) { if (config->type != TSDB_CHILD_TABLE) { terrno = TSDB_CODE_TDB_INVALID_CREATE_TB_MSG; return -1; } - if (dup) { + if (duplicate) { config->tagValues = tdKVRowDup(row); if (config->tagValues == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; @@ -1328,13 +1328,13 @@ static int tsdbTableSetTagValue(STableCfg *config, SKVRow row, bool dup) { return 0; } -static int tsdbTableSetStreamSql(STableCfg *config, char *sql, bool dup) { +static int tsdbTableSetStreamSql(STableCfg *config, char *sql, bool duplicate) { if (config->type != TSDB_STREAM_TABLE) { terrno = TSDB_CODE_TDB_INVALID_CREATE_TB_MSG; return -1; } - if (dup) { + if (duplicate) { config->sql = strdup(sql); if (config->sql == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 567b7ab85b..3d72a7bde3 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -986,7 +986,9 @@ static SMemRow getSMemRowInTableMem(STableCheckInfo* pCheckInfo, int32_t order, return rmem; } else { pCheckInfo->chosen = CHECKINFO_CHOSEN_BOTH; - *extraRow = rimem; + if (extraRow) { + *extraRow = rimem; + } return rmem; } } else { @@ -2589,10 +2591,10 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO while (numOfTotal < cnt) { int32_t pos = pTree->pNode[0].index; - int32_t index = sup.blockIndexArray[pos]++; + int32_t idx = sup.blockIndexArray[pos]++; STableBlockInfo* pBlocksInfo = sup.pDataBlockInfo[pos]; - pQueryHandle->pDataBlockInfo[numOfTotal++] = pBlocksInfo[index]; + pQueryHandle->pDataBlockInfo[numOfTotal++] = pBlocksInfo[idx]; // set data block index overflow, in order to disable the offset comparator if (sup.blockIndexArray[pos] >= sup.numOfBlocksPerTable[pos]) { @@ -3331,7 +3333,7 @@ static bool loadDataBlockFromTableSeq(STsdbQueryHandle* pQueryHandle) { size_t numOfTables = taosArrayGetSize(pQueryHandle->pTableCheckInfo); assert(numOfTables > 0); - int64_t stime = taosGetTimestampUs(); + int64_t lastTime = taosGetTimestampUs(); while(pQueryHandle->activeIndex < numOfTables) { if (loadBlockOfActiveTable(pQueryHandle)) { @@ -3349,7 +3351,7 @@ static bool loadDataBlockFromTableSeq(STsdbQueryHandle* pQueryHandle) { terrno = TSDB_CODE_SUCCESS; - int64_t elapsedTime = taosGetTimestampUs() - stime; + int64_t elapsedTime = taosGetTimestampUs() - lastTime; pQueryHandle->cost.checkForNextTime += elapsedTime; } @@ -3368,8 +3370,8 @@ bool tsdbNextDataBlock(TsdbQueryHandleT pHandle) { return false; } - int64_t stime = taosGetTimestampUs(); - int64_t elapsedTime = stime; + int64_t lastTime = taosGetTimestampUs(); + int64_t elapsedTime = lastTime; // TODO refactor: remove "type" if (pQueryHandle->type == TSDB_QUERY_TYPE_LAST) { @@ -3396,7 +3398,7 @@ bool tsdbNextDataBlock(TsdbQueryHandleT pHandle) { } if (exists) { - pQueryHandle->cost.checkForNextTime += (taosGetTimestampUs() - stime); + pQueryHandle->cost.checkForNextTime += (taosGetTimestampUs() - lastTime); return exists; } @@ -3408,7 +3410,7 @@ bool tsdbNextDataBlock(TsdbQueryHandleT pHandle) { bool ret = doHasDataInBuffer(pQueryHandle); terrno = TSDB_CODE_SUCCESS; - elapsedTime = taosGetTimestampUs() - stime; + elapsedTime = taosGetTimestampUs() - lastTime; pQueryHandle->cost.checkForNextTime += elapsedTime; return ret; } @@ -3757,7 +3759,7 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta return TSDB_CODE_SUCCESS; } - int64_t stime = taosGetTimestampUs(); + int64_t lastTime = taosGetTimestampUs(); int statisStatus = tsdbLoadBlockStatis(&pHandle->rhelper, pBlockInfo->compBlock); if (statisStatus < TSDB_STATIS_OK) { return terrno; @@ -3791,7 +3793,7 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta } } - int64_t elapsed = taosGetTimestampUs() - stime; + int64_t elapsed = taosGetTimestampUs() - lastTime; pHandle->cost.statisInfoLoadTime += elapsed; *pBlockStatis = pHandle->statis; diff --git a/src/util/inc/tthread.h b/src/util/inc/tthread.h index 7443ad706d..9ef1c23035 100644 --- a/src/util/inc/tthread.h +++ b/src/util/inc/tthread.h @@ -26,7 +26,7 @@ extern "C" { // create new thread pthread_t* taosCreateThread( void *(*__start_routine) (void *), void* param); // destory thread -bool taosDestoryThread(pthread_t* pthread); +bool taosDestroyThread(pthread_t* pthread); // thread running return true bool taosThreadRunning(pthread_t* pthread); diff --git a/src/util/src/hash.c b/src/util/src/hash.c index e2fd37fdc4..d4d4297615 100644 --- a/src/util/src/hash.c +++ b/src/util/src/hash.c @@ -47,7 +47,7 @@ typedef struct SHashEntry { SHashNode *next; } SHashEntry; -typedef struct SHashObj { +struct SHashObj { SHashEntry **hashList; size_t capacity; // number of slots size_t size; // number of elements in hash table @@ -58,7 +58,7 @@ typedef struct SHashObj { SHashLockTypeE type; // lock type bool enableUpdate; // enable update SArray *pMemBlock; // memory block allocated for SHashEntry -} SHashObj; +}; /* * Function definition @@ -303,7 +303,7 @@ int32_t taosHashGetSize(const SHashObj *pHashObj) { if (pHashObj == NULL) { return 0; } - return (int32_t)atomic_load_64(&pHashObj->size); + return (int32_t)atomic_load_64((int32_t *) &pHashObj->size); } static FORCE_INLINE bool taosHashTableEmpty(const SHashObj *pHashObj) { diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c index 20f6d5b250..efccf7dff8 100644 --- a/src/util/src/tarray.c +++ b/src/util/src/tarray.c @@ -180,15 +180,15 @@ void* taosArrayPop(SArray* pArray) { return TARRAY_GET_ELEM(pArray, pArray->size); } -void* taosArrayGet(const SArray* pArray, size_t index) { - assert(index < pArray->size); - return TARRAY_GET_ELEM(pArray, index); +void* taosArrayGet(const SArray* pArray, size_t idx) { + assert(idx < pArray->size); + return TARRAY_GET_ELEM(pArray, idx); } -void* taosArrayGetP(const SArray* pArray, size_t index) { - assert(index < pArray->size); +void* taosArrayGetP(const SArray* pArray, size_t idx) { + assert(idx < pArray->size); - void* d = TARRAY_GET_ELEM(pArray, index); + void* d = TARRAY_GET_ELEM(pArray, idx); return *(void**)d; } @@ -204,12 +204,12 @@ void taosArraySetSize(SArray* pArray, size_t size) { pArray->size = size; } -void* taosArrayInsert(SArray* pArray, size_t index, void* pData) { +void* taosArrayInsert(SArray* pArray, size_t idx, void* pData) { if (pArray == NULL || pData == NULL) { return NULL; } - if (index >= pArray->size) { + if (idx >= pArray->size) { return taosArrayPush(pArray, pData); } @@ -221,9 +221,9 @@ void* taosArrayInsert(SArray* pArray, size_t index, void* pData) { } } - void* dst = TARRAY_GET_ELEM(pArray, index); + void* dst = TARRAY_GET_ELEM(pArray, idx); - int32_t remain = (int32_t)(pArray->size - index); + int32_t remain = (int32_t)(pArray->size - idx); memmove((char*)dst + pArray->elemSize, (char*)dst, pArray->elemSize * remain); memcpy(dst, pData, pArray->elemSize); @@ -232,21 +232,21 @@ void* taosArrayInsert(SArray* pArray, size_t index, void* pData) { return dst; } -void taosArraySet(SArray* pArray, size_t index, void* pData) { - assert(index < pArray->size); - memcpy(TARRAY_GET_ELEM(pArray, index), pData, pArray->elemSize); +void taosArraySet(SArray* pArray, size_t idx, void* pData) { + assert(idx < pArray->size); + memcpy(TARRAY_GET_ELEM(pArray, idx), pData, pArray->elemSize); } -void taosArrayRemove(SArray* pArray, size_t index) { - assert(index < pArray->size); +void taosArrayRemove(SArray* pArray, size_t idx) { + assert(idx < pArray->size); - if (index == pArray->size - 1) { + if (idx == pArray->size - 1) { taosArrayPop(pArray); return; } - size_t remain = pArray->size - index - 1; - memmove((char*)pArray->pData + index * pArray->elemSize, (char*)pArray->pData + (index + 1) * pArray->elemSize, remain * pArray->elemSize); + size_t remain = pArray->size - idx - 1; + memmove((char*)pArray->pData + idx * pArray->elemSize, (char*)pArray->pData + (idx + 1) * pArray->elemSize, remain * pArray->elemSize); pArray->size -= 1; } diff --git a/src/util/src/tcache.c b/src/util/src/tcache.c index 39b674fe4f..6fac32e22d 100644 --- a/src/util/src/tcache.c +++ b/src/util/src/tcache.c @@ -624,9 +624,9 @@ void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) { return; } - const char* stat[] = {"false", "true"}; + const char* status[] = {"false", "true"}; uDebug("cache:%s start to cleanup trashcan, numOfElem in trashcan:%d, free:%s", pCacheObj->name, - pCacheObj->numOfElemsInTrash, (force? stat[1]:stat[0])); + pCacheObj->numOfElemsInTrash, (force? status[1]:status[0])); STrashElem *pElem = pCacheObj->pTrash; while (pElem) { @@ -683,10 +683,10 @@ bool travHashTableFn(void* param, void* data) { return true; } -static void doCacheRefresh(SCacheObj* pCacheObj, int64_t time, __cache_trav_fn_t fp, void* param1) { +static void doCacheRefresh(SCacheObj* pCacheObj, int64_t timeStamp, __cache_trav_fn_t fp, void* param1) { assert(pCacheObj != NULL); - SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = fp, .time = time, .param1 = param1}; + SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = fp, .time = timeStamp, .param1 = param1}; taosHashCondTraverse(pCacheObj->pHashTable, travHashTableFn, &sup); } diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 2ab5ddbbe0..565878f3e1 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -436,9 +436,9 @@ int WCSPatternMatch(const uint32_t *patterStr, const uint32_t *str, size_t size, return TSDB_PATTERN_MATCH; } - uint32_t accept[3] = {towupper(c), towlower(c), 0}; + uint32_t accept_array[3] = {towupper(c), towlower(c), 0}; while (1) { - size_t n = taosWcscspn(str, accept); + size_t n = taosWcscspn(str, accept_array); str += n; if (str[0] == 0 || (n >= size)) { diff --git a/src/util/src/tmempool.c b/src/util/src/tmempool.c index 678c965eb1..b580f9d9ab 100644 --- a/src/util/src/tmempool.c +++ b/src/util/src/tmempool.c @@ -89,19 +89,19 @@ char *taosMemPoolMalloc(mpool_h handle) { } void taosMemPoolFree(mpool_h handle, char *pMem) { - int index; + int idx; pool_t *pool_p = (pool_t *)handle; if (pMem == NULL) return; - index = (int)(pMem - pool_p->pool) % pool_p->blockSize; - if (index != 0) { + idx = (int)(pMem - pool_p->pool) % pool_p->blockSize; + if (idx != 0) { uError("invalid free address:%p\n", pMem); return; } - index = (int)((pMem - pool_p->pool) / pool_p->blockSize); - if (index < 0 || index >= pool_p->numOfBlock) { + idx = (int)((pMem - pool_p->pool) / pool_p->blockSize); + if (idx < 0 || idx >= pool_p->numOfBlock) { uError("mempool: error, invalid address:%p\n", pMem); return; } @@ -110,7 +110,7 @@ void taosMemPoolFree(mpool_h handle, char *pMem) { pthread_mutex_lock(&pool_p->mutex); - pool_p->freeList[(pool_p->first + pool_p->numOfFree) % pool_p->numOfBlock] = index; + pool_p->freeList[(pool_p->first + pool_p->numOfFree) % pool_p->numOfBlock] = idx; pool_p->numOfFree++; pthread_mutex_unlock(&pool_p->mutex); diff --git a/src/util/src/tnettest.c b/src/util/src/tnettest.c index 2094c3d4be..407884759a 100644 --- a/src/util/src/tnettest.c +++ b/src/util/src/tnettest.c @@ -314,27 +314,27 @@ static void taosNetCheckPort(uint32_t hostIp, int32_t startPort, int32_t endPort } void *taosNetInitRpc(char *secretEncrypt, char spi) { - SRpcInit rpcInit; + SRpcInit rpcInitial; void * pRpcConn = NULL; char user[] = "nettestinternal"; char pass[] = "nettestinternal"; taosEncryptPass((uint8_t *)pass, strlen(pass), secretEncrypt); - memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.localPort = 0; - rpcInit.label = "NT"; - rpcInit.numOfThreads = 1; // every DB connection has only one thread - rpcInit.cfp = NULL; - rpcInit.sessions = 16; - rpcInit.connType = TAOS_CONN_CLIENT; - rpcInit.user = user; - rpcInit.idleTime = 2000; - rpcInit.ckey = "key"; - rpcInit.spi = spi; - rpcInit.secret = secretEncrypt; - - pRpcConn = rpcOpen(&rpcInit); + memset(&rpcInitial, 0, sizeof(rpcInitial)); + rpcInitial.localPort = 0; + rpcInitial.label = "NT"; + rpcInitial.numOfThreads = 1; // every DB connection has only one thread + rpcInitial.cfp = NULL; + rpcInitial.sessions = 16; + rpcInitial.connType = TAOS_CONN_CLIENT; + rpcInitial.user = user; + rpcInitial.idleTime = 2000; + rpcInitial.ckey = "key"; + rpcInitial.spi = spi; + rpcInitial.secret = secretEncrypt; + + pRpcConn = rpcOpen(&rpcInitial); return pRpcConn; } diff --git a/src/util/src/tqueue.c b/src/util/src/tqueue.c index 1ffa94b0df..7b23b708b1 100644 --- a/src/util/src/tqueue.c +++ b/src/util/src/tqueue.c @@ -86,9 +86,8 @@ void taosCloseQueue(taos_queue param) { } pthread_mutex_destroy(&queue->mutex); - free(queue); - uTrace("queue:%p is closed", queue); + free(queue); } void *taosAllocateQitem(int size) { diff --git a/src/util/src/tref.c b/src/util/src/tref.c index 33323889c6..bff8b12aae 100644 --- a/src/util/src/tref.c +++ b/src/util/src/tref.c @@ -54,7 +54,7 @@ static void taosLockList(int64_t *lockedBy); static void taosUnlockList(int64_t *lockedBy); static void taosIncRsetCount(SRefSet *pSet); static void taosDecRsetCount(SRefSet *pSet); -static int taosDecRefCount(int rsetId, int64_t rid, int remove); +static int taosDecRefCount(int rsetId, int64_t rid, int rm); int taosOpenRef(int max, void (*fp)(void *)) { @@ -389,7 +389,7 @@ int taosListRef() { return num; } -static int taosDecRefCount(int rsetId, int64_t rid, int remove) { +static int taosDecRefCount(int rsetId, int64_t rid, int rm) { int hash; SRefSet *pSet; SRefNode *pNode; @@ -428,7 +428,7 @@ static int taosDecRefCount(int rsetId, int64_t rid, int remove) { if (pNode) { pNode->count--; - if (remove) pNode->removed = 1; + if (rm) pNode->removed = 1; if (pNode->count <= 0) { if (pNode->prev) { diff --git a/src/util/src/tthread.c b/src/util/src/tthread.c index 043b2de2f2..f77dea592e 100644 --- a/src/util/src/tthread.c +++ b/src/util/src/tthread.c @@ -38,7 +38,7 @@ pthread_t* taosCreateThread( void *(*__start_routine) (void *), void* param) { } // destory thread -bool taosDestoryThread(pthread_t* pthread) { +bool taosDestroyThread(pthread_t* pthread) { if(pthread == NULL) return false; if(taosThreadRunning(pthread)) { pthread_cancel(*pthread); diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c index 81ab56ccea..f215453f74 100644 --- a/src/vnode/src/vnodeMain.c +++ b/src/vnode/src/vnodeMain.c @@ -461,7 +461,7 @@ void vnodeStopWaitingThread(SVnodeObj* pVnode) { if(loop == 0) { vInfo("vgId:%d :SDEL force kill thread to quit. pthread=%p pWrite=%p", pVnode->vgId, pWaitThread->pthread, pWaitThread->param); // thread not stop , so need kill - taosDestoryThread(pWaitThread->pthread); + taosDestroyThread(pWaitThread->pthread); // write msg need remove from queue SVWriteMsg* pWrite = (SVWriteMsg* )pWaitThread->param; if (pWrite) @@ -586,9 +586,9 @@ void vnodeCleanUp(SVnodeObj *pVnode) { // stop replication module if (pVnode->sync > 0) { - int64_t sync = pVnode->sync; + int64_t syncRid = pVnode->sync; pVnode->sync = -1; - syncStop(sync); + syncStop(syncRid); } vDebug("vgId:%d, vnode is cleaned, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode); @@ -692,4 +692,4 @@ bool vnodeWaitTooMany(void* vparam) { tsem_t* vnodeSemWait(void* vparam) { SVnodeObj* pVnode = (SVnodeObj* )vparam; return &pVnode->semWait; -} \ No newline at end of file +} diff --git a/src/vnode/src/vnodeSync.c b/src/vnode/src/vnodeSync.c index 2bdfd2ead3..6edcadcf71 100644 --- a/src/vnode/src/vnodeSync.c +++ b/src/vnode/src/vnodeSync.c @@ -22,7 +22,7 @@ #include "vnodeMain.h" #include "vnodeStatus.h" -uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fver) { +uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *idx, uint32_t eindex, int64_t *size, uint64_t *fver) { SVnodeObj *pVnode = vnodeAcquire(vgId); if (pVnode == NULL) { vError("vgId:%d, vnode not found while get file info", vgId); @@ -30,7 +30,7 @@ uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t ei } *fver = pVnode->fversion; - uint32_t ret = tsdbGetFileInfo(pVnode->tsdb, name, index, eindex, size); + uint32_t ret = tsdbGetFileInfo(pVnode->tsdb, name, idx, eindex, size); vnodeRelease(pVnode); return ret; diff --git a/src/wal/test/waltest.c b/src/wal/test/waltest.c index 505728fbe4..ffb9767bb4 100644 --- a/src/wal/test/waltest.c +++ b/src/wal/test/waltest.c @@ -113,17 +113,17 @@ int main(int argc, char *argv[]) { printf("%d wal files are written\n", total); - int64_t index = 0; + int64_t idx = 0; char name[256]; while (1) { - int code = walGetWalFile(pWal, name, &index); + int code = walGetWalFile(pWal, name, &idx); if (code == -1) { - printf("failed to get wal file, index:%" PRId64 "\n", index); + printf("failed to get wal file, index:%" PRId64 "\n", idx); break; } - printf("index:%" PRId64 " wal:%s\n", index, name); + printf("index:%" PRId64 " wal:%s\n", idx, name); if (code == 0) break; } diff --git a/tests/develop-test/3-connectors/R/test.sh b/tests/develop-test/3-connectors/R/test.sh index 90b9489365..dd4577a356 100644 --- a/tests/develop-test/3-connectors/R/test.sh +++ b/tests/develop-test/3-connectors/R/test.sh @@ -22,7 +22,9 @@ cd ../../ WKC=`pwd` #echo "WKC:${WKC}" -JDBC_PATH=${WKC}'/src/connector/jdbc/' +git clone git@github.com:taosdata/taos-connector-jdbc.git --branch 2.0 --single-branch --depth 1 + +JDBC_PATH=${WKC}'/taos-connector-jdbc/' CASE_PATH=${WKC}'/tests/examples/R/' cd ${JDBC_PATH} #echo "JDBC_PATH:${JDBC_PATH}" diff --git a/tests/develop-test/3-connectors/c#/test.sh b/tests/develop-test/3-connectors/c#/test.sh index 8cfb3fe4fc..f77536c1fd 100755 --- a/tests/develop-test/3-connectors/c#/test.sh +++ b/tests/develop-test/3-connectors/c#/test.sh @@ -15,25 +15,45 @@ rm -rf /var/lib/taos/* rm -rf /var/log/taos/* nohup taosd -c /etc/taos/ > /dev/null 2>&1 & sleep 10 + +# define fun to check if execute correct. +check(){ +if [ $1 -eq 0 ] +then + echo "===================$2 succeed===================" +else + echo "===================$2 failed===================" + exit 1 +fi +} + cd ../../ WKC=`pwd` -cd ${WKC}/src/connector/C# -dotnet test -# run example under Driver -cd ${WKC}/src/connector/C#/examples -dotnet run - -#dotnet run --project src/test/Cases/Cases.csproj +echo "WKC:${WKC}" # run example with neuget package cd ${WKC}/tests/examples/C# + dotnet run --project C#checker/C#checker.csproj +check $? C#checker.csproj + dotnet run --project TDengineTest/TDengineTest.csproj +check $? TDengineTest.csproj + dotnet run --project schemaless/schemaless.csproj +check $? schemaless.csproj + dotnet run --project jsonTag/jsonTag.csproj +check $? jsonTag.csproj + dotnet run --project stmt/stmt.csproj +check $? stmt.csproj + +dotnet run --project insertCn/insertCn.csproj +check $? insertCn.csproj cd ${WKC}/tests/examples/C#/taosdemo dotnet build -c Release tree | true ./bin/Release/net5.0/taosdemo -c /etc/taos -y +check $? taosdemo diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py b/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py index 5239d1b5fb..c86d5300f5 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py +++ b/tests/develop-test/5-taos-tools/taosbenchmark/insert_alltypes_json.py @@ -117,8 +117,6 @@ class TDTestCase: tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from db.stb where c13 = 'b1' or c13 = 'b2'") tdSql.checkData(0, 0, 160) - tdSql.query("select count(*) from db.stb where t0 >= 0 and t0 <= 10") - tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from db.stb where t1 >= 0 and t1 <= 10") tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from db.stb where t2 >= 0 and t2 <= 10") @@ -326,4 +324,4 @@ class TDTestCase: tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/limit_offset_json.py b/tests/develop-test/5-taos-tools/taosbenchmark/limit_offset_json.py index b7f3fcd826..e2160f3c9c 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/limit_offset_json.py +++ b/tests/develop-test/5-taos-tools/taosbenchmark/limit_offset_json.py @@ -79,8 +79,6 @@ class TDTestCase: tdSql.checkData(0, 0, 8) tdSql.query("select count(*) from db.stb") tdSql.checkData(0, 0, 40) - tdSql.query("select distinct(c1) from db.stb") - tdSql.checkData(0, 0, None) tdSql.query("select distinct(c3) from db.stb") tdSql.checkData(0, 0, None) tdSql.query("select distinct(c4) from db.stb") diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 2174437f31..c2c462324e 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -1,4 +1,5 @@ # 20,,pytest,python3 insert/retentionpolicy.py change date time +500,,docs-examples-test,./test_node.sh 299,,pytest,python3 test.py -f update/merge_commit_data-0.py 290,,pytest,python3 test.py -f update/merge_commit_data.py 241,,pytest,python3 test.py -f update/merge_commit_data2.py @@ -236,6 +237,7 @@ 30,,script,./test.sh -f general/import/commit.sim 30,,script,./test.sh -f general/compute/diff2.sim 30,,develop-test,bash 3-connectors/R/test.sh +30,,develop-test,bash 3-connectors/c#/test.sh 29,,system-test,python3 ./test.py -f 0-others/create_col_tag.py 29,,script,./test.sh -f unique/arbitrator/dn3_mn1_full_createTableFail.sim 29,,script,./test.sh -f general/wal/maxtables.sim @@ -592,7 +594,6 @@ 8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py 8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py 8,,pytest,python3 test.py -f update/update2.py -7,,docs-examples-test,./test_node.sh 7,,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonSml-otherPara.py 7,,pytest,python3 test.py -f tools/taosdumpTest2.py 7,,pytest,python3 test.py -f tools/taosdemoTestdatatype.py @@ -813,6 +814,8 @@ 3,,pytest,python3 test.py -f table/columnNameValidation.py 3,,pytest,python3 test.py -f table/tagNameCaseSensitive.py 3,,pytest,python3 test.py -f table/tbNameCaseSensitive.py +3,,pytest,python3 test.py -f functions/function_max_row.py +3,,pytest,python3 test.py -f functions/function_min_row.py 3,,develop-test,python3 ./test.py -f 2-query/ts_hidden_column.py 3,,develop-test,python3 ./test.py -f 2-query/ts_shortcut.py 3,,develop-test,python3 ./test.py -f 2-query/nchar_funcs.py diff --git a/tests/pytest/functions/function_max_row.py b/tests/pytest/functions/function_max_row.py new file mode 100644 index 0000000000..7ffa9858b9 --- /dev/null +++ b/tests/pytest/functions/function_max_row.py @@ -0,0 +1,84 @@ +################################################################### +# 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 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +import numpy as np + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + self.rowNum = 10 + self.tables = 10 + self.ts = 1537146000000 + + def run(self): + tdSql.prepare() + + intData = [] + floatData = [] + + tdSql.execute("create table stb (ts timestamp, c1 int, c2 double, c3 float) tags(t1 int)") + for i in range(self.tables): + tdSql.execute("create table tb%d using stb tags(%d)" % (i, i)) + sql = "insert into tb%d values" % i + for j in range(self.rowNum): + sql += "(%d, %d, %f, %f)" % (self.ts + j * 3000, j, j + 0.1, j + 0.1) + intData.append(j) + floatData.append(j + 0.1) + tdSql.execute(sql) + + tdSql.error("select max_row(ts) from stb") + tdSql.error("select max_row(t1) from stb") + + tdSql.query("select max_row(c1) from stb") + tdSql.checkData(0, 0, np.max(intData)) + + tdSql.query("select max_row(c1), * from stb") + tdSql.checkData(0, 0, np.max(intData)) + tdSql.checkData(0, 2, np.max(intData)) + tdSql.checkData(0, 3, np.max(floatData)) + tdSql.checkData(0, 4, np.max(floatData)) + + tdSql.query("select max_row(c1), * from stb group by tbname") + for i in range(self.tables): + tdSql.checkData(i, 0, np.max(intData)) + tdSql.checkData(i, 2, np.max(intData)) + tdSql.checkData(i, 3, np.max(floatData)) + tdSql.checkData(i, 4, np.max(floatData)) + + tdSql.query("select max_row(c1), * from stb interval(6s)") + tdSql.checkRows(5) + + tdSql.query("select max_row(c1), * from tb1 interval(6s)") + tdSql.checkRows(5) + + tdSql.query("select max_row(c1), * from stb interval(6s) group by tbname") + tdSql.checkRows(50) + + tdSql.query("select max_row(c1), * from (select min_row(c1) c1, * from stb group by tbname)") + tdSql.checkData(0, 0, np.min(intData)) + tdSql.checkRows(1) + + 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 diff --git a/tests/pytest/functions/function_min_row.py b/tests/pytest/functions/function_min_row.py new file mode 100644 index 0000000000..9acc0eee5b --- /dev/null +++ b/tests/pytest/functions/function_min_row.py @@ -0,0 +1,84 @@ +################################################################### +# 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 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +import numpy as np + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + self.rowNum = 10 + self.tables = 10 + self.ts = 1537146000000 + + def run(self): + tdSql.prepare() + + intData = [] + floatData = [] + + tdSql.execute("create table stb (ts timestamp, c1 int, c2 double, c3 float) tags(t1 int)") + for i in range(self.tables): + tdSql.execute("create table tb%d using stb tags(%d)" % (i, i)) + sql = "insert into tb%d values" % i + for j in range(self.rowNum): + sql += "(%d, %d, %f, %f)" % (self.ts + j * 3000, j, j + 0.1, j + 0.1) + intData.append(j) + floatData.append(j + 0.1) + tdSql.execute(sql) + + tdSql.error("select min_row(ts) from stb") + tdSql.error("select min_row(t1) from stb") + + tdSql.query("select min_row(c1) from stb") + tdSql.checkData(0, 0, np.min(intData)) + + tdSql.query("select min_row(c1), * from stb") + tdSql.checkData(0, 0, np.min(intData)) + tdSql.checkData(0, 2, np.min(intData)) + tdSql.checkData(0, 3, np.min(floatData)) + tdSql.checkData(0, 4, np.min(floatData)) + + tdSql.query("select min_row(c1), * from stb group by tbname") + for i in range(self.tables): + tdSql.checkData(i, 0, np.min(intData)) + tdSql.checkData(i, 2, np.min(intData)) + tdSql.checkData(i, 3, np.min(floatData)) + tdSql.checkData(i, 4, np.min(floatData)) + + tdSql.query("select min_row(c1), * from stb interval(6s)") + tdSql.checkRows(5) + + tdSql.query("select min_row(c1), * from tb1 interval(6s)") + tdSql.checkRows(5) + + tdSql.query("select min_row(c1), * from stb interval(6s) group by tbname") + tdSql.checkRows(50) + + tdSql.query("select min_row(c1), * from (select max_row(c1) c1, * from stb group by tbname)") + tdSql.checkData(0, 0, np.max(intData)) + tdSql.checkRows(1) + + 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 diff --git a/tests/pytest/query/nestedQuery/nestedQuery.py b/tests/pytest/query/nestedQuery/nestedQuery.py index 89751bb7b8..9f9f56660c 100755 --- a/tests/pytest/query/nestedQuery/nestedQuery.py +++ b/tests/pytest/query/nestedQuery/nestedQuery.py @@ -2233,10 +2233,10 @@ class TDTestCase: sql = "select * from ( select ts , " for i in range(4094): sql += "c%d , " % (i) - sql += "c4094 from d0 " + sql += "c4094 from d0 " sql += " %s )" % random.choice(order_where) sql += " %s ;" % random.choice(order_desc_where) - tdLog.info(len(sql)) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkCols(4096) tdSql.checkRows(1000) diff --git a/tests/pytest/query/queryBase.py b/tests/pytest/query/queryBase.py index 4544fab3ad..9be950df49 100644 --- a/tests/pytest/query/queryBase.py +++ b/tests/pytest/query/queryBase.py @@ -171,6 +171,11 @@ class TDTestCase: tdSql.waitedQuery(sql, 1, WAITS) tdSql.checkData(0, 1, 229400) + # TS-1664 + tdSql.error("create database string") + tdSql.error("create table string(ts timestamp, c1 int)") + tdSql.error("select * from string") + # # add case with filename # diff --git a/tests/pytest/query/queryError.py b/tests/pytest/query/queryError.py index e5c468600b..7d752a9863 100644 --- a/tests/pytest/query/queryError.py +++ b/tests/pytest/query/queryError.py @@ -68,6 +68,16 @@ class TDTestCase: # TD-6006 tdSql.error("select * from dev_001 where 'name' is not null") tdSql.error("select * from dev_001 where \"name\" = 'first'") + + # TS-1577 + tdSql.query("show databases") + rows = tdSql.queryRows + + for i in range(1000): + tdSql.execute("create database test%d" % i) + + tdSql.query("show databases") + tdSql.checkRows(rows + 1000) def stop(self): tdSql.close() diff --git a/tests/pytest/table/tagNameCaseSensitive.py b/tests/pytest/table/tagNameCaseSensitive.py index ebd7f55a2d..c9ee64fa24 100644 --- a/tests/pytest/table/tagNameCaseSensitive.py +++ b/tests/pytest/table/tagNameCaseSensitive.py @@ -65,7 +65,7 @@ class TDTestCase: tdSql.query("select * from `STB6`") tdSql.checkRows(6) - tdSql.execute("delete from `STB6` where ` ` = 1 and ts = '2022-06-24 11:17:31.000'") + tdSql.execute("delete from `STB6` where ` ` = 1 and ts = 1656040651000") tdSql.checkAffectedRows(1) tdSql.query("select * from `STB6`") tdSql.checkRows(5) @@ -74,6 +74,10 @@ class TDTestCase: tdSql.query("select * from `STB6`") tdSql.checkRows(2) + tdSql.execute("alter table `STB6` add tag `1` int") + tdSql.execute("create table t1 using `STB6`(`1`) tags(1)") + tdSql.error("alter table t1 set tag 1=2222") + tdSql.error("alter table `STB6` add tag `` nchar(20)") def stop(self): @@ -82,4 +86,4 @@ class TDTestCase: tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py index c047e4b0aa..667b859c8f 100755 --- a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py +++ b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py @@ -56,18 +56,18 @@ class TDTestCase: tdSql.execute("use regular_old") tdSql.query("show tables;") tdSql.checkRows(1) - tdSql.query("select * from d0;") + tdSql.query("select * from meters;") tdSql.checkCols(1024) - tdSql.query("describe d0;") + tdSql.query("describe meters;") tdSql.checkRows(1024) os.system("%s -N -d regular_new -t 1 -n 10 -l 4095 -y" % binPath) tdSql.execute("use regular_new") tdSql.query("show tables;") tdSql.checkRows(1) - tdSql.query("select * from d0;") + tdSql.query("select * from meters;") tdSql.checkCols(4096) - tdSql.query("describe d0;") + tdSql.query("describe meters;") tdSql.checkRows(4096) # super table -d:database name -t:table num -n:rows num per table diff --git a/tests/pytest/tools/taosdumpTest.py b/tests/pytest/tools/taosdumpTest.py index 2155556776..95ed69b917 100644 --- a/tests/pytest/tools/taosdumpTest.py +++ b/tests/pytest/tools/taosdumpTest.py @@ -60,6 +60,13 @@ class TDTestCase: else: print("directory exists") + for i in range(1, 9): + if not os.path.exists("./taosdumptest/tmp%d" % i): + os.makedirs("./taosdumptest/tmp%d" % i) + else: + os.system("rm -rf ./taosdumptest/tmp%d" % i) + os.makedirs("./taosdumptest/tmp%d" % i) + if not os.path.exists("./taosdumptest/tmp2"): os.makedirs("./taosdumptest/tmp2") tdSql.execute("drop database if exists db") diff --git a/tests/pytest/tools/taosdumpTest3.py b/tests/pytest/tools/taosdumpTest3.py index 3994ad0323..e8fb46f3a8 100644 --- a/tests/pytest/tools/taosdumpTest3.py +++ b/tests/pytest/tools/taosdumpTest3.py @@ -57,6 +57,9 @@ class TDTestCase: def run(self): if not os.path.exists("./taosdumptest"): os.makedirs("./taosdumptest") + else: + print("directory exists") + for i in range(1, 9): if not os.path.exists("./taosdumptest/tmp%d" % i): os.makedirs("./taosdumptest/tmp%d" % i) diff --git a/tests/script/unique/account/paras.sim b/tests/script/unique/account/paras.sim index 102f5b6a38..77e010f5bd 100644 --- a/tests/script/unique/account/paras.sim +++ b/tests/script/unique/account/paras.sim @@ -17,7 +17,7 @@ endi if $data02 != 3/128 then return -1 endi -if $data03 != 0/128 then +if $data03 != 0/32767 then return -1 endi if $data04 != 0/2147483647 then @@ -111,4 +111,4 @@ if $data16 != 0.000/10.000 then return -1 endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insert4096columns_not_use_taosdemo.py b/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insert4096columns_not_use_taosdemo.py deleted file mode 100644 index ec55acb848..0000000000 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insert4096columns_not_use_taosdemo.py +++ /dev/null @@ -1,706 +0,0 @@ -################################################################### -# 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 -*- - -import random -import string -import os -import time -from util.log import tdLog -from util.cases import tdCases -from util.sql import tdSql -from util.dnodes import tdDnodes - -class TDTestCase: - updatecfgDict={'maxSQLLength':1048576} - def init(self, conn, logSql): - tdLog.debug("start to execute %s" % __file__) - tdSql.init(conn.cursor(), logSql) - - os.system("rm -rf tools/taosdemoAllTest/TD-5213/insert4096columns_not_use_taosdemo.py.sql") - - now = time.time() - self.ts = int(round(now * 1000)) - self.num = 100 - - def get_random_string(self, length): - letters = string.ascii_lowercase - result_str = ''.join(random.choice(letters) for i in range(length)) - return result_str - - def run(self): - tdSql.prepare() - # test case for https://jira.taosdata.com:18080/browse/TD-5213 - - print("==============step1, regular table, 1 ts + 4094 cols + 1 binary==============") - startTime = time.time() - sql = "create table regular_table_1(ts timestamp, " - for i in range(4094): - sql += "col%d int, " % (i + 1) - sql += "col4095 binary(22))" - tdLog.info(len(sql)) - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into regular_table_1 values(%d, " - for j in range(4094): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_1") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from regular_table_1") - tdSql.checkRows(self.num) - tdSql.checkCols(4096) - - endTime = time.time() - print("total time %ds" % (endTime - startTime)) - - #insert in order - tdLog.info('test insert in order') - for i in range(self.num): - sql = "insert into regular_table_1 (ts,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col4095) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 1000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_1") - tdSql.checkData(0, 0, 2*self.num) - tdSql.query("select * from regular_table_1") - tdSql.checkRows(2*self.num) - tdSql.checkCols(4096) - - #insert out of order - tdLog.info('test insert out of order') - for i in range(self.num): - sql = "insert into regular_table_1 (ts,col123,col2213,col331,col41,col523,col236,col71,col813,col912,col1320,col4095) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 2000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_1") - tdSql.checkData(0, 0, 3*self.num) - tdSql.query("select * from regular_table_1") - tdSql.checkRows(3*self.num) - tdSql.checkCols(4096) - - - print("==============step2,regular table error col or value==============") - tdLog.info('test regular table exceeds row num') - # column > 4096 - sql = "create table regular_table_2(ts timestamp, " - for i in range(4095): - sql += "col%d int, " % (i + 1) - sql += "col4096 binary(22))" - tdLog.info(len(sql)) - tdSql.error(sql) - - # column > 4096 - sql = "insert into regular_table_1 values(%d, " - for j in range(4095): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.error(sql) - - # insert column < 4096 - sql = "insert into regular_table_1 values(%d, " - for j in range(4092): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.error(sql) - - # alter column > 4096 - sql = "alter table regular_table_1 add column max int; " - tdSql.error(sql) - - print("==============step3,regular table , mix data type==============") - startTime = time.time() - sql = "create table regular_table_3(ts timestamp, " - for i in range(2000): - sql += "col%d int, " % (i + 1) - for i in range(2000,4094): - sql += "col%d bigint, " % (i + 1) - sql += "col4095 binary(22))" - tdLog.info(len(sql)) - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into regular_table_3 values(%d, " - for j in range(4094): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_3") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from regular_table_3") - tdSql.checkRows(self.num) - tdSql.checkCols(4096) - - endTime = time.time() - print("total time %ds" % (endTime - startTime)) - - sql = "create table regular_table_4(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(4), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(10), " % (i + 1) - for i in range(4090,4094): - sql += "timestamp_%d timestamp, " % (i + 1) - sql += "col4095 binary(22))" - tdLog.info(len(sql)) - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into regular_table_4 values(%d, " - for j in range(500): - str = "'%s', " % random.randint(-2147483647,2147483647) - sql += str - for j in range(500,1000): - str = "'%s', " % random.randint(-32767,32767 ) - sql += str - for j in range(1000,1500): - str = "'%s', " % random.randint(-127,127) - sql += str - for j in range(1500,2000): - str = "'%s', " % random.randint(-922337203685477580700,922337203685477580700) - sql += str - for j in range(2000,2500): - str = "'%s', " % random.randint(-92233720368547758070,92233720368547758070) - sql += str - for j in range(2500,3000): - str = "'%s', " % random.choice(['true','false']) - sql += str - for j in range(3000,3500): - str = "'%s', " % random.randint(-9223372036854775807,9223372036854775807) - sql += str - for j in range(3500,3800): - str = "'%s', " % self.get_random_string(4) - sql += str - for j in range(3800,4090): - str = "'%s', " % self.get_random_string(10) - sql += str - for j in range(4090,4094): - str = "%s, " % (self.ts + j) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_4") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from regular_table_4") - tdSql.checkRows(self.num) - tdSql.checkCols(4096) - tdLog.info("end ,now new one") - - #insert null value - tdLog.info('test insert null value') - for i in range(self.num): - sql = "insert into regular_table_4 values(%d, " - for j in range(2500): - str = "'%s', " % random.choice(['NULL' ,'NULL' ,'NULL' ,1 , 10 ,100 ,-100 ,-10, 88 ,66 ,'NULL' ,'NULL' ,'NULL' ]) - sql += str - for j in range(2500,3000): - str = "'%s', " % random.choice(['true' ,'false']) - sql += str - for j in range(3000,3500): - str = "'%s', " % random.randint(-9223372036854775807,9223372036854775807) - sql += str - for j in range(3500,3800): - str = "'%s', " % self.get_random_string(4) - sql += str - for j in range(3800,4090): - str = "'%s', " % self.get_random_string(10) - sql += str - for j in range(4090,4094): - str = "%s, " % (self.ts + j) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 10000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_4") - tdSql.checkData(0, 0, 2*self.num) - tdSql.query("select * from regular_table_4") - tdSql.checkRows(2*self.num) - tdSql.checkCols(4096) - - #insert in order - tdLog.info('test insert in order') - for i in range(self.num): - sql = "insert into regular_table_4 (ts,int_2,int_22,int_169,smallint_537,smallint_607,tinyint_1030,tinyint_1491,double_1629,double_1808,float_2075,col4095) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,100) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 1000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_4") - tdSql.checkData(0, 0, 3*self.num) - tdSql.query("select * from regular_table_4") - tdSql.checkRows(3*self.num) - tdSql.checkCols(4096) - - #insert out of order - tdLog.info('test insert out of order') - for i in range(self.num): - sql = "insert into regular_table_4 (ts,int_169,float_2075,int_369,tinyint_1491,tinyint_1030,float_2360,smallint_537,double_1808,double_1608,double_1629,col4095) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,100) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 2000)) - time.sleep(1) - tdSql.query("select count(*) from regular_table_4") - tdSql.checkData(0, 0, 4*self.num) - tdSql.query("select * from regular_table_4") - tdSql.checkRows(4*self.num) - tdSql.checkCols(4096) - - #define TSDB_MAX_BYTES_PER_ROW 49151[old:1024 && 16384] - #ts:8\int:4\smallint:2\bigint:8\bool:1\float:4\tinyint:1\nchar:4*()+2[offset]\binary:1*()+2[offset] - tdLog.info('test regular_table max bytes per row 49151') - sql = "create table regular_table_5(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(20), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(34), " % (i + 1) - for i in range(4090,4094): - sql += "timestamp_%d timestamp, " % (i + 1) - sql += "col4095 binary(69))" - tdSql.execute(sql) - tdSql.query("select * from regular_table_5") - tdSql.checkCols(4096) - # TD-5324 - sql = "alter table regular_table_5 modify column col4095 binary(70); " - tdSql.error(sql) - - # drop and add - sql = "alter table regular_table_5 drop column col4095; " - tdSql.execute(sql) - sql = "select * from regular_table_5; " - tdSql.query(sql) - tdSql.checkCols(4095) - sql = "alter table regular_table_5 add column col4095 binary(70); " - tdSql.error(sql) - sql = "alter table regular_table_5 add column col4095 binary(69); " - tdSql.execute(sql) - sql = "select * from regular_table_5; " - tdSql.query(sql) - tdSql.checkCols(4096) - - #out TSDB_MAX_BYTES_PER_ROW 49151 - tdLog.info('test regular_table max bytes per row out 49151') - sql = "create table regular_table_6(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(20), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(34), " % (i + 1) - for i in range(4090,4094): - sql += "timestamp_%d timestamp, " % (i + 1) - sql += "col4095 binary(70))" - tdLog.info(len(sql)) - tdSql.error(sql) - - - print("==============step4, super table , 1 ts + 4090 cols + 4 tags ==============") - startTime = time.time() - sql = "create stable stable_1(ts timestamp, " - for i in range(4090): - sql += "col%d int, " % (i + 1) - sql += "col4091 binary(22))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdLog.info(len(sql)) - tdSql.execute(sql) - sql = '''create table table_0 using stable_1 - tags('table_0' , '1' , '2' , '3' );''' - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into table_0 values(%d, " - for j in range(4090): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from table_0") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from table_0") - tdSql.checkRows(self.num) - tdSql.checkCols(4092) - - sql = '''create table table_1 using stable_1 - tags('table_1' , '1' , '2' , '3' );''' - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into table_1 values(%d, " - for j in range(2080): - sql += "'%d', " % random.randint(0,1000) - for j in range(2080,4080): - sql += "'%s', " % 'NULL' - for j in range(4080,4090): - sql += "'%s', " % random.randint(0,10000) - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from table_1") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from table_1") - tdSql.checkRows(self.num) - tdSql.checkCols(4092) - - endTime = time.time() - print("total time %ds" % (endTime - startTime)) - - #insert in order - tdLog.info('test insert in order') - for i in range(self.num): - sql = "insert into table_1 (ts,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col4091) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 1000)) - time.sleep(1) - tdSql.query("select count(*) from table_1") - tdSql.checkData(0, 0, 2*self.num) - tdSql.query("select * from table_1") - tdSql.checkRows(2*self.num) - tdSql.checkCols(4092) - - #insert out of order - tdLog.info('test insert out of order') - for i in range(self.num): - sql = "insert into table_1 (ts,col123,col2213,col331,col41,col523,col236,col71,col813,col912,col1320,col4091) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,1000) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 2000)) - time.sleep(1) - tdSql.query("select count(*) from table_1") - tdSql.checkData(0, 0, 3*self.num) - tdSql.query("select * from table_1") - tdSql.checkRows(3*self.num) - tdSql.checkCols(4092) - - print("==============step5,stable table , mix data type==============") - sql = "create stable stable_3(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(4), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(10), " % (i + 1) - sql += "col4091 binary(22))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdLog.info(len(sql)) - tdSql.execute(sql) - sql = '''create table table_30 using stable_3 - tags('table_30' , '1' , '2' , '3' );''' - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into table_30 values(%d, " - for j in range(500): - str = "'%s', " % random.randint(-2147483647,2147483647) - sql += str - for j in range(500,1000): - str = "'%s', " % random.randint(-32767,32767 ) - sql += str - for j in range(1000,1500): - str = "'%s', " % random.randint(-127,127) - sql += str - for j in range(1500,2000): - str = "'%s', " % random.randint(-922337203685477580700,922337203685477580700) - sql += str - for j in range(2000,2500): - str = "'%s', " % random.randint(-92233720368547758070,92233720368547758070) - sql += str - for j in range(2500,3000): - str = "'%s', " % random.choice(['true','false']) - sql += str - for j in range(3000,3500): - str = "'%s', " % random.randint(-9223372036854775807,9223372036854775807) - sql += str - for j in range(3500,3800): - str = "'%s', " % self.get_random_string(4) - sql += str - for j in range(3800,4090): - str = "'%s', " % self.get_random_string(10) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from table_30") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from table_30") - tdSql.checkRows(self.num) - tdSql.checkCols(4092) - - #insert null value - tdLog.info('test insert null value') - sql = '''create table table_31 using stable_3 - tags('table_31' , '1' , '2' , '3' );''' - tdSql.execute(sql) - - for i in range(self.num): - sql = "insert into table_31 values(%d, " - for j in range(2500): - str = "'%s', " % random.choice(['NULL' ,'NULL' ,'NULL' ,1 , 10 ,100 ,-100 ,-10, 88 ,66 ,'NULL' ,'NULL' ,'NULL' ]) - sql += str - for j in range(2500,3000): - str = "'%s', " % random.choice(['true' ,'false']) - sql += str - for j in range(3000,3500): - str = "'%s', " % random.randint(-9223372036854775807,9223372036854775807) - sql += str - for j in range(3500,3800): - str = "'%s', " % self.get_random_string(4) - sql += str - for j in range(3800,4090): - str = "'%s', " % self.get_random_string(10) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i)) - time.sleep(1) - tdSql.query("select count(*) from table_31") - tdSql.checkData(0, 0, self.num) - tdSql.query("select * from table_31") - tdSql.checkRows(self.num) - tdSql.checkCols(4092) - - #insert in order - tdLog.info('test insert in order') - for i in range(self.num): - sql = "insert into table_31 (ts,int_2,int_22,int_169,smallint_537,smallint_607,tinyint_1030,tinyint_1491,double_1629,double_1808,float_2075,col4091) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,100) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 1000)) - time.sleep(1) - tdSql.query("select count(*) from table_31") - tdSql.checkData(0, 0, 2*self.num) - tdSql.query("select * from table_31") - tdSql.checkRows(2*self.num) - tdSql.checkCols(4092) - - #insert out of order - tdLog.info('test insert out of order') - for i in range(self.num): - sql = "insert into table_31 (ts,int_169,float_2075,int_369,tinyint_1491,tinyint_1030,float_2360,smallint_537,double_1808,double_1608,double_1629,col4091) values(%d, " - for j in range(10): - str = "'%s', " % random.randint(0,100) - sql += str - sql += "'%s')" % self.get_random_string(22) - tdSql.execute(sql % (self.ts + i + 2000)) - time.sleep(1) - tdSql.query("select count(*) from table_31") - tdSql.checkData(0, 0, 3*self.num) - tdSql.query("select * from table_31") - tdSql.checkRows(3*self.num) - tdSql.checkCols(4092) - - #define TSDB_MAX_BYTES_PER_ROW 49151 TSDB_MAX_TAGS_LEN 16384 - #ts:8\int:4\smallint:2\bigint:8\bool:1\float:4\tinyint:1\nchar:4*()+2[offset]\binary:1*()+2[offset] - tdLog.info('test super table max bytes per row 49151') - sql = "create table stable_4(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(20), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(34), " % (i + 1) - sql += "col4091 binary(101))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdSql.execute(sql) - sql = '''create table table_40 using stable_4 - tags('table_40' , '1' , '2' , '3' );''' - tdSql.execute(sql) - tdSql.query("select * from table_40") - tdSql.checkCols(4092) - tdSql.query("describe table_40") - tdSql.checkRows(4096) - - tdLog.info('test super table drop and add column or tag') - sql = "alter stable stable_4 drop column col4091; " - tdSql.execute(sql) - sql = "select * from stable_4; " - tdSql.query(sql) - tdSql.checkCols(4095) - sql = "alter table stable_4 add column col4091 binary(102); " - tdSql.error(sql) - sql = "alter table stable_4 add column col4091 binary(101); " - tdSql.execute(sql) - sql = "select * from stable_4; " - tdSql.query(sql) - tdSql.checkCols(4096) - - sql = "alter stable stable_4 drop tag tag_1; " - tdSql.execute(sql) - sql = "select * from stable_4; " - tdSql.query(sql) - tdSql.checkCols(4095) - sql = "alter table stable_4 add tag tag_1 int; " - tdSql.execute(sql) - sql = "select * from stable_4; " - tdSql.query(sql) - tdSql.checkCols(4096) - sql = "alter table stable_4 add tag loc1 nchar(10); " - tdSql.error(sql) - - tdLog.info('test super table max bytes per row 49151') - sql = "create table stable_5(ts timestamp, " - for i in range(500): - sql += "int_%d int, " % (i + 1) - for i in range(500,1000): - sql += "smallint_%d smallint, " % (i + 1) - for i in range(1000,1500): - sql += "tinyint_%d tinyint, " % (i + 1) - for i in range(1500,2000): - sql += "double_%d double, " % (i + 1) - for i in range(2000,2500): - sql += "float_%d float, " % (i + 1) - for i in range(2500,3000): - sql += "bool_%d bool, " % (i + 1) - for i in range(3000,3500): - sql += "bigint_%d bigint, " % (i + 1) - for i in range(3500,3800): - sql += "nchar_%d nchar(20), " % (i + 1) - for i in range(3800,4090): - sql += "binary_%d binary(34), " % (i + 1) - sql += "col4091 binary(102))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdSql.error(sql) - - print("==============step6, super table error col ==============") - tdLog.info('test exceeds row num') - # column + tag > 4096 - sql = "create stable stable_2(ts timestamp, " - for i in range(4091): - sql += "col%d int, " % (i + 1) - sql += "col4092 binary(22))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int) " - tdLog.info(len(sql)) - tdSql.error(sql) - - # column + tag > 4096 - sql = "create stable stable_2(ts timestamp, " - for i in range(4090): - sql += "col%d int, " % (i + 1) - sql += "col4091 binary(22))" - sql += " tags (loc nchar(10),tag_1 int,tag_2 int,tag_3 int,tag_4 int) " - tdLog.info(len(sql)) - tdSql.error(sql) - - # alter column + tag > 4096 - sql = "alter table stable_1 add column max int; " - tdSql.error(sql) - # TD-5322 - sql = "alter table stable_1 add tag max int; " - tdSql.error(sql) - # TD-5324 - sql = "alter table stable_4 modify column col4091 binary(102); " - tdSql.error(sql) - sql = "alter table stable_4 modify tag loc nchar(20); " - tdSql.query("select * from table_40") - tdSql.checkCols(4092) - tdSql.query("describe table_40") - tdSql.checkRows(4096) - - - - - def stop(self): - tdSql.close() - tdLog.success("%s successfully executed" % __file__) - - -tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv b/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv deleted file mode 100755 index 5b30be5b4c..0000000000 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv +++ /dev/null @@ -1,3 +0,0 @@ -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438, 2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2449, 2450, 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, 2494, 2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2527, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, 2544, 2545, 2546, 2547, 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, 2583, 2584, 2585, 2586, 2587, 2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595, 2596, 2597, 2598, 2599, 2600, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2634, 2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643, 2644, 2645, 2646, 2647, 2648, 2649, 2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, 2715, 2716, 2717, 2718, 2719, 2720, 2721, 2722, 2723, 2724, 2725, 2726, 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734, 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, 2768, 2769, 2770, 2771, 2772, 2773, 2774, 2775, 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826, 2827, 2828, 2829, 2830, 2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887, 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, 2941, 2942, 2943, 2944, 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, 2963, 2964, 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999, 3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043, 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3077, 3078, 3079, 3080, 3081, 3082, 3083, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, 3095, 3096, 3097, 3098, 3099, 3100, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111, 3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, 3143, 3144, 3145, 3146, 3147, 3148, 3149, 3150, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183, 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213, 3214, 3215, 3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, 3238, 3239, 3240, 3241, 3242, 3243, 3244, 3245, 3246, 3247, 3248, 3249, 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3304, 3305, 3306, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357, 3358, 3359, 3360, 3361, 3362, 3363, 3364, 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, 3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438, 3439, 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, 3455, 3456, 3457, 3458, 3459, 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469, 3470, 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3478, 3479, 3480, 3481, 3482, 3483, 3484, 3485, 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494, 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518, 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532, 3533, 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, 3553, 3554, 3555, 3556, 3557, 3558, 3559, 3560, 3561, 3562, 3563, 3564, 3565, 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574, 3575, 3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680, 3681, 3682, 3683, 3684, 3685, 3686, 3687, 3688, 3689, 3690, 3691, 3692, 3693, 3694, 3695, 3696, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, 3705, 3706, 3707, 3708, 3709, 3710, 3711, 3712, 3713, 3714, 3715, 3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723, 3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3744, 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835, 3836, 3837, 3838, 3839, 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894, 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3904, 3905, 3906, 3907, 3908, 3909, 3910, 3911, 3912, 3913, 3914, 3915, 3916, 3917, 3918, 3919, 3920, 3921, 3922, 3923, 3924, 3925, 3926, 3927, 3928, 3929, 3930, 3931, 3932, 3933, 3934, 3935, 3936, 3937, 3938, 3939, 3940, 3941, 3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949, 3950, 3951, 3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, 3970, 3971, 3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979, 3980, 3981, 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, 3990, 3991, 3992, 3993, 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091 -1,2,3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL -1,2,3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,NULL,NULL,5,NULL,NULL,6,NULL,NULL,NULL,7,NULL,NULL,NULL,8,NULL,NULL,NULL,9,NULL,NULL,10 \ No newline at end of file diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.json deleted file mode 100755 index d7225dfd12..0000000000 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "filetype": "insert", - "cfgdir": "/etc/taos", - "host": "127.0.0.1", - "port": 6030, - "user": "root", - "password": "taosdata", - "thread_count": 10, - "thread_count_create_tbl": 10, - "result_file": "./insert_res.txt", - "confirm_parameter_prompt": "no", - "insert_interval": 0, - "interlace_rows": 10, - "num_of_records_per_req": 1, - "max_sql_len": 102400000, - "databases": [{ - "dbinfo": { - "name": "json_test", - "drop": "yes", - "replica": 1, - "days": 10, - "cache": 50, - "blocks": 8, - "precision": "ms", - "keep": 36500, - "minRows": 100, - "maxRows": 4096, - "comp":2, - "walLevel":1, - "cachelast":0, - "quorum":1, - "fsync":3000, - "update": 0 - }, - "super_tables": [{ - "name": "stb_old", - "child_table_exists":"no", - "childtable_count": 2, - "childtable_prefix": "stb_old_", - "auto_create_table": "no", - "batch_create_tbl_num": 5, - "data_source": "rand", - "insert_mode": "taosc", - "insert_rows": 2, - "childtable_limit": 0, - "childtable_offset":0, - "multi_thread_write_one_tbl": "no", - "interlace_rows": 0, - "insert_interval":0, - "max_sql_len": 1024000, - "disorder_ratio": 0, - "disorder_range": 1000, - "timestamp_step": 1, - "start_timestamp": "2020-10-01 00:00:00.000", - "sample_format": "csv", - "sample_file": "./5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv", - "tags_file": "", - "columns": [{"type": "INT","count":1000}, {"type": "BINARY", "len": 16, "count":20}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}] - },{ - "name": "stb_new", - "child_table_exists":"no", - "childtable_count": 2, - "childtable_prefix": "stb_new_", - "auto_create_table": "no", - "batch_create_tbl_num": 5, - "data_source": "rand", - "insert_mode": "taosc", - "insert_rows": 2, - "childtable_limit": 0, - "childtable_offset":0, - "multi_thread_write_one_tbl": "no", - "interlace_rows": 0, - "insert_interval":0, - "max_sql_len": 1024000, - "disorder_ratio": 0, - "disorder_range": 1000, - "timestamp_step": 1, - "start_timestamp": "2020-10-01 00:00:00.000", - "sample_format": "csv", - "sample_file": "./5-taos-tools/taosbenchmark/sample.csv", - "tags_file": "", - "columns": [{"type": "INT","count":4000}, {"type": "BINARY", "len": 16, "count":90}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":3}] - },{ - "name": "stb_mix", - "child_table_exists":"no", - "childtable_count": 2, - "childtable_prefix": "stb_mix_", - "auto_create_table": "no", - "batch_create_tbl_num": 5, - "data_source": "rand", - "insert_mode": "taosc", - "insert_rows": 2, - "childtable_limit": 0, - "childtable_offset":0, - "multi_thread_write_one_tbl": "no", - "interlace_rows": 0, - "insert_interval":0, - "max_sql_len": 1024000, - "disorder_ratio": 0, - "disorder_range": 1000, - "timestamp_step": 1, - "start_timestamp": "2020-10-01 00:00:00.000", - "sample_format": "csv", - "sample_file": "./5-taos-tools/taosbenchmark/sample.csv", - "tags_file": "", - "columns": [{"type": "INT","count":500},{"type": "SMALLINT","count":500},{"type": "TINYINT","count":500},{"type": "DOUBLE","count":500},{"type": "FLOAT","count":500},{"type": "BOOL","count":500},{"type": "BIGINT","count":500},{"type": "NCHAR","len": 20,"count":300},{"type": "BINARY","len": 34,"count":290},{"type": "BINARY","len": 101,"count":1}], - "tags": [{"type": "INT", "count":3}, {"type": "NCHAR", "len": 10, "count":1}] - },{ - "name": "stb_excel", - "child_table_exists":"no", - "childtable_count": 2, - "childtable_prefix": "stb_excel_", - "auto_create_table": "no", - "batch_create_tbl_num": 5, - "data_source": "sample", - "insert_mode": "taosc", - "insert_rows": 2, - "childtable_limit": 0, - "childtable_offset":0, - "multi_thread_write_one_tbl": "no", - "interlace_rows": 0, - "insert_interval":0, - "max_sql_len": 1024000, - "disorder_ratio": 0, - "disorder_range": 1000, - "timestamp_step": 1, - "start_timestamp": "2020-10-01 00:00:00.000", - "sample_format": "csv", - "sample_file": "./5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.csv", - "tags_file": "", - "columns": [{"type": "INT","count":500},{"type": "SMALLINT","count":500},{"type": "SMALLINT","count":500},{"type": "DOUBLE","count":500},{"type": "FLOAT","count":500},{"type": "BOOL","count":500},{"type": "BIGINT","count":500},{"type": "NCHAR","len": 19,"count":300},{"type": "BINARY","len": 34,"count":290},{"type": "BINARY","len": 101,"count":1}], - "tags": [{"type": "INT", "count":3}, {"type": "NCHAR", "len": 10, "count":1}] - }] - }] -} diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.py b/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.py deleted file mode 100755 index 56b51f5498..0000000000 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-5213/insertSigcolumnsNum4096.py +++ /dev/null @@ -1,176 +0,0 @@ -################################################################### -# 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 -*- - -import sys -import os -import time -from util.log import * -from util.cases import * -from util.sql import * -from util.dnodes import * - - -class TDTestCase: - def init(self, conn, logSql): - tdLog.debug("start to execute %s" % __file__) - tdSql.init(conn.cursor(), logSql) - - def getBuildPath(self): - selfPath = os.path.dirname(os.path.realpath(__file__)) - - if ("community" in selfPath): - projPath = selfPath[:selfPath.find("community")] - else: - projPath = selfPath[:selfPath.find("tests")] - - for root, dirs, files in os.walk(projPath): - if ("taosd" in files): - rootRealPath = os.path.dirname(os.path.realpath(root)) - if ("packaging" not in rootRealPath): - buildPath = root[:len(root)-len("/build/bin")] - break - return buildPath - - def run(self): - buildPath = self.getBuildPath() - if (buildPath == ""): - tdLog.exit("taosd not found!") - else: - tdLog.info("taosd found in %s" % buildPath) - binPath = buildPath+ "/build/bin/" - - #-N:regular table -d:database name -t:table num -n:rows num per table -l:col num -y:force - #regular old && new - startTime = time.time() - os.system("%staosBenchmark -N -d regular_old -t 1 -n 10 -l 1023 -y" % binPath) - tdSql.execute("use regular_old") - tdSql.query("show tables;") - tdSql.checkRows(1) - tdSql.query("select * from d0;") - tdSql.checkCols(1024) - tdSql.query("describe d0;") - tdSql.checkRows(1024) - - os.system("%staosBenchmark -N -d regular_new -t 1 -n 10 -l 4095 -y" % binPath) - tdSql.execute("use regular_new") - tdSql.query("show tables;") - tdSql.checkRows(1) - tdSql.query("select * from d0;") - tdSql.checkCols(4096) - tdSql.query("describe d0;") - tdSql.checkRows(4096) - - #super table -d:database name -t:table num -n:rows num per table -l:col num -y:force - os.system("%staosBenchmark -d super_old -t 1 -n 10 -l 1021 -y" % binPath) - tdSql.execute("use super_old") - tdSql.query("show tables;") - tdSql.checkRows(1) - tdSql.query("select * from meters;") - tdSql.checkCols(1024) - tdSql.query("select * from d0;") - tdSql.checkCols(1022) - tdSql.query("describe meters;") - tdSql.checkRows(1024) - tdSql.query("describe d0;") - tdSql.checkRows(1024) - - os.system("%staosBenchmark -d super_new -t 1 -n 10 -l 4093 -y" % binPath) - tdSql.execute("use super_new") - tdSql.query("show tables;") - tdSql.checkRows(1) - tdSql.query("select * from meters;") - tdSql.checkCols(4096) - tdSql.query("select * from d0;") - tdSql.checkCols(4094) - tdSql.query("describe meters;") - tdSql.checkRows(4096) - tdSql.query("describe d0;") - tdSql.checkRows(4096) - tdSql.execute("create table stb_new1_1 using meters tags(1,2)") - tdSql.query("select * from stb_new1_1") - tdSql.checkCols(4094) - tdSql.query("describe stb_new1_1;") - tdSql.checkRows(4096) - - # insert: create one or mutiple tables per sql and insert multiple rows per sql - # test case for https://jira.taosdata.com:18080/browse/TD-5213 - os.system("%staosBenchmark -f tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json -y " % binPath) - tdSql.execute("use json_test") - tdSql.query("select count (tbname) from stb_old") - tdSql.checkData(0, 0, 1) - - tdSql.query("select * from stb_old") - tdSql.checkRows(10) - tdSql.checkCols(1024) - - tdSql.query("select count (tbname) from stb_new") - tdSql.checkData(0, 0, 1) - - tdSql.query("select * from stb_new") - tdSql.checkRows(10) - tdSql.checkCols(4096) - tdSql.query("describe stb_new;") - tdSql.checkRows(4096) - tdSql.query("select * from stb_new_0") - tdSql.checkRows(10) - tdSql.checkCols(4091) - tdSql.query("describe stb_new_0;") - tdSql.checkRows(4096) - tdSql.execute("create table stb_new1_1 using stb_new tags(1,2,3,4,5)") - tdSql.query("select * from stb_new1_1") - tdSql.checkCols(4091) - tdSql.query("describe stb_new1_1;") - tdSql.checkRows(4096) - - tdSql.query("select count (tbname) from stb_mix") - tdSql.checkData(0, 0, 1) - - tdSql.query("select * from stb_mix") - tdSql.checkRows(10) - tdSql.checkCols(4096) - tdSql.query("describe stb_mix;") - tdSql.checkRows(4096) - tdSql.query("select * from stb_mix_0") - tdSql.checkRows(10) - tdSql.checkCols(4092) - tdSql.query("describe stb_mix_0;") - tdSql.checkRows(4096) - - tdSql.query("select count (tbname) from stb_excel") - tdSql.checkData(0, 0, 1) - - tdSql.query("select * from stb_excel") - tdSql.checkRows(10) - tdSql.checkCols(4096) - tdSql.query("describe stb_excel;") - tdSql.checkRows(4096) - tdSql.query("select * from stb_excel_0") - tdSql.checkRows(10) - tdSql.checkCols(4092) - tdSql.query("describe stb_excel_0;") - tdSql.checkRows(4096) - endTime = time.time() - print("total time %ds" % (endTime - startTime)) - - - os.system("rm -rf tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py.sql") - - - - def stop(self): - tdSql.close() - tdLog.success("%s successfully executed" % __file__) - - -tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/tsim/src/simExe.c b/tests/tsim/src/simExe.c index e880f1e446..d1288213c5 100644 --- a/tests/tsim/src/simExe.c +++ b/tests/tsim/src/simExe.c @@ -143,13 +143,13 @@ char *simGetVariable(SScript *script, char *varName, int32_t varLen) { return var->varValue; } -int32_t simExecuteExpression(SScript *script, char *exp) { +int32_t simExecuteExpression(SScript *script, char *expr) { char * op1, *op2, *var1, *var2, *var3, *rest; int32_t op1Len, op2Len, var1Len, var2Len, var3Len, val0, val1; char t0[1024], t1[1024], t2[1024], t3[2048]; int32_t result; - rest = paGetToken(exp, &var1, &var1Len); + rest = paGetToken(expr, &var1, &var1Len); rest = paGetToken(rest, &op1, &op1Len); rest = paGetToken(rest, &var2, &var2Len); rest = paGetToken(rest, &op2, &op2Len); diff --git a/tests/tsim/src/simParse.c b/tests/tsim/src/simParse.c index 1acdcd2ac6..7de2630006 100644 --- a/tests/tsim/src/simParse.c +++ b/tests/tsim/src/simParse.c @@ -251,11 +251,11 @@ SScript *simParseScript(char *fileName) { return script; } -int32_t simCheckExpression(char *exp) { +int32_t simCheckExpression(char *expr) { char * op1, *op2, *op, *rest; int32_t op1Len, op2Len, opLen; - rest = paGetToken(exp, &op1, &op1Len); + rest = paGetToken(expr, &op1, &op1Len); if (op1Len == 0) { sprintf(parseErr, "expression is required"); return -1; @@ -295,10 +295,10 @@ int32_t simCheckExpression(char *exp) { rest = paGetToken(rest, &op, &opLen); - if (opLen == 0) return (int32_t)(rest - exp); + if (opLen == 0) return (int32_t)(rest - expr); /* if it is key word "then" */ - if (strncmp(op, "then", 4) == 0) return (int32_t)(op - exp); + if (strncmp(op, "then", 4) == 0) return (int32_t)(op - expr); rest = paGetToken(rest, &op2, &op2Len); if (op2Len == 0) { @@ -312,7 +312,7 @@ int32_t simCheckExpression(char *exp) { } if (op[0] == '+' || op[0] == '-' || op[0] == '*' || op[0] == '/' || op[0] == '.') { - return (int32_t)(rest - exp); + return (int32_t)(rest - expr); } return -1; diff --git a/tests/tsim/src/simSystem.c b/tests/tsim/src/simSystem.c index 0879e371ef..7569d3fc7d 100644 --- a/tests/tsim/src/simSystem.c +++ b/tests/tsim/src/simSystem.c @@ -43,9 +43,9 @@ char *simParseArbitratorName(char *varName) { char *simParseHostName(char *varName) { static char hostName[140]; - int32_t index = atoi(varName + 8); + int32_t idx = atoi(varName + 8); int32_t port = 7100; - switch (index) { + switch (idx) { case 1: port = 7100; break; -- GitLab From 8a7605929fc07c5a720f38a33eba3611d568d8ff Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sun, 24 Jul 2022 01:19:27 +0000 Subject: [PATCH 221/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index f84cb6e515..9cfa195713 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit f84cb6e51556d8030585128c2b252aa2a6453328 +Subproject commit 9cfa195713d1cae9edf417a8d49bde87dd971016 -- GitLab From 87bb8bc249d861863477a02b4f8c51bda466acc9 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sun, 24 Jul 2022 13:22:26 +0800 Subject: [PATCH 222/380] feat: update taostools for2.6 (#15367) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index f84cb6e515..9cfa195713 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit f84cb6e51556d8030585128c2b252aa2a6453328 +Subproject commit 9cfa195713d1cae9edf417a8d49bde87dd971016 -- GitLab From daa4943f4e46a342e5c6159e752b4f576d209d28 Mon Sep 17 00:00:00 2001 From: cpvmrd Date: Mon, 25 Jul 2022 14:44:33 +0800 Subject: [PATCH 223/380] Update index.md Modify inaccurate statements --- docs/zh/12-taos-sql/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/12-taos-sql/index.md b/docs/zh/12-taos-sql/index.md index cb01b3a918..36cc20bd3b 100644 --- a/docs/zh/12-taos-sql/index.md +++ b/docs/zh/12-taos-sql/index.md @@ -5,7 +5,7 @@ description: "TAOS SQL 支持的语法规则、主要查询功能、支持的 SQ 本文档说明 TAOS SQL 支持的语法规则、主要查询功能、支持的 SQL 查询函数,以及常用技巧等内容。阅读本文档需要读者具有基本的 SQL 语言的基础。 -TAOS SQL 是用户对 TDengine 进行数据写入和查询的主要工具。TAOS SQL 为了便于用户快速上手,在一定程度上提供与标准 SQL 类似的风格和模式。严格意义上,TAOS SQL 并不是也不试图提供标准的 SQL 语法。此外,由于 TDengine 针对的时序性结构化数据不提供删除功能,因此在 TAO SQL 中不提供数据删除的相关功能。 +TAOS SQL 是用户对 TDengine 进行数据写入和查询的主要工具。TAOS SQL 为了便于用户快速上手,在一定程度上提供与标准 SQL 类似的风格和模式。严格意义上,TAOS SQL 并不是也不试图提供标准的 SQL 语法。此外,由于 TDengine 没有提供时序数据的删除功能,因此 TAOS SQL 中也没有提供数据删除的相关功能。不过从 TDengine 企业版从 2.6 开始提供了 DELETE 语句。 本章节 SQL 语法遵循如下约定: -- GitLab From d4d97738a78e7a5696c565a61c91adb420946f22 Mon Sep 17 00:00:00 2001 From: cpvmrd Date: Mon, 25 Jul 2022 14:54:54 +0800 Subject: [PATCH 224/380] Update index.md add the description about delete statement. --- docs/en/12-taos-sql/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/12-taos-sql/index.md b/docs/en/12-taos-sql/index.md index 33656338a7..1d1cb04ad4 100644 --- a/docs/en/12-taos-sql/index.md +++ b/docs/en/12-taos-sql/index.md @@ -5,7 +5,7 @@ description: "The syntax supported by TDengine SQL " This section explains the syntax of SQL to perform operations on databases, tables and STables, insert data, select data and use functions. We also provide some tips that can be used in TDengine SQL. If you have previous experience with SQL this section will be fairly easy to understand. If you do not have previous experience with SQL, you'll come to appreciate the simplicity and power of SQL. -TDengine SQL is the major interface for users to write data into or query from TDengine. For ease of use, the syntax is similar to that of standard SQL. However, please note that TDengine SQL is not standard SQL. For instance, TDengine doesn't provide a delete function for time series data and so corresponding statements are not provided in TDengine SQL. +TDengine SQL is the major interface for users to write data into or query from TDengine. For ease of use, the syntax is similar to that of standard SQL. However, please note that TDengine SQL is not standard SQL. For instance, TDengine doesn't provide a delete function for time series data and so corresponding statements are not provided in TDengine SQL. However, TDengine Enterprise Edition provides the DELETE function since version 2.6. Syntax Specifications used in this chapter: -- GitLab From 962572266335acca4758f8d1eef7e18e95b2b6e7 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Mon, 25 Jul 2022 20:27:45 +0800 Subject: [PATCH 225/380] fix(rpc): add global config and broken link method --- src/client/src/tscServer.c | 32 +++++++++++++++++++++++++------- src/common/inc/tglobal.h | 4 ++++ src/common/src/tglobal.c | 27 +++++++++++++++++++++++++++ src/dnode/inc/dnodeVRead.h | 2 -- src/dnode/src/dnodeShell.c | 2 -- src/dnode/src/dnodeVRead.c | 12 +----------- src/util/inc/tconfig.h | 2 +- 7 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index b626a5355e..2bd2f9bd4c 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -283,16 +283,34 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { // pSql connection link is broken bool dealConnBroken(SSqlObj * pSql) { - // TODO + // check valid + if (pSql == NULL || pSql->signature != pSql) { + return false; + } + if (pSql->cmd.command >= TSDB_SQL_LOCAL) { + return false; + } + + // cancel + if (pSql->rpcRid > 0) { + tscDebug("PROBE 0x%" PRIx64 " rpc cancel request rpcRid=0x%" PRIx64 ".", pSql->self, pSql->rpcRid); + rpcCancelRequest(pSql->rpcRid); + pSql->rpcRid = -1; + } + + // error + tscDebug("PROBE 0x%"PRIx64" async result error.", pSql->self); + tscAsyncResultOnError(pSql); return true; } // if return true, send probe connection msg to sever ok bool sendProbeConnMsg(SSqlObj* pSql) { - // check time out - int32_t probeTimeout = 1*1000; // over this value send probe msg - int32_t killTimeout = 3*60*1000; // over this value query can be killed + // TEST TODO DELETE + tsProbeSeconds = 1; // over this value send probe msg + tsProbeKillSeconds = 3*60; // over this value query can be killed + if(pSql->stime == 0) { // not start , no need probe return true; @@ -300,12 +318,12 @@ bool sendProbeConnMsg(SSqlObj* pSql) { int64_t stime = MAX(pSql->stime, pSql->lastAlive); int32_t diff = (int32_t)(taosGetTimestampMs() - stime); - if (diff < probeTimeout) { + if (diff < tsProbeSeconds * 1000) { // exec time short , need not probe alive return true; } - if (diff > killTimeout) { + if (diff > tsProbeKillSeconds * 1000) { // need kill query tscDebug("PROBE 0x%"PRIx64" need killed, noAckCnt:%d diff=%d", pSql->self, pSql->noAckCnt, diff); //return false; @@ -529,7 +547,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { if(rpcMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { pSql->noAckCnt = 0; pSql->lastAlive = taosGetTimestampMs(); - tscInfo(" recv sql probe msg. sql=%s", pSql->sqlstr); + tscDebug(" PROBE %p recv probe msg. sql=%s", pSql->self, pSql->sqlstr); return ; } diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 3add0b566d..7011ac06ec 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -218,6 +218,10 @@ extern int32_t debugFlag; extern int8_t tsClientMerge; +// probe alive connection +extern int32_t tsProbeSeconds; +extern int32_t tsProbeKillSeconds; + #ifdef TD_TSZ // lossy extern char lossyColumns[]; diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 44a53efd8c..dedc81fdb4 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -268,6 +268,11 @@ int32_t fsDebugFlag = 135; int8_t tsClientMerge = 0; +// probe alive connection +int32_t tsProbeSeconds = 10 * 60; // start probe link alive after tsProbeSeconds from starting query +int32_t tsProbeKillSeconds = 30 * 60; // start kill query after tsProbeKillSeconds from starting query + + #ifdef TD_TSZ // // lossy compress 6 @@ -1733,6 +1738,28 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); + // probeSeconds + cfg.option = "probeSeconds"; + cfg.ptr = &tsProbeSeconds; + cfg.valType = TAOS_CFG_VTYPE_INT32; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT; + cfg.minValue = 0; + cfg.maxValue = 0; + cfg.ptrLength = 0; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + + // probeKillSeconds + cfg.option = "probeKillSeconds"; + cfg.ptr = &tsProbeKillSeconds; + cfg.valType = TAOS_CFG_VTYPE_INT32; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT; + cfg.minValue = 0; + cfg.maxValue = 0; + cfg.ptrLength = 0; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + #ifdef TD_TSZ // lossy compress cfg.option = "lossyColumns"; diff --git a/src/dnode/inc/dnodeVRead.h b/src/dnode/inc/dnodeVRead.h index b467e93885..9171026f21 100644 --- a/src/dnode/inc/dnodeVRead.h +++ b/src/dnode/inc/dnodeVRead.h @@ -28,8 +28,6 @@ void * dnodeAllocVQueryQueue(void *pVnode); void * dnodeAllocVFetchQueue(void *pVnode); void dnodeFreeVQueryQueue(void *pQqueue); void dnodeFreeVFetchQueue(void *pFqueue); -// reponse probe connection msg -void dnodeResponseProbeMsg(SRpcMsg *pMsg); diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c index 2bf67f9a5c..26a2fc9651 100644 --- a/src/dnode/src/dnodeShell.c +++ b/src/dnode/src/dnodeShell.c @@ -78,8 +78,6 @@ int32_t dnodeInitShell() { dnodeProcessShellMsgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dnodeSendStartupStep; - dnodeProcessShellMsgFp[TSDB_MSG_TYPE_PROBE_CONN] = dnodeResponseProbeMsg; - int32_t numOfThreads = (int32_t)((tsNumOfCores * tsNumOfThreadsPerCore) / 2.0); if (numOfThreads < 1) { numOfThreads = 1; diff --git a/src/dnode/src/dnodeVRead.c b/src/dnode/src/dnodeVRead.c index 8a9cca4f5f..6b2a0ab8e0 100644 --- a/src/dnode/src/dnodeVRead.c +++ b/src/dnode/src/dnodeVRead.c @@ -155,14 +155,4 @@ static void *dnodeProcessReadQueue(void *wparam) { } return NULL; -} - -// reponse probe connection msg -void dnodeResponseProbeMsg(SRpcMsg *pMsg) { - // check probe conn msg - if(pMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN) { - SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = 0, .msgType = TSDB_MSG_TYPE_PROBE_CONN_RSP}; - rpcSendResponse(&rpcRsp); - return ; - } -} +} \ No newline at end of file diff --git a/src/util/inc/tconfig.h b/src/util/inc/tconfig.h index fd9a340a25..c0a4986936 100644 --- a/src/util/inc/tconfig.h +++ b/src/util/inc/tconfig.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define TSDB_CFG_MAX_NUM 131 +#define TSDB_CFG_MAX_NUM 133 #define TSDB_CFG_PRINT_LEN 23 #define TSDB_CFG_OPTION_LEN 24 #define TSDB_CFG_VALUE_LEN 41 -- GitLab From c3b58766f2f0bfc18da7a51e6f3081901c90a029 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Mon, 25 Jul 2022 20:31:04 +0800 Subject: [PATCH 226/380] fix(rpc): add global config and broken link method1 --- src/client/src/tscServer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 2bd2f9bd4c..a4bd164d78 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -547,7 +547,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { if(rpcMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { pSql->noAckCnt = 0; pSql->lastAlive = taosGetTimestampMs(); - tscDebug(" PROBE %p recv probe msg. sql=%s", pSql->self, pSql->sqlstr); + tscDebug("PROBE 0x%" PRIx64 " recv probe msg. sql=%s", pSql->self, pSql->sqlstr); return ; } -- GitLab From c62ea73daaf386d09bd410d2bba01d19948d8c30 Mon Sep 17 00:00:00 2001 From: Cary Xu Date: Tue, 26 Jul 2022 06:54:07 +0800 Subject: [PATCH 227/380] fix: shortcut support taos benchmark --- src/client/src/tscAsync.c | 2 +- src/client/src/tscServer.c | 2 +- src/inc/taoserror.h | 1 + src/util/src/terror.c | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index df1b98478c..3edebd88ec 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -313,7 +313,7 @@ static void tscAsyncResultCallback(SSchedMsg *pMsg) { } assert(pSql->res.code != TSDB_CODE_SUCCESS); - if (tsShortcutFlag) { + if (tsShortcutFlag && (pSql->res.code == TSDB_CODE_RPC_SHORTCUT)) { tscDebug("0x%" PRIx64 " async result callback, code:%s", pSql->self, tstrerror(pSql->res.code)); pSql->res.code = TSDB_CODE_SUCCESS; } else { diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index c952bc2eb3..3f0a261a25 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -335,7 +335,7 @@ int tscSendMsgToServer(SSqlObj *pSql) { if ((rpcMsg.msgType == TSDB_MSG_TYPE_SUBMIT) && (tsShortcutFlag & TSDB_SHORTCUT_RB_RPC_SEND_SUBMIT)) { rpcFreeCont(rpcMsg.pCont); - return TSDB_CODE_FAILED; + return TSDB_CODE_RPC_SHORTCUT; } rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid); diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 029d3bd40f..9f51952d28 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -60,6 +60,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_APP_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0014) //"Database not ready" #define TSDB_CODE_RPC_FQDN_ERROR TAOS_DEF_ERROR_CODE(0, 0x0015) //"Unable to resolve FQDN" #define TSDB_CODE_RPC_INVALID_VERSION TAOS_DEF_ERROR_CODE(0, 0x0016) //"Invalid app version" +#define TSDB_CODE_RPC_SHORTCUT TAOS_DEF_ERROR_CODE(0, 0x0017) //"Shortcut" //common & util #define TSDB_CODE_COM_OPS_NOT_SUPPORT TAOS_DEF_ERROR_CODE(0, 0x0100) //"Operation not supported" diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 0cc345d60a..640e842de3 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -68,6 +68,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_TIME_STAMP, "Client and server's t TAOS_DEFINE_ERROR(TSDB_CODE_APP_NOT_READY, "Database not ready") TAOS_DEFINE_ERROR(TSDB_CODE_RPC_FQDN_ERROR, "Unable to resolve FQDN") TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_VERSION, "Invalid app version") +TAOS_DEFINE_ERROR(TSDB_CODE_RPC_SHORTCUT, "Shortcut") //common & util TAOS_DEFINE_ERROR(TSDB_CODE_COM_OPS_NOT_SUPPORT, "Operation not supported") -- GitLab From 514b912c8377572cc3444e65699f65d23e83553d Mon Sep 17 00:00:00 2001 From: xywang Date: Tue, 26 Jul 2022 15:39:46 +0800 Subject: [PATCH 228/380] fix(query): fixed a free race condition --- src/client/inc/tsclient.h | 1 + src/client/src/tscAsync.c | 2 ++ src/client/src/tscServer.c | 2 ++ src/client/src/tscUtil.c | 4 ++++ 4 files changed, 9 insertions(+) diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 2ada7b32e8..94c1348bbc 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -387,6 +387,7 @@ typedef struct SSqlObj { SSqlRes res; SSubqueryState subState; + pthread_mutex_t mtxSubs; // avoid double access pSubs after failure struct SSqlObj **pSubs; struct SSqlObj *rootObj; diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 3edebd88ec..78dce41455 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -46,6 +46,8 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para pSql->fetchFp = fp; pSql->rootObj = pSql; + pthread_mutex_init(&pSql->mtxSubs, NULL); + registerSqlObj(pSql); pSql->sqlstr = calloc(1, sqlLen + 1); diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 3f0a261a25..61ee447152 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -3251,7 +3251,9 @@ int tscRenewTableMeta(SSqlObj *pSql) { pSql->rootObj->retryReason = pSql->retryReason; SSqlObj *rootSql = pSql->rootObj; + pthread_mutex_lock(&rootSql->mtxSubs); tscFreeSubobj(rootSql); + pthread_mutex_unlock(&rootSql->mtxSubs); tfree(rootSql->pSubs); tscResetSqlCmd(&rootSql->cmd, true, rootSql->self); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index c431a731c0..116f7deb1c 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -1760,6 +1760,10 @@ void tscFreeSqlObj(SSqlObj* pSql) { tscFreeSubobj(pSql); + if (pSql && (pSql == pSql->rootObj)) { + pthread_mutex_destroy(&pSql->mtxSubs); + } + pSql->signature = NULL; pSql->fp = NULL; tfree(pSql->sqlstr); -- GitLab From ae8ebac71ade102b0cfedf5748049d9837622442 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 26 Jul 2022 21:43:52 +0800 Subject: [PATCH 229/380] docs: add google data studio connector (#15424) * docs: add google data studio connector * docs: update google data studio --- .../20-third-party/13-Google-Data-Studio.mdx | 44 ++++++++++++++++++ .../20-third-party/gds/GDS-10-1-1024x531.png | Bin 0 -> 79947 bytes .../zh/20-third-party/gds/GDS-11-1024x531.png | Bin 0 -> 80016 bytes docs/zh/20-third-party/gds/GDS-2-2.png | Bin 0 -> 30421 bytes docs/zh/20-third-party/gds/GDS-3-2.png | Bin 0 -> 24531 bytes docs/zh/20-third-party/gds/GDS-4-1.png | Bin 0 -> 29474 bytes docs/zh/20-third-party/gds/GDS-5-1024x426.png | Bin 0 -> 20982 bytes docs/zh/20-third-party/gds/GDS-6-1024x368.png | Bin 0 -> 25305 bytes docs/zh/20-third-party/gds/GDS-7-1024x528.png | Bin 0 -> 85728 bytes docs/zh/20-third-party/gds/GDS-8-1024x531.png | Bin 0 -> 78957 bytes docs/zh/20-third-party/gds/GDS-9-1024x531.png | Bin 0 -> 77796 bytes 11 files changed, 44 insertions(+) create mode 100644 docs/zh/20-third-party/13-Google-Data-Studio.mdx create mode 100644 docs/zh/20-third-party/gds/GDS-10-1-1024x531.png create mode 100644 docs/zh/20-third-party/gds/GDS-11-1024x531.png create mode 100644 docs/zh/20-third-party/gds/GDS-2-2.png create mode 100644 docs/zh/20-third-party/gds/GDS-3-2.png create mode 100644 docs/zh/20-third-party/gds/GDS-4-1.png create mode 100644 docs/zh/20-third-party/gds/GDS-5-1024x426.png create mode 100644 docs/zh/20-third-party/gds/GDS-6-1024x368.png create mode 100644 docs/zh/20-third-party/gds/GDS-7-1024x528.png create mode 100644 docs/zh/20-third-party/gds/GDS-8-1024x531.png create mode 100644 docs/zh/20-third-party/gds/GDS-9-1024x531.png diff --git a/docs/zh/20-third-party/13-Google-Data-Studio.mdx b/docs/zh/20-third-party/13-Google-Data-Studio.mdx new file mode 100644 index 0000000000..0d1ec84aa3 --- /dev/null +++ b/docs/zh/20-third-party/13-Google-Data-Studio.mdx @@ -0,0 +1,44 @@ +--- +sidebar_label: Google Data Studio 连接器 +title: 如何通过 Google Data Studio 可视化处理 TDengine 数据 +--- + +Google Data Studio 是一个强大的报表可视化工具,它提供了丰富的数据图表和数据连接,可以非常方便地按照既定模板生成报表。因其简便易用和生态丰富而在数据分析领域得到一众数据科学家的青睐。 + +Data Studio 可以支持多种数据来源,除了诸如 Google Analytics、Google AdWords、Search Console、BigQuery 等 Google 自己的服务之外,用户也可以直接将离线文件上传至 Google Cloud Storage,或是通过连接器来接入其它数据源。 + +目前 TDengine 连接器已经发布到 Google Data Studio 应用商店,你可以在 “Connect to Data” 页面下直接搜索 TDengine,将其选作数据源。 + +![image](./gds/GDS-2-2.png) + +接下来选择 AUTHORIZE 按钮。 + +![image](./gds/GDS-3-2.png) + +设置允许连接自己的账号到外部服务。 + +![image](./gds/GDS-4-1.png) + +在接下来的页面选择运行 TDengine REST 服务的 URL,并输入用户名、密码、数据库名称、表名称以及查询时间范围,并点击右上角的 CONNECT 按钮。 + +注意:查询时间范围为可选输入项,如果不设置查询开始时间和结束时间,那么返回的数据为截至当前时间前30天的数据。如果30天内没有数据,生成的报告的会没数据。 + +![image](./gds/GDS-5-1024x426.png) + +连接成功后,就可以使用 GDS 方便地进行数据处理并创建报表了。 + +![image](./gds/GDS-6-1024x368.png) + +目前的维度和指标规则是:timestamp 类型的字段和 tag 字段会被连接器定义为维度,而其他类型的字段是指标。用户还可以根据自己的需求创建不同的表。 + +以下为使用 GDS 对 TDengine 提供数据进行可视化图表设计的过程示例。 + +![image](./gds/GDS-7-1024x528.png) + +![image](./gds/GDS-8-1024x531.png) + +![image](./gds/GDS-9-1024x531.png) + +![image](./gds/GDS-10-1-1024x531.png) + +![image](./gds/GDS-11-1024x531.png) diff --git a/docs/zh/20-third-party/gds/GDS-10-1-1024x531.png b/docs/zh/20-third-party/gds/GDS-10-1-1024x531.png new file mode 100644 index 0000000000000000000000000000000000000000..121ca63b18b0f6a7af58d823482d95b648e171b9 GIT binary patch literal 79947 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 Od!5%dI$L}O8}>iAFm)IJ literal 0 HcmV?d00001 diff --git a/docs/zh/20-third-party/gds/GDS-11-1024x531.png b/docs/zh/20-third-party/gds/GDS-11-1024x531.png new file mode 100644 index 0000000000000000000000000000000000000000..cf61951be65bd2461301725b07d2b20eae9576df GIT binary patch literal 80016 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

l1It-NP1dq8*r{2cjwTPM8F@A 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

99(=XEF&}w|od^5Sn0eNNricK*m!u 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 BEGGZ} literal 0 HcmV?d00001 diff --git a/docs/zh/20-third-party/gds/GDS-3-2.png b/docs/zh/20-third-party/gds/GDS-3-2.png new file mode 100644 index 0000000000000000000000000000000000000000..333cc7d8b549a43f27129b5895b96ee0bfb285ca GIT binary patch literal 24531 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 literal 0 HcmV?d00001 diff --git a/docs/zh/20-third-party/gds/GDS-6-1024x368.png b/docs/zh/20-third-party/gds/GDS-6-1024x368.png new file mode 100644 index 0000000000000000000000000000000000000000..af9afd8c33d6874de2086d77b9e67c17aeefbe32 GIT binary patch literal 25305 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 literal 0 HcmV?d00001 diff --git a/docs/zh/20-third-party/gds/GDS-7-1024x528.png b/docs/zh/20-third-party/gds/GDS-7-1024x528.png new file mode 100644 index 0000000000000000000000000000000000000000..34e0dab351e684b049c4ed291d9e253b86c3c222 GIT binary patch literal 85728 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 aep$YH+nz{Y3G`ouphq%_4}M4)djB7hrk?o# literal 0 HcmV?d00001 diff --git a/docs/zh/20-third-party/gds/GDS-8-1024x531.png b/docs/zh/20-third-party/gds/GDS-8-1024x531.png new file mode 100644 index 0000000000000000000000000000000000000000..4c6d627bdcde0ea12d07bf0fe9f672241686d416 GIT binary patch literal 78957 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%0DCM#j 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%0DMhe z{ud^|yX}Z%p9B()HFi2V@XQ5?D){QkJ$3B{WOzeEkisXL5)h`jXFinLaqqmFK?s&` zmT0U#5nYy8WcRW`^X+j#UmG0E9t2N%Lc(ojW#w<~X#FDMK-d-7Ck1;<$-`dIh%n?( zenCM{s52zyuCA_TlMBPBlMrk3;iMLhw~K--F?ec>@7G_(PoVv*^L@0;HV7-x?&i6s zJIE)gV7yd(Sd;u*SX1ug(IdH_z~?N)Xdm=K>4Vi%;e@K&+@$??JQ&ej@7*EidjNX+ z`(J2k4vmfyU}t7#E^Tb^K>hT1c=EHdVA$NkA0YVI_Y46x;BI#HGq$$2cW>Sl@i}vQ z{rdHb7uRjb%PkeVU|T^RPo-i=b4m)K&ZF2)Df1)sv4*IeI``VwOTqRHXph|d-@K`e zl3(Yy1KkW!3@IKX&dSc+@oU+Fd?5=X9W?c58|$9nwUJ2@s3^Y0d-H_X<~ANTkd^xUL?T8=^MFY)%^E zhQOBXYX*DhQwJN+V$fLN#eEmT)9Q;pT3An2gP+3G-XJg0lqv~UYaA;Z`1M7hW%^}J zdKih^zq^A3Iu4K$?D+WDE!CJsShx(j0R;ubH%JmUzj4C>46S_~pclnLF2cgXE-o%A zD=QH=M5$%K^#d<3pz`;!u8}Q)YzJgu@Xf-9Ide6q^$jAf)31Pt6F|pZtf)ixP zK7iND=Rx$2?!^p_K)>?86?H>0Usx_E$Lv5%bmlw(7-H<2^mFNg$uErtsu4Y&P^pHl@wNJcT4o3ULKIRTvsHOD zC3}e;O;lfnOG+qofCyVc%9nZS?#6aA1bTMG2f7o3<8V?J4rT_vtcEoqK;7K_DdGY* z$!y2x9uFw@(d?z`Hj~=+(yEpK$?H#jHeX%W^PMX0^p%4mbGMb>q)^REioXw@*O)2oM$oLF_8`1ws-d%+YwuLIh$u-n7g-U;ONy8!n#~v z!J~=0&D}_eHI?vz^5ClKUoV8=sl@Of8-?^$bi*WbYOP4C5Kz9$WWOMtp3MT~Y>-(% zhmBNSH2cOTFf`R3A%l$%Y?P{7kH& zrgmBproGDX@xf9OOltoLUB~5CMiHCfhYc)&7@W*jgk7z!5X+6~=WW(5UTZ~=gX@=E zP^N0^K&Uw8K#-A=lNc>v6~!^fI}tvhP_+C10mRDx0YvFp;>FORWAStZ`bXBIV)16K zh#NV&D-14UrFVQ7(IvXuJ7CU+J2(ahHKNT~aiiudUR>^9=L7~mz&vfNmB29`J-sCO zSY7Vu+n4&MSYhQ55Db#GPZ#0W7Lo|LZRYU@_yE*qMQo1Qt_O5y&+0Y)+y3jkq^=O*#OA=dVviuPY)jNN}$+824S2(aI}b=Ofh9xP(- zUBll$MBlW7=^s-eV%V?NlmnF4toV95?b-SW7ne2O`6|}sj>J%IoowL}Q5>F-QNzlO zn@Q2=Ub=TA9*N2Vr&7l4ynP-Xb%kKmDZ$+S$*xD#dDHmjb!W!> z%8ugXE3vvM?+dsF1w)d?&0oX@fj8`kXy!c|VPAvU4I{&#Uk&v2XJ70b@SB zh{}j#<#SP$frQcZPR=Xqyp9dBX$b?1dCJ54Z~GmHR)J+lptGW7Oazi^f(7v0-b1)C z#)JrU(}4)X`V<}(k09w=1l-RU(eFip{SF}1^ux&+i)AO%w1!wFgSfmr`Nws?(lB08 z&tD;#HTUUUcN4PH9U#<($}r)TAZ9P{)4+rYb2BOmz9V;d7q@z@& z&+N|3TiVO$xrPhxo;H>7>yJ4a&5CFE)V;o>ll$PaQzbpsO*PSWc0NE{xR8vKtk}-Y z#fuG<6Cmf;1kka_v7t?#WyM!yg(e|@a3v1C|N0S3;pa`%$SaD}p-1<`E*xp2Z{n-) z{`p!Dcs+Mjt=8x_c2b(59^g1=|213HE(k9g1xfobmmt7Ya^2qKgL51~K@myPp+u#r zNFU@2EFfb-tw;#SY@ooea0{66H`sFS4J-#TN$zzxR)w8U4Tf*FW?zg4i(ga=b7efi z28pW#6oi?ZRIbuB`+m9^7NzMi^)tS+t;Y;nFACPWz1N~7yVDsw)(w6U*rvGcgt}h- z;5t`n!o2l_L73X&7D!DW)a}bx?p3@=jCu!6>BTXCQZLSxIn@@3Hiww4MSeKC)-;AM z*p+7?O^QH$Uld-U@A!nW>}4D=7+QCUE!>3x#RHYaKj06{x5*mjb&zXoiI5{C&Q$q! z9{Nyz=%QIqUO*~^6pYO;JYNtgVAe=lzh8?*An^-5`1Q4p{3efx2IGPa(Px5%Tvb9Qc%%a@(7@RD?!YnxpE|qpO`4WE!xb+#$M?^BgJoB1*sdlgOV+cX|S@1;()%kH? zO>JQT9C8orq|l59wC?wA*8StHcTMn%NVWxWBPt}i+jh52501JGN5=~KoV{&XQ2&et z%DY_GN3bmEO)|My-m9FvUt2CzIF*w8>o8&Ua~5YtL5)}Mk6-fE#?~b%?ngU35wApl zE{#_)cRZyy%U;Xm$<5m1;ths9=lsjuu}BD&16ocg2Ag;2X&{L8gcz_An(5gx&&(6w zUED)zH}}=o8f-*fGpao+8RFR1kZM3bQ-fF*W#|Bgl9Q_|6%`eeh+S%J?Zw`5uO?>J z#Y+Gc0){Bvkp`>_M}J``6@CubT~%xd0 zg<$7^h&#~XNHgub<$=H7Rd4LvHRKK$U37MTte!^cS{COF$k25PzDx2w3vYtLn8;+N z<71^k8K(U4=}M86>N}mSh(aC{M)Zc8JJ`{?9Ug;&fzY$`)4wu;N-@J%==t0KY7>jr zElE_JJXHdJYCiNK@`dq}AS&urh}VpwZl4Alm@@so-ij~?{)l5xdTT$Bgd`+_{h&oW{1hQV6Z(P#Aj?6u>XuA0G0&nF@8 zbP|z@ke{ExMSuKbTdiRoSLgp9z(p@AzkbaQnEClj3JNxt{-i;v7Bu$I5MX-Mx1mH! zPiy<6dZJ#5U5^o+aG+IiCj`PuCkcx$18dy`guvOnO~H!;rPkT~+l-sr*z8Ii1}*;> zk#X{NvquH))(a^Lv-2=J+pC0&gvb;#Q{i33wSbHHN%t)Q-vg@GU2sJ?BS&gXCpO^{319*&3{bq1IE*Vy(kt{(^KRmE|wWb?lHh-b1ow%5~C|BggZRoRH z24i|_h=lPEkE0Uqowq092#@upUO$t$0@%q^*# zpx!WmMnr+1&tL{v?;)dk41k2XxVU&wU|@WF{Dkl2Ih1a_efxHAZ*MD2y90J}ZOfhr zb-NqZYOysmehU|Pa4Wk0s%dLtyM+M7;^zeUeejS=-hbYcJQ`0Y`oE!Z?N9=+_0%gZ1tzF~5pAw*#(7 z_{#wVU3Er^^e;V~p+_Gt!qA8EtnMK3(-W6br2>A_^V`1!;H2(gs)0Y{<`Ktd zbE)^ZCZvH(0qtx*wRWcOwiAu+VRvv61OL1BQtlA!?2f=Okm{0!0`NWz_*|<+t4|iJ z-x?^LGvACdr|OKCmjAcj=!$L_1{eI02P7XfsSrJApv_|IVn^gHW2Oq zAC0SiJ|V89yafH+7&k_6PR*(`LI~^*6+w?AKX|uO_4K}SaT+k+?LzPljyD~Y)?e%5 zKdgE^=*8VJw*VvIL1{pnQslh-shn<5?T1zKN|q|covZuyH6O}^R<4suZ)5fG$ukG$hB%+DSU8NRQNfy%9BLiR6!5wp4FK^*#6KS z=~*E~IK)J#RN*Gkw3rbEb%j8XyC(0~ta|;=)(@tb+_75Y=>{~bP=;wSWB9{^kRX_D z9je91ANB(KfApbsAa81%1|dRBk{Cr>kM^LqQS~uQ_~ZfE2_9x>M7!c8&r!gdQ|4|g z!rUS#C7FKC&>Hu6$d zJH_2W3fSDz)zzIb6-)@$3i-t$5p%VPxNMQAgY3?8rIHs83eRkU_ljDK5EzZa5bsK6 z7uLd;!SNBe9h49;Az(yd-D+6PloMsd3HNOD>Fn*=eBn~>kYppk=C0n%)Yb9?$zh!x zMNee@K)uSzUXxZCStB?iI!*AKJ7Vb?eCuW7>0ckGthmdxV8${%b-wqv?nZ9=ZAr>oH2WXx^BH5+; zmo(q^GYlIkfi&2W&=!bJe_13Pyh*LB)2R|k_g2aG_6>5G z9381kH=iHZw$E_M*L}_gKvjKXL4JN$cXyEBnt}T#e;P9xKgOB3RA%Vkn9PuL)p5lUQ_K1#c=HVL_E=9tBWRWUk;KlMuhfQ1 zX$f^zRh|Y0sOs638mDEl=!Ap>J{`2+!$1I{qN1oJAr}XUw#4Dgx4w+{)XkVu_w-#u zXpenggvqml8&KM7h=UW9)44frwOPl@1T^$%O-_w(;gDa z!h5_dxo=8HA`I@cZe5kD;^62}sukL6)DQ)Orocik{6aZEF$DT0EON?CL*l|=&QX=G z23NWe%)f0`hbK>H^&f0KcVGF%vnv5K6da(a|Ev{Dp8qSAPO+Id!Tw zMiVaV#>Uq4VPSgJsO&i&p}d>gXJ`wzLwwo!T2b(LUiALa7(`=#0?bghUg|+gcv}mg zSLs27Kg1R_S+D0YjQR$Duj;uauHnoGVsstC8PDHr)^pI8exyYI3qc={!2bBRUfyKL z2Hp5&OI6P=Pf9zHFz8!;BSFY!!*}8uC$~1EeC45G)GK(c8Ic2$`Gp+VyZtE{&+YyW zxS?J*IPqH2KE`WV$BZ#fVDU2!%Bi#y3J^~75+L>5pw;83%b@*bZ*L%v8Y9~O3GO0H zQ;QX-{Dz}dWbPR}?Ts#3rH7cHPYCdK7HUud&7*UjuE&x=K#dpWTxTJbl5!@IBiO5u z{qm^^fEej}_$2A2JVZc1?h)*P9zPp?4^+_P>ldMp!tMCE^%+fy)ygD@H&oRFBKSVy ziKzWeniB<&8RHi{nVoE0Pis7?|&N;(b8l5C10SLl+K zjFZX&xxbg)EW{YYmx(e42lq=lZBoj^m&Kl0hePEvLrIqlS1vJQ+D>0jlXM9XHkh;j zH;+7{%V?A4$9QFD(ZRH)JJ53)i>10tj0xbUn^}O_S!Mk)FMi2cmquE$UMWn^2fM07 zF`{4gT1&FIln8qL%~c;=JwCXCU5ZQ>ccGkoOk?bW1Sl182UcvAlR~wJD~wv(84#3; z&3_YdTCB50?z#BbnK3=X`Zx&Ip8;^@8id8@_#v*#t5zlu_C51E4*EJ&+m~g(2DTJs z-R>gckUD+{8m_36B6aOa5gnv3MW#A0J!zQ<1(`f4 zVk~`csGGGqYn3^K;9Fk9glxd$5BUyG-+j-mFsN*nGQ3n>!P|w4vVZu?vVZ##sIJlu zF~%KCtMs;b%LcZ?UR%d|wY;B7eX_62NEBuzXAUtiEbW~VPje_TS2W*L9mL3hAYwVMvS2?@23`fQ~hL$Uhap}8tnYKJ*ahL;Oskx(z3QZEA(%7p< zkmL3F*kF0fknnw=dEgEK$MXIX;nQy)m)XF7&WIi~dZm*?-jf1mke=cEEr8SWp>+f7 zE>uyX1}LsuzgmD{s?VCb5L47ubCUbl%Zvp~5DTAiz#UUY zsEiB^cRiuMVtAmETw=?HU=Ue$Wve143m-JgJ|B8>6ZJR&0l5rZpt&Lecrsp<4Sl#w z6|lh~$X$>C#qE8gOA>pccIbBA;kbXeQU#EFY0%czzB&TGQMGCE>XlBV)2-?I@>hUK zK^EZB#GySEXW2k71-1Zvrj;rT{JO^pV}|t6R8WnRE}&Qhq&`BR%v1r21_wRxWv(06 z^XW4VCKkJ=f~zN)^4U2aPOl!GJ9v;^t3BwM(xf&O8))@+7Yr@%5yS!1cYHuyrhhgB z1v9A42f(JLrg2X1*4M8+5?T%Ga1&VJpGJU~^dNB?TSW;I^i_ zaPR_lIIJ)rnEVfT(gQd33sqfx#kAx2vC7YPn{m)d9{v|w+c+-}z@=gqfzp=%B8MK< z5@2gH4643Yx)Q2BF_zmiJ0AP^b3GXda`1B$){F!h#88dje+sO(BRuS33J@F1?>jun*XO(iTQ z1l79TfXaS@v26A8DAylK1+L!rlo-*D$($rs@t9vgvjr=LFSuu zVe1S=!q(Ckgg``5-!|X7+tknJKT0!~faIA6PIsbcZx1g`7r`bqIVxlmI^?u<7nh1t z1eWZ4^x6=nE;Ru)#0}x1e2+%sACbq{KoG4MG2LBTTMM;{unKuM4ME&;PVT<&k5`eA z0^E?zTXK21c7kjy$;*fIk9456QkdvU_o&_{K}`&#YDZr?C@N7#nj+D1Yf$C!_`JHGlWrLldrj6qkYb7AcKd#y+!fHublc3%5dt~$UiOF|0twPOSS@Yb0KV+5+c zg$x@6SsDd?_j#2-khD$q##`%ax9WhP{YC83~+)Hs9DUT>d!)9#nV7k`TEs5!%-@CtV58)`OiYHF#SW zZDHa7i>KxKOV?xbP8x^#qcM#u%t4N!OOXeq^&Wz}wj%lNEhUqs+|%?RHk;R_A)FEh zZ0pWTlR0^)3E6KDItKH`J5Iis{OxR5=e08tA(6X?MR)mj@gN?cWex-ZX47uy1%osh z_b&ik&#ZYRIa2pCUJ{M3U27B}fDqR~S*sY8!qSbeup>&cQQZzR8Tv2Vn{3fnE)rD^ zrsbY#YsbgLP+^0Q?+|L>xl{=9-75RZDGqc(5E_>xS$Vb{M&xrJUcPOFh`l(X@HKie zhK%5+FeZRHdi*OZoWM{WFwIbR&=*CAC9nIJHx<%UG!Y|iuT_@>$_!-if~$_raM0(E zJiQ*yC3rtzY@H^#XpgMWBL>c&&#fuYKKBcm=rKFx>3&xr5C~;wQQt)h*#= zsj19dTwD&!YGXAiNcTsFj2%;dHIX**YUB-752me0P5wf zOTVZ^wJC_d*ub2Rx0N6 zgWypP9apGPi9ZSj(R>a5Q_nM$0z6+Bxzw83lLbA!Bp(+bFgqvz4@pbmV92xS3?M!Q zs+^9jzl65U(prmOHq@7)q=)0~gBP+I>e~`Xe!gk%Cm(`WbApp%g8M$!_sIXU@Xm5$ z;-cRW)31gHwEJCAG+*z*((W>KNtDOT)W&boe{=isU%d83LT%5)HXDwCjl(WMDiyDwWKBrCg#g6N^Dt) zQA2$@24r^e)h6R`1_IvMmGuqVq&`j<&Vy-HT1YAAFe%6M`D+-~WS_p|M)m2p`MQMx zeeX)19nFD-KGp}T=TYNtE~^JAFDy7F%i8sS3+#X;IT#gljO#K7Y&0D!@v+-UR;B#HnuK7O}Xk+LePcyuP` z-vZz^cot+OK+!t?;$LYL0KMeEC zuF7w_U2|KfR&_8)`GwcLjC;EkyMN`%$_K0YR4-(7HEg$SYe*iTAIjMCt-O`xdv!Pt zt2%@^&J``S*9l&p2ba?AR!QAE*DP)upzNop)85eDEndyO^E_<+cHe2St(;$az4S9_ zjZA{g;z8eYbsX*dGGAEO>yp*%!SON%0wOWA&p~_s?g_K@V+gF*oZ@zPkPf29@o%77+BJ z4oKtS_i-LZMD|cae9DDN@zNH5q)emV@_QyMi9d@LmxlE^9v)&uFzNobwzi7E`o@FU znwW%y;F0YH|B_Q3Vx|{N(mwQ?2A+vX|APceyjZMv*vuyKCMF!T;HB3=5Ob-OjZL$8 zW3Acm#2r{L%?Dh4x0yz~v27Jx6Q=xB`PBcgH6()|0=)JHxy-kDS-k=z3#VTieR`|B zmhZjNE$(~bHc}^DcD^e;vGen^>|*>-X!5MxI_31w(axQ^v4fxb))njTH7++ULWQNb z+ZKIJ{|+*G&Tnq`KIXn`|6DNcxaz1pcDz<#>%Q=QH0AuyzOuAv(b+6riu*#-IRE>HhS${adYzBS>Ceeghus2>cH+VPWhSfRiQa^-ZB*@-XN_EkV`ba##V@zg z=s4P$3RYLUCH6N9&iA&hyRF7VpN&2(^I50*)AH7%;Bt7tRg*TXcC9&}zM-#H}oo{?HF1%d=Nx0Gh|f z`|A%OUyO~?sgeA(>0K2#$DbKtEH0sY^~+WYm}*Jn!b25ldZ}EyNZ!*wUPUytU<-XM zbhy7hB)Ru7x+2`Oezl;EsGUv~K5Z9{&UO?-YM$BF9&;%A3Z!LcZO{MSk=4C<%{t7TTL|lU3R{?LoC7!F*_kn3 zqe%30fONDUrWJfnh4w53NQBP?=)?)W{0I=sr0Q zvXo6MoSdJY&qn3hv$x}uzL(x1H<%SC60-y4$X$X+iJvnDp`8*Oi|hWF(2GA}H1OIS zucFdDa-_v3y{|?pjT0!24O1a{cG+Z*6LxJD3jUwh3C(aJ*TI0+pCVaFjMX05-Hn2 zeqS^77P6vF`Y`q#Pdv_dmG!Rt$LpL}ps|`lQQ^(;yEj=#9dsj4p+}m@_3r8ES3(UY z0sA3JX0cO_I|gs^Lb46_zmhYgOUoN5;k_?nKdHN_oh~wc+mc~q(!@AA*TF=f zK=dKD_a^=oe^2r+k)CQ(MN__dlvGG(u*$u1_gW;pop7NkG4a!)2Qx3q@WB@<7nA31 z7x#*JiMUs29-bNo#)pcpy`^s_189?@)HEE1+9|vk=D&cm^lpB>9scb|{=rooQ@Uhl z>X!|h6m{<^n!6ue3dhoK2p`SZks47O=C8}mPGkAI3NU8aD*^IamUnv{g;RXYP>*!p zQ!+b>BeIXW@~?K2R=epJN%p^z*kg;}puhfC{V9aRisUY%ZmW4^Q!cr8O!oLR5m09| zODn6y9NBvr#&5R$=^q6VGbMlCY|#m@C08O^n)3f%?#7FlC1%K63e(Npd~FU4?oo70 zD8!l~$apw!N4z%r+08lj^k}U!Xnm2%)->6anLf}AOY8Fg+$&V6{qvg0)DJpzk8w1B zlJI^*a+H2;?Px zN0fho5aFII79cb;NPGj?CsaR*f}!UZ5C4BjJPZO?d1O?~BB!ilB8rQ$dAQ%+gt^P$ zYN_?o%e~=oM84HgqhhAuNjL9m>Gc+Rdsl@17u7};B)p2Nforr>Z;N* z(y%~EKMMe?-BECqu)z5g#U}ZD2i$;2YUYMZI5_RiC6qEE_jSYv-grk zG=F+3sY7c4K@RBY|Ff;DyG8+B{?)y^Lh`9Mp~ou$G(?A7ACdr-5F~~E_1_a8;;8_$1=fQn!AEZO#VzXZ%E*-#Imtd7``HCb$$SlNqo$4nd;gSEK#*jNTKp6e5P;fgGN*8G zyIDPlsP#{4F5*0c(BY^;m=FH(#a+WjjA>woqD{ro6JkXcXw z$$AU;{5!(sJKYyL;@-S@b9Qz%GNOGW@l8eeTJ%xL_wQK7SVy~azdy^9BCKw5bIVL5 zG&etbl@4{ZK(ZK2=I8U|R@+U(rSc#JaejXDgO@MqKFt}>81SapU#-`_mAZPg&;#HJ zL%OfKyQstKdZ-3%-IP*z%75?P7N;9{zxd?IlV5n$T+|E^YqF}U${vgLyW|BD4?~KZEL}JPRhSD2PZ<})PcF7e<-sgA z)IG9U*0M;mkWI&Xis8mVliU#DD5TdwATVT_@9%6&b*qU&tEdfiVWhWuij&X!>HyGx&d-h=sPr4~MvksXj<3~Nr75>Z=`;Ffrgx|GPgye( zZdvJU2L$8CQ1TRBpN3QHwva`QU>oLLmwmtgd52}m*^Qs{hIn>jrk$H6<(nU-yzv3c z;aSeO&71?wDz2|&`D3TH8ehC{J|ILGdUhN?zxE|MbBp0)UecG&A?(itX-X!2=HH+z zb$}VP)x=-KR`Oms)u+>XQ)?s!%*TR30M76TXe$nF0YSPX+H@?tg;YX*u+W`1G(!u&Ia6eCt*4OBR;HBKV&mejhG)u*JrsS1 zIfuw(BUg$l!v<^vfbYH#XIj|#(za%Q!gKSBS7eAai5W4h;*SzVm>}+-Q1v(DJw5`6 zmvFj5Y&rwj^)L9`SGkHP+RhiFn)>MM{itm17b-nB*l60%A%+Yr6EV%1ehvMm+8GPErpDe|2teluxmvw8L$4cLOU^#=MKuz-_oLuue0qF{P+Zc;#ZzES9O zg%350Cv18>eSBjYv^z)qMZXbPv5WhvoM^b#Pm z_Iney!}kfa+^~a>usw4&DhGkJnH1_G5Z#2Lh#(v}I2g6Hh1zpwu&m*-G2#$;GF%fk z#yu9d|7La_0~W-)h$#WDh@#q?eKXEAH*WOX9w30AdH9RPjNe9Fgyk!e`dma8g82)l zfxO9RlT;LjFnhGblz8G#;MNin+VqqRU@LXooaX09!s3q;Se~n5&PG2Z7+D-~#>Q>h zj8GVG^oKkS7arJ>3HlDF!{vYzGVBq3@RW;G%~z5i(=ig`_ZM!M#?;47lu3>U&=M4C z{J+M&JF2NA>h~m6fzYIP1OzD(svx14*l2=)A`qJNrZg!Mx^%H1iXcS=6*Wi|DS=Q_ zR6r1rCKzcFdKCoTBzV7j-?!c$?<^OdoHJ+Yo;|aFvkPWAE+uz9RPbxUyAgty)B01w zYSVec1dcxk{1T~*2#5ssMP=`^)Cm+Uw;~}O7g)meyl8cCT7dY!e7XDpr6sk z!{424JE4O`SVI-d%V51MMR)VvlP7%87)s=gCdr%UI}Tf3UhYV0)-yz_k*=lEj-5(~ zO!X69sHs|FCUSDAHn^_lJ97^-Y;ss@_2G5e8;~*G=hIzzHgGq`^R`MUv z@@m%vb(l#hpK#baQiz;!uVyrE62?;_ZKlx$*V;ioHBUJ)lr++<${OQ;NN?LAY(|3T z+q4B*TeHew@A!JFBG;mGOATy{+DiwHZ0Vk0$q}MUx72c%6B)l_ZQsPp8Vk9jv|58= z`U?G(?UmW*bm!bzs?g>!SN!$-3A!u(LO4X|0ao~;&T0R`7WI}lddnh~$!+;A6|i2> ztk|b~2LQ{LQvqi#-)pse+@e)o`hiM?-%rnPh~u;v0cau9)EedA8Ys3DsN<%47D<*c zz;Kxz36pX>hi6Sp64_F7R3_L&2Y|KHCpG}mr!#_>7$d0p;gifHrpzpXY9SjvWD@2O zhM#ow;=}QAtO~BAxxNbbwX6TSSiDEfoTE#=3y&MJ!JLgDP9n~g#5hEsCBO$M(F{4G zmDv-Ry%k9`L-cJ7s#w?9;O0>v6xee69IRrNM+&95z9!AP)DfDE7G&>Jn|f6s9y&et*NC2@IfyVEH;rb+Wtp)(!y*!I zVe>9LIQW1!u%R#>S7CM}*|1)XAK8f0G~v*STdyJ0#qL^w-%zJ&!bJ*>2^|9zGI2q8N6ZIkNYhfDSoVXd4K6q;WSC1-l;xjjDrbIWmvf~ z&GqJU(W=Bm>~l6Ei%slc>zxFzv&t-w3v4b*x{EUlw5Of> zN`^C~Bq3_z7LSahkBAFLTZ5F<%NCOO34=mBq1O zGKqp#N9M&se-<6&I02bDp*8_2g>oJsIA-D#@DKe@V_T_0;MtqgC*#?uwhz$ClzP?? zP_3#1JhMy1$cvbB`ElG15p0oJ$n%(Y&1MM)V(e`O1dyk?DrE%}meN6_w z*~B^pXy~sPBuf2?(FFkkSwJ90YDs)1ZI$8~A7vrof(T{k97ZD9kT`xSI<5PHjk**y znoboD`|*H4%dW*f-EL@(BRW2H)+{~rfUY-270=!bXV86)`B-p9?Hoa`IkWkZem!n3 zj)n!oDkQ$N;-H^p_3d+K=YtZO!n~7i22=&SYfV@@@|oqM`~$9m(h^1={JebQAH}S0 z3`a^K7S^02@OF$JRy-~ap}=0`(8$M@#}aLB&GR$k(Hu*$?2O|91&a?ecl|OMGvni| zlbZ>x38zz}C8Z_YLer$AJ((n*`DC^q!t(Zu9;Gca?j5lF8U8amF{)RgJld#A6qU|h zsrxgjnTBbYGdQZ3+KIf~RE4Nxe(hd<(f&xVq^qG(e|yH3tYO5dIry7-gwY*UV<;8p zb}WxgClGaWQL5=6L*vDZFEQ6p3t5+?DAS(_GSfJ7W!L~SQpgQkugmPq?@hct)de3z$!Y8ua*dciiK2*MSMO2pBZL#7{g?Cc))@sjHengCB}5VpY<0 zjB$pY%WqP1o~~)_ZW_1kjXB(8-~PL4eUqbD2Gz+vl%mVzon#TM*L5s5izp_b@++n? zk=-9L7V$$&;I3LQDdrWGD+3ZgkEM=qkb(`38Oev;wqS({&n&)6-N^JRWEw7!EA~?z zX-=<3j@Ir!;E_JCSFu}-ZUTx>8wtjj{HX{2Cf-FG*kv8za1E20MUX>}% zgThJ`4vj@VYEKbEK|=0z%35&ji$!tvDy=-@P?xc!1j$mKnzkOGPD>WySo?42p%uNY zHaYP%aS8}8&Yd0{vHM#_`qc_V$iXq#@w_sj5Z(xCXYR=(XU-{1u{RsjMgFOo!G!R9 zt63W}9jL^$I?g1I8VtM|;EvB%9xlc-Hdn;UrEGI2uyxV$yu~GT(|*ir(eQR6r6|Ro zGS~7BxQ)H(c!qGl9X$X^Tt8Vc0By(EV1mh`!bXJLsYYQ;JZE)c%b;I)dh8f)#lb|D zb^OCkE*yfHI#J}}5r2{z7f1YHx9Ye@S_aOj60_qyx5T=BFX3W+z>}vLd3sqjBhw3X^-}rAQMbq;vN0r|8A&!a_#=*IO%- zr;cQCOFyFnn-nWa$o=4oF=4@}R2U@^c9$ST?^w*(%Id3dh?9+vMM=3%_mP1*&dE^S zrp?}|zU1^HPxfO+I5Z&0*Ctu~EX*DWw>C7;p_ybn?)~K`nO1 zLIiHmaXwKqm^#qVWDZfSYhcU$$tb7wB%ZIrc=#J3>0yi9wSa{MKneh@I0+0Nu0lov zgY$=cY#XY|&4$9P2&GVp*OTI_y?;#|FB!snb{HybMBALUPJbM}qCQgZ7$#?K-sT)8 zMxSHjuV;yTaBoC9E)!9%@n!95f?&~l+Hys@r;W?4X8yR4q-BkMr{6y9SB@l2U46}A zSN^wT8i@WWgoW`?BQ;d^6dMrav%SY~eBtHR%l>IL;%~32w!S=}%|HPHN?fRPe)c%4 zYoFXlRIK9n|G$ZVWPnmJxh4C5_hC$M4+fL+1Sq$F`+v}peL)gPJ^P=Z6@&_3^Rh!g ztosGw_g>_xC#n6ufXsiY+pu||ko#q|j!t+u7-lk{Q}PJHGbD?kfy6{Z1Gx~J>G4m` z7zgvp-;;01`sI4@vY+2yK)P}j61jZp(8HakSh@|Mr?$E1_$UkgnU|tVz6P;=K|>9j z9&>ad9;PpP@-B38JDlFxT0d6dF#PFOiKbk3q2G+uDZEZlc z2B@<~ikD|NVO@wA2T@jxHLFc5`zBCf_B{TcU*;vm=PK^VLOBP6$|lNO=~(bf}#{<}URE8>SRI z<_jEpSxX{$tL+&Ck2|}9@M+*2z9vL?y?(^^t}8DQvT0jKuELy|8BuSPU_`rY{k})cvwy?N)L|(pKM5m@)*r-wbB*+f8KoIz$l8fM3xDG-9}c+iK5 z%Z6dgQpqtG-I`Nn*pSdYf(5+=95d^TF2k-pD`?%mw@-KGWcaTn&JNqQ0*yT*lsZuF zsRvGXg)h|8LH=q2=KXFz#bI)X0cWeGYsWb;&Sl1rj5F>e7hd;iX{h-u_MA1iv42*O zpPzAPN6O*mqim-CRI`ws2C^A=b{vKBt{!r{B8EU7Z5$mPZE9))&>_z}t{+6sD|=E^ z#U z6qNxQ3|4xPt*Xghs_MlHgv6NGpQLpR%oV6ikl6=i=xAsmo1fE@iJ$B&EiD}!9L&wT zfwS2n;q_yx3$wGaZyfCG)gpjqL!Q&UsG4vPvhi_d4|xSoMK4W>wPYjeJ+w^Af4d7lK>0GWsl zKQTi7@0+F*)0p)I007Xaa2VTgH5I})yecgvEiAO7kxL42EREx9qTo-cNSLw4cl=MR zof#@vSS2pweol_L+B;aEb{~FN7)f1%|C+vrTP{N+FhaC8@}UsiBj0~K`@bZ^MGqZ5 z4C_Q5J2r}59OF*cA6MZ~z<;>9%U}lVyRZkbY1#b$rEGBst2&F%Wt903v8XseHo9bD z0)$HGNXncdlOUN&DRwpgyxO;q+3#$S;9p#v(sqD3gR&?T24>N}AUb7ko}z*bmaV^b zCExr8wEF&s4%y+*2;T`K#aF-Id6w^!{r*6zQ<0Aivc-!(IhDN>DEQ62eROgjfZG35 z#rz5#^lfS-3^mI6I5U$i{XcJjCe!cAJ5%sD7~_AM2~4(;3;>+`ciQaBDdd5ptT=zy z8c;k?aQ{jN6-;Q#{9i-M4gI;+*g18}^_y=s9UMk({Xdy`s=%S++vh4@yqMcuA{rYT z18xWO+BXlfZHy#fsjt_a{0qoa%6cJ0hU2xbE{ngc|MBAo2;*2JDhLxOZvbi}r!+nZx-Clx0t9JhZGB8t6{ygsuz|zeQ0>UAK)`ju!gG0r z9#qKk5Y*M*&wat;yfzrZv${3vL@s0SEi;s=4%tYaWS@jY-oI>(F|f6|^*+v31jdz> z^9htzqRy!8ojQSFVR2}P_{|RZM5TA!kfQHr8+_V*QyI@AFcEfL0;8kcu_BD%W&68+ve(K9k9QYkdbQW8nbcY-7* z>97;BIV1LqeMe`xcdeIZU!|UZ0jALX9LyFAGjpDHl#oSKT*nMkXP%5!*5qnevaGSJ z!HcBgcXGr?j&q+^*Fa`~G_O-*vq!b817T;+1D zXTO(~l{E!K_-}3xcZkA!o1ZlnQq$9oE__^3SXGD%gk3~uT0*nmy-tX;r7(C@h8igqva8QNi*;!HoORc^4A8CTQN6o+ z0AF1MdY@bz93&8y5ri&!2c5OGO&N2*WhiV2qmW3X$PWm!y}NtO@tAWu-#RBhMnZLZ zZmxB>5^y*+1xRlU>7AMZj&um{gsLSEV`IcrwRxzQhj zm;wgA+Z<_zz&21@n4gfEaEC=~8}tmWIG|W(^v2Db?2a~sM{SDUt6}>7GR>-?baoin zf)wwB*kcfuk_7{cCj_JM8ol%uLZGAOb+a>5?*Op|;Va`5qsUX#aRd3iN%~N7<^U5y zX9dUG=Nw)~#p9pq4)MwJVed>#OsKK4(SeCXnbFkHn8N*Aw_>NXgx;Q@PM}-8A&RnD z8g3_4l$J7OkO~VAl{PtZdo7|`X$Kg$f4omYV0bWSZ>kPh##-xXbp{YM0&*Zz)Ns6S zC{GJ+`(gO}o8r8%UzPp#1bN;@+tRqldBA0-gCbT)dl`80p_dW%!u$}{4C83L;zG-Y z$J$bjF0uLY4%iLD@hk&uPpQrMe5HT^f@=bfz3tdMpG}gs<83Nh%se5YoezTg^2J~w ztfcEsG?pA(Tt6mbQpGnpCN(~^H{c;}Y%+D?SXNy4!4GJSG6;iL_#tMQ2sfM)fdT(^ zuzU*Z&V+8{=B7=l3DqE>u8@TE2$Vt@t*Lz-W0CMkeCSzXbjs8bS{MczQZurw$)?jUM1-&E=`ouCAM5*r@(4n?Qme~4; zc3q8&b2G={Y$2vFwk|#y!!us8^dTaoL$!P6@_j_paf>*1v!d(Q(f~I!EMOE?i9z5r zezk_x5ly`_Ov_}e=+rS(=5{sT3UzW6K8SumKW;vDa$v`)imEXZux9D6Fnl%@v>}8t z8n2~l7Yg0PN25Q^8wMlCzr-RI*_;wFu=!n^Hh5K&;>Q4mgE}=VNpVgo_fgs8CU9OW zG115E`WRglIUzeBDc*;H@uwh~WyG}E4_9tV)fv~sy;~dq)ZCGoljLNM2~8`pu0uyk zUl4jzWW$;)4F;0DIvj#ZTafu=THi1pJEagsW)jJ#1R*p1trW^Ojr_aNN*lua3AaUE zr-<$3CsLkYsdUV~(#l>4j$PM{?+ZL>5kXm80Yw7tdJ61|_ttg>1Zu)lDaBlQiB_kElMAxkIMs>)5R|w4&uSZYpAN#f3wU}@hUfle% zHHFapaHBONK80ZK?O!l7qB-p|XYpWu><#1Rm@qfH;`X{k2hqS*^>UgAid;KxOE=d{8` z?R&?bx!;k`5dGyg?O*Vs>R^+8<)7n{eIXZ@fA$||;k2p0R{4ZrH!@BO{0#6>9dNN$ z!y#0ec_sdB=2I9H9IEqmKKyjZ?zbQljSEF1TeY953(|7P;L1K9XW@Ng+@} z32rFP?j>J&jDCk2FK|gjq3Ps8E?UTnY{gDqg26xX&gSp^za;W^r?~$Gm?Qs_W?y#M ze||v_8tboc6-3&F?)qqd~`sX}JfwX9nymgYWYPtrmKQ z_XJn`GOX-bx`9zjIv0+-A9zzbXz+gatxR!zGdnX}6c6u!kJpfrT)z>+=lwQR;?C<~ zU6gP$8%hhM3)}N=OF}v~G&P}M0qFe{b19$EQyZzTcOtY*A@Zfcf^}mNFaLIDb@|lJ ziIiR4{ig_Mk4vOKXt>ttG9xQ^jhYHT3`Yy}1nX0%&8y}fsM*IU)gYP0=%u;=Xs;fEa)f&Q{wGF&OU z-eXcFq;N3B)5Q6bXzq%ENp9g z8<=8BN=gC){7Q5V*w6tTtjrSzjSPu|XdRs>x6shdwlw~&UI!qz=RJJbFWf6^4y?O@ z|3C-|R)UnzSW~$Nz6_{KSo6fnSic0i<69tX4e)t4_|ZjCIu68s+>G7s>$6Im1VPj* zzI^#o7_fIw$t}ac?KIC99%sw#qqZf-||AW@6pBULC2$B z>uGjb6j*Hjjj3fWmSEE?3I&T;Ukc*CN;^jG|IdG`|u`iVaxehU;njpm2Y-=@?aw5B)DxD z?weH94!_>W1racu;35IPUcl`-`4)}^lngE%An8zY{B<1iyc}}Pcv`zo_AgJX&dDnaU<5kGgQaT`RjQQ-!Ew_E7| z{{&Yh0^8c!Iy2+(Y3{Llo$~X$lj~o?P(mz;g!^K$91N{a3ZKTFpNvvbz@62#2=jRM z>hWWVHEepnP^70_lz~Np$9?4EW>qx)R=~n7ovZ3Xi&`}#RKUPUNLP4iS)H=L@~B_% zvQf}>}q`dRmn0qV4U<`HVWl*)7>SrxF~ePx$??$3zcUZ+zr>xwe9d6RqM~WIu$ti?%SQrdkS)M`OF&@ARl{8kX6#Uks^E|^ z)ANW=(fwF*Rl~I)&l{{cX*&nVBQZA4h*Ek^Jr~4I<*6B(Sk#wlp5Zr#sB#eaVWFvm?swa1c{H2HCQYyN$ zw6s)EP@p4{?^w?~KQq&PU7J1WjETuF;AyFS)CJAZAZ6Q8;ffY<1r z&z)XOw|^}h)$gM=J*WM1&TrKc?iV@pXyq$Hm(s=!P6#lt6i&XT&d;CIQ&ZiQqvi%x z(#9$+W&wjd6@x*RybAQxzITS1iOJpcksh757pn& zU9c<;*^H@d?EX64INrDXYbw~=aDx-LT>(5~4z6?T_w>j5&#PVnuW}*+Svo&4AXY2U zQ`kMNA(#&3BfwcHbA`-VVdPvAMWH-RjQbP&jxQ~CK@~O$nKN^**CQX2Q$xY5P?7`6 zwe(^9a}%zf04v&tGNEwswKW>blpauo&N5*CoNkoXTDF@?v##rpvUW&W*}j{`ofpus zk=r|Q`u&9Keo|@Z=6jdZD<2p;YdW;3Bu3QXSBC9r6S0|LzWQw~3J7{Lk9+_lv*X_V?}o zZ}0v;v%`|}|675-qwv4#iPsl|l3cz73~$-}9jqY)wBzvc^XJE3WI84!EHW4=t%GCe ztRXHg?(%OJufG2}p-0Xa3w(Pkfd!btvUH$DRwQ_+19@{oFS+`!3@;b&uVySE&`-q1 zGH%VWJfO6d$2M?&b7;+ROs%?Hm#IVM{P&lX?iPX8eWA^w^+pGUJok_Fp>>NtyZ`h= z$*r0Woh!Q95v=X2;v_Rs|Gsoc!FMQ~`vNX;k`y@VQ+p|oo=0pYJ($bbPhuhc=(J%j zOBKW4rf5Xc*PwLz@jKnxlOWT*xo1m1mYfK-Z|-W#wOQLmk>-VaG+c#Iww?#h*P1Qf z?P!zqY5R6akkWVrpK>g5ecOTGICoORAP>*m$8^Vb=t)RJqxI@K5gU4tE;I6?n1PdPAA-GF$*Wm6xxJwcU!9BRUy9N*L7F>h-d~?pZpZEV~ z^;*-@-P60ex~g{VtFDStQIbYSAw~fJ09{r_;u8SCL3d$rkzk--_@@sm0Eo3rR^p?& z*YZgRqM!bP_ny$V6Z3_2gCXbbYdh`-k1PK!Meg)*hhNJZ0gbzFEMwG|R-(#CrIYP+ zOx1qUN4*gkSbu*TJct3q1bkG7kwA=;10>GfeX?6Nz-OTFzElt!^L~EF?IX9$eTEwEyixzhM45`p4}XF1DSXmPS|@6clu|KZ%KnnP_ik z7uz_G~RZHTBS=jSd%3Q;;rJ_Vx9heoKY$ zpFYRbZqM)9grc*D2!eE}I0M(V>b31ETY{&pg3ltdw$Sss58c-Do%qM?Pp+N^lD9Uz zDn!-~n>Glw-AC*^?(=Pc!Erlo@jL6%+DArWv>R#QLe*;2k^wNKD;`rvOQ~;lsJM5a zbne!3w2Nn-K?(#Vc9oCox$t~(m~CU#Y;cCGj@Za^b8|^mXZ@R-#@^n1mmy}tyR^=D z-t<>vsT>UH&;9?ISc)eMz|BV&Ph}N596g55*lLWSf2t8IJG1emgh0F(#2A64G$_$# zc>b8lgGhPM)yf%vxR87c+0N?(FN*LRUrJtDr=c{3)+%v(!)#H9TsozG1tQn-4Qn9Z z+H_rNJeZ6GO6f4XMn|+c15I3BavLxn*ZEGL*8`sJ?pC^LMjy{Nh#&jq{bO+A3^zKY zBvAs@ij+)Rz*plu%2|RBuTSS@ysE5QO*Funr3q>0EWw5UvK}wY--VdqR!1u1+?+8fQ?m= zWs0`|T4kelFb?Jb7O8+z314paXU$M@D*bk=lgw!+BKYQNmf#=I_ zuSQ1mkRjXf&SvZT$$5;g`#~U4S0Zo$v(e?Z%BMjk(Rd6%rkvFD^=zPPIQ$l8xPVcr4yG zVEV|CUT9|0g$&*0z;y3U6Z`lrxvw8LWZ58bkvUdd)nhtb#mR((z1Ax z3JSFEtA0Q#6SVMUdSQAaHBZXx1b_m0M7&cddW;hU180mn{fN?qItH+z`ePAI(o|RP z#|oVQl9H0jjk?IkosQ?3=V8q)E#DzDWAy|Is;t{pgQdRsl*Bg`$Dgh=r3p_ir^a%S>M=;ugDzzO~YB3fy$`px==<|>CzG;nlz%|rt| z)t|_H;+GO8Rj%b2iGCunBM2yhCF+jXe}@zQ)UFz{fO;;U2k`_yL_F>U9UR_ z-dxikQHvG;IofAr@f_Msxt#>8hM{PE>NCH86Q)M)mM<4;$XAehKIwQ)ymlpf`a4^b zKn=C@%A9iL&1CS~ljP0q?3GPEjRRr#8Gpfzmye}4FY2hCX|Gq*%^h2xr zum(CBn!m~L0O1W023MqhnAfJ-um0NvgY3KuRxwyg94xe|_Dhtkm*&S}JQx{zG{~D? zy*;QG7Q?^=etNGj-|>HrZ2XD}(7(G?le~5=3B2vT5g(y3#M2ghE5E2WQm#*aZ7htj z8#_T%8P>&cbr1^&P*>N^yx8Q`98?}l55+CmWU`qJyPc;joN8bjaYn3U>mTu^ILeoK ztXsL^$VAZd`z;IXwFwLdS-3t3gbQ6Ltj90=eT4zq>ZZ@$k(h@3GJ69!-HALJ)3@|@ zK4)0(;Grhp3oXr4WOEu;dA{z>Z%wxUh76TORIYlwE~VwJ@svNgma}HDy>5&mcDB0y z@mwdqccegjiP(h&U%YNYZsxlws>m}mfhn1^H;1bt#jW6^8L!zJjt~*O@vct0%^i^=gG37=OtwGS>YnT-xf$Ti7r``}2iAml zd*EGKIGz2ioeEuwIA2U3U{ol-Pn#06`T6#A<>;-21|TkK-9z|MU(%vMF6FnEUkm9V zX2rhq{^?*Gi7I6zVyUsY_jW3&F;#F23|CE_1s?AnpSaeC!vFu5w{AMq{}|Pf)R4r> z=PLRI&y<0I8#6t4KL>;bT*&CNd5sqFDpKO{ju1uSQaIbwGsZ~*Dt%uDnz+X=dq3=q z7AfqKozaZYdR;YP#yg)}#SQIAliPJ#j61q~o)ZA48T&nD99qO2%LLi$L?7z6z*4v{ z?Mhtuod*W))s%y;xKK4juUR)d zUZ+cQJC+)&&PiU5CZ>~cp3XZ2?p;~$J}?7M8_sKw%ht=r^39(o9X)8iFDn1wyWP`H zZCG@htK}Gd)LB!rvH^*zX;A+9%khZTy>55hBtncHir%rYO2I{{k^-o(ToXRwxzdVg z+L7+$&d`Gtj!eiIN!Jf&;t66W0Xun5p}UWhKav{~v-H;b^xU)1%+q_&x-$(oTGjV! z;f8FH;|UTLg}WU7h;;CHb@qNZowrIn-NZseAQnUtpzyH&vogg%TZW35i%!C=U?8)& zZ1Wd_{cq|}tpW$cioAOVdz-+g5ylfb^A0)5{tZY}9WOThLSB%y)xBHOJM4PLwFhJ# zWj7p{Isr5bzOJm17YpvWw)e>EuD#HnZ&SYu_ZvtsQ73#l_7z%O+uDvAxJ~*bZSx&= z4_&}0(;^()4>PH!*0!kZTV{QEy_sDCLo$etgx9#!5c2vF+c)206|%Up_MDHi$k=OxAh z4(;>r%dRD^OVp~{xGMBW9e|!C)py97dSlQkRCSaPKG4NTdg8qiWj}BigX-*}O4rxy zBj4q*UC07lMn3OsxJ|$Qt~9|xY~Q7(_!?xV#qic5$o<6- z`<9}zN}F8*$pK}DbOtm!bTKLW`DR}bQGb|*KFE0X#u`3w`(S}2W9qK&p;3Mgq=e}| zw1W8i1T_i?E{Ms_`E;^|>{k!6e61i#vRnBcw#fGJFT`gB2}7(a&li#ybkj42*6uy{ zd@1fV0gC& zv`6t0{i37VIkMu2g}FvNNAL8Vj&<+4s65s+FeU5c2#@FWoF+&}GCc?!0bXI}4DH9#ht+LFn* zFR_V+xj8^s?I8EHPMRW85kV`+e#k9&)$9e+5tE&-w_MKn{l!b_A@aN4{1K2pQYL9C znp>3oELJh1+j4WpUAW!`sb2a>JaXc=j1{&kwpw?EnOMPu!bShY9$k7vB!9S#P945| z{Ab-q;nT>l@gw?$`sy>(e^*>7upq2CKGWK+8`VtOyw{s-4+LQID&+WiomB6FtE>lk zAOQ&tck`h03tP^Pr5oPXRm7i`Yz-0fH%NPWk2 zS+;!q1HQQ!pO(pM0G_!zu5N~J$xLn%d7+OKQH{iAnoT!?@4a7^_5{fd!(duX^+68G z^WrSk-H3iduLJC;(X5YmLrw5DDy}6HS>Y0=xKNUujcZHm z*Pf7(&M#;f{_00zM}qvkDz7GT5+zxsxu}iywd^`%Vu9~^iAvmGj-1u?W=gWc9h57c z;qjuhG(qeV45O4-IX3>>_J!vR8O#EVbxa02lz$d<{(%^R`EUVeu~-vPe{5@f^dK8- zCngw5aRQ+0!6&JrGr)hzONFw5dvk%@g3cJOd%M%|EQSi;^v3}Py|O95aJwN~(#t?*Vfw+eE{p)WpFi6QN$3BH03@qD8@S5(TR4Osqn6$vwJm?&b z4R*jmqKI=T29Y;3G}z>WWr8Ec!BG!=vW9wY67$7{eZ?{OzqvKlu@ob1j)Y%M>T8f8QwKRq9wK!VE{@!W?K!`tTVU6RlgK0B z%o^31RUXo5?$i4fYVR68xQUKXw@+nj(TE>T3tKg@4nra&K|>x5N65Q`JWCWnNX zCRcUHjv78J%4)@y7Kf&)UXH;+myWU_L2~fUzL4cn>B>r*sV5x%-|#J%16+9RZ%#6u zh1Yq>2RZT)#R#TL0mUe@=IHO; zP!CjW?SF%SHkwfC>&2c^ z{lyMN>ja-)sQ~PO7TAM}#wjF3_AT0`Efa#Ue;<>U+>%m*)e1iCC5QkGilGanavh_%+@N6i05EI$G{J6DvA?Os2=NryT?YX@_I4t6IoFNB$Ru_3PaedzDzI)?7DXQ_W94cjr& z*vbwq8{)`m{IhL5w$GTADY>!3@2QK(Y4a9H!GINe1Z(mDvF#1E(wm~|4FmFxevjS} z8jN|id%6~ZY9mfS!pK{iaa1T8o~o4FBt`7h%hK8bQP-jI!6#f$ag7BB(L(Rdz$GON zWinz?fS5gB&g4fBKsKa4_C|KLj29DG)7i$PyS;SH8`VuB6Qsge~^L)|B-z92S_Jo-y8aQPa@ z?bX98Mc%7;18+)cGwLmQltVV}mYjEYN|X1g^%<@PH#OvT2F4;RL-|K15lk!wk6 zDi$aIBZu*y*@@~M<*<(IQENgW4VXYf4mmW|@1KO>sW^%=d-?M9tEouP2ubD4IFmZ_ z@KGe5*_LM|QCqsGfPbTQWEtAU0H302LmFvHNCB3I3rc*?Wr!D@C)yi>7L9z60zYMw zni@oh07&!Lpf%_T!*_iPaIWzoD#=<_ANOHz&8IZgn23`iOW@t$$k08LV4y@%(<#wb zJE6@n+)ux;jT}+fiX}@TyG65&aNWrf>nKJtq-zsD2sQT8UrjV#Q88~Y1@X(P>dTjH z4%r;n42w1Q-1im#rjIDCDV!nq>CuN%(B<2bm@p~%T`bcwJEL~=iNxcgoRXw^zN}*W zpwkAk5xmIPaPi*Uzt)jf@&mFYH@}$Y#eVKPeHjiy^kM#=xwTk=83muB#ULuQM9rZr zl*qIs_73O^RME}3`oltbU**I$eL^oHGwl9LcPS&Q=+nS>n3Mtf#EoN)F{khoe~06A`ff z8W&W&H#a@-Sv5|a{j@oSjy{DKiGl_x{i-HNlM9c~=UehY)iT%?98wlEhZJGJelt^! zVHIUV_X&|1TRw;GKgi=!1 zEJS-_J;ybQ#>uF&iD>2jcl=ucFLlU(P2&IiO)dKy_Zyn<|3nHBz3A^|;4lH<3y z!PN0f{Am(1d6ZQA?SB|G%*PA@(Bwz5DWAGNaNDTf++l@!iP^R>m4=(wIYuo}19vI{ zk_K~v9DQh`X!>G}_gOkNvAvDd*P`u(tOu+qn*gd`{C7lq+25Z?hy&#Q#nFS10uS6w z3a_b-Wbv3jAqOryIL65ttgrZ#9(MllTH)tp0gM^G{^j(2dORXI^(xx8Qu?t6O!PU%(<{?I_v1!znF>$f=7+9&V zULgw!5oZV}YxPt+4jO(sP6)c6nC})A{h;b75u1>`a_Sr=I$)f6TY}1E@m<2p&XtQgU?Gmvi@YakP z#sz8;^%sSK+|vcxn*13ALOm-IkCS!q=G1hEbUeYE_243|b!%b&TQMVu=mEXrN-X6| z=KPl`vEXo*&vwl}epj(!6yc~LARrJuw5NwX@Sx6RA(+57)lNlXfj8wFp z>LRrq?!KDQ<(}s@a5k+9`3g6*6?w96k$H4pXpTrnBuoQ_)01DB6G&|wRQ_mU-ih^G z)=R{iEZWEDN-i3b_Kfp*A^G2d#rt$=dd2@uig;0g*I&97jXQL>HLl9X967HHxb<0? zpWg=8AOW8w(>b>G8;A6SazSG7z%_j=<)ueogr4+bvWMM?jnq6(*GtHsnSCou zHcVF-Pudjp;)*f~LelM=k`l?UMQotW>=qyprgEd6hOTPU!8U!s^ylK-F*mc}?fl^Q ziUF=VGAb(^qqfCojhn@k4^vsokGZ+Io3Hx2yWe}{-bbwEL%|`82-op&%#vX4sdmN% zb|dhy0S@9v{FS-2H4(OAE0!Nx>Y8PpN#C_3J~4ieJDZ*3Di$D=nhuYUZthCNRy4eF z#3$nmsO|hav1i}*>lb4}wwwCy7CfKoOe_$}AV^8n{}%4Qx^ z$7!SQ_K!~juV1+v04II}1A{daI+NcGH|T07q68YiL0cnVbFy+vV@(O)ry%{&vF)<{ zajJ&KhNe~f@sZJpsVhp?w!HW;c@cwJ)7>;R+4ne%V&MnA|kK~g8B>#JmvWvs(_{r*X+Hz~&_9uuq zDsV=|VXdyN;jafa%|{K~WE|%vR=iAP{|oYN7uL&DvBnv939Vdx{p@4h!z}Y=fz18>uOy; ztea(qW#g^3&#ld9$y~{g*5oU{1&V!^NX}1|z+Z?0I}kBG5>3m{Dbaj14MwoG!k5x4 z4g9>fhnK;{I(2#zF-Y|Xw+}!V`fV4Dsapk2JG*umMJRyx46}9yZ zCH8tx4`;r$=_ji{?`qKxQ{_j0S&Ld|Vhn{fMSGqsA!hHLmmK7wO9eZwY=}_dO z0EtU}7Z)|QL<@7FgY#s*#(!3GRDPug>@M#z65Z9T@8M^qZeg>@bx=pTUw9;f)+ei7 z(;H7$`y8h3Pf3NoioQ-Q55*4Fk7{igw9wMgvASV|3JUt(+yt@y{H?TUGkAkqV(nM( z24llPVmMP^eAToPeO#mg*bHaq6{Mcc3b@hL^uS<`jWCjh=`<3Q@rDoMYk@~&P4J(O z%V@k+iY6xG$itBzWh8XE=7>6DyBy1EXmDryKICj>hC4$>^BM1eKI4Txj>-$|Y~8-B z%#kxq!OuD6MP9M3e4uAZ`QLa$X8?5LL_6Shwb`J9Cu)eUc<%cu1blp+dKG3bLZF2_ zXeG0!rza~bYkPZpetw?K@%}wr_evSJ|NaB`)p#cBn5LqsZS?~RkUnnc--iDQRVT<$ z)DO>co0)W5N{QT%o~z+zu|0Qo>Z6~kF?BVT3<3t8J32ZRJ0adP;be5okKZN?`rp$6 z;J?Au9nQ7!r2?WC?M*hPOQr;EEEsek;3P{9oZ5=bSVsVFB99D!9M;?mIN%7nf@viEiYUk10U_L%M-y93^DBaOM47f<{j_b}Ovy+Gsh2 zc9l=M-@bb9tUjohpRid=MJ1~&{H$mEqC~BBU?63E@nw@#L)TE2kudr9Z#v7SngkMm%x?{uxfQY21Y&{rSO z?;JEfBIaUy=+<_A7k?Pq+16(HRM}CGm9?${>W&5RM7mvE{JkF4vVLnBE-lsf2XTYz z>|Eg7UsNe!g<}hAcjvZ3rwduuVqswfs7H5@jD6c-yy$r@;8k}p9~NU>wqXCqo)Xgf z_gM`U2(;PKm3q4TZd*}dFE|$qOs)*b|KO;y?3>0-oOG%3_T%m2NlLKdK8lwzl@ncd zMy+(waR@l@OjIr_wY^u`S{{-W-h2IqO7_)AB{XS00+M0VJ! zC~aL6>XE-M%WxO@unVjk>FJfN_r|rhwY~dss&oePN4vrK4w2-}FUhNfv-74gikPN&dSTA+7lenT^kKI!ZAeev{%r#=qFBOiLRv4p`x0=;Gncjcyo(d7(ZYt1(UH zx(KQ*Sv^Qc#7}E-VhT%QIfvGtsWrt7M(jc>rf3-GpZ9ln_6P41h!hv5HVeq0YBxNjA#OAxVFB`fmX~3L|QSU_5{f+Hkx7b#z04z`Odw0aQm{Ub^VN z3Eoo7Yps^f23ffpw#|KVYV#lMOl;A}Y-$s#83*h_m`wtQF3~@?WPQ&RdJAZKMHAr( zSao0Jbl_UTYBQPttS^W84T~5?DQ0gHz|8FF%+~xh(MVGjo*>A>7-c{K!?Ci}V5b#4 zXI6kZW$ReE2)>|KdP9fv%}Iu`r@#no8zz27)(b9FzOz0%I4Gd9`-!Czd%*clfQ}-c zSC}W3P8f$xJv`|)A3en*$HohDe-3861Rn5#-TJtEH*HePN19~Oz2J!uYB#Ou=^-riUooZBK{FJ>9TK5UMc_4_X|2&P^nur67L{UU=)z^dZeV~WB79OyOEFp)W@0&;{?CD`<7GN zJ_N@2i2Rao&|ny`b2N9~*Y_!xl5I^U4_5;a1ufVw!wB>Q#O~M2d9{~s)N6PLOtu=Z ze*&hkHOYUNbyiliK_}YecxCueoE&}KVV4o2R2hoerE%tp^2i*bF98y;wV^v)$0BHY zDjzBU6*v4j&`OM7GC4D?9vs@aR->!1*l?IXN=otL!IUaOXz1GvS+v6RYsqdi)g9Xp zR~PvdU5|U0cNi2xK^qu+BHC?RVLuF2VOVVr^!AQZ93JkU=xie5bb)lcCxb&oBu{;kKXrw5HyoLfhzu-O zTSDIU28xZwi%!I62j^`Sqwj`=TJK=Ho7zY%{xwg&lmUs7XMmkBd(z5q>M`kX_iTE# zwIu4ZWyRweJP7#$)%yRU!Q)Co*OJ?M!PI6gmKR>pWqFf;gstAJGF{9X=iH*wCrNYj z#YOl)d|?WlT`_9Y%fq_nje|qds#W$vQ`#8b&|6v(;p=`i6a~{HEvkrSbEnH@p`?(x z40*OZ<*yOaNpumG-*r$6-(V5;?0ZPTP!h^<@%kLmQ8Ae&`1rhY%qSePjrJi>|G@d4 zliGIniREAR4kZhWF?%w{yHMo7z|<~|Y9goE{`KyPki;|CoWpoHh7426JX2c|Tl&lz z9eN7FucR^!K{}C97H}Aa=%x4Fk#B(I&?`^+y*{PxToN*cm4f0s9(>S6F{J&72*0yWj&kbwUKV2lUHL@p*H8j#ig!pPSzbya_00Ty$UMPJwc9|H3{J+~&L zueT%Mt-aDAxzeEl&b+gp)P!`BHI~Po-EwpH9zj3)DLK2au&@ZXSFP^Hnz{c+PQ!YKaWCG0}f4l#?zs^8dSIEnCNI5 z8(Z|3mlyy4CqqWif~=*Up15Q7@f<k z@TjH@BvSt&>(Gh@ubH_y+~if~*_pr#Y}Np)4RtSbE%yGi=ZjVx6U*%Dc9*TjE=zjc zxD&y(9PobyRk+|5puMFE5yW;7_QL9|dgW6ewPqIiT_~Tk2pfKGdFfkTAW&TCv~(Jo z8b$^$lO_2-efE%2vcY1}0*fVsTh-d-_%Y0asmynu{uJRe5<~-7|D{#XYqe!y0)_Hp zY3r7muU`M$_^cW>F@E7qSybiV6yNM^Nk#nsU5Ygp4O}z}(bjRf9@Nfmc53QMYV&tF2u-ZFQ~KKOQUz+ zWy&cjK~o5%Qzpykn3(Utg>C0Va`+lakl1L%(0X`TWv1!F9<=p7f3=*?()pc(m`)!ZGpY_Xp=l;3X)svsI|KNl3 z9$gxR&4VqCmpV*$5o(~lRz|jwwYNvb&1l&;xUI5iJEW@R2PBx05)dXyLG;?0>9nPQ zTkJYBtU`qn%ceU82F|;>8gu<~iaIKG9iG06>tSTbjgB&&kaONPavQcKt1kTJ6P(gh zQ~ji=<|^#Gk=z$0t~pdM@$@`U&#}*PfE`_K$zsS4IYT+E5~g?$3=R%LxwTN{YO;6) z2HCXp{lylPPFbnnQk$12h74ryu}pM$F}<(I@A!OPs6kNotL=>2T)#~h+*FkNXD~fR zYqiww)ViW8%e$kqMVtT@YRw6wo}CpHaa|wMM60X2#RUWlIxfggN5O?14cdA&3VMIj zpfCIDx=tZ;fb3Huq?m?uX1hJ@3x#Ds-a~G3mu9duFDziF?B*AsAqoh#4PO4_ns2cE zBw+L;2ia!5W_|4K{>F;d@w~xArx}V2u#73o^E+)7isVqi{L~j}e&`q|8aMLxs z-K}f8J6W&wRrdMymnXT3wWLD8)%0!d5t3wz5fJsj5BEk?7}dp>|Ox-OyWaJ|cPw6}+@)wI9B| zIPkxGZ{+}Mc-~goP6o7;+wB;1k_KdpNC5Zg(Hxo%{A{M4dWvR3{x8-P_IyT*I)-k? zi_>ZXjrOCh&h{^bH^|bMWI{%pcl^;VtcJrQp7(`!4Q~;TyW&X&y#E}?Vm$wB%BuwB z7*#`Fp6)CyEcTQrSy>(TCo(^O{`?W7l9nB?_o;H)uFc7Gs58GPo}4c=F|p2WT3&K@ z_sNs|_~dZC&Sd82EC-`jh28PljGrMiSVOm-e0*Tz!T0o{(;26b&Qu@;K3E4{9+}L} z?oF)oFuAP%orv#0rc;CZg_Y9p&b;;2$RA--zN`XV_q+9p@AxmPZoI#&@}zG3Gp6m$ z2hYH?r!!`ly_IceU5-g|U(cIm_u~Z`gI{C34I*_o5!umomTI1kx=rW#Ata5CZBDd@ zeinRM+({eS4M%;C6I?2XX zG}Rvb)^lvXef2H#AXT)n?Q%7TROS!GGlP#Smgna?(iiBA#$K(STFC?&!POpSS{pgg zIUBkeXCVW4h0CTyxJVXw&+1f6MFF=G0228M5g;_@`INQd@U)FM&stvB37MQvG^!_m z`F2BisB=8csypewB0TRg$+P!LFPb)E!L7sOcY>m z1Kd9*i4+{5kRBxRtY%3_O8SSuu{MwGO8NFH63~;#1SBC;w>;Bb8W=5^zYMw@LwP^s z;CY|t(V&HVNH*7DS>t1!L&DCw67UsDv&db68>1?G11M}@Uqr|T;=ZM1!D11$!@xSU z=G4i_ZdoN4g;HYwVa391Mj78eV=0cFZ=I?6p?K1bQGgGTGe@$YM;J`yDcL0|V%P*c z&({Yy>7h*%FvhiU-Gk+?q3LI9qbEbcjzZUbsK}Gqt{XKx8J+@)uPVVJ${sLMuv1m> zNEd3GZv6ZEM%@1y8?Kt`qq(5KoZXO|^K@Z;{?eCAhtJ$NL3#c`Lqp^5LS}XY z5i&5r$;GvW?{~GQNFxK)jRZgmjJ@RmqV0BQ%}#FSXxkj@UBB5R>hFPXD&LI^4^OfTZ3_C&S&tqa#xqqXM*U$B1h3bZ-0J=Y(X+u?^T}K=rcH zpbZI~{2B=d8bx~HfrRY7!&+@Sd|Ts)b>nSjy74{Hv=cR!jC_%Qtl=O3#0IDUd`+uN zY_eai6z<5Z-irt^XiW}lpNJ`AU;6fH?si_lw{$JA3xPZW#wsMV$92TF#qqhi?XGHMVou&w&LP9;O2bT_5 zB(S&~$O~pO6yT;9v^hc&=^@NfqlZfdT?lwQ-#aIDhe(3NA}Bd%ZIKP7HK7_FG6JqS zuWtnmU+ES`A?6wE#bZ7I3e@edqU_|SdQelyt1P2^w z6q5<55Nw2F@xa{_wV_|90puLzXC8K)#t&v-NO$+$wOi@N3V<|2;?|4Ul8vFJ)x&^Tsr+#dX-UE`Dju zj60?vvcFn;2s-9b4RP7Mn~CvQhN_t?OHCtsO;pLmtt2#xI1=R0us(=4o@7F%Mi>oYLEmJsH#5)<^KmS4q3Ys=S^@L6+yKfwevR(g(EH%UwveI1>%#=T zZvJN=HeR&p^AT-D0Zs3GI@EEaSEqXd!$W!c#uxxg@D+yA9Qz`eaxzG(0jZgx8YuOaVTmS;E`)~B3f0_g` zX=CQB8pp0A-dWpJhd}N6$^fVrfopEJhdHeaYP5NZ2F>Dja@`k(9NB4;*&6tT>nao_9<$=7J8aoCQ>`tj1L|u4CUV7T2{7%+H=$ z9lNh~+LqaRUZb@rcvQ_C9a6Zv-}2wrZycl^=AT{pNFh8uA%xp&x>`!>Nn7rB8$%+$ zW)80oPGj$+Oz+%03X(JrFm1f%)#iUABRV?zq?B& z;1PSoTf(sW&IVa1@~8C7dOnm&jOCi?P|9+BnB$o=8HDmHD>c>obeSvdV_!2h@4bnq zQ#?EXcj{JSJQ2?a%cBcW@&9{N6%@1mJFUAKUP_7gH7UQ}VA#<` zvtea$9P*D=p|og-rR7alE4#J|pT~|AgwuBNg+)4+(G+C%!V)~u;{Csn^T@e9;XxT>G4|?@ZjO$t@(NH5AqX?w+LADz5Wgm z82O$yWWQb)C3QLPNF@Qi;iocp=NnLzzs>X9@KUf{BMTpA*>5sS$WBde2Yla0(L2G& zz%Y@)C!U}}Iom7!XUiCx#z8yqFiSuO=OV8=A}%2w=j-FIa)RWD7^FF)ySuw+tSihF zdQE2(uUi!Nk#UL5A?+3A*JmCVs9TTCToa3CdSWQ}R`nh!#you6$e7Iq;%N z`E}Qo%re|iJ!Xl5RCKuO1%5VF_hfvZt~)%rsIX|8JC)~KaUD8h?hyK<;&@m>BIHp4 z`7^NI_v6tsFE7@=rF06qt$(ESi{_Zr6Su)vPjnxg2HfW2$+)!rreL2VbRc{89VPG05KH zG@U1T-hMTq>_*9)lS|5E(0cvzhhbharpWU}9MAgw`dufY^6r?PW5>-71tdi)Qh<~P zzfvJ9BZE|950SzTI0r*s?lj`kc^nOEOyNyKI#q5icSlQ(&tK2Zr(lgU-b2rBe6vBS@$3_tTOfj4(gks1-=PlQAcaJ!~73luu z8;v})^G%4$;TmJEhr8@L{%GC*&cH{G!WtPT@-$IJjWhOdZrB*Ipf2c(y7>{u138zq zy1r4-lcB(~AqSUL$b;?^a>b*4#f89f9ILGsL`D8Z@pN_4SMBvXWNgStzw6lY2k+}m zx>;9s@3lbLIK;hfx9V0WTe-So+>KVNHDw2+k6*ii#~i$=j~|b(9vIw|&wMb1l03-S#Km+(THC z+%JYIgUP+;pVzhoEC!tdxupLleuB-wW-p^wWjApGxlpUu-))`^zeIH2xuTyxe>&-V zY-fB0k#xN&rjzoNVe@;F&qdSqa=QY({*NG@GkGHlkC4kBq}l8Q<{-mi4M=!Jr8wzfI~vwY9^_($pAx)euZu#bMMDv31A z4_5E^^O2g3FOXq#6N=VsJWP0|^mzxvcf;N6&+(PVCE1Wg>5jMQo^4qDfQSk_5iuWH zGjF{=P0Hexp(bjNQhrj)@-aD`C^B*v>@c6LUc8?zGb<=EBJz!{AHJ{oIcTJ7@>rG5 zv>|Mwmv|`XyJ9f6)6n`Ho&Lx*&dUE!Vu-~9%5iF1N^*9sub=iQnoiQSV(K*GTJ~?U z9T!&`H+REJiZ^5+JSFqsYFJi?N32ogWy+6p=i+jY%f~P3<6T^sp|~gWOeHz5Zxxz| zA8fshj*dS&D_mXy@#OZ@Xv1|EPbWFQ3|4&m9o%aQ7wGPX(9LhbzEN2*$w>c;kzUY; z{llr8l+vproaklh73rUEZRId4)V-7fO`DpsEewkPWP;t|%rJvG@UHAE_bJI+wKlS4 zrqMk+M96`z`x74(-mVfp;o{(2MC&xz;7u^_IIIR{_6?X+VyU6cDL~m>o3&%WMKTvq z!`i(oRsbKG1+&%JOk%&*`aKoo6U2&}LD;H{Fgu{td5Py2q(V6i`)9ll6?nG6!c&(B z@&avn^^GBC<`HBBf%8#@`-m?4o2yNZh%ogFio=wqrD;F#<|Jg~N^v5-&ptu9K3@r@m#i zio6A~{$>Xpg}Do48~*X~IV?7b`uqO(@2L8ILf*Q?`)jIqrkgvXv0abxhY38X;1oNN zPbW5{7e0PFJv@F?uuxBcbH)YQ-<8&BK}uY`p9?liQv!=JCeJhPnSC}LSG+E=4-(;+ z01w|AH1eh)k}-5@nMn%(a|cQv4qf(o$s2*AC+31NPKw%IgaLN*aa0-bieDexP@ zE2q`PHg&<;=y?-CEXk0b4@)Kh#@fW znB*3C?z6H9#t$YtM31W4r&n)Lrru!zAGIh*A6IZ;+9BJHwjCc$?kd4=6* zqACCrGE!jiVM)}2Winy5q3QD?&dy|)!}A)~-ahUrA2WHG{FP!kA^tyI{}u+o*h19- zCyeNafaiNX-4)j>ROeS!x+lblvqpEcgn0M68&5ZPOpJtjD0$-U785OjO=L=GGhzL; z=d0>OU7#06G6;GjCN$6m8}}ZiKicJJ1m?GpTm$QGDp|jROt(zj_=XoK6oAmLo10~& zH7zYfia0(N_-29OE)IA&oS%^U#Q}+UODC+n=pZ^tp!kchLn8O5!nuH)pOAp=GP;jV z$8;h>@H=2O5LO9dmSN!}-m}|@hKrTw7*Z*tdWp^0@oKLK>3iDYBg7{5pRIIq`))U{KT#bnI7%()K32s&Y~ ztt0>)U2q-7*m$b#ng;Uiho9Hd{qtWL=ZCDM^-uq-5#jDYDRduR%@kOc5JlM_@Bry3 zEmr^kN77Y>McFmsXP2crr34fZknV;h1e8W4r6r_8q+w}9N)V(&x=R{lX%M8lyOD0# z{nq#Uv)A?f*lYKkXU@z$GxyvFFQ)g55*w%;oX$z!1E2UDpQ_&`{arvZO!#X2MZfVLyiw3-iPp+rjOac{=b@;2*e?<{McaH(Z=uMlAZ<+)YWR57DXhQ%OpedxJ!GW+1r{&GprTmO>~I15Aztzc%yL1IR&aIt(3G7Iiw#z%i(yHYw@gW2-2~ zTYBsM%n`$T`q-=CasbN>-|Q>A&B*e8{7+(}0-)j59R-YReBO|&_-FNQ>{cwL$h474TwV$G(|G+Q1V?P|31mgR!jH$`VlR~Eq`%y~! zODMy^aLzZ7D--asz~4M7@$N0>=4;Zwh)_KhXAFYDs{zamD)aNq@QN|CbJz z#Y3Ye177y`|9fsE0*Ks|SgQ8StpYZ>_{u~C@@*TQQ3Kx6oTmF+KOq|lu-g{=3+d!0 ze2pcl&#{8&w)ZJ)qja*Wm%O7`X)n zIawkm&0JVw_~uqzpYYA~p?`jM88Oz-9vr{G^t8y~h0y%~-vp#(>DFn=-Du!;1jP@< z<|)Ty0~#QN_t?(?By(lvbZZs@R{@ChhH&yC1}u8o7VJ3>&u`xk@ch5%g8IA}l8yv` zO4CA~QfGZdpKh`$Qyp#Xj%U2)ayGBEw7vmZyvNE(T=NUnjU3{0E+jDww81>)>IwpH zY1TLaYqYYw^g*E!6J0?wz(Azu8nq^o$GjSmluv`R9qjDn1$i}4shfuDmXh}qM<38xF>vO5>*dJ^YxBbe-~9aG>9v{Vec03(lRkKj{*b@M=?df zF=k<#E5pjA>*aT}3F(_6k4j`CF<|o+;0^S%%GbMWdaz>n3?>7CS^v`JGr`Yf>r( zL^0A?gTj|!;-yhCUA8H0VRM#`pNL=5irSw3qy-bznNarrXFWPN1Z#LW=Uy`EJ1{ca zmZQjiSCn{Pvl<|!PV@79kg+sYOFm?2h!IpdXrpUGC%uxep7*RXu4?2EtV?n{aFjG< zA*N{ee}Aos4p(NBlS2u!q!E&MUFe8>0v%&n0p|$@Df8=xJM^}M`M;plH6pTTglhMu z>55}02y7C74Z}1yQ2NmZ=R1MCQ_Ei1%ou8;~a&~0mIN2ouQAY@xLhIOYidB z|D3LzAZcV;*dkt#7&Ki$ zCMded5kf8e!;^)G;+;6(p8Jks&6v~odHZ^C9>=v!4luOR1OiiM2&X#HdUZksRQlVN zXkT-3o|u~+(0lt&8+C?E=X3FGwFEnqerhKkFgN`Rr8hS7d5G&=i}U2gU=&l{`Zbe41oPV9X z?5Ri!Uk<00b-;^>Tsavy7hmc-SP*3I5wvMc{Q9D}uoP8`*X04jIf%L*d`d<~yz7jU2>WYEc+l+E2)SZ*{c<%Kyucjz*rYVOw1;3RE>#9qjcs}|9)*g*4 z@H=8ax|Hw!LA3KK0uQ;JyE@+(s)L!sfvszIpUm9DDautd&Rr#gDijCfEsz4r{)2oq zX$Q0%x0I)PCOy7r#VcRE>*3!Z{*NduyZt?Nq?MX)9`1w?j-u9U7jK7?mxt`ulZRB8QSWG42 z@E*OxR0 z`E+{Z!9m*j`9Pk9h1F07Ghu{v-Q3^NC$^{szXYx`P2{~WrA`yOJP?|uPf9@yLcf%o zYYfF7aO1o0PgrQguBb_jdDHYPcNXj$P7||z>)X5eU~-|UC3tA`k}i)JYE~89!5Py2 zsdm>gjjKn))JE1=9B9|hC95<#XkS1YSfgA%me^G?e;(P+T)w`;hP$v6~SH)>#Y8I97LMJND&6gw%svp)0r*)o0pQUhd4tu_2ZEg=BfI^hmpJoRO~hFu`sPF@3=Y71Wa zB-2sw8ADtv#gte6C+_b#$uut&FNi)kBb?9p$vE=NoF;IXFv8fB60J7(>TvG4KhWG| zRZ)JSSo7?+UJ2=MVqV~-w*yg-1b)`UNR<8d!vrFt(JW9%Wi)iW5v%$q@03`&IXheS zQ8+MSh*XTIWkRpFwugh?Zhx;mpxW*+kWw}=F|o0+vBERd$NqK6*_bsGMtCrh|4CBr zvJ#C~kdKVEP`%M29DgtGlL7{FB^&}wdmQR7A*V<(lT#j~F=zr*Th)*GzeFAxIg3cH zVKM!OqF&T@ItbFp#dph7zphY|s!b9h7~ucj-%--NanVrwQV6_03@S%X#dgiZYS!_v zZ)s6{rhh3`xHxZHID}UGCe+xhY#5KD3R~qdlsUmZwFhdzhNIu;kMui-=31Ff2x*w; z>r;an{6;ZYsRqO#k7|U2lhEao<|pmov{-;FI}gXP-#H1VjB~oUdo)cL!73A`60wrB zStOd&TId)LM&ikPJFB0j$)_7KFW}doQLr8>7=k}jXHWAk^OP8)Kt0n^V1}4#Or1RZ zsl)6q-#cA#L16>N;S3a{T=Nq;93hdSJ392+ZUi)_SA>^%)5|`2|M%)wK2rePH;>vx z#AcS4#zsaZGUhz(8^jf7#eG8ZJaJJj0G$z-V8kU1y;-#hboQFFj@cs)<2HkbR+ew(S(uGY7*hu;n5~^yO7A@y$wlKtE)J+yWYe1J0DeSnBuXm zLNOL?f-%Qk?9N;n07}vZsi&9*;(}&D+mw4TlbJ^Jl3rvsYMorWu&;6tnihBr3+V>@ zjMF}~i7*5B0Vr5XS8!30oWYMZnV*e~Z9+Lu0M^{YOAX`I(*Q%QkPpdoH_Ib&^i+45 z(qJe$`t6Yc=UYiTRmMSM6mJc+L5vTrBen@ybLs9!-xi-Yd_;VFZ73-3?~$ec2#AUj zOqks4zL+F;duxGT&wf4_bx8UM1Yi)#9L(xQ-CjhoGl@pzmxqA<;WD-|%2Id0Rn@j3j_xf9#{FRZFJ0a(;Wrby-xPx{08 zT8s5tgB#H%fHD)*H`G#X`UkVWK#g{xZF^%>E@?e|wv2=8!{Lt>nv2QJ$5+GT61qQPcfjzYdR=?DPDZ)T99-t8XsSti4b+B(JORG- z_Nlmgv6POuZ9Ty zj~{;GTFs@Rm9`4L#|KKlYAhM=^?@_wZf-mqHVfgwY(kvV+RSQ9HGf6N?Qo`=EMA(} zC#Kb|(Sf4vBvz41_vt?ir5?DjO5^)VNt|Z}M>H2PIt$3e{--AGU=qL~fWflMws<1| z9cFB0_tw!GTV2xSQhFHz8v{ahdbElcq}t>m|9B=p(4ndpyWZ?eh<;`6m51fUDO!_5 z&ZulK5TarDX2PA6LOCg-fP8V@`E$CE^o0olJ9`qiBPpyXuP%79WT!q6FXS zjB{%zP()Q=hPMI7*AiS61MLw&%=n?3xWpetru4sDOCbd_9?6oRX?3g`o0D4_S10y)pHr*4H}v-(q^DNzvcqZf#^qX4nF< zs&{CK0r{)>iC>#HB{vVv4=olqEw_DFi}faY$E0KrtA?V;9XK4#^&Sr_g*(b@5NeB( zcm(ZGclCrD=l&yqID<$eLX)hxpiM~iKi+di1$6eunVu-sKBbZ2mJed@*5X?C{&fIq77PuhNH6Q;LAo@oQI8G2^-sXwu3(~;Iw`^@Pd#po_Ti&MR1_XY9f*boTarrh#XIrT5AVZ;8ZM}|3TXn0q_rr% zZw`&5-`Cxbm5klVt2>GLWuQnt*iK&oE5SxXtQA;F6rHUPmhfVPH(Z@R0N>OdRTKY9j>3Se!d zKJ&=*m*0zr*H|#Pq91)ZvJV(UJ}dYz$lH@#+2$TG8^%k8n8R4N#*{Pu53EvRR&CFQ zL};8>eTRRKI$}xP?Jzd2QfXav>lKdDnGm7|=6<)(*njB;r3W=iI7oB*nXT6B zQ=GwqXL{ej#2ILk(?wks>~(05qTrOQTl7_0Sz=iA>dMvt>9>P|p1vAvYW}1HY$)BO zws{Z_b!c}WCp@V)%?ugLX7j!oO@iShC|BS;;nkN$&4?d&&zGcYT`?ZL3{5Z0lE6sY zmWkMRz^h>Zt`~)cKj;~!NN*ugCJkl>QPB9un$TC>WNy6tZ~Z#Jj{jn*n!kBPTXiQ& z&M>ATTZ`~s!kIT+4d4*@e}x!$6zsbu@u)d3*^xtY#0wM)4ytr@8-A;56AWOQn&CummaDfp2oqd=`M#>`}sQIB@eVInypWKdQ}>xrK9h@ z1W2g8qur)R1J52MKF7j^hs%5_`c?_JG6IwoHeKVN@6ZdZ^hnH6MPfX*0+gB-896yG zHhd5O!^At@0O#rWagB+y2`DBX8TueyqPqH%hi`SBXO=@w1r5^+)t8r_m_T2CB%uT= z7~q!&vvN^b9XITN39?+XY=fEegen;n?o6_h{GvxyI4uIwEBg(_n!o9M+w`BEhcE;8 zSiqmQ?a<2*x4D>T8)eek;j$?|FRf;A5k!mlBI43-8eZ7Dc`0h>S24USxYIPhFQDH_ zSF!x}JlW2OFUcN+8#uXYyFMf3XXkn=hH3a`QSHm(w$qJ76&2M4LG}m+qWt7hvb0mz zVKN$sr?<@nwU@YZzzQfZnX2dWxY7utkIjn053css4V3t_lj;mpE~z^MD+h%`%U_0S zpNM_jVAPP~yZbrDhXL|>7!Ey((F9(9^y3RX85Y+Y%3sYWn#~06!Xr|V9AQjp%t-8? z8N4zMywt~zl+y1cn3>Uu1Mf&X`$oQElIQaAh_}OHL4SD0>AC$(6QVMo?}+dPd3VX< z8*XW?8WqZ9IoW8^y=!>!1g~#cHEo(7=%GFw^G_m7_2(o5!ShZ0f6lH&o7((2oJ1cn;tT6Zn2CZCr%M(&g9SqdAqaQa5`P6m=lk}Ad(Kkta)3l-H z^}KvX%h7Buo+z#$+wwNL0S%hWk#@0(@y{F8R(iH)AU%K1u$E{va5b* zyC!&k`>&4i6zC{h->Y~Nxr}dNuD#42IUfJ;C+MVx5_ly786eN=n%`xwrFiNF5# zWqLm~Js~UmuM|SfTGuSK(_-p;1vZfun;p6&*I)uRN4WxGB1_7<Tqdf;R=q;nZQD#fTqqpPKJpA;K|q(v~Cf+7VJoRM4Qke)dq@mD5&J8Z=@+O;#D zt$Mc12A}d8e|5GOa7qrfKEiY@9vs?zRy^4|(^4s9_Mzi`c$r~P{WuskZz}Fz1y0&* z3r5yA+Hrs{Z(B|Mjhu}($!*d7jd*ogdxq&XQVA3=_-QA3AEa`q+)!Sm_Z=Yd9&aRs zPwvqN=_F+}(tq)`(f6Tj66I6b~ee3XkcNDgy6?SgzV5D9P$B`z|FvB?Bpxxe`5!VLp4tA)OdDB}DD!oQy1bVu zE4Nx0uc#V#KE3TrZmAmRRvowRso-j3QNooKzIUXT~su)(vQQM40+Pbln%LK+Zw z4jC{WeGDcAh(y0n{<_yWl=l3M`2G4aQ_9@w+dU_x~P_jjomuh?%g^Hc{%)H#7fBPWTo z-!r|5RQ_9n>yBK)hK?Npx}CNT-4W#S)6o`DvHv+kPeC-IdL zpz_b27T@QWh1ckKJy)+5gSdRWZxtn586B3^1gw90oFI-Ke@Z<>&5@!;u0-lQMK#zV z2VC^bPAiuXqt>b$z!auKymu@T@~viXP> z1l=1Q>k=c7^#G#ugD6CvdG1n-|Ek^ z;223K;{AIslKgW;BwAin0P?2%@Yf@6Ic4*@Z*kyRK92)8CCaCC7cXUTu><2ZeC}dss|o zNusXLGOZs1u6aPRxY}jm--tM~+XTF(h`iU{xGlp}aSDT)gv z%DKH%aeI*Hyil=>1%l_sx2$5ZD?j|Wn|AkH_Jn7;Rn*-Z`5r!2SZZME!e&YUR+gpn zFfEYj$XU0epHtp7H1LO=JC*~kngi{IHkDO`Mkm>EbI4{%ir7z(@g4;9T?k_N_?(0F z)X057st6haghx7qv-XS9m#(z+V1drgDVa(@2f%2|{g1A^* zs{eatWlGwx+}GTx>o|q4o0la9gOE5;xxSGtr-a__FtRprpn1E*bk~lWOPg zYyiVr7x>G;dZ#*B8_;=Au3<@^k_#dSGq}tX0i8;YV5fDNU#sl%>M_|`Q3XTT*dU^p zAHY0;T-OhV{b8Y$B=~%?PTCf8*qlr(0K-I4O4*O-T;%N&^NR3>z(SbRhXU!RTu?9f z9Pc?Kk0t^J$xlrv z&Fpq%U)xFPQq9MH5mdNF7Ha6yO*A@25U4xLw0DPJIR7lyY$8EbU$i>94 zL?ch9fe>+=0X|%1jvE>2%t#u^u!T2GgqMyxV zxGRKm0a%D85;O(~R2~azLjnU?7HB3n1Owr@AdtqAOV@7=HX+0|q?FJPodR~+ULikO z_zLdBY=!kz60$a!#2bX;e?t4(Vh2?v{;=i}<*JJj6vNO6hEGMN1q1JeS!5__8L$&z zFWm;o^W7aNzDL^_zh{BPYNUME{A&L7E6?-GCtjZ=EFhd!8L`hkVKKj?B%9Cv&0R$3 z((8GG3t(skmghMsCmQ0>@}~mu$fBA z`~LQtF!4j)y%O~K#Hn&*)ApOK=&`}a%*LFJK9i3J|Ma$fL|xZ#Z?E;cgA27y?^TF_ z2TO*arDgQ+EAK)f&ER006+8`j6)ad^5+ktpHH&%~HB;1{azY;J_ zD0^v(%A5z2kPf1!rTuBOBP45B1RKyu;C1@h6`*N}87qvHB=f@=(={k4*+S$C6A{40 zcZG$ewkkJtve4+t;Jw8`B)x^jAe9fO(fdjp&vw1tjMga9G5si5i~n1ylM|MtY3{Mq z;`v7J8F|VYv+-`rRqGa}&cs6NNk_W4dK5QnbDqEd zJq2ue-rGyr)_uYT_}#so91-d){wka@Lqh|B>8(a?RKI8WN2J>3IM|FmULZ>rkPil! zG69eKj8BT<#BkL*%Q0BpoIxwdu^}+CzERBA35#1hm5p+~>MW-Ps@kud`1l*I1UC9V zmzW!d4%4~2J8DzUaHMNAc;>B1Nb^c&V%y~P#AM+ZilD11WK742fo8|t&HZg<^Sd#| zKsAXXnS{Cr*pu4)?eW&G@71FFcW&b$1U8sT1!rXiHAl;LjiUU&S%Eo{9pdp}Ltw#O z@2XI#oJ>SzJn*Mq5rf`@d0Q=;nMjl=paO8OW#M`JacFaMjvx_$?e_cjIBS=``}`pU zg*Y`EENCgJ+rbB5ImlEf(}p|^7s!P3Ra%sKPD|Sh$Z=L`Kg5rB>0$vg%zkxeDV1C1 zF``@WG?bs@6~On+A4&Gkx77XD!o^7GR+x(|>zv>d2R_kBQgCYT-9_a5I zlzZGk)9}l|YV*0_vo`Qt&6!i7&et>&e#gp1+^Io#g9ob#MS~4ACLMH^ZJhE+kn07+ zWjw|ZSGw$VfW8B%K$9Ok{Wg<*51gx!LEOWl^Ho!O4rx@Uqdl-;mLkn91BeFpN|I-c(S3 zU`H8j4;?7UPC{7pnnj&{to(as_*=}Z@{;lum-fHKi_InO^o5epmnL@LRS0lF;e})5 zdCi~0Cx`p_lM5;*Z-FNN@>tJ7H>YYA=GNN@AOeV=0K$(0LN7}S+upvkBN{2-V_T^H z5?qk_#zyV+Qti8x$k-7=3LXy)sOG}_09|C$f$_#j2y>%R# zR-n682fmKs>Fhmu{*bt`cL`}rygGYX}p9w zTu9CjE$TV(1#LXsbegB*Ea&gV7V zbcXN3_Q~~_;yrV(88J-F%F5pAFk}jsB~{JHu1!g_lFnWInz84sdmpbfrWn_UkQB~I zH4>8&gHHB!rgc<*&0v7~7tTM+e%uiw*S_bwqA+4x@eO(xSa&C5tv5V9~}3*&6p@MWE@!_pcPl zz_|W7Y^ug^vK+_Tquf8DDC^Kl0hFBCzlPhOv1wtc@MA+=)sr&xajiKYEgbntH9{DE zMCCLjZRdHj@|SWVVt;LM@w*dUK=__w!_N$J#>4Ys#{Pb>c1fwHr%AjQ3QGppFd1j7gNM=i-BNXlltjM zBkNZ8fWtP9%b~Wc=Aa1wKo~YNONP}qWd*z#;9789H(~otdc1Uk1Im9j9%93p)@NS^ zPwhI}dMX${dHXyBE-xQv1{#rOF5t$Eu(b8#bo4l>(o!ZF65)Xj9~yJ~ zX5?^regANjPcc#CX_;0Rooe-Gu+GwQ7QrLzwAVy8a+1OvM!xjZ*%C`hW_5#y_0Q7& z^(Mytu7Ys|F%%W=4^@F4-6xe;=5E39W&a)U(af~$CoP491|Dg)Bt1O3L!_&>aVjj= z$G^;Omd@#CoXh|WELkP;UEGdAQehl!52>3HA!^)KI0rg5G&2sIJY>ak>vti}o~e72 z{b!pcPN61CfU)i4gbb1a3(BAbEDY1`QVCCsIs9_#0MGYQ+~CqYc~8(BlqI&*yGw%s zn?kDOAkW6do=Gjmd8gs@%Dnmy+rjPSfJmA~2xETHXiDure1{K$_qt;}fjo&V{?=vl zgp6CHaN^?SF~22Gy9C-+;lxcS4&<4Y!g2E7r0lPir6dKX{e=@sPp1f35L%B}o^m~Z zimg?Q4q^vuyjj27o;5U1p6u^X1v_2j-jxkU=Hre)ImZPz3Fg1k+uyY2#XMMYLm13; z^j>8nmndQBdCSksBGiDvQxin`#niIl`w+Cq%=PPDdwtu=(?>TKsJqJSUF>2kTf67jFZt=JfN(635;u6{aL=Kx_T6FQ+>C2Ngo#d5c`!}@+mlwo*`BJm zaR&yI_fPj9b8BaalYDjk8T^du5h_J0hroJ6KQ_Mq5<^c=O_Lt?p=98kfTdZ2s=;IC zI+qTU>Z(Xy*^MWoQ-mE9|C3JI{P}z4aJ0fC%sm*7L^*j;V86dQuZbA*o!=Tuy~z=o zV$Lh-55oPg6*jrOw!x@*!bH(8fyM@Pc12}niw(|<1Et0_miRhB*>UqpKOch7jTXqF zhw-o`SL4^vXd}Q_s0;Vje3J1S1#OrXN=N109?XG3phE6Z`r=TfCNbK`$Dy+!;{qm7 zpOd8I=*^*`-PNB?|E-RKMC5oHBk9=ypH?hz@chBS)6MpP66mBkek9b8DYAiZ`?_?1 z_tkYND@TvZi^&YoxXEnZD{(lXj6+v?e?SEL#S5HxjOH?cOx}D$Fki4>L)jn-sxUM` z%(=tERWZL;u#-!sE9nZgVyn~gf)+OPPnJVz{mPjU!r#PH^JP%BuT)G5T)@!;*uE+^ z9$dR!9w_h`X0V$GaCJR4gGgB9z3#ub1-&}xh7 z(PuT@%4*nG<8`RXGMkj6uAkCSgEf9`ea6CDLq74PBX~#K*2bnG4(~J0v&dL8_yM7T ziB?YGlUU!%7OaN4_x&VqA0Tm^>1(jT(DRNL`65qWv>)%o+(z!KZ$I@ap*1zJCZV&Y z0Xt=nB#(Se-_!uzZ;;~t*S(kOEyN$whx_VchL=vRJTrCupStQiCxOwYmA6VkDHuY& zH4^)Rob|T>{Pd}SFMr3V!%%*dR}Oe)(A+%Ap1m2+nUg>xf>Do@Dv|>ZjP5q~zpD#m zWDx)qFh)1Ua`E!8VYOH8J$K)7(Ocx$u4_F`%t(+q2SIo+ClB)fVj&UR#0k33*&y(B z-A7{Qn-(?v6_0?I#rbTO0T!^|K33Y1q{!80wYPUe88@vszlQH z&@FTfY=%$|9$TgWK*KwYu6==sMc`INi@_V`T&p2Cfd|A2!j0vfLXl^wA_+)Mm}h(| zDbtH+&xdb*Ap83JO@)HJH@3H32O37xqy|uuQRgL*Bt;6qj|tFD;n~nl^{!K<83<69 z*zve#+YhE4X`3Y30H&H*DY~{1xZqVn$bU2nhXoKhgQ#C{JzO;du9;e82k5p zcN~;o?Bet^c*$xoDZn=t`y@ff$aD~oPEeFV1e*)`4zsC8Le~AABwV;J^~~^>k0}2{ zsa{P(q=#u0At{xe>1?&d1os9`PLs(~x>9tQcRMkIt*IVIXP^k5yAR_2 zMpyau2$(33q_S+XdB<1<9Q##vNcuJ3W8<4Tw>2MI1#O}S0|zHq^S1v*5aasgw*oaD zXy~k;?{0C>43Q*;+Ow%2tGV1rRb;zp=zRXt?|VrPkL+)_TmeiN6%Ok48^ERoD$tC+ux4LF6mo*igcChuSUw|ri6OL+MEnB*=;4v$ zjH3i~U!1VWwDv-NkjCFfqlzMNbPxumidLhG#E4~d)?jMA@FqeHx=LJh9hvezfHhH7 z0{(eQ*eS&(1-e~!8zFctAAVY?m0e%#PJU40@(8G$c#A`rt(_V=C^q3Js^=xMiADvd zpq&e#N)*9Ih!&Bf5v8MsJEnIHA6`$tPG*w>`amhW_c3ih7h8{?ofEDD+eneC8s&(d zL#|;ZDlpHlEFVilTfDkQEq~`W(f)py`g`jcx?hENw05)?O`vVo+o_NKOlhn0>A#Hp zngUQ+vQDW4va->}bChKtAeq~S0RGDUhu1T|9Yz2VAXQhy0_PKqtO^LGVU^p2Yw7(z z1X6+`TCbtW?F! zBah$ODnw7lk;?#HeAV86`;2ZbRQ)TnnfNWR;AkN%I)ZK~rc)0{)3LmN@2uwliI?@~Bi$Ii7+A43!fv4560Jvw?-XriAGm-hWE()=L zMEtJbE^>5F4N?aF&V9ts>^uGsB2&dfRxBwP7)#$w0VGuhd4V-%b5C5!0UF)Q``@4mzwk>#K1ZOvXH=RGdZ}2HE-NSF8fA~BT zfMl`~e{EpatXq-M1q51m)9z}e59rZW{x+|uc}yYkwh5)|?^>@^w=)B!F?if`{6oIGm-a_-X&^$&Ru=aLJf-~V?SQAk7zWL+nC z)b#U9-PxL&HFR}TmQ|*Kkkk2HG9gTY#PT+24VIfXV_KOBb^PgTS#Uz>Juz{m=^W3gi7o?NRLjMh!T6>uljbOEdR~_^Fw} ziunTg_~*OutSI*5`#&xwQPMSbh|s(hW6o`V6TQ3P#JD59Pd)=$=WU!i^ffb?ujIEf zv7@;kn%(X@lFE^z2f!bC{qvat@0T6?9nsJ%WUV(xTe?NE)H0uc>!$FLzRM{GKZU*} zS54_W4a)OxB42CxNwdMqf7;YzWpz&ew(=0eYvYu7qssxHtY9n_P?@@yGG_2XQ;Am@ zFX&!)@*!$4qp8S&G6|&wBR~RZxYWK^pUgNb+fJ9V3I~o~CW22BwJzdv6;NLf2D;d@ zpsxbDjL}uFML{pAvlaqR2sOKN-*EEeapxB6+()m|h6QJ1N10pl6pvuzZpfIYMLJ=z zU55F5?e85FEj~ztXuGt(9DoLpa53()mG*dDt~$6pF4Pa)mTVMntdUb{Q*wXrqH&#} zPM~B=8&$KV7UJYDMhv*hWxWsCKaqlDJvb|O4s+Zf&1P>^m1nOwFp+<%|Jo)BBJCQl zJ0aI#Ny(v`MeZ58TL!;#dK@gNvw}wBJ}EIS|J*}hpHNrmF@X!Lep}CFN^dEJ=H2zh zn}O=X_A+5CsHMz};#Jz5Z>tp)3@x7|Sig6Sx|bHlLC#q(7DNK~nwW2yHLzeP{6oe7 z#6JNzFSo|+t*i^?)WYh=?F$C<2WZNotmcQ)?ZnBe1iftW?`Ru)lqluu#dqp+5(wmh zk=uIFx#Du2bX!UH;@vlW;H={KMSTsM7Q7OP!{QG;1!=Q7x@8t-1LWZ|N`Pk1Gy;X-#Pv zE%*fb>Qdd?{axg|X0Is{>{ey5Ufox$s}<7^qF5SB(t}~$lpU3~`8>F|VWRt$q?W4A z;42Iy{Flti0ZJzzO7yPY%q?{){K98SF3=_n^&pNXK$d|nNH-g$IkVTHs;YY80b%15 z+@Y;?U&}B$-=WP+3HK>p3x}DD<-Kwy!2oM+$5`Ni!42pg=1TakmuK9%sO69i7FR<#wTw%ar@#oMP z3mF)dUNaqHLDOFX(G!ms-Nf2f7XBWxxYHI&HPqV8ud*x3LST<0D$+$X+>UkSMn`YW zUqtoJZeQ1$>5opXE7C+iE|;u68bh>xzkFOQ*;3@e-}YGVoUpfn8KflsudPSN1@#yL z;k2WoQN2Vs7_<|ksdh#xFgpU^{Cc!RppgwR;gH7#g@6`bG5|AFD9OK@8^G6rqLaZkVC?+N?cw%f0iEmF z9lRHAVB)SzRqUnEClY1?TFH0frr>(lfTEmgNNo{FiE^+%@#b)fS)t=#y(;_20LXCG zI?h*gVnc`H6GJl%_ULMKGk*$5)7`(%J1a7Ie;nQom^dZHtzMtHm$_RI&fOF^daev% zKJwdd?M(Jo;GzV4{g)6X^Pd)~Pc(S$bvzMvqGq#i$M%u&^h^Mae$$Wd04{$ef%P4lKW$C7;K>m8>Sjd*V#U^av+Ud?rPIXQvy~1=wN?@3NSRt#phr3IH`|p~Rs9 z)tPA)@Q;N`FJ7Qid$Ho&@kne*T?4Vola68H_!QpG>AVcIl3w5Ley~zqJ>rs4ToANl zVEw4)hq|r3F(yY()hXWD+0|cdNrUl zS74Q|MS}W`DIJO*%YR&l*ke-6R=svGHW{2BuWz@6nON= z-dMo);=q1$emMm>HFj@7U;1EjnL_A-tMe=K4)L>lT$^l*YpL~&~3r=zaA~bq`|=zEw@P16YVXn&8f}j-ow)gX&Uu0uNXlCs!@_4g7F;Q zwLTLO8_|$u0@-{98f<1mMpYnC0chP$vHGj?PTlg78!I+8v}hFt*`;o_Dzp4`wKevy z4_f@^uB-4__~KsxeC~;eor8pHgz~CF;5-Ym6cy;IRDk0Ry`R1(CG;(qYxCS(v$f~5 z)0u`%w!0@Z6tJ#4x{v*_|L!omJjT>GRZr@1+~eWA=5 zKJ(egM$a>aZuIc?GQpq*9|s#CzAc;#no|A(N|0a@ButIEm&=IED*K$tryB3sOKOIH zr(FnQf;DS$D>nlQmywVXdI?{9QU<-2joVdZ-FlK+h{buXc-Tp`%1IhY{UH(KJoHiQ z@ZmE5pNqlAFP{L(~cyYOEDE zl3%{_ANdajHsWK!z_Zs^>+NlKKCA6}a^BCc=o~o+hyhvelfCxIu!{z?6Y?XZ$;wf! z$;46OSXnTru+OBS>vMkG*SE-CIUrC};=ulUxpDE|Lbg_Y?di9}1(W8u{=b|Q;0;l) zaE0~l?nFk`jK0u-Gb!g^RtCJJ{XU1%@H7oZ735Iq+k3m095o+McqbmsdNNF+?IE5) zOr7B#@M`s#ovy0`7wW$Bhix}`%xsZ|g}C6w+C0qK%l8fobc z6+~K)?(P!l2I=l*zu|d)@At<139~b2&N=seuKT)6@{cvel%P-PiB&ni`3`sAWW2#C zviNt?6TOcet0Ol1p$;Hclm21~Vdzoh4OVn4_1#x}mqo{1t)?=gt3CY=jYuRiRY}=? zKf`kUVCdj9dzH{Ke?j{J!baWIRGWDd86`}$@8m){Mphv@Eu}qT^5fu%nAXTG(R|Pf z$9%a+OXKmNsL5}}B^pd%y+66!Y4hD|Ozgq(z3E&FgRgGx6A*rqx+q{`uQ`gwKspDzo8BQxV@U>Ag*FFn(HmCHcRj8sET0*4Kf zEEG}!4xN9T3#bk0Hegc4KwK{1rp+zit?mb_!(Iarx8}Pa!bKF=LGhQYGTVdQXD0pH zCv!#kdu*?DcmdhFK1Q-v9#qDfw>;nq_CEj^7lnT>PpJn!>NDyD77rCijC7E7y1LPj z)GksQ6awz-qpw@(FN_}i{t)XEl@^fqEGFSd0Yo(J)j$MY>qCVT%P)@hoep7&-Z*g1 zGZH~GcvD0648gtcPgMMgKK>B;)8ENHdoG@b9^>IJKEaXnc*94Ft*qV+>wCJGO90jJ zpkJ9e$HQIk=i;4}$Eo*{{1RZXk|-Hnq9YO(ncO~plFltLM}u$m5<7cbmb1WZs-4T@ z&0)%y1WgLwx7Ps7Ajwvbgdwf}iR?YIuLxYN|E9o$yi6hT3?)F^C31{keKr#PsnM19 zIU<`75RfKeL~MWRhe<;bcU_{$UF^zWGgiFY^Gf@v?{|;Sv8QCa)}!iq2w;mu*F#jh zW&U1WLU-Vn=O@KPob9Z9;Np_*ia981C>k)^eQ#B><)Sq+Gh^pZPxN@ZWy&&H@we2u zM$zAk&h^-v5vmB4KZJc-l48GB7wv27X5`-v=2#|sx!2Zx1aj~YAur1?0X)a*F2ct| z=7fm(th7BFGt$TCNn_-I00s(OeUQb&iWn^Ar1@nrI{Pb=c14|vw|IR9-2hyLV3f-1 zGXcU~V|%>F*y}--&}jQu;aczbxEr19tx@}8!?4!B?yyZi^d+L}@ke$qA9QA}X5qqK#UH@d@=2*PYs+UYVB!<++m+lEmL* zSk9Lj8&}u2w4hGd{bX^*Tgz$_uMzmO4R65qdwKzfa}_8uXA6c*vwC_VSKZDqk@=DR zeIqu{Q9+B9p@#(!`vtP>3<#FLVy>?Zmw`&?Vat!d^Ir-{_=KBfu@pXgV=E|15B_>T zO0FT+9q+|PgyxuqqqgivG6F}`^pF61tfJ)1&CLriOh{R*5@yn?o|D&OCImw4q{aAS zJ~cZcEc_3KCAGmKQ{C!8unpEIh`f8SiwU=Xn^dgLwRtm}DOoWbrLB)reYHa%4lY9g?=< zV1~@3Cc^HMW#`D#yeZf@KTo%D@~|y%%D7j2%Z$LCIqPNS<;T$qEAFbg99a+N@;m(f zji~wpt>G9aK*H$*$vxC+%m#yK! z87!;*9q*%4WwC72n}j`HC76KY!WV)h!$#`g#?S8+9vTcT9$?aw^GfB0Ew%=5!-|Am zq2#ti#+9%7n&)N(a0z-%6lzNKa$UgFV2B$3uWxaM?R(xN$B?s!`s4~3aBpO8%X~24 zy|)z*53BKemYyopMi>qYroq~y=ux2vTo~P8o`KOrA!~$=@7&KcBVhy@PAJ(UX9>x_ zr3UU7C^gZ1Uj6B!i3*yFizgjph==gnMRFW`cLaTi!6O@^rv!iib@bP^x-Ii!{Ws*< zDF8+BqvS{)p9%M_nsd$%3Gx+)Y0VZCO7w0qX;C3A^9l z6NsY0vwgm^P8!)GMAT(Aq@BQRYdi%7kZYLhny5DOzp-C_SUp6024#M>%N8@DQI0m; zldaLi2{h}L8bAav+E%)ipiVd80_@SNN&S?i7{hkU7ywak{l{ZoC4&mL>)onn4LBrU zS~(M7P(U9VSRh9#J;=MLkmU$}qRdJbEtu9g9Xv&91qh?c1Y{!~xs}2Y*WLEbCrlDw zw>_21%FDB1CxeHVy{N%}-FG;$P_y2RuPWxY<`YQAC)HLU)SR1duY72IUjk0ZArldw z6G`iHb7qoTV;C<7O4`Lqev^*3nB%#fKSX5@*~HPPv3p|i<>p=$25|vk@Q$NLz2i9= zX7h=zjB^2>bMT?!K1GSOP;Hv9na=TTUqNsWt>+Mbf?>2c4+{p+`)vH6Sh@l|mq#%0 z9OLTIywWf*e^g)NmRZ(6Sg)^v!mBh7v3Fl*w(F?oc9&GS;(a5|DFp^tbOh)(D=4yxaPE+&LGx zQjX$**UWuEQhbTYH9EknC2v^k`^9dAoFwy5R03DFnq}j9EYL{J)MX|1HSDSEO5|I= zB3?ELO*7hfcS)0AYUt|X;uc;0)2HSG>ds_#SHWlfX-{H%rX8g=Fg8k-g?|SCNu!lR zyEC`BR=r+r3YaNN?l;C~iVdXwSD89c14@WPE$dq0O=oV@0~}uKeV;U+aUs_$*c~>w zTiZwhBfwhip@LXJ)I%TPfs2Ky&J?4ShvgAG3c_Z89}2mapd!d%8kxe3S+qOF{ANbz zz{auOB2gIMaAv&4VX4a3=;zz`wD9fVvP^YMEhbN^DI$4VPUtp74eBD5Lq0V6jEDQX z02miBl+$NbD6)Lr^*-`@Lfw1LgZOx1J}*1khHosxli80d?P^}EjP42y>f<)bLRF%L z4?mB7B~wR@)H~AO{&VZQcvX&@()JbI=XYUEJ!38=XkUQSZ(zax!C3nEEZnH9Po=w@ z;?zB|P?up@i5;*y;c4Z?L^#08^v?&8x!XPch9XeY>I@K`)N~aQl@VoJvQ{!Gtv6un zdGjMPsHJ%D!>^Egen;!<4~y;)BFKAT9wkM5_vZtex39LRdDJNMGYmZssaI&t$tAU{ zI1BxnNO;8ty`@up;RDT@b>1qrS{QQhcCIyc z@lEW6>T6OI_t|d!&fP!Q5#KNQFsep%$St}fuCb*5@lRcTNHpq-w7kI>A1xd5W~_N< zZvIBVTco)%wh?T@U=?-!$_j-e>N0`$%;kxbJO(0!0P(ANK#Kf0L^*M0jX!emWsoAE z^4M-g4h#o<5ROLkN`}tcA^6xzzhX|CJ5XsLmbx^*#&9mYoUU>A0>LE$u@_)t;<}#W4{JnqJJ+vwvp8Mf0>4s6Hg?FR_K8|IjM=EfuxM z&;8>hP?56%RseHyl8%5VUC?x8(DK-Mz0Y5{^~8@rZDhC2jE>XA{PW9_bsNgL16|fX zSs{dtuaEAHN9o{La~@WmY*4#2 z)ntFCTh`+tZNUMRdg683d&Qptz&Ie+4H*au6jIKvZ3Y_7;W{c#Jl^55S3|T~lFNPU zM@pxyeJ=z?UjN~QizU)z{;cUgkKc@>9dsShSmfYnqt(3e^s6w02I&hNY@T2FTWMev z3zxdVP%x8V79z6wG6BH0DibiAxk{J@z4wAeU@L81w6NBcj66NOLm_Y8au<~<|I7e@ zMn}mh_eJFPrs(n-KulOSbLlGi%ZyV2^`u10)okz-omA|2Iiqfc8^7P?oH$PLhsDOp zWzGTU)dC~kSRhFzup1ezHyCSl#yJq&HFpehi}Q72_xGG^)eHMT11ZX`j5}?GL4ex) zWAfnLaaXXa1%t64AWgh7EUO*!BuGVM;UwlU9nfL`$QN+9C?X3C;0Hxdz#K)t;~5`Y zk41klD5il+;JTl7)%*S6=R+`3-98H`dfeBjtmiegL^#*<&q%5$AR8}sWi(!2I^O3G z2$2GwM+e6=I~-hb0>R?T;E#)2v?{SADlWI;Fk=!gwPhPjit5!&7&n3UYEWwJL zirBm7GAgshe_oOUxr*F`G|~A%49C=ux4I&YB!bFUiTEi77YH#wP(N1{nS!|BqZuM z7_RDohVlba2KsCGcqLhBc}WWGDA2W=&gVV8B{Z!<#>l(j^`P~~kIp){8iX16^DRx7 z7Hb+$O~eo5=T8LCG6S9)z$D);BrZSFp?LR5`7(^%Kt;ijiFnCK#hRI-d^-4d6Y)FW zf@qy&zH%gi!?B}(9$$Zp+!9XVx}F`?Ecc}eFOI+7BK@}yYh_YGlN3VFbJs=sgmam| zrX&npb}nJpt5J0slw<-d+1X0R4vG3b1s-~G_|UB0fp_&NFxn;|YJ!>x zVoM+3-Lr#yPZGp~jgNo334w;+mJdBG_Ty47Z0|YytW_@ zy@JS&METKZ>Olkegc)FKZ3&^1JlNp!&4u=6Y4qOtvXGQXM@8<@LYobgwES&a;_jU* z>>rvQZKTR^puwU7%k4XsFsO##tHIv1!vaXtRyZ*5wsJ!0Q*5(9g^US8038Vu40SR`Z1{gYW1Y%OuPzXZB4z`1H0(!L)em8L{O{Duv zU2b??9<82en_%@FuMe4vY0&&m1=#QwUC|Y659;sMZ#{kOZinpdy1sunH~-FmwJ!)Y zF^Rv8ipS@91l^O}xMN*Qyp=laXiFE$+_(b|yAWw+z}x5f_UlgktB*iWnf}}>RURqR zwNJ5NVTj9l(_k;;LFI~hm<~8+y|2Uz8AC5J^6(zJpe;~Ne7Ne!MGWMW!&ghPu7sYNZQaAe`%q5_6>*OGHUeU%@b_P94#}&qu?0Pylh5|x04?zX>ZKT=s{&wg#uCX z+oNd5q-viN`#VlMq-d7`nebDx=ZB~Y0IPT~Kj{wdla0645NtYI;+bZhP73VqcNhf1 z*s}YBP#Bsh{6X$>Hi8hUUjy}>IY1&xyYJk_iY7w-Sz6p% zRGVhJMdxr7Ya{vY=m(Mzgp=XqQqskx-BgWywVQpPf#w0k23>mrtQ#JJ?lnS~2}iaC z;~xvZ1RGKu2!}2d=uWTP4Jp=UV5|U~Z?2MV@%1TA3z7B?hzwDO1Ruv^S>bq-Ak&-v zSn16Nq#O>x9O`NNEl-Z2t%)qPk8x4mMqfOJ@9de$Ocp0A>(g_fkEB*_K?a?c+^h zN1Wh%zXB11)1Ftn!rD`R1xyiyN3qXPaq*w21aLIK9S|$*w|4w3+;``emAK5$)fiiN zzdYb|B)l-msjc6t{mJ_{oQ!?3!(Jt>vbU}f4VXe0A4p&%we~7a$OXoIVg!2e5MRD; zWtnf8>nKJDKY@c#6`jiGR$x0oMIE^Sl9#*ZToM2+pkSTj8b6lY=}ANp zYlL7&=d_Wr>E}CI>OfFUOiS{1dr1gkb<3$plm~W50iDovU^SL~|3N z-th>Zx*imbE)lz2`e@fybo4xHEI&7Ph^^@6SMP%kmR)QA&WssFv?_gq@o^ns_bLC@MbDr*sQMccMz_l`N^hSj^Ll<6QKr1RG)()nD-3MfoI+nUU70WRT zh>9jGdU?^Ti(`l*<%Y{qS|BmD7#sBbIV*Xs#jWfEZ&fJ|yqdZLny)O95fw<#x8lCQ z0Ym7YabIU>vR-g^O*Gon+1m83-cpq=Vf?xH%)H>fKYTG~N;~hkRnr@^Ezxvw3!VXl z6iGnZQ%A~eZnjJf{=&xU>*v4)7NnUt91lbLF-`WQH=pcEc4!NQksW;g63tfg z*ZdC#yql<^prz_qxHuD;zI#6Z(=77av0~KJbL{LA#x0DvmHuw_+wxf+(u~`z;?r97 z;d`L-S(^~Co+;w7N3}?UR162RMoIPp`?$4y>Rqy7OuKXxWNTq|VfcPoHqh~CW3erX^H7ZooWuzvkvwb6FS;m*Pr z6gz$Yc!crEUejBaejgN~z?k65vkm9n6f82lAr@l6x;&n&V5|T>sSEUDnR~beg5w$# zFro5Mz7E{|0U$MoG1?%6tR#wT(l8%LBKr$aF#6x6C!lioLF<^;J6k=2O(pa{B&2`$ zc5Yi`&6E`+JaiJ5J$7rJb54+6$*?+~(jxXFq#fApZ-KAzr1-GIHKJq)$C~@}0y@oQ z3_O3n@xk8NVB{HXM4$+x{a5nNSXG&Ohx;pSz>|T&{`HrBR5=C!tjeXwWp`D(-F01r zKY$P2Hgp6^?+E)|b8tyEStnQa9qq96DVuZI5^H1>RP}F^_ESUfqA9E^qd4u6SJi4( zV@xyuEESm3l8p8^=uxAOOBSKe1_rd!11I(2g-u$4YeVD6T?6L?{<`P{RmDtNqjzHp z9~aOGhOFe{!8Z)Yg2zv??|36wK(F(y4&niX;~hc%Nt7b_>9a^@c;Xu>{xfm{mhUrJonpJbp4^^JLPS9xkuj19smpqquC=)oe z9k@;-H~+{L6@lk#JmwA1`b%ay$7aa( z^-iXqReBP2IOZTZ1Ekt4`Qzl#Hbb8esaA&QhmX{F%@fWEa$Q`=DS-gWwuWKJKKCIo zp?P{E-C3q-PpEzK9v8l>B}CjE+f=`kq=CYx8zTqze!bV7n-f=S`qX}J*E|L7y(mV4 zQ$>~GEbkCSdWt}MJVOefXEf?)2oCx{=R+0~+IP6^$tKE%N-?93q@Pe0{sPS9kWU9s z^d07jwxlCH9q1O1k^(mIeO~$f3@L0)M9X}ArCLGwa^7M;{ke$J&@N%lJy%ZslDUzz;?Zu5E`P19+5vuYJ6%-er7UL}6x`)zXdz z`l~BBbu2G8-}HSA=He;(`9{n5Bb9y@W#36e0_*#^1kRa7&s)bg?EGX}%jw?lL??WI zE}JF40?jK1hD|wOnU7Rj4kaZB%$#M|G=XI45HtULiNOocna6;1_}$4-!gJV@P>3|(dQ<=SBSYZ<@xXYUAj!Br5@jD8f33PZOL5b!?7DOg|BYwmWI@0!)I$khyWZm+B3HHzKQ z`(O3yrXRmg@fURPZ>Ow!rPh><9X%^Bt>p6FP>f2}9Iq?e^{MPUHcOtj5T5m=vmn_3 zeNNIQg%1!XB;Z7VB&5<9ij424!-+Jg{&V0Z1)5gQi7i-yTZse;KP7OQj3ZmJ_*4DC z!U7EF%tGqbI4~RB^U-6XNwF_R@Tkn2b%fD0RaN6*PHBw5fLP*z!|T z*0cRH=^keKe?oghU&>e6hbt{R}C%@}Z+ciB3T zM|u2jcr*uO5rP)aF9;0V$^mi1k9v(IKEAT&dG;1}*xY4tebG8z@PVpuAz~`{M*v}& zgy-2N&&eQ!=p4>p;d=@h#lbm=LV2UCOr*cWDwl*;%>q`AKIwk3_|9&`PHwpj<&Xk@ zn*yKlZ)}MUmIg%K|FkqvMCuU(n{31*s!;Emy8syCly7jjuJ#Yr<(%t6$0BbENz1zc z;3OMTyGizUl-u>XYNAG;%l_ur<(igLIQDR86Eg^_e>?E#SyOsxf?;KUqx`PaW4lf< z?>@ppqV*Zcir<&%oUtKE<1&u?w4Gtlem)a#*gowe{Ltlcnf-T zz_Uab6Tx?3&3k){l%7NXlWKYTiLq=U{1s(dh_&R;cMos{6yLUgUNU=CM>Op_mB#BY zt$OiF7CKBTfOcx;-OwhF=glANuE*niXVthe`mqvO_Q%~e@^p`LJN+2^hSN7m69V(r zD>j^OlFS>7Gfs;?j(e276tcXY#Og8^5~1Zfc_X>G;GtSjzNwp$mDuC}e=vJ5+PKjDYmnnf3r7U7w+Qx@4`_QE!_AIzp)5D`<-0)$HrA@e4B4$14Y>L&@%7K2s3P0Dpb9KNM&GCR>Je7Uta?5X;%rcgG3dL zHs9Cq$$z6+=zI}~@J`VwfTZvkOp0ImhGopH>rU(n>y&_paySHvI5=14!8=8JTS9(H zf=_$&E^mh##eDPS$?LcO%no9P>T1PB?v1M3r6G&a@~@B#; zf&QD;ADVJ8N-m5EVQEE$OuqOWa^3J+)f*9Xg|#;ON%O^M{dm#5>gq|_1o5ZIux3vI zia;{4%q!;^R-duT`tFZezZ*(g8=Br}nXHuA*(cCCdM_t_cue|NtHaWRr&=i8>2^Sr z+Eu|)^X=cQh$fKabx0*b^jvHc^}WuZjVF#I&|~oWNO&+#7o8~Y$vix(ebAH9I3uxg0>>XG>s4PCmVCCzV%ycHZVo;Ef;_f2L?Q3Ae%@Wf}2p>_u` z=S#xVlEr#M*Ndyg(Bl5!34@+{$(VBTAcNOM}Fk18}1FRWVSgUE{h6)0N@e)kNzxtcwPDw5SOD>!3iZ_s}h9A+OEyBP6TdZUS-jrRR z@1t*^l=Nih_C{xWwM3v3M7@KJN%Y>;*NZh8vEnjosX2$eJ@da9lh_FtTpZ4p+MXy0 z=E5<67$gLX&Hk$DB<&|0j(Vh=+YFDfh49)0iHDo$78;P}JtBnIE`da4AL|jFOjF2= z1%+FyG9+-^Lij4YqG_Z=Uwk^70ew_ELm3~JWgOpDCR}=3cnkl!3$3$O1f@{8-?0lt zlbU_&MI*(Z`TciMf4`EsOx(*2AsJm%UkB}wO;y2n9QAjCB)mffR9Tj4DpoO6!0>m` z|E!fC8G(SU^qz?Z!~`)#F+8NU0Ws68hHQ@v5Ch34ST4rOCHhpo}h9l^3zq z9sCkFH>_`y_+f0Z#+V9^F;F(2e<9`6;I*9>+hKYrY||c$)!42q#rK+*@0#F2uy0_= zq_zQufm)g}UlKuS3yU3ZK!j{~Q8c&dYeVyJCMBNnfHK|@!fg^cf15+cv%lR|0$i(|{LinEpz!_@L{&I@q8U6!xbOYj11WWhU zb9ZLXoaV-M1wan73Wzf|H6?tBYhgyjk;tj(u-FVqD`{@Ankc@{azi+8{?4I$duAvu zA_zj)3v1E~%x)6bN93p&8t=z3(=@8>=q*z9E|?5ZXt`?DFvyMIu1bWhV!$XnLR3`L z<8*7R+IeXfRYVUA4Zz;%Y}x#rIg}}x`SmcIsJ81s>2JZjJ;3Oa)&e$Q6y=5Kv^qFA zh;WLQfAUf*)W{wT@%_oV^0#mb7s;14d_hl;R<#2bJlP~xYctpglRp_Oxxh>e(I>Qn zdKhx}FYVC14bLnICKns19nYcu zfK;)`6J+KY6F)02D%r)r?jGJJPtC&?r{we!`;zgN&#(X8b_5i!V~7dR{9xBmj<@O@ zlUUWBV8_R2J#0H8l0QjQg_TGe1l@>t@E)WKeV~jQ`}0G2DmXYSedG;F*js1+B25F_ zVcNf;ccKPZ@Ps$=Ss$ahMaZ47f3GGLzBPk*Lm^7Pp1p7f%h=B6@Q`L_lY2j7&&j0WJ@&ut_w82}VWIHZzA1&0-#)4xsSGH{ots(l8(JZKypd1{7QBHuB^B zbPS!co=mFHt0!op40f8LGC&y68IDP~Bxv|K4>%%$TIb{uH^2)JpMxxChVj zfa4Eum&X^sE$}~WS*D`$dJ>|E8ph!P&GRaFw1ZZOX5wfGw=^v?z`3ytenb^b=x~+B z@9~?b%lzd|Pzm1l;ZNT!pl&L^voneQ`Avd9$8>Y)CiM{j&lI#GZ5R#wLW&a;pXT=k zMovY}MMhEE+M)7u(`n#6zgv8ij;^IrBi6@t3#wpcGaM(Zj^$vTH!jLlpB_r@gYku+ znAx~O3Bn=dy6bn<>lXj&+k5C$&n6`>6!I=d^bO?Gmn}8zLnm`h<}L#w{J2-q-?8$Z z0d`g`gdy_PNB*htuko!k@ZqxWix}7rY^qXPvqk7+SypK9e>gY@mOBX7zNr&yT2*pt zFHm@aalqlN@O{ysRFExM4;Wx)nc?;CAjHdYaZLTvDnt$t`?a-N8bI0WA=X9ju79T1 zLUDo=)q)t3?8Dyi^;%l*^iYzL)70?+q}4WyZaQAg=bkSXhDa8xaHL2|jhXwgVzRJw zh8Y_iHQblzLL2fF#&Xuyw`MoP{EfA<7)3CH-?{oylZyrK((>H{aq0UkpnF8vHij#E zoBzGz+as7k-g)iBvS(WZ)3P#i59U;^rrPE)!x<)5u-{~>&ty|#p17qK?#UL%0omh1 z3#p4C#z-Q1OLKxJ)jFsbXNsppl;#&X8$N;z?kaM=>|wg25sxSqo(I=zImS?Nv%-U-rD z_hyYWMl-oIQipFACr%i;N9EapB=5qf!nc#?B%%M?K*yhei3qtl|6limWb}cC+e(Bm zhF&{gO0z5#YsfWINbIES^M{A8S%!(K%v5FG7AJv|ak+nA5@*Z(= zMD(vdX7UFX52SP$pC$Y?P8RnNl6&~c9(F5*_HyQVzVrscT0Vo#l$BdqXTF8XyHD*kCYUVU+J=2!y3NM`cUg>HuTm6tR!;3_Hw3B zlvr4ebPr(o+QF|6D_AZzAwcG%FDdxjDtgEU==1cF_Cve?#Udp95p>w-rpq;)Bn%ew z>a``xiIjxTh3@^G9FS;EIQZH3EBdVzbrE?}aF|LK5wjw*iTSlqI^~zi<2&2H%g!nq zz65ZJL1XJa1>+yP=^JKq-zIOF`9q)UCo3hiLU*rHelZE%IV@b|zjXrlD0mb7y{z6p znn|6?W#v`TTV-Z>t+JU4nYQ)U_1Uk%fD{WbJP@rpgmf$SmEk|6%0Enlin)(U>F;mM zO`BTp#OA;UFr@=xk~N#tg1tI1Mwt%6D!(3oC{7tNsptIl>(@UU?EZK6*L}S3b3o5+ z`6O8Y#3bJmn3-+z-aCT*?)i0M=Tj8f=ao=`r6<7_5H59dU(@!%z~_I=K*IY;WngHl z1jOFH)vPfen!mk12m1uOEi`&X`z|jp$Hc@)1%sp|8ylO5`w1I10r2zRI!_>$1+V+e zBTP7mfjh#;hSHv(^maj&z)of}L#WE`?(TVro^db%E2<0R3jUow@O}3$e6MhyaC}~U zcyXTEnmN2=SGvd-SfZyKLO_1&p7`$u4goLl8wn|dAiU+kd#${0UK;|Q^vwBl_xv!p zB>%o&+60Dy_;W98|2-G~a}EA|N{u`wg8u&u!q^{htH0x}8ebj1u2QJlJD`{w5n`@6 zb#v1HFDv=KriT%@Dv!;7dgEbv8|al1rKq--f0$`If%ga1MRsqIr~Y@{OvI2x6ZK(b z$>4&?r~#n$(mGH2DbKHqP6V0~Q-!+Q)nn>hF0t6N^sT`8$9rq0KQ zRgI(i6-n5Y@|Aw?EZ;N{z_v86+_T-##qb`t&--k>HhH67^o{*rE8?G32dA_fgAg${ zwwL2ERPak>MdZ=1f4 z*KL~gUHvWy9LvBpojCh*r8HS!9H{~d-~F2YyQ4z7Up_#1se5un>A2f>{x1CRVyHeI z6@5~lmI1hHrQEMC>d@3ye52jCeTtfz%eC;tc{5VKp~-suN=njw?{u>U)s}Pi==V;1 z$*T3mT`Z5et>n*z$CUqP-@eS(0=91Y@Kx$-EWi=&|WIR8EJ?bL(XmEz&ka-9$7 zBuZ+aRu4_PEJwW1Hd~|apVE73e40U)%VQ+2|DAi`vNgQJ4k7qL9rOa;Yg}+^gV%k^ zs4L`XH*X^&*_G{lcy+c-HC3@{x6TkEqJb}tu?YROWid8hzI$9rrLV4&>H5X~^e0E( znfl&@%Ods>5>6Hpi?J#>HaNhsdv%#`PhD(*bUJKuOUEK%{^hjVj>rEqn zCJ;5{u3kN3r#TZEliD-aGoNvx^Zz-%{v8$J=OrRwjtTIvynY;y;$&MS*);9b@&-jq z<6(`WNu5#Uv~)$o{}BNRNEU%c;;8-@MfGgQDDN z;J;pANOYeKfg_HaL7;p8*ZaNrub?wN2f*mw|EMSM_Im;QZ{_x%yY5-cfB$j6eed_f z{m~1Gt#K+~QA-#y@>qP_kvgu$^&7g;<2mx0$PE5t277~bm@f?vGiz4C}rfB}EzY$h@__pkb$X4>|rXfp`M=gZ5Fl5vY&g7*Y6j~7>p-;0Zj zyVNy+1xw1xejA4NtuFVNH*~E)45q9r^G1U?vTnx?dxN9&HWnltcUr-)ItktL)Z-MW zrCLEe-y1IHf!BYv)Kq=c2jxm9qG-tDPNq%thbn#zV0;}f=Z13Wi9N8B7p1?ex z;f4;aJJ!u9e2;xSH$1GQuHH4Vw`bGYeE5V==8J+-slpe{4M4sjx|*z`qvM9dNZacq zPhPm{DD#QqTL0c$T}_kJLl`ol+lQNsNoL3)m=`Op+8% zmGgCD;MS{WLsHzYaXj#5Ek{*XHAhdQKL3I?-^=YuS*I=5b~5)xZ`#Mr-^}wy{gO1w z#I%bXB@TLy^{SU2FKp43;t;2EdL>=kjvik1Q9SAsG~#;hzmn9{ChP>?)q$#4n#mLs zp)Zi)eo|uoq*Ht>{ql`#=cw>QeXuAFQ_& zAv_4SJDMfty^5q3ZI%H~u)(3B{hghig+%eJxwlFgHRVi>=I>=RR<^6tbE48qjxDFh ztR^h2tTr*CRg{!~uE|>GZLoxjrKP2a_51gmKa{`UH=ANL7IE4jI9AX6*vkameQ+L+ z`g;=Ix7Cw0^Zh5wv6t;2s(9Aen4WJN0)s-VYsmu4=+*+G-C4U2DFCa=4>O&uz9{JA zZ-~q2`Hf^u{E-?TWKTL-awaU_zfa~fM$5dlh1r&qMwN_jewv*LX>Zl-jRAd z@S12!kyg}L=$6y|d;M!=Go_y2%2&5WfOfBX{@D8Gbl0GU}{yT>GHJAY~)vi)u zJyrJcc)^!GP5 zbjr;>sHu_W7lt57P5{|53c-N|N!9C(ouTgqPDl9-j|#`z+z?|K7h&kfa>Z=wWdgM)AITX*UhFsgU_fpto{k zB{TB1^UymY-r5NLW}~)_e(9(RRF`17Yje%TE_rE4~lv5nzK$`IHc0JK*{z>9@e$Wrn?BL`mUIf*hcPh6qX~Lv+x2 zvk;qM5&wO|XJEQ00@{pv!Sq>+I~yAt3uLgx##ZGOf4e469Z>4p=^z#dDfxPMtvDTV z?U3Z`qdc;i+#q0Rlu6*Dr-MTk6EQ@ABQ76p}M_rGC_W zu4{k)W+|+3ZiHyY2z+6TYywjoJDXe73pHBY2k~s^ND(kC0O#xIkE+Qp!b0@37IzOu zzbme%PatI$vr*73PA{~s1l7tgi6E}g*WHq`oBP+IQJd*B4ILB>&b3pS!VEY8K48(> zl&XSUl*6K;+9Kw%pE2@U&1O}HREOw6q0)}O#&B)FFWG#WpETJ64{H!jPr5+dp-t3! zT?VdkSM}eN=KUArQ4yzkKY0nWI9l2Vu;bJpYT?g%Xy{vE=_jMbKY~-kR4FBw0tZ=U zi7(|;y3{ccqpL?~r;i#yVbI6oVZf&fJ`|Yx@e&9~jw?qvaOzY?7jK49!){rpvDp&# zy*64Mu`i6<%i3_LP_n!S>(I;J{qE_hTD@{tk+9D|z^^5&~sR40|x4r2hE z^+fef0K^)d?2rw4lu)PS#%sCjHUa-9X$mQQyV+0DijU(HLm+JIk2s#bop-Bvvyi=xiW_gzC@7Yy4H z%$WJtPlC57_5hX}U)4UiiS_6Z=A zYk899-@PCQYPD`VOgIkib7{QHkT+h3Z%V6XW0Ca(X8U`4n|qr-r*^Bl--F&SX{LBg z1feV*>53YRPE2qK5O~Q+{o&8w$XikVt2KD|)MtssN2k}Sg^_529--l=r1Y9MFF+&i zTL`Mbue&oXUfewWoSnLg58%!SdC5-n4<@@uDbE2JwUv96W#WVZ{{yA{f*_X5?bMCZ zb(H@X)cu3K7#QCGFUg+Z zlYibRG+b`U7EOb8N;5{1q{gU+eSkJ_nF!t}g9pAe`1xH1)NpRE8ob1~+LPyy(1tGX;(e@eqvdltAi5@c#s=2)Bw- zlU~_FeN(IqNl}*_P*hkSiN5e)jj_N6^vsEWK(73Ef!jZ7{$WQYos3qLdz~gQ>`|iW=luR8493ZAol1JTr{<@1cO30)0j?8hNu_=&C)c z%4ze70~%-;@jrzv%1{nNVti!^G4Z=7?@nmI0924a2t`HseZA0CO2#g+65~@E$qvlX z1G|-nF!`e7b;k-RU!X4&2C$PQy_~8(&?&y*`q4<0vFKdNPX#Nf#ySfHOX`xtgFLV3 zZ_@3c1ohG*kYIK^5h^I6O#gnPP=VnG6RTgg@C48l8{AWarR>a5zS;@`G>R%X)kgWj z;wlSf7;*4XCw9PNp!2!9tK!UQd$gy_=-y-X1Ke+JpBw?CR-I-yL-nB+fSTRei6 zf|2<2z$0*84(k-Sf7caUIfC&1sPcgv4aDuPC$#s~m+R&e@H{cTGdVM$5N(>S$5dw!A$7g~Z#ZK#e|QF*7~EQ~ug(=SpS$BL z{;nUyU<6H^kJ_J@Vga4JYM@tLDdT{hPGXZ3ehGr>H{YAxH6X*Z!t}qni2_kif`QUz zJkIiFiJOFW#7;B+lApcAckU|IG(gA7MmxFcV@uf>c;fm3X$93_Wsv`fF=D0-Twvjh z<%LNhua3s!h1&_94K47r0a4rtJuoECVoNs4(xMVDSYAVHF*Mo@N?>Q>-R|vP<2V#GH#T!UVgHZ?^eS%eY=OFh;Q=~iV*pCb zajPJ`xX?`Dfp*&dW2&sK%d%psP{_koQPE0UR1ZE-^x<*c9O1{up!#C?@di+#l&*Uu z^qG%kD;J-lKC*iu3i%NPP#7YX441{ld)j87Wt#%G3fki6O|tNBJuNVI2>Umr2K|PH zF1a*gg4E>TxQIhX(zYJ~&5xv;5Nj#pTd`*qJ|k*AKOFau(_idodGFxN2s}p6C-Pg= zsj2($)0&!@cR7Ov9~m65p}g+SK+?}c&UYpFq^+LoRGTEKTH25- zP!l+z$1$+h22Qj!0YBGH^@{o0J6dSUUXjlGnOlwK5t=>JKUNTOBWfTWCN-ZzJy_wh z=?I1nJ*EtY55FVA1+^B170jU2G4@^%PwXJe@5hWDJKza>)Z=n1HuOE5*BD(pL)A*t zYLK@oMU`yR{wjX4;vFItHuv`X&=B8429HBM=a0JLG({~mQ`q_scWMX7_~^G#G9stK zs`Pm>(4r*p5lRGet-oezG>D)~tGXf`F*6jtcYPP0 zzIG+Nv3AaFV^GJp`E4r?pbbGfc_G6Q57l?nU~pF&WYO`Wz|NMH zn90K72Oo7+5jOk>K(KKLH=G#ZIFlBf>Bxz!KAv^BL-j%?xHr=txTxU!PXAB36!A=~ z^sRQz-09cYu}n!d!l_6-w>^~)*ZAk>p5E!V$J^JHVqFW?H6 zY&dYP@KOH2v!O6qQ`&iZL*Fn*B9`v$$zmxwYkIwQ7?#Ns>R>f5F+p%~T{LddQ0?sr zKZnUst938|Yc*4p9G*3h^#~2U>wx7 zQG@f6yA>>uVUqWc?`}W+Y0_8y(1G;!MRlZz5V5D`H=7QEu87Q#df~YPDc0 zH_m;kHaBMFta{t1Dr;G#HCOhhXza=xQ4~;G zx6Gr2?ym3P{XF0MzWf3FCeGPspR=!Z zt!u5l*2Lyg;$hV$;WK~*lmHvh8d$*v+g5#&3}>Ib#;4@|)^M&t?K-wfPJ11eFR4UL zKN(ibt`%G_!bNWIIWkuWHdR=BDz=C&4p<3XC#g(A`OC+^DJ(B_&+G6eU8a!Yg&&cm zzsagLtMhUX({1j^`Q~y|eTlXj^y8~M*dwyq;f!IL$$1?jTQgK!D!~K<(2gGV{E55g zyD*7a_lx7y)83e5Q%o+=)0$F3m74#_qDpo2xM0*i0G>u`<)RO!|`uSnB59=l&+>lEpyld!0(CjbyP4M>Ws>?e+=k}@_(hEHq+`82>=EVELv zU32MMwfZ(md{A5AP)w#%_g>-=^0+ZFxg$lKe`xep2F-q&1%5zPZ~WN=Mm6cU1bZU* zvuRVe`F2O|lO~CqDV64J7aH;m%Evw~ufHEviHs#4e{N}RUijeTI~M)fshGng+Rrj) zgUsozR9ExTloCkA2iX5^QJEw#`KvAJ;F*makX_$qJZ)k5g__G>C&JOle=m3KzyL4( z*x`>UK<9lkkSkO(DpfgAJ+ds_)j7?8p{?T*TOruFs3;UlVE<#HSFDOp;yCs}j zYxi7=F8d!XssAx200yNE1s0pddWeL)a4e9FK0r-5=OAwuemv^7YT!GZcn8qo2YLml z1}B>;k?2vm{Wy2clg7&!)5;kW4R3B-Tzqi!`K4%;2t|(HvrlLHAMwCZW@xtG89{&5 z>|xhgsA>G=7vg!9A|B4jd(kcH?!#5Ihu)8!4iYOwrs<+y@YqqvF4&U-Vcuz`-6u6` zk^w(!#oCvOeSey{1RQxF&++Qe{6?|nf4r8nrIs=jez1-s&PGm>Id{!&;xUnevGwRo$?e#+ka}zf3+g4ll@atXy zC(}EU7bTZ@8S}wdXp0A@X7BwbETc%GHSHHFa-#UF*Q#<5768N8Q&XU3R@+qekjRZs z5Fng>T+RvQ4ePZ`ojp3KTeimrRNc0za-4rlG)YPEbX&quJEAqKeB&!GWQ9cpm}dN~ z$|4#LetFPVYECV0{C=zH-!kT@o}wo%?CtPDzxsV?skCrP{vZI~e~l;J$T&;St5p?> zd#L*nogvn8JoCx_9H&3SFrpntY8&kklX6eR|BZjvxlhZP>6fo-*HS7?J{?_DivVob#aaZ3Kuh!*niZM003`wrA>T%Q9C`{)cVe*cCGy=1X=b+zjjRb z=HV^A@4|!*eI8!Y?LF8iltc2J>5&`-li1am>I012|AcP(ap-Z4S|u9F`<)MU=GPo~qjcLS$$r_XFQYs3D!>Dj%Oe0w8?mBKl8*&Bngj z_z!HTXJ*#yI=64V=^38pDna)MN`&j%Vb#ckNFYxEt}x>b5XhMFk)GQ+Iq@|(%fI-X zkgydYJUucpqDn$%Mi;9h@S5{irqov0ltda9CTFuACsR-oQ2ipFc*{ftf*!Gkxat-K z6kpRC=-0UDZp1~SelCYS7naj!AOe1sjDO^{im{I2E2*aC+_=DRMrkRhzy$qfWw%7P z399VzI3^1_GE~w>vXK91ztp4vuqC^Vgm_xpuI_29?Scbw9#Xlm(G5v z6L$0|5$aC#tgAoVzWcR!tZ{D)jLjEUGTruyJRD>vJXb{KvM;1?_}<~AoTIdCpwz`P zu?Y|`t9p@{?wP&umHU{cr5ulW^YYxl-h%7Rg;5(Et!7j3sa7!7_3}uIpYPqUgskl7 zkkNu_b%X16rqxrd=m}G?YzU$qAKOQ|?Aj>OF zIzJvR^Y^xOc6V>|HXjZD7E`J&{FPxpj)9S$Wn+_CLvvNE{<4%-O785mVA9$oFhGc+ zPSG-9^<`d}PK}6mvH#Z$*bwe%93DDNken3I31LjWmpoJishL)BFnRQ4b8~Y=g=E}C zCNI=qR0u$M;c?{n@#X@8g1(`P2y~KtK590MOK-8IMBFg|dA93Aq7B%JP7Z>a>rmnr z;kclW^Kb-@Q>$pgT6SbBKPj{Da$<8j-ZBLSqPj0Kc0(7KSG)9-;udWeHVf?^r&O?^ zn3Q*uRoxCMst;c1dj8ZX#?mlYGksYy<|RoChOZHTl*{nB#l)^?B{cIwyLBiGEHob0!!(=hYrBw>Pkc zAu7W{V>Ns|C_kfQ&a`ZEu~#Bb?J$ZMG5FbvZt9H2HOzpmw*8;kZ%%%rf%EYzAKZZBs{!r&({Nbj}kpj$E2v zeCj^?t#d%^@K7-UN`mwaWt`cJqUZM-*@e7Wf|S@_ctGKoOsnCAU(XV$;k+^n_^DI? zIV6*-6=mJVTW?Dd=|g?Yguf~MT~U3d4?nA8bL;>h@b$XaU~TzNGXjHCQwg&6*k~w~;SObI)IepGjKt&z z)YfPSA_=*}>NYQDS@8yM;v>H=A*%>YPJMs-(m`T*i)p2fuF?Qo=W8tCc!FUQsh&?H zrK~^xb|()woka4~uMD_a=*CqA)|h1Tk*KDBr#*p;fcTjg2aeRitJA@7MMSfRlk}SJ zl3HNl_5F2?oc<=RBonnqv&jn`uI_(y(CD?6b{_NEsf z-B_IUtG|Rj2vY?H%r}5myEr`GsF5DLF~SA-ytr{lDmE+tL(oG>K9zL^4>|9uODHFD zUiOZi$?Bz_5TZzRCV8$A?^#PmO=fy?o<%9x9CN#_QPDnh+}t<^I5ciqHYQmcL@Ul(Q!|kUBfdQzL_Ky zzF+}B-pQ3*k<=F~cQm28_RaUCO}h1x+&xk=mp8;-OFv#A0g*it~u zCjHnBAJmUKEe-`f2W%0RI9c;zcV%u1~*0Fq_^MLt9M7Z~$Xa zy~5P^LEigTKMcb(=M{xF9u=pTKQ+gPnlwHq?CW{zXU7YZ*Ls&zB1DG6aM+0pb~iEV zAnsxz&BsXgZTGqOG(+92W%(J7#M~)N%^trSA5i`0oD~A}m)YcCJn(0s_AWKP4XLg% z6R_>0(*2x3MS}gy;(;kPuoYDnda1u?CKCYA_H{6M=Gb4DXWX{rHYFJYr9I$nmd^(R zJ_|KMKuL*r!1}n)Y1cDJ&_N;kChPh8oM|P^gYyLG*Eng{S4BFa%|BCvJ;Ts~PVLLZ z!wHGnzHv*sw`TY40r`_b5x%5~DSecHAK@)xFuR6v0EikdnDM7Xm%NNw{tY)d59_l^ zr__$G;t(0p{^z~$l7ZKV)Fb^qMlsOX0Z(m<*G z+YGD9Xjam1AY}A`0*mRM0Qt{C3y^^CgV4hQ-7Xm0b)t@SPpO-&w;zmXJpLdJIDp@7 zk7Bko@S+kW3Am-lf{0Q28DUnhWHQT#U#`qMq~;w0nH-jTk(0h&-=)55Wzu{Y*yQZws$#|)Kg8`zKpm43#UEw{qpXdY?r?%Pt6t6JZET%qkAuoSNmR zk+IHy-fUb;v{=A}|93*E>VmtlshubhWsd0;sYrDUXL=VLV)y!7M zq@2dAa{iepQ0~+`FTZ(`dF+9lkYe;>amu`2I^;DnTkRIjt;~T~j;%^I0B=w2zA?SP z1z>t)Ou&ah=l!#(NGA#Cu#G-^zp?#nDh>-L#6xe-ba>K~=Y%=u}{sq_}!pSZDLf!zHcfDT6DlFG#`0DRuADiQ*3!yd40j7hBpjY>++tBP+M9we?3<)*U`R zzT3B-+uCBfVq+qwU8KxU2#c6G+r`@L>b>kF*XI73@ysM1+DF!xG!-`Z6`AvCP8 z4h$p{^@?lv#^_+m8}e$H9{Hj!podb=jcmk+Kh0ak!M0S|269qYb*|s zT`UbOE$8qiWqD`{cXol8d7-&tkV8T7 z`fA?vctLiM)GG)M+i^hVb#87VSjp%+;<;_V;!}~M6GWZ&%_He?2kbpe3E(RtH;lgjX(5EK9F4P@%Kca|^ZM>;N|j#D;U6oI>hyvd3>_(%?+3T3 zdTI2~OD_2?k-KnmrYvWs+6l42To+vEX5<)wp6^d@cKiJmJm5cnc{RVd;K($zH@XMm z@9&RKq;9>1f!sLQrt`Px!YXwwFS#Z=T_R{9f3Wun*Daz2gUq#5G0#Wy4t#CDPd zDFeSn(E)+#kFAP`TQ5|xX{f_`+>Ub|AK~ck&pRIWYJo7&^$QEEsK&Fe zpC*UN@@7jwbPsK$1kj0LuV*6I2DDi(*f_i_Ybu_RsSEtPbL9fcZpBJX# zo?$F`=*N_eM(ByILLd`pq-E_d){&dW&O5hrwlXa*}deepVPH=JfeVehbMeCkbzNGXD zqs$UAfo|(jyE3q=xvvm~AxPzBu1-3Ng--oG;wHBIVvGbho1Oy1$(e0z;aB-y4pWjV zLNIU#4~=PE3C!?h9ZNE+IBxpN%t_>iynogD6(ydx@H@C`BIAykzZ_$CH>>((H?zt? zVy^eou`loulCfy&s=Y45wW*Vx3wBybSLDn8jOP_E&Gi61TkT)(kaXjHHZw5>Z!h2T zqo7u!5&z)kkQh_9OVVAN6i|55*N=R}BsukVN{#^F_&;hNS{y@kk3;{E<#Hz%3x(Yl6m-ty{17<9AjsQ@uGKNiT$mH)ku zZ;q>=+iq(}1$wCd*kYcrWs<0^OduzSh{35b;u{0R-J)S27Y7e`7z|>?vU`~0?I*~vgX6t>Ow^y&;xw+RrDmXxic*@5V`aduRJknx%gi*O7ufCv_} z&Yyz6Bwq(eWy;UDa`y^NpIfoUnzn5cg}~*F&Kp0sDygVdri^;JejebIZIzVpZ+S18iDu}jncB#2%L)eQ+dCHiWfEzjWZpZ!vkX^4{YZ0>?P*9bxU zcJ0$c%LUlm$*hki?|XYbG-vlgF&jvK+PIPcE7L}3*T06(97n2kK>`}DHE`{Tb=N(5d@gMzfpPbQE`!fVHZ{#^`SwxwC) zW-^c(jW>HSPzGubwBevzr%W}BzbawWigDS>gzZ7`mIw$h#utA|BHshCL#}YNemw)) z3Jc7^o$Pt{zK+j}P+H`@qemkal)d_8b@e6S@(>4M2W*u2Z!EZ|?fV;F6EPDvki;hbl7Iz)g%*$zsXbW}3+wB;tZbD^$2I4K|pSI&YShg>q2!clJhPc?NqLa53#BosKADPQ_{VEG!JaQl-!MnCfGm% zAd4xdV*+zI24_7pSBIVdv@RaQ~4sB7^Tk7`m<{R*$gtsY%& zBh5h0o`0@pZYfw#o`fX^C8Ei*ce9w|l;Y~-sd^3ax&mKZ`FRj3T}3b~bawN9M(BPG zkPCQP5Gc1`yUP4e)W8CMT`}+9BO)7!J(_M&Jd{gjXVzQZT2e{iS2tKMQ!v>kZ01(( znUiI@ki)t@n+wZ`4tL%USu0$ao@&qeL2=salX!1DXRa?y7(dJ;aAs!4AaAy);I0i6 zF8glA@PPeeKLN_Q=Q5cO@$$SpsM%6p#&d~1szXPe%2M;m z=YOFLYkJk+qEzN<{AR`bl;|RPyp>V5<89OJn>!r!%9@Qh_)E#Ec+etbzy{llR8YOU zs{tYsEcw(gzklaIfDpQvm>6zuZYayRva+%vJWS+6{&iQQMD2RCqu?%JN;vWhfY_^7 zoDax`;HRv)llI)UB>E#RsyZy|L{<7*8X|M<8pEbyYj25xK_-Ml?LI0A zyM3?P`7}uKZtSC1BmHckFaKaq>AF&#v4ON!Ux+j);qn2VYGOAlIhdXviEiLz6X5{0 zT6}|S7(TY}*bG0i;;yM+0%?ojOT4Fpr=Q8+qs_Yaor(wEfyRK0e6d(E3RU zs4OYA%5?Zw``nE8veYWp`t@g%py*-d0v7PTc=F^408r!$i9~89OB)&)85tPRL5@_e zq0TXL@|B5_aHy7rDlnk4HqC5VPF7m~f~_CtvOm{8zaLuK_4a?hpG+5zX8z|U>rV7W zSVtrbeZ4HdsmB5ijrW!R=)9My2?#&zn#j!*0zDvyh}Ycbu1r9_RPHdmP$4ui=5*Mq{|L|KU=YU(k}#$;8HE7bC^3e=ZS>S5}%W6?mWC%EuU`FA9o#wmLW=66a=O8ioz40NhOc{A2m-=dL=Foti5?Nte9W&YV zUnI-bl)nD8vbOz1V|(!63f-D|aO6B2ORU8Cc{@C>GqJ_^= zx!)4S&~VxM$9Ml*Yl`c*%K168k#ci+nZl*d897VSV8lG0bwufawsElJBt*bdo-qaS zr}eNjQllwhSL6N{yhAr(p%;F`5!TJY+on~|v!|6lt%XZrU)*VhBNCHZ`dB+^bjf`8 zmVeg9|6@lqK#K+W_x$lfUm0#UtHC8%RnAnU4*%w0xa3}t=-g1N$wsEgc#dV7r0OgxfK;w4 z)(Zsw*(`W6_hP z!G@~dvfp7NBqk=t^t9lfy}}_zlS@iTjj7k6;{Jo)pM1oB9|N?FE*!nY&fMF2EH?+65E8|pe1WCM_QCZkg?RhCWnzo89+u&7@OxAugDYAj_Dx z88;~l+lpW$aq~YaAvk}I9lzzRcn50l4M)wAGlky{il=CRoD`3B82XD67T{ICqRZN{ zr_UVz$(a#Z8DBF;^Y2$nwN~c?^5LncuQaRrqCBagcjX}Op45W&1r0c=a{xUeQh=wj zU&)pPo$SnlK4#%-8{08=w?1#i2kP zC_fAOG8-Xz>}s;pAmW4_*zTszT<+>cnN2Vu^rrl4jSc$Zrf8Zra`|Q~}h#zrN z0mWjiGw;)?$)J&Xw9(U7upH5P^dz|uapsV9g#4>l1;N7>^6NL;t%=hms3e6RLKxHK zn>R*jr*z!&VR$5v`nq$ux-V+zI+C*i?P!|nCfI=XJy~y-P$#e{af1YeWqlI3 zq!1Z~?-gucay;#V`Wmi#7%hzPX2$B^n{(Gmeyfc88VC~fi-jea{J3T|%+b3gU{6Xx zDck^#QNlnzDm4sT3!HgW_kL=C;oKlNAnVa4lcA5G{FP_80|VKcZ*OMYv=UQG@xCDm zNwCvLOS@^DSe4cJ6k!+#!E1pJ*!9xwbVzq4%9Y0BNs66b5Zu8AWzbpdH?nql#@E4FzCHIKR1k_SV-^y^;T|8;&XL{G+r#y(zs3~%*re;Rt**iFTytvfm({WkjMvVqxDDu zj|U5&U_gC!m_731g|8>nIPl4c{)3n+09lPulv(d!qB>J@h|{rJomdkeD>buqp(Q*g*6NK-4 ziD^DSU817BWvbk#s;Kc+W$wB(c)wPXjB1?Px*L?z*01RqyaX#VdT;rEzAL|GQE&J% z=n9D2;ov9{4q_p>?YWCF(yn=`wzKc!=7*#qcNXx;)HOQ!tl)CiGqEI|2JQ2Y_do~^ zQgfdJ%$e+6tfwDHYYSE3vi&1hFB?pX0N;8aFl#?$vss*c0&Q`VSDQAv`5sT+dm8!; zDtuYM88M#7>UQPJPP{#Odq8uCOnzMC)egw!qX1V5CjQl^pcq5jFv`qqa;72l9f7o% znAnw3)ZltU&5sMpux7N;`NbYCAoaF1p%xog8sHTNacYq-p~v2Ys1~128;wN~j`k-a z0YA9!Pz<~BU@7lD)Y^z4+H^Ze!Lw=dM~&z~BXKJ)N|Tg5D=D4%Js&hJ;6fn)Sv(Dp zN(ays)fE*Lkfat8f=e#`pV3Oo{Pyh@v?G$8JsoQfjtk49XQ=FL8@JFbKmq zitc~`6%A}pBy0yTl{P`EfHhGdOVmmvMf1r>`V!2$<8{(y!%kGD^6r#XXDl9O+xMe( zrN>I2;o8K%Gy_p-8eTFCQPgL*rwg#Mxc#RPVT%&``GT}^!goQ2AwGX%D}?>dKb0Tu zjC_-WY?QSiF%_&glI1s+0dI5A=mIV1XSZhZ{-a>gV*L*1HaX+NR;sa600gCq{Ua_*a zrlF-xk@Y_rF0eFcrgS+KprC^$Y89ZJ0+W-IqoShb=jVfhg4~w6W-8g!&~{m6oQuRz zzRhTjRu7#eB=!HbZ!NF}Pd=F^J=W6wnCe^6dKrIY4U)N&tZ*@zz7Jta%*A+{Z=m=@ z@TbJm#g;f2S626!9yO$oej0E{zMskbXI+0T5%&6jMF!G}0nEq#y7=|mVKQ(i!Df&c zlh+1$v|1A|?aR9tk9efO-;L|XYqcYcQJ4Cvn#-pTq zEHspW0F@An_i!ZvLm*p;mJO3=-{`TDvD0)IQI)V;%k=Xm8QRBAAy0138tHW2K?HpS zlG=?REGQJLWn+b3KJ8JIZot96kAynBev!gweDUIiK$*f~S$V#)Do=k)5Yjp5brKp$ z^U>0u?KKuEjhd>Ng-Z3=gKLoZsYed}R>+>(U58K$K@UU3?*O`}ZH1vS_micIke7=E zE?Ag1-EcO5$w{vL!ynlJ1*opD*?z1>Nc@Arpr@D+|J^j(^W|2 z7Qn0p1YRkHcd?*;urQ4GaO0MDv$EH^aiP7$E|~UmDcA+#&HSfb0S)VPk)wf%J0Nwb z11_(vCInA)4B(RDCelOx9b!_Jt3pptg^ROZzez_&heeR;R9BkriV++=d)DyYT7D^rh2y27*pJ8a;;+K@D1Y5*e^rI|ZFVybVaT}8Xl zh5{ff2h(}#2SdGaAso-Zc#P}F>Ucjm!ule57Upza0R9`MsBk6o+T%cVOuh=Fe#xH; zCj|JhJ~$u<01s`Lyoq405fKf17iD?4EYpK#MyWjBC za$kFsO@9itz;uSf_GCOvEauKL=$?fD#ICZgc3XQ}6pIX@8gs+3^S*@ZJbuWojp4FX zi3v-ktcl#%3w0PtwZoEsFC_~0nz7J9L-tQ$@(9#T;7z^$-2jkJmA?XP znZa<(WMLfGdKobcv__~YfnzIU>?p$OTP=^Wc^};IHQKHy_Lf2zFKeSCey%Rp zurXJd5h)TJw{gk;TXX1md}1#`o`7dZb))9umuxqB?oCJ$`9S&h(8B}=8=h_?-)8KQ zHGinN$uOm)nkFez%u0VbEU%f{sskpDffRP~sJn+$C~r1XiAv|Yce zdDhwg#s3LqOli37Kl*J!dfV1nC2+Tb4mfL${?4$RhaLGm|GZ-k0l9Mk?}*jAS8%WK z=2a0G$m%QW_B^mqDlu&U=>EOKXJcdmf^=H{Fy&W^)gr*UsHtmOT zrok~{WK96wu_8tI85a^tIS(tFne=Ih+KR9+)~8Dsf6s>A@EPQ4zqhd(`YNMC1(7v3 z6FJGBu2Br$lK0g09PqTBwHH#ok3Vg$nG=L*XM=L$n~PqCn@NHuHAui2%( zWhC|=P{PnGG~-Uelh?02$YVbFd*A%)#0Q}VY+RBFNrK)W4T-<5?*=>R&vq0l7y{S_ zC9eh-SFE|A*D9#Sa58;GX;YVFg=Cd#ZyzwAy}PXXaDFqpNEVfYq^K60-~KuY8#9szhJO=@9^-az3gUom zCVMP-%#8f>I$~S|3Q$Lx;EOptF~YYMAGFcMw@!Hl)~a^DD-LFmgR3%XSYV*+ z=3?C+@o(j0kE@q9hsIwfltpq& z*yA-}{%$a>nS78Pj}>=>8dQZrLPBDj83~1}eVXklTWZ$YM*eo8p4O0!_!)G+fTVMZ zmKkLdAI&mX)>5k%E(ec61kIDshB$t+!EN@#_VAb!p zRFWUgc(0~=PS@k?m6CsXM8m-kA?S_&N%cTqvAU-KgSZ?ivZ1KL3ggTZ7yohR{V3Hf zwzx1CR%4SVPxN)?nYf;)?EHFHWxxMr)<+suwtKJl4wWp_=vnOjv0?2*mv8bknD9cJZa!|9NBVrM=ho5p$6Lly{3jJa2O-Zu1VEMY z*q^IrXYzlmuG74jEVuYse6h_PO%kn!`lWkvKymts@N=G&ev#}NEPc14V`cMWG09Y% zopJ40xkVo2!CFSI=8^q%y!Dh~E1qTnbuoEdFr{JNcmX|ScsXcbuTcpdHG}+VA z^(TNYgKsX_^*HAAD+%)ZuOMZ)Jzw~#Xci0n*a0**Z~&+;LsFo#+^7OUapldFd7hLpH?4l*K8`(_DiOeF!?Mzr8`H_&0sQ++U!%t5#c&F-0Hh% z`jX)(*p%*eJl9Y5`aJqsSNk72cK_Tw?d$FJ7~@%;jJxoj zIO#PFsN@v5RVz2WkMo}2S9X`N{X~V`*zmBY5rwM1fY|T;k0uI|98Lbyj^&*g6i+c~ zuQSYJETgn=0*WUiRZKCfWJjEgJ4aalG?&a$OslNI_N4Z<=ikG+1&Zgg9j zK5PxCT3M_8FgjHI)UehPN|R6Fubir&+d7VH`H;AQ`BXYG^dfQc;n`A9NQuOT`0{2E zp7h05cuBha-p=NqaC$|5izbDnJsgJkL>b(w+?aS;(}#$6evg#xxO1qBrPP&-HI-X;4>4-b!T zU%yUMIsepq@}xtIildGFqo${)s8LHKfz9D@vTVX5HMItzVHVmirKMgqB8X#tNdZa8 z1c*qJc5r_$;~E(lc-8*evNy(O0p2`gAZenf=eaU)+i&j6dz=m%C_nm&>RkD90=R}2 z*#pqe;9!V!z7l>@c6K&Y&}wt6bn};3%*JWMMv4smaoJ|8Otf_E=@%I`(DKPqaltq7UoZ)x6FtmnBgayVvl$nZy5c<*$A?EHB*dtQytREL|- z^D+Ot7pVQ^7s!AE^$&W`ufCK{y?Tbx&&5vtLP+am)w89YBAdgDgIno`{hCW7LkG&$ zPsz>#x-I!PPLw_zHi;*3maMD#PM2rqtc~p5@a3O8gd8s`dK;zi*OM=GlbM;BkI0+P z>saXNVI#A#VQ_$e%3!F7y^o2JJDPrZ>?;hFS)ms}Q1EWtHYk{(c(n8wo^~DTnEUa= zhv_|w;B;L7u7WKkL3c0>V`TXGGnif`FC4hBP7&nQUP$t6LTp%koIQ1=>Jf}aPWGO_ zd2eJ}TN{*ZQI3k;n*34@l^}Tv6O?^b>A7y_HPVzJSAK-o!UQ{_C**BG;|-SKXoK5P?*cbE@8)wo)cmcbkZ_0iD-ys zk_d{&R-{VO@87bmpAnd~Xq%&2^E|CubK0X{ii*dhn+hdmt|z~!QdP&+Ryt#%+lYf& z%YOUz&8?PH+|Sk)f4<27)UyL1@LBuu-BMuWrb_9m5Nd$mft+=~O%CT>5I73eIofI< z6A}_qP!OQdBZ8AdIosIil6TtO4RVKaXKtUZ_WkD9Ja5Z|UZtuKfY~L&xesx9(fg+i zg*tgB0`L;^W4G8eZ5U!B2U`QX?5Rx49m$47(+E9CI;u};j|eF)uNBFnxv1$l%rW$} zAZHGLjF5f$^iGr^z6*Z#3qOY~VRvh_j>g$LDZNI88XAY_nza`}7IfgXTCpU5- zw^VB&`~Ocw_H$&!BV|I570BA47R0gb5m3<~5)zW#U#g29d;-aD8~z?`&+YD<$K`D~ z*0;joiTPBtWY&l?3qaja5Pnj_qufo|agZ?G8bTVKp8Q%q)Mmv zQ(=J!gPVlW>rJ~(%J&T>V0{LrR}t(d|51n3Oeimi&N@W@ z>5$a+i^dw%%h0h)Z{O&1SQRv(v0NXZG#6HdBtj^6d=JOyf%GRm#ekk$wm1PAY6xzg zPUF@B)SD}zoeww^MnsDZ3|ZEyCX-wzr>E($yx%BEPRIFc_Gw?L^69Cz%up3SRYTtq;Ur0 z$3OdwO^<~p?z#gmM?A%2VkwGVqP!bTgl0kI(W+KlY=ty8rtcm!&{MZ+%HzLg3BhI) z$EJ9t4KLBAvv{|CC&FW`QEi*?ir8PJBtj?Py5j;eE4>S<)0thwr>h9tSr~tFM5*?x zHU_488uW#9{AI&l!zN&BVP(=PU=@{l9L2UQPKeN8AjQUgE$%I__bvkG*9_N9VMSqy zqp385hYtxCX#_mTm&&fR3rO5kg6_(jhg49$Xb_TY&D-FNF1bZjPWIJsNDi3}OKVl| zdQ@FN!~(mTBu$8g39Bml6Jo@YF$S!!??a?fcov!N3W(E3fS;0 zUi}xAMW=CHT}V4NFc!^%HGbS8TGB0e{78JY!G*Q^&Fun};f?wX*6ydZ;)>6PiJ2L9 zExTKtShBl{7JpO&3n0m)m6r|4u9G!_P%2I*Gojg6xS|$QV5jxI3Z?#HRK$-&Ik`? zkIVX~*d~3SAb-_)=NGy>f;SRj7zAfXd2{ zlse`nfuR8Vib6cTl-bRR#3oys@0Wl7W;V=_Be#%DlRZ2fWfP9klD4$r7L9Bvzi|n_ zP&n0-e>L0q1s0^%F$D+lW5P?|A_~#{ud84{lh^E z$IRwsW!X78vM?|((9_r9QMdXdeSIPAHXkxgSGSAGBNAWE_4e)C@$vD$EzQl%H$5wr zVo#lmsF4D9LiClIkup4&w>Ex3B|r)yKS6c1T;TOor18_kQ-gyviG3Ih2+#@*4b@gB z`)o!gHljqCe*wj|!_4ZkYM{O^mX?+;UgU7mOg6+H_!}89_(BDa!k>OosMI>%stLwU zXI+5OW1(>0cEm>5Xpiv|5pnU?B!PHe?1Km!R$)SD-G>h!qUFE*q_8;Yp2UOh7%vOR z{LCt8`0dG|UH%cOa3~IT^!)v#jCD3{2>V-WEOgldBLl^BI%i&jFQ{# zyY^1{N;4DzCYJC3H@PIkW<%Ojqo&?H23kISJv}``L;8RjsNUScUcaX0+)Faq-@kvO z4N*{9>ERTLHQgMlLU&b}uC2X2JUo2LXNh@D0xBj~qU`_`GY<|9&dm7ngCH2Pr6g{0 z5GM|uUs$jhCRX`E7a*lACjhq!xICSLPJ_kyC`mF{&IRG?dvbApYHVbrMaD6H)jyFb z%Ff(xTL}T~9QUVOyt)e+D(}teLoGQwW%@HNqa3|G%8!=a!9=t@+|F1h(T=G%^I=FW zz-WuFftYIyqlET@H66mcuy|)R{Y>W*d@qidw4r)fGi5vi{dL#!st*`)H5C+KC$-QR zuTn%c4i67)Y;4jA+(ASjhn7S(Y7KI3$-3}y8=-JRFOyxvBdX>F-|iY+H|`G_$l;z({Y_V50=?^u5Fhdi>;+%l;B0gX^V93gp>yu5FO zLh2oPSsQQ#1c;I;QNhRfs4yJ*d7{YjE~VLad%-Ruc!Qg;p2_z`v!XIRqP_>jbasqepCc+}@_>OgzrG#@?U3*=MM2qiS&+F^R6 zNE`9!^3v4u<9g|-8W`VvX3(`TW8sjM46CV=S2>S+fVR9Q4m+#yGY$2o!VCuozX^06K93{8aMB+LPWnsF6-C<6 z<>lvZ^I2juhhh$zejd$Rk`cQz5wX*~To?{*c}{Ch-cIWLf4v7Z(Y5j3{}T&E4F z8gM<+M5!9aUVTDz!UeW|$gj#19ql!IRpy2g2?PpV#7}VVkv~%Wd)dxkOU%w_xk8tr z@*pB_&cMMEF2=q{0yu}^*U;CauA_$c#9bn`zLcV0>6`mg>&vTSrS5uDr%>+Ed`#a> zi}_1tq=M37(Ix1r!>OYstq5I3-<`fCkB@=N)CFG~A|E1b$Lr;ie3{UTrxiMER^<5R zKMa0`71D(IZl;+#*e&w+6Nlbk4Dl7xK>H1}Bed$X(AP;R6(U^fZ9@vM=0G#a3GN&S zA&mfZG~NWF*d5Hn^y1hwxEpQ;_XNTaH&Tg7X>+@`oG~m0Prhgy58Kh%H^$csEBMgS zXVN#*M>q+;BD5f|U~H)u4Z0OdicweaVS4?jz9Bptz6XP^Kx5dF)!#_LQJ;?XN+ zv5E<*`+X}rzI4);h(`1zY!PwY0?r?{ZIp;3$&NoiVw2L8&y}U*_Eem{J3n7gGMta# z)5EGaN%ia4CA8|oPlDxe?qQ7X-M7UOW#Yq9wsX;Nwh}mc!&2XOFFliHebx?hcF)Iz ztLo%vE;@a8_+>lJ7!fTt$rn04tS(xq6y%1)04_JlQm~t1dKuea>XpW~TMUVUnA>x) zfr4+kS#lXC8T^b8QFCu*PAtjLgsNd=*K-AAalNCRm$y8p*WnNAhMNMIg8sk8t~;u! zrQ4s7(7UuCRf>cn1QA4vK@m_91gU~R0xCt6VgZyATBwR0Y*eL*5b)AOArK%+M|zVc zRjL%}yb0Xv=Y8wFwZ4B+&Y3xLW@gWxy??Vy=3G~G;0kg8pgdh zJZA7$keA^4JYmRvs#1zonOUQy{!(Q+m*z1_(}%cwdQn445x@9mMUP%~Viszu*SUj= zKIla2r=8!ab?Pz2c*Qiav50fdxpD)(oOpBo6xs3I4fgybD__H=Q!iB;`20xwl0ALn z?ieH)F6u4vUTX3&l@z0^pl1}>_c2mGFw@;*&RMS|u3amt2*mH=Lx`Ld(BbE<_TP|Z;j`pP2l-NLNpX^Ac#(PN$G9LY zH?InP^d6R|3OFn!PL)F)m*)`2bxUPA(W+BzJRZrRV~q|sM$XLv^&yaJ;3V9dKUGC7 zCe{d}hTl)*YD->lf1`z4*J# zwG_A-T1)eS=V}tW>c$fb+j14PXcuE1w3hdyVUCaD1BWgk@DwYR&y_Eu=T7robLHfc z9wO`!Nb*T)N*LU78x$CP5^^iDM!SvR5|u9H+b-K$Xk^BDU6s?18N&ywTM-;0i`JZ| zGYG|mC3uggwkJz}WKZ(>7)~?D$0ULs$R@6f^Kwv)U%x=4qO(h1%*teMVF^?XiydlG zJ98a^vaDI?E4FxRnX2$8urw3VwpGt{qBqG($fqbd8_Pm;9uDPDhIFh#?~A^PEUDN} zNQ%DtQq+)j1ozmjr+}4CZSsUQ1X+ISB;_ItLZsz-?5t<#Ct>^ zI}etsy?_CEEi5qTCvl?r>|a6giEv^<6N(Utt4!pvTtLqlAJIL8%Wwcb^M-a16q$r> z0QnUIWrK6gI=dj`%TP;3CN4n%CmNw@9x|U`0~=d^GS3ahWwmVfnqjjG*-dKtkNF-U zQ4#uqr_n)C@xziYmAixT!}iYcla?y=RTVsDR1t3UliXN58OG>cW(2Q+bSlGtc3)uR zz%l9dap4AZAHO{Bni?u}#UWLxr|#lQPDw{$)!OrQU&rNMv0&Wy3pPAV5p|)zJPQYG z?kNjozIFKEF2iGB=k3gzlf`>5I_zzisZPUD9Ec+Dg>iwYn;<=2e6EQ2xHn_9e4R;L zrhUC6LTRtV29levnSy?V$KX0Dc*EYv>T==AhAd5ky0P6A{-Msy*1Y}Pak^R}*r|&B zx+28edm4!m9&*_%dv!L6RmN}^f+Fh`VTB~fg(J$z7@`D$WGrBK$?#EF6TJo;iGG7; zbAY!7@B2DyywEK)IpJ`}&^Wj0~yRk&Q%2@7FUKF7P=75ca z48kwPItitT_7-^zsWKG>ZB_vL*C-_&*dl+2kt*%rp+G_G9>FMmi3Xb@TdY6yNoUNM z-G#%}5{17;p4U#xzWMq5H#T=1@PebBBA~#jEad0%$$9*I-BK`p<+$f(_`dHq1{G-^ z*}N7zK87O@m_qbh;j-qf!B+((m!k?!WbPld!e<^|jXt4`Vi8yWzCVy`EF8-myoi*h z&~35k%rX`q8bEO(g$=MV;Ri!*6Jf!^+3G+k)w33ReJZ`!$nm%vLdD(1n{CNJFnp{j z|7*SIaR`cAAAk6HGbFZ>Fb>bU6}P@GMhIpzsDDS>kE6L=r?A=4gOf<_M?Mugq#V%@ zrD1fafvO1pK7zn7)-B35Ifm?sn!M)G_MrCJ46BlLMEF7BHi2WEl|fu$L4$QO=KG>u z$M~4V4o#TjvHZq+ zjF$7tBvp&0>c3PZAf1O5>VA5c0lFKlHh7)}_d}dp+5T2o^qmJBLggu(?+q)Xv^|9p zPjpXSnL5_#RGFd8@0#fOk!oBD&a`$F(|4+nkqU;}cd9(PC9UK`2|2i8Foi)v>%v46 zgxOO?Y6`m)!y4DOk|^fEda!PQKf~cZ3w9qrvOChAC=oQNC}!8y^EaE zD=_erxhLrARkZefY)t&pMJGBaRpnf-sDgw!GZypJL@Yuol>sdUwTMXIHBXjAFv5!V zu(GhoMZP(0-G7GPfz@`A zjSgVzL|4EYNqgeYVYV5Dh+nC-!Aw)}27o|-8Tbd$0TcSaZ~Z;Rp!}a?M0LgA#RqmE zjdmmy{ulIl57ug6@79TIe0tJx9urP=cp$!0`rgv*Psy1KxHQV}vrjUh*&Rv+eR!e@ zxd!ncIQ0-+zUg1q^SI3=l<_DU?LI$LwYBB1F|75NlYpp!!$Y32y|8tSiH=UB6BIy) zYRbo6@%0s?A9{aRbI9`iQxAr%6I`971XM)q{YYd$GM(|*zyS7jF>rzS-N`-lkmV|G z6m9iwA0HoJs^aYI4AgFI?O@Ts+E|5Oi;Jcf7Ub?*s)FED24!+Jv#_u*Cnu+%fH%}* zWqcgP1k^xqiTs>m46JZs&jhksSz7}Wm)tbqO3Iofv(W{PRvdsyKMa}9dq+lAc7Cj> zi6fIn;LHn`KT#TR?vQo0v!8^|%R7kcW#$qj&#h>+x3&)On;)f{dS&Q%{kjt1I1{Rf zbzCYrFYG)!FowrwClZOo9_~&^0w3t>PLt&;3OhZ-zZ5KnZo}_4Vo^7S+LF<>$MZXb zec-LpZ0>ab0ne-~q0aGNw~1V(hmlob^{le}j!YsaqsxaSk-xkd3I9$F#O)46be&1sQ z^#b;FO&gx_%=SH{t6&rA^G7KedA`JYfu(ouFs5uVKGAon5C3SV3Iyoem2`K}zTd~^ z|5tA&p94@&@)79Ye@2f3GBV>4Dbo@iSXd<*{MlKX6o`0pc>ME88yg!tyM7W$%i6kU zWu*v&GKhE&`||~jA@7aBC{|Vw4rh9LT3J~cWEJ4&=Lax9@N{=|bp^+R2;{#&(he5L z^@F9Io%dh`SX#Gk-73!L?(PQZc7}$A>gvwqbm;%o&3ovn&|2Jv)`Dy?cD8w6M^^nn%eGOv{xsE1uOBhX5371$Cmjray0w zphHK>hFZqwz3;EjPG8X62Mx1FzE)v-liMAUxyGBG==_tI!8 z>|KoJN#0Sflu!cq<(x?K&Wz-!sh%wrH1P$*P_b0~a>FSc;mW#pG%snWD{Y%)x4$m7` zhS1Dd;Jnhzp1MsOr&p&Kn3hx^D@1NdDp`!tk^G{r;{1$(2HYB;oJDq&wP{?!R(mrmP6A8vF!jUUn`AI#h z97`#5Kw{b@bzm;oX6|A|L_?o@S4Y2mzxa{?ER4~8;N+HF1fZtb+wA?qMC`j>~VgL zV0mJoV{7ypCk}dorzZy1;7T06a9V{($Ix^#vLDYnS#6kG&G1r`7Zt3iX27^0lqHso zjIbYvK7`qK#{BfALk|cx!*1B#fYftOFiMFHiT*90Y9XK%n%iYMZX)fk;-4@>RyT`> zf7r?Rk8u#Td1ZTnDEq-Y6z7esB(5j;Eq7ry2H8R0dhHN}tVN2UI)oGzJfec;@$(8pWIwSYmn)zG zMbAR&4O_jZ3Cu;yEsu6W^vPB*o^UDX{T4`V>CH2$K1s9Wg~&(K9kY11!4)6#f}8<^F@7X=%GN4Y(Ku$mqBUxAGlHvG^Ef7E6C^Gc!L6 z!OP&^0=7A2Hyj@1tn6cOYX z+LX2WpW09H_56Zyb7xf_E50~r&x$&BfD^9E}B~E!h4_b0l8m2jB zPd+M{OD}+uV+y%ND3dtjGJh`pOgdq1Gs!+_dd@!C$`six-p$jgai?>aSy)lVVPwZbJ#P`@|Gq&H1TczcD70UN&Gi59I8CP-s zIm7&gK3C>j744L_QcPF*N_tTjEN3@FJFI%gYjUoq@^(pjq4PWAFI+sU;4uZ#7G-}8 zw1^q$QKR>@5|m}FfF%}Cl^T!9OvM1uJSy_TC=5g(9avqMU0+*}Vh>kal*G^tGX>V|75dD^V8Bm?oh}{&K0gNK^k>291+7wL0-Xa~kkja1d|C@jW5NNE$;Q_c z{oc*^z-kyLkLhgDRDG8FYaR#De*f`agzKi#$UW^bxg%{~<7~>)w~J-;be|3XjKieq z%D6o!q4V>(+3>n$xXK{AM&&$2dLYOg-)O4pu1bUzd`tyk54C@Qu|IQIX-N~EOMwvOcM%l20LowU&xC9At@i;cGfbUyBX<1?dvS1`# z(R80pna;#JO=I_iSGd*{dGN(F+=LR&crF__Rh!spC4B`F<)&+$X|F9|RY)w2_&m7! zEM=+tMy{@xW1cd8l#w^o(O@_|VR+V}f;RkV;pjRU*O z3z2hhe`TbpMd=AC+1ee!m0C&J4RR6?zUg+GR5$@+mYaxRtgYz?Y1Y@f_SCb-f-21J zyp}QsLfha~Drirda9`z#0Dfn?*Lf5mB=An>hfJGk!~cG{JrJY|+ZA3xsa;ui_txKn z;ZD_77kbFROu6M_`(;VkV2DVr<8sPn;p0@1YxmjU9R>2S?yfglUGi^h2q!f1<#m&< zdd1d;TBOiuIXOC!e=H?y9A6Hby#Vd`UCXorB09Uf6MIc{bacQ8WXpsgkX`sKJAo7f zf)IJA3U(@?(M=s4VVXcq9UdMQ7Z)d%%}3hCaaa{Q`BP$|CWrs^s#a}02J`aUvP49p2?M=j3WyXv2Rm zaRul?1kE9nK~8^OiMtAXuz%KK`UpKV3i~}n{~tkslS0^CUk$wp&K)_LN--cBL8aKh z5zDdekIRkCL+qNS23|h-9;XV6ZeY@>vdu1~08b|Y7!=+b@i|^edoyGi3!m4-T^Aph zdg!BrU|>SfD5cQV8_VY$ojD}TW%y|@uRv43XC-^N=U0Bq&CKu3zlS705ojCYG~42L zEY6;d3IDY8Z^N|v(rYvxybzs&loQkvqwZnoJTyJT(KJlmJ?D#PLl7J2rc^^cMWf9`y1B0IdUvS;Ofd z%$Vx{hv2=J<)q-^Bis{DVi&b_)=DJT?z~yMmo4^008s-cnt57eF%Z!yu8$kox!4Frs^l69(%sCTBgMw(VWWfVix#jwz^n~<-!Xl4l ze$6iQEl1w!kzKo*GwD^vsd0Xg8TFg#S)GK?DUgl;F`+o!A}Te!jbuMU>b;8%vlc0c z3N!DX@tF+Sn7yO%OUj3h=QFP~a47woVdc+3MBvIdDnN_UU~w`sqfD0;)O!B9zp-8D zrC@OG)lDc2L$JmKUa70Fq#X}>cfP3R_+g_D_f5|mAI`{2hS`f|Ae8y+nNHX{bHX2> zII#GL`>={j@+`lKVO)gx_=$=5ma)+?#|lYp1VR7!@ItG#jiy_|OlH@ovZHDJCRbix za^@3-An(861A)B^Q=?Ke5CjSLKq$x3Wrb^8z|;Z!O@oTaT`(B(NguhYz@e&PW~k=GK2UHV zke>8aOdn)`#KNHQtn@I?x+kUS2*kGc!LwzqPdmfIPboH!{-F zq{MLc_Cvs&uFXaH+d(v%V}yfVP}N=ZUPMe}VdYniZ{K=)?ofnPm8`OROiJ5~vwxuM z`r;KDLGS>=a-=KT4nvdgiQ1p!9@DS%eJAi1~Z6o*yeE1Q<* zDEjkn{N;WPt8anqiq+-0S(w|4P8YTMqgCNX8Ky&xNl8iG(%*Q(s=kNvD=Mj|@SYvg z&;rofLy1B=808YiZN}MeQ-pu+XITAgP7QCi9AA#hT^-pd9_trv86T+=J2yasb$*a) zVq)^%VlGW-uhP&jNRdlHhrROoQS;S#4gYR|NBLF@R()e7~!%iZ)|e(Uuk%KUr3Uy|?7!Vz{m{pDZEKVM*ufd)u^^rSj@EsvynKChq8 z-X}C}chioylSefYD5VKHN6w$!>N2xgwOtx{H>}C$q7&am%K(Vb7wX;8#r`5DjeVlk z`nZpGvtIS?{p!mn3ShJ#34u6NI(a9smt2GePE^!=f0)7F2* zH&N8ts8fIl>jb^j1efOPk zN7dA1z&-3y*!|RLKIqiBVm0#&V1@~rSAvFEv`S93{B=;9+RV;U6b16v&f27Q81eV= zgkYl3PWQFI7bt-TU(_K1js96{=K@5d1@8WL6{&*+``zL{wRSK3w-58phs||8k@d0t zYxZwe!irx}prfOs$P8Opr*z+=_DvKT^`OIgU%cp<*SzEUXVHgkGS_oss2Y(4J&*x|f=63$0n`EOm= zsVv+F#o6SSl`5Uj%Pg3hUNccRtGOArHh8`3Wt;DF9=B;j`Iy4XIcIp+4KJU!U1o8l z(7&%S&7Bw?O;CF{lccd!&3oJ`|>=9+_>`(ZVE8DekYC*)N{@yn^8ti82 zX#BSuwMmO^^e?Uy7;JB1m25ZDrTpfDC*J9ORh61UH^6s01%k1u-cX5h+Z?V*upHX{ z*{6Gf_Ag&;hu7!6cbHGN)aN;(a@wO>Vt>vg$z^Xx$okq(X+C4U$FuZW!+ZY^jVCsO z3PX{Jn^G;;Q&yXq&(EIx)*Smv=&B9hcNWkYngLD*{4-F=Z@Vr*;H<{s)v45KlbkaL zd`p+Nl5RBIRDYk*w6^MItkTln7%+TFP)VI%e*^h`jO((L n7Ag@o9aK?SE~3-wSyi}s&nP+JlIK})6*{G3cq02aHt2r<3Rb0v literal 0 HcmV?d00001 -- GitLab From 8ad91e1fd600b43c468503ecad2db9937b59a4ff Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Tue, 26 Jul 2022 17:46:26 +0800 Subject: [PATCH 230/380] fix: remove escaping double-quotation mark for sml binary str encoding in parseSmlValue enh: preallocate buffer for parseSmlValue --- src/client/src/tscParseLineProtocol.c | 63 ++++++++++++--------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index 8a1eb88e93..c979d1512d 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -2058,6 +2058,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, const char *start, *cur; int32_t ret = TSDB_CODE_SUCCESS; char *value = NULL; + int32_t bufSize = TSDB_FUNC_BUF_SIZE; int16_t len = 0; bool kv_done = false; @@ -2077,6 +2078,11 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, val_rqoute } val_state; + value = malloc(bufSize); + if (value == NULL) { + ret = TSDB_CODE_TSC_OUT_OF_MEMORY; + goto error; + } start = cur = *idx; tag_state = tag_common; val_state = val_common; @@ -2095,7 +2101,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, back_slash = false; cur++; - len++; break; } @@ -2104,7 +2109,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, tag_state = tag_lqoute; } cur += 1; - len += 1; break; } else if (*cur == 'L') { line_len = strlen(*idx); @@ -2122,7 +2126,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, tag_state = tag_lqoute; } cur += 2; - len += 2; break; } } @@ -2131,8 +2134,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, case '\\': back_slash = true; cur++; - len++; - break; + continue; case ',': kv_done = true; break; @@ -2146,7 +2148,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, default: cur++; - len++; } break; @@ -2160,7 +2161,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, back_slash = false; cur++; - len++; break; } else if (double_quote == true) { if (*cur != ' ' && *cur != ',' && *cur != '\0') { @@ -2182,13 +2182,11 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, case '\\': back_slash = true; cur++; - len++; - break; + continue; case '"': double_quote = true; cur++; - len++; break; case '\0': @@ -2199,7 +2197,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, default: cur++; - len++; } break; @@ -2217,9 +2214,8 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, goto error; } - back_slash = false; - cur++; - len++; + back_slash = false; + cur++; break; } @@ -2235,7 +2231,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, } cur += 1; - len += 1; break; } else if (*cur == 'L') { line_len = strlen(*idx); @@ -2252,12 +2247,10 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, if (cur + 1 == *idx + 1) { val_state = val_lqoute; cur += 2; - len += 2; } else { /* MUST at the end of string */ if (cur + 2 >= *idx + line_len) { cur += 2; - len += 2; *is_last_kv = true; kv_done = true; } else { @@ -2271,7 +2264,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, } cur += 2; - len += 2; kv_done = true; } } @@ -2284,8 +2276,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, case '\\': back_slash = true; cur++; - len++; - break; + continue; case ',': kv_done = true; @@ -2300,7 +2291,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, default: cur++; - len++; } break; @@ -2311,10 +2301,11 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR; goto error; } - + if (*cur == '"') { + start++; + } back_slash = false; cur++; - len++; break; } else if (double_quote == true) { if (*cur != ' ' && *cur != ',' && *cur != '\0') { @@ -2336,13 +2327,11 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, case '\\': back_slash = true; cur++; - len++; - break; + continue; case '"': double_quote = true; cur++; - len++; break; case '\0': @@ -2353,7 +2342,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, default: cur++; - len++; } break; @@ -2362,24 +2350,30 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, } } + if (start < cur) { + if (bufSize <= len + (cur - start)) { + bufSize *= 2; + value = realloc(value, bufSize); + } + memcpy(value + len, start, cur - start); // [start, cur) + len += cur - start; + start = cur; + } + if (kv_done == true) { break; } } if (len == 0 || ret != TSDB_CODE_SUCCESS) { - free(pKV->key); - pKV->key = NULL; - return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; + ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR; + goto error; } - value = calloc(len + 1, 1); - memcpy(value, start, len); value[len] = '\0'; if (!convertSmlValueType(pKV, value, len, info, isTag)) { tscError("SML:0x%"PRIx64" Failed to convert sml value string(%s) to any type", info->id, value); - free(value); ret = TSDB_CODE_TSC_INVALID_VALUE; goto error; } @@ -2389,7 +2383,8 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, return ret; error: - //free previous alocated key field + //free previous alocated buffer and key field + free(value); free(pKV->key); pKV->key = NULL; return ret; -- GitLab From 539e871014bef1aaa858c0744d081a1abd74a763 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Wed, 27 Jul 2022 16:30:42 +0800 Subject: [PATCH 231/380] docs: Create 13-DBeaver.mdx in 2.6 --- docs/zh/20-third-party/13-DBeaver.mdx | 68 +++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 docs/zh/20-third-party/13-DBeaver.mdx diff --git a/docs/zh/20-third-party/13-DBeaver.mdx b/docs/zh/20-third-party/13-DBeaver.mdx new file mode 100644 index 0000000000..ed257c8490 --- /dev/null +++ b/docs/zh/20-third-party/13-DBeaver.mdx @@ -0,0 +1,68 @@ +--- +sidebar_label: DBeaver +title: 通过开源数据库管理工具 DBeaver 连接 TDengine +--- + +DBeaver 是一款流行、开源的数据库管理工具以及 SQL 客户端,其功能强大,并且支持任何拥有 JDBC-Driver 的数据库(这意味着几乎所有数据库都支持)。 +其官网的介绍是这样的: +>Free multi-platform database tool for developers, database administrators, analysts and all people who need to work with databases. Supports all popular databases: MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Apache Hive, Phoenix, Presto, etc. + +只需要简单的配置即可使用 DBeaver 来连接、管理 TDengine。 + +## 前置条件 +1. DBeaver 依赖 Java (JDK) 11 ,不过其安装包中已包含。可选安装 Maven、Git。 +2. 已安装并启动了 TDengine。 +3. 若使用 TSDBDriver 驱动类连接请在本地安装 TDengine 客户端。 +4. 若使用 RestfulDriver 驱动类连接 TDengine,请确保 taosAdapter 已经正常运行。 + +## 配置步骤 +- 可以克隆 DBeaver 在 [GitHub](https://github.com/dbeaver/dbeaver) 上的源码,执行 `mvn package`,也可以直接下载打包好的安装包。此处选择直接下载安装包。 +- 在 GitHub DBeaver 仓库的 [Releases](https://github.com/dbeaver/dbeaver/releases) 处下载对应版本的 DBeaver,比如系统为 macOS,处理器芯片是 M1 ,此处下载 dbeaver-ce-22.1.2-macos-aarch64.dmg 进行安装。 +- 点击数据库标签,选择驱动管理器: + +![image](https://user-images.githubusercontent.com/70138133/181191577-7bb91c96-b4fc-455f-9f6c-545993f0a445.png) + +- 新建驱动,选择 TDengine 的 JDBC Connector 驱动包(其中的 dist.jar 包),此驱动包可以下载或者自行编译、打包,参考 [IDEA-源码编译 JDBC-Connector](https://docs.taosdata.com/third-party/IDEA#%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91-jdbc-connector): + +![image](https://user-images.githubusercontent.com/70138133/181191709-fcc3faa3-cfe9-4b0b-8c1b-5074c9411c8b.png) + +- 添加后点击找到类,此处使用 RESTful 驱动类演示(注意:若使用 com.taosdata.jdbc.TSDBDriver 驱动类,则需要安装 TDengine 客户端): + +![image](https://user-images.githubusercontent.com/70138133/181191776-fc1ab7ff-b323-4913-92d7-aa5a10a5a6d8.png) + +- 填写一下驱动名称,简单填下配置(需要在 hosts 文件上添加连接串内域名的解析): + +![image](https://user-images.githubusercontent.com/70138133/181191846-2c16b98a-c171-4936-a894-3fdaf96cfba1.png) + +- 点击新建连接,搜索配置好的驱动名称,点击后进入下一步: + +![image](https://user-images.githubusercontent.com/70138133/181191887-cc13a397-64a0-4dfc-b42f-d65608e71eae.png) + +- 输入密码后,点击“测试连接”: + +![image](https://user-images.githubusercontent.com/70138133/181191921-e5a05f93-0ef5-45fb-8707-5697bcdef64b.png) + +## 验证方法 +- 点击“测试连接”若弹出“已连接”的提示代表连接成功。界面左侧能看到刷新出来的数据库(database),点击特定的表可以查看表的结构及数据: + +![image](https://user-images.githubusercontent.com/70138133/181192410-e7509c1a-0f9c-4282-a69a-82685e659fd7.png) + +- 点击界面左上方的新建 SQL 编辑器,默认,输入 SQL 进行验证。需要注意的是,RESTful 请求是无状态的,查询、写入需要在表名前带上数据库名。 +- 2.X 版本中默认带 log 库,我们可以使用`SHOW log.stables;`查看包含哪些超级表后对特定表进行查询、调试: + +![image](https://user-images.githubusercontent.com/70138133/181192488-727c3c1d-906a-4fbe-bd2e-41678d5e1627.png) + +- 可以看到有个超级表叫做 dnodes_info,执行`describe log.dnodes_info;`查看表结构: + +![image](https://user-images.githubusercontent.com/70138133/181192651-0adaafeb-c7ff-4d02-93b4-e1e3aebb39ea.png) + +- 再执行`select last_row(*) from log.dnodes_info group by dnode_id;`通过 dnode_id 能分组查询各 dnode_id 下的最新一条数据: + +![image](https://user-images.githubusercontent.com/70138133/181192918-e71d6482-3901-4b14-956c-2894658e2b67.png) + +- 还有其他操作也可以自行测试,比如写入一条数据后进行查询: + +![image](https://user-images.githubusercontent.com/70138133/181192959-27b8ded5-9719-424a-ae08-3b5635dd7fbf.png) + +好了,到这里我们就大功告成了。DBeaver 功能强大,其他常用功能还包括导入导出 SQL 脚本、配置表过滤器、建立数据库任务等,大家可以慢慢体验。 + -- GitLab From 29a0b6122847653c9c3ba903f41cafdb5b435073 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Wed, 27 Jul 2022 16:36:11 +0800 Subject: [PATCH 232/380] Update 12-IDEA.mdx --- docs/zh/20-third-party/12-IDEA.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zh/20-third-party/12-IDEA.mdx b/docs/zh/20-third-party/12-IDEA.mdx index 2dd682f199..7d45c7f2ed 100644 --- a/docs/zh/20-third-party/12-IDEA.mdx +++ b/docs/zh/20-third-party/12-IDEA.mdx @@ -59,13 +59,12 @@ IDEA Ultimate 版自带数据库管理工具,类似于一个小型 Navicat。 ![image](https://user-images.githubusercontent.com/70138133/180197251-98764434-bb7b-4e3a-9674-0620ab6d8bad.png) -## 验证 +## 验证方法 -- 配置完后进行验证,点击刷新后再点击显示所有数据库: +- 配置完后进行验证,刷新后点击显示所有数据库,看是否出现了所有的数据库: ![image](https://user-images.githubusercontent.com/70138133/180202803-6e277132-44bd-4b22-8921-a54d16190d2b.png) - - 右击数据源,新建查询控制台测试能否查询。需要注意的是,RESTful 请求是无状态的,查询、写入需要在表名前带上数据库名。 - 2.X 版本中默认带 log 库,我们可以使用 `SHOW log.stables` 查看包含哪些超级表后对特定表进行查询、调试: @@ -82,3 +81,4 @@ IDEA Ultimate 版自带数据库管理工具,类似于一个小型 Navicat。 ![image](https://user-images.githubusercontent.com/70138133/180205161-7f0314eb-cdaa-442c-acb5-d33931c32648.png) + -- GitLab From 008087cc0b262fd6f6af5f8b4847d326b3af0cba Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Wed, 27 Jul 2022 16:56:27 +0800 Subject: [PATCH 233/380] Update 13-DBeaver.mdx --- docs/zh/20-third-party/13-DBeaver.mdx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/zh/20-third-party/13-DBeaver.mdx b/docs/zh/20-third-party/13-DBeaver.mdx index ed257c8490..7685de4dd8 100644 --- a/docs/zh/20-third-party/13-DBeaver.mdx +++ b/docs/zh/20-third-party/13-DBeaver.mdx @@ -30,20 +30,23 @@ DBeaver 是一款流行、开源的数据库管理工具以及 SQL 客户端, ![image](https://user-images.githubusercontent.com/70138133/181191776-fc1ab7ff-b323-4913-92d7-aa5a10a5a6d8.png) -- 填写一下驱动名称,简单填下配置(需要在 hosts 文件上添加连接串内域名的解析): +- 填写一下驱动名称,简单填下配置: ![image](https://user-images.githubusercontent.com/70138133/181191846-2c16b98a-c171-4936-a894-3fdaf96cfba1.png) -- 点击新建连接,搜索配置好的驱动名称,点击后进入下一步: +- TDengine 的 JDBC URL 规范为: +`jdbc:[TAOS|TAOS-RS]://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]` + +- 点击“新建连接”,搜索配置好的驱动名称,点击后进入下一步: ![image](https://user-images.githubusercontent.com/70138133/181191887-cc13a397-64a0-4dfc-b42f-d65608e71eae.png) -- 输入密码后,点击“测试连接”: +- 输入密码后,点击“测试连接”(注:需要在本机 hosts 文件上添加 URL 内域名的解析,URL 内的 locale、timezone 参数在 RESTful 连接中不生效): ![image](https://user-images.githubusercontent.com/70138133/181191921-e5a05f93-0ef5-45fb-8707-5697bcdef64b.png) ## 验证方法 -- 点击“测试连接”若弹出“已连接”的提示代表连接成功。界面左侧能看到刷新出来的数据库(database),点击特定的表可以查看表的结构及数据: +- 点击“测试连接”若弹出“已连接”的提示代表连接成功。界面左侧能看到刷新出来的数据库,点击特定的表可以查看表的结构及数据: ![image](https://user-images.githubusercontent.com/70138133/181192410-e7509c1a-0f9c-4282-a69a-82685e659fd7.png) -- GitLab From eb08390d12f6e54ddf6ee54d3721f91a7d67792f Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 28 Jul 2022 11:01:47 +0800 Subject: [PATCH 234/380] fix conn can not get --- src/client/src/tscServer.c | 3 ++ src/dnode/inc/dnodeVRead.h | 4 +-- src/dnode/src/dnodeShell.c | 1 + src/dnode/src/dnodeVRead.c | 10 ++++++ src/inc/taoserror.h | 1 + src/rpc/inc/rpcHead.h | 3 ++ src/rpc/src/rpcMain.c | 68 ++++++++++++++++++++++++++++++++------ src/util/src/terror.c | 2 ++ 8 files changed, 79 insertions(+), 13 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index a4bd164d78..751c96f527 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -291,6 +291,9 @@ bool dealConnBroken(SSqlObj * pSql) { return false; } + // set error + pSql->res.code = TSDB_CODE_RPC_CONN_BROKEN; + // cancel if (pSql->rpcRid > 0) { tscDebug("PROBE 0x%" PRIx64 " rpc cancel request rpcRid=0x%" PRIx64 ".", pSql->self, pSql->rpcRid); diff --git a/src/dnode/inc/dnodeVRead.h b/src/dnode/inc/dnodeVRead.h index 9171026f21..768075da91 100644 --- a/src/dnode/inc/dnodeVRead.h +++ b/src/dnode/inc/dnodeVRead.h @@ -28,8 +28,8 @@ void * dnodeAllocVQueryQueue(void *pVnode); void * dnodeAllocVFetchQueue(void *pVnode); void dnodeFreeVQueryQueue(void *pQqueue); void dnodeFreeVFetchQueue(void *pFqueue); - - +// reponse probe connection msg +void dnodeResponseProbeMsg(SRpcMsg *pMsg); #ifdef __cplusplus } diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c index 26a2fc9651..af1afc9766 100644 --- a/src/dnode/src/dnodeShell.c +++ b/src/dnode/src/dnodeShell.c @@ -77,6 +77,7 @@ int32_t dnodeInitShell() { dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_RETRIEVE_FUNC] = dnodeDispatchToMReadQueue; dnodeProcessShellMsgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dnodeSendStartupStep; + dnodeProcessShellMsgFp[TSDB_MSG_TYPE_PROBE_CONN] = dnodeResponseProbeMsg; int32_t numOfThreads = (int32_t)((tsNumOfCores * tsNumOfThreadsPerCore) / 2.0); if (numOfThreads < 1) { diff --git a/src/dnode/src/dnodeVRead.c b/src/dnode/src/dnodeVRead.c index 6b2a0ab8e0..50d6f30f26 100644 --- a/src/dnode/src/dnodeVRead.c +++ b/src/dnode/src/dnodeVRead.c @@ -155,4 +155,14 @@ static void *dnodeProcessReadQueue(void *wparam) { } return NULL; +} + +// reponse probe connection msg +void dnodeResponseProbeMsg(SRpcMsg *pMsg) { + // check probe conn msg + if(pMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN) { + SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = 0, .msgType = TSDB_MSG_TYPE_PROBE_CONN_RSP}; + rpcSendResponse(&rpcRsp); + return ; + } } \ No newline at end of file diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 029d3bd40f..0ffb7f89dc 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -60,6 +60,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_APP_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0014) //"Database not ready" #define TSDB_CODE_RPC_FQDN_ERROR TAOS_DEF_ERROR_CODE(0, 0x0015) //"Unable to resolve FQDN" #define TSDB_CODE_RPC_INVALID_VERSION TAOS_DEF_ERROR_CODE(0, 0x0016) //"Invalid app version" +#define TSDB_CODE_RPC_CONN_BROKEN TAOS_DEF_ERROR_CODE(0, 0x0017) //"connection is broken" //common & util #define TSDB_CODE_COM_OPS_NOT_SUPPORT TAOS_DEF_ERROR_CODE(0, 0x0100) //"Operation not supported" diff --git a/src/rpc/inc/rpcHead.h b/src/rpc/inc/rpcHead.h index 5b401ac54b..6bbd72f099 100644 --- a/src/rpc/inc/rpcHead.h +++ b/src/rpc/inc/rpcHead.h @@ -16,6 +16,9 @@ #ifndef TDENGINE_RPCHEAD_H #define TDENGINE_RPCHEAD_H +#define TSDB_MSG_TYPE_PROBE_CONN 0xFE +#define TSDB_MSG_TYPE_PROBE_CONN_RSP 0xFF + #ifdef __cplusplus extern "C" { #endif diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index da08c924a5..1c4d12a2a0 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -124,6 +124,7 @@ typedef struct SRpcConn { int8_t connType; // connection type int64_t lockedBy; // lock for connection SRpcReqContext *pContext; // request context + int64_t lastLiveTime; // last alive time with ms } SRpcConn; int tsRpcMaxUdpSize = 15000; // bytes @@ -993,6 +994,7 @@ static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv, SRpcReqCont pConn->peerPort = pRecv->port; if (pHead->port) pConn->peerPort = htons(pHead->port); + /* // probe msg if(pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN) { pConn->inType = pHead->msgType; @@ -1002,6 +1004,7 @@ static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv, SRpcReqCont pRecv->msg = NULL; return pConn; } + */ terrno = rpcCheckAuthentication(pConn, (char *)pHead, pRecv->msgLen); @@ -1086,6 +1089,41 @@ static void rpcProcessBrokenLink(SRpcConn *pConn) { rpcUnlockConn(pConn); } +// process probe msg , return true is probe msg, false is not probe msg +static bool rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { + SRpcHead *pHead = (SRpcHead *)pRecv->msg; + if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN) { + // response to + SRpcHead rspHead; + memset(&rspHead, 0, sizeof(SRpcHead)); + + rspHead.msgType = TSDB_MSG_TYPE_PROBE_CONN_RSP; + rspHead.version = 1; + rspHead.ahandle = pHead->ahandle; + rspHead.tranId = pHead->tranId; + rspHead.code = 0; + rspHead.spi = pHead->spi; + rspHead.linkUid = pHead->linkUid; + rspHead.sourceId = pConn->ownId; + rspHead.destId = pConn->peerId; + + memcpy(rspHead.user, pHead->user, tListLen(pHead->user)); + + bool ret = rpcSendMsgToPeer(pConn, &rspHead, sizeof(SRpcHead)); + tDebug("PROBE 0x%" PRIx64 " recv probe msg and response. ret=%d", pHead->ahandle, ret); + return true; + } else if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { + if(pConn) { + pConn->lastLiveTime = taosGetTimestampMs(); + rpcProcessIncomingMsg(pConn, pHead, pConn->pContext); + } + tDebug("PROBE 0x%" PRIx64 " recv response probe msg and update lastLiveTime. pConn=%p", pHead->ahandle, pConn); + return false; + } else { + return false; + } +} + static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) { SRpcHead *pHead = (SRpcHead *)pRecv->msg; SRpcInfo *pRpc = (SRpcInfo *)pRecv->shandle; @@ -1105,6 +1143,14 @@ static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) { SRpcReqContext *pContext; pConn = rpcProcessMsgHead(pRpc, pRecv, &pContext); + // deal probe msg + if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN || pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { + if (rpcProcessProbeMsg(pRecv, pConn)) { + rpcFreeMsg(pRecv->msg); + return pConn; + } + } + if (pHead->msgType >= 1 && pHead->msgType < TSDB_MSG_TYPE_MAX) { tDebug("%s %p %p, %s received from 0x%x:%hu, parse code:0x%x len:%d sig:0x%08x:0x%08x:%d code:0x%x", pRpc->label, pConn, (void *)pHead->ahandle, taosMsg[pHead->msgType], pRecv->ip, pRecv->port, terrno, pRecv->msgLen, @@ -1712,7 +1758,7 @@ bool doRpcSendProbe(SRpcConn *pConn) { pHead->msgType = TSDB_MSG_TYPE_PROBE_CONN; pHead->spi = pConn->spi; pHead->encrypt = 0; - pHead->tranId = pConn->inTranId; + pHead->tranId = (uint16_t)(taosRand() & 0xFFFF); // rand pHead->sourceId = pConn->ownId; pHead->destId = pConn->peerId; pHead->linkUid = pConn->linkUid; @@ -1720,9 +1766,8 @@ bool doRpcSendProbe(SRpcConn *pConn) { memcpy(pHead->user, pConn->user, tListLen(pHead->user)); pHead->code = htonl(code); - pConn->outType = pHead->msgType; bool ret = rpcSendMsgToPeer(pConn, msg, sizeof(SRpcHead) + sizeof(int32_t)); - pConn->secured = 1; // connection shall be secured + pConn->lastLiveTime = taosGetTimestampMs(); return ret; } @@ -1731,44 +1776,45 @@ bool doRpcSendProbe(SRpcConn *pConn) { bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPrevFdObj, int32_t prevFd) { bool ret = false; if(rpcRid < 0) { - tError("ACK rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); + tError("PROBE rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); return false; } // get req content SRpcReqContext *pContext = taosAcquireRef(tsRpcRefId, rpcRid); if (pContext == NULL) { - tError("ACK rpcRid=%" PRId64 " get context NULL.", rpcRid); + tError("PROBE rpcRid=%" PRId64 " get context NULL.", rpcRid); return false; } // context same if(pContext != pPrevContext) { - tError("ACK rpcRid=%" PRId64 " context diff. pContext=%p pPreContent=%p", rpcRid, pContext, pPrevContext); + tError("PROBE rpcRid=%" PRId64 " context diff. pContext=%p pPreContent=%p", rpcRid, pContext, pPrevContext); goto _END; } // conn same if (pContext->pConn != pPrevConn) { - tError("ACK rpcRid=%" PRId64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pPrevConn); + tError("PROBE rpcRid=%" PRId64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pPrevConn); goto _END; } // fdObj same if (pContext->pConn->chandle != pPrevFdObj) { - tError("ACK rpcRid=%" PRId64 " connect fdObj diff. pContext->pConn->chandle=%p pPrevFdObj=%p", rpcRid, pContext->pConn->chandle, pPrevFdObj); + tError("PROBE rpcRid=%" PRId64 " connect fdObj diff. pContext->pConn->chandle=%p pPrevFdObj=%p", rpcRid, pContext->pConn->chandle, pPrevFdObj); goto _END; } // fd same int32_t fd = taosGetFdID(pContext->pConn->chandle); if (fd != prevFd) { - tError("ACK rpcRid=%" PRId64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, prevFd); + tError("PROBE rpcRid=%" PRId64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, prevFd); goto _END; } // send syn ret = doRpcSendProbe(pContext->pConn); + tInfo("PROBE 0x%" PRIx64 " rpcRid=%" PRId64 " send data ret=%d fd=%d.", (int64_t)pContext->ahandle, rpcRid, ret, fd); _END: // put back req context @@ -1797,9 +1843,9 @@ bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppF *ppContext = pContext; if (ppConn) *ppConn = pContext->pConn; - if (ppFdObj) + if (ppFdObj && pContext->pConn) *ppFdObj = pContext->pConn->chandle; - if (pFd) + if (pFd && pContext->pConn) *pFd = taosGetFdID(pContext->pConn->chandle); taosReleaseRef(tsRpcRefId, rpcRid); diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 0cc345d60a..b617b7e701 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -68,6 +68,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_TIME_STAMP, "Client and server's t TAOS_DEFINE_ERROR(TSDB_CODE_APP_NOT_READY, "Database not ready") TAOS_DEFINE_ERROR(TSDB_CODE_RPC_FQDN_ERROR, "Unable to resolve FQDN") TAOS_DEFINE_ERROR(TSDB_CODE_RPC_INVALID_VERSION, "Invalid app version") +TAOS_DEFINE_ERROR(TSDB_CODE_RPC_CONN_BROKEN, "Connection broken") + //common & util TAOS_DEFINE_ERROR(TSDB_CODE_COM_OPS_NOT_SUPPORT, "Operation not supported") -- GitLab From ac8e33cf11286cce518feca2a987c6df0c5dd2e9 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 28 Jul 2022 11:26:04 +0800 Subject: [PATCH 235/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 9cfa195713..3e8085401a 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 9cfa195713d1cae9edf417a8d49bde87dd971016 +Subproject commit 3e8085401a759466dbd1a70216b499bded5ee413 -- GitLab From e7bd96fa7154faecaedb405ac9493cda9559320b Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 28 Jul 2022 11:15:08 +0800 Subject: [PATCH 236/380] fix: check for out of memory during realloc in parseSmlValue --- src/client/src/tscParseLineProtocol.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index c979d1512d..81056f2f77 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -2353,7 +2353,12 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx, if (start < cur) { if (bufSize <= len + (cur - start)) { bufSize *= 2; - value = realloc(value, bufSize); + char *tmp = realloc(value, bufSize); + if (tmp == NULL) { + ret = TSDB_CODE_TSC_OUT_OF_MEMORY; + goto error; + } + value = tmp; } memcpy(value + len, start, cur - start); // [start, cur) len += cur - start; -- GitLab From 489a1f51d9e89b5a6b3a1d27e5d673fd264d605d Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 28 Jul 2022 12:59:24 +0800 Subject: [PATCH 237/380] fix(query): count like first last to ignore loadBlock --- src/query/src/qExecutor.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index d12cf8d03f..1ee6fcf994 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -2812,8 +2812,9 @@ static bool onlyLastQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQue static bool notContainSessionOrStateWindow(SQueryAttr *pQueryAttr) { return !(pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow); } static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { - bool hasFirstLastFunc = false; + bool hasFirstLastCountFunc = false; bool hasOtherFunc = false; + bool hasCount = false; if (status == BLK_DATA_ALL_NEEDED || status == BLK_DATA_DISCARD) { return status; @@ -2827,14 +2828,14 @@ static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { continue; } - if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_LAST_DST) { - hasFirstLastFunc = true; + if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_LAST_DST || functionId == TSDB_FUNC_COUNT) { + hasFirstLastCountFunc = true; } else { hasOtherFunc = true; } } - if (hasFirstLastFunc && status == BLK_DATA_NO_NEEDED) { + if (hasFirstLastCountFunc && status == BLK_DATA_NO_NEEDED) { if(!hasOtherFunc) { return BLK_DATA_DISCARD; } else { -- GitLab From 3b06158d4003f8b6be128bc96a8ebc09f4030eda Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 28 Jul 2022 13:00:40 +0800 Subject: [PATCH 238/380] fix(query): count like first last to ignore loadBlock1 --- src/query/src/qExecutor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 1ee6fcf994..359cf21b55 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -2814,7 +2814,6 @@ static bool notContainSessionOrStateWindow(SQueryAttr *pQueryAttr) { return !(pQ static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { bool hasFirstLastCountFunc = false; bool hasOtherFunc = false; - bool hasCount = false; if (status == BLK_DATA_ALL_NEEDED || status == BLK_DATA_DISCARD) { return status; -- GitLab From 2d09e6d1690eb4f8a30a75847dcf498c854781b2 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 28 Jul 2022 13:16:56 +0800 Subject: [PATCH 239/380] fix(query): count first last status can be BLK_DATA_NO_NEED --- src/query/src/qExecutor.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 359cf21b55..28d3d60727 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -2812,8 +2812,9 @@ static bool onlyLastQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQue static bool notContainSessionOrStateWindow(SQueryAttr *pQueryAttr) { return !(pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow); } static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { - bool hasFirstLastCountFunc = false; + bool hasFirstLastFunc = false; bool hasOtherFunc = false; + bool hasCount = false; if (status == BLK_DATA_ALL_NEEDED || status == BLK_DATA_DISCARD) { return status; @@ -2827,16 +2828,18 @@ static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { continue; } - if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_LAST_DST || functionId == TSDB_FUNC_COUNT) { - hasFirstLastCountFunc = true; + if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_LAST_DST) { + hasFirstLastFunc = true; + } else if(functionId == TSDB_FUNC_COUNT) { + hasCount = true; } else { hasOtherFunc = true; } } - if (hasFirstLastCountFunc && status == BLK_DATA_NO_NEEDED) { + if (hasFirstLastFunc && status == BLK_DATA_NO_NEEDED) { if(!hasOtherFunc) { - return BLK_DATA_DISCARD; + return hasCount ? BLK_DATA_NO_NEEDED : BLK_DATA_DISCARD; } else { return BLK_DATA_ALL_NEEDED; } -- GitLab From 032e10a5c5ec1ed56d204d12e54166696fcff6f5 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 28 Jul 2022 14:38:14 +0800 Subject: [PATCH 240/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 3e8085401a..465e0c2957 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 3e8085401a759466dbd1a70216b499bded5ee413 +Subproject commit 465e0c29576854503407c5d7ee8f27d203d06734 -- GitLab From 726850c3e92a283a4c0e54926df7698a2f7c2267 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 28 Jul 2022 15:57:32 +0800 Subject: [PATCH 241/380] fix(query): remove self define msg --- src/rpc/inc/rpcHead.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rpc/inc/rpcHead.h b/src/rpc/inc/rpcHead.h index 6bbd72f099..5b401ac54b 100644 --- a/src/rpc/inc/rpcHead.h +++ b/src/rpc/inc/rpcHead.h @@ -16,9 +16,6 @@ #ifndef TDENGINE_RPCHEAD_H #define TDENGINE_RPCHEAD_H -#define TSDB_MSG_TYPE_PROBE_CONN 0xFE -#define TSDB_MSG_TYPE_PROBE_CONN_RSP 0xFF - #ifdef __cplusplus extern "C" { #endif -- GitLab From 3ba1b669f3cafe32b18c5f0dd98381f7ce41cb5d Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Thu, 28 Jul 2022 16:18:46 +0800 Subject: [PATCH 242/380] docs: fix broken link --- docs/zh/07-develop/03-insert-data/05-high-volume.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/07-develop/03-insert-data/05-high-volume.md b/docs/zh/07-develop/03-insert-data/05-high-volume.md index 6c60fd6e24..b8647b6ad7 100644 --- a/docs/zh/07-develop/03-insert-data/05-high-volume.md +++ b/docs/zh/07-develop/03-insert-data/05-high-volume.md @@ -44,7 +44,7 @@ import TabItem from "@theme/TabItem"; 如果总表数比较大(比如大于500万),适当增加 maxVgroupsPerDb 也能显著提高建表的速度。maxVgroupsPerDb 默认值为 0, 自动配置为 CPU 的核数。 如果表的数量巨大,也建议调节 maxTablesPerVnode 参数,以免超过单个 vnode 建表的上限。 -更多调优参数,请参考[性能优化](../../operation/optimize)和[配置参考](../../reference/config)部分。 +更多调优参数,请参考[性能优化](../../../operation/optimize)和[配置参考](../../../reference/config)部分。 ## 高效写入示例 {#sample-code} -- GitLab From 7e8fcbbab0adb6a0973307346bc5ad6980fb2971 Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Thu, 28 Jul 2022 16:21:22 +0800 Subject: [PATCH 243/380] docs: fix broken link --- docs/en/07-develop/03-insert-data/05-high-volume.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/07-develop/03-insert-data/05-high-volume.md b/docs/en/07-develop/03-insert-data/05-high-volume.md index fc4f071997..1a4813f74e 100644 --- a/docs/en/07-develop/03-insert-data/05-high-volume.md +++ b/docs/en/07-develop/03-insert-data/05-high-volume.md @@ -51,7 +51,7 @@ TDengine is a distributed and high performance time series database, there are a 1. Set proper number of `vgroups` according to available CPU cores. Normally, we recommend 2 \* number_of_cores as a starting point. If the verification result shows this is not enough to utilize CPU resources, you can use a higher value. 2. Set proper `minTablesPerVnode`, `tableIncStepPerVnode`, and `maxVgroupsPerDb` according to the number of tables so that tables are distributed even across vgroups. The purpose is to balance the workload among all vnodes so that system resources can be utilized better to get higher performance. -For more performance tuning tips, please refer to [Performance Optimization](../../operation/optimize) and [Configuration Parameters](../../reference/config). +For more performance tuning tips, please refer to [Performance Optimization](../../../operation/optimize) and [Configuration Parameters](../../../reference/config). ## Sample Programs -- GitLab From c106f194fafa0e2d9d164057721a9e7c6e1200ab Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 28 Jul 2022 17:01:01 +0800 Subject: [PATCH 244/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 465e0c2957..1665912c03 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 465e0c29576854503407c5d7ee8f27d203d06734 +Subproject commit 1665912c03805f137220fadf915768c75d279730 -- GitLab From 92eca3c734213edfa4695b04400ec5c70060055b Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 28 Jul 2022 17:31:29 +0800 Subject: [PATCH 245/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 1665912c03..0a85be38ec 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 1665912c03805f137220fadf915768c75d279730 +Subproject commit 0a85be38ecaa00cb067a751e57f812ac6a0815d5 -- GitLab From 7d2d19d6144500e9ae6dc1971f36545142e5be9f Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 28 Jul 2022 19:06:43 +0800 Subject: [PATCH 246/380] feat(rpc): proge msg is ok --- src/client/src/tscServer.c | 18 ++++++----- src/rpc/src/rpcMain.c | 64 ++++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 751c96f527..2187bacb4d 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -530,6 +530,16 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { assert(pSql->self == handle); + // check msgtype + if(rpcMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { + pSql->noAckCnt = 0; + pSql->lastAlive = taosGetTimestampMs(); + tscDebug("PROBE 0x%" PRIx64 " recv probe msg. sql=%s", pSql->self, pSql->sqlstr); + rpcFreeCont(rpcMsg->pCont); + return ; + } + + STscObj *pObj = pSql->pTscObj; SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; @@ -546,14 +556,6 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { return; } - // check msgtype - if(rpcMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { - pSql->noAckCnt = 0; - pSql->lastAlive = taosGetTimestampMs(); - tscDebug("PROBE 0x%" PRIx64 " recv probe msg. sql=%s", pSql->self, pSql->sqlstr); - return ; - } - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); if (pQueryInfo != NULL && pQueryInfo->type == TSDB_QUERY_TYPE_FREE_RESOURCE) { tscDebug("0x%"PRIx64" sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p", diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 1c4d12a2a0..937d60e926 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -124,7 +124,9 @@ typedef struct SRpcConn { int8_t connType; // connection type int64_t lockedBy; // lock for connection SRpcReqContext *pContext; // request context + int64_t rid; // probe msg use rid get pContext int64_t lastLiveTime; // last alive time with ms + } SRpcConn; int tsRpcMaxUdpSize = 15000; // bytes @@ -994,18 +996,6 @@ static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv, SRpcReqCont pConn->peerPort = pRecv->port; if (pHead->port) pConn->peerPort = htons(pHead->port); - /* - // probe msg - if(pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN) { - pConn->inType = pHead->msgType; - rpcSendQuickRsp(pConn, TSDB_CODE_SUCCESS); - rpcUnlockConn(pConn); - rpcFreeMsg(pRecv->msg); - pRecv->msg = NULL; - return pConn; - } - */ - terrno = rpcCheckAuthentication(pConn, (char *)pHead, pRecv->msgLen); // code can be transformed only after authentication @@ -1090,7 +1080,7 @@ static void rpcProcessBrokenLink(SRpcConn *pConn) { } // process probe msg , return true is probe msg, false is not probe msg -static bool rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { +static void rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { SRpcHead *pHead = (SRpcHead *)pRecv->msg; if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN) { // response to @@ -1104,24 +1094,35 @@ static bool rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { rspHead.code = 0; rspHead.spi = pHead->spi; rspHead.linkUid = pHead->linkUid; + + rpcLockConn(pConn); rspHead.sourceId = pConn->ownId; rspHead.destId = pConn->peerId; - memcpy(rspHead.user, pHead->user, tListLen(pHead->user)); bool ret = rpcSendMsgToPeer(pConn, &rspHead, sizeof(SRpcHead)); tDebug("PROBE 0x%" PRIx64 " recv probe msg and response. ret=%d", pHead->ahandle, ret); - return true; + rpcFreeCont(pRecv->msg); + rpcUnlockConn(pConn); } else if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { if(pConn) { + rpcLockConn(pConn); pConn->lastLiveTime = taosGetTimestampMs(); - rpcProcessIncomingMsg(pConn, pHead, pConn->pContext); + // get req content + SRpcReqContext *pContext = taosAcquireRef(tsRpcRefId, pConn->rid); + + if (pContext) { + rpcProcessIncomingMsg(pConn, pHead, pContext); + taosReleaseRef(tsRpcRefId, pConn->rid); + } else { + tError("PROBE recv probe msg get context is NULL. rid=%" PRId64 " NULL.", pConn->rid); + } + + rpcUnlockConn(pConn); } tDebug("PROBE 0x%" PRIx64 " recv response probe msg and update lastLiveTime. pConn=%p", pHead->ahandle, pConn); - return false; - } else { - return false; } + } static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) { @@ -1145,10 +1146,8 @@ static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) { // deal probe msg if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN || pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { - if (rpcProcessProbeMsg(pRecv, pConn)) { - rpcFreeMsg(pRecv->msg); - return pConn; - } + rpcProcessProbeMsg(pRecv, pConn); + return pConn; } if (pHead->msgType >= 1 && pHead->msgType < TSDB_MSG_TYPE_MAX) { @@ -1203,7 +1202,10 @@ static void rpcNotifyClient(SRpcReqContext *pContext, SRpcMsg *pMsg) { } // free the request message - taosRemoveRef(tsRpcRefId, pContext->rid); + if(pMsg->msgType != TSDB_MSG_TYPE_PROBE_CONN && pMsg->msgType != TSDB_MSG_TYPE_PROBE_CONN_RSP) { + taosRemoveRef(tsRpcRefId, pContext->rid); + } + } static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead, SRpcReqContext *pContext) { @@ -1241,6 +1243,14 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead, SRpcReqConte // it's a response rpcMsg.handle = pContext; rpcMsg.ahandle = pContext->ahandle; + + if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { + // probe msg + rpcNotifyClient(pContext, &rpcMsg); + return ; + } + + // reset pConn NULL pContext->pConn = NULL; // for UDP, port may be changed by server, the port in epSet shall be used for cache @@ -1397,6 +1407,8 @@ static bool rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { pConn->pReqMsg = msg; pConn->reqMsgLen = msgLen; pConn->pContext = pContext; + if(pContext) + pConn->rid = pContext->rid; bool ret = rpcSendMsgToPeer(pConn, msg, msgLen); if (pConn->connType != RPC_CONN_TCPC) @@ -1825,13 +1837,13 @@ _END: // after sql request send , save conn info bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd) { if(rpcRid < 0) { - tError("ACK saveSendInfo rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); + tError("PROBE saveSendInfo rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); return false; } // get req content SRpcReqContext *pContext = taosAcquireRef(tsRpcRefId, rpcRid); if (pContext == NULL) { - tError("ACK rpcRid=%" PRId64 " get context NULL.", rpcRid); + tError("PROBE rpcRid=%" PRId64 " get context NULL.", rpcRid); return false; } -- GitLab From 18c6bb757649c76a03b5a12f665281131c8c428b Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 28 Jul 2022 22:10:07 +0800 Subject: [PATCH 247/380] fix: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 0a85be38ec..bae7780e01 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 0a85be38ecaa00cb067a751e57f812ac6a0815d5 +Subproject commit bae7780e01c02dd564e3eb173d86b5a8205aa0c7 -- GitLab From ccfa8bff9e6d3e5a5a2106de22a1787b9dd8ca39 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Fri, 29 Jul 2022 11:05:50 +0800 Subject: [PATCH 248/380] Rename 13-DBeaver.mdx to 14-DBeaver.mdx --- docs/zh/20-third-party/{13-DBeaver.mdx => 14-DBeaver.mdx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/zh/20-third-party/{13-DBeaver.mdx => 14-DBeaver.mdx} (100%) diff --git a/docs/zh/20-third-party/13-DBeaver.mdx b/docs/zh/20-third-party/14-DBeaver.mdx similarity index 100% rename from docs/zh/20-third-party/13-DBeaver.mdx rename to docs/zh/20-third-party/14-DBeaver.mdx -- GitLab From 19bf81a459eda6cac468699be200d439d1a2d8d7 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 29 Jul 2022 15:00:17 +0800 Subject: [PATCH 249/380] fix(query): proble msg add to pSQL --- src/client/src/tscServer.c | 4 ++-- src/query/src/qExecutor.c | 4 ++++ src/rpc/src/rpcMain.c | 8 +++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 2187bacb4d..405676a9a6 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -312,7 +312,7 @@ bool dealConnBroken(SSqlObj * pSql) { bool sendProbeConnMsg(SSqlObj* pSql) { // TEST TODO DELETE tsProbeSeconds = 1; // over this value send probe msg - tsProbeKillSeconds = 3*60; // over this value query can be killed + tsProbeKillSeconds = 2*60; // over this value query can be killed if(pSql->stime == 0) { // not start , no need probe @@ -329,7 +329,7 @@ bool sendProbeConnMsg(SSqlObj* pSql) { if (diff > tsProbeKillSeconds * 1000) { // need kill query tscDebug("PROBE 0x%"PRIx64" need killed, noAckCnt:%d diff=%d", pSql->self, pSql->noAckCnt, diff); - //return false; + return false; } if (pSql->pPrevContext == NULL || pSql->pPrevConn == NULL || pSql->pPrevFdObj == NULL || pSql->prevFd <= 0) { diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index d12cf8d03f..9c29c7c8af 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -6367,6 +6367,10 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { SSDataBlock* pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); + // TEST TODU DELETE + taosMsleep(10*1000); + + if (pBlock == NULL) { //assert(*newgroup == false); diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 937d60e926..e86fd3437c 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1102,7 +1102,7 @@ static void rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { bool ret = rpcSendMsgToPeer(pConn, &rspHead, sizeof(SRpcHead)); tDebug("PROBE 0x%" PRIx64 " recv probe msg and response. ret=%d", pHead->ahandle, ret); - rpcFreeCont(pRecv->msg); + rpcFreeMsg(pRecv->msg); rpcUnlockConn(pConn); } else if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { if(pConn) { @@ -1786,6 +1786,7 @@ bool doRpcSendProbe(SRpcConn *pConn) { // send server syn bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPrevFdObj, int32_t prevFd) { + // return false can kill query bool ret = false; if(rpcRid < 0) { tError("PROBE rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); @@ -1795,8 +1796,8 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPr // get req content SRpcReqContext *pContext = taosAcquireRef(tsRpcRefId, rpcRid); if (pContext == NULL) { - tError("PROBE rpcRid=%" PRId64 " get context NULL.", rpcRid); - return false; + tError("PROBE rpcRid=%" PRId64 " get context NULL. sql finished no need send probe.", rpcRid); + return true; } // context same @@ -1808,6 +1809,7 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPr // conn same if (pContext->pConn != pPrevConn) { tError("PROBE rpcRid=%" PRId64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pPrevConn); + ret = pContext->pConn == NULL; goto _END; } -- GitLab From ef8e408413742f4fca64703f2cc94e58c125cedb Mon Sep 17 00:00:00 2001 From: WANG MINGMING Date: Fri, 29 Jul 2022 16:39:38 +0800 Subject: [PATCH 250/380] Update 13-schemaless.md --- .../13-schemaless/13-schemaless.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/zh/14-reference/13-schemaless/13-schemaless.md b/docs/zh/14-reference/13-schemaless/13-schemaless.md index f2712f2814..639be22d3c 100644 --- a/docs/zh/14-reference/13-schemaless/13-schemaless.md +++ b/docs/zh/14-reference/13-schemaless/13-schemaless.md @@ -41,10 +41,10 @@ tag_set 中的所有的数据自动转化为 nchar 数据类型,并不需要 | -------- | -------- | ------------ | -------------- | | 1 | 无或 f64 | double | 8 | | 2 | f32 | float | 4 | -| 3 | i8 | TinyInt | 1 | -| 4 | i16 | SmallInt | 2 | -| 5 | i32 | Int | 4 | -| 6 | i64 或 i | Bigint | 8 | +| 3 | i8/u8 | TinyInt/UTinyInt | 1 | +| 4 | i16/u16 | SmallInt/USmallInt | 2 | +| 5 | i32/u32 | Int/UInt | 4 | +| 6 | i64/i/u64/u | BigInt/BigInt/UBigInt/UBigInt | 8 | - t, T, true, True, TRUE, f, F, false, False 将直接作为 BOOL 型来处理。 @@ -69,16 +69,17 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4f64 1626006833639000000 ``` 需要注意的是,这里的 tag_key1, tag_key2 并不是用户输入的标签的原始顺序,而是使用了标签名称按照字符串升序排列后的结果。所以,tag_key1 并不是在行协议中输入的第一个标签。 -排列完成以后计算该字符串的 MD5 散列值 "md5_val"。然后将计算的结果与字符串组合生成表名:“t_md5_val”。其中的 “t\*” 是固定的前缀,每个通过该映射关系自动生成的表都具有该前缀。 +排列完成以后计算该字符串的 MD5 散列值 "md5_val"。然后将计算的结果与字符串组合生成表名:“t_md5_val”。其中的 “t_” 是固定的前缀,每个通过该映射关系自动生成的表都具有该前缀。 -2. 如果解析行协议获得的超级表不存在,则会创建这个超级表。 +2. 如果解析行协议获得的超级表不存在,则会创建这个超级表(不建议手动创建超级表,不然插入数据可能异常)。 3. 如果解析行协议获得子表不存在,则 Schemaless 会按照步骤 1 或 2 确定的子表名来创建子表。 4. 如果数据行中指定的标签列或普通列不存在,则在超级表中增加对应的标签列或普通列(只增不减)。 5. 如果超级表中存在一些标签列或普通列未在一个数据行中被指定取值,那么这些列的值在这一行中会被置为 NULL。 6. 对 BINARY 或 NCHAR 列,如果数据行中所提供值的长度超出了列类型的限制,自动增加该列允许存储的字符长度上限(只增不减),以保证数据的完整保存。 -7. 如果指定的数据子表已经存在,而且本次指定的标签列取值跟已保存的值不一样,那么最新的数据行中的值会覆盖旧的标签列取值。 -8. 整个处理过程中遇到的错误会中断写入过程,并返回错误代码。 +7. 整个处理过程中遇到的错误会中断写入过程,并返回错误代码。 +8. 为了提高写入的效率,默认假设同一个超级表中field_set的顺序是一样的(第一条数据包含所有的field,后面的数据按照这个顺序),如果顺序不一样,需要配置参数smlDataFormat为false,否则, + 数据写入按照相同顺序写入,库中数据会异常。。 :::tip 无模式所有的处理逻辑,仍会遵循 TDengine 对数据结构的底层限制,例如每行数据的总长度不能超过 @@ -94,7 +95,7 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4f64 1626006833639000000 | -------- | ------------------- | ------------------------------- | | 1 | SML_LINE_PROTOCOL | InfluxDB 行协议(Line Protocol) | | 2 | SML_TELNET_PROTOCOL | OpenTSDB 文本行协议 | -| 3 | SML_JSON_PROTOCOL | JSON 协议格式 | +| 3 | SML_JSON_PROTOCOL | OpenTSDB JSON 协议格式 | 在 SML_LINE_PROTOCOL 解析模式下,需要用户指定输入的时间戳的时间分辨率。可用的时间分辨率如下表所示: -- GitLab From 181240b0d903f734606e87f889df7ddd051315d6 Mon Sep 17 00:00:00 2001 From: WANG MINGMING Date: Fri, 29 Jul 2022 16:48:53 +0800 Subject: [PATCH 251/380] Update 13-schemaless.md --- .../13-schemaless/13-schemaless.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/en/14-reference/13-schemaless/13-schemaless.md b/docs/en/14-reference/13-schemaless/13-schemaless.md index acbbb1cd3c..dea14aa90a 100644 --- a/docs/en/14-reference/13-schemaless/13-schemaless.md +++ b/docs/en/14-reference/13-schemaless/13-schemaless.md @@ -37,12 +37,12 @@ In the schemaless writing data line protocol, each data item in the field_set ne | **Serial number** | **Postfix** | **Mapping type** | **Size (bytes)** | | -------- | -------- | ------------ | -------------- | -| 1 | none or f64 | double | 8 | -| 2 | f32 | float | 4 | -| 3 | i8 | TinyInt | 1 | -| 4 | i16 | SmallInt | 2 | -| 5 | i32 | Int | 4 | -| 6 | i64 or i | Bigint | 8 | +| 1 | none or f64 | double | 8 | +| 2 | f32 | float | 4 | +| 3 | i8/u8 | TinyInt/UTinyInt | 1 | +| 4 | i16/u16 | SmallInt/USmallInt | 2 | +| 5 | i32/u32 | Int/UInt | 4 | +| 6 | i64/i/u64/u | BigInt/BigInt/UBigInt/UBigInt | 8 | - `t`, `T`, `true`, `True`, `TRUE`, `f`, `F`, `false`, and `False` will be handled directly as BOOL types. @@ -67,13 +67,13 @@ Schemaless writes process row data according to the following principles. Note that tag_key1, tag_key2 are not the original order of the tags entered by the user but the result of using the tag names in ascending order of the strings. Therefore, tag_key1 is not the first tag entered in the line protocol. The string's MD5 hash value "md5_val" is calculated after the ranking is completed. The calculation result is then combined with the string to generate the table name: "t_md5_val". "t*" is a fixed prefix that every table generated by this mapping relationship has. -2. If the super table obtained by parsing the line protocol does not exist, this super table is created. +2. If the super table obtained by parsing the line protocol does not exist, this super table is created(It is not recommended to create a super table manually, otherwise the inserted data may be abnormal). If the subtable obtained by the parse line protocol does not exist, Schemaless creates the sub-table according to the subtable name determined in steps 1 or 2. 4. If the specified tag or regular column in the data row does not exist, the corresponding tag or regular column is added to the super table (only incremental). 5. If there are some tag columns or regular columns in the super table that are not specified to take values in a data row, then the values of these columns are set to NULL. 6. For BINARY or NCHAR columns, if the length of the value provided in a data row exceeds the column type limit, the maximum length of characters allowed to be stored in the column is automatically increased (only incremented and not decremented) to ensure complete preservation of the data. -7. If the specified data subtable already exists, and the specified tag column takes a value different from the saved value this time, the value in the latest data row overwrites the old tag column take value. -8. Errors encountered throughout the processing will interrupt the writing process and return an error code. +7. Errors encountered throughout the processing will interrupt the writing process and return an error code. +8. In order to improve the efficiency of writing, the order of fields in the same super table should be the same. If the order is different, you need to configure the parameter smlDataFormat to false, otherwise, the data in the library will be abnormal. :::tip All processing logic of schemaless will still follow TDengine's underlying restrictions on data structures, such as the total length of each row of data cannot exceed 48k bytes. See [TAOS SQL Boundary Limits](/taos-sql/limit) for specific constraints in this area. -- GitLab From e4f77e83b4bba941ec59806b011deb1c1dce8a87 Mon Sep 17 00:00:00 2001 From: WANG MINGMING Date: Fri, 29 Jul 2022 16:49:53 +0800 Subject: [PATCH 252/380] Update 13-schemaless.md --- docs/zh/14-reference/13-schemaless/13-schemaless.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/14-reference/13-schemaless/13-schemaless.md b/docs/zh/14-reference/13-schemaless/13-schemaless.md index 639be22d3c..ac356d5443 100644 --- a/docs/zh/14-reference/13-schemaless/13-schemaless.md +++ b/docs/zh/14-reference/13-schemaless/13-schemaless.md @@ -79,7 +79,7 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4f64 1626006833639000000 6. 对 BINARY 或 NCHAR 列,如果数据行中所提供值的长度超出了列类型的限制,自动增加该列允许存储的字符长度上限(只增不减),以保证数据的完整保存。 7. 整个处理过程中遇到的错误会中断写入过程,并返回错误代码。 8. 为了提高写入的效率,默认假设同一个超级表中field_set的顺序是一样的(第一条数据包含所有的field,后面的数据按照这个顺序),如果顺序不一样,需要配置参数smlDataFormat为false,否则, - 数据写入按照相同顺序写入,库中数据会异常。。 + 数据写入按照相同顺序写入,库中数据会异常。 :::tip 无模式所有的处理逻辑,仍会遵循 TDengine 对数据结构的底层限制,例如每行数据的总长度不能超过 -- GitLab From 3dd1679b7f03832a19b7a6af7f864b03c5cbfb82 Mon Sep 17 00:00:00 2001 From: WANG MINGMING Date: Fri, 29 Jul 2022 16:57:31 +0800 Subject: [PATCH 253/380] Update 18-escape.md --- docs/zh/12-taos-sql/18-escape.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/12-taos-sql/18-escape.md b/docs/zh/12-taos-sql/18-escape.md index 756e5c8159..1200669c40 100644 --- a/docs/zh/12-taos-sql/18-escape.md +++ b/docs/zh/12-taos-sql/18-escape.md @@ -27,4 +27,4 @@ title: 转义字符说明 2. 反引号``标识符: 保持原样,不转义 2. 数据里有转义字符 1. 遇到上面定义的转义字符会转义(%和\_见下面说明),如果没有匹配的转义字符会忽略掉转义符\。 - 2. 对于%和\_,因为在 like 里这两个字符是通配符,所以在模式匹配 like 里用`\%`%和`\_`表示字符里本身的%和\_,如果在 like 模式匹配上下文之外使用`\%`或`\_`,则它们的计算结果为字符串`\%`和`\_`,而不是%和\_。 + 2. 对于%和\_,因为在 like 里这两个字符是通配符,所以在模式匹配 like 里用`\%`和`\_`表示字符里本身的%和\_,如果在 like 模式匹配上下文之外使用`\%`或`\_`,则它们的计算结果为字符串`\%`和`\_`,而不是%和\_。 -- GitLab From 8356bcf82b93df859a60298a91e4d8df2bce2045 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 29 Jul 2022 17:04:10 +0800 Subject: [PATCH 254/380] fix: arm build for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index bae7780e01..d9a44b2405 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit bae7780e01c02dd564e3eb173d86b5a8205aa0c7 +Subproject commit d9a44b2405bc4180841f20834488f811911cb518 -- GitLab From 28ac77cbae8db8b3e55a8384a52d6c7376231308 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 29 Jul 2022 17:05:07 +0800 Subject: [PATCH 255/380] fix: disable make install on arm64 --- Jenkinsfile2 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index 257a13e4bf..df2ce5a2cd 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -134,6 +134,19 @@ def sync_source() { git submodule update --init --recursive ''' } +def pre_test_arm64() { + sync_source() + sh ''' + cd ${WK} + mkdir -p debug + cd debug + go env -w GOPROXY=https://goproxy.cn,direct + go env -w GO111MODULE=on + cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true > /dev/null + make -j8 >/dev/null + ''' + return 1 +} def pre_test() { sync_source() sh ''' @@ -330,7 +343,7 @@ pipeline { agent {label " worker07_arm64 || worker09_arm64 "} steps { timeout(time: 20, unit: 'MINUTES') { - pre_test() + pre_test_arm64() script { sh ''' echo "arm64 build done" -- GitLab From 9f20bf059a76f3c664834f42d1b0d410588e1c08 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 29 Jul 2022 17:43:05 +0800 Subject: [PATCH 256/380] feat(rpc): probe add complete log --- src/client/inc/tsclient.h | 1 - src/client/src/tscServer.c | 45 +++++++++++++++++++++++--------------- src/query/src/qExecutor.c | 4 +++- src/rpc/src/rpcMain.c | 26 ++++++++++++---------- 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index a8d5cff1d6..3e9ad0699a 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -401,7 +401,6 @@ typedef struct SSqlObj { // connect alive int64_t lastProbe; int64_t lastAlive; - char noAckCnt; // no recevie ack from sever count void * pPrevContext; void * pPrevConn; void * pPrevFdObj; diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 405676a9a6..84fe8e31d8 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -284,10 +284,9 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { // pSql connection link is broken bool dealConnBroken(SSqlObj * pSql) { // check valid - if (pSql == NULL || pSql->signature != pSql) { - return false; - } - if (pSql->cmd.command >= TSDB_SQL_LOCAL) { + + if (pSql->signature != pSql) { + tscInfo("PROBE 0x%" PRIx64 " break link signature is not equal pSql. signature=%p", pSql->self, pSql->signature); return false; } @@ -296,13 +295,15 @@ bool dealConnBroken(SSqlObj * pSql) { // cancel if (pSql->rpcRid > 0) { - tscDebug("PROBE 0x%" PRIx64 " rpc cancel request rpcRid=0x%" PRIx64 ".", pSql->self, pSql->rpcRid); + tscInfo("PROBE 0x%" PRIx64 " break link done. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); rpcCancelRequest(pSql->rpcRid); pSql->rpcRid = -1; + } else { + tscInfo("PROBE 0x%" PRIx64 " break link rpcRid <=0. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); } - // error - tscDebug("PROBE 0x%"PRIx64" async result error.", pSql->self); + // error notify + tscInfo("PROBE 0x%"PRIx64" async result error. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); tscAsyncResultOnError(pSql); return true; @@ -316,6 +317,7 @@ bool sendProbeConnMsg(SSqlObj* pSql) { if(pSql->stime == 0) { // not start , no need probe + tscInfo("PROBE 0x%" PRIx64 " not start, no need probe.", pSql->self); return true; } @@ -323,39 +325,47 @@ bool sendProbeConnMsg(SSqlObj* pSql) { int32_t diff = (int32_t)(taosGetTimestampMs() - stime); if (diff < tsProbeSeconds * 1000) { // exec time short , need not probe alive + tscInfo("PROBE 0x%" PRIx64 "not arrived probe time. timeout=%ds, no need probe. lastAlive=%" PRId64 " stime=%" PRId64, \ + pSql->self, tsProbeSeconds, pSql->lastAlive, pSql->stime); return true; } if (diff > tsProbeKillSeconds * 1000) { // need kill query - tscDebug("PROBE 0x%"PRIx64" need killed, noAckCnt:%d diff=%d", pSql->self, pSql->noAckCnt, diff); + tscInfo("PROBE 0x%" PRIx64 "kill query by probe. because arrived kill time. timeout=%ds lastAlive=%" PRId64 " stime=%" PRId64, \ + pSql->self, tsProbeKillSeconds, pSql->lastAlive, pSql->stime); + return false; } if (pSql->pPrevContext == NULL || pSql->pPrevConn == NULL || pSql->pPrevFdObj == NULL || pSql->prevFd <= 0) { // last connect info save uncompletely, so can't probe + tscInfo("PROBE 0x%" PRIx64 "save last connect info uncompletely. prev context=%p conn=%p fdobj=%p fd=%d", \ + pSql->self, pSql->pPrevContext, pSql->pPrevConn, pSql->pPrevFdObj, pSql->prevFd); return true; } if(pSql->rpcRid == -1) { // cancel or reponse ok from server, so need not probe + tscInfo("PROBE 0x%" PRIx64 " rpcRid is -1, response ok. no need probe.", pSql->self); return true; } // It's long time from lastAlive, so need probe - pSql->noAckCnt++; pSql->lastProbe = taosGetTimestampMs(); - tscDebug("0x%"PRIx64" sendProbeConnMsg noAckCnt:%d diff=%d", pSql->self, pSql->noAckCnt, diff); - - return rpcSendProbe(pSql->rpcRid, pSql->pPrevContext, pSql->pPrevConn, pSql->pPrevFdObj, pSql->prevFd); + + bool ret = rpcSendProbe(pSql->rpcRid, pSql->pPrevContext, pSql->pPrevConn, pSql->pPrevFdObj, pSql->prevFd); + tscInfo("PROBE 0x%" PRIx64 " rpcRid=0x%" PRIx64 " send probe msg, ret=%d", pSql->self, pSql->rpcRid, ret); + return ret; } // check have broken link queries than killed void checkBrokenQueries(STscObj *pTscObj) { - // + tscDebug("PROBE checkBrokenQueries pTscObj=%p pTscObj->rid=0x%" PRIx64, pTscObj, pTscObj->rid); SSqlObj *pSql = pTscObj->sqlList; while (pSql) { int32_t numOfSub = pSql->subState.numOfSub; + tscInfo("PROBE 0x%" PRIx64 " numOfSub=%d sql=%s", pSql->self, numOfSub, pSql->sqlstr == NULL ? "" : pSql->sqlstr); if (numOfSub == 0) { // no sub sql if(!sendProbeConnMsg(pSql)) { @@ -396,9 +406,9 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { assert(pHB->self == pObj->hbrid); // check queries already death - static int activetyTimerCnt = 0; - if (++activetyTimerCnt > 3) { // 1.5s * 10 = 15s interval call - activetyTimerCnt = 0; + static int activetyCnt = 0; + if (++activetyCnt > 3) { // 1.5s * 10 = 15s interval call + activetyCnt = 0; // call check if have query doing if(pObj->sqlList) { @@ -532,9 +542,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { // check msgtype if(rpcMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { - pSql->noAckCnt = 0; pSql->lastAlive = taosGetTimestampMs(); - tscDebug("PROBE 0x%" PRIx64 " recv probe msg. sql=%s", pSql->self, pSql->sqlstr); + tscDebug("PROBE 0x%" PRIx64 " recv probe response msg. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); rpcFreeCont(rpcMsg->pCont); return ; } diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 9c29c7c8af..cc9464ad72 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -6368,7 +6368,9 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); // TEST TODU DELETE - taosMsleep(10*1000); + static int loop = 0; + taosMsleep(3*1000); + qInfo(" loop=%d pEnv=%p", loop++, pRuntimeEnv); if (pBlock == NULL) { diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index e86fd3437c..11a8b4b70b 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1101,7 +1101,7 @@ static void rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { memcpy(rspHead.user, pHead->user, tListLen(pHead->user)); bool ret = rpcSendMsgToPeer(pConn, &rspHead, sizeof(SRpcHead)); - tDebug("PROBE 0x%" PRIx64 " recv probe msg and response. ret=%d", pHead->ahandle, ret); + tInfo("PROBE 0x%" PRIx64 " recv probe msg and do response. ret=%d", pHead->ahandle, ret); rpcFreeMsg(pRecv->msg); rpcUnlockConn(pConn); } else if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { @@ -1115,12 +1115,14 @@ static void rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { rpcProcessIncomingMsg(pConn, pHead, pContext); taosReleaseRef(tsRpcRefId, pConn->rid); } else { - tError("PROBE recv probe msg get context is NULL. rid=%" PRId64 " NULL.", pConn->rid); + tInfo("PROBE 0x%" PRIx64 " get reqContext by rid return NULL. pConn->rid=0x%" PRIX64, pHead->ahandle, pConn->rid); } rpcUnlockConn(pConn); + tInfo("PROBE 0x%" PRIx64 " recv response probe msg and update lastLiveTime. pConn=%p", pHead->ahandle, pConn); + } else { + tInfo("PROBE 0x%" PRIx64 " recv response probe msg but pConn is NULL.", pHead->ahandle); } - tDebug("PROBE 0x%" PRIx64 " recv response probe msg and update lastLiveTime. pConn=%p", pHead->ahandle, pConn); } } @@ -1789,46 +1791,46 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPr // return false can kill query bool ret = false; if(rpcRid < 0) { - tError("PROBE rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); + tError("PROBE rpcRid=0x%" PRIx64 " less than zero, invalid.", rpcRid); return false; } // get req content SRpcReqContext *pContext = taosAcquireRef(tsRpcRefId, rpcRid); if (pContext == NULL) { - tError("PROBE rpcRid=%" PRId64 " get context NULL. sql finished no need send probe.", rpcRid); + tError("PROBE rpcRid=0x%" PRIx64 " get context NULL. sql finished no need send probe.", rpcRid); return true; } // context same if(pContext != pPrevContext) { - tError("PROBE rpcRid=%" PRId64 " context diff. pContext=%p pPreContent=%p", rpcRid, pContext, pPrevContext); + tError("PROBE rpcRid=0x%" PRIx64 " context diff. pContext=%p pPreContent=%p", rpcRid, pContext, pPrevContext); goto _END; } // conn same if (pContext->pConn != pPrevConn) { - tError("PROBE rpcRid=%" PRId64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pPrevConn); + tError("PROBE rpcRid=0x%" PRIx64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pPrevConn); ret = pContext->pConn == NULL; goto _END; } // fdObj same if (pContext->pConn->chandle != pPrevFdObj) { - tError("PROBE rpcRid=%" PRId64 " connect fdObj diff. pContext->pConn->chandle=%p pPrevFdObj=%p", rpcRid, pContext->pConn->chandle, pPrevFdObj); + tError("PROBE rpcRid=0x%" PRIx64 " connect fdObj diff. pContext->pConn->chandle=%p pPrevFdObj=%p", rpcRid, pContext->pConn->chandle, pPrevFdObj); goto _END; } // fd same int32_t fd = taosGetFdID(pContext->pConn->chandle); if (fd != prevFd) { - tError("PROBE rpcRid=%" PRId64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, prevFd); + tError("PROBE rpcRid=0x%" PRIx64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, prevFd); goto _END; } // send syn ret = doRpcSendProbe(pContext->pConn); - tInfo("PROBE 0x%" PRIx64 " rpcRid=%" PRId64 " send data ret=%d fd=%d.", (int64_t)pContext->ahandle, rpcRid, ret, fd); + tInfo("PROBE 0x%" PRIx64 " rrpcRid=0x%" PRIx64 " send data ret=%d fd=%d.", (int64_t)pContext->ahandle, rpcRid, ret, fd); _END: // put back req context @@ -1839,13 +1841,13 @@ _END: // after sql request send , save conn info bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd) { if(rpcRid < 0) { - tError("PROBE saveSendInfo rpcRid=%" PRId64 " less than zero, invalid.", rpcRid); + tError("PROBE saveSendInfo rpcRid=0x%" PRIx64 " less than zero, invalid.", rpcRid); return false; } // get req content SRpcReqContext *pContext = taosAcquireRef(tsRpcRefId, rpcRid); if (pContext == NULL) { - tError("PROBE rpcRid=%" PRId64 " get context NULL.", rpcRid); + tError("PROBE saveSendInfo rpcRid=0x%" PRIx64 " get context NULL.", rpcRid); return false; } -- GitLab From 2781156bd7f8d2896f26edaeffd6d710864770b4 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 29 Jul 2022 17:39:18 +0800 Subject: [PATCH 257/380] fix: disable taodump test case in parallel_test/cases.task temporarily --- tests/parallel_test/cases.task | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index c2c462324e..f51a4c2442 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -204,7 +204,7 @@ 36,,script,./test.sh -f unique/arbitrator/offline_replica3_createTable_online.sim 36,,script,./test.sh -f unique/arbitrator/offline_replica2_dropTable_online.sim 36,,script,./test.sh -f general/parser/tbnameIn.sim -36,,pytest,python3 test.py -f tools/taosdumpTestNanoSupport.py +#36,,pytest,python3 test.py -f tools/taosdumpTestNanoSupport.py 35,,script,./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim 35,,script,./test.sh -f unique/arbitrator/offline_replica3_alterTag_online.sim 35,,script,./test.sh -f unique/arbitrator/offline_replica2_alterTag_online.sim @@ -219,7 +219,7 @@ 33,,script,./test.sh -f general/table/delete_writing.sim 33,,script,./test.sh -f general/parser/slimit.sim 33,,script,./test.sh -f general/db/topic1.sim -32,,system-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestColTag.py +#32,,system-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestColTag.py 32,,script,./test.sh -f unique/mnode/mgmt21.sim 32,,script,./test.sh -f unique/arbitrator/offline_replica3_dropDb_online.sim 32,,script,./test.sh -f unique/arbitrator/dn3_mn2_killDnode.sim @@ -323,7 +323,7 @@ 19,,script,./test.sh -f unique/stable/dnode2.sim 19,,script,./test.sh -f general/db/vnodes.sim 19,,pytest,python3 test.py -f multilevel/addAnotherDir.py -19,,pytest,python3 test.py -f tools/taosdumpTest3.py +#19,,pytest,python3 test.py -f tools/taosdumpTest3.py 19,,pytest,python3 test.py -f query/udf.py 19,,pytest,python3 test.py -f import_merge/importLastTPO.py 19,,pytest,python3 test.py -f import_merge/importDataLastHO.py @@ -579,34 +579,34 @@ 9,,pytest,python3 test.py -f stream/showStreamExecTimeisNull.py 9,,pytest,python3 test.py -f query/bug1876.py 9,,pytest,python3 test.py -f alter/alter_table_crash.py -9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeSmallInt.py -9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeFloat.py -8,,pytest,python3 test.py -f tools/taosdumpTest.py +#9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeSmallInt.py +#9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeFloat.py +#8,,pytest,python3 test.py -f tools/taosdumpTest.py 8,,pytest,python3 test.py -f query/unionAllTest.py 8,,pytest,python3 test.py -f query/queryFilterTswithDateUnit.py 8,,pytest,python3 test.py -f query/queryDiffColsTagsAndOr.py 8,,pytest,python3 test.py -f query/nestedQuery/nestedQuery_datacheck.py 8,,pytest,python3 test.py -f query/bug1874.py 8,,pytest,python3 test.py -f functions/function_floor.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedTinyInt.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedBigInt.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeTinyInt.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedTinyInt.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedBigInt.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeTinyInt.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py 8,,pytest,python3 test.py -f update/update2.py 7,,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonSml-otherPara.py -7,,pytest,python3 test.py -f tools/taosdumpTest2.py +#7,,pytest,python3 test.py -f tools/taosdumpTest2.py 7,,pytest,python3 test.py -f tools/taosdemoTestdatatype.py 7,,pytest,python3 test.py -f tag_lite/unsignedInt.py 7,,pytest,python3 test.py -f query/bug1875.py 7,,pytest,python3 test.py -f functions/function_stateWindow.py 7,,pytest,python3 test.py -f client/version.py 7,,pytest,python3 client/twoClients.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedSmallInt.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedInt.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeJson.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBool.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBigInt.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedSmallInt.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedInt.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeJson.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBool.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBigInt.py 7,,develop-test,python3 ./test.py -f 2-query/function_timetruncate.py 7,,develop-test,python3 ./test.py -f 2-query/function_timediff.py 7,,pytest,python3 test.py -f tsdb/delete.py @@ -660,7 +660,7 @@ 5,,pytest,python3 testMinTablesPerVnode.py 5,,pytest,python3 test.py -f tag_lite/unsignedTinyint.py 5,,pytest,python3 test.py -f tag_lite/timestamp.py -5,,pytest,python3 test.py -f tag_lite/TestModifyTag.py +#5,,pytest,python3 test.py -f tag_lite/TestModifyTag.py 5,,pytest,python3 test.py -f tag_lite/json_tag_extra.py 5,,pytest,python3 test.py -f tag_lite/int_binary.py 5,,pytest,python3 test.py -f tag_lite/float.py @@ -831,4 +831,4 @@ 1,,docs-examples-test, ./test_R.sh 1,,develop-test,python3 ./test.py -f 2-query/function_state.py 1,,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/demo.py -3,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestInspect.py +#3,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestInspect.py -- GitLab From 5ab843d1651a650982ff80e1bbfa88353fc3234a Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 29 Jul 2022 18:10:38 +0800 Subject: [PATCH 258/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- tests/parallel_test/cases.task | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index d9a44b2405..1f571eb998 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit d9a44b2405bc4180841f20834488f811911cb518 +Subproject commit 1f571eb99802d8d0f2777d144b24fa4052cadac7 diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index f51a4c2442..2322365dc8 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -410,7 +410,7 @@ 15,,pytest,python3 test.py -f functions/function_last.py -r 1 15,,pytest,python3 test.py -f functions/function_avg.py -r 1 14,,script,./test.sh -f general/stream/metrics_del.sim -14,,system-test,python3 ./test.py -f 5-taos-tools/TD-12478.py +#14,,system-test,python3 ./test.py -f 5-taos-tools/TD-12478.py 14,,script,./test.sh -f unique/account/basic.sim 14,,script,./test.sh -f general/table/limit.sim 14,,script,./test.sh -f general/table/createmulti.sim -- GitLab From 6aa6d72e220cab55765bc64222a54baf0d3179ec Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 29 Jul 2022 20:12:40 +0800 Subject: [PATCH 259/380] feat: update taostools for2.6 (#15494) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 --- Jenkinsfile2 | 15 ++++++++++++- src/kit/taos-tools | 2 +- tests/parallel_test/cases.task | 40 +++++++++++++++++----------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index 257a13e4bf..df2ce5a2cd 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -134,6 +134,19 @@ def sync_source() { git submodule update --init --recursive ''' } +def pre_test_arm64() { + sync_source() + sh ''' + cd ${WK} + mkdir -p debug + cd debug + go env -w GOPROXY=https://goproxy.cn,direct + go env -w GO111MODULE=on + cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true > /dev/null + make -j8 >/dev/null + ''' + return 1 +} def pre_test() { sync_source() sh ''' @@ -330,7 +343,7 @@ pipeline { agent {label " worker07_arm64 || worker09_arm64 "} steps { timeout(time: 20, unit: 'MINUTES') { - pre_test() + pre_test_arm64() script { sh ''' echo "arm64 build done" diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 9cfa195713..1f571eb998 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 9cfa195713d1cae9edf417a8d49bde87dd971016 +Subproject commit 1f571eb99802d8d0f2777d144b24fa4052cadac7 diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index c2c462324e..2322365dc8 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -204,7 +204,7 @@ 36,,script,./test.sh -f unique/arbitrator/offline_replica3_createTable_online.sim 36,,script,./test.sh -f unique/arbitrator/offline_replica2_dropTable_online.sim 36,,script,./test.sh -f general/parser/tbnameIn.sim -36,,pytest,python3 test.py -f tools/taosdumpTestNanoSupport.py +#36,,pytest,python3 test.py -f tools/taosdumpTestNanoSupport.py 35,,script,./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim 35,,script,./test.sh -f unique/arbitrator/offline_replica3_alterTag_online.sim 35,,script,./test.sh -f unique/arbitrator/offline_replica2_alterTag_online.sim @@ -219,7 +219,7 @@ 33,,script,./test.sh -f general/table/delete_writing.sim 33,,script,./test.sh -f general/parser/slimit.sim 33,,script,./test.sh -f general/db/topic1.sim -32,,system-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestColTag.py +#32,,system-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestColTag.py 32,,script,./test.sh -f unique/mnode/mgmt21.sim 32,,script,./test.sh -f unique/arbitrator/offline_replica3_dropDb_online.sim 32,,script,./test.sh -f unique/arbitrator/dn3_mn2_killDnode.sim @@ -323,7 +323,7 @@ 19,,script,./test.sh -f unique/stable/dnode2.sim 19,,script,./test.sh -f general/db/vnodes.sim 19,,pytest,python3 test.py -f multilevel/addAnotherDir.py -19,,pytest,python3 test.py -f tools/taosdumpTest3.py +#19,,pytest,python3 test.py -f tools/taosdumpTest3.py 19,,pytest,python3 test.py -f query/udf.py 19,,pytest,python3 test.py -f import_merge/importLastTPO.py 19,,pytest,python3 test.py -f import_merge/importDataLastHO.py @@ -410,7 +410,7 @@ 15,,pytest,python3 test.py -f functions/function_last.py -r 1 15,,pytest,python3 test.py -f functions/function_avg.py -r 1 14,,script,./test.sh -f general/stream/metrics_del.sim -14,,system-test,python3 ./test.py -f 5-taos-tools/TD-12478.py +#14,,system-test,python3 ./test.py -f 5-taos-tools/TD-12478.py 14,,script,./test.sh -f unique/account/basic.sim 14,,script,./test.sh -f general/table/limit.sim 14,,script,./test.sh -f general/table/createmulti.sim @@ -579,34 +579,34 @@ 9,,pytest,python3 test.py -f stream/showStreamExecTimeisNull.py 9,,pytest,python3 test.py -f query/bug1876.py 9,,pytest,python3 test.py -f alter/alter_table_crash.py -9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeSmallInt.py -9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeFloat.py -8,,pytest,python3 test.py -f tools/taosdumpTest.py +#9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeSmallInt.py +#9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeFloat.py +#8,,pytest,python3 test.py -f tools/taosdumpTest.py 8,,pytest,python3 test.py -f query/unionAllTest.py 8,,pytest,python3 test.py -f query/queryFilterTswithDateUnit.py 8,,pytest,python3 test.py -f query/queryDiffColsTagsAndOr.py 8,,pytest,python3 test.py -f query/nestedQuery/nestedQuery_datacheck.py 8,,pytest,python3 test.py -f query/bug1874.py 8,,pytest,python3 test.py -f functions/function_floor.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedTinyInt.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedBigInt.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeTinyInt.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py -8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedTinyInt.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedBigInt.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeTinyInt.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py +#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py 8,,pytest,python3 test.py -f update/update2.py 7,,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonSml-otherPara.py -7,,pytest,python3 test.py -f tools/taosdumpTest2.py +#7,,pytest,python3 test.py -f tools/taosdumpTest2.py 7,,pytest,python3 test.py -f tools/taosdemoTestdatatype.py 7,,pytest,python3 test.py -f tag_lite/unsignedInt.py 7,,pytest,python3 test.py -f query/bug1875.py 7,,pytest,python3 test.py -f functions/function_stateWindow.py 7,,pytest,python3 test.py -f client/version.py 7,,pytest,python3 client/twoClients.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedSmallInt.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedInt.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeJson.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBool.py -7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBigInt.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedSmallInt.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedInt.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeJson.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBool.py +#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBigInt.py 7,,develop-test,python3 ./test.py -f 2-query/function_timetruncate.py 7,,develop-test,python3 ./test.py -f 2-query/function_timediff.py 7,,pytest,python3 test.py -f tsdb/delete.py @@ -660,7 +660,7 @@ 5,,pytest,python3 testMinTablesPerVnode.py 5,,pytest,python3 test.py -f tag_lite/unsignedTinyint.py 5,,pytest,python3 test.py -f tag_lite/timestamp.py -5,,pytest,python3 test.py -f tag_lite/TestModifyTag.py +#5,,pytest,python3 test.py -f tag_lite/TestModifyTag.py 5,,pytest,python3 test.py -f tag_lite/json_tag_extra.py 5,,pytest,python3 test.py -f tag_lite/int_binary.py 5,,pytest,python3 test.py -f tag_lite/float.py @@ -831,4 +831,4 @@ 1,,docs-examples-test, ./test_R.sh 1,,develop-test,python3 ./test.py -f 2-query/function_state.py 1,,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/demo.py -3,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestInspect.py +#3,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestInspect.py -- GitLab From 7e5f6fec446c7ed9a2fa2fbe386344a5dd73725c Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 29 Jul 2022 20:28:23 +0800 Subject: [PATCH 260/380] feat: revert cases.task for taosdump --- tests/parallel_test/cases.task | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 2322365dc8..c2c462324e 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -204,7 +204,7 @@ 36,,script,./test.sh -f unique/arbitrator/offline_replica3_createTable_online.sim 36,,script,./test.sh -f unique/arbitrator/offline_replica2_dropTable_online.sim 36,,script,./test.sh -f general/parser/tbnameIn.sim -#36,,pytest,python3 test.py -f tools/taosdumpTestNanoSupport.py +36,,pytest,python3 test.py -f tools/taosdumpTestNanoSupport.py 35,,script,./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim 35,,script,./test.sh -f unique/arbitrator/offline_replica3_alterTag_online.sim 35,,script,./test.sh -f unique/arbitrator/offline_replica2_alterTag_online.sim @@ -219,7 +219,7 @@ 33,,script,./test.sh -f general/table/delete_writing.sim 33,,script,./test.sh -f general/parser/slimit.sim 33,,script,./test.sh -f general/db/topic1.sim -#32,,system-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestColTag.py +32,,system-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestColTag.py 32,,script,./test.sh -f unique/mnode/mgmt21.sim 32,,script,./test.sh -f unique/arbitrator/offline_replica3_dropDb_online.sim 32,,script,./test.sh -f unique/arbitrator/dn3_mn2_killDnode.sim @@ -323,7 +323,7 @@ 19,,script,./test.sh -f unique/stable/dnode2.sim 19,,script,./test.sh -f general/db/vnodes.sim 19,,pytest,python3 test.py -f multilevel/addAnotherDir.py -#19,,pytest,python3 test.py -f tools/taosdumpTest3.py +19,,pytest,python3 test.py -f tools/taosdumpTest3.py 19,,pytest,python3 test.py -f query/udf.py 19,,pytest,python3 test.py -f import_merge/importLastTPO.py 19,,pytest,python3 test.py -f import_merge/importDataLastHO.py @@ -410,7 +410,7 @@ 15,,pytest,python3 test.py -f functions/function_last.py -r 1 15,,pytest,python3 test.py -f functions/function_avg.py -r 1 14,,script,./test.sh -f general/stream/metrics_del.sim -#14,,system-test,python3 ./test.py -f 5-taos-tools/TD-12478.py +14,,system-test,python3 ./test.py -f 5-taos-tools/TD-12478.py 14,,script,./test.sh -f unique/account/basic.sim 14,,script,./test.sh -f general/table/limit.sim 14,,script,./test.sh -f general/table/createmulti.sim @@ -579,34 +579,34 @@ 9,,pytest,python3 test.py -f stream/showStreamExecTimeisNull.py 9,,pytest,python3 test.py -f query/bug1876.py 9,,pytest,python3 test.py -f alter/alter_table_crash.py -#9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeSmallInt.py -#9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeFloat.py -#8,,pytest,python3 test.py -f tools/taosdumpTest.py +9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeSmallInt.py +9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeFloat.py +8,,pytest,python3 test.py -f tools/taosdumpTest.py 8,,pytest,python3 test.py -f query/unionAllTest.py 8,,pytest,python3 test.py -f query/queryFilterTswithDateUnit.py 8,,pytest,python3 test.py -f query/queryDiffColsTagsAndOr.py 8,,pytest,python3 test.py -f query/nestedQuery/nestedQuery_datacheck.py 8,,pytest,python3 test.py -f query/bug1874.py 8,,pytest,python3 test.py -f functions/function_floor.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedTinyInt.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedBigInt.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeTinyInt.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedTinyInt.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedBigInt.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeTinyInt.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py 8,,pytest,python3 test.py -f update/update2.py 7,,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonSml-otherPara.py -#7,,pytest,python3 test.py -f tools/taosdumpTest2.py +7,,pytest,python3 test.py -f tools/taosdumpTest2.py 7,,pytest,python3 test.py -f tools/taosdemoTestdatatype.py 7,,pytest,python3 test.py -f tag_lite/unsignedInt.py 7,,pytest,python3 test.py -f query/bug1875.py 7,,pytest,python3 test.py -f functions/function_stateWindow.py 7,,pytest,python3 test.py -f client/version.py 7,,pytest,python3 client/twoClients.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedSmallInt.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedInt.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeJson.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBool.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBigInt.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedSmallInt.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedInt.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeJson.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBool.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBigInt.py 7,,develop-test,python3 ./test.py -f 2-query/function_timetruncate.py 7,,develop-test,python3 ./test.py -f 2-query/function_timediff.py 7,,pytest,python3 test.py -f tsdb/delete.py @@ -660,7 +660,7 @@ 5,,pytest,python3 testMinTablesPerVnode.py 5,,pytest,python3 test.py -f tag_lite/unsignedTinyint.py 5,,pytest,python3 test.py -f tag_lite/timestamp.py -#5,,pytest,python3 test.py -f tag_lite/TestModifyTag.py +5,,pytest,python3 test.py -f tag_lite/TestModifyTag.py 5,,pytest,python3 test.py -f tag_lite/json_tag_extra.py 5,,pytest,python3 test.py -f tag_lite/int_binary.py 5,,pytest,python3 test.py -f tag_lite/float.py @@ -831,4 +831,4 @@ 1,,docs-examples-test, ./test_R.sh 1,,develop-test,python3 ./test.py -f 2-query/function_state.py 1,,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/demo.py -#3,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestInspect.py +3,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestInspect.py -- GitLab From 8a6a6f7c7b2483cdff5d94859bce6b5d5f4c3531 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 30 Jul 2022 10:40:21 +0800 Subject: [PATCH 261/380] feat: update taos-tools 9dc2fec for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 1f571eb998..9dc2fec5e2 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 1f571eb99802d8d0f2777d144b24fa4052cadac7 +Subproject commit 9dc2fec5e2cb96a998feef7d8ed22bdba0bf9141 -- GitLab From b013299111c2d2e7b0ae1dc0a55883a862910f65 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 30 Jul 2022 13:30:30 +0800 Subject: [PATCH 262/380] fix: use jenkinsfile2 same as develop branch --- Jenkinsfile2 | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index df2ce5a2cd..6549f714a1 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -150,14 +150,8 @@ def pre_test_arm64() { def pre_test() { sync_source() sh ''' - cd ${WK} - mkdir -p debug - cd debug - go env -w GOPROXY=https://goproxy.cn,direct - go env -w GO111MODULE=on - cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true > /dev/null - make -j8 >/dev/null - make install + cd ${WKC}/tests/parallel_test + ./container_build.sh -w ${WKDIR} -t 8 >/dev/null ''' return 1 } @@ -325,6 +319,7 @@ pipeline { agent none options { skipDefaultCheckout() } environment{ + WKDIR = '/var/data/jenkins/workspace' WK = '/var/data/jenkins/workspace/TDinternal' WKC = '/var/data/jenkins/workspace/TDinternal/community' LOGDIR = '/var/data/jenkins/workspace/log' -- GitLab From c73c5e0e147727ffc83be86e1d7b122248bc965c Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 30 Jul 2022 14:00:39 +0800 Subject: [PATCH 263/380] feat: update taostools for2.6 (#15564) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch --- Jenkinsfile2 | 11 +++------- src/kit/taos-tools | 2 +- tests/parallel_test/cases.task | 40 +++++++++++++++++----------------- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/Jenkinsfile2 b/Jenkinsfile2 index df2ce5a2cd..6549f714a1 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -150,14 +150,8 @@ def pre_test_arm64() { def pre_test() { sync_source() sh ''' - cd ${WK} - mkdir -p debug - cd debug - go env -w GOPROXY=https://goproxy.cn,direct - go env -w GO111MODULE=on - cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true > /dev/null - make -j8 >/dev/null - make install + cd ${WKC}/tests/parallel_test + ./container_build.sh -w ${WKDIR} -t 8 >/dev/null ''' return 1 } @@ -325,6 +319,7 @@ pipeline { agent none options { skipDefaultCheckout() } environment{ + WKDIR = '/var/data/jenkins/workspace' WK = '/var/data/jenkins/workspace/TDinternal' WKC = '/var/data/jenkins/workspace/TDinternal/community' LOGDIR = '/var/data/jenkins/workspace/log' diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 1f571eb998..9dc2fec5e2 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 1f571eb99802d8d0f2777d144b24fa4052cadac7 +Subproject commit 9dc2fec5e2cb96a998feef7d8ed22bdba0bf9141 diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 2322365dc8..c2c462324e 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -204,7 +204,7 @@ 36,,script,./test.sh -f unique/arbitrator/offline_replica3_createTable_online.sim 36,,script,./test.sh -f unique/arbitrator/offline_replica2_dropTable_online.sim 36,,script,./test.sh -f general/parser/tbnameIn.sim -#36,,pytest,python3 test.py -f tools/taosdumpTestNanoSupport.py +36,,pytest,python3 test.py -f tools/taosdumpTestNanoSupport.py 35,,script,./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim 35,,script,./test.sh -f unique/arbitrator/offline_replica3_alterTag_online.sim 35,,script,./test.sh -f unique/arbitrator/offline_replica2_alterTag_online.sim @@ -219,7 +219,7 @@ 33,,script,./test.sh -f general/table/delete_writing.sim 33,,script,./test.sh -f general/parser/slimit.sim 33,,script,./test.sh -f general/db/topic1.sim -#32,,system-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestColTag.py +32,,system-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestColTag.py 32,,script,./test.sh -f unique/mnode/mgmt21.sim 32,,script,./test.sh -f unique/arbitrator/offline_replica3_dropDb_online.sim 32,,script,./test.sh -f unique/arbitrator/dn3_mn2_killDnode.sim @@ -323,7 +323,7 @@ 19,,script,./test.sh -f unique/stable/dnode2.sim 19,,script,./test.sh -f general/db/vnodes.sim 19,,pytest,python3 test.py -f multilevel/addAnotherDir.py -#19,,pytest,python3 test.py -f tools/taosdumpTest3.py +19,,pytest,python3 test.py -f tools/taosdumpTest3.py 19,,pytest,python3 test.py -f query/udf.py 19,,pytest,python3 test.py -f import_merge/importLastTPO.py 19,,pytest,python3 test.py -f import_merge/importDataLastHO.py @@ -410,7 +410,7 @@ 15,,pytest,python3 test.py -f functions/function_last.py -r 1 15,,pytest,python3 test.py -f functions/function_avg.py -r 1 14,,script,./test.sh -f general/stream/metrics_del.sim -#14,,system-test,python3 ./test.py -f 5-taos-tools/TD-12478.py +14,,system-test,python3 ./test.py -f 5-taos-tools/TD-12478.py 14,,script,./test.sh -f unique/account/basic.sim 14,,script,./test.sh -f general/table/limit.sim 14,,script,./test.sh -f general/table/createmulti.sim @@ -579,34 +579,34 @@ 9,,pytest,python3 test.py -f stream/showStreamExecTimeisNull.py 9,,pytest,python3 test.py -f query/bug1876.py 9,,pytest,python3 test.py -f alter/alter_table_crash.py -#9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeSmallInt.py -#9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeFloat.py -#8,,pytest,python3 test.py -f tools/taosdumpTest.py +9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeSmallInt.py +9,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeFloat.py +8,,pytest,python3 test.py -f tools/taosdumpTest.py 8,,pytest,python3 test.py -f query/unionAllTest.py 8,,pytest,python3 test.py -f query/queryFilterTswithDateUnit.py 8,,pytest,python3 test.py -f query/queryDiffColsTagsAndOr.py 8,,pytest,python3 test.py -f query/nestedQuery/nestedQuery_datacheck.py 8,,pytest,python3 test.py -f query/bug1874.py 8,,pytest,python3 test.py -f functions/function_floor.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedTinyInt.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedBigInt.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeTinyInt.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py -#8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedTinyInt.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedBigInt.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeTinyInt.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeInt.py +8,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeDouble.py 8,,pytest,python3 test.py -f update/update2.py 7,,system-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonSml-otherPara.py -#7,,pytest,python3 test.py -f tools/taosdumpTest2.py +7,,pytest,python3 test.py -f tools/taosdumpTest2.py 7,,pytest,python3 test.py -f tools/taosdemoTestdatatype.py 7,,pytest,python3 test.py -f tag_lite/unsignedInt.py 7,,pytest,python3 test.py -f query/bug1875.py 7,,pytest,python3 test.py -f functions/function_stateWindow.py 7,,pytest,python3 test.py -f client/version.py 7,,pytest,python3 client/twoClients.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedSmallInt.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedInt.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeJson.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBool.py -#7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBigInt.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedSmallInt.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeUnsignedInt.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeJson.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBool.py +7,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestTypeBigInt.py 7,,develop-test,python3 ./test.py -f 2-query/function_timetruncate.py 7,,develop-test,python3 ./test.py -f 2-query/function_timediff.py 7,,pytest,python3 test.py -f tsdb/delete.py @@ -660,7 +660,7 @@ 5,,pytest,python3 testMinTablesPerVnode.py 5,,pytest,python3 test.py -f tag_lite/unsignedTinyint.py 5,,pytest,python3 test.py -f tag_lite/timestamp.py -#5,,pytest,python3 test.py -f tag_lite/TestModifyTag.py +5,,pytest,python3 test.py -f tag_lite/TestModifyTag.py 5,,pytest,python3 test.py -f tag_lite/json_tag_extra.py 5,,pytest,python3 test.py -f tag_lite/int_binary.py 5,,pytest,python3 test.py -f tag_lite/float.py @@ -831,4 +831,4 @@ 1,,docs-examples-test, ./test_R.sh 1,,develop-test,python3 ./test.py -f 2-query/function_state.py 1,,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/demo.py -#3,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestInspect.py +3,,develop-test,python3 ./test.py -f 5-taos-tools/taosdump/taosdumpTestInspect.py -- GitLab From cdbb7c9a2688721a3b4ba6f9eadd39a4a5604be3 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 30 Jul 2022 15:52:30 +0800 Subject: [PATCH 264/380] chore: optimize upx download for2.6 (#15589) * chore: update taosadapter for 2.6 * chore: change upx download location * chore: optimize upx download for 2.6 --- src/plugins/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 6733b604fa..52d27593a1 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -63,7 +63,7 @@ ELSE () COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../inc CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -ldflags "-s -w -X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}" COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../inc CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -o taosadapter-debug -ldflags "-X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}" INSTALL_COMMAND - COMMAND wget -c https://github.com/upx/upx/releases/download/v3.96/upx-3.96-${PLATFORM_ARCH_STR}_linux.tar.xz -O ${CMAKE_CURRENT_SOURCE_DIR}/upx.tar.xz && tar -xvJf ${CMAKE_CURRENT_SOURCE_DIR}/upx.tar.xz -C ${CMAKE_CURRENT_SOURCE_DIR} --strip-components 1 > /dev/null && ${CMAKE_CURRENT_SOURCE_DIR}/upx taosadapter || : + COMMAND wget -c https://github.com/upx/upx/releases/download/v3.96/upx-3.96-${PLATFORM_ARCH_STR}_linux.tar.xz -O $ENV{HOME}/upx.tar.xz && tar -xvJf $ENV{HOME}/upx.tar.xz -C $ENV{HOME} --strip-components 1 > /dev/null && $ENV{HOME}/upx taosadapter || : COMMAND cmake -E copy taosadapter ${CMAKE_BINARY_DIR}/build/bin COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/test/cfg/ COMMAND cmake -E copy ./example/config/taosadapter.toml ${CMAKE_BINARY_DIR}/test/cfg/ -- GitLab From 2e6c9c640d47666d954f4fd568f457f471e116cd Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 30 Jul 2022 18:54:01 +0800 Subject: [PATCH 265/380] docs: python connector pandas supplyment (#15604) --- docs/en/14-reference/03-connector/python.mdx | 15 +++++++++++++++ docs/examples/python/conn_native_pandas.py | 6 +++--- .../examples/python/conn_native_sqlalchemy.py | 19 +++++++++++++++++++ docs/examples/python/conn_rest_pandas.py | 6 +++--- docs/examples/python/conn_rest_sqlalchemy.py | 19 +++++++++++++++++++ docs/zh/14-reference/03-connector/python.mdx | 14 ++++++++++++++ 6 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 docs/examples/python/conn_native_sqlalchemy.py create mode 100644 docs/examples/python/conn_rest_sqlalchemy.py diff --git a/docs/en/14-reference/03-connector/python.mdx b/docs/en/14-reference/03-connector/python.mdx index 04eb2e57d4..1e2eecb260 100644 --- a/docs/en/14-reference/03-connector/python.mdx +++ b/docs/en/14-reference/03-connector/python.mdx @@ -293,6 +293,21 @@ For a more detailed description of the `sql()` method, please refer to [RestClie {{#include docs/examples/python/conn_rest_pandas.py}} ``` + + + + +```python +{{#include docs/examples/python/conn_native_sqlalchemy.py}} +``` + + + + +```python +{{#include docs/examples/python/conn_rest_sqlachemy.py}} +``` + diff --git a/docs/examples/python/conn_native_pandas.py b/docs/examples/python/conn_native_pandas.py index 56942ef570..8b5555cf6d 100644 --- a/docs/examples/python/conn_native_pandas.py +++ b/docs/examples/python/conn_native_pandas.py @@ -1,8 +1,8 @@ +import taos import pandas -from sqlalchemy import create_engine -engine = create_engine("taos://root:taosdata@localhost:6030/power") -df = pandas.read_sql("SELECT * FROM meters", engine) +conn = taos.connect() +df: pandas.DataFrame = pandas.read_sql("SELECT * FROM meters", conn) # print index print(df.index) diff --git a/docs/examples/python/conn_native_sqlalchemy.py b/docs/examples/python/conn_native_sqlalchemy.py new file mode 100644 index 0000000000..40c68bda55 --- /dev/null +++ b/docs/examples/python/conn_native_sqlalchemy.py @@ -0,0 +1,19 @@ +import pandas +from sqlalchemy import create_engine + +engine = create_engine("taos://root:taosdata@localhost:6030/power") +df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", engine) + +# print index +print(df.index) +# print data type of element in ts column +print(type(df.ts[0])) +print(df.head(3)) + +# output: +# RangeIndex(start=0, stop=8, step=1) +# +# ts current ... location groupid +# 0 2018-10-03 14:38:05.500 11.8 ... california.losangeles 2 +# 1 2018-10-03 14:38:16.600 13.4 ... california.losangeles 2 +# 2 2018-10-03 14:38:05.000 10.8 ... california.losangeles 3 diff --git a/docs/examples/python/conn_rest_pandas.py b/docs/examples/python/conn_rest_pandas.py index 0164080cd5..356f01c5c5 100644 --- a/docs/examples/python/conn_rest_pandas.py +++ b/docs/examples/python/conn_rest_pandas.py @@ -1,8 +1,8 @@ +import taosrest import pandas -from sqlalchemy import create_engine -engine = create_engine("taosrest://root:taosdata@localhost:6041") -df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", engine) +conn = taosrest.connect() +df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", conn) # print index print(df.index) diff --git a/docs/examples/python/conn_rest_sqlalchemy.py b/docs/examples/python/conn_rest_sqlalchemy.py new file mode 100644 index 0000000000..0164080cd5 --- /dev/null +++ b/docs/examples/python/conn_rest_sqlalchemy.py @@ -0,0 +1,19 @@ +import pandas +from sqlalchemy import create_engine + +engine = create_engine("taosrest://root:taosdata@localhost:6041") +df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", engine) + +# print index +print(df.index) +# print data type of element in ts column +print(type(df.ts[0])) +print(df.head(3)) + +# output: +# RangeIndex(start=0, stop=8, step=1) +# +# ts current ... location groupid +# 0 2018-10-03 06:38:05.500000+00:00 11.8 ... california.losangeles 2 +# 1 2018-10-03 06:38:16.600000+00:00 13.4 ... california.losangeles 2 +# 2 2018-10-03 06:38:05+00:00 10.8 ... california.losangeles 3 diff --git a/docs/zh/14-reference/03-connector/python.mdx b/docs/zh/14-reference/03-connector/python.mdx index a77dc71db7..38b64a8aef 100644 --- a/docs/zh/14-reference/03-connector/python.mdx +++ b/docs/zh/14-reference/03-connector/python.mdx @@ -295,6 +295,20 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线 {{#include docs/examples/python/conn_rest_pandas.py}} ``` + + + +```python +{{#include docs/examples/python/conn_native_sqlalchemy.py}} +``` + + + + +```python +{{#include docs/examples/python/conn_rest_sqlachemy.py}} +``` + -- GitLab From c1e8cc7cd3a8ae14f8cd99ab87396e4298b52adf Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sun, 31 Jul 2022 14:12:56 +0800 Subject: [PATCH 266/380] feat: update taos-tools 0e0fea3431 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 9dc2fec5e2..f4e456a15f 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 9dc2fec5e2cb96a998feef7d8ed22bdba0bf9141 +Subproject commit f4e456a15f30814182b3c2834bfe591c10a745af -- GitLab From ae96ca6740993dbcefac74096082bb4cfd4e7194 Mon Sep 17 00:00:00 2001 From: zhaoyanggh Date: Fri, 29 Jul 2022 19:00:29 +0800 Subject: [PATCH 267/380] feat: cherry pick test case changes --- .../5-taos-tools/taosbenchmark/json/custom_col_tag.json | 3 +-- .../taosbenchmark/json/rest_auto_create_table.json | 3 +-- .../5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_auto_create_table.json | 3 +-- .../5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_interlace.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_json_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_rest_json.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_rest_line.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_rest_telnet.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json | 1 - .../taosbenchmark/json/stmt_auto_create_table.json | 3 +-- .../5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json | 1 - .../taosbenchmark/json/taosc_auto_create_table.json | 1 - .../5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/taosc_json_tag.json | 1 - .../5-taos-tools/taosbenchmark/json/taosc_limit_offset.json | 1 - .../taosbenchmark/json/taosc_only_create_table.json | 3 +-- .../5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json | 1 - 20 files changed, 5 insertions(+), 25 deletions(-) diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/custom_col_tag.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/custom_col_tag.json index 8f652b9d73..6558212816 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/custom_col_tag.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/custom_col_tag.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, @@ -88,4 +87,4 @@ }] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json index a4706bf47d..cebabf95b6 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, @@ -84,4 +83,4 @@ "tags": [{"type": "TIMESTAMP"},{"type": "INT"}, {"type": "BIGINT"}, {"type": "FLOAT"}, {"type": "DOUBLE"}, {"type": "SMALLINT"}, {"type": "TINYINT"}, {"type": "BOOL"}, {"type": "NCHAR","len": 17, "count":1}, {"type": "UINT"}, {"type": "UBIGINT"}, {"type": "UTINYINT"}, {"type": "USMALLINT"}, {"type": "BINARY", "len": 19, "count":1}] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json index 01e3950502..0a10458283 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json index 62846bf2b6..5cbd67e154 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, @@ -84,4 +83,4 @@ "tags": [{"type": "INT"}, {"type": "BIGINT"}, {"type": "FLOAT"}, {"type": "DOUBLE"}, {"type": "SMALLINT"}, {"type": "TINYINT"}, {"type": "BOOL"}, {"type": "NCHAR","len": 17, "count":1}, {"type": "UINT"}, {"type": "UBIGINT"}, {"type": "UTINYINT"}, {"type": "USMALLINT"}, {"type": "BINARY", "len": 19, "count":1}] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json index 8722d124d6..0cf1526041 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_interlace.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_interlace.json index 1aa5b09348..a0eec1c9af 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_interlace.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_interlace.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_json_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_json_alltypes.json index 8806b52a1e..4e7f6472f6 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_json_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_json_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_json.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_json.json index 1e9e28d4e8..2737f6e631 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_json.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_json.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_line.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_line.json index deef77fdef..f19f3734ef 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_line.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_line.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_telnet.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_telnet.json index 8893a73467..f083782c07 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_telnet.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_telnet.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json index 0bf363e673..9c590ae83c 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json index 84419760c1..60af5dfe54 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json index 2e5965c14b..5d74e960e2 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, @@ -84,4 +83,4 @@ "tags": [{"type": "TIMESTAMP"},{"type": "INT"}, {"type": "BIGINT"}, {"type": "FLOAT"}, {"type": "DOUBLE"}, {"type": "SMALLINT"}, {"type": "TINYINT"}, {"type": "BOOL"}, {"type": "NCHAR","len": 17, "count":1}, {"type": "UINT"}, {"type": "UBIGINT"}, {"type": "UTINYINT"}, {"type": "USMALLINT"}, {"type": "BINARY", "len": 19, "count":1}] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json index 48f4e23166..f7266ee71f 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json index 06c5be47bf..ba7660658f 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json index 1bb03b4fab..62685eb3c7 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_json_tag.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_json_tag.json index 893b203aa8..ef0b1d2784 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_json_tag.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_json_tag.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_limit_offset.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_limit_offset.json index b0e903347d..546885db7d 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_limit_offset.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_limit_offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_only_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_only_create_table.json index 4d42ed63fa..5869410c03 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_only_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_only_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":1, "quorum":1, "fsync":3000, @@ -59,4 +58,4 @@ "tags": [{"type": "TIMESTAMP"},{"type": "INT"}, {"type": "BIGINT"}, {"type": "FLOAT"}, {"type": "DOUBLE"}, {"type": "SMALLINT"}, {"type": "TINYINT"}, {"type": "BOOL"}, {"type": "NCHAR"}, {"type": "UINT"}, {"type": "UBIGINT"}, {"type": "UTINYINT"}, {"type": "USMALLINT"}, {"type": "BINARY"}] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json index 22bd13d5be..d9eb17ea1f 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, -- GitLab From a9c16769170e162bc70e16b6e6d16f382ce45b66 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Sun, 31 Jul 2022 21:31:04 +0800 Subject: [PATCH 268/380] feat(rpc): add probe msg --- src/client/inc/tsclient.h | 3 --- src/client/src/tscServer.c | 22 +++++++++++----------- src/inc/trpc.h | 11 +++++++++-- src/query/src/qExecutor.c | 2 +- src/rpc/src/rpcMain.c | 33 ++++++++++++++------------------- 5 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 3e9ad0699a..88d1916724 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -402,9 +402,6 @@ typedef struct SSqlObj { int64_t lastProbe; int64_t lastAlive; void * pPrevContext; - void * pPrevConn; - void * pPrevFdObj; - int32_t prevFd; } SSqlObj; typedef struct SSqlStream { diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 84fe8e31d8..0d3471126c 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -303,7 +303,7 @@ bool dealConnBroken(SSqlObj * pSql) { } // error notify - tscInfo("PROBE 0x%"PRIx64" async result error. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); + tscInfo("PROBE 0x%"PRIx64" call async result error." PRIx64, pSql->self); tscAsyncResultOnError(pSql); return true; @@ -325,23 +325,22 @@ bool sendProbeConnMsg(SSqlObj* pSql) { int32_t diff = (int32_t)(taosGetTimestampMs() - stime); if (diff < tsProbeSeconds * 1000) { // exec time short , need not probe alive - tscInfo("PROBE 0x%" PRIx64 "not arrived probe time. timeout=%ds, no need probe. lastAlive=%" PRId64 " stime=%" PRId64, \ + tscInfo("PROBE 0x%" PRIx64 " not arrived probe time. cfg timeout=%ds, no need probe. lastAlive=%" PRId64 " stime=%" PRId64, \ pSql->self, tsProbeSeconds, pSql->lastAlive, pSql->stime); return true; } if (diff > tsProbeKillSeconds * 1000) { // need kill query - tscInfo("PROBE 0x%" PRIx64 "kill query by probe. because arrived kill time. timeout=%ds lastAlive=%" PRId64 " stime=%" PRId64, \ - pSql->self, tsProbeKillSeconds, pSql->lastAlive, pSql->stime); + tscInfo("PROBE 0x%" PRIx64 " kill query by probe. because arrived kill time. time=%ds cfg timeout=%ds lastAlive=%" PRId64 " stime=%" PRId64, \ + pSql->self, diff/1000, tsProbeKillSeconds, pSql->lastAlive, pSql->stime); return false; } - if (pSql->pPrevContext == NULL || pSql->pPrevConn == NULL || pSql->pPrevFdObj == NULL || pSql->prevFd <= 0) { + if (pSql->pPrevContext == NULL) { // last connect info save uncompletely, so can't probe - tscInfo("PROBE 0x%" PRIx64 "save last connect info uncompletely. prev context=%p conn=%p fdobj=%p fd=%d", \ - pSql->self, pSql->pPrevContext, pSql->pPrevConn, pSql->pPrevFdObj, pSql->prevFd); + tscInfo("PROBE 0x%" PRIx64 " save last connect info uncompletely. prev context is null", pSql->self); return true; } @@ -354,8 +353,8 @@ bool sendProbeConnMsg(SSqlObj* pSql) { // It's long time from lastAlive, so need probe pSql->lastProbe = taosGetTimestampMs(); - bool ret = rpcSendProbe(pSql->rpcRid, pSql->pPrevContext, pSql->pPrevConn, pSql->pPrevFdObj, pSql->prevFd); - tscInfo("PROBE 0x%" PRIx64 " rpcRid=0x%" PRIx64 " send probe msg, ret=%d", pSql->self, pSql->rpcRid, ret); + bool ret = rpcSendProbe(pSql->rpcRid, pSql->pPrevContext); + tscInfo("PROBE 0x%" PRIx64 " send probe msg, ret=%d rpcRid=0x%" PRIx64, pSql->self, ret, pSql->rpcRid); return ret; } @@ -365,7 +364,7 @@ void checkBrokenQueries(STscObj *pTscObj) { SSqlObj *pSql = pTscObj->sqlList; while (pSql) { int32_t numOfSub = pSql->subState.numOfSub; - tscInfo("PROBE 0x%" PRIx64 " numOfSub=%d sql=%s", pSql->self, numOfSub, pSql->sqlstr == NULL ? "" : pSql->sqlstr); + tscInfo("PROBE 0x%" PRIx64 " check sql connection alive, numOfSub=%d sql=%s", pSql->self, numOfSub, pSql->sqlstr == NULL ? "" : pSql->sqlstr); if (numOfSub == 0) { // no sub sql if(!sendProbeConnMsg(pSql)) { @@ -460,9 +459,10 @@ int tscSendMsgToServer(SSqlObj *pSql) { return TSDB_CODE_FAILED; } + if(rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid)) { if(pSql->cmd.command != TSDB_SQL_HB) - rpcSaveSendInfo(pSql->rpcRid, &pSql->pPrevContext, &pSql->pPrevConn, &pSql->pPrevFdObj, &pSql->prevFd); + rpcSaveSendInfo(pSql->rpcRid, &pSql->pPrevContext); return TSDB_CODE_SUCCESS; } diff --git a/src/inc/trpc.h b/src/inc/trpc.h index 3e1edc2c0a..940a1bf044 100644 --- a/src/inc/trpc.h +++ b/src/inc/trpc.h @@ -78,6 +78,13 @@ typedef struct SRpcInit { int (*afp)(char *tableId, char *spi, char *encrypt, char *secret, char *ckey); } SRpcInit; +typedef struct SSendInfo { + void *pContext; + void *pConn; + void *pFdObj; + int32_t fd; +} SSendInfo; + int32_t rpcInit(); void rpcCleanup(); void *rpcOpen(const SRpcInit *pRpc); @@ -94,9 +101,9 @@ int rpcReportProgress(void *pConn, char *pCont, int contLen); void rpcCancelRequest(int64_t rid); int32_t rpcUnusedSession(void * rpcInfo, bool bLock); // send rpc Refid connection probe alive message -bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPrevFdObj, int32_t prevFd); +bool rpcSendProbe(int64_t rpcRid, void* pPrevContext); // after sql request send , save conn info -bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd); +bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext); #ifdef __cplusplus } diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index cc9464ad72..6f7e77d915 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -6369,7 +6369,7 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { // TEST TODU DELETE static int loop = 0; - taosMsleep(3*1000); + taosMsleep(1*1000); qInfo(" loop=%d pEnv=%p", loop++, pRuntimeEnv); diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 11a8b4b70b..e8564ac8ed 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -87,6 +87,7 @@ typedef struct { tsem_t *pSem; // for synchronous API SRpcEpSet *pSet; // for synchronous API char msg[0]; // RpcHead starts from here + SSendInfo sendInfo; // save last send information } SRpcReqContext; typedef struct SRpcConn { @@ -1412,6 +1413,11 @@ static bool rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { if(pContext) pConn->rid = pContext->rid; + // save + pContext->sendInfo.pConn = pConn; + pContext->sendInfo.pFdObj = pConn->chandle; + pContext->sendInfo.fd = taosGetFdID(pConn->chandle); + bool ret = rpcSendMsgToPeer(pConn, msg, msgLen); if (pConn->connType != RPC_CONN_TCPC) taosTmrReset(rpcProcessRetryTimer, tsRpcTimer, pConn, pRpc->tmrCtrl, &pConn->pTimer); @@ -1787,7 +1793,7 @@ bool doRpcSendProbe(SRpcConn *pConn) { } // send server syn -bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPrevFdObj, int32_t prevFd) { +bool rpcSendProbe(int64_t rpcRid, void* pPrevContext) { // return false can kill query bool ret = false; if(rpcRid < 0) { @@ -1809,28 +1815,27 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, void* pPrevConn, void* pPr } // conn same - if (pContext->pConn != pPrevConn) { - tError("PROBE rpcRid=0x%" PRIx64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pPrevConn); + if (pContext->pConn != pContext->sendInfo.pConn) { + tError("PROBE rpcRid=0x%" PRIx64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pContext->sendInfo.pConn); ret = pContext->pConn == NULL; goto _END; } // fdObj same - if (pContext->pConn->chandle != pPrevFdObj) { - tError("PROBE rpcRid=0x%" PRIx64 " connect fdObj diff. pContext->pConn->chandle=%p pPrevFdObj=%p", rpcRid, pContext->pConn->chandle, pPrevFdObj); + if (pContext->pConn->chandle != pContext->sendInfo.pFdObj) { + tError("PROBE rpcRid=0x%" PRIx64 " connect fdObj diff. pContext->pConn->chandle=%p pPrevFdObj=%p", rpcRid, pContext->pConn->chandle, pContext->sendInfo.pFdObj); goto _END; } // fd same int32_t fd = taosGetFdID(pContext->pConn->chandle); - if (fd != prevFd) { - tError("PROBE rpcRid=0x%" PRIx64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, prevFd); + if (fd != pContext->sendInfo.fd) { + tError("PROBE rpcRid=0x%" PRIx64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, pContext->sendInfo.fd); goto _END; } // send syn ret = doRpcSendProbe(pContext->pConn); - tInfo("PROBE 0x%" PRIx64 " rrpcRid=0x%" PRIx64 " send data ret=%d fd=%d.", (int64_t)pContext->ahandle, rpcRid, ret, fd); _END: // put back req context @@ -1839,7 +1844,7 @@ _END: } // after sql request send , save conn info -bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppFdObj, int32_t* pFd) { +bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext) { if(rpcRid < 0) { tError("PROBE saveSendInfo rpcRid=0x%" PRIx64 " less than zero, invalid.", rpcRid); return false; @@ -1851,18 +1856,8 @@ bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext, void** ppConn, void** ppF return false; } - if (pContext->pConn == NULL || pContext->pConn->chandle == NULL) { - return false; - } - if (ppContext) *ppContext = pContext; - if (ppConn) - *ppConn = pContext->pConn; - if (ppFdObj && pContext->pConn) - *ppFdObj = pContext->pConn->chandle; - if (pFd && pContext->pConn) - *pFd = taosGetFdID(pContext->pConn->chandle); taosReleaseRef(tsRpcRefId, rpcRid); return true; -- GitLab From 1e3d2a92a8c897d56011dd21e5b9ec30f0a4735b Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sun, 31 Jul 2022 14:57:36 +0000 Subject: [PATCH 269/380] fix: remove walLevel from json files --- tests/pytest/cluster/TD-3693/insert1Data.json | 1 - tests/pytest/cluster/TD-3693/insert2Data.json | 1 - tests/pytest/compress/insertDataDb1.json | 1 - tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json | 1 - tests/pytest/query/nestedQuery/insertData.json | 1 - tests/pytest/tools/insert-interlace.json | 1 - tests/pytest/tools/insert-tblimit-tboffset-createdb.json | 1 - tests/pytest/tools/insert-tblimit-tboffset-insertrec.json | 1 - tests/pytest/tools/insert-tblimit-tboffset.json | 1 - tests/pytest/tools/insert-tblimit-tboffset0.json | 1 - tests/pytest/tools/insert-tblimit1-tboffset.json | 1 - .../tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json | 1 - .../tools/taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json | 1 - .../tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json | 1 - .../taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabaseNow.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabasecsv.json | 1 - .../pytest/tools/taosdemoAllTest/TD-4985/query-limit-offset.json | 1 - .../tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-allDataType.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-chinese.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-disorder.json | 1 - .../pytest/tools/taosdemoAllTest/insert-drop-exist-auto-N00.json | 1 - .../pytest/tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-illegal.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-newdb.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-newtable.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-offset.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-renewdb.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-sample.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-timestep.json | 1 - .../insertBinaryLenLarge16374AllcolLar49151-error.json | 1 - .../taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151.json | 1 - tests/pytest/tools/taosdemoAllTest/insertChildTab0.json | 1 - tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json | 1 - .../pytest/tools/taosdemoAllTest/insertColumnsAndTagNum4096.json | 1 - .../tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json | 1 - tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json | 1 - .../pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json | 1 - tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json | 1 - tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json | 1 - .../tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json | 1 - tests/pytest/tools/taosdemoAllTest/insertRestful.json | 1 - tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json | 1 - tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json | 1 - tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json | 1 - tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json | 1 - tests/pytest/tools/taosdemoAllTest/manual_block2.json | 1 - tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json | 1 - tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json | 1 - tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json | 1 - tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json | 1 - tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json | 1 - tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json | 1 - tests/pytest/tools/taosdemoAllTest/query-interrupt.json | 1 - tests/pytest/tools/taosdemoAllTest/queryInsertdata.json | 1 - tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insert-allDataType-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json | 1 - .../taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json | 1 - .../taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json | 1 - .../tools/taosdemoAllTest/sml/insert-interlace-row-sml.json | 1 - .../tools/taosdemoAllTest/sml/insert-interval-speed-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json | 1 - .../tools/taosdemoAllTest/sml/insert-sml-json-alltype.json | 1 - .../tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json | 1 - .../sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json | 1 - .../sml/insertBinaryLenLarge16374AllcolLar49151-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json | 1 - .../tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json | 1 - .../taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json | 1 - .../taosdemoAllTest/sml/insertColumnsAndTagNumLarge4096-sml.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json | 1 - .../taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json | 1 - .../tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json | 1 - .../tools/taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json | 1 - .../taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json | 1 - .../tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json | 1 - .../tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insert-disorder-stmt.json | 1 - .../taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json | 1 - .../taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json | 1 - tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insert-newtable-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json | 1 - tests/pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json | 1 - tests/pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json | 1 - tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insert-timestep-stmt.json | 1 - .../stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json | 1 - .../stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json | 1 - .../taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json | 1 - .../stmt/insertColumnsAndTagNumLarge4096-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json | 1 - .../taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json | 1 - .../taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json | 1 - .../taosdemoAllTest/stmt/insertNumOfrecordPerReqless0-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json | 1 - tests/pytest/tools/taosdemoAllTest/subInsertdata.json | 1 - tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json | 1 - tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json | 1 - tests/pytest/tools/taosdump-insert-dp1.json | 1 - tests/pytest/tools/taosdump-insert-dp2.json | 1 - tests/pytest/tsdb/insertDataDb1.json | 1 - tests/pytest/tsdb/insertDataDb1Replica2.json | 1 - tests/pytest/tsdb/insertDataDb2.json | 1 - tests/pytest/tsdb/insertDataDb2Newstab.json | 1 - tests/pytest/tsdb/insertDataDb2NewstabReplica2.json | 1 - tests/pytest/tsdb/insertDataDb2Replica2.json | 1 - tests/pytest/wal/insertDataDb1.json | 1 - tests/pytest/wal/insertDataDb1Replica2.json | 1 - tests/pytest/wal/insertDataDb2.json | 1 - tests/pytest/wal/insertDataDb2Newstab.json | 1 - tests/pytest/wal/insertDataDb2NewstabReplica2.json | 1 - tests/pytest/wal/insertDataDb2Replica2.json | 1 - tests/system-test/2-query/td_12191.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseNow.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoTestNanoDatabasecsv.json | 1 - .../5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_no.json | 1 - .../5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_yes.json | 1 - .../5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json | 1 - .../5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-1s1tnt1r.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-1s1tntmr.json | 1 - .../5-taos-tools/taosbenchmark/insert-allDataType.json | 1 - .../5-taos-tools/taosbenchmark/insert-chinese-sml.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/insert-chinese.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-disorder.json | 1 - .../5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json | 1 - .../5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/insert-illegal.json | 1 - .../5-taos-tools/taosbenchmark/insert-interlace-row.json | 1 - .../5-taos-tools/taosbenchmark/insert-interval-speed.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-newtable.json | 1 - .../5-taos-tools/taosbenchmark/insert-nodbnodrop.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/insert-offset.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/insert-renewdb.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-sample-ts.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/insert-sample.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-timestep.json | 1 - .../insertBinaryLenLarge16374AllcolLar49151-error.json | 1 - .../taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insertChildTab0.json | 1 - .../5-taos-tools/taosbenchmark/insertChildTabLess0.json | 1 - .../5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json | 1 - .../taosbenchmark/insertColumnsAndTagNumLarge4096.json | 1 - .../5-taos-tools/taosbenchmark/insertColumnsNum0.json | 1 - .../5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json | 1 - .../5-taos-tools/taosbenchmark/insertMaxNumPerReq.json | 1 - .../5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json | 1 - .../5-taos-tools/taosbenchmark/insertNumOfrecordPerReqless0.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/insertRestful.json | 1 - .../5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json | 1 - .../5-taos-tools/taosbenchmark/insertTagsNumLarge128.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json | 1 - .../5-taos-tools/taosbenchmark/manual_block1_comp.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/manual_block2.json | 1 - .../5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json | 1 - .../5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json | 1 - .../5-taos-tools/taosbenchmark/moredemo-offset-limit1.json | 1 - .../5-taos-tools/taosbenchmark/moredemo-offset-limit5.json | 1 - .../5-taos-tools/taosbenchmark/moredemo-offset-limit94.json | 1 - .../5-taos-tools/taosbenchmark/moredemo-offset-newdb.json | 1 - .../system-test/5-taos-tools/taosbenchmark/query-interrupt.json | 1 - .../system-test/5-taos-tools/taosbenchmark/queryInsertdata.json | 1 - .../5-taos-tools/taosbenchmark/queryInsertrestdata.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json | 1 - .../taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json | 1 - .../taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-interlace-row-sml.json | 1 - .../taosbenchmark/sml/insert-interval-speed-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-offset-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-sample-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-sml-json-alltype.json | 1 - .../taosbenchmark/sml/insert-sml-telnet-alltype.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json | 1 - .../sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json | 1 - .../sml/insertBinaryLenLarge16374AllcolLar49151-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insertChildTabLess0-sml.json | 1 - .../taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json | 1 - .../taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json | 1 - .../taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json | 1 - .../taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json | 1 - .../5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json | 1 - .../taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json | 1 - .../taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json | 1 - .../taosbenchmark/sml/insertSigcolumnsNum4096-sml.json | 1 - .../taosbenchmark/sml/insertTagsNumLarge128-sml.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-allDataType-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json | 1 - .../taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json | 1 - .../taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json | 1 - .../taosbenchmark/stmt/insert-interlace-row-stmt.json | 1 - .../taosbenchmark/stmt/insert-interval-speed-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json | 1 - .../stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json | 1 - .../stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json | 1 - .../taosbenchmark/stmt/insertChildTabLess0-stmt.json | 1 - .../taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json | 1 - .../taosbenchmark/stmt/insertColumnsAndTagNumLarge4096-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insertColumnsNum0-stmt.json | 1 - .../taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insertMaxNumPerReq-stmt.json | 1 - .../taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json | 1 - .../taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json | 1 - .../taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json | 1 - .../taosbenchmark/stmt/insertTagsNumLarge128-stmt.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/subInsertdata.json | 1 - .../5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json | 1 - .../5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json | 1 - 264 files changed, 264 deletions(-) diff --git a/tests/pytest/cluster/TD-3693/insert1Data.json b/tests/pytest/cluster/TD-3693/insert1Data.json index 3ac289a63a..43aa789e48 100644 --- a/tests/pytest/cluster/TD-3693/insert1Data.json +++ b/tests/pytest/cluster/TD-3693/insert1Data.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/cluster/TD-3693/insert2Data.json b/tests/pytest/cluster/TD-3693/insert2Data.json index 25717df4c7..e2c3171798 100644 --- a/tests/pytest/cluster/TD-3693/insert2Data.json +++ b/tests/pytest/cluster/TD-3693/insert2Data.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/compress/insertDataDb1.json b/tests/pytest/compress/insertDataDb1.json index 65cec71a65..67006c4d1f 100644 --- a/tests/pytest/compress/insertDataDb1.json +++ b/tests/pytest/compress/insertDataDb1.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json b/tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json index 4f32b700d8..14cc984861 100644 --- a/tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json +++ b/tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/query/nestedQuery/insertData.json b/tests/pytest/query/nestedQuery/insertData.json index 149a4b56ac..1518da8c9d 100644 --- a/tests/pytest/query/nestedQuery/insertData.json +++ b/tests/pytest/query/nestedQuery/insertData.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-interlace.json b/tests/pytest/tools/insert-interlace.json index cd72958115..85cb2dcfce 100644 --- a/tests/pytest/tools/insert-interlace.json +++ b/tests/pytest/tools/insert-interlace.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit-tboffset-createdb.json b/tests/pytest/tools/insert-tblimit-tboffset-createdb.json index 025751bcd3..f5dad7a69d 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset-createdb.json +++ b/tests/pytest/tools/insert-tblimit-tboffset-createdb.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json b/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json index 6fa020433a..c013f616b1 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json +++ b/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit-tboffset.json b/tests/pytest/tools/insert-tblimit-tboffset.json index b4d4016ef9..5f8770070a 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset.json +++ b/tests/pytest/tools/insert-tblimit-tboffset.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit-tboffset0.json b/tests/pytest/tools/insert-tblimit-tboffset0.json index 8a7e39b17c..cbf5e78dff 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset0.json +++ b/tests/pytest/tools/insert-tblimit-tboffset0.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit1-tboffset.json b/tests/pytest/tools/insert-tblimit1-tboffset.json index 6e150203b3..bef719c5ee 100644 --- a/tests/pytest/tools/insert-tblimit1-tboffset.json +++ b/tests/pytest/tools/insert-tblimit1-tboffset.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json index 8bd5ddbae8..c3ea89a053 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json index 5408a9841a..b6428b482c 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json index 13eb80f3cf..4a648092cc 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json index 38ac666fac..afe156e18c 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json index 9ef4a0af66..ac2fbb39b7 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseNow.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseNow.json index a09dec21fa..dede88c2df 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseNow.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseNow.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabasecsv.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabasecsv.json index e99c528c6d..cc696518bf 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabasecsv.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabasecsv.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/TD-4985/query-limit-offset.json b/tests/pytest/tools/taosdemoAllTest/TD-4985/query-limit-offset.json index ad85f9607b..1b726ef5da 100644 --- a/tests/pytest/tools/taosdemoAllTest/TD-4985/query-limit-offset.json +++ b/tests/pytest/tools/taosdemoAllTest/TD-4985/query-limit-offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json index d6e3afdea3..9f79c1ae23 100755 --- a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json +++ b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json b/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json index d73719ebe4..f379fe61bf 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json b/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json index e10fd1116b..1420988650 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-allDataType.json b/tests/pytest/tools/taosdemoAllTest/insert-allDataType.json index a7ada9b84e..1e714c0813 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-allDataType.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-allDataType.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json b/tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json index 49407a76d7..3633bb6482 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-chinese.json b/tests/pytest/tools/taosdemoAllTest/insert-chinese.json index ab848b1317..88ace59778 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-chinese.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-chinese.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-disorder.json b/tests/pytest/tools/taosdemoAllTest/insert-disorder.json index d6420b100e..2ae3d6c1ce 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-disorder.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-disorder.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-N00.json b/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-N00.json index 2c3b8c6f81..fc2cf160a4 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-N00.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-N00.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json b/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json index f8fe21a6c4..39e4b3bbc8 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-illegal.json b/tests/pytest/tools/taosdemoAllTest/insert-illegal.json index c56f8f3040..920eed6456 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-illegal.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-illegal.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json b/tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json index 93bb92764d..a40c17d1f9 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json b/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json index d51dee428f..ae15b41e4f 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-newdb.json b/tests/pytest/tools/taosdemoAllTest/insert-newdb.json index 05a6f7606a..4386b7a7ee 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-newdb.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-newdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-newtable.json b/tests/pytest/tools/taosdemoAllTest/insert-newtable.json index 02b56bbfe8..a87e257ff9 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-newtable.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-newtable.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json b/tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json index 5978e5529f..44707e8748 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-offset.json b/tests/pytest/tools/taosdemoAllTest/insert-offset.json index 53edf41072..351a2b38d5 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-offset.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-renewdb.json b/tests/pytest/tools/taosdemoAllTest/insert-renewdb.json index 91c033c677..de023d15a2 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-renewdb.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-renewdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json b/tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json index b14c3a8ec6..d63549b79b 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-sample.json b/tests/pytest/tools/taosdemoAllTest/insert-sample.json index 87d442b7cb..d41433ff0c 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-sample.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-sample.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-timestep.json b/tests/pytest/tools/taosdemoAllTest/insert-timestep.json index c794c73c84..059643a851 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-timestep.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-timestep.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151-error.json b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151-error.json index be55d31d55..7f16fa74ec 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151-error.json +++ b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151-error.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151.json b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151.json index 67abdc67ee..ffcd49e32e 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151.json +++ b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json b/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json index 84aa75eca7..99f89eb7dc 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json b/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json index 58acd9bbd0..68fa2acf63 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum4096.json b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum4096.json index 17153c2f2c..4cd6e3ceb5 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum4096.json +++ b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json index 59cbedca72..04d32a3e79 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json +++ b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json b/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json index 52d6ae029d..867152a603 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json b/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json index 60a10d2501..0f4952074d 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json +++ b/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json b/tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json index 1166ac3643..686a2cc4f1 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json +++ b/tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json index 8247c5f015..def5043d4f 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json index 138ebbadf6..f1f4b7f3c6 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertRestful.json b/tests/pytest/tools/taosdemoAllTest/insertRestful.json index 682dcf2ce4..cb90c1f898 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertRestful.json +++ b/tests/pytest/tools/taosdemoAllTest/insertRestful.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json b/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json index e8468f5906..8b8f959e05 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json +++ b/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json b/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json index 4dbe2940e2..4480cf47d3 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json +++ b/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json b/tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json index 65973ccb48..ae82081525 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json +++ b/tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json b/tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json index a1a28c9ee9..5c8dc689ae 100644 --- a/tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json +++ b/tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/manual_block2.json b/tests/pytest/tools/taosdemoAllTest/manual_block2.json index 03f6e038fb..c92c18b025 100644 --- a/tests/pytest/tools/taosdemoAllTest/manual_block2.json +++ b/tests/pytest/tools/taosdemoAllTest/manual_block2.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json b/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json index 7b8abd6d4e..0f7786e682 100644 --- a/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json +++ b/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json b/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json index aeee6322e5..f8decfca41 100644 --- a/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json +++ b/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json index e30b7b0b1c..f166d461fe 100644 --- a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json +++ b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json index d4ce2fee46..ebbbc001f9 100644 --- a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json +++ b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json index ce12accf06..a18e1e0e1a 100644 --- a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json +++ b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json index 9ffb2953d3..4b246a93d7 100644 --- a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json +++ b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/query-interrupt.json b/tests/pytest/tools/taosdemoAllTest/query-interrupt.json index 896e484c25..8857d5adae 100644 --- a/tests/pytest/tools/taosdemoAllTest/query-interrupt.json +++ b/tests/pytest/tools/taosdemoAllTest/query-interrupt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/queryInsertdata.json b/tests/pytest/tools/taosdemoAllTest/queryInsertdata.json index eb196e4096..756316621d 100644 --- a/tests/pytest/tools/taosdemoAllTest/queryInsertdata.json +++ b/tests/pytest/tools/taosdemoAllTest/queryInsertdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json b/tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json index 0febbdfa19..0073f52e2b 100644 --- a/tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json +++ b/tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json index 5cd06c0275..8e96931e52 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json index 0885e01782..5042549f09 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-allDataType-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-allDataType-sml.json index cbd4f6cb59..0de5ddcc26 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-allDataType-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-allDataType-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json index 6f24801cb0..57006fcc3c 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json index 92e6ec0df7..dcca0f82ae 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json index c09493ec7b..cdfc5cb26d 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-interlace-row-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-interlace-row-sml.json index e04f2ff5e7..caf9a9466b 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-interlace-row-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-interlace-row-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-interval-speed-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-interval-speed-sml.json index 4a4227adb8..564f2405e3 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-interval-speed-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-interval-speed-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json index 1d29842e02..f0a84487d5 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json index 886503a950..ac5ba1dc5f 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json index ca99d135c5..50af8517bc 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json index d0109b50cf..d79ae2b005 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json index f8f3a8ee5c..459d47b114 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json index 780fd60bb7..35c808bd58 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-json-alltype.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-json-alltype.json index 66885ebab8..eca27390c6 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-json-alltype.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-json-alltype.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json index c9fa0f6fb0..6c780edd15 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json index 4e8ff40cfd..e7704b87fe 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json index 1d496b6b46..1d0490f539 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json index c70db14b4c..723260c422 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json index 12034adc07..ba3586635b 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json index 28f566833f..85ff34b99d 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json index 8f27feba6b..3e37ca197f 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json index 2e4063cf27..38477734e2 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNumLarge4096-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNumLarge4096-sml.json index c6fe0300f5..63ff800812 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNumLarge4096-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNumLarge4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json index 92e88141ca..0804acbae0 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json index 18f1a39e0a..73845c2dc5 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json b/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json index 01ec546012..b3a113ad38 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json index d950a260f6..33e61b7d20 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json index 0deed5ba54..aff3190e1a 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json index 9d1d1ee718..b9f1195457 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json index f732d2e0c5..e302d619c4 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json index 24f468d719..a692e4ef6f 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json index adb8764b2f..eaca2e040f 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json index b21154f1c5..8f7d0d2e80 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json index 46a0832612..134e4755b5 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-disorder-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-disorder-stmt.json index e750180421..bc948974b6 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-disorder-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-disorder-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json index 2712f88593..c09d5cfeb3 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json index f8fe21a6c4..39e4b3bbc8 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json index 45eb612e6f..4c5e90f185 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json index 4e6edb2199..c8c9684474 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json index 622b2554ec..f0ad1b4a5f 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-newtable-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-newtable-stmt.json index 31985c8546..15d2753c4b 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-newtable-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-newtable-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json index 3ebc377ca7..d636c95a94 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json index adc6fa74be..263a592dfa 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json index 715644f4f0..04165f16b1 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json index e3d6ce850a..cc4d180fb5 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json index b14c3a8ec6..d63549b79b 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-timestep-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-timestep-stmt.json index 563dc86d0a..ffe16eccd1 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-timestep-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-timestep-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json index f59d2e4e22..37714edc74 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json index 4903335d18..4625da3a6b 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json index a27feee68a..8f5b62be9b 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json index 50e1a7173b..a30c3f7c78 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json index ca0d17f93b..2966af8f23 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNumLarge4096-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNumLarge4096-stmt.json index c5a3a5f76d..40780dd992 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNumLarge4096-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNumLarge4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json index c86e759db4..cada61687e 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json index ee36b62f90..87386853b3 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json index 25086c856e..9e213b52a4 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json index 4bd071ec15..5b4bfbae65 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReqless0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReqless0-stmt.json index 628c86045f..efc01bb9e6 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReqless0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReqless0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json index 7abab6a0cf..e622415977 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json index 8f8539be21..51ac878c37 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/subInsertdata.json b/tests/pytest/tools/taosdemoAllTest/subInsertdata.json index 168b3753a1..57e823f74a 100644 --- a/tests/pytest/tools/taosdemoAllTest/subInsertdata.json +++ b/tests/pytest/tools/taosdemoAllTest/subInsertdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json b/tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json index 4fb7241012..18487defcc 100644 --- a/tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json +++ b/tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json index 99233bdd73..2c6e6260ff 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdump-insert-dp1.json b/tests/pytest/tools/taosdump-insert-dp1.json index 6481197bd6..a8efd17a9b 100644 --- a/tests/pytest/tools/taosdump-insert-dp1.json +++ b/tests/pytest/tools/taosdump-insert-dp1.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdump-insert-dp2.json b/tests/pytest/tools/taosdump-insert-dp2.json index 384a905c73..14b0c9265f 100644 --- a/tests/pytest/tools/taosdump-insert-dp2.json +++ b/tests/pytest/tools/taosdump-insert-dp2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb1.json b/tests/pytest/tsdb/insertDataDb1.json index 555ae46be3..353c704505 100644 --- a/tests/pytest/tsdb/insertDataDb1.json +++ b/tests/pytest/tsdb/insertDataDb1.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb1Replica2.json b/tests/pytest/tsdb/insertDataDb1Replica2.json index 20ea68cc06..973744c97f 100644 --- a/tests/pytest/tsdb/insertDataDb1Replica2.json +++ b/tests/pytest/tsdb/insertDataDb1Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb2.json b/tests/pytest/tsdb/insertDataDb2.json index 586fb60fcc..78fedb44e4 100644 --- a/tests/pytest/tsdb/insertDataDb2.json +++ b/tests/pytest/tsdb/insertDataDb2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb2Newstab.json b/tests/pytest/tsdb/insertDataDb2Newstab.json index 0558c8c33d..24963aba2c 100644 --- a/tests/pytest/tsdb/insertDataDb2Newstab.json +++ b/tests/pytest/tsdb/insertDataDb2Newstab.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb2NewstabReplica2.json b/tests/pytest/tsdb/insertDataDb2NewstabReplica2.json index 5bc145994d..a6b6b975a2 100644 --- a/tests/pytest/tsdb/insertDataDb2NewstabReplica2.json +++ b/tests/pytest/tsdb/insertDataDb2NewstabReplica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb2Replica2.json b/tests/pytest/tsdb/insertDataDb2Replica2.json index 07bbeaa632..bd97a0ee19 100644 --- a/tests/pytest/tsdb/insertDataDb2Replica2.json +++ b/tests/pytest/tsdb/insertDataDb2Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb1.json b/tests/pytest/wal/insertDataDb1.json index 1b7f757387..1e268faac5 100644 --- a/tests/pytest/wal/insertDataDb1.json +++ b/tests/pytest/wal/insertDataDb1.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb1Replica2.json b/tests/pytest/wal/insertDataDb1Replica2.json index 20ea68cc06..973744c97f 100644 --- a/tests/pytest/wal/insertDataDb1Replica2.json +++ b/tests/pytest/wal/insertDataDb1Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb2.json b/tests/pytest/wal/insertDataDb2.json index 15df1350c8..6743ee0c82 100644 --- a/tests/pytest/wal/insertDataDb2.json +++ b/tests/pytest/wal/insertDataDb2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb2Newstab.json b/tests/pytest/wal/insertDataDb2Newstab.json index 0558c8c33d..24963aba2c 100644 --- a/tests/pytest/wal/insertDataDb2Newstab.json +++ b/tests/pytest/wal/insertDataDb2Newstab.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb2NewstabReplica2.json b/tests/pytest/wal/insertDataDb2NewstabReplica2.json index 5bc145994d..a6b6b975a2 100644 --- a/tests/pytest/wal/insertDataDb2NewstabReplica2.json +++ b/tests/pytest/wal/insertDataDb2NewstabReplica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb2Replica2.json b/tests/pytest/wal/insertDataDb2Replica2.json index 07bbeaa632..bd97a0ee19 100644 --- a/tests/pytest/wal/insertDataDb2Replica2.json +++ b/tests/pytest/wal/insertDataDb2Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/2-query/td_12191.json b/tests/system-test/2-query/td_12191.json index f5d26db40d..daf938a461 100644 --- a/tests/system-test/2-query/td_12191.json +++ b/tests/system-test/2-query/td_12191.json @@ -24,7 +24,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json index 8bd5ddbae8..c3ea89a053 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json index 5408a9841a..b6428b482c 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json index 13eb80f3cf..4a648092cc 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json index 38ac666fac..afe156e18c 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json index 467c54988b..73511dbdd6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseNow.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseNow.json index a09dec21fa..dede88c2df 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseNow.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseNow.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabasecsv.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabasecsv.json index 52e772beca..20998d3392 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabasecsv.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabasecsv.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_no.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_no.json index 759a437b44..b741191303 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_no.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_no.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_yes.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_yes.json index aafc79215f..fa1eb1f7ff 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_yes.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_yes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json index c2e4920097..fc9bb5816d 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json index ad85f9607b..1b726ef5da 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tnt1r.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tnt1r.json index d73719ebe4..f379fe61bf 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tnt1r.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tnt1r.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tntmr.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tntmr.json index e10fd1116b..1420988650 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tntmr.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tntmr.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-allDataType.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-allDataType.json index a7ada9b84e..1e714c0813 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-allDataType.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-allDataType.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese-sml.json index 49407a76d7..3633bb6482 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese-sml.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese.json index ab848b1317..88ace59778 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-disorder.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-disorder.json index d6420b100e..2ae3d6c1ce 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-disorder.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-disorder.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json index 2c3b8c6f81..fc2cf160a4 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json index f8fe21a6c4..39e4b3bbc8 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-illegal.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-illegal.json index c56f8f3040..920eed6456 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-illegal.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-illegal.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-interlace-row.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-interlace-row.json index 93bb92764d..a40c17d1f9 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-interlace-row.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-interlace-row.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-interval-speed.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-interval-speed.json index d51dee428f..ae15b41e4f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-interval-speed.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-interval-speed.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json index 05a6f7606a..4386b7a7ee 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-newtable.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-newtable.json index 02b56bbfe8..a87e257ff9 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-newtable.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-newtable.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-nodbnodrop.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-nodbnodrop.json index 5978e5529f..44707e8748 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-nodbnodrop.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-nodbnodrop.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-offset.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-offset.json index 53edf41072..351a2b38d5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-offset.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-renewdb.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-renewdb.json index 91c033c677..de023d15a2 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-renewdb.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-renewdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-sample-ts.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-sample-ts.json index 344293b555..6d37233b97 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-sample-ts.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-sample-ts.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-sample.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-sample.json index c31099913b..d251dafe4b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-sample.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-sample.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-timestep.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-timestep.json index c794c73c84..059643a851 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-timestep.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-timestep.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151-error.json b/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151-error.json index be55d31d55..7f16fa74ec 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151-error.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151-error.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json b/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json index 67abdc67ee..ffcd49e32e 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertChildTab0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertChildTab0.json index 84aa75eca7..99f89eb7dc 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertChildTab0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertChildTab0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertChildTabLess0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertChildTabLess0.json index 58acd9bbd0..68fa2acf63 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertChildTabLess0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertChildTabLess0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json index ecc62b7251..a96422fc52 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNumLarge4096.json b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNumLarge4096.json index fe6f22527d..18ea19682c 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNumLarge4096.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNumLarge4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsNum0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsNum0.json index 52d6ae029d..867152a603 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsNum0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsNum0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json b/tests/system-test/5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json index 0c82f1d299..aaa5812c49 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertMaxNumPerReq.json b/tests/system-test/5-taos-tools/taosbenchmark/insertMaxNumPerReq.json index 1166ac3643..686a2cc4f1 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertMaxNumPerReq.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertMaxNumPerReq.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json index 8247c5f015..def5043d4f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReqless0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReqless0.json index 138ebbadf6..f1f4b7f3c6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReqless0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReqless0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertRestful.json b/tests/system-test/5-taos-tools/taosbenchmark/insertRestful.json index 682dcf2ce4..cb90c1f898 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertRestful.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertRestful.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json b/tests/system-test/5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json index e8468f5906..8b8f959e05 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertTagsNumLarge128.json b/tests/system-test/5-taos-tools/taosbenchmark/insertTagsNumLarge128.json index 4dbe2940e2..4480cf47d3 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertTagsNumLarge128.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertTagsNumLarge128.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json b/tests/system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json index 65973ccb48..ae82081525 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/manual_block1_comp.json b/tests/system-test/5-taos-tools/taosbenchmark/manual_block1_comp.json index a1a28c9ee9..5c8dc689ae 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/manual_block1_comp.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/manual_block1_comp.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/manual_block2.json b/tests/system-test/5-taos-tools/taosbenchmark/manual_block2.json index 03f6e038fb..c92c18b025 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/manual_block2.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/manual_block2.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json b/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json index 7b8abd6d4e..0f7786e682 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json b/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json index aeee6322e5..f8decfca41 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit1.json b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit1.json index e30b7b0b1c..f166d461fe 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit1.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit1.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit5.json b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit5.json index d4ce2fee46..ebbbc001f9 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit5.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit5.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit94.json b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit94.json index ce12accf06..a18e1e0e1a 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit94.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit94.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-newdb.json b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-newdb.json index 9ffb2953d3..4b246a93d7 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-newdb.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-newdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/query-interrupt.json b/tests/system-test/5-taos-tools/taosbenchmark/query-interrupt.json index 896e484c25..8857d5adae 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/query-interrupt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/query-interrupt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/queryInsertdata.json b/tests/system-test/5-taos-tools/taosbenchmark/queryInsertdata.json index eb196e4096..756316621d 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/queryInsertdata.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/queryInsertdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/queryInsertrestdata.json b/tests/system-test/5-taos-tools/taosbenchmark/queryInsertrestdata.json index 0febbdfa19..0073f52e2b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/queryInsertrestdata.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/queryInsertrestdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json index 5cd06c0275..8e96931e52 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json index 0885e01782..5042549f09 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json index cbd4f6cb59..0de5ddcc26 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json index 6f24801cb0..57006fcc3c 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json index 92e6ec0df7..dcca0f82ae 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json index c09493ec7b..cdfc5cb26d 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interlace-row-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interlace-row-sml.json index e04f2ff5e7..caf9a9466b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interlace-row-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interlace-row-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interval-speed-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interval-speed-sml.json index 4a4227adb8..564f2405e3 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interval-speed-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interval-speed-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json index 1d29842e02..f0a84487d5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json index 886503a950..ac5ba1dc5f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json index ca99d135c5..50af8517bc 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-offset-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-offset-sml.json index d0109b50cf..d79ae2b005 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-offset-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-offset-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json index f8f3a8ee5c..459d47b114 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sample-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sample-sml.json index a778c4860b..af214a2322 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sample-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sample-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-json-alltype.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-json-alltype.json index 66885ebab8..eca27390c6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-json-alltype.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-json-alltype.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-telnet-alltype.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-telnet-alltype.json index c9fa0f6fb0..6c780edd15 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-telnet-alltype.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-telnet-alltype.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json index 4e8ff40cfd..e7704b87fe 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json index 1d496b6b46..1d0490f539 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json index c70db14b4c..723260c422 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json index 12034adc07..ba3586635b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json index 4b27b6b4d0..b96357983d 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTabLess0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTabLess0-sml.json index 8f27feba6b..3e37ca197f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTabLess0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTabLess0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json index 2e4063cf27..38477734e2 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json index 83c08923c4..215d8f052a 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json index 92e88141ca..0804acbae0 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json index 18f1a39e0a..73845c2dc5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json index 01ec546012..b3a113ad38 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json index d950a260f6..33e61b7d20 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json index 0deed5ba54..aff3190e1a 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json index 9d1d1ee718..b9f1195457 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertSigcolumnsNum4096-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertSigcolumnsNum4096-sml.json index e15edfdf44..3db1de723f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertSigcolumnsNum4096-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertSigcolumnsNum4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertTagsNumLarge128-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertTagsNumLarge128-sml.json index 885aafd884..28a7251216 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertTagsNumLarge128-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertTagsNumLarge128-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json index f86eaedd14..98a2dd5ae6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json index be7421cd49..2a056b46e5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-allDataType-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-allDataType-stmt.json index 46a0832612..134e4755b5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-allDataType-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-allDataType-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json index e750180421..bc948974b6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json index 2712f88593..c09d5cfeb3 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json index f8fe21a6c4..39e4b3bbc8 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interlace-row-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interlace-row-stmt.json index 45eb612e6f..4c5e90f185 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interlace-row-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interlace-row-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json index 14fafd60d5..93e41ea575 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json index 622b2554ec..f0ad1b4a5f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json index 31985c8546..15d2753c4b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json index 3ebc377ca7..d636c95a94 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json index adc6fa74be..263a592dfa 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json index 715644f4f0..04165f16b1 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json index e3d6ce850a..cc4d180fb5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json index 344293b555..6d37233b97 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json index 563dc86d0a..ffe16eccd1 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json index f59d2e4e22..37714edc74 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json index 4903335d18..4625da3a6b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json index a27feee68a..8f5b62be9b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTabLess0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTabLess0-stmt.json index 50e1a7173b..a30c3f7c78 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTabLess0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTabLess0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json index ca0d17f93b..2966af8f23 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNumLarge4096-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNumLarge4096-stmt.json index c5a3a5f76d..40780dd992 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNumLarge4096-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNumLarge4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsNum0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsNum0-stmt.json index c86e759db4..cada61687e 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsNum0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsNum0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json index ee36b62f90..87386853b3 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertMaxNumPerReq-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertMaxNumPerReq-stmt.json index 25086c856e..9e213b52a4 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertMaxNumPerReq-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertMaxNumPerReq-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json index 4bd071ec15..5b4bfbae65 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json index 628c86045f..efc01bb9e6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json index 7abab6a0cf..e622415977 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertTagsNumLarge128-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertTagsNumLarge128-stmt.json index 8f8539be21..51ac878c37 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertTagsNumLarge128-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertTagsNumLarge128-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/subInsertdata.json b/tests/system-test/5-taos-tools/taosbenchmark/subInsertdata.json index 168b3753a1..57e823f74a 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/subInsertdata.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/subInsertdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json b/tests/system-test/5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json index 4fb7241012..18487defcc 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json b/tests/system-test/5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json index 99233bdd73..2c6e6260ff 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, -- GitLab From 4d0c7977c1de6575f53c703ef43fb579ea6f0dcf Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sun, 31 Jul 2022 15:20:55 +0000 Subject: [PATCH 270/380] fix: for taosdemo --- tests/pytest/perfbenchmark/bug3433.py | 1 - tests/pytest/query/query1970YearsAf.py | 1 - tests/pytest/tools/insert.json | 3 +-- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/pytest/perfbenchmark/bug3433.py b/tests/pytest/perfbenchmark/bug3433.py index 2f17e0bd3a..dbf7b9ad9e 100644 --- a/tests/pytest/perfbenchmark/bug3433.py +++ b/tests/pytest/perfbenchmark/bug3433.py @@ -74,7 +74,6 @@ class TDTestCase: "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/pytest/query/query1970YearsAf.py b/tests/pytest/query/query1970YearsAf.py index a365369b21..62b435fbef 100644 --- a/tests/pytest/query/query1970YearsAf.py +++ b/tests/pytest/query/query1970YearsAf.py @@ -65,7 +65,6 @@ class TDTestCase: "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/pytest/tools/insert.json b/tests/pytest/tools/insert.json index 996b91ed06..eacbb590f5 100644 --- a/tests/pytest/tools/insert.json +++ b/tests/pytest/tools/insert.json @@ -17,8 +17,7 @@ "cache": 16, "blocks": 8, "precision": "ms", - "update": 0, - "maxtablesPerVnode": 1000 + "update": 0 }, "super_tables": [{ "name": "stb01", -- GitLab From fd27faa3a04d58d5badb1c17bc451b8ff3739b32 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sun, 31 Jul 2022 23:58:36 +0800 Subject: [PATCH 271/380] feat: update taostools for2.6 (#15616) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- .../5-taos-tools/taosbenchmark/json/custom_col_tag.json | 3 +-- .../taosbenchmark/json/rest_auto_create_table.json | 3 +-- .../5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_auto_create_table.json | 3 +-- .../5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_interlace.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_json_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_rest_json.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_rest_line.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_rest_telnet.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json | 1 - .../taosbenchmark/json/stmt_auto_create_table.json | 3 +-- .../5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json | 1 - .../taosbenchmark/json/taosc_auto_create_table.json | 1 - .../5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json | 1 - .../5-taos-tools/taosbenchmark/json/taosc_json_tag.json | 1 - .../5-taos-tools/taosbenchmark/json/taosc_limit_offset.json | 1 - .../taosbenchmark/json/taosc_only_create_table.json | 3 +-- .../5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json | 1 - tests/pytest/cluster/TD-3693/insert1Data.json | 1 - tests/pytest/cluster/TD-3693/insert2Data.json | 1 - tests/pytest/compress/insertDataDb1.json | 1 - tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json | 1 - tests/pytest/perfbenchmark/bug3433.py | 1 - tests/pytest/query/nestedQuery/insertData.json | 1 - tests/pytest/query/query1970YearsAf.py | 1 - tests/pytest/tools/insert-interlace.json | 1 - tests/pytest/tools/insert-tblimit-tboffset-createdb.json | 1 - tests/pytest/tools/insert-tblimit-tboffset-insertrec.json | 1 - tests/pytest/tools/insert-tblimit-tboffset.json | 1 - tests/pytest/tools/insert-tblimit-tboffset0.json | 1 - tests/pytest/tools/insert-tblimit1-tboffset.json | 1 - tests/pytest/tools/insert.json | 3 +-- .../tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json | 1 - .../taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json | 1 - .../tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json | 1 - .../taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabaseNow.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabasecsv.json | 1 - .../tools/taosdemoAllTest/TD-4985/query-limit-offset.json | 1 - .../tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-allDataType.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-chinese.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-disorder.json | 1 - .../tools/taosdemoAllTest/insert-drop-exist-auto-N00.json | 1 - .../tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-illegal.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-newdb.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-newtable.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-offset.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-renewdb.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-sample.json | 1 - tests/pytest/tools/taosdemoAllTest/insert-timestep.json | 1 - .../insertBinaryLenLarge16374AllcolLar49151-error.json | 1 - .../insertBinaryLenLarge16374AllcolLar49151.json | 1 - tests/pytest/tools/taosdemoAllTest/insertChildTab0.json | 1 - tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json | 1 - .../tools/taosdemoAllTest/insertColumnsAndTagNum4096.json | 1 - .../tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json | 1 - tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json | 1 - .../tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json | 1 - tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json | 1 - .../pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json | 1 - .../tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json | 1 - tests/pytest/tools/taosdemoAllTest/insertRestful.json | 1 - .../pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json | 1 - tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json | 1 - tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json | 1 - tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json | 1 - tests/pytest/tools/taosdemoAllTest/manual_block2.json | 1 - .../pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json | 1 - .../pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json | 1 - tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json | 1 - tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json | 1 - .../pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json | 1 - tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json | 1 - tests/pytest/tools/taosdemoAllTest/query-interrupt.json | 1 - tests/pytest/tools/taosdemoAllTest/queryInsertdata.json | 1 - tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json | 1 - .../tools/taosdemoAllTest/sml/insert-allDataType-sml.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json | 1 - .../taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json | 1 - .../taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json | 1 - .../tools/taosdemoAllTest/sml/insert-interlace-row-sml.json | 1 - .../tools/taosdemoAllTest/sml/insert-interval-speed-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json | 1 - .../tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json | 1 - tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json | 1 - .../tools/taosdemoAllTest/sml/insert-sml-json-alltype.json | 1 - .../tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json | 1 - .../sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json | 1 - .../sml/insertBinaryLenLarge16374AllcolLar49151-sml.json | 1 - .../pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json | 1 - .../tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json | 1 - .../taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json | 1 - .../sml/insertColumnsAndTagNumLarge4096-sml.json | 1 - .../tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json | 1 - .../taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json | 1 - .../taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json | 1 - .../tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json | 1 - .../taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json | 1 - .../taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json | 1 - .../tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json | 1 - .../tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json | 1 - .../tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-disorder-stmt.json | 1 - .../taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json | 1 - .../taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json | 1 - tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-newtable-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json | 1 - .../pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insert-timestep-stmt.json | 1 - .../insertBinaryLenLarge16374AllcolLar49151-error-stmt.json | 1 - .../stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json | 1 - .../taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json | 1 - .../stmt/insertColumnsAndTagNumLarge4096-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json | 1 - .../taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json | 1 - .../taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json | 1 - .../stmt/insertNumOfrecordPerReqless0-stmt.json | 1 - .../taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json | 1 - .../tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json | 1 - tests/pytest/tools/taosdemoAllTest/subInsertdata.json | 1 - tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json | 1 - tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json | 1 - tests/pytest/tools/taosdump-insert-dp1.json | 1 - tests/pytest/tools/taosdump-insert-dp2.json | 1 - tests/pytest/tsdb/insertDataDb1.json | 1 - tests/pytest/tsdb/insertDataDb1Replica2.json | 1 - tests/pytest/tsdb/insertDataDb2.json | 1 - tests/pytest/tsdb/insertDataDb2Newstab.json | 1 - tests/pytest/tsdb/insertDataDb2NewstabReplica2.json | 1 - tests/pytest/tsdb/insertDataDb2Replica2.json | 1 - tests/pytest/wal/insertDataDb1.json | 1 - tests/pytest/wal/insertDataDb1Replica2.json | 1 - tests/pytest/wal/insertDataDb2.json | 1 - tests/pytest/wal/insertDataDb2Newstab.json | 1 - tests/pytest/wal/insertDataDb2NewstabReplica2.json | 1 - tests/pytest/wal/insertDataDb2Replica2.json | 1 - tests/system-test/2-query/td_12191.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json | 1 - .../taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabaseNow.json | 1 - .../NanoTestCase/taosdemoTestNanoDatabasecsv.json | 1 - .../taosbenchmark/TD-10539/create_taosdemo_no.json | 1 - .../taosbenchmark/TD-10539/create_taosdemo_yes.json | 1 - .../5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json | 1 - .../5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json | 1 - .../5-taos-tools/taosbenchmark/insert-1s1tnt1r.json | 1 - .../5-taos-tools/taosbenchmark/insert-1s1tntmr.json | 1 - .../5-taos-tools/taosbenchmark/insert-allDataType.json | 1 - .../5-taos-tools/taosbenchmark/insert-chinese-sml.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-chinese.json | 1 - .../5-taos-tools/taosbenchmark/insert-disorder.json | 1 - .../5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json | 1 - .../5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-illegal.json | 1 - .../5-taos-tools/taosbenchmark/insert-interlace-row.json | 1 - .../5-taos-tools/taosbenchmark/insert-interval-speed.json | 1 - tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json | 1 - .../5-taos-tools/taosbenchmark/insert-newtable.json | 1 - .../5-taos-tools/taosbenchmark/insert-nodbnodrop.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-offset.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-renewdb.json | 1 - .../5-taos-tools/taosbenchmark/insert-sample-ts.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert-sample.json | 1 - .../5-taos-tools/taosbenchmark/insert-timestep.json | 1 - .../insertBinaryLenLarge16374AllcolLar49151-error.json | 1 - .../taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json | 1 - .../5-taos-tools/taosbenchmark/insertChildTab0.json | 1 - .../5-taos-tools/taosbenchmark/insertChildTabLess0.json | 1 - .../5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json | 1 - .../taosbenchmark/insertColumnsAndTagNumLarge4096.json | 1 - .../5-taos-tools/taosbenchmark/insertColumnsNum0.json | 1 - .../5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json | 1 - .../5-taos-tools/taosbenchmark/insertMaxNumPerReq.json | 1 - .../5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json | 1 - .../taosbenchmark/insertNumOfrecordPerReqless0.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insertRestful.json | 1 - .../5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json | 1 - .../5-taos-tools/taosbenchmark/insertTagsNumLarge128.json | 1 - .../system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json | 1 - .../5-taos-tools/taosbenchmark/manual_block1_comp.json | 1 - .../system-test/5-taos-tools/taosbenchmark/manual_block2.json | 1 - .../5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json | 1 - .../5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json | 1 - .../5-taos-tools/taosbenchmark/moredemo-offset-limit1.json | 1 - .../5-taos-tools/taosbenchmark/moredemo-offset-limit5.json | 1 - .../5-taos-tools/taosbenchmark/moredemo-offset-limit94.json | 1 - .../5-taos-tools/taosbenchmark/moredemo-offset-newdb.json | 1 - .../5-taos-tools/taosbenchmark/query-interrupt.json | 1 - .../5-taos-tools/taosbenchmark/queryInsertdata.json | 1 - .../5-taos-tools/taosbenchmark/queryInsertrestdata.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json | 1 - .../taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json | 1 - .../taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json | 1 - .../taosbenchmark/sml/insert-interlace-row-sml.json | 1 - .../taosbenchmark/sml/insert-interval-speed-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-offset-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-sample-sml.json | 1 - .../taosbenchmark/sml/insert-sml-json-alltype.json | 1 - .../taosbenchmark/sml/insert-sml-telnet-alltype.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json | 1 - .../5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json | 1 - .../sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json | 1 - .../sml/insertBinaryLenLarge16374AllcolLar49151-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json | 1 - .../taosbenchmark/sml/insertChildTabLess0-sml.json | 1 - .../taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json | 1 - .../taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json | 1 - .../5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json | 1 - .../taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json | 1 - .../taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json | 1 - .../5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json | 1 - .../taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json | 1 - .../taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json | 1 - .../taosbenchmark/sml/insertSigcolumnsNum4096-sml.json | 1 - .../taosbenchmark/sml/insertTagsNumLarge128-sml.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json | 1 - .../taosbenchmark/stmt/insert-allDataType-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json | 1 - .../taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json | 1 - .../taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json | 1 - .../taosbenchmark/stmt/insert-interlace-row-stmt.json | 1 - .../taosbenchmark/stmt/insert-interval-speed-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json | 1 - .../taosbenchmark/stmt/insert-nodbnodrop-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json | 1 - .../insertBinaryLenLarge16374AllcolLar49151-error-stmt.json | 1 - .../stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json | 1 - .../5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json | 1 - .../taosbenchmark/stmt/insertChildTabLess0-stmt.json | 1 - .../taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json | 1 - .../stmt/insertColumnsAndTagNumLarge4096-stmt.json | 1 - .../taosbenchmark/stmt/insertColumnsNum0-stmt.json | 1 - .../taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json | 1 - .../taosbenchmark/stmt/insertMaxNumPerReq-stmt.json | 1 - .../taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json | 1 - .../taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json | 1 - .../taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json | 1 - .../taosbenchmark/stmt/insertTagsNumLarge128-stmt.json | 1 - .../system-test/5-taos-tools/taosbenchmark/subInsertdata.json | 1 - .../5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json | 1 - .../5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json | 1 - 288 files changed, 7 insertions(+), 294 deletions(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 9dc2fec5e2..f4e456a15f 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 9dc2fec5e2cb96a998feef7d8ed22bdba0bf9141 +Subproject commit f4e456a15f30814182b3c2834bfe591c10a745af diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/custom_col_tag.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/custom_col_tag.json index 8f652b9d73..6558212816 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/custom_col_tag.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/custom_col_tag.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, @@ -88,4 +87,4 @@ }] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json index a4706bf47d..cebabf95b6 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_auto_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, @@ -84,4 +83,4 @@ "tags": [{"type": "TIMESTAMP"},{"type": "INT"}, {"type": "BIGINT"}, {"type": "FLOAT"}, {"type": "DOUBLE"}, {"type": "SMALLINT"}, {"type": "TINYINT"}, {"type": "BOOL"}, {"type": "NCHAR","len": 17, "count":1}, {"type": "UINT"}, {"type": "UBIGINT"}, {"type": "UTINYINT"}, {"type": "USMALLINT"}, {"type": "BINARY", "len": 19, "count":1}] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json index 01e3950502..0a10458283 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/rest_insert_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json index 62846bf2b6..5cbd67e154 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_auto_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, @@ -84,4 +83,4 @@ "tags": [{"type": "INT"}, {"type": "BIGINT"}, {"type": "FLOAT"}, {"type": "DOUBLE"}, {"type": "SMALLINT"}, {"type": "TINYINT"}, {"type": "BOOL"}, {"type": "NCHAR","len": 17, "count":1}, {"type": "UINT"}, {"type": "UBIGINT"}, {"type": "UTINYINT"}, {"type": "USMALLINT"}, {"type": "BINARY", "len": 19, "count":1}] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json index 8722d124d6..0cf1526041 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_insert_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_interlace.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_interlace.json index 1aa5b09348..a0eec1c9af 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_interlace.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_interlace.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_json_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_json_alltypes.json index 8806b52a1e..4e7f6472f6 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_json_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_json_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_json.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_json.json index 1e9e28d4e8..2737f6e631 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_json.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_json.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_line.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_line.json index deef77fdef..f19f3734ef 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_line.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_line.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_telnet.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_telnet.json index 8893a73467..f083782c07 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_telnet.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_rest_telnet.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json index 0bf363e673..9c590ae83c 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json index 84419760c1..60af5dfe54 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/sml_telnet_tcp.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json index 2e5965c14b..5d74e960e2 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_auto_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, @@ -84,4 +83,4 @@ "tags": [{"type": "TIMESTAMP"},{"type": "INT"}, {"type": "BIGINT"}, {"type": "FLOAT"}, {"type": "DOUBLE"}, {"type": "SMALLINT"}, {"type": "TINYINT"}, {"type": "BOOL"}, {"type": "NCHAR","len": 17, "count":1}, {"type": "UINT"}, {"type": "UBIGINT"}, {"type": "UTINYINT"}, {"type": "USMALLINT"}, {"type": "BINARY", "len": 19, "count":1}] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json index 48f4e23166..f7266ee71f 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/stmt_insert_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json index 06c5be47bf..ba7660658f 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_auto_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json index 1bb03b4fab..62685eb3c7 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_insert_alltypes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_json_tag.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_json_tag.json index 893b203aa8..ef0b1d2784 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_json_tag.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_json_tag.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_limit_offset.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_limit_offset.json index b0e903347d..546885db7d 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_limit_offset.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_limit_offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_only_create_table.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_only_create_table.json index 4d42ed63fa..5869410c03 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_only_create_table.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_only_create_table.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":1, "quorum":1, "fsync":3000, @@ -59,4 +58,4 @@ "tags": [{"type": "TIMESTAMP"},{"type": "INT"}, {"type": "BIGINT"}, {"type": "FLOAT"}, {"type": "DOUBLE"}, {"type": "SMALLINT"}, {"type": "TINYINT"}, {"type": "BOOL"}, {"type": "NCHAR"}, {"type": "UINT"}, {"type": "UBIGINT"}, {"type": "UTINYINT"}, {"type": "USMALLINT"}, {"type": "BINARY"}] }] }] -} \ No newline at end of file +} diff --git a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json index 22bd13d5be..d9eb17ea1f 100644 --- a/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json +++ b/tests/develop-test/5-taos-tools/taosbenchmark/json/taosc_sample_use_ts.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/cluster/TD-3693/insert1Data.json b/tests/pytest/cluster/TD-3693/insert1Data.json index 3ac289a63a..43aa789e48 100644 --- a/tests/pytest/cluster/TD-3693/insert1Data.json +++ b/tests/pytest/cluster/TD-3693/insert1Data.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/cluster/TD-3693/insert2Data.json b/tests/pytest/cluster/TD-3693/insert2Data.json index 25717df4c7..e2c3171798 100644 --- a/tests/pytest/cluster/TD-3693/insert2Data.json +++ b/tests/pytest/cluster/TD-3693/insert2Data.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/compress/insertDataDb1.json b/tests/pytest/compress/insertDataDb1.json index 65cec71a65..67006c4d1f 100644 --- a/tests/pytest/compress/insertDataDb1.json +++ b/tests/pytest/compress/insertDataDb1.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json b/tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json index 4f32b700d8..14cc984861 100644 --- a/tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json +++ b/tests/pytest/manualTest/TD-5114/insertDataDb3Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/perfbenchmark/bug3433.py b/tests/pytest/perfbenchmark/bug3433.py index 2f17e0bd3a..dbf7b9ad9e 100644 --- a/tests/pytest/perfbenchmark/bug3433.py +++ b/tests/pytest/perfbenchmark/bug3433.py @@ -74,7 +74,6 @@ class TDTestCase: "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/pytest/query/nestedQuery/insertData.json b/tests/pytest/query/nestedQuery/insertData.json index 149a4b56ac..1518da8c9d 100644 --- a/tests/pytest/query/nestedQuery/insertData.json +++ b/tests/pytest/query/nestedQuery/insertData.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/query/query1970YearsAf.py b/tests/pytest/query/query1970YearsAf.py index a365369b21..62b435fbef 100644 --- a/tests/pytest/query/query1970YearsAf.py +++ b/tests/pytest/query/query1970YearsAf.py @@ -65,7 +65,6 @@ class TDTestCase: "minRows": 100, "maxRows": 4096, "comp": 2, - "walLevel": 1, "cachelast": 0, "quorum": 1, "fsync": 3000, diff --git a/tests/pytest/tools/insert-interlace.json b/tests/pytest/tools/insert-interlace.json index cd72958115..85cb2dcfce 100644 --- a/tests/pytest/tools/insert-interlace.json +++ b/tests/pytest/tools/insert-interlace.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit-tboffset-createdb.json b/tests/pytest/tools/insert-tblimit-tboffset-createdb.json index 025751bcd3..f5dad7a69d 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset-createdb.json +++ b/tests/pytest/tools/insert-tblimit-tboffset-createdb.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json b/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json index 6fa020433a..c013f616b1 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json +++ b/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit-tboffset.json b/tests/pytest/tools/insert-tblimit-tboffset.json index b4d4016ef9..5f8770070a 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset.json +++ b/tests/pytest/tools/insert-tblimit-tboffset.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit-tboffset0.json b/tests/pytest/tools/insert-tblimit-tboffset0.json index 8a7e39b17c..cbf5e78dff 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset0.json +++ b/tests/pytest/tools/insert-tblimit-tboffset0.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert-tblimit1-tboffset.json b/tests/pytest/tools/insert-tblimit1-tboffset.json index 6e150203b3..bef719c5ee 100644 --- a/tests/pytest/tools/insert-tblimit1-tboffset.json +++ b/tests/pytest/tools/insert-tblimit1-tboffset.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/insert.json b/tests/pytest/tools/insert.json index 996b91ed06..eacbb590f5 100644 --- a/tests/pytest/tools/insert.json +++ b/tests/pytest/tools/insert.json @@ -17,8 +17,7 @@ "cache": 16, "blocks": 8, "precision": "ms", - "update": 0, - "maxtablesPerVnode": 1000 + "update": 0 }, "super_tables": [{ "name": "stb01", diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json index 8bd5ddbae8..c3ea89a053 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertMSDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json index 5408a9841a..b6428b482c 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertNanoDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json index 13eb80f3cf..4a648092cc 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoInsertUSDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json index 38ac666fac..afe156e18c 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabase.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json index 9ef4a0af66..ac2fbb39b7 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseNow.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseNow.json index a09dec21fa..dede88c2df 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseNow.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabaseNow.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabasecsv.json b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabasecsv.json index e99c528c6d..cc696518bf 100644 --- a/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabasecsv.json +++ b/tests/pytest/tools/taosdemoAllTest/NanoTestCase/taosdemoTestNanoDatabasecsv.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/TD-4985/query-limit-offset.json b/tests/pytest/tools/taosdemoAllTest/TD-4985/query-limit-offset.json index ad85f9607b..1b726ef5da 100644 --- a/tests/pytest/tools/taosdemoAllTest/TD-4985/query-limit-offset.json +++ b/tests/pytest/tools/taosdemoAllTest/TD-4985/query-limit-offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json index d6e3afdea3..9f79c1ae23 100755 --- a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json +++ b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json b/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json index d73719ebe4..f379fe61bf 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json b/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json index e10fd1116b..1420988650 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-allDataType.json b/tests/pytest/tools/taosdemoAllTest/insert-allDataType.json index a7ada9b84e..1e714c0813 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-allDataType.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-allDataType.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json b/tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json index 49407a76d7..3633bb6482 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-chinese-sml.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-chinese.json b/tests/pytest/tools/taosdemoAllTest/insert-chinese.json index ab848b1317..88ace59778 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-chinese.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-chinese.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-disorder.json b/tests/pytest/tools/taosdemoAllTest/insert-disorder.json index d6420b100e..2ae3d6c1ce 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-disorder.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-disorder.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-N00.json b/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-N00.json index 2c3b8c6f81..fc2cf160a4 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-N00.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-N00.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json b/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json index f8fe21a6c4..39e4b3bbc8 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-drop-exist-auto-Y00.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-illegal.json b/tests/pytest/tools/taosdemoAllTest/insert-illegal.json index c56f8f3040..920eed6456 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-illegal.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-illegal.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json b/tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json index 93bb92764d..a40c17d1f9 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-interlace-row.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json b/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json index d51dee428f..ae15b41e4f 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-newdb.json b/tests/pytest/tools/taosdemoAllTest/insert-newdb.json index 05a6f7606a..4386b7a7ee 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-newdb.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-newdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-newtable.json b/tests/pytest/tools/taosdemoAllTest/insert-newtable.json index 02b56bbfe8..a87e257ff9 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-newtable.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-newtable.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json b/tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json index 5978e5529f..44707e8748 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-nodbnodrop.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-offset.json b/tests/pytest/tools/taosdemoAllTest/insert-offset.json index 53edf41072..351a2b38d5 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-offset.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-renewdb.json b/tests/pytest/tools/taosdemoAllTest/insert-renewdb.json index 91c033c677..de023d15a2 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-renewdb.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-renewdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json b/tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json index b14c3a8ec6..d63549b79b 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-sample-ts.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-sample.json b/tests/pytest/tools/taosdemoAllTest/insert-sample.json index 87d442b7cb..d41433ff0c 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-sample.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-sample.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-timestep.json b/tests/pytest/tools/taosdemoAllTest/insert-timestep.json index c794c73c84..059643a851 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-timestep.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-timestep.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151-error.json b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151-error.json index be55d31d55..7f16fa74ec 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151-error.json +++ b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151-error.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151.json b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151.json index 67abdc67ee..ffcd49e32e 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151.json +++ b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar49151.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json b/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json index 84aa75eca7..99f89eb7dc 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json b/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json index 58acd9bbd0..68fa2acf63 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum4096.json b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum4096.json index 17153c2f2c..4cd6e3ceb5 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum4096.json +++ b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json index 59cbedca72..04d32a3e79 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json +++ b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json b/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json index 52d6ae029d..867152a603 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json b/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json index 60a10d2501..0f4952074d 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json +++ b/tests/pytest/tools/taosdemoAllTest/insertInterlaceRowsLarge1M.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json b/tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json index 1166ac3643..686a2cc4f1 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json +++ b/tests/pytest/tools/taosdemoAllTest/insertMaxNumPerReq.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json index 8247c5f015..def5043d4f 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json index 138ebbadf6..f1f4b7f3c6 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertRestful.json b/tests/pytest/tools/taosdemoAllTest/insertRestful.json index 682dcf2ce4..cb90c1f898 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertRestful.json +++ b/tests/pytest/tools/taosdemoAllTest/insertRestful.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json b/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json index e8468f5906..8b8f959e05 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json +++ b/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json b/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json index 4dbe2940e2..4480cf47d3 100644 --- a/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json +++ b/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json b/tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json index 65973ccb48..ae82081525 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json +++ b/tests/pytest/tools/taosdemoAllTest/insert_5M_rows.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json b/tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json index a1a28c9ee9..5c8dc689ae 100644 --- a/tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json +++ b/tests/pytest/tools/taosdemoAllTest/manual_block1_comp.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/manual_block2.json b/tests/pytest/tools/taosdemoAllTest/manual_block2.json index 03f6e038fb..c92c18b025 100644 --- a/tests/pytest/tools/taosdemoAllTest/manual_block2.json +++ b/tests/pytest/tools/taosdemoAllTest/manual_block2.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json b/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json index 7b8abd6d4e..0f7786e682 100644 --- a/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json +++ b/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_A.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json b/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json index aeee6322e5..f8decfca41 100644 --- a/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json +++ b/tests/pytest/tools/taosdemoAllTest/manual_change_time_1_1_B.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json index e30b7b0b1c..f166d461fe 100644 --- a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json +++ b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit1.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json index d4ce2fee46..ebbbc001f9 100644 --- a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json +++ b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit5.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json index ce12accf06..a18e1e0e1a 100644 --- a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json +++ b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-limit94.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json index 9ffb2953d3..4b246a93d7 100644 --- a/tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json +++ b/tests/pytest/tools/taosdemoAllTest/moredemo-offset-newdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/query-interrupt.json b/tests/pytest/tools/taosdemoAllTest/query-interrupt.json index 896e484c25..8857d5adae 100644 --- a/tests/pytest/tools/taosdemoAllTest/query-interrupt.json +++ b/tests/pytest/tools/taosdemoAllTest/query-interrupt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/queryInsertdata.json b/tests/pytest/tools/taosdemoAllTest/queryInsertdata.json index eb196e4096..756316621d 100644 --- a/tests/pytest/tools/taosdemoAllTest/queryInsertdata.json +++ b/tests/pytest/tools/taosdemoAllTest/queryInsertdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json b/tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json index 0febbdfa19..0073f52e2b 100644 --- a/tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json +++ b/tests/pytest/tools/taosdemoAllTest/queryInsertrestdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json index 5cd06c0275..8e96931e52 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tnt1r-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json index 0885e01782..5042549f09 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-1s1tntmr-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-allDataType-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-allDataType-sml.json index cbd4f6cb59..0de5ddcc26 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-allDataType-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-allDataType-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json index 6f24801cb0..57006fcc3c 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-disorder-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json index 92e6ec0df7..dcca0f82ae 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-N00-sml.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json index c09493ec7b..cdfc5cb26d 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-drop-exist-auto-Y00-sml.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-interlace-row-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-interlace-row-sml.json index e04f2ff5e7..caf9a9466b 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-interlace-row-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-interlace-row-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-interval-speed-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-interval-speed-sml.json index 4a4227adb8..564f2405e3 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-interval-speed-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-interval-speed-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json index 1d29842e02..f0a84487d5 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-newdb-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json index 886503a950..ac5ba1dc5f 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-newtable-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json index ca99d135c5..50af8517bc 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-nodbnodrop-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json index d0109b50cf..d79ae2b005 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-offset-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json index f8f3a8ee5c..459d47b114 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-renewdb-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json index 780fd60bb7..35c808bd58 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-sample-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-json-alltype.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-json-alltype.json index 66885ebab8..eca27390c6 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-json-alltype.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-json-alltype.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json index c9fa0f6fb0..6c780edd15 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-telnet-alltype.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json index 4e8ff40cfd..e7704b87fe 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-sml-timestamp.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json index 1d496b6b46..1d0490f539 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insert-timestep-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json index c70db14b4c..723260c422 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json index 12034adc07..ba3586635b 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json index 28f566833f..85ff34b99d 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertChildTab0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json index 8f27feba6b..3e37ca197f 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertChildTabLess0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json index 2e4063cf27..38477734e2 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNum4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNumLarge4096-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNumLarge4096-sml.json index c6fe0300f5..63ff800812 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNumLarge4096-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsAndTagNumLarge4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json index 92e88141ca..0804acbae0 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertColumnsNum0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json index 18f1a39e0a..73845c2dc5 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertInterlaceRowsLarge1M-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json b/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json index 01ec546012..b3a113ad38 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml-telnet.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json index d950a260f6..33e61b7d20 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertMaxNumPerReq-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json index 0deed5ba54..aff3190e1a 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReq0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json index 9d1d1ee718..b9f1195457 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertNumOfrecordPerReqless0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json index f732d2e0c5..e302d619c4 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertSigcolumnsNum4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json b/tests/pytest/tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json index 24f468d719..a692e4ef6f 100644 --- a/tests/pytest/tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json +++ b/tests/pytest/tools/taosdemoAllTest/sml/insertTagsNumLarge128-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json index adb8764b2f..eaca2e040f 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tnt1r-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json index b21154f1c5..8f7d0d2e80 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-1s1tntmr-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json index 46a0832612..134e4755b5 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-allDataType-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-disorder-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-disorder-stmt.json index e750180421..bc948974b6 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-disorder-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-disorder-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json index 2712f88593..c09d5cfeb3 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-N00-stmt.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json index f8fe21a6c4..39e4b3bbc8 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-drop-exist-auto-Y00-stmt.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json index 45eb612e6f..4c5e90f185 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-interlace-row-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json index 4e6edb2199..c8c9684474 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-interval-speed-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json index 622b2554ec..f0ad1b4a5f 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-newdb-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-newtable-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-newtable-stmt.json index 31985c8546..15d2753c4b 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-newtable-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-newtable-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json index 3ebc377ca7..d636c95a94 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-nodbnodrop-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json index adc6fa74be..263a592dfa 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-offset-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json index 715644f4f0..04165f16b1 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-renewdb-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json index e3d6ce850a..cc4d180fb5 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json index b14c3a8ec6..d63549b79b 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-sample-ts-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insert-timestep-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insert-timestep-stmt.json index 563dc86d0a..ffe16eccd1 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insert-timestep-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insert-timestep-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json index f59d2e4e22..37714edc74 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json index 4903335d18..4625da3a6b 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json index a27feee68a..8f5b62be9b 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTab0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json index 50e1a7173b..a30c3f7c78 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertChildTabLess0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json index ca0d17f93b..2966af8f23 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNum4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNumLarge4096-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNumLarge4096-stmt.json index c5a3a5f76d..40780dd992 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNumLarge4096-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsAndTagNumLarge4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json index c86e759db4..cada61687e 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertColumnsNum0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json index ee36b62f90..87386853b3 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertInterlaceRowsLarge1M-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json index 25086c856e..9e213b52a4 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertMaxNumPerReq-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json index 4bd071ec15..5b4bfbae65 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReq0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReqless0-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReqless0-stmt.json index 628c86045f..efc01bb9e6 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReqless0-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertNumOfrecordPerReqless0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json index 7abab6a0cf..e622415977 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertSigcolumnsNum4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json b/tests/pytest/tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json index 8f8539be21..51ac878c37 100644 --- a/tests/pytest/tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json +++ b/tests/pytest/tools/taosdemoAllTest/stmt/insertTagsNumLarge128-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/subInsertdata.json b/tests/pytest/tools/taosdemoAllTest/subInsertdata.json index 168b3753a1..57e823f74a 100644 --- a/tests/pytest/tools/taosdemoAllTest/subInsertdata.json +++ b/tests/pytest/tools/taosdemoAllTest/subInsertdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json b/tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json index 4fb7241012..18487defcc 100644 --- a/tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json +++ b/tests/pytest/tools/taosdemoAllTest/subInsertdataMaxsql100.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json index 99233bdd73..2c6e6260ff 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoInsertNanoDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdump-insert-dp1.json b/tests/pytest/tools/taosdump-insert-dp1.json index 6481197bd6..a8efd17a9b 100644 --- a/tests/pytest/tools/taosdump-insert-dp1.json +++ b/tests/pytest/tools/taosdump-insert-dp1.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tools/taosdump-insert-dp2.json b/tests/pytest/tools/taosdump-insert-dp2.json index 384a905c73..14b0c9265f 100644 --- a/tests/pytest/tools/taosdump-insert-dp2.json +++ b/tests/pytest/tools/taosdump-insert-dp2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb1.json b/tests/pytest/tsdb/insertDataDb1.json index 555ae46be3..353c704505 100644 --- a/tests/pytest/tsdb/insertDataDb1.json +++ b/tests/pytest/tsdb/insertDataDb1.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb1Replica2.json b/tests/pytest/tsdb/insertDataDb1Replica2.json index 20ea68cc06..973744c97f 100644 --- a/tests/pytest/tsdb/insertDataDb1Replica2.json +++ b/tests/pytest/tsdb/insertDataDb1Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb2.json b/tests/pytest/tsdb/insertDataDb2.json index 586fb60fcc..78fedb44e4 100644 --- a/tests/pytest/tsdb/insertDataDb2.json +++ b/tests/pytest/tsdb/insertDataDb2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb2Newstab.json b/tests/pytest/tsdb/insertDataDb2Newstab.json index 0558c8c33d..24963aba2c 100644 --- a/tests/pytest/tsdb/insertDataDb2Newstab.json +++ b/tests/pytest/tsdb/insertDataDb2Newstab.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb2NewstabReplica2.json b/tests/pytest/tsdb/insertDataDb2NewstabReplica2.json index 5bc145994d..a6b6b975a2 100644 --- a/tests/pytest/tsdb/insertDataDb2NewstabReplica2.json +++ b/tests/pytest/tsdb/insertDataDb2NewstabReplica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/tsdb/insertDataDb2Replica2.json b/tests/pytest/tsdb/insertDataDb2Replica2.json index 07bbeaa632..bd97a0ee19 100644 --- a/tests/pytest/tsdb/insertDataDb2Replica2.json +++ b/tests/pytest/tsdb/insertDataDb2Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb1.json b/tests/pytest/wal/insertDataDb1.json index 1b7f757387..1e268faac5 100644 --- a/tests/pytest/wal/insertDataDb1.json +++ b/tests/pytest/wal/insertDataDb1.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb1Replica2.json b/tests/pytest/wal/insertDataDb1Replica2.json index 20ea68cc06..973744c97f 100644 --- a/tests/pytest/wal/insertDataDb1Replica2.json +++ b/tests/pytest/wal/insertDataDb1Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb2.json b/tests/pytest/wal/insertDataDb2.json index 15df1350c8..6743ee0c82 100644 --- a/tests/pytest/wal/insertDataDb2.json +++ b/tests/pytest/wal/insertDataDb2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb2Newstab.json b/tests/pytest/wal/insertDataDb2Newstab.json index 0558c8c33d..24963aba2c 100644 --- a/tests/pytest/wal/insertDataDb2Newstab.json +++ b/tests/pytest/wal/insertDataDb2Newstab.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb2NewstabReplica2.json b/tests/pytest/wal/insertDataDb2NewstabReplica2.json index 5bc145994d..a6b6b975a2 100644 --- a/tests/pytest/wal/insertDataDb2NewstabReplica2.json +++ b/tests/pytest/wal/insertDataDb2NewstabReplica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/pytest/wal/insertDataDb2Replica2.json b/tests/pytest/wal/insertDataDb2Replica2.json index 07bbeaa632..bd97a0ee19 100644 --- a/tests/pytest/wal/insertDataDb2Replica2.json +++ b/tests/pytest/wal/insertDataDb2Replica2.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/2-query/td_12191.json b/tests/system-test/2-query/td_12191.json index f5d26db40d..daf938a461 100644 --- a/tests/system-test/2-query/td_12191.json +++ b/tests/system-test/2-query/td_12191.json @@ -24,7 +24,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json index 8bd5ddbae8..c3ea89a053 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertMSDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json index 5408a9841a..b6428b482c 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertNanoDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json index 13eb80f3cf..4a648092cc 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoInsertUSDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json index 38ac666fac..afe156e18c 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabase.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json index 467c54988b..73511dbdd6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseInsertForSub.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseNow.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseNow.json index a09dec21fa..dede88c2df 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseNow.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabaseNow.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabasecsv.json b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabasecsv.json index 52e772beca..20998d3392 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabasecsv.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/NanoTestCase/taosdemoTestNanoDatabasecsv.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_no.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_no.json index 759a437b44..b741191303 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_no.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_no.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_yes.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_yes.json index aafc79215f..fa1eb1f7ff 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_yes.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/TD-10539/create_taosdemo_yes.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json index c2e4920097..fc9bb5816d 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/TD-3453/query-interrupt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json b/tests/system-test/5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json index ad85f9607b..1b726ef5da 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/TD-4985/query-limit-offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tnt1r.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tnt1r.json index d73719ebe4..f379fe61bf 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tnt1r.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tnt1r.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tntmr.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tntmr.json index e10fd1116b..1420988650 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tntmr.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-1s1tntmr.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-allDataType.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-allDataType.json index a7ada9b84e..1e714c0813 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-allDataType.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-allDataType.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese-sml.json index 49407a76d7..3633bb6482 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese-sml.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese.json index ab848b1317..88ace59778 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-chinese.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-disorder.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-disorder.json index d6420b100e..2ae3d6c1ce 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-disorder.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-disorder.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json index 2c3b8c6f81..fc2cf160a4 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-N00.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json index f8fe21a6c4..39e4b3bbc8 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-drop-exist-auto-Y00.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-illegal.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-illegal.json index c56f8f3040..920eed6456 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-illegal.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-illegal.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-interlace-row.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-interlace-row.json index 93bb92764d..a40c17d1f9 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-interlace-row.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-interlace-row.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-interval-speed.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-interval-speed.json index d51dee428f..ae15b41e4f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-interval-speed.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-interval-speed.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json index 05a6f7606a..4386b7a7ee 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-newdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-newtable.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-newtable.json index 02b56bbfe8..a87e257ff9 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-newtable.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-newtable.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-nodbnodrop.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-nodbnodrop.json index 5978e5529f..44707e8748 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-nodbnodrop.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-nodbnodrop.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-offset.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-offset.json index 53edf41072..351a2b38d5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-offset.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-offset.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-renewdb.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-renewdb.json index 91c033c677..de023d15a2 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-renewdb.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-renewdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-sample-ts.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-sample-ts.json index 344293b555..6d37233b97 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-sample-ts.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-sample-ts.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-sample.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-sample.json index c31099913b..d251dafe4b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-sample.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-sample.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert-timestep.json b/tests/system-test/5-taos-tools/taosbenchmark/insert-timestep.json index c794c73c84..059643a851 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert-timestep.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert-timestep.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151-error.json b/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151-error.json index be55d31d55..7f16fa74ec 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151-error.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151-error.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json b/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json index 67abdc67ee..ffcd49e32e 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertBinaryLenLarge16374AllcolLar49151.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertChildTab0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertChildTab0.json index 84aa75eca7..99f89eb7dc 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertChildTab0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertChildTab0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertChildTabLess0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertChildTabLess0.json index 58acd9bbd0..68fa2acf63 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertChildTabLess0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertChildTabLess0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json index ecc62b7251..a96422fc52 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNumLarge4096.json b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNumLarge4096.json index fe6f22527d..18ea19682c 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNumLarge4096.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsAndTagNumLarge4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsNum0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsNum0.json index 52d6ae029d..867152a603 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsNum0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertColumnsNum0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json b/tests/system-test/5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json index 0c82f1d299..aaa5812c49 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertInterlaceRowsLarge1M.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertMaxNumPerReq.json b/tests/system-test/5-taos-tools/taosbenchmark/insertMaxNumPerReq.json index 1166ac3643..686a2cc4f1 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertMaxNumPerReq.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertMaxNumPerReq.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json index 8247c5f015..def5043d4f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReq0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReqless0.json b/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReqless0.json index 138ebbadf6..f1f4b7f3c6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReqless0.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertNumOfrecordPerReqless0.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertRestful.json b/tests/system-test/5-taos-tools/taosbenchmark/insertRestful.json index 682dcf2ce4..cb90c1f898 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertRestful.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertRestful.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json b/tests/system-test/5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json index e8468f5906..8b8f959e05 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertSigcolumnsNum4096.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insertTagsNumLarge128.json b/tests/system-test/5-taos-tools/taosbenchmark/insertTagsNumLarge128.json index 4dbe2940e2..4480cf47d3 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insertTagsNumLarge128.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insertTagsNumLarge128.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json b/tests/system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json index 65973ccb48..ae82081525 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/insert_5M_rows.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/manual_block1_comp.json b/tests/system-test/5-taos-tools/taosbenchmark/manual_block1_comp.json index a1a28c9ee9..5c8dc689ae 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/manual_block1_comp.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/manual_block1_comp.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/manual_block2.json b/tests/system-test/5-taos-tools/taosbenchmark/manual_block2.json index 03f6e038fb..c92c18b025 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/manual_block2.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/manual_block2.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json b/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json index 7b8abd6d4e..0f7786e682 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_A.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json b/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json index aeee6322e5..f8decfca41 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/manual_change_time_1_1_B.json @@ -25,7 +25,6 @@ "minRows": 1000, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit1.json b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit1.json index e30b7b0b1c..f166d461fe 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit1.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit1.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit5.json b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit5.json index d4ce2fee46..ebbbc001f9 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit5.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit5.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit94.json b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit94.json index ce12accf06..a18e1e0e1a 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit94.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-limit94.json @@ -27,7 +27,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-newdb.json b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-newdb.json index 9ffb2953d3..4b246a93d7 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-newdb.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/moredemo-offset-newdb.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/query-interrupt.json b/tests/system-test/5-taos-tools/taosbenchmark/query-interrupt.json index 896e484c25..8857d5adae 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/query-interrupt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/query-interrupt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/queryInsertdata.json b/tests/system-test/5-taos-tools/taosbenchmark/queryInsertdata.json index eb196e4096..756316621d 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/queryInsertdata.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/queryInsertdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/queryInsertrestdata.json b/tests/system-test/5-taos-tools/taosbenchmark/queryInsertrestdata.json index 0febbdfa19..0073f52e2b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/queryInsertrestdata.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/queryInsertrestdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json index 5cd06c0275..8e96931e52 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tnt1r-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json index 0885e01782..5042549f09 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-1s1tntmr-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json index cbd4f6cb59..0de5ddcc26 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-allDataType-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json index 6f24801cb0..57006fcc3c 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-disorder-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json index 92e6ec0df7..dcca0f82ae 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-N00-sml.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json index c09493ec7b..cdfc5cb26d 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-drop-exist-auto-Y00-sml.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interlace-row-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interlace-row-sml.json index e04f2ff5e7..caf9a9466b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interlace-row-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interlace-row-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interval-speed-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interval-speed-sml.json index 4a4227adb8..564f2405e3 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interval-speed-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-interval-speed-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json index 1d29842e02..f0a84487d5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newdb-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json index 886503a950..ac5ba1dc5f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-newtable-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json index ca99d135c5..50af8517bc 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-nodbnodrop-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-offset-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-offset-sml.json index d0109b50cf..d79ae2b005 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-offset-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-offset-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json index f8f3a8ee5c..459d47b114 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-renewdb-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sample-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sample-sml.json index a778c4860b..af214a2322 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sample-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sample-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-json-alltype.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-json-alltype.json index 66885ebab8..eca27390c6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-json-alltype.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-json-alltype.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-telnet-alltype.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-telnet-alltype.json index c9fa0f6fb0..6c780edd15 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-telnet-alltype.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-telnet-alltype.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json index 4e8ff40cfd..e7704b87fe 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-sml-timestamp.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json index 1d496b6b46..1d0490f539 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insert-timestep-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json index c70db14b4c..723260c422 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-error-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json index 12034adc07..ba3586635b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertBinaryLenLarge16374AllcolLar49151-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json index 4b27b6b4d0..b96357983d 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTab0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTabLess0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTabLess0-sml.json index 8f27feba6b..3e37ca197f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTabLess0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertChildTabLess0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json index 2e4063cf27..38477734e2 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNum4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json index 83c08923c4..215d8f052a 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsAndTagNumLarge4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json index 92e88141ca..0804acbae0 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertColumnsNum0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json index 18f1a39e0a..73845c2dc5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertInterlaceRowsLarge1M-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json index 01ec546012..b3a113ad38 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml-telnet.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json index d950a260f6..33e61b7d20 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertMaxNumPerReq-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json index 0deed5ba54..aff3190e1a 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReq0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json index 9d1d1ee718..b9f1195457 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertNumOfrecordPerReqless0-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertSigcolumnsNum4096-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertSigcolumnsNum4096-sml.json index e15edfdf44..3db1de723f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertSigcolumnsNum4096-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertSigcolumnsNum4096-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertTagsNumLarge128-sml.json b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertTagsNumLarge128-sml.json index 885aafd884..28a7251216 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/sml/insertTagsNumLarge128-sml.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/sml/insertTagsNumLarge128-sml.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json index f86eaedd14..98a2dd5ae6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json index be7421cd49..2a056b46e5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-allDataType-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-allDataType-stmt.json index 46a0832612..134e4755b5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-allDataType-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-allDataType-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json index e750180421..bc948974b6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-disorder-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json index 2712f88593..c09d5cfeb3 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-N00-stmt.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json index f8fe21a6c4..39e4b3bbc8 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-drop-exist-auto-Y00-stmt.json @@ -25,7 +25,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interlace-row-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interlace-row-stmt.json index 45eb612e6f..4c5e90f185 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interlace-row-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interlace-row-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json index 14fafd60d5..93e41ea575 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json index 622b2554ec..f0ad1b4a5f 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json index 31985c8546..15d2753c4b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json index 3ebc377ca7..d636c95a94 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json index adc6fa74be..263a592dfa 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json index 715644f4f0..04165f16b1 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json index e3d6ce850a..cc4d180fb5 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json index 344293b555..6d37233b97 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-sample-ts-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json index 563dc86d0a..ffe16eccd1 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insert-timestep-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json index f59d2e4e22..37714edc74 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-error-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json index 4903335d18..4625da3a6b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertBinaryLenLarge16374AllcolLar49151-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json index a27feee68a..8f5b62be9b 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTab0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTabLess0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTabLess0-stmt.json index 50e1a7173b..a30c3f7c78 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTabLess0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertChildTabLess0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json index ca0d17f93b..2966af8f23 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNum4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNumLarge4096-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNumLarge4096-stmt.json index c5a3a5f76d..40780dd992 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNumLarge4096-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsAndTagNumLarge4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsNum0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsNum0-stmt.json index c86e759db4..cada61687e 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsNum0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertColumnsNum0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json index ee36b62f90..87386853b3 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertInterlaceRowsLarge1M-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertMaxNumPerReq-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertMaxNumPerReq-stmt.json index 25086c856e..9e213b52a4 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertMaxNumPerReq-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertMaxNumPerReq-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json index 4bd071ec15..5b4bfbae65 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReq0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json index 628c86045f..efc01bb9e6 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertNumOfrecordPerReqless0-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json index 7abab6a0cf..e622415977 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertSigcolumnsNum4096-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertTagsNumLarge128-stmt.json b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertTagsNumLarge128-stmt.json index 8f8539be21..51ac878c37 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertTagsNumLarge128-stmt.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/stmt/insertTagsNumLarge128-stmt.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/subInsertdata.json b/tests/system-test/5-taos-tools/taosbenchmark/subInsertdata.json index 168b3753a1..57e823f74a 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/subInsertdata.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/subInsertdata.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json b/tests/system-test/5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json index 4fb7241012..18487defcc 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/subInsertdataMaxsql100.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, diff --git a/tests/system-test/5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json b/tests/system-test/5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json index 99233bdd73..2c6e6260ff 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json +++ b/tests/system-test/5-taos-tools/taosbenchmark/taosdemoInsertNanoDB.json @@ -26,7 +26,6 @@ "minRows": 100, "maxRows": 4096, "comp":2, - "walLevel":1, "cachelast":0, "quorum":1, "fsync":3000, -- GitLab From ab25a28d5e6885c6140ddadc1e3e6ea3bf5b51f6 Mon Sep 17 00:00:00 2001 From: Bo Ding Date: Mon, 1 Aug 2022 11:29:37 +0800 Subject: [PATCH 272/380] docs: remove rust tab on subscribe page --- docs/zh/07-develop/07-subscribe.mdx | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/zh/07-develop/07-subscribe.mdx b/docs/zh/07-develop/07-subscribe.mdx index 0f531e07c9..962ed72e30 100644 --- a/docs/zh/07-develop/07-subscribe.mdx +++ b/docs/zh/07-develop/07-subscribe.mdx @@ -213,9 +213,6 @@ Query OK, 5 row(s) in set (0.004896s) {/* */} - - - {/* -- GitLab From 61c605a5d00fda7b2b1972754d022aa20aa8935d Mon Sep 17 00:00:00 2001 From: Bo Ding Date: Mon, 1 Aug 2022 11:30:41 +0800 Subject: [PATCH 273/380] docs: remove rust tab on subscribe page --- docs/en/07-develop/07-subscribe.mdx | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/en/07-develop/07-subscribe.mdx b/docs/en/07-develop/07-subscribe.mdx index 782fcdbaf2..0fde36f6cf 100644 --- a/docs/en/07-develop/07-subscribe.mdx +++ b/docs/en/07-develop/07-subscribe.mdx @@ -218,9 +218,6 @@ Query OK, 5 row(s) in set (0.004896s) {/* */} - - - {/* -- GitLab From 479cd003a09bcce29e220dab0a380489464ec718 Mon Sep 17 00:00:00 2001 From: Bo Ding Date: Mon, 1 Aug 2022 16:27:19 +0800 Subject: [PATCH 274/380] docs: typo in python connector reference (#15633) * docs: type in python connector reference * docs: grammer error --- docs/en/14-reference/03-connector/python.mdx | 7 ++++--- docs/zh/14-reference/03-connector/python.mdx | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/en/14-reference/03-connector/python.mdx b/docs/en/14-reference/03-connector/python.mdx index 1e2eecb260..20e8f7348c 100644 --- a/docs/en/14-reference/03-connector/python.mdx +++ b/docs/en/14-reference/03-connector/python.mdx @@ -110,6 +110,7 @@ If you have multiple versions of Python on your system, you may have various `pi C:\> pip3 install taospy Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Requirement already satisfied: taospy in c:\users\username\appdata\local\programs\python\python310\lib\site-packages (2.3.0) +``` ::: @@ -255,7 +256,7 @@ The TaosCursor class uses native connections for write and query operations. In ##### Use of TaosRestCursor class -The ``TaosRestCursor`` class is an implementation of the PEP249 Cursor interface. +The `TaosRestCursor` class is an implementation of the PEP249 Cursor interface. ```python title="Use of TaosRestCursor" {{#include docs/examples/python/connect_rest_examples.py:basic}} @@ -294,7 +295,7 @@ For a more detailed description of the `sql()` method, please refer to [RestClie ``` - + ```python @@ -305,7 +306,7 @@ For a more detailed description of the `sql()` method, please refer to [RestClie ```python -{{#include docs/examples/python/conn_rest_sqlachemy.py}} +{{#include docs/examples/python/conn_rest_sqlalchemy.py}} ``` diff --git a/docs/zh/14-reference/03-connector/python.mdx b/docs/zh/14-reference/03-connector/python.mdx index 38b64a8aef..ecd84fe9a1 100644 --- a/docs/zh/14-reference/03-connector/python.mdx +++ b/docs/zh/14-reference/03-connector/python.mdx @@ -306,7 +306,7 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线 ```python -{{#include docs/examples/python/conn_rest_sqlachemy.py}} +{{#include docs/examples/python/conn_rest_sqlalchemy.py}} ``` -- GitLab From 235953cadc05fb0b7f144aeb4894fcea70677d85 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 1 Aug 2022 16:42:26 +0800 Subject: [PATCH 275/380] docs: python connector pandas supplyment (#15640) --- docs/en/14-reference/03-connector/python.mdx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/en/14-reference/03-connector/python.mdx b/docs/en/14-reference/03-connector/python.mdx index 20e8f7348c..c992d4fcf6 100644 --- a/docs/en/14-reference/03-connector/python.mdx +++ b/docs/en/14-reference/03-connector/python.mdx @@ -295,15 +295,14 @@ For a more detailed description of the `sql()` method, please refer to [RestClie ``` - - + ```python {{#include docs/examples/python/conn_native_sqlalchemy.py}} ``` - + ```python {{#include docs/examples/python/conn_rest_sqlalchemy.py}} -- GitLab From 16a0c6ec36dedcba3870f52dcb7e0e2b477a8b8f Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 1 Aug 2022 18:44:21 +0800 Subject: [PATCH 276/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index f4e456a15f..2a2def12bb 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit f4e456a15f30814182b3c2834bfe591c10a745af +Subproject commit 2a2def12bb82687de34158e6f3fcda540bef100c -- GitLab From 174469fdaea36d78970f4c117ceac3228266437b Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 1 Aug 2022 19:23:14 +0800 Subject: [PATCH 277/380] feat: update taostools for2.6 (#15651) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index f4e456a15f..2a2def12bb 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit f4e456a15f30814182b3c2834bfe591c10a745af +Subproject commit 2a2def12bb82687de34158e6f3fcda540bef100c -- GitLab From b14514ae567355f4fad83a7358e2724cd066a341 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 2 Aug 2022 13:11:59 +0800 Subject: [PATCH 278/380] feat(rpc): add probe msg test ok --- src/client/inc/tsclient.h | 1 - src/client/src/tscAsync.c | 6 ++- src/client/src/tscServer.c | 96 ++++++++++++++++---------------------- src/query/src/qExecutor.c | 6 +-- src/rpc/src/rpcMain.c | 57 ++++++++++++---------- 5 files changed, 81 insertions(+), 85 deletions(-) diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 88d1916724..5a36256538 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -399,7 +399,6 @@ typedef struct SSqlObj { int64_t self; // connect alive - int64_t lastProbe; int64_t lastAlive; void * pPrevContext; } SSqlObj; diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index df1b98478c..759a301f2a 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -312,7 +312,11 @@ static void tscAsyncResultCallback(SSchedMsg *pMsg) { return; } - assert(pSql->res.code != TSDB_CODE_SUCCESS); + // probe send error , but result be responsed by server async + if(pSql->res.code == TSDB_CODE_SUCCESS) { + return ; + } + if (tsShortcutFlag) { tscDebug("0x%" PRIx64 " async result callback, code:%s", pSql->self, tstrerror(pSql->res.code)); pSql->res.code = TSDB_CODE_SUCCESS; diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 0d3471126c..552dee08ee 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -281,48 +281,16 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { } } -// pSql connection link is broken -bool dealConnBroken(SSqlObj * pSql) { - // check valid - - if (pSql->signature != pSql) { - tscInfo("PROBE 0x%" PRIx64 " break link signature is not equal pSql. signature=%p", pSql->self, pSql->signature); - return false; - } - - // set error - pSql->res.code = TSDB_CODE_RPC_CONN_BROKEN; - - // cancel - if (pSql->rpcRid > 0) { - tscInfo("PROBE 0x%" PRIx64 " break link done. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); - rpcCancelRequest(pSql->rpcRid); - pSql->rpcRid = -1; - } else { - tscInfo("PROBE 0x%" PRIx64 " break link rpcRid <=0. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); - } - - // error notify - tscInfo("PROBE 0x%"PRIx64" call async result error." PRIx64, pSql->self); - tscAsyncResultOnError(pSql); - - return true; -} - // if return true, send probe connection msg to sever ok -bool sendProbeConnMsg(SSqlObj* pSql) { - // TEST TODO DELETE - tsProbeSeconds = 1; // over this value send probe msg - tsProbeKillSeconds = 2*60; // over this value query can be killed - - if(pSql->stime == 0) { +bool sendProbeConnMsg(SSqlObj* pSql, int64_t stime) { + if(stime == 0) { // not start , no need probe tscInfo("PROBE 0x%" PRIx64 " not start, no need probe.", pSql->self); return true; } - int64_t stime = MAX(pSql->stime, pSql->lastAlive); - int32_t diff = (int32_t)(taosGetTimestampMs() - stime); + int64_t start = MAX(stime, pSql->lastAlive); + int32_t diff = (int32_t)(taosGetTimestampMs() - start); if (diff < tsProbeSeconds * 1000) { // exec time short , need not probe alive tscInfo("PROBE 0x%" PRIx64 " not arrived probe time. cfg timeout=%ds, no need probe. lastAlive=%" PRId64 " stime=%" PRId64, \ @@ -349,9 +317,6 @@ bool sendProbeConnMsg(SSqlObj* pSql) { tscInfo("PROBE 0x%" PRIx64 " rpcRid is -1, response ok. no need probe.", pSql->self); return true; } - - // It's long time from lastAlive, so need probe - pSql->lastProbe = taosGetTimestampMs(); bool ret = rpcSendProbe(pSql->rpcRid, pSql->pPrevContext); tscInfo("PROBE 0x%" PRIx64 " send probe msg, ret=%d rpcRid=0x%" PRIx64, pSql->self, ret, pSql->rpcRid); @@ -363,27 +328,49 @@ void checkBrokenQueries(STscObj *pTscObj) { tscDebug("PROBE checkBrokenQueries pTscObj=%p pTscObj->rid=0x%" PRIx64, pTscObj, pTscObj->rid); SSqlObj *pSql = pTscObj->sqlList; while (pSql) { + // avoid sqlobj may not be correctly removed from sql list + if (pSql->sqlstr == NULL) { + pSql = pSql->next; + continue; + } + + bool kill = false; int32_t numOfSub = pSql->subState.numOfSub; - tscInfo("PROBE 0x%" PRIx64 " check sql connection alive, numOfSub=%d sql=%s", pSql->self, numOfSub, pSql->sqlstr == NULL ? "" : pSql->sqlstr); + tscInfo("PROBE 0x%" PRIx64 " start checking sql connection alive, numOfSub=%d sql=%s", pSql->self, numOfSub, pSql->sqlstr == NULL ? "" : pSql->sqlstr); if (numOfSub == 0) { // no sub sql - if(!sendProbeConnMsg(pSql)) { - // send failed , connect already broken - dealConnBroken(pSql); + if(!sendProbeConnMsg(pSql, pSql->stime)) { + // need kill + tscInfo("PROBE 0x%" PRIx64 " need break link done. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); + kill = true; } - - return ; - } - - // have sub sql - for (int i = 0; i < numOfSub; i++) { - SSqlObj *pSubSql = pSql->pSubs[i]; - if(!sendProbeConnMsg(pSubSql)) { - // send failed , connect already broken - dealConnBroken(pSubSql); + } else { + // lock subs + pthread_mutex_lock(&pSql->subState.mutex); + if (pSql->pSubs) { + // have sub sql + for (int i = 0; i < numOfSub; i++) { + SSqlObj *pSubSql = pSql->pSubs[i]; + if(pSubSql) { + tscInfo("PROBE 0x%" PRIx64 " sub sql app is 0x%" PRIx64, pSql->self, pSubSql->self); + if(!sendProbeConnMsg(pSubSql, pSql->stime)) { + // need kill + tscInfo("PROBE 0x%" PRIx64 " i=%d sub app=0x%" PRIx64 " need break link done. rpcRid=0x%" PRIx64, pSql->self, i, pSubSql->self, pSubSql->rpcRid); + kill = true; + break; + } + } + } } + // unlock + pthread_mutex_unlock(&pSql->subState.mutex); } + // kill query + if(kill) { + taos_stop_query(pSql); + } + // move next pSql = pSql->next; } @@ -543,12 +530,11 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { // check msgtype if(rpcMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { pSql->lastAlive = taosGetTimestampMs(); - tscDebug("PROBE 0x%" PRIx64 " recv probe response msg. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); + tscInfo("PROBE 0x%" PRIx64 " recv probe msg response. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); rpcFreeCont(rpcMsg->pCont); return ; } - STscObj *pObj = pSql->pTscObj; SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 6f7e77d915..af859de8a1 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -6368,9 +6368,9 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); // TEST TODU DELETE - static int loop = 0; - taosMsleep(1*1000); - qInfo(" loop=%d pEnv=%p", loop++, pRuntimeEnv); + //static int loop = 0; + //taosMsleep(1*1000); + //qInfo(" loop=%d pEnv=%p", loop++, pRuntimeEnv); if (pBlock == NULL) { diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index e8564ac8ed..6a8a47c69a 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1083,28 +1083,32 @@ static void rpcProcessBrokenLink(SRpcConn *pConn) { // process probe msg , return true is probe msg, false is not probe msg static void rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { SRpcHead *pHead = (SRpcHead *)pRecv->msg; + uint64_t ahandle = pHead->ahandle; if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN) { // response to - SRpcHead rspHead; - memset(&rspHead, 0, sizeof(SRpcHead)); + char msg[RPC_MSG_OVERHEAD]; + SRpcHead *pRspHead; - rspHead.msgType = TSDB_MSG_TYPE_PROBE_CONN_RSP; - rspHead.version = 1; - rspHead.ahandle = pHead->ahandle; - rspHead.tranId = pHead->tranId; - rspHead.code = 0; - rspHead.spi = pHead->spi; - rspHead.linkUid = pHead->linkUid; + // set msg header + memset(msg, 0, sizeof(SRpcHead)); + pRspHead = (SRpcHead *)msg; + + pRspHead->msgType = TSDB_MSG_TYPE_PROBE_CONN_RSP; + pRspHead->version = 1; + pRspHead->ahandle = pHead->ahandle; + pRspHead->tranId = pHead->tranId; + pRspHead->code = 0; + pRspHead->linkUid = pHead->linkUid; rpcLockConn(pConn); - rspHead.sourceId = pConn->ownId; - rspHead.destId = pConn->peerId; - memcpy(rspHead.user, pHead->user, tListLen(pHead->user)); + pRspHead->sourceId = pConn->ownId; + pRspHead->destId = pConn->peerId; + memcpy(pRspHead->user, pHead->user, tListLen(pHead->user)); - bool ret = rpcSendMsgToPeer(pConn, &rspHead, sizeof(SRpcHead)); - tInfo("PROBE 0x%" PRIx64 " recv probe msg and do response. ret=%d", pHead->ahandle, ret); - rpcFreeMsg(pRecv->msg); + bool ret = rpcSendMsgToPeer(pConn, pRspHead, sizeof(SRpcHead)); + tInfo("PROBE 0x%" PRIx64 " recv probe msg and do response. ret=%d", ahandle, ret); rpcUnlockConn(pConn); + rpcFreeMsg(pRecv->msg); } else if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { if(pConn) { rpcLockConn(pConn); @@ -1116,16 +1120,16 @@ static void rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { rpcProcessIncomingMsg(pConn, pHead, pContext); taosReleaseRef(tsRpcRefId, pConn->rid); } else { - tInfo("PROBE 0x%" PRIx64 " get reqContext by rid return NULL. pConn->rid=0x%" PRIX64, pHead->ahandle, pConn->rid); + tInfo("PROBE 0x%" PRIx64 " recv response probe msg but pContext is NULL. pConn->rid=0x%" PRIX64, ahandle, pConn->rid); + rpcFreeMsg(pRecv->msg); } rpcUnlockConn(pConn); - tInfo("PROBE 0x%" PRIx64 " recv response probe msg and update lastLiveTime. pConn=%p", pHead->ahandle, pConn); } else { - tInfo("PROBE 0x%" PRIx64 " recv response probe msg but pConn is NULL.", pHead->ahandle); + tInfo("PROBE 0x%" PRIx64 " recv response probe msg but pConn is NULL.", ahandle); + rpcFreeMsg(pRecv->msg); } } - } static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) { @@ -1798,7 +1802,7 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext) { bool ret = false; if(rpcRid < 0) { tError("PROBE rpcRid=0x%" PRIx64 " less than zero, invalid.", rpcRid); - return false; + return true; } // get req content @@ -1815,22 +1819,25 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext) { } // conn same - if (pContext->pConn != pContext->sendInfo.pConn) { - tError("PROBE rpcRid=0x%" PRIx64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pContext->sendInfo.pConn); - ret = pContext->pConn == NULL; + if(pContext->pConn == NULL) { + tInfo("PROBE rpcRid=0x%" PRIx64 " connect obj is NULL. ", rpcRid); + ret = true; + goto _END; + } else if (pContext->pConn != pContext->sendInfo.pConn) { + tInfo("PROBE rpcRid=0x%" PRIx64 " connect obj diff. pContext->pConn=%p pPreConn=%p", rpcRid, pContext->pConn, pContext->sendInfo.pConn); goto _END; } // fdObj same if (pContext->pConn->chandle != pContext->sendInfo.pFdObj) { - tError("PROBE rpcRid=0x%" PRIx64 " connect fdObj diff. pContext->pConn->chandle=%p pPrevFdObj=%p", rpcRid, pContext->pConn->chandle, pContext->sendInfo.pFdObj); + tInfo("PROBE rpcRid=0x%" PRIx64 " connect fdObj diff. pContext->pConn->chandle=%p pPrevFdObj=%p", rpcRid, pContext->pConn->chandle, pContext->sendInfo.pFdObj); goto _END; } // fd same int32_t fd = taosGetFdID(pContext->pConn->chandle); if (fd != pContext->sendInfo.fd) { - tError("PROBE rpcRid=0x%" PRIx64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, pContext->sendInfo.fd); + tInfo("PROBE rpcRid=0x%" PRIx64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, pContext->sendInfo.fd); goto _END; } -- GitLab From 6265ecd48b87f193c5d9b9391abd26f2fe6f1c7e Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 2 Aug 2022 13:32:53 +0800 Subject: [PATCH 279/380] feat(rpc): add cfg probeInterval --- src/client/src/tscServer.c | 2 +- src/common/inc/tglobal.h | 1 + src/common/src/tglobal.c | 16 ++++++++++++++-- src/util/inc/tconfig.h | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 552dee08ee..98f3ed22dd 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -393,7 +393,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { // check queries already death static int activetyCnt = 0; - if (++activetyCnt > 3) { // 1.5s * 10 = 15s interval call + if (++activetyCnt > tsProbeInterval) { // 1.5s * 40 = 60s interval call check queries alive activetyCnt = 0; // call check if have query doing diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 7011ac06ec..e1b7cff8be 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -221,6 +221,7 @@ extern int8_t tsClientMerge; // probe alive connection extern int32_t tsProbeSeconds; extern int32_t tsProbeKillSeconds; +extern int32_t tsProbeInterval; #ifdef TD_TSZ // lossy diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index dedc81fdb4..26450b202d 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -269,8 +269,9 @@ int32_t fsDebugFlag = 135; int8_t tsClientMerge = 0; // probe alive connection -int32_t tsProbeSeconds = 10 * 60; // start probe link alive after tsProbeSeconds from starting query -int32_t tsProbeKillSeconds = 30 * 60; // start kill query after tsProbeKillSeconds from starting query +int32_t tsProbeSeconds = 5 * 60; // start probe link alive after tsProbeSeconds from starting query +int32_t tsProbeKillSeconds = 10 * 60; // start kill query after tsProbeKillSeconds from last alive time +int32_t tsProbeInterval = 40; // 40 * 1.5s = 60 s interval time #ifdef TD_TSZ @@ -1760,6 +1761,17 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); + // probeInterval + cfg.option = "probeInterval"; + cfg.ptr = &tsProbeInterval; + cfg.valType = TAOS_CFG_VTYPE_INT32; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT; + cfg.minValue = 0; + cfg.maxValue = 0; + cfg.ptrLength = 0; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + #ifdef TD_TSZ // lossy compress cfg.option = "lossyColumns"; diff --git a/src/util/inc/tconfig.h b/src/util/inc/tconfig.h index c0a4986936..872da82a8e 100644 --- a/src/util/inc/tconfig.h +++ b/src/util/inc/tconfig.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define TSDB_CFG_MAX_NUM 133 +#define TSDB_CFG_MAX_NUM 134 #define TSDB_CFG_PRINT_LEN 23 #define TSDB_CFG_OPTION_LEN 24 #define TSDB_CFG_VALUE_LEN 41 -- GitLab From db4086813aac5aa3a96411acd5da301441693e03 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 2 Aug 2022 13:50:56 +0800 Subject: [PATCH 280/380] feat(rpc): add cfg probeInterval --- src/query/src/qExecutor.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index af859de8a1..d12cf8d03f 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -6367,12 +6367,6 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) { SSDataBlock* pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC); - // TEST TODU DELETE - //static int loop = 0; - //taosMsleep(1*1000); - //qInfo(" loop=%d pEnv=%p", loop++, pRuntimeEnv); - - if (pBlock == NULL) { //assert(*newgroup == false); -- GitLab From 33737dc463d2121a517817abc9ab96c9f9e66b0e Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 2 Aug 2022 13:57:04 +0800 Subject: [PATCH 281/380] feat(rpc): add cfg probeInterval1 --- src/common/src/tglobal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 26450b202d..77540cd0b6 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -1745,7 +1745,7 @@ static void doInitGlobalConfig(void) { cfg.valType = TAOS_CFG_VTYPE_INT32; cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT; cfg.minValue = 0; - cfg.maxValue = 0; + cfg.maxValue = 100000; cfg.ptrLength = 0; cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); @@ -1756,7 +1756,7 @@ static void doInitGlobalConfig(void) { cfg.valType = TAOS_CFG_VTYPE_INT32; cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT; cfg.minValue = 0; - cfg.maxValue = 0; + cfg.maxValue = 100000; cfg.ptrLength = 0; cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); @@ -1767,7 +1767,7 @@ static void doInitGlobalConfig(void) { cfg.valType = TAOS_CFG_VTYPE_INT32; cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT; cfg.minValue = 0; - cfg.maxValue = 0; + cfg.maxValue = 100000; cfg.ptrLength = 0; cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); -- GitLab From d640b1a39b0abfe64b677f39b48130fa747e1735 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 2 Aug 2022 18:58:40 +0800 Subject: [PATCH 282/380] feat(rpc): probe msg fix bugs --- src/client/src/tscServer.c | 3 ++- src/rpc/src/rpcMain.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 98f3ed22dd..d3fe338c91 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -336,7 +336,8 @@ void checkBrokenQueries(STscObj *pTscObj) { bool kill = false; int32_t numOfSub = pSql->subState.numOfSub; - tscInfo("PROBE 0x%" PRIx64 " start checking sql connection alive, numOfSub=%d sql=%s", pSql->self, numOfSub, pSql->sqlstr == NULL ? "" : pSql->sqlstr); + tscInfo("PROBE 0x%" PRIx64 " start checking sql alive, numOfSub=%d sql=%s stime=%" PRId64 " alive=%" PRId64 " rpcRid=0x%" PRIx64 \ + ,pSql->self, numOfSub, pSql->sqlstr == NULL ? "" : pSql->sqlstr, pSql->stime, pSql->lastAlive, pSql->rpcRid); if (numOfSub == 0) { // no sub sql if(!sendProbeConnMsg(pSql, pSql->stime)) { diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 6a8a47c69a..fe4f3284ac 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -984,6 +984,10 @@ static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv, SRpcReqCont return NULL; } + if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN || pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { + return pConn; + } + rpcLockConn(pConn); if (rpcIsReq(pHead->msgType)) { @@ -1107,6 +1111,7 @@ static void rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { bool ret = rpcSendMsgToPeer(pConn, pRspHead, sizeof(SRpcHead)); tInfo("PROBE 0x%" PRIx64 " recv probe msg and do response. ret=%d", ahandle, ret); + rpcUnlockConn(pConn); rpcFreeMsg(pRecv->msg); } else if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { -- GitLab From a8c7b36c8bfcd40230a73ceb93bab75fc9ee3671 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 11:11:25 +0800 Subject: [PATCH 283/380] feat(rpc): reset taos-tools --- .gitmodules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitmodules b/.gitmodules index 161d481f89..8179b9caa5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,6 +7,9 @@ [submodule "deps/jemalloc"] path = deps/jemalloc url = https://github.com/jemalloc/jemalloc.git +[submodule "src/kit/taos-tools"] + path = src/kit/taos-tools + url = https://github.com/taosdata/taos-tools.git [submodule "src/plugins/taosadapter"] path = src/plugins/taosadapter url = https://github.com/taosdata/taosadapter.git -- GitLab From 2ea367eb041a3b2c232f2b2c44dba4e8ed604a2b Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 11:16:33 +0800 Subject: [PATCH 284/380] feat(rpc): reset not need modify file --- src/dnode/src/dnodeVRead.c | 6 +----- src/vnode/src/vnodeRead.c | 3 +-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/dnode/src/dnodeVRead.c b/src/dnode/src/dnodeVRead.c index 50d6f30f26..0b0bf29e50 100644 --- a/src/dnode/src/dnodeVRead.c +++ b/src/dnode/src/dnodeVRead.c @@ -136,11 +136,7 @@ static void *dnodeProcessReadQueue(void *wparam) { int32_t code = vnodeProcessRead(pVnode, pRead); - if(code == 9999) { - dInfo(" ******* doNotRsp Test **** msg:%p, app:%p type:%s will be processed in vquery queue, qtype:%d", pRead, pRead->rpcAhandle,taosMsg[pRead->msgType], qtype); - printf(" ******* doNotRsp Test **** msg:%p, app:%p type:%s will be processed in vquery queue, qtype:%d", pRead, pRead->rpcAhandle,taosMsg[pRead->msgType], qtype); - - } else if (qtype == TAOS_QTYPE_RPC && code != TSDB_CODE_QRY_NOT_READY) { + if (qtype == TAOS_QTYPE_RPC && code != TSDB_CODE_QRY_NOT_READY) { dnodeSendRpcVReadRsp(pVnode, pRead, code); } else { if (code == TSDB_CODE_QRY_HAS_RSP) { diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index 8f3c7a399a..e8495cac6d 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -339,9 +339,8 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, freehandle); } + } - // TEST CODE - //code = 9999; } return code; -- GitLab From b472511e0cbb147a3662d0d126cfc2aaf2724c58 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 13:43:08 +0800 Subject: [PATCH 285/380] feat(rpc): windows build error --- src/inc/trpc.h | 2 +- src/rpc/inc/rpcTcp.h | 2 +- src/rpc/src/rpcMain.c | 4 ++-- src/rpc/src/rpcTcp.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/inc/trpc.h b/src/inc/trpc.h index 940a1bf044..9176a8b068 100644 --- a/src/inc/trpc.h +++ b/src/inc/trpc.h @@ -82,7 +82,7 @@ typedef struct SSendInfo { void *pContext; void *pConn; void *pFdObj; - int32_t fd; + SOCKET fd; } SSendInfo; int32_t rpcInit(); diff --git a/src/rpc/inc/rpcTcp.h b/src/rpc/inc/rpcTcp.h index 20ebec4fec..a47fa39ceb 100644 --- a/src/rpc/inc/rpcTcp.h +++ b/src/rpc/inc/rpcTcp.h @@ -32,7 +32,7 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin void taosCloseTcpConnection(void *chandle); int taosSendTcpData(uint32_t ip, uint16_t port, void *data, int len, void *chandle); -int32_t taosGetFdID(void *chandle); +SOCKET taosGetFdID(void *chandle); #ifdef __cplusplus } diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 9360e7afd9..e350f9e5fe 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -86,8 +86,8 @@ typedef struct { SRpcMsg *pRsp; // for synchronous API tsem_t *pSem; // for synchronous API SRpcEpSet *pSet; // for synchronous API - char msg[0]; // RpcHead starts from here SSendInfo sendInfo; // save last send information + char msg[0]; // RpcHead starts from here } SRpcReqContext; typedef struct SRpcConn { @@ -1840,7 +1840,7 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext) { } // fd same - int32_t fd = taosGetFdID(pContext->pConn->chandle); + SOCKET fd = taosGetFdID(pContext->pConn->chandle); if (fd != pContext->sendInfo.fd) { tInfo("PROBE rpcRid=0x%" PRIx64 " connect fd diff.fd=%d prevFd=%d", rpcRid, fd, pContext->sendInfo.fd); goto _END; diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index aa13179af1..530a279cc7 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -675,7 +675,7 @@ static void taosFreeFdObj(SFdObj *pFdObj) { tfree(pFdObj); } -int32_t taosGetFdID(void *chandle) { +SOCKET taosGetFdID(void *chandle) { SFdObj * pFdObj = chandle; if(pFdObj == NULL) return -1; -- GitLab From f80597a1b1d269753dabe61b2794b18c33fa4c20 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 13:48:53 +0800 Subject: [PATCH 286/380] feat(rpc): windows build error1 --- src/inc/trpc.h | 7 ------- src/rpc/src/rpcMain.c | 8 +++++++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/inc/trpc.h b/src/inc/trpc.h index 9176a8b068..59908253c2 100644 --- a/src/inc/trpc.h +++ b/src/inc/trpc.h @@ -78,13 +78,6 @@ typedef struct SRpcInit { int (*afp)(char *tableId, char *spi, char *encrypt, char *secret, char *ckey); } SRpcInit; -typedef struct SSendInfo { - void *pContext; - void *pConn; - void *pFdObj; - SOCKET fd; -} SSendInfo; - int32_t rpcInit(); void rpcCleanup(); void *rpcOpen(const SRpcInit *pRpc); diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index e350f9e5fe..d531b300fc 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -69,6 +69,13 @@ typedef struct { struct SRpcConn *connList; // connection list } SRpcInfo; +typedef struct SSendInfo { + void *pContext; + void *pConn; + void *pFdObj; + SOCKET fd; +} SSendInfo; + typedef struct { SRpcInfo *pRpc; // associated SRpcInfo SRpcEpSet epSet; // ip list provided by app @@ -127,7 +134,6 @@ typedef struct SRpcConn { SRpcReqContext *pContext; // request context int64_t rid; // probe msg use rid get pContext int64_t lastLiveTime; // last alive time with ms - } SRpcConn; int tsRpcMaxUdpSize = 15000; // bytes -- GitLab From 44fe1eb29a05f4cb934745fc2d807599fe6d72bf Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 3 Aug 2022 17:16:11 +0800 Subject: [PATCH 287/380] docs: add emqx version note (#15706) --- docs/en/20-third-party/09-emq-broker.md | 1 + docs/zh/20-third-party/09-emq-broker.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/en/20-third-party/09-emq-broker.md b/docs/en/20-third-party/09-emq-broker.md index 8dfa09e6c7..6e44d11b5f 100644 --- a/docs/en/20-third-party/09-emq-broker.md +++ b/docs/en/20-third-party/09-emq-broker.md @@ -16,6 +16,7 @@ The following preparations are required for EMQX to add TDengine data sources co Depending on the current operating system, users can download the installation package from the [EMQX official website](https://www.emqx.io/downloads) and execute the installation. After installation, use `sudo emqx start` or `sudo systemctl start emqx` to start the EMQX service. +Note: this chapter is based on EMQX v4.4.5. Other version of EMQX probably change its user interface, configuration methods or functions. ## Create Database and Table diff --git a/docs/zh/20-third-party/09-emq-broker.md b/docs/zh/20-third-party/09-emq-broker.md index 84b1027f6b..07066ba94d 100644 --- a/docs/zh/20-third-party/09-emq-broker.md +++ b/docs/zh/20-third-party/09-emq-broker.md @@ -17,6 +17,7 @@ MQTT 是流行的物联网数据传输协议,[EMQX](https://github.com/emqx/em 用户可以根据当前的操作系统,到 EMQX 官网下载安装包,并执行安装。下载地址如下:。安装后使用 `sudo emqx start` 或 `sudo systemctl start emqx` 启动 EMQX 服务。 +注意:本文基于 EMQX v4.4.5 版本,其他版本由于相关配置界面、配置方法以及功能可能随着版本升级有所区别。 ## 创建数据库和表 -- GitLab From d65f5e7ffd40a4abec15962ae9a525835bb2579a Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 18:44:54 +0800 Subject: [PATCH 288/380] feat(rpc): remove unuse variant --- src/rpc/src/rpcMain.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index d531b300fc..bcc759f845 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -133,7 +133,6 @@ typedef struct SRpcConn { int64_t lockedBy; // lock for connection SRpcReqContext *pContext; // request context int64_t rid; // probe msg use rid get pContext - int64_t lastLiveTime; // last alive time with ms } SRpcConn; int tsRpcMaxUdpSize = 15000; // bytes @@ -1123,7 +1122,6 @@ static void rpcProcessProbeMsg(SRecvInfo *pRecv, SRpcConn *pConn) { } else if (pHead->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) { if(pConn) { rpcLockConn(pConn); - pConn->lastLiveTime = taosGetTimestampMs(); // get req content SRpcReqContext *pContext = taosAcquireRef(tsRpcRefId, pConn->rid); @@ -1802,7 +1800,6 @@ bool doRpcSendProbe(SRpcConn *pConn) { pHead->code = htonl(code); bool ret = rpcSendMsgToPeer(pConn, msg, sizeof(SRpcHead) + sizeof(int32_t)); - pConn->lastLiveTime = taosGetTimestampMs(); return ret; } -- GitLab From e7bf0e60f35258e4f69b4317abc7b9eb281c83a8 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 19:09:25 +0800 Subject: [PATCH 289/380] feat(rpc): add taos-tools --- src/kit/taos-tools | 1 + 1 file changed, 1 insertion(+) create mode 160000 src/kit/taos-tools diff --git a/src/kit/taos-tools b/src/kit/taos-tools new file mode 160000 index 0000000000..58f58ee4c7 --- /dev/null +++ b/src/kit/taos-tools @@ -0,0 +1 @@ +Subproject commit 58f58ee4c768de531c632a2362f4e6d903c182ed -- GitLab From 58fb9aa24b9290bf09904ce5720ceaa30d8e8073 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 19:15:22 +0800 Subject: [PATCH 290/380] feat(rpc): add taos-tools with tag --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 58f58ee4c7..2a2def12bb 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 58f58ee4c768de531c632a2362f4e6d903c182ed +Subproject commit 2a2def12bb82687de34158e6f3fcda540bef100c -- GitLab From fcf7e5e6a19b0b5d53d6616fd94421d0dd76843c Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 19:50:08 +0800 Subject: [PATCH 291/380] feat(rpc): remove kill query for PR --- src/client/src/tscServer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index e709df581a..6700e2258f 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -369,7 +369,8 @@ void checkBrokenQueries(STscObj *pTscObj) { // kill query if(kill) { - taos_stop_query(pSql); + //taos_stop_query(pSql); + tscInfo("PROBE do not kill."); } // move next -- GitLab From 49ac4cb205073c5d8136fd2544f41b56a9a5c056 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 20:18:33 +0800 Subject: [PATCH 292/380] feat(rpc): remove kill query for PR test1 --- src/client/src/tscServer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 6700e2258f..2c6e96334a 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -401,7 +401,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { // call check if have query doing if(pObj->sqlList) { // have queries executing - checkBrokenQueries(pObj); + //checkBrokenQueries(pObj); } } -- GitLab From c6fedd09b81b32447611768bb5f5fa660ed26520 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 20:39:55 +0800 Subject: [PATCH 293/380] feat(rpc): check valid in broken callback --- src/client/src/tscServer.c | 5 ++--- src/client/src/tscSubquery.c | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 2c6e96334a..e709df581a 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -369,8 +369,7 @@ void checkBrokenQueries(STscObj *pTscObj) { // kill query if(kill) { - //taos_stop_query(pSql); - tscInfo("PROBE do not kill."); + taos_stop_query(pSql); } // move next @@ -401,7 +400,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { // call check if have query doing if(pObj->sqlList) { // have queries executing - //checkBrokenQueries(pObj); + checkBrokenQueries(pObj); } } diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 5f1d996b54..3b655f3a01 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -3391,6 +3391,10 @@ static void doFreeInsertSupporter(SSqlObj* pSqlObj) { } static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) { + if(param == NULL) { + tscError("callback multiVnodeInsertFinalize param is NULL. tres=0x%" PRIx64 " numOfRows=%d", tres, numOfRows); + return ; + } SInsertSupporter *pSupporter = (SInsertSupporter *)param; SSqlObj* pParentObj = pSupporter->pSql; -- GitLab From 33647859a1d2baac77495f19ac744cac7e70cc0f Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 3 Aug 2022 20:47:17 +0800 Subject: [PATCH 294/380] feat(rpc): check valid in broken callback1 --- src/client/src/tscSubquery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 3b655f3a01..ab34d99bfc 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -3392,7 +3392,7 @@ static void doFreeInsertSupporter(SSqlObj* pSqlObj) { static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) { if(param == NULL) { - tscError("callback multiVnodeInsertFinalize param is NULL. tres=0x%" PRIx64 " numOfRows=%d", tres, numOfRows); + tscError("callback multiVnodeInsertFinalize param is NULL. tres=%p numOfRows=%d", tres, numOfRows); return ; } SInsertSupporter *pSupporter = (SInsertSupporter *)param; -- GitLab From 680f2ee785b5155ac15df0692b2db4b1d7d302a8 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 3 Aug 2022 15:51:59 +0000 Subject: [PATCH 295/380] feat: update taos-tools 8157e3b for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 2a2def12bb..8157e3bfe0 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 2a2def12bb82687de34158e6f3fcda540bef100c +Subproject commit 8157e3bfe04f1d43a250c2bf69e8db8803aa7020 -- GitLab From 40d735ccd419b90ca3d79e502d8f2e9776b81c59 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 4 Aug 2022 00:56:16 +0800 Subject: [PATCH 296/380] feat: update taostools for2.6 (#15728) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 2a2def12bb..8157e3bfe0 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 2a2def12bb82687de34158e6f3fcda540bef100c +Subproject commit 8157e3bfe04f1d43a250c2bf69e8db8803aa7020 -- GitLab From 7ac8dc9e39a67d4a57e512cd725b40daff5c230c Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 4 Aug 2022 09:53:36 +0800 Subject: [PATCH 297/380] feat(rpc): probe msg pass PR test --- src/client/src/tscServer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index e709df581a..6a59830331 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -400,7 +400,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { // call check if have query doing if(pObj->sqlList) { // have queries executing - checkBrokenQueries(pObj); + //checkBrokenQueries(pObj); } } -- GitLab From f5c4b36a43b9d2b7e4d682e4027ea44ac6fb9f1a Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 4 Aug 2022 11:17:35 +0800 Subject: [PATCH 298/380] feat: update taos-tools c9cc20f for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 8157e3bfe0..c9cc20f184 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 8157e3bfe04f1d43a250c2bf69e8db8803aa7020 +Subproject commit c9cc20f1846fac95dba98e660f4a5fffce322d45 -- GitLab From 76a69c59b18d5a642bff23675dd1b08a6d7c70c0 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 4 Aug 2022 11:43:49 +0800 Subject: [PATCH 299/380] feat: update taostools for2.6 (#15734) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 8157e3bfe0..c9cc20f184 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 8157e3bfe04f1d43a250c2bf69e8db8803aa7020 +Subproject commit c9cc20f1846fac95dba98e660f4a5fffce322d45 -- GitLab From 9679675d6fad500a8922b17e75ebc6e6cb8c418d Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 4 Aug 2022 13:37:44 +0800 Subject: [PATCH 300/380] docs: fix minor version typo of emq for 2.6 (#15738) * docs: add emqx version note * docs: fix minor version typo --- docs/en/20-third-party/09-emq-broker.md | 2 +- docs/zh/20-third-party/09-emq-broker.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/20-third-party/09-emq-broker.md b/docs/en/20-third-party/09-emq-broker.md index 6e44d11b5f..0900dd3d75 100644 --- a/docs/en/20-third-party/09-emq-broker.md +++ b/docs/en/20-third-party/09-emq-broker.md @@ -32,7 +32,7 @@ Note: The table schema is based on the blog [(In Chinese) Data Transfer, Storage ## Configuring EMQX Rules -Since the configuration interface of EMQX differs from version to version, here is v4.4.3 as an example. For other versions, please refer to the corresponding official documentation. +Since the configuration interface of EMQX differs from version to version, here is v4.4.5 as an example. For other versions, please refer to the corresponding official documentation. ### Login EMQX Dashboard diff --git a/docs/zh/20-third-party/09-emq-broker.md b/docs/zh/20-third-party/09-emq-broker.md index 07066ba94d..dd98374558 100644 --- a/docs/zh/20-third-party/09-emq-broker.md +++ b/docs/zh/20-third-party/09-emq-broker.md @@ -33,7 +33,7 @@ CREATE TABLE sensor_data (ts TIMESTAMP, temperature FLOAT, humidity FLOAT, volum ## 配置 EMQX 规则 -由于 EMQX 不同版本配置界面所有不同,这里仅以 v4.4.3 为例,其他版本请参考相应官网文档。 +由于 EMQX 不同版本配置界面所有不同,这里仅以 v4.4.5 为例,其他版本请参考相应官网文档。 ### 登录 EMQX Dashboard -- GitLab From 11cd05b5f141377bcdd0f25e969cb352bcc00177 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 4 Aug 2022 14:30:16 +0800 Subject: [PATCH 301/380] docs: update taosdump docs (#15741) --- docs/en/14-reference/06-taosdump.md | 7 +++++-- docs/zh/14-reference/06-taosdump.md | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/en/14-reference/06-taosdump.md b/docs/en/14-reference/06-taosdump.md index 96e68d0edb..2105ba83fa 100644 --- a/docs/en/14-reference/06-taosdump.md +++ b/docs/en/14-reference/06-taosdump.md @@ -29,7 +29,7 @@ There are two ways to install taosdump: 1. backing up all databases: specify `-A` or `-all-databases` parameter. 2. backup multiple specified databases: use `-D db1,db2,... ` parameters; -3. back up some super or normal tables in the specified database: use `-dbname stbname1 stbname2 tbname1 tbname2 ... ` parameters. Note that the first parameter of this input sequence is the database name, and only one database is supported. The second and subsequent parameters are the names of super or normal tables in that database, separated by spaces. +3. back up some super or normal tables in the specified database: use `dbname stbname1 stbname2 tbname1 tbname2 ... ` parameters. Note that the first parameter of this input sequence is the database name, and only one database is supported. The second and subsequent parameters are the names of super or normal tables in that database, separated by spaces. 4. back up the system log database: TDengine clusters usually contain a system database named `log`. The data in this database is the data that TDengine runs itself, and the taosdump will not back up the log database by default. If users need to back up the log database, users can use the `-a` or `-allow-sys` command-line parameter. 5. Loose mode backup: taosdump version 1.4.1 onwards provides `-n` and `-L` parameters for backing up data without using escape characters and "loose" mode, which can reduce the number of backups if table names, column names, tag names do not use escape characters. This can also reduce the backup data time and backup data footprint. If you are unsure about using `-n` and `-L` conditions, please use the default parameters for "strict" mode backup. See the [official documentation](/taos-sql/escape) for a description of escaped characters. @@ -104,7 +104,10 @@ Usage: taosdump [OPTION...] dbname [tbname ...] use letter and number only. Default is NOT. -n, --no-escape No escape char '`'. Default is using it. -T, --thread-num=THREAD_NUM Number of thread for dump in file. Default is - 5. + 8. + -C, --cloud=CLOUD_DSN specify a DSN to access TDengine cloud service + -R, --restful Use RESTful interface to connect TDengine + -t, --timeout=SECONDS The timeout seconds for websocket to interact. -g, --debug Print debug info. -?, --help Give this help list --usage Give a short usage message diff --git a/docs/zh/14-reference/06-taosdump.md b/docs/zh/14-reference/06-taosdump.md index 95ee20bfba..625499a949 100644 --- a/docs/zh/14-reference/06-taosdump.md +++ b/docs/zh/14-reference/06-taosdump.md @@ -107,7 +107,10 @@ Usage: taosdump [OPTION...] dbname [tbname ...] use letter and number only. Default is NOT. -n, --no-escape No escape char '`'. Default is using it. -T, --thread-num=THREAD_NUM Number of thread for dump in file. Default is - 5. + 8. + -C, --cloud=CLOUD_DSN specify a DSN to access TDengine cloud service + -R, --restful Use RESTful interface to connect TDengine + -t, --timeout=SECONDS The timeout seconds for websocket to interact. -g, --debug Print debug info. -?, --help Give this help list --usage Give a short usage message -- GitLab From 5609bfc4d87ee660eed92942a8a2fc92b02f2257 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 4 Aug 2022 14:36:25 +0800 Subject: [PATCH 302/380] feat(rpc): probe msg sendmsgtosever always return ok --- src/client/src/tscServer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 6a59830331..c753ee3160 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -400,7 +400,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { // call check if have query doing if(pObj->sqlList) { // have queries executing - //checkBrokenQueries(pObj); + checkBrokenQueries(pObj); } } @@ -449,12 +449,12 @@ int tscSendMsgToServer(SSqlObj *pSql) { if(rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid)) { - if(pSql->cmd.command != TSDB_SQL_HB) + if(pSql->cmd.command < TSDB_SQL_HB) rpcSaveSendInfo(pSql->rpcRid, &pSql->pPrevContext); return TSDB_CODE_SUCCESS; } - return TSDB_CODE_FAILED; + return TSDB_CODE_SUCCESS; } // handle three situation -- GitLab From f969b22778d5f9c7a95dcb2ce0e7508d0bf187a8 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 5 Aug 2022 16:21:22 +0800 Subject: [PATCH 303/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index c9cc20f184..8a5e336198 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit c9cc20f1846fac95dba98e660f4a5fffce322d45 +Subproject commit 8a5e336198bf199a0f57dda1e533786490d22dd5 -- GitLab From 0969d880eba1bfa63647e6e101472a83832777d4 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 5 Aug 2022 16:51:15 +0800 Subject: [PATCH 304/380] feat: update taostools for2.6 (#15773) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index c9cc20f184..8a5e336198 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit c9cc20f1846fac95dba98e660f4a5fffce322d45 +Subproject commit 8a5e336198bf199a0f57dda1e533786490d22dd5 -- GitLab From a8c0e03f9640ad608fdeecb9b1fb66d15ce9bfc3 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 6 Aug 2022 18:27:23 +0800 Subject: [PATCH 305/380] feat: update taos-tools 3c7dafe for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 8a5e336198..3c7dafeea3 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 8a5e336198bf199a0f57dda1e533786490d22dd5 +Subproject commit 3c7dafeea3e558968165b73bee0f51024898e3da -- GitLab From c1bc307a38928d12f4af0ca47bfcf70697fbd2f6 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Sat, 6 Aug 2022 23:41:54 +0800 Subject: [PATCH 306/380] feat: update taostools 3c7dafe for2.6 (#15814) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 8a5e336198..3c7dafeea3 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 8a5e336198bf199a0f57dda1e533786490d22dd5 +Subproject commit 3c7dafeea3e558968165b73bee0f51024898e3da -- GitLab From 678560406f113c0552f69e87b37437cfde82c5b0 Mon Sep 17 00:00:00 2001 From: Yang Zhao Date: Tue, 9 Aug 2022 10:07:16 +0800 Subject: [PATCH 307/380] docs: fix taosbenchmark query sql (#15873) * docs: fix taosbenchmark query sql * few more sections Co-authored-by: Shuduo Sang --- docs/zh/05-get-started/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zh/05-get-started/index.md b/docs/zh/05-get-started/index.md index 818027174e..bdb17aef36 100644 --- a/docs/zh/05-get-started/index.md +++ b/docs/zh/05-get-started/index.md @@ -132,7 +132,7 @@ Query OK, 2 row(s) in set (0.003128s) taosBenchmark ``` -该命令将在数据库 test 下面自动创建一张超级表 meters,该超级表下有 1 万张表,表名为 "d0" 到 "d9999",每张表有 1 万条记录,每条记录有 (ts, current, voltage, phase) 四个字段,时间戳从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:40:09 999",每张表带有标签 location 和 groupId,groupId 被设置为 1 到 10, location 被设置为 "California.SanFrancisco" 或者 "California.LosAngeles"。 +该命令将在数据库 test 下面自动创建一张超级表 meters,该超级表下有 1 万张表,表名为 "d0" 到 "d9999",每张表有 1 万条记录,每条记录有 (ts, current, voltage, phase) 四个字段,时间戳从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:40:09 999",每张表带有标签 location 和 groupId,groupId 被设置为 1 到 10, location 被设置为 "San Francisco" 或者 "Los Angeles"等城市名称。 这条命令很快完成 1 亿条记录的插入。具体时间取决于硬件性能,即使在一台普通的 PC 服务器往往也仅需十几秒。 @@ -154,10 +154,10 @@ taos> select count(*) from test.meters; taos> select avg(current), max(voltage), min(phase) from test.meters; ``` -查询 location="California.SanFrancisco" 的记录总条数: +查询 location="San Francisco" 的记录总条数: ```sql -taos> select count(*) from test.meters where location="California.SanFrancisco"; +taos> select count(*) from test.meters where location="San Francisco"; ``` 查询 groupId=10 的所有记录的平均值、最大值、最小值等: -- GitLab From 909b02e008d2e940b13e77d5429e0b1582ac5120 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Tue, 9 Aug 2022 14:04:57 +0800 Subject: [PATCH 308/380] fix: count the number of aligned time intervals properly --- src/os/src/detail/osTime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 3590703695..45f630e1eb 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -573,7 +573,7 @@ int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char skey = tmp; } if (unit != 'n' && unit != 'y') { - return (int32_t)((ekey - skey) / interval); + return (int32_t)(ekey/interval - skey/interval); } skey /= (int64_t)(TSDB_TICK_PER_SECOND(precision)); @@ -592,7 +592,7 @@ int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char interval *= 12; } - return (emon - smon) / (int32_t)interval; + return (int32_t)(emon/interval - smon/interval); } int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision) { -- GitLab From 6941eecab0d0f5331a7b8bb8e08bf5c767e4de20 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Tue, 9 Aug 2022 18:50:16 +0800 Subject: [PATCH 309/380] fix: consider local timezone offset during computing the number of time intervals --- src/os/src/detail/osTime.c | 8 +++++--- src/query/src/qFill.c | 3 --- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 45f630e1eb..7a60256220 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -565,15 +565,17 @@ int64_t taosTimeSub(int64_t t, int64_t duration, char unit, int32_t precision) { return (int64_t)(mktime(&tm) * TSDB_TICK_PER_SECOND(precision)); } - int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision) { if (ekey < skey) { int64_t tmp = ekey; ekey = skey; skey = tmp; } + + int64_t tz_offset = -1 * timezone * TSDB_TICK_PER_SECOND(precision); + if (unit != 'n' && unit != 'y') { - return (int32_t)(ekey/interval - skey/interval); + return (int32_t)((ekey+tz_offset)/interval - (skey+tz_offset)/interval) + 1; } skey /= (int64_t)(TSDB_TICK_PER_SECOND(precision)); @@ -592,7 +594,7 @@ int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char interval *= 12; } - return (int32_t)(emon/interval - smon/interval); + return (int32_t)(emon/interval - smon/interval) + 1; } int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision) { diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index 1f4bbed831..9a90a27daf 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -463,7 +463,6 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) pFillInfo->interval.sliding, pFillInfo->interval.slidingUnit, pFillInfo->precision); - numOfRes += 1; if(numOfRes < numOfRows || pFillInfo->currentKey < lastKey) { // set currentKey max pFillInfo->currentKey = tsList[0]; @@ -504,7 +503,6 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma pFillInfo->interval.sliding, pFillInfo->interval.slidingUnit, pFillInfo->precision); - numOfRes += 1; assert(numOfRes >= numOfRows); } else { // reach the end of data if ((ekey1 < pFillInfo->currentKey && FILL_IS_ASC_FILL(pFillInfo)) || @@ -517,7 +515,6 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma pFillInfo->interval.sliding, pFillInfo->interval.slidingUnit, pFillInfo->precision); - numOfRes += 1; } return (numOfRes > maxNumOfRows) ? maxNumOfRows : numOfRes; -- GitLab From fef28ad04f705be27f8b248c44d07996c5312bfd Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Tue, 9 Aug 2022 19:06:31 +0800 Subject: [PATCH 310/380] fix: link against _timezone for win OS in taosTimeCountInterval --- src/os/src/detail/osTime.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 7a60256220..207222f79e 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -572,6 +572,12 @@ int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char skey = tmp; } +#ifdef _MSC_VER +#if _MSC_VER >= 1900 + int64_t timezone = _timezone; +#endif +#endif + int64_t tz_offset = -1 * timezone * TSDB_TICK_PER_SECOND(precision); if (unit != 'n' && unit != 'y') { -- GitLab From ed3d4fdb99837b8e568377480dd14fdf02b412c9 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 9 Aug 2022 19:13:33 +0800 Subject: [PATCH 311/380] feat: update taos-tools for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 3c7dafeea3..2d68404df8 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 3c7dafeea3e558968165b73bee0f51024898e3da +Subproject commit 2d68404df83d75a5fea26d5bae8a7a1fb53b26d0 -- GitLab From 92835da81ba6fc0d880e3f681000defa3300da49 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 9 Aug 2022 20:35:54 +0800 Subject: [PATCH 312/380] feat: update taostools for2.6 (#15912) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 3c7dafeea3..2d68404df8 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 3c7dafeea3e558968165b73bee0f51024898e3da +Subproject commit 2d68404df83d75a5fea26d5bae8a7a1fb53b26d0 -- GitLab From 37e2ce3d363dbda3c542a18a04fb499da011b7c1 Mon Sep 17 00:00:00 2001 From: Zhengmao Zhu <70138133+fenghuazzm@users.noreply.github.com> Date: Wed, 10 Aug 2022 12:03:25 +0800 Subject: [PATCH 313/380] Update 14-DBeaver.mdx --- docs/zh/20-third-party/14-DBeaver.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zh/20-third-party/14-DBeaver.mdx b/docs/zh/20-third-party/14-DBeaver.mdx index 7685de4dd8..bbaa468f87 100644 --- a/docs/zh/20-third-party/14-DBeaver.mdx +++ b/docs/zh/20-third-party/14-DBeaver.mdx @@ -12,17 +12,17 @@ DBeaver 是一款流行、开源的数据库管理工具以及 SQL 客户端, ## 前置条件 1. DBeaver 依赖 Java (JDK) 11 ,不过其安装包中已包含。可选安装 Maven、Git。 2. 已安装并启动了 TDengine。 -3. 若使用 TSDBDriver 驱动类连接请在本地安装 TDengine 客户端。 -4. 若使用 RestfulDriver 驱动类连接 TDengine,请确保 taosAdapter 已经正常运行。 +3. 若使用原生连接(选择 TSDBDriver 驱动类),请在本地安装 TDengine 客户端。 +4. 若使用 REST 连接(选择 RestfulDriver 驱动类),请确保 taosAdapter 已经正常运行。 ## 配置步骤 - 可以克隆 DBeaver 在 [GitHub](https://github.com/dbeaver/dbeaver) 上的源码,执行 `mvn package`,也可以直接下载打包好的安装包。此处选择直接下载安装包。 -- 在 GitHub DBeaver 仓库的 [Releases](https://github.com/dbeaver/dbeaver/releases) 处下载对应版本的 DBeaver,比如系统为 macOS,处理器芯片是 M1 ,此处下载 dbeaver-ce-22.1.2-macos-aarch64.dmg 进行安装。 +- 在 GitHub DBeaver 仓库的 [Releases](https://github.com/dbeaver/dbeaver/releases) 处下载对应版本的 DBeaver,比如系统为 macOS,处理器芯片是 M1 ,此处下载 dbeaver-ce-22.1.2-macos-aarch64.dmg 进行安装。推荐使用 22.1.2 版本的 DBeaver,后续版本未进行验证。 - 点击数据库标签,选择驱动管理器: ![image](https://user-images.githubusercontent.com/70138133/181191577-7bb91c96-b4fc-455f-9f6c-545993f0a445.png) -- 新建驱动,选择 TDengine 的 JDBC Connector 驱动包(其中的 dist.jar 包),此驱动包可以下载或者自行编译、打包,参考 [IDEA-源码编译 JDBC-Connector](https://docs.taosdata.com/third-party/IDEA#%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91-jdbc-connector): +- 新建驱动,选择 TDengine 的 JDBC Connector 驱动包(其中的 dist.jar 包),此驱动包可以下载或者自行编译、打包,参考 [IDEA-源码编译 JDBC-Connector](../IDEA/#%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91-jdbc-connector): ![image](https://user-images.githubusercontent.com/70138133/181191709-fcc3faa3-cfe9-4b0b-8c1b-5074c9411c8b.png) -- GitLab From 0125cbe7a315eb3203ef7fd05c604e0b93e1fe33 Mon Sep 17 00:00:00 2001 From: Bo Xiao Date: Wed, 10 Aug 2022 15:28:26 +0800 Subject: [PATCH 314/380] Update cpp.mdx --- docs/zh/14-reference/03-connector/cpp.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/14-reference/03-connector/cpp.mdx b/docs/zh/14-reference/03-connector/cpp.mdx index aba1d6c717..12cea8579b 100644 --- a/docs/zh/14-reference/03-connector/cpp.mdx +++ b/docs/zh/14-reference/03-connector/cpp.mdx @@ -280,7 +280,7 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多 2. 调用 `taos_stmt_prepare()` 解析 INSERT 语句; 3. 如果 INSERT 语句中预留了表名但没有预留 TAGS,那么调用 `taos_stmt_set_tbname()` 来设置表名; 4. 如果 INSERT 语句中既预留了表名又预留了 TAGS(例如 INSERT 语句采取的是自动建表的方式),那么调用 `taos_stmt_set_tbname_tags()` 来设置表名和 TAGS 的值; -5. 调用 `taos_stmt_bind_param_batch()` 以多列的方式设置 VALUES 的值,或者调用 `taos_stmt_bind_param()` 以单行的方式设置 VALUES 的值; +5. 调用 `taos_stmt_bind_param_batch()` 以多行的方式设置 VALUES 的值,或者调用 `taos_stmt_bind_param()` 以单行的方式设置 VALUES 的值; 6. 调用 `taos_stmt_add_batch()` 把当前绑定的参数加入批处理; 7. 可以重复第 3 ~ 6 步,为批处理加入更多的数据行; 8. 调用 `taos_stmt_execute()` 执行已经准备好的批处理指令; -- GitLab From acca0882a53c4aa842877156c9bb97f04d59969e Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 10 Aug 2022 17:45:59 +0800 Subject: [PATCH 315/380] fix(query): subscribe all child tables skey calc error --- src/query/src/qExecutor.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 28d3d60727..11b6651c6c 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -5320,15 +5320,17 @@ int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr } static void doTableQueryInfoTimeWindowCheck(SQueryAttr* pQueryAttr, STableQueryInfo* pTableQueryInfo) { + // + // current subscribe can not ensure pTableQueryInfo->lastKey >= pTableQueryInfo->win.skey, so remove this condition check + // reason is subscribe calc query windows skey is all child table smallest skey, so bigest child table block->skey maybe large than this table's pTableQueryInfo->win.skey + // if (QUERY_IS_ASC_QUERY(pQueryAttr)) { assert( (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) && - (pTableQueryInfo->lastKey >= pTableQueryInfo->win.skey) && (pTableQueryInfo->win.skey >= pQueryAttr->window.skey && pTableQueryInfo->win.ekey <= pQueryAttr->window.ekey)); } else { assert( (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) && - (pTableQueryInfo->lastKey <= pTableQueryInfo->win.skey) && (pTableQueryInfo->win.skey <= pQueryAttr->window.skey && pTableQueryInfo->win.ekey >= pQueryAttr->window.ekey)); } } @@ -5430,6 +5432,24 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { break; } + // check windows condition + int64_t skey = (*pTableQueryInfo)->win.skey; + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { + // ASC + if ( skey > pBlock->info.window.ekey ) { + qWarn(" pTableQueryInfo skey(%" PRId64 ") > pBlock ekey(%" PRId64 "), so remove this block. pBlock skey=% tid=%d" PRId64, + skey, pBlock->info.window.ekey, pBlock->info.window.skey, pBlock->info.tid); + continue; + } + } else { + // DESC + if ( skey < pBlock->info.window.skey ) { + qWarn(" pTableQueryInfo skey(%" PRId64 ") < pBlock skey(%" PRId64 "), so remove this block. pBlock ekey=% tid=%d" PRId64, + skey, pBlock->info.window.skey, pBlock->info.window.ekey, pBlock->info.tid); + continue; + } + } + pRuntimeEnv->current = *pTableQueryInfo; doTableQueryInfoTimeWindowCheck(pQueryAttr, *pTableQueryInfo); -- GitLab From 4a2ca48f9105c01c04c370eba5e62712343cfbcb Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 10 Aug 2022 18:51:50 +0800 Subject: [PATCH 316/380] fix(query): subscribe fix build error --- src/query/src/qExecutor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 11b6651c6c..1be4334d19 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -5437,14 +5437,14 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { if (QUERY_IS_ASC_QUERY(pQueryAttr)) { // ASC if ( skey > pBlock->info.window.ekey ) { - qWarn(" pTableQueryInfo skey(%" PRId64 ") > pBlock ekey(%" PRId64 "), so remove this block. pBlock skey=% tid=%d" PRId64, + qWarn(" pTableQueryInfo skey(%" PRId64 ") > pBlock ekey(%" PRId64 "), so remove this block. pBlock skey=%" PRId64 " tid=%d", skey, pBlock->info.window.ekey, pBlock->info.window.skey, pBlock->info.tid); continue; } } else { // DESC if ( skey < pBlock->info.window.skey ) { - qWarn(" pTableQueryInfo skey(%" PRId64 ") < pBlock skey(%" PRId64 "), so remove this block. pBlock ekey=% tid=%d" PRId64, + qWarn(" pTableQueryInfo skey(%" PRId64 ") < pBlock skey(%" PRId64 "), so remove this block. pBlock ekey=%" PRId64 "tid=%d", skey, pBlock->info.window.skey, pBlock->info.window.ekey, pBlock->info.tid); continue; } -- GitLab From 00cd24711a4726122a024abad19de0bb3dda094e Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 10 Aug 2022 19:17:19 +0800 Subject: [PATCH 317/380] fix(query): subscribe remove block check block window --- src/query/src/qExecutor.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 1be4334d19..3edd19e016 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -5433,21 +5433,25 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { } // check windows condition - int64_t skey = (*pTableQueryInfo)->win.skey; - if (QUERY_IS_ASC_QUERY(pQueryAttr)) { - // ASC - if ( skey > pBlock->info.window.ekey ) { - qWarn(" pTableQueryInfo skey(%" PRId64 ") > pBlock ekey(%" PRId64 "), so remove this block. pBlock skey=%" PRId64 " tid=%d", - skey, pBlock->info.window.ekey, pBlock->info.window.skey, pBlock->info.tid); - continue; - } - } else { - // DESC - if ( skey < pBlock->info.window.skey ) { - qWarn(" pTableQueryInfo skey(%" PRId64 ") < pBlock skey(%" PRId64 "), so remove this block. pBlock ekey=%" PRId64 "tid=%d", - skey, pBlock->info.window.skey, pBlock->info.window.ekey, pBlock->info.tid); - continue; - } + if (pBlock->info.window.skey != INT64_MIN && pBlock->info.window.skey != INT64_MAX && + pBlock->info.window.ekey != INT64_MIN && pBlock->info.window.ekey != INT64_MAX) { + // normal block not specail block like last_row + int64_t skey = (*pTableQueryInfo)->win.skey; + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { + // ASC + if ( skey > pBlock->info.window.ekey ) { + qWarn(" pTableQueryInfo skey(%" PRId64 ") > pBlock ekey(%" PRId64 "), so remove this block. pBlock skey=%" PRId64 " tid=%d", + skey, pBlock->info.window.ekey, pBlock->info.window.skey, pBlock->info.tid); + continue; + } + } else { + // DESC + if ( skey < pBlock->info.window.skey ) { + qWarn(" pTableQueryInfo skey(%" PRId64 ") < pBlock skey(%" PRId64 "), so remove this block. pBlock ekey=%" PRId64 "tid=%d", + skey, pBlock->info.window.skey, pBlock->info.window.ekey, pBlock->info.tid); + continue; + } + } } pRuntimeEnv->current = *pTableQueryInfo; -- GitLab From c6cc1b3c1242139d34b06f6060d2e03f4c44ad0d Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 10 Aug 2022 23:21:45 +0800 Subject: [PATCH 318/380] feat: update taos-tools 57bdfbf for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 2d68404df8..57bdfbfbcd 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 2d68404df83d75a5fea26d5bae8a7a1fb53b26d0 +Subproject commit 57bdfbfbcd8b4f8a3d38ab8eb9fd44d372a65911 -- GitLab From 5da8a0c4f87665a9f35a9550927b44c39b2e0273 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 11 Aug 2022 10:18:06 +0800 Subject: [PATCH 319/380] feat: update taostools for2.6 (#15961) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 57bdfbf for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 2d68404df8..57bdfbfbcd 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 2d68404df83d75a5fea26d5bae8a7a1fb53b26d0 +Subproject commit 57bdfbfbcd8b4f8a3d38ab8eb9fd44d372a65911 -- GitLab From 4b770b2bebba3458171c23af27084292ffff6836 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 11 Aug 2022 18:55:41 +0800 Subject: [PATCH 320/380] feat: update taos-tools 11d23e5 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 57bdfbfbcd..11d23e5d12 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 57bdfbfbcd8b4f8a3d38ab8eb9fd44d372a65911 +Subproject commit 11d23e5d121ee6a3ad1451795208ab9dcf12fe4f -- GitLab From 7b2b192e1aca956ad066ae782df716be26d681ea Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 11 Aug 2022 19:54:10 +0800 Subject: [PATCH 321/380] feat: update taostools for2.6 (#16006) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 57bdfbf for 2.6 * feat: update taos-tools 11d23e5 for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 57bdfbfbcd..11d23e5d12 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 57bdfbfbcd8b4f8a3d38ab8eb9fd44d372a65911 +Subproject commit 11d23e5d121ee6a3ad1451795208ab9dcf12fe4f -- GitLab From fbe70bb6d3a9a553a00f151e78fe65f6198da1d4 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 11 Aug 2022 23:25:41 +0800 Subject: [PATCH 322/380] feat: update taos-tools 43924b8 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 11d23e5d12..43924b8006 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 11d23e5d121ee6a3ad1451795208ab9dcf12fe4f +Subproject commit 43924b8006c85bc67f0ce3b7cc294425a80c2ee9 -- GitLab From 20a52bc3adc8fde23f2fe5ed915332694a79ba3e Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 12 Aug 2022 07:50:17 +0800 Subject: [PATCH 323/380] feat: update taostools 43924b8 for2.6 (#16020) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 57bdfbf for 2.6 * feat: update taos-tools 11d23e5 for 2.6 * feat: update taos-tools 43924b8 for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 11d23e5d12..43924b8006 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 11d23e5d121ee6a3ad1451795208ab9dcf12fe4f +Subproject commit 43924b8006c85bc67f0ce3b7cc294425a80c2ee9 -- GitLab From c827475a9092986a7f2edea83dd42696bba67282 Mon Sep 17 00:00:00 2001 From: Chait Diwadkar <94201190+cdiwadkar16@users.noreply.github.com> Date: Thu, 11 Aug 2022 18:00:12 -0700 Subject: [PATCH 324/380] docs:cdiwadkar16-patch-1 - Create 12-jupyterlab.md This is an additional doc to show how to connect JupyterLab with Python kernel to TDengine. --- docs/en/20-third-party/12-jupyterlab.md | 98 +++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 docs/en/20-third-party/12-jupyterlab.md diff --git a/docs/en/20-third-party/12-jupyterlab.md b/docs/en/20-third-party/12-jupyterlab.md new file mode 100644 index 0000000000..fbd7e530f0 --- /dev/null +++ b/docs/en/20-third-party/12-jupyterlab.md @@ -0,0 +1,98 @@ +--- +sidebar_label: JupyterLab +title: Connect JupyterLab to TDengine +--- + +JupyterLab is the next generation of the ubiquitous Jupyter Notebook. In this note we show you how to install the TDengine Python connector to connect to TDengine in JupyterLab. You can then insert data and perform queries against the TDengine instance within JupyterLab. + +## Install JupyterLab +Installing JupyterLab is very easy. Installation instructions can be found at: + +https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html. + +If you don't feel like clicking on the link here are the instructions. +Jupyter's preferred Python package manager is pip, so we show the instructions for pip. +You can also use **conda** or **pipenv** if you are managing Python environments. +```` +pip install jupyterlab +```` + +For **conda** you can run: +```` +conda install -c conda-forge jupyterlab +```` + +For **pipenv** you can run: +```` +pipenv install jupyterlab +pipenv shell +```` + +## Run JupyterLab +You can start JupyterLab from the command line by running: +```` +jupyter lab +```` +This will automatically launch your default browser and connect to your JupyterLab instance, usually on port 8888. + +## Install the TDengine Python connector +You can now install the TDengine Python connector as follows. + +Start a new Python kernel in JupyterLab. + +If using **conda** run the following: +```` +# Install a conda package in the current Jupyter kernel +import sys +!conda install --yes --prefix {sys.prefix} taospy +```` +If using **pip** run the following: +```` +# Install a pip package in the current Jupyter kernel +import sys +!{sys.executable} -m pip install taospy +```` + +## Connect to TDengine +You can find detailed examples to use the Python connector, in the TDengine documentation here. +Once you have installed the TDengine Python connector in your JupyterLab kernel, the process of connecting to TDengine is the same as that you would use if you weren't using JupyterLab. +Each TDengine instance, has a database called "log" which has monitoring information about the TDengine instance. +In the "log" database there is a [supertable](https://docs.tdengine.com/taos-sql/stable/) called "disks_info". + +The structure of this table is as follows: +```` +taos> desc disks_info; + Field | Type | Length | Note | +================================================================================= + ts | TIMESTAMP | 8 | | + datadir_l0_used | FLOAT | 4 | | + datadir_l0_total | FLOAT | 4 | | + datadir_l1_used | FLOAT | 4 | | + datadir_l1_total | FLOAT | 4 | | + datadir_l2_used | FLOAT | 4 | | + datadir_l2_total | FLOAT | 4 | | + dnode_id | INT | 4 | TAG | + dnode_ep | BINARY | 134 | TAG | +Query OK, 9 row(s) in set (0.000238s) +```` + +The code below is used to fetch data from this table into a pandas DataFrame. + +```` +import sys +import taos +import pandas + +def sqlQuery(conn): + df: pandas.DataFrame = pandas.read_sql("select * from log.disks_info limit 500", conn) + print(df) + return df + +conn = taos.connect() + +result = sqlQuery(conn) + +print(result) +```` + +TDengine has connectors for various languages including Node.js, Go, PHP and there are kernels for these languages which can be found [here](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels). -- GitLab From 70615c07581a79a9d843dcca65a37efddf24de69 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 12 Aug 2022 16:30:52 +0800 Subject: [PATCH 325/380] fix(rpc): if req over, update lastalive time --- src/client/src/tscServer.c | 19 +++++++++++++++---- src/inc/trpc.h | 2 +- src/rpc/src/rpcMain.c | 7 +++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index c753ee3160..ef58bde228 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -282,7 +282,7 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { } // if return true, send probe connection msg to sever ok -bool sendProbeConnMsg(SSqlObj* pSql, int64_t stime) { +bool sendProbeConnMsg(SSqlObj* pSql, int64_t stime, bool *pReqOver) { if(stime == 0) { // not start , no need probe tscInfo("PROBE 0x%" PRIx64 " not start, no need probe.", pSql->self); @@ -318,7 +318,7 @@ bool sendProbeConnMsg(SSqlObj* pSql, int64_t stime) { return true; } - bool ret = rpcSendProbe(pSql->rpcRid, pSql->pPrevContext); + bool ret = rpcSendProbe(pSql->rpcRid, pSql->pPrevContext, pReqOver); tscInfo("PROBE 0x%" PRIx64 " send probe msg, ret=%d rpcRid=0x%" PRIx64, pSql->self, ret, pSql->rpcRid); return ret; } @@ -335,16 +335,22 @@ void checkBrokenQueries(STscObj *pTscObj) { } bool kill = false; + bool reqOver = false; int32_t numOfSub = pSql->subState.numOfSub; tscInfo("PROBE 0x%" PRIx64 " start checking sql alive, numOfSub=%d sql=%s stime=%" PRId64 " alive=%" PRId64 " rpcRid=0x%" PRIx64 \ ,pSql->self, numOfSub, pSql->sqlstr == NULL ? "" : pSql->sqlstr, pSql->stime, pSql->lastAlive, pSql->rpcRid); if (numOfSub == 0) { // no sub sql - if(!sendProbeConnMsg(pSql, pSql->stime)) { + if(!sendProbeConnMsg(pSql, pSql->stime, &reqOver)) { // need kill tscInfo("PROBE 0x%" PRIx64 " need break link done. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid); kill = true; } + + if (reqOver) { + // current request is finished over, so upate alive to now + pSql->lastAlive = taosGetTimestampMs(); + } } else { // lock subs pthread_mutex_lock(&pSql->subState.mutex); @@ -354,13 +360,18 @@ void checkBrokenQueries(STscObj *pTscObj) { SSqlObj *pSubSql = pSql->pSubs[i]; if(pSubSql) { tscInfo("PROBE 0x%" PRIx64 " sub sql app is 0x%" PRIx64, pSql->self, pSubSql->self); - if(!sendProbeConnMsg(pSubSql, pSql->stime)) { + if(!sendProbeConnMsg(pSubSql, pSql->stime, &reqOver)) { // need kill tscInfo("PROBE 0x%" PRIx64 " i=%d sub app=0x%" PRIx64 " need break link done. rpcRid=0x%" PRIx64, pSql->self, i, pSubSql->self, pSubSql->rpcRid); kill = true; break; } } + + if (reqOver) { + // current request is finished over, so upate alive to now + pSubSql->lastAlive = taosGetTimestampMs(); + } } } // unlock diff --git a/src/inc/trpc.h b/src/inc/trpc.h index 59908253c2..db29785699 100644 --- a/src/inc/trpc.h +++ b/src/inc/trpc.h @@ -94,7 +94,7 @@ int rpcReportProgress(void *pConn, char *pCont, int contLen); void rpcCancelRequest(int64_t rid); int32_t rpcUnusedSession(void * rpcInfo, bool bLock); // send rpc Refid connection probe alive message -bool rpcSendProbe(int64_t rpcRid, void* pPrevContext); +bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, bool *pReqOver); // after sql request send , save conn info bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext); diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index bcc759f845..e0c0b1ea8c 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1805,7 +1805,7 @@ bool doRpcSendProbe(SRpcConn *pConn) { } // send server syn -bool rpcSendProbe(int64_t rpcRid, void* pPrevContext) { +bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, bool *pReqOver) { // return false can kill query bool ret = false; if(rpcRid < 0) { @@ -1828,7 +1828,10 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext) { // conn same if(pContext->pConn == NULL) { - tInfo("PROBE rpcRid=0x%" PRIx64 " connect obj is NULL. ", rpcRid); + tInfo("PROBE rpcRid=0x%" PRIx64 " reqContext->pConn is NULL. The req is finished.", rpcRid); + if (pReqOver) + pReqOver = true; + ret = true; goto _END; } else if (pContext->pConn != pContext->sendInfo.pConn) { -- GitLab From e0fb57aaa86c761f9ab4df2d82acfb65d9a2d677 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 12 Aug 2022 16:34:22 +0800 Subject: [PATCH 326/380] fix(rpc): if req over, update lastalive time1 --- src/rpc/src/rpcMain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index e0c0b1ea8c..501421b483 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1830,8 +1830,8 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, bool *pReqOver) { if(pContext->pConn == NULL) { tInfo("PROBE rpcRid=0x%" PRIx64 " reqContext->pConn is NULL. The req is finished.", rpcRid); if (pReqOver) - pReqOver = true; - + *pReqOver = true; + ret = true; goto _END; } else if (pContext->pConn != pContext->sendInfo.pConn) { -- GitLab From 421869c4d31f0260b6e84e03824f381d4d4e91f6 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Fri, 12 Aug 2022 17:31:16 +0800 Subject: [PATCH 327/380] doc: fix broken links in 2.4 --- docs/zh/02-intro.md | 6 +++--- docs/zh/05-get-started/index.md | 2 +- docs/zh/07-develop/04-query-data/index.mdx | 2 +- docs/zh/12-taos-sql/12-interval.md | 2 +- docs/zh/21-tdinternal/01-arch.md | 2 +- docs/zh/21-tdinternal/03-taosd.md | 2 +- docs/zh/25-application/03-immigrate.md | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/zh/02-intro.md b/docs/zh/02-intro.md index 191e1cbcc2..c9f4c476a2 100644 --- a/docs/zh/02-intro.md +++ b/docs/zh/02-intro.md @@ -16,9 +16,9 @@ TDengine的主要功能如下: 3. 支持[各种查询](/develop/query-data),包括聚合查询、嵌套查询、降采样查询、插值等 4. 支持[用户自定义函数](/develop/udf) 5. 支持[缓存](/develop/cache),将每张表的最后一条记录缓存起来,这样无需 Redis -6. 支持[连续查询](/develop/continuous-query)(Continuous Query) -7. 支持[数据订阅](/develop/subscribe),而且可以指定过滤条件 -8. 支持[集群](/cluster/),可以通过多节点进行水平扩展,并通过多副本实现高可靠 +6. 支持[连续查询](../develop/continuous-query)(Continuous Query) +7. 支持[数据订阅](../develop/subscribe),而且可以指定过滤条件 +8. 支持[集群](../cluster/),可以通过多节点进行水平扩展,并通过多副本实现高可靠 9. 提供[命令行程序](/reference/taos-shell),便于管理集群,检查系统状态,做即席查询 10. 提供多种数据的[导入](/operation/import)、[导出](/operation/export) 11. 支持对[TDengine 集群本身的监控](/operation/monitor) diff --git a/docs/zh/05-get-started/index.md b/docs/zh/05-get-started/index.md index bdb17aef36..ee7ee57698 100644 --- a/docs/zh/05-get-started/index.md +++ b/docs/zh/05-get-started/index.md @@ -36,7 +36,7 @@ docker exec -it bash 然后就可以执行相关的 Linux 命令操作和访问 TDengine -详细操作方法请参照 [通过 Docker 快速体验 TDengine](/train-faq/docker)。 +详细操作方法请参照 [通过 Docker 快速体验 TDengine](../../train-faq/docker)。 :::info 从 2.4.0.10 开始,除 taosd 以外,Docker 镜像还包含:taos、taosAdapter、taosdump、taosBenchmark、TDinsight 安装脚本和示例代码。启动 Docker 容器时,将同时启动 taosAdapter 和 taosd,实现对 RESTful 的支持。 diff --git a/docs/zh/07-develop/04-query-data/index.mdx b/docs/zh/07-develop/04-query-data/index.mdx index 824f36ef2f..50572c6e10 100644 --- a/docs/zh/07-develop/04-query-data/index.mdx +++ b/docs/zh/07-develop/04-query-data/index.mdx @@ -120,7 +120,7 @@ Query OK, 5 row(s) in set (0.001521s) 如果一个时间间隔里,没有采集的数据,TDengine 还提供插值计算的功能。 -语法规则细节请见 [TAOS SQL 的按时间窗口切分聚合](/taos-sql/interval) 章节。 +语法规则细节请见 [TAOS SQL 的按时间窗口切分聚合](../../../taos-sql/interval) 章节。 ## 示例代码 diff --git a/docs/zh/12-taos-sql/12-interval.md b/docs/zh/12-taos-sql/12-interval.md index b0619ea5ce..ac273a6d8a 100644 --- a/docs/zh/12-taos-sql/12-interval.md +++ b/docs/zh/12-taos-sql/12-interval.md @@ -93,7 +93,7 @@ SELECT function_list FROM stb_name ::: -时间聚合也常被用于连续查询场景,可以参考文档 [连续查询(Continuous Query)](/develop/continuous-query)。 +时间聚合也常被用于连续查询场景,可以参考文档 [连续查询(Continuous Query)](../../develop/continuous-query)。 ## 示例 diff --git a/docs/zh/21-tdinternal/01-arch.md b/docs/zh/21-tdinternal/01-arch.md index 507ccea629..f1fd75d4f3 100644 --- a/docs/zh/21-tdinternal/01-arch.md +++ b/docs/zh/21-tdinternal/01-arch.md @@ -171,7 +171,7 @@ Vnode 会保持一个数据版本号(version),对内存数据进行持久 3. 在线的虚拟节点数过半,而且有虚拟节点是 slave 的话,该虚拟节点自动成为 master 4. 对于 2 和 3,如果多个虚拟节点满足成为 master 的要求,那么虚拟节点组的节点列表里,最前面的选为 master -更多的关于数据复制的流程,请见[《TDengine 2.0 数据复制模块设计》](/tdinternal/replica/)。 +更多的关于数据复制的流程,请见[《TDengine 2.0 数据复制模块设计》](../replica/)。 ### 同步复制 diff --git a/docs/zh/21-tdinternal/03-taosd.md b/docs/zh/21-tdinternal/03-taosd.md index 9470311f94..92677e5700 100644 --- a/docs/zh/21-tdinternal/03-taosd.md +++ b/docs/zh/21-tdinternal/03-taosd.md @@ -94,7 +94,7 @@ TSDB 中存储的元数据包含属于其所在的 vnode 中表的类型,schem 该模块实现数据的多副本复制,包括 vnode 与 mnode 的数据复制,支持异步和同步两种复制方式,以满足 meta data 与时序数据不同复制的需求。因为它为 mnode 与 vnode 共享,系统为 mnode 副本预留了一个特殊的 vgroup ID:1。因此 vnode group 的 ID 是从 2 开始的。 -每个 vnode/mnode 模块实例会有一对应的 sync 模块实例,他们是一一对应的。详细设计请见[TDengine 2.0 数据复制模块设计](/tdinternal/replica/) +每个 vnode/mnode 模块实例会有一对应的 sync 模块实例,他们是一一对应的。详细设计请见[TDengine 2.0 数据复制模块设计](../replica/) ## WAL 模块 diff --git a/docs/zh/25-application/03-immigrate.md b/docs/zh/25-application/03-immigrate.md index d1c9caea09..320d26e332 100644 --- a/docs/zh/25-application/03-immigrate.md +++ b/docs/zh/25-application/03-immigrate.md @@ -411,7 +411,7 @@ FQDN、firstEp、secondEP、dataDir、logDir、tmpDir、serverPort。各参数 按照相同的步骤,在需要运行的节点上设置参数,并启动 `taosd` 服务,然后添加 Dnode 到集群中。 -最后启动 `taos` 命令行程序,执行命令 `show dnodes`,如果能看到所有的加入集群的节点,那么集群顺利搭建完成。具体的操作流程及注意事项,请参阅文档《[TDengine 集群安装、管理](/cluster/)》 +最后启动 `taos` 命令行程序,执行命令 `show dnodes`,如果能看到所有的加入集群的节点,那么集群顺利搭建完成。具体的操作流程及注意事项,请参阅文档《[TDengine 集群安装、管理](../../cluster/)》 ## 附录 4: 超级表名称 -- GitLab From e82dae05de19e711e0a03a0ab732438acd0b009e Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Fri, 12 Aug 2022 17:48:38 +0800 Subject: [PATCH 328/380] doc: fix broken link --- docs/zh/25-application/03-immigrate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/25-application/03-immigrate.md b/docs/zh/25-application/03-immigrate.md index 320d26e332..6978d47754 100644 --- a/docs/zh/25-application/03-immigrate.md +++ b/docs/zh/25-application/03-immigrate.md @@ -407,7 +407,7 @@ TDengine 提供了丰富的帮助文档说明集群安装、部署的诸多方 为确保系统能够正常获取运行的必要信息。请在服务端正确设置以下关键参数: -FQDN、firstEp、secondEP、dataDir、logDir、tmpDir、serverPort。各参数的具体含义及设置的要求,可参见文档《[TDengine 集群安装、管理](/cluster/)》 +FQDN、firstEp、secondEP、dataDir、logDir、tmpDir、serverPort。各参数的具体含义及设置的要求,可参见文档《[TDengine 集群安装、管理](../../cluster/)》 按照相同的步骤,在需要运行的节点上设置参数,并启动 `taosd` 服务,然后添加 Dnode 到集群中。 -- GitLab From d64c276013bd380bbee81adbc8335e2e3735c479 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Fri, 12 Aug 2022 17:52:42 +0800 Subject: [PATCH 329/380] doc: fix broken links --- docs/zh/02-intro.md | 2 +- docs/zh/05-get-started/index.md | 2 +- docs/zh/07-develop/04-query-data/index.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zh/02-intro.md b/docs/zh/02-intro.md index c9f4c476a2..095ffa0372 100644 --- a/docs/zh/02-intro.md +++ b/docs/zh/02-intro.md @@ -3,7 +3,7 @@ title: 产品简介 toc_max_heading_level: 2 --- -TDengine 是一款高性能、分布式、支持 SQL 的时序数据库 (Database),其核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。TDengine 能被广泛运用于物联网、工业互联网、车联网、IT 运维、金融等领域。除核心的时序数据库 (Database) 功能外,TDengine 还提供[缓存](/develop/cache/)、[数据订阅](/develop/subscribe)、[流式计算](/develop/continuous-query)等大数据平台所需要的系列功能,最大程度减少研发和运维的复杂度。 +TDengine 是一款高性能、分布式、支持 SQL 的时序数据库 (Database),其核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。TDengine 能被广泛运用于物联网、工业互联网、车联网、IT 运维、金融等领域。除核心的时序数据库 (Database) 功能外,TDengine 还提供[缓存](/develop/cache/)、[数据订阅](../develop/subscribe)、[流式计算](../develop/continuous-query)等大数据平台所需要的系列功能,最大程度减少研发和运维的复杂度。 本章节介绍TDengine的主要功能、竞争优势、适用场景、与其他数据库的对比测试等等,让大家对TDengine有个整体的了解。 diff --git a/docs/zh/05-get-started/index.md b/docs/zh/05-get-started/index.md index ee7ee57698..cc2e5df80e 100644 --- a/docs/zh/05-get-started/index.md +++ b/docs/zh/05-get-started/index.md @@ -36,7 +36,7 @@ docker exec -it bash 然后就可以执行相关的 Linux 命令操作和访问 TDengine -详细操作方法请参照 [通过 Docker 快速体验 TDengine](../../train-faq/docker)。 +详细操作方法请参照 [通过 Docker 快速体验 TDengine](../train-faq/docker)。 :::info 从 2.4.0.10 开始,除 taosd 以外,Docker 镜像还包含:taos、taosAdapter、taosdump、taosBenchmark、TDinsight 安装脚本和示例代码。启动 Docker 容器时,将同时启动 taosAdapter 和 taosd,实现对 RESTful 的支持。 diff --git a/docs/zh/07-develop/04-query-data/index.mdx b/docs/zh/07-develop/04-query-data/index.mdx index 50572c6e10..58b6738f43 100644 --- a/docs/zh/07-develop/04-query-data/index.mdx +++ b/docs/zh/07-develop/04-query-data/index.mdx @@ -120,7 +120,7 @@ Query OK, 5 row(s) in set (0.001521s) 如果一个时间间隔里,没有采集的数据,TDengine 还提供插值计算的功能。 -语法规则细节请见 [TAOS SQL 的按时间窗口切分聚合](../../../taos-sql/interval) 章节。 +语法规则细节请见 [TAOS SQL 的按时间窗口切分聚合](../../taos-sql/interval) 章节。 ## 示例代码 -- GitLab From a336ce938d3fef19d7b3018d480ccd38eb0ed669 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 12 Aug 2022 19:13:31 +0800 Subject: [PATCH 330/380] fix(rpx): remove send data error, maybe sometime have error --- src/rpc/src/rpcMain.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 501421b483..bb2a384985 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1853,7 +1853,9 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, bool *pReqOver) { } // send syn - ret = doRpcSendProbe(pContext->pConn); + if (!doRpcSendProbe(pContext->pConn)) { + tError("PROBE rpcRid=0x%" PRIx64 " fd=%d rpc send probe data error.", rpcRid, fd); + } _END: // put back req context -- GitLab From a2c46f786979e4164a1b45a58f1cac1427f151e3 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 12 Aug 2022 19:16:53 +0800 Subject: [PATCH 331/380] fix(rpx): remove send data error, maybe sometime have error1 --- src/rpc/src/rpcMain.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index bb2a384985..dc69cb8905 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1856,6 +1856,7 @@ bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, bool *pReqOver) { if (!doRpcSendProbe(pContext->pConn)) { tError("PROBE rpcRid=0x%" PRIx64 " fd=%d rpc send probe data error.", rpcRid, fd); } + ret = true; _END: // put back req context -- GitLab From 3086f1fdc6b16692ea429f8845ee01c7e4c6ab96 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 12 Aug 2022 20:05:42 +0800 Subject: [PATCH 332/380] fix(rpc): if reqDver can not printlog --- src/client/src/tscServer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index ef58bde228..3f4e9864aa 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -319,7 +319,8 @@ bool sendProbeConnMsg(SSqlObj* pSql, int64_t stime, bool *pReqOver) { } bool ret = rpcSendProbe(pSql->rpcRid, pSql->pPrevContext, pReqOver); - tscInfo("PROBE 0x%" PRIx64 " send probe msg, ret=%d rpcRid=0x%" PRIx64, pSql->self, ret, pSql->rpcRid); + if (!(*pReqOver)) + tscInfo("PROBE 0x%" PRIx64 " send probe msg, ret=%d rpcRid=0x%" PRIx64, pSql->self, ret, pSql->rpcRid); return ret; } -- GitLab From a370d94857dc0b62c4379f96bd2aba3a8d9d28f8 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Tue, 16 Aug 2022 11:38:45 +0800 Subject: [PATCH 333/380] fix(query): check the upper boundary of startPos in hashIntervalAgg --- src/query/src/qExecutor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 3edd19e016..6ba582138c 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1704,7 +1704,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul while (1) { int32_t prevEndPos = (forwardStep - 1) * step + startPos; startPos = getNextQualifiedWindow(pQueryAttr, &nextWin, &pSDataBlock->info, tsCols, binarySearchForKey, prevEndPos); - if (startPos < 0) { + if (startPos < 0 || startPos >= pSDataBlock->info.rows) { break; } -- GitLab From e99f512e30db9ac6a1f598eb20c06eddb75632b3 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 16 Aug 2022 15:45:53 +0800 Subject: [PATCH 334/380] fix(rpc): insert data send failed --- src/client/src/tscServer.c | 5 +++-- src/client/src/tscSubquery.c | 3 ++- src/inc/taoserror.h | 1 + src/util/src/terror.c | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 3f4e9864aa..a2f6a92c6c 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -461,12 +461,13 @@ int tscSendMsgToServer(SSqlObj *pSql) { if(rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid)) { - if(pSql->cmd.command < TSDB_SQL_HB) + if(pSql->cmd.command == TSDB_SQL_SELECT) rpcSaveSendInfo(pSql->rpcRid, &pSql->pPrevContext); return TSDB_CODE_SUCCESS; } - return TSDB_CODE_SUCCESS; + tscError("0x%"PRIx64" rpc send data failed. msg=%s", pSql->self, taosMsg[pSql->cmd.msgType]); + return TSDB_CODE_TSC_SEND_DATA_FAILED; } // handle three situation diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index ab34d99bfc..09574e741f 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -3296,7 +3296,8 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) { // the param may be null, since it may be done by other query threads. and the asyncOnError may enter in this // function while kill query by a user. if (param == NULL) { - assert(code != TSDB_CODE_SUCCESS); + if(code != TSDB_CODE_SUCCESS) + tscError("tscRetrieveDataRes param is NULL, error code=%d", code); return; } diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 9f51952d28..fc387d331b 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -118,6 +118,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSC_RES_TOO_MANY TAOS_DEF_ERROR_CODE(0, 0x0227) //"Result set too large to be output") #define TSDB_CODE_TSC_INVALID_SCHEMA_VERSION TAOS_DEF_ERROR_CODE(0, 0x0228) //"invalid table schema version") #define TSDB_CODE_TSC_TOO_MANY_SML_LINES TAOS_DEF_ERROR_CODE(0, 0x0229) //"too many lines in batch") +#define TSDB_CODE_TSC_SEND_DATA_FAILED TAOS_DEF_ERROR_CODE(0, 0x0230) //"Client send request data error" // mnode #define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed" diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 640e842de3..f66152988e 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -125,6 +125,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_PROTOCOL_TYPE, "Invalid line protocol TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_PRECISION_TYPE, "Invalid timestamp precision type") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_RES_TOO_MANY, "Result set too large to be output") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_TOO_MANY_SML_LINES, "Too many lines in batch") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SEND_DATA_FAILED, "Client send request data failed") // mnode TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, "Message not processed") -- GitLab From de5a51521efca95f570c93798a80f34cf0cae053 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 17 Aug 2022 17:32:00 +0800 Subject: [PATCH 335/380] fix(query): add TBOOL type --- src/client/src/tscServer.c | 2 +- src/inc/taos.h | 6 ++++++ src/inc/trpc.h | 2 +- src/rpc/src/rpcMain.c | 15 ++++++++------- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index a2f6a92c6c..07aff292f8 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -460,7 +460,7 @@ int tscSendMsgToServer(SSqlObj *pSql) { } - if(rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid)) { + if(rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid) != BOOL_FALSE) { if(pSql->cmd.command == TSDB_SQL_SELECT) rpcSaveSendInfo(pSql->rpcRid, &pSql->pPrevContext); return TSDB_CODE_SUCCESS; diff --git a/src/inc/taos.h b/src/inc/taos.h index 5cb0420fe2..44d83969a8 100644 --- a/src/inc/taos.h +++ b/src/inc/taos.h @@ -48,6 +48,12 @@ typedef void **TAOS_ROW; #define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes #define TSDB_DATA_TYPE_JSON 15 // json string +typedef enum { + BOOL_FALSE = 0, + BOOL_TRUE = 1, + BOOL_ASYNC = 2 //request is processed by async for another thread, not now true or false +} TBOOL; + typedef enum { TSDB_OPTION_LOCALE, TSDB_OPTION_CHARSET, diff --git a/src/inc/trpc.h b/src/inc/trpc.h index db29785699..fe061eb4f2 100644 --- a/src/inc/trpc.h +++ b/src/inc/trpc.h @@ -85,7 +85,7 @@ void rpcClose(void *); void *rpcMallocCont(int contLen); void rpcFreeCont(void *pCont); void *rpcReallocCont(void *ptr, int contLen); -bool rpcSendRequest(void *thandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *rid); +TBOOL rpcSendRequest(void *thandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *rid); void rpcSendResponse(const SRpcMsg *pMsg); void rpcSendRedirectRsp(void *pConn, const SRpcEpSet *pEpSet); int rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo); diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index dc69cb8905..54df052596 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -202,7 +202,7 @@ static SRpcConn *rpcAllocateClientConn(SRpcInfo *pRpc); static SRpcConn *rpcAllocateServerConn(SRpcInfo *pRpc, SRecvInfo *pRecv); static SRpcConn *rpcGetConnObj(SRpcInfo *pRpc, int sid, SRecvInfo *pRecv); -static bool rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext); +static TBOOL rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext); static void rpcSendQuickRsp(SRpcConn *pConn, int32_t code); static void rpcSendErrorMsgToPeer(SRecvInfo *pRecv, int32_t code); static bool rpcSendMsgToPeer(SRpcConn *pConn, void *data, int dataLen); @@ -394,7 +394,7 @@ void *rpcReallocCont(void *ptr, int contLen) { return start + sizeof(SRpcReqContext) + sizeof(SRpcHead); } -bool rpcSendRequest(void *shandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *pRid) { +TBOOL rpcSendRequest(void *shandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *pRid) { SRpcInfo *pRpc = (SRpcInfo *)shandle; SRpcReqContext *pContext; @@ -1384,7 +1384,7 @@ static void rpcSendErrorMsgToPeer(SRecvInfo *pRecv, int32_t code) { return; } -static bool rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { +static TBOOL rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { SRpcHead *pHead = rpcHeadFromCont(pContext->pCont); char *msg = (char *)pHead; int msgLen = rpcMsgLenFromCont(pContext->contLen); @@ -1394,8 +1394,9 @@ static bool rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { SRpcConn *pConn = rpcSetupConnToServer(pContext); if (pConn == NULL) { pContext->code = terrno; + // in rpcProcessConnError if numOfTry over limit, could call rpcNotifyClient to stop query taosTmrStart(rpcProcessConnError, 1, pContext, pRpc->tmrCtrl); - return false; + return BOOL_ASYNC; } pContext->pConn = pConn; @@ -1436,7 +1437,7 @@ static bool rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { taosTmrReset(rpcProcessRetryTimer, tsRpcTimer, pConn, pRpc->tmrCtrl, &pConn->pTimer); rpcUnlockConn(pConn); - return ret; + return ret ? BOOL_TRUE : BOOL_FALSE; } static bool rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) { @@ -1478,8 +1479,6 @@ static void rpcProcessConnError(void *param, void *id) { return; } - tDebug("%s %p, connection error happens", pRpc->label, pContext->ahandle); - if (pContext->numOfTry >= pContext->epSet.numOfEps || pContext->msgType == TSDB_MSG_TYPE_FETCH) { rpcMsg.msgType = pContext->msgType+1; rpcMsg.ahandle = pContext->ahandle; @@ -1487,9 +1486,11 @@ static void rpcProcessConnError(void *param, void *id) { rpcMsg.pCont = NULL; rpcMsg.contLen = 0; + tWarn("%s %p, connection error. notify client query over. numOfTry=%d msgType=%d", pRpc->label, pContext->ahandle, pContext->numOfTry, pContext->msgType); rpcNotifyClient(pContext, &rpcMsg); } else { // move to next IP + tWarn("%s %p, connection error. retry to send request again. numOfTry=%d msgType=%d", pRpc->label, pContext->ahandle, pContext->numOfTry, pContext->msgType); pContext->epSet.inUse++; pContext->epSet.inUse = pContext->epSet.inUse % pContext->epSet.numOfEps; rpcSendReqToServer(pRpc, pContext); -- GitLab From e20433298f54166716be8dcc0d366058a13a1071 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Thu, 18 Aug 2022 15:41:32 +0800 Subject: [PATCH 336/380] fix(query): if send data failed then retry next ip again --- src/rpc/src/rpcMain.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 54df052596..6566bf9e79 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1437,7 +1437,16 @@ static TBOOL rpcSendReqToServer(SRpcInfo *pRpc, SRpcReqContext *pContext) { taosTmrReset(rpcProcessRetryTimer, tsRpcTimer, pConn, pRpc->tmrCtrl, &pConn->pTimer); rpcUnlockConn(pConn); - return ret ? BOOL_TRUE : BOOL_FALSE; + + if(ret == BOOL_FALSE) { + // try next ip again + pContext->code = terrno; + // in rpcProcessConnError if numOfTry over limit, could call rpcNotifyClient to stop query + taosTmrStart(rpcProcessConnError, 1, pContext, pRpc->tmrCtrl); + return BOOL_ASYNC; + } + + return BOOL_TRUE; } static bool rpcSendMsgToPeer(SRpcConn *pConn, void *msg, int msgLen) { -- GitLab From 2c8ddb96bff280595dd408941c8a5e924c402c34 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Fri, 19 Aug 2022 13:25:42 +0800 Subject: [PATCH 337/380] test: add test case for subscribe case sensitive --- tests/pytest/subscribe/singlemeter.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/pytest/subscribe/singlemeter.py b/tests/pytest/subscribe/singlemeter.py index 879e0a75eb..ff182f70b5 100644 --- a/tests/pytest/subscribe/singlemeter.py +++ b/tests/pytest/subscribe/singlemeter.py @@ -68,8 +68,24 @@ class TDTestCase: tdSub.consume() tdSub.checkRows(11) + + # TS-1788: Subscribe a case sensitive table + tdLog.info("create a table and insert 10 rows.") + tdSql.execute("create table `T1`(ts timestamp, a int, b int);") + for i in range(0, 10): + tdSql.execute("insert into `T1` values (%d, %d, %d);" % (now + i, i, i)) + + sqlstr = "select * from `T1`" + topic = "topic1" + now = int(time.time() * 1000) + + tdSub.init(self.conn.subscribe(True, topic, sqlstr, 0)) + tdSub.consume() + tdSub.checkRows(10) + tdSub.close(True) + def stop(self): tdSub.close(False) tdSql.close() -- GitLab From c41546d514df7b42691abf4f93c7ee95d244e8eb Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 19 Aug 2022 15:43:13 +0800 Subject: [PATCH 338/380] fix(subscribe): remove strtolower for sql string --- src/client/src/tscSub.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/src/tscSub.c b/src/client/src/tscSub.c index e44f88189f..b3d18f5011 100644 --- a/src/client/src/tscSub.c +++ b/src/client/src/tscSub.c @@ -149,7 +149,6 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char* goto fail; } - strtolower(pSql->sqlstr, pSql->sqlstr); pRes->qId = 0; pRes->numOfRows = 1; pCmd->resColumnId = TSDB_RES_COL_ID; -- GitLab From 4dcae817c25f9c5438e038f7833bebe2ceecdb4a Mon Sep 17 00:00:00 2001 From: dingbo Date: Mon, 22 Aug 2022 09:11:58 +0800 Subject: [PATCH 339/380] docs: fix error links --- docs/en/05-get-started/_pkg_install.mdx | 4 +--- docs/zh/05-get-started/_pkg_install.mdx | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/en/05-get-started/_pkg_install.mdx b/docs/en/05-get-started/_pkg_install.mdx index cf10497c96..2d514d6cd2 100644 --- a/docs/en/05-get-started/_pkg_install.mdx +++ b/docs/en/05-get-started/_pkg_install.mdx @@ -10,8 +10,6 @@ Between two major release versions, some beta versions may be delivered for user -For the details please refer to [Install and Uninstall](/operation/pkg-install)。 +For the details please refer to [Install and Uninstall](../13-operation/01-pkg-install.md). To see the details of versions, please refer to [Download List](https://tdengine.com/all-downloads) and [Release Notes](https://github.com/taosdata/TDengine/releases). - - diff --git a/docs/zh/05-get-started/_pkg_install.mdx b/docs/zh/05-get-started/_pkg_install.mdx index 83c987af8b..85d6d7b6ed 100644 --- a/docs/zh/05-get-started/_pkg_install.mdx +++ b/docs/zh/05-get-started/_pkg_install.mdx @@ -10,8 +10,8 @@ TDengine 的安装非常简单,从下载到安装成功仅仅只要几秒钟 -具体的安装方法,请参见[安装包的安装和卸载](/operation/pkg-install)。 +具体的安装方法,请参见[安装包的安装和卸载](../13-operation/01-pkg-install.md)。 -下载其他组件、最新 Beta 版及之前版本的安装包,请点击[这里](https://www.taosdata.com/all-downloads) +下载其他组件、最新 Beta 版及之前版本的安装包,请点击[这里](https://www.taosdata.com/all-downloads)。 -查看 Release Notes, 请点击[这里](https://github.com/taosdata/TDengine/releases) +查看 Release Notes, 请点击[这里](https://github.com/taosdata/TDengine/releases)。 -- GitLab From dc0ec7f025ec5e2bc1e2430133c3cf7755b213b2 Mon Sep 17 00:00:00 2001 From: dingbo Date: Mon, 22 Aug 2022 16:41:14 +0800 Subject: [PATCH 340/380] docs: fix broken links --- docs/en/05-get-started/index.md | 10 +++++----- docs/en/07-develop/04-query-data/index.mdx | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/en/05-get-started/index.md b/docs/en/05-get-started/index.md index 9c5a853820..0450d132dd 100644 --- a/docs/en/05-get-started/index.md +++ b/docs/en/05-get-started/index.md @@ -10,7 +10,7 @@ import AptGetInstall from "./\_apt_get_install.mdx"; ## Quick Install -The full package of TDengine includes the server(taosd), taosAdapter for connecting with third-party systems and providing a RESTful interface, client driver(taosc), command-line program(CLI, taos) and some tools. For the current version, the server taosd and taosAdapter can only be installed and run on Linux systems. In the future taosd and taosAdapter will also be supported on Windows, macOS and other systems. The client driver taosc and TDengine CLI can be installed and run on Windows or Linux. In addition to connectors for multiple languages, TDengine also provides a [RESTful interface](/reference/rest-api) through [taosAdapter](/reference/taosadapter). Prior to version 2.4.0.0, taosAdapter did not exist and the RESTful interface was provided by the built-in HTTP service of taosd. +The full package of TDengine includes the server(taosd), taosAdapter for connecting with third-party systems and providing a RESTful interface, client driver(taosc), command-line program(CLI, taos) and some tools. For the current version, the server taosd and taosAdapter can only be installed and run on Linux systems. In the future taosd and taosAdapter will also be supported on Windows, macOS and other systems. The client driver taosc and TDengine CLI can be installed and run on Windows or Linux. In addition to connectors for multiple languages, TDengine also provides a [RESTful interface](../14-reference/02-rest-api/02-rest-api.mdx) through [taosAdapter](../14-reference/04-taosadapter.md). Prior to version 2.4.0.0, taosAdapter did not exist and the RESTful interface was provided by the built-in HTTP service of taosd. TDengine supports X64/ARM64/MIPS64/Alpha64 hardware platforms, and will support ARM32, RISC-V and other CPU architectures in the future. @@ -36,7 +36,7 @@ docker exec -it bash Then you can execute the Linux commands and access TDengine. -For detailed steps, please visit [Experience TDengine via Docker](/train-faq/docker)。 +For detailed steps, please visit [Experience TDengine via Docker](../27-train-faq/03-docker.md). :::info Starting from 2.4.0.10,besides taosd,TDengine docker image includes: taos,taosAdapter,taosdump,taosBenchmark,TDinsight, scripts and sample code. Once the TDengine container is started,it will start both taosAdapter and taosd automatically to support RESTful interface. @@ -98,7 +98,7 @@ To manage the TDengine running instance,or execute ad-hoc queries, TDengine pr taos ``` -If it connects to the TDengine server successfully, it will print out the version and welcome message. If it fails, it will print out the error message, please check [FAQ](/train-faq/faq) for trouble shooting connection issue. TDengine CLI's prompt is: +If it connects to the TDengine server successfully, it will print out the version and welcome message. If it fails, it will print out the error message, please check [FAQ](../27-train-faq/01-faq.md) for trouble shooting connection issue. TDengine CLI's prompt is: ```cmd taos> @@ -120,7 +120,7 @@ select * from t; Query OK, 2 row(s) in set (0.003128s) ``` -Besides executing SQL commands, system administrators can check running status, add/drop user accounts and manage the running instances. TDengine CLI with client driver can be installed and run on either Linux or Windows machines. For more details on CLI, please [check here](../reference/taos-shell/). +Besides executing SQL commands, system administrators can check running status, add/drop user accounts and manage the running instances. TDengine CLI with client driver can be installed and run on either Linux or Windows machines. For more details on CLI, please [check here](../14-reference/08-taos-shell.md). ## Experience the blazing fast speed @@ -134,7 +134,7 @@ This command will create a super table "meters" under database "test". Under "me This command will insert 100 million rows into the database quickly. Time to insert depends on the hardware configuration, it only takes a dozen seconds for a regular PC server. -taosBenchmark provides command-line options and a configuration file to customize the scenarios, like number of tables, number of rows per table, number of columns and more. Please execute `taosBenchmark --help` to list them. For details on running taosBenchmark, please check [reference for taosBenchmark](/reference/taosbenchmark) +taosBenchmark provides command-line options and a configuration file to customize the scenarios, like number of tables, number of rows per table, number of columns and more. Please execute `taosBenchmark --help` to list them. For details on running taosBenchmark, please check [reference for taosBenchmark](../14-reference/05-taosbenchmark.md) ## Experience query speed diff --git a/docs/en/07-develop/04-query-data/index.mdx b/docs/en/07-develop/04-query-data/index.mdx index a212fa9529..786411152c 100644 --- a/docs/en/07-develop/04-query-data/index.mdx +++ b/docs/en/07-develop/04-query-data/index.mdx @@ -48,7 +48,7 @@ Query OK, 2 row(s) in set (0.001100s) To meet the requirements of varied use cases, some special functions have been added in TDengine. Some examples are `twa` (Time Weighted Average), `spread` (The difference between the maximum and the minimum), and `last_row` (the last row). Furthermore, continuous query is also supported in TDengine. -For detailed query syntax please refer to [Select](/taos-sql/select). +For detailed query syntax please refer to [Select](../../12-taos-sql/06-select.md). ## Aggregation among Tables @@ -81,7 +81,7 @@ taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now - Query OK, 1 row(s) in set (0.002136s) ``` -Join queries are only allowed between subtables of the same STable. In [Select](/taos-sql/select), all query operations are marked as to whether they support STables or not. +Join queries are only allowed between subtables of the same STable. In [Select](../../12-taos-sql/06-select.md), all query operations are marked as to whether they support STables or not. ## Down Sampling and Interpolation @@ -128,13 +128,13 @@ In many use cases, it's hard to align the timestamp of the data collected by eac Interpolation can be performed in TDengine if there is no data in a time range. -For more details please refer to [Aggregate by Window](/taos-sql/interval). +For more details please refer to [Aggregate by Window](../../12-taos-sql/08-interval.md). ## Examples ### Query -In the section describing [Insert](/develop/insert-data/sql-writing), a database named `power` is created and some data are inserted into STable `meters`. Below sample code demonstrates how to query the data in this STable. +In the section describing [Insert](../03-insert-data/01-sql-writing.mdx), a database named `power` is created and some data are inserted into STable `meters`. Below sample code demonstrates how to query the data in this STable. -- GitLab From 7a56387c549fed7a9e7cd7ff00c1723cbadb5010 Mon Sep 17 00:00:00 2001 From: dingbo Date: Mon, 22 Aug 2022 16:54:46 +0800 Subject: [PATCH 341/380] docs: fix links --- docs/en/07-develop/04-query-data/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/07-develop/04-query-data/index.mdx b/docs/en/07-develop/04-query-data/index.mdx index 786411152c..e8e4b5c0ad 100644 --- a/docs/en/07-develop/04-query-data/index.mdx +++ b/docs/en/07-develop/04-query-data/index.mdx @@ -128,7 +128,7 @@ In many use cases, it's hard to align the timestamp of the data collected by eac Interpolation can be performed in TDengine if there is no data in a time range. -For more details please refer to [Aggregate by Window](../../12-taos-sql/08-interval.md). +For more details please refer to [Aggregate by Window](../../12-taos-sql/12-interval.md). ## Examples -- GitLab From 2fabd40237d6a4dde86b0e531095a2aa11189bf1 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Mon, 22 Aug 2022 18:25:07 +0800 Subject: [PATCH 342/380] doc: fix broken links --- docs/en/02-intro/index.md | 6 +++--- docs/en/07-develop/07-subscribe.mdx | 2 +- docs/en/12-taos-sql/12-interval.md | 2 +- docs/en/25-application/03-immigrate.md | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index 23cf1203b2..e605988d95 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -16,9 +16,9 @@ The major features are listed below: 3. Support for [all kinds of queries](/develop/query-data), including aggregation, nested query, downsampling, interpolation and others. 4. Support for [user defined functions](/develop/udf). 5. Support for [caching](/develop/cache). TDengine always saves the last data point in cache, so Redis is not needed in some scenarios. -6. Support for [continuous query](/develop/continuous-query). -7. Support for [data subscription](/develop/subscribe) with the capability to specify filter conditions. -8. Support for [cluster](/cluster/), with the capability of increasing processing power by adding more nodes. High availability is supported by replication. +6. Support for [continuous query](../develop/continuous-query). +7. Support for [data subscription](../develop/subscribe) with the capability to specify filter conditions. +8. Support for [cluster](../cluster/), with the capability of increasing processing power by adding more nodes. High availability is supported by replication. 9. Provides an interactive [command-line interface](/reference/taos-shell) for management, maintenance and ad-hoc queries. 10. Provides many ways to [import](/operation/import) and [export](/operation/export) data. 11. Provides [monitoring](/operation/monitor) on running instances of TDengine. diff --git a/docs/en/07-develop/07-subscribe.mdx b/docs/en/07-develop/07-subscribe.mdx index 0fde36f6cf..e309a33fc8 100644 --- a/docs/en/07-develop/07-subscribe.mdx +++ b/docs/en/07-develop/07-subscribe.mdx @@ -28,7 +28,7 @@ taos_consume taos_unsubscribe ``` -For more details about these APIs please refer to [C/C++ Connector](/reference/connector/cpp). Their usage will be introduced below using the use case of meters, in which the schema of STable and subtables from the previous section [Continuous Query](/develop/continuous-query) are used. Full sample code can be found [here](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c). +For more details about these APIs please refer to [C/C++ Connector](/reference/connector/cpp). Their usage will be introduced below using the use case of meters, in which the schema of STable and subtables from the previous section [Continuous Query](../continuous-query) are used. Full sample code can be found [here](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c). If we want to get a notification and take some actions if the current exceeds a threshold, like 10A, from some meters, there are two ways: diff --git a/docs/en/12-taos-sql/12-interval.md b/docs/en/12-taos-sql/12-interval.md index acfb0de0e1..2d55027810 100644 --- a/docs/en/12-taos-sql/12-interval.md +++ b/docs/en/12-taos-sql/12-interval.md @@ -93,7 +93,7 @@ SELECT function_list FROM stb_name ::: -Aggregate by time window is also used in continuous query, please refer to [Continuous Query](/develop/continuous-query). +Aggregate by time window is also used in continuous query, please refer to [Continuous Query](../../develop/continuous-query). ## Examples diff --git a/docs/en/25-application/03-immigrate.md b/docs/en/25-application/03-immigrate.md index fe67f97389..806b996f6d 100644 --- a/docs/en/25-application/03-immigrate.md +++ b/docs/en/25-application/03-immigrate.md @@ -419,11 +419,11 @@ Note that once the installation is complete, do not immediately start the `taosd To ensure that the system can obtain the necessary information for regular operation. Please set the following vital parameters correctly on the server: -FQDN, firstEp, secondEP, dataDir, logDir, tmpDir, serverPort. For the specific meaning and setting requirements of each parameter, please refer to the document "[TDengine Cluster Installation and Management](/cluster/)" +FQDN, firstEp, secondEP, dataDir, logDir, tmpDir, serverPort. For the specific meaning and setting requirements of each parameter, please refer to the document "[TDengine Cluster Installation and Management](../../cluster/)" Follow the same steps to set parameters on the other nodes, start the taosd service, and then add Dnodes to the cluster. -Finally, start `taos` and execute the `show dnodes` command. If you can see all the nodes that have joined the cluster, the cluster building process was successfully completed. For specific operation procedures and precautions, please refer to the document "[TDengine Cluster Installation and Management](/cluster/)". +Finally, start `taos` and execute the `show dnodes` command. If you can see all the nodes that have joined the cluster, the cluster building process was successfully completed. For specific operation procedures and precautions, please refer to the document "[TDengine Cluster Installation and Management](../../cluster/)". ## Appendix 4: Super Table Names -- GitLab From e0750ad1b2734933c966c4461c8a3a096f943851 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Mon, 22 Aug 2022 18:42:57 +0800 Subject: [PATCH 343/380] doc: fix broken links --- docs/en/02-intro/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index e605988d95..1637a3d454 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -3,7 +3,7 @@ title: Introduction toc_max_heading_level: 2 --- -TDengine is a high-performance, scalable time-series database with SQL support. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](/develop/cache), [stream processing](/develop/continuous-query), [data subscription](/develop/subscribe) and other functionalities to reduce the complexity and cost of development and operation. +TDengine is a high-performance, scalable time-series database with SQL support. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](/develop/cache), [stream processing](../develop/continuous-query), [data subscription](../develop/subscribe) and other functionalities to reduce the complexity and cost of development and operation. This section introduces the major features, competitive advantages, typical use-cases and benchmarks to help you get a high level overview of TDengine. -- GitLab From 106aa0d01a092a2e403cc3599ebb9184ce8f667c Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 23 Aug 2022 12:46:02 +0800 Subject: [PATCH 344/380] feat: update taos-tools 6bde102 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 43924b8006..6bde102e50 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 43924b8006c85bc67f0ce3b7cc294425a80c2ee9 +Subproject commit 6bde102e505a198f83b799a1faa457083ec2f36e -- GitLab From 36c0bed12d7a70b1a2172c41c49588ed8d133ced Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 23 Aug 2022 14:36:40 +0800 Subject: [PATCH 345/380] fix: cmake 3.10 failed for 2.6 (#16326) --- src/plugins/CMakeLists.txt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 52d27593a1..deba5a93e0 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -50,26 +50,37 @@ ELSE () IF (TD_LINUX) include(ExternalProject) + set(_upx_prefix "$ENV{HOME}/.taos/externals/upx") + ExternalProject_Add(upx + PREFIX "${_upx_prefix}" + URL https://github.com/upx/upx/releases/download/v3.96/upx-3.96-${PLATFORM_ARCH_STR}_linux.tar.xz + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + ExternalProject_Add(taosadapter PREFIX "taosadapter" SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/taosadapter BUILD_ALWAYS off - DEPENDS taos + DEPENDS taos upx BUILD_IN_SOURCE 1 CONFIGURE_COMMAND cmake -E echo "taosadapter no need cmake to config" PATCH_COMMAND COMMAND git clean -f -d BUILD_COMMAND + COMMAND cmake -E echo "building taosadapter ..." COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../inc CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -ldflags "-s -w -X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}" COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../inc CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -o taosadapter-debug -ldflags "-X github.com/taosdata/taosadapter/version.Version=${taos_version} -X github.com/taosdata/taosadapter/version.CommitID=${taosadapter_commit_sha1}" INSTALL_COMMAND - COMMAND wget -c https://github.com/upx/upx/releases/download/v3.96/upx-3.96-${PLATFORM_ARCH_STR}_linux.tar.xz -O $ENV{HOME}/upx.tar.xz && tar -xvJf $ENV{HOME}/upx.tar.xz -C $ENV{HOME} --strip-components 1 > /dev/null && $ENV{HOME}/upx taosadapter || : + COMMAND ${_upx_prefix}/src/upx/upx taosadapter COMMAND cmake -E copy taosadapter ${CMAKE_BINARY_DIR}/build/bin COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/test/cfg/ COMMAND cmake -E copy ./example/config/taosadapter.toml ${CMAKE_BINARY_DIR}/test/cfg/ COMMAND cmake -E copy ./taosadapter.service ${CMAKE_BINARY_DIR}/test/cfg/ COMMAND cmake -E copy taosadapter-debug ${CMAKE_BINARY_DIR}/build/bin ) + unset(_upx_prefix) ELSEIF (TD_DARWIN) include(ExternalProject) ExternalProject_Add(taosadapter -- GitLab From 79e365f8063c35ddf2131b2b7ad1d5fee7c405b2 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 23 Aug 2022 14:42:41 +0800 Subject: [PATCH 346/380] feat: update taostools 6bde102 for2.6 (#16328) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 57bdfbf for 2.6 * feat: update taos-tools 11d23e5 for 2.6 * feat: update taos-tools 43924b8 for 2.6 * feat: update taos-tools 6bde102 for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 43924b8006..6bde102e50 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 43924b8006c85bc67f0ce3b7cc294425a80c2ee9 +Subproject commit 6bde102e505a198f83b799a1faa457083ec2f36e -- GitLab From c8e611033f32e7c888194ebebaf2d55c5442c764 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 23 Aug 2022 16:33:39 +0800 Subject: [PATCH 347/380] fix(query): remove assert for pQInfo->rspContent NULL check --- src/query/src/queryMain.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index ee3245dd57..325225e695 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -320,7 +320,6 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex pthread_mutex_lock(&pQInfo->lock); - assert(pQInfo->rspContext == NULL); if (pQInfo->dataReady == QUERY_RESULT_READY) { *buildRes = true; qDebug("QInfo:0x%"PRIx64" retrieve result info, rowsize:%d, rows:%d, code:%s", pQInfo->qId, pQueryAttr->resultRowSize, -- GitLab From a31c1a5152e38519518c48c1ca8211dce1c27526 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Tue, 23 Aug 2022 15:23:09 +0000 Subject: [PATCH 348/380] feat: update taos-tools 2af2222 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 6bde102e50..2af22229bf 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 6bde102e505a198f83b799a1faa457083ec2f36e +Subproject commit 2af22229bfe78b0122389a49376567f160dd266c -- GitLab From 423d96d4ba18b1627bf63ac40ad2945886b9f01e Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 24 Aug 2022 10:13:25 +0800 Subject: [PATCH 349/380] feat: update taostools 2af2222 for2.6 (#16360) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 57bdfbf for 2.6 * feat: update taos-tools 11d23e5 for 2.6 * feat: update taos-tools 43924b8 for 2.6 * feat: update taos-tools 6bde102 for 2.6 * feat: update taos-tools 2af2222 for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 6bde102e50..2af22229bf 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 6bde102e505a198f83b799a1faa457083ec2f36e +Subproject commit 2af22229bfe78b0122389a49376567f160dd266c -- GitLab From 6cc37bb2df10f1fe4bc85e64c29885e25f20d4ca Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Wed, 24 Aug 2022 10:35:44 +0800 Subject: [PATCH 350/380] doc: fix broken links --- docs/zh/02-intro.md | 22 +++++++++---------- .../07-develop/01-connect/_connect_java.mdx | 2 +- docs/zh/07-develop/01-connect/index.md | 2 +- docs/zh/07-develop/07-subscribe.mdx | 2 +- docs/zh/07-develop/index.md | 2 +- docs/zh/14-reference/03-connector/cpp.mdx | 4 ++-- docs/zh/14-reference/03-connector/csharp.mdx | 4 ++-- docs/zh/14-reference/03-connector/go.mdx | 4 ++-- docs/zh/14-reference/03-connector/java.mdx | 4 ++-- docs/zh/14-reference/03-connector/node.mdx | 4 ++-- docs/zh/14-reference/03-connector/php.mdx | 2 +- docs/zh/14-reference/03-connector/python.mdx | 4 ++-- docs/zh/14-reference/03-connector/rust.mdx | 4 ++-- docs/zh/14-reference/04-taosadapter.md | 2 +- docs/zh/14-reference/08-taos-shell.md | 4 ++-- docs/zh/20-third-party/11-kafka.md | 2 +- docs/zh/27-train-faq/01-faq.md | 2 +- 17 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/zh/02-intro.md b/docs/zh/02-intro.md index 095ffa0372..607cef7195 100644 --- a/docs/zh/02-intro.md +++ b/docs/zh/02-intro.md @@ -3,7 +3,7 @@ title: 产品简介 toc_max_heading_level: 2 --- -TDengine 是一款高性能、分布式、支持 SQL 的时序数据库 (Database),其核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。TDengine 能被广泛运用于物联网、工业互联网、车联网、IT 运维、金融等领域。除核心的时序数据库 (Database) 功能外,TDengine 还提供[缓存](/develop/cache/)、[数据订阅](../develop/subscribe)、[流式计算](../develop/continuous-query)等大数据平台所需要的系列功能,最大程度减少研发和运维的复杂度。 +TDengine 是一款高性能、分布式、支持 SQL 的时序数据库 (Database),其核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。TDengine 能被广泛运用于物联网、工业互联网、车联网、IT 运维、金融等领域。除核心的时序数据库 (Database) 功能外,TDengine 还提供[缓存](../develop/cache/)、[数据订阅](../develop/subscribe)、[流式计算](../develop/continuous-query)等大数据平台所需要的系列功能,最大程度减少研发和运维的复杂度。 本章节介绍TDengine的主要功能、竞争优势、适用场景、与其他数据库的对比测试等等,让大家对TDengine有个整体的了解。 @@ -11,20 +11,20 @@ TDengine 是一款高性能、分布式、支持 SQL 的时序数据库 (Databas TDengine的主要功能如下: -1. 高速数据写入,除 [SQL 写入](/develop/insert-data/sql-writing)外,还支持 [Schemaless 写入](/reference/schemaless/),支持 [InfluxDB LINE 协议](/develop/insert-data/influxdb-line),[OpenTSDB Telnet](/develop/insert-data/opentsdb-telnet), [OpenTSDB JSON ](/develop/insert-data/opentsdb-json)等协议写入; -2. 第三方数据采集工具 [Telegraf](/third-party/telegraf),[Prometheus](/third-party/prometheus),[StatsD](/third-party/statsd),[collectd](/third-party/collectd),[icinga2](/third-party/icinga2), [TCollector](/third-party/tcollector), [EMQ](/third-party/emq-broker), [HiveMQ](/third-party/hive-mq-broker) 等都可以进行配置后,不用任何代码,即可将数据写入; -3. 支持[各种查询](/develop/query-data),包括聚合查询、嵌套查询、降采样查询、插值等 -4. 支持[用户自定义函数](/develop/udf) -5. 支持[缓存](/develop/cache),将每张表的最后一条记录缓存起来,这样无需 Redis +1. 高速数据写入,除 [SQL 写入](../develop/insert-data/sql-writing)外,还支持 [Schemaless 写入](../reference/schemaless/),支持 [InfluxDB LINE 协议](../develop/insert-data/influxdb-line),[OpenTSDB Telnet](../develop/insert-data/opentsdb-telnet), [OpenTSDB JSON ](../develop/insert-data/opentsdb-json)等协议写入; +2. 第三方数据采集工具 [Telegraf](../third-party/telegraf),[Prometheus](../third-party/prometheus),[StatsD](../third-party/statsd),[collectd](../third-party/collectd),[icinga2](../third-party/icinga2), [TCollector](../third-party/tcollector), [EMQ](../third-party/emq-broker), [HiveMQ](../third-party/hive-mq-broker) 等都可以进行配置后,不用任何代码,即可将数据写入; +3. 支持[各种查询](../develop/query-data),包括聚合查询、嵌套查询、降采样查询、插值等 +4. 支持[用户自定义函数](../develop/udf) +5. 支持[缓存](../develop/cache),将每张表的最后一条记录缓存起来,这样无需 Redis 6. 支持[连续查询](../develop/continuous-query)(Continuous Query) 7. 支持[数据订阅](../develop/subscribe),而且可以指定过滤条件 8. 支持[集群](../cluster/),可以通过多节点进行水平扩展,并通过多副本实现高可靠 -9. 提供[命令行程序](/reference/taos-shell),便于管理集群,检查系统状态,做即席查询 -10. 提供多种数据的[导入](/operation/import)、[导出](/operation/export) +9. 提供[命令行程序](../reference/taos-shell),便于管理集群,检查系统状态,做即席查询 +10. 提供多种数据的[导入](../operation/import)、[导出](../operation/export) 11. 支持对[TDengine 集群本身的监控](/operation/monitor) -12. 提供 [C/C++](/reference/connector/cpp), [Java](/reference/connector/java), [Python](/reference/connector/python), [Go](/reference/connector/go), [Rust](/reference/connector/rust), [Node.js](/reference/connector/node) 等多种编程语言的[连接器](/reference/connector/) -13. 支持 [REST 接口](/reference/rest-api/) -14. 支持与[ Grafana 无缝集成](/third-party/grafana) +12. 提供各种语言的[连接器](../reference/connector): C/C++, Java, Go, Python, Rust, Node.JS, C# +13. 支持 [REST 接口](../reference/rest-api/) +14. 支持与[ Grafana 无缝集成](../third-party/grafana) 15. 支持与 Google Data Studio 无缝集成 更多细小的功能,请阅读整个文档。 diff --git a/docs/zh/07-develop/01-connect/_connect_java.mdx b/docs/zh/07-develop/01-connect/_connect_java.mdx index f5b8ea1cc2..124b61182c 100644 --- a/docs/zh/07-develop/01-connect/_connect_java.mdx +++ b/docs/zh/07-develop/01-connect/_connect_java.mdx @@ -12,4 +12,4 @@ {{#include docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}} ``` -更多连接参数配置,参考[Java 连接器](/reference/connector/java) +更多连接参数配置,参考[Java 连接器](../../reference/connector/java) diff --git a/docs/zh/07-develop/01-connect/index.md b/docs/zh/07-develop/01-connect/index.md index a56577e2be..5448e6ba1a 100644 --- a/docs/zh/07-develop/01-connect/index.md +++ b/docs/zh/07-develop/01-connect/index.md @@ -33,7 +33,7 @@ TDengine 提供了丰富的应用程序开发接口,为了便于用户快速 关键不同点在于: 1. 使用 REST 连接,用户无需安装客户端驱动程序 taosc,具有跨平台易用的优势,但性能要下降 30%左右。 -2. 使用原生连接可以体验 TDengine 的全部功能,如[参数绑定接口](/reference/connector/cpp#参数绑定-api)、[订阅](/reference/connector/cpp#订阅和消费-api)等等。 +2. 使用原生连接可以体验 TDengine 的全部功能,如[参数绑定接口](../../reference/connector/cpp#参数绑定-api)、[订阅](../../reference/connector/cpp#订阅和消费-api)等等。 ## 安装客户端驱动 taosc diff --git a/docs/zh/07-develop/07-subscribe.mdx b/docs/zh/07-develop/07-subscribe.mdx index 962ed72e30..eb1103963a 100644 --- a/docs/zh/07-develop/07-subscribe.mdx +++ b/docs/zh/07-develop/07-subscribe.mdx @@ -28,7 +28,7 @@ taos_consume taos_unsubscribe ``` -这些 API 的文档请见 [C/C++ Connector](/reference/connector/cpp),下面仍以智能电表场景为例介绍一下它们的具体用法(超级表和子表结构请参考上一节“连续查询”),完整的示例代码可以在 [这里](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c) 找到。 +这些 API 的文档请见 [C/C++ Connector](../../reference/connector/cpp),下面仍以智能电表场景为例介绍一下它们的具体用法(超级表和子表结构请参考上一节“连续查询”),完整的示例代码可以在 [这里](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c) 找到。 如果我们希望当某个电表的电流超过一定限制(比如 10A)后能得到通知并进行一些处理, 有两种方法:一是分别对每张子表进行查询,每次查询后记录最后一条数据的时间戳,后续只查询这个时间戳之后的数据: diff --git a/docs/zh/07-develop/index.md b/docs/zh/07-develop/index.md index 0393a87ab2..61b3a3010c 100644 --- a/docs/zh/07-develop/index.md +++ b/docs/zh/07-develop/index.md @@ -12,7 +12,7 @@ title: 开发指南 7. 在很多场景下(如车辆管理),应用需要获取每个数据采集点的最新状态,那么建议你采用TDengine的cache功能,而不用单独部署Redis等缓存软件。 8. 如果你发现TDengine的函数无法满足你的要求,那么你可以使用用户自定义函数来解决问题。 -本部分内容就是按照上述的顺序组织的。为便于理解,TDengine为每个功能为每个支持的编程语言都提供了示例代码。如果你希望深入了解SQL的使用,需要查看[SQL手册](/taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](/reference/connector/)。如果还希望想将TDengine与第三方系统集成起来,比如Grafana, 请参考[第三方工具](/third-party/)。 +本部分内容就是按照上述的顺序组织的。为便于理解,TDengine为每个功能为每个支持的编程语言都提供了示例代码。如果你希望深入了解SQL的使用,需要查看[SQL手册](/taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](../../reference/connector/)。如果还希望想将TDengine与第三方系统集成起来,比如Grafana, 请参考[第三方工具](../../third-party/)。 如果在开发过程中遇到任何问题,请点击每个页面下方的["反馈问题"](https://github.com/taosdata/TDengine/issues/new/choose), 在GitHub上直接递交issue。 diff --git a/docs/zh/14-reference/03-connector/cpp.mdx b/docs/zh/14-reference/03-connector/cpp.mdx index 12cea8579b..cff64209f3 100644 --- a/docs/zh/14-reference/03-connector/cpp.mdx +++ b/docs/zh/14-reference/03-connector/cpp.mdx @@ -22,7 +22,7 @@ TDengine 客户端驱动的动态库位于: ## 支持的平台 -请参考[支持的平台列表](/reference/connector#支持的平台) +请参考[支持的平台列表](../connector#支持的平台) ## 支持的版本 @@ -30,7 +30,7 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一 ## 安装步骤 -TDengine 客户端驱动的安装请参考 [安装指南](/reference/connector#安装步骤) +TDengine 客户端驱动的安装请参考 [安装指南](../connector#安装步骤) ## 建立连接 diff --git a/docs/zh/14-reference/03-connector/csharp.mdx b/docs/zh/14-reference/03-connector/csharp.mdx index 1e23df9286..947cd7c629 100644 --- a/docs/zh/14-reference/03-connector/csharp.mdx +++ b/docs/zh/14-reference/03-connector/csharp.mdx @@ -30,7 +30,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx" ## 版本支持 -请参考[版本支持列表](/reference/connector#版本支持) +请参考[版本支持列表](../connector#版本支持) ## 支持的功能特性 @@ -47,7 +47,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx" * 安装 [.NET SDK](https://dotnet.microsoft.com/download) * [Nuget 客户端](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (可选安装) -* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动) +* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动) ### 使用 dotnet CLI 安装 diff --git a/docs/zh/14-reference/03-connector/go.mdx b/docs/zh/14-reference/03-connector/go.mdx index 79ced6f427..52ed47b767 100644 --- a/docs/zh/14-reference/03-connector/go.mdx +++ b/docs/zh/14-reference/03-connector/go.mdx @@ -30,7 +30,7 @@ REST 连接支持所有能运行 Go 的平台。 ## 版本支持 -请参考[版本支持列表](/reference/connector#版本支持) +请参考[版本支持列表](../connector#版本支持) ## 支持的功能特性 @@ -56,7 +56,7 @@ REST 连接支持所有能运行 Go 的平台。 ### 安装前准备 - 安装 Go 开发环境(Go 1.14 及以上,GCC 4.8.5 及以上) -- 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动) +- 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动) 配置好环境变量,检查命令: diff --git a/docs/zh/14-reference/03-connector/java.mdx b/docs/zh/14-reference/03-connector/java.mdx index f7bd540088..3b4fdeeb04 100644 --- a/docs/zh/14-reference/03-connector/java.mdx +++ b/docs/zh/14-reference/03-connector/java.mdx @@ -35,7 +35,7 @@ REST 连接支持所有能运行 Java 的平台。 ## 版本支持 -请参考[版本支持列表](/reference/connector#版本支持) +请参考[版本支持列表](../connector#版本支持) ## TDengine DataType 和 Java DataType @@ -64,7 +64,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对 使用 Java Connector 连接数据库前,需要具备以下条件: - 已安装 Java 1.8 或以上版本运行时环境和 Maven 3.6 或以上版本 -- 已安装 TDengine 客户端驱动(使用原生连接必须安装,使用 REST 连接无需安装),具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动) +- 已安装 TDengine 客户端驱动(使用原生连接必须安装,使用 REST 连接无需安装),具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动) ### 安装连接器 diff --git a/docs/zh/14-reference/03-connector/node.mdx b/docs/zh/14-reference/03-connector/node.mdx index 9f2bed9e97..215d53966b 100644 --- a/docs/zh/14-reference/03-connector/node.mdx +++ b/docs/zh/14-reference/03-connector/node.mdx @@ -28,7 +28,7 @@ REST 连接器支持所有能运行 Node.js 的平台。 ## 版本支持 -请参考[版本支持列表](/reference/connector#版本支持) +请参考[版本支持列表](../connector#版本支持) ## 支持的功能特性 @@ -52,7 +52,7 @@ REST 连接器支持所有能运行 Node.js 的平台。 ### 安装前准备 - 安装 Node.js 开发环境 -- 如果使用 REST 连接器,跳过此步。但如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动)。我们使用 [node-gyp](https://github.com/nodejs/node-gyp) 和 TDengine 实例进行交互,还需要根据具体操作系统来安装下文提到的一些依赖工具。 +- 如果使用 REST 连接器,跳过此步。但如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动)。我们使用 [node-gyp](https://github.com/nodejs/node-gyp) 和 TDengine 实例进行交互,还需要根据具体操作系统来安装下文提到的一些依赖工具。 diff --git a/docs/zh/14-reference/03-connector/php.mdx b/docs/zh/14-reference/03-connector/php.mdx index 2b7ff2a6fe..af132e6653 100644 --- a/docs/zh/14-reference/03-connector/php.mdx +++ b/docs/zh/14-reference/03-connector/php.mdx @@ -38,7 +38,7 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一 ### 安装 TDengine 客户端驱动 -TDengine 客户端驱动的安装请参考 [安装指南](/reference/connector#安装步骤) +TDengine 客户端驱动的安装请参考 [安装指南](../connector#安装步骤) ### 编译安装 php-tdengine diff --git a/docs/zh/14-reference/03-connector/python.mdx b/docs/zh/14-reference/03-connector/python.mdx index ecd84fe9a1..211884c92c 100644 --- a/docs/zh/14-reference/03-connector/python.mdx +++ b/docs/zh/14-reference/03-connector/python.mdx @@ -8,7 +8,7 @@ description: "taospy 是 TDengine 的官方 Python 连接器。taospy 提供了 import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。`taospy` 对 TDengine 的[原生接口](/reference/connector/cpp)和 [REST 接口](/reference/rest-api)都进行了封装, 分别对应 `taospy` 包的 `taos` 模块 和 `taosrest` 模块。 +`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。`taospy` 对 TDengine 的[原生接口](../connector/cpp)和 [REST 接口](/reference/rest-api)都进行了封装, 分别对应 `taospy` 包的 `taos` 模块 和 `taosrest` 模块。 除了对原生接口和 REST 接口的封装,`taospy` 还提供了符合 [Python 数据访问规范(PEP 249)](https://peps.python.org/pep-0249/) 的编程接口。这使得 `taospy` 和很多第三方工具集成变得简单,比如 [SQLAlchemy](https://www.sqlalchemy.org/) 和 [pandas](https://pandas.pydata.org/)。 使用客户端驱动提供的原生接口直接与服务端建立的连接的方式下文中称为“原生连接”;使用 taosAdapter 提供的 REST 接口与服务端建立的连接的方式下文中称为“REST 连接”。 @@ -17,7 +17,7 @@ Python 连接器的源码托管在 [GitHub](https://github.com/taosdata/taos-con ## 支持的平台 -- 原生连接[支持的平台](/reference/connector/#支持的平台)和 TDengine 客户端支持的平台一致。 +- 原生连接[支持的平台](../connector/#支持的平台)和 TDengine 客户端支持的平台一致。 - REST 连接支持所有能运行 Python 的平台。 ## 版本选择 diff --git a/docs/zh/14-reference/03-connector/rust.mdx b/docs/zh/14-reference/03-connector/rust.mdx index 25a8409b6e..7c00f29348 100644 --- a/docs/zh/14-reference/03-connector/rust.mdx +++ b/docs/zh/14-reference/03-connector/rust.mdx @@ -30,7 +30,7 @@ REST 连接支持所有能运行 Rust 的平台。 ## 版本支持 -请参考[版本支持列表](/reference/connector#版本支持) +请参考[版本支持列表](../connector#版本支持) Rust 连接器仍然在快速开发中,1.0 之前无法保证其向后兼容。建议使用 2.4 版本以上的 TDengine,以避免已知问题。 @@ -38,7 +38,7 @@ Rust 连接器仍然在快速开发中,1.0 之前无法保证其向后兼容 ### 安装前准备 * 安装 Rust 开发工具链 -* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动) +* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动) ### 添加 libtaos 依赖 diff --git a/docs/zh/14-reference/04-taosadapter.md b/docs/zh/14-reference/04-taosadapter.md index 42bc51a6d3..7888bbee7e 100644 --- a/docs/zh/14-reference/04-taosadapter.md +++ b/docs/zh/14-reference/04-taosadapter.md @@ -177,7 +177,7 @@ AllowWebSockets ### TDengine RESTful 接口 -您可以使用任何支持 http 协议的客户端通过访问 RESTful 接口地址 `http://:6041/` 来写入数据到 TDengine 或从 TDengine 中查询数据。细节请参考[官方文档](/reference/connector#restful)。支持如下 EndPoint : +您可以使用任何支持 http 协议的客户端通过访问 RESTful 接口地址 `http://:6041/` 来写入数据到 TDengine 或从 TDengine 中查询数据。细节请参考[官方文档](../connector#restful)。支持如下 EndPoint : ```text /rest/sql diff --git a/docs/zh/14-reference/08-taos-shell.md b/docs/zh/14-reference/08-taos-shell.md index 1be53adcdc..dd91cbdff7 100644 --- a/docs/zh/14-reference/08-taos-shell.md +++ b/docs/zh/14-reference/08-taos-shell.md @@ -8,7 +8,7 @@ TDengine 命令行程序(以下简称 TDengine CLI)是用户操作 TDengine ## 安装 -如果在 TDengine 服务器端执行,无需任何安装,已经自动安装好 TDengine CLI。如果要在非 TDengine 服务器端运行,需要安装 TDengine 客户端驱动安装包,具体安装,请参考 [安装客户端驱动](/reference/connector/#安装客户端驱动)。 +如果在 TDengine 服务器端执行,无需任何安装,已经自动安装好 TDengine CLI。如果要在非 TDengine 服务器端运行,需要安装 TDengine 客户端驱动安装包,具体安装,请参考 [安装客户端驱动](../connector/#安装客户端驱动)。 ## 执行 @@ -18,7 +18,7 @@ TDengine 命令行程序(以下简称 TDengine CLI)是用户操作 TDengine taos ``` -如果连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印错误消息。(请参考 [FAQ](/train-faq/faq) 来解决终端连接服务端失败的问题)。TDengine CLI 的提示符号如下: +如果连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印错误消息。(请参考 [FAQ](../../train-faq/faq) 来解决终端连接服务端失败的问题)。TDengine CLI 的提示符号如下: ```cmd taos> diff --git a/docs/zh/20-third-party/11-kafka.md b/docs/zh/20-third-party/11-kafka.md index 8369806adc..2536e09049 100644 --- a/docs/zh/20-third-party/11-kafka.md +++ b/docs/zh/20-third-party/11-kafka.md @@ -184,7 +184,7 @@ echo `cat /tmp/confluent.current`/connect/connect.stdout TDengine Sink Connector 的作用是同步指定 topic 的数据到 TDengine。用户无需提前创建数据库和超级表。可手动指定目标数据库的名字(见配置参数 connection.database), 也可按一定规则生成(见配置参数 connection.database.prefix)。 -TDengine Sink Connector 内部使用 TDengine [无模式写入接口](/reference/connector/cpp#无模式写入-api)写数据到 TDengine,目前支持三种格式的数据:[InfluxDB 行协议格式](/develop/insert-data/influxdb-line)、 [OpenTSDB Telnet 协议格式](/develop/insert-data/opentsdb-telnet) 和 [OpenTSDB JSON 协议格式](/develop/insert-data/opentsdb-json)。 +TDengine Sink Connector 内部使用 TDengine [无模式写入接口](../../reference/connector/cpp#无模式写入-api)写数据到 TDengine,目前支持三种格式的数据:[InfluxDB 行协议格式](../../develop/insert-data/influxdb-line)、 [OpenTSDB Telnet 协议格式](../../develop/insert-data/opentsdb-telnet) 和 [OpenTSDB JSON 协议格式](../../develop/insert-data/opentsdb-json)。 下面的示例将主题 meters 的数据,同步到目标数据库 power。数据格式为 InfluxDB Line 协议格式。 diff --git a/docs/zh/27-train-faq/01-faq.md b/docs/zh/27-train-faq/01-faq.md index bb92c69c3f..11458b565d 100644 --- a/docs/zh/27-train-faq/01-faq.md +++ b/docs/zh/27-train-faq/01-faq.md @@ -141,7 +141,7 @@ charset UTF-8 ### 14. JDBC 报错: the executed SQL is not a DML or a DDL? -请更新至最新的 JDBC 驱动,参考 [Java 连接器](/reference/connector/java) +请更新至最新的 JDBC 驱动,参考 [Java 连接器](../../reference/connector/java) ### 15. taos connect failed, reason: invalid timestamp -- GitLab From 8043fba8d0055e095f95eb75bba2a4827a162af6 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Wed, 24 Aug 2022 11:02:11 +0800 Subject: [PATCH 351/380] doc: fix broken links --- docs/zh/05-get-started/index.md | 2 +- docs/zh/07-develop/09-udf.md | 2 +- docs/zh/07-develop/index.md | 2 +- docs/zh/14-reference/03-connector/cpp.mdx | 4 ++-- docs/zh/14-reference/03-connector/csharp.mdx | 4 ++-- docs/zh/14-reference/03-connector/go.mdx | 4 ++-- docs/zh/14-reference/03-connector/java.mdx | 4 ++-- docs/zh/14-reference/03-connector/node.mdx | 4 ++-- docs/zh/14-reference/03-connector/php.mdx | 2 +- docs/zh/14-reference/03-connector/rust.mdx | 4 ++-- docs/zh/20-third-party/09-emq-broker.md | 4 ++-- docs/zh/27-train-faq/03-docker.md | 2 +- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/zh/05-get-started/index.md b/docs/zh/05-get-started/index.md index cc2e5df80e..272a231ed7 100644 --- a/docs/zh/05-get-started/index.md +++ b/docs/zh/05-get-started/index.md @@ -10,7 +10,7 @@ import AptGetInstall from "./\_apt_get_install.mdx"; ## 安装 -TDengine 完整的软件包包括服务端(taosd)、用于与第三方系统对接并提供 RESTful 接口的 taosAdapter、应用驱动(taosc)、命令行程序 (CLI,taos) 和一些工具软件,目前 2.X 版服务端 taosd 和 taosAdapter 仅在 Linux 系统上安装和运行,后续将支持 Windows、macOS 等系统。应用驱动 taosc 与 TDengine CLI 可以在 Windows 或 Linux 上安装和运行。TDengine 除了提供多种语言的连接器之外,还通过 [taosAdapter](/reference/taosadapter) 提供 [RESTful 接口](/reference/rest-api)。但在 2.4 之前的版本中没有 taosAdapter,RESTful 接口是由 taosd 内置的 HTTP 服务提供的。 +TDengine 完整的软件包包括服务端(taosd)、用于与第三方系统对接并提供 RESTful 接口的 taosAdapter、应用驱动(taosc)、命令行程序 (CLI,taos) 和一些工具软件,目前 2.X 版服务端 taosd 和 taosAdapter 仅在 Linux 系统上安装和运行,后续将支持 Windows、macOS 等系统。应用驱动 taosc 与 TDengine CLI 可以在 Windows 或 Linux 上安装和运行。TDengine 除了提供多种语言的连接器之外,还通过 [taosAdapter](../reference/taosadapter) 提供 [RESTful 接口](../reference/rest-api)。但在 2.4 之前的版本中没有 taosAdapter,RESTful 接口是由 taosd 内置的 HTTP 服务提供的。 TDengine 支持 X64/ARM64/MIPS64/Alpha64 硬件平台,后续将支持 ARM32、RISC-V 等 CPU 架构。 diff --git a/docs/zh/07-develop/09-udf.md b/docs/zh/07-develop/09-udf.md index 09681650db..998260fe21 100644 --- a/docs/zh/07-develop/09-udf.md +++ b/docs/zh/07-develop/09-udf.md @@ -22,7 +22,7 @@ description: "支持用户编码的聚合函数和标量函数,在查询中嵌 - udfNormalFunc 中各参数的具体含义是: - data:输入数据。 - - itype:输入数据的类型。这里采用的是短整型表示法,与各种数据类型对应的值可以参见 [column_meta 中的列类型说明](/reference/rest-api/)。例如 4 用于表示 INT 型。 + - itype:输入数据的类型。这里采用的是短整型表示法,与各种数据类型对应的值可以参见 [column_meta 中的列类型说明](../../reference/rest-api/)。例如 4 用于表示 INT 型。 - iBytes:输入数据中每个值会占用的字节数。 - numOfRows:输入数据的总行数。 - ts:主键时间戳在输入中的列数据(只读)。 diff --git a/docs/zh/07-develop/index.md b/docs/zh/07-develop/index.md index 61b3a3010c..041ac090b5 100644 --- a/docs/zh/07-develop/index.md +++ b/docs/zh/07-develop/index.md @@ -12,7 +12,7 @@ title: 开发指南 7. 在很多场景下(如车辆管理),应用需要获取每个数据采集点的最新状态,那么建议你采用TDengine的cache功能,而不用单独部署Redis等缓存软件。 8. 如果你发现TDengine的函数无法满足你的要求,那么你可以使用用户自定义函数来解决问题。 -本部分内容就是按照上述的顺序组织的。为便于理解,TDengine为每个功能为每个支持的编程语言都提供了示例代码。如果你希望深入了解SQL的使用,需要查看[SQL手册](/taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](../../reference/connector/)。如果还希望想将TDengine与第三方系统集成起来,比如Grafana, 请参考[第三方工具](../../third-party/)。 +本部分内容就是按照上述的顺序组织的。为便于理解,TDengine为每个功能为每个支持的编程语言都提供了示例代码。如果你希望深入了解SQL的使用,需要查看[SQL手册](/taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](../reference/connector/)。如果还希望想将TDengine与第三方系统集成起来,比如Grafana, 请参考[第三方工具](../third-party/)。 如果在开发过程中遇到任何问题,请点击每个页面下方的["反馈问题"](https://github.com/taosdata/TDengine/issues/new/choose), 在GitHub上直接递交issue。 diff --git a/docs/zh/14-reference/03-connector/cpp.mdx b/docs/zh/14-reference/03-connector/cpp.mdx index cff64209f3..fb126d8be4 100644 --- a/docs/zh/14-reference/03-connector/cpp.mdx +++ b/docs/zh/14-reference/03-connector/cpp.mdx @@ -22,7 +22,7 @@ TDengine 客户端驱动的动态库位于: ## 支持的平台 -请参考[支持的平台列表](../connector#支持的平台) +请参考[支持的平台列表](../connector/#支持的平台) ## 支持的版本 @@ -30,7 +30,7 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一 ## 安装步骤 -TDengine 客户端驱动的安装请参考 [安装指南](../connector#安装步骤) +TDengine 客户端驱动的安装请参考 [安装指南](../connector/#安装步骤) ## 建立连接 diff --git a/docs/zh/14-reference/03-connector/csharp.mdx b/docs/zh/14-reference/03-connector/csharp.mdx index 947cd7c629..fd7eb6c098 100644 --- a/docs/zh/14-reference/03-connector/csharp.mdx +++ b/docs/zh/14-reference/03-connector/csharp.mdx @@ -30,7 +30,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx" ## 版本支持 -请参考[版本支持列表](../connector#版本支持) +请参考[版本支持列表](../connector/#版本支持) ## 支持的功能特性 @@ -47,7 +47,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx" * 安装 [.NET SDK](https://dotnet.microsoft.com/download) * [Nuget 客户端](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (可选安装) -* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动) +* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动) ### 使用 dotnet CLI 安装 diff --git a/docs/zh/14-reference/03-connector/go.mdx b/docs/zh/14-reference/03-connector/go.mdx index 52ed47b767..cb0955e8b1 100644 --- a/docs/zh/14-reference/03-connector/go.mdx +++ b/docs/zh/14-reference/03-connector/go.mdx @@ -30,7 +30,7 @@ REST 连接支持所有能运行 Go 的平台。 ## 版本支持 -请参考[版本支持列表](../connector#版本支持) +请参考[版本支持列表](../connector/#版本支持) ## 支持的功能特性 @@ -56,7 +56,7 @@ REST 连接支持所有能运行 Go 的平台。 ### 安装前准备 - 安装 Go 开发环境(Go 1.14 及以上,GCC 4.8.5 及以上) -- 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动) +- 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动) 配置好环境变量,检查命令: diff --git a/docs/zh/14-reference/03-connector/java.mdx b/docs/zh/14-reference/03-connector/java.mdx index 3b4fdeeb04..1d60895f52 100644 --- a/docs/zh/14-reference/03-connector/java.mdx +++ b/docs/zh/14-reference/03-connector/java.mdx @@ -35,7 +35,7 @@ REST 连接支持所有能运行 Java 的平台。 ## 版本支持 -请参考[版本支持列表](../connector#版本支持) +请参考[版本支持列表](../connector/#版本支持) ## TDengine DataType 和 Java DataType @@ -64,7 +64,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对 使用 Java Connector 连接数据库前,需要具备以下条件: - 已安装 Java 1.8 或以上版本运行时环境和 Maven 3.6 或以上版本 -- 已安装 TDengine 客户端驱动(使用原生连接必须安装,使用 REST 连接无需安装),具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动) +- 已安装 TDengine 客户端驱动(使用原生连接必须安装,使用 REST 连接无需安装),具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动) ### 安装连接器 diff --git a/docs/zh/14-reference/03-connector/node.mdx b/docs/zh/14-reference/03-connector/node.mdx index 215d53966b..c6629183c4 100644 --- a/docs/zh/14-reference/03-connector/node.mdx +++ b/docs/zh/14-reference/03-connector/node.mdx @@ -28,7 +28,7 @@ REST 连接器支持所有能运行 Node.js 的平台。 ## 版本支持 -请参考[版本支持列表](../connector#版本支持) +请参考[版本支持列表](../connector/#版本支持) ## 支持的功能特性 @@ -52,7 +52,7 @@ REST 连接器支持所有能运行 Node.js 的平台。 ### 安装前准备 - 安装 Node.js 开发环境 -- 如果使用 REST 连接器,跳过此步。但如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动)。我们使用 [node-gyp](https://github.com/nodejs/node-gyp) 和 TDengine 实例进行交互,还需要根据具体操作系统来安装下文提到的一些依赖工具。 +- 如果使用 REST 连接器,跳过此步。但如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动)。我们使用 [node-gyp](https://github.com/nodejs/node-gyp) 和 TDengine 实例进行交互,还需要根据具体操作系统来安装下文提到的一些依赖工具。 diff --git a/docs/zh/14-reference/03-connector/php.mdx b/docs/zh/14-reference/03-connector/php.mdx index af132e6653..49c66bf14c 100644 --- a/docs/zh/14-reference/03-connector/php.mdx +++ b/docs/zh/14-reference/03-connector/php.mdx @@ -38,7 +38,7 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一 ### 安装 TDengine 客户端驱动 -TDengine 客户端驱动的安装请参考 [安装指南](../connector#安装步骤) +TDengine 客户端驱动的安装请参考 [安装指南](../connector/#安装步骤) ### 编译安装 php-tdengine diff --git a/docs/zh/14-reference/03-connector/rust.mdx b/docs/zh/14-reference/03-connector/rust.mdx index 7c00f29348..080b34b951 100644 --- a/docs/zh/14-reference/03-connector/rust.mdx +++ b/docs/zh/14-reference/03-connector/rust.mdx @@ -30,7 +30,7 @@ REST 连接支持所有能运行 Rust 的平台。 ## 版本支持 -请参考[版本支持列表](../connector#版本支持) +请参考[版本支持列表](../connector/#版本支持) Rust 连接器仍然在快速开发中,1.0 之前无法保证其向后兼容。建议使用 2.4 版本以上的 TDengine,以避免已知问题。 @@ -38,7 +38,7 @@ Rust 连接器仍然在快速开发中,1.0 之前无法保证其向后兼容 ### 安装前准备 * 安装 Rust 开发工具链 -* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector#安装客户端驱动) +* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动) ### 添加 libtaos 依赖 diff --git a/docs/zh/20-third-party/09-emq-broker.md b/docs/zh/20-third-party/09-emq-broker.md index dd98374558..a300644633 100644 --- a/docs/zh/20-third-party/09-emq-broker.md +++ b/docs/zh/20-third-party/09-emq-broker.md @@ -10,7 +10,7 @@ MQTT 是流行的物联网数据传输协议,[EMQX](https://github.com/emqx/em 要让 EMQX 能正常添加 TDengine 数据源,需要以下几方面的准备工作。 - TDengine 集群已经部署并正常运行 -- taosAdapter 已经安装并正常运行。具体细节请参考 [taosAdapter 的使用手册](/reference/taosadapter) +- taosAdapter 已经安装并正常运行。具体细节请参考 [taosAdapter 的使用手册](../../reference/taosadapter) - 如果使用后文介绍的模拟写入程序,需要安装合适版本的 Node.js,推荐安装 v12 ## 安装并启动 EMQX @@ -90,7 +90,7 @@ http://127.0.0.1:6041/rest/sql ``` Basic cm9vdDp0YW9zZGF0YQ== ``` -相关文档请参考[ TDengine REST API 文档](/reference/rest-api/)。 +相关文档请参考[ TDengine REST API 文档](../../reference/rest-api/)。 在消息体中输入规则引擎替换模板: diff --git a/docs/zh/27-train-faq/03-docker.md b/docs/zh/27-train-faq/03-docker.md index 72b4603dda..1a0285fe4a 100644 --- a/docs/zh/27-train-faq/03-docker.md +++ b/docs/zh/27-train-faq/03-docker.md @@ -119,7 +119,7 @@ curl -L -u root:taosdata -d "show databases" 127.0.0.1:6041/rest/sql 这条命令,通过 REST API 访问 TDengine server,这时连接的是本机的 6041 端口,可见连接成功。 -TDengine REST API 详情请参考[官方文档](/reference/rest-api/)。 +TDengine REST API 详情请参考[官方文档](../../reference/rest-api/)。 ### 使用 Docker 容器运行 TDengine server 和 taosAdapter -- GitLab From a63cacea2192ae29006d9ec6c7a33ba386bd2dc1 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Wed, 24 Aug 2022 11:58:49 +0800 Subject: [PATCH 352/380] doc: fix broken links --- docs/zh/14-reference/03-connector/cpp.mdx | 4 ++-- docs/zh/14-reference/03-connector/csharp.mdx | 6 +++--- docs/zh/14-reference/03-connector/go.mdx | 2 +- docs/zh/14-reference/03-connector/java.mdx | 4 ++-- docs/zh/14-reference/03-connector/node.mdx | 4 ++-- docs/zh/14-reference/03-connector/php.mdx | 2 +- docs/zh/14-reference/03-connector/python.mdx | 6 +++--- docs/zh/14-reference/03-connector/rust.mdx | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/zh/14-reference/03-connector/cpp.mdx b/docs/zh/14-reference/03-connector/cpp.mdx index fb126d8be4..c74b6f76f0 100644 --- a/docs/zh/14-reference/03-connector/cpp.mdx +++ b/docs/zh/14-reference/03-connector/cpp.mdx @@ -22,7 +22,7 @@ TDengine 客户端驱动的动态库位于: ## 支持的平台 -请参考[支持的平台列表](../connector/#支持的平台) +请参考[支持的平台列表](../#支持的平台) ## 支持的版本 @@ -30,7 +30,7 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一 ## 安装步骤 -TDengine 客户端驱动的安装请参考 [安装指南](../connector/#安装步骤) +TDengine 客户端驱动的安装请参考 [安装指南](../#安装步骤) ## 建立连接 diff --git a/docs/zh/14-reference/03-connector/csharp.mdx b/docs/zh/14-reference/03-connector/csharp.mdx index fd7eb6c098..db3c59806d 100644 --- a/docs/zh/14-reference/03-connector/csharp.mdx +++ b/docs/zh/14-reference/03-connector/csharp.mdx @@ -18,7 +18,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx" `TDengine.Connector` 是 TDengine 提供的 C# 语言连接器。C# 开发人员可以通过它开发存取 TDengine 集群数据的 C# 应用软件。 -`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、订阅、schemaless 数据写入、参数绑定接口数据写入等功能 `TDengine.Connector` 目前暂未提供 REST 连接方式,用户可以参考 [REST API](/reference/rest-api/) 文档自行编写。 +`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、订阅、schemaless 数据写入、参数绑定接口数据写入等功能 `TDengine.Connector` 目前暂未提供 REST 连接方式,用户可以参考 [REST API](../../rest-api/) 文档自行编写。 本文介绍如何在 Linux 或 Windows 环境中安装 `TDengine.Connector`,并通过 `TDengine.Connector` 连接 TDengine 集群,进行数据写入、查询等基本操作。 @@ -30,7 +30,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx" ## 版本支持 -请参考[版本支持列表](../connector/#版本支持) +请参考[版本支持列表](../#版本支持) ## 支持的功能特性 @@ -47,7 +47,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx" * 安装 [.NET SDK](https://dotnet.microsoft.com/download) * [Nuget 客户端](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (可选安装) -* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动) +* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动) ### 使用 dotnet CLI 安装 diff --git a/docs/zh/14-reference/03-connector/go.mdx b/docs/zh/14-reference/03-connector/go.mdx index cb0955e8b1..e7b93b33b1 100644 --- a/docs/zh/14-reference/03-connector/go.mdx +++ b/docs/zh/14-reference/03-connector/go.mdx @@ -30,7 +30,7 @@ REST 连接支持所有能运行 Go 的平台。 ## 版本支持 -请参考[版本支持列表](../connector/#版本支持) +请参考[版本支持列表](../#版本支持) ## 支持的功能特性 diff --git a/docs/zh/14-reference/03-connector/java.mdx b/docs/zh/14-reference/03-connector/java.mdx index 1d60895f52..d1f8b2afc6 100644 --- a/docs/zh/14-reference/03-connector/java.mdx +++ b/docs/zh/14-reference/03-connector/java.mdx @@ -35,7 +35,7 @@ REST 连接支持所有能运行 Java 的平台。 ## 版本支持 -请参考[版本支持列表](../connector/#版本支持) +请参考[版本支持列表](../#版本支持) ## TDengine DataType 和 Java DataType @@ -64,7 +64,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对 使用 Java Connector 连接数据库前,需要具备以下条件: - 已安装 Java 1.8 或以上版本运行时环境和 Maven 3.6 或以上版本 -- 已安装 TDengine 客户端驱动(使用原生连接必须安装,使用 REST 连接无需安装),具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动) +- 已安装 TDengine 客户端驱动(使用原生连接必须安装,使用 REST 连接无需安装),具体步骤请参考[安装客户端驱动](../#安装客户端驱动) ### 安装连接器 diff --git a/docs/zh/14-reference/03-connector/node.mdx b/docs/zh/14-reference/03-connector/node.mdx index c6629183c4..d410dcfd96 100644 --- a/docs/zh/14-reference/03-connector/node.mdx +++ b/docs/zh/14-reference/03-connector/node.mdx @@ -28,7 +28,7 @@ REST 连接器支持所有能运行 Node.js 的平台。 ## 版本支持 -请参考[版本支持列表](../connector/#版本支持) +请参考[版本支持列表](../#版本支持) ## 支持的功能特性 @@ -52,7 +52,7 @@ REST 连接器支持所有能运行 Node.js 的平台。 ### 安装前准备 - 安装 Node.js 开发环境 -- 如果使用 REST 连接器,跳过此步。但如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动)。我们使用 [node-gyp](https://github.com/nodejs/node-gyp) 和 TDengine 实例进行交互,还需要根据具体操作系统来安装下文提到的一些依赖工具。 +- 如果使用 REST 连接器,跳过此步。但如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)。我们使用 [node-gyp](https://github.com/nodejs/node-gyp) 和 TDengine 实例进行交互,还需要根据具体操作系统来安装下文提到的一些依赖工具。 diff --git a/docs/zh/14-reference/03-connector/php.mdx b/docs/zh/14-reference/03-connector/php.mdx index 49c66bf14c..d93a295627 100644 --- a/docs/zh/14-reference/03-connector/php.mdx +++ b/docs/zh/14-reference/03-connector/php.mdx @@ -38,7 +38,7 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一 ### 安装 TDengine 客户端驱动 -TDengine 客户端驱动的安装请参考 [安装指南](../connector/#安装步骤) +TDengine 客户端驱动的安装请参考 [安装指南](../#安装步骤) ### 编译安装 php-tdengine diff --git a/docs/zh/14-reference/03-connector/python.mdx b/docs/zh/14-reference/03-connector/python.mdx index 211884c92c..0101805512 100644 --- a/docs/zh/14-reference/03-connector/python.mdx +++ b/docs/zh/14-reference/03-connector/python.mdx @@ -8,7 +8,7 @@ description: "taospy 是 TDengine 的官方 Python 连接器。taospy 提供了 import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。`taospy` 对 TDengine 的[原生接口](../connector/cpp)和 [REST 接口](/reference/rest-api)都进行了封装, 分别对应 `taospy` 包的 `taos` 模块 和 `taosrest` 模块。 +`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。`taospy` 对 TDengine 的[原生接口](../cpp)和 [REST 接口](/reference/rest-api)都进行了封装, 分别对应 `taospy` 包的 `taos` 模块 和 `taosrest` 模块。 除了对原生接口和 REST 接口的封装,`taospy` 还提供了符合 [Python 数据访问规范(PEP 249)](https://peps.python.org/pep-0249/) 的编程接口。这使得 `taospy` 和很多第三方工具集成变得简单,比如 [SQLAlchemy](https://www.sqlalchemy.org/) 和 [pandas](https://pandas.pydata.org/)。 使用客户端驱动提供的原生接口直接与服务端建立的连接的方式下文中称为“原生连接”;使用 taosAdapter 提供的 REST 接口与服务端建立的连接的方式下文中称为“REST 连接”。 @@ -17,7 +17,7 @@ Python 连接器的源码托管在 [GitHub](https://github.com/taosdata/taos-con ## 支持的平台 -- 原生连接[支持的平台](../connector/#支持的平台)和 TDengine 客户端支持的平台一致。 +- 原生连接[支持的平台](../#支持的平台)和 TDengine 客户端支持的平台一致。 - REST 连接支持所有能运行 Python 的平台。 ## 版本选择 @@ -266,7 +266,7 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线 ##### RestClient 类的使用 -`RestClient` 类是对于 [REST API](/reference/rest-api) 的直接封装。它只包含一个 `sql()` 方法用于执行任意 SQL 语句, 并返回执行结果。 +`RestClient` 类是对于 [REST API](../../rest-api) 的直接封装。它只包含一个 `sql()` 方法用于执行任意 SQL 语句, 并返回执行结果。 ```python title="RestClient 的使用" {{#include docs/examples/python/rest_client_example.py}} diff --git a/docs/zh/14-reference/03-connector/rust.mdx b/docs/zh/14-reference/03-connector/rust.mdx index 080b34b951..fa6d496fa5 100644 --- a/docs/zh/14-reference/03-connector/rust.mdx +++ b/docs/zh/14-reference/03-connector/rust.mdx @@ -30,7 +30,7 @@ REST 连接支持所有能运行 Rust 的平台。 ## 版本支持 -请参考[版本支持列表](../connector/#版本支持) +请参考[版本支持列表](../#版本支持) Rust 连接器仍然在快速开发中,1.0 之前无法保证其向后兼容。建议使用 2.4 版本以上的 TDengine,以避免已知问题。 @@ -38,7 +38,7 @@ Rust 连接器仍然在快速开发中,1.0 之前无法保证其向后兼容 ### 安装前准备 * 安装 Rust 开发工具链 -* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动) +* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动) ### 添加 libtaos 依赖 -- GitLab From 4aeccad12bb7a32c1cfa14a98308a61f05d03051 Mon Sep 17 00:00:00 2001 From: gccgdb1234 Date: Wed, 24 Aug 2022 12:09:53 +0800 Subject: [PATCH 353/380] doc: fix broken links --- docs/zh/14-reference/03-connector/go.mdx | 2 +- docs/zh/14-reference/03-connector/python.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh/14-reference/03-connector/go.mdx b/docs/zh/14-reference/03-connector/go.mdx index e7b93b33b1..b566c36624 100644 --- a/docs/zh/14-reference/03-connector/go.mdx +++ b/docs/zh/14-reference/03-connector/go.mdx @@ -56,7 +56,7 @@ REST 连接支持所有能运行 Go 的平台。 ### 安装前准备 - 安装 Go 开发环境(Go 1.14 及以上,GCC 4.8.5 及以上) -- 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../connector/#安装客户端驱动) +- 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动) 配置好环境变量,检查命令: diff --git a/docs/zh/14-reference/03-connector/python.mdx b/docs/zh/14-reference/03-connector/python.mdx index 0101805512..5e2af7d516 100644 --- a/docs/zh/14-reference/03-connector/python.mdx +++ b/docs/zh/14-reference/03-connector/python.mdx @@ -8,7 +8,7 @@ description: "taospy 是 TDengine 的官方 Python 连接器。taospy 提供了 import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。`taospy` 对 TDengine 的[原生接口](../cpp)和 [REST 接口](/reference/rest-api)都进行了封装, 分别对应 `taospy` 包的 `taos` 模块 和 `taosrest` 模块。 +`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。`taospy` 对 TDengine 的[原生接口](../cpp)和 [REST 接口](../../rest-api)都进行了封装, 分别对应 `taospy` 包的 `taos` 模块 和 `taosrest` 模块。 除了对原生接口和 REST 接口的封装,`taospy` 还提供了符合 [Python 数据访问规范(PEP 249)](https://peps.python.org/pep-0249/) 的编程接口。这使得 `taospy` 和很多第三方工具集成变得简单,比如 [SQLAlchemy](https://www.sqlalchemy.org/) 和 [pandas](https://pandas.pydata.org/)。 使用客户端驱动提供的原生接口直接与服务端建立的连接的方式下文中称为“原生连接”;使用 taosAdapter 提供的 REST 接口与服务端建立的连接的方式下文中称为“REST 连接”。 -- GitLab From a012424873ff7b1383726e1aa81d64593ce46bf3 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 24 Aug 2022 16:19:15 +0800 Subject: [PATCH 354/380] feat: update taos-tools 833b721 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 2af22229bf..833b7216e9 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 2af22229bfe78b0122389a49376567f160dd266c +Subproject commit 833b7216e9d6b18f0bee8b0ac525d22fe1fe3927 -- GitLab From d7f2d93a8fb6300ae726df9d1ef292c1600f72e0 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 24 Aug 2022 17:00:11 +0800 Subject: [PATCH 355/380] feat: update taostools 833b721 for2.6 (#16380) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 57bdfbf for 2.6 * feat: update taos-tools 11d23e5 for 2.6 * feat: update taos-tools 43924b8 for 2.6 * feat: update taos-tools 6bde102 for 2.6 * feat: update taos-tools 2af2222 for 2.6 * feat: update taos-tools 833b721 for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 2af22229bf..833b7216e9 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 2af22229bfe78b0122389a49376567f160dd266c +Subproject commit 833b7216e9d6b18f0bee8b0ac525d22fe1fe3927 -- GitLab From 6ed50e7d904aec12547c02b896af02ec57a7be2e Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 26 Aug 2022 14:11:48 +0800 Subject: [PATCH 356/380] feat: update taos-tools e8bfca6 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 833b7216e9..e8bfca6407 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 833b7216e9d6b18f0bee8b0ac525d22fe1fe3927 +Subproject commit e8bfca64075235248ad192cf18ccd637165a2e6b -- GitLab From 89013563d533b92f7e96d3ed4d4d5183051c14ff Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 26 Aug 2022 14:37:04 +0800 Subject: [PATCH 357/380] feat: update taostools e8bfca6 for2.6 (#16436) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 57bdfbf for 2.6 * feat: update taos-tools 11d23e5 for 2.6 * feat: update taos-tools 43924b8 for 2.6 * feat: update taos-tools 6bde102 for 2.6 * feat: update taos-tools 2af2222 for 2.6 * feat: update taos-tools 833b721 for 2.6 * feat: update taos-tools e8bfca6 for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 833b7216e9..e8bfca6407 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 833b7216e9d6b18f0bee8b0ac525d22fe1fe3927 +Subproject commit e8bfca64075235248ad192cf18ccd637165a2e6b -- GitLab From 9a1da22426f271377a00ba178fb181177f5d69d0 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 18 Aug 2022 10:32:43 +0800 Subject: [PATCH 358/380] enh: refactor taosTimeTruncate and taosTimeCountInterval --- src/os/inc/osTime.h | 2 +- src/os/src/detail/osTime.c | 84 +++++++++++++------------------------- src/query/src/qFill.c | 3 ++ 3 files changed, 32 insertions(+), 57 deletions(-) diff --git a/src/os/inc/osTime.h b/src/os/inc/osTime.h index 1fb21ff38b..449151cba0 100644 --- a/src/os/inc/osTime.h +++ b/src/os/inc/osTime.h @@ -106,7 +106,7 @@ int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision); int64_t taosTimeSub(int64_t t, int64_t duration, char unit, int32_t precision); int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision); -int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision); +int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t sliding, int64_t slidingUnit, int64_t intervalUnit, int32_t precision); int32_t parseAbsoluteDuration(char* token, int32_t tokenlen, int64_t* ts, char* unit, int32_t timePrecision); int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* duration, char* unit, int32_t timePrecision); diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 207222f79e..7841e96cbf 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -565,23 +565,29 @@ int64_t taosTimeSub(int64_t t, int64_t duration, char unit, int32_t precision) { return (int64_t)(mktime(&tm) * TSDB_TICK_PER_SECOND(precision)); } -int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision) { +int64_t taosTimeTzOffset(int64_t intervalUnit, int32_t precision) { + int64_t tz_offset = 0; + if (intervalUnit == 'd' || intervalUnit == 'w') { + #if defined(WINDOWS) && _MSC_VER >= 1900 + // see https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019 + int64_t timezone = _timezone; + #endif + tz_offset = -1 * timezone * TSDB_TICK_PER_SECOND(precision); + } + return tz_offset; +} + +int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t sliding, int64_t slidingUnit, int64_t intervalUnit, int32_t precision) { if (ekey < skey) { int64_t tmp = ekey; ekey = skey; skey = tmp; } -#ifdef _MSC_VER -#if _MSC_VER >= 1900 - int64_t timezone = _timezone; -#endif -#endif - - int64_t tz_offset = -1 * timezone * TSDB_TICK_PER_SECOND(precision); - - if (unit != 'n' && unit != 'y') { - return (int32_t)((ekey+tz_offset)/interval - (skey+tz_offset)/interval) + 1; + int64_t tz_offset = taosTimeTzOffset(intervalUnit, precision); + + if (slidingUnit != 'n' && slidingUnit != 'y') { + return (int32_t)((ekey+tz_offset)/sliding - (skey+tz_offset)/sliding) + 1; } skey /= (int64_t)(TSDB_TICK_PER_SECOND(precision)); @@ -596,11 +602,11 @@ int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char localtime_r(&t, &tm); int emon = tm.tm_year * 12 + tm.tm_mon; - if (unit == 'y') { - interval *= 12; + if (slidingUnit == 'y') { + sliding *= 12; } - return (int32_t)(emon/interval - smon/interval) + 1; + return (int32_t)(emon/sliding - smon/sliding) + 1; } int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision) { @@ -622,56 +628,22 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio if (pInterval->slidingUnit == 'y') { tm.tm_mon = 0; - tm.tm_year = (int)(tm.tm_year / pInterval->sliding * pInterval->sliding); + tm.tm_year -= (int)(tm.tm_year%pInterval->sliding); } else { int mon = tm.tm_year * 12 + tm.tm_mon; - mon = (int)(mon / pInterval->sliding * pInterval->sliding); + mon -= (int)(mon % pInterval->sliding); tm.tm_year = mon / 12; tm.tm_mon = mon % 12; } start = (int64_t)(mktime(&tm) * TSDB_TICK_PER_SECOND(precision)); } else { - int64_t delta = t - pInterval->interval; - int32_t factor = (delta >= 0) ? 1 : -1; - - start = (delta / pInterval->sliding + factor) * pInterval->sliding; - - if (pInterval->intervalUnit == 'd' || pInterval->intervalUnit == 'w') { - /* - * here we revised the start time of day according to the local time zone, - * but in case of DST, the start time of one day need to be dynamically decided. - */ - // todo refactor to extract function that is available for Linux/Windows/Mac platform - #if defined(WINDOWS) && _MSC_VER >= 1900 - // see https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019 - int64_t timezone = _timezone; - int32_t daylight = _daylight; - char** tzname = _tzname; - #endif - - start += (int64_t)(timezone * TSDB_TICK_PER_SECOND(precision)); - } - - int64_t end = 0; - - // not enough time range - if (start < 0 || INT64_MAX - start > pInterval->interval - 1) { - end = start + pInterval->interval - 1; - - while(end < t && ((start + pInterval->sliding) <= INT64_MAX)) { // move forward to the correct time window - start += pInterval->sliding; - - if (start < 0 || INT64_MAX - start > pInterval->interval - 1) { - end = start + pInterval->interval - 1; - } else { - end = INT64_MAX; - break; - } - } - } else { - end = INT64_MAX; - } + // To avoid the overly complicated effect of DST on size of sliding windows, the DST(daylight saving time) is + // better to be respected by users' input and output for display only, maintaining the status quo. + // In this way, the size of sliding windows keeps unchanging during each cycle of processing of requests. + start = t - pInterval->interval + pInterval->sliding; + int64_t tz_offset = taosTimeTzOffset(pInterval->intervalUnit, precision); + start -= (start+tz_offset)%pInterval->sliding; } if (pInterval->offset > 0) { diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index 9a90a27daf..1cbe1b4660 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -462,6 +462,7 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) pFillInfo->currentKey, pFillInfo->interval.sliding, pFillInfo->interval.slidingUnit, + pFillInfo->interval.intervalUnit, pFillInfo->precision); if(numOfRes < numOfRows || pFillInfo->currentKey < lastKey) { // set currentKey max @@ -502,6 +503,7 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma pFillInfo->currentKey, pFillInfo->interval.sliding, pFillInfo->interval.slidingUnit, + pFillInfo->interval.intervalUnit, pFillInfo->precision); assert(numOfRes >= numOfRows); } else { // reach the end of data @@ -514,6 +516,7 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma pFillInfo->currentKey, pFillInfo->interval.sliding, pFillInfo->interval.slidingUnit, + pFillInfo->interval.intervalUnit, pFillInfo->precision); } -- GitLab From 14600bf1d1ab2abb73b6ca84f80d564d491923f3 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 25 Aug 2022 01:44:16 -0500 Subject: [PATCH 359/380] enh: validate alignment of sliding windows to fill --- src/query/src/qFill.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index 1cbe1b4660..c3524c8475 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -485,6 +485,15 @@ bool taosFillHasMoreResults(SFillInfo* pFillInfo) { return false; } +bool validateAlignOfSlidingWindows(TSKEY lastKey, TSKEY currentKey, SFillInfo *pFillInfo) { + if (pFillInfo->interval.slidingUnit != 'n' && pFillInfo->interval.slidingUnit != 'y') { + assert((lastKey-currentKey)%pFillInfo->interval.sliding == 0 && + "Sliding windows not aligned." + "Most likely caused by mismatched timezones between client and/or dnodes"); + } + return true; +} + int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t maxNumOfRows) { int64_t* tsList = (int64_t*) pFillInfo->pData[0]; @@ -498,6 +507,7 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma int64_t numOfRes = -1; if (numOfRows > 0) { // still fill gap within current data block, not generating data after the result set. TSKEY lastKey = tsList[pFillInfo->numOfRows - 1]; + if(!validateAlignOfSlidingWindows(lastKey, pFillInfo->currentKey, pFillInfo)) return 0; numOfRes = taosTimeCountInterval( lastKey, pFillInfo->currentKey, @@ -505,7 +515,8 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma pFillInfo->interval.slidingUnit, pFillInfo->interval.intervalUnit, pFillInfo->precision); - assert(numOfRes >= numOfRows); + assert(numOfRes >= numOfRows && + "Sliding windows to fill mismatched"); } else { // reach the end of data if ((ekey1 < pFillInfo->currentKey && FILL_IS_ASC_FILL(pFillInfo)) || (ekey1 > pFillInfo->currentKey && !FILL_IS_ASC_FILL(pFillInfo))) { -- GitLab From 8f820334e316bf6906bf6effef4757d34beefefb Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 29 Aug 2022 12:51:50 +0800 Subject: [PATCH 360/380] feat: update taos-tools aa45ad4 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index e8bfca6407..aa45ad44c6 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit e8bfca64075235248ad192cf18ccd637165a2e6b +Subproject commit aa45ad44c61f7ea47149290eeafb6cf2dc2f3a42 -- GitLab From 25d9627db4c6f300608cbb2adec4f80d26f2a01c Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Mon, 29 Aug 2022 13:26:22 +0800 Subject: [PATCH 361/380] feat: update taostools aa45ad4 for2.6 (#16470) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 57bdfbf for 2.6 * feat: update taos-tools 11d23e5 for 2.6 * feat: update taos-tools 43924b8 for 2.6 * feat: update taos-tools 6bde102 for 2.6 * feat: update taos-tools 2af2222 for 2.6 * feat: update taos-tools 833b721 for 2.6 * feat: update taos-tools e8bfca6 for 2.6 * feat: update taos-tools aa45ad4 for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index e8bfca6407..aa45ad44c6 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit e8bfca64075235248ad192cf18ccd637165a2e6b +Subproject commit aa45ad44c61f7ea47149290eeafb6cf2dc2f3a42 -- GitLab From 879946c98e8e93722929e03d204e27f6f06de920 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 31 Aug 2022 20:29:41 +0800 Subject: [PATCH 362/380] feat: taosdump multiple directories (#16541) fix: test cases --- tests/pytest/tools/taosdumpTest2.py | 3 +++ tests/pytest/tools/taosdumpTest3.py | 33 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/tests/pytest/tools/taosdumpTest2.py b/tests/pytest/tools/taosdumpTest2.py index c0de2c957a..94c5adf309 100644 --- a/tests/pytest/tools/taosdumpTest2.py +++ b/tests/pytest/tools/taosdumpTest2.py @@ -63,6 +63,7 @@ class TDTestCase: os.makedirs("./taosdumptest/tmp") else: print("directory exists") + os.system("rm -rf ./taosdumptest/tmp/*") tdSql.prepare() @@ -87,6 +88,7 @@ class TDTestCase: os.system("rm ./taosdumptest/tmp/*.sql") os.system("rm ./taosdumptest/tmp/*.avro*") + os.system("rm -rf ./taosdumptest/taosdump.*") os.system( "%s --databases db -o ./taosdumptest/tmp " % binPath) @@ -122,6 +124,7 @@ class TDTestCase: os.system("rm ./taosdumptest/tmp/*.sql") os.system("rm ./taosdumptest/tmp/*.avro*") + os.system("rm -rf ./taosdumptest/tmp/taosdump.*") os.system("%s -D test -o ./taosdumptest/tmp -y" % binPath) tdSql.execute("drop database test") diff --git a/tests/pytest/tools/taosdumpTest3.py b/tests/pytest/tools/taosdumpTest3.py index e8fb46f3a8..2a9561f7c5 100644 --- a/tests/pytest/tools/taosdumpTest3.py +++ b/tests/pytest/tools/taosdumpTest3.py @@ -59,6 +59,7 @@ class TDTestCase: os.makedirs("./taosdumptest") else: print("directory exists") + os.system("rm -rf ./taosdumptest/*") for i in range(1, 9): if not os.path.exists("./taosdumptest/tmp%d" % i): @@ -83,15 +84,15 @@ class TDTestCase: tdSql.execute( "create table st0_0 using st0 tags(0) st0_1 using st0 tags (1) ") tdSql.execute( - "insert into st0_0 values(1614218412000,8537,'R')(1614218422000,8538,'E')") + "insert into st0_0 values(1661997612000,8537,'R')(1661997622000,8538,'E')") tdSql.execute( - "insert into st0_1 values(1614218413000,1537,'A')(1614218423000,1538,'D')") + "insert into st0_1 values(1661997613000,1537,'A')(1661997623000,1538,'D')") tdSql.execute( "create table if not exists gt0 (ts timestamp, c0 int, c1 float) ") tdSql.execute( "create table if not exists gt1 (ts timestamp, c0 int, c1 double) ") - tdSql.execute("insert into gt0 values(1614218412000,637,8.861)") - tdSql.execute("insert into gt1 values(1614218413000,638,8.862)") + tdSql.execute("insert into gt0 values(1661997602000,637,8.861)") + tdSql.execute("insert into gt1 values(1661997603000,638,8.862)") # create db1 , three stables:stb0,include ctables stb0_0 \ stb0_1,stb1 include ctables stb1_0 and stb1_1 # \stb3,include ctables stb3_0 and stb3_1 @@ -103,35 +104,35 @@ class TDTestCase: tdSql.execute( "create table st0_0 using st0 tags(0) st0_1 using st0 tags(1) ") tdSql.execute( - "insert into st0_0 values(1614218412000,8600,'R')(1614218422000,8600,'E')") + "insert into st0_0 values(1654218412000,8600,'R')(1654218422000,8600,'E')") tdSql.execute( - "insert into st0_1 values(1614218413000,8601,'A')(1614218423000,8601,'D')") + "insert into st0_1 values(1654218413000,8601,'A')(1654218423000,8601,'D')") tdSql.execute( "create stable st1(ts timestamp, c11 float, c12 nchar(10)) tags(t1 int)") tdSql.execute( "create table st1_0 using st1 tags(0) st1_1 using st1 tags(1) ") tdSql.execute( - "insert into st1_0 values(1614218412000,8610.1,'R')(1614218422000,8610.1,'E')") + "insert into st1_0 values(1654218412000,8610.1,'R')(1654218422000,8610.1,'E')") tdSql.execute( - "insert into st1_1 values(1614218413000,8611.2,'A')(1614218423000,8611.1,'D')") + "insert into st1_1 values(1654218413000,8611.2,'A')(1654218423000,8611.1,'D')") tdSql.execute( "create stable st2(ts timestamp, c21 float, c22 nchar(10)) tags(t1 int)") tdSql.execute( "create table st2_0 using st2 tags(0) st2_1 using st2 tags(1) ") tdSql.execute( - "insert into st2_0 values(1614218412000,8620.3,'R')(1614218422000,8620.3,'E')") + "insert into st2_0 values(1654218412000,8620.3,'R')(1654218422000,8620.3,'E')") tdSql.execute( - "insert into st2_1 values(1614218413000,8621.4,'A')(1614218423000,8621.4,'D')") + "insert into st2_1 values(1654218413000,8621.4,'A')(1654218423000,8621.4,'D')") tdSql.execute( "create table if not exists gt0 (ts timestamp, c00 int, c01 float) ") tdSql.execute( "create table if not exists gt1 (ts timestamp, c10 int, c11 double) ") tdSql.execute( "create table if not exists gt2 (ts timestamp, c20 int, c21 float) ") - tdSql.execute("insert into gt0 values(1614218412700,8637,78.86155)") + tdSql.execute("insert into gt0 values(1654218412700,8637,78.86155)") tdSql.execute( - "insert into gt1 values(1614218413800,8638,78.862020199)") - tdSql.execute("insert into gt2 values(1614218413900,8639,78.863)") + "insert into gt1 values(1654218413800,8638,78.862020199)") + tdSql.execute("insert into gt2 values(1654218413900,8639,78.863)") # create tdSql.execute("create database if not exists dp3 precision 'ns'") @@ -141,13 +142,15 @@ class TDTestCase: tdSql.execute( "create table st0_0 using st0 tags(0) st0_1 using st0 tags(1) ") tdSql.execute( - "insert into st0_0 values(1614218412000000001,8600,'R')(1614218422000000002,8600,'E')") + "insert into st0_0 values(1654218412000000001,8600,'R')(1654218422000000002,8600,'E')") tdSql.execute( - "insert into st0_1 values(1614218413000000001,8601,'A')(1614218423000000002,8601,'D')") + "insert into st0_1 values(1654218413000000001,8601,'A')(1654218423000000002,8601,'D')") +# sys.exit(0) # # taosdump stable and general table os.system("%s -o ./taosdumptest/tmp1 -D dp1,dp2 -T 8 " % binPath) os.system("%s -o ./taosdumptest/tmp2 dp1 st0 gt0 -T 8 " % binPath) + #sys.exit(0) os.system( "%s -o ./taosdumptest/tmp3 dp2 st0 st1_0 gt0 -T 8 " % binPath) -- GitLab From a4d4fa1a44a2eeb1bc948987ca41811f0b325ced Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 1 Sep 2022 15:26:54 +0800 Subject: [PATCH 363/380] feat: update taos-tools 2460442 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index aa45ad44c6..2460442287 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit aa45ad44c61f7ea47149290eeafb6cf2dc2f3a42 +Subproject commit 246044228767cbf14452d19e2c895cdce842e1e7 -- GitLab From 7d02865ff6ed8b9e21109668f1b7710c5a9b20b0 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 1 Sep 2022 15:53:16 +0800 Subject: [PATCH 364/380] feat: update taos-tools d2b5dec for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 2460442287..d2b5dece5a 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 246044228767cbf14452d19e2c895cdce842e1e7 +Subproject commit d2b5dece5ab16fab19be78dbfd122646d0898087 -- GitLab From 19f9a350ac77885ca55d0afc86c2c82c72a29c7c Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Thu, 1 Sep 2022 16:08:54 +0800 Subject: [PATCH 365/380] Update index.md --- docs/en/02-intro/index.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index a21d495018..1dc27ae0a0 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -3,7 +3,7 @@ title: Introduction toc_max_heading_level: 2 --- -TDengine is a high-performance, scalable [time-series database](https://tdengine.com/tsdb) with SQL support. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](/develop/cache), [stream processing](/develop/continuous-query), [data subscription](/develop/subscribe) and other functionalities to reduce the complexity and cost of development and operation. +TDengine is a high-performance, scalable [time-series database](https://tdengine.com/tsdb) with SQL support. Its code, including its cluster feature is open source under GNU AGPL v3.0. Besides the database engine, it provides [caching](../develop/cache), [stream processing](../develop/continuous-query), [data subscription](../develop/subscribe) and other functionalities to reduce the complexity and cost of development and operation. This section introduces the major features, competitive advantages, typical use-cases and benchmarks to help you get a high level overview of TDengine. @@ -11,20 +11,20 @@ This section introduces the major features, competitive advantages, typical use- The major features are listed below: -1. While TDengine supports [using SQL to insert](/develop/insert-data/sql-writing), it also supports [Schemaless writing](/reference/schemaless/) just like NoSQL databases. TDengine also supports standard protocols like [InfluxDB LINE](/develop/insert-data/influxdb-line),[OpenTSDB Telnet](/develop/insert-data/opentsdb-telnet), [OpenTSDB JSON ](/develop/insert-data/opentsdb-json) among others. -2. TDengine supports seamless integration with third-party data collection agents like [Telegraf](/third-party/telegraf),[Prometheus](/third-party/prometheus),[StatsD](/third-party/statsd),[collectd](/third-party/collectd),[icinga2](/third-party/icinga2), [TCollector](/third-party/tcollector), [EMQX](/third-party/emq-broker), [HiveMQ](/third-party/hive-mq-broker). These agents can write data into TDengine with simple configuration and without a single line of code. -3. Support for [all kinds of queries](/develop/query-data), including aggregation, nested query, downsampling, interpolation and others. -4. Support for [user defined functions](/develop/udf). -5. Support for [caching](/develop/cache). TDengine always saves the last data point in cache, so Redis is not needed in some scenarios. +1. While TDengine supports [using SQL to insert](../develop/insert-data/sql-writing), it also supports [Schemaless writing](../reference/schemaless/) just like NoSQL databases. TDengine also supports standard protocols like [InfluxDB LINE](/develop/insert-data/influxdb-line),[OpenTSDB Telnet](../develop/insert-data/opentsdb-telnet), [OpenTSDB JSON ](../develop/insert-data/opentsdb-json) among others. +2. TDengine supports seamless integration with third-party data collection agents like [Telegraf](../third-party/telegraf),[Prometheus](../third-party/prometheus),[StatsD](../third-party/statsd),[collectd](../third-party/collectd),[icinga2](../third-party/icinga2), [TCollector](../third-party/tcollector), [EMQX](../third-party/emq-broker), [HiveMQ](../third-party/hive-mq-broker). These agents can write data into TDengine with simple configuration and without a single line of code. +3. Support for [all kinds of queries](../develop/query-data), including aggregation, nested query, downsampling, interpolation and others. +4. Support for [user defined functions](../develop/udf). +5. Support for [caching](../develop/cache). TDengine always saves the last data point in cache, so Redis is not needed in some scenarios. 6. Support for [continuous query](../develop/continuous-query). 7. Support for [data subscription](../develop/subscribe) with the capability to specify filter conditions. 8. Support for [cluster](../cluster/), with the capability of increasing processing power by adding more nodes. High availability is supported by replication. -9. Provides an interactive [command-line interface](/reference/taos-shell) for management, maintenance and ad-hoc queries. -10. Provides many ways to [import](/operation/import) and [export](/operation/export) data. -11. Provides [monitoring](/operation/monitor) on running instances of TDengine. -12. Provides [connectors](/reference/connector/) for [C/C++](/reference/connector/cpp), [Java](/reference/connector/java), [Python](/reference/connector/python), [Go](/reference/connector/go), [Rust](/reference/connector/rust), [Node.js](/reference/connector/node) and other programming languages. -13. Provides a [REST API](/reference/rest-api/). -14. Supports seamless integration with [Grafana](/third-party/grafana) for visualization. +9. Provides an interactive [command-line interface](../reference/taos-shell) for management, maintenance and ad-hoc queries. +10. Provides many ways to [import](/operation/import) and [export](../operation/export) data. +11. Provides [monitoring](../operation/monitor) on running instances of TDengine. +12. Provides [connectors](../reference/connector/) for [C/C++](../reference/connector/cpp), [Java](../reference/connector/java), [Python](../reference/connector/python), [Go](../reference/connector/go), [Rust](../reference/connector/rust), [Node.js](../reference/connector/node) and other programming languages. +13. Provides a [REST API](../reference/rest-api/). +14. Supports seamless integration with [Grafana](../third-party/grafana) for visualization. 15. Supports seamless integration with Google Data Studio. For more details on features, please read through the entire documentation. -- GitLab From d8518c65b598591c0f9c7352d274073cf5ee8671 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 1 Sep 2022 19:29:46 +0800 Subject: [PATCH 366/380] feat: update taostools for2.6 (#16572) * feat: update taos-tools for 2.6 [TD-14141] * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: updaete taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools for 2.6 * fix: update taos-tools for 2.6 * fix: arm build for 2.6 * fix: disable make install on arm64 * fix: disable taodump test case in parallel_test/cases.task temporarily * feat: update taos-tools for 2.6 * feat: revert cases.task for taosdump * feat: update taos-tools 9dc2fec for 2.6 * fix: use jenkinsfile2 same as develop branch * feat: update taos-tools 0e0fea3431 for 2.6 * feat: cherry pick test case changes * fix: remove walLevel from json files * fix: for taosdemo * feat: update taos-tools for 2.6 * feat: update taos-tools 8157e3b for 2.6 * feat: update taos-tools c9cc20f for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 3c7dafe for 2.6 * feat: update taos-tools for 2.6 * feat: update taos-tools 57bdfbf for 2.6 * feat: update taos-tools 11d23e5 for 2.6 * feat: update taos-tools 43924b8 for 2.6 * feat: update taos-tools 6bde102 for 2.6 * feat: update taos-tools 2af2222 for 2.6 * feat: update taos-tools 833b721 for 2.6 * feat: update taos-tools e8bfca6 for 2.6 * feat: update taos-tools aa45ad4 for 2.6 * feat: update taos-tools 2460442 for 2.6 * feat: update taos-tools d2b5dec for 2.6 Co-authored-by: zhaoyanggh --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index aa45ad44c6..d2b5dece5a 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit aa45ad44c61f7ea47149290eeafb6cf2dc2f3a42 +Subproject commit d2b5dece5ab16fab19be78dbfd122646d0898087 -- GitLab From 68b746be7d08b2f3d8585c66674524a4bd4273d4 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 1 Sep 2022 22:57:42 +0800 Subject: [PATCH 367/380] feat: update taos-tools 212c34d for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index d2b5dece5a..212c34d2dd 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit d2b5dece5ab16fab19be78dbfd122646d0898087 +Subproject commit 212c34d2dd71b34e8602ed2e29e84ce789cc358b -- GitLab From 01c657813d78e6e3424d3160aad637f58910e6cd Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 2 Sep 2022 13:23:46 +0800 Subject: [PATCH 368/380] feat(rcp): add some log on rpc and tcp --- src/rpc/src/rpcTcp.c | 29 +++++++++++++++++++++++++++-- src/util/src/tsocket.c | 9 ++++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index 530a279cc7..a92750e00c 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -32,6 +32,7 @@ typedef struct SFdObj { struct SThreadObj *pThreadObj; struct SFdObj *prev; struct SFdObj *next; + uint64_t ctime; // create time } SFdObj; typedef struct SThreadObj { @@ -280,6 +281,7 @@ static void *taosAcceptTcpConnection(void *arg) { if (pFdObj) { pFdObj->ip = caddr.sin_addr.s_addr; pFdObj->port = htons(caddr.sin_port); + pFdObj->ctime = taosGetTimestampMs(); tDebug("%s new TCP connection from %s:%hu, fd:%d FD:%p numOfFds:%d", pServerObj->label, taosInetNtoa(caddr.sin_addr), pFdObj->port, connFd, pFdObj, pThreadObj->numOfFds); } else { @@ -417,6 +419,7 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin pFdObj->thandle = thandle; pFdObj->port = port; pFdObj->ip = ip; + pFdObj->ctime = taosGetTimestampMs(); tDebug("%s %p TCP connection to 0x%x:%hu is created, localPort:%hu FD:%p numOfFds:%d", pThreadObj->label, thandle, ip, port, localPort, pFdObj, pThreadObj->numOfFds); } else { @@ -432,7 +435,7 @@ void taosCloseTcpConnection(void *chandle) { if (pFdObj == NULL || pFdObj->signature != pFdObj) return; SThreadObj *pThreadObj = pFdObj->pThreadObj; - tDebug("%s %p TCP connection will be closed, FD:%p", pThreadObj->label, pFdObj->thandle, pFdObj); + tDebug("DEEP %s shutdown3 fd=%d ip=%d port=%d ctime=%" PRId64, pThreadObj->label, pFdObj->fd, pFdObj->ip, pFdObj->port, pFdObj->ctime); // pFdObj->thandle = NULL; pFdObj->closedByApp = 1; @@ -441,11 +444,28 @@ void taosCloseTcpConnection(void *chandle) { int taosSendTcpData(uint32_t ip, uint16_t port, void *data, int len, void *chandle) { SFdObj *pFdObj = chandle; - if (pFdObj == NULL || pFdObj->signature != pFdObj) return -1; + if (pFdObj == NULL) { + tError("DEEP TCP send data failed(chandle null). data=0x%p len=%d ip=0x%0x port=%d", data, len, ip, port); + return -1; + } + if(pFdObj->signature != pFdObj) { + tError("DEEP TCP send data failed(sig diff). pFdObj=0x%p sig=0x%p data=%p len=%d ip=0x%x port=%d", pFdObj, pFdObj->signature, data, len, ip, port); + return -2; + } + SThreadObj *pThreadObj = pFdObj->pThreadObj; int ret = taosWriteMsg(pFdObj->fd, data, len); tTrace("%s %p TCP data is sent, FD:%p fd:%d bytes:%d", pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, ret); + if(ret < 0) { + tError("DEEP %s %p TCP data sent failed and try again, FD:%p fd:%d ctime=" PRId64 " ret=%d le=%d ip=%d port=%d threadid=%d numofFds=%d", + pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, pFdObj->ctime, ret, len, ip, port, pThreadObj->threadId, pThreadObj->numOfFds); + ret = taosWriteMsg(pFdObj->fd, data, len); + if(ret < 0) { + tError("DEEP %s %p Second TCP data sent failed, FD:%p fd:%d ctime=" PRId64 " ret=%d le=%d ip=%d port=%d threadid=%d numofFds=%d", + pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, pFdObj->ctime, ret, len, ip, port, pThreadObj->threadId, pThreadObj->numOfFds); + } + } return ret; } @@ -457,6 +477,7 @@ static void taosReportBrokenLink(SFdObj *pFdObj) { // notify the upper layer, so it will clean the associated context if (pFdObj->closedByApp == 0) { shutdown(pFdObj->fd, SHUT_WR); + tDebug("DEEP %s shutdown2 fd=%d ip=%d port=%d ctime=%" PRId64, pThreadObj->label, pFdObj->fd, pFdObj->ip, pFdObj->port, pFdObj->ctime); SRecvInfo recvInfo; recvInfo.msg = NULL; @@ -574,6 +595,7 @@ static void *taosProcessTcpData(void *param) { } if (taosReadTcpData(pFdObj, &recvInfo) < 0) { + tDebug("DEEP %s shutdown1 fd=%d ip=%d port=%d ctime=%" PRId64, pThreadObj->label, pFdObj->fd, pFdObj->ip, pFdObj->port, pFdObj->ctime); shutdown(pFdObj->fd, SHUT_WR); continue; } @@ -650,7 +672,10 @@ static void taosFreeFdObj(SFdObj *pFdObj) { pFdObj->signature = NULL; epoll_ctl(pThreadObj->pollFd, EPOLL_CTL_DEL, pFdObj->fd, NULL); + tDebug("DEEP %s close1 fd=%d pFdObj=%p ip=%d port=%d ctime=%" PRId64 " thandle=%p", + pThreadObj->label, pFdObj->fd, pFdObj, pFdObj->ip, pFdObj->port,pFdObj->thandle); taosCloseSocket(pFdObj->fd); + pThreadObj->numOfFds--; if (pThreadObj->numOfFds < 0) diff --git a/src/util/src/tsocket.c b/src/util/src/tsocket.c index 0ebe9c8f8a..19c72d2e0b 100644 --- a/src/util/src/tsocket.c +++ b/src/util/src/tsocket.c @@ -129,15 +129,18 @@ int32_t taosWriteMsg(SOCKET fd, void *buf, int32_t nbytes) { if (nwritten <= 0) { if (errno == EINTR /* || errno == EAGAIN || errno == EWOULDBLOCK */) continue; - else - return -1; + else { + uError("DEEP write socket failed3. errno=%d fd=%d writeten=%d left=%d", errno, fd, nwritten, nleft); + return -3; + } } else { nleft -= nwritten; ptr += nwritten; } if (errno == SIGPIPE || errno == EPIPE) { - return -1; + uError("DEEP write socket failed4. errno=%d fd=%d writeten=%d left=%d", errno, fd, nwritten, nleft); + return -4; } } -- GitLab From 9bc2a93daaeddc70b9dadeaba98c965201ac1047 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 2 Sep 2022 13:24:40 +0800 Subject: [PATCH 369/380] feat: update taos-tools f169c0f for 2.6 (#16602) --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index 212c34d2dd..f169c0f721 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit 212c34d2dd71b34e8602ed2e29e84ce789cc358b +Subproject commit f169c0f7219add756bc109d0ae89ee37d170eee4 -- GitLab From 07ee8a3cc5ae2aedcfcc460e885fcd338a42b642 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 2 Sep 2022 13:40:17 +0800 Subject: [PATCH 370/380] feat(rpc): fixed build error --- src/rpc/src/rpcTcp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index a92750e00c..b5a71972ef 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -458,11 +458,11 @@ int taosSendTcpData(uint32_t ip, uint16_t port, void *data, int len, void *chand int ret = taosWriteMsg(pFdObj->fd, data, len); tTrace("%s %p TCP data is sent, FD:%p fd:%d bytes:%d", pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, ret); if(ret < 0) { - tError("DEEP %s %p TCP data sent failed and try again, FD:%p fd:%d ctime=" PRId64 " ret=%d le=%d ip=%d port=%d threadid=%d numofFds=%d", + tError("DEEP %s %p TCP data sent failed and try again, FD:%p fd:%d ctime=%" PRId64 " ret=%d le=%d ip=%d port=%d threadid=%d numofFds=%d", pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, pFdObj->ctime, ret, len, ip, port, pThreadObj->threadId, pThreadObj->numOfFds); ret = taosWriteMsg(pFdObj->fd, data, len); if(ret < 0) { - tError("DEEP %s %p Second TCP data sent failed, FD:%p fd:%d ctime=" PRId64 " ret=%d le=%d ip=%d port=%d threadid=%d numofFds=%d", + tError("DEEP %s %p Second TCP data sent failed, FD:%p fd:%d ctime=%" PRId64 " ret=%d le=%d ip=%d port=%d threadid=%d numofFds=%d", pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, pFdObj->ctime, ret, len, ip, port, pThreadObj->threadId, pThreadObj->numOfFds); } } @@ -673,7 +673,7 @@ static void taosFreeFdObj(SFdObj *pFdObj) { pFdObj->signature = NULL; epoll_ctl(pThreadObj->pollFd, EPOLL_CTL_DEL, pFdObj->fd, NULL); tDebug("DEEP %s close1 fd=%d pFdObj=%p ip=%d port=%d ctime=%" PRId64 " thandle=%p", - pThreadObj->label, pFdObj->fd, pFdObj, pFdObj->ip, pFdObj->port,pFdObj->thandle); + pThreadObj->label, pFdObj->fd, pFdObj, pFdObj->ip, pFdObj->port, pFdObj->ctime, pFdObj->thandle); taosCloseSocket(pFdObj->fd); -- GitLab From df5b08c0ddd66ab4cf070e1f0f2f066a0cbfbc16 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Fri, 2 Sep 2022 13:54:00 +0800 Subject: [PATCH 371/380] feat(rpc): ip replace hex format --- src/rpc/src/rpcTcp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index b5a71972ef..43c386b8b5 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -435,7 +435,7 @@ void taosCloseTcpConnection(void *chandle) { if (pFdObj == NULL || pFdObj->signature != pFdObj) return; SThreadObj *pThreadObj = pFdObj->pThreadObj; - tDebug("DEEP %s shutdown3 fd=%d ip=%d port=%d ctime=%" PRId64, pThreadObj->label, pFdObj->fd, pFdObj->ip, pFdObj->port, pFdObj->ctime); + tDebug("DEEP %s shutdown3 fd=%d ip=0x%x port=%d ctime=%" PRId64, pThreadObj->label, pFdObj->fd, pFdObj->ip, pFdObj->port, pFdObj->ctime); // pFdObj->thandle = NULL; pFdObj->closedByApp = 1; @@ -458,11 +458,11 @@ int taosSendTcpData(uint32_t ip, uint16_t port, void *data, int len, void *chand int ret = taosWriteMsg(pFdObj->fd, data, len); tTrace("%s %p TCP data is sent, FD:%p fd:%d bytes:%d", pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, ret); if(ret < 0) { - tError("DEEP %s %p TCP data sent failed and try again, FD:%p fd:%d ctime=%" PRId64 " ret=%d le=%d ip=%d port=%d threadid=%d numofFds=%d", + tError("DEEP %s %p TCP data sent failed and try again, FD:%p fd:%d ctime=%" PRId64 " ret=%d le=%d ip=0x%x port=%d threadid=%d numofFds=%d", pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, pFdObj->ctime, ret, len, ip, port, pThreadObj->threadId, pThreadObj->numOfFds); ret = taosWriteMsg(pFdObj->fd, data, len); if(ret < 0) { - tError("DEEP %s %p Second TCP data sent failed, FD:%p fd:%d ctime=%" PRId64 " ret=%d le=%d ip=%d port=%d threadid=%d numofFds=%d", + tError("DEEP %s %p Second TCP data sent failed, FD:%p fd:%d ctime=%" PRId64 " ret=%d le=%d ip=0x%x port=%d threadid=%d numofFds=%d", pThreadObj->label, pFdObj->thandle, pFdObj, pFdObj->fd, pFdObj->ctime, ret, len, ip, port, pThreadObj->threadId, pThreadObj->numOfFds); } } @@ -477,7 +477,7 @@ static void taosReportBrokenLink(SFdObj *pFdObj) { // notify the upper layer, so it will clean the associated context if (pFdObj->closedByApp == 0) { shutdown(pFdObj->fd, SHUT_WR); - tDebug("DEEP %s shutdown2 fd=%d ip=%d port=%d ctime=%" PRId64, pThreadObj->label, pFdObj->fd, pFdObj->ip, pFdObj->port, pFdObj->ctime); + tDebug("DEEP %s shutdown2 fd=%d ip=0x%x port=%d ctime=%" PRId64, pThreadObj->label, pFdObj->fd, pFdObj->ip, pFdObj->port, pFdObj->ctime); SRecvInfo recvInfo; recvInfo.msg = NULL; @@ -595,7 +595,7 @@ static void *taosProcessTcpData(void *param) { } if (taosReadTcpData(pFdObj, &recvInfo) < 0) { - tDebug("DEEP %s shutdown1 fd=%d ip=%d port=%d ctime=%" PRId64, pThreadObj->label, pFdObj->fd, pFdObj->ip, pFdObj->port, pFdObj->ctime); + tDebug("DEEP %s shutdown1 fd=%d ip=0x%x port=%d ctime=%" PRId64, pThreadObj->label, pFdObj->fd, pFdObj->ip, pFdObj->port, pFdObj->ctime); shutdown(pFdObj->fd, SHUT_WR); continue; } @@ -672,7 +672,7 @@ static void taosFreeFdObj(SFdObj *pFdObj) { pFdObj->signature = NULL; epoll_ctl(pThreadObj->pollFd, EPOLL_CTL_DEL, pFdObj->fd, NULL); - tDebug("DEEP %s close1 fd=%d pFdObj=%p ip=%d port=%d ctime=%" PRId64 " thandle=%p", + tDebug("DEEP %s close1 fd=%d pFdObj=%p ip=0x%x port=%d ctime=%" PRId64 " thandle=%p", pThreadObj->label, pFdObj->fd, pFdObj, pFdObj->ip, pFdObj->port, pFdObj->ctime, pFdObj->thandle); taosCloseSocket(pFdObj->fd); -- GitLab From d61a86e6db21dc4511b3d751efd32c6f646c8c40 Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Fri, 2 Sep 2022 18:45:51 +0800 Subject: [PATCH 372/380] feat: update taostools a4d9b92 for2.6 (#16628) * feat: update taos-tools f169c0f for 2.6 * feat: update taos-tools a4d9b92 for 2.6 --- src/kit/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index f169c0f721..a4d9b9229a 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit f169c0f7219add756bc109d0ae89ee37d170eee4 +Subproject commit a4d9b9229a7243a1c337ee6e34ee369a2f942dfb -- GitLab From 8905096b67978e930291f4ac092a8050c1ea427f Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 6 Sep 2022 10:14:23 +0800 Subject: [PATCH 373/380] fix: typo error when find long query --- src/query/src/queryMain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index 325225e695..7187637b70 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -642,7 +642,7 @@ static int compareLongQuery(const void* p1, const void* p2) { } // callback for taosCacheRefresh -static void cbFoundItem(void* handle, void* param1) { +static void cbFoundLongQuery(void* handle, void* param1) { SQInfo * qInfo = *(SQInfo**) handle; if(qInfo == NULL) return ; SArray* qids = (SArray*) param1; @@ -654,7 +654,7 @@ static void cbFoundItem(void* handle, void* param1) { SMemTable* imem = qInfo->query.memRef.snapshot.imem; if(mem == NULL || T_REF_VAL_GET(mem) == 0) usedMem = false; - if(imem == NULL || T_REF_VAL_GET(mem) == 0) + if(imem == NULL || T_REF_VAL_GET(imem) == 0) usedIMem = false ; if(!usedMem && !usedIMem) @@ -675,7 +675,7 @@ void* qObtainLongQuery(void* param){ SArray* qids = taosArrayInit(4, sizeof(int64_t*)); if(qids == NULL) return NULL; // Get each item - taosCacheRefresh(qMgmt->qinfoPool, cbFoundItem, qids); + taosCacheRefresh(qMgmt->qinfoPool, cbFoundLongQuery, qids); size_t cnt = taosArrayGetSize(qids); if(cnt == 0) { -- GitLab From 09cc26f044f1aa2050334a7600a613e7d788bf0d Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 6 Sep 2022 10:26:59 +0800 Subject: [PATCH 374/380] fix: return syntax error when field num is zero in line protocol --- src/client/src/tscParseLineProtocol.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index 81056f2f77..a5673378f5 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -930,7 +930,7 @@ _cleanup: free(colKVs); if (r == fromIndex) { - tscError("buffer can not fit one line"); + tscDebug("buffer can not fit one line"); *cTableSqlLen = 0; } else { *cTableSqlLen = totalLen; @@ -2608,6 +2608,12 @@ int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData, SSmlLinesInf return ret; } tscDebug("SML:0x%"PRIx64" Parse fields finished, num of fields:%d", info->id, smlData->fieldNum); + if (smlData->fieldNum == 0) { + tscDebug("SML:0x%"PRIx64" Parse fields error, no field in line", info->id); + taosHashCleanup(keyHashTable); + return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; + } + taosHashCleanup(keyHashTable); //Parse timestamp -- GitLab From 6d79a5f58967bfe9ef2277f12aca59a10afa3b02 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 6 Sep 2022 12:52:47 +0800 Subject: [PATCH 375/380] fix(query): save row count with int16_t smaller --- src/common/inc/texpr.h | 2 +- src/common/src/texpr.c | 42 ++++++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/common/inc/texpr.h b/src/common/inc/texpr.h index 5fdb56703d..3ce519c140 100644 --- a/src/common/inc/texpr.h +++ b/src/common/inc/texpr.h @@ -85,7 +85,7 @@ struct SSchema; typedef struct { int16_t type; int16_t bytes; - int16_t numOfRows; + int32_t numOfRows; char* data; } tExprOperandInfo; diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index 7198c3d464..1acfd3c4f9 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -668,55 +668,56 @@ void exprTreeExprNodeTraverse(tExprNode *pExpr, int32_t numOfRows, tExprOperandI pl = ltmp; pt = transl; + int32_t i; switch (left.type) { case TSDB_DATA_TYPE_TINYINT: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((int8_t *) pl + i)); } break; case TSDB_DATA_TYPE_SMALLINT: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((int16_t *) pl + i)); } break; case TSDB_DATA_TYPE_INT: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((int32_t *) pl + i)); } break; case TSDB_DATA_TYPE_BIGINT: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((int64_t *) pl + i)); } break; case TSDB_DATA_TYPE_UTINYINT: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((uint8_t *) pl + i)); } break; case TSDB_DATA_TYPE_USMALLINT: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((uint16_t *) pl + i)); } break; case TSDB_DATA_TYPE_UINT: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((uint32_t *) pl + i)); } break; case TSDB_DATA_TYPE_UBIGINT: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((uint64_t *) pl + i)); } break; case TSDB_DATA_TYPE_FLOAT: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((float *) pl + i)); } break; case TSDB_DATA_TYPE_DOUBLE: - for (int16_t i = 0; i < left.numOfRows; i++) { + for (i = 0; i < left.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((double *) pl + i)); } break; @@ -766,55 +767,56 @@ void exprTreeExprNodeTraverse(tExprNode *pExpr, int32_t numOfRows, tExprOperandI pr = rtmp; pt = transr; + int32_t i; switch (right.type) { case TSDB_DATA_TYPE_TINYINT: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((int8_t *) pr + i)); } break; case TSDB_DATA_TYPE_SMALLINT: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((int16_t *) pr + i)); } break; case TSDB_DATA_TYPE_INT: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((int32_t *) pr + i)); } break; case TSDB_DATA_TYPE_BIGINT: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((int64_t *) pr + i)); } break; case TSDB_DATA_TYPE_UTINYINT: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((uint8_t *) pr + i)); } break; case TSDB_DATA_TYPE_USMALLINT: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((uint16_t *) pr + i)); } break; case TSDB_DATA_TYPE_UINT: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((uint32_t *) pr + i)); } break; case TSDB_DATA_TYPE_UBIGINT: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((uint64_t *) pr + i)); } break; case TSDB_DATA_TYPE_FLOAT: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((float *) pr + i)); } break; case TSDB_DATA_TYPE_DOUBLE: - for (int16_t i = 0; i < right.numOfRows; i++) { + for (i = 0; i < right.numOfRows; i++) { *((int64_t *) pt + i) = (int64_t)(*((double *) pr + i)); } break; -- GitLab From e1b0f65639c18a93da1f549c09714b403843bb46 Mon Sep 17 00:00:00 2001 From: slzhou Date: Wed, 7 Sep 2022 08:52:39 +0800 Subject: [PATCH 376/380] fix: tag should not be null for filled rows --- src/client/src/tscUtil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 116f7deb1c..6c03aeefd7 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -4965,7 +4965,7 @@ int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaI } } - if (!pQueryInfo->stableQuery && TSDB_COL_IS_TAG(pSource->base.colInfo.flag)) { + if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) && TSDB_COL_IS_TAG(pSource->base.colInfo.flag)) { pse->colInfo.flag = (pSource->base.colInfo.flag) & (~TSDB_COL_TAG); } else { pse->colInfo.flag = pSource->base.colInfo.flag; -- GitLab From b3a4bf11c366c08697bc6856b0538bf67f1281fc Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Wed, 7 Sep 2022 13:33:30 +0800 Subject: [PATCH 377/380] feat: update taostools 7d5c1c0 for2.6 (#16711) * feat: update taos-tools f169c0f for 2.6 * feat: update taos-tools a4d9b92 for 2.6 * feat: update taos-tools 7d5c1c0 for 2.6 * fix: 5-taos-tools/taosbenchmark/taosdemoTestInsertWithJson-childTable.py after, create table without if not exits * fix: 5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonStmt.py after, create table without if not exits --- src/kit/taos-tools | 2 +- .../taosdemoTestInsertWithJson-childTable.py | 60 +++++---- .../taosdemoTestInsertWithJsonStmt.py | 127 ++++++++++-------- 3 files changed, 110 insertions(+), 79 deletions(-) diff --git a/src/kit/taos-tools b/src/kit/taos-tools index a4d9b9229a..7d5c1c016d 160000 --- a/src/kit/taos-tools +++ b/src/kit/taos-tools @@ -1 +1 @@ -Subproject commit a4d9b9229a7243a1c337ee6e34ee369a2f942dfb +Subproject commit 7d5c1c016d2022d152a6aaa38589f2fbaa0d25a4 diff --git a/tests/system-test/5-taos-tools/taosbenchmark/taosdemoTestInsertWithJson-childTable.py b/tests/system-test/5-taos-tools/taosbenchmark/taosdemoTestInsertWithJson-childTable.py index 56d402baa1..1729f4201c 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/taosdemoTestInsertWithJson-childTable.py +++ b/tests/system-test/5-taos-tools/taosbenchmark/taosdemoTestInsertWithJson-childTable.py @@ -27,37 +27,43 @@ class TDTestCase: def getBuildPath(self): selfPath = os.path.dirname(os.path.realpath(__file__)) - if ("community" in selfPath): - projPath = selfPath[:selfPath.find("community")] + if "community" in selfPath: + projPath = selfPath[: selfPath.find("community")] else: - projPath = selfPath[:selfPath.find("tests")] + projPath = selfPath[: selfPath.find("tests")] for root, dirs, files in os.walk(projPath): - if ("taosd" in files): + if "taosd" in files: rootRealPath = os.path.dirname(os.path.realpath(root)) - if ("packaging" not in rootRealPath): - buildPath = root[:len(root)-len("/build/bin")] + if "packaging" not in rootRealPath: + buildPath = root[: len(root) - len("/build/bin")] break return buildPath def run(self): buildPath = self.getBuildPath() - if (buildPath == ""): + if buildPath == "": tdLog.exit("taosd not found!") else: tdLog.info("taosd found in %s" % buildPath) - binPath = buildPath+ "/build/bin/" + binPath = buildPath + "/build/bin/" testcaseFilename = os.path.split(__file__)[-1] os.system("rm -rf ./insert*_res.txt*") - os.system("rm -rf 5-taos-tools/taosbenchmark/%s.sql" % testcaseFilename ) + os.system("rm -rf 5-taos-tools/taosbenchmark/%s.sql" % testcaseFilename) # spend 2min30s for 3 testcases. # insert: drop and child_table_exists combination test # insert: using parament "childtable_offset and childtable_limit" to control table'offset point and offset - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-nodbnodrop.json -y" % binPath) + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-nodbnodrop.json -y" + % binPath + ) tdSql.error("show dbno.stables") - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-newdb.json -y" % binPath) + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-newdb.json -y" + % binPath + ) tdSql.execute("use db") tdSql.query("select count (tbname) from stb0") tdSql.checkData(0, 0, 5) @@ -69,7 +75,10 @@ class TDTestCase: tdSql.checkData(0, 0, 8) tdSql.query("select count (tbname) from stb4") tdSql.checkData(0, 0, 8) - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-offset.json -y" % binPath) + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-offset.json -y" + % binPath + ) tdSql.execute("use db") tdSql.query("select count(*) from stb0") tdSql.checkData(0, 0, 50) @@ -81,19 +90,25 @@ class TDTestCase: tdSql.checkData(0, 0, 180) tdSql.query("select count(*) from stb4") tdSql.checkData(0, 0, 160) - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-newtable.json -y" % binPath) + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-newtable.json -y" + % binPath + ) tdSql.execute("use db") tdSql.query("select count(*) from stb0") - tdSql.checkData(0, 0, 150) + tdSql.checkData(0, 0, 50) tdSql.query("select count(*) from stb1") - tdSql.checkData(0, 0, 360) + tdSql.checkData(0, 0, 240) tdSql.query("select count(*) from stb2") - tdSql.checkData(0, 0, 360) + tdSql.checkData(0, 0, 220) tdSql.query("select count(*) from stb3") - tdSql.checkData(0, 0, 340) + tdSql.checkData(0, 0, 180) tdSql.query("select count(*) from stb4") - tdSql.checkData(0, 0, 400) - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-renewdb.json -y" % binPath) + tdSql.checkData(0, 0, 160) + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/insert-renewdb.json -y" + % binPath + ) tdSql.execute("use db") tdSql.query("select count(*) from stb0") tdSql.checkData(0, 0, 50) @@ -105,15 +120,10 @@ class TDTestCase: tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from stb4") tdSql.checkData(0, 0, 160) - + # rm useless files os.system("rm -rf ./insert*_res.txt*") - - - - - def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/system-test/5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonStmt.py b/tests/system-test/5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonStmt.py index d470dee214..885d580a9e 100644 --- a/tests/system-test/5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonStmt.py +++ b/tests/system-test/5-taos-tools/taosbenchmark/taosdemoTestInsertWithJsonStmt.py @@ -23,33 +23,36 @@ class TDTestCase: def init(self, conn, logSql): tdLog.debug("start to execute %s" % __file__) tdSql.init(conn.cursor(), logSql) - + def getBuildPath(self): selfPath = os.path.dirname(os.path.realpath(__file__)) - if ("community" in selfPath): - projPath = selfPath[:selfPath.find("community")] + if "community" in selfPath: + projPath = selfPath[: selfPath.find("community")] else: - projPath = selfPath[:selfPath.find("tests")] + projPath = selfPath[: selfPath.find("tests")] for root, dirs, files in os.walk(projPath): - if ("taosd" in files): + if "taosd" in files: rootRealPath = os.path.dirname(os.path.realpath(root)) - if ("packaging" not in rootRealPath): - buildPath = root[:len(root)-len("/build/bin")] + if "packaging" not in rootRealPath: + buildPath = root[: len(root) - len("/build/bin")] break return buildPath - + def run(self): buildPath = self.getBuildPath() - if (buildPath == ""): + if buildPath == "": tdLog.exit("taosd not found!") else: tdLog.info("taosd found in %s" % buildPath) - binPath = buildPath+ "/build/bin/" + binPath = buildPath + "/build/bin/" - # insert: create one or mutiple tables per sql and insert multiple rows per sql - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json -y " % binPath) + # insert: create one or mutiple tables per sql and insert multiple rows per sql + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-1s1tnt1r-stmt.json -y " + % binPath + ) tdSql.execute("use db") tdSql.query("select count (tbname) from stb0") tdSql.checkData(0, 0, 10) @@ -62,50 +65,61 @@ class TDTestCase: tdSql.query("select count(*) from stb01_1") tdSql.checkData(0, 0, 200) tdSql.query("select count(*) from stb1") - tdSql.checkData(0, 0, 4000) + tdSql.checkData(0, 0, 4000) - - # insert: create mutiple tables per sql and insert one rows per sql . - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json -y " % binPath) + # insert: create mutiple tables per sql and insert one rows per sql . + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-1s1tntmr-stmt.json -y " + % binPath + ) tdSql.execute("use db") tdSql.query("select count (tbname) from stb0") tdSql.checkData(0, 0, 10) tdSql.query("select count (tbname) from stb1") tdSql.checkData(0, 0, 20) tdSql.query("select count(*) from stb00_0") - tdSql.checkData(0, 0, 100) + tdSql.checkData(0, 0, 100) tdSql.query("select count(*) from stb0") - tdSql.checkData(0, 0, 1000) + tdSql.checkData(0, 0, 1000) tdSql.query("select count(*) from stb01_0") - tdSql.checkData(0, 0, 200) + tdSql.checkData(0, 0, 200) tdSql.query("select count(*) from stb1") - tdSql.checkData(0, 0, 4000) + tdSql.checkData(0, 0, 4000) - # insert: using parament "insert_interval to controls spped of insert. + # insert: using parament "insert_interval to controls spped of insert. # but We need to have accurate methods to control the speed, such as getting the speed value, checking the count and so on。 - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json -y" % binPath) + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-interval-speed-stmt.json -y" + % binPath + ) tdSql.execute("use db") tdSql.query("select count (tbname) from stb0") tdSql.checkData(0, 0, 10) tdSql.query("select count (tbname) from stb1") tdSql.checkData(0, 0, 20) tdSql.query("select count(*) from stb00_0") - tdSql.checkData(0, 0, 100) + tdSql.checkData(0, 0, 100) tdSql.query("select count(*) from stb0") - tdSql.checkData(0, 0, 1000) + tdSql.checkData(0, 0, 1000) tdSql.query("show stables") tdSql.checkData(1, 4, 20) tdSql.query("select count(*) from stb01_0") - tdSql.checkData(0, 0, 200) + tdSql.checkData(0, 0, 200) tdSql.query("select count(*) from stb1") - tdSql.checkData(0, 0, 4000) - + tdSql.checkData(0, 0, 4000) + # spend 2min30s for 3 testcases. # insert: drop and child_table_exists combination test - # insert: using parament "childtable_offset and childtable_limit" to control table'offset point and offset - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json -y" % binPath) + # insert: using parament "childtable_offset and childtable_limit" to control table'offset point and offset + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-nodbnodrop-stmt.json -y" + % binPath + ) tdSql.error("show dbno.stables") - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json -y" % binPath) + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-newdb-stmt.json -y" + % binPath + ) tdSql.execute("use db") tdSql.query("select count (tbname) from stb0") tdSql.checkData(0, 0, 5) @@ -114,41 +128,50 @@ class TDTestCase: tdSql.query("select count (tbname) from stb2") tdSql.checkData(0, 0, 7) tdSql.query("select count (tbname) from stb3") - tdSql.checkData(0, 0, 8) + tdSql.checkData(0, 0, 8) tdSql.query("select count (tbname) from stb4") - tdSql.checkData(0, 0, 8) - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json -y" % binPath) - tdSql.execute("use db") + tdSql.checkData(0, 0, 8) + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-offset-stmt.json -y" + % binPath + ) + tdSql.execute("use db") tdSql.query("select count(*) from stb0") - tdSql.checkData(0, 0, 50) + tdSql.checkData(0, 0, 50) tdSql.query("select count(*) from stb1") - tdSql.checkData(0, 0, 240) + tdSql.checkData(0, 0, 240) tdSql.query("select count(*) from stb2") - tdSql.checkData(0, 0, 220) + tdSql.checkData(0, 0, 220) tdSql.query("select count(*) from stb3") tdSql.checkData(0, 0, 180) tdSql.query("select count(*) from stb4") tdSql.checkData(0, 0, 160) - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json -y" % binPath) - tdSql.execute("use db") + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-newtable-stmt.json -y" + % binPath + ) + tdSql.execute("use db") tdSql.query("select count(*) from stb0") - tdSql.checkData(0, 0, 150) + tdSql.checkData(0, 0, 50) tdSql.query("select count(*) from stb1") - tdSql.checkData(0, 0, 360) + tdSql.checkData(0, 0, 240) tdSql.query("select count(*) from stb2") - tdSql.checkData(0, 0, 360) + tdSql.checkData(0, 0, 220) tdSql.query("select count(*) from stb3") - tdSql.checkData(0, 0, 340) + tdSql.checkData(0, 0, 180) tdSql.query("select count(*) from stb4") - tdSql.checkData(0, 0, 400) - os.system("%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json -y" % binPath) - tdSql.execute("use db") + tdSql.checkData(0, 0, 160) + os.system( + "%staosBenchmark -f 5-taos-tools/taosbenchmark/stmt/insert-renewdb-stmt.json -y" + % binPath + ) + tdSql.execute("use db") tdSql.query("select count(*) from stb0") - tdSql.checkData(0, 0, 50) + tdSql.checkData(0, 0, 50) tdSql.query("select count(*) from stb1") - tdSql.checkData(0, 0, 120) + tdSql.checkData(0, 0, 120) tdSql.query("select count(*) from stb2") - tdSql.checkData(0, 0, 140) + tdSql.checkData(0, 0, 140) tdSql.query("select count(*) from stb3") tdSql.checkData(0, 0, 160) tdSql.query("select count(*) from stb4") @@ -156,10 +179,8 @@ class TDTestCase: testcaseFilename = os.path.split(__file__)[-1] os.system("rm -rf ./insert_res.txt") - os.system("rm -rf 5-taos-tools/taosbenchmark/%s.sql" % testcaseFilename ) - - - + os.system("rm -rf 5-taos-tools/taosbenchmark/%s.sql" % testcaseFilename) + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) -- GitLab From e5ce7a3573f01dd5672ea127eb4c44f05db401b4 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Wed, 7 Sep 2022 14:18:00 +0800 Subject: [PATCH 378/380] fix: resolve an assertion of index out of range on updating subquery status --- src/client/src/tscSubquery.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 09574e741f..1805c22a9d 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -101,13 +101,12 @@ static bool allSubqueryDone(SSqlObj *pParentSql) { bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx) { SSubqueryState *subState = &pParentSql->subState; - assert(idx < subState->numOfSub); pthread_mutex_lock(&subState->mutex); - - tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", idx:%d state set to 1", pParentSql->self, pSql->self, idx); - subState->states[idx] = 1; - + if (idx < subState->numOfSub) { + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index:%d state set to 1", pParentSql->self, pSql->self, idx); + subState->states[idx] = 1; + } bool done = allSubqueryDone(pParentSql); if (!done) { tscDebug("0x%"PRIx64" sub:%p,%d completed, total:%d", pParentSql->self, pSql, idx, pParentSql->subState.numOfSub); -- GitLab From c251cf591d7c7d6d2e95a8d976d28fac3dcc4343 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Wed, 7 Sep 2022 15:07:36 +0800 Subject: [PATCH 379/380] fix: resolve an issue of index out-of-range in tscBuildQueryStreamDesc etc. --- src/client/src/tscProfile.c | 13 ++----------- src/client/src/tscServer.c | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c index 8dfb0b7d67..7de9ef762a 100644 --- a/src/client/src/tscProfile.c +++ b/src/client/src/tscProfile.c @@ -283,18 +283,8 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) { // } pthread_mutex_lock(&pSql->subState.mutex); if (pSql->pSubs != NULL && pSql->subState.states != NULL) { - for (int32_t i = 0; i < pQdesc->numOfSub; ++i) { + for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { // because subState maybe free on anytime by any thread, check validate from here - if(pSql->subState.numOfSub != pQdesc->numOfSub || - pSql->pSubs == NULL || - pSql->subState.states == NULL) { - tscError(" QUERY-HEART STscObj=%p subState maybe free. numOfSub=%d pSubs=%p states=%p", - pObj, pSql->subState.numOfSub, pSql->pSubs, pSql->subState.states); - pQdesc->numOfSub = 0; - // break for - break; - } - SSqlObj *psub = pSql->pSubs[i]; int64_t self = (psub != NULL)? psub->self : 0; @@ -307,6 +297,7 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) { p += len; } } + pQdesc->numOfSub = pSql->subState.numOfSub; pthread_mutex_unlock(&pSql->subState.mutex); } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 07aff292f8..92a6f6e149 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -357,7 +357,7 @@ void checkBrokenQueries(STscObj *pTscObj) { pthread_mutex_lock(&pSql->subState.mutex); if (pSql->pSubs) { // have sub sql - for (int i = 0; i < numOfSub; i++) { + for (int i = 0; i < pSql->subState.numOfSub; i++) { SSqlObj *pSubSql = pSql->pSubs[i]; if(pSubSql) { tscInfo("PROBE 0x%" PRIx64 " sub sql app is 0x%" PRIx64, pSql->self, pSubSql->self); -- GitLab From 965c99dd96820697faf47980c750ab200d34d685 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Wed, 7 Sep 2022 17:55:22 +0800 Subject: [PATCH 380/380] fix(query): the name of fields maybe contain dot --- src/client/src/tscSQLParser.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index bb31b752a1..193676cd93 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -8481,7 +8481,15 @@ static bool check_expr_in_groupby_colum(SGroupbyExpr* pGroupbyExpr, SExprInfo* p return false; for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols ; ++k) { pIndex = taosArrayGet(pGroupbyExpr->columnInfo, k); - if (!strcmp(pIndex->name,&pExpr->base.colInfo.name[1])){ // notes:first char is dot, skip one char. + + // find last dot + char * name = strrchr(pExpr->base.colInfo.name, '.'); + if(name) + name += 1; + else + name = pExpr->base.colInfo.name; + + if (!strcmp(pIndex->name, name)){ return true; } } -- GitLab