diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..6f98693addd5cba9a40f6ab9335054951a78b2ee --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,13 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference +version: 2.1 +# Use a package of configuration called an orb. +orbs: + # Declare a dependency on the welcome-orb + welcome: circleci/welcome-orb@0.4.1 +# Orchestrate or schedule a set of jobs +workflows: + # Name the workflow "welcome" + welcome: + # Run the welcome/run job in its own container + jobs: + - welcome/run diff --git a/.drone.yml b/.drone.yml index e7ae6ebbdaed1b2446e99e3f0365907ff44754d0..f7ee4e976f7b6a077ea0b9a8cb7f9cadb5c3628f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,41 +7,22 @@ platform: arch: amd64 steps: -- name: smoke_test - image: python:3.8 +- name: build + image: gcc commands: - apt-get update - - apt-get install -y cmake build-essential gcc - - pip3 install psutil - - pip3 install guppy3 - - pip3 install src/connector/python/linux/python3/ + - apt-get install -y cmake build-essential - mkdir debug - cd debug - cmake .. - make - - cd ../tests - - ./test-all.sh smoke + trigger: + event: + - pull_request when: branch: - develop - master - - -- name: crash_gen - image: python:3.8 - commands: - - pip3 install requests - - pip3 install src/connector/python/linux/python3/ - - pip3 install psutil - - pip3 install guppy3 - - cd tests/pytest - - ./crash_gen.sh -a -p -t 4 -s 2000 - when: - branch: - - develop - - master - - --- kind: pipeline name: test_arm64 @@ -60,6 +41,9 @@ steps: - cd debug - cmake .. -DCPUTYPE=aarch64 > /dev/null - make + trigger: + event: + - pull_request when: branch: - develop @@ -82,6 +66,9 @@ steps: - cd debug - cmake .. -DCPUTYPE=aarch32 > /dev/null - make + trigger: + event: + - pull_request when: branch: - develop @@ -106,11 +93,13 @@ steps: - cd debug - cmake .. - make + trigger: + event: + - pull_request when: branch: - develop - master - --- kind: pipeline name: build_xenial @@ -129,6 +118,9 @@ steps: - cd debug - cmake .. - make + trigger: + event: + - pull_request when: branch: - develop @@ -151,6 +143,32 @@ steps: - cd debug - cmake .. - make + trigger: + event: + - pull_request + when: + branch: + - develop + - master +--- +kind: pipeline +name: build_centos7 +platform: + os: linux + arch: amd64 + +steps: +- name: build + image: ansible/centos7-ansible + commands: + - yum install -y gcc gcc-c++ make cmake + - mkdir debug + - cd debug + - cmake .. + - make + trigger: + event: + - pull_request when: branch: - develop diff --git a/.gitignore b/.gitignore index 1ff11080569e9312369f6e9c00463e25853fd38b..da47590a2fac52879c470e3c6b89dffaa57d775a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ build/ .vscode/ .idea/ cmake-build-debug/ +cmake-build-release/ cscope.out .DS_Store debug/ diff --git a/.gitmodules b/.gitmodules index 74afbbf9973abec6423633b848181b349de4ed6f..0e65b02221be24495edbb3f8da136a0ac61ff812 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,12 @@ [submodule "src/connector/go"] path = src/connector/go - url = https://github.com/taosdata/driver-go + url = git@github.com:taosdata/driver-go.git [submodule "src/connector/grafanaplugin"] path = src/connector/grafanaplugin - url = https://github.com/taosdata/grafanaplugin + url = git@github.com:taosdata/grafanaplugin.git [submodule "src/connector/hivemq-tdengine-extension"] path = src/connector/hivemq-tdengine-extension - url = https://github.com/huskar-t/hivemq-tdengine-extension.git + url = git@github.com:taosdata/hivemq-tdengine-extension.git [submodule "tests/examples/rust"] path = tests/examples/rust url = https://github.com/songtianyi/tdengine-rust-bindings.git diff --git a/CMakeLists.txt b/CMakeLists.txt index e0d6e82923ce66abccefda6ee685ec98d6450d2e..6f50aca0797cb2d3a2b61796d43137fb417f76ee 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ IF (CMAKE_VERSION VERSION_LESS 3.0) PROJECT(TDengine CXX) SET(PROJECT_VERSION_MAJOR "${LIB_MAJOR_VERSION}") SET(PROJECT_VERSION_MINOR "${LIB_MINOR_VERSION}") - SET(PROJECT_VERSION_PATCH"${LIB_PATCH_VERSION}") + SET(PROJECT_VERSION_PATCH "${LIB_PATCH_VERSION}") SET(PROJECT_VERSION "${LIB_VERSION_STRING}") ELSE () CMAKE_POLICY(SET CMP0048 NEW) @@ -42,6 +42,13 @@ INCLUDE(cmake/env.inc) INCLUDE(cmake/version.inc) INCLUDE(cmake/install.inc) +IF (CMAKE_SYSTEM_NAME MATCHES "Linux") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -Wall -Wshadow -Werror") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -Wall -Wshadow -Werror") +ENDIF () +MESSAGE(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") +MESSAGE(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") + ADD_SUBDIRECTORY(deps) ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(tests) diff --git a/Jenkinsfile b/Jenkinsfile index 33ce784bce134134bbb78ffffb9d58b71dbd17f7..b48dca02419a3e4f3f78ea1a16d93fd376e9d703 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -94,7 +94,7 @@ def pre_test(){ make > /dev/null make install > /dev/null cd ${WKC}/tests - pip3 install ${WKC}/src/connector/python/linux/python3/ + pip3 install ${WKC}/src/connector/python ''' return 1 } diff --git a/README-CN.md b/README-CN.md index d4c10e71d684ab5d21c1c767c398707956946232..afb242d6219069887be615b606f3a0eb5206422c 100644 --- a/README-CN.md +++ b/README-CN.md @@ -116,7 +116,7 @@ mkdir debug && cd debug cmake .. && cmake --build . ``` -在X86-64、X86、arm64 和 arm32 平台上,TDengine 生成脚本可以自动检测机器架构。也可以手动配置 CPUTYPE 参数来指定 CPU 类型,如 aarch64 或 aarch32 等。 +在X86-64、X86、arm64、arm32 和 mips64 平台上,TDengine 生成脚本可以自动检测机器架构。也可以手动配置 CPUTYPE 参数来指定 CPU 类型,如 aarch64 或 aarch32 等。 aarch64: @@ -130,6 +130,12 @@ aarch32: cmake .. -DCPUTYPE=aarch32 && cmake --build . ``` +mips64: + +```bash +cmake .. -DCPUTYPE=mips64 && cmake --build . +``` + ### Windows 系统 如果你使用的是 Visual Studio 2013 版本: diff --git a/README.md b/README.md index 45a955f458c953af3e4135430d6cce3f56017c1a..2c33119e34305cbbfa114842e2589ddf87417100 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/taosdata/TDengine.svg?branch=master)](https://travis-ci.org/taosdata/TDengine) +[![Build Status](https://cloud.drone.io/api/badges/taosdata/TDengine/status.svg?ref=refs/heads/master)](https://cloud.drone.io/taosdata/TDengine) [![Build status](https://ci.appveyor.com/api/projects/status/kf3pwh2or5afsgl9/branch/master?svg=true)](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master) [![Coverage Status](https://coveralls.io/repos/github/taosdata/TDengine/badge.svg?branch=develop)](https://coveralls.io/github/taosdata/TDengine?branch=develop) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4201/badge)](https://bestpractices.coreinfrastructure.org/projects/4201) @@ -110,7 +110,7 @@ mkdir debug && cd debug cmake .. && cmake --build . ``` -TDengine build script can detect the host machine's architecture on X86-64, X86, arm64 and arm32 platform. +TDengine build script can detect the host machine's architecture on X86-64, X86, arm64, arm32 and mips64 platform. You can also specify CPUTYPE option like aarch64 or aarch32 too if the detection result is not correct: aarch64: @@ -123,6 +123,11 @@ aarch32: cmake .. -DCPUTYPE=aarch32 && cmake --build . ``` +mips64: +```bash +cmake .. -DCPUTYPE=mips64 && cmake --build . +``` + ### On Windows platform If you use the Visual Studio 2013, please open a command window by executing "cmd.exe". diff --git a/cmake/define.inc b/cmake/define.inc index 4115dd0c4143535130b1bf8a132ee400d828d87d..57351e547846055a6074c6e5c28a00796d2e4933 100755 --- a/cmake/define.inc +++ b/cmake/define.inc @@ -57,7 +57,7 @@ IF (TD_LINUX_64) ADD_DEFINITIONS(-D_M_X64) ADD_DEFINITIONS(-D_TD_LINUX_64) MESSAGE(STATUS "linux64 is defined") - SET(COMMON_FLAGS "-Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ADD_DEFINITIONS(-DUSE_LIBICONV) ENDIF () @@ -65,7 +65,7 @@ IF (TD_LINUX_32) ADD_DEFINITIONS(-D_TD_LINUX_32) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "linux32 is defined") - SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -munaligned-access -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -fsigned-char -munaligned-access -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_ARM_64) @@ -73,7 +73,7 @@ IF (TD_ARM_64) ADD_DEFINITIONS(-D_TD_ARM_) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "arm64 is defined") - SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_ARM_32) @@ -81,7 +81,7 @@ IF (TD_ARM_32) ADD_DEFINITIONS(-D_TD_ARM_) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "arm32 is defined") - SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-incompatible-pointer-types ") + SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-incompatible-pointer-types ") ENDIF () IF (TD_MIPS_64) @@ -89,7 +89,7 @@ IF (TD_MIPS_64) ADD_DEFINITIONS(-D_TD_MIPS_64) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "mips64 is defined") - SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_MIPS_32) @@ -97,7 +97,7 @@ IF (TD_MIPS_32) ADD_DEFINITIONS(-D_TD_MIPS_32) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "mips32 is defined") - SET(COMMON_FLAGS "-Wall -Werror -fPIC -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_APLHINE) @@ -138,7 +138,7 @@ IF (TD_DARWIN_64) ADD_DEFINITIONS(-D_REENTRANT -D__USE_POSIX -D_LIBC_REENTRANT) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "darwin64 is defined") - SET(COMMON_FLAGS "-Wall -Werror -Wno-missing-braces -fPIC -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -Wno-missing-braces -fPIC -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") SET(DEBUG_FLAGS "-O0 -g3 -DDEBUG") SET(RELEASE_FLAGS "-Og") INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc) @@ -157,7 +157,7 @@ IF (TD_WINDOWS) IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900)) SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18") ENDIF () - SET(DEBUG_FLAGS "/Zi /W3 /GL") + SET(DEBUG_FLAGS "/fsanitize=thread /fsanitize=leak /fsanitize=memory /fsanitize=undefined /fsanitize=hwaddress /Zi /W3 /GL") SET(RELEASE_FLAGS "/W0 /O3 /GL") ENDIF () diff --git a/cmake/install.inc b/cmake/install.inc index 9e325531d51c7ebb315fb01ccbd0cbb06ffcd5d5..f8b3b7c3c62c16df537a941d7f14ccb74bc64217 100755 --- a/cmake/install.inc +++ b/cmake/install.inc @@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS) #INSTALL(TARGETS taos RUNTIME DESTINATION driver) #INSTALL(TARGETS shell RUNTIME DESTINATION .) IF (TD_MVN_INSTALLED) - INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.28-dist.jar DESTINATION connector/jdbc) + INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.29.jar DESTINATION connector/jdbc) ENDIF () ELSEIF (TD_DARWIN) SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh") diff --git a/cmake/platform.inc b/cmake/platform.inc index dcd0183e27b58f2ebd22c584fab359e025044cba..5f7391c996120bb44a96a09b659147be90985d30 100755 --- a/cmake/platform.inc +++ b/cmake/platform.inc @@ -102,6 +102,12 @@ IF ("${CPUTYPE}" STREQUAL "") SET(TD_LINUX TRUE) SET(TD_LINUX_64 FALSE) SET(TD_ARM_64 TRUE) + ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "mips64") + SET(CPUTYPE "mips64") + MESSAGE(STATUS "Set CPUTYPE to mips64") + SET(TD_LINUX TRUE) + SET(TD_LINUX_64 FALSE) + SET(TD_MIPS_64 TRUE) ENDIF () ELSE () diff --git a/cmake/version.inc b/cmake/version.inc index 0ee23f319a9c5761cfb6b47c6118f72e5c768f84..ed8e7a156cc8fffd231889932940d4ff68614102 100755 --- a/cmake/version.inc +++ b/cmake/version.inc @@ -4,7 +4,7 @@ PROJECT(TDengine) IF (DEFINED VERNUMBER) SET(TD_VER_NUMBER ${VERNUMBER}) ELSE () - SET(TD_VER_NUMBER "2.1.0.0") + SET(TD_VER_NUMBER "2.1.1.0") ENDIF () IF (DEFINED VERCOMPATIBLE) diff --git a/deps/rmonotonic/src/monotonic.c b/deps/rmonotonic/src/monotonic.c index 1470f91b56c79b4ee2d8429ecf58fc365d03e737..c6d2df9097ce0d435fb9dd1ec42952dd37c10de9 100644 --- a/deps/rmonotonic/src/monotonic.c +++ b/deps/rmonotonic/src/monotonic.c @@ -36,6 +36,15 @@ static char monotonic_info_string[32]; static long mono_ticksPerMicrosecond = 0; +#ifdef _TD_NINGSI_60 +// implement __rdtsc in ningsi60 +uint64_t __rdtsc(){ + unsigned int lo,hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return ((uint64_t)hi << 32) | lo; +} +#endif + static monotime getMonotonicUs_x86() { return __rdtsc() / mono_ticksPerMicrosecond; } diff --git a/documentation20/cn/02.getting-started/docs.md b/documentation20/cn/02.getting-started/docs.md index a98159d8c408c7140b1a24f2534e575b38d1c56a..6eb58a1433ed0d43b313a9dc979ae5873ba00e8f 100644 --- a/documentation20/cn/02.getting-started/docs.md +++ b/documentation20/cn/02.getting-started/docs.md @@ -24,7 +24,7 @@ TDengine的安装非常简单,从下载到安装成功仅仅只要几秒钟。 ## 轻松启动 -安装成功后,用户可使用`systemctl`命令来启动TDengine的服务进程。 +安装成功后,用户可使用 `systemctl` 命令来启动 TDengine 的服务进程。 ```bash $ systemctl start taosd @@ -35,21 +35,22 @@ $ systemctl start taosd $ systemctl status taosd ``` -如果TDengine服务正常工作,那么您可以通过TDengine的命令行程序`taos`来访问并体验TDengine。 +如果 TDengine 服务正常工作,那么您可以通过 TDengine 的命令行程序 `taos` 来访问并体验 TDengine。 **注意:** -- systemctl命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 sudo -- 为更好的获得产品反馈,改善产品,TDengine会采集基本的使用信息,但您可以修改系统配置文件taos.cfg里的配置参数telemetryReporting, 将其设为0,就可将其关闭。 -- TDengine采用FQDN(一般就是hostname)作为节点的ID,为保证正常运行,需要给运行taosd的服务器配置好hostname,在客户端应用运行的机器配置好DNS服务或hosts文件,保证FQDN能够解析。 +- systemctl 命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 sudo 。 +- 为更好的获得产品反馈,改善产品,TDengine 会采集基本的使用信息,但您可以修改系统配置文件 taos.cfg 里的配置参数 telemetryReporting, 将其设为 0,就可将其关闭。 +- TDengine 采用 FQDN (一般就是 hostname )作为节点的 ID,为保证正常运行,需要给运行 taosd 的服务器配置好 hostname,在客户端应用运行的机器配置好 DNS 服务或 hosts 文件,保证 FQDN 能够解析。 +- `systemctl stop taosd` 指令在执行后并不会马上停止 TDengine 服务,而是会等待系统中必要的落盘工作正常完成。在数据量很大的情况下,这可能会消耗较长时间。 -* TDengine 支持在使用[`systemd`](https://en.wikipedia.org/wiki/Systemd)做进程服务管理的linux系统上安装,用`which systemctl`命令来检测系统中是否存在`systemd`包: +* TDengine 支持在使用 [`systemd`](https://en.wikipedia.org/wiki/Systemd) 做进程服务管理的 linux 系统上安装,用 `which systemctl` 命令来检测系统中是否存在 `systemd` 包: ```bash $ which systemctl ``` - 如果系统中不支持systemd,也可以用手动运行 /usr/local/taos/bin/taosd 方式启动 TDengine 服务。 + 如果系统中不支持 systemd,也可以用手动运行 /usr/local/taos/bin/taosd 方式启动 TDengine 服务。 ## TDengine命令行程序 diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 59f80b0a556f68e81501694ed8e87f3f7e96a9c7..9edeb78c6884c79932c464cfaa2ac3d70123d787 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -345,7 +345,7 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 * taos:已经建立好的数据库连接 * sql:SQL查询语句(仅能使用查询语句) * fp:用户定义的回调函数指针,每次流式计算完成后,TDengine将查询的结果(TAOS_ROW)、查询状态(TAOS_RES)、用户定义参数(PARAM)传递给回调函数,在回调函数内,用户可以使用taos_num_fields获取结果集列数,taos_fetch_fields获取结果集每列数据的类型。 - * stime:是流式计算开始的时间,如果是0,表示从现在开始,如果不为零,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数) + * stime:是流式计算开始的时间。如果是“64位整数最小值”,表示从现在开始;如果不为“64位整数最小值”,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数)。 * param:是应用提供的用于回调的一个参数,回调时,提供给应用 * callback: 第二个回调函数,会在连续查询自动停止时被调用。 @@ -400,27 +400,22 @@ Python连接器的使用参见[视频教程](https://www.taosdata.com/blog/2020/ #### Linux -用户可以在源代码的src/connector/python(或者tar.gz的/connector/python)文件夹下找到python2和python3的connector安装包。用户可以通过pip命令安装: +用户可以在源代码的src/connector/python(或者tar.gz的/connector/python)文件夹下找到connector安装包。用户可以通过pip命令安装: -​ `pip install src/connector/python/linux/python2/` +​ `pip install src/connector/python/` 或 -​ `pip3 install src/connector/python/linux/python3/` +​ `pip3 install src/connector/python/` #### Windows 在已安装Windows TDengine 客户端的情况下, 将文件"C:\TDengine\driver\taos.dll" 拷贝到 "C:\windows\system32" 目录下, 然后进入Windwos cmd 命令行界面 ```cmd -cd C:\TDengine\connector\python\windows -python -m pip install python2\ -``` -或 -```cmd -cd C:\TDengine\connector\python\windows -python -m pip install python3\ +cd C:\TDengine\connector\python +python -m pip install . ``` -* 如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。 +* 如果机器上没有pip命令,用户可将src/connector/python下的taos文件夹拷贝到应用程序的目录使用。 对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。 ### 使用 diff --git a/documentation20/cn/09.connections/docs.md b/documentation20/cn/09.connections/docs.md index 79380f3bbd9680120f63f89a0bfbe6f31f5c7a74..6a2ead37666d4b44e1f16f55e3e41694fee5f694 100644 --- a/documentation20/cn/09.connections/docs.md +++ b/documentation20/cn/09.connections/docs.md @@ -16,7 +16,7 @@ TDengine的Grafana插件在安装包的/usr/local/taos/connector/grafanaplugin 以CentOS 7.2操作系统为例,将grafanaplugin目录拷贝到/var/lib/grafana/plugins目录下,重新启动grafana即可。 ```bash -sudo cp -rf /usr/local/taos/connector/grafanaplugin /var/lib/grafana/tdengine +sudo cp -rf /usr/local/taos/connector/grafanaplugin /var/lib/grafana/plugins/tdengine ``` ### 使用 Grafana diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md index bfa0456c7d4e80d1fd9336d7c4b7b9ca829b278e..ee2f34ff11ef5e69195c01d0b605383c3257f48c 100644 --- a/documentation20/cn/11.administrator/docs.md +++ b/documentation20/cn/11.administrator/docs.md @@ -129,7 +129,7 @@ taosd -C - blocks:每个VNODE(TSDB)中有多少cache大小的内存块。因此一个VNODE的用的内存大小粗略为(cache * blocks)。单位为块,默认值:4。(可通过 alter database 修改) - replica:副本个数,取值范围:1-3。单位为个,默认值:1。(可通过 alter database 修改) - precision:时间戳精度标识,ms表示毫秒,us表示微秒。默认值:ms。 -- cacheLast:是否在内存中缓存子表 last_row,0:关闭;1:开启。默认值:0。(可通过 alter database 修改)(从 2.0.11 版本开始支持此参数) +- cacheLast:是否在内存中缓存子表的最近数据,0:关闭;1:缓存子表最近一行数据;2:缓存子表每一列的最近的非NULL值,3:同时打开缓存最近行和列功能,默认值:0。(可通过 alter database 修改)(从 2.0.11 版本开始支持此参数) 对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL: diff --git a/documentation20/cn/12.taos-sql/01.error-code/docs.md b/documentation20/cn/12.taos-sql/01.error-code/docs.md index 95975dba5aeeeee9f42c3bf0b34f48095ea83fa3..867aa18715f87a1dfc9ea36203d32382bb726e30 100644 --- a/documentation20/cn/12.taos-sql/01.error-code/docs.md +++ b/documentation20/cn/12.taos-sql/01.error-code/docs.md @@ -1,172 +1,172 @@ # TDengine 2.0 错误码以及对应的十进制码 -| 状态码 | 模 | 错误码(十六进制) | 错误描述 | 错误码(十进制) | -|-----------------------| :---: | :---------: | :------------------------ | ---------------- | -|TSDB_CODE_RPC_ACTION_IN_PROGRESS| 0 | 0x0001| "Action in progress"| -2147483647| -|TSDB_CODE_RPC_AUTH_REQUIRED| 0 | 0x0002 | "Authentication required"| -2147483646| -|TSDB_CODE_RPC_AUTH_FAILURE| 0| 0x0003 | "Authentication failure"| -2147483645| -|TSDB_CODE_RPC_REDIRECT |0 | 0x0004| "Redirect"| -2147483644| -|TSDB_CODE_RPC_NOT_READY| 0 | 0x0005 | "System not ready"| -2147483643| -|TSDB_CODE_RPC_ALREADY_PROCESSED| 0 | 0x0006 |"Message already processed"| -2147483642| -|TSDB_CODE_RPC_LAST_SESSION_NOT_FINISHED| 0 |0x0007| "Last session not finished"| -2147483641| -|TSDB_CODE_RPC_MISMATCHED_LINK_ID| 0| 0x0008 | "Mismatched meter id"| -2147483640| -|TSDB_CODE_RPC_TOO_SLOW| 0 | 0x0009 | "Processing of request timed out"| -2147483639| -|TSDB_CODE_RPC_MAX_SESSIONS| 0 | 0x000A | "Number of sessions reached limit"| -2147483638| -|TSDB_CODE_RPC_NETWORK_UNAVAIL| 0 |0x000B | "Unable to establish connection" |-2147483637| -|TSDB_CODE_RPC_APP_ERROR| 0| 0x000C | "Unexpected generic error in RPC"| -2147483636| -|TSDB_CODE_RPC_UNEXPECTED_RESPONSE| 0 |0x000D | "Unexpected response"| -2147483635| -|TSDB_CODE_RPC_INVALID_VALUE| 0 | 0x000E | "Invalid value"| -2147483634| -|TSDB_CODE_RPC_INVALID_TRAN_ID| 0 | 0x000F | "Invalid transaction id"| -2147483633| -|TSDB_CODE_RPC_INVALID_SESSION_ID| 0| 0x0010 | "Invalid session id"| -2147483632| -|TSDB_CODE_RPC_INVALID_MSG_TYPE| 0| 0x0011| "Invalid message type"| -2147483631| -|TSDB_CODE_RPC_INVALID_RESPONSE_TYPE| 0 | 0x0012| "Invalid response type"| -2147483630| -|TSDB_CODE_RPC_INVALID_TIME_STAMP| 0| 0x0013| "Invalid timestamp"| -2147483629| -|TSDB_CODE_COM_OPS_NOT_SUPPORT| 0 | 0x0100| "Operation not supported"| -2147483392| -|TSDB_CODE_COM_MEMORY_CORRUPTED |0| 0x0101 | "Memory corrupted"| -2147483391| -|TSDB_CODE_COM_OUT_OF_MEMORY| 0| 0x0102| "Out of memory"| -2147483390| -|TSDB_CODE_COM_INVALID_CFG_MSG| 0 | 0x0103| "Invalid config message"| -2147483389| -|TSDB_CODE_COM_FILE_CORRUPTED| 0| 0x0104| "Data file corrupted" |-2147483388| -|TSDB_CODE_TSC_INVALID_SQL| 0| 0x0200 | "Invalid SQL statement"| -2147483136| -|TSDB_CODE_TSC_INVALID_QHANDLE| 0 | 0x0201 | "Invalid qhandle"| -2147483135| -|TSDB_CODE_TSC_INVALID_TIME_STAMP| 0 | 0x0202 | "Invalid combination of client/service time"| -2147483134| -|TSDB_CODE_TSC_INVALID_VALUE| 0 | 0x0203| "Invalid value in client"| -2147483133| -|TSDB_CODE_TSC_INVALID_VERSION| 0 | 0x0204 | "Invalid client version" |-2147483132| -|TSDB_CODE_TSC_INVALID_IE| 0 | 0x0205 | "Invalid client ie" |-2147483131| -|TSDB_CODE_TSC_INVALID_FQDN| 0 | 0x0206| "Invalid host name"| -2147483130| -|TSDB_CODE_TSC_INVALID_USER_LENGTH| 0 | 0x0207| "Invalid user name"| -2147483129| -|TSDB_CODE_TSC_INVALID_PASS_LENGTH| 0 | 0x0208 | "Invalid password"| -2147483128| -|TSDB_CODE_TSC_INVALID_DB_LENGTH| 0 | 0x0209| "Database name too long"| -2147483127| -|TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH| 0 | 0x020A | "Table name too long"| -2147483126| -|TSDB_CODE_TSC_INVALID_CONNECTION| 0 | 0x020B| "Invalid connection"| -2147483125| -|TSDB_CODE_TSC_OUT_OF_MEMORY| 0 | 0x020C | "System out of memory" |-2147483124| -|TSDB_CODE_TSC_NO_DISKSPACE| 0 | 0x020D | "System out of disk space"| -2147483123| -|TSDB_CODE_TSC_QUERY_CACHE_ERASED| 0 | 0x020E| "Query cache erased"| -2147483122| -|TSDB_CODE_TSC_QUERY_CANCELLED| 0 | 0x020F |"Query terminated"| -2147483121| -|TSDB_CODE_TSC_SORTED_RES_TOO_MANY| 0 |0x0210 | "Result set too large to be sorted"| -2147483120| -|TSDB_CODE_TSC_APP_ERROR| 0 | 0x0211 | "Application error"| -2147483119| -|TSDB_CODE_TSC_ACTION_IN_PROGRESS| 0 |0x0212 | "Action in progress"| -2147483118| -|TSDB_CODE_TSC_DISCONNECTED| 0 | 0x0213 |"Disconnected from service" |-2147483117| -|TSDB_CODE_TSC_NO_WRITE_AUTH| 0 | 0x0214 | "No write permission" |-2147483116| -|TSDB_CODE_MND_MSG_NOT_PROCESSED| 0| 0x0300| "Message not processed"| -2147482880| -|TSDB_CODE_MND_ACTION_IN_PROGRESS| 0 | 0x0301 |"Message is progressing"| -2147482879| -|TSDB_CODE_MND_ACTION_NEED_REPROCESSED| 0 | 0x0302 |"Messag need to be reprocessed"| -2147482878| -|TSDB_CODE_MND_NO_RIGHTS| 0 | 0x0303| "Insufficient privilege for operation"| -2147482877| -|TSDB_CODE_MND_APP_ERROR| 0 | 0x0304 | "Unexpected generic error in mnode"| -2147482876| -|TSDB_CODE_MND_INVALID_CONNECTION| 0 | 0x0305 | "Invalid message connection"| -2147482875| -|TSDB_CODE_MND_INVALID_MSG_VERSION| 0 | 0x0306 | "Incompatible protocol version"| -2147482874| -|TSDB_CODE_MND_INVALID_MSG_LEN| 0| 0x0307 | "Invalid message length"| -2147482873| -|TSDB_CODE_MND_INVALID_MSG_TYPE| 0 | 0x0308 | "Invalid message type" |-2147482872| -|TSDB_CODE_MND_TOO_MANY_SHELL_CONNS| 0 |0x0309 | "Too many connections"| -2147482871| -|TSDB_CODE_MND_OUT_OF_MEMORY| 0 |0x030A | "Out of memory in mnode"| -2147482870| -|TSDB_CODE_MND_INVALID_SHOWOBJ| 0 | 0x030B |"Data expired"| -2147482869| -|TSDB_CODE_MND_INVALID_QUERY_ID |0 | 0x030C |"Invalid query id" |-2147482868| -|TSDB_CODE_MND_INVALID_STREAM_ID| 0 |0x030D | "Invalid stream id"| -2147482867| -|TSDB_CODE_MND_INVALID_CONN_ID| 0| 0x030E | "Invalid connection id" |-2147482866| -|TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE| 0 | 0x0320| "Object already there"| -2147482848| -|TSDB_CODE_MND_SDB_ERROR| 0 |0x0321 | "Unexpected generic error in sdb" |-2147482847| -|TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE| 0 | 0x0322| "Invalid table type" |-2147482846| -|TSDB_CODE_MND_SDB_OBJ_NOT_THERE| 0 | 0x0323 |"Object not there" |-2147482845| -|TSDB_CODE_MND_SDB_INVAID_META_ROW| 0 | 0x0324| "Invalid meta row" |-2147482844| -|TSDB_CODE_MND_SDB_INVAID_KEY_TYPE| 0 | 0x0325 |"Invalid key type" |-2147482843| -|TSDB_CODE_MND_DNODE_ALREADY_EXIST| 0 | 0x0330 | "DNode already exists"| -2147482832| -|TSDB_CODE_MND_DNODE_NOT_EXIST| 0 | 0x0331| "DNode does not exist" |-2147482831| -|TSDB_CODE_MND_VGROUP_NOT_EXIST| 0 | 0x0332 |"VGroup does not exist"| -2147482830| -|TSDB_CODE_MND_NO_REMOVE_MASTER |0 | 0x0333 | "Master DNode cannot be removed"| -2147482829| -|TSDB_CODE_MND_NO_ENOUGH_DNODES |0 | 0x0334| "Out of DNodes"| -2147482828| -|TSDB_CODE_MND_CLUSTER_CFG_INCONSISTENT |0 | 0x0335 | "Cluster cfg inconsistent"| -2147482827| -|TSDB_CODE_MND_INVALID_DNODE_CFG_OPTION| 0 | 0x0336 | "Invalid dnode cfg option"| -2147482826| -|TSDB_CODE_MND_BALANCE_ENABLED| 0 | 0x0337 | "Balance already enabled" |-2147482825| -|TSDB_CODE_MND_VGROUP_NOT_IN_DNODE| 0 |0x0338 | "Vgroup not in dnode"| -2147482824| -|TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE| 0 | 0x0339 | "Vgroup already in dnode"| -2147482823| -|TSDB_CODE_MND_DNODE_NOT_FREE |0 | 0x033A |"Dnode not avaliable"| -2147482822| -|TSDB_CODE_MND_INVALID_CLUSTER_ID |0 |0x033B | "Cluster id not match"| -2147482821| -|TSDB_CODE_MND_NOT_READY| 0 | 0x033C |"Cluster not ready"| -2147482820| -|TSDB_CODE_MND_ACCT_ALREADY_EXIST| 0 | 0x0340 | "Account already exists" |-2147482816| -|TSDB_CODE_MND_INVALID_ACCT| 0 | 0x0341| "Invalid account"| -2147482815| -|TSDB_CODE_MND_INVALID_ACCT_OPTION| 0 | 0x0342 | "Invalid account options"| -2147482814| -|TSDB_CODE_MND_USER_ALREADY_EXIST| 0 | 0x0350 | "User already exists"| -2147482800| -|TSDB_CODE_MND_INVALID_USER |0 | 0x0351 | "Invalid user" |-2147482799| -|TSDB_CODE_MND_INVALID_USER_FORMAT| 0 |0x0352 |"Invalid user format" |-2147482798| -|TSDB_CODE_MND_INVALID_PASS_FORMAT| 0| 0x0353 | "Invalid password format"| -2147482797| -|TSDB_CODE_MND_NO_USER_FROM_CONN| 0 | 0x0354 | "Can not get user from conn"| -2147482796| -|TSDB_CODE_MND_TOO_MANY_USERS| 0 | 0x0355| "Too many users"| -2147482795| -|TSDB_CODE_MND_TABLE_ALREADY_EXIST| 0| 0x0360| "Table already exists"| -2147482784| -|TSDB_CODE_MND_INVALID_TABLE_ID| 0| 0x0361| "Table name too long"| -2147482783| -|TSDB_CODE_MND_INVALID_TABLE_NAME| 0| 0x0362 | "Table does not exist"| -2147482782| -|TSDB_CODE_MND_INVALID_TABLE_TYPE| 0| 0x0363 | "Invalid table type in tsdb"| -2147482781| -|TSDB_CODE_MND_TOO_MANY_TAGS| 0 | 0x0364| "Too many tags"| -2147482780| -|TSDB_CODE_MND_TOO_MANY_TIMESERIES| 0| 0x0366| "Too many time series"| -2147482778| -|TSDB_CODE_MND_NOT_SUPER_TABLE| 0 |0x0367| "Not super table"| -2147482777| -|TSDB_CODE_MND_COL_NAME_TOO_LONG| 0| 0x0368| "Tag name too long"| -2147482776| -|TSDB_CODE_MND_TAG_ALREAY_EXIST| 0| 0x0369| "Tag already exists"| -2147482775| -|TSDB_CODE_MND_TAG_NOT_EXIST| 0 |0x036A | "Tag does not exist" |-2147482774| -|TSDB_CODE_MND_FIELD_ALREAY_EXIST| 0 | 0x036B| "Field already exists"| -2147482773| -|TSDB_CODE_MND_FIELD_NOT_EXIST| 0 | 0x036C | "Field does not exist"| -2147482772| -|TSDB_CODE_MND_INVALID_STABLE_NAME |0 | 0x036D |"Super table does not exist" |-2147482771| -|TSDB_CODE_MND_DB_NOT_SELECTED| 0 | 0x0380 | "Database not specified or available"| -2147482752| -|TSDB_CODE_MND_DB_ALREADY_EXIST| 0 | 0x0381 | "Database already exists"| -2147482751| -|TSDB_CODE_MND_INVALID_DB_OPTION| 0 | 0x0382 | "Invalid database options"| -2147482750| -|TSDB_CODE_MND_INVALID_DB| 0 | 0x0383 | "Invalid database name"| -2147482749| -|TSDB_CODE_MND_MONITOR_DB_FORBIDDEN| 0 | 0x0384 | "Cannot delete monitor database"| -2147482748| -|TSDB_CODE_MND_TOO_MANY_DATABASES| 0| 0x0385 | "Too many databases for account"| -2147482747| -|TSDB_CODE_MND_DB_IN_DROPPING| 0 | 0x0386| "Database not available" |-2147482746| -|TSDB_CODE_DND_MSG_NOT_PROCESSED| 0| 0x0400 | "Message not processed"| -2147482624| -|TSDB_CODE_DND_OUT_OF_MEMORY |0 | 0x0401 | "Dnode out of memory"| -2147482623| -|TSDB_CODE_DND_NO_WRITE_ACCESS| 0 | 0x0402 | "No permission for disk files in dnode"| -2147482622| -|TSDB_CODE_DND_INVALID_MSG_LEN| 0 | 0x0403 | "Invalid message length"| -2147482621| -|TSDB_CODE_VND_ACTION_IN_PROGRESS |0 |0x0500| "Action in progress" |-2147482368| -|TSDB_CODE_VND_MSG_NOT_PROCESSED| 0 |0x0501 | "Message not processed" |-2147482367| -|TSDB_CODE_VND_ACTION_NEED_REPROCESSED |0 |0x0502| "Action need to be reprocessed"| -2147482366| -|TSDB_CODE_VND_INVALID_VGROUP_ID |0 | 0x0503| "Invalid Vgroup ID"| -2147482365| -|TSDB_CODE_VND_INIT_FAILED| 0 | 0x0504 | "Vnode initialization failed"| -2147482364| -|TSDB_CODE_VND_NO_DISKSPACE| 0 |0x0505| "System out of disk space" |-2147482363| -|TSDB_CODE_VND_NO_DISK_PERMISSIONS| 0 | 0x0506| "No write permission for disk files" |-2147482362| -|TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR| 0 | 0x0507 | "Missing data file"| -2147482361| -|TSDB_CODE_VND_OUT_OF_MEMORY |0| 0x0508 | "Out of memory"| -2147482360| -|TSDB_CODE_VND_APP_ERROR| 0| 0x0509 | "Unexpected generic error in vnode"| -2147482359| -|TSDB_CODE_VND_INVALID_STATUS |0| 0x0510 | "Database not ready"| -2147482352| -|TSDB_CODE_VND_NOT_SYNCED| 0 | 0x0511 | "Database suspended"| -2147482351| -|TSDB_CODE_VND_NO_WRITE_AUTH| 0 | 0x0512| "Write operation denied" |-2147482350| -|TSDB_CODE_TDB_INVALID_TABLE_ID |0 | 0x0600 | "Invalid table ID"| -2147482112| -|TSDB_CODE_TDB_INVALID_TABLE_TYPE| 0| 0x0601 |"Invalid table type"| -2147482111| -|TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION| 0| 0x0602| "Invalid table schema version"| -2147482110| -|TSDB_CODE_TDB_TABLE_ALREADY_EXIST| 0 | 0x0603| "Table already exists"| -2147482109| -|TSDB_CODE_TDB_INVALID_CONFIG| 0 | 0x0604| "Invalid configuration"| -2147482108| -|TSDB_CODE_TDB_INIT_FAILED| 0 | 0x0605| "Tsdb init failed"| -2147482107| -|TSDB_CODE_TDB_NO_DISKSPACE| 0 | 0x0606| "No diskspace for tsdb"| -2147482106| -|TSDB_CODE_TDB_NO_DISK_PERMISSIONS| 0 | 0x0607| "No permission for disk files"| -2147482105| -|TSDB_CODE_TDB_FILE_CORRUPTED| 0 | 0x0608| "Data file(s) corrupted"| -2147482104| -|TSDB_CODE_TDB_OUT_OF_MEMORY| 0 | 0x0609| "Out of memory"| -2147482103| -|TSDB_CODE_TDB_TAG_VER_OUT_OF_DATE| 0 | 0x060A| "Tag too old"| -2147482102| -|TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE |0| 0x060B | "Timestamp data out of range"| -2147482101| -|TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP| 0| 0x060C| "Submit message is messed up"| -2147482100| -|TSDB_CODE_TDB_INVALID_ACTION| 0 | 0x060D | "Invalid operation"| -2147482099| -|TSDB_CODE_TDB_INVALID_CREATE_TB_MSG| 0 | 0x060E| "Invalid creation of table"| -2147482098| -|TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM| 0 | 0x060F| "No table data in memory skiplist" |-2147482097| -|TSDB_CODE_TDB_FILE_ALREADY_EXISTS| 0 | 0x0610| "File already exists"| -2147482096| -|TSDB_CODE_TDB_TABLE_RECONFIGURE| 0 | 0x0611| "Need to reconfigure table"| -2147482095| -|TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO| 0 | 0x0612| "Invalid information to create table"| -2147482094| -|TSDB_CODE_QRY_INVALID_QHANDLE| 0 | 0x0700| "Invalid handle"| -2147481856| -|TSDB_CODE_QRY_INVALID_MSG| 0 | 0x0701| "Invalid message"| -2147481855| -|TSDB_CODE_QRY_NO_DISKSPACE| 0 | 0x0702 | "No diskspace for query"| -2147481854| -|TSDB_CODE_QRY_OUT_OF_MEMORY| 0 | 0x0703 | "System out of memory"| -2147481853| -|TSDB_CODE_QRY_APP_ERROR| 0 | 0x0704 | "Unexpected generic error in query"| -2147481852| -|TSDB_CODE_QRY_DUP_JOIN_KEY| 0 | 0x0705| "Duplicated join key"| -2147481851| -|TSDB_CODE_QRY_EXCEED_TAGS_LIMIT| 0 | 0x0706 | "Tag conditon too many"| -2147481850| -|TSDB_CODE_QRY_NOT_READY |0| 0x0707 | "Query not ready" |-2147481849| -|TSDB_CODE_QRY_HAS_RSP| 0 | 0x0708| "Query should response"| -2147481848| -|TSDB_CODE_GRANT_EXPIRED| 0 | 0x0800| "License expired"| -2147481600| -|TSDB_CODE_GRANT_DNODE_LIMITED| 0 | 0x0801 | "DNode creation limited by licence"| -2147481599| -|TSDB_CODE_GRANT_ACCT_LIMITED |0| 0x0802 |"Account creation limited by license"| -2147481598| -|TSDB_CODE_GRANT_TIMESERIES_LIMITED| 0 | 0x0803 | "Table creation limited by license"| -2147481597| -|TSDB_CODE_GRANT_DB_LIMITED| 0 | 0x0804 | "DB creation limited by license"| -2147481596| -|TSDB_CODE_GRANT_USER_LIMITED| 0 | 0x0805 | "User creation limited by license"| -2147481595| -|TSDB_CODE_GRANT_CONN_LIMITED| 0| 0x0806 | "Conn creation limited by license" |-2147481594| -|TSDB_CODE_GRANT_STREAM_LIMITED| 0 | 0x0807 | "Stream creation limited by license"| -2147481593| -|TSDB_CODE_GRANT_SPEED_LIMITED| 0 | 0x0808 | "Write speed limited by license" |-2147481592| -|TSDB_CODE_GRANT_STORAGE_LIMITED| 0 |0x0809 | "Storage capacity limited by license"| -2147481591| -|TSDB_CODE_GRANT_QUERYTIME_LIMITED| 0 | 0x080A | "Query time limited by license" |-2147481590| -|TSDB_CODE_GRANT_CPU_LIMITED| 0 |0x080B |"CPU cores limited by license"| -2147481589| -|TSDB_CODE_SYN_INVALID_CONFIG| 0 | 0x0900| "Invalid Sync Configuration"| -2147481344| -|TSDB_CODE_SYN_NOT_ENABLED| 0 | 0x0901 | "Sync module not enabled" |-2147481343| -|TSDB_CODE_WAL_APP_ERROR| 0| 0x1000 | "Unexpected generic error in wal" |-2147479552| \ No newline at end of file +| 状态码 | 模 | 错误码(十六进制) | 错误描述 | 错误码(十进制) | +| :-------------------------------------- | :--: | :----------------: | :------------------------------------------- | :--------------- | +| TSDB_CODE_RPC_ACTION_IN_PROGRESS | 0 | 0x0001 | "Action in progress" | -2147483647 | +| TSDB_CODE_RPC_AUTH_REQUIRED | 0 | 0x0002 | "Authentication required" | -2147483646 | +| TSDB_CODE_RPC_AUTH_FAILURE | 0 | 0x0003 | "Authentication failure" | -2147483645 | +| TSDB_CODE_RPC_REDIRECT | 0 | 0x0004 | "Redirect" | -2147483644 | +| TSDB_CODE_RPC_NOT_READY | 0 | 0x0005 | "System not ready" | -2147483643 | +| TSDB_CODE_RPC_ALREADY_PROCESSED | 0 | 0x0006 | "Message already processed" | -2147483642 | +| TSDB_CODE_RPC_LAST_SESSION_NOT_FINISHED | 0 | 0x0007 | "Last session not finished" | -2147483641 | +| TSDB_CODE_RPC_MISMATCHED_LINK_ID | 0 | 0x0008 | "Mismatched meter id" | -2147483640 | +| TSDB_CODE_RPC_TOO_SLOW | 0 | 0x0009 | "Processing of request timed out" | -2147483639 | +| TSDB_CODE_RPC_MAX_SESSIONS | 0 | 0x000A | "Number of sessions reached limit" | -2147483638 | +| TSDB_CODE_RPC_NETWORK_UNAVAIL | 0 | 0x000B | "Unable to establish connection" | -2147483637 | +| TSDB_CODE_RPC_APP_ERROR | 0 | 0x000C | "Unexpected generic error in RPC" | -2147483636 | +| TSDB_CODE_RPC_UNEXPECTED_RESPONSE | 0 | 0x000D | "Unexpected response" | -2147483635 | +| TSDB_CODE_RPC_INVALID_VALUE | 0 | 0x000E | "Invalid value" | -2147483634 | +| TSDB_CODE_RPC_INVALID_TRAN_ID | 0 | 0x000F | "Invalid transaction id" | -2147483633 | +| TSDB_CODE_RPC_INVALID_SESSION_ID | 0 | 0x0010 | "Invalid session id" | -2147483632 | +| TSDB_CODE_RPC_INVALID_MSG_TYPE | 0 | 0x0011 | "Invalid message type" | -2147483631 | +| TSDB_CODE_RPC_INVALID_RESPONSE_TYPE | 0 | 0x0012 | "Invalid response type" | -2147483630 | +| TSDB_CODE_RPC_INVALID_TIME_STAMP | 0 | 0x0013 | "Invalid timestamp" | -2147483629 | +| TSDB_CODE_COM_OPS_NOT_SUPPORT | 0 | 0x0100 | "Operation not supported" | -2147483392 | +| TSDB_CODE_COM_MEMORY_CORRUPTED | 0 | 0x0101 | "Memory corrupted" | -2147483391 | +| TSDB_CODE_COM_OUT_OF_MEMORY | 0 | 0x0102 | "Out of memory" | -2147483390 | +| TSDB_CODE_COM_INVALID_CFG_MSG | 0 | 0x0103 | "Invalid config message" | -2147483389 | +| TSDB_CODE_COM_FILE_CORRUPTED | 0 | 0x0104 | "Data file corrupted" | -2147483388 | +| TSDB_CODE_TSC_INVALID_OPERATION | 0 | 0x0200 | "Invalid SQL statement" | -2147483136 | +| TSDB_CODE_TSC_INVALID_QHANDLE | 0 | 0x0201 | "Invalid qhandle" | -2147483135 | +| TSDB_CODE_TSC_INVALID_TIME_STAMP | 0 | 0x0202 | "Invalid combination of client/service time" | -2147483134 | +| TSDB_CODE_TSC_INVALID_VALUE | 0 | 0x0203 | "Invalid value in client" | -2147483133 | +| TSDB_CODE_TSC_INVALID_VERSION | 0 | 0x0204 | "Invalid client version" | -2147483132 | +| TSDB_CODE_TSC_INVALID_IE | 0 | 0x0205 | "Invalid client ie" | -2147483131 | +| TSDB_CODE_TSC_INVALID_FQDN | 0 | 0x0206 | "Invalid host name" | -2147483130 | +| TSDB_CODE_TSC_INVALID_USER_LENGTH | 0 | 0x0207 | "Invalid user name" | -2147483129 | +| TSDB_CODE_TSC_INVALID_PASS_LENGTH | 0 | 0x0208 | "Invalid password" | -2147483128 | +| TSDB_CODE_TSC_INVALID_DB_LENGTH | 0 | 0x0209 | "Database name too long" | -2147483127 | +| TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH | 0 | 0x020A | "Table name too long" | -2147483126 | +| TSDB_CODE_TSC_INVALID_CONNECTION | 0 | 0x020B | "Invalid connection" | -2147483125 | +| TSDB_CODE_TSC_OUT_OF_MEMORY | 0 | 0x020C | "System out of memory" | -2147483124 | +| TSDB_CODE_TSC_NO_DISKSPACE | 0 | 0x020D | "System out of disk space" | -2147483123 | +| TSDB_CODE_TSC_QUERY_CACHE_ERASED | 0 | 0x020E | "Query cache erased" | -2147483122 | +| TSDB_CODE_TSC_QUERY_CANCELLED | 0 | 0x020F | "Query terminated" | -2147483121 | +| TSDB_CODE_TSC_SORTED_RES_TOO_MANY | 0 | 0x0210 | "Result set too large to be sorted" | -2147483120 | +| TSDB_CODE_TSC_APP_ERROR | 0 | 0x0211 | "Application error" | -2147483119 | +| TSDB_CODE_TSC_ACTION_IN_PROGRESS | 0 | 0x0212 | "Action in progress" | -2147483118 | +| TSDB_CODE_TSC_DISCONNECTED | 0 | 0x0213 | "Disconnected from service" | -2147483117 | +| TSDB_CODE_TSC_NO_WRITE_AUTH | 0 | 0x0214 | "No write permission" | -2147483116 | +| TSDB_CODE_MND_MSG_NOT_PROCESSED | 0 | 0x0300 | "Message not processed" | -2147482880 | +| TSDB_CODE_MND_ACTION_IN_PROGRESS | 0 | 0x0301 | "Message is progressing" | -2147482879 | +| TSDB_CODE_MND_ACTION_NEED_REPROCESSED | 0 | 0x0302 | "Messag need to be reprocessed" | -2147482878 | +| TSDB_CODE_MND_NO_RIGHTS | 0 | 0x0303 | "Insufficient privilege for operation" | -2147482877 | +| TSDB_CODE_MND_APP_ERROR | 0 | 0x0304 | "Unexpected generic error in mnode" | -2147482876 | +| TSDB_CODE_MND_INVALID_CONNECTION | 0 | 0x0305 | "Invalid message connection" | -2147482875 | +| TSDB_CODE_MND_INVALID_MSG_VERSION | 0 | 0x0306 | "Incompatible protocol version" | -2147482874 | +| TSDB_CODE_MND_INVALID_MSG_LEN | 0 | 0x0307 | "Invalid message length" | -2147482873 | +| TSDB_CODE_MND_INVALID_MSG_TYPE | 0 | 0x0308 | "Invalid message type" | -2147482872 | +| TSDB_CODE_MND_TOO_MANY_SHELL_CONNS | 0 | 0x0309 | "Too many connections" | -2147482871 | +| TSDB_CODE_MND_OUT_OF_MEMORY | 0 | 0x030A | "Out of memory in mnode" | -2147482870 | +| TSDB_CODE_MND_INVALID_SHOWOBJ | 0 | 0x030B | "Data expired" | -2147482869 | +| TSDB_CODE_MND_INVALID_QUERY_ID | 0 | 0x030C | "Invalid query id" | -2147482868 | +| TSDB_CODE_MND_INVALID_STREAM_ID | 0 | 0x030D | "Invalid stream id" | -2147482867 | +| TSDB_CODE_MND_INVALID_CONN_ID | 0 | 0x030E | "Invalid connection id" | -2147482866 | +| TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE | 0 | 0x0320 | "Object already there" | -2147482848 | +| TSDB_CODE_MND_SDB_ERROR | 0 | 0x0321 | "Unexpected generic error in sdb" | -2147482847 | +| TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE | 0 | 0x0322 | "Invalid table type" | -2147482846 | +| TSDB_CODE_MND_SDB_OBJ_NOT_THERE | 0 | 0x0323 | "Object not there" | -2147482845 | +| TSDB_CODE_MND_SDB_INVAID_META_ROW | 0 | 0x0324 | "Invalid meta row" | -2147482844 | +| TSDB_CODE_MND_SDB_INVAID_KEY_TYPE | 0 | 0x0325 | "Invalid key type" | -2147482843 | +| TSDB_CODE_MND_DNODE_ALREADY_EXIST | 0 | 0x0330 | "DNode already exists" | -2147482832 | +| TSDB_CODE_MND_DNODE_NOT_EXIST | 0 | 0x0331 | "DNode does not exist" | -2147482831 | +| TSDB_CODE_MND_VGROUP_NOT_EXIST | 0 | 0x0332 | "VGroup does not exist" | -2147482830 | +| TSDB_CODE_MND_NO_REMOVE_MASTER | 0 | 0x0333 | "Master DNode cannot be removed" | -2147482829 | +| TSDB_CODE_MND_NO_ENOUGH_DNODES | 0 | 0x0334 | "Out of DNodes" | -2147482828 | +| TSDB_CODE_MND_CLUSTER_CFG_INCONSISTENT | 0 | 0x0335 | "Cluster cfg inconsistent" | -2147482827 | +| TSDB_CODE_MND_INVALID_DNODE_CFG_OPTION | 0 | 0x0336 | "Invalid dnode cfg option" | -2147482826 | +| TSDB_CODE_MND_BALANCE_ENABLED | 0 | 0x0337 | "Balance already enabled" | -2147482825 | +| TSDB_CODE_MND_VGROUP_NOT_IN_DNODE | 0 | 0x0338 | "Vgroup not in dnode" | -2147482824 | +| TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE | 0 | 0x0339 | "Vgroup already in dnode" | -2147482823 | +| TSDB_CODE_MND_DNODE_NOT_FREE | 0 | 0x033A | "Dnode not avaliable" | -2147482822 | +| TSDB_CODE_MND_INVALID_CLUSTER_ID | 0 | 0x033B | "Cluster id not match" | -2147482821 | +| TSDB_CODE_MND_NOT_READY | 0 | 0x033C | "Cluster not ready" | -2147482820 | +| TSDB_CODE_MND_ACCT_ALREADY_EXIST | 0 | 0x0340 | "Account already exists" | -2147482816 | +| TSDB_CODE_MND_INVALID_ACCT | 0 | 0x0341 | "Invalid account" | -2147482815 | +| TSDB_CODE_MND_INVALID_ACCT_OPTION | 0 | 0x0342 | "Invalid account options" | -2147482814 | +| TSDB_CODE_MND_USER_ALREADY_EXIST | 0 | 0x0350 | "User already exists" | -2147482800 | +| TSDB_CODE_MND_INVALID_USER | 0 | 0x0351 | "Invalid user" | -2147482799 | +| TSDB_CODE_MND_INVALID_USER_FORMAT | 0 | 0x0352 | "Invalid user format" | -2147482798 | +| TSDB_CODE_MND_INVALID_PASS_FORMAT | 0 | 0x0353 | "Invalid password format" | -2147482797 | +| TSDB_CODE_MND_NO_USER_FROM_CONN | 0 | 0x0354 | "Can not get user from conn" | -2147482796 | +| TSDB_CODE_MND_TOO_MANY_USERS | 0 | 0x0355 | "Too many users" | -2147482795 | +| TSDB_CODE_MND_TABLE_ALREADY_EXIST | 0 | 0x0360 | "Table already exists" | -2147482784 | +| TSDB_CODE_MND_INVALID_TABLE_ID | 0 | 0x0361 | "Table name too long" | -2147482783 | +| TSDB_CODE_MND_INVALID_TABLE_NAME | 0 | 0x0362 | "Table does not exist" | -2147482782 | +| TSDB_CODE_MND_INVALID_TABLE_TYPE | 0 | 0x0363 | "Invalid table type in tsdb" | -2147482781 | +| TSDB_CODE_MND_TOO_MANY_TAGS | 0 | 0x0364 | "Too many tags" | -2147482780 | +| TSDB_CODE_MND_TOO_MANY_TIMESERIES | 0 | 0x0366 | "Too many time series" | -2147482778 | +| TSDB_CODE_MND_NOT_SUPER_TABLE | 0 | 0x0367 | "Not super table" | -2147482777 | +| TSDB_CODE_MND_COL_NAME_TOO_LONG | 0 | 0x0368 | "Tag name too long" | -2147482776 | +| TSDB_CODE_MND_TAG_ALREAY_EXIST | 0 | 0x0369 | "Tag already exists" | -2147482775 | +| TSDB_CODE_MND_TAG_NOT_EXIST | 0 | 0x036A | "Tag does not exist" | -2147482774 | +| TSDB_CODE_MND_FIELD_ALREAY_EXIST | 0 | 0x036B | "Field already exists" | -2147482773 | +| TSDB_CODE_MND_FIELD_NOT_EXIST | 0 | 0x036C | "Field does not exist" | -2147482772 | +| TSDB_CODE_MND_INVALID_STABLE_NAME | 0 | 0x036D | "Super table does not exist" | -2147482771 | +| TSDB_CODE_MND_DB_NOT_SELECTED | 0 | 0x0380 | "Database not specified or available" | -2147482752 | +| TSDB_CODE_MND_DB_ALREADY_EXIST | 0 | 0x0381 | "Database already exists" | -2147482751 | +| TSDB_CODE_MND_INVALID_DB_OPTION | 0 | 0x0382 | "Invalid database options" | -2147482750 | +| TSDB_CODE_MND_INVALID_DB | 0 | 0x0383 | "Invalid database name" | -2147482749 | +| TSDB_CODE_MND_MONITOR_DB_FORBIDDEN | 0 | 0x0384 | "Cannot delete monitor database" | -2147482748 | +| TSDB_CODE_MND_TOO_MANY_DATABASES | 0 | 0x0385 | "Too many databases for account" | -2147482747 | +| TSDB_CODE_MND_DB_IN_DROPPING | 0 | 0x0386 | "Database not available" | -2147482746 | +| TSDB_CODE_DND_MSG_NOT_PROCESSED | 0 | 0x0400 | "Message not processed" | -2147482624 | +| TSDB_CODE_DND_OUT_OF_MEMORY | 0 | 0x0401 | "Dnode out of memory" | -2147482623 | +| TSDB_CODE_DND_NO_WRITE_ACCESS | 0 | 0x0402 | "No permission for disk files in dnode" | -2147482622 | +| TSDB_CODE_DND_INVALID_MSG_LEN | 0 | 0x0403 | "Invalid message length" | -2147482621 | +| TSDB_CODE_VND_ACTION_IN_PROGRESS | 0 | 0x0500 | "Action in progress" | -2147482368 | +| TSDB_CODE_VND_MSG_NOT_PROCESSED | 0 | 0x0501 | "Message not processed" | -2147482367 | +| TSDB_CODE_VND_ACTION_NEED_REPROCESSED | 0 | 0x0502 | "Action need to be reprocessed" | -2147482366 | +| TSDB_CODE_VND_INVALID_VGROUP_ID | 0 | 0x0503 | "Invalid Vgroup ID" | -2147482365 | +| TSDB_CODE_VND_INIT_FAILED | 0 | 0x0504 | "Vnode initialization failed" | -2147482364 | +| TSDB_CODE_VND_NO_DISKSPACE | 0 | 0x0505 | "System out of disk space" | -2147482363 | +| TSDB_CODE_VND_NO_DISK_PERMISSIONS | 0 | 0x0506 | "No write permission for disk files" | -2147482362 | +| TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR | 0 | 0x0507 | "Missing data file" | -2147482361 | +| TSDB_CODE_VND_OUT_OF_MEMORY | 0 | 0x0508 | "Out of memory" | -2147482360 | +| TSDB_CODE_VND_APP_ERROR | 0 | 0x0509 | "Unexpected generic error in vnode" | -2147482359 | +| TSDB_CODE_VND_INVALID_STATUS | 0 | 0x0510 | "Database not ready" | -2147482352 | +| TSDB_CODE_VND_NOT_SYNCED | 0 | 0x0511 | "Database suspended" | -2147482351 | +| TSDB_CODE_VND_NO_WRITE_AUTH | 0 | 0x0512 | "Write operation denied" | -2147482350 | +| TSDB_CODE_TDB_INVALID_TABLE_ID | 0 | 0x0600 | "Invalid table ID" | -2147482112 | +| TSDB_CODE_TDB_INVALID_TABLE_TYPE | 0 | 0x0601 | "Invalid table type" | -2147482111 | +| TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION | 0 | 0x0602 | "Invalid table schema version" | -2147482110 | +| TSDB_CODE_TDB_TABLE_ALREADY_EXIST | 0 | 0x0603 | "Table already exists" | -2147482109 | +| TSDB_CODE_TDB_INVALID_CONFIG | 0 | 0x0604 | "Invalid configuration" | -2147482108 | +| TSDB_CODE_TDB_INIT_FAILED | 0 | 0x0605 | "Tsdb init failed" | -2147482107 | +| TSDB_CODE_TDB_NO_DISKSPACE | 0 | 0x0606 | "No diskspace for tsdb" | -2147482106 | +| TSDB_CODE_TDB_NO_DISK_PERMISSIONS | 0 | 0x0607 | "No permission for disk files" | -2147482105 | +| TSDB_CODE_TDB_FILE_CORRUPTED | 0 | 0x0608 | "Data file(s) corrupted" | -2147482104 | +| TSDB_CODE_TDB_OUT_OF_MEMORY | 0 | 0x0609 | "Out of memory" | -2147482103 | +| TSDB_CODE_TDB_TAG_VER_OUT_OF_DATE | 0 | 0x060A | "Tag too old" | -2147482102 | +| TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE | 0 | 0x060B | "Timestamp data out of range" | -2147482101 | +| TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP | 0 | 0x060C | "Submit message is messed up" | -2147482100 | +| TSDB_CODE_TDB_INVALID_ACTION | 0 | 0x060D | "Invalid operation" | -2147482099 | +| TSDB_CODE_TDB_INVALID_CREATE_TB_MSG | 0 | 0x060E | "Invalid creation of table" | -2147482098 | +| TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM | 0 | 0x060F | "No table data in memory skiplist" | -2147482097 | +| TSDB_CODE_TDB_FILE_ALREADY_EXISTS | 0 | 0x0610 | "File already exists" | -2147482096 | +| TSDB_CODE_TDB_TABLE_RECONFIGURE | 0 | 0x0611 | "Need to reconfigure table" | -2147482095 | +| TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO | 0 | 0x0612 | "Invalid information to create table" | -2147482094 | +| TSDB_CODE_QRY_INVALID_QHANDLE | 0 | 0x0700 | "Invalid handle" | -2147481856 | +| TSDB_CODE_QRY_INVALID_MSG | 0 | 0x0701 | "Invalid message" | -2147481855 | +| TSDB_CODE_QRY_NO_DISKSPACE | 0 | 0x0702 | "No diskspace for query" | -2147481854 | +| TSDB_CODE_QRY_OUT_OF_MEMORY | 0 | 0x0703 | "System out of memory" | -2147481853 | +| TSDB_CODE_QRY_APP_ERROR | 0 | 0x0704 | "Unexpected generic error in query" | -2147481852 | +| TSDB_CODE_QRY_DUP_JOIN_KEY | 0 | 0x0705 | "Duplicated join key" | -2147481851 | +| TSDB_CODE_QRY_EXCEED_TAGS_LIMIT | 0 | 0x0706 | "Tag conditon too many" | -2147481850 | +| TSDB_CODE_QRY_NOT_READY | 0 | 0x0707 | "Query not ready" | -2147481849 | +| TSDB_CODE_QRY_HAS_RSP | 0 | 0x0708 | "Query should response" | -2147481848 | +| TSDB_CODE_GRANT_EXPIRED | 0 | 0x0800 | "License expired" | -2147481600 | +| TSDB_CODE_GRANT_DNODE_LIMITED | 0 | 0x0801 | "DNode creation limited by licence" | -2147481599 | +| TSDB_CODE_GRANT_ACCT_LIMITED | 0 | 0x0802 | "Account creation limited by license" | -2147481598 | +| TSDB_CODE_GRANT_TIMESERIES_LIMITED | 0 | 0x0803 | "Table creation limited by license" | -2147481597 | +| TSDB_CODE_GRANT_DB_LIMITED | 0 | 0x0804 | "DB creation limited by license" | -2147481596 | +| TSDB_CODE_GRANT_USER_LIMITED | 0 | 0x0805 | "User creation limited by license" | -2147481595 | +| TSDB_CODE_GRANT_CONN_LIMITED | 0 | 0x0806 | "Conn creation limited by license" | -2147481594 | +| TSDB_CODE_GRANT_STREAM_LIMITED | 0 | 0x0807 | "Stream creation limited by license" | -2147481593 | +| TSDB_CODE_GRANT_SPEED_LIMITED | 0 | 0x0808 | "Write speed limited by license" | -2147481592 | +| TSDB_CODE_GRANT_STORAGE_LIMITED | 0 | 0x0809 | "Storage capacity limited by license" | -2147481591 | +| TSDB_CODE_GRANT_QUERYTIME_LIMITED | 0 | 0x080A | "Query time limited by license" | -2147481590 | +| TSDB_CODE_GRANT_CPU_LIMITED | 0 | 0x080B | "CPU cores limited by license" | -2147481589 | +| TSDB_CODE_SYN_INVALID_CONFIG | 0 | 0x0900 | "Invalid Sync Configuration" | -2147481344 | +| TSDB_CODE_SYN_NOT_ENABLED | 0 | 0x0901 | "Sync module not enabled" | -2147481343 | +| TSDB_CODE_WAL_APP_ERROR | 0 | 0x1000 | "Unexpected generic error in wal" | -2147479552 | diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md index 112ad99391521b31bdb4876519be6b68d8b62fe6..af78074eb25391d605bfca9067d24e1626296891 100644 --- a/documentation20/cn/12.taos-sql/docs.md +++ b/documentation20/cn/12.taos-sql/docs.md @@ -41,9 +41,9 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM 在TDengine中,普通表的数据模型中可使用以下 10 种数据类型。 -| | 类型 | Bytes | 说明 | +| # | **类型** | **Bytes** | **说明** | | ---- | :-------: | ------ | ------------------------------------------------------------ | -| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。(从 2.0.18 版本开始,已经去除了这一时间范围限制) | +| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。(从 2.0.18.0 版本开始,已经去除了这一时间范围限制) | | 2 | INT | 4 | 整型,范围 [-2^31+1, 2^31-1], -2^31 用作 NULL | | 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用于 NULL | | 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] | @@ -53,6 +53,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM | 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128 用于 NULL | | 9 | BOOL | 1 | 布尔型,{true, false} | | 10 | NCHAR | 自定义 | 记录包含多字节字符在内的字符串,如中文字符。每个 nchar 字符占用 4 bytes 的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 `\’`。nchar 使用时须指定字符串大小,类型为 nchar(10) 的列表示此列的字符串最多存储 10 个 nchar 字符,会固定占用 40 bytes 的空间。如果用户字符串长度超出声明长度,将会报错。 | + **Tips**: 1. TDengine 对 SQL 语句中的英文字符不区分大小写,自动转化为小写执行。因此用户大小写敏感的字符串及密码,需要使用单引号将字符串引起来。 @@ -63,11 +64,11 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM - **创建数据库** ```mysql - CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [UPDATE 1]; + CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1]; ``` - 说明: + 说明: - 1) KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据; + 1) KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据; 2) UPDATE 标志数据库支持更新相同时间戳数据; @@ -75,7 +76,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM 4) 一条SQL 语句的最大长度为65480个字符; - 5) 数据库还有更多与存储相关的配置参数,请参见系统管理。 + 5) 数据库还有更多与存储相关的配置参数,请参见 [服务端配置](https://www.taosdata.com/cn/documentation/administrator#config) 章节。 - **显示系统当前参数** @@ -125,7 +126,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM ```mysql ALTER DATABASE db_name CACHELAST 0; ``` - CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11 版本开始支持,修改后需要重启服务器生效。) + CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11.0 版本开始支持。从 2.1.1.0 版本开始,修改此参数后无需重启服务器即可生效。) **Tips**: 以上所有参数修改后都可以用show databases来确认是否修改成功。 @@ -135,6 +136,14 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM SHOW DATABASES; ``` +- **显示一个数据库的创建语句** + + ```mysql + SHOW CREATE DATABASE db_name; + ``` + 常用于数据库迁移。对一个已经存在的数据库,返回其创建语句;在另一个集群中执行该语句,就能得到一个设置完全相同的 Database。 + + ## 表管理 - **创建数据表** @@ -159,22 +168,22 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM ```mysql CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...); ``` - 以指定的超级表为模板,指定 tags 的值来创建数据表。 + 以指定的超级表为模板,指定 TAGS 的值来创建数据表。 -- **以超级表为模板创建数据表,并指定具体的 tags 列** +- **以超级表为模板创建数据表,并指定具体的 TAGS 列** ```mysql CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...); ``` - 以指定的超级表为模板,指定一部分 tags 列的值来创建数据表。(没被指定的 tags 列会设为空值。) - 说明:从 2.0.17 版本开始支持这种方式。在之前的版本中,不允许指定 tags 列,而必须显式给出所有 tags 列的取值。 + 以指定的超级表为模板,指定一部分 TAGS 列的值来创建数据表(没被指定的 TAGS 列会设为空值)。 + 说明:从 2.0.17.0 版本开始支持这种方式。在之前的版本中,不允许指定 TAGS 列,而必须显式给出所有 TAGS 列的取值。 - **批量创建数据表** ```mysql CREATE TABLE [IF NOT EXISTS] tb_name1 USING stb_name TAGS (tag_value1, ...) tb_name2 USING stb_name TAGS (tag_value2, ...) ...; ``` - 以更快的速度批量创建大量数据表。(服务器端 2.0.14 及以上版本) + 以更快的速度批量创建大量数据表(服务器端 2.0.14 及以上版本)。 说明: @@ -200,11 +209,19 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM 通配符匹配:1)’%’ (百分号)匹配0到任意个字符;2)’\_’下划线匹配一个字符。 +- **显示一个数据表的创建语句** + + ```mysql + SHOW CREATE TABLE tb_name; + ``` + 常用于数据库迁移。对一个已经存在的数据表,返回其创建语句;在另一个集群中执行该语句,就能得到一个结构完全相同的数据表。 + - **在线修改显示字符宽度** ```mysql SET MAX_BINARY_DISPLAY_WIDTH ; ``` + 如显示的内容后面以...结尾时,表示该内容已被截断,可通过本命令修改显示字符宽度以显示完整的内容。 - **获取表的结构信息** @@ -221,14 +238,14 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM 1) 列的最大个数为1024,最小个数为2; - 2) 列名最大长度为64; + 2) 列名最大长度为64。 - **表删除列** ```mysql ALTER TABLE tb_name DROP COLUMN field_name; ``` - 如果表是通过[超级表](../super-table/)创建,更改表结构的操作只能对超级表进行。同时针对超级表的结构更改对所有通过该结构创建的表生效。对于不是通过超级表创建的表,可以直接修改表结构 + 如果表是通过超级表创建,更改表结构的操作只能对超级表进行。同时针对超级表的结构更改对所有通过该结构创建的表生效。对于不是通过超级表创建的表,可以直接修改表结构。 ## 超级表STable管理 @@ -239,7 +256,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM ```mysql CREATE STABLE [IF NOT EXISTS] stb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...]) TAGS (tag1_name tag_type1, tag2_name tag_type2 [, tag3_name tag_type3]); ``` - 创建 STable,与创建表的 SQL 语法相似,但需指定 TAGS 字段的名称和类型 + 创建 STable,与创建表的 SQL 语法相似,但需要指定 TAGS 字段的名称和类型 说明: @@ -261,10 +278,17 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM - **显示当前数据库下的所有超级表信息** ```mysql - SHOW STABLES [LIKE tb_name_wildcar]; + SHOW STABLES [LIKE tb_name_wildcard]; ``` 查看数据库内全部 STable,及其相关信息,包括 STable 的名称、创建时间、列数量、标签(TAG)数量、通过该 STable 建表的数量。 +- **显示一个超级表的创建语句** + + ```mysql + SHOW CREATE STABLE stb_name; + ``` + 常用于数据库迁移。对一个已经存在的超级表,返回其创建语句;在另一个集群中执行该语句,就能得到一个结构完全相同的超级表。 + - **获取超级表的结构信息** ```mysql @@ -319,7 +343,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM ```mysql INSERT INTO tb_name VALUES (field_value, ...); ``` - 向表tb_name中插入一条记录 + 向表tb_name中插入一条记录。 - **插入一条记录,数据对应到指定的列** ```mysql @@ -331,42 +355,56 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM ```mysql INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...) ...; ``` - 向表tb_name中插入多条记录 + 向表tb_name中插入多条记录。 **注意**:在使用“插入多条记录”方式写入数据时,不能把第一列的时间戳取值都设为now,否则会导致语句中的多条记录使用相同的时间戳,于是就可能出现相互覆盖以致这些数据行无法全部被正确保存。 - **按指定的列插入多条记录** ```mysql INSERT INTO tb_name (field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...; ``` - 向表tb_name中按指定的列插入多条记录 + 向表tb_name中按指定的列插入多条记录。 - **向多个表插入多条记录** ```mysql INSERT INTO tb1_name VALUES (field1_value1, ...) (field1_value2, ...) ... tb2_name VALUES (field1_value1, ...) (field1_value2, ...) ...; ``` - 同时向表tb1_name和tb2_name中分别插入多条记录 + 同时向表tb1_name和tb2_name中分别插入多条记录。 - **同时向多个表按列插入多条记录** ```mysql INSERT INTO tb1_name (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ... tb2_name (tb2_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...; ``` - 同时向表tb1_name和tb2_name中按列分别插入多条记录 + 同时向表tb1_name和tb2_name中按列分别插入多条记录。 - 注意:允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的keep值(数据保留的天数),允许插入的最新记录的时间戳,是相对于当前服务器时间,加上配置的days值(数据文件存储数据的时间跨度,单位为天)。keep和days都是可以在创建数据库时指定的,缺省值分别是3650天和10天。 + 注意: + 1) 如果时间戳为now,系统将自动使用客户端当前时间作为该记录的时间戳; + 2) 允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的keep值(数据保留的天数),允许插入的最新记录的时间戳,是相对于当前服务器时间,加上配置的days值(数据文件存储数据的时间跨度,单位为天)。keep和days都是可以在创建数据库时指定的,缺省值分别是3650天和10天。 - **插入记录时自动建表** ```mysql INSERT INTO tb_name USING stb_name TAGS (tag_value1, ...) VALUES (field_value1, ...); ``` - 如果用户在写数据时并不确定某个表是否存在,此时可以在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。自动建表时,要求必须以超级表为模板,并写明数据表的 tags 取值。 + 如果用户在写数据时并不确定某个表是否存在,此时可以在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。自动建表时,要求必须以超级表为模板,并写明数据表的 TAGS 取值。 -- **插入记录时自动建表,并指定具体的 tags 列** +- **插入记录时自动建表,并指定具体的 TAGS 列** ```mysql INSERT INTO tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...) VALUES (field_value1, ...); ``` - 在自动建表时,可以只是指定部分 tags 列的取值,未被指定的 tags 列将取为空值。 + 在自动建表时,可以只是指定部分 TAGS 列的取值,未被指定的 TAGS 列将取为空值。 + +- **同时向多个表按列插入多条记录,自动建表** + ```mysql + INSERT INTO tb1_name (tb1_field1_name, ...) [USING stb1_name TAGS (tag_value1, ...)] VALUES (field1_value1, ...) (field1_value2, ...) ... + tb2_name (tb2_field1_name, ...) [USING stb2_name TAGS (tag_value2, ...)] VALUES (field1_value1, ...) (field1_value2, ...) ...; + ``` + 以自动建表的方式,同时向表tb1_name和tb2_name中按列分别插入多条记录。 + 从 2.0.20.5 版本开始,子表的列名可以不跟在子表名称后面,而是可以放在 TAGS 和 VALUES 之间,例如像下面这样写: + ```mysql + INSERT INTO tb1_name [USING stb1_name TAGS (tag_value1, ...)] (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...; + ``` + 注意:虽然两种写法都可以,但并不能在一条 SQL 语句中混用,否则会报语法错误。 **历史记录写入**:可使用IMPORT或者INSERT命令,IMPORT的语法,功能与INSERT完全一样。 @@ -449,7 +487,7 @@ Query OK, 9 row(s) in set (0.002022s) SELECT * FROM d1001; SELECT d1001.* FROM d1001; ``` -在Join查询中,带前缀的\*和不带前缀\*返回的结果有差别, \*返回全部表的所有列数据(不包含标签),带前缀的通配符,则只返回该表的列数据。 +在JOIN查询中,带前缀的\*和不带前缀\*返回的结果有差别, \*返回全部表的所有列数据(不包含标签),带前缀的通配符,则只返回该表的列数据。 ```mysql taos> SELECT * FROM d1001, d1003 WHERE d1001.ts=d1003.ts; ts | current | voltage | phase | ts | current | voltage | phase | @@ -465,7 +503,7 @@ taos> SELECT d1001.* FROM d1001,d1003 WHERE d1001.ts = d1003.ts; Query OK, 1 row(s) in set (0.020443s) ``` -在使用SQL函数来进行查询过程中,部分SQL函数支持通配符操作。其中的区别在于: +在使用SQL函数来进行查询的过程中,部分SQL函数支持通配符操作。其中的区别在于: ```count(*)```函数只返回一列。```first```、```last```、```last_row```函数则是返回全部列。 ```mysql @@ -500,12 +538,12 @@ Query OK, 2 row(s) in set (0.003112s) ##### 获取标签列的去重取值 -从 2.0.15 版本开始,支持在超级表查询标签列时,指定 distinct 关键字,这样将返回指定标签列的所有不重复取值。 +从 2.0.15 版本开始,支持在超级表查询标签列时,指定 DISTINCT 关键字,这样将返回指定标签列的所有不重复取值。 ```mysql SELECT DISTINCT tag_name FROM stb_name; ``` -注意:目前 distinct 关键字只支持对超级表的标签列进行去重,而不能用于普通列。 +注意:目前 DISTINCT 关键字只支持对超级表的标签列进行去重,而不能用于普通列。 @@ -540,7 +578,7 @@ SELECT * FROM d1001; #### 特殊功能 -部分特殊的查询功能可以不使用FROM子句执行。获取当前所在的数据库 database() +部分特殊的查询功能可以不使用FROM子句执行。获取当前所在的数据库 database(): ```mysql taos> SELECT DATABASE(); database() | @@ -548,7 +586,7 @@ taos> SELECT DATABASE(); power | Query OK, 1 row(s) in set (0.000079s) ``` -如果登录的时候没有指定默认数据库,且没有使用```use```命令切换数据,则返回NULL。 +如果登录的时候没有指定默认数据库,且没有使用```USE```命令切换数据,则返回NULL。 ```mysql taos> SELECT DATABASE(); database() | @@ -556,7 +594,7 @@ taos> SELECT DATABASE(); NULL | Query OK, 1 row(s) in set (0.000184s) ``` -获取服务器和客户端版本号: +获取服务器和客户端版本号: ```mysql taos> SELECT CLIENT_VERSION(); client_version() | @@ -600,7 +638,7 @@ SELECT TBNAME, location FROM meters; ```mysql SELECT COUNT(TBNAME) FROM meters; ``` -以上两个查询均只支持在Where条件子句中添加针对标签(TAGS)的过滤条件。例如: +以上两个查询均只支持在WHERE条件子句中添加针对标签(TAGS)的过滤条件。例如: ```mysql taos> SELECT TBNAME, location FROM meters; tbname | location | @@ -626,30 +664,31 @@ Query OK, 1 row(s) in set (0.001091s) - 参数 LIMIT 控制输出条数,OFFSET 指定从第几条开始输出。LIMIT/OFFSET 对结果集的执行顺序在 ORDER BY 之后。 * 在有 GROUP BY 子句的情况下,LIMIT 参数控制的是每个分组中至多允许输出的条数。 - 参数 SLIMIT 控制由 GROUP BY 指令划分的分组中,至多允许输出几个分组的数据。 -- 通过 ">>" 输出结果可以导出到指定文件。 +- 通过 “>>” 输出结果可以导出到指定文件。 ### 支持的条件过滤操作 -| Operation | Note | Applicable Data Types | -| ----------- | ----------------------------- | ------------------------------------- | -| > | larger than | **`timestamp`** and all numeric types | -| < | smaller than | **`timestamp`** and all numeric types | -| >= | larger than or equal to | **`timestamp`** and all numeric types | -| <= | smaller than or equal to | **`timestamp`** and all numeric types | -| = | equal to | all types | -| <> | not equal to | all types | -| between and | within a certain range | **`timestamp`** and all numeric types | -| % | match with any char sequences | **`binary`** **`nchar`** | -| _ | match with a single char | **`binary`** **`nchar`** | +| **Operation** | **Note** | **Applicable Data Types** | +| --------------- | ----------------------------- | ------------------------------------- | +| > | larger than | **`timestamp`** and all numeric types | +| < | smaller than | **`timestamp`** and all numeric types | +| >= | larger than or equal to | **`timestamp`** and all numeric types | +| <= | smaller than or equal to | **`timestamp`** and all numeric types | +| = | equal to | all types | +| <> | not equal to | all types | +| between and | within a certain range | **`timestamp`** and all numeric types | +| % | match with any char sequences | **`binary`** **`nchar`** | +| _ | match with a single char | **`binary`** **`nchar`** | 1. 同时进行多个字段的范围过滤,需要使用关键词 AND 来连接不同的查询条件,暂不支持 OR 连接的不同列之间的查询过滤条件。 2. 针对单一字段的过滤,如果是时间过滤条件,则一条语句中只支持设定一个;但针对其他的(普通)列或标签列,则可以使用 `OR` 关键字进行组合条件的查询过滤。例如:((value > 20 AND value < 30) OR (value < 12)) 。 3. 从 2.0.17 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。 -### UNION ALL 操作符 + +### UNION ALL 操作符 ```mysql SELECT ... @@ -669,37 +709,38 @@ TDengine 支持 UNION ALL 操作符。也就是说,如果多个 SELECT 子句 ### SQL 示例 -- 对于下面的例子,表tb1用以下语句创建 +- 对于下面的例子,表tb1用以下语句创建: ```mysql CREATE TABLE tb1 (ts TIMESTAMP, col1 INT, col2 FLOAT, col3 BINARY(50)); ``` -- 查询tb1刚过去的一个小时的所有记录 +- 查询tb1刚过去的一个小时的所有记录: ```mysql SELECT * FROM tb1 WHERE ts >= NOW - 1h; ``` -- 查询表tb1从2018-06-01 08:00:00.000 到2018-06-02 08:00:00.000时间范围,并且col3的字符串是'nny'结尾的记录,结果按照时间戳降序 +- 查询表tb1从2018-06-01 08:00:00.000 到2018-06-02 08:00:00.000时间范围,并且col3的字符串是'nny'结尾的记录,结果按照时间戳降序: ```mysql SELECT * FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND ts <= '2018-06-02 08:00:00.000' AND col3 LIKE '%nny' ORDER BY ts DESC; ``` -- 查询col1与col2的和,并取名complex, 时间大于2018-06-01 08:00:00.000, col2大于1.2,结果输出仅仅10条记录,从第5条开始 +- 查询col1与col2的和,并取名complex, 时间大于2018-06-01 08:00:00.000, col2大于1.2,结果输出仅仅10条记录,从第5条开始: ```mysql SELECT (col1 + col2) AS 'complex' FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND col2 > 1.2 LIMIT 10 OFFSET 5; ``` -- 查询过去10分钟的记录,col2的值大于3.14,并且将结果输出到文件 `/home/testoutpu.csv`. +- 查询过去10分钟的记录,col2的值大于3.14,并且将结果输出到文件 `/home/testoutpu.csv`: ```mysql SELECT COUNT(*) FROM tb1 WHERE ts >= NOW - 10m AND col2 > 3.14 >> /home/testoutpu.csv; ``` -## SQL 函数 + +## SQL 函数 ### 聚合函数 @@ -719,7 +760,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 说明: - 1)可以使用星号\*来替代具体的字段,使用星号(\*)返回全部记录数量。 + 1)可以使用星号(\*)来替代具体的字段,使用星号(\*)返回全部记录数量。 2)针对同一表的(不包含NULL值)字段查询结果均相同。 @@ -990,7 +1031,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 1)*k*值取值范围1≤*k*≤100; - 2)系统同时返回该记录关联的时间戳列。 + 2)系统同时返回该记录关联的时间戳列; + + 3)限制:TOP函数不支持FILL子句。 示例: ```mysql @@ -1026,7 +1069,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 1)*k*值取值范围1≤*k*≤100; - 2)系统同时返回该记录关联的时间戳列。 + 2)系统同时返回该记录关联的时间戳列; + + 3)限制:BOTTOM函数不支持FILL子句。 示例: ```mysql @@ -1102,7 +1147,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 适用于:**表、超级表**。 - 说明:与last函数不同,last_row不支持时间范围限制,强制返回最后一条记录。 + 说明:与LAST函数不同,LAST_ROW不支持时间范围限制,强制返回最后一条记录。 + + 限制:LAST_ROW()不能与INTERVAL一起使用。 示例: ```mysql @@ -1211,40 +1258,40 @@ SELECT function_list FROM tb_name [WHERE where_condition] INTERVAL (interval [, offset]) [SLIDING sliding] - [FILL ({NONE | VALUE | PREV | NULL | LINEAR})] + [FILL ({NONE | VALUE | PREV | NULL | LINEAR | NEXT})] SELECT function_list FROM stb_name [WHERE where_condition] INTERVAL (interval [, offset]) [SLIDING sliding] - [FILL ({ VALUE | PREV | NULL | LINEAR})] + [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})] [GROUP BY tags] ``` - 聚合时间段的长度由关键词INTERVAL指定,最短时间间隔10毫秒(10a),并且支持偏移(偏移必须小于间隔)。聚合查询中,能够同时执行的聚合和选择函数仅限于单个输出的函数:count、avg、sum 、stddev、leastsquares、percentile、min、max、first、last,不能使用具有多行输出结果的函数(例如:top、bottom、diff以及四则运算)。 -- WHERE语句可以指定查询的起止时间和其他过滤条件 -- SLIDING语句用于指定聚合时间段的前向增量 +- WHERE语句可以指定查询的起止时间和其他过滤条件。 +- SLIDING语句用于指定聚合时间段的前向增量。 - FILL语句指定某一时间区间数据缺失的情况下的填充模式。填充模式包括以下几种: - * 不进行填充:NONE(默认填充模式)。 - * VALUE填充:固定值填充,此时需要指定填充的数值。例如:fill(value, 1.23)。 - * NULL填充:使用NULL填充数据。例如:fill(null)。 - * PREV填充:使用前一个非NULL值填充数据。例如:fill(prev)。 + 1. 不进行填充:NONE(默认填充模式)。 + 2. VALUE填充:固定值填充,此时需要指定填充的数值。例如:FILL(VALUE, 1.23)。 + 3. NULL填充:使用NULL填充数据。例如:FILL(NULL)。 + 4. PREV填充:使用前一个非NULL值填充数据。例如:FILL(PREV)。 + 5. NEXT填充:使用下一个非NULL值填充数据。例如:FILL(NEXT)。 说明: 1. 使用FILL语句的时候可能生成大量的填充输出,务必指定查询的时间区间。针对每次查询,系统可返回不超过1千万条具有插值的结果。 2. 在时间维度聚合中,返回的结果中时间序列严格单调递增。 - 3. 如果查询对象是超级表,则聚合函数会作用于该超级表下满足值过滤条件的所有表的数据。如果查询中没有使用group by语句,则返回的结果按照时间序列严格单调递增;如果查询中使用了group by语句分组,则返回结果中每个group内不按照时间序列严格单调递增。 + 3. 如果查询对象是超级表,则聚合函数会作用于该超级表下满足值过滤条件的所有表的数据。如果查询中没有使用GROUP BY语句,则返回的结果按照时间序列严格单调递增;如果查询中使用了GROUP BY语句分组,则返回结果中每个GROUP内不按照时间序列严格单调递增。 时间聚合也常被用于连续查询场景,可以参考文档 [连续查询(Continuous Query)](https://www.taosdata.com/cn/documentation/advanced-features#continuous-query)。 -**示例:** 智能电表的建表语句如下: +**示例**: 智能电表的建表语句如下: ```mysql CREATE TABLE meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT); ``` -针对智能电表采集的数据,以10分钟为一个阶段,计算过去24小时的电流数据的平均值、最大值、电流的中位数、以及随着时间变化的电流走势拟合直线。如果没有计算值,用前一个非NULL值填充。 -使用的查询语句如下: +针对智能电表采集的数据,以10分钟为一个阶段,计算过去24小时的电流数据的平均值、最大值、电流的中位数、以及随着时间变化的电流走势拟合直线。如果没有计算值,用前一个非NULL值填充。使用的查询语句如下: ```mysql SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), PERCENTILE(current, 50) FROM meters @@ -1265,15 +1312,15 @@ SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), P ## TAOS SQL其他约定 -**group by的限制** +**GROUP BY的限制** -TAOS SQL支持对标签、tbname进行group by操作,也支持普通列进行group by,前提是:仅限一列且该列的唯一值小于10万个。 +TAOS SQL支持对标签、TBNAME进行GROUP BY操作,也支持普通列进行GROUP BY,前提是:仅限一列且该列的唯一值小于10万个。 -**join操作的限制** +**JOIN操作的限制** TAOS SQL支持表之间按主键时间戳来join两张表的列,暂不支持两个表之间聚合后的四则运算。 -**is not null与不为空的表达式适用范围** +**IS NOT NULL与不为空的表达式适用范围** -is not null支持所有类型的列。不为空的表达式为 <>"",仅对非数值类型的列适用。 +IS NOT NULL支持所有类型的列。不为空的表达式为 <>"",仅对非数值类型的列适用。 diff --git a/documentation20/cn/13.faq/docs.md b/documentation20/cn/13.faq/docs.md index e561f91c948a89dd6b909ea81460df2dcf0ec4db..8d18ae269d871786df6bb5f1c65315bb28085b55 100644 --- a/documentation20/cn/13.faq/docs.md +++ b/documentation20/cn/13.faq/docs.md @@ -26,17 +26,17 @@ ## 2. Windows平台下JDBCDriver找不到动态链接库,怎么办? -请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/jdbcdriver找不到动态链接库/) +请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/950.html) ## 3. 创建数据表时提示more dnodes are needed -请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/创建数据表时提示more-dnodes-are-needed/) +请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/965.html) ## 4. 如何让TDengine crash时生成core文件? -请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/06/tdengine-crash时生成core文件的方法/) +请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/06/974.html) -## 5. 遇到错误"Unable to establish connection", 我怎么办? +## 5. 遇到错误“Unable to establish connection”, 我怎么办? 客户端遇到连接故障,请按照下面的步骤进行检查: @@ -51,13 +51,13 @@ 4. 确认客户端连接时指定了正确的服务器FQDN (Fully Qualified Domain Name(可在服务器上执行Linux命令hostname -f获得)),FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。 -5. ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件 +5. ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件。如果部署的是TDengine集群,客户端需要能ping通所有集群节点的FQDN。 6. 检查防火墙设置(Ubuntu 使用 ufw status,CentOS 使用 firewall-cmd --list-port),确认TCP/UDP 端口6030-6042 是打开的 7. 对于Linux上的JDBC(ODBC, Python, Go等接口类似)连接, 确保*libtaos.so*在目录*/usr/local/taos/driver*里, 并且*/usr/local/taos/driver*在系统库函数搜索路径*LD_LIBRARY_PATH*里 -8. 对于windows上的JDBC, ODBC, Python, Go等连接,确保*C:\TDengine\driver\taos.dll*在你的系统库函数搜索目录里 (建议*taos.dll*放在目录 *C:\Windows\System32*) +8. 对于Windows上的JDBC, ODBC, Python, Go等连接,确保*C:\TDengine\driver\taos.dll*在你的系统库函数搜索目录里 (建议*taos.dll*放在目录 *C:\Windows\System32*) 9. 如果仍不能排除连接故障 @@ -70,7 +70,8 @@ 10. 也可以使用taos程序内嵌的网络连通检测功能,来验证服务器和客户端之间指定的端口连接是否通畅(包括TCP和UDP):[TDengine 内嵌网络检测工具使用指南](https://www.taosdata.com/blog/2020/09/08/1816.html)。 -## 6. 遇到错误“Unexpected generic error in RPC”或者"TDengine Error: Unable to resolve FQDN", 我怎么办? +## 6. 遇到错误“Unexpected generic error in RPC”或者“Unable to resolve FQDN”,我怎么办? + 产生这个错误,是由于客户端或数据节点无法解析FQDN(Fully Qualified Domain Name)导致。对于TAOS Shell或客户端应用,请做如下检查: 1. 请检查连接的服务器的FQDN是否正确,FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。 @@ -102,7 +103,7 @@ TDengine 目前尚不支持删除功能,未来根据用户需求可能会支 批量插入。每条写入语句可以一张表同时插入多条记录,也可以同时插入多张表的多条记录。 -## 12. windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决? +## 12. Windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决? Windows下插入nchar类的数据中如果有中文,请先确认系统的地区设置成了中国(在Control Panel里可以设置),这时cmd中的`taos`客户端应该已经可以正常工作了;如果是在IDE里开发Java应用,比如Eclipse, Intellij,请确认IDE里的文件编码为GBK(这是Java默认的编码类型),然后在生成Connection时,初始化客户端的配置,具体语句如下: ```JAVA @@ -115,15 +116,15 @@ Connection = DriverManager.getConnection(url, properties); ## 13.JDBC报错: the excuted SQL is not a DML or a DDL? 请更新至最新的JDBC驱动 -```JAVA +```xml com.taosdata.jdbc taos-jdbcdriver - 2.0.4 + 2.0.27 ``` -## 14. taos connect failed, reason: invalid timestamp +## 14. taos connect failed, reason: invalid timestamp 常见原因是服务器和客户端时间没有校准,可以通过和时间服务器同步的方式(Linux 下使用 ntpdate 命令,Windows 在系统时间设置中选择自动同步)校准。 @@ -157,7 +158,8 @@ ALTER LOCAL RESETLOG; 其含义是,清空本机所有由客户端生成的日志文件。 -## 18. 时间戳的时区信息是怎样处理的? + +## 18. 时间戳的时区信息是怎样处理的? TDengine 中时间戳的时区总是由客户端进行处理,而与服务端无关。具体来说,客户端会对 SQL 语句中的时间戳进行时区转换,转为 UTC 时区(即 Unix 时间戳——Unix Timestamp)再交由服务端进行写入和查询;在读取数据时,服务端也是采用 UTC 时区提供原始数据,客户端收到后再根据本地设置,把时间戳转换为本地系统所要求的时区进行显示。 @@ -167,12 +169,13 @@ TDengine 中时间戳的时区总是由客户端进行处理,而与服务端 3. 如果在 C/C++/Java/Python 等各种编程语言的 Connector Driver 中,在建立数据库连接时显式指定了 timezone,那么会以这个指定的时区设置为准。例如 Java Connector 的 JDBC URL 中就有 timezone 参数。 4. 在书写 SQL 语句时,也可以直接使用 Unix 时间戳(例如 `1554984068000`)或带有时区的时间戳字符串,也即以 RFC 3339 格式(例如 `2013-04-12T15:52:01.123+08:00`)或 ISO-8601 格式(例如 `2013-04-12T15:52:01.123+0800`)来书写时间戳,此时这些时间戳的取值将不再受其他时区设置的影响。 -## 19. TDengine 都会用到哪些网络端口? + +## 19. TDengine 都会用到哪些网络端口? 在 TDengine 2.0 版本中,会用到以下这些网络端口(以默认端口 6030 为前提进行说明,如果修改了配置文件中的设置,那么这里列举的端口都会出现变化),管理员可以参考这里的信息调整防火墙设置: | 协议 | 默认端口 | 用途说明 | 修改方法 | -| --- | --------- | ------------------------------- | ------------------------------ | +| :--- | :-------- | :---------------------------------- | :------------------------------- | | TCP | 6030 | 客户端与服务端之间通讯。 | 由配置文件设置 serverPort 决定。 | | TCP | 6035 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 | | TCP | 6040 | 多节点集群的节点间数据同步。 | 随 serverPort 端口变化。 | diff --git a/packaging/deb/makedeb.sh b/packaging/deb/makedeb.sh index 36870b2ebe49d45390d7b5ce18f6984b9e8e2ac2..28be037e6c56e6ea156bfd963053f83b0d403a68 100755 --- a/packaging/deb/makedeb.sh +++ b/packaging/deb/makedeb.sh @@ -58,7 +58,12 @@ cp ${compile_dir}/build/lib/${libfile} ${pkg_dir}${install_home_pat cp ${compile_dir}/../src/inc/taos.h ${pkg_dir}${install_home_path}/include cp ${compile_dir}/../src/inc/taoserror.h ${pkg_dir}${install_home_path}/include cp -r ${top_dir}/tests/examples/* ${pkg_dir}${install_home_path}/examples -cp -r ${top_dir}/src/connector/grafanaplugin ${pkg_dir}${install_home_path}/connector +if [ -d "${top_dir}/src/connector/grafanaplugin/dist" ]; then + cp -r ${top_dir}/src/connector/grafanaplugin/dist ${pkg_dir}${install_home_path}/connector/grafanaplugin +else + echo "grafanaplugin bundled directory not found!" + exit 1 +fi cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector diff --git a/packaging/release.sh b/packaging/release.sh index 68f947ccab3ef18a1b351b91a58db64a8f465c8e..1e54bc28724dacf4a2835552eaca678f9ee3cd00 100755 --- a/packaging/release.sh +++ b/packaging/release.sh @@ -1,11 +1,11 @@ #!/bin/bash # -# Generate the deb package for ubunt, or rpm package for centos, or tar.gz package for other linux os +# Generate the deb package for ubuntu, or rpm package for centos, or tar.gz package for other linux os set -e #set -x -# releash.sh -v [cluster | edge] +# release.sh -v [cluster | edge] # -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] # -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...] # -V [stable | beta] diff --git a/packaging/rpm/tdengine.spec b/packaging/rpm/tdengine.spec index 92c917cb3d6d4cd5f41441c9ca75a742aa3641b6..9910e20bfe8583a64067bbd3fded2c32e23f83d8 100644 --- a/packaging/rpm/tdengine.spec +++ b/packaging/rpm/tdengine.spec @@ -66,7 +66,12 @@ cp %{_compiledir}/build/bin/taosdump %{buildroot}%{homepath}/bin cp %{_compiledir}/build/lib/${libfile} %{buildroot}%{homepath}/driver cp %{_compiledir}/../src/inc/taos.h %{buildroot}%{homepath}/include cp %{_compiledir}/../src/inc/taoserror.h %{buildroot}%{homepath}/include -cp -r %{_compiledir}/../src/connector/grafanaplugin %{buildroot}%{homepath}/connector +if [ -d %{_compiledir}/../src/connector/grafanaplugin/dist ]; then + cp -r %{_compiledir}/../src/connector/grafanaplugin/dist %{buildroot}%{homepath}/connector/grafanaplugin +else + echo grafanaplugin bundled directory not found! + exit 1 +fi cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index dca3dd2ff623672eb85b3de72bcc34e0ea5e3d8a..178a248cfe26e7df248665c744ba462f4eb8fd8b 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -607,6 +607,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}" @@ -630,6 +631,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}" @@ -655,6 +657,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo 'PIDFile=/usr/local/nginxd/logs/nginx.pid' >> ${nginx_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/local/nginxd/sbin/nginx' >> ${nginx_service_config}" ${csudo} bash -c "echo 'ExecStop=/usr/local/nginxd/sbin/nginx -s stop' >> ${nginx_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${nginx_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${nginx_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${nginx_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${nginx_service_config}" diff --git a/packaging/tools/install_arbi.sh b/packaging/tools/install_arbi.sh index a89d2257dc96234c646f593c5bc45a4998575d5c..f47c3672cb0f806ee429209462c2a001be6090de 100755 --- a/packaging/tools/install_arbi.sh +++ b/packaging/tools/install_arbi.sh @@ -205,6 +205,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}" diff --git a/packaging/tools/install_arbi_power.sh b/packaging/tools/install_arbi_power.sh index 4b12913760e013049f44ec1ba9f7275322c436bd..3f271751511a124994a0f1833b59ff406dd9b227 100755 --- a/packaging/tools/install_arbi_power.sh +++ b/packaging/tools/install_arbi_power.sh @@ -205,6 +205,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}" diff --git a/packaging/tools/install_power.sh b/packaging/tools/install_power.sh index ba6ace400935c10caadd9426c0701c16b4f86baa..9f28435cb5f1cc43ae3bf1433074920889ccee3b 100755 --- a/packaging/tools/install_power.sh +++ b/packaging/tools/install_power.sh @@ -577,6 +577,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo 'Type=simple' >> ${powerd_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/powerd' >> ${powerd_service_config}" ${csudo} bash -c "echo 'ExecStartPre=/usr/local/power/bin/startPre.sh' >> ${powerd_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${powerd_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${powerd_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${powerd_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${powerd_service_config}" @@ -599,6 +600,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo '[Service]' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'Type=simple' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/tarbitrator' >> ${tarbitratord_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${tarbitratord_service_config}" @@ -624,6 +626,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo 'PIDFile=/usr/local/nginxd/logs/nginx.pid' >> ${nginx_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/local/nginxd/sbin/nginx' >> ${nginx_service_config}" ${csudo} bash -c "echo 'ExecStop=/usr/local/nginxd/sbin/nginx -s stop' >> ${nginx_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${nginx_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${nginx_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${nginx_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${nginx_service_config}" diff --git a/packaging/tools/make_install.sh b/packaging/tools/make_install.sh index 1fd0e943b155d0c96c26c3fdcec7061bd25197e4..d6ace0a0638bf6c8e78a3c87ce150f731ffca396 100755 --- a/packaging/tools/make_install.sh +++ b/packaging/tools/make_install.sh @@ -243,9 +243,17 @@ function install_data() { } function install_connector() { - ${csudo} cp -rf ${source_dir}/src/connector/grafanaplugin ${install_main_dir}/connector + if [ -d "${source_dir}/src/connector/grafanaplugin/dist" ]; then + ${csudo} cp -rf ${source_dir}/src/connector/grafanaplugin/dist ${install_main_dir}/connector/grafanaplugin + else + echo "WARNING: grafanaplugin bundled dir not found, please check if want to use it!" + fi + if find ${source_dir}/src/connector/go -mindepth 1 -maxdepth 1 | read; then + ${csudo} cp -r ${source_dir}/src/connector/go ${install_main_dir}/connector + else + echo "WARNING: go connector not found, please check if want to use it!" + fi ${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_dir}/connector - ${csudo} cp -rf ${source_dir}/src/connector/go ${install_main_dir}/connector ${csudo} cp ${binary_dir}/build/lib/*.jar ${install_main_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_dir}/connector/*.jar || echo &> /dev/null } @@ -333,6 +341,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}" diff --git a/packaging/tools/makeclient.sh b/packaging/tools/makeclient.sh index 30e9fa51a7d9c4a98d2c8f300287ebd242fecd74..d0eeffc86a980269a72cf3ceab59f9bca85b4d53 100755 --- a/packaging/tools/makeclient.sh +++ b/packaging/tools/makeclient.sh @@ -117,10 +117,18 @@ if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then if [ "$osType" != "Darwin" ]; then cp ${build_dir}/lib/*.jar ${install_dir}/connector ||: fi - cp -r ${connector_dir}/grafanaplugin ${install_dir}/connector/ - cp -r ${connector_dir}/python ${install_dir}/connector/ - cp -r ${connector_dir}/go ${install_dir}/connector - cp -r ${connector_dir}/nodejs ${install_dir}/connector + if [ -d "${connector_dir}/grafanaplugin/dist" ]; then + cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin + else + echo "WARNING: grafanaplugin bundled dir not found, please check if want to use it!" + 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/makeclient_power.sh b/packaging/tools/makeclient_power.sh index 181536b7f19d252164201291d9c37cade6cf3490..8241319e4f03a3f7a4953513df2ca3301541a16b 100755 --- a/packaging/tools/makeclient_power.sh +++ b/packaging/tools/makeclient_power.sh @@ -144,24 +144,23 @@ if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then if [ "$osType" != "Darwin" ]; then cp ${build_dir}/lib/*.jar ${install_dir}/connector ||: fi - cp -r ${connector_dir}/grafanaplugin ${install_dir}/connector/ - cp -r ${connector_dir}/python ${install_dir}/connector/ - cp -r ${connector_dir}/go ${install_dir}/connector + if [ -d "${connector_dir}/grafanaplugin/dist" ]; then + cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin + else + echo "WARNING: grafanaplugin bunlded dir not found, please check if want to use it!" + 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 - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/cinterface.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/cinterface.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/cinterface.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/cinterface.py + sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/cinterface.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/subscription.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/subscription.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/subscription.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/subscription.py + sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/subscription.py - sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/connection.py - sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/connection.py - sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/connection.py - sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/connection.py + sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/connection.py fi # Copy release note # cp ${script_dir}/release_note ${install_dir} diff --git a/packaging/tools/makepkg.sh b/packaging/tools/makepkg.sh index 36b1fe5bd88950f69a56e84d98fba9c4dae0cf05..e4d2d71b014293e1e328112e0d5e6e5677b772c0 100755 --- a/packaging/tools/makepkg.sh +++ b/packaging/tools/makepkg.sh @@ -114,6 +114,25 @@ mkdir -p ${install_dir}/examples examples_dir="${top_dir}/tests/examples" cp -r ${examples_dir}/c ${install_dir}/examples if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then + if [ -d ${examples_dir}/JDBC/connectionPools/target ]; then + rm -rf ${examples_dir}/JDBC/connectionPools/target + fi + if [ -d ${examples_dir}/JDBC/JDBCDemo/target ]; then + rm -rf ${examples_dir}/JDBC/JDBCDemo/target + fi + if [ -d ${examples_dir}/JDBC/mybatisplus-demo/target ]; then + rm -rf ${examples_dir}/JDBC/mybatisplus-demo/target + fi + if [ -d ${examples_dir}/JDBC/springbootdemo/target ]; then + rm -rf ${examples_dir}/JDBC/springbootdemo/target + fi + if [ -d ${examples_dir}/JDBC/SpringJdbcTemplate/target ]; then + rm -rf ${examples_dir}/JDBC/SpringJdbcTemplate/target + fi + if [ -d ${examples_dir}/JDBC/taosdemo/target ]; then + rm -rf ${examples_dir}/JDBC/taosdemo/target + fi + cp -r ${examples_dir}/JDBC ${install_dir}/examples cp -r ${examples_dir}/matlab ${install_dir}/examples cp -r ${examples_dir}/python ${install_dir}/examples @@ -131,9 +150,17 @@ connector_dir="${code_dir}/connector" mkdir -p ${install_dir}/connector if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then cp ${build_dir}/lib/*.jar ${install_dir}/connector ||: - cp -r ${connector_dir}/grafanaplugin ${install_dir}/connector/ - cp -r ${connector_dir}/python ${install_dir}/connector/ - cp -r ${connector_dir}/go ${install_dir}/connector + if [ -d "${connector_dir}/grafanaplugin/dist" ]; then + cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin + else + echo "WARNING: grafanaplugin bundled dir not found, please check if you want to use it!" + 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 diff --git a/packaging/tools/makepkg_power.sh b/packaging/tools/makepkg_power.sh index 554e7884b1c3db69acd3ba0e3234e468b1d31c79..633a135c14e908786b5a18a32077a7d987a46d4a 100755 --- a/packaging/tools/makepkg_power.sh +++ b/packaging/tools/makepkg_power.sh @@ -166,24 +166,24 @@ connector_dir="${code_dir}/connector" mkdir -p ${install_dir}/connector if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then cp ${build_dir}/lib/*.jar ${install_dir}/connector ||: - cp -r ${connector_dir}/grafanaplugin ${install_dir}/connector/ + + if [ -d "${connector_dir}/grafanaplugin/dist" ]; then + cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin + else + echo "WARNING: grafanaplugin bundled dir not found, please check if want to use it!" + 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}/go ${install_dir}/connector - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/cinterface.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/cinterface.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/cinterface.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/cinterface.py + sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/cinterface.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/subscription.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/subscription.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/subscription.py - sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/subscription.py + sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/subscription.py - sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python2/taos/connection.py - sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/linux/python3/taos/connection.py - sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python2/taos/connection.py - sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/windows/python3/taos/connection.py + sed -i '/self._password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/connection.py fi # Copy release note # cp ${script_dir}/release_note ${install_dir} diff --git a/packaging/tools/post.sh b/packaging/tools/post.sh index 8665b3fec3a392b3dcae8c6a197625ba85ed953b..3aa808317521e385aaea60a6c5223a960ed0e2d8 100755 --- a/packaging/tools/post.sh +++ b/packaging/tools/post.sh @@ -405,6 +405,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo 'Type=simple' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStart=/usr/bin/taosd' >> ${taosd_service_config}" ${csudo} bash -c "echo 'ExecStartPre=/usr/local/taos/bin/startPre.sh' >> ${taosd_service_config}" + ${csudo} bash -c "echo 'TimeoutStopSec=1000000s' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNOFILE=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitNPROC=infinity' >> ${taosd_service_config}" ${csudo} bash -c "echo 'LimitCORE=infinity' >> ${taosd_service_config}" diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 66f22fda1a6ff41406b5c63c10a78dd28173269e..a63225ab324cb1eefc9f221423c1018e8e1528eb 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,6 @@ name: tdengine base: core18 -version: '2.1.0.0' +version: '2.1.1.0' icon: snap/gui/t-dengine.svg summary: an open-source big data platform designed and optimized for IoT. description: | @@ -72,7 +72,7 @@ parts: - usr/bin/taosd - usr/bin/taos - usr/bin/taosdemo - - usr/lib/libtaos.so.2.1.0.0 + - usr/lib/libtaos.so.2.1.1.0 - usr/lib/libtaos.so.1 - usr/lib/libtaos.so diff --git a/src/client/inc/tscLocalMerge.h b/src/client/inc/tscLocalMerge.h index 143922bb1fb6d6e10a157de5d90af2da5e221f76..3c0bde000030000330b33212c7e0c942d50d6a90 100644 --- a/src/client/inc/tscLocalMerge.h +++ b/src/client/inc/tscLocalMerge.h @@ -39,39 +39,29 @@ typedef struct SLocalDataSource { } SLocalDataSource; typedef struct SLocalMerger { - SLocalDataSource ** pLocalDataSrc; + SLocalDataSource **pLocalDataSrc; int32_t numOfBuffer; int32_t numOfCompleted; int32_t numOfVnode; - SLoserTreeInfo * pLoserTree; - tFilePage * pResultBuf; - int32_t nResultBufSize; - tFilePage * pTempBuffer; - struct SQLFunctionCtx *pCtx; - int32_t rowSize; // size of each intermediate result. - tOrderDescriptor * pDesc; - SColumnModel * resColModel; - SColumnModel* finalModel; - tExtMemBuffer ** pExtMemBuffer; // disk-based buffer - bool orderPrjOnSTable; // projection query on stable + SLoserTreeInfo *pLoserTree; + int32_t rowSize; // size of each intermediate result. + tOrderDescriptor *pDesc; + tExtMemBuffer **pExtMemBuffer; // disk-based buffer + char *buf; // temp buffer } SLocalMerger; typedef struct SRetrieveSupport { tExtMemBuffer ** pExtMemBuffer; // for build loser tree tOrderDescriptor *pOrderDescriptor; - SColumnModel* pFinalColModel; // colModel for final result - SColumnModel* pFFColModel; int32_t subqueryIndex; // index of current vnode in vnode list SSqlObj * pParentSql; tFilePage * localBuffer; // temp buffer, there is a buffer for each vnode to uint32_t numOfRetry; // record the number of retry times } SRetrieveSupport; -int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pDesc, - SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSize); +int32_t tscLocalReducerEnvCreate(SQueryInfo* pQueryInfo, tExtMemBuffer ***pMemBuffer, int32_t numOfSub, tOrderDescriptor **pDesc, uint32_t nBufferSize, int64_t id); -void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel* pFFModel, - int32_t numOfVnodes); +void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, int32_t numOfVnodes); int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data, int32_t numOfRows, int32_t orderType); @@ -81,12 +71,10 @@ int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tF /* * create local reducer to launch the second-stage reduce process at client site */ -void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc, - SColumnModel *finalModel, SColumnModel *pFFModel, SSqlObj* pSql); +int32_t tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc, + SQueryInfo *pQueryInfo, SLocalMerger **pMerger, int64_t id); -void tscDestroyLocalMerger(SSqlObj *pSql); - -//int32_t tscDoLocalMerge(SSqlObj *pSql); +void tscDestroyLocalMerger(SLocalMerger* pLocalMerger); #ifdef __cplusplus } diff --git a/src/client/inc/tscSubquery.h b/src/client/inc/tscSubquery.h index 15ef54b7b13eb8463c54a7b979eb6d007560bb0e..f0349c2b3dc5b03b44afdca682f314709ecf6886 100644 --- a/src/client/inc/tscSubquery.h +++ b/src/client/inc/tscSubquery.h @@ -48,6 +48,8 @@ void tscLockByThread(int64_t *lockedBy); void tscUnlockByThread(int64_t *lockedBy); +int tsInsertInitialCheck(SSqlObj *pSql); + #ifdef __cplusplus } #endif diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 73be7664c6f7e116b3f4ce6b86e599905ac6ec3e..176cef74ee28d9fb7635d21d5e5f79b03e52265f 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -20,6 +20,7 @@ extern "C" { #endif +#include "tsched.h" #include "exception.h" #include "os.h" #include "qExtbuffer.h" @@ -36,6 +37,9 @@ extern "C" { #define UTIL_TABLE_IS_NORMAL_TABLE(metaInfo)\ (!(UTIL_TABLE_IS_SUPER_TABLE(metaInfo) || UTIL_TABLE_IS_CHILD_TABLE(metaInfo))) +#define UTIL_TABLE_IS_TMP_TABLE(metaInfo) \ + (((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE)) + #pragma pack(push,1) // this struct is transfered as binary, padding two bytes to avoid // an 'uid' whose low bytes is 0xff being recoginized as NULL, @@ -59,7 +63,7 @@ typedef struct SJoinSupporter { SArray* exprList; SFieldInfo fieldsInfo; STagCond tagCond; - SSqlGroupbyExpr groupInfo; // group by info + SGroupbyExpr groupInfo; // group by info struct STSBuf* pTSBuf; // the TSBuf struct that holds the compressed timestamp array FILE* f; // temporary file in order to create TSBuf char path[PATH_MAX]; // temporary file path, todo dynamic allocate memory @@ -90,22 +94,14 @@ typedef struct SVgroupTableInfo { SArray *itemList; // SArray } SVgroupTableInfo; -static FORCE_INLINE SQueryInfo* tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex) { - assert(pCmd != NULL && subClauseIndex >= 0); - if (pCmd->pQueryInfo == NULL || subClauseIndex >= pCmd->numOfClause) { - return NULL; - } - - return pCmd->pQueryInfo[subClauseIndex]; -} - -SQueryInfo* tscGetActiveQueryInfo(SSqlCmd* pCmd); +int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len); int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, SName* name, STableMeta* pTableMeta, STableDataBlocks** dataBlocks); void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta); void tscSortRemoveDataBlockDupRows(STableDataBlocks* dataBuf); void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo); +void doRetrieveSubqueryData(SSchedMsg *pMsg); SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, int16_t bytes, uint32_t offset); @@ -129,6 +125,7 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo); bool tscIsTWAQuery(SQueryInfo* pQueryInfo); bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo); bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo); +bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo); bool tscGroupbyColumn(SQueryInfo* pQueryInfo); bool tscIsTopBotQuery(SQueryInfo* pQueryInfo); bool hasTagValOutput(SQueryInfo* pQueryInfo); @@ -137,13 +134,14 @@ bool isStabledev(SQueryInfo* pQueryInfo); bool isTsCompQuery(SQueryInfo* pQueryInfo); bool isSimpleAggregate(SQueryInfo* pQueryInfo); bool isBlockDistQuery(SQueryInfo* pQueryInfo); -int32_t tscGetTopbotQueryParam(SQueryInfo* pQueryInfo); +bool isSimpleAggregateRv(SQueryInfo* pQueryInfo); bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex); bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex); bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex); bool tscIsProjectionQuery(SQueryInfo* pQueryInfo); +bool tscHasColumnFilter(SQueryInfo* pQueryInfo); bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex); bool tscQueryTags(SQueryInfo* pQueryInfo); @@ -151,9 +149,9 @@ bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t tableIndex); bool tscQueryBlockInfo(SQueryInfo* pQueryInfo); SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, - SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType); + SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType, int16_t colId); -int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql); +int32_t tscSetTableFullName(SName* pName, SStrToken* pzTableName, SSqlObj* pSql); void tscClearInterpInfo(SQueryInfo* pQueryInfo); bool tscIsInsertData(char* sqlstr); @@ -172,35 +170,49 @@ void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo); int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index); void tscFieldInfoClear(SFieldInfo* pFieldInfo); +void tscFieldInfoCopy(SFieldInfo* pFieldInfo, const SFieldInfo* pSrc, const SArray* pExprList); static FORCE_INLINE int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutput; } -int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2); +int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize); +void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid); +int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2); void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes); int32_t tscGetResRowLength(SArray* pExprList); -SExprInfo* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol); -SExprInfo* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscExprCreate(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, + int16_t size, int16_t resColId, int16_t interSize, int32_t colType); + +void tscExprAddParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes); + +SExprInfo* tscExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol); -SExprInfo* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type, +SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type, int16_t size); -size_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo); -void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid); -SExprInfo* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index); -int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy); -void tscSqlExprAssign(SExprInfo* dst, const SExprInfo* src); -void tscSqlExprInfoDestroy(SArray* pExprInfo); +size_t tscNumOfExprs(SQueryInfo* pQueryInfo); +SExprInfo *tscExprGet(SQueryInfo* pQueryInfo, int32_t index); +int32_t tscExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy); +int32_t tscExprCopyAll(SArray* dst, const SArray* src, bool deepcopy); +void tscExprAssign(SExprInfo* dst, const SExprInfo* src); +void tscExprDestroy(SArray* pExprInfo); + +int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num); + +void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta); SColumn* tscColumnClone(const SColumn* src); bool tscColumnExists(SArray* pColumnList, int32_t columnIndex, uint64_t uid); SColumn* tscColumnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema); void tscColumnListDestroy(SArray* pColList); +void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid); +void tscColumnListCopyAll(SArray* dst, const SArray* src); void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo); @@ -222,14 +234,14 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo); bool tscShouldBeFreed(SSqlObj* pSql); -STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t subClauseIndex, int32_t tableIndex); +STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t tableIndex); STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex); void tscInitQueryInfo(SQueryInfo* pQueryInfo); void tscClearSubqueryInfo(SSqlCmd* pCmd); int32_t tscAddQueryInfo(SSqlCmd *pCmd); -SQueryInfo *tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex); -SQueryInfo *tscGetQueryInfoS(SSqlCmd *pCmd, int32_t subClauseIndex); +SQueryInfo *tscGetQueryInfo(SSqlCmd* pCmd); +SQueryInfo *tscGetQueryInfoS(SSqlCmd *pCmd); void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo); @@ -243,12 +255,11 @@ SArray* tscVgroupTableInfoDup(SArray* pVgroupTables); void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index); void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo); -int tscGetSTableVgroupInfo(SSqlObj* pSql, int32_t clauseIndex); +int tscGetSTableVgroupInfo(SSqlObj* pSql, SQueryInfo* pQueryInfo); int tscGetTableMeta(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo); int tscGetTableMetaEx(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, bool createIfNotExists); void tscResetForNextRetrieve(SSqlRes* pRes); -void tscDoQuery(SSqlObj* pSql); void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo); void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo); @@ -279,7 +290,7 @@ void registerSqlObj(SSqlObj* pSql); SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t fp, void* param, int32_t cmd, SSqlObj* pPrevSql); void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex); -void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex); +void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex, SSqlCmd* pCmd); int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid); int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId); @@ -295,6 +306,11 @@ void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp); void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows); void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp); int tscSetMgmtEpSetFromCfg(const char *first, const char *second, SRpcCorEpSet *corEpSet); +int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, __async_cb_func_t fp); + +int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray); + +bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx); bool tscSetSqlOwner(SSqlObj* pSql); void tscClearSqlOwner(SSqlObj* pSql); @@ -307,12 +323,14 @@ STableMeta* createSuperTableMeta(STableMetaMsg* pChild); uint32_t tscGetTableMetaSize(STableMeta* pTableMeta); CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta); uint32_t tscGetTableMetaMaxSize(); -int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name); +int32_t tscCreateTableMetaFromSTableMeta(STableMeta* pChild, const char* name, void* buf); STableMeta* tscTableMetaDup(STableMeta* pTableMeta); +SVgroupsInfo* tscVgroupsInfoDup(SVgroupsInfo* pVgroupsInfo); + int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr); void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema); -void* createQueryInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage); +void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage); void* malloc_throw(size_t size); void* calloc_throw(size_t nmemb, size_t size); diff --git a/src/client/inc/tschemautil.h b/src/client/inc/tschemautil.h index a9dcd230a6db824f8cf40e05603c78bd95e0168b..0026a27e199289fa06dbcd8f10a2313bc61430ea 100644 --- a/src/client/inc/tschemautil.h +++ b/src/client/inc/tschemautil.h @@ -21,8 +21,8 @@ extern "C" { #endif #include "taosmsg.h" -#include "tstoken.h" #include "tsclient.h" +#include "ttoken.h" /** * get the number of tags of this table diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 554a062d96fd6cf2bb42d83dd21100c6b61e5043..b899725fca4d71c70c2a22dd0145eecb08af7cd1 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -42,12 +42,6 @@ extern "C" { struct SSqlInfo; struct SLocalMerger; -// data source from sql string or from file -enum { - DATA_FROM_SQL_STRING = 1, - DATA_FROM_DATA_FILE = 2, -}; - typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows); typedef struct STableComInfo { @@ -68,14 +62,16 @@ typedef struct CChildTableMeta { int32_t vgId; STableId id; uint8_t tableType; - char sTableName[TSDB_TABLE_FNAME_LEN]; //super table name, not full name + char sTableName[TSDB_TABLE_FNAME_LEN]; // TODO: refactor super table name, not full name + uint64_t suid; // super table id } CChildTableMeta; typedef struct STableMeta { int32_t vgId; STableId id; uint8_t tableType; - char sTableName[TSDB_TABLE_FNAME_LEN]; + char sTableName[TSDB_TABLE_FNAME_LEN]; // super table name + uint64_t suid; // super table id int16_t sversion; int16_t tversion; STableComInfo tableInfo; @@ -83,9 +79,10 @@ typedef struct STableMeta { } STableMeta; typedef struct STableMetaInfo { - STableMeta *pTableMeta; // table meta, cached in client side and acquired by name - SVgroupsInfo *vgroupList; - SArray *pVgroupTables; // SArray + STableMeta *pTableMeta; // table meta, cached in client side and acquired by name + uint32_t tableMetaSize; + SVgroupsInfo *vgroupList; + SArray *pVgroupTables; // SArray /* * 1. keep the vgroup index during the multi-vnode super table projection query @@ -134,8 +131,8 @@ typedef struct SJoinNode { } SJoinNode; typedef struct SJoinInfo { - bool hasJoin; - SJoinNode* joinTables[TSDB_MAX_JOIN_TABLE_NUM]; + bool hasJoin; + SJoinNode *joinTables[TSDB_MAX_JOIN_TABLE_NUM]; } SJoinInfo; typedef struct STagCond { @@ -154,13 +151,12 @@ typedef struct STagCond { typedef struct SParamInfo { int32_t idx; - char type; + uint8_t type; uint8_t timePrec; int16_t bytes; uint32_t offset; } SParamInfo; - typedef struct SBoundColumn { bool hasVal; // denote if current column has bound or not int32_t offset; // all column offset value @@ -203,10 +199,11 @@ typedef struct SQueryInfo { SInterval interval; // tumble time window SSessionWindow sessionWindow; // session time window - SSqlGroupbyExpr groupbyExpr; // groupby tags info + SGroupbyExpr groupbyExpr; // groupby tags info SArray * colList; // SArray SFieldInfo fieldsInfo; SArray * exprList; // SArray + SArray * exprList1; // final exprlist in case of arithmetic expression exists SLimitVal limit; SLimitVal slimit; STagCond tagCond; @@ -231,30 +228,50 @@ typedef struct SQueryInfo { int32_t bufLen; char* buf; SQInfo* pQInfo; // global merge operator - SArray* pDSOperator; // data source operator - SArray* pPhyOperator; // physical query execution plan SQueryAttr* pQueryAttr; // query object struct SQueryInfo *sibling; // sibling SArray *pUpstream; // SArray struct SQueryInfo *pDownstream; int32_t havingFieldNum; + bool stableQuery; + bool groupbyColumn; + bool simpleAgg; + bool arithmeticOnAgg; + bool projectionQuery; + bool hasFilter; + bool onlyTagQuery; } SQueryInfo; +typedef struct { + STableMeta *pTableMeta; + SVgroupsInfo *pVgroupInfo; +} STableMetaVgroupInfo; + +typedef struct SInsertStatementParam { + SName **pTableNameList; // all involved tableMeta list of current insert sql statement. + int32_t numOfTables; // number of tables in table name list + SHashObj *pTableBlockHashList; // data block for each table + SArray *pDataBlocks; // SArray. Merged submit block for each vgroup + int8_t schemaAttached; // denote if submit block is built with table schema or not + STagData tagData; // NOTE: pTagData->data is used as a variant length array + + char msg[512]; // error message + char *sql; // current sql statement position + uint32_t insertType; // insert data from [file|sql statement| bound statement] +} SInsertStatementParam; + +// TODO extract sql parser supporter typedef struct { int command; uint8_t msgType; + SInsertStatementParam insertParam; char reserve1[3]; // fix bus error on arm32 - bool autoCreated; // create table if it is not existed during retrieve table meta in mnode - union { int32_t count; - int32_t numOfTablesInSubmit; }; - uint32_t insertType; // TODO remove it char * curSql; // current sql, resume position of sql after parsing paused - int8_t parseFinished; char reserve2[3]; // fix bus error on arm32 int16_t numOfCols; @@ -263,25 +280,13 @@ typedef struct { char * payload; int32_t payloadLen; - SQueryInfo **pQueryInfo; - int32_t numOfClause; - int32_t clauseIndex; // index of multiple subclause query - SQueryInfo *active; // current active query info - - int32_t batchSize; // for parameter ('?') binding and batch processing + SHashObj *pTableMetaMap; // local buffer to keep the queried table meta, before validating the AST + SQueryInfo *pQueryInfo; + SQueryInfo *active; // current active query info + int32_t batchSize; // for parameter ('?') binding and batch processing int32_t numOfParams; - - int8_t dataSourceType; // load data from file or not - char reserve4[3]; // fix bus error on arm32 - int8_t submitSchema; // submit block is built with table schema - char reserve5[3]; // fix bus error on arm32 STagData tagData; // NOTE: pTagData->data is used as a variant length array - - SName **pTableNameList; // all involved tableMeta list of current insert sql statement. - int32_t numOfTables; - - SHashObj *pTableBlockHashList; // data block for each table - SArray *pDataBlocks; // SArray. Merged submit block for each vgroup + int32_t resColumnId; } SSqlCmd; typedef struct SResRec { @@ -373,7 +378,8 @@ typedef struct SSqlObj { tsem_t rspSem; SSqlCmd cmd; SSqlRes res; - + bool isBind; + SSubqueryState subState; struct SSqlObj **pSubs; @@ -441,7 +447,7 @@ int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo); void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo); void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock); -void handleDownstreamOperator(SSqlRes* pRes, SQueryInfo* pQueryInfo); +void handleDownstreamOperator(SSqlObj** pSqlList, int32_t numOfUpstream, SQueryInfo* px, SSqlRes* pOutput); void destroyTableNameList(SSqlCmd* pCmd); void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta); @@ -487,7 +493,7 @@ char *tscGetErrorMsgPayload(SSqlCmd *pCmd); int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql); int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* sql); -int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo); +int32_t tscValidateSqlInfo(SSqlObj *pSql, struct SSqlInfo *pInfo); extern int32_t sentinel; extern SHashObj *tscVgroupMap; @@ -503,7 +509,7 @@ extern int tscNumOfObj; // number of existed sqlObj in current process. extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo); void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables); -int16_t getNewResColId(SQueryInfo* pQueryInfo); +int16_t getNewResColId(SSqlCmd* pCmd); #ifdef __cplusplus } diff --git a/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h b/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h index b3060e2c820d7bbb405bf6e96a4bf8af8ed0ec55..d16b672f38fe1f7d9c36990f0eab28253f2d4d1b 100644 --- a/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h +++ b/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h @@ -100,7 +100,7 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp /* * Class: com_taosdata_jdbc_TSDBJNIConnector * Method: isUpdateQueryImp - * Signature: (J)J + * Signature: (JJ)I */ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_isUpdateQueryImp (JNIEnv *env, jobject jobj, jlong con, jlong tres); @@ -185,6 +185,52 @@ JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_unsubscribeImp JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTableSqlImp (JNIEnv *, jobject, jlong, jbyteArray); +/* + * Class: com_taosdata_jdbc_TSDBJNIConnector + * Method: prepareStmtImp + * Signature: ([BJ)I + */ +JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_prepareStmtImp + (JNIEnv *, jobject, jbyteArray, jlong); + +/* + * Class: com_taosdata_jdbc_TSDBJNIConnector + * Method: setBindTableNameImp + * Signature: (JLjava/lang/String;J)I + */ +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameImp + (JNIEnv *, jobject, jlong, jstring, jlong); + +/* + * Class: com_taosdata_jdbc_TSDBJNIConnector + * Method: bindColDataImp + * Signature: (J[B[B[BIIIIJ)J + */ +JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp +(JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jbyteArray, jint, jint, jint, jint, jlong); + +/* + * Class: com_taosdata_jdbc_TSDBJNIConnector + * Method: executeBatchImp + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(JNIEnv *env, jobject jobj, jlong stmt, jlong con); + +/* + * Class: com_taosdata_jdbc_TSDBJNIConnector + * Method: closeStmt + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con); + +/** + * Class: com_taosdata_jdbc_TSDBJNIConnector + * Method: setTableNameTagsImp + * Signature: (JLjava/lang/String;I[B[B[B[BJ)I + */ +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp + (JNIEnv *, jobject, jlong, jstring, jint, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jlong); + #ifdef __cplusplus } #endif diff --git a/src/client/src/TSDBJNIConnector.c b/src/client/src/TSDBJNIConnector.c index 7447e36ac9cf1074db0c62077be07b6a41a99256..324c436dce442f78b6daea314506c5c6b465f97f 100644 --- a/src/client/src/TSDBJNIConnector.c +++ b/src/client/src/TSDBJNIConnector.c @@ -687,4 +687,252 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrec } return taos_result_precision(result); -} \ No newline at end of file +} + +JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_prepareStmtImp(JNIEnv *env, jobject jobj, jbyteArray jsql, jlong con) { + TAOS *tscon = (TAOS *)con; + if (tscon == NULL) { + jniError("jobj:%p, connection already closed", jobj); + return JNI_CONNECTION_NULL; + } + + if (jsql == NULL) { + jniError("jobj:%p, conn:%p, empty sql string", jobj, tscon); + return JNI_SQL_NULL; + } + + jsize len = (*env)->GetArrayLength(env, jsql); + + char *str = (char *) calloc(1, sizeof(char) * (len + 1)); + if (str == NULL) { + jniError("jobj:%p, conn:%p, alloc memory failed", jobj, tscon); + return JNI_OUT_OF_MEMORY; + } + + (*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)str); + if ((*env)->ExceptionCheck(env)) { + // todo handle error + } + + TAOS_STMT* pStmt = taos_stmt_init(tscon); + int32_t code = taos_stmt_prepare(pStmt, str, len); + if (code != TSDB_CODE_SUCCESS) { + jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code)); + return JNI_TDENGINE_ERROR; + } + + free(str); + return (jlong) pStmt; +} + +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameImp(JNIEnv *env, jobject jobj, jlong stmt, jstring jname, jlong conn) { + TAOS *tsconn = (TAOS *)conn; + if (tsconn == NULL) { + jniError("jobj:%p, connection already closed", jobj); + return JNI_CONNECTION_NULL; + } + + TAOS_STMT* pStmt = (TAOS_STMT*) stmt; + if (pStmt == NULL) { + jniError("jobj:%p, conn:%p, invalid stmt handle", jobj, tsconn); + return JNI_SQL_NULL; + } + + const char *name = (*env)->GetStringUTFChars(env, jname, NULL); + + int32_t code = taos_stmt_set_tbname((void*)stmt, name); + if (code != TSDB_CODE_SUCCESS) { + (*env)->ReleaseStringUTFChars(env, jname, name); + + jniError("jobj:%p, conn:%p, code:%s", jobj, tsconn, tstrerror(code)); + return JNI_TDENGINE_ERROR; + } + + jniDebug("jobj:%p, conn:%p, set stmt bind table name:%s", jobj, tsconn, name); + (*env)->ReleaseStringUTFChars(env, jname, name); + return JNI_SUCCESS; +} + +JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(JNIEnv *env, jobject jobj, jlong stmt, + jbyteArray colDataList, jbyteArray lengthList, jbyteArray nullList, jint dataType, jint dataBytes, jint numOfRows, jint colIndex, jlong con) { + TAOS *tscon = (TAOS *)con; + if (tscon == NULL) { + jniError("jobj:%p, connection already closed", jobj); + return JNI_CONNECTION_NULL; + } + + TAOS_STMT *pStmt = (TAOS_STMT *)stmt; + if (pStmt == NULL) { + jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon); + return JNI_SQL_NULL; + } + + // todo refactor + jsize len = (*env)->GetArrayLength(env, colDataList); + char *colBuf = (char *)calloc(1, len); + (*env)->GetByteArrayRegion(env, colDataList, 0, len, (jbyte *)colBuf); + if ((*env)->ExceptionCheck(env)) { + // todo handle error + } + + len = (*env)->GetArrayLength(env, lengthList); + char *lengthArray = (char *)calloc(1, len); + (*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte *)lengthArray); + if ((*env)->ExceptionCheck(env)) { + } + + len = (*env)->GetArrayLength(env, nullList); + char *nullArray = (char *)calloc(1, len); + (*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte *)nullArray); + if ((*env)->ExceptionCheck(env)) { + } + + // bind multi-rows with only one invoke. + TAOS_MULTI_BIND* b = calloc(1, sizeof(TAOS_MULTI_BIND)); + + b->num = numOfRows; + b->buffer_type = dataType; // todo check data type + b->buffer_length = IS_VAR_DATA_TYPE(dataType)? dataBytes:tDataTypes[dataType].bytes; + b->is_null = nullArray; + b->buffer = colBuf; + b->length = (int32_t*)lengthArray; + + // set the length and is_null array + if (!IS_VAR_DATA_TYPE(dataType)) { + int32_t bytes = tDataTypes[dataType].bytes; + for (int32_t i = 0; i < numOfRows; ++i) { + b->length[i] = bytes; + } + } + + int32_t code = taos_stmt_bind_single_param_batch(pStmt, b, colIndex); + tfree(b->length); + tfree(b->buffer); + tfree(b->is_null); + tfree(b); + + if (code != TSDB_CODE_SUCCESS) { + jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code)); + return JNI_TDENGINE_ERROR; + } + + return JNI_SUCCESS; +} + +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(JNIEnv *env, jobject jobj, jlong stmt, jlong con) { + TAOS *tscon = (TAOS *)con; + if (tscon == NULL) { + jniError("jobj:%p, connection already closed", jobj); + return JNI_CONNECTION_NULL; + } + + TAOS_STMT *pStmt = (TAOS_STMT*) stmt; + if (pStmt == NULL) { + jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon); + return JNI_SQL_NULL; + } + + taos_stmt_add_batch(pStmt); + int32_t code = taos_stmt_execute(pStmt); + if (code != TSDB_CODE_SUCCESS) { + jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code)); + return JNI_TDENGINE_ERROR; + } + + jniDebug("jobj:%p, conn:%p, batch execute", jobj, tscon); + return JNI_SUCCESS; +} + +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con) { + TAOS *tscon = (TAOS *)con; + if (tscon == NULL) { + jniError("jobj:%p, connection already closed", jobj); + return JNI_CONNECTION_NULL; + } + + TAOS_STMT *pStmt = (TAOS_STMT*) stmt; + if (pStmt == NULL) { + jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon); + return JNI_SQL_NULL; + } + + int32_t code = taos_stmt_close(pStmt); + if (code != TSDB_CODE_SUCCESS) { + jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code)); + return JNI_TDENGINE_ERROR; + } + + jniDebug("jobj:%p, conn:%p, stmt closed", jobj, tscon); + return JNI_SUCCESS; +} + +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp(JNIEnv *env, jobject jobj, + jlong stmt, jstring tableName, jint numOfTags, jbyteArray tags, jbyteArray typeList, jbyteArray lengthList, jbyteArray nullList, jlong conn) { + TAOS *tsconn = (TAOS *)conn; + if (tsconn == NULL) { + jniError("jobj:%p, connection already closed", jobj); + return JNI_CONNECTION_NULL; + } + + TAOS_STMT* pStmt = (TAOS_STMT*) stmt; + if (pStmt == NULL) { + jniError("jobj:%p, conn:%p, invalid stmt handle", jobj, tsconn); + return JNI_SQL_NULL; + } + + jsize len = (*env)->GetArrayLength(env, tags); + char *tagsData = (char *)calloc(1, len); + (*env)->GetByteArrayRegion(env, tags, 0, len, (jbyte *)tagsData); + if ((*env)->ExceptionCheck(env)) { + // todo handle error + } + + len = (*env)->GetArrayLength(env, lengthList); + int64_t *lengthArray = (int64_t*) calloc(1, len); + (*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte*) lengthArray); + if ((*env)->ExceptionCheck(env)) { + } + + len = (*env)->GetArrayLength(env, typeList); + char *typeArray = (char*) calloc(1, len); + (*env)->GetByteArrayRegion(env, typeList, 0, len, (jbyte*) typeArray); + if ((*env)->ExceptionCheck(env)) { + } + + len = (*env)->GetArrayLength(env, nullList); + int32_t *nullArray = (int32_t*) calloc(1, len); + (*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte*) nullArray); + if ((*env)->ExceptionCheck(env)) { + } + + const char *name = (*env)->GetStringUTFChars(env, tableName, NULL); + char* curTags = tagsData; + + TAOS_BIND *tagsBind = calloc(numOfTags, sizeof(TAOS_BIND)); + for(int32_t i = 0; i < numOfTags; ++i) { + tagsBind[i].buffer_type = typeArray[i]; + tagsBind[i].buffer = curTags; + tagsBind[i].is_null = &nullArray[i]; + tagsBind[i].length = (uintptr_t*) &lengthArray[i]; + + curTags += lengthArray[i]; + } + + int32_t code = taos_stmt_set_tbname_tags((void*)stmt, name, tagsBind); + + int32_t nTags = (int32_t) numOfTags; + jniDebug("jobj:%p, conn:%p, set table name:%s, numOfTags:%d", jobj, tsconn, name, nTags); + + tfree(tagsData); + tfree(lengthArray); + tfree(typeArray); + tfree(nullArray); + (*env)->ReleaseStringUTFChars(env, tableName, name); + + if (code != TSDB_CODE_SUCCESS) { + jniError("jobj:%p, conn:%p, code:%s", jobj, tsconn, tstrerror(code)); + return JNI_TDENGINE_ERROR; + } + + return JNI_SUCCESS; +} diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 09b31e4b19c095cb712a4c0f54bb42db34b9949c..47798f4e339b6f84231ba4f83ef7dfe702be1677 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -59,6 +59,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr); pCmd->curSql = pSql->sqlstr; + pCmd->resColumnId = TSDB_RES_COL_ID; int32_t code = tsParseSql(pSql, true); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) return; @@ -69,7 +70,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para return; } - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); executeQuery(pSql, pQueryInfo); } @@ -127,7 +128,8 @@ static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) { * all available virtual node has been checked already, now we need to check * for the next subclause queries */ - if (pCmd->clauseIndex < pCmd->numOfClause - 1) { + if (pCmd->active->sibling != NULL) { + pCmd->active = pCmd->active->sibling; tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode); return; } @@ -220,6 +222,17 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) { tscResetForNextRetrieve(pRes); // handle the sub queries of join query + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); + if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { + SSchedMsg schedMsg = {0}; + schedMsg.fp = doRetrieveSubqueryData; + schedMsg.ahandle = (void *)pSql; + schedMsg.thandle = (void *)1; + schedMsg.msg = 0; + taosScheduleTask(tscQhandle, &schedMsg); + return; + } + if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) { tscFetchDatablockForSubquery(pSql); } else if (pRes->completed) { @@ -231,7 +244,8 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) { * all available virtual nodes in current clause has been checked already, now try the * next one in the following union subclause */ - if (pCmd->clauseIndex < pCmd->numOfClause - 1) { + if (pCmd->active->sibling != NULL) { + pCmd->active = pCmd->active->sibling; // todo refactor tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode); return; } @@ -255,7 +269,7 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) { pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; } - SQueryInfo* pQueryInfo1 = tscGetActiveQueryInfo(&pSql->cmd); + SQueryInfo* pQueryInfo1 = tscGetQueryInfo(&pSql->cmd); tscBuildAndSendRequest(pSql, pQueryInfo1); } } @@ -317,26 +331,38 @@ static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableM // update the pExpr info, colList info, number of table columns // TODO Re-parse this sql and issue the corresponding subquery as an alternative for this case. if (pSql->retryReason == TSDB_CODE_TDB_INVALID_TABLE_ID) { - int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + int32_t numOfExprs = (int32_t) tscNumOfExprs(pQueryInfo); int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); int32_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta); SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); + SSchema *pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); + for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr *pExpr = &(tscSqlExprGet(pQueryInfo, i)->base); + SSqlExpr *pExpr = &(tscExprGet(pQueryInfo, i)->base); + + // update the table uid pExpr->uid = pTableMetaInfo->pTableMeta->id.uid; if (pExpr->colInfo.colIndex >= 0) { int32_t index = pExpr->colInfo.colIndex; if ((TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && index >= numOfCols) || - (TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < numOfCols || index >= (numOfCols + numOfTags)))) { + (TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < 0 || index >= numOfTags))) { return pSql->retryReason; } - if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) && - strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) { - return pSql->retryReason; + if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { + if ((pTagSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) && + strcasecmp(pExpr->colInfo.name, pTagSchema[pExpr->colInfo.colIndex].name) != 0) { + return pSql->retryReason; + } + } else if (TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag)) { + if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) && + strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) { + return pSql->retryReason; + } + } else { // do nothing for udc } } } @@ -374,12 +400,12 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { tscDebug("0x%"PRIx64" get %s successfully", pSql->self, msg); if (pSql->pStream == NULL) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); // check if it is a sub-query of super table query first, if true, enter another routine - if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) { - tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send the corresponding query", pSql->self); - + if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY | TSDB_QUERY_TYPE_SUBQUERY | + TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) { + tscDebug("0x%" PRIx64 " update cached table-meta, continue to process sql and send the corresponding query", pSql->self); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); code = tscGetTableMeta(pSql, pTableMetaInfo); @@ -401,42 +427,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { taosReleaseRef(tscObjRef, pSql->self); return; } else { // continue to process normal async query - if (pCmd->parseFinished) { - tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send corresponding query", pSql->self); - - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - code = tscGetTableMeta(pSql, pTableMetaInfo); - - assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS || code == TSDB_CODE_SUCCESS); - if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { - taosReleaseRef(tscObjRef, pSql->self); - return; - } - - assert(pCmd->command != TSDB_SQL_INSERT); - - if (pCmd->command == TSDB_SQL_SELECT) { - tscDebug("0x%"PRIx64" redo parse sql string and proceed", pSql->self); - pCmd->parseFinished = false; - tscResetSqlCmd(pCmd, true); - - code = tsParseSql(pSql, true); - if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { - taosReleaseRef(tscObjRef, pSql->self); - return; - } else if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - tscBuildAndSendRequest(pSql, NULL); - } else { // in all other cases, simple retry - tscBuildAndSendRequest(pSql, NULL); - } - - taosReleaseRef(tscObjRef, pSql->self); - return; - } else { - tscDebug("0x%"PRIx64" continue parse sql after get table meta", pSql->self); + if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) { + tscDebug("0x%" PRIx64 " continue parse sql after get table-meta", pSql->self); code = tsParseSql(pSql, false); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { @@ -446,8 +438,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { goto _error; } - if (pCmd->insertType == TSDB_QUERY_TYPE_STMT_INSERT) { - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_STMT_INSERT)) { + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); code = tscGetTableMeta(pSql, pTableMetaInfo); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { taosReleaseRef(tscObjRef, pSql->self); @@ -457,59 +449,52 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { } (*pSql->fp)(pSql->param, pSql, code); - } else if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) { - if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) { + } else { + if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) { tscImportDataFromFile(pSql); } else { tscHandleMultivnodeInsert(pSql); } + } + } else { + if (pSql->retryReason != TSDB_CODE_SUCCESS) { + tscDebug("0x%" PRIx64 " update cached table-meta, re-validate sql statement and send query again", + pSql->self); + tscResetSqlCmd(pCmd, false); + pSql->retryReason = TSDB_CODE_SUCCESS; } else { - SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pCmd, pCmd->clauseIndex); - executeQuery(pSql, pQueryInfo1); + tscDebug("0x%" PRIx64 " cached table-meta, continue validate sql statement and send query", pSql->self); } - taosReleaseRef(tscObjRef, pSql->self); - return; - } - } + code = tsParseSql(pSql, true); + if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + taosReleaseRef(tscObjRef, pSql->self); + return; + } else if (code != TSDB_CODE_SUCCESS) { + goto _error; + } - } else { // stream computing - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pCmd); + executeQuery(pSql, pQueryInfo1); + } - code = tscGetTableMeta(pSql, pTableMetaInfo); - if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { taosReleaseRef(tscObjRef, pSql->self); return; - } else if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - code = tscGetSTableVgroupInfo(pSql, pCmd->clauseIndex); - if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { - taosReleaseRef(tscObjRef, pSql->self); - return; - } else if (code != TSDB_CODE_SUCCESS) { - goto _error; - } } + } else { // stream computing + tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pCmd->command); - tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pSql->cmd.command); - if (!pSql->cmd.parseFinished) { + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); + if (tscNumOfExprs(pQueryInfo) == 0) { tsParseSql(pSql, false); } (*pSql->fp)(pSql->param, pSql, code); - taosReleaseRef(tscObjRef, pSql->self); - return; } -// tscDoQuery(pSql); - taosReleaseRef(tscObjRef, pSql->self); - return; _error: diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index 6b55780af93554446f7f0599fe267e42e258ae81..abac2407fb7019dd298468a20838fbad680ea7ec 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -53,7 +53,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { SSqlRes *pRes = &pSql->res; // one column for each row - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -154,14 +154,14 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, pSql->cmd.numOfCols = numOfCols; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); pQueryInfo->order.order = TSDB_ORDER_ASC; 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 = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + 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); @@ -171,7 +171,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Type", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), + 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; @@ -181,7 +181,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Length", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), + 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); @@ -191,7 +191,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Note", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), + 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; @@ -199,7 +199,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, } static int32_t tscProcessDescribeTable(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL); @@ -390,7 +390,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const SColumnIndex index = {0}; pSql->cmd.numOfCols = 2; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); pQueryInfo->order.order = TSDB_ORDER_ASC; TAOS_FIELD f; @@ -405,7 +405,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscSqlExprAppend(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, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); rowLen += f.bytes; @@ -418,7 +418,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false); rowLen += ddlLen + VARSTR_HEADER_SIZE; @@ -428,7 +428,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) { SSqlRes *pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); int32_t numOfRows = 1; if (strlen(ddl) == 0) { @@ -445,7 +445,7 @@ static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const c return 0; } static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char *str, const char *result) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result); tscFieldInfoUpdateOffset(pQueryInfo); @@ -532,7 +532,7 @@ static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) { } buf[0] = 0; - STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->pTableMeta; + STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0)->pTableMeta; if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE || pMeta->tableType == TSDB_STREAM_TABLE) { free(buf); @@ -553,7 +553,7 @@ static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) { return TSDB_CODE_SUCCESS; } static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, char *ddl) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -607,7 +607,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch } static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -634,7 +634,7 @@ static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, } static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, char *ddl) { char *result = ddl; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -675,7 +675,7 @@ static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, } static int32_t tscProcessShowCreateTable(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); assert(pTableMetaInfo->pTableMeta != NULL); @@ -704,7 +704,7 @@ static int32_t tscProcessShowCreateTable(SSqlObj *pSql) { } static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -713,13 +713,12 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SCreateBuilder *param = (SCreateBuilder *)malloc(sizeof(SCreateBuilder)); + SCreateBuilder *param = (SCreateBuilder *)calloc(1, sizeof(SCreateBuilder)); if (param == NULL) { free(pInterSql); return TSDB_CODE_TSC_OUT_OF_MEMORY; } - - strncpy(param->buf, tNameGetTableName(&pTableMetaInfo->name), TSDB_TABLE_NAME_LEN); + tNameGetDbName(&pTableMetaInfo->name, param->buf); param->pParentSql = pSql; param->pInterSql = pInterSql; @@ -731,7 +730,7 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { return TSDB_CODE_TSC_ACTION_IN_PROGRESS; } static int32_t tscProcessCurrentUser(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resBytes = TSDB_USER_LEN + TSDB_DATA_TYPE_BINARY; @@ -758,7 +757,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) { extractDBName(pSql->pTscObj->db, db); pthread_mutex_unlock(&pSql->pTscObj->mutex); - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resType = TSDB_DATA_TYPE_BINARY; @@ -785,7 +784,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) { static int32_t tscProcessServerVer(SSqlObj *pSql) { const char* v = pSql->pTscObj->sversion; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resType = TSDB_DATA_TYPE_BINARY; @@ -808,7 +807,7 @@ static int32_t tscProcessServerVer(SSqlObj *pSql) { } static int32_t tscProcessClientVer(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resType = TSDB_DATA_TYPE_BINARY; @@ -860,7 +859,7 @@ static int32_t tscProcessServStatus(SSqlObj *pSql) { return pSql->res.code; } - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); int32_t val = 1; @@ -874,7 +873,7 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa pCmd->numOfCols = 1; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); pQueryInfo->order.order = TSDB_ORDER_ASC; tscFieldInfoClear(&pQueryInfo->fieldsInfo); @@ -929,7 +928,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) { } else if (pCmd->command == TSDB_SQL_SERV_STATUS) { pRes->code = tscProcessServStatus(pSql); } else { - pRes->code = TSDB_CODE_TSC_INVALID_SQL; + pRes->code = TSDB_CODE_TSC_INVALID_OPERATION; tscError("0x%"PRIx64" not support command:%d", pSql->self, pCmd->command); } diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c index e4a3ace6b5af128971a5bed21562082602754d97..77a4c7fb464652d8b92b08e4877b6601afb8b529 100644 --- a/src/client/src/tscLocalMerge.c +++ b/src/client/src/tscLocalMerge.c @@ -19,8 +19,6 @@ #include "texpr.h" #include "tlosertree.h" #include "tscLog.h" -#include "tscUtil.h" -#include "tschemautil.h" #include "tsclient.h" #include "qUtil.h" @@ -59,77 +57,25 @@ int32_t treeComparator(const void *pLeft, const void *pRight, void *param) { } } -// todo merge with vnode side function -void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema) { - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - - for (int32_t i = 0; i < size; ++i) { - SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); - - pCtx[i].order = pQueryInfo->order.order; - pCtx[i].functionId = pExpr->base.functionId; - - pCtx[i].order = pQueryInfo->order.order; - pCtx[i].functionId = pExpr->base.functionId; - - // input data format comes from pModel - pCtx[i].inputType = pSchema[i].type; - pCtx[i].inputBytes = pSchema[i].bytes; - - pCtx[i].outputBytes = pExpr->base.resBytes; - pCtx[i].outputType = pExpr->base.resType; - - // input buffer hold only one point data - pCtx[i].size = 1; - pCtx[i].hasNull = true; - pCtx[i].currentStage = MERGE_STAGE; - - // for top/bottom function, the output of timestamp is the first column - int32_t functionId = pExpr->base.functionId; - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) { - pCtx[i].ptsOutputBuf = pCtx[0].pOutput; - pCtx[i].param[2].i64 = pQueryInfo->order.order; - pCtx[i].param[2].nType = TSDB_DATA_TYPE_BIGINT; - pCtx[i].param[1].i64 = pQueryInfo->order.orderColId; - pCtx[i].param[0].i64 = pExpr->base.param[0].i64; // top/bot parameter - } else if (functionId == TSDB_FUNC_APERCT) { - pCtx[i].param[0].i64 = pExpr->base.param[0].i64; - pCtx[i].param[0].nType = pExpr->base.param[0].nType; - } else if (functionId == TSDB_FUNC_BLKINFO) { - pCtx[i].param[0].i64 = pExpr->base.param[0].i64; - pCtx[i].param[0].nType = pExpr->base.param[0].nType; - pCtx[i].numOfParams = 1; - } - - pCtx[i].interBufBytes = pExpr->base.interBytes; - pCtx[i].stableQuery = true; - } -} - -void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc, - SColumnModel *finalmodel, SColumnModel *pFFModel, SSqlObj *pSql) { - SSqlCmd* pCmd = &pSql->cmd; - SSqlRes* pRes = &pSql->res; - +int32_t tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc, + SQueryInfo* pQueryInfo, SLocalMerger **pMerger, int64_t id) { if (pMemBuffer == NULL) { - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); - tscError("pMemBuffer:%p is NULL", pMemBuffer); - pRes->code = TSDB_CODE_TSC_APP_ERROR; - return; + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer); + tscError("0x%"PRIx64" %p pMemBuffer is NULL", id, pMemBuffer); + return TSDB_CODE_TSC_APP_ERROR; } if (pDesc->pColumnModel == NULL) { - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); - tscError("0x%"PRIx64" no local buffer or intermediate result format model", pSql->self); - pRes->code = TSDB_CODE_TSC_APP_ERROR; - return; + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer); + tscError("0x%"PRIx64" no local buffer or intermediate result format model", id); + return TSDB_CODE_TSC_APP_ERROR; } int32_t numOfFlush = 0; for (int32_t i = 0; i < numOfBuffer; ++i) { int32_t len = pMemBuffer[i]->fileMeta.flushoutData.nLength; if (len == 0) { - tscDebug("0x%"PRIx64" no data retrieved from orderOfVnode:%d", pSql->self, i + 1); + tscDebug("0x%"PRIx64" no data retrieved from orderOfVnode:%d", id, i + 1); continue; } @@ -137,41 +83,36 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde } if (numOfFlush == 0 || numOfBuffer == 0) { - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); - pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty - tscDebug("0x%"PRIx64" retrieved no data", pSql->self); - return; + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer); + tscDebug("0x%"PRIx64" no data to retrieve", id); + return TSDB_CODE_SUCCESS; } if (pDesc->pColumnModel->capacity >= pMemBuffer[0]->pageSize) { - tscError("0x%"PRIx64" Invalid value of buffer capacity %d and page size %d ", pSql->self, pDesc->pColumnModel->capacity, + tscError("0x%"PRIx64" Invalid value of buffer capacity %d and page size %d ", id, pDesc->pColumnModel->capacity, pMemBuffer[0]->pageSize); - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); - pRes->code = TSDB_CODE_TSC_APP_ERROR; - return; + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer); + return TSDB_CODE_TSC_APP_ERROR; } - size_t size = sizeof(SLocalMerger) + POINTER_BYTES * numOfFlush; - - SLocalMerger *pMerger = (SLocalMerger *) calloc(1, size); - if (pMerger == NULL) { - tscError("0x%"PRIx64" failed to create local merge structure, out of memory", pSql->self); + *pMerger = (SLocalMerger *) calloc(1, sizeof(SLocalMerger)); + if ((*pMerger) == NULL) { + tscError("0x%"PRIx64" failed to create local merge structure, out of memory", id); - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); - pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - return; + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer); + return TSDB_CODE_TSC_OUT_OF_MEMORY; } - pMerger->pExtMemBuffer = pMemBuffer; - pMerger->pLocalDataSrc = (SLocalDataSource **)&pMerger[1]; - assert(pMerger->pLocalDataSrc != NULL); + (*pMerger)->pExtMemBuffer = pMemBuffer; + (*pMerger)->pLocalDataSrc = calloc(numOfFlush, POINTER_BYTES); + assert((*pMerger)->pLocalDataSrc != NULL); - pMerger->numOfBuffer = numOfFlush; - pMerger->numOfVnode = numOfBuffer; + (*pMerger)->numOfBuffer = numOfFlush; + (*pMerger)->numOfVnode = numOfBuffer; - pMerger->pDesc = pDesc; - tscDebug("0x%"PRIx64" the number of merged leaves is: %d", pSql->self, pMerger->numOfBuffer); + (*pMerger)->pDesc = pDesc; + tscDebug("0x%"PRIx64" the number of merged leaves is: %d", id, (*pMerger)->numOfBuffer); int32_t idx = 0; for (int32_t i = 0; i < numOfBuffer; ++i) { @@ -180,13 +121,12 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde for (int32_t j = 0; j < numOfFlushoutInFile; ++j) { SLocalDataSource *ds = (SLocalDataSource *)malloc(sizeof(SLocalDataSource) + pMemBuffer[0]->pageSize); if (ds == NULL) { - tscError("0x%"PRIx64" failed to create merge structure", pSql->self); - pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; + tscError("0x%"PRIx64" failed to create merge structure", id); tfree(pMerger); - return; + return TSDB_CODE_TSC_OUT_OF_MEMORY; } - pMerger->pLocalDataSrc[idx] = ds; + (*pMerger)->pLocalDataSrc[idx] = ds; ds->pMemBuffer = pMemBuffer[i]; ds->flushoutIdx = j; @@ -194,12 +134,12 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde ds->pageId = 0; ds->rowIdx = 0; - tscDebug("0x%"PRIx64" load data from disk into memory, orderOfVnode:%d, total:%d", pSql->self, i + 1, idx + 1); + tscDebug("0x%"PRIx64" load data from disk into memory, orderOfVnode:%d, total:%d", id, i + 1, idx + 1); tExtMemBufferLoadData(pMemBuffer[i], &(ds->filePage), j, 0); #ifdef _DEBUG_VIEW printf("load data page into mem for build loser tree: %" PRIu64 " rows\n", ds->filePage.num); SSrcColumnInfo colInfo[256] = {0}; - SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd); tscGetSrcColumnInfo(colInfo, pQueryInfo); @@ -208,7 +148,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde #endif if (ds->filePage.num == 0) { // no data in this flush, the index does not increase - tscDebug("0x%"PRIx64" flush data is empty, ignore %d flush record", pSql->self, idx); + tscDebug("0x%"PRIx64" flush data is empty, ignore %d flush record", id, idx); tfree(ds); continue; } @@ -219,115 +159,54 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde // no data actually, no need to merge result. if (idx == 0) { - tfree(pMerger); - return; + tscDebug("0x%"PRIx64" retrieved no data", id); + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer); + return TSDB_CODE_SUCCESS; } - pMerger->numOfBuffer = idx; + (*pMerger)->numOfBuffer = idx; SCompareParam *param = malloc(sizeof(SCompareParam)); if (param == NULL) { - tfree(pMerger); - return; + tfree((*pMerger)); + return TSDB_CODE_TSC_OUT_OF_MEMORY; } - param->pLocalData = pMerger->pLocalDataSrc; - param->pDesc = pMerger->pDesc; - param->num = pMerger->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + param->pLocalData = (*pMerger)->pLocalDataSrc; + param->pDesc = (*pMerger)->pDesc; + param->num = (*pMerger)->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage; param->groupOrderType = pQueryInfo->groupbyExpr.orderType; - pMerger->orderPrjOnSTable = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0); - pRes->code = tLoserTreeCreate(&pMerger->pLoserTree, pMerger->numOfBuffer, param, treeComparator); - if (pMerger->pLoserTree == NULL || pRes->code != 0) { + int32_t code = tLoserTreeCreate(&(*pMerger)->pLoserTree, (*pMerger)->numOfBuffer, param, treeComparator); + if ((*pMerger)->pLoserTree == NULL || code != TSDB_CODE_SUCCESS) { tfree(param); - tfree(pMerger); - return; - } - - // the input data format follows the old format, but output in a new format. - // so, all the input must be parsed as old format - pMerger->pCtx = (SQLFunctionCtx *)calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SQLFunctionCtx)); - pMerger->rowSize = pMemBuffer[0]->nElemSize; - - tscFieldInfoUpdateOffset(pQueryInfo); - - if (pMerger->rowSize > pMemBuffer[0]->pageSize) { - assert(false); // todo fixed row size is larger than the minimum page size; + tfree((*pMerger)); + return code; } - // used to keep the latest input row - pMerger->pTempBuffer = (tFilePage *)calloc(1, pMerger->rowSize + sizeof(tFilePage)); + (*pMerger)->rowSize = pMemBuffer[0]->nElemSize; - pMerger->nResultBufSize = pMemBuffer[0]->pageSize * 16; - pMerger->pResultBuf = (tFilePage *)calloc(1, pMerger->nResultBufSize + sizeof(tFilePage)); + // todo fixed row size is larger than the minimum page size; + assert((*pMerger)->rowSize <= pMemBuffer[0]->pageSize); - pMerger->resColModel = finalmodel; - pMerger->resColModel->capacity = pMerger->nResultBufSize; - pMerger->finalModel = pFFModel; - - if (finalmodel->rowSize > 0) { - pMerger->resColModel->capacity /= finalmodel->rowSize; - } - - assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pMerger->rowSize); - - if (pMerger->pTempBuffer == NULL || pMerger->pLoserTree == NULL) { - tfree(pMerger->pTempBuffer); - tfree(pMerger->pLoserTree); + if ((*pMerger)->pLoserTree == NULL) { + tfree((*pMerger)->pLoserTree); tfree(param); - tfree(pMerger); - pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - return; - } - - pMerger->pTempBuffer->num = 0; - tscCreateResPointerInfo(pRes, pQueryInfo); - - SSchema* pschema = calloc(pDesc->pColumnModel->numOfCols, sizeof(SSchema)); - for(int32_t i = 0; i < pDesc->pColumnModel->numOfCols; ++i) { - pschema[i] = pDesc->pColumnModel->pFields[i].field; - } - - tsCreateSQLFunctionCtx(pQueryInfo, pMerger->pCtx, pschema); -// setCtxInputOutputBuffer(pQueryInfo, pMerger->pCtx, pMerger, pDesc); - - tfree(pschema); - - int32_t maxBufSize = 0; - for (int32_t k = 0; k < tscSqlExprNumOfExprs(pQueryInfo); ++k) { - SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, k); - if (maxBufSize < pExpr->base.resBytes && pExpr->base.functionId == TSDB_FUNC_TAG) { - maxBufSize = pExpr->base.resBytes; - } + tfree((*pMerger)); + return TSDB_CODE_TSC_OUT_OF_MEMORY; } - // we change the capacity of schema to denote that there is only one row in temp buffer - pMerger->pDesc->pColumnModel->capacity = 1; - // restore the limitation value at the last stage if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { pQueryInfo->limit.limit = pQueryInfo->clauseLimit; pQueryInfo->limit.offset = pQueryInfo->prjOffset; } - pRes->pLocalMerger = pMerger; - pRes->numOfGroups = 0; + // we change the capacity of schema to denote that there is only one row in temp buffer + (*pMerger)->pDesc->pColumnModel->capacity = 1; -// STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); -// STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - -// TSKEY stime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.skey : pQueryInfo->window.ekey; -// int64_t revisedSTime = taosTimeTruncate(stime, &pQueryInfo->interval, tinfo.precision); - -// if (pQueryInfo->fillType != TSDB_FILL_NONE) { -// SFillColInfo* pFillCol = createFillColInfo(pQueryInfo); -// pMerger->pFillInfo = -// taosCreateFillInfo(pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols, 4096, -// (int32_t)pQueryInfo->fieldsInfo.numOfOutput, pQueryInfo->interval.sliding, -// pQueryInfo->interval.slidingUnit, tinfo.precision, pQueryInfo->fillType, pFillCol, pSql); -// } + return TSDB_CODE_SUCCESS; } static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, @@ -418,44 +297,32 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa return 0; } -void tscDestroyLocalMerger(SSqlObj *pSql) { - if (pSql == NULL) { +void tscDestroyLocalMerger(SLocalMerger* pLocalMerger) { + if (pLocalMerger == NULL) { return; } - SSqlRes *pRes = &(pSql->res); - if (pRes->pLocalMerger == NULL) { - return; + for (int32_t i = 0; i < pLocalMerger->numOfBuffer; ++i) { + tfree(pLocalMerger->pLocalDataSrc[i]); } - // there is no more result, so we release all allocated resource - SLocalMerger *pLocalMerge = (SLocalMerger *)atomic_exchange_ptr(&pRes->pLocalMerger, NULL); - tfree(pLocalMerge->pResultBuf); - tfree(pLocalMerge->pCtx); + pLocalMerger->numOfBuffer = 0; + tscLocalReducerEnvDestroy(pLocalMerger->pExtMemBuffer, pLocalMerger->pDesc, pLocalMerger->numOfVnode); - if (pLocalMerge->pLoserTree) { - tfree(pLocalMerge->pLoserTree->param); - tfree(pLocalMerge->pLoserTree); - } + pLocalMerger->numOfCompleted = 0; - tscLocalReducerEnvDestroy(pLocalMerge->pExtMemBuffer, pLocalMerge->pDesc, pLocalMerge->resColModel, - pLocalMerge->finalModel, pLocalMerge->numOfVnode); - for (int32_t i = 0; i < pLocalMerge->numOfBuffer; ++i) { - tfree(pLocalMerge->pLocalDataSrc[i]); + if (pLocalMerger->pLoserTree) { + tfree(pLocalMerger->pLoserTree->param); + tfree(pLocalMerger->pLoserTree); } - pLocalMerge->numOfBuffer = 0; - pLocalMerge->numOfCompleted = 0; - tfree(pLocalMerge->pTempBuffer); - - free(pLocalMerge); - - tscDebug("0x%"PRIx64" free local reducer finished", pSql->self); + tfree(pLocalMerger->buf); + tfree(pLocalMerger->pLocalDataSrc); + free(pLocalMerger); } -static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, SColumnModel *pModel) { - int32_t numOfGroupByCols = 0; - SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); +static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SQueryInfo* pQueryInfo, SColumnModel *pModel) { + int32_t numOfGroupByCols = 0; if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { numOfGroupByCols = pQueryInfo->groupbyExpr.numOfGroupCols; @@ -474,13 +341,13 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm if (numOfGroupByCols > 0) { if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { - int32_t numOfInternalOutput = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + int32_t numOfInternalOutput = (int32_t) tscNumOfExprs(pQueryInfo); // the last "pQueryInfo->groupbyExpr.numOfGroupCols" columns are order-by columns for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i); for(int32_t j = 0; j < numOfInternalOutput; ++j) { - SExprInfo* pExprInfo = tscSqlExprGet(pQueryInfo, j); + SExprInfo* pExprInfo = tscExprGet(pQueryInfo, j); int32_t functionId = pExprInfo->base.functionId; if (pColIndex->colId == pExprInfo->base.colInfo.colId && (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG)) { @@ -502,9 +369,9 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm if (pQueryInfo->interval.interval != 0) { orderColIndexList[0] = PRIMARYKEY_TIMESTAMP_COL_INDEX; } else { - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo *pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { orderColIndexList[0] = i; } @@ -525,37 +392,30 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm } } -int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc, - SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSizes) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SSchema * pSchema = NULL; +int32_t tscLocalReducerEnvCreate(SQueryInfo *pQueryInfo, tExtMemBuffer ***pMemBuffer, int32_t numOfSub, + tOrderDescriptor **pOrderDesc, uint32_t nBufferSizes, int64_t id) { + SSchema *pSchema = NULL; SColumnModel *pModel = NULL; - *pFinalModel = NULL; - SQueryInfo * pQueryInfo = tscGetActiveQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - (*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pSql->subState.numOfSub); + (*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * numOfSub); if (*pMemBuffer == NULL) { - tscError("0x%"PRIx64" failed to allocate memory", pSql->self); - pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - return pRes->code; + tscError("0x%"PRIx64" failed to allocate memory", id); + return TSDB_CODE_TSC_OUT_OF_MEMORY; } - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); pSchema = (SSchema *)calloc(1, sizeof(SSchema) * size); if (pSchema == NULL) { - tscError("0x%"PRIx64" failed to allocate memory", pSql->self); - pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - return pRes->code; + tscError("0x%"PRIx64" failed to allocate memory", id); + return TSDB_CODE_TSC_OUT_OF_MEMORY; } int32_t rlen = 0; for (int32_t i = 0; i < size; ++i) { - SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo *pExpr = tscExprGet(pQueryInfo, i); pSchema[i].bytes = pExpr->base.resBytes; pSchema[i].type = (int8_t)pExpr->base.resType; @@ -570,6 +430,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr } pModel = createColumnModel(pSchema, (int32_t)size, capacity); + tfree(pSchema); int32_t pg = DEFAULT_PAGE_SIZE; int32_t overhead = sizeof(tFilePage); @@ -577,95 +438,26 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr pg *= 2; } - size_t numOfSubs = pSql->subState.numOfSub; - assert(numOfSubs <= pTableMetaInfo->vgroupList->numOfVgroups); - for (int32_t i = 0; i < numOfSubs; ++i) { + assert(numOfSub <= pTableMetaInfo->vgroupList->numOfVgroups); + for (int32_t i = 0; i < numOfSub; ++i) { (*pMemBuffer)[i] = createExtMemBuffer(nBufferSizes, rlen, pg, pModel); (*pMemBuffer)[i]->flushModel = MULTIPLE_APPEND_MODEL; } - if (createOrderDescriptor(pOrderDesc, pCmd, pModel) != TSDB_CODE_SUCCESS) { - pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - tfree(pSchema); - return pRes->code; - } - - // final result depends on the fields number - memset(pSchema, 0, sizeof(SSchema) * size); - - for (int32_t i = 0; i < size; ++i) { - SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); - - SSchema p1 = {0}; - if (pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { - p1 = *tGetTbnameColumnSchema(); - } else if (TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag)) { - p1.bytes = pExpr->base.resBytes; - p1.type = (uint8_t) pExpr->base.resType; - tstrncpy(p1.name, pExpr->base.aliasName, tListLen(p1.name)); - } else { - p1 = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex); - } - - int32_t inter = 0; - int16_t type = -1; - int16_t bytes = 0; - - // the final result size and type in the same as query on single table. - // so here, set the flag to be false; - int32_t functionId = pExpr->base.functionId; - if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) { - type = pModel->pFields[i].field.type; - bytes = pModel->pFields[i].field.bytes; - } else { - if (functionId == TSDB_FUNC_FIRST_DST) { - functionId = TSDB_FUNC_FIRST; - } else if (functionId == TSDB_FUNC_LAST_DST) { - functionId = TSDB_FUNC_LAST; - } else if (functionId == TSDB_FUNC_STDDEV_DST) { - functionId = TSDB_FUNC_STDDEV; - } - - int32_t ret = getResultDataInfo(p1.type, p1.bytes, functionId, 0, &type, &bytes, &inter, 0, false); - assert(ret == TSDB_CODE_SUCCESS); - } - - pSchema[i].type = (uint8_t)type; - pSchema[i].bytes = bytes; - strcpy(pSchema[i].name, pModel->pFields[i].field.name); - } - - *pFinalModel = createColumnModel(pSchema, (int32_t)size, capacity); - - memset(pSchema, 0, sizeof(SSchema) * size); - size = tscNumOfFields(pQueryInfo); - - for(int32_t i = 0; i < size; ++i) { - SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i); - pSchema[i].bytes = pField->field.bytes; - pSchema[i].type = pField->field.type; - tstrncpy(pSchema[i].name, pField->field.name, tListLen(pSchema[i].name)); + if (createOrderDescriptor(pOrderDesc, pQueryInfo, pModel) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; } - *pFFModel = createColumnModel(pSchema, (int32_t) size, capacity); - - tfree(pSchema); return TSDB_CODE_SUCCESS; } /** * @param pMemBuffer * @param pDesc - * @param pFinalModel * @param numOfVnodes */ -void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel *pFFModel, - int32_t numOfVnodes) { - destroyColumnModel(pFinalModel); - destroyColumnModel(pFFModel); - +void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, int32_t numOfVnodes) { tOrderDescDestroy(pDesc); - for (int32_t i = 0; i < numOfVnodes; ++i) { pMemBuffer[i] = destoryExtMemBuffer(pMemBuffer[i]); } @@ -877,10 +669,12 @@ static bool isAllSourcesCompleted(SLocalMerger *pLocalMerge) { return (pLocalMerge->numOfBuffer == pLocalMerge->numOfCompleted); } -void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen) { - SSqlRes *pRes = &pObj->res; +void tscInitResObjForLocalQuery(SSqlObj *pSql, int32_t numOfRes, int32_t rowLen) { + SSqlRes *pRes = &pSql->res; if (pRes->pLocalMerger != NULL) { - tscDestroyLocalMerger(pObj); + tscDestroyLocalMerger(pRes->pLocalMerger); + pRes->pLocalMerger = NULL; + tscDebug("0x%"PRIx64" free local reducer finished", pSql->self); } pRes->qId = 1; // hack to pass the safety check in fetch_row function @@ -891,14 +685,12 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen) pRes->pLocalMerger = (SLocalMerger *)calloc(1, sizeof(SLocalMerger)); /* - * we need one additional byte space - * the sprintf function needs one additional space to put '\0' at the end of string + * One more byte space is required, since the sprintf function needs one additional space to put '\0' at + * the end of string */ - size_t allocSize = numOfRes * rowLen + sizeof(tFilePage) + 1; - pRes->pLocalMerger->pResultBuf = (tFilePage *)calloc(1, allocSize); - - pRes->pLocalMerger->pResultBuf->num = numOfRes; - pRes->data = pRes->pLocalMerger->pResultBuf->data; + size_t size = numOfRes * rowLen + 1; + pRes->pLocalMerger->buf = calloc(1, size); + pRes->data = pRes->pLocalMerger->buf; } int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) { @@ -910,12 +702,12 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_ // todo refactor arithSup.offset = 0; - arithSup.numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + arithSup.numOfCols = (int32_t) tscNumOfExprs(pQueryInfo); arithSup.exprList = pQueryInfo->exprList; arithSup.data = calloc(arithSup.numOfCols, POINTER_BYTES); for(int32_t k = 0; k < arithSup.numOfCols; ++k) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k); + SExprInfo* pExpr = tscExprGet(pQueryInfo, k); arithSup.data[k] = (pOutput->data + pOutput->num* pExpr->base.offset); } @@ -944,8 +736,8 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_ return offset; } -#define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \ - (data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes) +#define COLMODEL_GET_VAL(data, schema, rowId, colId) \ + (data + (schema)->pFields[colId].offset * ((schema)->capacity) + (rowId) * (schema)->pFields[colId].field.bytes) static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel *pModel, int32_t rowIndex, int32_t maxRows) { @@ -953,7 +745,7 @@ static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i); char* p = pColInfo->pData + pBlock->info.rows * pColInfo->info.bytes; - char *src = COLMODEL_GET_VAL(buf, pModel, maxRows, rowIndex, i); + char *src = COLMODEL_GET_VAL(buf, pModel, rowIndex, i); memmove(p, src, pColInfo->info.bytes); } @@ -970,8 +762,6 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) { SLocalMerger *pMerger = pInfo->pMerge; SLoserTreeInfo *pTree = pMerger->pLoserTree; - SColumnModel *pModel = pMerger->pDesc->pColumnModel; - tFilePage *tmpBuffer = pMerger->pTempBuffer; pInfo->binfo.pRes->info.rows = 0; @@ -984,7 +774,7 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) { printf("chosen data in pTree[0] = %d\n", pTree->pNode[0].index); #endif - assert((pTree->pNode[0].index < pMerger->numOfBuffer) && (pTree->pNode[0].index >= 0) && tmpBuffer->num == 0); + assert((pTree->pNode[0].index < pMerger->numOfBuffer) && (pTree->pNode[0].index >= 0)); // chosen from loser tree SLocalDataSource *pOneDataSrc = pMerger->pLocalDataSrc[pTree->pNode[0].index]; @@ -997,11 +787,10 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) { SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i); SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex); - char *newRow = - COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity, - pOneDataSrc->rowIdx, pIndex->colIndex); + char *newRow = COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel, + pOneDataSrc->rowIdx, pIndex->colIndex); - char * data = pInfo->prevRow[i]; + char *data = pInfo->prevRow[i]; int32_t ret = columnValueAscendingComparator(data, newRow, pColInfo->info.type, pColInfo->info.bytes); if (ret == 0) { continue; @@ -1020,9 +809,8 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) { SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i); SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex); - char *curCol = - COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity, - pOneDataSrc->rowIdx, pIndex->colIndex); + char *curCol = COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel, + pOneDataSrc->rowIdx, pIndex->colIndex); memcpy(pInfo->prevRow[i], curCol, pColInfo->info.bytes); } @@ -1033,7 +821,8 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) { return pInfo->binfo.pRes; } - appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pModel, pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity); + appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel, + pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity); #if defined(_DEBUG_VIEW) printf("chosen row:\t"); @@ -1082,7 +871,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) { } SMultiwayMergeInfo *pAggInfo = pOperator->info; - SOperatorInfo *upstream = pOperator->upstream; + SOperatorInfo *upstream = pOperator->upstream[0]; *newgroup = false; bool handleData = false; @@ -1166,7 +955,6 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) { if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && pRes->info.rows > 0) { STimeWindow* w = &pRes->info.window; - // TODO in case of desc order, swap it w->skey = *(int64_t*)pInfoData->pData; w->ekey = *(int64_t*)(((char*)pInfoData->pData) + TSDB_KEYSIZE * (pRes->info.rows - 1)); @@ -1186,7 +974,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) { SSDataBlock* pBlock = NULL; if (pInfo->currentGroupOffset == 0) { - pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); if (pBlock == NULL) { setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); pOperator->status = OP_EXEC_DONE; @@ -1194,7 +982,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) { if (*newgroup == false && pInfo->limit.limit > 0 && pInfo->rowsTotal >= pInfo->limit.limit) { while ((*newgroup) == false) { // ignore the remain blocks - pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); if (pBlock == NULL) { setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); pOperator->status = OP_EXEC_DONE; @@ -1206,7 +994,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) { return pBlock; } - pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); if (pBlock == NULL) { setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); pOperator->status = OP_EXEC_DONE; @@ -1220,7 +1008,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) { } while ((*newgroup) == false) { - pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); if (pBlock == NULL) { setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); pOperator->status = OP_EXEC_DONE; diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index d8b40f397fae8d66ffd0c489744bfee0a010de43..cc89fd6220cfc24faf36157ba7541aa497f2e523 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -29,8 +29,7 @@ #include "taosdef.h" #include "tscLog.h" -#include "tscSubquery.h" -#include "tstoken.h" +#include "ttoken.h" #include "tdataformat.h" @@ -108,7 +107,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 } if (parseAbsoluteDuration(valueToken.z, valueToken.n, &interval) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (timePrec == TSDB_TIME_PRECISION_MILLI) { @@ -386,7 +385,7 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha * The server time/client time should not be mixed up in one sql string * Do not employ sort operation is not involved if server time is used. */ -static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start) { +int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start) { // once the data block is disordered, we do NOT keep previous timestamp any more if (!pDataBlocks->ordered) { return TSDB_CODE_SUCCESS; @@ -411,6 +410,7 @@ static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start if (k <= pDataBlocks->prevTS && (pDataBlocks->tsSource == TSDB_USE_CLI_TS)) { pDataBlocks->ordered = false; + tscWarn("NOT ordered input timestamp"); } pDataBlocks->prevTS = k; @@ -441,7 +441,7 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1 *str += index; if (sToken.type == TK_QUESTION) { - if (pCmd->insertType != TSDB_QUERY_TYPE_STMT_INSERT) { + if (pCmd->insertParam.insertType != TSDB_QUERY_TYPE_STMT_INSERT) { return tscSQLSyntaxErrMsg(pCmd->payload, "? only allowed in binding insertion", *str); } @@ -463,23 +463,24 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1 // Remove quotation marks if (TK_STRING == sToken.type) { // delete escape character: \\, \', \" - char delim = sToken.z[0]; + char delim = sToken.z[0]; + int32_t cnt = 0; int32_t j = 0; for (uint32_t k = 1; k < sToken.n - 1; ++k) { - if (sToken.z[k] == delim || sToken.z[k] == '\\') { - if (sToken.z[k + 1] == delim) { - cnt++; + if (sToken.z[k] == '\\' || (sToken.z[k] == delim && sToken.z[k + 1] == delim)) { tmpTokenBuf[j] = sToken.z[k + 1]; - j++; - k++; - continue; - } + + cnt++; + j++; + k++; + continue; } tmpTokenBuf[j] = sToken.z[k]; j++; } + tmpTokenBuf[j] = 0; sToken.z = tmpTokenBuf; sToken.n -= 2 + cnt; @@ -576,12 +577,13 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SSq index = 0; sToken = tStrGetToken(*str, &index, false); - *str += index; if (sToken.n == 0 || sToken.type != TK_RP) { tscSQLSyntaxErrMsg(pCmd->payload, ") expected", *str); code = TSDB_CODE_TSC_SQL_SYNTAX_ERROR; - return -1; + return code; } + + *str += index; (*numOfRows)++; } @@ -645,7 +647,7 @@ static int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, pBlocks->sversion = pTableMeta->sversion; if (pBlocks->numOfRows + numOfRows >= INT16_MAX) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } else { pBlocks->numOfRows += numOfRows; return TSDB_CODE_SUCCESS; @@ -693,6 +695,8 @@ void tscSortRemoveDataBlockDupRows(STableDataBlocks *dataBuf) { pBlocks->numOfRows = i + 1; dataBuf->size = sizeof(SSubmitBlk) + dataBuf->rowSize * pBlocks->numOfRows; } + + dataBuf->prevTS = INT64_MIN; } static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlocks* dataBuf, int32_t *totalNum) { @@ -704,16 +708,11 @@ static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlock return TSDB_CODE_TSC_OUT_OF_MEMORY; } - code = TSDB_CODE_TSC_INVALID_SQL; - char *tmpTokenBuf = calloc(1, 16*1024); // used for deleting Escape character: \\, \', \" - if (NULL == tmpTokenBuf) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } + code = TSDB_CODE_TSC_INVALID_OPERATION; + char tmpTokenBuf[16*1024] = {0}; // used for deleting Escape character: \\, \', \" int32_t numOfRows = 0; code = tsParseValues(str, dataBuf, maxNumOfRows, pCmd, &numOfRows, tmpTokenBuf); - - free(tmpTokenBuf); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -748,12 +747,10 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC const int32_t STABLE_INDEX = 1; SSqlCmd * pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); char *sql = *sqlstr; - pSql->cmd.autoCreated = false; - // get the token of specified table index = 0; tableToken = tStrGetToken(sql, &index, false); @@ -787,7 +784,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } if (numOfColList == 0 && (*boundColumn) != NULL) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX); @@ -803,7 +800,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } STableMetaInfo *pSTableMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX); - code = tscSetTableFullName(pSTableMetaInfo, &sToken, pSql); + code = tscSetTableFullName(&pSTableMetaInfo->name, &sToken, pSql); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -880,7 +877,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC if (TK_ILLEGAL == sToken.type) { tdDestroyKVRowBuilder(&kvRowBuilder); tscDestroyBoundColumnInfo(&spd); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (sToken.n == 0 || sToken.type == TK_RP) { @@ -934,17 +931,53 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC return tscSQLSyntaxErrMsg(pCmd->payload, ") expected", sToken.z); } + /* parse columns after super table tags values. + * 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; + int numOfColsAfterTags = 0; + if (sToken.type == TK_LP) { + if (*boundColumn != NULL) { + return tscSQLSyntaxErrMsg(pCmd->payload, "bind columns again", sToken.z); + } else { + *boundColumn = &sToken.z[0]; + } + + while (1) { + index = 0; + sToken = tStrGetToken(sql, &index, false); + + if (sToken.type == TK_RP) { + break; + } + + sql += index; + ++numOfColsAfterTags; + } + + if (numOfColsAfterTags == 0 && (*boundColumn) != NULL) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + sToken = tStrGetToken(sql, &index, false); + } + + sql = sToken.z; + if (tscValidateName(&tableToken) != TSDB_CODE_SUCCESS) { return tscInvalidSQLErrMsg(pCmd->payload, "invalid table name", *sqlstr); } - int32_t ret = tscSetTableFullName(pTableMetaInfo, &tableToken, pSql); + int32_t ret = tscSetTableFullName(&pTableMetaInfo->name, &tableToken, pSql); if (ret != TSDB_CODE_SUCCESS) { return ret; } if (sql == NULL) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } code = tscGetTableMetaEx(pSql, pTableMetaInfo, true); @@ -956,7 +989,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC sql = sToken.z; if (sql == NULL) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } code = tscGetTableMetaEx(pSql, pTableMetaInfo, false); @@ -975,17 +1008,22 @@ int validateTableName(char *tblName, int len, SStrToken* psTblToken) { psTblToken->n = len; psTblToken->type = TK_ID; - tSQLGetToken(psTblToken->z, &psTblToken->type); + tGetToken(psTblToken->z, &psTblToken->type); return tscValidateName(psTblToken); } -static int32_t validateDataSource(SSqlCmd *pCmd, int8_t type, const char *sql) { - if (pCmd->dataSourceType != 0 && pCmd->dataSourceType != type) { - return tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES and FILE are not allowed to mix up", sql); +static int32_t validateDataSource(SSqlCmd *pCmd, int32_t type, const char *sql) { + uint32_t *insertType = &pCmd->insertParam.insertType; + if (*insertType == TSDB_QUERY_TYPE_STMT_INSERT && type == TSDB_QUERY_TYPE_INSERT) { + return TSDB_CODE_SUCCESS; + } + + if ((*insertType) != 0 && (*insertType) != type) { + return tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES and FILE are not allowed to mixed up", sql); } - pCmd->dataSourceType = type; + *insertType = type; return TSDB_CODE_SUCCESS; } @@ -1055,7 +1093,6 @@ static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SS _clean: pCmd->curSql = NULL; - pCmd->parseFinished = 1; return code; } @@ -1071,7 +1108,7 @@ int tsParseInsertSql(SSqlObj *pSql) { int32_t totalNum = 0; int32_t code = TSDB_CODE_SUCCESS; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); assert(pQueryInfo != NULL); STableMetaInfo *pTableMetaInfo = (pQueryInfo->numOfTables == 0)? tscAddEmptyMetaInfo(pQueryInfo):tscGetMetaInfo(pQueryInfo, 0); @@ -1085,9 +1122,9 @@ int tsParseInsertSql(SSqlObj *pSql) { return code; } - if (NULL == pCmd->pTableBlockHashList) { - pCmd->pTableBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); - if (NULL == pCmd->pTableBlockHashList) { + if (NULL == pCmd->insertParam.pTableBlockHashList) { + pCmd->insertParam.pTableBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + if (NULL == pCmd->insertParam.pTableBlockHashList) { code = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _clean; } @@ -1095,7 +1132,7 @@ int tsParseInsertSql(SSqlObj *pSql) { str = pCmd->curSql; } - tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pCmd->pTableBlockHashList); + tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pCmd->insertParam.pTableBlockHashList); while (1) { int32_t index = 0; @@ -1107,7 +1144,7 @@ int tsParseInsertSql(SSqlObj *pSql) { * if the data is from the data file, no data has been generated yet. So, there no data to * merge or submit, save the file path and parse the file in other routines. */ - if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) { + if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) { goto _clean; } @@ -1116,7 +1153,7 @@ int tsParseInsertSql(SSqlObj *pSql) { * Otherwise, create the first submit block and submit to virtual node. */ if (totalNum == 0) { - code = TSDB_CODE_TSC_INVALID_SQL; + code = TSDB_CODE_TSC_INVALID_OPERATION; goto _clean; } else { break; @@ -1133,7 +1170,7 @@ int tsParseInsertSql(SSqlObj *pSql) { goto _clean; } - if ((code = tscSetTableFullName(pTableMetaInfo, &sTblToken, pSql)) != TSDB_CODE_SUCCESS) { + if ((code = tscSetTableFullName(&pTableMetaInfo->name, &sTblToken, pSql)) != TSDB_CODE_SUCCESS) { goto _clean; } @@ -1168,7 +1205,7 @@ int tsParseInsertSql(SSqlObj *pSql) { STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); if (sToken.type == TK_FILE) { - if (validateDataSource(pCmd, DATA_FROM_DATA_FILE, sToken.z) != TSDB_CODE_SUCCESS) { + if (validateDataSource(pCmd, TSDB_QUERY_TYPE_FILE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) { goto _clean; } @@ -1201,12 +1238,12 @@ int tsParseInsertSql(SSqlObj *pSql) { if (bindedColumns == NULL) { STableMeta *pTableMeta = pTableMetaInfo->pTableMeta; - if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) { + if (validateDataSource(pCmd, TSDB_QUERY_TYPE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) { goto _clean; } STableDataBlocks *dataBuf = NULL; - int32_t ret = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE, + int32_t ret = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE, sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta, &dataBuf, NULL); if (ret != TSDB_CODE_SUCCESS) { @@ -1219,14 +1256,14 @@ int tsParseInsertSql(SSqlObj *pSql) { } } else { // bindedColumns != NULL // insert into tablename(col1, col2,..., coln) values(v1, v2,... vn); - STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta; + STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, 0)->pTableMeta; - if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) { + if (validateDataSource(pCmd, TSDB_QUERY_TYPE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) { goto _clean; } STableDataBlocks *dataBuf = NULL; - int32_t ret = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE, + int32_t ret = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE, sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta, &dataBuf, NULL); if (ret != TSDB_CODE_SUCCESS) { @@ -1262,7 +1299,8 @@ int tsParseInsertSql(SSqlObj *pSql) { goto _clean; } - if (taosHashGetSize(pCmd->pTableBlockHashList) > 0) { // merge according to vgId + // merge according to vgId + if (!TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pCmd->insertParam.pTableBlockHashList) > 0) { if ((code = tscMergeTableDataBlocks(pSql, true)) != TSDB_CODE_SUCCESS) { goto _clean; } @@ -1273,7 +1311,6 @@ int tsParseInsertSql(SSqlObj *pSql) { _clean: pCmd->curSql = NULL; - pCmd->parseFinished = 1; return code; } @@ -1291,9 +1328,8 @@ int tsInsertInitialCheck(SSqlObj *pSql) { pCmd->count = 0; pCmd->command = TSDB_SQL_INSERT; - SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex); - - TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT | pCmd->insertType); + SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd); + TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT); sToken = tStrGetToken(pSql->sqlstr, &index, false); if (sToken.type != TK_INTO) { @@ -1308,11 +1344,11 @@ int tsParseSql(SSqlObj *pSql, bool initial) { int32_t ret = TSDB_CODE_SUCCESS; SSqlCmd* pCmd = &pSql->cmd; - if ((!pCmd->parseFinished) && (!initial)) { + if (!initial) { tscDebug("0x%"PRIx64" resume to parse sql: %s", pSql->self, pCmd->curSql); } - ret = tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE); + ret = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE); if (TSDB_CODE_SUCCESS != ret) { return ret; } @@ -1322,31 +1358,32 @@ int tsParseSql(SSqlObj *pSql, bool initial) { return ret; } - // make a backup as tsParseInsertSql may modify the string - char* sqlstr = strdup(pSql->sqlstr); ret = tsParseInsertSql(pSql); - if ((sqlstr == NULL) || (pSql->parseRetry >= 1) || - (ret != TSDB_CODE_TSC_SQL_SYNTAX_ERROR && ret != TSDB_CODE_TSC_INVALID_SQL)) { - free(sqlstr); - } else { + assert(ret == TSDB_CODE_SUCCESS || ret == TSDB_CODE_TSC_ACTION_IN_PROGRESS || ret == TSDB_CODE_TSC_SQL_SYNTAX_ERROR || ret == TSDB_CODE_TSC_INVALID_OPERATION); + + if (pSql->parseRetry < 1 && (ret == TSDB_CODE_TSC_SQL_SYNTAX_ERROR || ret == TSDB_CODE_TSC_INVALID_OPERATION)) { + tscDebug("0x%"PRIx64 " parse insert sql statement failed, code:%s, clear meta cache and retry ", pSql->self, tstrerror(ret)); + tscResetSqlCmd(pCmd, true); - free(pSql->sqlstr); - pSql->sqlstr = sqlstr; pSql->parseRetry++; + if ((ret = tsInsertInitialCheck(pSql)) == TSDB_CODE_SUCCESS) { ret = tsParseInsertSql(pSql); } } } else { - SSqlInfo SQLInfo = qSqlParse(pSql->sqlstr); - ret = tscToSQLCmd(pSql, &SQLInfo); - if (ret == TSDB_CODE_TSC_INVALID_SQL && pSql->parseRetry == 0 && SQLInfo.type == TSDB_SQL_NULL) { + SSqlInfo sqlInfo = qSqlParse(pSql->sqlstr); + ret = tscValidateSqlInfo(pSql, &sqlInfo); + if (ret == TSDB_CODE_TSC_INVALID_OPERATION && pSql->parseRetry < 1 && sqlInfo.type == TSDB_SQL_SELECT) { + tscDebug("0x%"PRIx64 " parse query sql statement failed, code:%s, clear meta cache and retry ", pSql->self, tstrerror(ret)); + tscResetSqlCmd(pCmd, true); pSql->parseRetry++; - ret = tscToSQLCmd(pSql, &SQLInfo); + + ret = tscValidateSqlInfo(pSql, &sqlInfo); } - SqlInfoDestroy(&SQLInfo); + SqlInfoDestroy(&sqlInfo); } /* @@ -1363,8 +1400,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock SSqlCmd *pCmd = &pSql->cmd; pSql->res.numOfRows = 0; - assert(pCmd->numOfClause == 1); - STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta; + STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, 0)->pTableMeta; SSubmitBlk *pBlocks = (SSubmitBlk *)(pTableDataBlocks->pData); code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows); @@ -1376,7 +1412,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock return code; } - STableDataBlocks *pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0); + STableDataBlocks *pDataBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, 0); if ((code = tscCopyDataBlockToPayload(pSql, pDataBlock)) != TSDB_CODE_SUCCESS) { return code; } @@ -1426,17 +1462,17 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow // accumulate the total submit records pParentSql->res.numOfRows += pSql->res.numOfRows; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; STableComInfo tinfo = tscGetTableInfo(pTableMeta); destroyTableNameList(pCmd); - pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); + pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks); - if (pCmd->pTableBlockHashList == NULL) { - pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); - if (pCmd->pTableBlockHashList == NULL) { + if (pCmd->insertParam.pTableBlockHashList == NULL) { + pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + if (pCmd->insertParam.pTableBlockHashList == NULL) { code = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } @@ -1444,7 +1480,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow STableDataBlocks *pTableDataBlock = NULL; int32_t ret = - tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), + tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pTableDataBlock, NULL); if (ret != TSDB_CODE_SUCCESS) { pParentSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -1526,8 +1562,8 @@ void tscImportDataFromFile(SSqlObj *pSql) { return; } - assert(pCmd->dataSourceType == DATA_FROM_DATA_FILE && strlen(pCmd->payload) != 0); - pCmd->active = pCmd->pQueryInfo[0]; + assert(TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT) && strlen(pCmd->payload) != 0); + pCmd->active = pCmd->pQueryInfo; SImportFileSupport *pSupporter = calloc(1, sizeof(SImportFileSupport)); SSqlObj *pNew = createSubqueryObj(pSql, 0, parseFileSendDataBlock, pSupporter, TSDB_SQL_INSERT, NULL); diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index c3c8986e2f7d07692fe2a8aaf3200637a6dc97fb..b80bdabbfcd0a13d20b661760443f0f16c704379 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -24,6 +24,7 @@ #include "tscSubquery.h" int tsParseInsertSql(SSqlObj *pSql); +int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start); //////////////////////////////////////////////////////////////////////////////// // functions for normal statement preparation @@ -43,10 +44,36 @@ typedef struct SNormalStmt { tVariant* params; } SNormalStmt; +typedef struct SMultiTbStmt { + bool nameSet; + bool tagSet; + uint64_t currentUid; + uint32_t tbNum; + SStrToken tbname; + SStrToken stbname; + SStrToken values; + SArray *tags; + SHashObj *pTableHash; + SHashObj *pTableBlockHashList; // data block for each table +} SMultiTbStmt; + +typedef enum { + STMT_INIT = 1, + STMT_PREPARE, + STMT_SETTBNAME, + STMT_BIND, + STMT_BIND_COL, + STMT_ADD_BATCH, + STMT_EXECUTE +} STMT_ST; + typedef struct STscStmt { bool isInsert; + bool multiTbInsert; + int16_t last; STscObj* taos; SSqlObj* pSql; + SMultiTbStmt mtb; SNormalStmt normal; } STscStmt; @@ -135,7 +162,7 @@ static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { break; default: - tscDebug("param %d: type mismatch or invalid", i); + tscDebug("0x%"PRIx64" bind column%d: type mismatch or invalid", stmt->pSql->self, i); return TSDB_CODE_TSC_INVALID_VALUE; } } @@ -151,7 +178,7 @@ static int normalStmtPrepare(STscStmt* stmt) { while (sql[i] != 0) { SStrToken token = {0}; - token.n = tSQLGetToken(sql + i, &token.type); + token.n = tGetToken(sql + i, &token.type); if (token.type == TK_QUESTION) { sql[i] = 0; @@ -253,14 +280,69 @@ static char* normalStmtBuildSql(STscStmt* stmt) { return taosStringBuilderGetResult(&sb, NULL); } +static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) { + SParsedDataColInfo* spd = &pBlock->boundColumnInfo; + int32_t offset = 0; + SSchema *schema = (SSchema*)pBlock->pTableMeta->schema; + + for (int32_t i = 0; i < spd->numOfCols; ++i) { + if (!spd->cols[i].hasVal) { // current column do not have any value to insert, set it to null + for (int32_t n = 0; n < rowNum; ++n) { + char *ptr = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * n + offset; + + if (schema[i].type == TSDB_DATA_TYPE_BINARY) { + varDataSetLen(ptr, sizeof(int8_t)); + *(uint8_t*) varDataVal(ptr) = TSDB_DATA_BINARY_NULL; + } else if (schema[i].type == TSDB_DATA_TYPE_NCHAR) { + varDataSetLen(ptr, sizeof(int32_t)); + *(uint32_t*) varDataVal(ptr) = TSDB_DATA_NCHAR_NULL; + } else { + setNull(ptr, schema[i].type, schema[i].bytes); + } + } + } + + offset += schema[i].bytes; + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t fillTablesColumnsNull(SSqlObj* pSql) { + SSqlCmd* pCmd = &pSql->cmd; + + STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL); + + STableDataBlocks* pOneTableBlock = *p; + while(pOneTableBlock) { + SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData; + if (pBlocks->numOfRows > 0 && pOneTableBlock->boundColumnInfo.numOfBound < pOneTableBlock->boundColumnInfo.numOfCols) { + fillColumnsNull(pOneTableBlock, pBlocks->numOfRows); + } + + p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p); + if (p == NULL) { + break; + } + + pOneTableBlock = *p; + } + + return TSDB_CODE_SUCCESS; +} + + + //////////////////////////////////////////////////////////////////////////////// // functions for insertion statement preparation -static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) { +static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, TAOS_BIND* bind, int32_t colNum) { if (bind->is_null != NULL && *(bind->is_null)) { setNull(data + param->offset, param->type, param->bytes); return TSDB_CODE_SUCCESS; } +#if 0 if (0) { // allow user bind param data with different type union { @@ -641,6 +723,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) { } } } +#endif if (bind->buffer_type != param->type) { return TSDB_CODE_TSC_INVALID_VALUE; @@ -690,29 +773,106 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) { } memcpy(data + param->offset, bind->buffer, size); + if (param->offset == 0) { + if (tsCheckTimestamp(pBlock, data + param->offset) != TSDB_CODE_SUCCESS) { + tscError("invalid timestamp"); + return TSDB_CODE_TSC_INVALID_VALUE; + } + } + return TSDB_CODE_SUCCESS; } -static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { - SSqlCmd* pCmd = &stmt->pSql->cmd; - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0); +static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* bind, int32_t rowNum) { + if (bind->buffer_type != param->type || !isValidDataType(param->type)) { + return TSDB_CODE_TSC_INVALID_VALUE; + } - STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - if (pCmd->pTableBlockHashList == NULL) { - pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + if (IS_VAR_DATA_TYPE(param->type) && bind->length == NULL) { + tscError("BINARY/NCHAR no length"); + return TSDB_CODE_TSC_INVALID_VALUE; } + for (int i = 0; i < bind->num; ++i) { + char* data = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * (rowNum + i); + + if (bind->is_null != NULL && bind->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); + + if (param->offset == 0) { + if (tsCheckTimestamp(pBlock, data + param->offset) != TSDB_CODE_SUCCESS) { + tscError("invalid timestamp"); + return TSDB_CODE_TSC_INVALID_VALUE; + } + } + } 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]); + 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); + } 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]); + 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)); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + varDataSetLen(data + param->offset, output); + } + } + + return TSDB_CODE_SUCCESS; +} + +static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { + SSqlCmd* pCmd = &stmt->pSql->cmd; + STscStmt* pStmt = (STscStmt*)stmt; + STableDataBlocks* pBlock = NULL; - int32_t ret = - tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), - pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL); - if (ret != 0) { - // todo handle error + if (pStmt->multiTbInsert) { + if (pCmd->insertParam.pTableBlockHashList == NULL) { + tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid)); + if (t1 == NULL) { + tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid); + return TSDB_CODE_TSC_APP_ERROR; + } + + pBlock = *t1; + } else { + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); + + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + if (pCmd->insertParam.pTableBlockHashList == NULL) { + pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + } + + int32_t ret = + tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), + pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL); + if (ret != 0) { + return ret; + } } - uint32_t totalDataSize = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize; + uint32_t totalDataSize = sizeof(SSubmitBlk) + (pCmd->batchSize + 1) * pBlock->rowSize; if (totalDataSize > pBlock->nAllocSize) { const double factor = 1.5; @@ -729,19 +889,144 @@ 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(data, param, &bind[param->idx]); + int code = doBindParam(pBlock, data, param, &bind[param->idx], 1); + if (code != TSDB_CODE_SUCCESS) { + tscDebug("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); + return code; + } + } + + return TSDB_CODE_SUCCESS; +} + + +static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int colIdx) { + SSqlCmd* pCmd = &stmt->pSql->cmd; + STscStmt* pStmt = (STscStmt*)stmt; + int rowNum = bind->num; + + STableDataBlocks* pBlock = NULL; + + if (pStmt->multiTbInsert) { + if (pCmd->insertParam.pTableBlockHashList == NULL) { + tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid)); + if (t1 == NULL) { + tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid); + return TSDB_CODE_TSC_APP_ERROR; + } + + pBlock = *t1; + } else { + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); + + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + if (pCmd->insertParam.pTableBlockHashList == NULL) { + pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + } + + int32_t ret = + tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), + pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL); + if (ret != 0) { + return ret; + } + } + + assert(colIdx == -1 || (colIdx >= 0 && colIdx < pBlock->numOfParams)); + + uint32_t totalDataSize = sizeof(SSubmitBlk) + (pCmd->batchSize + rowNum) * pBlock->rowSize; + if (totalDataSize > pBlock->nAllocSize) { + const double factor = 1.5; + + void* tmp = realloc(pBlock->pData, (uint32_t)(totalDataSize * factor)); + if (tmp == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + pBlock->pData = (char*)tmp; + pBlock->nAllocSize = (uint32_t)(totalDataSize * factor); + } + + 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); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + int code = doBindBatchParam(pBlock, param, &bind[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 code; + } + } + + pCmd->batchSize += rowNum - 1; + } else { + SParamInfo* param = &pBlock->params[colIdx]; + + int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize); if (code != TSDB_CODE_SUCCESS) { - tscDebug("param %d: type mismatch or invalid", param->idx); + tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); return code; } + + if (colIdx == (pBlock->numOfParams - 1)) { + pCmd->batchSize += rowNum - 1; + } } return TSDB_CODE_SUCCESS; } + +static int insertStmtUpdateBatch(STscStmt* stmt) { + SSqlObj* pSql = stmt->pSql; + SSqlCmd* pCmd = &pSql->cmd; + STableDataBlocks* pBlock = NULL; + + if (pCmd->batchSize > INT16_MAX) { + tscError("too many record:%d", pCmd->batchSize); + return TSDB_CODE_TSC_APP_ERROR; + } + + if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) { + return TSDB_CODE_SUCCESS; + } + + STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&stmt->mtb.currentUid, sizeof(stmt->mtb.currentUid)); + if (t1 == NULL) { + tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, stmt->mtb.currentUid); + return TSDB_CODE_TSC_APP_ERROR; + } + + pBlock = *t1; + + STableMeta* pTableMeta = pBlock->pTableMeta; + + pBlock->size = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize; + SSubmitBlk* pBlk = (SSubmitBlk*) pBlock->pData; + pBlk->numOfRows = pCmd->batchSize; + pBlk->dataLen = 0; + pBlk->uid = pTableMeta->id.uid; + pBlk->tid = pTableMeta->id.tid; + + return TSDB_CODE_SUCCESS; +} + static int insertStmtAddBatch(STscStmt* stmt) { SSqlCmd* pCmd = &stmt->pSql->cmd; ++pCmd->batchSize; + + if (stmt->multiTbInsert) { + return insertStmtUpdateBatch(stmt); + } + return TSDB_CODE_SUCCESS; } @@ -750,9 +1035,9 @@ static int insertStmtReset(STscStmt* pStmt) { if (pCmd->batchSize > 2) { int32_t alloced = (pCmd->batchSize + 1) / 2; - size_t size = taosArrayGetSize(pCmd->pDataBlocks); + size_t size = taosArrayGetSize(pCmd->insertParam.pDataBlocks); for (int32_t i = 0; i < size; ++i) { - STableDataBlocks* pBlock = taosArrayGetP(pCmd->pDataBlocks, i); + STableDataBlocks* pBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, i); uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk); pBlock->size = sizeof(SSubmitBlk) + totalDataSize / alloced; @@ -763,7 +1048,7 @@ static int insertStmtReset(STscStmt* pStmt) { } pCmd->batchSize = 0; - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); pTableMetaInfo->vgroupIndex = 0; return TSDB_CODE_SUCCESS; } @@ -774,22 +1059,21 @@ static int insertStmtExecute(STscStmt* stmt) { return TSDB_CODE_TSC_INVALID_VALUE; } - assert(pCmd->numOfClause == 1); - if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) { + if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) { return TSDB_CODE_SUCCESS; } - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - if (pCmd->pTableBlockHashList == NULL) { - pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + if (pCmd->insertParam.pTableBlockHashList == NULL) { + pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); } STableDataBlocks* pBlock = NULL; int32_t ret = - tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), + tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL); assert(ret == 0); pBlock->size = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize; @@ -799,12 +1083,14 @@ static int insertStmtExecute(STscStmt* stmt) { pBlk->uid = pTableMeta->id.uid; pBlk->tid = pTableMeta->id.tid; + fillTablesColumnsNull(stmt->pSql); + int code = tscMergeTableDataBlocks(stmt->pSql, false); if (code != TSDB_CODE_SUCCESS) { return code; } - STableDataBlocks* pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0); + STableDataBlocks* pDataBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, 0); code = tscCopyDataBlockToPayload(stmt->pSql, pDataBlock); if (code != TSDB_CODE_SUCCESS) { return code; @@ -822,19 +1108,279 @@ static int insertStmtExecute(STscStmt* stmt) { // data block reset pCmd->batchSize = 0; - for(int32_t i = 0; i < pCmd->numOfTables; ++i) { - if (pCmd->pTableNameList && pCmd->pTableNameList[i]) { - tfree(pCmd->pTableNameList[i]); + for(int32_t i = 0; i < pCmd->insertParam.numOfTables; ++i) { + if (pCmd->insertParam.pTableNameList && pCmd->insertParam.pTableNameList[i]) { + tfree(pCmd->insertParam.pTableNameList[i]); } } - pCmd->numOfTables = 0; - tfree(pCmd->pTableNameList); - pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); + pCmd->insertParam.numOfTables = 0; + tfree(pCmd->insertParam.pTableNameList); + pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks); return pSql->res.code; } +static void insertBatchClean(STscStmt* pStmt) { + SSqlCmd *pCmd = &pStmt->pSql->cmd; + SSqlObj *pSql = pStmt->pSql; + int32_t size = taosHashGetSize(pCmd->insertParam.pTableBlockHashList); + + // data block reset + pCmd->batchSize = 0; + + for(int32_t i = 0; i < size; ++i) { + if (pCmd->insertParam.pTableNameList && pCmd->insertParam.pTableNameList[i]) { + tfree(pCmd->insertParam.pTableNameList[i]); + } + } + + tfree(pCmd->insertParam.pTableNameList); + +/* + STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL); + + STableDataBlocks* pOneTableBlock = *p; + + while (1) { + SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData; + + pOneTableBlock->size = sizeof(SSubmitBlk); + + pBlocks->numOfRows = 0; + + p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p); + if (p == NULL) { + break; + } + + pOneTableBlock = *p; + } +*/ + + pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks); + pCmd->insertParam.numOfTables = 0; + + taosHashEmpty(pCmd->insertParam.pTableBlockHashList); + tscFreeSqlResult(pSql); + tscFreeSubobj(pSql); + tfree(pSql->pSubs); + pSql->subState.numOfSub = 0; +} + +static int insertBatchStmtExecute(STscStmt* pStmt) { + int32_t code = 0; + + if(pStmt->mtb.nameSet == false) { + tscError("0x%"PRIx64" no table name set", pStmt->pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + pStmt->pSql->retry = pStmt->pSql->maxRetry + 1; //no retry + + if (taosHashGetSize(pStmt->pSql->cmd.insertParam.pTableBlockHashList) <= 0) { // merge according to vgId + tscError("0x%"PRIx64" no data block to insert", pStmt->pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + fillTablesColumnsNull(pStmt->pSql); + + if ((code = tscMergeTableDataBlocks(pStmt->pSql, false)) != TSDB_CODE_SUCCESS) { + return code; + } + + code = tscHandleMultivnodeInsert(pStmt->pSql); + + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + // wait for the callback function to post the semaphore + tsem_wait(&pStmt->pSql->rspSem); + + insertBatchClean(pStmt); + + return pStmt->pSql->res.code; +} + + +int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) { + SSqlCmd *pCmd = &pSql->cmd; + int32_t ret = TSDB_CODE_SUCCESS; + + if ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS) { + return ret; + } + + int32_t index = 0; + SStrToken sToken = tStrGetToken(pCmd->curSql, &index, false); + if (sToken.n == 0) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + if (sToken.n == 1 && sToken.type == TK_QUESTION) { + pStmt->multiTbInsert = true; + pStmt->mtb.tbname = sToken; + pStmt->mtb.nameSet = false; + if (pStmt->mtb.pTableHash == NULL) { + pStmt->mtb.pTableHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false); + } + + if (pStmt->mtb.pTableBlockHashList == NULL) { + pStmt->mtb.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + } + + pStmt->mtb.tagSet = true; + + sToken = tStrGetToken(pCmd->curSql, &index, false); + if (sToken.n > 0 && sToken.type == TK_VALUES) { + return TSDB_CODE_SUCCESS; + } + + if (sToken.n <= 0 || sToken.type != TK_USING) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + sToken = tStrGetToken(pCmd->curSql, &index, false); + if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + pStmt->mtb.stbname = sToken; + + sToken = tStrGetToken(pCmd->curSql, &index, false); + if (sToken.n <= 0 || sToken.type != TK_TAGS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + sToken = tStrGetToken(pCmd->curSql, &index, false); + if (sToken.n <= 0 || sToken.type != TK_LP) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + pStmt->mtb.tags = taosArrayInit(4, sizeof(SStrToken)); + + int32_t loopCont = 1; + + while (loopCont) { + sToken = tStrGetToken(pCmd->curSql, &index, false); + if (sToken.n <= 0) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + switch (sToken.type) { + case TK_RP: + loopCont = 0; + break; + case TK_VALUES: + return TSDB_CODE_TSC_INVALID_OPERATION; + case TK_QUESTION: + pStmt->mtb.tagSet = false; //continue + default: + taosArrayPush(pStmt->mtb.tags, &sToken); + break; + } + } + + if (taosArrayGetSize(pStmt->mtb.tags) <= 0) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + sToken = tStrGetToken(pCmd->curSql, &index, false); + if (sToken.n <= 0 || sToken.type != TK_VALUES) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + pStmt->mtb.values = sToken; + } + + return TSDB_CODE_SUCCESS; +} + + + + +int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAOS_BIND* tags) { + size_t tagNum = taosArrayGetSize(pStmt->mtb.tags); + size_t size = 1048576; + char *str = calloc(1, size); + size_t len = 0; + int32_t ret = 0; + int32_t j = 0; + + while (1) { + len = (size_t)snprintf(str, size - 1, "insert into %s using %.*s tags(", name, pStmt->mtb.stbname.n, pStmt->mtb.stbname.z); + if (len >= (size -1)) { + size *= 2; + free(str); + str = calloc(1, size); + continue; + } + + j = 0; + + for (size_t i = 0; i < tagNum && len < (size - 1); ++i) { + SStrToken *t = taosArrayGet(pStmt->mtb.tags, i); + if (t->type == TK_QUESTION) { + int32_t l = 0; + if (i > 0) { + str[len++] = ','; + } + + if (tags[j].is_null && (*tags[j].is_null)) { + ret = converToStr(str + len, TSDB_DATA_TYPE_NULL, NULL, -1, &l); + } else { + if (tags[j].buffer == NULL) { + free(str); + tscError("empty"); + return TSDB_CODE_TSC_APP_ERROR; + } + + ret = converToStr(str + len, tags[j].buffer_type, tags[j].buffer, tags[j].length ? (int32_t)*tags[j].length : -1, &l); + } + + ++j; + + if (ret) { + free(str); + return ret; + } + + len += l; + } else { + len += (size_t)snprintf(str + len, size - len - 1, i > 0 ? ",%.*s" : "%.*s", t->n, t->z); + } + } + + if (len >= (size - 1)) { + size *= 2; + free(str); + str = calloc(1, size); + continue; + } + + strcat(str, ") "); + len += 2; + + if ((len + strlen(pStmt->mtb.values.z)) >= (size - 1)) { + size *= 2; + free(str); + str = calloc(1, size); + continue; + } + + strcat(str, pStmt->mtb.values.z); + + break; + } + + free(pSql->sqlstr); + pSql->sqlstr = str; + + return TSDB_CODE_SUCCESS; +} + + + //////////////////////////////////////////////////////////////////////////////// // interface functions @@ -855,6 +1401,7 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) { pStmt->taos = pObj; SSqlObj* pSql = calloc(1, sizeof(SSqlObj)); + if (pSql == NULL) { free(pStmt); terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -866,7 +1413,9 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) { pSql->signature = pSql; pSql->pTscObj = pObj; pSql->maxRetry = TSDB_MAX_REPLICA; + pSql->isBind = true; pStmt->pSql = pSql; + pStmt->last = STMT_INIT; return pStmt; } @@ -879,6 +1428,13 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { return TSDB_CODE_TSC_DISCONNECTED; } + if (pStmt->last != STMT_INIT) { + tscError("prepare status error, last:%d", pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + + pStmt->last = STMT_PREPARE; + SSqlObj* pSql = pStmt->pSql; size_t sqlLen = strlen(sql); @@ -888,7 +1444,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { pSql->fp = waitForQueryRsp; pSql->fetchFp = waitForQueryRsp; - pCmd->insertType = TSDB_QUERY_TYPE_STMT_INSERT; + pCmd->insertParam.insertType = TSDB_QUERY_TYPE_STMT_INSERT; if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) { tscError("%p failed to malloc payload buffer", pSql); @@ -917,6 +1473,17 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { registerSqlObj(pSql); + int32_t ret = stmtParseInsertTbTags(pSql, pStmt); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + + if (pStmt->multiTbInsert) { + return TSDB_CODE_SUCCESS; + } + + memset(&pStmt->mtb, 0, sizeof(pStmt->mtb)); + int32_t code = tsParseSql(pSql, true); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { // wait for the callback function to post the semaphore @@ -931,6 +1498,123 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { return normalStmtPrepare(pStmt); } +int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags) { + STscStmt* pStmt = (STscStmt*)stmt; + SSqlObj* pSql = pStmt->pSql; + SSqlCmd* pCmd = &pSql->cmd; + + if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { + terrno = TSDB_CODE_TSC_DISCONNECTED; + return TSDB_CODE_TSC_DISCONNECTED; + } + + if (name == NULL) { + terrno = TSDB_CODE_TSC_APP_ERROR; + tscError("0x%"PRIx64" name is NULL", pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + if (pStmt->multiTbInsert == false || !tscIsInsertData(pSql->sqlstr)) { + terrno = TSDB_CODE_TSC_APP_ERROR; + tscError("0x%"PRIx64" not multi table insert", pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + if (pStmt->last == STMT_INIT || pStmt->last == STMT_BIND || pStmt->last == STMT_BIND_COL) { + tscError("0x%"PRIx64" settbname status error, last:%d", pSql->self, pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + + pStmt->last = STMT_SETTBNAME; + + uint64_t* uid = (uint64_t*)taosHashGet(pStmt->mtb.pTableHash, name, strlen(name)); + if (uid != NULL) { + pStmt->mtb.currentUid = *uid; + + STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pStmt->mtb.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid)); + if (t1 == NULL) { + tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, pStmt->mtb.currentUid); + return TSDB_CODE_TSC_APP_ERROR; + } + + SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData; + pCmd->batchSize = pBlk->numOfRows; + + taosHashPut(pCmd->insertParam.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES); + + tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid); + return TSDB_CODE_SUCCESS; + } + + if (pStmt->mtb.tagSet) { + pStmt->mtb.tbname = tscReplaceStrToken(&pSql->sqlstr, &pStmt->mtb.tbname, name); + } else { + if (tags == NULL) { + tscError("No tags set"); + return TSDB_CODE_TSC_APP_ERROR; + } + + int32_t ret = stmtGenInsertStatement(pSql, pStmt, name, tags); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + } + + pStmt->mtb.nameSet = true; + pStmt->mtb.tagSet = true; + + tscDebug("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr); + + pSql->cmd.numOfParams = 0; + pSql->cmd.batchSize = 0; + + if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) > 0) { + SHashObj* hashList = pCmd->insertParam.pTableBlockHashList; + pCmd->insertParam.pTableBlockHashList = NULL; + tscResetSqlCmd(pCmd, true); + pCmd->insertParam.pTableBlockHashList = hashList; + } + + int32_t code = tsParseSql(pStmt->pSql, true); + if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + // wait for the callback function to post the semaphore + tsem_wait(&pStmt->pSql->rspSem); + + code = pStmt->pSql->res.code; + } + + if (code == TSDB_CODE_SUCCESS) { + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); + + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + STableDataBlocks* pBlock = NULL; + code = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), + pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + SSubmitBlk* blk = (SSubmitBlk*)pBlock->pData; + blk->numOfRows = 0; + + pStmt->mtb.currentUid = pTableMeta->id.uid; + pStmt->mtb.tbNum++; + + taosHashPut(pStmt->mtb.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)&pBlock, POINTER_BYTES); + taosHashPut(pStmt->mtb.pTableHash, name, strlen(name), (char*) &pTableMeta->id.uid, sizeof(pTableMeta->id.uid)); + + tscDebug("0x%"PRIx64" table:%s is prepared, uid:%" PRIx64, pSql->self, name, pStmt->mtb.currentUid); + } + + return code; +} + + +int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) { + return taos_stmt_set_tbname_tags(stmt, name, NULL); +} + + int taos_stmt_close(TAOS_STMT* stmt) { STscStmt* pStmt = (STscStmt*)stmt; if (!pStmt->isInsert) { @@ -943,6 +1627,14 @@ int taos_stmt_close(TAOS_STMT* stmt) { } free(normal->parts); free(normal->sql); + } else { + if (pStmt->multiTbInsert) { + taosHashCleanup(pStmt->mtb.pTableHash); + pStmt->mtb.pTableBlockHashList = tscDestroyBlockHashTable(pStmt->mtb.pTableBlockHashList, true); + taosHashCleanup(pStmt->pSql->cmd.insertParam.pTableBlockHashList); + pStmt->pSql->cmd.insertParam.pTableBlockHashList = NULL; + taosArrayDestroy(pStmt->mtb.tags); + } } taos_free_result(pStmt->pSql); @@ -952,18 +1644,122 @@ int taos_stmt_close(TAOS_STMT* stmt) { int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) { STscStmt* pStmt = (STscStmt*)stmt; + if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { + terrno = TSDB_CODE_TSC_DISCONNECTED; + return TSDB_CODE_TSC_DISCONNECTED; + } + if (pStmt->isInsert) { + if (pStmt->multiTbInsert) { + if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) { + tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + } else { + if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_EXECUTE) { + tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + } + + pStmt->last = STMT_BIND; + return insertStmtBindParam(pStmt, bind); } else { return normalStmtBindParam(pStmt, bind); } } + +int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) { + STscStmt* pStmt = (STscStmt*)stmt; + + if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { + terrno = TSDB_CODE_TSC_DISCONNECTED; + return TSDB_CODE_TSC_DISCONNECTED; + } + + if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) { + tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + if (!pStmt->isInsert) { + tscError("0x%"PRIx64" not or invalid batch insert", pStmt->pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + if (pStmt->multiTbInsert) { + if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) { + tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + } else { + if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_EXECUTE) { + tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + } + + pStmt->last = STMT_BIND; + + return insertStmtBindParamBatch(pStmt, bind, -1); +} + +int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int colIdx) { + STscStmt* pStmt = (STscStmt*)stmt; + if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { + terrno = TSDB_CODE_TSC_DISCONNECTED; + return TSDB_CODE_TSC_DISCONNECTED; + } + + if (bind == NULL || bind->num <= 0 || bind->num > INT16_MAX) { + tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + if (!pStmt->isInsert) { + tscError("0x%"PRIx64" not or invalid batch insert", pStmt->pSql->self); + return TSDB_CODE_TSC_APP_ERROR; + } + + if (pStmt->multiTbInsert) { + if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL) { + tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + } else { + if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL && pStmt->last != STMT_EXECUTE) { + tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + } + + pStmt->last = STMT_BIND_COL; + + return insertStmtBindParamBatch(pStmt, bind, colIdx); +} + + + int taos_stmt_add_batch(TAOS_STMT* stmt) { STscStmt* pStmt = (STscStmt*)stmt; + if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { + terrno = TSDB_CODE_TSC_DISCONNECTED; + return TSDB_CODE_TSC_DISCONNECTED; + } + if (pStmt->isInsert) { + if (pStmt->last != STMT_BIND && pStmt->last != STMT_BIND_COL) { + tscError("0x%"PRIx64" add batch status error, last:%d", pStmt->pSql->self, pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + + pStmt->last = STMT_ADD_BATCH; + return insertStmtAddBatch(pStmt); } + return TSDB_CODE_COM_OPS_NOT_SUPPORT; } @@ -978,17 +1774,34 @@ int taos_stmt_reset(TAOS_STMT* stmt) { int taos_stmt_execute(TAOS_STMT* stmt) { int ret = 0; STscStmt* pStmt = (STscStmt*)stmt; + if (stmt == NULL || pStmt->pSql == NULL || pStmt->taos == NULL) { + terrno = TSDB_CODE_TSC_DISCONNECTED; + return TSDB_CODE_TSC_DISCONNECTED; + } + if (pStmt->isInsert) { - ret = insertStmtExecute(pStmt); + if (pStmt->last != STMT_ADD_BATCH) { + tscError("0x%"PRIx64" exec status error, last:%d", pStmt->pSql->self, pStmt->last); + return TSDB_CODE_TSC_APP_ERROR; + } + + pStmt->last = STMT_EXECUTE; + + if (pStmt->multiTbInsert) { + ret = insertBatchStmtExecute(pStmt); + } else { + ret = insertStmtExecute(pStmt); + } } else { // normal stmt query char* sql = normalStmtBuildSql(pStmt); if (sql == NULL) { ret = TSDB_CODE_TSC_OUT_OF_MEMORY; } else { if (pStmt->pSql != NULL) { - taos_free_result(pStmt->pSql); + tscFreeSqlObj(pStmt->pSql); pStmt->pSql = NULL; } + pStmt->pSql = taos_query((TAOS*)pStmt->taos, sql); ret = taos_errno(pStmt->pSql); free(sql); @@ -1058,23 +1871,23 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) { if (pStmt->isInsert) { SSqlCmd* pCmd = &pStmt->pSql->cmd; - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - if (pCmd->pTableBlockHashList == NULL) { - pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + if (pCmd->insertParam.pTableBlockHashList == NULL) { + pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); } STableDataBlocks* pBlock = NULL; int32_t ret = - tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), + tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL); if (ret != 0) { // todo handle error } if (idx<0 || idx>=pBlock->numOfParams) { - tscError("param %d: out of range", idx); + tscError("0x%"PRIx64" param %d: out of range", pStmt->pSql->self, idx); abort(); } diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c index 777a136a6e215110aaebb2ff93f97456dd215dcf..b9ef98681001b657dafe02214853ef28e02e559c 100644 --- a/src/client/src/tscProfile.c +++ b/src/client/src/tscProfile.c @@ -54,14 +54,14 @@ void tscAddIntoSqlList(SSqlObj *pSql) { pSql->next = pObj->sqlList; if (pObj->sqlList) pObj->sqlList->prev = pSql; pObj->sqlList = pSql; - pSql->queryId = queryId++; + pSql->queryId = atomic_fetch_add_32(&queryId, 1); pthread_mutex_unlock(&pObj->mutex); pSql->stime = taosGetTimestampMs(); pSql->listed = 1; - tscDebug("0x%"PRIx64" added into sqlList", pSql->self); + tscDebug("0x%"PRIx64" added into sqlList, queryId:%u", pSql->self, pSql->queryId); } void tscSaveSlowQueryFpCb(void *param, TAOS_RES *result, int code) { diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index b02d2fb5a400e2842f57f3529a46050fbb601662..3acc8782d06394f5192d0eaee6883b628bba09be 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -21,20 +21,21 @@ #endif // __APPLE__ #include "os.h" -#include "ttype.h" -#include "texpr.h" #include "taos.h" #include "taosmsg.h" #include "tcompare.h" +#include "texpr.h" #include "tname.h" #include "tscLog.h" #include "tscUtil.h" #include "tschemautil.h" #include "tsclient.h" -#include "tstoken.h" #include "tstrbuild.h" +#include "ttoken.h" #include "ttokendef.h" +#include "ttype.h" #include "qUtil.h" +#include "qPlan.h" #define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0" @@ -57,7 +58,7 @@ typedef struct SConvertFunc { int32_t execFuncId; } SConvertFunc; -static SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex); +static SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex, int32_t colId); static int32_t setShowInfo(SSqlObj* pSql, SSqlInfo* pInfo); static char* getAccountId(SSqlObj* pSql); @@ -70,7 +71,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC static int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* len); -static void getColumnName(tSqlExprItem* pItem, char* resultFieldName, int32_t nameLength); +static void getColumnName(tSqlExprItem* pItem, char* resultFieldName, char* rawName, int32_t nameLength); static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult); static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes, @@ -112,7 +113,7 @@ static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField); static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo); static bool hasNormalColumnFilter(SQueryInfo* pQueryInfo); -static int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t index, SSqlNode* pSqlNode, SSqlObj* pSql); +static int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSqlObj* pSql); static int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDbInfo* pCreateDbSql); static int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex); static int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex); @@ -127,17 +128,18 @@ static SColumnList createColumnList(int32_t num, int16_t tableIndex, int32_t col static int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo); static int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo); static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo); -static int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index); +static int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInfo); static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, uint64_t *uid); static bool validateDebugFlag(int32_t v); static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); +static int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo); static bool isTimeWindowQuery(SQueryInfo* pQueryInfo) { return pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0; } -int16_t getNewResColId(SQueryInfo* pQueryInfo) { - return pQueryInfo->resColumnId--; +int16_t getNewResColId(SSqlCmd* pCmd) { + return pCmd->resColumnId--; } static uint8_t convertOptr(SStrToken *pToken) { @@ -193,7 +195,7 @@ static bool validateDebugFlag(int32_t v) { * Used during parsing query sql. Since the query sql usually small in length, error position * is not needed in the final error message. */ -static int32_t invalidSqlErrMsg(char* dstBuffer, const char* errMsg) { +static int32_t invalidOperationMsg(char* dstBuffer, const char* errMsg) { return tscInvalidSQLErrMsg(dstBuffer, errMsg, NULL); } @@ -209,11 +211,11 @@ static int setColumnFilterInfoForTimestamp(SSqlCmd* pCmd, SQueryInfo* pQueryInfo if (seg != NULL) { if (taosParseTime(pVar->pz, &time, pVar->nLen, tinfo.precision, tsDaylight) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } } else { if (tVariantDump(pVar, (char*)&time, TSDB_DATA_TYPE_BIGINT, true)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } } @@ -229,24 +231,56 @@ static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) { const char* msg3 = "password needs single quote marks enclosed"; if (pPwd->type != TK_STRING) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } strdequote(pPwd->z); pPwd->n = (uint32_t)strtrim(pPwd->z); // trim space before and after passwords if (pPwd->n <= 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pPwd->n >= TSDB_KEY_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } return TSDB_CODE_SUCCESS; } -int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { +// validate the out put field type for "UNION ALL" subclause +static int32_t normalizeVarDataTypeLength(SSqlCmd* pCmd) { + const char* msg1 = "columns in select clause not identical"; + + int32_t diffSize = 0; + + // if there is only one element, the limit of clause is the limit of global result. + SQueryInfo* pQueryInfo1 = pCmd->pQueryInfo; + SQueryInfo* pSibling = pQueryInfo1->sibling; + + while(pSibling != NULL) { + int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pSibling->fieldsInfo, &diffSize); + if (ret != 0) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + pSibling = pSibling->sibling; + } + + if (diffSize) { + pQueryInfo1 = pCmd->pQueryInfo; + pSibling = pQueryInfo1->sibling; + + while(pSibling->sibling != NULL) { + tscFieldInfoSetSize(&pQueryInfo1->fieldsInfo, &pSibling->fieldsInfo); + pSibling = pSibling->sibling; + } + } + + return TSDB_CODE_SUCCESS; +} + +int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (pInfo == NULL || pSql == NULL) { return TSDB_CODE_TSC_APP_ERROR; } @@ -260,7 +294,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { return tscSQLSyntaxErrMsg(tscGetErrorMsgPayload(pCmd), NULL, pInfo->msg); } - SQueryInfo* pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfoS(pCmd); if (pQueryInfo == NULL) { pRes->code = terrno; return pRes->code; @@ -282,37 +316,36 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { case TSDB_SQL_DROP_DB: { const char* msg2 = "invalid name"; const char* msg3 = "param name too long"; - const char* msg4 = "table is not super table"; SStrToken* pzName = taosArrayGet(pInfo->pMiscInfo->a, 0); if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (tscValidateName(pzName) != TSDB_CODE_SUCCESS)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } 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 invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } else if (pInfo->type == TSDB_SQL_DROP_TABLE) { assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1); - code = tscSetTableFullName(pTableMetaInfo, pzName, pSql); + code = tscSetTableFullName(&pTableMetaInfo->name, pzName, pSql); if(code != TSDB_CODE_SUCCESS) { return code; } if (pInfo->pMiscInfo->tableType == TSDB_SUPER_TABLE) { - code = tscGetTableMeta(pSql, pTableMetaInfo); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - - if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); - } +//// code = tscGetTableMeta(pSql, pTableMetaInfo); +//// if (code != TSDB_CODE_SUCCESS) { +//// return code; +//// } +// +// if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { +// return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); +// } } } else if (pInfo->type == TSDB_SQL_DROP_DNODE) { @@ -320,7 +353,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { strncpy(pCmd->payload, pzName->z, pzName->n); } else { // drop user/account if (pzName->n >= TSDB_USER_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } strncpy(pCmd->payload, pzName->z, pzName->n); @@ -334,12 +367,12 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken); if (ret != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } break; @@ -351,7 +384,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { case TSDB_SQL_SHOW: { if (setShowInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } break; @@ -364,16 +397,16 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { SCreateDbInfo* pCreateDB = &(pInfo->pMiscInfo->dbOpt); if (tscValidateName(&pCreateDB->dbname) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), &(pCreateDB->dbname)); if (ret != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } break; @@ -383,7 +416,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { const char* msg = "invalid host name (ip address)"; if (taosArrayGetSize(pInfo->pMiscInfo->a) > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } SStrToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0); @@ -401,15 +434,15 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { SStrToken* pPwd = &pInfo->pMiscInfo->user.passwd; if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pName->n >= TSDB_USER_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (tscValidateName(pName) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } SCreateAcctInfo* pAcctOpt = &pInfo->pMiscInfo->acctOpt; @@ -419,7 +452,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { } else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) { } else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) { } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -431,27 +464,26 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - // additional msg has been attached already - code = tscSetTableFullName(pTableMetaInfo, pToken, pSql); + code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql); if (code != TSDB_CODE_SUCCESS) { return code; } return tscGetTableMeta(pSql, pTableMetaInfo); } - case TSDB_SQL_SHOW_CREATE_STABLE: + case TSDB_SQL_SHOW_CREATE_STABLE: case TSDB_SQL_SHOW_CREATE_TABLE: { const char* msg1 = "invalid table name"; SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - code = tscSetTableFullName(pTableMetaInfo, pToken, pSql); + code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -463,14 +495,13 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pToken->n > TSDB_DB_NAME_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - - return tscSetTableFullName(pTableMetaInfo, pToken, pSql); + return tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken); } case TSDB_SQL_CFG_DNODE: { const char* msg2 = "invalid configure options or values, such as resetlog / debugFlag 135 / balance 'vnode:2-dnode:2' / monitor 1 "; @@ -481,7 +512,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { /* validate the parameter names and options */ if (validateDNodeConfig(pMiscInfo) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } char* pMsg = pCmd->payload; @@ -495,7 +526,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { strncpy(pCfg->ep, t0->z, t0->n); if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } strncpy(pCfg->config, t1->z, t1->n); @@ -524,21 +555,21 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { SStrToken* pPwd = &pUser->passwd; if (pName->n >= TSDB_USER_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (tscValidateName(pName) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } if (pCmd->command == TSDB_SQL_CREATE_USER) { if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } else { if (pUser->type == TSDB_ALTER_USER_PASSWD) { if (handlePassword(pCmd, pPwd) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } else if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) { assert(pPwd->type == TSDB_DATA_TYPE_NULL); @@ -552,10 +583,10 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { } else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) { pCmd->count = 3; } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } } @@ -568,7 +599,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { // validate the parameter names and options if (validateLocalConfig(pMiscInfo) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } int32_t numOfToken = (int32_t) taosArrayGetSize(pMiscInfo->a); @@ -608,48 +639,41 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { } case TSDB_SQL_SELECT: { - const char* msg1 = "columns in select clause not identical"; - - size_t size = taosArrayGetSize(pInfo->list); - for (int32_t i = pCmd->numOfClause; i < size; ++i) { - SQueryInfo* p = tscGetQueryInfoS(pCmd, i); - if (p == NULL) { - pRes->code = terrno; - return pRes->code; - } + code = loadAllTableMeta(pSql, pInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; } - assert(pCmd->numOfClause == size); - for (int32_t i = pCmd->clauseIndex; i < size; ++i) { + pQueryInfo = tscGetQueryInfo(pCmd); + + size_t size = taosArrayGetSize(pInfo->list); + for (int32_t i = 0; i < size; ++i) { SSqlNode* pSqlNode = taosArrayGetP(pInfo->list, i); - tscTrace("%p start to parse %dth subclause, total:%d", pSql, i, (int32_t) size); - if ((code = validateSqlNode(pSql, pSqlNode, i)) != TSDB_CODE_SUCCESS) { + + tscTrace("%p start to parse %dth subclause, total:%"PRIzu, pSql, i, size); + if ((code = validateSqlNode(pSql, pSqlNode, pQueryInfo)) != TSDB_CODE_SUCCESS) { return code; } tscPrintSelNodeList(pSql, i); - pCmd->clauseIndex += 1; - } - - // restore the clause index - pCmd->clauseIndex = 0; - // set the command/global limit parameters from the first subclause to the sqlcmd object - SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pCmd, 0); - pCmd->command = pQueryInfo1->command; - - // if there is only one element, the limit of clause is the limit of global result. - // validate the select node for "UNION ALL" subclause - for (int32_t i = 1; i < pCmd->numOfClause; ++i) { - SQueryInfo* pQueryInfo2 = tscGetQueryInfo(pCmd, i); + if ((i + 1) < size && pQueryInfo->sibling == NULL) { + if ((code = tscAddQueryInfo(pCmd)) != TSDB_CODE_SUCCESS) { + return code; + } - int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo); - if (ret != 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + pQueryInfo = pCmd->active; } } - pCmd->parseFinished = 1; + if ((code = normalizeVarDataTypeLength(pCmd)) != TSDB_CODE_SUCCESS) { + return code; + } + + // set the command/global limit parameters from the first subclause to the sqlcmd object + pCmd->active = pCmd->pQueryInfo; + pCmd->command = pCmd->pQueryInfo->command; + return TSDB_CODE_SUCCESS; // do not build query message here } @@ -677,20 +701,19 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1); code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName); if (code != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } break; } default: - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression"); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression"); } - pSql->cmd.parseFinished = 1; if (tscBuildMsg[pCmd->command] != NULL) { return tscBuildMsg[pCmd->command](pSql, pInfo); } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression"); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "not support sql expression"); } } @@ -699,10 +722,10 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { * are available. */ static bool isTopBottomQuery(SQueryInfo* pQueryInfo) { - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; + int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { return true; @@ -713,8 +736,8 @@ static bool isTopBottomQuery(SQueryInfo* pQueryInfo) { } // need to add timestamp column in result set, if it is a time window query -static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo) { - uint64_t uid = tscSqlExprGet(pQueryInfo, 0)->base.uid; +static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) { + uint64_t uid = tscExprGet(pQueryInfo, 0)->base.uid; int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL; for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { @@ -726,14 +749,14 @@ static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo) { } if (tableIndex == COLUMN_INDEX_INITIAL_VAL) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX}; 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); + tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL, getNewResColId(pCmd)); return TSDB_CODE_SUCCESS; } @@ -749,7 +772,7 @@ static int32_t checkInvalidExprForTimeWindow(SSqlCmd* pCmd, SQueryInfo* pQueryIn // order by normal column is not supported int32_t colId = pQueryInfo->order.orderColId; if (isTimeWindowQuery(pQueryInfo) && colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } return TSDB_CODE_SUCCESS; @@ -759,11 +782,11 @@ static int32_t checkInvalidExprForTimeWindow(SSqlCmd* pCmd, SQueryInfo* pQueryIn * invalid sql: * select count(tbname)/count(tag1)/count(tag2) from super_table_name [interval(1d)|session(ts, 1d)]; */ - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -772,10 +795,10 @@ static int32_t checkInvalidExprForTimeWindow(SSqlCmd* pCmd, SQueryInfo* pQueryIn * select tbname, tags_fields from super_table_name [interval(1s)|session(ts,1s)] */ if (tscQueryTags(pQueryInfo) && isTimeWindowQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - return addPrimaryTsColumnForTimeWindowQuery(pQueryInfo); + return addPrimaryTsColumnForTimeWindowQuery(pQueryInfo, pCmd); } int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) { @@ -789,7 +812,7 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS if (!TPARSER_HAS_TOKEN(pSqlNode->interval.interval)) { if (TPARSER_HAS_TOKEN(pSqlNode->sliding)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } return TSDB_CODE_SUCCESS; @@ -803,7 +826,7 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS // interval is not null SStrToken *t = &pSqlNode->interval.interval; if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.interval, &pQueryInfo->interval.intervalUnit) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit != 'y') { @@ -814,16 +837,16 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS // interval cannot be less than 10 milliseconds if (pQueryInfo->interval.interval < tsMinIntervalTime) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } if (parseIntervalOffset(pCmd, pQueryInfo, &pSqlNode->interval.offset) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (parseSlidingClause(pCmd, pQueryInfo, &pSqlNode->sliding) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // The following part is used to check for the invalid query expression. @@ -844,35 +867,35 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); } if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } pQueryInfo->groupbyExpr.numOfGroupCols = 1; //TODO(dengyihao): check tag column if (isStable) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, col, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta); if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr; + SGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr; if (pGroupExpr->columnInfo == NULL) { pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex)); } SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); @@ -899,11 +922,11 @@ int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pS char timeUnit = 0; if (parseNatualDuration(gap->z, gap->n, &pQueryInfo->sessionWindow.gap, &timeUnit) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } if (timeUnit == 'y' || timeUnit == 'n') { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } // if the unit of time window value is millisecond, change the value from microsecond @@ -914,18 +937,18 @@ int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pS } if (pQueryInfo->sessionWindow.gap != 0 && pQueryInfo->interval.interval != 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } if (pQueryInfo->sessionWindow.gap == 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, col, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } pQueryInfo->sessionWindow.primaryColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; @@ -950,11 +973,11 @@ int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* of } if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.offset, &pQueryInfo->interval.offsetUnit) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pQueryInfo->interval.offset < 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pQueryInfo->interval.offsetUnit != 'n' && pQueryInfo->interval.offsetUnit != 'y') { @@ -964,18 +987,18 @@ int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* of } if (pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit != 'y') { if (pQueryInfo->interval.offset >= pQueryInfo->interval.interval) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } } else if (pQueryInfo->interval.offsetUnit == pQueryInfo->interval.intervalUnit) { if (pQueryInfo->interval.offset >= pQueryInfo->interval.interval) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } else if (pQueryInfo->interval.intervalUnit == 'n' && pQueryInfo->interval.offsetUnit == 'y') { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } else if (pQueryInfo->interval.intervalUnit == 'y' && pQueryInfo->interval.offsetUnit == 'n') { if (pQueryInfo->interval.interval * 12 <= pQueryInfo->interval.offset) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } else { // TODO: offset should be shorter than interval, but how to check @@ -1003,7 +1026,7 @@ int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSl } if (pQueryInfo->interval.intervalUnit == 'n' || pQueryInfo->interval.intervalUnit == 'y') { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } parseAbsoluteDuration(pSliding->z, pSliding->n, &pQueryInfo->interval.sliding); @@ -1012,59 +1035,58 @@ int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSl } if (pQueryInfo->interval.sliding < tsMinSlidingTime) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } if (pQueryInfo->interval.sliding > pQueryInfo->interval.interval) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if ((pQueryInfo->interval.interval != 0) && (pQueryInfo->interval.interval/pQueryInfo->interval.sliding > INTERVAL_SLIDING_FACTOR)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } // if (pQueryInfo->interval.sliding != pQueryInfo->interval.interval && pSql->pStream == NULL) { -// return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); +// return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); // } return TSDB_CODE_SUCCESS; } -int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pTableName, SSqlObj* pSql) { +int32_t tscSetTableFullName(SName* pName, SStrToken* pTableName, SSqlObj* pSql) { const char* msg1 = "name too long"; const char* msg2 = "acctId too long"; const char* msg3 = "no acctId"; const char* msg4 = "db name too long"; const char* msg5 = "table name too long"; - SSqlCmd* pCmd = &pSql->cmd; int32_t code = TSDB_CODE_SUCCESS; - int32_t idx = getDelimiterIndex(pTableName); + int32_t 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) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - code = tNameSetAcctId(&pTableMetaInfo->name, acctId); + code = tNameSetAcctId(pName, acctId); if (code != 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - if (idx >= TSDB_DB_NAME_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + if (idx >= TSDB_DB_NAME_LEN) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - + if (pTableName->n - 1 - idx >= TSDB_TABLE_NAME_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } - + char name[TSDB_TABLE_FNAME_LEN] = {0}; strncpy(name, pTableName->z, pTableName->n); - code = tNameFromString(&pTableMetaInfo->name, name, T_NAME_DB|T_NAME_TABLE); + code = tNameFromString(pName, name, T_NAME_DB|T_NAME_TABLE); if (code != 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } else { // get current DB name first, and then set it into path char* t = cloneCurrentDBName(pSql); @@ -1072,7 +1094,7 @@ int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pTableNam return TSDB_CODE_TSC_DB_NOT_SELECTED; } - code = tNameFromString(&pTableMetaInfo->name, t, T_NAME_ACCT | T_NAME_DB); + code = tNameFromString(pName, t, T_NAME_ACCT | T_NAME_DB); if (code != 0) { free(t); return TSDB_CODE_TSC_DB_NOT_SELECTED; @@ -1081,15 +1103,15 @@ int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pTableNam free(t); if (pTableName->n >= TSDB_TABLE_NAME_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } char name[TSDB_TABLE_FNAME_LEN] = {0}; strncpy(name, pTableName->z, pTableName->n); - code = tNameFromString(&pTableMetaInfo->name, name, T_NAME_TABLE); + code = tNameFromString(pName, name, T_NAME_TABLE); if (code != 0) { - code = invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + code = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -1110,14 +1132,14 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { // number of fields no less than 2 size_t numOfCols = taosArrayGetSize(pFieldList); if (numOfCols <= 1 || numOfCols > TSDB_MAX_COLUMNS) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); return false; } // first column must be timestamp TAOS_FIELD* pField = taosArrayGet(pFieldList, 0); if (pField->type != TSDB_DATA_TYPE_TIMESTAMP) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return false; } @@ -1125,29 +1147,29 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { for (int32_t i = 0; i < numOfCols; ++i) { pField = taosArrayGet(pFieldList, i); if (!isValidDataType(pField->type)) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); return false; } if (pField->bytes == 0) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); return false; } if ((pField->type == TSDB_DATA_TYPE_BINARY && (pField->bytes <= 0 || pField->bytes > TSDB_MAX_BINARY_LEN)) || (pField->type == TSDB_DATA_TYPE_NCHAR && (pField->bytes <= 0 || pField->bytes > TSDB_MAX_NCHAR_LEN))) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); return false; } if (validateColumnName(pField->name) != TSDB_CODE_SUCCESS) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); return false; } // field name must be unique if (has(pFieldList, i + 1, pField->name) == true) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return false; } @@ -1156,7 +1178,7 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { // max row length must be less than TSDB_MAX_BYTES_PER_ROW if (nLen > TSDB_MAX_BYTES_PER_ROW) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return false; } @@ -1178,7 +1200,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC // number of fields at least 1 size_t numOfTags = taosArrayGetSize(pTagsList); if (numOfTags < 1 || numOfTags > TSDB_MAX_TAGS) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return false; } @@ -1187,28 +1209,28 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC TAOS_FIELD* p = taosArrayGet(pTagsList, i); if (p->type == TSDB_DATA_TYPE_TIMESTAMP) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); return false; } if (!isValidDataType(p->type)) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); return false; } if ((p->type == TSDB_DATA_TYPE_BINARY && p->bytes <= 0) || (p->type == TSDB_DATA_TYPE_NCHAR && p->bytes <= 0)) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); return false; } if (validateColumnName(p->name) != TSDB_CODE_SUCCESS) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); return false; } if (has(pTagsList, i + 1, p->name) == true) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return false; } } @@ -1217,7 +1239,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC for (int32_t i = 0; i < numOfTags; ++i) { TAOS_FIELD* p = taosArrayGet(pTagsList, i); if (p->bytes == 0) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); return false; } @@ -1226,7 +1248,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC // max tag row length must be less than TSDB_MAX_TAGS_LEN if (nLen > TSDB_MAX_TAGS_LEN) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return false; } @@ -1235,7 +1257,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC TAOS_FIELD* p = taosArrayGet(pTagsList, i); if (has(pFieldList, 0, p->name) == true) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return false; } } @@ -1254,9 +1276,7 @@ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { const char* msg5 = "invalid binary/nchar tag length"; const char* msg6 = "invalid data type in tags"; - assert(pCmd->numOfClause == 1); - - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfTags = tscGetNumOfTags(pTableMeta); @@ -1267,18 +1287,18 @@ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { char msg[128] = {0}; sprintf(msg, "tags no more than %d", TSDB_MAX_TAGS); - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); return false; } // no timestamp allowable if (pTagField->type == TSDB_DATA_TYPE_TIMESTAMP) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return false; } if ((pTagField->type < TSDB_DATA_TYPE_BOOL) || (pTagField->type > TSDB_DATA_TYPE_UBIGINT)) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); return false; } @@ -1291,19 +1311,19 @@ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { // length less than TSDB_MAX_TASG_LEN if (nLen + pTagField->bytes > TSDB_MAX_TAGS_LEN) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return false; } // tags name can not be a keyword if (validateColumnName(pTagField->name) != TSDB_CODE_SUCCESS) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); return false; } // binary(val), val can not be equalled to or less than 0 if ((pTagField->type == TSDB_DATA_TYPE_BINARY || pTagField->type == TSDB_DATA_TYPE_NCHAR) && pTagField->bytes <= 0) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); return false; } @@ -1312,7 +1332,7 @@ bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { for (int32_t i = 0; i < numOfTags + numOfCols; ++i) { if (strncasecmp(pTagField->name, pSchema[i].name, sizeof(pTagField->name) - 1) == 0) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return false; } } @@ -1328,8 +1348,8 @@ bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { const char* msg5 = "invalid column name"; const char* msg6 = "invalid column length"; - assert(pCmd->numOfClause == 1); - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); +// assert(pCmd->numOfClause == 1); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfTags = tscGetNumOfTags(pTableMeta); @@ -1337,17 +1357,17 @@ bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { // no more max columns if (numOfCols >= TSDB_MAX_COLUMNS || numOfTags + numOfCols >= TSDB_MAX_COLUMNS) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return false; } if (pColField->type < TSDB_DATA_TYPE_BOOL || pColField->type > TSDB_DATA_TYPE_UBIGINT) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); return false; } if (validateColumnName(pColField->name) != TSDB_CODE_SUCCESS) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); return false; } @@ -1359,20 +1379,20 @@ bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) { } if (pColField->bytes <= 0) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); return false; } // length less than TSDB_MAX_BYTES_PER_ROW if (nLen + pColField->bytes > TSDB_MAX_BYTES_PER_ROW) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return false; } // 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) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return false; } } @@ -1424,7 +1444,7 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr /* db name is not specified, the tableName dose not include db name */ if (pDB != NULL) { if (pDB->n >= TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } memcpy(&fullName[totalLen], pDB->z, pDB->n); @@ -1438,12 +1458,12 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr /* here we only check the table name length limitation */ if (!tscValidateTableNameLength(tableName->n)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } else { // pDB == NULL, the db prefix name is specified in tableName /* the length limitation includes tablename + dbname + sep */ if (tableName->n >= TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -1459,7 +1479,7 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr fullName[totalLen] = 0; } - return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL; + return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_OPERATION; } void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t tableUid) { @@ -1477,7 +1497,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 int32_t arithmeticType = NON_ARITHMEIC_EXPR; if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } int32_t tableIndex = columnList.ids[0].tableIndex; @@ -1487,15 +1507,15 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 // all columns in arithmetic expression must belong to the same table for (int32_t f = 1; f < columnList.num; ++f) { if (columnList.ids[f].tableIndex != tableIndex) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } } // expr string is set as the parameter of function SColumnIndex index = {.tableIndex = tableIndex}; - SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double), - getNewResColId(pQueryInfo), sizeof(double), false); + SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double), + getNewResColId(pCmd), sizeof(double), false); char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->token.z; size_t len = MIN(sizeof(pExpr->base.aliasName), pItem->pNode->token.n + 1); @@ -1508,7 +1528,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 if (ret != TSDB_CODE_SUCCESS) { taosArrayDestroy(colList); tExprTreeDestroy(pNode, NULL); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } // check for if there is a tag in the arithmetic express @@ -1519,7 +1539,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 tExprTreeDestroy(pNode, NULL); taosArrayDestroy(colList); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -1537,7 +1557,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 char* c = tbufGetData(&bw, false); // set the serialized binary string as the parameter of arithmetic expression - addExprParams(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len); + tscExprAddParams(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len); insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->base.aliasName, pExpr); // add ts column @@ -1550,40 +1570,37 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 columnList.num = 0; columnList.ids[0] = (SColumnIndex) {0, 0}; + char rawName[TSDB_COL_NAME_LEN] = {0}; char aliasName[TSDB_COL_NAME_LEN] = {0}; - if (pItem->aliasName != NULL) { - tstrncpy(aliasName, pItem->aliasName, TSDB_COL_NAME_LEN); - } else { - int32_t nameLen = MIN(TSDB_COL_NAME_LEN, pItem->pNode->token.n + 1); - tstrncpy(aliasName, pItem->pNode->token.z, nameLen); - } + getColumnName(pItem, aliasName, rawName, TSDB_COL_NAME_LEN); insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, aliasName, NULL); int32_t slot = tscNumOfFields(pQueryInfo) - 1; SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot); + assert(pInfo->pExpr == NULL); - if (pInfo->pExpr == NULL) { - SExprInfo* pExprInfo = calloc(1, sizeof(SExprInfo)); + SExprInfo* pExprInfo = calloc(1, sizeof(SExprInfo)); - // arithmetic expression always return result in the format of double float - pExprInfo->base.resBytes = sizeof(double); - pExprInfo->base.interBytes = sizeof(double); - pExprInfo->base.resType = TSDB_DATA_TYPE_DOUBLE; + // arithmetic expression always return result in the format of double float + pExprInfo->base.resBytes = sizeof(double); + pExprInfo->base.interBytes = sizeof(double); + pExprInfo->base.resType = TSDB_DATA_TYPE_DOUBLE; - pExprInfo->base.functionId = TSDB_FUNC_ARITHM; - pExprInfo->base.numOfParams = 1; - pExprInfo->base.resColId = getNewResColId(pQueryInfo); + pExprInfo->base.functionId = TSDB_FUNC_ARITHM; + pExprInfo->base.numOfParams = 1; + pExprInfo->base.resColId = getNewResColId(pCmd); + strncpy(pExprInfo->base.aliasName, aliasName, tListLen(pExprInfo->base.aliasName)); + strncpy(pExprInfo->base.token, rawName, tListLen(pExprInfo->base.token)); - int32_t ret = exprTreeFromSqlExpr(pCmd, &pExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &(pExprInfo->base.uid)); - if (ret != TSDB_CODE_SUCCESS) { - tExprTreeDestroy(pExprInfo->pExpr, NULL); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause"); - } - - pInfo->pExpr = pExprInfo; + int32_t ret = exprTreeFromSqlExpr(pCmd, &pExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &(pExprInfo->base.uid)); + if (ret != TSDB_CODE_SUCCESS) { + tExprTreeDestroy(pExprInfo->pExpr, NULL); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause"); } + pInfo->pExpr = pExprInfo; + SBufferWriter bw = tbufInitWriter(NULL, false); TRY(0) { @@ -1605,8 +1622,8 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 return TSDB_CODE_SUCCESS; } -static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSqlExprItem* pItem) { - SExprInfo* pExpr = doAddProjectCol(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex); +static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSqlExprItem* pItem, int32_t colId) { + SExprInfo* pExpr = doAddProjectCol(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex, colId); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; @@ -1628,11 +1645,11 @@ static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumn insertResultField(pQueryInfo, startPos, &ids, pExpr->base.resBytes, (int8_t)pExpr->base.resType, pExpr->base.aliasName, pExpr); } -static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) { +static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) { // primary timestamp column has been added already - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { return; } @@ -1645,8 +1662,8 @@ static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) { // add the timestamp column into the output columns SColumnIndex index = {0}; // primary timestamp column info - int32_t numOfCols = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); - tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL); + int32_t numOfCols = (int32_t)tscNumOfExprs(pQueryInfo); + tscAddFuncInSelectClause(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); SInternalField* pSupInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfCols); pSupInfo->visible = false; @@ -1661,17 +1678,33 @@ bool isValidDistinctSql(SQueryInfo* pQueryInfo) { if ((pQueryInfo->type & TSDB_QUERY_TYPE_STABLE_QUERY) != TSDB_QUERY_TYPE_STABLE_QUERY) { return false; } - if (tscQueryTags(pQueryInfo) && tscSqlExprNumOfExprs(pQueryInfo) == 1){ + if (tscQueryTags(pQueryInfo) && tscNumOfExprs(pQueryInfo) == 1){ return true; } return false; } +static bool hasNoneUserDefineExpr(SQueryInfo* pQueryInfo) { + size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList); + for (int32_t i = 0; i < numOfExprs; ++i) { + SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i); + + if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) { + continue; + } + + return true; + } + + return false; +} + int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelNodeList, bool isSTable, bool joinQuery, bool timeWindowQuery) { assert(pSelNodeList != NULL && pCmd != NULL); const char* msg1 = "too many items in selection clause"; + const char* msg2 = "functions or others can not be mixed up"; const char* msg3 = "not support query expression"; const char* msg4 = "only support distinct one tag"; @@ -1679,7 +1712,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS // too many result columns not support order by in query if (taosArrayGetSize(pSelNodeList) > TSDB_MAX_COLUMNS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pQueryInfo->colList == NULL) { @@ -1689,7 +1722,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS bool hasDistinct = false; size_t numOfExpr = taosArrayGetSize(pSelNodeList); for (int32_t i = 0; i < numOfExpr; ++i) { - int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); + int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo); tSqlExprItem* pItem = taosArrayGet(pSelNodeList, i); if (hasDistinct == false) { @@ -1700,18 +1733,18 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS if (type == SQL_NODE_SQLFUNCTION) { pItem->pNode->functionId = isValidFunction(pItem->pNode->operand.z, pItem->pNode->operand.n); if (pItem->pNode->functionId < 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } // sql function in selection clause, append sql function info in pSqlCmd structure sequentially if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } else if (type == SQL_NODE_TABLE_COLUMN || type == SQL_NODE_VALUE) { // use the dynamic array list to decide if the function is valid or not // select table_name1.field_name1, table_name2.field_name2 from table_name1, table_name2 if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } else if (type == SQL_NODE_EXPR) { int32_t code = handleArithmeticExpr(pCmd, pQueryInfo, i, pItem); @@ -1719,29 +1752,29 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS return code; } } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } if (hasDistinct == true) { if (!isValidDistinctSql(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } pQueryInfo->distinctTag = true; } // there is only one user-defined column in the final result field, add the timestamp column. size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList); - if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) { - addPrimaryTsColIntoResult(pQueryInfo); + if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) { + addPrimaryTsColIntoResult(pQueryInfo, pCmd); } if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } return TSDB_CODE_SUCCESS; @@ -1770,7 +1803,7 @@ int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnLi return TSDB_CODE_SUCCESS; } -SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex) { +SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex, int32_t colId) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta); @@ -1787,18 +1820,16 @@ SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tab index.columnIndex = colIndex; } - int16_t colId = getNewResColId(pQueryInfo); - return tscSqlExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes, colId, pSchema->bytes, + return tscExprAppend(pQueryInfo, functionId, &index, pSchema->type, pSchema->bytes, colId, pSchema->bytes, (functionId == TSDB_FUNC_TAGPRJ)); } SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, - SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) { - int16_t colId = getNewResColId(pQueryInfo); - - SExprInfo* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type, + SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag, int16_t colId) { + SExprInfo* pExpr = tscExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type, pColSchema->bytes, colId, pColSchema->bytes, TSDB_COL_IS_TAG(flag)); tstrncpy(pExpr->base.aliasName, pColSchema->name, sizeof(pExpr->base.aliasName)); + tstrncpy(pExpr->base.token, pColSchema->name, sizeof(pExpr->base.token)); SColumnList ids = createColumnList(1, pIndex->tableIndex, pIndex->columnIndex); if (TSDB_COL_IS_TAG(flag)) { @@ -1817,7 +1848,7 @@ SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColInd return pExpr; } -static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) { +static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos, SSqlCmd* pCmd) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); int32_t numOfTotalColumns = 0; @@ -1833,7 +1864,7 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum } for (int32_t j = 0; j < numOfTotalColumns; ++j) { - SExprInfo* pExpr = doAddProjectCol(pQueryInfo, j, pIndex->tableIndex); + SExprInfo* pExpr = doAddProjectCol(pQueryInfo, j, pIndex->tableIndex, getNewResColId(pCmd)); tstrncpy(pExpr->base.aliasName, pSchema[j].name, sizeof(pExpr->base.aliasName)); pIndex->columnIndex = j; @@ -1851,7 +1882,7 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t const char* msg0 = "invalid column name"; const char* msg1 = "tag for normal table query is not allowed"; - int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); + int32_t startPos = (int32_t)tscNumOfExprs(pQueryInfo); int32_t optr = pItem->pNode->tokenId; if (optr == TK_ALL) { // project on all fields @@ -1859,18 +1890,18 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getTableIndexByName(&pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } // all meters columns are required if (index.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); + int32_t inc = doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos, pCmd); startPos += inc; } } else { - doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos); + doAddProjectionExprAndResultFields(pQueryInfo, &index, startPos, pCmd); } // add the primary timestamp column even though it is not required by user @@ -1887,7 +1918,7 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->value, &pItem->pNode->token, pItem->aliasName); SExprInfo* pExpr = - tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC); + tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC, getNewResColId(pCmd)); // NOTE: the first parameter is reserved for the tag column id during join query process. pExpr->base.numOfParams = 2; @@ -1896,32 +1927,34 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { SSchema* colSchema = tGetTbnameColumnSchema(); - tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, colSchema, TSDB_COL_TAG); + tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, colSchema, TSDB_COL_TAG, getNewResColId(pCmd)); } else if (index.columnIndex == TSDB_BLOCK_DIST_COLUMN_INDEX) { SSchema colSchema = tGetBlockDistColumnSchema(); - tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_TAG); + tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_TAG, getNewResColId(pCmd)); } else { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - addProjectQueryCol(pQueryInfo, startPos, &index, pItem); + addProjectQueryCol(pQueryInfo, startPos, &index, 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); - tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); + if (!UTIL_TABLE_IS_TMP_TABLE(pTableMetaInfo)) { + tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); + } } else { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return TSDB_CODE_SUCCESS; @@ -1938,7 +1971,7 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS if (functionID == TSDB_FUNC_SPREAD) { int32_t t1 = pSchema->type; if (t1 == TSDB_DATA_TYPE_BINARY || t1 == TSDB_DATA_TYPE_NCHAR || t1 == TSDB_DATA_TYPE_BOOL) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return -1; } else { type = TSDB_DATA_TYPE_DOUBLE; @@ -1949,7 +1982,7 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS bytes = pSchema->bytes; } - SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, getNewResColId(pQueryInfo), bytes, false); + SExprInfo* pExpr = tscExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, getNewResColId(pCmd), bytes, false); tstrncpy(pExpr->base.aliasName, name, tListLen(pExpr->base.aliasName)); if (cvtFunc.originFuncId == TSDB_FUNC_LAST_ROW && cvtFunc.originFuncId != functionID) { @@ -2003,9 +2036,9 @@ void setResultColName(char* name, tSqlExprItem* pItem, int32_t functionId, SStrT static void updateLastScanOrderIfNeeded(SQueryInfo* pQueryInfo) { if (pQueryInfo->sessionWindow.gap > 0 || tscGroupbyColumn(pQueryInfo)) { - size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExpr = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExpr; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId != TSDB_FUNC_LAST && pExpr->base.functionId != TSDB_FUNC_LAST_DST) { continue; } @@ -2035,7 +2068,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col case TSDB_FUNC_COUNT: { /* more than one parameter for count() function */ if (pItem->pNode->pParam != NULL && taosArrayGetSize(pItem->pNode->pParam) != 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } SExprInfo* pExpr = NULL; @@ -2044,43 +2077,28 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col if (pItem->pNode->pParam != NULL) { tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->pParam, 0); SStrToken* pToken = &pParamElem->pNode->colInfo; - int16_t sqlOptr = pParamElem->pNode->tokenId; - if ((pToken->z == NULL || pToken->n == 0) - && (TK_INTEGER != sqlOptr)) /*select count(1) from table*/ { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + int16_t tokenId = pParamElem->pNode->tokenId; + if ((pToken->z == NULL || pToken->n == 0) && (TK_INTEGER != tokenId)) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } - if (sqlOptr == TK_ALL) { - // select table.* + // select count(table.*) + // select count(1)|count(2) + if (tokenId == TK_ALL || tokenId == TK_INTEGER) { // check if the table name is valid or not SStrToken tmpToken = pParamElem->pNode->colInfo; if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false); - } else if (sqlOptr == TK_INTEGER) { // select count(1) from table1 - char buf[8] = {0}; - int64_t val = -1; - tVariant* pVariant = &pParamElem->pNode->value; - if (pVariant->nType == TSDB_DATA_TYPE_BIGINT) { - tVariantDump(pVariant, buf, TSDB_DATA_TYPE_BIGINT, true); - val = GET_INT64_VAL(buf); - } - if (val == 1) { - index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false); - } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); - } + pExpr = tscExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, false); } else { - // count the number of meters created according to the super table + // count the number of table created according to the super table if (getColumnIndexByName(pCmd, pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); @@ -2093,18 +2111,18 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, isTag); + pExpr = tscExprAppend(pQueryInfo, functionId, &index, 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}; int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false); + pExpr = tscExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pCmd), size, false); } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); - getColumnName(pItem, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1); + getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token,sizeof(pExpr->base.aliasName) - 1); SColumnList list = createColumnList(1, index.tableIndex, index.columnIndex); if (finalResult) { @@ -2143,21 +2161,21 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col if (pItem->pNode->pParam == NULL || (functionId != TSDB_FUNC_LEASTSQR && taosArrayGetSize(pItem->pNode->pParam) != 1) || (functionId == TSDB_FUNC_LEASTSQR && taosArrayGetSize(pItem->pNode->pParam) != 3)) { /* no parameters or more than one parameter for function */ - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->pParam, 0); if (pParamElem->pNode->tokenId != TK_ALL && pParamElem->pNode->tokenId != TK_ID) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } SColumnIndex index = COLUMN_INDEX_INITIALIZER; if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } // 2. check if sql function can be applied on this column data type @@ -2165,9 +2183,9 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); if (!IS_NUMERIC_TYPE(pSchema->type)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && functionId == TSDB_FUNC_DIFF) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); } int16_t resultType = 0; @@ -2176,15 +2194,15 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col if (getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize, &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // set the first column ts for diff query if (functionId == TSDB_FUNC_DIFF) { colIndex += 1; SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; - SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, - getNewResColId(pQueryInfo), TSDB_KEYSIZE, false); + SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, + getNewResColId(pCmd), TSDB_KEYSIZE, false); SColumnList ids = createColumnList(1, 0, 0); insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].name, pExpr); @@ -2192,32 +2210,32 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // functions can not be applied to tags if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); + SExprInfo* pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), resultSize, false); if (functionId == TSDB_FUNC_LEASTSQR) { /* set the leastsquares parameters */ char val[8] = {0}; if (tVariantDump(&pParamElem[1].pNode->value, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } - addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES); + tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES); memset(val, 0, tListLen(val)); if (tVariantDump(&pParamElem[2].pNode->value, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } - addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); + tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); } SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); - getColumnName(pItem, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1); + getColumnName(pItem, pExpr->base.aliasName, pExpr->base.token,sizeof(pExpr->base.aliasName) - 1); if (finalResult) { int32_t numOfOutput = tscNumOfFields(pQueryInfo); @@ -2246,18 +2264,18 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col if (!requireAllFields) { if (taosArrayGetSize(pItem->pNode->pParam) < 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (taosArrayGetSize(pItem->pNode->pParam) > 1 && (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); } /* in first/last function, multiple columns can be add to resultset */ for (int32_t i = 0; i < taosArrayGetSize(pItem->pNode->pParam); ++i) { tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->pParam, i); if (pParamElem->pNode->tokenId != TK_ALL && pParamElem->pNode->tokenId != TK_ID) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } SColumnIndex index = COLUMN_INDEX_INITIALIZER; @@ -2266,7 +2284,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SStrToken tmpToken = pParamElem->pNode->colInfo; if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); @@ -2279,20 +2297,20 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col setResultColName(name, pItem, cvtFunc.originFuncId, &t, true); if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult) != 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } } else { if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); // functions can not be applied to tags if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } char name[TSDB_COL_NAME_LEN] = {0}; @@ -2302,7 +2320,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->colInfo, multiColOutput); if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex++, &index, finalResult) != 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } } @@ -2313,7 +2331,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // multicolumn selection does not support alias name if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); } for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) { @@ -2328,7 +2346,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col setResultColName(name, pItem, cvtFunc.originFuncId, &t, true); if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult) != 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } colIndex++; } @@ -2347,21 +2365,21 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // 1. valid the number of parameters if (pItem->pNode->pParam == NULL || taosArrayGetSize(pItem->pNode->pParam) != 2) { /* no parameters or more than one parameter for function */ - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->pParam, 0); if (pParamElem->pNode->tokenId != TK_ID) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); @@ -2369,17 +2387,17 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // functions can not be applied to tags if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } // 2. valid the column type if (!IS_NUMERIC_TYPE(pSchema->type)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } // 3. valid the parameters if (pParamElem[1].pNode->tokenId == TK_ID) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } tVariant* pVariant = &pParamElem[1].pNode->value; @@ -2395,7 +2413,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col double dp = GET_DOUBLE_VAL(val); if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } resultSize = sizeof(double); @@ -2409,20 +2427,20 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); colIndex += 1; // the first column is ts - pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); - addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); + pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), resultSize, false); + tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); } else { tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true); int64_t nTop = GET_INT32_VAL(val); if (nTop <= 0 || nTop > 100) { // todo use macro - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } // todo REFACTOR // set the first column ts for top/bottom query SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pQueryInfo), + pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pCmd), TSDB_KEYSIZE, false); tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->base.aliasName)); @@ -2433,12 +2451,12 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col colIndex += 1; // the first column is ts - pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); - addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); + pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), resultSize, false); + tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); } memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); - getColumnName(pItem, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1); + 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); @@ -2456,12 +2474,12 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col case TSDB_FUNC_TID_TAG: { pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } // no parameters or more than one parameter for function if (pItem->pNode->pParam == NULL || taosArrayGetSize(pItem->pNode->pParam) != 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } tSqlExprItem* pParamItem = taosArrayGet(pItem->pNode->pParam, 0); @@ -2469,7 +2487,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pParam->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); @@ -2478,7 +2496,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // functions can not be applied to normal columns int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } if (index.columnIndex > 0) { @@ -2494,7 +2512,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } if (colType == TSDB_DATA_TYPE_BOOL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, @@ -2519,14 +2537,14 @@ 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); + tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TID_TAG, &index, &s, TSDB_COL_TAG, getNewResColId(pCmd)); return TSDB_CODE_SUCCESS; } case TSDB_FUNC_BLKINFO: { // no parameters or more than one parameter for function if (pItem->pNode->pParam != NULL && taosArrayGetSize(pItem->pNode->pParam) != 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } SColumnIndex index = {.tableIndex = 0, .columnIndex = TSDB_BLOCK_DIST_COLUMN_INDEX,}; @@ -2540,7 +2558,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col s.bytes = bytes; s.type = (uint8_t)resType; - SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, &s, TSDB_COL_TAG); + SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, &s, TSDB_COL_TAG, getNewResColId(pCmd)); pExpr->base.numOfParams = 1; pExpr->base.param[0].i64 = pTableMetaInfo->pTableMeta->tableInfo.rowSize; pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; @@ -2549,7 +2567,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } default: - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -2568,12 +2586,14 @@ static SColumnList createColumnList(int32_t num, int16_t tableIndex, int32_t col return columnList; } -void getColumnName(tSqlExprItem* pItem, char* resultFieldName, int32_t nameLength) { +void getColumnName(tSqlExprItem* pItem, char* resultFieldName, char* rawName, int32_t nameLength) { + int32_t len = ((int32_t)pItem->pNode->token.n < nameLength) ? (int32_t)pItem->pNode->token.n : nameLength; + strncpy(rawName, pItem->pNode->token.z, len); + if (pItem->aliasName != NULL) { - strncpy(resultFieldName, pItem->aliasName, nameLength); + strncpy(resultFieldName, pItem->aliasName, len); } else { - int32_t len = ((int32_t)pItem->pNode->token.n < nameLength) ? (int32_t)pItem->pNode->token.n : nameLength; - strncpy(resultFieldName, pItem->pNode->token.z, len); + strncpy(resultFieldName, rawName, len); } } @@ -2634,7 +2654,7 @@ int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQu if (colIndex != COLUMN_INDEX_INITIAL_VAL) { if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } else { pIndex->tableIndex = i; pIndex->columnIndex = colIndex; @@ -2649,14 +2669,14 @@ int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQu } if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } if (COLUMN_INDEX_VALIDE(*pIndex)) { return TSDB_CODE_SUCCESS; } else { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -2682,7 +2702,7 @@ int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColum } if (pIndex->tableIndex < 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return TSDB_CODE_SUCCESS; @@ -2693,7 +2713,7 @@ int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIn extractTableNameFromToken(pToken, &tableToken); if (getTableIndexImpl(&tableToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return TSDB_CODE_SUCCESS; @@ -2701,13 +2721,13 @@ int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIn int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex) { if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } SStrToken tmpToken = *pToken; if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex); @@ -2715,8 +2735,7 @@ int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SSqlCmd* pCmd = &pSql->cmd; - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - assert(pCmd->numOfClause == 1); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); pCmd->command = TSDB_SQL_SHOW; @@ -2739,20 +2758,20 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (pDbPrefixToken->type != 0) { if (pDbPrefixToken->n >= TSDB_DB_NAME_LEN) { // db name is too long - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (pDbPrefixToken->n <= 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } if (tscValidateName(pDbPrefixToken) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pDbPrefixToken); if (ret != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -2762,26 +2781,26 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { pPattern->n = strdequote(pPattern->z); if (pPattern->n <= 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } if (!tscValidateTableNameLength(pCmd->payloadLen)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } } else if (showType == TSDB_MGMT_TABLE_VNODES) { if (pShowInfo->prefix.type == 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode"); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "No specified ip of dnode"); } // show vnodes may be ip addr of dnode in payload SStrToken* pDnodeIp = &pShowInfo->prefix; if (pDnodeIp->n >= TSDB_IPv4ADDR_LEN) { // ip addr is too long - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (!validateIpAddress(pDnodeIp->z, pDnodeIp->n)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } } return TSDB_CODE_SUCCESS; @@ -2797,7 +2816,7 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { SStrToken* idStr = &(pInfo->pMiscInfo->id); if (idStr->n > TSDB_KILL_MSG_LEN) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } strncpy(pCmd->payload, idStr->z, idStr->n); @@ -2809,7 +2828,7 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { int32_t connId = (int32_t)strtol(connIdStr, NULL, 10); if (connId <= 0) { memset(pCmd->payload, 0, strlen(pCmd->payload)); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (killType == TSDB_SQL_KILL_CONNECTION) { @@ -2820,9 +2839,9 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { if (queryId <= 0) { memset(pCmd->payload, 0, strlen(pCmd->payload)); if (killType == TSDB_SQL_KILL_QUERY) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -2844,7 +2863,7 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (pTableMetaInfo->pTableMeta == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } assert(tscGetNumOfTags(pTableMetaInfo->pTableMeta) >= 0); @@ -2853,9 +2872,9 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { int16_t type = 0; int32_t interBytes = 0; - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t k = 0; k < size; ++k) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k); + SExprInfo* pExpr = tscExprGet(pQueryInfo, k); int16_t functionId = aAggs[pExpr->base.functionId].stableFuncId; int32_t colIndex = pExpr->base.colInfo.colIndex; @@ -2866,10 +2885,10 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) { if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->base.param[0].i64, &type, &bytes, &interBytes, 0, true) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } - tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->base.colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes); + tscExprUpdate(pQueryInfo, k, functionId, pExpr->base.colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes); // todo refactor pExpr->base.interBytes = interBytes; } @@ -2886,9 +2905,9 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { return; } - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 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. @@ -2919,33 +2938,33 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) const char* msg3 = "function not support for super table query"; // filter sql function not supported by metric query yet. - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; + int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId; if ((aAggs[functionId].status & TSDB_FUNCSTATE_STABLE) == 0) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return true; } } if (tscIsTWAQuery(pQueryInfo)) { if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return true; } if (pQueryInfo->groupbyExpr.numOfGroupCols != 1) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return true; } else { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0); if (pColIndex->colIndex != TSDB_TBNAME_COLUMN_INDEX) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return true; } } } else if (tscIsSessionWindowQuery(pQueryInfo)) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return true; } @@ -2972,10 +2991,10 @@ static bool groupbyTagsOrNull(SQueryInfo* pQueryInfo) { static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool twQuery) { int32_t startIdx = 0; - size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExpr = tscNumOfExprs(pQueryInfo); assert(numOfExpr > 0); - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, startIdx); + SExprInfo* pExpr = tscExprGet(pQueryInfo, startIdx); // ts function can be simultaneously used with any other functions. int32_t functionID = pExpr->base.functionId; @@ -2983,18 +3002,18 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool startIdx++; } - int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->base.functionId]; + int32_t factor = functionCompatList[tscExprGet(pQueryInfo, startIdx)->base.functionId]; - if (tscSqlExprGet(pQueryInfo, 0)->base.functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) { + if (tscExprGet(pQueryInfo, 0)->base.functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) { return false; } // diff function cannot be executed with other function // arithmetic function can be executed with other arithmetic functions - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = startIdx + 1; i < size; ++i) { - SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr1 = tscExprGet(pQueryInfo, i); int16_t functionId = pExpr1->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) { @@ -3043,11 +3062,11 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd pQueryInfo->groupbyExpr.numOfGroupCols = (int16_t)taosArrayGetSize(pList); if (pQueryInfo->groupbyExpr.numOfGroupCols > TSDB_MAX_TAGS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pQueryInfo->numOfTables > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } STableMeta* pTableMeta = NULL; @@ -3064,13 +3083,13 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &token, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } if (tableIndex == COLUMN_INDEX_INITIAL_VAL) { tableIndex = index.tableIndex; } else if (tableIndex != index.tableIndex) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); @@ -3088,14 +3107,14 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd groupTag = true; } - SSqlGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr; + SGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr; if (pGroupExpr->columnInfo == NULL) { pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex)); } if (groupTag) { if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); } int32_t relIndex = index.columnIndex; @@ -3104,6 +3123,7 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd } SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, }; + strncpy(colIndex.name, pSchema->name, tListLen(colIndex.name)); taosArrayPush(pGroupExpr->columnInfo, &colIndex); index.columnIndex = relIndex; @@ -3111,17 +3131,19 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd } else { // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); } tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; + strncpy(colIndex.name, pSchema->name, tListLen(colIndex.name)); + taosArrayPush(pGroupExpr->columnInfo, &colIndex); pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC; if (i == 0 && num > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } } } @@ -3200,7 +3222,7 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, } if (retVal != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } switch (pExpr->tokenId) { @@ -3232,7 +3254,7 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, pColumnFilter->lowerRelOptr = TSDB_RELATION_NOTNULL; break; default: - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } return TSDB_CODE_SUCCESS; @@ -3260,7 +3282,7 @@ static int32_t tablenameListToString(tSqlExpr* pExpr, SStringBuilder* sb) { int32_t size = (int32_t) taosArrayGetSize(pList); if (size <= 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (size > 0) { @@ -3278,7 +3300,7 @@ static int32_t tablenameListToString(tSqlExpr* pExpr, SStringBuilder* sb) { } if (pVar->nLen <= 0 || !tscValidateTableNameLength(pVar->nLen)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -3334,7 +3356,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC return TSDB_CODE_TSC_OUT_OF_MEMORY; } } else { // error; - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } pColFilter->filterstr = @@ -3347,17 +3369,17 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC && pExpr->tokenId != TK_NOTNULL && pExpr->tokenId != TK_LIKE ) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } else { if (pExpr->tokenId == TK_LIKE) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } 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) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } } @@ -3381,7 +3403,7 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* tSqlExpr* pRight = pTableCond->pRight; if (!isTablenameToken(&pLeft->colInfo)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t ret = TSDB_CODE_SUCCESS; @@ -3390,14 +3412,14 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* ret = tablenameListToString(pRight, sb); } else if (pTableCond->tokenId == TK_LIKE) { if (pRight->tokenId != TK_STRING) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } ret = tablenameCondToString(pRight, sb); } if (ret != TSDB_CODE_SUCCESS) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } return ret; @@ -3418,7 +3440,7 @@ static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSq } else { // handle leaf node SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return extractColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr); @@ -3447,7 +3469,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); @@ -3457,7 +3479,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS SJoinNode **leftNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; if (*leftNode == NULL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } (*leftNode)->uid = pTableMetaInfo->pTableMeta->id.uid; @@ -3471,7 +3493,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema1); if (taosArrayGetSize(pTableMetaInfo->tagColList) > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } } @@ -3480,7 +3502,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS index = (SColumnIndex)COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); @@ -3490,7 +3512,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; if (*rightNode == NULL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } (*rightNode)->uid = pTableMetaInfo->pTableMeta->id.uid; @@ -3503,7 +3525,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema2); if (taosArrayGetSize(pTableMetaInfo->tagColList) > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } } @@ -3511,7 +3533,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS int16_t rightIdx = index.tableIndex; if (pTagSchema1->type != pTagSchema2->type) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if ((*leftNode)->tagJoin == NULL) { @@ -3545,12 +3567,12 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer if (*type == NON_ARITHMEIC_EXPR) { *type = NORMAL_ARITHMETIC; } else if (*type == AGG_ARIGHTMEIC) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pExpr->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql @@ -3559,21 +3581,21 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer if ((pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || (pSchema->type == TSDB_DATA_TYPE_BOOL) || (pSchema->type == TSDB_DATA_TYPE_BINARY) || (pSchema->type == TSDB_DATA_TYPE_NCHAR)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } pList->ids[pList->num++] = index; } else if ((pExpr->tokenId == TK_FLOAT && (isnan(pExpr->value.dKey) || isinf(pExpr->value.dKey))) || pExpr->tokenId == TK_NULL) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } else if (pExpr->type == SQL_NODE_SQLFUNCTION) { if (*type == NON_ARITHMEIC_EXPR) { *type = AGG_ARIGHTMEIC; } else if (*type == NORMAL_ARITHMETIC) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } - int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); + int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo); tSqlExprItem item = {.pNode = pExpr, .aliasName = NULL}; @@ -3581,32 +3603,32 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer // Append the sqlExpr into exprList of pQueryInfo structure sequentially pExpr->functionId = isValidFunction(pExpr->operand.z, pExpr->operand.n); if (pExpr->functionId < 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // It is invalid in case of more than one sqlExpr, such as first(ts, k) - last(ts, k) - int32_t inc = (int32_t) tscSqlExprNumOfExprs(pQueryInfo) - outputIndex; + int32_t inc = (int32_t) tscNumOfExprs(pQueryInfo) - outputIndex; if (inc > 1) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // Not supported data type in arithmetic expression uint64_t id = -1; for(int32_t i = 0; i < inc; ++i) { - SExprInfo* p1 = tscSqlExprGet(pQueryInfo, i + outputIndex); + SExprInfo* p1 = tscExprGet(pQueryInfo, i + outputIndex); int16_t t = p1->base.resType; if (t == TSDB_DATA_TYPE_BINARY || t == TSDB_DATA_TYPE_NCHAR || t == TSDB_DATA_TYPE_BOOL || t == TSDB_DATA_TYPE_TIMESTAMP) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (i == 0) { id = p1->base.uid; } else if (id != p1->base.uid) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -3651,7 +3673,7 @@ static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryI // the expression not from the same table, return error if (uidLeft != uidRight && uidLeft != 0 && uidRight != 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -3735,14 +3757,14 @@ static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr } if (pExpr->tokenId != TK_EQ) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return false; } SColumnIndex rightIndex = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &rightIndex) != TSDB_CODE_SUCCESS) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return false; } @@ -3751,21 +3773,25 @@ static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr SSchema* pLeftSchema = tscGetTableSchema(pLeftMeterMeta->pTableMeta); int16_t leftType = pLeftSchema[pLeftIndex->columnIndex].type; + tscColumnListInsert(pQueryInfo->colList, pLeftIndex->columnIndex, pLeftMeterMeta->pTableMeta->id.uid, &pLeftSchema[pLeftIndex->columnIndex]); + STableMetaInfo* pRightMeterMeta = tscGetMetaInfo(pQueryInfo, rightIndex.tableIndex); SSchema* pRightSchema = tscGetTableSchema(pRightMeterMeta->pTableMeta); int16_t rightType = pRightSchema[rightIndex.columnIndex].type; + tscColumnListInsert(pQueryInfo->colList, rightIndex.columnIndex, pRightMeterMeta->pTableMeta->id.uid, &pRightSchema[rightIndex.columnIndex]); + if (leftType != rightType) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return false; } else if (pLeftIndex->tableIndex == rightIndex.tableIndex) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); return false; } // table to table/ super table to super table are allowed if (UTIL_TABLE_IS_SUPER_TABLE(pLeftMeterMeta) != UTIL_TABLE_IS_SUPER_TABLE(pRightMeterMeta)) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); return false; } @@ -3787,7 +3813,7 @@ static bool validTableNameOptr(tSqlExpr* pExpr) { static int32_t setExprToCond(tSqlExpr** parent, tSqlExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) { if (*parent != NULL) { if (parentOptr == TK_OR && msg != NULL) { - return invalidSqlErrMsg(msgBuf, msg); + return invalidOperationMsg(msgBuf, msg); } *parent = tSqlExprCreate((*parent), pExpr, parentOptr); @@ -3803,7 +3829,7 @@ static int32_t validateNullExpr(tSqlExpr* pExpr, char* msgBuf) { tSqlExpr* pRight = pExpr->pRight; if (pRight->tokenId == TK_NULL && (!(pExpr->tokenId == TK_ISNULL || pExpr->tokenId == TK_NOTNULL))) { - return invalidSqlErrMsg(msgBuf, msg); + return invalidOperationMsg(msgBuf, msg); } return TSDB_CODE_SUCCESS; @@ -3819,12 +3845,12 @@ static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t if (pExpr->tokenId == TK_LIKE) { if (pRight->value.nLen > TSDB_PATTERN_STRING_MAX_LEN) { - return invalidSqlErrMsg(msgBuf, msg1); + return invalidOperationMsg(msgBuf, msg1); } SSchema* pSchema = tscGetTableSchema(pTableMeta); if ((!isTablenameToken(&pLeft->colInfo)) && !IS_VAR_DATA_TYPE(pSchema[index].type)) { - return invalidSqlErrMsg(msgBuf, msg2); + return invalidOperationMsg(msgBuf, msg2); } } @@ -3848,7 +3874,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } assert(tSqlExprIsParentOfLeaf(*pExpr)); @@ -3870,7 +3896,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql if (index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // query on time range if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // set join query condition @@ -3890,11 +3916,11 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql int16_t leftIdx = index.tableIndex; if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } if (index.tableIndex < 0 || index.tableIndex >= TSDB_MAX_JOIN_TABLE_NUM) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } SJoinNode **rightNode = &pQueryInfo->tagCond.joinInfo.joinTables[index.tableIndex]; @@ -3919,7 +3945,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql taosArrayPush((*rightNode)->tsJoin, &leftIdx); /* - * to release expression, e.g., m1.ts = m2.ts, + * To release expression, e.g., m1.ts = m2.ts, * since this expression is used to set the join query type */ tSqlExprDestroy(*pExpr); @@ -3932,17 +3958,17 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } else if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) || index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { // query on tags, check for tag query condition if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } // in case of in operator, keep it in a seprate attribute if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { if (!validTableNameOptr(*pExpr)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pCondExpr->pTableCond == NULL) { @@ -3950,7 +3976,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql pCondExpr->relType = parentOptr; pCondExpr->tableCondIndex = index.tableIndex; } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } *type = TSQL_EXPR_TBNAME; @@ -3958,7 +3984,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } else { if (pRight != NULL && pRight->tokenId == TK_ID) { // join on tag columns for stable query if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY; @@ -3977,7 +4003,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql *type = TSQL_EXPR_COLUMN; if (pRight->tokenId == TK_ID) { // other column cannot be served as the join column - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } ret = setExprToCond(&pCondExpr->pColumnCond, *pExpr, NULL, parentOptr, pQueryInfo->msg); @@ -3996,14 +4022,14 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr const char* msg1 = "query condition between different columns must use 'AND'"; if ((*pExpr)->flags & (1 << EXPR_FLAG_TS_ERROR)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } tSqlExpr* pLeft = (*pExpr)->pLeft; tSqlExpr* pRight = (*pExpr)->pRight; if (!isValidExpr(pLeft, pRight, (*pExpr)->tokenId)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t leftType = -1; @@ -4026,7 +4052,7 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr */ if (leftType != rightType) { if ((*pExpr)->tokenId == TK_OR && (leftType + rightType != TSQL_EXPR_TBNAME + TSQL_EXPR_TAG)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -4037,11 +4063,11 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr exchangeExpr(*pExpr); if (pLeft->tokenId == TK_ID && pRight->tokenId == TK_TIMESTAMP && (pRight->flags & (1 << EXPR_FLAG_TIMESTAMP_VAR))) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if ((pLeft->flags & (1 << EXPR_FLAG_TS_ERROR)) || (pRight->flags & (1 << EXPR_FLAG_TS_ERROR))) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr); @@ -4153,7 +4179,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, taosStringBuilderDestroy(&sb1); tfree(segments); - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); return ret; } @@ -4208,7 +4234,7 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE if (!tSqlExprIsParentOfLeaf(pExpr)) { if (pExpr->tokenId == TK_OR) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } code = getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pLeft); @@ -4220,7 +4246,7 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE } else { SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); @@ -4230,7 +4256,7 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX}; if (getTimeRange(&win, pRight, pExpr->tokenId, tinfo.precision) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } // update the timestamp query range @@ -4255,7 +4281,7 @@ static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr if (pQueryInfo->numOfTables == 1) { return TSDB_CODE_SUCCESS; } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -4263,12 +4289,12 @@ static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // for stable join, tag columns // must be present for join if (pCondExpr->pJoinExpr == NULL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } if (!pCondExpr->tsJoin) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } return TSDB_CODE_SUCCESS; @@ -4339,7 +4365,7 @@ static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) { } if (IS_ARITHMETIC_OPTR(p->_node.optr)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (!IS_RELATION_OPTR(p->_node.optr)) { @@ -4397,7 +4423,7 @@ static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) { } if (retVal != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } while (0); @@ -4458,7 +4484,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE taosArrayDestroy(colList); if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table"); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table"); } if (ret) { @@ -4478,7 +4504,7 @@ int32_t validateJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; if (node == NULL || node->tsJoin == NULL || taosArrayGetSize(node->tsJoin) <= 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); } } @@ -4488,7 +4514,7 @@ int32_t validateJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; if (node == NULL || node->tagJoin == NULL || taosArrayGetSize(node->tagJoin) <= 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2); } } } @@ -4536,7 +4562,7 @@ int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { } if (taosArrayGetSize(pQueryInfo->tagCond.joinInfo.joinTables[0]->tsJoin) != pQueryInfo->numOfTables) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -4557,7 +4583,7 @@ int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { } if (taosArrayGetSize(pQueryInfo->tagCond.joinInfo.joinTables[0]->tagJoin) != pQueryInfo->numOfTables) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2); } } @@ -4581,7 +4607,7 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq SCondExpr condExpr = {0}; if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); } int32_t type = 0; @@ -4634,7 +4660,7 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq } if (!validateFilterExpr(pQueryInfo)) { - ret = invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2); + ret = invalidOperationMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2); goto PARSE_WHERE_EXIT; } @@ -4668,7 +4694,7 @@ int32_t getTimeRange(STimeWindow* win, tSqlExpr* pRight, int32_t optr, int16_t t * where ts in ('2015-12-12 4:8:12') */ if (pRight->tokenId == TK_SET || optr == TK_IN) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } int64_t val = 0; @@ -4681,14 +4707,14 @@ int32_t getTimeRange(STimeWindow* win, tSqlExpr* pRight, int32_t optr, int16_t t if (taosParseTime(pRight->value.pz, &val, pRight->value.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) { parsed = true; } else { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } else { SStrToken token = {.z = pRight->value.pz, .n = pRight->value.nLen, .type = TK_ID}; - int32_t len = tSQLGetToken(pRight->value.pz, &token.type); + int32_t len = tGetToken(pRight->value.pz, &token.type); if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->value.nLen) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } } else if (pRight->tokenId == TK_INTEGER && timePrecision == TSDB_TIME_PRECISION_MILLI) { @@ -4769,7 +4795,7 @@ int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { for (int32_t j = i + 1; j < pQueryInfo->fieldsInfo.numOfOutput; ++j) { if (strncasecmp(fieldName, tscFieldInfoGetField(&pQueryInfo->fieldsInfo, j)->name, (TSDB_COL_NAME_LEN - 1)) == 0) { const char* msg = "duplicated column name in new table"; - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } } } @@ -4794,7 +4820,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo const char* msg5 = "fill only available for interval query"; if ((!isTimeWindowQuery(pQueryInfo)) && (!tscIsPointInterpQuery(pQueryInfo))) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } /* @@ -4802,12 +4828,12 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo * the columns may be increased due to group by operation */ if (checkQueryRangeForFill(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } size_t numOfFields = tscNumOfFields(pQueryInfo); @@ -4838,7 +4864,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo size_t num = taosArrayGetSize(pFillToken); if (num == 1) { // no actual value, return with error code - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } int32_t startPos = 1; @@ -4868,7 +4894,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo tVariant* p = taosArrayGet(pFillToken, j); int32_t ret = tVariantDump(p, (char*)&pQueryInfo->fillVal[i], pField->type, true); if (ret != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } } @@ -4886,14 +4912,14 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo } } } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_TOP || pExpr->base.functionId == TSDB_FUNC_BOTTOM) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -4947,11 +4973,11 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq size_t size = taosArrayGetSize(pSortorder); if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { if (size > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } } else { if (size > 2) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -4968,7 +4994,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // super table query if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } bool orderByTags = false; @@ -4979,7 +5005,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq // it is a tag column if (pQueryInfo->groupbyExpr.columnInfo == NULL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0); if (relTagIndex == pColIndex->colIndex) { @@ -4994,7 +5020,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } if (!(orderByTags || orderByTS) && !isTopBottomQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } else { // order by top/bottom result value column is not supported in case of interval query. assert(!(orderByTags && orderByTS)); } @@ -5008,12 +5034,12 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq pQueryInfo->groupbyExpr.orderType = p1->sortOrder; } else if (isTopBottomQuery(pQueryInfo)) { /* order of top/bottom query in interval is not valid */ - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + SExprInfo* pExpr = tscExprGet(pQueryInfo, 0); assert(pExpr->base.functionId == TSDB_FUNC_TS); - pExpr = tscSqlExprGet(pQueryInfo, 1); + pExpr = tscExprGet(pQueryInfo, 1); if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); @@ -5028,7 +5054,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq // orderby ts query on super table if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { - addPrimaryTsColIntoResult(pQueryInfo); + addPrimaryTsColIntoResult(pQueryInfo, pCmd); } } } @@ -5047,11 +5073,11 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq tVariant* pVar2 = &pItem->pVar; SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz}; if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } else { tVariantListItem* p1 = taosArrayGet(pSortorder, 1); pQueryInfo->order.order = p1->sortOrder; @@ -5061,21 +5087,21 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } else { // meter query if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX && !isTopBottomQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } if (isTopBottomQuery(pQueryInfo)) { /* order of top/bottom query in interval is not valid */ - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + SExprInfo* pExpr = tscExprGet(pQueryInfo, 0); assert(pExpr->base.functionId == TSDB_FUNC_TS); - pExpr = tscSqlExprGet(pQueryInfo, 1); + pExpr = tscExprGet(pQueryInfo, 1); if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); @@ -5121,15 +5147,15 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SSqlCmd* pCmd = &pSql->cmd; SAlterTableInfo* pAlterSQL = pInfo->pAlterInfo; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, DEFAULT_TABLE_INDEX); if (tscValidateName(&(pAlterSQL->name)) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - code = tscSetTableFullName(pTableMetaInfo, &(pAlterSQL->name), pSql); + code = tscSetTableFullName(&pTableMetaInfo->name, &(pAlterSQL->name), pSql); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -5142,60 +5168,60 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; if (pAlterSQL->tableType == TSDB_SUPER_TABLE && !(UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg20); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg20); } if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) { if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) && (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo))) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } else if ((pAlterSQL->type == TSDB_ALTER_TABLE_ADD_COLUMN || pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) && UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } if (pAlterSQL->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) { SArray* pFieldList = pAlterSQL->pAddColumns; if (taosArrayGetSize(pFieldList) > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } TAOS_FIELD* p = taosArrayGet(pFieldList, 0); if (!validateOneTags(pCmd, p)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p); } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) { if (tscGetNumOfTags(pTableMeta) == 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } // numOfTags == 1 if (taosArrayGetSize(pAlterSQL->varList) > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); } tVariantListItem* pItem = taosArrayGet(pAlterSQL->varList, 0); if (pItem->pVar.nLen >= TSDB_COL_NAME_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); } SColumnIndex index = COLUMN_INDEX_INITIALIZER; SStrToken name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen, .type = TK_STRING}; if (getColumnIndexByName(pCmd, &name, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t numOfCols = tscGetNumOfColumns(pTableMeta); if (index.columnIndex < numOfCols) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg10); } else if (index.columnIndex == numOfCols) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11); } char name1[128] = {0}; @@ -5206,18 +5232,18 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { } else if (pAlterSQL->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) { SArray* pVarList = pAlterSQL->varList; if (taosArrayGetSize(pVarList) > 2) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } tVariantListItem* pSrcItem = taosArrayGet(pAlterSQL->varList, 0); tVariantListItem* pDstItem = taosArrayGet(pAlterSQL->varList, 1); if (pSrcItem->pVar.nLen >= TSDB_COL_NAME_LEN || pDstItem->pVar.nLen >= TSDB_COL_NAME_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); } if (pSrcItem->pVar.nType != TSDB_DATA_TYPE_BINARY || pDstItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg10); } SColumnIndex srcIndex = COLUMN_INDEX_INITIALIZER; @@ -5225,12 +5251,12 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SStrToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING}; if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg17); } SStrToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING}; if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg19); } tVariantListItem* pItem = taosArrayGet(pVarList, 0); @@ -5258,11 +5284,11 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER; SStrToken name = {.type = TK_STRING, .z = item->pVar.pz, .n = item->pVar.nLen}; if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (columnIndex.columnIndex < tscGetNumOfColumns(pTableMeta)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg12); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg12); } tVariantListItem* pItem = taosArrayGet(pVarList, 1); @@ -5270,7 +5296,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { pAlterSQL->tagData.data = calloc(1, pTagsSchema->bytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE); if (tVariantDump(&pItem->pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg13); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg13); } pAlterSQL->tagData.dataLen = pTagsSchema->bytes; @@ -5278,7 +5304,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { // validate the length of binary if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) && varDataTLen(pAlterSQL->tagData.data) > pTagsSchema->bytes) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg14); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg14); } int32_t schemaLen = sizeof(STColumn) * numOfTags; @@ -5333,23 +5359,23 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SArray* pFieldList = pAlterSQL->pAddColumns; if (taosArrayGetSize(pFieldList) > 1) { const char* msg = "only support add one column"; - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } TAOS_FIELD* p = taosArrayGet(pFieldList, 0); if (!validateOneColumn(pCmd, p)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } tscFieldInfoAppend(&pQueryInfo->fieldsInfo, p); } else if (pAlterSQL->type == TSDB_ALTER_TABLE_DROP_COLUMN) { if (tscGetNumOfColumns(pTableMeta) == TSDB_MIN_COLUMNS) { // - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg15); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg15); } size_t size = taosArrayGetSize(pAlterSQL->varList); if (size > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg16); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg16); } tVariantListItem* pItem = taosArrayGet(pAlterSQL->varList, 0); @@ -5357,11 +5383,11 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER; SStrToken name = {.type = TK_STRING, .z = pItem->pVar.pz, .n = pItem->pVar.nLen}; if (getColumnIndexByName(pCmd, &name, pQueryInfo, &columnIndex) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg17); } if (columnIndex.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg18); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg18); } char name1[TSDB_COL_NAME_LEN] = {0}; @@ -5380,14 +5406,14 @@ int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { if (pQueryInfo->interval.interval != 0 && pQueryInfo->interval.interval < 10 && pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit != 'y') { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - int32_t functId = tscSqlExprGet(pQueryInfo, i)->base.functionId; + int32_t functId = tscExprGet(pQueryInfo, i)->base.functionId; if (!IS_STREAM_QUERY_VALID(aAggs[functId].status)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -5402,13 +5428,13 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t k = 0; k < size; ++k) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k); + SExprInfo* pExpr = tscExprGet(pQueryInfo, k); // 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) { bool hasSelectivity = false; for (int32_t j = 0; j < size; ++j) { - SExprInfo* pEx = tscSqlExprGet(pQueryInfo, j); + SExprInfo* pEx = tscExprGet(pQueryInfo, j); if ((aAggs[pEx->base.functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) { hasSelectivity = true; break; @@ -5427,10 +5453,10 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu } if (isProjectionFunction) { - invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_SQL : TSDB_CODE_SUCCESS; + return isProjectionFunction == true ? TSDB_CODE_TSC_INVALID_OPERATION : TSDB_CODE_SUCCESS; } typedef struct SDNodeDynConfOption { @@ -5447,12 +5473,12 @@ int32_t validateEp(char* ep) { if (NULL == pos) { int32_t val = strtol(ep, NULL, 10); if (val <= 0 || val > 65536) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } else { uint16_t port = atoi(pos + 1); if (0 == port) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -5463,7 +5489,7 @@ int32_t validateDNodeConfig(SMiscInfo* pOptions) { int32_t numOfToken = (int32_t) taosArrayGetSize(pOptions->a); if (numOfToken < 2 || numOfToken > 3) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } const int tokenLogEnd = 2; @@ -5498,7 +5524,7 @@ int32_t validateDNodeConfig(SMiscInfo* pOptions) { strdequote(pValToken->z); bool parseOk = taosCheckBalanceCfgOptions(pValToken->z, &vnodeId, &dnodeId); if (!parseOk) { - return TSDB_CODE_TSC_INVALID_SQL; // options value is invalid + return TSDB_CODE_TSC_INVALID_OPERATION; // options value is invalid } return TSDB_CODE_SUCCESS; } else if ((strncasecmp(cfgOptions[tokenMonitor].name, pOptionToken->z, pOptionToken->n) == 0) && @@ -5506,7 +5532,7 @@ int32_t validateDNodeConfig(SMiscInfo* pOptions) { SStrToken* pValToken = taosArrayGet(pOptions->a, 2); int32_t val = strtol(pValToken->z, NULL, 10); if (val != 0 && val != 1) { - return TSDB_CODE_TSC_INVALID_SQL; // options value is invalid + return TSDB_CODE_TSC_INVALID_OPERATION; // options value is invalid } return TSDB_CODE_SUCCESS; } else { @@ -5515,7 +5541,7 @@ int32_t validateDNodeConfig(SMiscInfo* pOptions) { int32_t val = strtol(pValToken->z, NULL, 10); if (val < 0 || val > 256) { /* options value is out of valid range */ - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } for (int32_t i = tokenDebugFlag; i < tokenDebugFlagEnd; ++i) { @@ -5528,13 +5554,13 @@ int32_t validateDNodeConfig(SMiscInfo* pOptions) { } } - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t validateLocalConfig(SMiscInfo* pOptions) { int32_t numOfToken = (int32_t) taosArrayGetSize(pOptions->a); if (numOfToken < 1 || numOfToken > 2) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } SDNodeDynConfOption LOCAL_DYNAMIC_CFG_OPTIONS[6] = {{"resetLog", 8}, {"rpcDebugFlag", 12}, {"tmrDebugFlag", 12}, @@ -5557,7 +5583,7 @@ int32_t validateLocalConfig(SMiscInfo* pOptions) { int32_t val = strtol(pValToken->z, NULL, 10); if (!validateDebugFlag(val)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } for (int32_t i = 1; i < tListLen(LOCAL_DYNAMIC_CFG_OPTIONS); ++i) { @@ -5568,20 +5594,20 @@ int32_t validateLocalConfig(SMiscInfo* pOptions) { } } } - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t validateColumnName(char* name) { - bool ret = isKeyWord(name, (int32_t)strlen(name)); + bool ret = taosIsKeyWordToken(name, (int32_t)strlen(name)); if (ret) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } SStrToken token = {.z = name}; - token.n = tSQLGetToken(name, &token.type); + token.n = tGetToken(name, &token.type); if (token.type != TK_STRING && token.type != TK_ID) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (token.type == TK_STRING) { @@ -5589,15 +5615,15 @@ int32_t validateColumnName(char* name) { strntolower(token.z, token.z, token.n); token.n = (uint32_t)strtrim(token.z); - int32_t k = tSQLGetToken(token.z, &token.type); + int32_t k = tGetToken(token.z, &token.type); if (k != token.n) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return validateColumnName(token.z); } else { if (isNumber(&token)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -5616,7 +5642,7 @@ bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) { return !(pQueryInfo->window.skey != pQueryInfo->window.ekey && pQueryInfo->interval.interval == 0); } -int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIndex, SSqlNode* pSqlNode, SSqlObj* pSql) { +int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSqlObj* pSql) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); const char* msg0 = "soffset/offset can not be less than 0"; @@ -5632,7 +5658,7 @@ int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseI pQueryInfo->limit.limit, pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset); if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0); } if (pQueryInfo->limit.limit == 0) { @@ -5646,7 +5672,7 @@ int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseI if (!tscQueryTags(pQueryInfo)) { // local handle the super table tag query if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) { if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } // for projection query on super table, all queries are subqueries @@ -5669,10 +5695,7 @@ int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseI * And then launching multiple async-queries against all qualified virtual nodes, during the first-stage * query operation. */ - int32_t code = tscGetSTableVgroupInfo(pSql, clauseIndex); - if (code != TSDB_CODE_SUCCESS) { - return code; - } +// assert(allVgroupInfoRetrieved(pQueryInfo)); // No tables included. No results generated. Query results are empty. if (pTableMetaInfo->vgroupList->numOfVgroups == 0) { @@ -5702,7 +5725,7 @@ int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseI } } else { if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -5740,7 +5763,7 @@ static int32_t setKeepOption(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDbInfo* p pMsg->daysToKeep2 = htonl((int32_t)p2->pVar.i64); break; } - default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); } + default: { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } } } @@ -5764,7 +5787,7 @@ static int32_t setTimePrecision(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDbInfo strlen(TSDB_TIME_PRECISION_MICRO_STR) == pToken->n) { pMsg->precision = TSDB_TIME_PRECISION_MICRO; } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } } @@ -5796,30 +5819,30 @@ int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDbInfo* pCreateDbSql) { setCreateDBOption(pMsg, pCreateDbSql); if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (setTimePrecision(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (tscCheckCreateDbParams(pCmd, pMsg) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return TSDB_CODE_SUCCESS; } void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) { - SQueryInfo* pParentQueryInfo = tscGetQueryInfo(&pParentObj->cmd, subClauseIndex); + SQueryInfo* pParentQueryInfo = tscGetQueryInfo(&pParentObj->cmd); if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, subClauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); SExprInfo* pExpr = NULL; size_t size = taosArrayGetSize(pQueryInfo->exprList); if (size > 0) { - pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1); + pExpr = tscExprGet(pQueryInfo, (int32_t)size - 1); } if (pExpr == NULL || pExpr->base.functionId != TSDB_FUNC_TAG) { @@ -5836,7 +5859,7 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau int16_t type = pTagSchema->type; int16_t bytes = pTagSchema->bytes; - pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(pQueryInfo), bytes, true); + pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(&pSql->cmd), bytes, true); pExpr->base.colInfo.flag = TSDB_COL_TAG; // NOTE: tag column does not add to source column list @@ -5861,16 +5884,19 @@ static void doLimitOutputNormalColOfGroupby(SExprInfo* pExpr) { pExpr->base.numOfParams = 1; } -void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) { +void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex, SSqlCmd* pCmd) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex); - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->colIndex); SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pColIndex->colIndex}; - tscAddFuncInSelectClause(pQueryInfo, (int32_t)size, TSDB_FUNC_PRJ, &colIndex, pSchema, TSDB_COL_NORMAL); + SExprInfo* pExprInfo = tscAddFuncInSelectClause(pQueryInfo, (int32_t)size, TSDB_FUNC_PRJ, &colIndex, pSchema, + TSDB_COL_NORMAL, getNewResColId(pCmd)); + + strncpy(pExprInfo->base.token, pExprInfo->base.colInfo.name, tListLen(pExprInfo->base.token)); int32_t numOfFields = tscNumOfFields(pQueryInfo); SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfFields - 1); @@ -5888,7 +5914,7 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ || pExpr->base.functionId == TSDB_FUNC_TAG) { pExpr->base.functionId = TSDB_FUNC_TAG_DUMMY; tagLength += pExpr->base.resBytes; @@ -5901,7 +5927,7 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); 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))) { SSchema* pColSchema = &pSchema[pExpr->base.colInfo.colIndex]; @@ -5915,7 +5941,7 @@ static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_PRJ && (!TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag) && (pExpr->base.colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX))) { bool qualifiedCol = false; @@ -5932,7 +5958,7 @@ static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { // it is not a tag column/tbname column/user-defined column, return error if (!qualifiedCol) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } } @@ -5940,7 +5966,7 @@ static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { return TSDB_CODE_SUCCESS; } -static bool tagColumnInGroupby(SSqlGroupbyExpr* pGroupbyExpr, int16_t columnId) { +static bool tagColumnInGroupby(SGroupbyExpr* pGroupbyExpr, int16_t columnId) { for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) { SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j); @@ -5958,7 +5984,7 @@ static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_PRJ) { hasColumnPrj = true; } else if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ) { @@ -5973,9 +5999,9 @@ static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) { static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) { bool allInGroupby = true; - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId != TSDB_FUNC_TAGPRJ) { continue; } @@ -5994,7 +6020,7 @@ static void updateTagPrjFunction(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ) { pExpr->base.functionId = TSDB_FUNC_TAG; } @@ -6045,7 +6071,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) // 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) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } /* @@ -6064,7 +6090,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) * Otherwise, return with error code. */ for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); int16_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ || (aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == 0) { continue; @@ -6074,7 +6100,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) (functionId == TSDB_FUNC_LAST_DST && (pExpr->base.colInfo.flag & TSDB_COL_NULL) != 0)) { // do nothing } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -6087,7 +6113,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) } else { if ((pQueryInfo->type & TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0) { if (numOfAggregation > 0 && pQueryInfo->groupbyExpr.numOfGroupCols == 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (numOfAggregation > 0 || numOfSelectivity > 0) { @@ -6132,15 +6158,16 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo } } - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); if (TSDB_COL_IS_TAG(pColIndex->flag)) { SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; - SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, s->type, s->bytes, - getNewResColId(pQueryInfo), s->bytes, true); + SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, s->type, s->bytes, + getNewResColId(pCmd), s->bytes, true); memset(pExpr->base.aliasName, 0, sizeof(pExpr->base.aliasName)); tstrncpy(pExpr->base.aliasName, s->name, sizeof(pExpr->base.aliasName)); + tstrncpy(pExpr->base.token, s->name, sizeof(pExpr->base.aliasName)); pExpr->base.colInfo.flag = TSDB_COL_TAG; @@ -6150,12 +6177,12 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo } else { // if this query is "group by" normal column, time window query is not allowed if (isTimeWindowQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } bool hasGroupColumn = false; for (int32_t j = 0; j < size; ++j) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, j); + SExprInfo* pExpr = tscExprGet(pQueryInfo, j); if ((pExpr->base.functionId == TSDB_FUNC_PRJ) && pExpr->base.colInfo.colId == pColIndex->colId) { hasGroupColumn = true; break; @@ -6164,7 +6191,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo //if the group by column does not required by user, add an invisible column into the final result set. if (!hasGroupColumn) { - doAddGroupColumnForSubquery(pQueryInfo, i); + doAddGroupColumnForSubquery(pQueryInfo, i, pCmd); } } } @@ -6176,10 +6203,10 @@ static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) { bool tagProjection = false; bool tableCounting = false; - int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + int32_t numOfCols = (int32_t) tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfCols; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); int32_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ) { @@ -6206,17 +6233,17 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { // only retrieve tags, group by is not supportted if (tscQueryTags(pQueryInfo)) { if (doTagFunctionCheck(pQueryInfo) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || isTimeWindowQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } else { return TSDB_CODE_SUCCESS; } } - if (tscIsProjectionQuery(pQueryInfo) && pQueryInfo->sessionWindow.gap > 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + if (tscIsProjectionQuery(pQueryInfo) && tscIsSessionWindowQuery(pQueryInfo)) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { @@ -6228,9 +6255,9 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { } // check all query functions in selection clause, multi-output functions are not allowed - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); int32_t functId = pExpr->base.functionId; /* @@ -6248,31 +6275,31 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { } if (!qualified) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } if (IS_MULTIOUTPUT(aAggs[functId].status) && functId != TSDB_FUNC_TOP && functId != TSDB_FUNC_BOTTOM && functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_PRJ) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (functId == TSDB_FUNC_COUNT && pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } if (checkUpdateTagPrjFunctions(pQueryInfo, pCmd) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // projection query on super table does not compatible with "group by" syntax if (tscIsProjectionQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } return TSDB_CODE_SUCCESS; @@ -6288,7 +6315,7 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq SArray* pExprList = pSqlNode->pSelNodeList; size_t size = taosArrayGetSize(pExprList); if (size != 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } bool server_status = false; @@ -6299,7 +6326,7 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (pExpr->token.n == 1 && 0 == strncasecmp(pExpr->token.z, "1", 1)) { server_status = true; } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } // TODO redefine the function @@ -6333,12 +6360,12 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq pQueryInfo->command = TSDB_SQL_CLI_VERSION;break; case 4: pQueryInfo->command = TSDB_SQL_CURRENT_USER;break; - default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } + default: { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } SColumnIndex ind = {0}; - SExprInfo* pExpr1 = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT, - tDataTypes[TSDB_DATA_TYPE_INT].bytes, getNewResColId(pQueryInfo), tDataTypes[TSDB_DATA_TYPE_INT].bytes, false); + 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); tSqlExprItem* item = taosArrayGet(pExprList, 0); const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[index].name; @@ -6353,69 +6380,69 @@ int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) { if (pCreate->walLevel != -1 && (pCreate->walLevel < TSDB_MIN_WAL_LEVEL || pCreate->walLevel > TSDB_MAX_WAL_LEVEL)) { snprintf(msg, tListLen(msg), "invalid db option walLevel: %d, only 1-2 allowed", pCreate->walLevel); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } if (pCreate->replications != -1 && (pCreate->replications < TSDB_MIN_DB_REPLICA_OPTION || pCreate->replications > TSDB_MAX_DB_REPLICA_OPTION)) { snprintf(msg, tListLen(msg), "invalid db option replications: %d valid range: [%d, %d]", pCreate->replications, TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } if (pCreate->quorum != -1 && (pCreate->quorum < TSDB_MIN_DB_QUORUM_OPTION || pCreate->quorum > TSDB_MAX_DB_QUORUM_OPTION)) { snprintf(msg, tListLen(msg), "invalid db option quorum: %d valid range: [%d, %d]", pCreate->quorum, TSDB_MIN_DB_QUORUM_OPTION, TSDB_MAX_DB_QUORUM_OPTION); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } int32_t val = htonl(pCreate->daysPerFile); if (val != -1 && (val < TSDB_MIN_DAYS_PER_FILE || val > TSDB_MAX_DAYS_PER_FILE)) { snprintf(msg, tListLen(msg), "invalid db option daysPerFile: %d valid range: [%d, %d]", val, TSDB_MIN_DAYS_PER_FILE, TSDB_MAX_DAYS_PER_FILE); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } val = htonl(pCreate->cacheBlockSize); if (val != -1 && (val < TSDB_MIN_CACHE_BLOCK_SIZE || val > TSDB_MAX_CACHE_BLOCK_SIZE)) { snprintf(msg, tListLen(msg), "invalid db option cacheBlockSize: %d valid range: [%d, %d]", val, TSDB_MIN_CACHE_BLOCK_SIZE, TSDB_MAX_CACHE_BLOCK_SIZE); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } val = htonl(pCreate->maxTables); if (val != -1 && (val < TSDB_MIN_TABLES || val > TSDB_MAX_TABLES)) { snprintf(msg, tListLen(msg), "invalid db option maxSessions: %d valid range: [%d, %d]", val, TSDB_MIN_TABLES, TSDB_MAX_TABLES); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } if (pCreate->precision != TSDB_TIME_PRECISION_MILLI && pCreate->precision != TSDB_TIME_PRECISION_MICRO) { snprintf(msg, tListLen(msg), "invalid db option timePrecision: %d valid value: [%d, %d]", pCreate->precision, TSDB_TIME_PRECISION_MILLI, TSDB_TIME_PRECISION_MICRO); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } val = htonl(pCreate->commitTime); if (val != -1 && (val < TSDB_MIN_COMMIT_TIME || val > TSDB_MAX_COMMIT_TIME)) { snprintf(msg, tListLen(msg), "invalid db option commitTime: %d valid range: [%d, %d]", val, TSDB_MIN_COMMIT_TIME, TSDB_MAX_COMMIT_TIME); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } val = htonl(pCreate->fsyncPeriod); if (val != -1 && (val < TSDB_MIN_FSYNC_PERIOD || val > TSDB_MAX_FSYNC_PERIOD)) { snprintf(msg, tListLen(msg), "invalid db option fsyncPeriod: %d valid range: [%d, %d]", val, TSDB_MIN_FSYNC_PERIOD, TSDB_MAX_FSYNC_PERIOD); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } if (pCreate->compression != -1 && (pCreate->compression < TSDB_MIN_COMP_LEVEL || pCreate->compression > TSDB_MAX_COMP_LEVEL)) { snprintf(msg, tListLen(msg), "invalid db option compression: %d valid range: [%d, %d]", pCreate->compression, TSDB_MIN_COMP_LEVEL, TSDB_MAX_COMP_LEVEL); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } val = (int16_t)htons(pCreate->partitions); @@ -6423,7 +6450,7 @@ int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) { (val < TSDB_MIN_DB_PARTITON_OPTION || val > TSDB_MAX_DB_PARTITON_OPTION)) { snprintf(msg, tListLen(msg), "invalid topic option partition: %d valid range: [%d, %d]", val, TSDB_MIN_DB_PARTITON_OPTION, TSDB_MAX_DB_PARTITON_OPTION); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg); } @@ -6432,9 +6459,9 @@ int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) { // for debug purpose void tscPrintSelNodeList(SSqlObj* pSql, int32_t subClauseIndex) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, subClauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); - int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); + int32_t size = (int32_t)tscNumOfExprs(pQueryInfo); if (size == 0) { return; } @@ -6446,7 +6473,7 @@ void tscPrintSelNodeList(SSqlObj* pSql, int32_t subClauseIndex) { offset += sprintf(str, "num:%d [", size); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); char tmpBuf[1024] = {0}; int32_t tmpLen = 0; @@ -6474,7 +6501,7 @@ int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* p const char* msg1 = "invalid table name"; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; @@ -6488,17 +6515,17 @@ int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* p SStrToken* pzTableName = &(pCreateTable->name); if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - int32_t code = tscSetTableFullName(pTableMetaInfo, pzTableName, pSql); + int32_t code = tscSetTableFullName(&pTableMetaInfo->name, pzTableName, pSql); if(code != TSDB_CODE_SUCCESS) { return code; } if (!validateTableColumnInfo(pFieldList, pCmd) || (pTagList != NULL && !validateTagParams(pTagList, pFieldList, pCmd))) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t col = 0; @@ -6533,7 +6560,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { SSqlCmd* pCmd = &pSql->cmd; SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); // two table: the first one is for current table, and the secondary is for the super table. if (pQueryInfo->numOfTables < 2) { @@ -6552,10 +6579,10 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { SStrToken* pToken = &pCreateTableInfo->stableName; if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - int32_t code = tscSetTableFullName(pStableMetaInfo, pToken, pSql); + int32_t code = tscSetTableFullName(&pStableMetaInfo->name, pToken, pSql); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -6591,12 +6618,12 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { if (valSize != nameSize) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } if (schemaSize < valSize) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } bool findColumnIndex = false; @@ -6620,7 +6647,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) { if (pItem->pVar.nLen > pSchema->bytes) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -6631,13 +6658,13 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { int16_t len = varDataTLen(tagVal); if (len > pSchema->bytes) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } if (ret != TSDB_CODE_SUCCESS) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal); @@ -6655,7 +6682,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { } else { if (schemaSize != valSize) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } for (int32_t i = 0; i < valSize; ++i) { @@ -6666,7 +6693,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) { if (pItem->pVar.nLen > pSchema->bytes) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -6677,13 +6704,13 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { int16_t len = varDataTLen(tagVal); if (len > pSchema->bytes) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } if (ret != TSDB_CODE_SUCCESS) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal); @@ -6707,11 +6734,11 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { // table name if (tscValidateName(&(pCreateTableInfo->name)) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX); - ret = tscSetTableFullName(pTableMetaInfo, &pCreateTableInfo->name, pSql); + ret = tscSetTableFullName(&pTableMetaInfo->name, &pCreateTableInfo->name, pSql); if (ret != TSDB_CODE_SUCCESS) { return ret; } @@ -6719,7 +6746,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { pCreateTableInfo->fullname = calloc(1, tNameLen(&pTableMetaInfo->name) + 1); ret = tNameExtractFullName(&pTableMetaInfo->name, pCreateTableInfo->fullname); if (ret != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -6736,7 +6763,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { const char* msg7 = "time interval is required"; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); assert(pQueryInfo->numOfTables == 1); SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; @@ -6747,21 +6774,21 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { SSqlNode* pSqlNode = pCreateTable->pSelect; if (tscValidateName(pName) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } SRelationInfo* pFromInfo = pInfo->pCreateTableInfo->pSelect->from; if (pFromInfo == NULL || taosArrayGetSize(pFromInfo->list) == 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); } - STableNamePair* p1 = taosArrayGet(pFromInfo->list, 0); - SStrToken srcToken = {.z = p1->name.z, .n = p1->name.n, .type = TK_STRING}; + SRelElementPair* p1 = taosArrayGet(pFromInfo->list, 0); + SStrToken srcToken = {.z = p1->tableName.z, .n = p1->tableName.n, .type = TK_STRING}; if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - int32_t code = tscSetTableFullName(pTableMetaInfo, &srcToken, pSql); + int32_t code = tscSetTableFullName(&pTableMetaInfo->name, &srcToken, pSql); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -6773,47 +6800,47 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); if (validateSelectNodeList(&pSql->cmd, pQueryInfo, pSqlNode->pSelNodeList, isSTable, false, false) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pSqlNode->pWhere != NULL) { // query condition in stream computing if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } // set interval value if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } if (!tscIsProjectionQuery(pQueryInfo) && pQueryInfo->interval.interval == 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } // set the created table[stream] name - code = tscSetTableFullName(pTableMetaInfo, pName, pSql); + code = tscSetTableFullName(&pTableMetaInfo->name, pName, pSql); if (code != TSDB_CODE_SUCCESS) { return code; } if (pSqlNode->sqlstr.n > TSDB_MAX_SAVED_SQL_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } if (tsRewriteFieldNameIfNecessary(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput; if (validateSqlFunctionInStreamSql(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } /* @@ -6822,14 +6849,14 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { */ if (pSqlNode->fillType != NULL) { if (pQueryInfo->interval.interval == 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } tVariantListItem* pItem = taosArrayGet(pSqlNode->fillType, 0); if (pItem->pVar.nType == TSDB_DATA_TYPE_BINARY) { if (!((strncmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) || (strncmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4))) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } } } @@ -6848,7 +6875,7 @@ int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER); if (initialWindows) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey); @@ -6868,7 +6895,7 @@ int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { } // number of result is not greater than 10,000,000 if ((timeRange == 0) || (timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } return TSDB_CODE_SUCCESS; @@ -6895,9 +6922,9 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect getColumnIndexByName(pCmd, pToken, pQueryInfo, &index); } - size_t numOfNodeInSel = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfNodeInSel = tscNumOfExprs(pQueryInfo); for(int32_t k = 0; k < numOfNodeInSel; ++k) { - SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, k); + SExprInfo* pExpr1 = tscExprGet(pQueryInfo, k); if (pExpr1->base.functionId != functionId) { continue; @@ -6919,17 +6946,17 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect tSqlExprItem item = {.pNode = pSqlExpr, .aliasName = NULL, .distinct = false}; - int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); + int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo); // ADD TRUE FOR TEST if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, true) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } ++pQueryInfo->havingFieldNum; - size_t n = tscSqlExprNumOfExprs(pQueryInfo); - *pExpr = tscSqlExprGet(pQueryInfo, (int32_t)n - 1); + size_t n = tscNumOfExprs(pQueryInfo); + *pExpr = tscExprGet(pQueryInfo, (int32_t)n - 1); SInternalField* pField = taosArrayGet(pQueryInfo->fieldsInfo.internalField, n - 1); pField->visible = false; @@ -6978,7 +7005,7 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, S return TSDB_CODE_TSC_OUT_OF_MEMORY; } } else { // error; - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } pColFilter->filterstr = @@ -6991,16 +7018,16 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, S && pExpr->tokenId != TK_NOTNULL && pExpr->tokenId != TK_LIKE ) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } } else { if (pExpr->tokenId == TK_LIKE) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (expr->base.resType == TSDB_DATA_TYPE_BOOL) { if (pExpr->tokenId != TK_EQ && pExpr->tokenId != TK_NE) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } } @@ -7037,11 +7064,11 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNode } if (pLeft == NULL || pRight == NULL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pLeft->type == pRight->type) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } exchangeExpr(pExpr); @@ -7049,15 +7076,15 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNode pLeft = pExpr->pLeft; pRight = pExpr->pRight; if (pLeft->type != SQL_NODE_SQLFUNCTION) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pRight->type != SQL_NODE_VALUE) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pExpr->tokenId >= TK_BITAND) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pLeft->pParam) { @@ -7071,17 +7098,17 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNode pExpr1->tokenId != TK_STRING && pExpr1->tokenId != TK_INTEGER && pExpr1->tokenId != TK_FLOAT) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pExpr1->tokenId == TK_ID && (pExpr1->colInfo.z == NULL && pExpr1->colInfo.n == 0)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pExpr1->tokenId == TK_ID) { SColumnIndex index = COLUMN_INDEX_INITIALIZER; if ((getColumnIndexByName(pCmd, &pExpr1->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); @@ -7089,7 +7116,7 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNode if (index.columnIndex <= 0 || index.columnIndex >= tscGetNumOfColumns(pTableMeta)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } } } @@ -7097,7 +7124,7 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNode pLeft->functionId = isValidFunction(pLeft->operand.z, pLeft->operand.n); if (pLeft->functionId < 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } return handleExprInHavingClause(pCmd, pQueryInfo, pSelectNodeList, pExpr, parentOptr); @@ -7114,11 +7141,11 @@ int32_t validateHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* p } if (pQueryInfo->groupbyExpr.numOfGroupCols <= 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } if (pExpr->pLeft == NULL || pExpr->pRight == NULL) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } if (pQueryInfo->colList == NULL) { @@ -7133,41 +7160,211 @@ int32_t validateHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* p //REDO function check if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } return TSDB_CODE_SUCCESS; } -static int32_t doLoadAllTableMeta(SSqlObj* pSql, int32_t index, SSqlNode* pSqlNode, int32_t numOfTables) { +static int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, char* msgBuf, SSqlObj* pSql) { + const char* msg1 = "invalid table name"; + + int32_t numOfTables = (int32_t) taosArrayGetSize(pSqlNode->from->list); + assert(pSqlNode->from->type == SQL_NODE_FROM_TABLELIST); + + for(int32_t j = 0; j < numOfTables; ++j) { + SRelElementPair* item = taosArrayGet(pSqlNode->from->list, j); + + SStrToken* t = &item->tableName; + if (t->type == TK_INTEGER || t->type == TK_FLOAT) { + return invalidOperationMsg(msgBuf, msg1); + } + + tscDequoteAndTrimToken(t); + if (tscValidateName(t) != TSDB_CODE_SUCCESS) { + return invalidOperationMsg(msgBuf, msg1); + } + + SName name = {0}; + if (tscSetTableFullName(&name, t, pSql) != TSDB_CODE_SUCCESS) { + return invalidOperationMsg(msgBuf, msg1); + } + + taosArrayPush(tableNameList, &name); + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameList, char* msgBuf, SSqlObj* pSql) { + int32_t numOfSub = (int32_t) taosArrayGetSize(pSqlNode->from->list); + + for(int32_t j = 0; j < numOfSub; ++j) { + SRelElementPair* sub = taosArrayGet(pSqlNode->from->list, j); + + int32_t num = (int32_t)taosArrayGetSize(sub->pSubquery); + for (int32_t i = 0; i < num; ++i) { + SSqlNode* p = taosArrayGetP(sub->pSubquery, i); + if (p->from->type == SQL_NODE_FROM_TABLELIST) { + int32_t code = getTableNameFromSqlNode(p, tableNameList, msgBuf, pSql); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } else { + getTableNameFromSubquery(p, tableNameList, msgBuf, pSql); + } + } + } + + return TSDB_CODE_SUCCESS; +} + +void tscTableMetaCallBack(void *param, TAOS_RES *res, int code); +static void freeElem(void* p) { + tfree(*(char**)p); +} + +int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) { + SSqlCmd* pCmd = &pSql->cmd; + + // the table meta has already been loaded from local buffer or mnode already + if (pCmd->pTableMetaMap != NULL) { + return TSDB_CODE_SUCCESS; + } + + int32_t code = TSDB_CODE_SUCCESS; + + SArray* tableNameList = NULL; + SArray* pVgroupList = NULL; + SArray* plist = NULL; + STableMeta* pTableMeta = NULL; + + pCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); + + tableNameList = taosArrayInit(4, sizeof(SName)); + size_t size = taosArrayGetSize(pInfo->list); + for (int32_t i = 0; i < size; ++i) { + SSqlNode* pSqlNode = taosArrayGetP(pInfo->list, i); + if (pSqlNode->from == NULL) { + goto _end; + } + + // load the table meta in the from clause + if (pSqlNode->from->type == SQL_NODE_FROM_TABLELIST) { + code = getTableNameFromSqlNode(pSqlNode, tableNameList, tscGetErrorMsgPayload(pCmd), pSql); + if (code != TSDB_CODE_SUCCESS) { + goto _end; + } + } else { + code = getTableNameFromSubquery(pSqlNode, tableNameList, tscGetErrorMsgPayload(pCmd), pSql); + if (code != TSDB_CODE_SUCCESS) { + goto _end; + } + } + } + + uint32_t maxSize = tscGetTableMetaMaxSize(); + char name[TSDB_TABLE_FNAME_LEN] = {0}; + + char buf[80 * 1024] = {0}; + assert(maxSize < 80 * 1024); + pTableMeta = calloc(1, maxSize); + + plist = taosArrayInit(4, POINTER_BYTES); + pVgroupList = taosArrayInit(4, POINTER_BYTES); + + size_t numOfTables = taosArrayGetSize(tableNameList); + for (int32_t i = 0; i < numOfTables; ++i) { + SName* pname = taosArrayGet(tableNameList, i); + tNameExtractFullName(pname, name); + + size_t len = strlen(name); + memset(pTableMeta, 0, maxSize); + taosHashGetClone(tscTableMetaInfo, name, len, NULL, pTableMeta, -1); + + if (pTableMeta->id.uid > 0) { + if (pTableMeta->tableType == TSDB_CHILD_TABLE) { + code = tscCreateTableMetaFromSTableMeta(pTableMeta, name, buf); + + // create the child table meta from super table failed, try load it from mnode + if (code != TSDB_CODE_SUCCESS) { + char* t = strdup(name); + taosArrayPush(plist, &t); + continue; + } + } else if (pTableMeta->tableType == TSDB_SUPER_TABLE) { + // the vgroup list of a super table is not kept in local buffer, so here need retrieve it + // from the mnode each time + char* t = strdup(name); + taosArrayPush(pVgroupList, &t); + } + + STableMeta* pMeta = tscTableMetaDup(pTableMeta); + STableMetaVgroupInfo p = { .pTableMeta = pMeta }; + + const char* px = tNameGetTableName(pname); + taosHashPut(pCmd->pTableMetaMap, px, strlen(px), &p, sizeof(STableMetaVgroupInfo)); + } else { // add to the retrieve table meta array list. + char* t = strdup(name); + taosArrayPush(plist, &t); + } + } + + // load the table meta for a given table name list + if (taosArrayGetSize(plist) > 0 || taosArrayGetSize(pVgroupList) > 0) { + code = getMultiTableMetaFromMnode(pSql, plist, pVgroupList, tscTableMetaCallBack); + } + +_end: + if (plist != NULL) { + taosArrayDestroyEx(plist, freeElem); + } + + if (pVgroupList != NULL) { + taosArrayDestroyEx(pVgroupList, freeElem); + } + + if (tableNameList != NULL) { + taosArrayDestroy(tableNameList); + } + + tfree(pTableMeta); + + return code; +} + +static int32_t doLoadAllTableMeta(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, int32_t numOfTables) { const char* msg1 = "invalid table name"; const char* msg2 = "invalid table alias name"; const char* msg3 = "alias name too long"; + const char* msg4 = "self join not allowed"; int32_t code = TSDB_CODE_SUCCESS; - SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, index); + + if (numOfTables > taosHashGetSize(pCmd->pTableMetaMap)) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); + } for (int32_t i = 0; i < numOfTables; ++i) { if (pQueryInfo->numOfTables <= i) { // more than one table tscAddEmptyMetaInfo(pQueryInfo); } - STableNamePair *item = taosArrayGet(pSqlNode->from->list, i); - SStrToken *oriName = &item->name; + SRelElementPair *item = taosArrayGet(pSqlNode->from->list, i); + SStrToken *oriName = &item->tableName; if (oriName->type == TK_INTEGER || oriName->type == TK_FLOAT) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } tscDequoteAndTrimToken(oriName); if (tscValidateName(oriName) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); - code = tscSetTableFullName(pTableMetaInfo, oriName, pSql); + code = tscSetTableFullName(&pTableMetaInfo->name, oriName, pSql); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -7175,25 +7372,29 @@ static int32_t doLoadAllTableMeta(SSqlObj* pSql, int32_t index, SSqlNode* pSqlNo SStrToken* aliasName = &item->aliasName; if (TPARSER_HAS_TOKEN(*aliasName)) { if (aliasName->type == TK_INTEGER || aliasName->type == TK_FLOAT) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } tscDequoteAndTrimToken(aliasName); - if (tscValidateName(aliasName) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); - } - - if (aliasName->n >= TSDB_TABLE_NAME_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + if (tscValidateName(aliasName) != TSDB_CODE_SUCCESS || aliasName->n >= TSDB_TABLE_NAME_LEN) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } strncpy(pTableMetaInfo->aliasName, aliasName->z, aliasName->n); } else { - strncpy(pTableMetaInfo->aliasName, tNameGetTableName(&pTableMetaInfo->name), - tListLen(pTableMetaInfo->aliasName)); + strncpy(pTableMetaInfo->aliasName, tNameGetTableName(&pTableMetaInfo->name), tListLen(pTableMetaInfo->aliasName)); + } + + const char* name = tNameGetTableName(&pTableMetaInfo->name); + STableMetaVgroupInfo* p = taosHashGet(pCmd->pTableMetaMap, name, strlen(name)); + + pTableMetaInfo->pTableMeta = tscTableMetaDup(p->pTableMeta); + assert(pTableMetaInfo->pTableMeta != NULL); + + if (p->pVgroupInfo != NULL) { + pTableMetaInfo->vgroupList = tscVgroupsInfoDup(p->pVgroupInfo); } - code = tscGetTableMeta(pSql, pTableMetaInfo); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -7202,7 +7403,7 @@ static int32_t doLoadAllTableMeta(SSqlObj* pSql, int32_t index, SSqlNode* pSqlNo return TSDB_CODE_SUCCESS; } -static STableMeta* extractTempTableMetaFromNestQuery(SQueryInfo* pUpstream) { +static STableMeta* extractTempTableMetaFromSubquery(SQueryInfo* pUpstream) { int32_t numOfColumns = pUpstream->fieldsInfo.numOfOutput; STableMeta* meta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * numOfColumns); @@ -7227,31 +7428,84 @@ static STableMeta* extractTempTableMetaFromNestQuery(SQueryInfo* pUpstream) { return meta; } -int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { +static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SSqlObj* pSql, SQueryInfo* pQueryInfo, char* msgBuf) { + SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, index); + + // union all is not support currently + SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0); + + SQueryInfo* pSub = calloc(1, sizeof(SQueryInfo)); + tscInitQueryInfo(pSub); + + int32_t code = validateSqlNode(pSql, p, pSub); + assert(code != TSDB_CODE_TSC_ACTION_IN_PROGRESS); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + pSub->pDownstream = pQueryInfo; + + // create dummy table meta info + STableMetaInfo* pTableMetaInfo1 = calloc(1, sizeof(STableMetaInfo)); + pTableMetaInfo1->pTableMeta = extractTempTableMetaFromSubquery(pSub); + + if (subInfo->aliasName.n > 0) { + if (subInfo->aliasName.n >= TSDB_TABLE_FNAME_LEN) { + return invalidOperationMsg(msgBuf, "subquery alias name too long"); + } + + strncpy(pTableMetaInfo1->aliasName, subInfo->aliasName.z, subInfo->aliasName.n); + } + + taosArrayPush(pQueryInfo->pUpstream, &pSub); + + // NOTE: order mix up in subquery not support yet. + pQueryInfo->order = pSub->order; + + STableMetaInfo** tmp = realloc(pQueryInfo->pTableMetaInfo, (pQueryInfo->numOfTables + 1) * POINTER_BYTES); + if (tmp == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + pQueryInfo->pTableMetaInfo = tmp; + + pQueryInfo->pTableMetaInfo[pQueryInfo->numOfTables] = pTableMetaInfo1; + pQueryInfo->numOfTables += 1; + + // all columns are added into the table column list + STableMeta* pMeta = pTableMetaInfo1->pTableMeta; + int32_t startOffset = (int32_t) taosArrayGetSize(pQueryInfo->colList); + + for(int32_t i = 0; i < pMeta->tableInfo.numOfColumns; ++i) { + tscColumnListInsert(pQueryInfo->colList, i + startOffset, pMeta->id.uid, &pMeta->schema[i]); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInfo) { assert(pSqlNode != NULL && (pSqlNode->from == NULL || taosArrayGetSize(pSqlNode->from->list) > 0)); const char* msg1 = "point interpolation query needs timestamp"; const char* msg2 = "too many tables in from clause"; const char* msg3 = "start(end) time of query range required or time range too large"; + const char* msg9 = "only tag query not compatible with normal column filter"; int32_t code = TSDB_CODE_SUCCESS; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, index); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (pTableMetaInfo == NULL) { pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo); } - assert(pCmd->clauseIndex == index); - /* * handle the sql expression without from subclause - * select current_database(); + * select server_status(); * select server_version(); * select client_version(); - * select server_state(); + * select current_database(); */ if (pSqlNode->from == NULL) { assert(pSqlNode->fillType == NULL && pSqlNode->pGroupby == NULL && pSqlNode->pWhere == NULL && @@ -7260,71 +7514,55 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { } if (pSqlNode->from->type == SQL_NODE_FROM_SUBQUERY) { - // parse the subquery in the first place - SArray* list = taosArrayGetP(pSqlNode->from->list, 0); - SSqlNode* p = taosArrayGetP(list, 0); + clearAllTableMetaInfo(pQueryInfo, false); + pQueryInfo->numOfTables = 0; - code = validateSqlNode(pSql, p, 0); - if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { - return code; + // parse the subquery in the first place + int32_t numOfSub = (int32_t) taosArrayGetSize(pSqlNode->from->list); + for(int32_t i = 0; i < numOfSub; ++i) { + code = doValidateSubquery(pSqlNode, i, pSql, pQueryInfo, tscGetErrorMsgPayload(pCmd)); + if (code != TSDB_CODE_SUCCESS) { + return code; + } } - if (code != TSDB_CODE_SUCCESS) { - return code; + if (validateSelectNodeList(pCmd, pQueryInfo, pSqlNode->pSelNodeList, false, false, false) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; } - pQueryInfo = pCmd->pQueryInfo[0]; - - SQueryInfo* current = calloc(1, sizeof(SQueryInfo)); - - tscInitQueryInfo(current); - taosArrayPush(current->pUpstream, &pQueryInfo); - - STableMeta* pTableMeta = extractTempTableMetaFromNestQuery(pQueryInfo); - STableMetaInfo* pTableMetaInfo1 = calloc(1, sizeof(STableMetaInfo)); - pTableMetaInfo1->pTableMeta = pTableMeta; - - current->pTableMetaInfo = calloc(1, POINTER_BYTES); - current->pTableMetaInfo[0] = pTableMetaInfo1; - current->numOfTables = 1; - current->order = pQueryInfo->order; - - pCmd->pQueryInfo[0] = current; - pQueryInfo->pDownstream = current; + if (pSqlNode->pWhere != NULL) { + if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } - if (validateSelectNodeList(pCmd, current, pSqlNode->pSelNodeList, false, false, false) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; + if (pTableMeta->tableInfo.precision == TSDB_TIME_PRECISION_MILLI) { + pQueryInfo->window.skey = pQueryInfo->window.skey / 1000; + pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000; + } } - } else { pQueryInfo->command = TSDB_SQL_SELECT; - size_t fromSize = taosArrayGetSize(pSqlNode->from->list); - if (fromSize > TSDB_MAX_JOIN_TABLE_NUM) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + size_t numOfTables = taosArrayGetSize(pSqlNode->from->list); + if (numOfTables > TSDB_MAX_JOIN_TABLE_NUM) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } // set all query tables, which are maybe more than one. - code = doLoadAllTableMeta(pSql, index, pSqlNode, (int32_t) fromSize); + code = doLoadAllTableMeta(pSql, pQueryInfo, pSqlNode, (int32_t) numOfTables); if (code != TSDB_CODE_SUCCESS) { return code; } bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); - if (isSTable) { - code = tscGetSTableVgroupInfo(pSql, index); // TODO refactor: getTablemeta along with vgroupInfo - if (code != TSDB_CODE_SUCCESS) { - return code; - } - TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY); - } else { - TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY); - } + int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY; + TSDB_QUERY_SET_TYPE(pQueryInfo->type, type); // parse the group by clause in the first place if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // set where info @@ -7332,7 +7570,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { if (pSqlNode->pWhere != NULL) { if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } pSqlNode->pWhere = NULL; @@ -7340,10 +7578,9 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { pQueryInfo->window.skey = pQueryInfo->window.skey / 1000; pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000; } - } else { // set the time rang - if (taosArrayGetSize(pSqlNode->from->list) > 1) { - // If it is a join query, no where clause is not allowed. - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "condition missing for join query "); + } else { + if (taosArrayGetSize(pSqlNode->from->list) > 1) { // Cross join not allowed yet + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "cross join not supported yet"); } } @@ -7353,32 +7590,46 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { if (validateSelectNodeList(pCmd, pQueryInfo, pSqlNode->pSelNodeList, isSTable, joinQuery, timeWindowQuery) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // parse the window_state if (validateStateWindowNode(pCmd, pQueryInfo, pSqlNode, isSTable) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // set order by info if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // set interval value if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } else { if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; + } + } + + if (tscQueryTags(pQueryInfo)) { + SExprInfo* pExpr1 = tscExprGet(pQueryInfo, 0); + + if (pExpr1->base.functionId != TSDB_FUNC_TID_TAG) { + int32_t numOfCols = (int32_t)taosArrayGetSize(pQueryInfo->colList); + for (int32_t i = 0; i < numOfCols; ++i) { + SColumn* pCols = taosArrayGetP(pQueryInfo->colList, i); + if (pCols->info.flist.numOfFilters > 0) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); + } + } } } // parse the having clause in the first place if (validateHavingClause(pQueryInfo, pSqlNode->pHaving, pCmd, pSqlNode->pSelNodeList, joinQuery, timeWindowQuery) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } /* @@ -7386,18 +7637,16 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { * in dealing with super table queries such as: count/first/last */ if (validateSessionNode(pCmd, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (isSTable) { tscTansformFuncForSTableQuery(pQueryInfo); - if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } - // no result due to invalid query time range if (pQueryInfo->window.skey > pQueryInfo->window.ekey) { pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; @@ -7405,18 +7654,18 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { } if (!hasTimestampForPointInterpQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } // in case of join query, time range is required. if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) { int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey); if (timeRange == 0 && pQueryInfo->window.skey == 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } - if ((code = validateLimitNode(pCmd, pQueryInfo, index, pSqlNode, pSql)) != TSDB_CODE_SUCCESS) { + if ((code = validateLimitNode(pCmd, pQueryInfo, pSqlNode, pSql)) != TSDB_CODE_SUCCESS) { return code; } @@ -7432,6 +7681,34 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { } } + { // set the query info + pQueryInfo->projectionQuery = tscIsProjectionQuery(pQueryInfo); + pQueryInfo->hasFilter = tscHasColumnFilter(pQueryInfo); + pQueryInfo->simpleAgg = isSimpleAggregateRv(pQueryInfo); + pQueryInfo->onlyTagQuery = onlyTagPrjFunction(pQueryInfo); + pQueryInfo->groupbyColumn = tscGroupbyColumn(pQueryInfo); + + pQueryInfo->arithmeticOnAgg = tsIsArithmeticQueryOnAggResult(pQueryInfo); + + SExprInfo** p = NULL; + int32_t numOfExpr = 0; + code = createProjectionExpr(pQueryInfo, pTableMetaInfo, &p, &numOfExpr); + + if (pQueryInfo->exprList1 == NULL) { + pQueryInfo->exprList1 = taosArrayInit(4, POINTER_BYTES); + } + + taosArrayAddBatch(pQueryInfo->exprList1, (void*) p, numOfExpr); + } + +#if 0 + SQueryNode* p = qCreateQueryPlan(pQueryInfo); + char* s = queryPlanToString(p); + tfree(s); + + qDestroyQueryPlan(p); +#endif + return TSDB_CODE_SUCCESS; // Does not build query message here } @@ -7523,7 +7800,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS return TSDB_CODE_SUCCESS; } else { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression"); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression"); } } else { @@ -7543,9 +7820,9 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) { if (pRight->nodeType == TSQL_NODE_VALUE) { if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64 == 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } } @@ -7554,7 +7831,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) { if (pRight != NULL && pRight->nodeType == TSQL_NODE_VALUE) { if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } } @@ -7574,4 +7851,3 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) { return false; } - diff --git a/src/client/src/tscSchemaUtil.c b/src/client/src/tscSchemaUtil.c index 2ea382132b8de9a97bd75d1e80b03a6eb6131756..114fc8ee7383787a0448b237e4ef1f8dc8be31e0 100644 --- a/src/client/src/tscSchemaUtil.c +++ b/src/client/src/tscSchemaUtil.c @@ -94,6 +94,7 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) { pTableMeta->tableType = pTableMetaMsg->tableType; pTableMeta->vgId = pTableMetaMsg->vgroup.vgId; + pTableMeta->suid = pTableMetaMsg->suid; pTableMeta->tableInfo = (STableComInfo) { .numOfTags = pTableMetaMsg->numOfTags, diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 7b2e83a1eceffb8c1036cbba0c861f6db11ce6ad..a94463383bd85856601c9a0d7ae7069052a713fc 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -116,7 +116,7 @@ static void tscDumpEpSetFromVgroupInfo(SRpcEpSet *pEpSet, SNewVgroupInfo *pVgrou static void tscUpdateVgroupInfo(SSqlObj *pSql, SRpcEpSet *pEpSet) { SSqlCmd *pCmd = &pSql->cmd; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); if (pTableMetaInfo == NULL || pTableMetaInfo->pTableMeta == NULL) { return; } @@ -335,7 +335,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { return; } - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); + 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", pSql->self, pCmd->command, pQueryInfo->type, pObj, pObj->signature); @@ -360,7 +360,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { // set the flag to denote that sql string needs to be re-parsed and build submit block with table schema if (cmd == TSDB_SQL_INSERT && rpcMsg->code == TSDB_CODE_TDB_TABLE_RECONFIGURE) { - pSql->cmd.submitSchema = 1; + pSql->cmd.insertParam.schemaAttached = 1; } if ((cmd == TSDB_SQL_SELECT || cmd == TSDB_SQL_UPDATE_TAGS_VAL) && @@ -477,7 +477,7 @@ int doBuildAndSendMsg(SSqlObj *pSql) { pCmd->command == TSDB_SQL_INSERT || pCmd->command == TSDB_SQL_CONNECT || pCmd->command == TSDB_SQL_HB || - pCmd->command == TSDB_SQL_META || +// pCmd->command == TSDB_SQL_META || pCmd->command == TSDB_SQL_STABLEVGROUP) { pRes->code = tscBuildMsg[pCmd->command](pSql, NULL); } @@ -506,7 +506,7 @@ int tscBuildAndSendRequest(SSqlObj *pSql, SQueryInfo* pQueryInfo) { uint32_t type = 0; if (pQueryInfo == NULL) { - pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + pQueryInfo = tscGetQueryInfo(pCmd); } STableMetaInfo *pTableMetaInfo = NULL; @@ -539,7 +539,7 @@ int tscBuildAndSendRequest(SSqlObj *pSql, SQueryInfo* pQueryInfo) { int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg *) pSql->cmd.payload; - SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(&pSql->cmd); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); pRetrieveMsg->free = htons(pQueryInfo->type); pRetrieveMsg->qId = htobe64(pSql->res.qId); @@ -581,25 +581,8 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; - - char* pMsg = pSql->cmd.payload; - - // NOTE: shell message size should not include SMsgDesc - int32_t size = pSql->cmd.payloadLen - sizeof(SMsgDesc); - - SMsgDesc* pMsgDesc = (SMsgDesc*) pMsg; - pMsgDesc->numOfVnodes = htonl(1); // always one vnode - - pMsg += sizeof(SMsgDesc); - SSubmitMsg *pShellMsg = (SSubmitMsg *)pMsg; - - pShellMsg->header.vgId = htonl(pTableMeta->vgId); - pShellMsg->header.contLen = htonl(size); // the length not includes the size of SMsgDesc - pShellMsg->length = pShellMsg->header.contLen; - - pShellMsg->numOfBlocks = htonl(pSql->cmd.numOfTablesInSubmit); // number of tables to be inserted // pSql->cmd.payloadLen is set during copying data into payload pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT; @@ -608,29 +591,28 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) { taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo)); tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo); - tscDebug("0x%"PRIx64" build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql->self, pTableMeta->vgId, pSql->cmd.numOfTablesInSubmit, - pSql->epSet.numOfEps); + tscDebug("0x%"PRIx64" submit msg built, numberOfEP:%d", pSql->self, pSql->epSet.numOfEps); + return TSDB_CODE_SUCCESS; } /* * for table query, simply return the size <= 1k */ -static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql, int32_t clauseIndex) { +static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql) { const static int32_t MIN_QUERY_MSG_PKT_SIZE = TSDB_MAX_BYTES_PER_ROW * 5; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo)); - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); int32_t exprSize = (int32_t)(sizeof(SSqlExpr) * numOfExprs * 2); int32_t tsBufSize = (pQueryInfo->tsBuf != NULL) ? pQueryInfo->tsBuf->fileSize : 0; int32_t sqlLen = (int32_t) strlen(pSql->sqlstr) + 1; - int32_t tableSerialize = 0; STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (pTableMetaInfo->pVgroupTables != NULL) { @@ -754,7 +736,7 @@ static int32_t serializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t nu if (pColFilter->lowerRelOptr == TSDB_RELATION_INVALID && pColFilter->upperRelOptr == TSDB_RELATION_INVALID) { tscError("invalid filter info"); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -773,7 +755,7 @@ static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo, if (validateColumn && !tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId, pExpr->numOfParams)) { tscError("0x%"PRIx64" table schema is not matched with parsed sql", id); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } assert(pExpr->resColId < 0); @@ -816,14 +798,14 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; int32_t code = TSDB_CODE_SUCCESS; - int32_t size = tscEstimateQueryMsgSize(pSql, pCmd->clauseIndex); + int32_t size = tscEstimateQueryMsgSize(pSql); if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) { tscError("%p failed to malloc for query msg", pSql); - return TSDB_CODE_TSC_INVALID_SQL; // todo add test for this + return TSDB_CODE_TSC_INVALID_OPERATION; // todo add test for this } - SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); SQueryAttr query = {{0}}; tscCreateQueryFromQueryInfo(pQueryInfo, &query, pSql); @@ -930,7 +912,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { goto _end; } - SSqlGroupbyExpr *pGroupbyExpr = query.pGroupbyExpr; + SGroupbyExpr *pGroupbyExpr = query.pGroupbyExpr; if (pGroupbyExpr->numOfGroupCols > 0) { pQueryMsg->orderByIdx = htons(pGroupbyExpr->orderIndex); pQueryMsg->orderType = htons(pGroupbyExpr->orderType); @@ -1051,8 +1033,8 @@ int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SCreateDbMsg *pCreateDbMsg = (SCreateDbMsg *)pCmd->payload; - assert(pCmd->numOfClause == 1); - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); +// assert(pCmd->numOfClause == 1); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pCreateDbMsg->db); assert(code == TSDB_CODE_SUCCESS); @@ -1172,7 +1154,7 @@ int32_t tscBuildDropDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SDropDbMsg *pDropDbMsg = (SDropDbMsg*)pCmd->payload; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pDropDbMsg->db); assert(code == TSDB_CODE_SUCCESS && pTableMetaInfo->name.type == TSDB_DB_NAME_T); @@ -1193,9 +1175,10 @@ int32_t tscBuildDropTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } SCMDropTableMsg *pDropTableMsg = (SCMDropTableMsg*)pCmd->payload; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); tNameExtractFullName(&pTableMetaInfo->name, pDropTableMsg->name); + pDropTableMsg->supertable = (pInfo->pMiscInfo->tableType == TSDB_SUPER_TABLE)? 1:0; pDropTableMsg->igNotExists = pInfo->pMiscInfo->existsCheck ? 1 : 0; pCmd->msgType = TSDB_MSG_TYPE_CM_DROP_TABLE; return TSDB_CODE_SUCCESS; @@ -1250,7 +1233,7 @@ int32_t tscBuildUseDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } SUseDbMsg *pUseDbMsg = (SUseDbMsg *)pCmd->payload; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); tNameExtractFullName(&pTableMetaInfo->name, pUseDbMsg->db); pCmd->msgType = TSDB_MSG_TYPE_CM_USE_DB; @@ -1267,7 +1250,7 @@ int32_t tscBuildSyncDbReplicaMsg(SSqlObj* pSql, SSqlInfo *pInfo) { } SSyncDbMsg *pSyncMsg = (SSyncDbMsg *)pCmd->payload; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); tNameExtractFullName(&pTableMetaInfo->name, pSyncMsg->db); pCmd->msgType = TSDB_MSG_TYPE_CM_SYNC_DB; @@ -1287,7 +1270,7 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SShowMsg *pShowMsg = (SShowMsg *)pCmd->payload; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); if (tNameIsEmpty(&pTableMetaInfo->name)) { pthread_mutex_lock(&pObj->mutex); @@ -1361,7 +1344,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSchema *pSchema; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); // Reallocate the payload size @@ -1450,7 +1433,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscEstimateAlterTableMsgLength(SSqlCmd *pCmd) { - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); return minMsgSize() + sizeof(SAlterTableMsg) + sizeof(SSchema) * tscNumOfFields(pQueryInfo) + TSDB_EXTRA_PAYLOAD_SIZE; } @@ -1459,7 +1442,7 @@ int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int msgLen = 0; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -1508,7 +1491,7 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) { SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload; pCmd->payloadLen = htonl(pUpdateMsg->head.contLen); - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); STableMeta *pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; SNewVgroupInfo vgroupInfo = {.vgId = -1}; @@ -1528,7 +1511,7 @@ int tscAlterDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SAlterDbMsg *pAlterDbMsg = (SAlterDbMsg* )pCmd->payload; pAlterDbMsg->dbType = -1; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); tNameExtractFullName(&pTableMetaInfo->name, pAlterDbMsg->db); return TSDB_CODE_SUCCESS; @@ -1544,7 +1527,7 @@ int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg*)pCmd->payload; pRetrieveMsg->qId = htobe64(pSql->res.qId); pRetrieveMsg->free = htons(pQueryInfo->type); @@ -1568,7 +1551,7 @@ static int tscLocalResultCommonBuilder(SSqlObj *pSql, int32_t numOfRes) { pRes->row = 0; pRes->rspType = 1; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) { return pRes->code; } @@ -1592,7 +1575,7 @@ static int tscLocalResultCommonBuilder(SSqlObj *pSql, int32_t numOfRes) { int tscProcessDescribeTableRsp(SSqlObj *pSql) { SSqlCmd * pCmd = &pSql->cmd; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); @@ -1616,8 +1599,13 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) { return code; } + if (pRes->pLocalMerger == NULL) { // no result from subquery, so abort here directly. + (*pSql->fp)(pSql->param, pSql, pRes->numOfRows); + return code; + } + // global aggregation may be the upstream for parent query - SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); if (pQueryInfo->pQInfo == NULL) { STableGroupInfo tableGroupInfo = {.numOfTables = 1, .pGroupList = taosArrayInit(1, POINTER_BYTES),}; tableGroupInfo.map = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); @@ -1628,21 +1616,21 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) { taosArrayPush(group, &tableKeyInfo); taosArrayPush(tableGroupInfo.pGroupList, &group); - SExprInfo* list = calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SExprInfo)); - for(int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) { - SExprInfo* pExprInfo = tscSqlExprGet(pQueryInfo, i); + // todo remove it + SExprInfo* list = calloc(tscNumOfExprs(pQueryInfo), sizeof(SExprInfo)); + for(int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) { + SExprInfo* pExprInfo = tscExprGet(pQueryInfo, i); list[i] = *pExprInfo; } - pQueryInfo->pQInfo = createQueryInfoFromQueryNode(pQueryInfo, list, &tableGroupInfo, NULL, NULL, pRes->pLocalMerger, MERGE_STAGE); + pQueryInfo->pQInfo = createQInfoFromQueryNode(pQueryInfo, list, &tableGroupInfo, NULL, NULL, pRes->pLocalMerger, MERGE_STAGE); + tfree(list); } uint64_t localQueryId = 0; qTableQuery(pQueryInfo->pQInfo, &localQueryId); convertQueryResult(pRes, pQueryInfo); - handleDownstreamOperator(pRes, pQueryInfo); - code = pRes->code; if (pRes->code == TSDB_CODE_SUCCESS) { (*pSql->fp)(pSql->param, pSql, pRes->numOfRows); @@ -1688,15 +1676,16 @@ int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { +#if 0 SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableInfoMsg *pInfoMsg = (STableInfoMsg *)pCmd->payload; int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pInfoMsg->tableFname); if (code != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } pInfoMsg->createFlag = htons(pSql->cmd.autoCreated ? 1 : 0); @@ -1709,64 +1698,40 @@ int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pCmd->payloadLen = (int32_t)(pMsg - (char*)pInfoMsg); pCmd->msgType = TSDB_MSG_TYPE_CM_TABLE_META; +#endif return TSDB_CODE_SUCCESS; } /** * multi table meta req pkg format: - * | SMgmtHead | SMultiTableInfoMsg | tableId0 | tableId1 | tableId2 | ...... - * no used 4B + * |SMultiTableInfoMsg | tableId0 | tableId1 | tableId2 | ...... + * 4B **/ -int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { -#if 0 +int tscBuildMultiTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; - // copy payload content to temp buff - char *tmpData = 0; - if (pCmd->payloadLen > 0) { - if ((tmpData = calloc(1, pCmd->payloadLen + 1)) == NULL) return -1; - memcpy(tmpData, pCmd->payload, pCmd->payloadLen); - } - - // fill head info - SMgmtHead *pMgmt = (SMgmtHead *)(pCmd->payload + tsRpcHeadSize); - memset(pMgmt->db, 0, TSDB_TABLE_FNAME_LEN); // server don't need the db - - SMultiTableInfoMsg *pInfoMsg = (SMultiTableInfoMsg *)(pCmd->payload + tsRpcHeadSize + sizeof(SMgmtHead)); - pInfoMsg->numOfTables = htonl((int32_t)pCmd->count); - - if (pCmd->payloadLen > 0) { - memcpy(pInfoMsg->tableIds, tmpData, pCmd->payloadLen); - } - - tfree(tmpData); - - pCmd->payloadLen += sizeof(SMgmtHead) + sizeof(SMultiTableInfoMsg); pCmd->msgType = TSDB_MSG_TYPE_CM_TABLES_META; - assert(pCmd->payloadLen + minMsgSize() <= pCmd->allocSize); - tscDebug("0x%"PRIx64" build load multi-metermeta msg completed, numOfTables:%d, msg size:%d", pSql->self, pCmd->count, + tscDebug("0x%"PRIx64" build load multi-tablemeta msg completed, numOfTables:%d, msg size:%d", pSql->self, pCmd->count, pCmd->payloadLen); return pCmd->payloadLen; -#endif - return 0; } int tscBuildSTableVgroupMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; char* pMsg = pCmd->payload; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); SSTableVgroupMsg *pStableVgroupMsg = (SSTableVgroupMsg *)pMsg; pStableVgroupMsg->numOfTables = htonl(pQueryInfo->numOfTables); pMsg += sizeof(SSTableVgroupMsg); for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, i); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, i); int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pMsg); assert(code == TSDB_CODE_SUCCESS); @@ -1826,18 +1791,16 @@ int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return TSDB_CODE_SUCCESS; } -int tscProcessTableMetaRsp(SSqlObj *pSql) { - STableMetaMsg *pMetaMsg = (STableMetaMsg *)pSql->res.pRsp; - +static int32_t tableMetaMsgConvert(STableMetaMsg* pMetaMsg) { pMetaMsg->tid = htonl(pMetaMsg->tid); pMetaMsg->sversion = htons(pMetaMsg->sversion); pMetaMsg->tversion = htons(pMetaMsg->tversion); pMetaMsg->vgroup.vgId = htonl(pMetaMsg->vgroup.vgId); - + pMetaMsg->uid = htobe64(pMetaMsg->uid); - pMetaMsg->contLen = htons(pMetaMsg->contLen); +// pMetaMsg->contLen = htonl(pMetaMsg->contLen); pMetaMsg->numOfColumns = htons(pMetaMsg->numOfColumns); - + if ((pMetaMsg->tableType != TSDB_SUPER_TABLE) && (pMetaMsg->tid <= 0 || pMetaMsg->vgroup.vgId < 2 || pMetaMsg->vgroup.numOfEps <= 0)) { tscError("invalid value in table numOfEps:%d, vgId:%d tid:%d, name:%s", pMetaMsg->vgroup.numOfEps, pMetaMsg->vgroup.vgId, @@ -1872,21 +1835,34 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) { pSchema++; } - - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); - assert(pTableMetaInfo->pTableMeta == NULL); - STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg); - if (!tIsValidSchema(pTableMeta->schema, pTableMeta->tableInfo.numOfColumns, pTableMeta->tableInfo.numOfTags)) { - tscError("0x%"PRIx64" invalid table meta from mnode, name:%s", pSql->self, tNameGetTableName(&pTableMetaInfo->name)); - return TSDB_CODE_TSC_INVALID_VALUE; + return TSDB_CODE_SUCCESS; +} + +// update the vgroupInfo if needed +static void doUpdateVgroupInfo(STableMeta *pTableMeta, SVgroupMsg *pVgroupMsg) { + if (pTableMeta->vgId > 0) { + int32_t vgId = pTableMeta->vgId; + assert(pTableMeta->tableType != TSDB_SUPER_TABLE); + + SNewVgroupInfo vgroupInfo = {.inUse = -1}; + taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo)); + + // vgroup info exists, compare with it + if (((vgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&vgroupInfo, pVgroupMsg)) || (vgroupInfo.inUse < 0)) { + vgroupInfo = createNewVgroupInfo(pVgroupMsg); + taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(vgroupInfo)); + tscDebug("add new VgroupInfo, vgId:%d, total cached:%d", vgId, (int32_t) taosHashGetSize(tscVgroupMap)); + } } +} +static void doAddTableMetaToLocalBuf(STableMeta* pTableMeta, STableMetaMsg* pMetaMsg, bool updateSTable) { if (pTableMeta->tableType == TSDB_CHILD_TABLE) { - // check if super table hashmap or not + // add or update the corresponding super table meta data info int32_t len = (int32_t) strnlen(pTableMeta->sTableName, TSDB_TABLE_FNAME_LEN); - // super tableMeta data alreay exists, create it according to tableMeta and add it to hash map + // The super tableMeta already exists, create it according to tableMeta and add it to hash map STableMeta* pSupTableMeta = createSuperTableMeta(pMetaMsg); uint32_t size = tscGetTableMetaSize(pSupTableMeta); @@ -1896,147 +1872,176 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) { tfree(pSupTableMeta); CChildTableMeta* cMeta = tscCreateChildMeta(pTableMeta); - - char name[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(&pTableMetaInfo->name, name); - - taosHashPut(tscTableMetaInfo, name, strlen(name), cMeta, sizeof(CChildTableMeta)); + taosHashPut(tscTableMetaInfo, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), cMeta, sizeof(CChildTableMeta)); tfree(cMeta); } else { uint32_t s = tscGetTableMetaSize(pTableMeta); - - char name[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(&pTableMetaInfo->name, name); - - taosHashPut(tscTableMetaInfo, name, strlen(name), pTableMeta, s); + taosHashPut(tscTableMetaInfo, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), pTableMeta, s); } +} - // update the vgroupInfo if needed - if (pTableMeta->vgId > 0) { - int32_t vgId = pTableMeta->vgId; - assert(pTableMeta->tableType != TSDB_SUPER_TABLE); +int tscProcessTableMetaRsp(SSqlObj *pSql) { + STableMetaMsg *pMetaMsg = (STableMetaMsg *)pSql->res.pRsp; + int32_t code = tableMetaMsgConvert(pMetaMsg); + if (code != TSDB_CODE_SUCCESS) { + return code; + } - SNewVgroupInfo vgroupInfo = {.inUse = -1}; - taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo)); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); + assert(pTableMetaInfo->pTableMeta == NULL); - if (((vgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&vgroupInfo, &pMetaMsg->vgroup)) || - (vgroupInfo.inUse < 0)) { // vgroup info exists, compare with it - vgroupInfo = createNewVgroupInfo(&pMetaMsg->vgroup); - taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(vgroupInfo)); - tscDebug("add new VgroupInfo, vgId:%d, total cached:%d", vgId, (int32_t) taosHashGetSize(tscVgroupMap)); - } + STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg); + if (!tIsValidSchema(pTableMeta->schema, pTableMeta->tableInfo.numOfColumns, pTableMeta->tableInfo.numOfTags)) { + tscError("0x%"PRIx64" invalid table meta from mnode, name:%s", pSql->self, tNameGetTableName(&pTableMetaInfo->name)); + return TSDB_CODE_TSC_INVALID_VALUE; } - tscDebug("0x%"PRIx64" recv table meta, uid:%" PRIu64 ", tid:%d, name:%s", pSql->self, pTableMeta->id.uid, pTableMeta->id.tid, - tNameGetTableName(&pTableMetaInfo->name)); + char name[TSDB_TABLE_FNAME_LEN] = {0}; + tNameExtractFullName(&pTableMetaInfo->name, name); + assert(strncmp(pMetaMsg->tableFname, name, tListLen(pMetaMsg->tableFname)) == 0); + + doAddTableMetaToLocalBuf(pTableMeta, pMetaMsg, true); + doUpdateVgroupInfo(pTableMeta, &pMetaMsg->vgroup); + + tscDebug("0x%"PRIx64" recv table meta, uid:%" PRIu64 ", tid:%d, name:%s, numOfCols:%d, numOfTags:%d", pSql->self, + pTableMeta->id.uid, pTableMeta->id.tid, tNameGetTableName(&pTableMetaInfo->name), pTableMeta->tableInfo.numOfColumns, + pTableMeta->tableInfo.numOfTags); free(pTableMeta); return TSDB_CODE_SUCCESS; } -/** - * multi table meta rsp pkg format: - * | STaosRsp | SMultiTableInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2 - * |...... 1B 4B - **/ -int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) { -#if 0 +static SVgroupsInfo* createVgroupInfoFromMsg(char* pMsg, int32_t* size, uint64_t id) { + SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)pMsg; + pVgroupMsg->numOfVgroups = htonl(pVgroupMsg->numOfVgroups); + + *size = (int32_t)(sizeof(SVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsMsg)); + + size_t vgroupsz = sizeof(SVgroupInfo) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsInfo); + SVgroupsInfo *pVgroupInfo = calloc(1, vgroupsz); + assert(pVgroupInfo != NULL); + + pVgroupInfo->numOfVgroups = pVgroupMsg->numOfVgroups; + if (pVgroupInfo->numOfVgroups <= 0) { + tscDebug("0x%" PRIx64 " empty vgroup info, no corresponding tables for stable", id); + } else { + for (int32_t j = 0; j < pVgroupInfo->numOfVgroups; ++j) { + // just init, no need to lock + SVgroupInfo *pVgroup = &pVgroupInfo->vgroups[j]; + + SVgroupMsg *vmsg = &pVgroupMsg->vgroups[j]; + vmsg->vgId = htonl(vmsg->vgId); + vmsg->numOfEps = vmsg->numOfEps; + for (int32_t k = 0; k < vmsg->numOfEps; ++k) { + vmsg->epAddr[k].port = htons(vmsg->epAddr[k].port); + } + + SNewVgroupInfo newVi = createNewVgroupInfo(vmsg); + pVgroup->numOfEps = newVi.numOfEps; + pVgroup->vgId = newVi.vgId; + for (int32_t k = 0; k < vmsg->numOfEps; ++k) { + pVgroup->epAddr[k].port = newVi.ep[k].port; + pVgroup->epAddr[k].fqdn = strndup(newVi.ep[k].fqdn, TSDB_FQDN_LEN); + } + + // check if current buffer contains the vgroup info. + // If not, add it + SNewVgroupInfo existVgroupInfo = {.inUse = -1}; + taosHashGetClone(tscVgroupMap, &newVi.vgId, sizeof(newVi.vgId), NULL, &existVgroupInfo, sizeof(SNewVgroupInfo)); + + if (((existVgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&existVgroupInfo, vmsg)) || + (existVgroupInfo.inUse < 0)) { // vgroup info exists, compare with it + taosHashPut(tscVgroupMap, &newVi.vgId, sizeof(newVi.vgId), &newVi, sizeof(newVi)); + tscDebug("0x%" PRIx64 " add new VgroupInfo, vgId:%d, total cached:%d", id, newVi.vgId, (int32_t)taosHashGetSize(tscVgroupMap)); + } + } + } + + return pVgroupInfo; +} + +int tscProcessMultiTableMetaRsp(SSqlObj *pSql) { char *rsp = pSql->res.pRsp; - ieType = *rsp; - if (ieType != TSDB_IE_TYPE_META) { - tscError("invalid ie type:%d", ieType); - pSql->res.code = TSDB_CODE_TSC_INVALID_IE; - pSql->res.numOfTotal = 0; - return TSDB_CODE_TSC_APP_ERROR; + SMultiTableMeta *pMultiMeta = (SMultiTableMeta *)rsp; + pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables); + pMultiMeta->numOfVgroup = htonl(pMultiMeta->numOfVgroup); + + rsp += sizeof(SMultiTableMeta); + + SSqlObj* pParentSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pSql->param); + if(pParentSql == NULL) { + return pSql->res.code; } - rsp++; + SSqlCmd *pParentCmd = &pParentSql->cmd; - SMultiTableInfoMsg *pInfo = (SMultiTableInfoMsg *)rsp; - totalNum = htonl(pInfo->numOfTables); - rsp += sizeof(SMultiTableInfoMsg); + SHashObj *pSet = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); - for (i = 0; i < totalNum; i++) { - SMultiTableMeta *pMultiMeta = (SMultiTableMeta *)rsp; - STableMeta * pMeta = pMultiMeta->metas; + char* pMsg = pMultiMeta->meta; + for (int32_t i = 0; i < pMultiMeta->numOfTables; i++) { + STableMetaMsg *pMetaMsg = (STableMetaMsg *)pMsg; + int32_t code = tableMetaMsgConvert(pMetaMsg); + if (code != TSDB_CODE_SUCCESS) { + taosHashCleanup(pSet); + taosReleaseRef(tscObjRef, pParentSql->self); + return code; + } + + STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg); + if (!tIsValidSchema(pTableMeta->schema, pTableMeta->tableInfo.numOfColumns, pTableMeta->tableInfo.numOfTags)) { + tscError("0x%"PRIx64" invalid table meta from mnode, name:%s", pSql->self, pMetaMsg->tableFname); + taosHashCleanup(pSet); + taosReleaseRef(tscObjRef, pParentSql->self); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + SName sn = {0}; + tNameFromString(&sn, pMetaMsg->tableFname, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE); - pMeta->sid = htonl(pMeta->sid); - pMeta->sversion = htons(pMeta->sversion); - pMeta->vgId = htonl(pMeta->vgId); - pMeta->uid = htobe64(pMeta->uid); + const char* tableName = tNameGetTableName(&sn); + size_t keyLen = strlen(tableName); - if (pMeta->sid <= 0 || pMeta->vgId < 0) { - tscError("invalid meter vgId:%d, sid%d", pMeta->vgId, pMeta->sid); - pSql->res.code = TSDB_CODE_TSC_INVALID_VALUE; - pSql->res.numOfTotal = i; - return TSDB_CODE_TSC_APP_ERROR; + STableMetaVgroupInfo p = {.pTableMeta = pTableMeta,}; + taosHashPut(pParentCmd->pTableMetaMap, tableName, keyLen, &p, sizeof(STableMetaVgroupInfo)); + + bool addToBuf = false; + if (taosHashGet(pSet, &pMetaMsg->uid, sizeof(pMetaMsg->uid)) == NULL) { + addToBuf = true; + taosHashPut(pSet, &pMetaMsg->uid, sizeof(pMetaMsg->uid), "", 0); } - // pMeta->numOfColumns = htons(pMeta->numOfColumns); - // - // if (pMeta->numOfTags > TSDB_MAX_TAGS || pMeta->numOfTags < 0) { - // tscError("invalid tag value count:%d", pMeta->numOfTags); - // pSql->res.code = TSDB_CODE_TSC_INVALID_VALUE; - // pSql->res.numOfTotal = i; - // return TSDB_CODE_TSC_APP_ERROR; - // } - // - // if (pMeta->numOfTags > TSDB_MAX_TAGS || pMeta->numOfTags < 0) { - // tscError("invalid numOfTags:%d", pMeta->numOfTags); - // pSql->res.code = TSDB_CODE_TSC_INVALID_VALUE; - // pSql->res.numOfTotal = i; - // return TSDB_CODE_TSC_APP_ERROR; - // } - // - // if (pMeta->numOfColumns > TSDB_MAX_COLUMNS || pMeta->numOfColumns < 0) { - // tscError("invalid numOfColumns:%d", pMeta->numOfColumns); - // pSql->res.code = TSDB_CODE_TSC_INVALID_VALUE; - // pSql->res.numOfTotal = i; - // return TSDB_CODE_TSC_APP_ERROR; - // } - // - // for (int j = 0; j < TSDB_REPLICA_MAX_NUM; ++j) { - // pMeta->vpeerDesc[j].vnode = htonl(pMeta->vpeerDesc[j].vnode); - // } - // - // pMeta->rowSize = 0; - // rsp += sizeof(SMultiTableMeta); - // pSchema = (SSchema *)rsp; - // - // int32_t numOfTotalCols = pMeta->numOfColumns + pMeta->numOfTags; - // for (int j = 0; j < numOfTotalCols; ++j) { - // pSchema->bytes = htons(pSchema->bytes); - // pSchema->colId = htons(pSchema->colId); - // - // // ignore the tags length - // if (j < pMeta->numOfColumns) { - // pMeta->rowSize += pSchema->bytes; - // } - // pSchema++; - // } - // - // rsp += numOfTotalCols * sizeof(SSchema); - // - // int32_t tagLen = 0; - // SSchema *pTagsSchema = tscGetTableTagSchema(pMeta); - // - // if (pMeta->tableType == TSDB_CHILD_TABLE) { - // for (int32_t j = 0; j < pMeta->numOfTags; ++j) { - // tagLen += pTagsSchema[j].bytes; - // } - // } - // - // rsp += tagLen; - // int32_t size = (int32_t)(rsp - ((char *)pMeta)); // Consistent with STableMeta in cache - // } + // create the tableMeta and add it into the TableMeta map + doAddTableMetaToLocalBuf(pTableMeta, pMetaMsg, addToBuf); + + // if the vgroup is not updated in current process, update it. + int64_t vgId = pMetaMsg->vgroup.vgId; + if (pTableMeta->tableType != TSDB_SUPER_TABLE && taosHashGet(pSet, &vgId, sizeof(vgId)) == NULL) { + doUpdateVgroupInfo(pTableMeta, &pMetaMsg->vgroup); + taosHashPut(pSet, &vgId, sizeof(vgId), "", 0); + } + + pMsg += pMetaMsg->contLen; } - + + for(int32_t i = 0; i < pMultiMeta->numOfVgroup; ++i) { + char* name = pMsg; + pMsg += TSDB_TABLE_NAME_LEN; + + STableMetaVgroupInfo* p = taosHashGet(pParentCmd->pTableMetaMap, name, strnlen(name, TSDB_TABLE_NAME_LEN)); + assert(p != NULL); + + int32_t size = 0; + p->pVgroupInfo = createVgroupInfoFromMsg(pMsg, &size, pSql->self); + pMsg += size; + } + pSql->res.code = TSDB_CODE_SUCCESS; - pSql->res.numOfTotal = i; - tscDebug("0x%"PRIx64" load multi-metermeta resp from complete num:%d", pSql->self, pSql->res.numOfTotal); -#endif - + pSql->res.numOfTotal = pMultiMeta->numOfTables; + tscDebug("0x%"PRIx64" load multi-tableMeta from mnode, numOfTables:%d", pSql->self, pMultiMeta->numOfTables); + + taosHashCleanup(pSet); + taosReleaseRef(tscObjRef, pParentSql->self); return TSDB_CODE_SUCCESS; } @@ -2048,68 +2053,38 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) { } assert(parent->signature == parent && (int64_t)pSql->param == parent->self); - + SSqlRes* pRes = &pSql->res; - + // NOTE: the order of several table must be preserved. SSTableVgroupRspMsg *pStableVgroup = (SSTableVgroupRspMsg *)pRes->pRsp; pStableVgroup->numOfTables = htonl(pStableVgroup->numOfTables); char *pMsg = pRes->pRsp + sizeof(SSTableVgroupRspMsg); - - SSqlCmd* pCmd = &parent->cmd; - for(int32_t i = 0; i < pStableVgroup->numOfTables; ++i) { - STableMetaInfo *pInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, i); - SVgroupsMsg * pVgroupMsg = (SVgroupsMsg *) pMsg; - pVgroupMsg->numOfVgroups = htonl(pVgroupMsg->numOfVgroups); - - size_t size = sizeof(SVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsMsg); - - size_t vgroupsz = sizeof(SVgroupInfo) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsInfo); - pInfo->vgroupList = calloc(1, vgroupsz); - assert(pInfo->vgroupList != NULL); + SSqlCmd* pCmd = &parent->cmd; + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); - pInfo->vgroupList->numOfVgroups = pVgroupMsg->numOfVgroups; - if (pInfo->vgroupList->numOfVgroups <= 0) { - tscDebug("0x%"PRIx64" empty vgroup info, no corresponding tables for stable", pSql->self); - } else { - for (int32_t j = 0; j < pInfo->vgroupList->numOfVgroups; ++j) { - // just init, no need to lock - SVgroupInfo *pVgroup = &pInfo->vgroupList->vgroups[j]; - - SVgroupMsg *vmsg = &pVgroupMsg->vgroups[j]; - vmsg->vgId = htonl(vmsg->vgId); - vmsg->numOfEps = vmsg->numOfEps; - for (int32_t k = 0; k < vmsg->numOfEps; ++k) { - vmsg->epAddr[k].port = htons(vmsg->epAddr[k].port); - } - - SNewVgroupInfo newVi = createNewVgroupInfo(vmsg); - pVgroup->numOfEps = newVi.numOfEps; - pVgroup->vgId = newVi.vgId; - for (int32_t k = 0; k < vmsg->numOfEps; ++k) { - pVgroup->epAddr[k].port = newVi.ep[k].port; - pVgroup->epAddr[k].fqdn = strndup(newVi.ep[k].fqdn, TSDB_FQDN_LEN); - } - - // check if current buffer contains the vgroup info. - // If not, add it - SNewVgroupInfo existVgroupInfo = {.inUse = -1}; - taosHashGetClone(tscVgroupMap, &newVi.vgId, sizeof(newVi.vgId), NULL, &existVgroupInfo, sizeof(SNewVgroupInfo)); - - if (((existVgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&existVgroupInfo, vmsg)) || - (existVgroupInfo.inUse < 0)) { // vgroup info exists, compare with it - taosHashPut(tscVgroupMap, &newVi.vgId, sizeof(newVi.vgId), &newVi, sizeof(newVi)); - tscDebug("add new VgroupInfo, vgId:%d, total cached:%d", newVi.vgId, (int32_t) taosHashGetSize(tscVgroupMap)); - } + for(int32_t i = 0; i < pStableVgroup->numOfTables; ++i) { + char* name = pMsg; + pMsg += TSDB_TABLE_NAME_LEN; + + STableMetaInfo *pInfo = NULL; + for(int32_t j = 0; j < pQueryInfo->numOfTables; ++j) { + STableMetaInfo *pInfo1 = tscGetTableMetaInfoFromCmd(pCmd, j); + if (strcmp(name, tNameGetTableName(&pInfo1->name)) != 0) { + continue; } + + pInfo = pInfo1; + break; } + int32_t size = 0; + pInfo->vgroupList = createVgroupInfoFromMsg(pMsg, &size, pSql->self); pMsg += size; } taosReleaseRef(tscObjRef, parent->self); - return pSql->res.code; } @@ -2121,7 +2096,7 @@ int tscProcessShowRsp(SSqlObj *pSql) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -2162,8 +2137,8 @@ int tscProcessShowRsp(SSqlObj *pSql) { TAOS_FIELD f = tscCreateField(pSchema->type, pSchema->name, pSchema->bytes); SInternalField* pInfo = tscFieldInfoAppend(pFieldInfo, &f); - pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, - pTableSchema[i].type, pTableSchema[i].bytes, getNewResColId(pQueryInfo), pTableSchema[i].bytes, false); + pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, + pTableSchema[i].type, pTableSchema[i].bytes, getNewResColId(pCmd), pTableSchema[i].bytes, false); } pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput; @@ -2181,7 +2156,7 @@ static void createHbObj(STscObj* pObj) { pSql->fp = tscProcessHeartBeatRsp; - SQueryInfo *pQueryInfo = tscGetQueryInfoS(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfoS(&pSql->cmd); if (pQueryInfo == NULL) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; tfree(pSql); @@ -2247,7 +2222,7 @@ int tscProcessConnectRsp(SSqlObj *pSql) { int tscProcessUseDbRsp(SSqlObj *pSql) { STscObj * pObj = pSql->pTscObj; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); pthread_mutex_lock(&pObj->mutex); int ret = tNameExtractFullName(&pTableMetaInfo->name, pObj->db); @@ -2265,7 +2240,7 @@ int tscProcessDropDbRsp(SSqlObj *pSql) { } int tscProcessDropTableRsp(SSqlObj *pSql) { - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); //The cached tableMeta is expired in this case, so clean it in hash table char name[TSDB_TABLE_FNAME_LEN] = {0}; @@ -2279,7 +2254,7 @@ int tscProcessDropTableRsp(SSqlObj *pSql) { } int tscProcessAlterTableMsgRsp(SSqlObj *pSql) { - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); char name[TSDB_TABLE_FNAME_LEN] = {0}; tNameExtractFullName(&pTableMetaInfo->name, name); @@ -2339,7 +2314,7 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { pRes->completed = (pRetrieve->completed == 1); pRes->data = pRetrieve->data; - SQueryInfo* pQueryInfo = tscGetActiveQueryInfo(pCmd); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) { return pRes->code; } @@ -2353,8 +2328,6 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { tscSetResRawPtr(pRes, pQueryInfo); } - handleDownstreamOperator(pRes, pQueryInfo); - if (pSql->pSubscription != NULL) { int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput; @@ -2384,53 +2357,130 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { void tscTableMetaCallBack(void *param, TAOS_RES *res, int code); -static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) { +static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool autocreate) { SSqlObj *pNew = calloc(1, sizeof(SSqlObj)); if (NULL == pNew) { tscError("0x%"PRIx64" malloc failed for new sqlobj to get table meta", pSql->self); return TSDB_CODE_TSC_OUT_OF_MEMORY; } - pNew->pTscObj = pSql->pTscObj; - pNew->signature = pNew; + pNew->pTscObj = pSql->pTscObj; + pNew->signature = pNew; pNew->cmd.command = TSDB_SQL_META; tscAddQueryInfo(&pNew->cmd); - SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd, 0); - - pNew->cmd.autoCreated = pSql->cmd.autoCreated; // create table if not exists + SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd); if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE + pSql->cmd.payloadLen)) { tscError("0x%"PRIx64" malloc failed for payload to get table meta", pSql->self); + tscFreeSqlObj(pNew); return TSDB_CODE_TSC_OUT_OF_MEMORY; } - STableMetaInfo *pNewMeterMetaInfo = tscAddEmptyMetaInfo(pNewQueryInfo); - assert(pNew->cmd.numOfClause == 1 && pNewQueryInfo->numOfTables == 1); + STableMetaInfo *pNewTableMetaInfo = tscAddEmptyMetaInfo(pNewQueryInfo); + assert(pNewQueryInfo->numOfTables == 1); - tNameAssign(&pNewMeterMetaInfo->name, &pTableMetaInfo->name); + tNameAssign(&pNewTableMetaInfo->name, &pTableMetaInfo->name); - if (pSql->cmd.autoCreated) { - int32_t code = copyTagData(&pNew->cmd.tagData, &pSql->cmd.tagData); + registerSqlObj(pNew); + + pNew->fp = tscTableMetaCallBack; + pNew->param = (void *)pSql->self; + + tscDebug("0x%"PRIx64" new pSqlObj:0x%"PRIx64" to get tableMeta, auto create:%d, metaRid from %"PRId64" to %"PRId64, + pSql->self, pNew->self, autocreate, pSql->metaRid, pNew->self); + pSql->metaRid = pNew->self; + + { + STableInfoMsg *pInfoMsg = (STableInfoMsg *)pNew->cmd.payload; + int32_t code = tNameExtractFullName(&pNewTableMetaInfo->name, pInfoMsg->tableFname); if (code != TSDB_CODE_SUCCESS) { - tscError("0x%"PRIx64" malloc failed for new tag data to get table meta", pSql->self); - tscFreeSqlObj(pNew); - return TSDB_CODE_TSC_OUT_OF_MEMORY; + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + pInfoMsg->createFlag = htons(autocreate? 1 : 0); + char *pMsg = (char *)pInfoMsg + sizeof(STableInfoMsg); + + // tag data exists + if (autocreate && pSql->cmd.tagData.dataLen != 0) { + pMsg = serializeTagData(&pSql->cmd.tagData, pMsg); + } + + pNew->cmd.payloadLen = (int32_t)(pMsg - (char*)pInfoMsg); + pNew->cmd.msgType = TSDB_MSG_TYPE_CM_TABLE_META; + } + + int32_t code = tscBuildAndSendRequest(pNew, NULL); + if (code == TSDB_CODE_SUCCESS) { + code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated + } + + return code; +} + +int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, __async_cb_func_t fp) { + SSqlObj *pNew = calloc(1, sizeof(SSqlObj)); + if (NULL == pNew) { + tscError("0x%"PRIx64" failed to allocate sqlobj to get multiple table meta", pSql->self); + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + pNew->pTscObj = pSql->pTscObj; + pNew->signature = pNew; + pNew->cmd.command = TSDB_SQL_MULTI_META; + + int32_t numOfTable = (int32_t) taosArrayGetSize(pNameList); + int32_t numOfVgroupList = (int32_t) taosArrayGetSize(pVgroupNameList); + + int32_t size = (numOfTable + numOfVgroupList) * TSDB_TABLE_FNAME_LEN + sizeof(SMultiTableInfoMsg); + if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, size)) { + tscError("0x%"PRIx64" malloc failed for payload to get table meta", pSql->self); + tscFreeSqlObj(pNew); + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + SMultiTableInfoMsg* pInfo = (SMultiTableInfoMsg*) pNew->cmd.payload; + pInfo->numOfTables = htonl((uint32_t) taosArrayGetSize(pNameList)); + pInfo->numOfVgroups = htonl((uint32_t) taosArrayGetSize(pVgroupNameList)); + + char* start = pInfo->tableNames; + int32_t len = 0; + for(int32_t i = 0; i < numOfTable; ++i) { + char* name = taosArrayGetP(pNameList, i); + if (i < numOfTable - 1 || numOfVgroupList > 0) { + len = sprintf(start, "%s,", name); + } else { + len = sprintf(start, "%s", name); + } + + start += len; + } + + for(int32_t i = 0; i < numOfVgroupList; ++i) { + char* name = taosArrayGetP(pVgroupNameList, i); + if (i < numOfVgroupList - 1) { + len = sprintf(start, "%s,", name); + } else { + len = sprintf(start, "%s", name); } + + start += len; } + pNew->cmd.payloadLen = (int32_t) ((start - pInfo->tableNames) + sizeof(SMultiTableInfoMsg)); + pNew->cmd.msgType = TSDB_MSG_TYPE_CM_TABLES_META; + registerSqlObj(pNew); - tscDebug("0x%"PRIx64" new pSqlObj:0x%"PRIx64" to get tableMeta, auto create:%d", pSql->self, pNew->self, - pNew->cmd.autoCreated); + tscDebug("0x%"PRIx64" new pSqlObj:0x%"PRIx64" to get %d tableMeta, vgroupInfo:%d, msg size:%d", pSql->self, + pNew->self, numOfTable, numOfVgroupList, pNew->cmd.payloadLen); - pNew->fp = tscTableMetaCallBack; + pNew->fp = fp; pNew->param = (void *)pSql->self; tscDebug("0x%"PRIx64" metaRid from %" PRId64 " to %" PRId64 , pSql->self, pSql->metaRid, pNew->self); - - pSql->metaRid = pNew->self; + pSql->metaRid = pNew->self; int32_t code = tscBuildAndSendRequest(pNew, NULL); if (code == TSDB_CODE_SUCCESS) { code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated @@ -2439,13 +2489,23 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn return code; } -int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) { +int32_t tscGetTableMetaImpl(SSqlObj* pSql, STableMetaInfo *pTableMetaInfo, bool autocreate) { assert(tIsValidName(&pTableMetaInfo->name)); - tfree(pTableMetaInfo->pTableMeta); - uint32_t size = tscGetTableMetaMaxSize(); - pTableMetaInfo->pTableMeta = calloc(1, size); + if (pTableMetaInfo->pTableMeta == NULL) { + pTableMetaInfo->pTableMeta = calloc(1, size); + pTableMetaInfo->tableMetaSize = size; + } else if (pTableMetaInfo->tableMetaSize < size) { + char *tmp = realloc(pTableMetaInfo->pTableMeta, size); + if (tmp == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + pTableMetaInfo->pTableMeta = (STableMeta *)tmp; + } + + memset(pTableMetaInfo->pTableMeta, 0, size); + pTableMetaInfo->tableMetaSize = size; pTableMetaInfo->pTableMeta->tableType = -1; pTableMetaInfo->pTableMeta->tableInfo.numOfColumns = -1; @@ -2457,28 +2517,35 @@ int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) { taosHashGetClone(tscTableMetaInfo, name, len, NULL, pTableMetaInfo->pTableMeta, -1); // TODO resize the tableMeta + char buf[80*1024] = {0}; + assert(size < 80*1024); + STableMeta* pMeta = pTableMetaInfo->pTableMeta; if (pMeta->id.uid > 0) { + // in case of child table, here only get the if (pMeta->tableType == TSDB_CHILD_TABLE) { - int32_t code = tscCreateTableMetaFromCChildMeta(pTableMetaInfo->pTableMeta, name); + int32_t code = tscCreateTableMetaFromSTableMeta(pTableMetaInfo->pTableMeta, name, buf); if (code != TSDB_CODE_SUCCESS) { - return getTableMetaFromMnode(pSql, pTableMetaInfo); + return getTableMetaFromMnode(pSql, pTableMetaInfo, autocreate); } } return TSDB_CODE_SUCCESS; } - return getTableMetaFromMnode(pSql, pTableMetaInfo); + return getTableMetaFromMnode(pSql, pTableMetaInfo, autocreate); +} + +int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) { + return tscGetTableMetaImpl(pSql, pTableMetaInfo, false); } int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool createIfNotExists) { - pSql->cmd.autoCreated = createIfNotExists; - return tscGetTableMeta(pSql, pTableMetaInfo); + return tscGetTableMetaImpl(pSql, pTableMetaInfo, createIfNotExists); } /** - * retrieve table meta from mnode, and update the local table meta hashmap. + * retrieve table meta from mnode, and then update the local table meta hashmap. * @param pSql sql object * @param tableIndex table index * @return status code @@ -2486,14 +2553,14 @@ int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool create int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) { SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); char name[TSDB_TABLE_FNAME_LEN] = {0}; int32_t code = tNameExtractFullName(&pTableMetaInfo->name, name); if (code != TSDB_CODE_SUCCESS) { tscError("0x%"PRIx64" failed to generate the table full name", pSql->self); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; @@ -2506,11 +2573,10 @@ int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) { size_t len = strlen(name); taosHashRemove(tscTableMetaInfo, name, len); - return getTableMetaFromMnode(pSql, pTableMetaInfo); + return getTableMetaFromMnode(pSql, pTableMetaInfo, false); } -static bool allVgroupInfoRetrieved(SSqlCmd* pCmd, int32_t clauseIndex) { - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); +static bool allVgroupInfoRetrieved(SQueryInfo* pQueryInfo) { for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); if (pTableMetaInfo->vgroupList == NULL) { @@ -2522,11 +2588,9 @@ static bool allVgroupInfoRetrieved(SSqlCmd* pCmd, int32_t clauseIndex) { return true; } -int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) { - int code = TSDB_CODE_RPC_NETWORK_UNAVAIL; - SSqlCmd *pCmd = &pSql->cmd; - - if (allVgroupInfoRetrieved(pCmd, clauseIndex)) { +int tscGetSTableVgroupInfo(SSqlObj *pSql, SQueryInfo* pQueryInfo) { + int32_t code = TSDB_CODE_RPC_NETWORK_UNAVAIL; + if (allVgroupInfoRetrieved(pQueryInfo)) { return TSDB_CODE_SUCCESS; } @@ -2537,13 +2601,12 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) { pNew->cmd.command = TSDB_SQL_STABLEVGROUP; // TODO TEST IT - SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd); if (pNewQueryInfo == NULL) { tscFreeSqlObj(pNew); return code; } - - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); + for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo *pMInfo = tscGetMetaInfo(pQueryInfo, i); STableMeta* pTableMeta = tscTableMetaDup(pMInfo->pTableMeta); @@ -2602,9 +2665,8 @@ void tscInitMsgsFp() { tscBuildMsg[TSDB_SQL_CONNECT] = tscBuildConnectMsg; tscBuildMsg[TSDB_SQL_USE_DB] = tscBuildUseDbMsg; - tscBuildMsg[TSDB_SQL_META] = tscBuildTableMetaMsg; +// tscBuildMsg[TSDB_SQL_META] = tscBuildTableMetaMsg; tscBuildMsg[TSDB_SQL_STABLEVGROUP] = tscBuildSTableVgroupMsg; - tscBuildMsg[TSDB_SQL_MULTI_META] = tscBuildMultiMeterMetaMsg; tscBuildMsg[TSDB_SQL_HB] = tscBuildHeartBeatMsg; tscBuildMsg[TSDB_SQL_SHOW] = tscBuildShowMsg; @@ -2622,7 +2684,7 @@ void tscInitMsgsFp() { tscProcessMsgRsp[TSDB_SQL_USE_DB] = tscProcessUseDbRsp; tscProcessMsgRsp[TSDB_SQL_META] = tscProcessTableMetaRsp; tscProcessMsgRsp[TSDB_SQL_STABLEVGROUP] = tscProcessSTableVgroupRsp; - tscProcessMsgRsp[TSDB_SQL_MULTI_META] = tscProcessMultiMeterMetaRsp; + tscProcessMsgRsp[TSDB_SQL_MULTI_META] = tscProcessMultiTableMetaRsp; tscProcessMsgRsp[TSDB_SQL_SHOW] = tscProcessShowRsp; tscProcessMsgRsp[TSDB_SQL_RETRIEVE] = tscProcessRetrieveRspFromNode; // rsp handled by same function. diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 364af4e8b152b0c5be6027659a643dfd0c4aeb94..1ffa6416b221fdcaf7d8f1ba2a13d6cce14ca027 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -373,11 +373,15 @@ int taos_num_fields(TAOS_RES *res) { if (pSql == NULL || pSql->signature != pSql) return 0; int32_t num = 0; - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); if (pQueryInfo == NULL) { return num; } + while(pQueryInfo->pDownstream != NULL) { + pQueryInfo = pQueryInfo->pDownstream; + } + size_t numOfCols = tscNumOfFields(pQueryInfo); for(int32_t i = 0; i < numOfCols; ++i) { SInternalField* pInfo = taosArrayGet(pQueryInfo->fieldsInfo.internalField, i); @@ -408,7 +412,7 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { SSqlRes *pRes = &pSql->res; if (pSql == NULL || pSql->signature != pSql) return 0; - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); if (pQueryInfo == NULL) { return NULL; } @@ -560,7 +564,7 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) { return true; } - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); if ((pQueryInfo == NULL) || tscIsTwoStageSTableQuery(pQueryInfo, 0)) { return true; @@ -614,7 +618,7 @@ int taos_errno(TAOS_RES *tres) { * why the sql is invalid */ static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) { - if (code != TSDB_CODE_TSC_INVALID_SQL + if (code != TSDB_CODE_TSC_INVALID_OPERATION && code != TSDB_CODE_TSC_SQL_SYNTAX_ERROR) { return false; } @@ -673,7 +677,7 @@ char *taos_get_client_info() { return version; } static void tscKillSTableQuery(SSqlObj *pSql) { SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); if (!tscIsTwoStageSTableQuery(pQueryInfo, 0)) { return; @@ -724,7 +728,7 @@ void taos_stop_query(TAOS_RES *res) { // set the error code for master pSqlObj firstly pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { assert(pSql->rpcRid <= 0); @@ -754,7 +758,7 @@ bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) { return true; } - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); if (pQueryInfo == NULL) { return true; } @@ -829,9 +833,9 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) case TSDB_DATA_TYPE_NCHAR: { int32_t charLen = varDataLen((char*)row[i] - VARSTR_HEADER_SIZE); if (fields[i].type == TSDB_DATA_TYPE_BINARY) { - assert(charLen <= fields[i].bytes); + assert(charLen <= fields[i].bytes && charLen >= 0); } else { - assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE); + assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE && charLen >= 0); } memcpy(str + len, row[i], charLen); @@ -868,15 +872,11 @@ int taos_validate_sql(TAOS *taos, const char *sql) { SSqlObj* pSql = calloc(1, sizeof(SSqlObj)); - pSql->pTscObj = taos; + pSql->pTscObj = taos; pSql->signature = pSql; - - SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; - pRes->numOfTotal = 0; - pRes->numOfClauseTotal = 0; - + pCmd->resColumnId = TSDB_RES_COL_ID; tscDebug("0x%"PRIx64" Valid SQL: %s pObj:%p", pSql->self, sql, pObj); @@ -896,10 +896,10 @@ int taos_validate_sql(TAOS *taos, const char *sql) { strtolower(pSql->sqlstr, sql); - pCmd->curSql = NULL; - if (NULL != pCmd->pTableBlockHashList) { - taosHashCleanup(pCmd->pTableBlockHashList); - pCmd->pTableBlockHashList = NULL; +// pCmd->curSql = NULL; + if (NULL != pCmd->insertParam.pTableBlockHashList) { + taosHashCleanup(pCmd->insertParam.pTableBlockHashList); + pCmd->insertParam.pTableBlockHashList = NULL; } pSql->fp = asyncCallback; @@ -921,90 +921,19 @@ int taos_validate_sql(TAOS *taos, const char *sql) { return code; } -static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t tblListLen) { - // must before clean the sqlcmd object - tscResetSqlCmd(&pSql->cmd, false); - - SSqlCmd *pCmd = &pSql->cmd; - - pCmd->command = TSDB_SQL_MULTI_META; - pCmd->count = 0; - - int code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; - char *str = (char *)tblNameList; - - SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex); - if (pQueryInfo == NULL) { - pSql->res.code = terrno; - return terrno; - } - - STableMetaInfo *pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo); - - if ((code = tscAllocPayload(pCmd, tblListLen + 16)) != TSDB_CODE_SUCCESS) { - return code; - } - - char *nextStr; - char tblName[TSDB_TABLE_FNAME_LEN]; - int payloadLen = 0; - char *pMsg = pCmd->payload; - while (1) { - nextStr = strchr(str, ','); - if (nextStr == NULL) { - break; - } - - memcpy(tblName, str, nextStr - str); - int32_t len = (int32_t)(nextStr - str); - tblName[len] = '\0'; - - str = nextStr + 1; - len = (int32_t)strtrim(tblName); - - SStrToken sToken = {.n = len, .type = TK_ID, .z = tblName}; - tSQLGetToken(tblName, &sToken.type); - - // Check if the table name available or not - if (tscValidateName(&sToken) != TSDB_CODE_SUCCESS) { - code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; - sprintf(pCmd->payload, "table name is invalid"); - return code; - } - - if ((code = tscSetTableFullName(pTableMetaInfo, &sToken, pSql)) != TSDB_CODE_SUCCESS) { - return code; - } - - if (++pCmd->count > TSDB_MULTI_TABLEMETA_MAX_NUM) { - code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; - sprintf(pCmd->payload, "tables over the max number"); - return code; - } - - int32_t xlen = tNameLen(&pTableMetaInfo->name); - if (payloadLen + xlen + 128 >= pCmd->allocSize) { - char *pNewMem = realloc(pCmd->payload, pCmd->allocSize + tblListLen); - if (pNewMem == NULL) { - code = TSDB_CODE_TSC_OUT_OF_MEMORY; - sprintf(pCmd->payload, "failed to allocate memory"); - return code; - } - - pCmd->payload = pNewMem; - pCmd->allocSize = pCmd->allocSize + tblListLen; - pMsg = pCmd->payload; - } - - char n[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(&pTableMetaInfo->name, n); - payloadLen += sprintf(pMsg + payloadLen, "%s,", n); +void loadMultiTableMetaCallback(void *param, TAOS_RES *res, int code) { + SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)param); + if (pSql == NULL) { + return; } - *(pMsg + payloadLen) = '\0'; - pCmd->payloadLen = payloadLen + 1; + taosReleaseRef(tscObjRef, pSql->self); + pSql->res.code = code; + tsem_post(&pSql->rspSem); +} - return TSDB_CODE_SUCCESS; +static void freeElem(void* p) { + tfree(*(char**)p); } int taos_load_table_info(TAOS *taos, const char *tableNameList) { @@ -1020,38 +949,28 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { pSql->pTscObj = taos; pSql->signature = pSql; - SSqlRes *pRes = &pSql->res; - - pRes->code = 0; - pRes->numOfTotal = 0; // the number of getting table meta from server - pRes->numOfClauseTotal = 0; - - assert(pSql->fp == NULL); - tscDebug("0x%"PRIx64" tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj); + pSql->fp = NULL; // todo set the correct callback function pointer + pSql->cmd.pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); - int32_t tblListLen = (int32_t)strlen(tableNameList); - if (tblListLen > MAX_TABLE_NAME_LENGTH) { - tscError("0x%"PRIx64" tableNameList too long, length:%d, maximum allowed:%d", pSql->self, tblListLen, MAX_TABLE_NAME_LENGTH); + int32_t length = (int32_t)strlen(tableNameList); + if (length > MAX_TABLE_NAME_LENGTH) { + tscError("0x%"PRIx64" tableNameList too long, length:%d, maximum allowed:%d", pSql->self, length, MAX_TABLE_NAME_LENGTH); tscFreeSqlObj(pSql); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } - char *str = calloc(1, tblListLen + 1); + char *str = calloc(1, length + 1); if (str == NULL) { - tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self); + tscError("0x%"PRIx64" failed to allocate sql string buffer", pSql->self); tscFreeSqlObj(pSql); return TSDB_CODE_TSC_OUT_OF_MEMORY; } strtolower(str, tableNameList); - int32_t code = (uint8_t) tscParseTblNameList(pSql, str, tblListLen); - - /* - * set the qhandle to 0 before return in order to erase the qhandle value assigned in the previous successful query. - * If qhandle is NOT set 0, the function of taos_free_result() will send message to server by calling tscBuildAndSendRequest() - * to free connection, which may cause segment fault, when the parse phrase is not even successfully executed. - */ - pRes->qId = 0; + SArray* plist = taosArrayInit(4, POINTER_BYTES); + SArray* vgroupList = taosArrayInit(4, POINTER_BYTES); + + int32_t code = (uint8_t) tscTransferTableNameList(pSql, str, length, plist); free(str); if (code != TSDB_CODE_SUCCESS) { @@ -1059,12 +978,23 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { return code; } - tscDoQuery(pSql); + registerSqlObj(pSql); + tscDebug("0x%"PRIx64" load multiple table meta, tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj); - tscDebug("0x%"PRIx64" load multi-table meta result:%d %s pObj:%p", pSql->self, pRes->code, taos_errstr(pSql), pObj); - if ((code = pRes->code) != TSDB_CODE_SUCCESS) { - tscFreeSqlObj(pSql); + code = getMultiTableMetaFromMnode(pSql, plist, vgroupList, loadMultiTableMetaCallback); + if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + code = TSDB_CODE_SUCCESS; } + taosArrayDestroyEx(plist, freeElem); + taosArrayDestroyEx(vgroupList, freeElem); + + if (code != TSDB_CODE_SUCCESS) { + tscFreeRegisteredSqlObj(pSql); + return code; + } + + tsem_wait(&pSql->rspSem); + tscFreeRegisteredSqlObj(pSql); return code; } diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c index 17bf575b60eed9f71e72a608d0aef4944c887bef..8e11fd0cfb435e0eadc24ecdcd175163f81e797b 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -37,7 +37,7 @@ static int64_t getDelayValueAfterTimewindowClosed(SSqlStream* pStream, int64_t l static bool isProjectStream(SQueryInfo* pQueryInfo) { for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo *pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId != TSDB_FUNC_PRJ) { return false; } @@ -89,12 +89,12 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) { return; } - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); code = tscGetTableMeta(pSql, pTableMetaInfo); if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - code = tscGetSTableVgroupInfo(pSql, 0); + code = tscGetSTableVgroupInfo(pSql, pQueryInfo); } if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { @@ -138,7 +138,7 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) { pStream->numOfRes = 0; // reset the numOfRes. SSqlObj *pSql = pStream->pSql; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); tscDebug("0x%"PRIx64" timer launch query", pSql->self); if (pStream->isProject) { @@ -197,7 +197,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf tscError("0x%"PRIx64" stream:%p, query data failed, code:0x%08x, retry in %" PRId64 "ms", pStream->pSql->self, pStream, numOfRows, retryDelay); - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0, 0); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0); char name[TSDB_TABLE_FNAME_LEN] = {0}; tNameExtractFullName(&pTableMetaInfo->name, name); @@ -224,7 +224,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) { #if 0 SSqlObj * pSql = pStream->pSql; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); if (pQueryInfo->fillType != TSDB_FILL_SET_VALUE && pQueryInfo->fillType != TSDB_FILL_NULL) { return; @@ -273,7 +273,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf return; } - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo *pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; if (numOfRows > 0) { // when reaching here the first execution of stream computing is successful. @@ -444,7 +444,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) { int64_t minIntervalTime = (pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); if (!pStream->isProject && pQueryInfo->interval.interval == 0) { sprintf(pSql->cmd.payload, "the interval value is 0"); @@ -494,7 +494,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) { } static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); if (pStream->isProject) { // no data in table, flush all data till now to destination meter, 10sec delay @@ -556,7 +556,7 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) { return; } - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); @@ -614,31 +614,32 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p return NULL; } - pStream->stime = stime; - pStream->fp = fp; + pStream->stime = stime; + pStream->fp = fp; pStream->callback = callback; - pStream->param = param; - pStream->pSql = pSql; - pSql->pStream = pStream; - pSql->param = pStream; - pSql->maxRetry = TSDB_MAX_REPLICA; + pStream->param = param; + pStream->pSql = pSql; - pSql->sqlstr = calloc(1, strlen(sqlstr) + 1); + pSql->pStream = pStream; + pSql->param = pStream; + pSql->maxRetry = TSDB_MAX_REPLICA; + pSql->sqlstr = calloc(1, strlen(sqlstr) + 1); if (pSql->sqlstr == NULL) { tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self); tscFreeSqlObj(pSql); + free(pStream); return NULL; } strtolower(pSql->sqlstr, sqlstr); + pSql->fp = tscCreateStream; + pSql->fetchFp = tscCreateStream; + pSql->cmd.resColumnId = TSDB_RES_COL_ID; + tsem_init(&pSql->rspSem, 0, 0); registerSqlObj(pSql); tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr); - tsem_init(&pSql->rspSem, 0, 0); - - pSql->fp = tscCreateStream; - pSql->fetchFp = tscCreateStream; int32_t code = tsParseSql(pSql, true); if (code == TSDB_CODE_SUCCESS) { diff --git a/src/client/src/tscSub.c b/src/client/src/tscSub.c index 6928058f2301b05f7eda0b4a2b77f0d0edf0f45f..42330aa18e48eb60389ef3056c96a2aab386a6ca 100644 --- a/src/client/src/tscSub.c +++ b/src/client/src/tscSub.c @@ -151,6 +151,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char* strtolower(pSql->sqlstr, pSql->sqlstr); pRes->qId = 0; pRes->numOfRows = 1; + pCmd->resColumnId = TSDB_RES_COL_ID; code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE); if (code != TSDB_CODE_SUCCESS) { @@ -173,7 +174,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char* if (pSql->cmd.command != TSDB_SQL_SELECT && pSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) { line = __LINE__; - code = TSDB_CODE_TSC_INVALID_SQL; + code = TSDB_CODE_TSC_INVALID_OPERATION; goto fail; } @@ -215,7 +216,7 @@ static void tscProcessSubscriptionTimer(void *handle, void *tmrId) { taosTmrReset(tscProcessSubscriptionTimer, pSub->interval, pSub, tscTmr, &pSub->pTimer); } - +//TODO refactor: extract table list name not simply from the sql static SArray* getTableList( SSqlObj* pSql ) { const char* p = strstr( pSql->sqlstr, " from " ); assert(p != NULL); // we are sure this is a 'select' statement @@ -224,11 +225,11 @@ static SArray* getTableList( SSqlObj* pSql ) { SSqlObj* pNew = taos_query(pSql->pTscObj, sql); if (pNew == NULL) { - tscError("0x%"PRIx64"failed to retrieve table id: cannot create new sql object.", pSql->self); + tscError("0x%"PRIx64" failed to retrieve table id: cannot create new sql object.", pSql->self); return NULL; } else if (taos_errno(pNew) != TSDB_CODE_SUCCESS) { - tscError("0x%"PRIx64"failed to retrieve table id,error: %s", pSql->self, tstrerror(taos_errno(pNew))); + tscError("0x%"PRIx64" failed to retrieve table id,error: %s", pSql->self, tstrerror(taos_errno(pNew))); return NULL; } @@ -266,7 +267,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { pSub->lastSyncTime = taosGetTimestampMs(); - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; SSubscriptionProgress target = {.uid = pTableMeta->id.uid, .key = 0}; @@ -284,7 +285,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { } size_t numOfTables = taosArrayGetSize(tables); - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); SArray* progress = taosArrayInit(numOfTables, sizeof(SSubscriptionProgress)); for( size_t i = 0; i < numOfTables; i++ ) { STidTags* tt = taosArrayGet( tables, i ); @@ -304,7 +305,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { } taosArrayDestroy(tables); - TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd, 0)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY); + TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY); return 1; } @@ -503,8 +504,8 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) { SSqlObj *pSql = pSub->pSql; SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single table subscription size_t size = taosArrayGetSize(pSub->progress); diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 67eea432e650f4237fd53106470cbaf91d50e7c1..37c60edd385d545b7285dc6edec3b6b57abbbd58 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -55,9 +55,9 @@ static void skipRemainValue(STSBuf* pTSBuf, tVariant* tag1) { } while (tsBufNextPos(pTSBuf)) { - STSElem el1 = tsBufGetElem(pTSBuf); + el1 = tsBufGetElem(pTSBuf); - int32_t res = tVariantCompare(el1.tag, tag1); + res = tVariantCompare(el1.tag, tag1); if (res != 0) { // it is a record with new tag return; } @@ -65,15 +65,11 @@ static void skipRemainValue(STSBuf* pTSBuf, tVariant* tag1) { } static void subquerySetState(SSqlObj *pSql, SSubqueryState *subState, int idx, int8_t state) { - assert(idx < subState->numOfSub); - assert(subState->states); + assert(idx < subState->numOfSub && subState->states != NULL); + tscDebug("subquery:0x%"PRIx64",%d state set to %d", pSql->self, idx, state); pthread_mutex_lock(&subState->mutex); - - tscDebug("subquery:0x%"PRIx64",%d state set to %d", pSql->self, idx, state); - subState->states[idx] = state; - pthread_mutex_unlock(&subState->mutex); } @@ -86,8 +82,7 @@ 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, abort query completion check", pParentSql->self, - pSub->self, i); + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index: %d NOT finished yet", pParentSql->self, pSub->self, i); done = false; break; } else { @@ -102,39 +97,31 @@ static bool allSubqueryDone(SSqlObj *pParentSql) { return done; } -static bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx) { +bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx) { SSubqueryState *subState = &pParentSql->subState; - assert(idx < subState->numOfSub); pthread_mutex_lock(&subState->mutex); - bool done = allSubqueryDone(pParentSql); - - if (done) { - tscDebug("0x%"PRIx64" subquery:0x%"PRIx64",%d all subs already done", pParentSql->self, - pSql->self, idx); - - pthread_mutex_unlock(&subState->mutex); - - return false; - } - - tscDebug("0x%"PRIx64" subquery:0x%"PRIx64",%d state set to 1", pParentSql->self, pSql->self, idx); +// bool done = allSubqueryDone(pParentSql); +// if (done) { +// tscDebug("0x%"PRIx64" subquery:0x%"PRIx64",%d all subs already done", pParentSql->self, pSql->self, idx); +// pthread_mutex_unlock(&subState->mutex); +// return false; +// } + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index:%d state set to 1", pParentSql->self, pSql->self, idx); subState->states[idx] = 1; - done = allSubqueryDone(pParentSql); - + bool done = allSubqueryDone(pParentSql); pthread_mutex_unlock(&subState->mutex); - return done; } static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); win->skey = INT64_MAX; win->ekey = INT64_MIN; @@ -159,7 +146,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { for (int32_t i = 0; i < joinNum; ++i) { STSBuf* output = tsBufCreate(true, pQueryInfo->order.order); - SQueryInfo* pSubQueryInfo = tscGetQueryInfo(&pSql->pSubs[i]->cmd, 0); + SQueryInfo* pSubQueryInfo = tscGetQueryInfo(&pSql->pSubs[i]->cmd); pSubQueryInfo->tsBuf = output; @@ -404,12 +391,12 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { pSupporter->pObj = pSql; pSupporter->subqueryIndex = index; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); memcpy(&pSupporter->interval, &pQueryInfo->interval, sizeof(pSupporter->interval)); pSupporter->limit = pQueryInfo->limit; - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, index); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, index); pSupporter->uid = pTableMetaInfo->pTableMeta->id.uid; assert (pSupporter->uid != 0); @@ -427,14 +414,15 @@ static void tscDestroyJoinSupporter(SJoinSupporter* pSupporter) { } if (pSupporter->exprList != NULL) { - tscSqlExprInfoDestroy(pSupporter->exprList); + tscExprDestroy(pSupporter->exprList); + pSupporter->exprList = NULL; } if (pSupporter->colList != NULL) { tscColumnListDestroy(pSupporter->colList); } - tscFieldInfoClear(&pSupporter->fieldsInfo); +// tscFieldInfoClear(&pSupporter->fieldsInfo); if (pSupporter->pTSBuf != NULL) { tsBufDestroy(pSupporter->pTSBuf); @@ -448,7 +436,6 @@ static void tscDestroyJoinSupporter(SJoinSupporter* pSupporter) { pSupporter->f = NULL; } - if (pSupporter->pVgroupTables != NULL) { taosArrayDestroy(pSupporter->pVgroupTables); pSupporter->pVgroupTables = NULL; @@ -559,12 +546,12 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { continue; } - SQueryInfo *pSubQueryInfo = tscGetQueryInfo(&pPrevSub->cmd, 0); + SQueryInfo *pSubQueryInfo = tscGetQueryInfo(&pPrevSub->cmd); STSBuf *pTsBuf = pSubQueryInfo->tsBuf; pSubQueryInfo->tsBuf = NULL; // free result for async object will also free sqlObj - assert(tscSqlExprNumOfExprs(pSubQueryInfo) == 1); // ts_comp query only requires one result columns + assert(tscNumOfExprs(pSubQueryInfo) == 1); // ts_comp query only requires one result columns taos_free_result(pPrevSub); SSqlObj *pNew = createSubqueryObj(pSql, (int16_t) i, tscJoinQueryCallback, pSupporter, TSDB_SQL_SELECT, NULL); @@ -577,7 +564,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { tscClearSubqueryInfo(&pNew->cmd); pSql->pSubs[i] = pNew; - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pNew->cmd); pQueryInfo->tsBuf = pTsBuf; // transfer the ownership of timestamp comp-z data to the new created object // set the second stage sub query for join process @@ -592,7 +579,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { pQueryInfo->groupbyExpr = pSupporter->groupInfo; pQueryInfo->pUpstream = taosArrayInit(4, sizeof(POINTER_BYTES)); - assert(pNew->subState.numOfSub == 0 && pNew->cmd.numOfClause == 1 && pQueryInfo->numOfTables == 1); + assert(pNew->subState.numOfSub == 0 && pQueryInfo->numOfTables == 1); tscFieldInfoUpdateOffset(pQueryInfo); @@ -600,22 +587,20 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { pTableMetaInfo->pVgroupTables = pSupporter->pVgroupTables; pSupporter->exprList = NULL; - pSupporter->colList = NULL; + pSupporter->colList = NULL; pSupporter->pVgroupTables = NULL; memset(&pSupporter->fieldsInfo, 0, sizeof(SFieldInfo)); - memset(&pSupporter->groupInfo, 0, sizeof(SSqlGroupbyExpr)); + memset(&pSupporter->groupInfo, 0, sizeof(SGroupbyExpr)); /* * When handling the projection query, the offset value will be modified for table-table join, which is changed * during the timestamp intersection. */ pSupporter->limit = pQueryInfo->limit; -// pQueryInfo->limit = pSupporter->limit; - SColumnIndex index = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; SSchema* s = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, 0); - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + SExprInfo* pExpr = tscExprGet(pQueryInfo, 0); int16_t funcId = pExpr->base.functionId; // add the invisible timestamp column @@ -624,11 +609,11 @@ 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); + tscAddFuncInSelectClause(pQueryInfo, 0, functionId, &index, s, TSDB_COL_NORMAL, getNewResColId(&pNew->cmd)); tscPrintSelNodeList(pNew, 0); tscFieldInfoUpdateOffset(pQueryInfo); - pExpr = tscSqlExprGet(pQueryInfo, 0); + pExpr = tscExprGet(pQueryInfo, 0); } // set the join condition tag column info, todo extract method @@ -637,7 +622,13 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid); // set the tag column id for executor to extract correct tag value +#ifndef _TD_NINGSI_60 pExpr->base.param[0] = (tVariant) {.i64 = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)}; +#else + pExpr->base.param[0].i64 = colId; + pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; + pExpr->base.param[0].nLen = sizeof(int64_t); +#endif pExpr->base.numOfParams = 1; } @@ -652,11 +643,11 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { } } - subquerySetState(pPrevSub, &pSql->subState, i, 0); + subquerySetState(pNew, &pSql->subState, i, 0); size_t numOfCols = taosArrayGetSize(pQueryInfo->colList); - tscDebug("0x%"PRIx64" subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, name:%s", - pSql->self, pNew, 0, pTableMetaInfo->vgroupIndex, pQueryInfo->type, taosArrayGetSize(pQueryInfo->exprList), + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64" tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, name:%s", + pSql->self, pNew->self, 0, pTableMetaInfo->vgroupIndex, pQueryInfo->type, taosArrayGetSize(pQueryInfo->exprList), numOfCols, pQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); } @@ -675,7 +666,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { continue; } - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->pSubs[i]->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->pSubs[i]->cmd); executeQuery(pSql->pSubs[i], pQueryInfo); } @@ -701,8 +692,6 @@ void freeJoinSubqueryObj(SSqlObj* pSql) { } tfree(pSql->subState.states); - - pSql->subState.numOfSub = 0; } @@ -721,8 +710,6 @@ static int32_t quitAllSubquery(SSqlObj* pSqlSub, SSqlObj* pSqlObj, SJoinSupporte static void updateQueryTimeRange(SQueryInfo* pQueryInfo, STimeWindow* win) { assert(pQueryInfo->window.skey <= win->skey && pQueryInfo->window.ekey >= win->ekey); pQueryInfo->window = *win; - - } int32_t tidTagsCompar(const void* p1, const void* p2) { @@ -814,12 +801,14 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* tscClearSubqueryInfo(pCmd); tscFreeSqlResult(pSql); - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); assert(pQueryInfo->numOfTables == 1); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + STimeWindow window = pQueryInfo->window; tscInitQueryInfo(pQueryInfo); + pQueryInfo->window = window; TSDB_QUERY_CLEAR_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY); TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY); @@ -829,11 +818,11 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = 1}; SColumnIndex index = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &index, &colSchema, TSDB_COL_NORMAL); + tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &index, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); // set the tags value for ts_comp function if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, 0); + SExprInfo *pExpr = tscExprGet(pQueryInfo, 0); int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid); pExpr->base.param[0].i64 = tagColId; pExpr->base.param[0].nLen = sizeof(int64_t); @@ -861,7 +850,7 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* "0x%"PRIx64" subquery:0x%"PRIx64" tableIndex:%d, vgroupIndex:%d, numOfVgroups:%d, type:%d, ts_comp query to retrieve timestamps, " "numOfExpr:%" PRIzu ", colList:%" PRIzu ", numOfOutputFields:%d, name:%s", pParent->self, pSql->self, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pQueryInfo->type, - tscSqlExprNumOfExprs(pQueryInfo), numOfCols, pQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); + tscNumOfExprs(pQueryInfo), numOfCols, pQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); tscBuildAndSendRequest(pSql, NULL); } @@ -1103,7 +1092,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); // todo, the type may not include TSDB_QUERY_TYPE_TAG_FILTER_QUERY assert(TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY)); @@ -1225,7 +1214,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow SSqlCmd* pSubCmd = &pParentSql->pSubs[m]->cmd; SArray** s = taosArrayGet(resList, m); - SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pSubCmd, 0); + SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pSubCmd); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo1, 0); tscBuildVgroupTableInfo(pParentSql, pTableMetaInfo, *s); @@ -1259,7 +1248,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); assert(!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)); if (pParentSql->res.code != TSDB_CODE_SUCCESS) { @@ -1294,7 +1283,6 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow if (pSupporter->f == NULL) { tscError("0x%"PRIx64" failed to create tmp file:%s, reason:%s", pSql->self, pSupporter->path, strerror(errno)); - pParentSql->res.code = TAOS_SYSTEM_ERROR(errno); if (quitAllSubquery(pSql, pParentSql, pSupporter)) { @@ -1391,7 +1379,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow } // launch the query the retrieve actual results from vnode along with the filtered timestamp - SQueryInfo* pPQueryInfo = tscGetQueryInfo(&pParentSql->cmd, pParentSql->cmd.clauseIndex); + SQueryInfo* pPQueryInfo = tscGetQueryInfo(&pParentSql->cmd); updateQueryTimeRange(pPQueryInfo, &win); //update the vgroup that involved in real data query @@ -1407,7 +1395,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); if (pParentSql->res.code != TSDB_CODE_SUCCESS) { tscError("0x%"PRIx64" abort query due to other subquery failure. code:%d, global code:%d", pSql->self, numOfRows, pParentSql->res.code); @@ -1416,7 +1404,6 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR } tscAsyncResultOnError(pParentSql); - return; } @@ -1516,7 +1503,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { SSqlRes *pRes = &pSub->res; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSub->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSub->cmd); if (!tscHasReachLimitation(pQueryInfo, pRes)) { if (pRes->row >= pRes->numOfRows) { // no data left in current result buffer @@ -1568,7 +1555,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { continue; } - SQueryInfo* p = tscGetQueryInfo(&pSub->cmd, 0); + SQueryInfo* p = tscGetQueryInfo(&pSub->cmd); orderedPrjQuery = tscNonOrderedProjectionQueryOnSTable(p, 0); if (orderedPrjQuery) { break; @@ -1592,7 +1579,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { continue; } - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSub->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSub->cmd); if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && pSub->res.row >= pSub->res.numOfRows && pSub->res.completed) { @@ -1649,7 +1636,6 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { } SSqlRes* pRes1 = &pSql1->res; - if (pRes1->row >= pRes1->numOfRows) { subquerySetState(pSql1, &pSql->subState, i, 0); } @@ -1667,7 +1653,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { pSupporter = (SJoinSupporter*)pSql1->param; // wait for all subqueries completed - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd1, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd1); assert(pRes1->numOfRows >= 0 && pQueryInfo->numOfTables == 1); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -1698,9 +1684,9 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { return; } - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); - int32_t numOfExprs = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); + int32_t numOfExprs = (int32_t)tscNumOfExprs(pQueryInfo); pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * numOfExprs); if (pRes->pColumnIndex == NULL) { pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -1708,7 +1694,7 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { } for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); int32_t tableIndexOfSub = -1; for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) { @@ -1722,11 +1708,11 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { assert(tableIndexOfSub >= 0 && tableIndexOfSub < pQueryInfo->numOfTables); SSqlCmd* pSubCmd = &pSql->pSubs[tableIndexOfSub]->cmd; - SQueryInfo* pSubQueryInfo = tscGetQueryInfo(pSubCmd, 0); + SQueryInfo* pSubQueryInfo = tscGetQueryInfo(pSubCmd); size_t numOfSubExpr = taosArrayGetSize(pSubQueryInfo->exprList); for (int32_t k = 0; k < numOfSubExpr; ++k) { - SExprInfo* pSubExpr = tscSqlExprGet(pSubQueryInfo, k); + SExprInfo* pSubExpr = tscExprGet(pSubQueryInfo, k); if (pExpr->base.functionId == pSubExpr->base.functionId && pExpr->base.colInfo.colId == pSubExpr->base.colInfo.colId) { pRes->pColumnIndex[i] = (SColumnIndex){.tableIndex = tableIndexOfSub, .columnIndex = k}; break; @@ -1735,8 +1721,8 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { } // restore the offset value for super table query in case of final result. - tscRestoreFuncForSTableQuery(pQueryInfo); - tscFieldInfoUpdateOffset(pQueryInfo); +// tscRestoreFuncForSTableQuery(pQueryInfo); +// tscFieldInfoUpdateOffset(pQueryInfo); } void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { @@ -1746,10 +1732,10 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { SSqlObj* pParentSql = pSupporter->pObj; // There is only one subquery and table for each subquery. - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - assert(pQueryInfo->numOfTables == 1 && pSql->cmd.numOfClause == 1); + assert(pQueryInfo->numOfTables == 1); // retrieve actual query results from vnode during the second stage join subquery if (pParentSql->res.code != TSDB_CODE_SUCCESS) { @@ -1830,7 +1816,7 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter *pSupporter) { SSqlCmd * pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); pSql->res.qId = 0x1; assert(pSql->res.numOfRows == 0); @@ -1853,15 +1839,9 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter addGroupInfoForSubquery(pSql, pNew, 0, tableIndex); // refactor as one method - SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd); assert(pNewQueryInfo != NULL); - // update the table index -// size_t num = taosArrayGetSize(pNewQueryInfo->colList); -// for (int32_t i = 0; i < num; ++i) { -// SColumn* pCol = taosArrayGetP(pNewQueryInfo->colList, i); -// } - pSupporter->colList = pNewQueryInfo->colList; pNewQueryInfo->colList = NULL; @@ -1877,7 +1857,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter } pSupporter->groupInfo = pNewQueryInfo->groupbyExpr; - memset(&pNewQueryInfo->groupbyExpr, 0, sizeof(SSqlGroupbyExpr)); + memset(&pNewQueryInfo->groupbyExpr, 0, sizeof(SGroupbyExpr)); pNew->cmd.numOfCols = 0; pNewQueryInfo->interval.interval = 0; @@ -1890,9 +1870,12 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter pNewQueryInfo->order.orderColId = INT32_MIN; // backup the data and clear it in the sqlcmd object - memset(&pNewQueryInfo->groupbyExpr, 0, sizeof(SSqlGroupbyExpr)); - + memset(&pNewQueryInfo->groupbyExpr, 0, sizeof(SGroupbyExpr)); + + STimeWindow range = pNewQueryInfo->window; tscInitQueryInfo(pNewQueryInfo); + + pNewQueryInfo->window = range; STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pNewQueryInfo, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // return the tableId & tag @@ -1918,21 +1901,21 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter // set get tags query type TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY); - tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TID_TAG, &colIndex, &s1, TSDB_COL_TAG); + tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TID_TAG, &colIndex, &s1, TSDB_COL_TAG, getNewResColId(pCmd)); size_t numOfCols = taosArrayGetSize(pNewQueryInfo->colList); tscDebug( "%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, transfer to tid_tag query to retrieve (tableId, tags), " "exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, tagIndex:%d, name:%s", - pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo), + pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscNumOfExprs(pNewQueryInfo), numOfCols, pNewQueryInfo->fieldsInfo.numOfOutput, colIndex.columnIndex, tNameGetTableName(&pNewQueryInfo->pTableMetaInfo[0]->name)); } else { SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = 1}; SColumnIndex colIndex = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TS_COMP, &colIndex, &colSchema, TSDB_COL_NORMAL); + tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TS_COMP, &colIndex, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); // set the tags value for ts_comp function - SExprInfo *pExpr = tscSqlExprGet(pNewQueryInfo, 0); + SExprInfo *pExpr = tscExprGet(pNewQueryInfo, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid); @@ -1959,12 +1942,12 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter tscDebug( "%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%u, transfer to ts_comp query to retrieve timestamps, " "exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, name:%s", - pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo), + pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscNumOfExprs(pNewQueryInfo), numOfCols, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pNewQueryInfo->pTableMetaInfo[0]->name)); } } else { assert(0); - SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd); pNewQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY; } @@ -1975,7 +1958,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); assert((pQueryInfo->type & TSDB_QUERY_TYPE_SUBQUERY) == 0); int32_t code = TSDB_CODE_SUCCESS; @@ -2010,7 +1993,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { } SSqlObj* pSub = pSql->pSubs[i]; - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSub->cmd, 0, 0); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSub->cmd, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) && (pTableMetaInfo->vgroupList->numOfVgroups == 0)) { pSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; break; @@ -2098,7 +2081,7 @@ typedef struct SFirstRoundQuerySup { void doAppendData(SInterResult* pInterResult, TAOS_ROW row, int32_t numOfCols, SQueryInfo* pQueryInfo) { TSKEY key = INT64_MIN; for(int32_t i = 0; i < numOfCols; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag) || pExpr->base.functionId == TSDB_FUNC_PRJ) { continue; } @@ -2159,7 +2142,7 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { SFirstRoundQuerySup* pSup = param; SSqlObj* pParent = pSup->pParent; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); int32_t code = taos_errno(pSql); if (code != TSDB_CODE_SUCCESS) { @@ -2191,7 +2174,7 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { int32_t offset = 0; for (int32_t i = 0; i < numOfCols && offset < pSup->tagLen; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); // tag or group by column if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag) || pExpr->base.functionId == TSDB_FUNC_PRJ) { @@ -2242,7 +2225,7 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { // set the parameters for the second round query process SSqlCmd *pPCmd = &pParent->cmd; - SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pPCmd, 0); + SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pPCmd); int32_t resRows = pSup->numOfRows; if (pSup->numOfRows > 0) { @@ -2292,8 +2275,8 @@ void tscFirstRoundCallback(void* param, TAOS_RES* tres, int code) { } int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); - STableMetaInfo* pTableMetaInfo1 = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); + STableMetaInfo* pTableMetaInfo1 = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); SFirstRoundQuerySup *pSup = calloc(1, sizeof(SFirstRoundQuerySup)); @@ -2305,15 +2288,20 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { SSqlObj *pNew = createSubqueryObj(pSql, 0, tscFirstRoundCallback, pSup, TSDB_SQL_SELECT, NULL); SSqlCmd *pCmd = &pNew->cmd; + SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pCmd); + assert(pQueryInfo->numOfTables == 1); + + SArray* pColList = pNewQueryInfo->colList; + pNewQueryInfo->colList = NULL; + tscClearSubqueryInfo(pCmd); tscFreeSqlResult(pSql); - SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pCmd, 0); - assert(pQueryInfo->numOfTables == 1); - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pNewQueryInfo, 0); tscInitQueryInfo(pNewQueryInfo); + + // add the group cond pNewQueryInfo->groupbyExpr = pQueryInfo->groupbyExpr; if (pQueryInfo->groupbyExpr.columnInfo != NULL) { pNewQueryInfo->groupbyExpr.columnInfo = taosArrayDup(pQueryInfo->groupbyExpr.columnInfo); @@ -2323,28 +2311,31 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { } } + // add the tag filter cond if (tscTagCondCopy(&pNewQueryInfo->tagCond, &pQueryInfo->tagCond) != 0) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } + pNewQueryInfo->window = pQueryInfo->window; pNewQueryInfo->interval = pQueryInfo->interval; + pNewQueryInfo->sessionWindow = pQueryInfo->sessionWindow; pCmd->command = TSDB_SQL_SELECT; pNew->fp = tscFirstRoundCallback; - int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + int32_t numOfExprs = (int32_t) tscNumOfExprs(pQueryInfo); int32_t index = 0; for(int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_TS && pQueryInfo->interval.interval > 0) { taosArrayPush(pSup->pColsInfo, &pExpr->base.resColId); 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); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, 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); @@ -2353,7 +2344,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); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, 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; @@ -2366,7 +2357,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { schema = tGetTbnameColumnSchema(); } - SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG, getNewResColId(pCmd)); p->base.resColId = pExpr->base.resColId; } else if (pExpr->base.functionId == TSDB_FUNC_PRJ) { int32_t num = (int32_t) taosArrayGetSize(pNewQueryInfo->groupbyExpr.columnInfo); @@ -2380,7 +2371,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); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, 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; @@ -2390,6 +2381,21 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { } } + // add the normal column filter cond + if (pColList != NULL) { + size_t s = taosArrayGetSize(pColList); + for (int32_t i = 0; i < s; ++i) { + SColumn *pCol = taosArrayGetP(pColList, i); + + if (pCol->info.flist.numOfFilters > 0) { // copy to the pNew->cmd.colList if it is filtered. + SColumn *p = tscColumnClone(pCol); + taosArrayPush(pNewQueryInfo->colList, &p); + } + } + + tscColumnListDestroy(pColList); + } + tscInsertPrimaryTsSourceColumn(pNewQueryInfo, pTableMetaInfo->pTableMeta->id.uid); tscTansformFuncForSTableQuery(pNewQueryInfo); @@ -2397,7 +2403,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, - tscSqlExprNumOfExprs(pNewQueryInfo), index+1, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); + tscNumOfExprs(pNewQueryInfo), index+1, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); tscHandleMasterSTableQuery(pNew); return TSDB_CODE_SUCCESS; @@ -2422,14 +2428,12 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { tExtMemBuffer **pMemoryBuf = NULL; tOrderDescriptor *pDesc = NULL; - SColumnModel *pModel = NULL; - SColumnModel *pFinalModel = NULL; pRes->qId = 0x1; // hack the qhandle check const uint32_t nBufferSize = (1u << 16u); // 64KB - SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); SSubqueryState *pState = &pSql->subState; @@ -2442,9 +2446,9 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { assert(pState->numOfSub > 0); - int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, &pFinalModel, nBufferSize); + int32_t ret = tscLocalReducerEnvCreate(pQueryInfo, &pMemoryBuf, pSql->subState.numOfSub, &pDesc, nBufferSize, pSql->self); if (ret != 0) { - pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; + pRes->code = ret; tscAsyncResultOnError(pSql); tfree(pMemoryBuf); return ret; @@ -2455,7 +2459,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { if (pSql->pSubs == NULL) { tfree(pSql->pSubs); pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel,pState->numOfSub); + tscLocalReducerEnvDestroy(pMemoryBuf, pDesc,pState->numOfSub); tscAsyncResultOnError(pSql); return ret; @@ -2498,8 +2502,6 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { trs->subqueryIndex = i; trs->pParentSql = pSql; - trs->pFinalColModel = pModel; - trs->pFFColModel = pFinalModel; SSqlObj *pNew = tscCreateSTableSubquery(pSql, trs, NULL); if (pNew == NULL) { @@ -2511,7 +2513,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { // todo handle multi-vnode situation if (pQueryInfo->tsBuf) { - SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd); pNewQueryInfo->tsBuf = tsBufClone(pQueryInfo->tsBuf); assert(pNewQueryInfo->tsBuf != NULL); } @@ -2524,13 +2526,13 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { tscError("0x%"PRIx64" failed to prepare subquery structure and launch subqueries", pSql->self); pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel, pState->numOfSub); + tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pState->numOfSub); doCleanupSubqueries(pSql, i); return pRes->code; // free all allocated resource } if (pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED) { - tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel, pState->numOfSub); + tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pState->numOfSub); doCleanupSubqueries(pSql, i); return pRes->code; } @@ -2598,7 +2600,7 @@ static int32_t tscReissueSubquery(SRetrieveSupport *oriTrs, SSqlObj *pSql, int32 SSqlObj *pParentSql = trsupport->pParentSql; int32_t subqueryIndex = trsupport->subqueryIndex; - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); SVgroupInfo* pVgroup = &pTableMetaInfo->vgroupList->vgroups[0]; tExtMemBufferClear(trsupport->pExtMemBuffer[subqueryIndex]); @@ -2695,13 +2697,13 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO tstrerror(pParentSql->res.code)); // release allocated resource - tscLocalReducerEnvDestroy(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor, trsupport->pFinalColModel, trsupport->pFFColModel, + tscLocalReducerEnvDestroy(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor, pState->numOfSub); tscFreeRetrieveSup(pSql); // in case of second stage join subquery, invoke its callback function instead of regular QueueAsyncRes - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pParentSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pParentSql->cmd); if (!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) { (*pParentSql->fp)(pParentSql->param, pParentSql, pParentSql->res.code); @@ -2718,7 +2720,7 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p tOrderDescriptor *pDesc = trsupport->pOrderDescriptor; SSubqueryState* pState = &pParentSql->subState; - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; @@ -2767,22 +2769,28 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p tscDebug("0x%"PRIx64" retrieve from %d vnodes completed.final NumOfRows:%" PRId64 ",start to build loser tree", pParentSql->self, pState->numOfSub, pState->numOfRetrievedRows); - SQueryInfo *pPQueryInfo = tscGetQueryInfo(&pParentSql->cmd, 0); + SQueryInfo *pPQueryInfo = tscGetQueryInfo(&pParentSql->cmd); tscClearInterpInfo(pPQueryInfo); - tscCreateLocalMerger(trsupport->pExtMemBuffer, pState->numOfSub, pDesc, trsupport->pFinalColModel, trsupport->pFFColModel, pParentSql); + code = tscCreateLocalMerger(trsupport->pExtMemBuffer, pState->numOfSub, pDesc, pPQueryInfo, &pParentSql->res.pLocalMerger, pParentSql->self); + pParentSql->res.code = code; + + if (code == TSDB_CODE_SUCCESS && trsupport->pExtMemBuffer == NULL) { + pParentSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty + } else { + pParentSql->cmd.command = TSDB_SQL_RETRIEVE_LOCALMERGE; + } + + tscCreateResPointerInfo(&pParentSql->res, pPQueryInfo); + tscDebug("0x%"PRIx64" build loser tree completed", pParentSql->self); pParentSql->res.precision = pSql->res.precision; pParentSql->res.numOfRows = 0; pParentSql->res.row = 0; - - tscFreeRetrieveSup(pSql); + pParentSql->res.numOfGroups = 0; - // set the command flag must be after the semaphore been correctly set. - if (pParentSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) { - pParentSql->cmd.command = TSDB_SQL_RETRIEVE_LOCALMERGE; - } + tscFreeRetrieveSup(pSql); if (pParentSql->res.code == TSDB_CODE_SUCCESS) { (*pParentSql->fp)(pParentSql->param, pParentSql, 0); @@ -2808,7 +2816,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR SSubqueryState* pState = &pParentSql->subState; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); SVgroupInfo *pVgroup = &pTableMetaInfo->vgroupList->vgroups[0]; if (pParentSql->res.code != TSDB_CODE_SUCCESS) { @@ -2846,7 +2854,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR } SSqlRes * pRes = &pSql->res; - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); if (numOfRows > 0) { assert(pRes->numOfRows == numOfRows); @@ -2855,7 +2863,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR tscDebug("0x%"PRIx64" sub:%p retrieve numOfRows:%d totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d", pParentSql->self, pSql, pRes->numOfRows, pState->numOfRetrievedRows, pSql->epSet.fqdn[pSql->epSet.inUse], idx); - if (num > tsMaxNumOfOrderedResults && tscIsProjectionQueryOnSTable(pQueryInfo, 0)) { + if (num > tsMaxNumOfOrderedResults && tscIsProjectionQueryOnSTable(pQueryInfo, 0) && !(tscGetQueryInfo(&pParentSql->cmd)->distinctTag)) { tscError("0x%"PRIx64" sub:0x%"PRIx64" num of OrderedRes is too many, max allowed:%" PRId32 " , current:%" PRId64, pParentSql->self, pSql->self, tsMaxNumOfOrderedResults, num); tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_TSC_SORTED_RES_TOO_MANY); @@ -2898,7 +2906,7 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo SSqlObj *pNew = createSubqueryObj(pSql, table_index, tscRetrieveDataRes, trsupport, TSDB_SQL_SELECT, prevSqlObj); if (pNew != NULL) { // the sub query of two-stage super table query - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pNew->cmd); pNew->cmd.active = pQueryInfo; pQueryInfo->type |= TSDB_QUERY_TYPE_STABLE_SUBQUERY; @@ -2907,7 +2915,7 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo pQueryInfo->limit.limit = -1; pQueryInfo->limit.offset = 0; - assert(pQueryInfo->numOfTables == 1 && pNew->cmd.numOfClause == 1 && trsupport->subqueryIndex < pSql->subState.numOfSub); + assert(trsupport->subqueryIndex < pSql->subState.numOfSub); // launch subquery for each vnode, so the subquery index equals to the vgroupIndex. STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, table_index); @@ -2933,10 +2941,10 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) { SSqlObj* pParentSql = trsupport->pParentSql; SSqlObj* pSql = (SSqlObj *) tres; - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); - assert(pSql->cmd.numOfClause == 1 && pQueryInfo->numOfTables == 1); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); + assert(pQueryInfo->numOfTables == 1); - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); SVgroupInfo* pVgroup = &pTableMetaInfo->vgroupList->vgroups[trsupport->subqueryIndex]; // stable query killed or other subquery failed, all query stopped @@ -2963,7 +2971,6 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) { tscError("0x%"PRIx64" sub:0x%"PRIx64" failed code:%s, retry:%d", pParentSql->self, pSql->self, tstrerror(code), trsupport->numOfRetry); int32_t sent = 0; - tscReissueSubquery(trsupport, pSql, code, &sent); if (sent) { return; @@ -3035,8 +3042,8 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) pParentObj->res.code = pSql->res.code; // set the flag in the parent sqlObj - if (pSql->cmd.submitSchema) { - pParentObj->cmd.submitSchema = 1; + if (pSql->cmd.insertParam.schemaAttached) { + pParentObj->cmd.insertParam.schemaAttached = 1; } } @@ -3071,8 +3078,8 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) // clean up tableMeta in cache tscFreeQueryInfo(&pSql->cmd, false); - SQueryInfo* pQueryInfo = tscGetQueryInfoS(&pSql->cmd, 0); - STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pParentObj->cmd, pSql->cmd.clauseIndex, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfoS(&pSql->cmd); + STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pParentObj->cmd, 0); tscAddTableMetaInfo(pQueryInfo, &pMasterTableMetaInfo->name, NULL, NULL, NULL, NULL); subquerySetState(pSql, &pParentObj->subState, i, 0); @@ -3084,15 +3091,15 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) tscError("0x%"PRIx64" Async insertion completed, total inserted:%d rows, numOfFailed:%d, numOfTotal:%d", pParentObj->self, pParentObj->res.numOfRows, numOfFailed, numOfSub); - tscDebug("0x%"PRIx64" cleanup %d tableMeta in hashTable before reparse sql", pParentObj->self, pParentObj->cmd.numOfTables); - for(int32_t i = 0; i < pParentObj->cmd.numOfTables; ++i) { + tscDebug("0x%"PRIx64" cleanup %d tableMeta in hashTable before reparse sql", pParentObj->self, pParentObj->cmd.insertParam.numOfTables); + for(int32_t i = 0; i < pParentObj->cmd.insertParam.numOfTables; ++i) { char name[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(pParentObj->cmd.pTableNameList[i], name); + tNameExtractFullName(pParentObj->cmd.insertParam.pTableNameList[i], name); taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN)); } pParentObj->res.code = TSDB_CODE_SUCCESS; - pParentObj->cmd.parseFinished = false; +// pParentObj->cmd.parseFinished = false; tscResetSqlCmd(&pParentObj->cmd, false); @@ -3127,7 +3134,7 @@ int32_t tscHandleInsertRetry(SSqlObj* pParent, SSqlObj* pSql) { SInsertSupporter* pSupporter = (SInsertSupporter*) pSql->param; assert(pSupporter->index < pSupporter->pSql->subState.numOfSub); - STableDataBlocks* pTableDataBlock = taosArrayGetP(pParent->cmd.pDataBlocks, pSupporter->index); + STableDataBlocks* pTableDataBlock = taosArrayGetP(pParent->cmd.insertParam.pDataBlocks, pSupporter->index); int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock); if ((pRes->code = code)!= TSDB_CODE_SUCCESS) { @@ -3160,7 +3167,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { return TSDB_CODE_SUCCESS; } - pSql->subState.numOfSub = (uint16_t)taosArrayGetSize(pCmd->pDataBlocks); + pSql->subState.numOfSub = (uint16_t)taosArrayGetSize(pCmd->insertParam.pDataBlocks); assert(pSql->subState.numOfSub > 0); pRes->code = TSDB_CODE_SUCCESS; @@ -3210,7 +3217,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { pNew->fetchFp = pNew->fp; pSql->pSubs[numOfSub] = pNew; - STableDataBlocks* pTableDataBlock = taosArrayGetP(pCmd->pDataBlocks, numOfSub); + STableDataBlocks* pTableDataBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, numOfSub); pRes->code = tscCopyDataBlockToPayload(pNew, pTableDataBlock); if (pRes->code == TSDB_CODE_SUCCESS) { tscDebug("0x%"PRIx64" sub:%p create subObj success. orderOfSub:%d", pSql->self, pNew, numOfSub); @@ -3228,7 +3235,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { goto _error; } - pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); + pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks); // use the local variable for (int32_t j = 0; j < numOfSub; ++j) { @@ -3244,7 +3251,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { } static char* getResultBlockPosition(SSqlCmd* pCmd, SSqlRes* pRes, int32_t columnIndex, int16_t* bytes) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); SInternalField* pInfo = (SInternalField*) TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, columnIndex); assert(pInfo->pExpr->pExpr == NULL); @@ -3260,7 +3267,7 @@ static char* getResultBlockPosition(SSqlCmd* pCmd, SSqlRes* pRes, int32_t column static void doBuildResFromSubqueries(SSqlObj* pSql) { SSqlRes* pRes = &pSql->res; - SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); int32_t numOfRes = INT32_MAX; for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { @@ -3278,7 +3285,7 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { return; } - tscRestoreFuncForSTableQuery(pQueryInfo); +// tscRestoreFuncForSTableQuery(pQueryInfo); int32_t rowSize = tscGetResRowLength(pQueryInfo->exprList); assert(numOfRes * rowSize > 0); @@ -3306,12 +3313,12 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { continue; } - SQueryInfo* pSubQueryInfo = pSub->cmd.pQueryInfo[0]; + SQueryInfo* pSubQueryInfo = pSub->cmd.pQueryInfo; tscRestoreFuncForSTableQuery(pSubQueryInfo); tscFieldInfoUpdateOffset(pSubQueryInfo); } - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { SColumnIndex* pIndex = &pRes->pColumnIndex[i]; SSqlRes* pRes1 = &pSql->pSubs[pIndex->tableIndex]->res; @@ -3357,8 +3364,8 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { } if (pRes->tsrow == NULL) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); - pRes->numOfCols = (int16_t) tscSqlExprNumOfExprs(pQueryInfo); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd); + pRes->numOfCols = (int16_t) tscNumOfExprs(pQueryInfo); pRes->tsrow = calloc(pRes->numOfCols, POINTER_BYTES); pRes->urow = calloc(pRes->numOfCols, POINTER_BYTES); @@ -3370,8 +3377,6 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { tscAsyncResultOnError(pSql); return; } - - tscRestoreFuncForSTableQuery(pQueryInfo); } assert (pRes->row >= pRes->numOfRows); @@ -3411,7 +3416,7 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql) { return pRes->tsrow; } - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); size_t size = tscNumOfFields(pQueryInfo); @@ -3444,7 +3449,7 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { bool hasData = true; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { bool allSubqueryExhausted = true; @@ -3456,7 +3461,7 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { SSqlRes *pRes1 = &pSql->pSubs[i]->res; SSqlCmd *pCmd1 = &pSql->pSubs[i]->cmd; - SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pCmd1, pCmd1->clauseIndex); + SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pCmd1); assert(pQueryInfo1->numOfTables == 1); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo1, 0); @@ -3480,7 +3485,7 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { } SSqlRes * pRes1 = &pSql->pSubs[i]->res; - SQueryInfo *pQueryInfo1 = tscGetQueryInfo(&pSql->pSubs[i]->cmd, 0); + SQueryInfo *pQueryInfo1 = tscGetQueryInfo(&pSql->pSubs[i]->cmd); if ((pRes1->row >= pRes1->numOfRows && tscHasReachLimitation(pQueryInfo1, pRes1) && tscIsProjectionQuery(pQueryInfo1)) || @@ -3494,11 +3499,10 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { return hasData; } -void* createQueryInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, - SOperatorInfo* pSourceOperator, char* sql, void* merger, int32_t stage) { +// todo remove pExprs +void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, + SOperatorInfo* pSourceOperator, char* sql, void* merger, int32_t stage) { assert(pQueryInfo != NULL); - int16_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput; - SQInfo *pQInfo = (SQInfo *)calloc(1, sizeof(SQInfo)); if (pQInfo == NULL) { goto _cleanup; @@ -3516,13 +3520,25 @@ void* createQueryInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, ST pQueryAttr->tableGroupInfo = *pTableGroupInfo; // calculate the result row size - for (int16_t col = 0; col < numOfOutput; ++col) { - assert(pExprs[col].base.resBytes > 0); - pQueryAttr->resultRowSize += pExprs[col].base.resBytes; + SExprInfo* pEx = NULL; + int32_t num = 0; + if (pQueryAttr->pExpr3 != NULL) { + pEx = pQueryAttr->pExpr3; + num = pQueryAttr->numOfExpr3; + } else if (pQueryAttr->pExpr2 != NULL) { + pEx = pQueryAttr->pExpr2; + num = pQueryAttr->numOfExpr2; + } else { + pEx = pQueryAttr->pExpr1; + num = pQueryAttr->numOfOutput; + } + + for (int16_t col = 0; col < num; ++col) { + pQueryAttr->resultRowSize += pEx[col].base.resBytes; // keep the tag length - if (TSDB_COL_IS_TAG(pExprs[col].base.colInfo.flag)) { - pQueryAttr->tagLen += pExprs[col].base.resBytes; + if (TSDB_COL_IS_TAG(pEx[col].base.colInfo.flag)) { + pQueryAttr->tagLen += pEx[col].base.resBytes; } } @@ -3580,15 +3596,9 @@ void* createQueryInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, ST } } - for (int32_t i = 0; i < numOfOutput; ++i) { - SExprInfo* pExprInfo = &pExprs[i]; - if (pExprInfo->pExpr != NULL) { - tExprTreeDestroy(pExprInfo->pExpr, NULL); - pExprInfo->pExpr = NULL; - } - } - - tfree(pExprs); + // todo refactor: filter should not be applied here. + createFilterInfo(pQueryAttr, 0); + pQueryAttr->numOfFilterCols = 0; SArray* pa = NULL; if (stage == MASTER_SCAN) { diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 902d8bef5f077333d78e0f8e5fcf3d916661a366..50d4325483402136931bec130c657a82053fb725 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -14,10 +14,11 @@ */ #include "tscUtil.h" +#include "tsched.h" #include "hash.h" #include "os.h" -#include "texpr.h" #include "taosmsg.h" +#include "texpr.h" #include "tkey.h" #include "tmd5.h" #include "tscLocalMerge.h" @@ -30,7 +31,67 @@ #include "ttokendef.h" static void freeQueryInfoImpl(SQueryInfo* pQueryInfo); -static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta); + +int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len) { + int32_t n = 0; + + switch (type) { + case TSDB_DATA_TYPE_NULL: + n = sprintf(str, "null"); + break; + + case TSDB_DATA_TYPE_BOOL: + n = sprintf(str, (*(int8_t*)buf) ? "true" : "false"); + break; + + case TSDB_DATA_TYPE_TINYINT: + n = sprintf(str, "%d", *(int8_t*)buf); + break; + + case TSDB_DATA_TYPE_SMALLINT: + n = sprintf(str, "%d", *(int16_t*)buf); + break; + + case TSDB_DATA_TYPE_INT: + n = sprintf(str, "%d", *(int32_t*)buf); + break; + + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_TIMESTAMP: + n = sprintf(str, "%" PRId64, *(int64_t*)buf); + break; + + case TSDB_DATA_TYPE_FLOAT: + n = sprintf(str, "%f", GET_FLOAT_VAL(buf)); + break; + + case TSDB_DATA_TYPE_DOUBLE: + n = sprintf(str, "%f", GET_DOUBLE_VAL(buf)); + break; + + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + if (bufSize < 0) { + tscError("invalid buf size"); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + *str = '"'; + memcpy(str + 1, buf, bufSize); + *(str + bufSize + 1) = '"'; + n = bufSize + 2; + break; + + default: + tscError("unsupported type:%d", type); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + *len = n; + + return TSDB_CODE_SUCCESS; +} + static void tscStrToLower(char *str, int32_t n) { if (str == NULL || n <= 0) { return;} @@ -78,10 +139,10 @@ void tsSetSTableQueryCond(STagCond* pTagCond, uint64_t uid, SBufferWriter* bw) { } bool tscQueryTags(SQueryInfo* pQueryInfo) { - int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + int32_t numOfCols = (int32_t) tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfCols; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); int32_t functId = pExpr->base.functionId; // "select count(tbname)" query @@ -98,10 +159,10 @@ bool tscQueryTags(SQueryInfo* pQueryInfo) { } bool tscQueryBlockInfo(SQueryInfo* pQueryInfo) { - int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + int32_t numOfCols = (int32_t) tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfCols; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); int32_t functId = pExpr->base.functionId; if (functId == TSDB_FUNC_BLKINFO) { @@ -146,14 +207,14 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) { * 1. failed to get tableMeta from server; 2. not a super table; 3. limitation is 0; * 4. show queries, instead of a select query */ - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); if (pTableMetaInfo == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) || pQueryInfo->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT || numOfExprs == 0) { return false; } for (int32_t i = 0; i < numOfExprs; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; + int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId; if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ && @@ -189,10 +250,10 @@ bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableInde } bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) { - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; + int32_t functionId = tscExprGet(pQueryInfo, i)->base.functionId; if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ && functionId != TSDB_FUNC_TAG && functionId != TSDB_FUNC_TS && functionId != TSDB_FUNC_ARITHM) { @@ -203,10 +264,27 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) { return true; } +bool tscHasColumnFilter(SQueryInfo* pQueryInfo) { + // filter on primary timestamp column + if (pQueryInfo->window.skey != INT64_MIN || pQueryInfo->window.ekey != INT64_MAX) { + return true; + } + + size_t size = taosArrayGetSize(pQueryInfo->colList); + for (int32_t i = 0; i < size; ++i) { + SColumn* pCol = taosArrayGet(pQueryInfo->colList, i); + if (pCol->info.flist.numOfFilters > 0) { + return true; + } + } + + return false; +} + bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) { - size_t size = tscSqlExprNumOfExprs(pQueryInfo); + size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); assert(pExpr != NULL); int32_t functionId = pExpr->base.functionId; @@ -222,7 +300,7 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) { return true; } -bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo) { +bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo) { if (tscIsProjectionQuery(pQueryInfo)) { return false; } @@ -242,7 +320,7 @@ bool tscGroupbyColumn(SQueryInfo* pQueryInfo) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - SSqlGroupbyExpr* pGroupbyExpr = &pQueryInfo->groupbyExpr; + SGroupbyExpr* pGroupbyExpr = &pQueryInfo->groupbyExpr; for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols; ++k) { SColIndex* pIndex = taosArrayGet(pGroupbyExpr->columnInfo, k); if (!TSDB_COL_IS_TAG(pIndex->flag) && pIndex->colIndex < numOfCols) { // group by normal columns @@ -254,10 +332,10 @@ bool tscGroupbyColumn(SQueryInfo* pQueryInfo) { } bool tscIsTopBotQuery(SQueryInfo* pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } @@ -275,8 +353,8 @@ bool tscIsTopBotQuery(SQueryInfo* pQueryInfo) { } bool isTsCompQuery(SQueryInfo* pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, 0); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); + SExprInfo* pExpr1 = tscExprGet(pQueryInfo, 0); if (numOfExprs != 1) { return false; } @@ -285,15 +363,15 @@ bool isTsCompQuery(SQueryInfo* pQueryInfo) { } bool hasTagValOutput(SQueryInfo* pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, 0); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); + SExprInfo* pExpr1 = tscExprGet(pQueryInfo, 0); if (numOfExprs == 1 && pExpr1->base.functionId == TSDB_FUNC_TS_COMP) { return true; } for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } @@ -308,9 +386,9 @@ bool hasTagValOutput(SQueryInfo* pQueryInfo) { } bool timeWindowInterpoRequired(SQueryInfo *pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } @@ -325,9 +403,9 @@ bool timeWindowInterpoRequired(SQueryInfo *pQueryInfo) { } bool isStabledev(SQueryInfo* pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } @@ -342,9 +420,9 @@ bool isStabledev(SQueryInfo* pQueryInfo) { } bool tscIsTWAQuery(SQueryInfo* pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } @@ -361,9 +439,9 @@ bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo) { } bool tscNeedReverseScan(SQueryInfo* pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } @@ -399,9 +477,38 @@ bool isSimpleAggregate(SQueryInfo* pQueryInfo) { return true; } - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + + if (!IS_MULTIOUTPUT(aAggs[functionId].status)) { + return true; + } + } + + return false; +} + +bool isSimpleAggregateRv(SQueryInfo* pQueryInfo) { + if (pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0) { + return false; + } + + if (tscGroupbyColumn(pQueryInfo) || isTsCompQuery(pQueryInfo)) { + return false; + } + + size_t numOfExprs = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } @@ -417,11 +524,12 @@ bool isSimpleAggregate(SQueryInfo* pQueryInfo) { } return false; + } bool isBlockDistQuery(SQueryInfo* pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); + SExprInfo* pExpr = tscExprGet(pQueryInfo, 0); return (numOfExprs == 1 && pExpr->base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX); } @@ -435,9 +543,9 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo) { } int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) { - if (pRes->tsrow == NULL) { - pRes->numOfCols = pQueryInfo->fieldsInfo.numOfOutput; + pRes->numOfCols = pQueryInfo->fieldsInfo.numOfOutput; + if (pRes->tsrow == NULL) { pRes->tsrow = calloc(pRes->numOfCols, POINTER_BYTES); pRes->urow = calloc(pRes->numOfCols, POINTER_BYTES); pRes->length = calloc(pRes->numOfCols, sizeof(int32_t)); @@ -590,58 +698,237 @@ void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBloc } } -static SColumnInfo* extractColumnInfoFromResult(STableMeta* pTableMeta, SArray* pTableCols) { +static SColumnInfo* extractColumnInfoFromResult(SArray* pTableCols) { int32_t numOfCols = (int32_t) taosArrayGetSize(pTableCols); SColumnInfo* pColInfo = calloc(numOfCols, sizeof(SColumnInfo)); - - SSchema *pSchema = pTableMeta->schema; for(int32_t i = 0; i < numOfCols; ++i) { SColumn* pCol = taosArrayGetP(pTableCols, i); - int32_t index = pCol->columnIndex; - - pColInfo[i].type = pSchema[index].type; - pColInfo[i].bytes = pSchema[index].bytes; - pColInfo[i].colId = pSchema[index].colId; + pColInfo[i] = pCol->info;//[index].type; } return pColInfo; } typedef struct SDummyInputInfo { - SSDataBlock *block; - SSqlRes *pRes; // refactor: remove it + SSDataBlock *block; + SSqlObj *pSql; // refactor: remove it + int32_t numOfFilterCols; + SSingleColumnFilterInfo *pFilterInfo; } SDummyInputInfo; -SSDataBlock* doGetDataBlock(void* param, bool* newgroup) { - SOperatorInfo *pOperator = (SOperatorInfo*) param; +typedef struct SJoinStatus { + SSDataBlock* pBlock; // point to the upstream block + int32_t index; + bool completed;// current upstream is completed or not +} SJoinStatus; - SDummyInputInfo *pInput = pOperator->info; - char* pData = pInput->pRes->data; - - SSDataBlock* pBlock = pInput->block; - pBlock->info.rows = pInput->pRes->numOfRows; - if (pBlock->info.rows == 0) { - return NULL; - } +typedef struct SJoinOperatorInfo { + SSDataBlock *pRes; + SJoinStatus *status; + int32_t numOfUpstream; + SRspResultInfo resultInfo; // todo refactor, add this info for each operator +} SJoinOperatorInfo; - //TODO refactor +static void doSetupSDataBlock(SSqlRes* pRes, SSDataBlock* pBlock) { int32_t offset = 0; + char* pData = pRes->data; for(int32_t i = 0; i < pBlock->info.numOfCols; ++i) { SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, i); if (pData != NULL) { pColData->pData = pData + offset * pBlock->info.rows; } else { - pColData->pData = pInput->pRes->urow[i]; + pColData->pData = pRes->urow[i]; } offset += pColData->info.bytes; } - pInput->pRes->numOfRows = 0; + pRes->numOfRows = 0; +} + +// NOTE: there is already exists data blocks before this function calls. +SSDataBlock* doGetDataBlock(void* param, bool* newgroup) { + SOperatorInfo *pOperator = (SOperatorInfo*) param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SDummyInputInfo *pInput = pOperator->info; + SSqlObj* pSql = pInput->pSql; + SSqlRes* pRes = &pSql->res; + + SSDataBlock* pBlock = pInput->block; + + pBlock->info.rows = pRes->numOfRows; + if (pRes->numOfRows != 0) { + doSetupSDataBlock(pRes, pBlock); + + if (pInput->numOfFilterCols > 0) { + doSetFilterColumnInfo(pInput->pFilterInfo, pInput->numOfFilterCols, pBlock); + int8_t* p = calloc(pBlock->info.rows, sizeof(int8_t)); + bool all = doFilterDataBlock(pInput->pFilterInfo, pInput->numOfFilterCols, pBlock->info.rows, p); + if (!all) { + doCompactSDataBlock(pBlock, pBlock->info.rows, p); + } + + tfree(p); + } + + *newgroup = false; + return pBlock; + } + + // No data block exists. So retrieve and transfer it into to SSDataBlock + TAOS_ROW pRow = NULL; + taos_fetch_block(pSql, &pRow); + + if (pRes->numOfRows == 0) { + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + pBlock->info.rows = pRes->numOfRows; + doSetupSDataBlock(pRes, pBlock); *newgroup = false; return pBlock; } +SSDataBlock* doDataBlockJoin(void* param, bool* newgroup) { + SOperatorInfo *pOperator = (SOperatorInfo*) param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + assert(pOperator->numOfUpstream > 1); + + SJoinOperatorInfo* pJoinInfo = pOperator->info; + pJoinInfo->pRes->info.rows = 0; + + while(1) { + for (int32_t i = 0; i < pOperator->numOfUpstream; ++i) { + SJoinStatus* pStatus = &pJoinInfo->status[i]; + if (pStatus->pBlock == NULL || pStatus->index >= pStatus->pBlock->info.rows) { + pStatus->pBlock = pOperator->upstream[i]->exec(pOperator->upstream[i], newgroup); + pStatus->index = 0; + + if (pStatus->pBlock == NULL) { + pOperator->status = OP_EXEC_DONE; + + pJoinInfo->resultInfo.total += pJoinInfo->pRes->info.rows; + return pJoinInfo->pRes; + } + } + } + + SJoinStatus* st0 = &pJoinInfo->status[0]; + SColumnInfoData* p0 = taosArrayGet(st0->pBlock->pDataBlock, 0); + int64_t* ts0 = (int64_t*) p0->pData; + + bool prefixEqual = true; + + while(1) { + prefixEqual = true; + for (int32_t i = 1; i < pJoinInfo->numOfUpstream; ++i) { + SJoinStatus* st = &pJoinInfo->status[i]; + + SColumnInfoData* p = taosArrayGet(st->pBlock->pDataBlock, 0); + int64_t* ts = (int64_t*)p->pData; + + if (ts[st->index] < ts0[st0->index]) { // less than the first + prefixEqual = false; + if ((++(st->index)) >= st->pBlock->info.rows) { + break; + } + } else if (ts[st->index] > ts0[st0->index]) { // greater than the first; + if (prefixEqual == true) { + prefixEqual = false; + for (int32_t j = 0; j < i; ++j) { + SJoinStatus* stx = &pJoinInfo->status[j]; + if ((++(stx->index)) >= stx->pBlock->info.rows) { + break; + } + } + } else { + if ((++(st0->index)) >= st0->pBlock->info.rows) { + break; + } + } + } + } + + if (prefixEqual) { + int32_t offset = 0; + bool completed = false; + for (int32_t i = 0; i < pOperator->numOfUpstream; ++i) { + SJoinStatus* st1 = &pJoinInfo->status[i]; + int32_t rows = pJoinInfo->pRes->info.rows; + + for (int32_t j = 0; j < st1->pBlock->info.numOfCols; ++j) { + SColumnInfoData* pCol1 = taosArrayGet(pJoinInfo->pRes->pDataBlock, j + offset); + SColumnInfoData* pSrc = taosArrayGet(st1->pBlock->pDataBlock, j); + + int32_t bytes = pSrc->info.bytes; + memcpy(pCol1->pData + rows * bytes, pSrc->pData + st1->index * bytes, bytes); + } + + offset += st1->pBlock->info.numOfCols; + if ((++(st1->index)) == st1->pBlock->info.rows) { + completed = true; + } + } + + if ((++pJoinInfo->pRes->info.rows) >= pJoinInfo->resultInfo.capacity) { + pJoinInfo->resultInfo.total += pJoinInfo->pRes->info.rows; + return pJoinInfo->pRes; + } + + if (completed == true) { + break; + } + } + } +/* + while (st0->index < st0->pBlock->info.rows && st1->index < st1->pBlock->info.rows) { + SColumnInfoData* p0 = taosArrayGet(st0->pBlock->pDataBlock, 0); + SColumnInfoData* p1 = taosArrayGet(st1->pBlock->pDataBlock, 0); + + int64_t* ts0 = (int64_t*)p0->pData; + int64_t* ts1 = (int64_t*)p1->pData; + if (ts0[st0->index] == ts1[st1->index]) { // add to the final result buffer + // check if current output buffer is over the threshold to pause current loop + int32_t rows = pJoinInfo->pRes->info.rows; + for (int32_t j = 0; j < st0->pBlock->info.numOfCols; ++j) { + SColumnInfoData* pCol1 = taosArrayGet(pJoinInfo->pRes->pDataBlock, j); + SColumnInfoData* pSrc = taosArrayGet(st0->pBlock->pDataBlock, j); + + int32_t bytes = pSrc->info.bytes; + memcpy(pCol1->pData + rows * bytes, pSrc->pData + st0->index * bytes, bytes); + } + + for (int32_t j = 0; j < st1->pBlock->info.numOfCols; ++j) { + SColumnInfoData* pCol1 = taosArrayGet(pJoinInfo->pRes->pDataBlock, j + st0->pBlock->info.numOfCols); + SColumnInfoData* pSrc = taosArrayGet(st1->pBlock->pDataBlock, j); + + int32_t bytes = pSrc->info.bytes; + memcpy(pCol1->pData + rows * bytes, pSrc->pData + st1->index * bytes, bytes); + } + + st0->index++; + st1->index++; + + if ((++pJoinInfo->pRes->info.rows) >= pJoinInfo->resultInfo.capacity) { + pJoinInfo->resultInfo.total += pJoinInfo->pRes->info.rows; + return pJoinInfo->pRes; + } + } else if (ts0[st0->index] < ts1[st1->index]) { + st0->index++; + } else { + st1->index++; + } + }*/ + } +} + static void destroyDummyInputOperator(void* param, int32_t numOfOutput) { SDummyInputInfo* pInfo = (SDummyInputInfo*) param; @@ -652,15 +939,17 @@ static void destroyDummyInputOperator(void* param, int32_t numOfOutput) { } pInfo->block = destroyOutputBuf(pInfo->block); - pInfo->pRes = NULL; + pInfo->pSql = NULL; } // todo this operator servers as the adapter for Operator tree and SqlRes result, remove it later -SOperatorInfo* createDummyInputOperator(char* pResult, SSchema* pSchema, int32_t numOfCols) { +SOperatorInfo* createDummyInputOperator(SSqlObj* pSql, SSchema* pSchema, int32_t numOfCols, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols) { assert(numOfCols > 0); SDummyInputInfo* pInfo = calloc(1, sizeof(SDummyInputInfo)); - pInfo->pRes = (SSqlRes*) pResult; + pInfo->pSql = pSql; + pInfo->pFilterInfo = pFilterInfo; + pInfo->numOfFilterCols = numOfFilterCols; pInfo->block = calloc(numOfCols, sizeof(SSDataBlock)); pInfo->block->info.numOfCols = numOfCols; @@ -686,6 +975,52 @@ SOperatorInfo* createDummyInputOperator(char* pResult, SSchema* pSchema, int32_t return pOptr; } +static void destroyJoinOperator(void* param, int32_t numOfOutput) { + SJoinOperatorInfo* pInfo = (SJoinOperatorInfo*) param; + tfree(pInfo->status); + + pInfo->pRes = destroyOutputBuf(pInfo->pRes); +} + +SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUpstream, SSchema* pSchema, int32_t numOfOutput) { + SJoinOperatorInfo* pInfo = calloc(1, sizeof(SJoinOperatorInfo)); + + pInfo->numOfUpstream = numOfUpstream; + pInfo->status = calloc(numOfUpstream, sizeof(SJoinStatus)); + + SRspResultInfo* pResInfo = &pInfo->resultInfo; + pResInfo->capacity = 4096; + pResInfo->threshold = (int32_t) (4096 * 0.8); + + pInfo->pRes = calloc(1, sizeof(SSDataBlock)); + pInfo->pRes->info.numOfCols = numOfOutput; + pInfo->pRes->pDataBlock = taosArrayInit(numOfOutput, sizeof(SColumnInfoData)); + for(int32_t i = 0; i < numOfOutput; ++i) { + SColumnInfoData colData = {{0}}; + colData.info.bytes = pSchema[i].bytes; + colData.info.type = pSchema[i].type; + colData.info.colId = pSchema[i].colId; + colData.pData = calloc(1, colData.info.bytes * pResInfo->capacity); + + taosArrayPush(pInfo->pRes->pDataBlock, &colData); + } + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + pOperator->name = "JoinOperator"; + pOperator->operatorType = OP_Join; + pOperator->numOfOutput = numOfOutput; + pOperator->blockingOptr = false; + pOperator->info = pInfo; + pOperator->exec = doDataBlockJoin; + pOperator->cleanup = destroyJoinOperator; + + for(int32_t i = 0; i < numOfUpstream; ++i) { + appendUpstream(pOperator, pUpstream[i]); + } + + return pOperator; +} + void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo) { // set the correct result SSDataBlock* p = pQueryInfo->pQInfo->runtimeEnv.outputBuf; @@ -700,18 +1035,26 @@ void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo) { pRes->completed = (pRes->numOfRows == 0); } -void handleDownstreamOperator(SSqlRes* pRes, SQueryInfo* pQueryInfo) { - if (pQueryInfo->pDownstream != NULL) { - // handle the following query process - SQueryInfo *px = pQueryInfo->pDownstream; - SColumnInfo* pColumnInfo = extractColumnInfoFromResult(px->pTableMetaInfo[0]->pTableMeta, px->colList); - int32_t numOfOutput = (int32_t) tscSqlExprNumOfExprs(px); +void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQueryInfo* px, SSqlRes* pOutput) { + // handle the following query process + if (px->pQInfo == NULL) { + SColumnInfo* pColumnInfo = extractColumnInfoFromResult(px->colList); + + int32_t numOfOutput = (int32_t)tscNumOfExprs(px); + int32_t numOfCols = (int32_t)taosArrayGetSize(px->colList); + + SQueriedTableInfo info = { + .colList = pColumnInfo, + .numOfCols = numOfCols, + }; - int32_t numOfCols = (int32_t) taosArrayGetSize(px->colList); - SQueriedTableInfo info = {.colList = pColumnInfo, .numOfCols = numOfCols,}; SSchema* pSchema = tscGetTableSchema(px->pTableMetaInfo[0]->pTableMeta); - STableGroupInfo tableGroupInfo = {.numOfTables = 1, .pGroupList = taosArrayInit(1, POINTER_BYTES),}; + STableGroupInfo tableGroupInfo = { + .numOfTables = 1, + .pGroupList = taosArrayInit(1, POINTER_BYTES), + }; + tableGroupInfo.map = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); STableKeyInfo tableKeyInfo = {.pTable = NULL, .lastKey = INT64_MIN}; @@ -721,18 +1064,93 @@ void handleDownstreamOperator(SSqlRes* pRes, SQueryInfo* pQueryInfo) { taosArrayPush(tableGroupInfo.pGroupList, &group); - SOperatorInfo* pSourceOptr = createDummyInputOperator((char*)pRes, pSchema, numOfCols); + // if it is a join query, create join operator here + int32_t numOfCol1 = px->pTableMetaInfo[0]->pTableMeta->tableInfo.numOfColumns; - SExprInfo *exprInfo = NULL; - /*int32_t code = */createQueryFunc(&info, numOfOutput, &exprInfo, px->exprList->pData, NULL, px->type, NULL); - px->pQInfo = createQueryInfoFromQueryNode(px, exprInfo, &tableGroupInfo, pSourceOptr, NULL, NULL, MASTER_SCAN); + int32_t numOfFilterCols = 0; + SColumnInfo* tableCols = calloc(numOfCol1, sizeof(SColumnInfo)); + for(int32_t i = 0; i < numOfCol1; ++i) { + SColumn* pCol = taosArrayGetP(px->colList, i); + if (pCol->info.flist.numOfFilters > 0) { + numOfFilterCols += 1; + } - uint64_t qId = 0; - qTableQuery(px->pQInfo, &qId); - convertQueryResult(pRes, px); + tableCols[i] = pCol->info; + } + SSingleColumnFilterInfo* pFilterInfo = NULL; + if (numOfFilterCols > 0) { + doCreateFilterInfo(tableCols, numOfCol1, numOfFilterCols, &pFilterInfo, 0); + } + + SOperatorInfo* pSourceOperator = createDummyInputOperator(pSqlObjList[0], pSchema, numOfCol1, pFilterInfo, numOfFilterCols); + + SSchema* schema = NULL; + if (px->numOfTables > 1) { + SOperatorInfo** p = calloc(px->numOfTables, POINTER_BYTES); + p[0] = pSourceOperator; + + int32_t num = (int32_t) taosArrayGetSize(px->colList); + schema = calloc(num, sizeof(SSchema)); + memcpy(schema, pSchema, numOfCol1*sizeof(SSchema)); + + int32_t offset = pSourceOperator->numOfOutput; + + for(int32_t i = 1; i < px->numOfTables; ++i) { + SSchema* pSchema1 = tscGetTableSchema(px->pTableMetaInfo[i]->pTableMeta); + int32_t n = px->pTableMetaInfo[i]->pTableMeta->tableInfo.numOfColumns; + + int32_t numOfFilterCols1 = 0; + SColumnInfo* tableCols1 = calloc(numOfCol1, sizeof(SColumnInfo)); + for(int32_t j = 0; j < numOfCol1; ++j) { + SColumn* pCol = taosArrayGetP(px->colList, j); + if (pCol->info.flist.numOfFilters > 0) { + numOfFilterCols += 1; + } + + tableCols1[j] = pCol->info; + } + + SSingleColumnFilterInfo* pFilterInfo1 = NULL; + if (numOfFilterCols1 > 0) { + doCreateFilterInfo(tableCols1, numOfCol1, numOfFilterCols1, &pFilterInfo1, 0); + } + + p[i] = createDummyInputOperator(pSqlObjList[i], pSchema1, n, pFilterInfo1, numOfFilterCols1); + memcpy(&schema[offset], pSchema1, n * sizeof(SSchema)); + offset += n; + } + + pSourceOperator = createJoinOperatorInfo(p, px->numOfTables, schema, num); + tfree(p); + } else { + size_t num = taosArrayGetSize(px->colList); + schema = calloc(num, sizeof(SSchema)); + memcpy(schema, pSchema, numOfCol1*sizeof(SSchema)); + } + + SExprInfo* exprInfo = NULL; + /*int32_t code = */ createQueryFunc(&info, numOfOutput, &exprInfo, px->exprList->pData, NULL, px->type, NULL); + for(int32_t i = 0; i < numOfOutput; ++i) { + SExprInfo* pex = taosArrayGetP(px->exprList, i); + int32_t colId = pex->base.colInfo.colId; + for(int32_t j = 0; j < pSourceOperator->numOfOutput; ++j) { + if (colId == schema[j].colId) { + pex->base.colInfo.colIndex = j; + break; + } + } + } + + px->pQInfo = createQInfoFromQueryNode(px, exprInfo, &tableGroupInfo, pSourceOperator, NULL, NULL, MASTER_SCAN); tfree(pColumnInfo); + tfree(schema); + tfree(exprInfo); } + + uint64_t qId = 0; + qTableQuery(px->pQInfo, &qId); + convertQueryResult(pOutput, px); } static void tscDestroyResPointerInfo(SSqlRes* pRes) { @@ -765,26 +1183,29 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) { } void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeMeta) { - if (pCmd == NULL || pCmd->numOfClause == 0) { + if (pCmd == NULL) { return; } - - for (int32_t i = 0; i < pCmd->numOfClause; ++i) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, i); - - // recursive call it - if (taosArrayGetSize(pQueryInfo->pUpstream) > 0) { - SQueryInfo* pUp = taosArrayGetP(pQueryInfo->pUpstream, 0); - freeQueryInfoImpl(pUp); - clearAllTableMetaInfo(pUp, removeMeta); - if (pUp->pQInfo != NULL) { - qDestroyQueryInfo(pUp->pQInfo); - pUp->pQInfo = NULL; + + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); + + while(pQueryInfo != NULL) { + SQueryInfo* p = pQueryInfo->sibling; + + size_t numOfUpstream = taosArrayGetSize(pQueryInfo->pUpstream); + for(int32_t i = 0; i < numOfUpstream; ++i) { + SQueryInfo* pUpQueryInfo = taosArrayGetP(pQueryInfo->pUpstream, i); + freeQueryInfoImpl(pUpQueryInfo); + + clearAllTableMetaInfo(pUpQueryInfo, removeMeta); + if (pUpQueryInfo->pQInfo != NULL) { + qDestroyQueryInfo(pUpQueryInfo->pQInfo); + pUpQueryInfo->pQInfo = NULL; } - tfree(pUp); + tfree(pUpQueryInfo); } - + freeQueryInfoImpl(pQueryInfo); clearAllTableMetaInfo(pQueryInfo, removeMeta); @@ -794,48 +1215,60 @@ void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeMeta) { } tfree(pQueryInfo); + pQueryInfo = p; } - - pCmd->numOfClause = 0; - tfree(pCmd->pQueryInfo); + + pCmd->pQueryInfo = NULL; + pCmd->active = NULL; } void destroyTableNameList(SSqlCmd* pCmd) { - if (pCmd->numOfTables == 0) { - assert(pCmd->pTableNameList == NULL); + if (pCmd->insertParam.numOfTables == 0) { + assert(pCmd->insertParam.pTableNameList == NULL); return; } - for(int32_t i = 0; i < pCmd->numOfTables; ++i) { - tfree(pCmd->pTableNameList[i]); + for(int32_t i = 0; i < pCmd->insertParam.numOfTables; ++i) { + tfree(pCmd->insertParam.pTableNameList[i]); } - pCmd->numOfTables = 0; - tfree(pCmd->pTableNameList); + pCmd->insertParam.numOfTables = 0; + tfree(pCmd->insertParam.pTableNameList); } -void tscResetSqlCmd(SSqlCmd* pCmd, bool removeMeta) { +void tscResetSqlCmd(SSqlCmd* pCmd, bool clearCachedMeta) { pCmd->command = 0; pCmd->numOfCols = 0; pCmd->count = 0; pCmd->curSql = NULL; pCmd->msgType = 0; - pCmd->parseFinished = 0; - pCmd->autoCreated = 0; destroyTableNameList(pCmd); - pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList, removeMeta); - pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); - tscFreeQueryInfo(pCmd, removeMeta); + pCmd->insertParam.pTableBlockHashList = tscDestroyBlockHashTable(pCmd->insertParam.pTableBlockHashList, clearCachedMeta); + pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks); + tscFreeQueryInfo(pCmd, clearCachedMeta); + + if (pCmd->pTableMetaMap != NULL) { + STableMetaVgroupInfo* p = taosHashIterate(pCmd->pTableMetaMap, NULL); + while (p) { + tfree(p->pVgroupInfo); + tfree(p->pTableMeta); + p = taosHashIterate(pCmd->pTableMetaMap, p); + } + + taosHashCleanup(pCmd->pTableMetaMap); + pCmd->pTableMetaMap = NULL; + } } void tscFreeSqlResult(SSqlObj* pSql) { - tscDestroyLocalMerger(pSql); - SSqlRes* pRes = &pSql->res; - tscDestroyResPointerInfo(pRes); + tscDestroyLocalMerger(pRes->pLocalMerger); + pRes->pLocalMerger = NULL; + + tscDestroyResPointerInfo(pRes); memset(&pSql->res, 0, sizeof(SSqlRes)); } @@ -857,7 +1290,6 @@ void tscFreeSubobj(SSqlObj* pSql) { } tfree(pSql->subState.states); - pSql->subState.numOfSub = 0; } @@ -881,7 +1313,6 @@ void tscFreeRegisteredSqlObj(void *pSql) { tscDebug("0x%"PRIx64" free SqlObj, total in tscObj:%d, total:%d", p->self, num, total); tscFreeSqlObj(p); taosReleaseRef(tscRefId, pTscObj->rid); - } void tscFreeMetaSqlObj(int64_t *rid){ @@ -1025,14 +1456,11 @@ void* tscDestroyBlockHashTable(SHashObj* pBlockHashTable, bool removeMeta) { int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) { SSqlCmd* pCmd = &pSql->cmd; - assert(pDataBlock->pTableMeta != NULL); + assert(pDataBlock->pTableMeta != NULL && pDataBlock->size <= pDataBlock->nAllocSize && pDataBlock->size > sizeof(SMsgDesc)); - pCmd->numOfTablesInSubmit = pDataBlock->numOfTables; + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); - assert(pCmd->numOfClause == 1); - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - - // todo refactor + // todo remove it later // set the correct table meta object, the table meta has been locked in pDataBlocks, so it must be in the cache if (pTableMetaInfo->pTableMeta != pDataBlock->pTableMeta) { tNameAssign(&pTableMetaInfo->name, &pDataBlock->tableName); @@ -1041,33 +1469,43 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) { tfree(pTableMetaInfo->pTableMeta); } - pTableMetaInfo->pTableMeta = tscTableMetaDup(pDataBlock->pTableMeta); + pTableMetaInfo->pTableMeta = tscTableMetaDup(pDataBlock->pTableMeta); + pTableMetaInfo->tableMetaSize = tscGetTableMetaSize(pDataBlock->pTableMeta); } /* - * the submit message consists of : [RPC header|message body|digest] - * the dataBlock only includes the RPC Header buffer and actual submit message body, space for digest needs - * additional space. + * the format of submit message is as follows [RPC header|message body|digest] + * the dataBlock only includes the RPC Header buffer and actual submit message body, + * space for digest needs additional space. */ - int ret = tscAllocPayload(pCmd, pDataBlock->size + 100); + int ret = tscAllocPayload(pCmd, pDataBlock->size); if (TSDB_CODE_SUCCESS != ret) { return ret; } - assert(pDataBlock->size <= pDataBlock->nAllocSize); memcpy(pCmd->payload, pDataBlock->pData, pDataBlock->size); - /* - * the payloadLen should be actual message body size - * the old value of payloadLen is the allocated payload size - */ + //the payloadLen should be actual message body size, the old value of payloadLen is the allocated payload size pCmd->payloadLen = pDataBlock->size; + assert(pCmd->allocSize >= (uint32_t)(pCmd->payloadLen)); + + // NOTE: shell message size should not include SMsgDesc + int32_t size = pCmd->payloadLen - sizeof(SMsgDesc); - assert(pCmd->allocSize >= (uint32_t)(pCmd->payloadLen + 100) && pCmd->payloadLen > 0); + SMsgDesc* pMsgDesc = (SMsgDesc*) pCmd->payload; + pMsgDesc->numOfVnodes = htonl(1); // always for one vnode + + SSubmitMsg *pShellMsg = (SSubmitMsg *)(pCmd->payload + sizeof(SMsgDesc)); + pShellMsg->header.vgId = htonl(pDataBlock->pTableMeta->vgId); // data in current block all routes to the same vgroup + pShellMsg->header.contLen = htonl(size); // the length not includes the size of SMsgDesc + pShellMsg->length = pShellMsg->header.contLen; + pShellMsg->numOfBlocks = htonl(pDataBlock->numOfTables); // the number of tables to be inserted + + tscDebug("0x%"PRIx64" submit msg built, vgId:%d numOfTables:%d", pSql->self, pDataBlock->pTableMeta->vgId, pDataBlock->numOfTables); return TSDB_CODE_SUCCESS; } -SQueryInfo* tscGetActiveQueryInfo(SSqlCmd* pCmd) { +SQueryInfo* tscGetQueryInfo(SSqlCmd* pCmd) { return pCmd->active; } @@ -1225,25 +1663,25 @@ static int32_t getRowExpandSize(STableMeta* pTableMeta) { } static void extractTableNameList(SSqlCmd* pCmd, bool freeBlockMap) { - pCmd->numOfTables = (int32_t) taosHashGetSize(pCmd->pTableBlockHashList); - if (pCmd->pTableNameList == NULL) { - pCmd->pTableNameList = calloc(pCmd->numOfTables, POINTER_BYTES); + pCmd->insertParam.numOfTables = (int32_t) taosHashGetSize(pCmd->insertParam.pTableBlockHashList); + if (pCmd->insertParam.pTableNameList == NULL) { + pCmd->insertParam.pTableNameList = calloc(pCmd->insertParam.numOfTables, POINTER_BYTES); } else { - memset(pCmd->pTableNameList, 0, pCmd->numOfTables * POINTER_BYTES); + memset(pCmd->insertParam.pTableNameList, 0, pCmd->insertParam.numOfTables * POINTER_BYTES); } - STableDataBlocks **p1 = taosHashIterate(pCmd->pTableBlockHashList, NULL); + STableDataBlocks **p1 = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL); int32_t i = 0; while(p1) { STableDataBlocks* pBlocks = *p1; - tfree(pCmd->pTableNameList[i]); + tfree(pCmd->insertParam.pTableNameList[i]); - pCmd->pTableNameList[i++] = tNameDup(&pBlocks->tableName); - p1 = taosHashIterate(pCmd->pTableBlockHashList, p1); + pCmd->insertParam.pTableNameList[i++] = tNameDup(&pBlocks->tableName); + p1 = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p1); } if (freeBlockMap) { - pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList, false); + pCmd->insertParam.pTableBlockHashList = tscDestroyBlockHashTable(pCmd->insertParam.pTableBlockHashList, false); } } @@ -1254,72 +1692,78 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { void* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); SArray* pVnodeDataBlockList = taosArrayInit(8, POINTER_BYTES); - STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL); + STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL); STableDataBlocks* pOneTableBlock = *p; while(pOneTableBlock) { - // the maximum expanded size in byte when a row-wise data is converted to SDataRow format - int32_t expandSize = getRowExpandSize(pOneTableBlock->pTableMeta); - STableDataBlocks* dataBuf = NULL; - - int32_t ret = tscGetDataBlockFromList(pVnodeDataBlockHashList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE, - INSERT_HEAD_SIZE, 0, &pOneTableBlock->tableName, pOneTableBlock->pTableMeta, &dataBuf, pVnodeDataBlockList); - if (ret != TSDB_CODE_SUCCESS) { - tscError("0x%"PRIx64" failed to prepare the data block buffer for merging table data, code:%d", pSql->self, ret); - taosHashCleanup(pVnodeDataBlockHashList); - tscDestroyBlockArrayList(pVnodeDataBlockList); - return ret; - } - SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData; - int64_t destSize = dataBuf->size + pOneTableBlock->size + pBlocks->numOfRows * expandSize + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta); - - if (dataBuf->nAllocSize < destSize) { - while (dataBuf->nAllocSize < destSize) { - dataBuf->nAllocSize = (uint32_t)(dataBuf->nAllocSize * 1.5); + if (pBlocks->numOfRows > 0) { + // the maximum expanded size in byte when a row-wise data is converted to SDataRow format + int32_t expandSize = getRowExpandSize(pOneTableBlock->pTableMeta); + STableDataBlocks* dataBuf = NULL; + + int32_t ret = tscGetDataBlockFromList(pVnodeDataBlockHashList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE, + INSERT_HEAD_SIZE, 0, &pOneTableBlock->tableName, pOneTableBlock->pTableMeta, &dataBuf, pVnodeDataBlockList); + if (ret != TSDB_CODE_SUCCESS) { + tscError("0x%"PRIx64" failed to prepare the data block buffer for merging table data, code:%d", pSql->self, ret); + taosHashCleanup(pVnodeDataBlockHashList); + tscDestroyBlockArrayList(pVnodeDataBlockList); + return ret; } - char* tmp = realloc(dataBuf->pData, dataBuf->nAllocSize); - if (tmp != NULL) { - dataBuf->pData = tmp; - memset(dataBuf->pData + dataBuf->size, 0, dataBuf->nAllocSize - dataBuf->size); - } else { // failed to allocate memory, free already allocated memory and return error code - tscError("0x%"PRIx64" failed to allocate memory for merging submit block, size:%d", pSql->self, dataBuf->nAllocSize); + int64_t destSize = dataBuf->size + pOneTableBlock->size + pBlocks->numOfRows * expandSize + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta); - taosHashCleanup(pVnodeDataBlockHashList); - tscDestroyBlockArrayList(pVnodeDataBlockList); - tfree(dataBuf->pData); + if (dataBuf->nAllocSize < destSize) { + while (dataBuf->nAllocSize < destSize) { + dataBuf->nAllocSize = (uint32_t)(dataBuf->nAllocSize * 1.5); + } - return TSDB_CODE_TSC_OUT_OF_MEMORY; + char* tmp = realloc(dataBuf->pData, dataBuf->nAllocSize); + if (tmp != NULL) { + dataBuf->pData = tmp; + memset(dataBuf->pData + dataBuf->size, 0, dataBuf->nAllocSize - dataBuf->size); + } else { // failed to allocate memory, free already allocated memory and return error code + tscError("0x%"PRIx64" failed to allocate memory for merging submit block, size:%d", pSql->self, dataBuf->nAllocSize); + + taosHashCleanup(pVnodeDataBlockHashList); + tscDestroyBlockArrayList(pVnodeDataBlockList); + tfree(dataBuf->pData); + + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } } - } - tscSortRemoveDataBlockDupRows(pOneTableBlock); - char* ekey = (char*)pBlocks->data + pOneTableBlock->rowSize*(pBlocks->numOfRows-1); + tscSortRemoveDataBlockDupRows(pOneTableBlock); + char* ekey = (char*)pBlocks->data + pOneTableBlock->rowSize*(pBlocks->numOfRows-1); - tscDebug("0x%"PRIx64" name:%s, name:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql->self, tNameGetTableName(&pOneTableBlock->tableName), - pBlocks->tid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->data), GET_INT64_VAL(ekey)); + tscDebug("0x%"PRIx64" name:%s, name:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql->self, tNameGetTableName(&pOneTableBlock->tableName), + pBlocks->tid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->data), GET_INT64_VAL(ekey)); - int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + expandSize) + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta); + int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + expandSize) + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta); - pBlocks->tid = htonl(pBlocks->tid); - pBlocks->uid = htobe64(pBlocks->uid); - pBlocks->sversion = htonl(pBlocks->sversion); - pBlocks->numOfRows = htons(pBlocks->numOfRows); - pBlocks->schemaLen = 0; + pBlocks->tid = htonl(pBlocks->tid); + pBlocks->uid = htobe64(pBlocks->uid); + pBlocks->sversion = htonl(pBlocks->sversion); + pBlocks->numOfRows = htons(pBlocks->numOfRows); + pBlocks->schemaLen = 0; - // erase the empty space reserved for binary data - int32_t finalLen = trimDataBlock(dataBuf->pData + dataBuf->size, pOneTableBlock, pCmd->submitSchema); - assert(finalLen <= len); + // erase the empty space reserved for binary data + int32_t finalLen = trimDataBlock(dataBuf->pData + dataBuf->size, pOneTableBlock, pCmd->insertParam.schemaAttached); + assert(finalLen <= len); - dataBuf->size += (finalLen + sizeof(SSubmitBlk)); - assert(dataBuf->size <= dataBuf->nAllocSize); + dataBuf->size += (finalLen + sizeof(SSubmitBlk)); + assert(dataBuf->size <= dataBuf->nAllocSize); - // the length does not include the SSubmitBlk structure - pBlocks->dataLen = htonl(finalLen); - dataBuf->numOfTables += 1; + // the length does not include the SSubmitBlk structure + pBlocks->dataLen = htonl(finalLen); + dataBuf->numOfTables += 1; - p = taosHashIterate(pCmd->pTableBlockHashList, p); + pBlocks->numOfRows = 0; + }else { + tscDebug("0x%"PRIx64" table %s data block is empty", pSql->self, pOneTableBlock->tableName.tname); + } + + p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p); if (p == NULL) { break; } @@ -1330,7 +1774,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { extractTableNameList(pCmd, freeBlockMap); // free the table data blocks; - pCmd->pDataBlocks = pVnodeDataBlockList; + pCmd->insertParam.pDataBlocks = pVnodeDataBlockList; taosHashCleanup(pVnodeDataBlockHashList); return TSDB_CODE_SUCCESS; @@ -1362,18 +1806,22 @@ bool tscIsInsertData(char* sqlstr) { } int tscAllocPayload(SSqlCmd* pCmd, int size) { - assert(size > 0); - if (pCmd->payload == NULL) { assert(pCmd->allocSize == 0); pCmd->payload = (char*)calloc(1, size); - if (pCmd->payload == NULL) return TSDB_CODE_TSC_OUT_OF_MEMORY; + if (pCmd->payload == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + pCmd->allocSize = size; } else { if (pCmd->allocSize < (uint32_t)size) { char* b = realloc(pCmd->payload, size); - if (b == NULL) return TSDB_CODE_TSC_OUT_OF_MEMORY; + if (b == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + pCmd->payload = b; pCmd->allocSize = size; } @@ -1381,7 +1829,7 @@ int tscAllocPayload(SSqlCmd* pCmd, int size) { memset(pCmd->payload, 0, pCmd->allocSize); } - assert(pCmd->allocSize >= (uint32_t)size); + assert(pCmd->allocSize >= (uint32_t)size && size > 0); return TSDB_CODE_SUCCESS; } @@ -1410,16 +1858,14 @@ SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_F } void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - - SExprInfo* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); - pExpr->base.offset = 0; + int32_t offset = 0; + size_t numOfExprs = tscNumOfExprs(pQueryInfo); - for (int32_t i = 1; i < numOfExprs; ++i) { - SExprInfo* prev = taosArrayGetP(pQueryInfo->exprList, i - 1); + for (int32_t i = 0; i < numOfExprs; ++i) { SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, i); - p->base.offset = prev->base.offset + prev->base.resBytes; + p->base.offset = offset; + offset += p->base.resBytes; } } @@ -1440,7 +1886,7 @@ int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) { return pInfo->pExpr->base.offset; } -int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2) { +int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize) { assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL); if (pFieldInfo1->numOfOutput != pFieldInfo2->numOfOutput) { @@ -1452,15 +1898,37 @@ int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFi TAOS_FIELD* pField2 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo2, i); if (pField1->type != pField2->type || - pField1->bytes != pField2->bytes || strcasecmp(pField1->name, pField2->name) != 0) { return 1; } + + if (pField1->bytes != pField2->bytes) { + *diffSize = 1; + + if (pField2->bytes > pField1->bytes) { + assert(IS_VAR_DATA_TYPE(pField1->type)); + pField1->bytes = pField2->bytes; + } + } + } + + return 0; +} + +int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2) { + assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL); + + for (int32_t i = 0; i < pFieldInfo1->numOfOutput; ++i) { + TAOS_FIELD* pField1 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo1, i); + TAOS_FIELD* pField2 = tscFieldInfoGetField((SFieldInfo*) pFieldInfo2, i); + + pField2->bytes = pField1->bytes; } return 0; } + int32_t tscGetResRowLength(SArray* pExprList) { size_t num = taosArrayGetSize(pExprList); if (num == 0) { @@ -1530,8 +1998,43 @@ void tscFieldInfoClear(SFieldInfo* pFieldInfo) { memset(pFieldInfo, 0, sizeof(SFieldInfo)); } -static SExprInfo* doCreateSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, - int16_t size, int16_t resColId, int16_t interSize, int32_t colType) { +void tscFieldInfoCopy(SFieldInfo* pFieldInfo, const SFieldInfo* pSrc, const SArray* pExprList) { + assert(pFieldInfo != NULL && pSrc != NULL && pExprList != NULL); + pFieldInfo->numOfOutput = pSrc->numOfOutput; + + if (pSrc->final != NULL) { + pFieldInfo->final = calloc(pSrc->numOfOutput, sizeof(TAOS_FIELD)); + memcpy(pFieldInfo->final, pSrc->final, sizeof(TAOS_FIELD) * pSrc->numOfOutput); + } + + if (pSrc->internalField != NULL) { + size_t num = taosArrayGetSize(pSrc->internalField); + size_t numOfExpr = taosArrayGetSize(pExprList); + + for (int32_t i = 0; i < num; ++i) { + SInternalField* pfield = taosArrayGet(pSrc->internalField, i); + + SInternalField p = {.visible = pfield->visible, .field = pfield->field}; + + int32_t resColId = pfield->pExpr->base.resColId; + for(int32_t j = 0; j < numOfExpr; ++j) { + SExprInfo* pExpr = taosArrayGetP(pExprList, j); + if (pExpr->base.resColId == resColId) { + p.pExpr = pExpr; + break; + } + } +// p.pExpr = calloc(1, sizeof(SExprInfo)); + +// tscExprAssign(p.pExpr, pfield->pExpr); + taosArrayPush(pFieldInfo->internalField, &p); + } + } +} + + +SExprInfo* tscExprCreate(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, + int16_t size, int16_t resColId, int16_t interSize, int32_t colType) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pColIndex->tableIndex); SExprInfo* pExpr = calloc(1, sizeof(SExprInfo)); @@ -1590,29 +2093,29 @@ static SExprInfo* doCreateSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SC return pExpr; } -SExprInfo* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) { int32_t num = (int32_t)taosArrayGetSize(pQueryInfo->exprList); if (index == num) { - return tscSqlExprAppend(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); + return tscExprAppend(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); } - SExprInfo* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); + SExprInfo* pExpr = tscExprCreate(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); taosArrayInsert(pQueryInfo->exprList, index, &pExpr); return pExpr; } -SExprInfo* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) { - SExprInfo* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); + SExprInfo* pExpr = tscExprCreate(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); taosArrayPush(pQueryInfo->exprList, &pExpr); return pExpr; } -SExprInfo* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, +SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type, int16_t size) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, index); + SExprInfo* pExpr = tscExprGet(pQueryInfo, index); if (pExpr == NULL) { return NULL; } @@ -1634,9 +2137,9 @@ bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t index) { return false; } - int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + int32_t numOfExprs = (int32_t) tscNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); if (pExpr->base.functionId == TSDB_FUNC_STDDEV_DST) { return true; } @@ -1645,11 +2148,11 @@ bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t index) { return false; } -size_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo) { +size_t tscNumOfExprs(SQueryInfo* pQueryInfo) { return taosArrayGetSize(pQueryInfo->exprList); } -void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) { +void tscExprAddParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) { assert (pExpr != NULL || argument != NULL || bytes != 0); // set parameter value @@ -1660,14 +2163,14 @@ void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) assert(pExpr->numOfParams <= 3); } -SExprInfo* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index) { +SExprInfo* tscExprGet(SQueryInfo* pQueryInfo, int32_t index) { return taosArrayGetP(pQueryInfo->exprList, index); } /* * NOTE: Does not release SExprInfo here. */ -void tscSqlExprInfoDestroy(SArray* pExprInfo) { +void tscExprDestroy(SArray* pExprInfo) { size_t size = taosArrayGetSize(pExprInfo); for(int32_t i = 0; i < size; ++i) { @@ -1678,23 +2181,42 @@ void tscSqlExprInfoDestroy(SArray* pExprInfo) { taosArrayDestroy(pExprInfo); } -int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy) { +int32_t tscExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy) { assert(src != NULL && dst != NULL); size_t size = taosArrayGetSize(src); for (int32_t i = 0; i < size; ++i) { SExprInfo* pExpr = taosArrayGetP(src, i); - + if (pExpr->base.uid == uid) { if (deepcopy) { SExprInfo* p1 = calloc(1, sizeof(SExprInfo)); - tscSqlExprAssign(p1, pExpr); + tscExprAssign(p1, pExpr); taosArrayPush(dst, &p1); } else { taosArrayPush(dst, &pExpr); } + } + } + return 0; +} + +int32_t tscExprCopyAll(SArray* dst, const SArray* src, bool deepcopy) { + assert(src != NULL && dst != NULL); + + size_t size = taosArrayGetSize(src); + for (int32_t i = 0; i < size; ++i) { + SExprInfo* pExpr = taosArrayGetP(src, i); + + if (deepcopy) { + SExprInfo* p1 = calloc(1, sizeof(SExprInfo)); + tscExprAssign(p1, pExpr); + + taosArrayPush(dst, &p1); + } else { + taosArrayPush(dst, &pExpr); } } @@ -1727,7 +2249,7 @@ bool tscColumnExists(SArray* pColumnList, int32_t columnIndex, uint64_t uid) { return true; } -void tscSqlExprAssign(SExprInfo* dst, const SExprInfo* src) { +void tscExprAssign(SExprInfo* dst, const SExprInfo* src) { assert(dst != NULL && src != NULL); *dst = *src; @@ -1839,6 +2361,18 @@ void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid) { } } +void tscColumnListCopyAll(SArray* dst, const SArray* src) { + assert(src != NULL && dst != NULL); + + size_t num = taosArrayGetSize(src); + for (int32_t i = 0; i < num; ++i) { + SColumn* pCol = taosArrayGetP(src, i); + SColumn* p = tscColumnClone(pCol); + taosArrayPush(dst, &p); + } +} + + void tscColumnListDestroy(SArray* pColumnList) { if (pColumnList == NULL) { return; @@ -1870,14 +2404,14 @@ void tscColumnListDestroy(SArray* pColumnList) { static int32_t validateQuoteToken(SStrToken* pToken) { tscDequoteAndTrimToken(pToken); - int32_t k = tSQLGetToken(pToken->z, &pToken->type); + int32_t k = tGetToken(pToken->z, &pToken->type); if (pToken->type == TK_STRING) { return tscValidateName(pToken); } if (k != pToken->n || pToken->type != TK_ID) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return TSDB_CODE_SUCCESS; } @@ -1927,7 +2461,7 @@ void tscDequoteAndTrimToken(SStrToken* pToken) { int32_t tscValidateName(SStrToken* pToken) { if (pToken->type != TK_STRING && pToken->type != TK_ID) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true); @@ -1938,7 +2472,7 @@ int32_t tscValidateName(SStrToken* pToken) { tscStrToLower(pToken->z, pToken->n); //pToken->n = (uint32_t)strtrim(pToken->z); - int len = tSQLGetToken(pToken->z, &pToken->type); + int len = tGetToken(pToken->z, &pToken->type); // single token, validate it if (len == pToken->n) { @@ -1946,14 +2480,14 @@ int32_t tscValidateName(SStrToken* pToken) { } else { sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true); if (sep == NULL) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return tscValidateName(pToken); } } else { if (isNumber(pToken)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } } else { // two part @@ -1964,30 +2498,30 @@ int32_t tscValidateName(SStrToken* pToken) { pToken->n = (uint32_t)strtrim(pToken->z); } - pToken->n = tSQLGetToken(pToken->z, &pToken->type); + pToken->n = tGetToken(pToken->z, &pToken->type); if (pToken->z[pToken->n] != TS_PATH_DELIMITER[0]) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pToken->type != TK_STRING && pToken->type != TK_ID) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pToken->type == TK_STRING && validateQuoteToken(pToken) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t firstPartLen = pToken->n; pToken->z = sep + 1; pToken->n = (uint32_t)(oldLen - (sep - pStr) - 1); - int32_t len = tSQLGetToken(pToken->z, &pToken->type); + int32_t len = tGetToken(pToken->z, &pToken->type); if (len != pToken->n || (pToken->type != TK_STRING && pToken->type != TK_ID)) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pToken->type == TK_STRING && validateQuoteToken(pToken) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } // re-build the whole name string @@ -2141,9 +2675,9 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); pColInfo[i].functionId = pExpr->base.functionId; if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { @@ -2195,14 +2729,9 @@ bool tscShouldBeFreed(SSqlObj* pSql) { * @param tableIndex denote the table index for join query, where more than one table exists * @return */ -STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd* pCmd, int32_t clauseIndex, int32_t tableIndex) { - if (pCmd == NULL || pCmd->numOfClause == 0) { - return NULL; - } - - assert(clauseIndex >= 0 && clauseIndex < pCmd->numOfClause); - - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); +STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd* pCmd, int32_t tableIndex) { + assert(pCmd != NULL); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); return tscGetMetaInfo(pQueryInfo, tableIndex); } @@ -2219,8 +2748,8 @@ STableMetaInfo* tscGetMetaInfo(SQueryInfo* pQueryInfo, int32_t tableIndex) { return pQueryInfo->pTableMetaInfo[tableIndex]; } -SQueryInfo* tscGetQueryInfoS(SSqlCmd* pCmd, int32_t subClauseIndex) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); +SQueryInfo* tscGetQueryInfoS(SSqlCmd* pCmd) { + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); int32_t ret = TSDB_CODE_SUCCESS; while ((pQueryInfo) == NULL) { @@ -2229,7 +2758,7 @@ SQueryInfo* tscGetQueryInfoS(SSqlCmd* pCmd, int32_t subClauseIndex) { return NULL; } - pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); + pQueryInfo = tscGetQueryInfo(pCmd); } return pQueryInfo; @@ -2253,6 +2782,7 @@ STableMetaInfo* tscGetTableMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, i return tscGetMetaInfo(pQueryInfo, k); } +// todo refactor void tscInitQueryInfo(SQueryInfo* pQueryInfo) { assert(pQueryInfo->fieldsInfo.internalField == NULL); pQueryInfo->fieldsInfo.internalField = taosArrayInit(4, sizeof(SInternalField)); @@ -2262,27 +2792,17 @@ void tscInitQueryInfo(SQueryInfo* pQueryInfo) { pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES); pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); pQueryInfo->udColumnId = TSDB_UD_COLUMN_INDEX; - pQueryInfo->resColumnId = TSDB_RES_COL_ID; pQueryInfo->limit.limit = -1; pQueryInfo->limit.offset = 0; pQueryInfo->slimit.limit = -1; pQueryInfo->slimit.offset = 0; pQueryInfo->pUpstream = taosArrayInit(4, POINTER_BYTES); + pQueryInfo->window = TSWINDOW_INITIALIZER; } int32_t tscAddQueryInfo(SSqlCmd* pCmd) { assert(pCmd != NULL); - - // todo refactor: remove this structure - size_t s = pCmd->numOfClause + 1; - char* tmp = realloc(pCmd->pQueryInfo, s * POINTER_BYTES); - if (tmp == NULL) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - - pCmd->pQueryInfo = (SQueryInfo**)tmp; - SQueryInfo* pQueryInfo = calloc(1, sizeof(SQueryInfo)); if (pQueryInfo == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -2290,10 +2810,20 @@ int32_t tscAddQueryInfo(SSqlCmd* pCmd) { tscInitQueryInfo(pQueryInfo); - pQueryInfo->window = TSWINDOW_INITIALIZER; pQueryInfo->msg = pCmd->payload; // pointer to the parent error message buffer - pCmd->pQueryInfo[pCmd->numOfClause++] = pQueryInfo; + if (pCmd->pQueryInfo == NULL) { + pCmd->pQueryInfo = pQueryInfo; + } else { + SQueryInfo* p = pCmd->pQueryInfo; + while(p->sibling != NULL) { + p = p->sibling; + } + + p->sibling = pQueryInfo; + } + + pCmd->active = pQueryInfo; return TSDB_CODE_SUCCESS; } @@ -2301,9 +2831,14 @@ static void freeQueryInfoImpl(SQueryInfo* pQueryInfo) { tscTagCondRelease(&pQueryInfo->tagCond); tscFieldInfoClear(&pQueryInfo->fieldsInfo); - tscSqlExprInfoDestroy(pQueryInfo->exprList); + tscExprDestroy(pQueryInfo->exprList); pQueryInfo->exprList = NULL; + if (pQueryInfo->exprList1 != NULL) { + tscExprDestroy(pQueryInfo->exprList1); + pQueryInfo->exprList1 = NULL; + } + tscColumnListDestroy(pQueryInfo->colList); pQueryInfo->colList = NULL; @@ -2323,10 +2858,92 @@ static void freeQueryInfoImpl(SQueryInfo* pQueryInfo) { } void tscClearSubqueryInfo(SSqlCmd* pCmd) { - for (int32_t i = 0; i < pCmd->numOfClause; ++i) { - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, i); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); + while (pQueryInfo != NULL) { + SQueryInfo* p = pQueryInfo->sibling; freeQueryInfoImpl(pQueryInfo); + pQueryInfo = p; + } +} + +int32_t tscQueryInfoCopy(SQueryInfo* pQueryInfo, const SQueryInfo* pSrc) { + assert(pQueryInfo != NULL && pSrc != NULL); + int32_t code = TSDB_CODE_SUCCESS; + + memcpy(&pQueryInfo->interval, &pSrc->interval, sizeof(pQueryInfo->interval)); + + pQueryInfo->command = pSrc->command; + pQueryInfo->type = pSrc->type; + pQueryInfo->window = pSrc->window; + pQueryInfo->limit = pSrc->limit; + pQueryInfo->slimit = pSrc->slimit; + pQueryInfo->order = pSrc->order; + pQueryInfo->vgroupLimit = pSrc->vgroupLimit; + pQueryInfo->tsBuf = NULL; + pQueryInfo->fillType = pSrc->fillType; + pQueryInfo->fillVal = NULL; + pQueryInfo->clauseLimit = pSrc->clauseLimit; + pQueryInfo->numOfTables = 0; + pQueryInfo->window = pSrc->window; + pQueryInfo->sessionWindow = pSrc->sessionWindow; + pQueryInfo->pTableMetaInfo = NULL; + + pQueryInfo->bufLen = pSrc->bufLen; + pQueryInfo->buf = malloc(pSrc->bufLen); + if (pQueryInfo->buf == NULL) { + code = TSDB_CODE_TSC_OUT_OF_MEMORY; + goto _error; + } + + if (pSrc->bufLen > 0) { + memcpy(pQueryInfo->buf, pSrc->buf, pSrc->bufLen); + } + + pQueryInfo->groupbyExpr = pSrc->groupbyExpr; + if (pSrc->groupbyExpr.columnInfo != NULL) { + pQueryInfo->groupbyExpr.columnInfo = taosArrayDup(pSrc->groupbyExpr.columnInfo); + if (pQueryInfo->groupbyExpr.columnInfo == NULL) { + code = TSDB_CODE_TSC_OUT_OF_MEMORY; + goto _error; + } } + + if (tscTagCondCopy(&pQueryInfo->tagCond, &pSrc->tagCond) != 0) { + code = TSDB_CODE_TSC_OUT_OF_MEMORY; + goto _error; + } + + if (pSrc->fillType != TSDB_FILL_NONE) { + pQueryInfo->fillVal = malloc(pSrc->fieldsInfo.numOfOutput * sizeof(int64_t)); + if (pQueryInfo->fillVal == NULL) { + code = TSDB_CODE_TSC_OUT_OF_MEMORY; + goto _error; + } + + memcpy(pQueryInfo->fillVal, pSrc->fillVal, pSrc->fieldsInfo.numOfOutput * sizeof(int64_t)); + } + + if (tscExprCopyAll(pQueryInfo->exprList, pSrc->exprList, true) != 0) { + code = TSDB_CODE_TSC_OUT_OF_MEMORY; + goto _error; + } + + tscColumnListCopyAll(pQueryInfo->colList, pSrc->colList); + tscFieldInfoCopy(&pQueryInfo->fieldsInfo, &pSrc->fieldsInfo, pQueryInfo->exprList); + + for(int32_t i = 0; i < pSrc->numOfTables; ++i) { + STableMetaInfo* p1 = tscGetMetaInfo((SQueryInfo*) pSrc, i); + + STableMeta* pMeta = tscTableMetaDup(p1->pTableMeta); + if (pMeta == NULL) { + // todo handle the error + } + + tscAddTableMetaInfo(pQueryInfo, &p1->name, pMeta, p1->vgroupList, p1->tagColList, p1->pVgroupTables); + } + + _error: + return code; } void tscFreeVgroupTableInfo(SArray* pVgroupTables) { @@ -2400,28 +3017,29 @@ void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta) { if (removeMeta) { char name[TSDB_TABLE_FNAME_LEN] = {0}; tNameExtractFullName(&pTableMetaInfo->name, name); - taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN)); } tscFreeVgroupTableInfo(pTableMetaInfo->pVgroupTables); tscClearTableMetaInfo(pTableMetaInfo); + free(pTableMetaInfo); } - + tfree(pQueryInfo->pTableMetaInfo); } STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, SName* name, STableMeta* pTableMeta, SVgroupsInfo* vgroupList, SArray* pTagCols, SArray* pVgroupTables) { - void* pAlloc = realloc(pQueryInfo->pTableMetaInfo, (pQueryInfo->numOfTables + 1) * POINTER_BYTES); - if (pAlloc == NULL) { + void* tmp = realloc(pQueryInfo->pTableMetaInfo, (pQueryInfo->numOfTables + 1) * POINTER_BYTES); + if (tmp == NULL) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return NULL; } - pQueryInfo->pTableMetaInfo = pAlloc; + pQueryInfo->pTableMetaInfo = tmp; STableMetaInfo* pTableMetaInfo = calloc(1, sizeof(STableMetaInfo)); + if (pTableMetaInfo == NULL) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return NULL; @@ -2434,6 +3052,11 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, SName* name, STableM } pTableMetaInfo->pTableMeta = pTableMeta; + if (pTableMetaInfo->pTableMeta == NULL) { + pTableMetaInfo->tableMetaSize = 0; + } else { + pTableMetaInfo->tableMetaSize = tscGetTableMetaSize(pTableMeta); + } if (vgroupList != NULL) { pTableMetaInfo->vgroupList = tscVgroupInfoClone(vgroupList); @@ -2501,8 +3124,6 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, in SSqlCmd* pCmd = &pNew->cmd; pCmd->command = cmd; - pCmd->parseFinished = 1; - pCmd->autoCreated = pSql->cmd.autoCreated; int32_t code = copyTagData(&pNew->cmd.tagData, &pSql->cmd.tagData); if (code != TSDB_CODE_SUCCESS) { @@ -2526,10 +3147,8 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, in pNew->sqlstr = NULL; pNew->maxRetry = TSDB_MAX_REPLICA; - SQueryInfo* pQueryInfo = tscGetQueryInfoS(pCmd, 0); - - assert(pSql->cmd.clauseIndex == 0); - STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfoS(pCmd); + STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0); tscAddTableMetaInfo(pQueryInfo, &pMasterTableMetaInfo->name, NULL, NULL, NULL, NULL); registerSqlObj(pNew); @@ -2538,14 +3157,14 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, in } static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pNewQueryInfo, int64_t uid) { - int32_t numOfOutput = (int32_t)tscSqlExprNumOfExprs(pNewQueryInfo); + int32_t numOfOutput = (int32_t)tscNumOfExprs(pNewQueryInfo); if (numOfOutput == 0) { return; } // set the field info in pNewQueryInfo object according to sqlExpr information for (int32_t i = 0; i < numOfOutput; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pNewQueryInfo, i); + SExprInfo* pExpr = tscExprGet(pNewQueryInfo, i); TAOS_FIELD f = tscCreateField((int8_t) pExpr->base.resType, pExpr->base.aliasName, pExpr->base.resBytes); SInternalField* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f); @@ -2559,7 +3178,7 @@ static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pNewQueryInfo, int64_t ui bool matched = false; for (int32_t k1 = 0; k1 < numOfOutput; ++k1) { - SExprInfo* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1); + SExprInfo* pExpr1 = tscExprGet(pNewQueryInfo, k1); if (strcmp(field->name, pExpr1->base.aliasName) == 0) { // establish link according to the result field name SInternalField* pInfo = tscFieldInfoGetInternalField(&pNewQueryInfo->fieldsInfo, f); @@ -2587,7 +3206,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t return NULL; } - SQueryInfo* pQueryInfo = tscGetActiveQueryInfo(pCmd); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[tableIndex]; pNew->pTscObj = pSql->pTscObj; @@ -2596,20 +3215,18 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t SSqlCmd* pnCmd = &pNew->cmd; memcpy(pnCmd, pCmd, sizeof(SSqlCmd)); - + pnCmd->command = cmd; pnCmd->payload = NULL; pnCmd->allocSize = 0; + pnCmd->pTableMetaMap = NULL; pnCmd->pQueryInfo = NULL; - pnCmd->numOfClause = 0; - pnCmd->clauseIndex = 0; - pnCmd->pDataBlocks = NULL; - - pnCmd->numOfTables = 0; - pnCmd->parseFinished = 1; - pnCmd->pTableNameList = NULL; - pnCmd->pTableBlockHashList = NULL; + pnCmd->insertParam.pDataBlocks = NULL; + + pnCmd->insertParam.numOfTables = 0; + pnCmd->insertParam.pTableNameList = NULL; + pnCmd->insertParam.pTableBlockHashList = NULL; pnCmd->tagData.data = NULL; pnCmd->tagData.dataLen = 0; @@ -2618,7 +3235,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t goto _error; } - SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pnCmd, 0); + SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pnCmd); pNewQueryInfo->command = pQueryInfo->command; pnCmd->active = pNewQueryInfo; @@ -2683,13 +3300,13 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t // set the correct query type if (pPrevSql != NULL) { - SQueryInfo* pPrevQueryInfo = tscGetQueryInfo(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex); + SQueryInfo* pPrevQueryInfo = tscGetQueryInfo(&pPrevSql->cmd); pNewQueryInfo->type = pPrevQueryInfo->type; } else { TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_SUBQUERY);// it must be the subquery } - if (tscSqlExprCopy(pNewQueryInfo->exprList, pQueryInfo->exprList, uid, true) != 0) { + if (tscExprCopy(pNewQueryInfo->exprList, pQueryInfo->exprList, uid, true) != 0) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } @@ -2709,8 +3326,9 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, &pTableMetaInfo->name, pTableMeta, pTableMetaInfo->vgroupList, pTableMetaInfo->tagColList, pTableMetaInfo->pVgroupTables); + } else { // transfer the ownership of pTableMeta to the newly create sql object. - STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex, 0); + STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, 0); if (pPrevInfo->pTableMeta && pPrevInfo->pTableMeta->tableType < 0) { terrno = TSDB_CODE_TSC_APP_ERROR; goto _error; @@ -2749,7 +3367,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t tscDebug("0x%"PRIx64" new subquery:0x%"PRIx64", tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%" PRIzu ", colList:%" PRIzu "," "fieldInfo:%d, name:%s, qrang:%" PRId64 " - %" PRId64 " order:%d, limit:%" PRId64, - pSql->self, pNew->self, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo), + pSql->self, pNew->self, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscNumOfExprs(pNewQueryInfo), size, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pFinalInfo->name), pNewQueryInfo->window.skey, pNewQueryInfo->window.ekey, pNewQueryInfo->order.order, pNewQueryInfo->limit.limit); @@ -2784,91 +3402,119 @@ void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { } } -// do execute the query according to the query execution plan -void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { - if (pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) { - (*pSql->fp)(pSql->param, pSql, 0); +void doRetrieveSubqueryData(SSchedMsg *pMsg) { + SSqlObj* pSql = (SSqlObj*) pMsg->ahandle; + if (pSql == NULL || pSql->signature != pSql) { + tscDebug("%p SqlObj is freed, not add into queue async res", pMsg->ahandle); return; } - if (pSql->cmd.command == TSDB_SQL_SELECT) { - tscAddIntoSqlList(pSql); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd); + handleDownstreamOperator(pSql->pSubs, pSql->subState.numOfSub, pQueryInfo, &pSql->res); + + pSql->res.qId = -1; + if (pSql->res.code == TSDB_CODE_SUCCESS) { + (*pSql->fp)(pSql->param, pSql, pSql->res.numOfRows); + } else { + tscAsyncResultOnError(pSql); } +} - if (taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // nest query. do execute it firstly - SQueryInfo* pq = taosArrayGetP(pQueryInfo->pUpstream, 0); +// NOTE: the blocking query can not be executed in the rpc message handler thread +static void tscSubqueryRetrieveCallback(void* param, TAOS_RES* tres, int code) { + // handle the pDownStream process + SRetrieveSupport* ps = param; + SSqlObj* pParentSql = ps->pParentSql; + SSqlObj* pSql = tres; - pSql->cmd.active = pq; - pSql->cmd.command = TSDB_SQL_SELECT; + int32_t index = ps->subqueryIndex; + bool ret = subAndCheckDone(pSql, pParentSql, index); - executeQuery(pSql, pq); + // TODO refactor + tfree(ps); + pSql->param = NULL; - // merge nest query result and generate final results + if (!ret) { + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, index); return; } - pSql->cmd.active = pQueryInfo; - doExecuteQuery(pSql, pQueryInfo); + pParentSql->cmd.active = pParentSql->cmd.pQueryInfo; + + SSchedMsg schedMsg = {0}; + schedMsg.fp = doRetrieveSubqueryData; + schedMsg.ahandle = (void *)pParentSql; + schedMsg.thandle = (void *)1; + schedMsg.msg = 0; + taosScheduleTask(tscQhandle, &schedMsg); } -/** - * todo remove it - * To decide if current is a two-stage super table query, join query, or insert. And invoke different - * procedure accordingly - * @param pSql - */ -void tscDoQuery(SSqlObj* pSql) { - SSqlCmd* pCmd = &pSql->cmd; - SSqlRes* pRes = &pSql->res; - - pRes->code = TSDB_CODE_SUCCESS; - - if (pCmd->command > TSDB_SQL_LOCAL) { - tscProcessLocalCmd(pSql); +// todo handle the failure +static void tscSubqueryCompleteCallback(void* param, TAOS_RES* tres, int code) { + taos_fetch_rows_a(tres, tscSubqueryRetrieveCallback, param); +} + +// do execute the query according to the query execution plan +void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { + if (pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) { + (*pSql->fp)(pSql->param, pSql, 0); return; } - - if (pCmd->command == TSDB_SQL_SELECT) { + + if (pSql->cmd.command == TSDB_SQL_SELECT) { tscAddIntoSqlList(pSql); } - if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) { - tscImportDataFromFile(pSql); - } else { - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); - uint16_t type = pQueryInfo->type; - - if (QUERY_IS_JOIN_QUERY(type)) { - if (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_SUBQUERY)) { - tscHandleMasterJoinQuery(pSql); - } else { // for first stage sub query, iterate all vnodes to get all timestamp - if (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) { - tscBuildAndSendRequest(pSql, NULL); - } else { // secondary stage join query. - if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query - tscLockByThread(&pSql->squeryLock); - tscHandleMasterSTableQuery(pSql); - tscUnlockByThread(&pSql->squeryLock); - } else { - tscBuildAndSendRequest(pSql, NULL); - } - } + if (taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // nest query. do execute it firstly + pSql->subState.numOfSub = (int32_t) taosArrayGetSize(pQueryInfo->pUpstream); + + pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES); + pSql->subState.states = calloc(pSql->subState.numOfSub, sizeof(int8_t)); + + for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) { + SQueryInfo* pSub = taosArrayGetP(pQueryInfo->pUpstream, i); + + pSql->cmd.active = pSub; + pSql->cmd.command = TSDB_SQL_SELECT; + + // TODO handle memory failure + SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj)); + if (pNew == NULL) { + terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; + // return NULL; + } + + pNew->pTscObj = pSql->pTscObj; + pNew->signature = pNew; + pNew->sqlstr = strdup(pSql->sqlstr); // todo refactor + pNew->fp = tscSubqueryCompleteCallback; + + SRetrieveSupport* ps = calloc(1, sizeof(SRetrieveSupport)); // todo use object id + ps->pParentSql = pSql; + ps->subqueryIndex = i; + + pNew->param = ps; + pSql->pSubs[i] = pNew; + registerSqlObj(pNew); + + SSqlCmd* pCmd = &pNew->cmd; + pCmd->command = TSDB_SQL_SELECT; + if (tscAddQueryInfo(pCmd) != TSDB_CODE_SUCCESS) { } - return; - } else if (tscMultiRoundQuery(pQueryInfo, 0) && pQueryInfo->round == 0) { - tscHandleFirstRoundStableQuery(pSql); // todo lock? - return; - } else if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query - tscLockByThread(&pSql->squeryLock); - tscHandleMasterSTableQuery(pSql); - tscUnlockByThread(&pSql->squeryLock); - return; + SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pCmd); + tscQueryInfoCopy(pNewQueryInfo, pSub); + + // create sub query to handle the sub query. + executeQuery(pNew, pNewQueryInfo); } - pCmd->active = pQueryInfo; - tscBuildAndSendRequest(pSql, NULL); + // merge sub query result and generate final results + return; } + + pSql->cmd.active = pQueryInfo; + doExecuteQuery(pSql, pQueryInfo); } int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid) { @@ -2926,17 +3572,15 @@ bool tscIsQueryWithLimit(SSqlObj* pSql) { } SSqlCmd* pCmd = &pSql->cmd; - for (int32_t i = 0; i < pCmd->numOfClause; ++i) { - SQueryInfo* pqi = tscGetQueryInfoS(pCmd, i); - if (pqi == NULL) { - continue; - } - + SQueryInfo* pqi = tscGetQueryInfo(pCmd); + while(pqi != NULL) { if (pqi->limit.limit > 0) { return true; } + + pqi = pqi->sibling; } - + return false; } @@ -2978,7 +3622,7 @@ int32_t tscInvalidSQLErrMsg(char* msg, const char* additionalInfo, const char* s if (sql == NULL) { assert(additionalInfo != NULL); sprintf(msg, msgFormat1, additionalInfo); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } char buf[64] = {0}; // only extract part of sql string @@ -2990,7 +3634,7 @@ int32_t tscInvalidSQLErrMsg(char* msg, const char* additionalInfo, const char* s sprintf(msg, msgFormat3, buf); // no additional information for invalid sql error } - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } bool tscHasReachLimitation(SQueryInfo* pQueryInfo, SSqlRes* pRes) { @@ -3012,7 +3656,7 @@ bool hasMoreVnodesToTry(SSqlObj* pSql) { } assert(pRes->completed); - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); // for normal table, no need to try any more if results are all retrieved from one vnode @@ -3030,14 +3674,15 @@ bool hasMoreVnodesToTry(SSqlObj* pSql) { } bool hasMoreClauseToTry(SSqlObj* pSql) { - return pSql->cmd.clauseIndex < pSql->cmd.numOfClause - 1; + SSqlCmd* pCmd = &pSql->cmd; + return pCmd->active->sibling != NULL; } void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); /* * no result returned from the current virtual node anymore, try the next vnode if exists @@ -3093,17 +3738,19 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - // current subclause is completed, try the next subclause - assert(pCmd->clauseIndex < pCmd->numOfClause - 1); - - pCmd->clauseIndex++; - SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd); pSql->cmd.command = pQueryInfo->command; //backup the total number of result first int64_t num = pRes->numOfTotal + pRes->numOfClauseTotal; + + + // DON't free final since it may be recoreded and used later in APP + TAOS_FIELD* finalBk = pRes->final; + pRes->final = NULL; tscFreeSqlResult(pSql); + pRes->final = finalBk; pRes->numOfTotal = num; @@ -3111,7 +3758,7 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) { pSql->subState.numOfSub = 0; pSql->fp = fp; - tscDebug("0x%"PRIx64" try data in the next subclause:%d, total subclause:%d", pSql->self, pCmd->clauseIndex, pCmd->numOfClause); + tscDebug("0x%"PRIx64" try data in the next subclause", pSql->self); if (pCmd->command > TSDB_SQL_LOCAL) { tscProcessLocalCmd(pSql); } else { @@ -3328,22 +3975,25 @@ CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta) { assert(pTableMeta != NULL); CChildTableMeta* cMeta = calloc(1, sizeof(CChildTableMeta)); + cMeta->tableType = TSDB_CHILD_TABLE; - cMeta->vgId = pTableMeta->vgId; - cMeta->id = pTableMeta->id; + cMeta->vgId = pTableMeta->vgId; + cMeta->id = pTableMeta->id; + cMeta->suid = pTableMeta->suid; tstrncpy(cMeta->sTableName, pTableMeta->sTableName, TSDB_TABLE_FNAME_LEN); return cMeta; } -int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name) { - assert(pChild != NULL); - - uint32_t size = tscGetTableMetaMaxSize(); - STableMeta* p = calloc(1, size); +int32_t tscCreateTableMetaFromSTableMeta(STableMeta* pChild, const char* name, void* buf) { + assert(pChild != NULL && buf != NULL); + STableMeta* p = buf; taosHashGetClone(tscTableMetaInfo, pChild->sTableName, strnlen(pChild->sTableName, TSDB_TABLE_FNAME_LEN), NULL, p, -1); - if (p->id.uid > 0) { // tableMeta exists, build child table meta and return + + // tableMeta exists, build child table meta according to the super table meta + // the uid need to be checked in addition to the general name of the super table. + if (p->id.uid > 0 && pChild->suid == p->id.uid) { pChild->sversion = p->sversion; pChild->tversion = p->tversion; @@ -3351,13 +4001,9 @@ int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name) { int32_t total = pChild->tableInfo.numOfColumns + pChild->tableInfo.numOfTags; memcpy(pChild->schema, p->schema, sizeof(SSchema) *total); - - tfree(p); return TSDB_CODE_SUCCESS; } else { // super table has been removed, current tableMeta is also expired. remove it here taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN)); - - tfree(p); return -1; } } @@ -3368,75 +4014,94 @@ uint32_t tscGetTableMetaMaxSize() { STableMeta* tscTableMetaDup(STableMeta* pTableMeta) { assert(pTableMeta != NULL); - uint32_t size = tscGetTableMetaSize(pTableMeta); + size_t size = tscGetTableMetaSize(pTableMeta); + STableMeta* p = calloc(1, size); memcpy(p, pTableMeta, size); return p; } -static int32_t createSecondaryExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo) { - if (!tscIsSecondStageQuery(pQueryInfo)) { +SVgroupsInfo* tscVgroupsInfoDup(SVgroupsInfo* pVgroupsInfo) { + assert(pVgroupsInfo != NULL); + + size_t size = sizeof(SVgroupInfo) * pVgroupsInfo->numOfVgroups + sizeof(SVgroupsInfo); + SVgroupsInfo* pInfo = calloc(1, size); + memcpy(pInfo, pVgroupsInfo, size); + return pInfo; +} + +int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num) { + if (!pQueryInfo->arithmeticOnAgg) { return TSDB_CODE_SUCCESS; } - pQueryAttr->numOfExpr2 = tscNumOfFields(pQueryInfo); - pQueryAttr->pExpr2 = calloc(pQueryAttr->numOfExpr2, sizeof(SExprInfo)); - if (pQueryAttr->pExpr2 == NULL) { + *num = tscNumOfFields(pQueryInfo); + *pExpr = calloc(*(num), POINTER_BYTES); + if ((*pExpr) == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - for (int32_t i = 0; i < pQueryAttr->numOfExpr2; ++i) { + for (int32_t i = 0; i < (*num); ++i) { SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i); - SExprInfo* pExpr = pField->pExpr; + SExprInfo* pSource = pField->pExpr; - SSqlExpr *pse = &pQueryAttr->pExpr2[i].base; + SExprInfo* px = calloc(1, sizeof(SExprInfo)); + (*pExpr)[i] = px; + + SSqlExpr *pse = &px->base; pse->uid = pTableMetaInfo->pTableMeta->id.uid; - pse->resColId = pExpr->base.resColId; + pse->resColId = pSource->base.resColId; + strncpy(pse->aliasName, pSource->base.aliasName, tListLen(pse->aliasName)); + strncpy(pse->token, pSource->base.token, tListLen(pse->token)); - if (pExpr->base.functionId != TSDB_FUNC_ARITHM) { // this should be switched to projection query + if (pSource->base.functionId != TSDB_FUNC_ARITHM) { // this should be switched to projection query pse->numOfParams = 0; // no params for projection query pse->functionId = TSDB_FUNC_PRJ; - pse->colInfo.colId = pExpr->base.resColId; + pse->colInfo.colId = pSource->base.resColId; - for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) { - if (pQueryAttr->pExpr1[j].base.resColId == pse->colInfo.colId) { + int32_t numOfOutput = (int32_t) taosArrayGetSize(pQueryInfo->exprList); + for (int32_t j = 0; j < numOfOutput; ++j) { + SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, j); + if (p->base.resColId == pse->colInfo.colId) { pse->colInfo.colIndex = j; + break; } } pse->colInfo.flag = TSDB_COL_NORMAL; - pse->resType = pExpr->base.resType; - pse->resBytes = pExpr->base.resBytes; + pse->resType = pSource->base.resType; + pse->resBytes = pSource->base.resBytes; + strncpy(pse->colInfo.name, pSource->base.aliasName, tListLen(pse->colInfo.name)); // TODO restore refactor - int32_t functionId = pExpr->base.functionId; - if (pExpr->base.functionId == TSDB_FUNC_FIRST_DST) { + int32_t functionId = pSource->base.functionId; + if (pSource->base.functionId == TSDB_FUNC_FIRST_DST) { functionId = TSDB_FUNC_FIRST; - } else if (pExpr->base.functionId == TSDB_FUNC_LAST_DST) { + } else if (pSource->base.functionId == TSDB_FUNC_LAST_DST) { functionId = TSDB_FUNC_LAST; - } else if (pExpr->base.functionId == TSDB_FUNC_STDDEV_DST) { + } else if (pSource->base.functionId == TSDB_FUNC_STDDEV_DST) { functionId = TSDB_FUNC_STDDEV; } int32_t inter = 0; - getResultDataInfo(pExpr->base.colType, pExpr->base.colBytes, functionId, 0, &pse->resType, + getResultDataInfo(pSource->base.colType, pSource->base.colBytes, functionId, 0, &pse->resType, &pse->resBytes, &inter, 0, false); pse->colType = pse->resType; pse->colBytes = pse->resBytes; } else { // arithmetic expression - pse->colInfo.colId = pExpr->base.colInfo.colId; - pse->colType = pExpr->base.colType; - pse->colBytes = pExpr->base.colBytes; + pse->colInfo.colId = pSource->base.colInfo.colId; + pse->colType = pSource->base.colType; + pse->colBytes = pSource->base.colBytes; pse->resBytes = sizeof(double); pse->resType = TSDB_DATA_TYPE_DOUBLE; - pse->functionId = pExpr->base.functionId; - pse->numOfParams = pExpr->base.numOfParams; + pse->functionId = pSource->base.functionId; + pse->numOfParams = pSource->base.numOfParams; - for (int32_t j = 0; j < pExpr->base.numOfParams; ++j) { - tVariantAssign(&pse->param[j], &pExpr->base.param[j]); - buildArithmeticExprFromMsg(&pQueryAttr->pExpr2[i], NULL); + for (int32_t j = 0; j < pSource->base.numOfParams; ++j) { + tVariantAssign(&pse->param[j], &pSource->base.param[j]); + buildArithmeticExprFromMsg(px, NULL); } } } @@ -3447,7 +4112,7 @@ static int32_t createSecondaryExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInf static int32_t createGlobalAggregateExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInfo) { assert(tscIsTwoStageSTableQuery(pQueryInfo, 0)); - pQueryAttr->numOfExpr3 = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + pQueryAttr->numOfExpr3 = (int32_t) tscNumOfExprs(pQueryInfo); pQueryAttr->pExpr3 = calloc(pQueryAttr->numOfExpr3, sizeof(SExprInfo)); if (pQueryAttr->pExpr3 == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -3457,7 +4122,7 @@ static int32_t createGlobalAggregateExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQu SExprInfo* pExpr = &pQueryAttr->pExpr1[i]; SSqlExpr* pse = &pQueryAttr->pExpr3[i].base; - tscSqlExprAssign(&pQueryAttr->pExpr3[i], pExpr); + tscExprAssign(&pQueryAttr->pExpr3[i], pExpr); pse->colInfo.colId = pExpr->base.resColId; pse->colInfo.colIndex = i; @@ -3521,7 +4186,7 @@ static int32_t createTagColumnInfo(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInf if ((pCol->columnIndex >= numOfTagColumns || pCol->columnIndex < TSDB_TBNAME_COLUMN_INDEX) || (!isValidDataType(pColSchema->type))) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } SColumnInfo* pTagCol = &pQueryAttr->tagColList[i]; @@ -3539,7 +4204,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt memset(pQueryAttr, 0, sizeof(SQueryAttr)); int16_t numOfCols = (int16_t) taosArrayGetSize(pQueryInfo->colList); - int16_t numOfOutput = (int16_t) tscSqlExprNumOfExprs(pQueryInfo); + int16_t numOfOutput = (int16_t) tscNumOfExprs(pQueryInfo); pQueryAttr->topBotQuery = tscIsTopBotQuery(pQueryInfo); pQueryAttr->hasTagResults = hasTagValOutput(pQueryInfo); @@ -3576,7 +4241,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; - pQueryAttr->pGroupbyExpr = calloc(1, sizeof(SSqlGroupbyExpr)); + pQueryAttr->pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr)); *(pQueryAttr->pGroupbyExpr) = pQueryInfo->groupbyExpr; if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { @@ -3587,8 +4252,8 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt pQueryAttr->pExpr1 = calloc(pQueryAttr->numOfOutput, sizeof(SExprInfo)); for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); - tscSqlExprAssign(&pQueryAttr->pExpr1[i], pExpr); + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); + tscExprAssign(&pQueryAttr->pExpr1[i], pExpr); if (pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_ARITHM) { for (int32_t j = 0; j < pQueryAttr->pExpr1[i].base.numOfParams; ++j) { @@ -3614,13 +4279,17 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt } // for simple table, not for super table - int32_t code = createSecondaryExpr(pQueryAttr, pQueryInfo, pTableMetaInfo); - if (code != TSDB_CODE_SUCCESS) { - return code; + if (pQueryInfo->arithmeticOnAgg) { + pQueryAttr->numOfExpr2 = (int32_t) taosArrayGetSize(pQueryInfo->exprList1); + pQueryAttr->pExpr2 = calloc(pQueryAttr->numOfExpr2, sizeof(SExprInfo)); + for(int32_t i = 0; i < pQueryAttr->numOfExpr2; ++i) { + SExprInfo* p = taosArrayGetP(pQueryInfo->exprList1, i); + tscExprAssign(&pQueryAttr->pExpr2[i], p); + } } // tag column info - code = createTagColumnInfo(pQueryAttr, pQueryInfo, pTableMetaInfo); + int32_t code = createTagColumnInfo(pQueryAttr, pQueryInfo, pTableMetaInfo); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -3645,19 +4314,106 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt tscError("%p illegal value of numOfCols in query msg: %" PRIu64 ", table cols:%d", addr, (uint64_t)pQueryAttr->numOfCols, numOfCols); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pQueryAttr->interval.interval < 0) { tscError("%p illegal value of aggregation time interval in query msg: %" PRId64, addr, (int64_t)pQueryInfo->interval.interval); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (pQueryAttr->pGroupbyExpr->numOfGroupCols < 0) { tscError("%p illegal value of numOfGroupCols in query msg: %d", addr, pQueryInfo->groupbyExpr.numOfGroupCols); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return TSDB_CODE_SUCCESS; } + +static int32_t doAddTableName(char* nextStr, char** str, SArray* pNameArray, SSqlObj* pSql) { + int32_t code = TSDB_CODE_SUCCESS; + SSqlCmd* pCmd = &pSql->cmd; + + char tablename[TSDB_TABLE_FNAME_LEN] = {0}; + int32_t len = 0; + + if (nextStr == NULL) { + strncpy(tablename, *str, TSDB_TABLE_FNAME_LEN); + len = (int32_t) strlen(tablename); + } else { + memcpy(tablename, *str, nextStr - (*str)); + len = (int32_t)(nextStr - (*str)); + tablename[len] = '\0'; + } + + (*str) = nextStr + 1; + len = (int32_t)strtrim(tablename); + + SStrToken sToken = {.n = len, .type = TK_ID, .z = tablename}; + tGetToken(tablename, &sToken.type); + + // Check if the table name available or not + if (tscValidateName(&sToken) != TSDB_CODE_SUCCESS) { + code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; + sprintf(pCmd->payload, "table name is invalid"); + return code; + } + + SName name = {0}; + if ((code = tscSetTableFullName(&name, &sToken, pSql)) != TSDB_CODE_SUCCESS) { + return code; + } + + memset(tablename, 0, tListLen(tablename)); + tNameExtractFullName(&name, tablename); + + char* p = strdup(tablename); + taosArrayPush(pNameArray, &p); + return TSDB_CODE_SUCCESS; +} + +int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray) { + SSqlCmd *pCmd = &pSql->cmd; + + pCmd->command = TSDB_SQL_MULTI_META; + pCmd->msgType = TSDB_MSG_TYPE_CM_TABLES_META; + + int code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; + char *str = (char *)pNameList; + + SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd); + if (pQueryInfo == NULL) { + pSql->res.code = terrno; + return terrno; + } + + char *nextStr; + while (1) { + nextStr = strchr(str, ','); + if (nextStr == NULL) { + code = doAddTableName(nextStr, &str, pNameArray, pSql); + break; + } + + code = doAddTableName(nextStr, &str, pNameArray, pSql); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + if (taosArrayGetSize(pNameArray) > TSDB_MULTI_TABLEMETA_MAX_NUM) { + code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; + sprintf(pCmd->payload, "tables over the max number"); + return code; + } + } + + if (taosArrayGetSize(pNameArray) > TSDB_MULTI_TABLEMETA_MAX_NUM) { + code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; + sprintf(pCmd->payload, "tables over the max number"); + return code; + } + + return TSDB_CODE_SUCCESS; +} + diff --git a/src/client/tests/timeParseTest.cpp b/src/client/tests/timeParseTest.cpp index d7325430cd1d859ab9dd3e86f8dd55ab0dd1355d..692398e3b7329b31ac02d4c36635000d4721d8fc 100644 --- a/src/client/tests/timeParseTest.cpp +++ b/src/client/tests/timeParseTest.cpp @@ -4,7 +4,7 @@ #include #include "taos.h" -#include "tstoken.h" +#include "ttoken.h" #include "tutil.h" int main(int argc, char** argv) { @@ -98,7 +98,7 @@ TEST(testCase, parse_time) { taosParseTime(t41, &time, strlen(t41), TSDB_TIME_PRECISION_MILLI, 0); EXPECT_EQ(time, 852048000999); - int64_t k = timezone; +// int64_t k = timezone; char t42[] = "1997-1-1T0:0:0.999999999Z"; taosParseTime(t42, &time, strlen(t42), TSDB_TIME_PRECISION_MILLI, 0); EXPECT_EQ(time, 852048000999 - timezone * MILLISECOND_PER_SECOND); @@ -163,7 +163,7 @@ TEST(testCase, parse_time) { taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0); EXPECT_EQ(time, -28800 * MILLISECOND_PER_SECOND); - char* t = "2021-01-08T02:11:40.000+00:00"; + char t[] = "2021-01-08T02:11:40.000+00:00"; taosParseTime(t, &time, strlen(t), TSDB_TIME_PRECISION_MILLI, 0); printf("%ld\n", time); } diff --git a/src/common/inc/tdataformat.h b/src/common/inc/tdataformat.h index 88d5b850102cc2ecc796ead0fd75408da428c431..fcae7a415fae8bc1b5897bf6865f1cc2004ba731 100644 --- a/src/common/inc/tdataformat.h +++ b/src/common/inc/tdataformat.h @@ -234,6 +234,7 @@ typedef struct SDataCol { int len; // column data length VarDataOffsetT *dataOff; // For binary and nchar data, the offset in the data column void * pData; // Actual data pointer + TSKEY ts; // only used in last NULL column } SDataCol; static FORCE_INLINE void dataColReset(SDataCol *pDataCol) { pDataCol->len = 0; } diff --git a/src/common/inc/texpr.h b/src/common/inc/texpr.h index a0854ce81b96c5cb3c77614b7f92497cf4c56340..275dd12fd7ca9f9771592039d846593fa958f240 100644 --- a/src/common/inc/texpr.h +++ b/src/common/inc/texpr.h @@ -87,10 +87,9 @@ tExprNode* exprTreeFromBinary(const void* data, size_t size); tExprNode* exprTreeFromTableName(const char* tbnameCond); tExprNode* exprdup(tExprNode* pTree); -bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param); +void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree); -typedef void (*_arithmetic_operator_fn_t)(void *left, int32_t numLeft, int32_t leftType, void *right, int32_t numRight, - int32_t rightType, void *output, int32_t order); +bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param); void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order, char *(*cb)(void *, const char*, int32_t)); diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 2f4aa4c2b2ad0822fcf7a45987b812376fe5d9f0..e07c3611d7b62b82689785446173d8a0d2fe9d11 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -142,12 +142,15 @@ extern int32_t tsMonitorInterval; extern int8_t tsEnableStream; // internal +extern int8_t tsCompactMnodeWal; extern int8_t tsPrintAuth; extern int8_t tscEmbedded; extern char configDir[]; extern char tsVnodeDir[]; extern char tsDnodeDir[]; extern char tsMnodeDir[]; +extern char tsMnodeBakDir[]; +extern char tsMnodeTmpDir[]; extern char tsDataDir[]; extern char tsLogDir[]; extern char tsScriptDir[]; diff --git a/src/common/inc/tname.h b/src/common/inc/tname.h index f37a4d9a3667554fff60389d95e9a897ef2e4664..ec2d76147ae71ce1e57abb606ceb73d3ef277248 100644 --- a/src/common/inc/tname.h +++ b/src/common/inc/tname.h @@ -18,7 +18,7 @@ #include "os.h" #include "taosmsg.h" -#include "tstoken.h" +#include "ttoken.h" #include "tvariant.h" typedef struct SDataStatis { @@ -44,8 +44,8 @@ typedef struct SResPair { // the structure for sql function in select clause typedef struct SSqlExpr { char aliasName[TSDB_COL_NAME_LEN]; // as aliasName + char token[TSDB_COL_NAME_LEN]; // original token SColIndex colInfo; - uint64_t uid; // refactor use the pointer int16_t functionId; // function id in aAgg array @@ -92,8 +92,6 @@ size_t tableIdPrefix(const char* name, char* prefix, int32_t len); void extractTableNameFromToken(SStrToken *pToken, SStrToken* pTable); -//SSchema tGetTbnameColumnSchema(); - SSchema tGetBlockDistColumnSchema(); SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const char* name); diff --git a/src/common/inc/tvariant.h b/src/common/inc/tvariant.h index f8f715c6cae1990b3c208c50bd75a1355795671e..21b7fd8223d59f57ed3c00eed019048a901ddf96 100644 --- a/src/common/inc/tvariant.h +++ b/src/common/inc/tvariant.h @@ -16,8 +16,8 @@ #ifndef TDENGINE_TVARIANT_H #define TDENGINE_TVARIANT_H -#include "tstoken.h" #include "tarray.h" +#include "ttoken.h" #ifdef __cplusplus extern "C" { diff --git a/src/common/src/tarithoperator.c b/src/common/src/tarithoperator.c index 1cb667d259f040cfab0656562f7c97444fc48d8a..b37e358b9c8688b888fb6122289dbe766f6306c9 100644 --- a/src/common/src/tarithoperator.c +++ b/src/common/src/tarithoperator.c @@ -2569,6 +2569,7 @@ _arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) { case TSDB_BINARY_OP_REMAINDER: return vectorRemainder; default: + assert(0); return NULL; } } diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index 4334a0de263e9857385222462724d4b8c758593e..f2dd3890a163ec1e1e25d2ac8b55f23aa9d5a79d 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -13,6 +13,7 @@ * along with this program. If not, see . */ +#include #include "os.h" #include "texpr.h" @@ -465,27 +466,29 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { return expr; } -tExprNode* exprdup(tExprNode* pTree) { - if (pTree == NULL) { +tExprNode* exprdup(tExprNode* pNode) { + if (pNode == NULL) { return NULL; } - tExprNode* pNode = calloc(1, sizeof(tExprNode)); - if (pTree->nodeType == TSQL_NODE_EXPR) { - tExprNode* pLeft = exprdup(pTree->_node.pLeft); - tExprNode* pRight = exprdup(pTree->_node.pRight); - - pNode->nodeType = TSQL_NODE_EXPR; - pNode->_node.pLeft = pLeft; - pNode->_node.pRight = pRight; - } else if (pTree->nodeType == TSQL_NODE_VALUE) { - pNode->pVal = calloc(1, sizeof(tVariant)); - tVariantAssign(pNode->pVal, pTree->pVal); - } else if (pTree->nodeType == TSQL_NODE_COL) { - pNode->pSchema = calloc(1, sizeof(SSchema)); - *pNode->pSchema = *pTree->pSchema; + tExprNode* pCloned = calloc(1, sizeof(tExprNode)); + if (pNode->nodeType == TSQL_NODE_EXPR) { + tExprNode* pLeft = exprdup(pNode->_node.pLeft); + tExprNode* pRight = exprdup(pNode->_node.pRight); + + pCloned->_node.pLeft = pLeft; + pCloned->_node.pRight = pRight; + pCloned->_node.optr = pNode->_node.optr; + pCloned->_node.hasPK = pNode->_node.hasPK; + } else if (pNode->nodeType == TSQL_NODE_VALUE) { + pCloned->pVal = calloc(1, sizeof(tVariant)); + tVariantAssign(pCloned->pVal, pNode->pVal); + } else if (pNode->nodeType == TSQL_NODE_COL) { + pCloned->pSchema = calloc(1, sizeof(SSchema)); + *pCloned->pSchema = *pNode->pSchema; } - return pNode; + pCloned->nodeType = pNode->nodeType; + return pCloned; } diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index db97c3a5af3e804316c60419bea3f2095f89b53c..d6bbc288adf92674b308e8d423d1b19cd58113c0 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -176,12 +176,15 @@ int32_t tsMonitorInterval = 30; // seconds int8_t tsEnableStream = 1; // internal +int8_t tsCompactMnodeWal = 0; int8_t tsPrintAuth = 0; int8_t tscEmbedded = 0; char configDir[TSDB_FILENAME_LEN] = {0}; char tsVnodeDir[TSDB_FILENAME_LEN] = {0}; char tsDnodeDir[TSDB_FILENAME_LEN] = {0}; char tsMnodeDir[TSDB_FILENAME_LEN] = {0}; +char tsMnodeTmpDir[TSDB_FILENAME_LEN] = {0}; +char tsMnodeBakDir[TSDB_FILENAME_LEN] = {0}; char tsDataDir[TSDB_FILENAME_LEN] = {0}; char tsScriptDir[TSDB_FILENAME_LEN] = {0}; char tsTempDir[TSDB_FILENAME_LEN] = "/tmp/"; diff --git a/src/common/src/tname.c b/src/common/src/tname.c index f1ddc60637323de747d077011a93b2602e4764f8..dc868d805790688c15192b2b282f42d4e6e8b957 100644 --- a/src/common/src/tname.c +++ b/src/common/src/tname.c @@ -2,7 +2,7 @@ #include "tutil.h" #include "tname.h" -#include "tstoken.h" +#include "ttoken.h" #include "tvariant.h" #define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS) diff --git a/src/common/src/tvariant.c b/src/common/src/tvariant.c index c872d8731b572661a35ca91248afd167fefca0bf..9988450c30f341d03a97c2393e1939aff96daf7d 100644 --- a/src/common/src/tvariant.c +++ b/src/common/src/tvariant.c @@ -14,14 +14,14 @@ */ #include "os.h" -#include "tvariant.h" #include "hash.h" #include "taos.h" #include "taosdef.h" -#include "tstoken.h" +#include "ttoken.h" #include "ttokendef.h" -#include "tutil.h" #include "ttype.h" +#include "tutil.h" +#include "tvariant.h" void tVariantCreate(tVariant *pVar, SStrToken *token) { int32_t ret = 0; @@ -49,7 +49,7 @@ void tVariantCreate(tVariant *pVar, SStrToken *token) { ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, true); if (ret != 0) { SStrToken t = {0}; - tSQLGetToken(token->z, &t.type); + tGetToken(token->z, &t.type); if (t.type == TK_MINUS) { // it is a signed number which is greater than INT64_MAX or less than INT64_MIN pVar->nType = -1; // -1 means error type return; @@ -460,7 +460,7 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result *result = (int64_t) pVariant->dKey; } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { SStrToken token = {.z = pVariant->pz, .n = pVariant->nLen}; - /*int32_t n = */tSQLGetToken(pVariant->pz, &token.type); + /*int32_t n = */tGetToken(pVariant->pz, &token.type); if (token.type == TK_NULL) { if (releaseVariantPtr) { @@ -495,10 +495,10 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result wchar_t *endPtr = NULL; SStrToken token = {0}; - token.n = tSQLGetToken(pVariant->pz, &token.type); + token.n = tGetToken(pVariant->pz, &token.type); if (token.type == TK_MINUS || token.type == TK_PLUS) { - token.n = tSQLGetToken(pVariant->pz + token.n, &token.type); + token.n = tGetToken(pVariant->pz + token.n, &token.type); } if (token.type == TK_FLOAT) { diff --git a/src/connector/go b/src/connector/go index 050667e5b4d0eafa5387e4283e713559b421203f..8ce6d86558afc8c0b50c10f990fd2b4270cf06fc 160000 --- a/src/connector/go +++ b/src/connector/go @@ -1 +1 @@ -Subproject commit 050667e5b4d0eafa5387e4283e713559b421203f +Subproject commit 8ce6d86558afc8c0b50c10f990fd2b4270cf06fc diff --git a/src/connector/grafanaplugin b/src/connector/grafanaplugin index 32e2c97a4cf7bedaa99f5d6dd8cb036e7f4470df..3530c6df097134a410bacec6b3cd013ef38a61aa 160000 --- a/src/connector/grafanaplugin +++ b/src/connector/grafanaplugin @@ -1 +1 @@ -Subproject commit 32e2c97a4cf7bedaa99f5d6dd8cb036e7f4470df +Subproject commit 3530c6df097134a410bacec6b3cd013ef38a61aa diff --git a/src/connector/jdbc/CMakeLists.txt b/src/connector/jdbc/CMakeLists.txt index de4b8f6bfb92d2de0810dab50c70452f7d47b7a8..61e976cb184d3240bdc8917a5b2e5f3182d55fcc 100644 --- a/src/connector/jdbc/CMakeLists.txt +++ b/src/connector/jdbc/CMakeLists.txt @@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED) ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME} POST_BUILD COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.28-dist.jar ${LIBRARY_OUTPUT_PATH} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.29.jar ${LIBRARY_OUTPUT_PATH} COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml COMMENT "build jdbc driver") ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME}) diff --git a/src/connector/jdbc/deploy-pom.xml b/src/connector/jdbc/deploy-pom.xml index a31796ffdeeb4b76835e4b04d40720dda149fddc..968a9bf470ddde1996467467fa24cfd2fbf355e0 100755 --- a/src/connector/jdbc/deploy-pom.xml +++ b/src/connector/jdbc/deploy-pom.xml @@ -5,7 +5,7 @@ com.taosdata.jdbc taos-jdbcdriver - 2.0.28 + 2.0.29 jar JDBCDriver diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml index 3400a82e73640c79f6157fafd2bbe8c7520145dd..ef353d1d19d37da3c1a3e9bdc4a2a378cf4edc0c 100755 --- a/src/connector/jdbc/pom.xml +++ b/src/connector/jdbc/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.taosdata.jdbc taos-jdbcdriver - 2.0.28 + 2.0.29 jar JDBCDriver https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc @@ -122,6 +122,7 @@ **/FailOverTest.java **/InvalidResultSetPointerTest.java **/RestfulConnectionTest.java + **/TD4144Test.java true diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java index 4b5b88d93bdf14b2387708a3e24229d0fd5d74d7..f8ea9af4230e9584197f1141dc5a4f7c1621b3ff 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java @@ -84,10 +84,12 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet } @Override + @Deprecated public InputStream getUnicodeStream(int columnIndex) throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); - + } + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } @@ -171,6 +173,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet } @Override + @Deprecated public InputStream getUnicodeStream(String columnLabel) throws SQLException { return getUnicodeStream(findColumn(columnLabel)); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java index c8ab9fb15ae0ece504ff825dbbe16e12408aede0..02fee74eb5544f282559f88dab723ccfd8ca096f 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java @@ -49,7 +49,7 @@ public class TSDBConnection extends AbstractConnection { this.databaseMetaData.setConnection(this); } - public TSDBJNIConnector getConnection() { + public TSDBJNIConnector getConnector() { return this.connector; } @@ -58,7 +58,7 @@ public class TSDBConnection extends AbstractConnection { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); } - return new TSDBStatement(this, this.connector); + return new TSDBStatement(this); } public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException { @@ -74,14 +74,18 @@ public class TSDBConnection extends AbstractConnection { } public PreparedStatement prepareStatement(String sql) throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); - return new TSDBPreparedStatement(this, this.connector, sql); + } + + return new TSDBPreparedStatement(this, sql); } public void close() throws SQLException { - if (isClosed) + if (isClosed) { return; + } + this.connector.closeConnection(); this.isClosed = true; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java index 37073e243fef99176c6d3d16d87d7cdaabb0e1b4..f38555ce8a6c7ee946b3bdbda2204c702b49198a 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java @@ -30,6 +30,7 @@ public abstract class TSDBConstants { public static final int JNI_FETCH_END = -6; public static final int JNI_OUT_OF_MEMORY = -7; // TSDB Data Types + public static final int TSDB_DATA_TYPE_NULL = 0; public static final int TSDB_DATA_TYPE_BOOL = 1; public static final int TSDB_DATA_TYPE_TINYINT = 2; public static final int TSDB_DATA_TYPE_SMALLINT = 3; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java index bbd8519a0315015e6e775362f997d21f1af8930a..55533bd28cc4027c2e4a258cf2a36fd5b72d12f2 100755 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java @@ -104,7 +104,7 @@ public class TSDBDriver extends AbstractDriver { static { try { - java.sql.DriverManager.registerDriver(new TSDBDriver()); + DriverManager.registerDriver(new TSDBDriver()); } catch (SQLException e) { throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_CANNOT_REGISTER_JNI_DRIVER, e); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java index 5e3ffffa4fe7326b8c1e89ac91a37e95c346784f..179bad2cedea7759b05f507525b584029bfd3ef9 100755 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java @@ -18,6 +18,7 @@ package com.taosdata.jdbc; import com.taosdata.jdbc.utils.TaosInfo; +import java.nio.ByteBuffer; import java.sql.SQLException; import java.sql.SQLWarning; import java.util.List; @@ -29,10 +30,13 @@ public class TSDBJNIConnector { private static volatile Boolean isInitialized = false; private TaosInfo taosInfo = TaosInfo.getInstance(); + // Connection pointer used in C private long taos = TSDBConstants.JNI_NULL_POINTER; + // result set status in current connection - private boolean isResultsetClosed = true; + private boolean isResultsetClosed; + private int affectedRows = -1; static { @@ -75,7 +79,6 @@ public class TSDBJNIConnector { public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException { if (this.taos != TSDBConstants.JNI_NULL_POINTER) { -// this.closeConnectionImp(this.taos); closeConnection(); this.taos = TSDBConstants.JNI_NULL_POINTER; } @@ -97,12 +100,6 @@ public class TSDBJNIConnector { * @throws SQLException */ public long executeQuery(String sql) throws SQLException { - // close previous result set if the user forgets to invoke the - // free method to close previous result set. -// if (!this.isResultsetClosed) { -// freeResultSet(taosResultSetPointer); -// } - Long pSql = 0l; try { pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos); @@ -135,6 +132,7 @@ public class TSDBJNIConnector { // Try retrieving result set for the executed SQL using the current connection pointer. pSql = this.getResultSetImp(this.taos, pSql); + // if pSql == 0L that means resultset is closed isResultsetClosed = (pSql == TSDBConstants.JNI_NULL_POINTER); return pSql; @@ -169,37 +167,14 @@ public class TSDBJNIConnector { private native long isUpdateQueryImp(long connection, long pSql); /** - * Free resultset operation from C to release resultset pointer by JNI + * Free result set operation from C to release result set pointer by JNI */ public int freeResultSet(long pSql) { - int res = TSDBConstants.JNI_SUCCESS; -// if (result != taosResultSetPointer && taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) { -// throw new RuntimeException("Invalid result set pointer"); -// } - -// if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) { - res = this.freeResultSetImp(this.taos, pSql); -// taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER; -// } - + int res = this.freeResultSetImp(this.taos, pSql); isResultsetClosed = true; return res; } - /** - * Close the open result set which is associated to the current connection. If the result set is already - * closed, return 0 for success. - */ -// public int freeResultSet() { -// int resCode = TSDBConstants.JNI_SUCCESS; -// if (!isResultsetClosed) { -// resCode = this.freeResultSetImp(this.taos, this.taosResultSetPointer); -// taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER; -// isResultsetClosed = true; -// } -// return resCode; -// } - private native int freeResultSetImp(long connection, long result); /** @@ -246,6 +221,7 @@ public class TSDBJNIConnector { */ public void closeConnection() throws SQLException { int code = this.closeConnectionImp(this.taos); + if (code < 0) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); } else if (code == 0) { @@ -253,6 +229,7 @@ public class TSDBJNIConnector { } else { throw new SQLException("Undefined error code returned by TDengine when closing a connection"); } + // invoke closeConnectionImpl only here taosInfo.connect_close_increment(); } @@ -289,7 +266,7 @@ public class TSDBJNIConnector { private native void unsubscribeImp(long subscription, boolean isKeep); /** - * Validate if a create table sql statement is correct without actually creating that table + * Validate if a create table SQL statement is correct without actually creating that table */ public boolean validateCreateTableSql(String sql) { int res = validateCreateTableSqlImp(taos, sql.getBytes()); @@ -297,4 +274,76 @@ public class TSDBJNIConnector { } private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes); + + public long prepareStmt(String sql) throws SQLException { + Long stmt = 0L; + try { + stmt = prepareStmtImp(sql.getBytes(), this.taos); + } catch (Exception e) { + e.printStackTrace(); + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING); + } + + if (stmt == TSDBConstants.JNI_CONNECTION_NULL) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); + } + + if (stmt == TSDBConstants.JNI_SQL_NULL) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL); + } + + if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY); + } + + return stmt; + } + + private native long prepareStmtImp(byte[] sql, long con); + + public void setBindTableName(long stmt, String tableName) throws SQLException { + int code = setBindTableNameImp(stmt, tableName, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to set table name"); + } + } + + private native int setBindTableNameImp(long stmt, String name, long conn); + + public void setBindTableNameAndTags(long stmt, String tableName, int numOfTags, ByteBuffer tags, ByteBuffer typeList, ByteBuffer lengthList, ByteBuffer nullList) throws SQLException { + int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(), + nullList.array(), this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags"); + } + } + + private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn); + + public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) throws SQLException { + int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind column data"); + } + } + + private native int bindColDataImp(long stmt, byte[] colDataList, byte[] lengthList, byte[] isNullList, int type, int bytes, int numOfRows, int columnIndex, long conn); + + public void executeBatch(long stmt) throws SQLException { + int code = executeBatchImp(stmt, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to execute batch bind"); + } + } + + private native int executeBatchImp(long stmt, long con); + + public void closeBatch(long stmt) throws SQLException { + int code = closeStmt(stmt, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to close batch bind"); + } + } + + private native int closeStmt(long stmt, long con); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java index 56f971a35e72c60608fcc294298a2f3ca7fbc292..f6810237c097a62a4c8f0f63d6e435bfb0354125 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java @@ -18,33 +18,43 @@ import com.taosdata.jdbc.utils.Utils; import java.io.InputStream; import java.io.Reader; +import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.sql.*; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.regex.Matcher; import java.util.regex.Pattern; /* - * TDengine only supports a subset of the standard SQL, thus this implemetation of the + * TDengine only supports a subset of the standard SQL, thus this implementation of the * standard JDBC API contains more or less some adjustments customized for certain * compatibility needs. */ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement { - private String rawSql; private Object[] parameters; private boolean isPrepared; - + + private ArrayList colData; + private ArrayList tableTags; + private int tagValueLength; + + private String tableName; + private long nativeStmtHandle = 0; + private volatile TSDBParameterMetaData parameterMetaData; - TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) { - super(connection, connecter); + TSDBPreparedStatement(TSDBConnection connection, String sql) { + super(connection); init(sql); + int parameterCnt = 0; if (sql.contains("?")) { - int parameterCnt = 0; for (int i = 0; i < sql.length(); i++) { if ('?' == sql.charAt(i)) { parameterCnt++; @@ -53,6 +63,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat parameters = new Object[parameterCnt]; this.isPrepared = true; } + + if (parameterCnt > 1) { + // the table name is also a parameter, so ignore it. + this.colData = new ArrayList(); + this.tableTags = new ArrayList(); + } } private void init(String sql) { @@ -260,10 +276,14 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setObject(int parameterIndex, Object x) throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - if (parameterIndex < 1 && parameterIndex >= parameters.length) + } + + if (parameterIndex < 1 && parameterIndex >= parameters.length) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); + } + parameters[parameterIndex - 1] = x; } @@ -300,9 +320,10 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setRef(int parameterIndex, Ref x) throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - + } + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } @@ -515,4 +536,489 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } + + /////////////////////////////////////////////////////////////////////// + // NOTE: the following APIs are not JDBC compatible + // set the bind table name + private static class ColumnInfo { + @SuppressWarnings("rawtypes") + private ArrayList data; + private int type; + private int bytes; + private boolean typeIsSet; + + public ColumnInfo() { + this.typeIsSet = false; + } + + public void setType(int type) throws SQLException { + if (this.isTypeSet()) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type has been set"); + } + + this.typeIsSet = true; + this.type = type; + } + + public boolean isTypeSet() { + return this.typeIsSet; + } + }; + + private static class TableTagInfo { + private boolean isNull; + private Object value; + private int type; + public TableTagInfo(Object value, int type) { + this.value = value; + this.type = type; + } + + public static TableTagInfo createNullTag(int type) { + TableTagInfo info = new TableTagInfo(null, type); + info.isNull = true; + return info; + } + }; + + public void setTableName(String name) { + this.tableName = name; + } + + private void ensureTagCapacity(int index) { + if (this.tableTags.size() < index + 1) { + int delta = index + 1 - this.tableTags.size(); + this.tableTags.addAll(Collections.nCopies(delta, null)); + } + } + + public void setTagNull(int index, int type) { + ensureTagCapacity(index); + this.tableTags.set(index, TableTagInfo.createNullTag(type)); + } + + public void setTagBoolean(int index, boolean value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL)); + this.tagValueLength += Byte.BYTES; + } + + public void setTagInt(int index, int value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT)); + this.tagValueLength += Integer.BYTES; + } + + public void setTagByte(int index, byte value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT)); + this.tagValueLength += Byte.BYTES; + } + + public void setTagShort(int index, short value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT)); + this.tagValueLength += Short.BYTES; + } + + public void setTagLong(int index, long value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT)); + this.tagValueLength += Long.BYTES; + } + + public void setTagTimestamp(int index, long value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP)); + this.tagValueLength += Long.BYTES; + } + + public void setTagFloat(int index, float value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT)); + this.tagValueLength += Float.BYTES; + } + + public void setTagDouble(int index, double value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE)); + this.tagValueLength += Double.BYTES; + } + + public void setTagString(int index, String value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY)); + this.tagValueLength += value.getBytes().length; + } + + public void setTagNString(int index, String value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR)); + + String charset = TaosGlobalConfig.getCharset(); + try { + this.tagValueLength += value.getBytes(charset).length; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + + public void setValueImpl(int columnIndex, ArrayList list, int type, int bytes) throws SQLException { + if (this.colData.size() == 0) { + this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null)); + + } + ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex); + if (col == null) { + ColumnInfo p = new ColumnInfo(); + p.setType(type); + p.bytes = bytes; + p.data = (ArrayList) list.clone(); + this.colData.set(columnIndex, p); + } else { + if (col.type != type) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type mismatch"); + } + col.data.addAll(list); + } + } + + public void setInt(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES); + } + + public void setFloat(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES); + } + + public void setTimestamp(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES); + } + + public void setLong(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES); + } + + public void setDouble(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES); + } + + public void setBoolean(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES); + } + + public void setByte(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES); + } + + public void setShort(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES); + } + + public void setString(int columnIndex, ArrayList list, int size) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY, size); + } + + // note: expand the required space for each NChar character + public void setNString(int columnIndex, ArrayList list, int size) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR, size * Integer.BYTES); + } + + public void columnDataAddBatch() throws SQLException { + // pass the data block to native code + if (rawSql == null) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "sql statement not set yet"); + } + + // table name is not set yet, abort + if (this.tableName == null) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "table name not set yet"); + } + + int numOfCols = this.colData.size(); + if (numOfCols == 0) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); + } + + TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); + this.nativeStmtHandle = connector.prepareStmt(rawSql); + + if (this.tableTags == null) { + connector.setBindTableName(this.nativeStmtHandle, this.tableName); + } else { + int num = this.tableTags.size(); + ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength); + tagDataList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer typeList = ByteBuffer.allocate(num); + typeList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES); + lengthList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES); + isNullList.order(ByteOrder.LITTLE_ENDIAN); + + for (int i = 0; i < num; ++i) { + TableTagInfo tag = this.tableTags.get(i); + if (tag.isNull) { + typeList.put((byte) tag.type); + isNullList.putInt(1); + lengthList.putLong(0); + continue; + } + + switch (tag.type) { + case TSDBConstants.TSDB_DATA_TYPE_INT: { + Integer val = (Integer) tag.value; + tagDataList.putInt(val); + lengthList.putLong(Integer.BYTES); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { + Byte val = (Byte) tag.value; + tagDataList.put(val); + lengthList.putLong(Byte.BYTES); + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_BOOL: { + Boolean val = (Boolean) tag.value; + tagDataList.put((byte) (val ? 1 : 0)); + lengthList.putLong(Byte.BYTES); + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { + Short val = (Short) tag.value; + tagDataList.putShort(val); + lengthList.putLong(Short.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { + Long val = (Long) tag.value; + tagDataList.putLong(val == null ? 0 : val); + lengthList.putLong(Long.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { + Float val = (Float) tag.value; + tagDataList.putFloat(val == null ? 0 : val); + lengthList.putLong(Float.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + Double val = (Double) tag.value; + tagDataList.putDouble(val == null ? 0 : val); + lengthList.putLong(Double.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + String charset = TaosGlobalConfig.getCharset(); + String val = (String) tag.value; + + byte[] b = null; + try { + if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) { + b = val.getBytes(); + } else { + b = val.getBytes(charset); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + tagDataList.put(b); + lengthList.putLong(b.length); + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: + case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: + case TSDBConstants.TSDB_DATA_TYPE_UINT: + case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types"); + } + } + + typeList.put((byte) tag.type); + isNullList.putInt(tag.isNull? 1 : 0); + } + + connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList, + typeList, lengthList, isNullList); + } + + ColumnInfo colInfo = (ColumnInfo) this.colData.get(0); + if (colInfo == null) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); + } + + int rows = colInfo.data.size(); + for (int i = 0; i < numOfCols; ++i) { + ColumnInfo col1 = this.colData.get(i); + if (col1 == null || !col1.isTypeSet()) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); + } + + if (rows != col1.data.size()) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "the rows in column data not identical"); + } + + ByteBuffer colDataList = ByteBuffer.allocate(rows * col1.bytes); + colDataList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer lengthList = ByteBuffer.allocate(rows * Integer.BYTES); + lengthList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer isNullList = ByteBuffer.allocate(rows * Byte.BYTES); + isNullList.order(ByteOrder.LITTLE_ENDIAN); + + switch (col1.type) { + case TSDBConstants.TSDB_DATA_TYPE_INT: { + for (int j = 0; j < rows; ++j) { + Integer val = (Integer) col1.data.get(j); + colDataList.putInt(val == null? Integer.MIN_VALUE:val); + isNullList.put((byte) (val == null? 1:0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { + for (int j = 0; j < rows; ++j) { + Byte val = (Byte) col1.data.get(j); + colDataList.put(val == null? 0:val); + isNullList.put((byte) (val == null? 1:0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_BOOL: { + for (int j = 0; j < rows; ++j) { + Boolean val = (Boolean) col1.data.get(j); + if (val == null) { + colDataList.put((byte) 0); + } else { + colDataList.put((byte) (val? 1:0)); + } + + isNullList.put((byte) (val == null? 1:0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { + for (int j = 0; j < rows; ++j) { + Short val = (Short) col1.data.get(j); + colDataList.putShort(val == null? 0:val); + isNullList.put((byte) (val == null? 1:0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { + for (int j = 0; j < rows; ++j) { + Long val = (Long) col1.data.get(j); + colDataList.putLong(val == null? 0:val); + isNullList.put((byte) (val == null? 1:0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { + for (int j = 0; j < rows; ++j) { + Float val = (Float) col1.data.get(j); + colDataList.putFloat(val == null? 0:val); + isNullList.put((byte) (val == null? 1:0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + for (int j = 0; j < rows; ++j) { + Double val = (Double) col1.data.get(j); + colDataList.putDouble(val == null? 0:val); + isNullList.put((byte) (val == null? 1:0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + String charset = TaosGlobalConfig.getCharset(); + for (int j = 0; j < rows; ++j) { + String val = (String) col1.data.get(j); + + colDataList.position(j * col1.bytes); // seek to the correct position + if (val != null) { + byte[] b = null; + try { + if (col1.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) { + b = val.getBytes(); + } else { + b = val.getBytes(charset); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + if (val.length() > col1.bytes) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "string data too long"); + } + + colDataList.put(b); + lengthList.putInt(b.length); + isNullList.put((byte) 0); + } else { + lengthList.putInt(0); + isNullList.put((byte) 1); + } + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: + case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: + case TSDBConstants.TSDB_DATA_TYPE_UINT: + case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types"); + } + }; + + connector.bindColumnDataArray(this.nativeStmtHandle, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i); + } + } + + public void columnDataExecuteBatch() throws SQLException { + TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); + connector.executeBatch(this.nativeStmtHandle); + this.columnDataClearBatch(); + } + + public void columnDataClearBatch() { + int size = this.colData.size(); + this.colData.clear(); + + this.colData.addAll(Collections.nCopies(size, null)); + this.tableName = null; // clear the table name + } + + public void columnDataCloseBatch() throws SQLException { + TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); + connector.closeBatch(this.nativeStmtHandle); + + this.nativeStmtHandle = 0L; + this.tableName = null; + } } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java index 2576a25f0d40e15efbb958706f672a40fbd2ee2e..aba29d602b8900d3bedee49ee94e7d226b3bd1f0 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java @@ -109,6 +109,8 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { public void close() throws SQLException { if (isClosed) return; + if (this.statement == null) + return; if (this.jniConnector != null) { int code = this.jniConnector.freeResultSet(this.resultSetPointer); if (code == TSDBConstants.JNI_CONNECTION_NULL) { @@ -461,12 +463,13 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { } public boolean isClosed() throws SQLException { - if (isClosed) - return true; - if (jniConnector != null) { - isClosed = jniConnector.isResultsetClosed(); - } return isClosed; +// if (isClosed) +// return true; +// if (jniConnector != null) { +// isClosed = jniConnector.isResultsetClosed(); +// } +// return isClosed; } public String getNString(int columnIndex) throws SQLException { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java index ce5290de6616dfcc367434cc2e24899e992ddd63..7b3be5d26397eae704d98f1e1802af14abaad4fc 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java @@ -29,6 +29,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.taosdata.jdbc.utils.NullType; + public class TSDBResultSetBlockData { private int numOfRows = 0; private int rowIndex = 0; @@ -164,59 +166,7 @@ public class TSDBResultSetBlockData { } } - private static class NullType { - private static final byte NULL_BOOL_VAL = 0x2; - private static final String NULL_STR = "null"; - - public String toString() { - return NullType.NULL_STR; - } - - public static boolean isBooleanNull(byte val) { - return val == NullType.NULL_BOOL_VAL; - } - - private static boolean isTinyIntNull(byte val) { - return val == Byte.MIN_VALUE; - } - - private static boolean isSmallIntNull(short val) { - return val == Short.MIN_VALUE; - } - - private static boolean isIntNull(int val) { - return val == Integer.MIN_VALUE; - } - - private static boolean isBigIntNull(long val) { - return val == Long.MIN_VALUE; - } - - private static boolean isFloatNull(float val) { - return Float.isNaN(val); - } - - private static boolean isDoubleNull(double val) { - return Double.isNaN(val); - } - - private static boolean isBinaryNull(byte[] val, int length) { - if (length != Byte.BYTES) { - return false; - } - - return val[0] == 0xFF; - } - - private static boolean isNcharNull(byte[] val, int length) { - if (length != Integer.BYTES) { - return false; - } - - return (val[0] & val[1] & val[2] & val[3]) == 0xFF; - } - - } + /** * The original type may not be a string type, but will be converted to by @@ -488,8 +438,8 @@ public class TSDBResultSetBlockData { } try { - String ss = TaosGlobalConfig.getCharset(); - return new String(dest, ss); + String charset = TaosGlobalConfig.getCharset(); + return new String(dest, charset); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java index 34470fbc4e5c06caa117737923612478d7039a90..618e896a6ddfe43d63f631b663a356f485575b06 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java @@ -84,7 +84,8 @@ public class TSDBResultSetRowData { data.set(col, value); } - public int getInt(int col, int srcType) throws SQLException { + @SuppressWarnings("deprecation") + public int getInt(int col, int srcType) throws SQLException { Object obj = data.get(col); switch (srcType) { @@ -128,7 +129,7 @@ public class TSDBResultSetRowData { long value = (long) obj; if (value < 0) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); - return new Long(value).intValue(); + return Long.valueOf(value).intValue(); } } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java index fb20a621b0f11413e13e4234be357f6456a2a4fa..d8ba67576d069a6aec0a5bb17e9549e41b8cf31e 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java @@ -19,8 +19,6 @@ import java.sql.ResultSet; import java.sql.SQLException; public class TSDBStatement extends AbstractStatement { - - private TSDBJNIConnector connector; /** * Status of current statement */ @@ -29,29 +27,26 @@ public class TSDBStatement extends AbstractStatement { private TSDBConnection connection; private TSDBResultSet resultSet; - public void setConnection(TSDBConnection connection) { - this.connection = connection; - } - - TSDBStatement(TSDBConnection connection, TSDBJNIConnector connector) { + TSDBStatement(TSDBConnection connection) { this.connection = connection; - this.connector = connector; } public ResultSet executeQuery(String sql) throws SQLException { // check if closed - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); + } + //TODO: 如果在executeQuery方法中执行insert语句,那么先执行了SQL,再通过pSql来检查是否为一个insert语句,但这个insert SQL已经执行成功了 // execute query - long pSql = this.connector.executeQuery(sql); + long pSql = this.connection.getConnector().executeQuery(sql); // if pSql is create/insert/update/delete/alter SQL - if (this.connector.isUpdateQuery(pSql)) { - this.connector.freeResultSet(pSql); + if (this.connection.getConnector().isUpdateQuery(pSql)) { + this.connection.getConnector().freeResultSet(pSql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); } - TSDBResultSet res = new TSDBResultSet(this, this.connector, pSql); + TSDBResultSet res = new TSDBResultSet(this, this.connection.getConnector(), pSql); res.setBatchFetch(this.connection.getBatchFetch()); return res; } @@ -60,14 +55,14 @@ public class TSDBStatement extends AbstractStatement { if (isClosed()) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - long pSql = this.connector.executeQuery(sql); + long pSql = this.connection.getConnector().executeQuery(sql); // if pSql is create/insert/update/delete/alter SQL - if (!this.connector.isUpdateQuery(pSql)) { - this.connector.freeResultSet(pSql); + if (!this.connection.getConnector().isUpdateQuery(pSql)) { + this.connection.getConnector().freeResultSet(pSql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE); } - int affectedRows = this.connector.getAffectedRows(pSql); - this.connector.freeResultSet(pSql); + int affectedRows = this.connection.getConnector().getAffectedRows(pSql); + this.connection.getConnector().freeResultSet(pSql); return affectedRows; } @@ -81,30 +76,29 @@ public class TSDBStatement extends AbstractStatement { public boolean execute(String sql) throws SQLException { // check if closed - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); + } + // execute query - long pSql = this.connector.executeQuery(sql); + long pSql = this.connection.getConnector().executeQuery(sql); // if pSql is create/insert/update/delete/alter SQL - if (this.connector.isUpdateQuery(pSql)) { - this.affectedRows = this.connector.getAffectedRows(pSql); - this.connector.freeResultSet(pSql); + if (this.connection.getConnector().isUpdateQuery(pSql)) { + this.affectedRows = this.connection.getConnector().getAffectedRows(pSql); + this.connection.getConnector().freeResultSet(pSql); return false; } - this.resultSet = new TSDBResultSet(this, this.connector, pSql); + this.resultSet = new TSDBResultSet(this, this.connection.getConnector(), pSql); this.resultSet.setBatchFetch(this.connection.getBatchFetch()); return true; } public ResultSet getResultSet() throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); -// long resultSetPointer = connector.getResultSet(); -// TSDBResultSet resSet = null; -// if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) { -// resSet = new TSDBResultSet(connector, resultSetPointer); -// } + } + return this.resultSet; } @@ -115,12 +109,20 @@ public class TSDBStatement extends AbstractStatement { } public Connection getConnection() throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - if (this.connector == null) + } + + if (this.connection.getConnector() == null) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); + } + return this.connection; } + + public void setConnection(TSDBConnection connection) { + this.connection = connection; + } public boolean isClosed() throws SQLException { return isClosed; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java index 6efe13561d9509ee00d453e731bbc1ae4e3f0a75..a94cfa6e07c62ee9b163823aaad03bcc402bbffc 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java @@ -17,7 +17,7 @@ public class RestfulDriver extends AbstractDriver { static { try { - java.sql.DriverManager.registerDriver(new RestfulDriver()); + DriverManager.registerDriver(new RestfulDriver()); } catch (SQLException e) { throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_URL_NOT_SET, e); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java index f846a1162e4a1e6a84bc7b748718dcc852657de9..f58e3f8cd2406e6372900c2f7b2547a450fb7fe9 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java @@ -1,26 +1,15 @@ package com.taosdata.jdbc.rs; -import com.google.common.collect.Range; -import com.google.common.collect.RangeSet; -import com.google.common.collect.TreeRangeSet; import com.taosdata.jdbc.TSDBError; import com.taosdata.jdbc.TSDBErrorNumbers; -import com.taosdata.jdbc.utils.SqlSyntaxValidator; import com.taosdata.jdbc.utils.Utils; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; import java.net.URL; -import java.nio.charset.Charset; import java.sql.*; import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.IntStream; public class RestfulPreparedStatement extends RestfulStatement implements PreparedStatement { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java index db635f5f79f187dab98cb9fdfdc50369ca682fa9..530b433d42bf4b387db0e9973ddcf48e3844f2f3 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java @@ -6,11 +6,13 @@ import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.primitives.Shorts; import com.taosdata.jdbc.*; +import com.taosdata.jdbc.utils.Utils; import java.math.BigDecimal; import java.sql.*; import java.time.Instant; import java.time.ZoneOffset; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Calendar; @@ -18,14 +20,13 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { private volatile boolean isClosed; private int pos = -1; - private final String database; private final Statement statement; // data - private final ArrayList> resultSet; + private final ArrayList> resultSet = new ArrayList<>(); // meta - private ArrayList columnNames; - private ArrayList columns; + private ArrayList columnNames = new ArrayList<>(); + private ArrayList columns = new ArrayList<>(); private RestfulResultSetMetaData metaData; /** @@ -37,10 +38,46 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { this.database = database; this.statement = statement; - // column metadata + // get column metadata JSONArray columnMeta = resultJson.getJSONArray("column_meta"); - columnNames = new ArrayList<>(); - columns = new ArrayList<>(); + // get row data + JSONArray data = resultJson.getJSONArray("data"); + if (data == null || data.isEmpty()) { + columnNames.clear(); + columns.clear(); + this.resultSet.clear(); + return; + } + // get head + JSONArray head = resultJson.getJSONArray("head"); + // get rows + Integer rows = resultJson.getInteger("rows"); + // parse column_meta + if (columnMeta != null) { + parseColumnMeta_new(columnMeta); + } else { + parseColumnMeta_old(head, data, rows); + } + this.metaData = new RestfulResultSetMetaData(this.database, columns, this); + // parse row data + resultSet.clear(); + for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) { + ArrayList row = new ArrayList(); + JSONArray jsonRow = data.getJSONArray(rowIndex); + for (int colIndex = 0; colIndex < this.metaData.getColumnCount(); colIndex++) { + row.add(parseColumnData(jsonRow, colIndex, columns.get(colIndex).taos_type)); + } + resultSet.add(row); + } + } + + /*** + * use this method after TDengine-2.0.18.0 to parse column meta, restful add column_meta in resultSet + * @Param columnMeta + */ + private void parseColumnMeta_new(JSONArray columnMeta) throws SQLException { + columnNames.clear(); + columns.clear(); for (int colIndex = 0; colIndex < columnMeta.size(); colIndex++) { JSONArray col = columnMeta.getJSONArray(colIndex); String col_name = col.getString(0); @@ -50,23 +87,55 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { columnNames.add(col_name); columns.add(new Field(col_name, col_type, col_length, "", taos_type)); } - this.metaData = new RestfulResultSetMetaData(this.database, columns, this); + } - // row data - JSONArray data = resultJson.getJSONArray("data"); - resultSet = new ArrayList<>(); - for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) { - ArrayList row = new ArrayList(); - JSONArray jsonRow = data.getJSONArray(rowIndex); - for (int colIndex = 0; colIndex < jsonRow.size(); colIndex++) { - row.add(parseColumnData(jsonRow, colIndex, columns.get(colIndex).taos_type)); + /** + * use this method before TDengine-2.0.18.0 to parse column meta + */ + private void parseColumnMeta_old(JSONArray head, JSONArray data, int rows) { + columnNames.clear(); + columns.clear(); + for (int colIndex = 0; colIndex < head.size(); colIndex++) { + String col_name = head.getString(colIndex); + columnNames.add(col_name); + + int col_type = Types.NULL; + int col_length = 0; + int taos_type = TSDBConstants.TSDB_DATA_TYPE_NULL; + + JSONArray row0Json = data.getJSONArray(0); + if (colIndex < row0Json.size()) { + Object value = row0Json.get(colIndex); + if (value instanceof Boolean) { + col_type = Types.BOOLEAN; + col_length = 1; + taos_type = TSDBConstants.TSDB_DATA_TYPE_BOOL; + } + if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) { + col_type = Types.BIGINT; + col_length = 8; + taos_type = TSDBConstants.TSDB_DATA_TYPE_BIGINT; + } + if (value instanceof Float || value instanceof Double || value instanceof BigDecimal) { + col_type = Types.DOUBLE; + col_length = 8; + taos_type = TSDBConstants.TSDB_DATA_TYPE_DOUBLE; + } + if (value instanceof String) { + col_type = Types.NCHAR; + col_length = ((String) value).length(); + taos_type = TSDBConstants.TSDB_DATA_TYPE_NCHAR; + } } - resultSet.add(row); + columns.add(new Field(col_name, col_type, col_length, "", taos_type)); } } + private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException { switch (taosType) { + case TSDBConstants.TSDB_DATA_TYPE_NULL: + return null; case TSDBConstants.TSDB_DATA_TYPE_BOOL: return row.getBoolean(colIndex); case TSDBConstants.TSDB_DATA_TYPE_TINYINT: @@ -290,8 +359,10 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return 0; } wasNull = false; - if (value instanceof Float || value instanceof Double) + if (value instanceof Float) return (float) value; + if (value instanceof Double) + return new Float((Double) value); return Float.parseFloat(value.toString()); } @@ -329,6 +400,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return Shorts.toByteArray((short) value); if (value instanceof Byte) return new byte[]{(byte) value}; + if (value instanceof Timestamp) { + return Utils.formatTimestamp((Timestamp) value).getBytes(); + } return value.toString().getBytes(); } @@ -342,7 +416,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return null; if (value instanceof Timestamp) return new Date(((Timestamp) value).getTime()); - return Date.valueOf(value.toString()); + Date date = null; + date = Utils.parseDate(value.toString()); + return date; } @Override @@ -354,7 +430,13 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return null; if (value instanceof Timestamp) return new Time(((Timestamp) value).getTime()); - return Time.valueOf(value.toString()); + Time time = null; + try { + time = Utils.parseTime(value.toString()); + } catch (DateTimeParseException e) { + time = null; + } + return time; } @Override @@ -366,14 +448,20 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return null; if (value instanceof Timestamp) return (Timestamp) value; -// if (value instanceof Long) { -// if (1_0000_0000_0000_0L > (long) value) -// return Timestamp.from(Instant.ofEpochMilli((long) value)); -// long epochSec = (long) value / 1000_000L; -// long nanoAdjustment = (long) ((long) value % 1000_000L * 1000); -// return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); -// } - return Timestamp.valueOf(value.toString()); + if (value instanceof Long) { + if (1_0000_0000_0000_0L > (long) value) + return Timestamp.from(Instant.ofEpochMilli((long) value)); + long epochSec = (long) value / 1000_000L; + long nanoAdjustment = (long) value % 1000_000L * 1000; + return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); + } + Timestamp ret; + try { + ret = Utils.parseTimestamp(value.toString()); + } catch (Exception e) { + ret = null; + } + return ret; } @Override @@ -415,7 +503,13 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return new BigDecimal(Double.valueOf(value.toString())); if (value instanceof Timestamp) return new BigDecimal(((Timestamp) value).getTime()); - return new BigDecimal(value.toString()); + BigDecimal ret; + try { + ret = new BigDecimal(value.toString()); + } catch (Exception e) { + ret = null; + } + return ret; } @Override diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java new file mode 100755 index 0000000000000000000000000000000000000000..0e05aeeee7ae0eeb7728910cb5e77a5084d0aa2f --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java @@ -0,0 +1,91 @@ +package com.taosdata.jdbc.utils; + +public class NullType { + private static final byte NULL_BOOL_VAL = 0x2; + private static final String NULL_STR = "null"; + + public String toString() { + return NullType.NULL_STR; + } + + public static boolean isBooleanNull(byte val) { + return val == NullType.NULL_BOOL_VAL; + } + + public static boolean isTinyIntNull(byte val) { + return val == Byte.MIN_VALUE; + } + + public static boolean isSmallIntNull(short val) { + return val == Short.MIN_VALUE; + } + + public static boolean isIntNull(int val) { + return val == Integer.MIN_VALUE; + } + + public static boolean isBigIntNull(long val) { + return val == Long.MIN_VALUE; + } + + public static boolean isFloatNull(float val) { + return Float.isNaN(val); + } + + public static boolean isDoubleNull(double val) { + return Double.isNaN(val); + } + + public static boolean isBinaryNull(byte[] val, int length) { + if (length != Byte.BYTES) { + return false; + } + + return val[0] == 0xFF; + } + + public static boolean isNcharNull(byte[] val, int length) { + if (length != Integer.BYTES) { + return false; + } + + return (val[0] & val[1] & val[2] & val[3]) == 0xFF; + } + + public static byte getBooleanNull() { + return NullType.NULL_BOOL_VAL; + } + + public static byte getTinyintNull() { + return Byte.MIN_VALUE; + } + + public static int getIntNull() { + return Integer.MIN_VALUE; + } + + public static short getSmallIntNull() { + return Short.MIN_VALUE; + } + + public static long getBigIntNull() { + return Long.MIN_VALUE; + } + + public static int getFloatNull() { + return 0x7FF00000; + } + + public static long getDoubleNull() { + return 0x7FFFFF0000000000L; + } + + public static byte getBinaryNull() { + return (byte) 0xFF; + } + + public static byte[] getNcharNull() { + return new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; + } + +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/UtcTimestampUtil.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/UtcTimestampUtil.java deleted file mode 100644 index 04a11a2beb00832a20d9d2d887a8ce5a68e5cf54..0000000000000000000000000000000000000000 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/UtcTimestampUtil.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.taosdata.jdbc.utils; - -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeFormatterBuilder; - -public class UtcTimestampUtil { - public static final DateTimeFormatter formatter = new DateTimeFormatterBuilder() - .appendPattern("yyyy-MM-ddTHH:mm:ss.SSS+") -// .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true) - .toFormatter(); - -} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java index a7cb71ad38c649535acb5f5e7c3b97c2d63c809d..eeb936a1d0843c56e0de63a6c4b113fb644b778f 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java @@ -5,7 +5,15 @@ import com.google.common.collect.RangeSet; import com.google.common.collect.TreeRangeSet; import java.nio.charset.Charset; +import java.sql.Date; +import java.sql.Time; import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.DateTimeParseException; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; @@ -17,6 +25,41 @@ public class Utils { private static Pattern ptn = Pattern.compile(".*?'"); + private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder() + .appendPattern("yyyy-MM-dd HH:mm:ss.SSS").toFormatter(); + private static final DateTimeFormatter formatter2 = new DateTimeFormatterBuilder() + .appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSS").toFormatter(); + + public static Time parseTime(String timestampStr) throws DateTimeParseException { + LocalTime time; + try { + time = LocalTime.parse(timestampStr, formatter); + } catch (DateTimeParseException e) { + time = LocalTime.parse(timestampStr, formatter2); + } + return Time.valueOf(time); + } + + public static Date parseDate(String timestampStr) throws DateTimeParseException { + LocalDate date; + try { + date = LocalDate.parse(timestampStr, formatter); + } catch (DateTimeParseException e) { + date = LocalDate.parse(timestampStr, formatter2); + } + return Date.valueOf(date); + } + + public static Timestamp parseTimestamp(String timeStampStr) { + LocalDateTime dateTime; + try { + dateTime = LocalDateTime.parse(timeStampStr, formatter); + } catch (DateTimeParseException e) { + dateTime = LocalDateTime.parse(timeStampStr, formatter2); + } + return Timestamp.valueOf(dateTime); + } + public static String escapeSingleQuota(String origin) { Matcher m = ptn.matcher(origin); StringBuffer sb = new StringBuffer(); @@ -67,7 +110,7 @@ public class Utils { findPlaceholderPosition(preparedSql, placeholderPositions); findClauseRangeSet(preparedSql, clause, clauseRangeSet); - return transformSql(preparedSql, parameters, placeholderPositions, clauseRangeSet); + return transformSql(rawSql, parameters, placeholderPositions, clauseRangeSet); } private static void findClauseRangeSet(String preparedSql, String[] regexArr, RangeSet clauseRangeSet) { @@ -95,14 +138,15 @@ public class Utils { /*** * - * @param preparedSql + * @param rawSql * @param paramArr * @param placeholderPosition * @param clauseRangeSet * @return */ - private static String transformSql(String preparedSql, Object[] paramArr, Map placeholderPosition, RangeSet clauseRangeSet) { - String[] sqlArr = preparedSql.split("\\?"); + private static String transformSql(String rawSql, Object[] paramArr, Map placeholderPosition, RangeSet clauseRangeSet) { + String[] sqlArr = rawSql.split("\\?"); + return IntStream.range(0, sqlArr.length).mapToObj(index -> { if (index == paramArr.length) return sqlArr[index]; @@ -132,4 +176,13 @@ public class Utils { }).collect(Collectors.joining()); } + + public static String formatTimestamp(Timestamp timestamp) { + int nanos = timestamp.getNanos(); + if (nanos % 1000000l != 0) + return timestamp.toLocalDateTime().format(formatter2); + return timestamp.toLocalDateTime().format(formatter); + } + + } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SubscribeTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SubscribeTest.java index 11c3de305280a48b690ccdacd2df9751f4b718a9..24c73fdd5c14af41039eb12a7713216166312a09 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SubscribeTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SubscribeTest.java @@ -1,6 +1,7 @@ package com.taosdata.jdbc; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -12,67 +13,74 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; public class SubscribeTest { + Connection connection; Statement statement; String dbName = "test"; String tName = "t0"; String host = "127.0.0.1"; String topic = "test"; + private long ts; - @Before - public void createDatabase() { + @Test + public void subscribe() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); - Properties properties = new Properties(); - properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); - properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); - properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); - connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties); + String rawSql = "select * from " + dbName + "." + tName + ";"; + TSDBConnection conn = connection.unwrap(TSDBConnection.class); + TSDBSubscribe subscribe = conn.subscribe(topic, rawSql, false); + + for (int j = 0; j < 10; j++) { + TimeUnit.SECONDS.sleep(1); + TSDBResultSet resSet = subscribe.consume(); - statement = connection.createStatement(); - statement.execute("drop database if exists " + dbName); - statement.execute("create database if not exists " + dbName); - statement.execute("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); - long ts = System.currentTimeMillis(); - for (int i = 0; i < 2; i++) { - ts += i; - String sql = "insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")"; - statement.executeUpdate(sql); + int rowCnt = 0; + while (resSet.next()) { + if (rowCnt == 0) { + long cur_ts = resSet.getTimestamp(1).getTime(); + int k = resSet.getInt(2); + int v = resSet.getInt(3); + Assert.assertEquals(ts, cur_ts); + Assert.assertEquals(100, k); + Assert.assertEquals(1, v); + } + if (rowCnt == 1) { + long cur_ts = resSet.getTimestamp(1).getTime(); + int k = resSet.getInt(2); + int v = resSet.getInt(3); + Assert.assertEquals(ts + 1, cur_ts); + Assert.assertEquals(101, k); + Assert.assertEquals(2, v); + + } + rowCnt++; + } + if (j == 0) + Assert.assertEquals(2, rowCnt); + resSet.close(); } + subscribe.close(true); + - } catch (ClassNotFoundException | SQLException e) { - return; + } catch (SQLException | InterruptedException throwables) { + throwables.printStackTrace(); } } - @Test - public void subscribe() { - try { - String rawSql = "select * from " + dbName + "." + tName + ";"; - System.out.println(rawSql); -// TSDBSubscribe subscribe = ((TSDBConnection) connection).subscribe(topic, rawSql, false); + @Before + public void createDatabase() throws SQLException { + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties); -// int a = 0; -// while (true) { -// TimeUnit.MILLISECONDS.sleep(1000); -// TSDBResultSet resSet = subscribe.consume(); -// while (resSet.next()) { -// for (int i = 1; i <= resSet.getMetaData().getColumnCount(); i++) { -// System.out.printf(i + ": " + resSet.getString(i) + "\t"); -// } -// System.out.println("\n======" + a + "=========="); -// } -// a++; -// if (a >= 2) { -// break; -// } -// resSet.close(); -// } -// -// subscribe.close(true); - } catch (Exception e) { - e.printStackTrace(); - } + statement = connection.createStatement(); + statement.execute("drop database if exists " + dbName); + statement.execute("create database if not exists " + dbName); + statement.execute("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); + ts = System.currentTimeMillis(); + statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", 100, 1)"); + statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + (ts + 1) + ", 101, 2)"); } @After @@ -86,6 +94,5 @@ public class SubscribeTest { } catch (SQLException e) { e.printStackTrace(); } - } } \ No newline at end of file diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java index dc6fd4c5016bd67eb8e5dcf0e9d497f4f2f97612..52858e7f88c9375ea6ff0282fbe0519b9953a121 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java @@ -8,6 +8,8 @@ import org.junit.Test; import java.io.IOException; import java.io.Serializable; import java.sql.*; +import java.util.ArrayList; +import java.util.Random; public class TSDBPreparedStatementTest { private static final String host = "127.0.0.1"; @@ -97,6 +99,177 @@ public class TSDBPreparedStatementTest { Assert.assertEquals(1, result); } + @Test + public void executeTest() throws SQLException { + Statement stmt = conn.createStatement(); + + int numOfRows = 1000; + + for (int loop = 0; loop < 10; loop++){ + stmt.execute("drop table if exists weather_test"); + stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); + + TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? values(?, ?, ?, ?, ?, ?, ?, ?)"); + Random r = new Random(); + s.setTableName("weather_test"); + + ArrayList ts = new ArrayList(); + for(int i = 0; i < numOfRows; i++) { + ts.add(System.currentTimeMillis() + i); + } + s.setTimestamp(0, ts); + + int random = 10 + r.nextInt(5); + ArrayList s2 = new ArrayList(); + for(int i = 0; i < numOfRows; i++) { + if(i % random == 0) { + s2.add(null); + }else{ + s2.add("分支" + i % 4); + } + } + s.setNString(1, s2, 4); + + random = 10 + r.nextInt(5); + ArrayList s3 = new ArrayList(); + for(int i = 0; i < numOfRows; i++) { + if(i % random == 0) { + s3.add(null); + }else{ + s3.add(r.nextFloat()); + } + } + s.setFloat(2, s3); + + random = 10 + r.nextInt(5); + ArrayList s4 = new ArrayList(); + for(int i = 0; i < numOfRows; i++) { + if(i % random == 0) { + s4.add(null); + }else{ + s4.add(r.nextDouble()); + } + } + s.setDouble(3, s4); + + random = 10 + r.nextInt(5); + ArrayList ts2 = new ArrayList(); + for(int i = 0; i < numOfRows; i++) { + if(i % random == 0) { + ts2.add(null); + }else{ + ts2.add(System.currentTimeMillis() + i); + } + } + s.setTimestamp(4, ts2); + + random = 10 + r.nextInt(5); + ArrayList vals = new ArrayList<>(); + for(int i = 0; i < numOfRows; i++) { + if(i % random == 0) { + vals.add(null); + }else{ + vals.add(r.nextInt()); + } + } + s.setInt(5, vals); + + random = 10 + r.nextInt(5); + ArrayList sb = new ArrayList<>(); + for(int i = 0; i < numOfRows; i++) { + if(i % random == 0) { + sb.add(null); + }else{ + sb.add(i % 2 == 0 ? true : false); + } + } + s.setBoolean(6, sb); + + random = 10 + r.nextInt(5); + ArrayList s5 = new ArrayList(); + for(int i = 0; i < numOfRows; i++) { + if(i % random == 0) { + s5.add(null); + }else{ + s5.add("test" + i % 10); + } + } + s.setString(7, s5, 10); + + s.columnDataAddBatch(); + s.columnDataExecuteBatch(); + s.columnDataCloseBatch(); + + String sql = "select * from weather_test"; + PreparedStatement statement = conn.prepareStatement(sql); + ResultSet rs = statement.executeQuery(); + int rows = 0; + while(rs.next()) { + rows++; + } + Assert.assertEquals(numOfRows, rows); + } + } + + @Test + public void bindDataSelectColumnTest() throws SQLException { + Statement stmt = conn.createStatement(); + + int numOfRows = 1000; + + for (int loop = 0; loop < 10; loop++){ + stmt.execute("drop table if exists weather_test"); + stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); + + TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? (ts, f1, f7) values(?, ?, ?)"); + Random r = new Random(); + s.setTableName("weather_test"); + + ArrayList ts = new ArrayList(); + for(int i = 0; i < numOfRows; i++) { + ts.add(System.currentTimeMillis() + i); + } + s.setTimestamp(0, ts); + + int random = 10 + r.nextInt(5); + ArrayList s2 = new ArrayList(); + for(int i = 0; i < numOfRows; i++) { + if(i % random == 0) { + s2.add(null); + }else{ + s2.add("分支" + i % 4); + } + } + s.setNString(1, s2, 4); + + random = 10 + r.nextInt(5); + ArrayList s5 = new ArrayList(); + for(int i = 0; i < numOfRows; i++) { + if(i % random == 0) { + s5.add(null); + }else{ + s5.add("test" + i % 10); + } + } + s.setString(2, s5, 10); + + s.columnDataAddBatch(); + s.columnDataExecuteBatch(); + s.columnDataCloseBatch(); + + String sql = "select * from weather_test"; + PreparedStatement statement = conn.prepareStatement(sql); + ResultSet rs = statement.executeQuery(); + int rows = 0; + while(rs.next()) { + rows++; + } + Assert.assertEquals(numOfRows, rows); + } + } + + + @Test public void setBoolean() throws SQLException { pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java index c5c6f7bca5226ca87441e0d080b269231f0167c0..f304fd687406ccf919ea1b1e457cd218239e765f 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java @@ -3,7 +3,6 @@ package com.taosdata.jdbc; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.primitives.Shorts; -import com.taosdata.jdbc.rs.RestfulResultSet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -177,7 +176,8 @@ public class TSDBResultSetTest { rs.getAsciiStream("f1"); } - @Test(expected = SQLFeatureNotSupportedException.class) + @SuppressWarnings("deprecation") + @Test(expected = SQLFeatureNotSupportedException.class) public void getUnicodeStream() throws SQLException { rs.getUnicodeStream("f1"); } @@ -326,7 +326,7 @@ public class TSDBResultSetTest { @Test(expected = SQLFeatureNotSupportedException.class) public void getRow() throws SQLException { - int row = rs.getRow(); + rs.getRow(); } @Test(expected = SQLFeatureNotSupportedException.class) @@ -405,12 +405,12 @@ public class TSDBResultSetTest { @Test(expected = SQLFeatureNotSupportedException.class) public void updateByte() throws SQLException { - rs.updateByte(1, new Byte("0")); + rs.updateByte(1, (byte) 0); } @Test(expected = SQLFeatureNotSupportedException.class) public void updateShort() throws SQLException { - rs.updateShort(1, new Short("0")); + rs.updateShort(1, (short) 0); } @Test(expected = SQLFeatureNotSupportedException.class) diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java index e7d327413612edec118a527a35ed4cb7a7630a94..4b4e83719ff64578e0ca5b34cd4cfe11ea8d98f3 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java @@ -12,7 +12,7 @@ public class InsertSpecialCharacterJniTest { private static String tbname1 = "test"; private static String tbname2 = "weather"; private static String special_character_str_1 = "$asd$$fsfsf$"; - private static String special_character_str_2 = "\\asdfsfsf\\\\"; + private static String special_character_str_2 = "\\\\asdfsfsf\\\\"; private static String special_character_str_3 = "\\\\asdfsfsf\\"; private static String special_character_str_4 = "?asd??fsf?sf?"; private static String special_character_str_5 = "?#sd@$f(('<(s[P)>\"){]}f?s[]{}%vaew|\"fsfs^a&d*jhg)(j))(f@~!?$"; @@ -70,7 +70,7 @@ public class InsertSpecialCharacterJniTest { String f1 = new String(rs.getBytes(2)); //TODO: bug to be fixed // Assert.assertEquals(special_character_str_2, f1); - Assert.assertEquals(special_character_str_2.substring(0, special_character_str_1.length() - 2), f1); + Assert.assertEquals(special_character_str_2.substring(1, special_character_str_1.length() - 1), f1); String f2 = rs.getString(3); Assert.assertNull(f2); } @@ -345,6 +345,32 @@ public class InsertSpecialCharacterJniTest { } } + + @Test + public void testCase12() throws SQLException { + final long now = System.currentTimeMillis(); + // insert + final String sql = "insert into " + tbname1 + "(ts, f1, f2) values(?, 'HelloTDengine', ?) ; "; + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.setTimestamp(1, new Timestamp(now)); + pstmt.setString(2, special_character_str_4); + int ret = pstmt.executeUpdate(); + Assert.assertEquals(1, ret); + } + // query + final String query = "select * from " + tbname1; + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery(query); + rs.next(); + long timestamp = rs.getTimestamp(1).getTime(); + Assert.assertEquals(now, timestamp); + String f1 = new String(rs.getBytes(2)); + Assert.assertEquals("HelloTDengine", f1); + String f2 = rs.getString(3); + Assert.assertEquals(special_character_str_4, f2); + } + } + @Before public void before() throws SQLException { try (Statement stmt = conn.createStatement()) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterRestfulTest.java index 64a0e976846d72631549bd32b2b63558e0466c47..fa6cbd22b5da0869d4a74e90de12c952fecd22c7 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterRestfulTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterRestfulTest.java @@ -7,13 +7,12 @@ import java.sql.*; public class InsertSpecialCharacterRestfulTest { private static final String host = "127.0.0.1"; - // private static final String host = "master"; private static Connection conn; private static String dbName = "spec_char_test"; private static String tbname1 = "test"; private static String tbname2 = "weather"; private static String special_character_str_1 = "$asd$$fsfsf$"; - private static String special_character_str_2 = "\\asdfsfsf\\\\"; + private static String special_character_str_2 = "\\\\asdfsfsf\\\\"; private static String special_character_str_3 = "\\\\asdfsfsf\\"; private static String special_character_str_4 = "?asd??fsf?sf?"; private static String special_character_str_5 = "?#sd@$f(('<(s[P)>\"){]}f?s[]{}%vaew|\"fsfs^a&d*jhg)(j))(f@~!?$"; @@ -49,7 +48,7 @@ public class InsertSpecialCharacterRestfulTest { @Test public void testCase02() throws SQLException { //TODO: - // Expected :\asdfsfsf\\ + // Expected :\asdfsfsf\ // Actual :\asdfsfsf\ final long now = System.currentTimeMillis(); @@ -71,7 +70,7 @@ public class InsertSpecialCharacterRestfulTest { String f1 = new String(rs.getBytes(2)); //TODO: bug to be fixed // Assert.assertEquals(special_character_str_2, f1); - Assert.assertEquals(special_character_str_2.substring(0, special_character_str_1.length() - 2), f1); + Assert.assertEquals(special_character_str_2.substring(1, special_character_str_1.length() - 1), f1); String f2 = rs.getString(3); Assert.assertNull(f2); } @@ -346,6 +345,31 @@ public class InsertSpecialCharacterRestfulTest { } } + @Test + public void testCase12() throws SQLException { + final long now = System.currentTimeMillis(); + // insert + final String sql = "insert into " + tbname1 + "(ts, f1, f2) values(?, 'HelloTDengine', ?) ; "; + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.setTimestamp(1, new Timestamp(now)); + pstmt.setString(2, special_character_str_4); + int ret = pstmt.executeUpdate(); + Assert.assertEquals(1, ret); + } + // query + final String query = "select * from " + tbname1; + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery(query); + rs.next(); + long timestamp = rs.getTimestamp(1).getTime(); + Assert.assertEquals(now, timestamp); + String f1 = new String(rs.getBytes(2)); + Assert.assertEquals("HelloTDengine", f1); + String f2 = rs.getString(3); + Assert.assertEquals(special_character_str_4, f2); + } + } + @Before public void before() throws SQLException { try (Statement stmt = conn.createStatement()) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4144Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4144Test.java new file mode 100644 index 0000000000000000000000000000000000000000..6f29f64111c51600303ad73d517faaa7c59cfe7c --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4144Test.java @@ -0,0 +1,105 @@ +package com.taosdata.jdbc.cases; + +import com.taosdata.jdbc.TSDBConnection; +import com.taosdata.jdbc.TSDBDriver; +import com.taosdata.jdbc.TSDBResultSet; +import com.taosdata.jdbc.TSDBSubscribe; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.sql.DriverManager; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +public class TD4144Test { + + private static TSDBConnection connection; + private static final String host = "127.0.0.1"; + + private static final String topic = "topic-meter-current-bg-10"; + private static final String sql = "select * from meters where current > 10"; + private static final String sql2 = "select * from meters where ts >= '2020-08-15 12:20:00.000'"; + + + @Test + public void test() throws SQLException { + TSDBSubscribe subscribe = null; + TSDBResultSet res = null; + boolean hasNext = false; + + try { + subscribe = connection.subscribe(topic, sql, false); + int count = 0; + while (true) { + // 等待1秒,避免频繁调用 consume,给服务端造成压力 + TimeUnit.SECONDS.sleep(1); + if (res == null) { + // 消费数据 + res = subscribe.consume(); + hasNext = res.next(); + } + + if (res == null) { + continue; + } + ResultSetMetaData metaData = res.getMetaData(); + int number = 0; + while (hasNext) { + int columnCount = metaData.getColumnCount(); + for (int i = 1; i <= columnCount; i++) { + System.out.print(metaData.getColumnLabel(i) + ": " + res.getString(i) + "\t"); + } + System.out.println(); + count++; + number++; + hasNext = res.next(); + if (!hasNext) { + res.close(); + res = null; + System.out.println("rows: " + count); + } + if (hasNext == true && number >= 10) { + System.out.println("batch" + number); + break; + } + } + + } + + } catch (SQLException | InterruptedException throwables) { + throwables.printStackTrace(); + } finally { + if (subscribe != null) + subscribe.close(true); + } + } + + @BeforeClass + public static void beforeClass() throws SQLException { + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; + connection = (DriverManager.getConnection(url, properties)).unwrap(TSDBConnection.class); + try (Statement stmt = connection.createStatement()) { + stmt.execute("drop database if exists power"); + stmt.execute("create database if not exists power"); + stmt.execute("use power"); + stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(location binary(64), groupId int)"); + stmt.execute("create table d1001 using meters tags(\"Beijing.Chaoyang\", 2)"); + stmt.execute("create table d1002 using meters tags(\"Beijing.Haidian\", 2)"); + stmt.execute("insert into d1001 values(\"2020-08-15 12:00:00.000\", 12, 220, 1),(\"2020-08-15 12:10:00.000\", 12.3, 220, 2),(\"2020-08-15 12:20:00.000\", 12.2, 220, 1)"); + stmt.execute("insert into d1002 values(\"2020-08-15 12:00:00.000\", 9.9, 220, 1),(\"2020-08-15 12:10:00.000\", 10.3, 220, 1),(\"2020-08-15 12:20:00.000\", 11.2, 220, 1)"); + } + } + + @AfterClass + public static void afterClass() throws SQLException { + if (connection != null) + connection.close(); + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4174Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4174Test.java new file mode 100644 index 0000000000000000000000000000000000000000..2704d4cfa558ebdb6885c320d7ba775b36b99f09 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4174Test.java @@ -0,0 +1,62 @@ +package com.taosdata.jdbc.cases; + +import com.alibaba.fastjson.JSONObject; +import com.taosdata.jdbc.TSDBDriver; +import org.junit.*; + +import java.sql.*; +import java.util.Properties; + +public class TD4174Test { + private Connection conn; + private static final String host = "127.0.0.1"; + + @Test + public void test() { + long ts = System.currentTimeMillis(); + try (PreparedStatement pstmt = conn.prepareStatement("insert into weather values(" + ts + ", ?)")) { + JSONObject value = new JSONObject(); + value.put("name", "John Smith"); + value.put("age", 20); + Assert.assertEquals("{\"name\":\"John Smith\",\"age\":20}",value.toJSONString()); + pstmt.setString(1, value.toJSONString()); + + int ret = pstmt.executeUpdate(); + Assert.assertEquals(1, ret); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + JSONObject value = new JSONObject(); + value.put("name", "John Smith"); + value.put("age", 20); + System.out.println(value.toJSONString()); + } + + @Before + public void before() throws SQLException { + String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + + conn = DriverManager.getConnection(url, properties); + try (Statement stmt = conn.createStatement()) { + stmt.execute("drop database if exists td4174"); + stmt.execute("create database if not exists td4174"); + stmt.execute("use td4174"); + stmt.execute("create table weather(ts timestamp, text binary(64))"); + } + } + + @After + public void after() throws SQLException { + if (conn != null) + conn.close(); + + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java index ed4f979ef33354595bfeb707678e3b9797aba686..5c83b5a9da527a55387a8ad399e78462b6fab63c 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java @@ -13,6 +13,7 @@ import java.util.Properties; public class TwoTypeTimestampPercisionInRestfulTest { private static final String host = "127.0.0.1"; + private static final String ms_timestamp_db = "ms_precision_test"; private static final String us_timestamp_db = "us_precision_test"; private static final long timestamp1 = System.currentTimeMillis(); @@ -94,7 +95,8 @@ public class TwoTypeTimestampPercisionInRestfulTest { try (Statement stmt = conn3.createStatement()) { ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather"); rs.next(); - long ts = rs.getTimestamp(1).getTime(); + Timestamp actual = rs.getTimestamp(1); + long ts = actual == null ? 0 : actual.getTime(); Assert.assertEquals(timestamp1, ts); ts = rs.getLong(1); Assert.assertEquals(timestamp1, ts); @@ -110,7 +112,7 @@ public class TwoTypeTimestampPercisionInRestfulTest { rs.next(); Timestamp timestamp = rs.getTimestamp(1); - long ts = timestamp.getTime(); + long ts = timestamp == null ? 0 : timestamp.getTime(); Assert.assertEquals(timestamp1, ts); int nanos = timestamp.getNanos(); Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberJniTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberJniTest.java index d1816a3e7c84703e76a28e6b0e5db842de9c0ac4..fb23c0e64aa7469443d5476de47af305cfd3c09f 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberJniTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberJniTest.java @@ -9,19 +9,19 @@ import java.util.Properties; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class UnsignedNumberJniTest { + private static final String host = "127.0.0.1"; private static Connection conn; + private static long ts; @Test public void testCase001() { try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery("select * from us_table"); ResultSetMetaData meta = rs.getMetaData(); + assertResultSetMetaData(meta); while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); Assert.assertEquals("127", rs.getString(2)); Assert.assertEquals("32767", rs.getString(3)); Assert.assertEquals("2147483647", rs.getString(4)); @@ -37,13 +37,10 @@ public class UnsignedNumberJniTest { try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery("select * from us_table"); ResultSetMetaData meta = rs.getMetaData(); + assertResultSetMetaData(meta); + while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); Assert.assertEquals(127, rs.getByte(2)); Assert.assertEquals(32767, rs.getShort(3)); Assert.assertEquals(2147483647, rs.getInt(4)); @@ -61,16 +58,14 @@ public class UnsignedNumberJniTest { stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,2147483647, 18446744073709551614)"); ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); ResultSetMetaData meta = rs.getMetaData(); + assertResultSetMetaData(meta); while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); + Assert.assertEquals(now, rs.getTimestamp(1).getTime()); Assert.assertEquals(127, rs.getByte(2)); Assert.assertEquals(32767, rs.getShort(3)); Assert.assertEquals(2147483647, rs.getInt(4)); + Assert.assertEquals("18446744073709551614", rs.getString(5)); + rs.getLong(5); } } } @@ -82,15 +77,15 @@ public class UnsignedNumberJniTest { stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,4294967294, 18446744073709551614)"); ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); ResultSetMetaData meta = rs.getMetaData(); + assertResultSetMetaData(meta); + while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); + Assert.assertEquals(now, rs.getTimestamp(1).getTime()); Assert.assertEquals(127, rs.getByte(2)); Assert.assertEquals(32767, rs.getShort(3)); + Assert.assertEquals("4294967294", rs.getString(4)); + Assert.assertEquals("18446744073709551614", rs.getString(5)); + rs.getInt(4); } } } @@ -102,15 +97,15 @@ public class UnsignedNumberJniTest { stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 65534,4294967294, 18446744073709551614)"); ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); ResultSetMetaData meta = rs.getMetaData(); - while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); + assertResultSetMetaData(meta); + while (rs.next()) { + Assert.assertEquals(now, rs.getTimestamp(1).getTime()); Assert.assertEquals(127, rs.getByte(2)); + Assert.assertEquals("65534", rs.getString(3)); + Assert.assertEquals("4294967294", rs.getString(4)); + Assert.assertEquals("18446744073709551614", rs.getString(5)); + rs.getShort(3); } } } @@ -122,37 +117,27 @@ public class UnsignedNumberJniTest { stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)"); ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); ResultSetMetaData meta = rs.getMetaData(); - while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); - } - } - } + assertResultSetMetaData(meta); - @Test - public void testCase007() throws SQLException { - try (Statement stmt = conn.createStatement()) { - long now = System.currentTimeMillis(); - stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)"); - ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); - ResultSetMetaData meta = rs.getMetaData(); while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); + Assert.assertEquals(now, rs.getTimestamp(1).getTime()); Assert.assertEquals("254", rs.getString(2)); Assert.assertEquals("65534", rs.getString(3)); Assert.assertEquals("4294967294", rs.getString(4)); Assert.assertEquals("18446744073709551614", rs.getString(5)); + rs.getByte(2); } } } + private void assertResultSetMetaData(ResultSetMetaData meta) throws SQLException { + Assert.assertEquals(5, meta.getColumnCount()); + Assert.assertEquals("ts", meta.getColumnLabel(1)); + Assert.assertEquals("f1", meta.getColumnLabel(2)); + Assert.assertEquals("f2", meta.getColumnLabel(3)); + Assert.assertEquals("f3", meta.getColumnLabel(4)); + Assert.assertEquals("f4", meta.getColumnLabel(5)); + } @BeforeClass public static void beforeClass() { @@ -160,20 +145,19 @@ public class UnsignedNumberJniTest { properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + ts = System.currentTimeMillis(); try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; conn = DriverManager.getConnection(url, properties); - Statement stmt = conn.createStatement(); stmt.execute("drop database if exists unsign_jni"); stmt.execute("create database if not exists unsign_jni"); stmt.execute("use unsign_jni"); stmt.execute("create table us_table(ts timestamp, f1 tinyint unsigned, f2 smallint unsigned, f3 int unsigned, f4 bigint unsigned)"); - stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(now, 127, 32767,2147483647, 9223372036854775807)"); + stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + ts + ", 127, 32767,2147483647, 9223372036854775807)"); stmt.close(); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberRestfulTest.java index 4ae2f36fe95a37eba27dd78222f3120f5cbfaf3a..a659a490cb557f3825deb4bb58d32941b47a62ab 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberRestfulTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberRestfulTest.java @@ -13,17 +13,20 @@ public class UnsignedNumberRestfulTest { private static final String host = "127.0.0.1"; private static Connection conn; + private static long ts; @Test public void testCase001() { try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery("select * from us_table"); ResultSetMetaData meta = rs.getMetaData(); + assertResultSetMetaData(meta); while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals("127", rs.getString(2)); + Assert.assertEquals("32767", rs.getString(3)); + Assert.assertEquals("2147483647", rs.getString(4)); + Assert.assertEquals("9223372036854775807", rs.getString(5)); } } catch (SQLException e) { e.printStackTrace(); @@ -35,13 +38,14 @@ public class UnsignedNumberRestfulTest { try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery("select * from us_table"); ResultSetMetaData meta = rs.getMetaData(); + assertResultSetMetaData(meta); + while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(127, rs.getByte(2)); + Assert.assertEquals(32767, rs.getShort(3)); + Assert.assertEquals(2147483647, rs.getInt(4)); + Assert.assertEquals(9223372036854775807l, rs.getLong(5)); } } catch (SQLException e) { e.printStackTrace(); @@ -55,13 +59,14 @@ public class UnsignedNumberRestfulTest { stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,2147483647, 18446744073709551614)"); ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); ResultSetMetaData meta = rs.getMetaData(); + assertResultSetMetaData(meta); while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); + Assert.assertEquals(now, rs.getTimestamp(1).getTime()); + Assert.assertEquals(127, rs.getByte(2)); + Assert.assertEquals(32767, rs.getShort(3)); + Assert.assertEquals(2147483647, rs.getInt(4)); + Assert.assertEquals("18446744073709551614", rs.getString(5)); + rs.getLong(5); } } } @@ -73,13 +78,15 @@ public class UnsignedNumberRestfulTest { stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 32767,4294967294, 18446744073709551614)"); ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); ResultSetMetaData meta = rs.getMetaData(); + assertResultSetMetaData(meta); + while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); + Assert.assertEquals(now, rs.getTimestamp(1).getTime()); + Assert.assertEquals(127, rs.getByte(2)); + Assert.assertEquals(32767, rs.getShort(3)); + Assert.assertEquals("4294967294", rs.getString(4)); + Assert.assertEquals("18446744073709551614", rs.getString(5)); + rs.getInt(4); } } } @@ -91,13 +98,15 @@ public class UnsignedNumberRestfulTest { stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 127, 65534,4294967294, 18446744073709551614)"); ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); ResultSetMetaData meta = rs.getMetaData(); + assertResultSetMetaData(meta); + while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); + Assert.assertEquals(now, rs.getTimestamp(1).getTime()); + Assert.assertEquals(127, rs.getByte(2)); + Assert.assertEquals("65534", rs.getString(3)); + Assert.assertEquals("4294967294", rs.getString(4)); + Assert.assertEquals("18446744073709551614", rs.getString(5)); + rs.getShort(3); } } } @@ -109,57 +118,47 @@ public class UnsignedNumberRestfulTest { stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)"); ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); ResultSetMetaData meta = rs.getMetaData(); - while (rs.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + rs.getTimestamp(1) + "\t"); - System.out.print(meta.getColumnLabel(2) + ": " + rs.getByte(2) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + rs.getShort(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + rs.getInt(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + rs.getLong(5) + "\t"); - System.out.println(); - } - } - } + assertResultSetMetaData(meta); - @Test - public void testCase007() throws SQLException { - try (Statement stmt = conn.createStatement()) { - long now = System.currentTimeMillis(); - stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + now + ", 254, 65534,4294967294, 18446744073709551614)"); - ResultSet rs = stmt.executeQuery("select * from us_table where ts = " + now); - ResultSetMetaData meta = rs.getMetaData(); while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); + Assert.assertEquals(now, rs.getTimestamp(1).getTime()); Assert.assertEquals("254", rs.getString(2)); Assert.assertEquals("65534", rs.getString(3)); Assert.assertEquals("4294967294", rs.getString(4)); Assert.assertEquals("18446744073709551614", rs.getString(5)); + rs.getByte(2); } } } + private void assertResultSetMetaData(ResultSetMetaData meta) throws SQLException { + Assert.assertEquals(5, meta.getColumnCount()); + Assert.assertEquals("ts", meta.getColumnLabel(1)); + Assert.assertEquals("f1", meta.getColumnLabel(2)); + Assert.assertEquals("f2", meta.getColumnLabel(3)); + Assert.assertEquals("f3", meta.getColumnLabel(4)); + Assert.assertEquals("f4", meta.getColumnLabel(5)); + } + @BeforeClass public static void beforeClass() { Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + ts = System.currentTimeMillis(); try { - Class.forName("com.taosdata.jdbc.rs.RestfulDriver"); final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; conn = DriverManager.getConnection(url, properties); - Statement stmt = conn.createStatement(); stmt.execute("drop database if exists unsign_restful"); stmt.execute("create database if not exists unsign_restful"); stmt.execute("use unsign_restful"); stmt.execute("create table us_table(ts timestamp, f1 tinyint unsigned, f2 smallint unsigned, f3 int unsigned, f4 bigint unsigned)"); - stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(now, 127, 32767,2147483647, 9223372036854775807)"); + stmt.executeUpdate("insert into us_table(ts,f1,f2,f3,f4) values(" + ts + ", 127, 32767,2147483647, 9223372036854775807)"); stmt.close(); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulPreparedStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulPreparedStatementTest.java index e4dd6384f9cc2f22d6c9cbcd04ae9b0f67dc477b..ee457ff4127ccf3fe88cf277d581a3dcb3475df9 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulPreparedStatementTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulPreparedStatementTest.java @@ -10,7 +10,6 @@ import java.sql.*; public class RestfulPreparedStatementTest { private static final String host = "127.0.0.1"; - // private static final String host = "master"; private static Connection conn; private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; private static PreparedStatement pstmt_insert; @@ -371,7 +370,6 @@ public class RestfulPreparedStatementTest { pstmt_insert.setSQLXML(1, null); } - @BeforeClass public static void beforeClass() { try { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java index 9bfe9a04ffb33f1ecf9466b2aba85121da85e846..81e762c5ca9646875f21acd89f55bd939440cfd4 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java @@ -18,7 +18,6 @@ import java.text.SimpleDateFormat; public class RestfulResultSetTest { private static final String host = "127.0.0.1"; - private static Connection conn; private static Statement stmt; private static ResultSet rs; @@ -95,7 +94,8 @@ public class RestfulResultSetTest { @Test public void getBigDecimal() throws SQLException { BigDecimal f1 = rs.getBigDecimal("f1"); - Assert.assertEquals(1609430400000l, f1.longValue()); + long actual = (f1 == null) ? 0 : f1.longValue(); + Assert.assertEquals(1609430400000l, actual); BigDecimal f2 = rs.getBigDecimal("f2"); Assert.assertEquals(1, f2.intValue()); @@ -119,7 +119,7 @@ public class RestfulResultSetTest { @Test public void getBytes() throws SQLException { byte[] f1 = rs.getBytes("f1"); - Assert.assertEquals("2021-01-01 00:00:00.0", new String(f1)); + Assert.assertEquals("2021-01-01 00:00:00.000", new String(f1)); byte[] f2 = rs.getBytes("f2"); Assert.assertEquals(1, Ints.fromByteArray(f2)); diff --git a/src/connector/nodejs/nodetaos/cinterface.js b/src/connector/nodejs/nodetaos/cinterface.js index 43a08a800afe7aa3e445a943f8d7a7f95f1ed05f..f3961e3787c4fb6d7da7092b68632d08a8b57e20 100644 --- a/src/connector/nodejs/nodetaos/cinterface.js +++ b/src/connector/nodejs/nodetaos/cinterface.js @@ -9,7 +9,7 @@ const ffi = require('ffi-napi'); const ArrayType = require('ref-array-napi'); const Struct = require('ref-struct-napi'); const FieldTypes = require('./constants'); -const errors = require ('./error'); +const errors = require('./error'); const TaosObjects = require('./taosobjects'); const { NULL_POINTER } = require('ref-napi'); @@ -22,7 +22,7 @@ function convertMicrosecondsToDatetime(time) { return new TaosObjects.TaosTimestamp(time * 0.001, true); } -function convertTimestamp(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertTimestamp(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { timestampConverter = convertMillisecondsToDatetime; if (micro == true) { timestampConverter = convertMicrosecondsToDatetime; @@ -44,14 +44,14 @@ function convertTimestamp(data, num_of_rows, nbytes = 0, offset = 0, micro=false } return res; } -function convertBool(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertBool(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = new Array(data.length); for (let i = 0; i < data.length; i++) { if (data[i] == 0) { res[i] = false; } - else if (data[i] == 1){ + else if (data[i] == 1) { res[i] = true; } else if (data[i] == FieldTypes.C_BOOL_NULL) { @@ -60,29 +60,29 @@ function convertBool(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { } return res; } -function convertTinyint(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertTinyint(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = []; let currOffset = 0; while (currOffset < data.length) { - let d = data.readIntLE(currOffset,1); + let d = data.readIntLE(currOffset, 1); res.push(d == FieldTypes.C_TINYINT_NULL ? null : d); currOffset += nbytes; } return res; } -function convertSmallint(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertSmallint(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = []; let currOffset = 0; while (currOffset < data.length) { - let d = data.readIntLE(currOffset,2); + let d = data.readIntLE(currOffset, 2); res.push(d == FieldTypes.C_SMALLINT_NULL ? null : d); currOffset += nbytes; } return res; } -function convertInt(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertInt(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = []; let currOffset = 0; @@ -93,7 +93,7 @@ function convertInt(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { } return res; } -function convertBigint(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertBigint(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = []; let currOffset = 0; @@ -104,7 +104,7 @@ function convertBigint(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { } return res; } -function convertFloat(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertFloat(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = []; let currOffset = 0; @@ -115,7 +115,7 @@ function convertFloat(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { } return res; } -function convertDouble(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertDouble(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = []; let currOffset = 0; @@ -126,7 +126,7 @@ function convertDouble(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { } return res; } -function convertBinary(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertBinary(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = []; let currOffset = 0; @@ -142,7 +142,7 @@ function convertBinary(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { } return res; } -function convertNchar(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { +function convertNchar(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = []; let dataEntry = data.slice(0, nbytes); //one entry in a row under a column; @@ -153,23 +153,23 @@ function convertNchar(data, num_of_rows, nbytes = 0, offset = 0, micro=false) { // Object with all the relevant converters from pblock data to javascript readable data let convertFunctions = { - [FieldTypes.C_BOOL] : convertBool, - [FieldTypes.C_TINYINT] : convertTinyint, - [FieldTypes.C_SMALLINT] : convertSmallint, - [FieldTypes.C_INT] : convertInt, - [FieldTypes.C_BIGINT] : convertBigint, - [FieldTypes.C_FLOAT] : convertFloat, - [FieldTypes.C_DOUBLE] : convertDouble, - [FieldTypes.C_BINARY] : convertBinary, - [FieldTypes.C_TIMESTAMP] : convertTimestamp, - [FieldTypes.C_NCHAR] : convertNchar + [FieldTypes.C_BOOL]: convertBool, + [FieldTypes.C_TINYINT]: convertTinyint, + [FieldTypes.C_SMALLINT]: convertSmallint, + [FieldTypes.C_INT]: convertInt, + [FieldTypes.C_BIGINT]: convertBigint, + [FieldTypes.C_FLOAT]: convertFloat, + [FieldTypes.C_DOUBLE]: convertDouble, + [FieldTypes.C_BINARY]: convertBinary, + [FieldTypes.C_TIMESTAMP]: convertTimestamp, + [FieldTypes.C_NCHAR]: convertNchar } // Define TaosField structure var char_arr = ArrayType(ref.types.char); var TaosField = Struct({ - 'name': char_arr, - }); + 'name': char_arr, +}); TaosField.fields.name.type.size = 65; TaosField.defineProperty('type', ref.types.char); TaosField.defineProperty('bytes', ref.types.short); @@ -183,7 +183,7 @@ TaosField.defineProperty('bytes', ref.types.short); * @classdesc The CTaosInterface is the interface through which Node.JS communicates data back and forth with TDengine. It is not advised to * access this class directly and use it unless you understand what these functions do. */ -function CTaosInterface (config = null, pass = false) { +function CTaosInterface(config = null, pass = false) { ref.types.char_ptr = ref.refType(ref.types.char); ref.types.void_ptr = ref.refType(ref.types.void); ref.types.void_ptr2 = ref.refType(ref.types.void_ptr); @@ -196,64 +196,65 @@ function CTaosInterface (config = null, pass = false) { taoslibname = 'libtaos'; } this.libtaos = ffi.Library(taoslibname, { - 'taos_options': [ ref.types.int, [ ref.types.int , ref.types.void_ptr ] ], - 'taos_init': [ ref.types.void, [ ] ], + 'taos_options': [ref.types.int, [ref.types.int, ref.types.void_ptr]], + 'taos_init': [ref.types.void, []], //TAOS *taos_connect(char *ip, char *user, char *pass, char *db, int port) - 'taos_connect': [ ref.types.void_ptr, [ ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.int ] ], + 'taos_connect': [ref.types.void_ptr, [ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.int]], //void taos_close(TAOS *taos) - 'taos_close': [ ref.types.void, [ ref.types.void_ptr ] ], - //int *taos_fetch_lengths(TAOS_RES *taos); - 'taos_fetch_lengths': [ ref.types.void_ptr, [ ref.types.void_ptr ] ], + 'taos_close': [ref.types.void, [ref.types.void_ptr]], + //int *taos_fetch_lengths(TAOS_RES *res); + 'taos_fetch_lengths': [ref.types.void_ptr, [ref.types.void_ptr]], //int taos_query(TAOS *taos, char *sqlstr) - 'taos_query': [ ref.types.void_ptr, [ ref.types.void_ptr, ref.types.char_ptr ] ], - //int taos_affected_rows(TAOS *taos) - 'taos_affected_rows': [ ref.types.int, [ ref.types.void_ptr] ], + 'taos_query': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.char_ptr]], + //int taos_affected_rows(TAOS_RES *res) + 'taos_affected_rows': [ref.types.int, [ref.types.void_ptr]], //int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) - 'taos_fetch_block': [ ref.types.int, [ ref.types.void_ptr, ref.types.void_ptr] ], + 'taos_fetch_block': [ref.types.int, [ref.types.void_ptr, ref.types.void_ptr]], //int taos_num_fields(TAOS_RES *res); - 'taos_num_fields': [ ref.types.int, [ ref.types.void_ptr] ], + 'taos_num_fields': [ref.types.int, [ref.types.void_ptr]], //TAOS_ROW taos_fetch_row(TAOS_RES *res) //TAOS_ROW is void **, but we set the return type as a reference instead to get the row - 'taos_fetch_row': [ ref.refType(ref.types.void_ptr2), [ ref.types.void_ptr ] ], + 'taos_fetch_row': [ref.refType(ref.types.void_ptr2), [ref.types.void_ptr]], + 'taos_print_row': [ref.types.int, [ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr, ref.types.int]], //int taos_result_precision(TAOS_RES *res) - 'taos_result_precision': [ ref.types.int, [ ref.types.void_ptr ] ], + 'taos_result_precision': [ref.types.int, [ref.types.void_ptr]], //void taos_free_result(TAOS_RES *res) - 'taos_free_result': [ ref.types.void, [ ref.types.void_ptr] ], + 'taos_free_result': [ref.types.void, [ref.types.void_ptr]], //int taos_field_count(TAOS *taos) - 'taos_field_count': [ ref.types.int, [ ref.types.void_ptr ] ], + 'taos_field_count': [ref.types.int, [ref.types.void_ptr]], //TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) - 'taos_fetch_fields': [ ref.refType(TaosField), [ ref.types.void_ptr ] ], + 'taos_fetch_fields': [ref.refType(TaosField), [ref.types.void_ptr]], //int taos_errno(TAOS *taos) - 'taos_errno': [ ref.types.int, [ ref.types.void_ptr] ], + 'taos_errno': [ref.types.int, [ref.types.void_ptr]], //char *taos_errstr(TAOS *taos) - 'taos_errstr': [ ref.types.char_ptr, [ ref.types.void_ptr] ], + 'taos_errstr': [ref.types.char_ptr, [ref.types.void_ptr]], //void taos_stop_query(TAOS_RES *res); - 'taos_stop_query': [ ref.types.void, [ ref.types.void_ptr] ], + 'taos_stop_query': [ref.types.void, [ref.types.void_ptr]], //char *taos_get_server_info(TAOS *taos); - 'taos_get_server_info': [ ref.types.char_ptr, [ ref.types.void_ptr ] ], + 'taos_get_server_info': [ref.types.char_ptr, [ref.types.void_ptr]], //char *taos_get_client_info(); - 'taos_get_client_info': [ ref.types.char_ptr, [ ] ], + 'taos_get_client_info': [ref.types.char_ptr, []], // ASYNC // void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *, TAOS_RES *, int), void *param) - 'taos_query_a': [ ref.types.void, [ ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr ] ], + 'taos_query_a': [ref.types.void, [ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr]], // void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param); - 'taos_fetch_rows_a': [ ref.types.void, [ ref.types.void_ptr, ref.types.void_ptr, ref.types.void_ptr ]], + 'taos_fetch_rows_a': [ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.types.void_ptr]], // Subscription //TAOS_SUB *taos_subscribe(TAOS* taos, int restart, const char* topic, const char *sql, TAOS_SUBSCRIBE_CALLBACK fp, void *param, int interval) - 'taos_subscribe': [ ref.types.void_ptr, [ ref.types.void_ptr, ref.types.int, ref.types.char_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr, ref.types.int] ], + 'taos_subscribe': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.int, ref.types.char_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr, ref.types.int]], // TAOS_RES *taos_consume(TAOS_SUB *tsub) - 'taos_consume': [ ref.types.void_ptr, [ref.types.void_ptr] ], + 'taos_consume': [ref.types.void_ptr, [ref.types.void_ptr]], //void taos_unsubscribe(TAOS_SUB *tsub); - 'taos_unsubscribe': [ ref.types.void, [ ref.types.void_ptr ] ], + 'taos_unsubscribe': [ref.types.void, [ref.types.void_ptr]], // Continuous Query //TAOS_STREAM *taos_open_stream(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), // int64_t stime, void *param, void (*callback)(void *)); - 'taos_open_stream': [ ref.types.void_ptr, [ ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.int64, ref.types.void_ptr, ref.types.void_ptr ] ], + 'taos_open_stream': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.int64, ref.types.void_ptr, ref.types.void_ptr]], //void taos_close_stream(TAOS_STREAM *tstr); - 'taos_close_stream': [ ref.types.void, [ ref.types.void_ptr ] ] + 'taos_close_stream': [ref.types.void, [ref.types.void_ptr]] }); if (pass == false) { @@ -264,7 +265,7 @@ function CTaosInterface (config = null, pass = false) { try { this._config = ref.allocCString(config); } - catch(err){ + catch (err) { throw "Attribute Error: config is expected as a str"; } } @@ -276,38 +277,38 @@ function CTaosInterface (config = null, pass = false) { return this; } CTaosInterface.prototype.config = function config() { - return this._config; - } -CTaosInterface.prototype.connect = function connect(host=null, user="root", password="taosdata", db=null, port=0) { - let _host,_user,_password,_db,_port; - try { + return this._config; +} +CTaosInterface.prototype.connect = function connect(host = null, user = "root", password = "taosdata", db = null, port = 0) { + let _host, _user, _password, _db, _port; + try { _host = host != null ? ref.allocCString(host) : ref.alloc(ref.types.char_ptr, ref.NULL); } - catch(err) { + catch (err) { throw "Attribute Error: host is expected as a str"; } try { _user = ref.allocCString(user) } - catch(err) { + catch (err) { throw "Attribute Error: user is expected as a str"; } try { _password = ref.allocCString(password); } - catch(err) { + catch (err) { throw "Attribute Error: password is expected as a str"; } try { _db = db != null ? ref.allocCString(db) : ref.alloc(ref.types.char_ptr, ref.NULL); } - catch(err) { + catch (err) { throw "Attribute Error: db is expected as a str"; } try { _port = ref.alloc(ref.types.int, port); } - catch(err) { + catch (err) { throw TypeError("port is expected as an int") } let connection = this.libtaos.taos_connect(_host, _user, _password, _db, _port); @@ -324,10 +325,10 @@ CTaosInterface.prototype.close = function close(connection) { console.log("Connection is closed"); } CTaosInterface.prototype.query = function query(connection, sql) { - return this.libtaos.taos_query(connection, ref.allocCString(sql)); + return this.libtaos.taos_query(connection, ref.allocCString(sql)); } -CTaosInterface.prototype.affectedRows = function affectedRows(connection) { - return this.libtaos.taos_affected_rows(connection); +CTaosInterface.prototype.affectedRows = function affectedRows(result) { + return this.libtaos.taos_affected_rows(result); } CTaosInterface.prototype.useResult = function useResult(result) { @@ -337,8 +338,8 @@ CTaosInterface.prototype.useResult = function useResult(result) { pfields = ref.reinterpret(pfields, this.fieldsCount(result) * 68, 0); for (let i = 0; i < pfields.length; i += 68) { //0 - 63 = name //64 - 65 = bytes, 66 - 67 = type - fields.push( { - name: ref.readCString(ref.reinterpret(pfields,65,i)), + fields.push({ + name: ref.readCString(ref.reinterpret(pfields, 65, i)), type: pfields[i + 65], bytes: pfields[i + 66] }) @@ -347,11 +348,10 @@ CTaosInterface.prototype.useResult = function useResult(result) { return fields; } CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) { - //let pblock = ref.ref(ref.ref(ref.NULL)); // equal to our raw data - let pblock = this.libtaos.taos_fetch_row(result); - let num_of_rows = 1; - if (ref.isNull(pblock) == true) { - return {block:null, num_of_rows:0}; + let pblock = ref.NULL_POINTER; + let num_of_rows = this.libtaos.taos_fetch_block(result, pblock); + if (ref.isNull(pblock.deref()) == true) { + return { block: null, num_of_rows: 0 }; } var fieldL = this.libtaos.taos_fetch_lengths(result); @@ -359,10 +359,10 @@ CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) { let isMicro = (this.libtaos.taos_result_precision(result) == FieldTypes.C_TIMESTAMP_MICRO); var fieldlens = []; - + if (ref.isNull(fieldL) == false) { - for (let i = 0; i < fields.length; i ++) { - let plen = ref.reinterpret(fieldL, 4, i*4); + for (let i = 0; i < fields.length; i++) { + let plen = ref.reinterpret(fieldL, 4, i * 4); let len = plen.readInt32LE(0); fieldlens.push(len); } @@ -370,21 +370,23 @@ CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) { let blocks = new Array(fields.length); blocks.fill(null); - //num_of_rows = Math.abs(num_of_rows); + num_of_rows = Math.abs(num_of_rows); let offset = 0; + let ptr = pblock.deref(); + for (let i = 0; i < fields.length; i++) { - pdata = ref.reinterpret(pblock,8,i*8); - if(ref.isNull(pdata.readPointer())){ - blocks[i] = new Array(); - }else{ - pdata = ref.ref(pdata.readPointer()); - if (!convertFunctions[fields[i]['type']] ) { - throw new errors.DatabaseError("Invalid data type returned from database"); - } - blocks[i] = convertFunctions[fields[i]['type']](pdata, 1, fieldlens[i], offset, isMicro); - } - } - return {blocks: blocks, num_of_rows:Math.abs(num_of_rows)} + pdata = ref.reinterpret(ptr, 8, i * 8); + if (ref.isNull(pdata.readPointer())) { + blocks[i] = new Array(); + } else { + pdata = ref.ref(pdata.readPointer()); + if (!convertFunctions[fields[i]['type']]) { + throw new errors.DatabaseError("Invalid data type returned from database"); + } + blocks[i] = convertFunctions[fields[i]['type']](pdata, num_of_rows, fieldlens[i], offset, isMicro); + } + } + return { blocks: blocks, num_of_rows } } CTaosInterface.prototype.fetchRow = function fetchRow(result, fields) { let row = this.libtaos.taos_fetch_row(result); @@ -414,7 +416,7 @@ CTaosInterface.prototype.errStr = function errStr(result) { // Async CTaosInterface.prototype.query_a = function query_a(connection, sql, callback, param = ref.ref(ref.NULL)) { // void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, int), void *param) - callback = ffi.Callback(ref.types.void, [ ref.types.void_ptr, ref.types.void_ptr, ref.types.int ], callback); + callback = ffi.Callback(ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.types.int], callback); this.libtaos.taos_query_a(connection, ref.allocCString(sql), callback, param); return param; } @@ -439,46 +441,46 @@ CTaosInterface.prototype.fetch_rows_a = function fetch_rows_a(result, callback, var fieldL = cti.libtaos.taos_fetch_lengths(result); var fieldlens = []; if (ref.isNull(fieldL) == false) { - - for (let i = 0; i < fields.length; i ++) { - let plen = ref.reinterpret(fieldL, 8, i*8); - let len = ref.get(plen,0,ref.types.int32); + + for (let i = 0; i < fields.length; i++) { + let plen = ref.reinterpret(fieldL, 8, i * 8); + let len = ref.get(plen, 0, ref.types.int32); fieldlens.push(len); } } - if (numOfRows2 > 0){ + if (numOfRows2 > 0) { for (let i = 0; i < fields.length; i++) { - if(ref.isNull(pdata.readPointer())){ - blocks[i] = new Array(); - }else{ - if (!convertFunctions[fields[i]['type']] ) { - throw new errors.DatabaseError("Invalid data type returned from database"); - } - let prow = ref.reinterpret(row,8,i*8); - prow = prow.readPointer(); - prow = ref.ref(prow); - blocks[i] = convertFunctions[fields[i]['type']](prow, 1, fieldlens[i], offset, isMicro); - //offset += fields[i]['bytes'] * numOfRows2; - } + if (ref.isNull(pdata.readPointer())) { + blocks[i] = new Array(); + } else { + if (!convertFunctions[fields[i]['type']]) { + throw new errors.DatabaseError("Invalid data type returned from database"); + } + let prow = ref.reinterpret(row, 8, i * 8); + prow = prow.readPointer(); + prow = ref.ref(prow); + blocks[i] = convertFunctions[fields[i]['type']](prow, 1, fieldlens[i], offset, isMicro); + //offset += fields[i]['bytes'] * numOfRows2; + } } } callback(param2, result2, numOfRows2, blocks); } - asyncCallbackWrapper = ffi.Callback(ref.types.void, [ ref.types.void_ptr, ref.types.void_ptr, ref.types.int ], asyncCallbackWrapper); + asyncCallbackWrapper = ffi.Callback(ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.types.int], asyncCallbackWrapper); this.libtaos.taos_fetch_rows_a(result, asyncCallbackWrapper, param); return param; } // Fetch field meta data by result handle -CTaosInterface.prototype.fetchFields_a = function fetchFields_a (result) { +CTaosInterface.prototype.fetchFields_a = function fetchFields_a(result) { let pfields = this.fetchFields(result); let pfieldscount = this.numFields(result); let fields = []; if (ref.isNull(pfields) == false) { - pfields = ref.reinterpret(pfields, 68 * pfieldscount , 0); + pfields = ref.reinterpret(pfields, 68 * pfieldscount, 0); for (let i = 0; i < pfields.length; i += 68) { //0 - 64 = name //65 = type, 66 - 67 = bytes - fields.push( { - name: ref.readCString(ref.reinterpret(pfields,65,i)), + fields.push({ + name: ref.readCString(ref.reinterpret(pfields, 65, i)), type: pfields[i + 65], bytes: pfields[i + 66] }) @@ -488,7 +490,7 @@ CTaosInterface.prototype.fetchFields_a = function fetchFields_a (result) { } // Stop a query by result handle CTaosInterface.prototype.stopQuery = function stopQuery(result) { - if (result != null){ + if (result != null) { this.libtaos.taos_stop_query(result); } else { @@ -509,13 +511,13 @@ CTaosInterface.prototype.subscribe = function subscribe(connection, restart, top try { sql = sql != null ? ref.allocCString(sql) : ref.alloc(ref.types.char_ptr, ref.NULL); } - catch(err) { + catch (err) { throw "Attribute Error: sql is expected as a str"; } try { topic = topic != null ? ref.allocCString(topic) : ref.alloc(ref.types.char_ptr, ref.NULL); } - catch(err) { + catch (err) { throw TypeError("topic is expected as a str"); } @@ -539,8 +541,8 @@ CTaosInterface.prototype.consume = function consume(subscription) { pfields = ref.reinterpret(pfields, this.numFields(result) * 68, 0); for (let i = 0; i < pfields.length; i += 68) { //0 - 63 = name //64 - 65 = bytes, 66 - 67 = type - fields.push( { - name: ref.readCString(ref.reinterpret(pfields,64,i)), + fields.push({ + name: ref.readCString(ref.reinterpret(pfields, 64, i)), bytes: pfields[i + 64], type: pfields[i + 66] }) @@ -548,7 +550,7 @@ CTaosInterface.prototype.consume = function consume(subscription) { } let data = []; - while(true) { + while (true) { let { blocks, num_of_rows } = this.fetchBlock(result, fields); if (num_of_rows == 0) { break; @@ -559,7 +561,7 @@ CTaosInterface.prototype.consume = function consume(subscription) { for (let j = 0; j < fields.length; j++) { rowBlock[j] = blocks[j][i]; } - data[data.length-1] = (rowBlock); + data[data.length - 1] = (rowBlock); } } return { data: data, fields: fields, result: result }; @@ -570,11 +572,11 @@ CTaosInterface.prototype.unsubscribe = function unsubscribe(subscription) { } // Continuous Query -CTaosInterface.prototype.openStream = function openStream(connection, sql, callback, stime,stoppingCallback, param = ref.ref(ref.NULL)) { +CTaosInterface.prototype.openStream = function openStream(connection, sql, callback, stime, stoppingCallback, param = ref.ref(ref.NULL)) { try { sql = ref.allocCString(sql); } - catch(err) { + catch (err) { throw "Attribute Error: sql string is expected as a str"; } var cti = this; @@ -587,7 +589,7 @@ CTaosInterface.prototype.openStream = function openStream(connection, sql, callb let offset = 0; if (numOfRows2 > 0) { for (let i = 0; i < fields.length; i++) { - if (!convertFunctions[fields[i]['type']] ) { + if (!convertFunctions[fields[i]['type']]) { throw new errors.DatabaseError("Invalid data type returned from database"); } blocks[i] = convertFunctions[fields[i]['type']](row, numOfRows2, fields[i]['bytes'], offset, isMicro); @@ -596,8 +598,8 @@ CTaosInterface.prototype.openStream = function openStream(connection, sql, callb } callback(param2, result2, blocks, fields); } - asyncCallbackWrapper = ffi.Callback(ref.types.void, [ ref.types.void_ptr, ref.types.void_ptr, ref.refType(ref.types.void_ptr2) ], asyncCallbackWrapper); - asyncStoppingCallbackWrapper = ffi.Callback( ref.types.void, [ ref.types.void_ptr ], stoppingCallback); + asyncCallbackWrapper = ffi.Callback(ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.refType(ref.types.void_ptr2)], asyncCallbackWrapper); + asyncStoppingCallbackWrapper = ffi.Callback(ref.types.void, [ref.types.void_ptr], stoppingCallback); let streamHandle = this.libtaos.taos_open_stream(connection, sql, asyncCallbackWrapper, stime, param, asyncStoppingCallbackWrapper); if (ref.isNull(streamHandle)) { throw new errors.TDError('Failed to open a stream with TDengine'); diff --git a/src/connector/nodejs/nodetaos/cursor.js b/src/connector/nodejs/nodetaos/cursor.js index e18e6c2500019684dea85fe05bc7306e0a372478..f879d89d487eae9290fd9fc70259699f27937928 100644 --- a/src/connector/nodejs/nodetaos/cursor.js +++ b/src/connector/nodejs/nodetaos/cursor.js @@ -1,7 +1,7 @@ const ref = require('ref-napi'); require('./globalfunc.js') const CTaosInterface = require('./cinterface') -const errors = require ('./error') +const errors = require('./error') const TaosQuery = require('./taosquery') const { PerformanceObserver, performance } = require('perf_hooks'); module.exports = TDengineCursor; @@ -22,7 +22,7 @@ module.exports = TDengineCursor; * @property {fields} - Array of the field objects in order from left to right of the latest data retrieved * @since 1.0.0 */ -function TDengineCursor(connection=null) { +function TDengineCursor(connection = null) { //All parameters are store for sync queries only. this._rowcount = -1; this._connection = null; @@ -91,7 +91,7 @@ TDengineCursor.prototype.execute = function execute(operation, options, callback return null; } - if (typeof options == 'function') { + if (typeof options == 'function') { callback = options; } if (typeof options != 'object') options = {} @@ -144,10 +144,10 @@ TDengineCursor.prototype.execute = function execute(operation, options, callback } TDengineCursor.prototype._createAffectedResponse = function (num, time) { - return "Query OK, " + num + " row(s) affected (" + (time * 0.001).toFixed(8) + "s)"; + return "Query OK, " + num + " row(s) affected (" + (time * 0.001).toFixed(8) + "s)"; } TDengineCursor.prototype._createSetResponse = function (num, time) { - return "Query OK, " + num + " row(s) in set (" + (time * 0.001).toFixed(8) + "s)"; + return "Query OK, " + num + " row(s) in set (" + (time * 0.001).toFixed(8) + "s)"; } TDengineCursor.prototype.executemany = function executemany() { @@ -176,27 +176,22 @@ TDengineCursor.prototype.fetchall = function fetchall(options, callback) { throw new errors.OperationalError("Invalid use of fetchall, either result or fields from query are null. First execute a query first"); } - let data = []; + let num_of_rows = this._chandle.affectedRows(this._result); + let data = new Array(num_of_rows); + this._rowcount = 0; - //let nodetime = 0; + let time = 0; const obs = new PerformanceObserver((items) => { time += items.getEntries()[0].duration; performance.clearMarks(); }); - /* - const obs2 = new PerformanceObserver((items) => { - nodetime += items.getEntries()[0].duration; - performance.clearMarks(); - }); - obs2.observe({ entryTypes: ['measure'] }); - performance.mark('nodea'); - */ obs.observe({ entryTypes: ['measure'] }); performance.mark('A'); - while(true) { - + while (true) { let blockAndRows = this._chandle.fetchBlock(this._result, this._fields); + // console.log(blockAndRows); + // break; let block = blockAndRows.blocks; let num_of_rows = blockAndRows.num_of_rows; if (num_of_rows == 0) { @@ -205,22 +200,24 @@ TDengineCursor.prototype.fetchall = function fetchall(options, callback) { this._rowcount += num_of_rows; let numoffields = this._fields.length; for (let i = 0; i < num_of_rows; i++) { - data.push([]); - + // data.push([]); + let rowBlock = new Array(numoffields); for (let j = 0; j < numoffields; j++) { rowBlock[j] = block[j][i]; } - data[data.length-1] = (rowBlock); + data[this._rowcount - num_of_rows + i] = (rowBlock); + // data.push(rowBlock); } } + performance.mark('B'); performance.measure('query', 'A', 'B'); let response = this._createSetResponse(this._rowcount, time) console.log(response); - // this._connection._clearResultSet(); + // this._connection._clearResultSet(); let fields = this.fields; this._reset_result(); this.data = data; @@ -239,12 +236,12 @@ TDengineCursor.prototype.fetchall = function fetchall(options, callback) { * @return {number | Buffer} Number of affected rows or a Buffer that points to the results of the query * @since 1.0.0 */ -TDengineCursor.prototype.execute_a = function execute_a (operation, options, callback, param) { +TDengineCursor.prototype.execute_a = function execute_a(operation, options, callback, param) { if (operation == undefined) { throw new errors.ProgrammingError('No operation passed as argument'); return null; } - if (typeof options == 'function') { + if (typeof options == 'function') { //we expect the parameter after callback to be param param = callback; callback = options; @@ -265,14 +262,14 @@ TDengineCursor.prototype.execute_a = function execute_a (operation, options, cal } if (resCode >= 0) { -// let fieldCount = cr._chandle.numFields(res2); -// if (fieldCount == 0) { -// //cr._chandle.freeResult(res2); -// return res2; -// } -// else { -// return res2; -// } + // let fieldCount = cr._chandle.numFields(res2); + // if (fieldCount == 0) { + // //cr._chandle.freeResult(res2); + // return res2; + // } + // else { + // return res2; + // } return res2; } @@ -317,7 +314,7 @@ TDengineCursor.prototype.execute_a = function execute_a (operation, options, cal * }) */ TDengineCursor.prototype.fetchall_a = function fetchall_a(result, options, callback, param = {}) { - if (typeof options == 'function') { + if (typeof options == 'function') { //we expect the parameter after callback to be param param = callback; callback = options; @@ -360,17 +357,17 @@ TDengineCursor.prototype.fetchall_a = function fetchall_a(result, options, callb for (let k = 0; k < fields.length; k++) { rowBlock[k] = block[k][j]; } - data[data.length-1] = rowBlock; + data[data.length - 1] = rowBlock; } } cr._chandle.freeResult(result2); // free result, avoid seg faults and mem leaks! - callback(param2, result2, numOfRows2, {data:data,fields:fields}); + callback(param2, result2, numOfRows2, { data: data, fields: fields }); } } ref.writeObject(buf, 0, param); param = this._chandle.fetch_rows_a(result, asyncCallbackWrapper, buf); //returned param - return {param:param,result:result}; + return { param: param, result: result }; } /** * Stop a query given the result handle. @@ -428,7 +425,7 @@ TDengineCursor.prototype.subscribe = function subscribe(config) { */ TDengineCursor.prototype.consumeData = async function consumeData(subscription, callback) { while (true) { - let { data, fields, result} = this._chandle.consume(subscription); + let { data, fields, result } = this._chandle.consume(subscription); callback(data, fields, result); } } @@ -450,30 +447,30 @@ TDengineCursor.prototype.unsubscribe = function unsubscribe(subscription) { * @return {Buffer} A buffer pointing to the stream handle * @since 1.3.0 */ - TDengineCursor.prototype.openStream = function openStream(sql, callback, stime = 0, stoppingCallback, param = {}) { - let buf = ref.alloc('Object'); - ref.writeObject(buf, 0, param); +TDengineCursor.prototype.openStream = function openStream(sql, callback, stime = 0, stoppingCallback, param = {}) { + let buf = ref.alloc('Object'); + ref.writeObject(buf, 0, param); - let asyncCallbackWrapper = function (param2, result2, blocks, fields) { - let data = []; - let num_of_rows = blocks[0].length; - for (let j = 0; j < num_of_rows; j++) { - data.push([]); - let rowBlock = new Array(fields.length); - for (let k = 0; k < fields.length; k++) { - rowBlock[k] = blocks[k][j]; - } - data[data.length-1] = rowBlock; - } - callback(param2, result2, blocks, fields); - } - return this._chandle.openStream(this._connection._conn, sql, asyncCallbackWrapper, stime, stoppingCallback, buf); - } - /** - * Close a stream - * @param {Buffer} - A buffer pointing to the handle of the stream to be closed - * @since 1.3.0 - */ - TDengineCursor.prototype.closeStream = function closeStream(stream) { - this._chandle.closeStream(stream); - } + let asyncCallbackWrapper = function (param2, result2, blocks, fields) { + let data = []; + let num_of_rows = blocks[0].length; + for (let j = 0; j < num_of_rows; j++) { + data.push([]); + let rowBlock = new Array(fields.length); + for (let k = 0; k < fields.length; k++) { + rowBlock[k] = blocks[k][j]; + } + data[data.length - 1] = rowBlock; + } + callback(param2, result2, blocks, fields); + } + return this._chandle.openStream(this._connection._conn, sql, asyncCallbackWrapper, stime, stoppingCallback, buf); +} +/** + * Close a stream + * @param {Buffer} - A buffer pointing to the handle of the stream to be closed + * @since 1.3.0 + */ +TDengineCursor.prototype.closeStream = function closeStream(stream) { + this._chandle.closeStream(stream); +} diff --git a/src/connector/nodejs/package-lock.json b/src/connector/nodejs/package-lock.json deleted file mode 100644 index 9ca174ccd12f782b047789e44a6abce231b15ad0..0000000000000000000000000000000000000000 --- a/src/connector/nodejs/package-lock.json +++ /dev/null @@ -1,285 +0,0 @@ -{ - "name": "td2.0-connector", - "version": "2.0.6", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "array-index": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-index/-/array-index-1.0.0.tgz", - "integrity": "sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k=", - "requires": { - "debug": "^2.2.0", - "es6-symbol": "^3.0.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" - } - } - }, - "ffi-napi": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ffi-napi/-/ffi-napi-3.1.0.tgz", - "integrity": "sha512-EsHO+sP2p/nUC/3l/l8m9niee1BLm4asUFDzkkBGR4kYVgp2KqdAYUomZhkKtzim4Fq7mcYHjpUaIHsMqs+E1g==", - "requires": { - "debug": "^4.1.1", - "get-uv-event-loop-napi-h": "^1.0.5", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.1", - "ref-napi": "^2.0.1", - "ref-struct-di": "^1.1.0" - }, - "dependencies": { - "ref-napi": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-2.1.2.tgz", - "integrity": "sha512-aFl+vrIuLWUXMUTQGAwGAuSNLX3Ub5W3iVP8b7KyFFZUdn4+i4U1TXXTop0kCTUfGNu8glBGVz4lowkwMcPVVA==", - "requires": { - "debug": "^4.1.1", - "get-symbol-from-current-process-h": "^1.0.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.1" - } - } - } - }, - "get-symbol-from-current-process-h": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", - "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" - }, - "get-uv-event-loop-napi-h": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", - "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", - "requires": { - "get-symbol-from-current-process-h": "^1.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" - }, - "ref-array-napi": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ref-array-napi/-/ref-array-napi-1.2.1.tgz", - "integrity": "sha512-jQp2WWSucmxkqVfoNfm7yDlDeGu3liAbzqfwjNybL80ooLOCnCZpAK2woDInY+lxNOK/VlIVSqeDEYb4gVPuNQ==", - "requires": { - "array-index": "1", - "debug": "2", - "ref-napi": "^1.4.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ref-napi": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-1.5.2.tgz", - "integrity": "sha512-hwyNmWpUkt1bDWDW4aiwCoC+SJfJO69UIdjqssNqdaS0sYJpgqzosGg/rLtk69UoQ8drZdI9yyQefM7eEMM3Gw==", - "requires": { - "debug": "^3.1.0", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.1" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - } - } - }, - "ref-napi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-3.0.1.tgz", - "integrity": "sha512-W3rcb0E+tlO9u9ySFnX5vifInwwPGToOfFgTZUHJBNiOBsW0NNvgHz2zJN7ctABo/2yIlgdPQUvuqqfORIF4LA==", - "requires": { - "debug": "^4.1.1", - "get-symbol-from-current-process-h": "^1.0.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.1" - } - }, - "ref-struct-di": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ref-struct-di/-/ref-struct-di-1.1.1.tgz", - "integrity": "sha512-2Xyn/0Qgz89VT+++WP0sTosdm9oeowLP23wRJYhG4BFdMUrLj3jhwHZNEytYNYgtPKLNTP3KJX4HEgBvM1/Y2g==", - "requires": { - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "ref-struct-napi": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ref-struct-napi/-/ref-struct-napi-1.1.1.tgz", - "integrity": "sha512-YgS5/d7+kT5zgtySYI5ieH0hREdv+DabgDvoczxsui0f9VLm0rrDcWEj4DHKehsH+tJnVMsLwuyctWgvdEcVRw==", - "requires": { - "debug": "2", - "ref-napi": "^1.4.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ref-napi": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-1.5.2.tgz", - "integrity": "sha512-hwyNmWpUkt1bDWDW4aiwCoC+SJfJO69UIdjqssNqdaS0sYJpgqzosGg/rLtk69UoQ8drZdI9yyQefM7eEMM3Gw==", - "requires": { - "debug": "^3.1.0", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.1" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - } - } - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - } - } -} diff --git a/src/connector/nodejs/package.json b/src/connector/nodejs/package.json index b39ce2c17d8e693d0e981885aed55ba1b82313b6..d21b62108b14e5a132ad5457d190bbcbc58b73a8 100644 --- a/src/connector/nodejs/package.json +++ b/src/connector/nodejs/package.json @@ -1,6 +1,6 @@ { "name": "td2.0-connector", - "version": "2.0.6", + "version": "2.0.7", "description": "A Node.js connector for TDengine.", "main": "tdengine.js", "directories": { diff --git a/src/connector/odbc/examples/c/main.c b/src/connector/odbc/examples/c/main.c index e36c75688e3440a62b66fa5fc2f8b13b83f55237..de01d2b85eda0a6851ceede8b1932ce6d9231595 100644 --- a/src/connector/odbc/examples/c/main.c +++ b/src/connector/odbc/examples/c/main.c @@ -18,8 +18,8 @@ #define CHK_TEST(statement) \ do { \ D("testing: %s", #statement); \ - int r = (statement); \ - if (r) { \ + int _r = (statement); \ + if (_r) { \ D("testing failed: %s", #statement); \ return 1; \ } \ @@ -181,7 +181,7 @@ static int do_statement(SQLHSTMT stmt, const char *statement) { r = traverse_cols(stmt, cols); char buf[4096]; while (1) { - SQLRETURN r = SQLFetch(stmt); + r = SQLFetch(stmt); if (r==SQL_NO_DATA) break; CHK_RESULT(r, SQL_HANDLE_STMT, stmt, ""); for (size_t i=0; itsdb_params = tsdb_params; for (int i=0; i name (mondatory) - > type_code (mondatory) - > display_size - > internal_size - > precision - > scale - > null_ok - - This attribute will be None for operations that do not return rows or - if the cursor has not had an operation invoked via the .execute*() method yet. - - .rowcount:This read-only attribute specifies the number of rows that the last - .execute*() produced (for DQL statements like SELECT) or affected - """ - - def __init__(self, connection=None): - self._description = [] - self._rowcount = -1 - self._connection = None - self._result = None - self._fields = None - self._block = None - self._block_rows = -1 - self._block_iter = 0 - self._affected_rows = 0 - self._logfile = "" - - if connection is not None: - self._connection = connection - - def __iter__(self): - return self - - def next(self): - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetch iterator") - - if self._block_rows <= self._block_iter: - block, self._block_rows = CTaosInterface.fetchRow( - self._result, self._fields) - if self._block_rows == 0: - raise StopIteration - self._block = list(map(tuple, zip(*block))) - self._block_iter = 0 - - data = self._block[self._block_iter] - self._block_iter += 1 - - return data - - @property - def description(self): - """Return the description of the object. - """ - return self._description - - @property - def rowcount(self): - """Return the rowcount of the object - """ - return self._rowcount - - @property - def affected_rows(self): - """Return the affected_rows of the object - """ - return self._affected_rows - - def callproc(self, procname, *args): - """Call a stored database procedure with the given name. - - Void functionality since no stored procedures. - """ - pass - - def log(self, logfile): - self._logfile = logfile - - def close(self): - """Close the cursor. - """ - if self._connection is None: - return False - - self._reset_result() - self._connection = None - - return True - - def execute(self, operation, params=None): - """Prepare and execute a database operation (query or command). - """ - if not operation: - return None - - if not self._connection: - # TODO : change the exception raised here - raise ProgrammingError("Cursor is not connected") - - self._reset_result() - - stmt = operation - if params is not None: - pass - - # global querySeqNum - # querySeqNum += 1 - # localSeqNum = querySeqNum # avoid raice condition - # print(" >> Exec Query ({}): {}".format(localSeqNum, str(stmt))) - self._result = CTaosInterface.query(self._connection._conn, stmt) - # print(" << Query ({}) Exec Done".format(localSeqNum)) - if (self._logfile): - with open(self._logfile, "a") as logfile: - logfile.write("%s;\n" % operation) - - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno == 0: - if CTaosInterface.fieldsCount(self._result) == 0: - self._affected_rows += CTaosInterface.affectedRows( - self._result) - return CTaosInterface.affectedRows(self._result) - else: - self._fields = CTaosInterface.useResult( - self._result) - return self._handle_result() - else: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - - def executemany(self, operation, seq_of_parameters): - """Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters. - """ - pass - - def fetchone(self): - """Fetch the next row of a query result set, returning a single sequence, or None when no more data is available. - """ - pass - - def fetchmany(self): - pass - - def istype(self, col, dataType): - if (dataType.upper() == "BOOL"): - if (self._description[col][1] == FieldType.C_BOOL): - return True - if (dataType.upper() == "TINYINT"): - if (self._description[col][1] == FieldType.C_TINYINT): - return True - if (dataType.upper() == "TINYINT UNSIGNED"): - if (self._description[col][1] == FieldType.C_TINYINT_UNSIGNED): - return True - if (dataType.upper() == "SMALLINT"): - if (self._description[col][1] == FieldType.C_SMALLINT): - return True - if (dataType.upper() == "SMALLINT UNSIGNED"): - if (self._description[col][1] == FieldType.C_SMALLINT_UNSIGNED): - return True - if (dataType.upper() == "INT"): - if (self._description[col][1] == FieldType.C_INT): - return True - if (dataType.upper() == "INT UNSIGNED"): - if (self._description[col][1] == FieldType.C_INT_UNSIGNED): - return True - if (dataType.upper() == "BIGINT"): - if (self._description[col][1] == FieldType.C_BIGINT): - return True - if (dataType.upper() == "BIGINT UNSIGNED"): - if (self._description[col][1] == FieldType.C_BIGINT_UNSIGNED): - return True - if (dataType.upper() == "FLOAT"): - if (self._description[col][1] == FieldType.C_FLOAT): - return True - if (dataType.upper() == "DOUBLE"): - if (self._description[col][1] == FieldType.C_DOUBLE): - return True - if (dataType.upper() == "BINARY"): - if (self._description[col][1] == FieldType.C_BINARY): - return True - if (dataType.upper() == "TIMESTAMP"): - if (self._description[col][1] == FieldType.C_TIMESTAMP): - return True - if (dataType.upper() == "NCHAR"): - if (self._description[col][1] == FieldType.C_NCHAR): - return True - - return False - - def fetchall_row(self): - """Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation. - """ - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetchall") - - buffer = [[] for i in range(len(self._fields))] - self._rowcount = 0 - while True: - block, num_of_fields = CTaosInterface.fetchRow( - self._result, self._fields) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno != 0: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - if num_of_fields == 0: - break - self._rowcount += num_of_fields - for i in range(len(self._fields)): - buffer[i].extend(block[i]) - return list(map(tuple, zip(*buffer))) - - def fetchall(self): - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetchall") - - buffer = [[] for i in range(len(self._fields))] - self._rowcount = 0 - while True: - block, num_of_fields = CTaosInterface.fetchBlock( - self._result, self._fields) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno != 0: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - if num_of_fields == 0: - break - self._rowcount += num_of_fields - for i in range(len(self._fields)): - buffer[i].extend(block[i]) - return list(map(tuple, zip(*buffer))) - - def nextset(self): - """ - """ - pass - - def setinputsize(self, sizes): - pass - - def setutputsize(self, size, column=None): - pass - - def _reset_result(self): - """Reset the result to unused version. - """ - self._description = [] - self._rowcount = -1 - if self._result is not None: - CTaosInterface.freeResult(self._result) - self._result = None - self._fields = None - self._block = None - self._block_rows = -1 - self._block_iter = 0 - self._affected_rows = 0 - - def _handle_result(self): - """Handle the return result from query. - """ - self._description = [] - for ele in self._fields: - self._description.append( - (ele['name'], ele['type'], None, None, None, None, False)) - - return self._result diff --git a/src/connector/python/linux/python3/LICENSE b/src/connector/python/linux/python3/LICENSE deleted file mode 100644 index 79a9d730868bfe5d3fa01d679a4abfe9ee7811f0..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ - 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 . diff --git a/src/connector/python/linux/python3/README.md b/src/connector/python/linux/python3/README.md deleted file mode 100644 index 70db6bba13a8b52b9f707400b80d1302542dbc34..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/README.md +++ /dev/null @@ -1 +0,0 @@ -# TDengine python client interface \ No newline at end of file diff --git a/src/connector/python/linux/python3/setup.py b/src/connector/python/linux/python3/setup.py deleted file mode 100644 index 0bd7d51b6a3699acc6c923de2533cd85393f6ae3..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/setup.py +++ /dev/null @@ -1,20 +0,0 @@ -import setuptools - -with open("README.md", "r") as fh: - long_description = fh.read() - -setuptools.setup( - name="taos", - version="2.0.9", - author="Taosdata Inc.", - author_email="support@taosdata.com", - description="TDengine python client package", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/pypa/sampleproject", - packages=setuptools.find_packages(), - classifiers=[ - "Programming Language :: Python :: 3", - "Operating System :: Linux", - ], -) diff --git a/src/connector/python/linux/python3/taos/__init__.py b/src/connector/python/linux/python3/taos/__init__.py deleted file mode 100644 index 973263573808232e4e71dc0158585624a8e7d2ab..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/taos/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ - -from .connection import TDengineConnection -from .cursor import TDengineCursor - -# Globals -threadsafety = 0 -paramstyle = 'pyformat' - -__all__ = ['connection', 'cursor'] - - -def connect(*args, **kwargs): - """ Function to return a TDengine connector object - - Current supporting keyword parameters: - @dsn: Data source name as string - @user: Username as string(optional) - @password: Password as string(optional) - @host: Hostname(optional) - @database: Database name(optional) - - @rtype: TDengineConnector - """ - return TDengineConnection(*args, **kwargs) diff --git a/src/connector/python/linux/python3/taos/cinterface.py b/src/connector/python/linux/python3/taos/cinterface.py deleted file mode 100644 index 3d0ecd290156b71e2d738fe7d3693763e0047338..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/taos/cinterface.py +++ /dev/null @@ -1,648 +0,0 @@ -import ctypes -from .constants import FieldType -from .error import * -import math -import datetime - - -def _convert_millisecond_to_datetime(milli): - return datetime.datetime.fromtimestamp(milli / 1000.0) - - -def _convert_microsecond_to_datetime(micro): - return datetime.datetime.fromtimestamp(micro / 1000000.0) - - -def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bool row to python row - """ - _timestamp_converter = _convert_millisecond_to_datetime - if micro: - _timestamp_converter = _convert_microsecond_to_datetime - - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] - - -def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bool row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_byte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_bool))[ - :abs(num_of_rows)]] - - -def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C tinyint row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] - - -def _crow_tinyint_unsigned_to_python( - data, - num_of_rows, - nbytes=None, - micro=False): - """Function to convert C tinyint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] - - -def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C smallint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] - - -def _crow_smallint_unsigned_to_python( - data, num_of_rows, nbytes=None, micro=False): - """Function to convert C smallint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] - - -def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C int row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] - - -def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C int row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] - - -def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bigint row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] - - -def _crow_bigint_unsigned_to_python( - data, - num_of_rows, - nbytes=None, - micro=False): - """Function to convert C bigint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] - - -def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C float row to python row - """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] - - -def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C double row to python row - """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] - - -def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C binary row to python row - """ - assert(nbytes is not None) - if num_of_rows > 0: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] - else: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] - - -def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C nchar row to python row - """ - assert(nbytes is not None) - res = [] - for i in range(abs(num_of_rows)): - try: - if num_of_rows >= 0: - tmpstr = ctypes.c_char_p(data) - res.append(tmpstr.value.decode()) - else: - res.append((ctypes.cast(data + nbytes * i, - ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value) - except ValueError: - res.append(None) - - return res - - -def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C binary row to python row - """ - assert(nbytes is not None) - res = [] - if num_of_rows > 0: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) - return res - - -def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C nchar row to python row - """ - assert(nbytes is not None) - res = [] - if num_of_rows >= 0: - for i in range(abs(num_of_rows)): - try: - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - res.append((ctypes.cast(data + nbytes * i + 2, - ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value) - except ValueError: - res.append(None) - return res - - -_CONVERT_FUNC = { - FieldType.C_BOOL: _crow_bool_to_python, - FieldType.C_TINYINT: _crow_tinyint_to_python, - FieldType.C_SMALLINT: _crow_smallint_to_python, - FieldType.C_INT: _crow_int_to_python, - FieldType.C_BIGINT: _crow_bigint_to_python, - FieldType.C_FLOAT: _crow_float_to_python, - FieldType.C_DOUBLE: _crow_double_to_python, - FieldType.C_BINARY: _crow_binary_to_python, - FieldType.C_TIMESTAMP: _crow_timestamp_to_python, - FieldType.C_NCHAR: _crow_nchar_to_python, - FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python, - FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, - FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, - FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python -} - -_CONVERT_FUNC_BLOCK = { - FieldType.C_BOOL: _crow_bool_to_python, - FieldType.C_TINYINT: _crow_tinyint_to_python, - FieldType.C_SMALLINT: _crow_smallint_to_python, - FieldType.C_INT: _crow_int_to_python, - FieldType.C_BIGINT: _crow_bigint_to_python, - FieldType.C_FLOAT: _crow_float_to_python, - FieldType.C_DOUBLE: _crow_double_to_python, - FieldType.C_BINARY: _crow_binary_to_python_block, - FieldType.C_TIMESTAMP: _crow_timestamp_to_python, - FieldType.C_NCHAR: _crow_nchar_to_python_block, - FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python, - FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, - FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, - FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python -} - -# Corresponding TAOS_FIELD structure in C - - -class TaosField(ctypes.Structure): - _fields_ = [('name', ctypes.c_char * 65), - ('type', ctypes.c_char), - ('bytes', ctypes.c_short)] - -# C interface class - - -class CTaosInterface(object): - - libtaos = ctypes.CDLL('libtaos.so') - - libtaos.taos_fetch_fields.restype = ctypes.POINTER(TaosField) - libtaos.taos_init.restype = None - libtaos.taos_connect.restype = ctypes.c_void_p - #libtaos.taos_use_result.restype = ctypes.c_void_p - libtaos.taos_fetch_row.restype = ctypes.POINTER(ctypes.c_void_p) - libtaos.taos_errstr.restype = ctypes.c_char_p - libtaos.taos_subscribe.restype = ctypes.c_void_p - libtaos.taos_consume.restype = ctypes.c_void_p - libtaos.taos_fetch_lengths.restype = ctypes.c_void_p - libtaos.taos_free_result.restype = None - libtaos.taos_errno.restype = ctypes.c_int - libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p) - - def __init__(self, config=None): - ''' - Function to initialize the class - @host : str, hostname to connect - @user : str, username to connect to server - @password : str, password to connect to server - @db : str, default db to use when log in - @config : str, config directory - - @rtype : None - ''' - if config is None: - self._config = ctypes.c_char_p(None) - else: - try: - self._config = ctypes.c_char_p(config.encode('utf-8')) - except AttributeError: - raise AttributeError("config is expected as a str") - - if config is not None: - CTaosInterface.libtaos.taos_options(3, self._config) - - CTaosInterface.libtaos.taos_init() - - @property - def config(self): - """ Get current config - """ - return self._config - - def connect( - self, - host=None, - user="root", - password="taosdata", - db=None, - port=0): - ''' - Function to connect to server - - @rtype: c_void_p, TDengine handle - ''' - # host - try: - _host = ctypes.c_char_p(host.encode( - "utf-8")) if host is not None else ctypes.c_char_p(None) - except AttributeError: - raise AttributeError("host is expected as a str") - - # user - try: - _user = ctypes.c_char_p(user.encode("utf-8")) - except AttributeError: - raise AttributeError("user is expected as a str") - - # password - try: - _password = ctypes.c_char_p(password.encode("utf-8")) - except AttributeError: - raise AttributeError("password is expected as a str") - - # db - try: - _db = ctypes.c_char_p( - db.encode("utf-8")) if db is not None else ctypes.c_char_p(None) - except AttributeError: - raise AttributeError("db is expected as a str") - - # port - try: - _port = ctypes.c_int(port) - except TypeError: - raise TypeError("port is expected as an int") - - connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect( - _host, _user, _password, _db, _port)) - - if connection.value is None: - print('connect to TDengine failed') - raise ConnectionError("connect to TDengine failed") - # sys.exit(1) - # else: - # print('connect to TDengine success') - - return connection - - @staticmethod - def close(connection): - '''Close the TDengine handle - ''' - CTaosInterface.libtaos.taos_close(connection) - #print('connection is closed') - - @staticmethod - def query(connection, sql): - '''Run SQL - - @sql: str, sql string to run - - @rtype: 0 on success and -1 on failure - ''' - try: - return CTaosInterface.libtaos.taos_query( - connection, ctypes.c_char_p(sql.encode('utf-8'))) - except AttributeError: - raise AttributeError("sql is expected as a string") - # finally: - # CTaosInterface.libtaos.close(connection) - - @staticmethod - def affectedRows(result): - """The affected rows after runing query - """ - return CTaosInterface.libtaos.taos_affected_rows(result) - - @staticmethod - def subscribe(connection, restart, topic, sql, interval): - """Create a subscription - @restart boolean, - @sql string, sql statement for data query, must be a 'select' statement. - @topic string, name of this subscription - """ - return ctypes.c_void_p(CTaosInterface.libtaos.taos_subscribe( - connection, - 1 if restart else 0, - ctypes.c_char_p(topic.encode('utf-8')), - ctypes.c_char_p(sql.encode('utf-8')), - None, - None, - interval)) - - @staticmethod - def consume(sub): - """Consume data of a subscription - """ - result = ctypes.c_void_p(CTaosInterface.libtaos.taos_consume(sub)) - fields = [] - pfields = CTaosInterface.fetchFields(result) - for i in range(CTaosInterface.libtaos.taos_num_fields(result)): - fields.append({'name': pfields[i].name.decode('utf-8'), - 'bytes': pfields[i].bytes, - 'type': ord(pfields[i].type)}) - return result, fields - - @staticmethod - def unsubscribe(sub, keepProgress): - """Cancel a subscription - """ - CTaosInterface.libtaos.taos_unsubscribe(sub, 1 if keepProgress else 0) - - @staticmethod - def useResult(result): - '''Use result after calling self.query - ''' - fields = [] - pfields = CTaosInterface.fetchFields(result) - for i in range(CTaosInterface.fieldsCount(result)): - fields.append({'name': pfields[i].name.decode('utf-8'), - 'bytes': pfields[i].bytes, - 'type': ord(pfields[i].type)}) - - return fields - - @staticmethod - def fetchBlock(result, fields): - pblock = ctypes.c_void_p(0) - num_of_rows = CTaosInterface.libtaos.taos_fetch_block( - result, ctypes.byref(pblock)) - if num_of_rows == 0: - return None, 0 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ - ele for ele in ctypes.cast( - fieldL, ctypes.POINTER( - ctypes.c_int))[ - :len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if fields[i]['type'] not in _CONVERT_FUNC_BLOCK: - raise DatabaseError("Invalid data type returned from database") - blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) - - return blocks, abs(num_of_rows) - - @staticmethod - def fetchRow(result, fields): - pblock = ctypes.c_void_p(0) - pblock = CTaosInterface.libtaos.taos_fetch_row(result) - if pblock: - num_of_rows = 1 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ - ele for ele in ctypes.cast( - fieldL, ctypes.POINTER( - ctypes.c_int))[ - :len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if fields[i]['type'] not in _CONVERT_FUNC: - raise DatabaseError( - "Invalid data type returned from database") - if data is None: - blocks[i] = [None] - else: - blocks[i] = _CONVERT_FUNC[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) - else: - return None, 0 - return blocks, abs(num_of_rows) - - @staticmethod - def freeResult(result): - CTaosInterface.libtaos.taos_free_result(result) - result.value = None - - @staticmethod - def fieldsCount(result): - return CTaosInterface.libtaos.taos_field_count(result) - - @staticmethod - def fetchFields(result): - return CTaosInterface.libtaos.taos_fetch_fields(result) - - # @staticmethod - # def fetchRow(result, fields): - # l = [] - # row = CTaosInterface.libtaos.taos_fetch_row(result) - # if not row: - # return None - - # for i in range(len(fields)): - # l.append(CTaosInterface.getDataValue( - # row[i], fields[i]['type'], fields[i]['bytes'])) - - # return tuple(l) - - # @staticmethod - # def getDataValue(data, dtype, byte): - # ''' - # ''' - # if not data: - # return None - - # if (dtype == CTaosInterface.TSDB_DATA_TYPE_BOOL): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TINYINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_SMALLINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_INT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BIGINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int64))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_FLOAT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_DOUBLE): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BINARY): - # return (ctypes.cast(data, ctypes.POINTER(ctypes.c_char))[0:byte]).rstrip('\x00') - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TIMESTAMP): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int64))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_NCHAR): - # return (ctypes.cast(data, ctypes.c_char_p).value).rstrip('\x00') - - @staticmethod - def errno(result): - """Return the error number. - """ - return CTaosInterface.libtaos.taos_errno(result) - - @staticmethod - def errStr(result): - """Return the error styring - """ - return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8') - - -if __name__ == '__main__': - cinter = CTaosInterface() - conn = cinter.connect() - result = cinter.query(conn, 'show databases') - - print('Query Affected rows: {}'.format(cinter.affectedRows(result))) - - fields = CTaosInterface.useResult(result) - - data, num_of_rows = CTaosInterface.fetchBlock(result, fields) - - print(data) - - cinter.freeResult(result) - cinter.close(conn) diff --git a/src/connector/python/linux/python3/taos/connection.py b/src/connector/python/linux/python3/taos/connection.py deleted file mode 100644 index f6c395342c9c39a24bda6022f0ed36cb7bfe045b..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/taos/connection.py +++ /dev/null @@ -1,95 +0,0 @@ -from .cursor import TDengineCursor -from .subscription import TDengineSubscription -from .cinterface import CTaosInterface - - -class TDengineConnection(object): - """ TDengine connection object - """ - - def __init__(self, *args, **kwargs): - self._conn = None - self._host = None - self._user = "root" - self._password = "taosdata" - self._database = None - self._port = 0 - self._config = None - self._chandle = None - - self.config(**kwargs) - - def config(self, **kwargs): - # host - if 'host' in kwargs: - self._host = kwargs['host'] - - # user - if 'user' in kwargs: - self._user = kwargs['user'] - - # password - if 'password' in kwargs: - self._password = kwargs['password'] - - # database - if 'database' in kwargs: - self._database = kwargs['database'] - - # port - if 'port' in kwargs: - self._port = kwargs['port'] - - # config - if 'config' in kwargs: - self._config = kwargs['config'] - - self._chandle = CTaosInterface(self._config) - self._conn = self._chandle.connect( - self._host, - self._user, - self._password, - self._database, - self._port) - - def close(self): - """Close current connection. - """ - return CTaosInterface.close(self._conn) - - def subscribe(self, restart, topic, sql, interval): - """Create a subscription. - """ - if self._conn is None: - return None - sub = CTaosInterface.subscribe( - self._conn, restart, topic, sql, interval) - return TDengineSubscription(sub) - - def cursor(self): - """Return a new Cursor object using the connection. - """ - return TDengineCursor(self) - - def commit(self): - """Commit any pending transaction to the database. - - Since TDengine do not support transactions, the implement is void functionality. - """ - pass - - def rollback(self): - """Void functionality - """ - pass - - def clear_result_set(self): - """Clear unused result set on this connection. - """ - pass - - -if __name__ == "__main__": - conn = TDengineConnection(host='192.168.1.107') - conn.close() - print("Hello world") diff --git a/src/connector/python/linux/python3/taos/constants.py b/src/connector/python/linux/python3/taos/constants.py deleted file mode 100644 index 93466f5184a6bf37c2e1c915a00aa5c5e91d1801..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/taos/constants.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Constants in TDengine python -""" - -from .dbapi import * - - -class FieldType(object): - """TDengine Field Types - """ - # type_code - C_NULL = 0 - C_BOOL = 1 - C_TINYINT = 2 - C_SMALLINT = 3 - C_INT = 4 - C_BIGINT = 5 - C_FLOAT = 6 - C_DOUBLE = 7 - C_BINARY = 8 - C_TIMESTAMP = 9 - C_NCHAR = 10 - C_TINYINT_UNSIGNED = 11 - C_SMALLINT_UNSIGNED = 12 - C_INT_UNSIGNED = 13 - C_BIGINT_UNSIGNED = 14 - # NULL value definition - # NOTE: These values should change according to C definition in tsdb.h - C_BOOL_NULL = 0x02 - C_TINYINT_NULL = -128 - C_TINYINT_UNSIGNED_NULL = 255 - C_SMALLINT_NULL = -32768 - C_SMALLINT_UNSIGNED_NULL = 65535 - C_INT_NULL = -2147483648 - C_INT_UNSIGNED_NULL = 4294967295 - C_BIGINT_NULL = -9223372036854775808 - C_BIGINT_UNSIGNED_NULL = 18446744073709551615 - C_FLOAT_NULL = float('nan') - C_DOUBLE_NULL = float('nan') - C_BINARY_NULL = bytearray([int('0xff', 16)]) - # Timestamp precision definition - C_TIMESTAMP_MILLI = 0 - C_TIMESTAMP_MICRO = 1 diff --git a/src/connector/python/linux/python3/taos/dbapi.py b/src/connector/python/linux/python3/taos/dbapi.py deleted file mode 100644 index 594681ada953abf388e503c23199043cf686e1a3..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/taos/dbapi.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Type Objects and Constructors. -""" - -import time -import datetime - - -class DBAPITypeObject(object): - def __init__(self, *values): - self.values = values - - def __com__(self, other): - if other in self.values: - return 0 - if other < self.values: - return 1 - else: - return -1 - - -Date = datetime.date -Time = datetime.time -Timestamp = datetime.datetime - - -def DataFromTicks(ticks): - return Date(*time.localtime(ticks)[:3]) - - -def TimeFromTicks(ticks): - return Time(*time.localtime(ticks)[3:6]) - - -def TimestampFromTicks(ticks): - return Timestamp(*time.localtime(ticks)[:6]) - - -Binary = bytes - -# STRING = DBAPITypeObject(*constants.FieldType.get_string_types()) -# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types()) -# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types()) -# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types()) -# ROWID = DBAPITypeObject() diff --git a/src/connector/python/linux/python3/taos/error.py b/src/connector/python/linux/python3/taos/error.py deleted file mode 100644 index c584badce8320cd35dc81e8f6b613c56163b1a29..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/taos/error.py +++ /dev/null @@ -1,66 +0,0 @@ -"""Python exceptions -""" - - -class Error(Exception): - def __init__(self, msg=None, errno=None): - self.msg = msg - self._full_msg = self.msg - self.errno = errno - - def __str__(self): - return self._full_msg - - -class Warning(Exception): - """Exception raised for important warnings like data truncations while inserting. - """ - pass - - -class InterfaceError(Error): - """Exception raised for errors that are related to the database interface rather than the database itself. - """ - pass - - -class DatabaseError(Error): - """Exception raised for errors that are related to the database. - """ - pass - - -class DataError(DatabaseError): - """Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range. - """ - pass - - -class OperationalError(DatabaseError): - """Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer - """ - pass - - -class IntegrityError(DatabaseError): - """Exception raised when the relational integrity of the database is affected. - """ - pass - - -class InternalError(DatabaseError): - """Exception raised when the database encounters an internal error. - """ - pass - - -class ProgrammingError(DatabaseError): - """Exception raised for programming errors. - """ - pass - - -class NotSupportedError(DatabaseError): - """Exception raised in case a method or database API was used which is not supported by the database,. - """ - pass diff --git a/src/connector/python/linux/python3/taos/subscription.py b/src/connector/python/linux/python3/taos/subscription.py deleted file mode 100644 index 270d9de09217fc58a389981a3542698dd1c0428a..0000000000000000000000000000000000000000 --- a/src/connector/python/linux/python3/taos/subscription.py +++ /dev/null @@ -1,57 +0,0 @@ -from .cinterface import CTaosInterface -from .error import * - - -class TDengineSubscription(object): - """TDengine subscription object - """ - - def __init__(self, sub): - self._sub = sub - - def consume(self): - """Consume rows of a subscription - """ - if self._sub is None: - raise OperationalError("Invalid use of consume") - - result, fields = CTaosInterface.consume(self._sub) - buffer = [[] for i in range(len(fields))] - while True: - block, num_of_fields = CTaosInterface.fetchBlock(result, fields) - if num_of_fields == 0: - break - for i in range(len(fields)): - buffer[i].extend(block[i]) - - self.fields = fields - return list(map(tuple, zip(*buffer))) - - def close(self, keepProgress=True): - """Close the Subscription. - """ - if self._sub is None: - return False - - CTaosInterface.unsubscribe(self._sub, keepProgress) - return True - - -if __name__ == '__main__': - from .connection import TDengineConnection - conn = TDengineConnection( - host="127.0.0.1", - user="root", - password="taosdata", - database="test") - - # Generate a cursor object to run SQL commands - sub = conn.subscribe(True, "test", "select * from meters;", 1000) - - for i in range(0, 10): - data = sub.consume() - for d in data: - print(d) - - sub.close() - conn.close() diff --git a/src/connector/python/osx/python3/LICENSE b/src/connector/python/osx/python3/LICENSE deleted file mode 100644 index 79a9d730868bfe5d3fa01d679a4abfe9ee7811f0..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ - 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 . diff --git a/src/connector/python/osx/python3/README.md b/src/connector/python/osx/python3/README.md deleted file mode 100644 index 70db6bba13a8b52b9f707400b80d1302542dbc34..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/README.md +++ /dev/null @@ -1 +0,0 @@ -# TDengine python client interface \ No newline at end of file diff --git a/src/connector/python/osx/python3/setup.py b/src/connector/python/osx/python3/setup.py deleted file mode 100644 index 4c865676c9145846e61ee789cb503b84ad424bf1..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/setup.py +++ /dev/null @@ -1,20 +0,0 @@ -import setuptools - -with open("README.md", "r") as fh: - long_description = fh.read() - -setuptools.setup( - name="taos", - version="2.0.9", - author="Taosdata Inc.", - author_email="support@taosdata.com", - description="TDengine python client package", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/pypa/sampleproject", - packages=setuptools.find_packages(), - classifiers=[ - "Programming Language :: Python :: 3", - "Operating System :: MacOS X", - ], -) diff --git a/src/connector/python/osx/python3/taos/__init__.py b/src/connector/python/osx/python3/taos/__init__.py deleted file mode 100644 index 973263573808232e4e71dc0158585624a8e7d2ab..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/taos/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ - -from .connection import TDengineConnection -from .cursor import TDengineCursor - -# Globals -threadsafety = 0 -paramstyle = 'pyformat' - -__all__ = ['connection', 'cursor'] - - -def connect(*args, **kwargs): - """ Function to return a TDengine connector object - - Current supporting keyword parameters: - @dsn: Data source name as string - @user: Username as string(optional) - @password: Password as string(optional) - @host: Hostname(optional) - @database: Database name(optional) - - @rtype: TDengineConnector - """ - return TDengineConnection(*args, **kwargs) diff --git a/src/connector/python/osx/python3/taos/cinterface.py b/src/connector/python/osx/python3/taos/cinterface.py deleted file mode 100644 index 720fbef6f5111c2ec85394498ec862c85aafbc99..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/taos/cinterface.py +++ /dev/null @@ -1,648 +0,0 @@ -import ctypes -from .constants import FieldType -from .error import * -import math -import datetime - - -def _convert_millisecond_to_datetime(milli): - return datetime.datetime.fromtimestamp(milli / 1000.0) - - -def _convert_microsecond_to_datetime(micro): - return datetime.datetime.fromtimestamp(micro / 1000000.0) - - -def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bool row to python row - """ - _timestamp_converter = _convert_millisecond_to_datetime - if micro: - _timestamp_converter = _convert_microsecond_to_datetime - - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] - - -def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bool row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_byte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_bool))[ - :abs(num_of_rows)]] - - -def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C tinyint row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] - - -def _crow_tinyint_unsigned_to_python( - data, - num_of_rows, - nbytes=None, - micro=False): - """Function to convert C tinyint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] - - -def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C smallint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] - - -def _crow_smallint_unsigned_to_python( - data, num_of_rows, nbytes=None, micro=False): - """Function to convert C smallint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] - - -def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C int row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] - - -def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C int row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] - - -def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bigint row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] - - -def _crow_bigint_unsigned_to_python( - data, - num_of_rows, - nbytes=None, - micro=False): - """Function to convert C bigint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] - - -def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C float row to python row - """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] - - -def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C double row to python row - """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] - - -def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C binary row to python row - """ - assert(nbytes is not None) - if num_of_rows > 0: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] - else: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] - - -def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C nchar row to python row - """ - assert(nbytes is not None) - res = [] - for i in range(abs(num_of_rows)): - try: - if num_of_rows >= 0: - tmpstr = ctypes.c_char_p(data) - res.append(tmpstr.value.decode()) - else: - res.append((ctypes.cast(data + nbytes * i, - ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value) - except ValueError: - res.append(None) - - return res - - -def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C binary row to python row - """ - assert(nbytes is not None) - res = [] - if num_of_rows > 0: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) - return res - - -def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C nchar row to python row - """ - assert(nbytes is not None) - res = [] - if num_of_rows >= 0: - for i in range(abs(num_of_rows)): - try: - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - res.append((ctypes.cast(data + nbytes * i + 2, - ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value) - except ValueError: - res.append(None) - return res - - -_CONVERT_FUNC = { - FieldType.C_BOOL: _crow_bool_to_python, - FieldType.C_TINYINT: _crow_tinyint_to_python, - FieldType.C_SMALLINT: _crow_smallint_to_python, - FieldType.C_INT: _crow_int_to_python, - FieldType.C_BIGINT: _crow_bigint_to_python, - FieldType.C_FLOAT: _crow_float_to_python, - FieldType.C_DOUBLE: _crow_double_to_python, - FieldType.C_BINARY: _crow_binary_to_python, - FieldType.C_TIMESTAMP: _crow_timestamp_to_python, - FieldType.C_NCHAR: _crow_nchar_to_python, - FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python, - FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, - FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, - FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python -} - -_CONVERT_FUNC_BLOCK = { - FieldType.C_BOOL: _crow_bool_to_python, - FieldType.C_TINYINT: _crow_tinyint_to_python, - FieldType.C_SMALLINT: _crow_smallint_to_python, - FieldType.C_INT: _crow_int_to_python, - FieldType.C_BIGINT: _crow_bigint_to_python, - FieldType.C_FLOAT: _crow_float_to_python, - FieldType.C_DOUBLE: _crow_double_to_python, - FieldType.C_BINARY: _crow_binary_to_python_block, - FieldType.C_TIMESTAMP: _crow_timestamp_to_python, - FieldType.C_NCHAR: _crow_nchar_to_python_block, - FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python, - FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, - FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, - FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python -} - -# Corresponding TAOS_FIELD structure in C - - -class TaosField(ctypes.Structure): - _fields_ = [('name', ctypes.c_char * 65), - ('type', ctypes.c_char), - ('bytes', ctypes.c_short)] - -# C interface class - - -class CTaosInterface(object): - - libtaos = ctypes.CDLL('libtaos.dylib') - - libtaos.taos_fetch_fields.restype = ctypes.POINTER(TaosField) - libtaos.taos_init.restype = None - libtaos.taos_connect.restype = ctypes.c_void_p - #libtaos.taos_use_result.restype = ctypes.c_void_p - libtaos.taos_fetch_row.restype = ctypes.POINTER(ctypes.c_void_p) - libtaos.taos_errstr.restype = ctypes.c_char_p - libtaos.taos_subscribe.restype = ctypes.c_void_p - libtaos.taos_consume.restype = ctypes.c_void_p - libtaos.taos_fetch_lengths.restype = ctypes.c_void_p - libtaos.taos_free_result.restype = None - libtaos.taos_errno.restype = ctypes.c_int - libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p) - - def __init__(self, config=None): - ''' - Function to initialize the class - @host : str, hostname to connect - @user : str, username to connect to server - @password : str, password to connect to server - @db : str, default db to use when log in - @config : str, config directory - - @rtype : None - ''' - if config is None: - self._config = ctypes.c_char_p(None) - else: - try: - self._config = ctypes.c_char_p(config.encode('utf-8')) - except AttributeError: - raise AttributeError("config is expected as a str") - - if config is not None: - CTaosInterface.libtaos.taos_options(3, self._config) - - CTaosInterface.libtaos.taos_init() - - @property - def config(self): - """ Get current config - """ - return self._config - - def connect( - self, - host=None, - user="root", - password="taosdata", - db=None, - port=0): - ''' - Function to connect to server - - @rtype: c_void_p, TDengine handle - ''' - # host - try: - _host = ctypes.c_char_p(host.encode( - "utf-8")) if host is not None else ctypes.c_char_p(None) - except AttributeError: - raise AttributeError("host is expected as a str") - - # user - try: - _user = ctypes.c_char_p(user.encode("utf-8")) - except AttributeError: - raise AttributeError("user is expected as a str") - - # password - try: - _password = ctypes.c_char_p(password.encode("utf-8")) - except AttributeError: - raise AttributeError("password is expected as a str") - - # db - try: - _db = ctypes.c_char_p( - db.encode("utf-8")) if db is not None else ctypes.c_char_p(None) - except AttributeError: - raise AttributeError("db is expected as a str") - - # port - try: - _port = ctypes.c_int(port) - except TypeError: - raise TypeError("port is expected as an int") - - connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect( - _host, _user, _password, _db, _port)) - - if connection.value is None: - print('connect to TDengine failed') - raise ConnectionError("connect to TDengine failed") - # sys.exit(1) - # else: - # print('connect to TDengine success') - - return connection - - @staticmethod - def close(connection): - '''Close the TDengine handle - ''' - CTaosInterface.libtaos.taos_close(connection) - #print('connection is closed') - - @staticmethod - def query(connection, sql): - '''Run SQL - - @sql: str, sql string to run - - @rtype: 0 on success and -1 on failure - ''' - try: - return CTaosInterface.libtaos.taos_query( - connection, ctypes.c_char_p(sql.encode('utf-8'))) - except AttributeError: - raise AttributeError("sql is expected as a string") - # finally: - # CTaosInterface.libtaos.close(connection) - - @staticmethod - def affectedRows(result): - """The affected rows after runing query - """ - return CTaosInterface.libtaos.taos_affected_rows(result) - - @staticmethod - def subscribe(connection, restart, topic, sql, interval): - """Create a subscription - @restart boolean, - @sql string, sql statement for data query, must be a 'select' statement. - @topic string, name of this subscription - """ - return ctypes.c_void_p(CTaosInterface.libtaos.taos_subscribe( - connection, - 1 if restart else 0, - ctypes.c_char_p(topic.encode('utf-8')), - ctypes.c_char_p(sql.encode('utf-8')), - None, - None, - interval)) - - @staticmethod - def consume(sub): - """Consume data of a subscription - """ - result = ctypes.c_void_p(CTaosInterface.libtaos.taos_consume(sub)) - fields = [] - pfields = CTaosInterface.fetchFields(result) - for i in range(CTaosInterface.libtaos.taos_num_fields(result)): - fields.append({'name': pfields[i].name.decode('utf-8'), - 'bytes': pfields[i].bytes, - 'type': ord(pfields[i].type)}) - return result, fields - - @staticmethod - def unsubscribe(sub, keepProgress): - """Cancel a subscription - """ - CTaosInterface.libtaos.taos_unsubscribe(sub, 1 if keepProgress else 0) - - @staticmethod - def useResult(result): - '''Use result after calling self.query - ''' - fields = [] - pfields = CTaosInterface.fetchFields(result) - for i in range(CTaosInterface.fieldsCount(result)): - fields.append({'name': pfields[i].name.decode('utf-8'), - 'bytes': pfields[i].bytes, - 'type': ord(pfields[i].type)}) - - return fields - - @staticmethod - def fetchBlock(result, fields): - pblock = ctypes.c_void_p(0) - num_of_rows = CTaosInterface.libtaos.taos_fetch_block( - result, ctypes.byref(pblock)) - if num_of_rows == 0: - return None, 0 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ - ele for ele in ctypes.cast( - fieldL, ctypes.POINTER( - ctypes.c_int))[ - :len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if fields[i]['type'] not in _CONVERT_FUNC_BLOCK: - raise DatabaseError("Invalid data type returned from database") - blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) - - return blocks, abs(num_of_rows) - - @staticmethod - def fetchRow(result, fields): - pblock = ctypes.c_void_p(0) - pblock = CTaosInterface.libtaos.taos_fetch_row(result) - if pblock: - num_of_rows = 1 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ - ele for ele in ctypes.cast( - fieldL, ctypes.POINTER( - ctypes.c_int))[ - :len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if fields[i]['type'] not in _CONVERT_FUNC: - raise DatabaseError( - "Invalid data type returned from database") - if data is None: - blocks[i] = [None] - else: - blocks[i] = _CONVERT_FUNC[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) - else: - return None, 0 - return blocks, abs(num_of_rows) - - @staticmethod - def freeResult(result): - CTaosInterface.libtaos.taos_free_result(result) - result.value = None - - @staticmethod - def fieldsCount(result): - return CTaosInterface.libtaos.taos_field_count(result) - - @staticmethod - def fetchFields(result): - return CTaosInterface.libtaos.taos_fetch_fields(result) - - # @staticmethod - # def fetchRow(result, fields): - # l = [] - # row = CTaosInterface.libtaos.taos_fetch_row(result) - # if not row: - # return None - - # for i in range(len(fields)): - # l.append(CTaosInterface.getDataValue( - # row[i], fields[i]['type'], fields[i]['bytes'])) - - # return tuple(l) - - # @staticmethod - # def getDataValue(data, dtype, byte): - # ''' - # ''' - # if not data: - # return None - - # if (dtype == CTaosInterface.TSDB_DATA_TYPE_BOOL): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TINYINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_SMALLINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_INT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BIGINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int64))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_FLOAT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_DOUBLE): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BINARY): - # return (ctypes.cast(data, ctypes.POINTER(ctypes.c_char))[0:byte]).rstrip('\x00') - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TIMESTAMP): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int64))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_NCHAR): - # return (ctypes.cast(data, ctypes.c_char_p).value).rstrip('\x00') - - @staticmethod - def errno(result): - """Return the error number. - """ - return CTaosInterface.libtaos.taos_errno(result) - - @staticmethod - def errStr(result): - """Return the error styring - """ - return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8') - - -if __name__ == '__main__': - cinter = CTaosInterface() - conn = cinter.connect() - result = cinter.query(conn, 'show databases') - - print('Query Affected rows: {}'.format(cinter.affectedRows(result))) - - fields = CTaosInterface.useResult(result) - - data, num_of_rows = CTaosInterface.fetchBlock(result, fields) - - print(data) - - cinter.freeResult(result) - cinter.close(conn) diff --git a/src/connector/python/osx/python3/taos/connection.py b/src/connector/python/osx/python3/taos/connection.py deleted file mode 100644 index f6c395342c9c39a24bda6022f0ed36cb7bfe045b..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/taos/connection.py +++ /dev/null @@ -1,95 +0,0 @@ -from .cursor import TDengineCursor -from .subscription import TDengineSubscription -from .cinterface import CTaosInterface - - -class TDengineConnection(object): - """ TDengine connection object - """ - - def __init__(self, *args, **kwargs): - self._conn = None - self._host = None - self._user = "root" - self._password = "taosdata" - self._database = None - self._port = 0 - self._config = None - self._chandle = None - - self.config(**kwargs) - - def config(self, **kwargs): - # host - if 'host' in kwargs: - self._host = kwargs['host'] - - # user - if 'user' in kwargs: - self._user = kwargs['user'] - - # password - if 'password' in kwargs: - self._password = kwargs['password'] - - # database - if 'database' in kwargs: - self._database = kwargs['database'] - - # port - if 'port' in kwargs: - self._port = kwargs['port'] - - # config - if 'config' in kwargs: - self._config = kwargs['config'] - - self._chandle = CTaosInterface(self._config) - self._conn = self._chandle.connect( - self._host, - self._user, - self._password, - self._database, - self._port) - - def close(self): - """Close current connection. - """ - return CTaosInterface.close(self._conn) - - def subscribe(self, restart, topic, sql, interval): - """Create a subscription. - """ - if self._conn is None: - return None - sub = CTaosInterface.subscribe( - self._conn, restart, topic, sql, interval) - return TDengineSubscription(sub) - - def cursor(self): - """Return a new Cursor object using the connection. - """ - return TDengineCursor(self) - - def commit(self): - """Commit any pending transaction to the database. - - Since TDengine do not support transactions, the implement is void functionality. - """ - pass - - def rollback(self): - """Void functionality - """ - pass - - def clear_result_set(self): - """Clear unused result set on this connection. - """ - pass - - -if __name__ == "__main__": - conn = TDengineConnection(host='192.168.1.107') - conn.close() - print("Hello world") diff --git a/src/connector/python/osx/python3/taos/constants.py b/src/connector/python/osx/python3/taos/constants.py deleted file mode 100644 index 93466f5184a6bf37c2e1c915a00aa5c5e91d1801..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/taos/constants.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Constants in TDengine python -""" - -from .dbapi import * - - -class FieldType(object): - """TDengine Field Types - """ - # type_code - C_NULL = 0 - C_BOOL = 1 - C_TINYINT = 2 - C_SMALLINT = 3 - C_INT = 4 - C_BIGINT = 5 - C_FLOAT = 6 - C_DOUBLE = 7 - C_BINARY = 8 - C_TIMESTAMP = 9 - C_NCHAR = 10 - C_TINYINT_UNSIGNED = 11 - C_SMALLINT_UNSIGNED = 12 - C_INT_UNSIGNED = 13 - C_BIGINT_UNSIGNED = 14 - # NULL value definition - # NOTE: These values should change according to C definition in tsdb.h - C_BOOL_NULL = 0x02 - C_TINYINT_NULL = -128 - C_TINYINT_UNSIGNED_NULL = 255 - C_SMALLINT_NULL = -32768 - C_SMALLINT_UNSIGNED_NULL = 65535 - C_INT_NULL = -2147483648 - C_INT_UNSIGNED_NULL = 4294967295 - C_BIGINT_NULL = -9223372036854775808 - C_BIGINT_UNSIGNED_NULL = 18446744073709551615 - C_FLOAT_NULL = float('nan') - C_DOUBLE_NULL = float('nan') - C_BINARY_NULL = bytearray([int('0xff', 16)]) - # Timestamp precision definition - C_TIMESTAMP_MILLI = 0 - C_TIMESTAMP_MICRO = 1 diff --git a/src/connector/python/osx/python3/taos/cursor.py b/src/connector/python/osx/python3/taos/cursor.py deleted file mode 100644 index 32dc0ea3c3676c61c65bf92b4fb04a5373314126..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/taos/cursor.py +++ /dev/null @@ -1,280 +0,0 @@ -from .cinterface import CTaosInterface -from .error import * -from .constants import FieldType - -# querySeqNum = 0 - - -class TDengineCursor(object): - """Database cursor which is used to manage the context of a fetch operation. - - Attributes: - .description: Read-only attribute consists of 7-item sequences: - - > name (mondatory) - > type_code (mondatory) - > display_size - > internal_size - > precision - > scale - > null_ok - - This attribute will be None for operations that do not return rows or - if the cursor has not had an operation invoked via the .execute*() method yet. - - .rowcount:This read-only attribute specifies the number of rows that the last - .execute*() produced (for DQL statements like SELECT) or affected - """ - - def __init__(self, connection=None): - self._description = [] - self._rowcount = -1 - self._connection = None - self._result = None - self._fields = None - self._block = None - self._block_rows = -1 - self._block_iter = 0 - self._affected_rows = 0 - self._logfile = "" - - if connection is not None: - self._connection = connection - - def __iter__(self): - return self - - def __next__(self): - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetch iterator") - - if self._block_rows <= self._block_iter: - block, self._block_rows = CTaosInterface.fetchRow( - self._result, self._fields) - if self._block_rows == 0: - raise StopIteration - self._block = list(map(tuple, zip(*block))) - self._block_iter = 0 - - data = self._block[self._block_iter] - self._block_iter += 1 - - return data - - @property - def description(self): - """Return the description of the object. - """ - return self._description - - @property - def rowcount(self): - """Return the rowcount of the object - """ - return self._rowcount - - @property - def affected_rows(self): - """Return the rowcount of insertion - """ - return self._affected_rows - - def callproc(self, procname, *args): - """Call a stored database procedure with the given name. - - Void functionality since no stored procedures. - """ - pass - - def log(self, logfile): - self._logfile = logfile - - def close(self): - """Close the cursor. - """ - if self._connection is None: - return False - - self._reset_result() - self._connection = None - - return True - - def execute(self, operation, params=None): - """Prepare and execute a database operation (query or command). - """ - if not operation: - return None - - if not self._connection: - # TODO : change the exception raised here - raise ProgrammingError("Cursor is not connected") - - self._reset_result() - - stmt = operation - if params is not None: - pass - - # global querySeqNum - # querySeqNum += 1 - # localSeqNum = querySeqNum # avoid raice condition - # print(" >> Exec Query ({}): {}".format(localSeqNum, str(stmt))) - self._result = CTaosInterface.query(self._connection._conn, stmt) - # print(" << Query ({}) Exec Done".format(localSeqNum)) - if (self._logfile): - with open(self._logfile, "a") as logfile: - logfile.write("%s;\n" % operation) - - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno == 0: - if CTaosInterface.fieldsCount(self._result) == 0: - self._affected_rows += CTaosInterface.affectedRows( - self._result) - return CTaosInterface.affectedRows(self._result) - else: - self._fields = CTaosInterface.useResult( - self._result) - return self._handle_result() - else: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - - def executemany(self, operation, seq_of_parameters): - """Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters. - """ - pass - - def fetchone(self): - """Fetch the next row of a query result set, returning a single sequence, or None when no more data is available. - """ - pass - - def fetchmany(self): - pass - - def istype(self, col, dataType): - if (dataType.upper() == "BOOL"): - if (self._description[col][1] == FieldType.C_BOOL): - return True - if (dataType.upper() == "TINYINT"): - if (self._description[col][1] == FieldType.C_TINYINT): - return True - if (dataType.upper() == "TINYINT UNSIGNED"): - if (self._description[col][1] == FieldType.C_TINYINT_UNSIGNED): - return True - if (dataType.upper() == "SMALLINT"): - if (self._description[col][1] == FieldType.C_SMALLINT): - return True - if (dataType.upper() == "SMALLINT UNSIGNED"): - if (self._description[col][1] == FieldType.C_SMALLINT_UNSIGNED): - return True - if (dataType.upper() == "INT"): - if (self._description[col][1] == FieldType.C_INT): - return True - if (dataType.upper() == "INT UNSIGNED"): - if (self._description[col][1] == FieldType.C_INT_UNSIGNED): - return True - if (dataType.upper() == "BIGINT"): - if (self._description[col][1] == FieldType.C_BIGINT): - return True - if (dataType.upper() == "BIGINT UNSIGNED"): - if (self._description[col][1] == FieldType.C_BIGINT_UNSIGNED): - return True - if (dataType.upper() == "FLOAT"): - if (self._description[col][1] == FieldType.C_FLOAT): - return True - if (dataType.upper() == "DOUBLE"): - if (self._description[col][1] == FieldType.C_DOUBLE): - return True - if (dataType.upper() == "BINARY"): - if (self._description[col][1] == FieldType.C_BINARY): - return True - if (dataType.upper() == "TIMESTAMP"): - if (self._description[col][1] == FieldType.C_TIMESTAMP): - return True - if (dataType.upper() == "NCHAR"): - if (self._description[col][1] == FieldType.C_NCHAR): - return True - - return False - - def fetchall_row(self): - """Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation. - """ - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetchall") - - buffer = [[] for i in range(len(self._fields))] - self._rowcount = 0 - while True: - block, num_of_fields = CTaosInterface.fetchRow( - self._result, self._fields) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno != 0: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - if num_of_fields == 0: - break - self._rowcount += num_of_fields - for i in range(len(self._fields)): - buffer[i].extend(block[i]) - return list(map(tuple, zip(*buffer))) - - def fetchall(self): - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetchall") - - buffer = [[] for i in range(len(self._fields))] - self._rowcount = 0 - while True: - block, num_of_fields = CTaosInterface.fetchBlock( - self._result, self._fields) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno != 0: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - if num_of_fields == 0: - break - self._rowcount += num_of_fields - for i in range(len(self._fields)): - buffer[i].extend(block[i]) - return list(map(tuple, zip(*buffer))) - - def nextset(self): - """ - """ - pass - - def setinputsize(self, sizes): - pass - - def setutputsize(self, size, column=None): - pass - - def _reset_result(self): - """Reset the result to unused version. - """ - self._description = [] - self._rowcount = -1 - if self._result is not None: - CTaosInterface.freeResult(self._result) - self._result = None - self._fields = None - self._block = None - self._block_rows = -1 - self._block_iter = 0 - self._affected_rows = 0 - - def _handle_result(self): - """Handle the return result from query. - """ - self._description = [] - for ele in self._fields: - self._description.append( - (ele['name'], ele['type'], None, None, None, None, False)) - - return self._result diff --git a/src/connector/python/osx/python3/taos/dbapi.py b/src/connector/python/osx/python3/taos/dbapi.py deleted file mode 100644 index 594681ada953abf388e503c23199043cf686e1a3..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/taos/dbapi.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Type Objects and Constructors. -""" - -import time -import datetime - - -class DBAPITypeObject(object): - def __init__(self, *values): - self.values = values - - def __com__(self, other): - if other in self.values: - return 0 - if other < self.values: - return 1 - else: - return -1 - - -Date = datetime.date -Time = datetime.time -Timestamp = datetime.datetime - - -def DataFromTicks(ticks): - return Date(*time.localtime(ticks)[:3]) - - -def TimeFromTicks(ticks): - return Time(*time.localtime(ticks)[3:6]) - - -def TimestampFromTicks(ticks): - return Timestamp(*time.localtime(ticks)[:6]) - - -Binary = bytes - -# STRING = DBAPITypeObject(*constants.FieldType.get_string_types()) -# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types()) -# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types()) -# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types()) -# ROWID = DBAPITypeObject() diff --git a/src/connector/python/osx/python3/taos/error.py b/src/connector/python/osx/python3/taos/error.py deleted file mode 100644 index c584badce8320cd35dc81e8f6b613c56163b1a29..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/taos/error.py +++ /dev/null @@ -1,66 +0,0 @@ -"""Python exceptions -""" - - -class Error(Exception): - def __init__(self, msg=None, errno=None): - self.msg = msg - self._full_msg = self.msg - self.errno = errno - - def __str__(self): - return self._full_msg - - -class Warning(Exception): - """Exception raised for important warnings like data truncations while inserting. - """ - pass - - -class InterfaceError(Error): - """Exception raised for errors that are related to the database interface rather than the database itself. - """ - pass - - -class DatabaseError(Error): - """Exception raised for errors that are related to the database. - """ - pass - - -class DataError(DatabaseError): - """Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range. - """ - pass - - -class OperationalError(DatabaseError): - """Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer - """ - pass - - -class IntegrityError(DatabaseError): - """Exception raised when the relational integrity of the database is affected. - """ - pass - - -class InternalError(DatabaseError): - """Exception raised when the database encounters an internal error. - """ - pass - - -class ProgrammingError(DatabaseError): - """Exception raised for programming errors. - """ - pass - - -class NotSupportedError(DatabaseError): - """Exception raised in case a method or database API was used which is not supported by the database,. - """ - pass diff --git a/src/connector/python/osx/python3/taos/subscription.py b/src/connector/python/osx/python3/taos/subscription.py deleted file mode 100644 index 270d9de09217fc58a389981a3542698dd1c0428a..0000000000000000000000000000000000000000 --- a/src/connector/python/osx/python3/taos/subscription.py +++ /dev/null @@ -1,57 +0,0 @@ -from .cinterface import CTaosInterface -from .error import * - - -class TDengineSubscription(object): - """TDengine subscription object - """ - - def __init__(self, sub): - self._sub = sub - - def consume(self): - """Consume rows of a subscription - """ - if self._sub is None: - raise OperationalError("Invalid use of consume") - - result, fields = CTaosInterface.consume(self._sub) - buffer = [[] for i in range(len(fields))] - while True: - block, num_of_fields = CTaosInterface.fetchBlock(result, fields) - if num_of_fields == 0: - break - for i in range(len(fields)): - buffer[i].extend(block[i]) - - self.fields = fields - return list(map(tuple, zip(*buffer))) - - def close(self, keepProgress=True): - """Close the Subscription. - """ - if self._sub is None: - return False - - CTaosInterface.unsubscribe(self._sub, keepProgress) - return True - - -if __name__ == '__main__': - from .connection import TDengineConnection - conn = TDengineConnection( - host="127.0.0.1", - user="root", - password="taosdata", - database="test") - - # Generate a cursor object to run SQL commands - sub = conn.subscribe(True, "test", "select * from meters;", 1000) - - for i in range(0, 10): - data = sub.consume() - for d in data: - print(d) - - sub.close() - conn.close() diff --git a/src/connector/python/setup.py b/src/connector/python/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..901e8396c0440bd1c90163f0360b687dd5684ff3 --- /dev/null +++ b/src/connector/python/setup.py @@ -0,0 +1,34 @@ +import setuptools + +with open("README.md", "r") as fh: + long_description = fh.read() + +setuptools.setup( + name="taos", + version="2.0.10", + author="Taosdata Inc.", + author_email="support@taosdata.com", + description="TDengine python client package", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/taosdata/TDengine/tree/develop/src/connector/python", + packages=setuptools.find_packages(), + classifiers=[ + "Environment :: Console", + "Environment :: MacOS X", + "Environment :: Win32 (MS Windows)", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", + "Operating System :: MacOS", + "Programming Language :: Python :: 2.7", + "Operating System :: Linux", + "Operating System :: POSIX :: Linux", + "Operating System :: Microsoft :: Windows", + "Operating System :: Microsoft :: Windows :: Windows 10", + ], +) diff --git a/src/connector/python/linux/python2/taos/__init__.py b/src/connector/python/taos/__init__.py similarity index 100% rename from src/connector/python/linux/python2/taos/__init__.py rename to src/connector/python/taos/__init__.py diff --git a/src/connector/python/linux/python2/taos/cinterface.py b/src/connector/python/taos/cinterface.py similarity index 70% rename from src/connector/python/linux/python2/taos/cinterface.py rename to src/connector/python/taos/cinterface.py index 3d0ecd290156b71e2d738fe7d3693763e0047338..b8824327b017fc0bb7f9639942e20e72891ac808 100644 --- a/src/connector/python/linux/python2/taos/cinterface.py +++ b/src/connector/python/taos/cinterface.py @@ -3,6 +3,7 @@ from .constants import FieldType from .error import * import math import datetime +import platform def _convert_millisecond_to_datetime(milli): @@ -20,46 +21,28 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): if micro: _timestamp_converter = _convert_microsecond_to_datetime - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] + return [ + None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( + data, ctypes.POINTER( + ctypes.c_int64))[ + :abs(num_of_rows)]] def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bool row to python row """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_byte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_bool))[ - :abs(num_of_rows)]] + return [ + None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( + data, ctypes.POINTER( + ctypes.c_byte))[ + :abs(num_of_rows)]] def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C tinyint row to python row """ - if num_of_rows > 0: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] + return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( + data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] def _crow_tinyint_unsigned_to_python( @@ -69,92 +52,56 @@ def _crow_tinyint_unsigned_to_python( micro=False): """Function to convert C tinyint row to python row """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] + return [ + None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( + data, ctypes.POINTER( + ctypes.c_ubyte))[ + :abs(num_of_rows)]] def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C smallint row to python row """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] + return [ + None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( + data, ctypes.POINTER( + ctypes.c_short))[ + :abs(num_of_rows)]] def _crow_smallint_unsigned_to_python( data, num_of_rows, nbytes=None, micro=False): """Function to convert C smallint row to python row """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] + return [ + None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( + data, ctypes.POINTER( + ctypes.c_ushort))[ + :abs(num_of_rows)]] def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C int row to python row """ - if num_of_rows > 0: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] + return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( + data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C int row to python row """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] + return [ + None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( + data, ctypes.POINTER( + ctypes.c_uint))[ + :abs(num_of_rows)]] def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bigint row to python row """ - if num_of_rows > 0: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] + return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( + data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] def _crow_bigint_unsigned_to_python( @@ -164,52 +111,33 @@ def _crow_bigint_unsigned_to_python( micro=False): """Function to convert C bigint row to python row """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] + return [ + None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( + data, ctypes.POINTER( + ctypes.c_uint64))[ + :abs(num_of_rows)]] def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C float row to python row """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] + return [None if math.isnan(ele) else ele for ele in ctypes.cast( + data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C double row to python row """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] + return [None if math.isnan(ele) else ele for ele in ctypes.cast( + data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ assert(nbytes is not None) - if num_of_rows > 0: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] - else: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] + return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( + 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): @@ -236,30 +164,17 @@ def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): """ assert(nbytes is not None) res = [] - if num_of_rows > 0: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) + for i in range(abs(num_of_rows)): + try: + rbyte = ctypes.cast( + data + nbytes * i, + ctypes.POINTER( + ctypes.c_short))[ + :1].pop() + tmpstr = ctypes.c_char_p(data + nbytes * i + 2) + res.append(tmpstr.value.decode()[0:rbyte]) + except ValueError: + res.append(None) return res @@ -268,20 +183,12 @@ def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False): """ assert(nbytes is not None) res = [] - if num_of_rows >= 0: - for i in range(abs(num_of_rows)): - try: - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - res.append((ctypes.cast(data + nbytes * i + 2, - ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value) - except ValueError: - res.append(None) + for i in range(abs(num_of_rows)): + try: + tmpstr = ctypes.c_char_p(data + nbytes * i + 2) + res.append(tmpstr.value.decode()) + except ValueError: + res.append(None) return res @@ -330,14 +237,38 @@ class TaosField(ctypes.Structure): # C interface class +def _load_taos_linux(): + return ctypes.CDLL('libtaos.so') + + +def _load_taos_darwin(): + return ctypes.cDLL('libtaos.dylib') + + +def _load_taos_windows(): + return ctypes.windll.LoadLibrary('taos') + + +def _load_taos(): + load_func = { + 'Linux': _load_taos_linux, + 'Darwin': _load_taos_darwin, + 'Windows': _load_taos_windows, + } + try: + return load_func[platform.system()]() + except: + sys.exit('unsupported platform to TDengine connector') + + class CTaosInterface(object): - libtaos = ctypes.CDLL('libtaos.so') + libtaos = _load_taos() libtaos.taos_fetch_fields.restype = ctypes.POINTER(TaosField) libtaos.taos_init.restype = None libtaos.taos_connect.restype = ctypes.c_void_p - #libtaos.taos_use_result.restype = ctypes.c_void_p + # libtaos.taos_use_result.restype = ctypes.c_void_p libtaos.taos_fetch_row.restype = ctypes.POINTER(ctypes.c_void_p) libtaos.taos_errstr.restype = ctypes.c_char_p libtaos.taos_subscribe.restype = ctypes.c_void_p @@ -438,7 +369,7 @@ class CTaosInterface(object): '''Close the TDengine handle ''' CTaosInterface.libtaos.taos_close(connection) - #print('connection is closed') + # print('connection is closed') @staticmethod def query(connection, sql): diff --git a/src/connector/python/linux/python2/taos/connection.py b/src/connector/python/taos/connection.py similarity index 100% rename from src/connector/python/linux/python2/taos/connection.py rename to src/connector/python/taos/connection.py diff --git a/src/connector/python/linux/python2/taos/constants.py b/src/connector/python/taos/constants.py similarity index 100% rename from src/connector/python/linux/python2/taos/constants.py rename to src/connector/python/taos/constants.py diff --git a/src/connector/python/linux/python3/taos/cursor.py b/src/connector/python/taos/cursor.py similarity index 98% rename from src/connector/python/linux/python3/taos/cursor.py rename to src/connector/python/taos/cursor.py index 32dc0ea3c3676c61c65bf92b4fb04a5373314126..d443ec95d07bd970da96c6280674dd5c9477a38f 100644 --- a/src/connector/python/linux/python3/taos/cursor.py +++ b/src/connector/python/taos/cursor.py @@ -45,6 +45,12 @@ class TDengineCursor(object): return self def __next__(self): + return self._taos_next() + + def next(self): + return self._taos_next() + + def _taos_next(self): if self._result is None or self._fields is None: raise OperationalError("Invalid use of fetch iterator") diff --git a/src/connector/python/linux/python2/taos/dbapi.py b/src/connector/python/taos/dbapi.py similarity index 100% rename from src/connector/python/linux/python2/taos/dbapi.py rename to src/connector/python/taos/dbapi.py diff --git a/src/connector/python/linux/python2/taos/error.py b/src/connector/python/taos/error.py similarity index 100% rename from src/connector/python/linux/python2/taos/error.py rename to src/connector/python/taos/error.py diff --git a/src/connector/python/linux/python2/taos/subscription.py b/src/connector/python/taos/subscription.py similarity index 100% rename from src/connector/python/linux/python2/taos/subscription.py rename to src/connector/python/taos/subscription.py diff --git a/src/connector/python/windows/python2/LICENSE b/src/connector/python/windows/python2/LICENSE deleted file mode 100644 index 79a9d730868bfe5d3fa01d679a4abfe9ee7811f0..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ - 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 . diff --git a/src/connector/python/windows/python2/README.md b/src/connector/python/windows/python2/README.md deleted file mode 100644 index 70db6bba13a8b52b9f707400b80d1302542dbc34..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/README.md +++ /dev/null @@ -1 +0,0 @@ -# TDengine python client interface \ No newline at end of file diff --git a/src/connector/python/windows/python2/setup.py b/src/connector/python/windows/python2/setup.py deleted file mode 100644 index 24d75f937cdb2a61cd2330138c0575e4ccbe2875..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/setup.py +++ /dev/null @@ -1,20 +0,0 @@ -import setuptools - -with open("README.md", "r") as fh: - long_description = fh.read() - -setuptools.setup( - name="taos", - version="2.0.9", - author="Taosdata Inc.", - author_email="support@taosdata.com", - description="TDengine python client package", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/pypa/sampleproject", - packages=setuptools.find_packages(), - classifiers=[ - "Programming Language :: Python :: 2", - "Operating System :: Windows", - ], -) diff --git a/src/connector/python/windows/python2/taos/__init__.py b/src/connector/python/windows/python2/taos/__init__.py deleted file mode 100644 index 973263573808232e4e71dc0158585624a8e7d2ab..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/taos/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ - -from .connection import TDengineConnection -from .cursor import TDengineCursor - -# Globals -threadsafety = 0 -paramstyle = 'pyformat' - -__all__ = ['connection', 'cursor'] - - -def connect(*args, **kwargs): - """ Function to return a TDengine connector object - - Current supporting keyword parameters: - @dsn: Data source name as string - @user: Username as string(optional) - @password: Password as string(optional) - @host: Hostname(optional) - @database: Database name(optional) - - @rtype: TDengineConnector - """ - return TDengineConnection(*args, **kwargs) diff --git a/src/connector/python/windows/python2/taos/cinterface.py b/src/connector/python/windows/python2/taos/cinterface.py deleted file mode 100644 index 65cb183f26978dc83553b3e88a5c6599ccc1dd48..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/taos/cinterface.py +++ /dev/null @@ -1,648 +0,0 @@ -import ctypes -from .constants import FieldType -from .error import * -import math -import datetime - - -def _convert_millisecond_to_datetime(milli): - return datetime.datetime.fromtimestamp(milli / 1000.0) - - -def _convert_microsecond_to_datetime(micro): - return datetime.datetime.fromtimestamp(micro / 1000000.0) - - -def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bool row to python row - """ - _timestamp_converter = _convert_millisecond_to_datetime - if micro: - _timestamp_converter = _convert_microsecond_to_datetime - - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] - - -def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bool row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_byte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_bool))[ - :abs(num_of_rows)]] - - -def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C tinyint row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] - - -def _crow_tinyint_unsigned_to_python( - data, - num_of_rows, - nbytes=None, - micro=False): - """Function to convert C tinyint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] - - -def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C smallint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] - - -def _crow_smallint_unsigned_to_python( - data, num_of_rows, nbytes=None, micro=False): - """Function to convert C smallint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] - - -def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C int row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] - - -def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C int row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] - - -def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bigint row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] - - -def _crow_bigint_unsigned_to_python( - data, - num_of_rows, - nbytes=None, - micro=False): - """Function to convert C bigint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] - - -def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C float row to python row - """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] - - -def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C double row to python row - """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] - - -def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C binary row to python row - """ - assert(nbytes is not None) - if num_of_rows > 0: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] - else: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] - - -def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C nchar row to python row - """ - assert(nbytes is not None) - res = [] - for i in range(abs(num_of_rows)): - try: - if num_of_rows >= 0: - tmpstr = ctypes.c_char_p(data) - res.append(tmpstr.value.decode()) - else: - res.append((ctypes.cast(data + nbytes * i, - ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value) - except ValueError: - res.append(None) - - return res - - -def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C binary row to python row - """ - assert(nbytes is not None) - res = [] - if num_of_rows > 0: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) - return res - - -def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C nchar row to python row - """ - assert(nbytes is not None) - res = [] - if num_of_rows >= 0: - for i in range(abs(num_of_rows)): - try: - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - res.append((ctypes.cast(data + nbytes * i + 2, - ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value) - except ValueError: - res.append(None) - return res - - -_CONVERT_FUNC = { - FieldType.C_BOOL: _crow_bool_to_python, - FieldType.C_TINYINT: _crow_tinyint_to_python, - FieldType.C_SMALLINT: _crow_smallint_to_python, - FieldType.C_INT: _crow_int_to_python, - FieldType.C_BIGINT: _crow_bigint_to_python, - FieldType.C_FLOAT: _crow_float_to_python, - FieldType.C_DOUBLE: _crow_double_to_python, - FieldType.C_BINARY: _crow_binary_to_python, - FieldType.C_TIMESTAMP: _crow_timestamp_to_python, - FieldType.C_NCHAR: _crow_nchar_to_python, - FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python, - FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, - FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, - FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python -} - -_CONVERT_FUNC_BLOCK = { - FieldType.C_BOOL: _crow_bool_to_python, - FieldType.C_TINYINT: _crow_tinyint_to_python, - FieldType.C_SMALLINT: _crow_smallint_to_python, - FieldType.C_INT: _crow_int_to_python, - FieldType.C_BIGINT: _crow_bigint_to_python, - FieldType.C_FLOAT: _crow_float_to_python, - FieldType.C_DOUBLE: _crow_double_to_python, - FieldType.C_BINARY: _crow_binary_to_python_block, - FieldType.C_TIMESTAMP: _crow_timestamp_to_python, - FieldType.C_NCHAR: _crow_nchar_to_python_block, - FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python, - FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, - FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, - FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python -} - -# Corresponding TAOS_FIELD structure in C - - -class TaosField(ctypes.Structure): - _fields_ = [('name', ctypes.c_char * 65), - ('type', ctypes.c_char), - ('bytes', ctypes.c_short)] - -# C interface class - - -class CTaosInterface(object): - - libtaos = ctypes.windll.LoadLibrary('taos') - - libtaos.taos_fetch_fields.restype = ctypes.POINTER(TaosField) - libtaos.taos_init.restype = None - libtaos.taos_connect.restype = ctypes.c_void_p - #libtaos.taos_use_result.restype = ctypes.c_void_p - libtaos.taos_fetch_row.restype = ctypes.POINTER(ctypes.c_void_p) - libtaos.taos_errstr.restype = ctypes.c_char_p - libtaos.taos_subscribe.restype = ctypes.c_void_p - libtaos.taos_consume.restype = ctypes.c_void_p - libtaos.taos_fetch_lengths.restype = ctypes.c_void_p - libtaos.taos_free_result.restype = None - libtaos.taos_errno.restype = ctypes.c_int - libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p) - - def __init__(self, config=None): - ''' - Function to initialize the class - @host : str, hostname to connect - @user : str, username to connect to server - @password : str, password to connect to server - @db : str, default db to use when log in - @config : str, config directory - - @rtype : None - ''' - if config is None: - self._config = ctypes.c_char_p(None) - else: - try: - self._config = ctypes.c_char_p(config.encode('utf-8')) - except AttributeError: - raise AttributeError("config is expected as a str") - - if config is not None: - CTaosInterface.libtaos.taos_options(3, self._config) - - CTaosInterface.libtaos.taos_init() - - @property - def config(self): - """ Get current config - """ - return self._config - - def connect( - self, - host=None, - user="root", - password="taosdata", - db=None, - port=0): - ''' - Function to connect to server - - @rtype: c_void_p, TDengine handle - ''' - # host - try: - _host = ctypes.c_char_p(host.encode( - "utf-8")) if host is not None else ctypes.c_char_p(None) - except AttributeError: - raise AttributeError("host is expected as a str") - - # user - try: - _user = ctypes.c_char_p(user.encode("utf-8")) - except AttributeError: - raise AttributeError("user is expected as a str") - - # password - try: - _password = ctypes.c_char_p(password.encode("utf-8")) - except AttributeError: - raise AttributeError("password is expected as a str") - - # db - try: - _db = ctypes.c_char_p( - db.encode("utf-8")) if db is not None else ctypes.c_char_p(None) - except AttributeError: - raise AttributeError("db is expected as a str") - - # port - try: - _port = ctypes.c_int(port) - except TypeError: - raise TypeError("port is expected as an int") - - connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect( - _host, _user, _password, _db, _port)) - - if connection.value is None: - print('connect to TDengine failed') - raise ConnectionError("connect to TDengine failed") - # sys.exit(1) - # else: - # print('connect to TDengine success') - - return connection - - @staticmethod - def close(connection): - '''Close the TDengine handle - ''' - CTaosInterface.libtaos.taos_close(connection) - #print('connection is closed') - - @staticmethod - def query(connection, sql): - '''Run SQL - - @sql: str, sql string to run - - @rtype: 0 on success and -1 on failure - ''' - try: - return CTaosInterface.libtaos.taos_query( - connection, ctypes.c_char_p(sql.encode('utf-8'))) - except AttributeError: - raise AttributeError("sql is expected as a string") - # finally: - # CTaosInterface.libtaos.close(connection) - - @staticmethod - def affectedRows(result): - """The affected rows after runing query - """ - return CTaosInterface.libtaos.taos_affected_rows(result) - - @staticmethod - def subscribe(connection, restart, topic, sql, interval): - """Create a subscription - @restart boolean, - @sql string, sql statement for data query, must be a 'select' statement. - @topic string, name of this subscription - """ - return ctypes.c_void_p(CTaosInterface.libtaos.taos_subscribe( - connection, - 1 if restart else 0, - ctypes.c_char_p(topic.encode('utf-8')), - ctypes.c_char_p(sql.encode('utf-8')), - None, - None, - interval)) - - @staticmethod - def consume(sub): - """Consume data of a subscription - """ - result = ctypes.c_void_p(CTaosInterface.libtaos.taos_consume(sub)) - fields = [] - pfields = CTaosInterface.fetchFields(result) - for i in range(CTaosInterface.libtaos.taos_num_fields(result)): - fields.append({'name': pfields[i].name.decode('utf-8'), - 'bytes': pfields[i].bytes, - 'type': ord(pfields[i].type)}) - return result, fields - - @staticmethod - def unsubscribe(sub, keepProgress): - """Cancel a subscription - """ - CTaosInterface.libtaos.taos_unsubscribe(sub, 1 if keepProgress else 0) - - @staticmethod - def useResult(result): - '''Use result after calling self.query - ''' - fields = [] - pfields = CTaosInterface.fetchFields(result) - for i in range(CTaosInterface.fieldsCount(result)): - fields.append({'name': pfields[i].name.decode('utf-8'), - 'bytes': pfields[i].bytes, - 'type': ord(pfields[i].type)}) - - return fields - - @staticmethod - def fetchBlock(result, fields): - pblock = ctypes.c_void_p(0) - num_of_rows = CTaosInterface.libtaos.taos_fetch_block( - result, ctypes.byref(pblock)) - if num_of_rows == 0: - return None, 0 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ - ele for ele in ctypes.cast( - fieldL, ctypes.POINTER( - ctypes.c_int))[ - :len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if fields[i]['type'] not in _CONVERT_FUNC_BLOCK: - raise DatabaseError("Invalid data type returned from database") - blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) - - return blocks, abs(num_of_rows) - - @staticmethod - def fetchRow(result, fields): - pblock = ctypes.c_void_p(0) - pblock = CTaosInterface.libtaos.taos_fetch_row(result) - if pblock: - num_of_rows = 1 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ - ele for ele in ctypes.cast( - fieldL, ctypes.POINTER( - ctypes.c_int))[ - :len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if fields[i]['type'] not in _CONVERT_FUNC: - raise DatabaseError( - "Invalid data type returned from database") - if data is None: - blocks[i] = [None] - else: - blocks[i] = _CONVERT_FUNC[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) - else: - return None, 0 - return blocks, abs(num_of_rows) - - @staticmethod - def freeResult(result): - CTaosInterface.libtaos.taos_free_result(result) - result.value = None - - @staticmethod - def fieldsCount(result): - return CTaosInterface.libtaos.taos_field_count(result) - - @staticmethod - def fetchFields(result): - return CTaosInterface.libtaos.taos_fetch_fields(result) - - # @staticmethod - # def fetchRow(result, fields): - # l = [] - # row = CTaosInterface.libtaos.taos_fetch_row(result) - # if not row: - # return None - - # for i in range(len(fields)): - # l.append(CTaosInterface.getDataValue( - # row[i], fields[i]['type'], fields[i]['bytes'])) - - # return tuple(l) - - # @staticmethod - # def getDataValue(data, dtype, byte): - # ''' - # ''' - # if not data: - # return None - - # if (dtype == CTaosInterface.TSDB_DATA_TYPE_BOOL): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TINYINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_SMALLINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_INT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BIGINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int64))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_FLOAT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_DOUBLE): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BINARY): - # return (ctypes.cast(data, ctypes.POINTER(ctypes.c_char))[0:byte]).rstrip('\x00') - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TIMESTAMP): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int64))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_NCHAR): - # return (ctypes.cast(data, ctypes.c_char_p).value).rstrip('\x00') - - @staticmethod - def errno(result): - """Return the error number. - """ - return CTaosInterface.libtaos.taos_errno(result) - - @staticmethod - def errStr(result): - """Return the error styring - """ - return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8') - - -if __name__ == '__main__': - cinter = CTaosInterface() - conn = cinter.connect() - result = cinter.query(conn, 'show databases') - - print('Query Affected rows: {}'.format(cinter.affectedRows(result))) - - fields = CTaosInterface.useResult(result) - - data, num_of_rows = CTaosInterface.fetchBlock(result, fields) - - print(data) - - cinter.freeResult(result) - cinter.close(conn) diff --git a/src/connector/python/windows/python2/taos/connection.py b/src/connector/python/windows/python2/taos/connection.py deleted file mode 100644 index 5729d01c6df8c0e58086726c4001467811e9fee5..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/taos/connection.py +++ /dev/null @@ -1,96 +0,0 @@ -from .cursor import TDengineCursor -from .subscription import TDengineSubscription -from .cinterface import CTaosInterface - - -class TDengineConnection(object): - """ TDengine connection object - """ - - def __init__(self, *args, **kwargs): - self._conn = None - self._host = None - self._user = "root" - self._password = "taosdata" - self._database = None - self._port = 0 - self._config = None - self._chandle = None - - if len(kwargs) > 0: - self.config(**kwargs) - - def config(self, **kwargs): - # host - if 'host' in kwargs: - self._host = kwargs['host'] - - # user - if 'user' in kwargs: - self._user = kwargs['user'] - - # password - if 'password' in kwargs: - self._password = kwargs['password'] - - # database - if 'database' in kwargs: - self._database = kwargs['database'] - - # port - if 'port' in kwargs: - self._port = kwargs['port'] - - # config - if 'config' in kwargs: - self._config = kwargs['config'] - - self._chandle = CTaosInterface(self._config) - self._conn = self._chandle.connect( - self._host, - self._user, - self._password, - self._database, - self._port) - - def close(self): - """Close current connection. - """ - return CTaosInterface.close(self._conn) - - def subscribe(self, restart, topic, sql, interval): - """Create a subscription. - """ - if self._conn is None: - return None - sub = CTaosInterface.subscribe( - self._conn, restart, topic, sql, interval) - return TDengineSubscription(sub) - - def cursor(self): - """Return a new Cursor object using the connection. - """ - return TDengineCursor(self) - - def commit(self): - """Commit any pending transaction to the database. - - Since TDengine do not support transactions, the implement is void functionality. - """ - pass - - def rollback(self): - """Void functionality - """ - pass - - def clear_result_set(self): - """Clear unused result set on this connection. - """ - pass - - -if __name__ == "__main__": - conn = TDengineConnection(host='192.168.1.107') - conn.close() - print("Hello world") diff --git a/src/connector/python/windows/python2/taos/constants.py b/src/connector/python/windows/python2/taos/constants.py deleted file mode 100644 index 8a8011c3e36c52993e9d03228c2a50e2af6a7c9e..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/taos/constants.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Constants in TDengine python -""" - -from .dbapi import * - - -class FieldType(object): - """TDengine Field Types - """ - # type_code - C_NULL = 0 - C_BOOL = 1 - C_TINYINT = 2 - C_SMALLINT = 3 - C_INT = 4 - C_BIGINT = 5 - C_FLOAT = 6 - C_DOUBLE = 7 - C_BINARY = 8 - C_TIMESTAMP = 9 - C_NCHAR = 10 - C_TINYINT_UNSIGNED = 11 - C_SMALLINT_UNSIGNED = 12 - C_INT_UNSIGNED = 13 - C_BIGINT_UNSIGNED = 14 - # NULL value definition - # NOTE: These values should change according to C definition in tsdb.h - C_BOOL_NULL = 0x02 - C_TINYINT_NULL = -128 - C_TINYINT_UNSIGNED_NULL = 255 - C_SMALLINT_NULL = -32768 - C_SMALLINT_UNSIGNED_NULL = 65535 - C_INT_NULL = -2147483648 - C_INT_UNSIGNED_NULL = 4294967295 - C_BIGINT_NULL = -9223372036854775808 - C_BIGINT_UNSIGNED_NULL = 18446744073709551615 - C_FLOAT_NULL = float('nan') - C_DOUBLE_NULL = float('nan') - C_BINARY_NULL = bytearray([int('0xff', 16)]) - # Time precision definition - C_TIMESTAMP_MILLI = 0 - C_TIMESTAMP_MICRO = 1 diff --git a/src/connector/python/windows/python2/taos/cursor.py b/src/connector/python/windows/python2/taos/cursor.py deleted file mode 100644 index 5f4666b59396d4dbd7df6daaf62beb814e3b53f7..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/taos/cursor.py +++ /dev/null @@ -1,220 +0,0 @@ -from .cinterface import CTaosInterface -from .error import * -from .constants import FieldType - -# querySeqNum = 0 - - -class TDengineCursor(object): - """Database cursor which is used to manage the context of a fetch operation. - - Attributes: - .description: Read-only attribute consists of 7-item sequences: - - > name (mondatory) - > type_code (mondatory) - > display_size - > internal_size - > precision - > scale - > null_ok - - This attribute will be None for operations that do not return rows or - if the cursor has not had an operation invoked via the .execute*() method yet. - - .rowcount:This read-only attribute specifies the number of rows that the last - .execute*() produced (for DQL statements like SELECT) or affected - """ - - def __init__(self, connection=None): - self._description = [] - self._rowcount = -1 - self._connection = None - self._result = None - self._fields = None - self._block = None - self._block_rows = -1 - self._block_iter = 0 - self._affected_rows = 0 - self._logfile = "" - - if connection is not None: - self._connection = connection - - def __iter__(self): - return self - - def __next__(self): - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetch iterator") - - if self._block_rows <= self._block_iter: - block, self._block_rows = CTaosInterface.fetchRow( - self._result, self._fields) - if self._block_rows == 0: - raise StopIteration - self._block = list(map(tuple, zip(*block))) - self._block_iter = 0 - - data = self._block[self._block_iter] - self._block_iter += 1 - - return data - - @property - def description(self): - """Return the description of the object. - """ - return self._description - - @property - def rowcount(self): - """Return the rowcount of the object - """ - return self._rowcount - - @property - def affected_rows(self): - """Return the affected_rows of the object - """ - return self._affected_rows - - def callproc(self, procname, *args): - """Call a stored database procedure with the given name. - - Void functionality since no stored procedures. - """ - pass - - def close(self): - """Close the cursor. - """ - if self._connection is None: - return False - - self._reset_result() - self._connection = None - - return True - - def execute(self, operation, params=None): - """Prepare and execute a database operation (query or command). - """ - if not operation: - return None - - if not self._connection: - # TODO : change the exception raised here - raise ProgrammingError("Cursor is not connected") - - self._reset_result() - - stmt = operation - if params is not None: - pass - - self._result = CTaosInterface.query(self._connection._conn, stmt) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno == 0: - if CTaosInterface.fieldsCount(self._result) == 0: - self._affected_rows += CTaosInterface.affectedRows( - self._result) - return CTaosInterface.affectedRows(self._result) - else: - self._fields = CTaosInterface.useResult(self._result) - return self._handle_result() - else: - raise ProgrammingError(CTaosInterface.errStr(self._result), errno) - - def executemany(self, operation, seq_of_parameters): - """Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters. - """ - pass - - def fetchone(self): - """Fetch the next row of a query result set, returning a single sequence, or None when no more data is available. - """ - pass - - def fetchmany(self): - pass - - def fetchall_row(self): - """Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation. - """ - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetchall") - - buffer = [[] for i in range(len(self._fields))] - self._rowcount = 0 - while True: - block, num_of_fields = CTaosInterface.fetchRow( - self._result, self._fields) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno != 0: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - if num_of_fields == 0: - break - self._rowcount += num_of_fields - for i in range(len(self._fields)): - buffer[i].extend(block[i]) - return list(map(tuple, zip(*buffer))) - - def fetchall(self): - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetchall") - - buffer = [[] for i in range(len(self._fields))] - self._rowcount = 0 - while True: - block, num_of_fields = CTaosInterface.fetchBlock( - self._result, self._fields) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno != 0: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - if num_of_fields == 0: - break - self._rowcount += num_of_fields - for i in range(len(self._fields)): - buffer[i].extend(block[i]) - - return list(map(tuple, zip(*buffer))) - - def nextset(self): - """ - """ - pass - - def setinputsize(self, sizes): - pass - - def setutputsize(self, size, column=None): - pass - - def _reset_result(self): - """Reset the result to unused version. - """ - self._description = [] - self._rowcount = -1 - if self._result is not None: - CTaosInterface.freeResult(self._result) - self._result = None - self._fields = None - self._block = None - self._block_rows = -1 - self._block_iter = 0 - self._affected_rows = 0 - - def _handle_result(self): - """Handle the return result from query. - """ - self._description = [] - for ele in self._fields: - self._description.append( - (ele['name'], ele['type'], None, None, None, None, False)) - - return self._result diff --git a/src/connector/python/windows/python2/taos/dbapi.py b/src/connector/python/windows/python2/taos/dbapi.py deleted file mode 100644 index 594681ada953abf388e503c23199043cf686e1a3..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/taos/dbapi.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Type Objects and Constructors. -""" - -import time -import datetime - - -class DBAPITypeObject(object): - def __init__(self, *values): - self.values = values - - def __com__(self, other): - if other in self.values: - return 0 - if other < self.values: - return 1 - else: - return -1 - - -Date = datetime.date -Time = datetime.time -Timestamp = datetime.datetime - - -def DataFromTicks(ticks): - return Date(*time.localtime(ticks)[:3]) - - -def TimeFromTicks(ticks): - return Time(*time.localtime(ticks)[3:6]) - - -def TimestampFromTicks(ticks): - return Timestamp(*time.localtime(ticks)[:6]) - - -Binary = bytes - -# STRING = DBAPITypeObject(*constants.FieldType.get_string_types()) -# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types()) -# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types()) -# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types()) -# ROWID = DBAPITypeObject() diff --git a/src/connector/python/windows/python2/taos/error.py b/src/connector/python/windows/python2/taos/error.py deleted file mode 100644 index c584badce8320cd35dc81e8f6b613c56163b1a29..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/taos/error.py +++ /dev/null @@ -1,66 +0,0 @@ -"""Python exceptions -""" - - -class Error(Exception): - def __init__(self, msg=None, errno=None): - self.msg = msg - self._full_msg = self.msg - self.errno = errno - - def __str__(self): - return self._full_msg - - -class Warning(Exception): - """Exception raised for important warnings like data truncations while inserting. - """ - pass - - -class InterfaceError(Error): - """Exception raised for errors that are related to the database interface rather than the database itself. - """ - pass - - -class DatabaseError(Error): - """Exception raised for errors that are related to the database. - """ - pass - - -class DataError(DatabaseError): - """Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range. - """ - pass - - -class OperationalError(DatabaseError): - """Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer - """ - pass - - -class IntegrityError(DatabaseError): - """Exception raised when the relational integrity of the database is affected. - """ - pass - - -class InternalError(DatabaseError): - """Exception raised when the database encounters an internal error. - """ - pass - - -class ProgrammingError(DatabaseError): - """Exception raised for programming errors. - """ - pass - - -class NotSupportedError(DatabaseError): - """Exception raised in case a method or database API was used which is not supported by the database,. - """ - pass diff --git a/src/connector/python/windows/python2/taos/subscription.py b/src/connector/python/windows/python2/taos/subscription.py deleted file mode 100644 index 270d9de09217fc58a389981a3542698dd1c0428a..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python2/taos/subscription.py +++ /dev/null @@ -1,57 +0,0 @@ -from .cinterface import CTaosInterface -from .error import * - - -class TDengineSubscription(object): - """TDengine subscription object - """ - - def __init__(self, sub): - self._sub = sub - - def consume(self): - """Consume rows of a subscription - """ - if self._sub is None: - raise OperationalError("Invalid use of consume") - - result, fields = CTaosInterface.consume(self._sub) - buffer = [[] for i in range(len(fields))] - while True: - block, num_of_fields = CTaosInterface.fetchBlock(result, fields) - if num_of_fields == 0: - break - for i in range(len(fields)): - buffer[i].extend(block[i]) - - self.fields = fields - return list(map(tuple, zip(*buffer))) - - def close(self, keepProgress=True): - """Close the Subscription. - """ - if self._sub is None: - return False - - CTaosInterface.unsubscribe(self._sub, keepProgress) - return True - - -if __name__ == '__main__': - from .connection import TDengineConnection - conn = TDengineConnection( - host="127.0.0.1", - user="root", - password="taosdata", - database="test") - - # Generate a cursor object to run SQL commands - sub = conn.subscribe(True, "test", "select * from meters;", 1000) - - for i in range(0, 10): - data = sub.consume() - for d in data: - print(d) - - sub.close() - conn.close() diff --git a/src/connector/python/windows/python3/LICENSE b/src/connector/python/windows/python3/LICENSE deleted file mode 100644 index 2d032e65d8c7508776cc8bafc31965c82905e756..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ - 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 . diff --git a/src/connector/python/windows/python3/README.md b/src/connector/python/windows/python3/README.md deleted file mode 100644 index 70db6bba13a8b52b9f707400b80d1302542dbc34..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/README.md +++ /dev/null @@ -1 +0,0 @@ -# TDengine python client interface \ No newline at end of file diff --git a/src/connector/python/windows/python3/setup.py b/src/connector/python/windows/python3/setup.py deleted file mode 100644 index 2659c493aad8c3059095f0d4c98c61b69ed834f2..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/setup.py +++ /dev/null @@ -1,20 +0,0 @@ -import setuptools - -with open("README.md", "r") as fh: - long_description = fh.read() - -setuptools.setup( - name="taos", - version="2.0.9", - author="Taosdata Inc.", - author_email="support@taosdata.com", - description="TDengine python client package", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/pypa/sampleproject", - packages=setuptools.find_packages(), - classifiers=[ - "Programming Language :: Python :: 3", - "Operating System :: Windows", - ], -) diff --git a/src/connector/python/windows/python3/taos/__init__.py b/src/connector/python/windows/python3/taos/__init__.py deleted file mode 100644 index b57e25fd2c320956e46b190d9f0a1139db1cced0..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/taos/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ - -from .connection import TDengineConnection -from .cursor import TDengineCursor - -# Globals -threadsafety = 0 -paramstyle = 'pyformat' - -__all__ = ['connection', 'cursor'] - - -def connect(*args, **kwargs): - """ Function to return a TDengine connector object - - Current supporting keyword parameters: - @dsn: Data source name as string - @user: Username as string(optional) - @password: Password as string(optional) - @host: Hostname(optional) - @database: Database name(optional) - - @rtype: TDengineConnector - """ - return TDengineConnection(*args, **kwargs) diff --git a/src/connector/python/windows/python3/taos/cinterface.py b/src/connector/python/windows/python3/taos/cinterface.py deleted file mode 100644 index 65cb183f26978dc83553b3e88a5c6599ccc1dd48..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/taos/cinterface.py +++ /dev/null @@ -1,648 +0,0 @@ -import ctypes -from .constants import FieldType -from .error import * -import math -import datetime - - -def _convert_millisecond_to_datetime(milli): - return datetime.datetime.fromtimestamp(milli / 1000.0) - - -def _convert_microsecond_to_datetime(micro): - return datetime.datetime.fromtimestamp(micro / 1000000.0) - - -def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bool row to python row - """ - _timestamp_converter = _convert_millisecond_to_datetime - if micro: - _timestamp_converter = _convert_microsecond_to_datetime - - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_int64))[ - :abs(num_of_rows)]] - - -def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bool row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_byte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_bool))[ - :abs(num_of_rows)]] - - -def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C tinyint row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]] - - -def _crow_tinyint_unsigned_to_python( - data, - num_of_rows, - nbytes=None, - micro=False): - """Function to convert C tinyint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ubyte))[ - :abs(num_of_rows)]] - - -def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C smallint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_short))[ - :abs(num_of_rows)]] - - -def _crow_smallint_unsigned_to_python( - data, num_of_rows, nbytes=None, micro=False): - """Function to convert C smallint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_ushort))[ - :abs(num_of_rows)]] - - -def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C int row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] - - -def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C int row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint))[ - :abs(num_of_rows)]] - - -def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C bigint row to python row - """ - if num_of_rows > 0: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] - else: - return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_int64))[:abs(num_of_rows)]] - - -def _crow_bigint_unsigned_to_python( - data, - num_of_rows, - nbytes=None, - micro=False): - """Function to convert C bigint row to python row - """ - if num_of_rows > 0: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] - else: - return [ - None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( - data, ctypes.POINTER( - ctypes.c_uint64))[ - :abs(num_of_rows)]] - - -def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C float row to python row - """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] - - -def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C double row to python row - """ - if num_of_rows > 0: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] - else: - return [None if math.isnan(ele) else ele for ele in ctypes.cast( - data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] - - -def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C binary row to python row - """ - assert(nbytes is not None) - if num_of_rows > 0: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] - else: - return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode( - 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] - - -def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C nchar row to python row - """ - assert(nbytes is not None) - res = [] - for i in range(abs(num_of_rows)): - try: - if num_of_rows >= 0: - tmpstr = ctypes.c_char_p(data) - res.append(tmpstr.value.decode()) - else: - res.append((ctypes.cast(data + nbytes * i, - ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value) - except ValueError: - res.append(None) - - return res - - -def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C binary row to python row - """ - assert(nbytes is not None) - res = [] - if num_of_rows > 0: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - rbyte = ctypes.cast( - data + nbytes * i, - ctypes.POINTER( - ctypes.c_short))[ - :1].pop() - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()[0:rbyte]) - except ValueError: - res.append(None) - return res - - -def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False): - """Function to convert C nchar row to python row - """ - assert(nbytes is not None) - res = [] - if num_of_rows >= 0: - for i in range(abs(num_of_rows)): - try: - tmpstr = ctypes.c_char_p(data + nbytes * i + 2) - res.append(tmpstr.value.decode()) - except ValueError: - res.append(None) - else: - for i in range(abs(num_of_rows)): - try: - res.append((ctypes.cast(data + nbytes * i + 2, - ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value) - except ValueError: - res.append(None) - return res - - -_CONVERT_FUNC = { - FieldType.C_BOOL: _crow_bool_to_python, - FieldType.C_TINYINT: _crow_tinyint_to_python, - FieldType.C_SMALLINT: _crow_smallint_to_python, - FieldType.C_INT: _crow_int_to_python, - FieldType.C_BIGINT: _crow_bigint_to_python, - FieldType.C_FLOAT: _crow_float_to_python, - FieldType.C_DOUBLE: _crow_double_to_python, - FieldType.C_BINARY: _crow_binary_to_python, - FieldType.C_TIMESTAMP: _crow_timestamp_to_python, - FieldType.C_NCHAR: _crow_nchar_to_python, - FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python, - FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, - FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, - FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python -} - -_CONVERT_FUNC_BLOCK = { - FieldType.C_BOOL: _crow_bool_to_python, - FieldType.C_TINYINT: _crow_tinyint_to_python, - FieldType.C_SMALLINT: _crow_smallint_to_python, - FieldType.C_INT: _crow_int_to_python, - FieldType.C_BIGINT: _crow_bigint_to_python, - FieldType.C_FLOAT: _crow_float_to_python, - FieldType.C_DOUBLE: _crow_double_to_python, - FieldType.C_BINARY: _crow_binary_to_python_block, - FieldType.C_TIMESTAMP: _crow_timestamp_to_python, - FieldType.C_NCHAR: _crow_nchar_to_python_block, - FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python, - FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, - FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, - FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python -} - -# Corresponding TAOS_FIELD structure in C - - -class TaosField(ctypes.Structure): - _fields_ = [('name', ctypes.c_char * 65), - ('type', ctypes.c_char), - ('bytes', ctypes.c_short)] - -# C interface class - - -class CTaosInterface(object): - - libtaos = ctypes.windll.LoadLibrary('taos') - - libtaos.taos_fetch_fields.restype = ctypes.POINTER(TaosField) - libtaos.taos_init.restype = None - libtaos.taos_connect.restype = ctypes.c_void_p - #libtaos.taos_use_result.restype = ctypes.c_void_p - libtaos.taos_fetch_row.restype = ctypes.POINTER(ctypes.c_void_p) - libtaos.taos_errstr.restype = ctypes.c_char_p - libtaos.taos_subscribe.restype = ctypes.c_void_p - libtaos.taos_consume.restype = ctypes.c_void_p - libtaos.taos_fetch_lengths.restype = ctypes.c_void_p - libtaos.taos_free_result.restype = None - libtaos.taos_errno.restype = ctypes.c_int - libtaos.taos_query.restype = ctypes.POINTER(ctypes.c_void_p) - - def __init__(self, config=None): - ''' - Function to initialize the class - @host : str, hostname to connect - @user : str, username to connect to server - @password : str, password to connect to server - @db : str, default db to use when log in - @config : str, config directory - - @rtype : None - ''' - if config is None: - self._config = ctypes.c_char_p(None) - else: - try: - self._config = ctypes.c_char_p(config.encode('utf-8')) - except AttributeError: - raise AttributeError("config is expected as a str") - - if config is not None: - CTaosInterface.libtaos.taos_options(3, self._config) - - CTaosInterface.libtaos.taos_init() - - @property - def config(self): - """ Get current config - """ - return self._config - - def connect( - self, - host=None, - user="root", - password="taosdata", - db=None, - port=0): - ''' - Function to connect to server - - @rtype: c_void_p, TDengine handle - ''' - # host - try: - _host = ctypes.c_char_p(host.encode( - "utf-8")) if host is not None else ctypes.c_char_p(None) - except AttributeError: - raise AttributeError("host is expected as a str") - - # user - try: - _user = ctypes.c_char_p(user.encode("utf-8")) - except AttributeError: - raise AttributeError("user is expected as a str") - - # password - try: - _password = ctypes.c_char_p(password.encode("utf-8")) - except AttributeError: - raise AttributeError("password is expected as a str") - - # db - try: - _db = ctypes.c_char_p( - db.encode("utf-8")) if db is not None else ctypes.c_char_p(None) - except AttributeError: - raise AttributeError("db is expected as a str") - - # port - try: - _port = ctypes.c_int(port) - except TypeError: - raise TypeError("port is expected as an int") - - connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect( - _host, _user, _password, _db, _port)) - - if connection.value is None: - print('connect to TDengine failed') - raise ConnectionError("connect to TDengine failed") - # sys.exit(1) - # else: - # print('connect to TDengine success') - - return connection - - @staticmethod - def close(connection): - '''Close the TDengine handle - ''' - CTaosInterface.libtaos.taos_close(connection) - #print('connection is closed') - - @staticmethod - def query(connection, sql): - '''Run SQL - - @sql: str, sql string to run - - @rtype: 0 on success and -1 on failure - ''' - try: - return CTaosInterface.libtaos.taos_query( - connection, ctypes.c_char_p(sql.encode('utf-8'))) - except AttributeError: - raise AttributeError("sql is expected as a string") - # finally: - # CTaosInterface.libtaos.close(connection) - - @staticmethod - def affectedRows(result): - """The affected rows after runing query - """ - return CTaosInterface.libtaos.taos_affected_rows(result) - - @staticmethod - def subscribe(connection, restart, topic, sql, interval): - """Create a subscription - @restart boolean, - @sql string, sql statement for data query, must be a 'select' statement. - @topic string, name of this subscription - """ - return ctypes.c_void_p(CTaosInterface.libtaos.taos_subscribe( - connection, - 1 if restart else 0, - ctypes.c_char_p(topic.encode('utf-8')), - ctypes.c_char_p(sql.encode('utf-8')), - None, - None, - interval)) - - @staticmethod - def consume(sub): - """Consume data of a subscription - """ - result = ctypes.c_void_p(CTaosInterface.libtaos.taos_consume(sub)) - fields = [] - pfields = CTaosInterface.fetchFields(result) - for i in range(CTaosInterface.libtaos.taos_num_fields(result)): - fields.append({'name': pfields[i].name.decode('utf-8'), - 'bytes': pfields[i].bytes, - 'type': ord(pfields[i].type)}) - return result, fields - - @staticmethod - def unsubscribe(sub, keepProgress): - """Cancel a subscription - """ - CTaosInterface.libtaos.taos_unsubscribe(sub, 1 if keepProgress else 0) - - @staticmethod - def useResult(result): - '''Use result after calling self.query - ''' - fields = [] - pfields = CTaosInterface.fetchFields(result) - for i in range(CTaosInterface.fieldsCount(result)): - fields.append({'name': pfields[i].name.decode('utf-8'), - 'bytes': pfields[i].bytes, - 'type': ord(pfields[i].type)}) - - return fields - - @staticmethod - def fetchBlock(result, fields): - pblock = ctypes.c_void_p(0) - num_of_rows = CTaosInterface.libtaos.taos_fetch_block( - result, ctypes.byref(pblock)) - if num_of_rows == 0: - return None, 0 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ - ele for ele in ctypes.cast( - fieldL, ctypes.POINTER( - ctypes.c_int))[ - :len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if fields[i]['type'] not in _CONVERT_FUNC_BLOCK: - raise DatabaseError("Invalid data type returned from database") - blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) - - return blocks, abs(num_of_rows) - - @staticmethod - def fetchRow(result, fields): - pblock = ctypes.c_void_p(0) - pblock = CTaosInterface.libtaos.taos_fetch_row(result) - if pblock: - num_of_rows = 1 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ - ele for ele in ctypes.cast( - fieldL, ctypes.POINTER( - ctypes.c_int))[ - :len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if fields[i]['type'] not in _CONVERT_FUNC: - raise DatabaseError( - "Invalid data type returned from database") - if data is None: - blocks[i] = [None] - else: - blocks[i] = _CONVERT_FUNC[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) - else: - return None, 0 - return blocks, abs(num_of_rows) - - @staticmethod - def freeResult(result): - CTaosInterface.libtaos.taos_free_result(result) - result.value = None - - @staticmethod - def fieldsCount(result): - return CTaosInterface.libtaos.taos_field_count(result) - - @staticmethod - def fetchFields(result): - return CTaosInterface.libtaos.taos_fetch_fields(result) - - # @staticmethod - # def fetchRow(result, fields): - # l = [] - # row = CTaosInterface.libtaos.taos_fetch_row(result) - # if not row: - # return None - - # for i in range(len(fields)): - # l.append(CTaosInterface.getDataValue( - # row[i], fields[i]['type'], fields[i]['bytes'])) - - # return tuple(l) - - # @staticmethod - # def getDataValue(data, dtype, byte): - # ''' - # ''' - # if not data: - # return None - - # if (dtype == CTaosInterface.TSDB_DATA_TYPE_BOOL): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TINYINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_SMALLINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_INT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BIGINT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int64))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_FLOAT): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_DOUBLE): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_BINARY): - # return (ctypes.cast(data, ctypes.POINTER(ctypes.c_char))[0:byte]).rstrip('\x00') - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_TIMESTAMP): - # return ctypes.cast(data, ctypes.POINTER(ctypes.c_int64))[0] - # elif (dtype == CTaosInterface.TSDB_DATA_TYPE_NCHAR): - # return (ctypes.cast(data, ctypes.c_char_p).value).rstrip('\x00') - - @staticmethod - def errno(result): - """Return the error number. - """ - return CTaosInterface.libtaos.taos_errno(result) - - @staticmethod - def errStr(result): - """Return the error styring - """ - return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8') - - -if __name__ == '__main__': - cinter = CTaosInterface() - conn = cinter.connect() - result = cinter.query(conn, 'show databases') - - print('Query Affected rows: {}'.format(cinter.affectedRows(result))) - - fields = CTaosInterface.useResult(result) - - data, num_of_rows = CTaosInterface.fetchBlock(result, fields) - - print(data) - - cinter.freeResult(result) - cinter.close(conn) diff --git a/src/connector/python/windows/python3/taos/connection.py b/src/connector/python/windows/python3/taos/connection.py deleted file mode 100644 index 5729d01c6df8c0e58086726c4001467811e9fee5..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/taos/connection.py +++ /dev/null @@ -1,96 +0,0 @@ -from .cursor import TDengineCursor -from .subscription import TDengineSubscription -from .cinterface import CTaosInterface - - -class TDengineConnection(object): - """ TDengine connection object - """ - - def __init__(self, *args, **kwargs): - self._conn = None - self._host = None - self._user = "root" - self._password = "taosdata" - self._database = None - self._port = 0 - self._config = None - self._chandle = None - - if len(kwargs) > 0: - self.config(**kwargs) - - def config(self, **kwargs): - # host - if 'host' in kwargs: - self._host = kwargs['host'] - - # user - if 'user' in kwargs: - self._user = kwargs['user'] - - # password - if 'password' in kwargs: - self._password = kwargs['password'] - - # database - if 'database' in kwargs: - self._database = kwargs['database'] - - # port - if 'port' in kwargs: - self._port = kwargs['port'] - - # config - if 'config' in kwargs: - self._config = kwargs['config'] - - self._chandle = CTaosInterface(self._config) - self._conn = self._chandle.connect( - self._host, - self._user, - self._password, - self._database, - self._port) - - def close(self): - """Close current connection. - """ - return CTaosInterface.close(self._conn) - - def subscribe(self, restart, topic, sql, interval): - """Create a subscription. - """ - if self._conn is None: - return None - sub = CTaosInterface.subscribe( - self._conn, restart, topic, sql, interval) - return TDengineSubscription(sub) - - def cursor(self): - """Return a new Cursor object using the connection. - """ - return TDengineCursor(self) - - def commit(self): - """Commit any pending transaction to the database. - - Since TDengine do not support transactions, the implement is void functionality. - """ - pass - - def rollback(self): - """Void functionality - """ - pass - - def clear_result_set(self): - """Clear unused result set on this connection. - """ - pass - - -if __name__ == "__main__": - conn = TDengineConnection(host='192.168.1.107') - conn.close() - print("Hello world") diff --git a/src/connector/python/windows/python3/taos/constants.py b/src/connector/python/windows/python3/taos/constants.py deleted file mode 100644 index 49fc17b2fb98a6684e74e4a044651fdc6237518e..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/taos/constants.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Constants in TDengine python -""" - -from .dbapi import * - - -class FieldType(object): - """TDengine Field Types - """ - # type_code - C_NULL = 0 - C_BOOL = 1 - C_TINYINT = 2 - C_SMALLINT = 3 - C_INT = 4 - C_BIGINT = 5 - C_FLOAT = 6 - C_DOUBLE = 7 - C_BINARY = 8 - C_TIMESTAMP = 9 - C_NCHAR = 10 - C_TINYINT_UNSIGNED = 11 - C_SMALLINT_UNSIGNED = 12 - C_INT_UNSIGNED = 13 - C_BIGINT_UNSIGNED = 14 - # NULL value definition - # NOTE: These values should change according to C definition in tsdb.h - C_BOOL_NULL = 0x02 - C_TINYINT_NULL = -128 - C_TINYINT_UNSIGNED_NULL = 255 - C_SMALLINT_NULL = -32768 - C_SMALLINT_UNSIGNED_NULL = 65535 - C_INT_NULL = -2147483648 - C_INT_UNSIGNED_NULL = 4294967295 - C_BIGINT_NULL = -9223372036854775808 - C_BIGINT_UNSIGNED_NULL = 18446744073709551615 - C_FLOAT_NULL = float('nan') - C_DOUBLE_NULL = float('nan') - C_BINARY_NULL = bytearray([int('0xff', 16)]) - # Timestamp precision definition - C_TIMESTAMP_MILLI = 0 - C_TIMESTAMP_MICRO = 1 diff --git a/src/connector/python/windows/python3/taos/cursor.py b/src/connector/python/windows/python3/taos/cursor.py deleted file mode 100644 index 136cd42fe47a51a34b301730745d73e893861f7c..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/taos/cursor.py +++ /dev/null @@ -1,220 +0,0 @@ -from .cinterface import CTaosInterface -from .error import * -from .constants import FieldType - -# querySeqNum = 0 - - -class TDengineCursor(object): - """Database cursor which is used to manage the context of a fetch operation. - - Attributes: - .description: Read-only attribute consists of 7-item sequences: - - > name (mondatory) - > type_code (mondatory) - > display_size - > internal_size - > precision - > scale - > null_ok - - This attribute will be None for operations that do not return rows or - if the cursor has not had an operation invoked via the .execute*() method yet. - - .rowcount:This read-only attribute specifies the number of rows that the last - .execute*() produced (for DQL statements like SELECT) or affected - """ - - def __init__(self, connection=None): - self._description = [] - self._rowcount = -1 - self._connection = None - self._result = None - self._fields = None - self._block = None - self._block_rows = -1 - self._block_iter = 0 - self._affected_rows = 0 - self._logfile = "" - - if connection is not None: - self._connection = connection - - def __iter__(self): - return self - - def __next__(self): - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetch iterator") - - if self._block_rows <= self._block_iter: - block, self._block_rows = CTaosInterface.fetchRow( - self._result, self._fields) - if self._block_rows == 0: - raise StopIteration - self._block = list(map(tuple, zip(*block))) - self._block_iter = 0 - - data = self._block[self._block_iter] - self._block_iter += 1 - - return data - - @property - def description(self): - """Return the description of the object. - """ - return self._description - - @property - def rowcount(self): - """Return the rowcount of the object - """ - return self._rowcount - - @property - def affected_rows(self): - """Return the affected_rows of the object - """ - return self._affected_rows - - def callproc(self, procname, *args): - """Call a stored database procedure with the given name. - - Void functionality since no stored procedures. - """ - pass - - def close(self): - """Close the cursor. - """ - if self._connection is None: - return False - - self._reset_result() - self._connection = None - - return True - - def execute(self, operation, params=None): - """Prepare and execute a database operation (query or command). - """ - if not operation: - return None - - if not self._connection: - # TODO : change the exception raised here - raise ProgrammingError("Cursor is not connected") - - self._reset_result() - - stmt = operation - if params is not None: - pass - - self._result = CTaosInterface.query(self._connection._conn, stmt) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno == 0: - if CTaosInterface.fieldsCount(self._result) == 0: - self._affected_rows += CTaosInterface.affectedRows( - self._result) - return CTaosInterface.affectedRows(self._result) - else: - self._fields = CTaosInterface.useResult(self._result) - return self._handle_result() - else: - raise ProgrammingError(CTaosInterface.errStr(self._result), errno) - - def executemany(self, operation, seq_of_parameters): - """Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters. - """ - pass - - def fetchone(self): - """Fetch the next row of a query result set, returning a single sequence, or None when no more data is available. - """ - pass - - def fetchmany(self): - pass - - def fetchall_row(self): - """Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation. - """ - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetchall") - - buffer = [[] for i in range(len(self._fields))] - self._rowcount = 0 - while True: - block, num_of_fields = CTaosInterface.fetchRow( - self._result, self._fields) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno != 0: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - if num_of_fields == 0: - break - self._rowcount += num_of_fields - for i in range(len(self._fields)): - buffer[i].extend(block[i]) - return list(map(tuple, zip(*buffer))) - - def fetchall(self): - if self._result is None or self._fields is None: - raise OperationalError("Invalid use of fetchall") - - buffer = [[] for i in range(len(self._fields))] - self._rowcount = 0 - while True: - block, num_of_fields = CTaosInterface.fetchBlock( - self._result, self._fields) - errno = CTaosInterface.libtaos.taos_errno(self._result) - if errno != 0: - raise ProgrammingError( - CTaosInterface.errStr( - self._result), errno) - if num_of_fields == 0: - break - self._rowcount += num_of_fields - for i in range(len(self._fields)): - buffer[i].extend(block[i]) - - return list(map(tuple, zip(*buffer))) - - def nextset(self): - """ - """ - pass - - def setinputsize(self, sizes): - pass - - def setutputsize(self, size, column=None): - pass - - def _reset_result(self): - """Reset the result to unused version. - """ - self._description = [] - self._rowcount = -1 - if self._result is not None: - CTaosInterface.freeResult(self._result) - self._result = None - self._fields = None - self._block = None - self._block_rows = -1 - self._block_iter = 0 - self._affected_rows = 0 - - def _handle_result(self): - """Handle the return result from query. - """ - self._description = [] - for ele in self._fields: - self._description.append( - (ele['name'], ele['type'], None, None, None, None, False)) - - return self._result diff --git a/src/connector/python/windows/python3/taos/dbapi.py b/src/connector/python/windows/python3/taos/dbapi.py deleted file mode 100644 index a29621f7a3594a618b59b30bdc96197c4222a619..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/taos/dbapi.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Type Objects and Constructors. -""" - -import time -import datetime - - -class DBAPITypeObject(object): - def __init__(self, *values): - self.values = values - - def __com__(self, other): - if other in self.values: - return 0 - if other < self.values: - return 1 - else: - return -1 - - -Date = datetime.date -Time = datetime.time -Timestamp = datetime.datetime - - -def DataFromTicks(ticks): - return Date(*time.localtime(ticks)[:3]) - - -def TimeFromTicks(ticks): - return Time(*time.localtime(ticks)[3:6]) - - -def TimestampFromTicks(ticks): - return Timestamp(*time.localtime(ticks)[:6]) - - -Binary = bytes - -# STRING = DBAPITypeObject(*constants.FieldType.get_string_types()) -# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types()) -# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types()) -# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types()) -# ROWID = DBAPITypeObject() diff --git a/src/connector/python/windows/python3/taos/error.py b/src/connector/python/windows/python3/taos/error.py deleted file mode 100644 index 238b293a0b609570e7b5d536648c6ada3ca2f209..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/taos/error.py +++ /dev/null @@ -1,66 +0,0 @@ -"""Python exceptions -""" - - -class Error(Exception): - def __init__(self, msg=None, errno=None): - self.msg = msg - self._full_msg = self.msg - self.errno = errno - - def __str__(self): - return self._full_msg - - -class Warning(Exception): - """Exception raised for important warnings like data truncations while inserting. - """ - pass - - -class InterfaceError(Error): - """Exception raised for errors that are related to the database interface rather than the database itself. - """ - pass - - -class DatabaseError(Error): - """Exception raised for errors that are related to the database. - """ - pass - - -class DataError(DatabaseError): - """Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range. - """ - pass - - -class OperationalError(DatabaseError): - """Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer - """ - pass - - -class IntegrityError(DatabaseError): - """Exception raised when the relational integrity of the database is affected. - """ - pass - - -class InternalError(DatabaseError): - """Exception raised when the database encounters an internal error. - """ - pass - - -class ProgrammingError(DatabaseError): - """Exception raised for programming errors. - """ - pass - - -class NotSupportedError(DatabaseError): - """Exception raised in case a method or database API was used which is not supported by the database,. - """ - pass diff --git a/src/connector/python/windows/python3/taos/subscription.py b/src/connector/python/windows/python3/taos/subscription.py deleted file mode 100644 index 270d9de09217fc58a389981a3542698dd1c0428a..0000000000000000000000000000000000000000 --- a/src/connector/python/windows/python3/taos/subscription.py +++ /dev/null @@ -1,57 +0,0 @@ -from .cinterface import CTaosInterface -from .error import * - - -class TDengineSubscription(object): - """TDengine subscription object - """ - - def __init__(self, sub): - self._sub = sub - - def consume(self): - """Consume rows of a subscription - """ - if self._sub is None: - raise OperationalError("Invalid use of consume") - - result, fields = CTaosInterface.consume(self._sub) - buffer = [[] for i in range(len(fields))] - while True: - block, num_of_fields = CTaosInterface.fetchBlock(result, fields) - if num_of_fields == 0: - break - for i in range(len(fields)): - buffer[i].extend(block[i]) - - self.fields = fields - return list(map(tuple, zip(*buffer))) - - def close(self, keepProgress=True): - """Close the Subscription. - """ - if self._sub is None: - return False - - CTaosInterface.unsubscribe(self._sub, keepProgress) - return True - - -if __name__ == '__main__': - from .connection import TDengineConnection - conn = TDengineConnection( - host="127.0.0.1", - user="root", - password="taosdata", - database="test") - - # Generate a cursor object to run SQL commands - sub = conn.subscribe(True, "test", "select * from meters;", 1000) - - for i in range(0, 10): - data = sub.consume() - for d in data: - print(d) - - sub.close() - conn.close() diff --git a/src/dnode/src/dnodeMain.c b/src/dnode/src/dnodeMain.c index 410e6bb1888a11858e5d091f3f82c54df4dc2022..64da11f3123b5eafd1de2ae9253fe5fc3090ad80 100644 --- a/src/dnode/src/dnodeMain.c +++ b/src/dnode/src/dnodeMain.c @@ -40,6 +40,7 @@ #include "dnodeShell.h" #include "dnodeTelemetry.h" #include "module.h" +#include "mnode.h" #if !defined(_MODULE) || !defined(_TD_LINUX) int32_t moduleStart() { return 0; } @@ -85,6 +86,17 @@ static SStep tsDnodeSteps[] = { {"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry}, }; +static SStep tsDnodeCompactSteps[] = { + {"dnode-tfile", tfInit, tfCleanup}, + {"dnode-storage", dnodeInitStorage, dnodeCleanupStorage}, + {"dnode-eps", dnodeInitEps, dnodeCleanupEps}, + {"dnode-wal", walInit, walCleanUp}, + {"dnode-mread", dnodeInitMRead, NULL}, + {"dnode-mwrite", dnodeInitMWrite, NULL}, + {"dnode-mpeer", dnodeInitMPeer, NULL}, + {"dnode-modules", dnodeInitModules, dnodeCleanupModules}, +}; + static int dnodeCreateDir(const char *dir) { if (mkdir(dir, 0755) != 0 && errno != EEXIST) { return -1; @@ -94,13 +106,23 @@ static int dnodeCreateDir(const char *dir) { } static void dnodeCleanupComponents() { - int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep); - dnodeStepCleanup(tsDnodeSteps, stepSize); + if (!tsCompactMnodeWal) { + int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep); + dnodeStepCleanup(tsDnodeSteps, stepSize); + } else { + int32_t stepSize = sizeof(tsDnodeCompactSteps) / sizeof(SStep); + dnodeStepCleanup(tsDnodeCompactSteps, stepSize); + } } static int32_t dnodeInitComponents() { - int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep); - return dnodeStepInit(tsDnodeSteps, stepSize); + if (!tsCompactMnodeWal) { + int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep); + return dnodeStepInit(tsDnodeSteps, stepSize); + } else { + int32_t stepSize = sizeof(tsDnodeCompactSteps) / sizeof(SStep); + return dnodeStepInit(tsDnodeCompactSteps, stepSize); + } } static int32_t dnodeInitTmr() { @@ -216,6 +238,23 @@ static int32_t dnodeInitStorage() { sprintf(tsDnodeDir, "%s/dnode", tsDataDir); // sprintf(tsVnodeBakDir, "%s/vnode_bak", tsDataDir); + if (tsCompactMnodeWal == 1) { + sprintf(tsMnodeTmpDir, "%s/mnode_tmp", tsDataDir); + if (taosDirExist(tsMnodeTmpDir)) { + dError("mnode_tmp dir already exist in %s,quit compact job", tsMnodeTmpDir); + return -1; + } + if (dnodeCreateDir(tsMnodeTmpDir) < 0) { + dError("failed to create dir: %s, reason: %s", tsMnodeTmpDir, strerror(errno)); + return -1; + } + + sprintf(tsMnodeBakDir, "%s/mnode_bak", tsDataDir); + if (taosDirExist(tsMnodeBakDir)) { + dError("mnode_bak dir already exist in %s,quit compact job", tsMnodeBakDir); + return -1; + } + } //TODO(dengyihao): no need to init here if (dnodeCreateDir(tsMnodeDir) < 0) { dError("failed to create dir: %s, reason: %s", tsMnodeDir, strerror(errno)); diff --git a/src/dnode/src/dnodeSystem.c b/src/dnode/src/dnodeSystem.c index e49b3eba99408c9453189106dc6f01e0d0afc7fe..ee37ffdcbb90f710253d051f1d4895ee8bc26dea 100644 --- a/src/dnode/src/dnodeSystem.c +++ b/src/dnode/src/dnodeSystem.c @@ -42,6 +42,8 @@ int32_t main(int32_t argc, char *argv[]) { } } else if (strcmp(argv[i], "-C") == 0) { dump_config = 1; + } else if (strcmp(argv[i], "--compact-mnode-wal") == 0) { + tsCompactMnodeWal = 1; } else if (strcmp(argv[i], "-V") == 0) { #ifdef _ACCT char *versionStr = "enterprise"; diff --git a/src/inc/mnode.h b/src/inc/mnode.h index 2495a42ba2e5d23cb361e2d64de04d1f710764ea..203ac57469c5bf7e1aa226c63d9bd32ffe068b46 100644 --- a/src/inc/mnode.h +++ b/src/inc/mnode.h @@ -73,6 +73,9 @@ int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg); void mnodeProcessPeerRsp(SRpcMsg *pMsg); int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, char *ckey); +int32_t mnodeCompactWal(); +int32_t mnodeCompactComponents(); + #ifdef __cplusplus } #endif diff --git a/src/inc/monitor.h b/src/inc/monitor.h index 1aefb0b84887270c7997c381402096006fe6eaee..d2e5e06487dbdf311cef6da125d7ba3050b53a4d 100644 --- a/src/inc/monitor.h +++ b/src/inc/monitor.h @@ -54,7 +54,8 @@ void monCleanupSystem(); void monSaveAcctLog(SAcctMonitorObj *pMonObj); void monSaveLog(int32_t level, const char *const format, ...); void monExecuteSQL(char *sql); - +typedef void (*MonExecuteSQLCbFP)(void *param, TAOS_RES *, int code); +void monExecuteSQLWithResultCallback(char *sql, MonExecuteSQLCbFP callback, void* param); #ifdef __cplusplus } #endif diff --git a/src/inc/taos.h b/src/inc/taos.h index cd8e116053bd9adabda9a1eeeb20c6d92679d99d..d27828fc364fd795e238b33df464fdc3548b60e2 100644 --- a/src/inc/taos.h +++ b/src/inc/taos.h @@ -82,6 +82,7 @@ typedef struct TAOS_BIND { uintptr_t buffer_length; // unused uintptr_t *length; int * is_null; + int is_unsigned; // unused int * error; // unused union { @@ -99,12 +100,26 @@ typedef struct TAOS_BIND { unsigned int allocated; } TAOS_BIND; +typedef struct TAOS_MULTI_BIND { + int buffer_type; + void *buffer; + uintptr_t buffer_length; + int32_t *length; + char *is_null; + int num; +} TAOS_MULTI_BIND; + + TAOS_STMT *taos_stmt_init(TAOS *taos); int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length); +int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags); +int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name); int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert); int taos_stmt_num_params(TAOS_STMT *stmt, int *nums); int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes); int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND *bind); +int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind); +int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int colIdx); int taos_stmt_add_batch(TAOS_STMT *stmt); int taos_stmt_execute(TAOS_STMT *stmt); TAOS_RES * taos_stmt_use_result(TAOS_STMT *stmt); diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index e596ee67ecf1ab736246056d4e510661eee677fe..c00fde18162a1c7006706286ac26bc5cd6e7e547 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -33,6 +33,8 @@ extern "C" { #endif #define TSWINDOW_INITIALIZER ((STimeWindow) {INT64_MIN, INT64_MAX}) +#define TSWINDOW_DESC_INITIALIZER ((STimeWindow) {INT64_MAX, INT64_MIN}) + #define TSKEY_INITIAL_VAL INT64_MIN // Bytes for each type. @@ -298,7 +300,7 @@ do { \ #define TSDB_DEFAULT_DB_UPDATE_OPTION 0 #define TSDB_MIN_DB_CACHE_LAST_ROW 0 -#define TSDB_MAX_DB_CACHE_LAST_ROW 1 +#define TSDB_MAX_DB_CACHE_LAST_ROW 3 #define TSDB_DEFAULT_CACHE_LAST_ROW 0 #define TSDB_MIN_FSYNC_PERIOD 0 @@ -345,6 +347,7 @@ do { \ #define TSDB_QUERY_TYPE_TAG_FILTER_QUERY 0x400u #define TSDB_QUERY_TYPE_INSERT 0x100u // insert type #define TSDB_QUERY_TYPE_MULTITABLE_QUERY 0x200u +#define TSDB_QUERY_TYPE_FILE_INSERT 0x400u // insert data from file #define TSDB_QUERY_TYPE_STMT_INSERT 0x800u // stmt insert type #define TSDB_QUERY_HAS_TYPE(x, _type) (((x) & (_type)) != 0) diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index eff4eecbc1baaea7f96a6560757bd2000eeab1bf..09f632ea32077b3e9bd3fcddcff418f280192c3f 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -74,7 +74,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_REF_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x010A) //"Ref is not there") //client -#define TSDB_CODE_TSC_INVALID_SQL TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid SQL statement") +#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid Operation") #define TSDB_CODE_TSC_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0201) //"Invalid qhandle") #define TSDB_CODE_TSC_INVALID_TIME_STAMP TAOS_DEF_ERROR_CODE(0, 0x0202) //"Invalid combination of client/service time") #define TSDB_CODE_TSC_INVALID_VALUE TAOS_DEF_ERROR_CODE(0, 0x0203) //"Invalid value in client") @@ -218,6 +218,8 @@ int32_t* taosGetErrno(); #define TSDB_CODE_VND_NOT_SYNCED TAOS_DEF_ERROR_CODE(0, 0x0511) //"Database suspended") #define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied") #define TSDB_CODE_VND_IS_SYNCING TAOS_DEF_ERROR_CODE(0, 0x0513) //"Database is syncing") +#define TSDB_CODE_VND_INVALID_TSDB_STATE TAOS_DEF_ERROR_CODE(0, 0x0514) //"Invalid tsdb state") +#define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0515) //"Database is closing") // tsdb #define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) //"Invalid table ID") @@ -426,6 +428,9 @@ int32_t* taosGetErrno(); #define TSDB_CODE_FS_INVLD_LEVEL TAOS_DEF_ERROR_CODE(0, 0x2207) //"tfs invalid level") #define TSDB_CODE_FS_NO_VALID_DISK TAOS_DEF_ERROR_CODE(0, 0x2208) //"tfs no valid disk") +// monitor +#define TSDB_CODE_MON_CONNECTION_INVALID TAOS_DEF_ERROR_CODE(0, 0x2300) //"monitor invalid monitor db connection") + #ifdef __cplusplus } #endif diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index d98fc9a6e2b60d8a7b278810b1a7d029e025c4eb..0d8f555670f642ee580d02a435462c689287230e 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -84,7 +84,7 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_TABLE, "drop-table" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_TABLE, "alter-table" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLE_META, "table-meta" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_STABLE_VGROUP, "stable-vgroup" ) -TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLES_META, "tables-meta" ) +TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLES_META, "multiTable-meta" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_STREAM, "alter-stream" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_SHOW, "show" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_RETRIEVE, "retrieve" ) @@ -294,6 +294,8 @@ typedef struct { typedef struct { char name[TSDB_TABLE_FNAME_LEN]; + // if user specify DROP STABLE, this flag will be set. And an error will be returned if it is not a super table + int8_t supertable; int8_t igNotExists; } SCMDropTableMsg; @@ -704,8 +706,9 @@ typedef struct { } STableInfoMsg; typedef struct { + int32_t numOfVgroups; int32_t numOfTables; - char tableIds[]; + char tableNames[]; } SMultiTableInfoMsg; typedef struct SSTableVgroupMsg { @@ -754,8 +757,9 @@ typedef struct STableMetaMsg { typedef struct SMultiTableMeta { int32_t numOfTables; + int32_t numOfVgroup; int32_t contLen; - char metas[]; + char meta[]; } SMultiTableMeta; typedef struct { diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h index 1ba5131f6db82cf7f0fdd512b7dbf94bd68914dc..21d55d5d0fea0312b07e17eee2cbfc91e2175fc1 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -69,9 +69,13 @@ typedef struct { int8_t precision; int8_t compression; int8_t update; - int8_t cacheLastRow; + int8_t cacheLastRow; // 0:no cache, 1: cache last row, 2: cache last NULL column 3: 1&2 } STsdbCfg; +#define CACHE_NO_LAST(c) ((c)->cacheLastRow == 0) +#define CACHE_LAST_ROW(c) (((c)->cacheLastRow & 1) > 0) +#define CACHE_LAST_NULL_COLUMN(c) (((c)->cacheLastRow & 2) > 0) + // --------- TSDB REPOSITORY USAGE STATISTICS typedef struct { int64_t totalStorage; // total bytes occupie @@ -261,6 +265,12 @@ TsdbQueryHandleT *tsdbQueryTables(STsdbRepo *tsdb, STsdbQueryCond *pCond, STable TsdbQueryHandleT tsdbQueryLastRow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfo, uint64_t qId, SMemRef *pRef); + +TsdbQueryHandleT tsdbQueryCacheLast(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, uint64_t qId, SMemRef* pMemRef); + +bool isTsdbCacheLastRow(TsdbQueryHandleT* pQueryHandle); + + /** * get the queried table object list * @param pHandle diff --git a/src/inc/ttokendef.h b/src/inc/ttokendef.h index e9585636fd97bd4bcb856317689aed615d275026..21e67413af6fec2bbf47d2ae0b3323a8e96d5d5c 100644 --- a/src/inc/ttokendef.h +++ b/src/inc/ttokendef.h @@ -17,105 +17,105 @@ #define TDENGINE_TTOKENDEF_H -#define TK_ID 1 -#define TK_BOOL 2 -#define TK_TINYINT 3 -#define TK_SMALLINT 4 -#define TK_INTEGER 5 -#define TK_BIGINT 6 -#define TK_FLOAT 7 -#define TK_DOUBLE 8 -#define TK_STRING 9 -#define TK_TIMESTAMP 10 -#define TK_BINARY 11 -#define TK_NCHAR 12 -#define TK_OR 13 -#define TK_AND 14 -#define TK_NOT 15 -#define TK_EQ 16 -#define TK_NE 17 -#define TK_ISNULL 18 -#define TK_NOTNULL 19 -#define TK_IS 20 -#define TK_LIKE 21 -#define TK_GLOB 22 -#define TK_BETWEEN 23 -#define TK_IN 24 -#define TK_GT 25 -#define TK_GE 26 -#define TK_LT 27 -#define TK_LE 28 -#define TK_BITAND 29 -#define TK_BITOR 30 -#define TK_LSHIFT 31 -#define TK_RSHIFT 32 -#define TK_PLUS 33 -#define TK_MINUS 34 -#define TK_DIVIDE 35 -#define TK_TIMES 36 -#define TK_STAR 37 -#define TK_SLASH 38 -#define TK_REM 39 -#define TK_CONCAT 40 -#define TK_UMINUS 41 -#define TK_UPLUS 42 -#define TK_BITNOT 43 -#define TK_SHOW 44 -#define TK_DATABASES 45 -#define TK_TOPICS 46 -#define TK_MNODES 47 -#define TK_DNODES 48 -#define TK_ACCOUNTS 49 -#define TK_USERS 50 -#define TK_MODULES 51 -#define TK_QUERIES 52 -#define TK_CONNECTIONS 53 -#define TK_STREAMS 54 -#define TK_VARIABLES 55 -#define TK_SCORES 56 -#define TK_GRANTS 57 -#define TK_VNODES 58 -#define TK_IPTOKEN 59 -#define TK_DOT 60 -#define TK_CREATE 61 -#define TK_TABLE 62 -#define TK_STABLE 63 -#define TK_DATABASE 64 -#define TK_TABLES 65 -#define TK_STABLES 66 -#define TK_VGROUPS 67 -#define TK_DROP 68 -#define TK_TOPIC 69 -#define TK_DNODE 70 -#define TK_USER 71 -#define TK_ACCOUNT 72 -#define TK_USE 73 -#define TK_DESCRIBE 74 -#define TK_ALTER 75 -#define TK_PASS 76 -#define TK_PRIVILEGE 77 -#define TK_LOCAL 78 -#define TK_IF 79 -#define TK_EXISTS 80 -#define TK_PPS 81 -#define TK_TSERIES 82 -#define TK_DBS 83 -#define TK_STORAGE 84 -#define TK_QTIME 85 -#define TK_CONNS 86 -#define TK_STATE 87 -#define TK_KEEP 88 -#define TK_CACHE 89 -#define TK_REPLICA 90 -#define TK_QUORUM 91 -#define TK_DAYS 92 -#define TK_MINROWS 93 -#define TK_MAXROWS 94 -#define TK_BLOCKS 95 -#define TK_CTIME 96 -#define TK_WAL 97 -#define TK_FSYNC 98 -#define TK_COMP 99 +#define TK_ID 1 +#define TK_BOOL 2 +#define TK_TINYINT 3 +#define TK_SMALLINT 4 +#define TK_INTEGER 5 +#define TK_BIGINT 6 +#define TK_FLOAT 7 +#define TK_DOUBLE 8 +#define TK_STRING 9 +#define TK_TIMESTAMP 10 +#define TK_BINARY 11 +#define TK_NCHAR 12 +#define TK_OR 13 +#define TK_AND 14 +#define TK_NOT 15 +#define TK_EQ 16 +#define TK_NE 17 +#define TK_ISNULL 18 +#define TK_NOTNULL 19 +#define TK_IS 20 +#define TK_LIKE 21 +#define TK_GLOB 22 +#define TK_BETWEEN 23 +#define TK_IN 24 +#define TK_GT 25 +#define TK_GE 26 +#define TK_LT 27 +#define TK_LE 28 +#define TK_BITAND 29 +#define TK_BITOR 30 +#define TK_LSHIFT 31 +#define TK_RSHIFT 32 +#define TK_PLUS 33 +#define TK_MINUS 34 +#define TK_DIVIDE 35 +#define TK_TIMES 36 +#define TK_STAR 37 +#define TK_SLASH 38 +#define TK_REM 39 +#define TK_CONCAT 40 +#define TK_UMINUS 41 +#define TK_UPLUS 42 +#define TK_BITNOT 43 +#define TK_SHOW 44 +#define TK_DATABASES 45 +#define TK_TOPICS 46 +#define TK_MNODES 47 +#define TK_DNODES 48 +#define TK_ACCOUNTS 49 +#define TK_USERS 50 +#define TK_MODULES 51 +#define TK_QUERIES 52 +#define TK_CONNECTIONS 53 +#define TK_STREAMS 54 +#define TK_VARIABLES 55 +#define TK_SCORES 56 +#define TK_GRANTS 57 +#define TK_VNODES 58 +#define TK_IPTOKEN 59 +#define TK_DOT 60 +#define TK_CREATE 61 +#define TK_TABLE 62 +#define TK_STABLE 63 +#define TK_DATABASE 64 +#define TK_TABLES 65 +#define TK_STABLES 66 +#define TK_VGROUPS 67 +#define TK_DROP 68 +#define TK_TOPIC 69 +#define TK_DNODE 70 +#define TK_USER 71 +#define TK_ACCOUNT 72 +#define TK_USE 73 +#define TK_DESCRIBE 74 +#define TK_ALTER 75 +#define TK_PASS 76 +#define TK_PRIVILEGE 77 +#define TK_LOCAL 78 +#define TK_IF 79 +#define TK_EXISTS 80 +#define TK_PPS 81 +#define TK_TSERIES 82 +#define TK_DBS 83 +#define TK_STORAGE 84 +#define TK_QTIME 85 +#define TK_CONNS 86 +#define TK_STATE 87 +#define TK_KEEP 88 +#define TK_CACHE 89 +#define TK_REPLICA 90 +#define TK_QUORUM 91 +#define TK_DAYS 92 +#define TK_MINROWS 93 +#define TK_MAXROWS 94 +#define TK_BLOCKS 95 +#define TK_CTIME 96 +#define TK_WAL 97 +#define TK_FSYNC 98 +#define TK_COMP 99 #define TK_PRECISION 100 #define TK_UPDATE 101 #define TK_CACHELAST 102 diff --git a/src/kit/shell/src/shellCheck.c b/src/kit/shell/src/shellCheck.c index 8f7f47553657056623671c7616459cf18fcc9d4a..4ff5dc36fc72bf2bfaa7ffea3f6a47c619c6235b 100644 --- a/src/kit/shell/src/shellCheck.c +++ b/src/kit/shell/src/shellCheck.c @@ -148,15 +148,15 @@ static void *shellCheckThreadFp(void *arg) { return NULL; } -static void shellRunCheckThreads(TAOS *con, SShellArguments *args) { +static void shellRunCheckThreads(TAOS *con, SShellArguments *_args) { pthread_attr_t thattr; - ShellThreadObj *threadObj = (ShellThreadObj *)calloc(args->threadNum, sizeof(ShellThreadObj)); - for (int t = 0; t < args->threadNum; ++t) { + ShellThreadObj *threadObj = (ShellThreadObj *)calloc(_args->threadNum, sizeof(ShellThreadObj)); + for (int t = 0; t < _args->threadNum; ++t) { ShellThreadObj *pThread = threadObj + t; pThread->threadIndex = t; - pThread->totalThreads = args->threadNum; + pThread->totalThreads = _args->threadNum; pThread->taos = con; - pThread->db = args->database; + pThread->db = _args->database; pthread_attr_init(&thattr); pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); @@ -167,31 +167,31 @@ static void shellRunCheckThreads(TAOS *con, SShellArguments *args) { } } - for (int t = 0; t < args->threadNum; ++t) { + for (int t = 0; t < _args->threadNum; ++t) { pthread_join(threadObj[t].threadID, NULL); } - for (int t = 0; t < args->threadNum; ++t) { + for (int t = 0; t < _args->threadNum; ++t) { taos_close(threadObj[t].taos); } free(threadObj); } -void shellCheck(TAOS *con, SShellArguments *args) { +void shellCheck(TAOS *con, SShellArguments *_args) { int64_t start = taosGetTimestampMs(); - if (shellUseDb(con, args->database) != 0) { + if (shellUseDb(con, _args->database) != 0) { shellFreeTbnames(); return; } - if (shellShowTables(con, args->database) != 0) { + if (shellShowTables(con, _args->database) != 0) { shellFreeTbnames(); return; } - fprintf(stdout, "total %d tables will be checked by %d threads\n", tbNum, args->threadNum); - shellRunCheckThreads(con, args); + fprintf(stdout, "total %d tables will be checked by %d threads\n", tbNum, _args->threadNum); + shellRunCheckThreads(con, _args); int64_t end = taosGetTimestampMs(); fprintf(stdout, "total %d tables checked, failed:%d, time spent %.2f seconds\n", checkedNum, errorNum, diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index 0eb1248fad8fe78857b255d8861ea825ab501933..d4176fca91cd412b4d2d20a9a6c72a998c443428 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -56,24 +56,24 @@ extern TAOS *taos_connect_auth(const char *ip, const char *user, const char *aut /* * FUNCTION: Initialize the shell. */ -TAOS *shellInit(SShellArguments *args) { +TAOS *shellInit(SShellArguments *_args) { printf("\n"); printf(CLIENT_VERSION, tsOsName, taos_get_client_info()); fflush(stdout); // set options before initializing - if (args->timezone != NULL) { - taos_options(TSDB_OPTION_TIMEZONE, args->timezone); + if (_args->timezone != NULL) { + taos_options(TSDB_OPTION_TIMEZONE, _args->timezone); } - if (args->is_use_passwd) { - if (args->password == NULL) args->password = getpass("Enter password: "); + if (_args->is_use_passwd) { + if (_args->password == NULL) _args->password = getpass("Enter password: "); } else { - args->password = TSDB_DEFAULT_PASS; + _args->password = TSDB_DEFAULT_PASS; } - if (args->user == NULL) { - args->user = TSDB_DEFAULT_USER; + if (_args->user == NULL) { + _args->user = TSDB_DEFAULT_USER; } if (taos_init()) { @@ -84,10 +84,10 @@ TAOS *shellInit(SShellArguments *args) { // Connect to the database. TAOS *con = NULL; - if (args->auth == NULL) { - con = taos_connect(args->host, args->user, args->password, args->database, args->port); + if (_args->auth == NULL) { + con = taos_connect(_args->host, _args->user, _args->password, _args->database, _args->port); } else { - con = taos_connect_auth(args->host, args->user, args->auth, args->database, args->port); + con = taos_connect_auth(_args->host, _args->user, _args->auth, _args->database, _args->port); } if (con == NULL) { @@ -100,14 +100,14 @@ TAOS *shellInit(SShellArguments *args) { read_history(); // Check if it is temperory run - if (args->commands != NULL || args->file[0] != 0) { - if (args->commands != NULL) { - printf("%s%s\n", PROMPT_HEADER, args->commands); - shellRunCommand(con, args->commands); + if (_args->commands != NULL || _args->file[0] != 0) { + if (_args->commands != NULL) { + printf("%s%s\n", PROMPT_HEADER, _args->commands); + shellRunCommand(con, _args->commands); } - if (args->file[0] != 0) { - source_file(con, args->file); + if (_args->file[0] != 0) { + source_file(con, _args->file); } taos_close(con); @@ -116,14 +116,14 @@ TAOS *shellInit(SShellArguments *args) { } #ifndef WINDOWS - if (args->dir[0] != 0) { - source_dir(con, args); + if (_args->dir[0] != 0) { + source_dir(con, _args); taos_close(con); exit(EXIT_SUCCESS); } - if (args->check != 0) { - shellCheck(con, args); + if (_args->check != 0) { + shellCheck(con, _args); taos_close(con); exit(EXIT_SUCCESS); } diff --git a/src/kit/shell/src/shellImport.c b/src/kit/shell/src/shellImport.c index af61995c618bc80389b8abf6d8c6f6c929327925..5de50a3aaf70074da0592e628b932e49aaf89c48 100644 --- a/src/kit/shell/src/shellImport.c +++ b/src/kit/shell/src/shellImport.c @@ -233,15 +233,15 @@ void* shellImportThreadFp(void *arg) return NULL; } -static void shellRunImportThreads(SShellArguments* args) +static void shellRunImportThreads(SShellArguments* _args) { pthread_attr_t thattr; - ShellThreadObj *threadObj = (ShellThreadObj *)calloc(args->threadNum, sizeof(ShellThreadObj)); - for (int t = 0; t < args->threadNum; ++t) { + ShellThreadObj *threadObj = (ShellThreadObj *)calloc(_args->threadNum, sizeof(ShellThreadObj)); + for (int t = 0; t < _args->threadNum; ++t) { ShellThreadObj *pThread = threadObj + t; pThread->threadIndex = t; - pThread->totalThreads = args->threadNum; - pThread->taos = taos_connect(args->host, args->user, args->password, args->database, tsDnodeShellPort); + pThread->totalThreads = _args->threadNum; + pThread->taos = taos_connect(_args->host, _args->user, _args->password, _args->database, tsDnodeShellPort); if (pThread->taos == NULL) { fprintf(stderr, "ERROR: thread:%d failed connect to TDengine, error:%s\n", pThread->threadIndex, "null taos"/*taos_errstr(pThread->taos)*/); exit(0); @@ -256,18 +256,18 @@ static void shellRunImportThreads(SShellArguments* args) } } - for (int t = 0; t < args->threadNum; ++t) { + for (int t = 0; t < _args->threadNum; ++t) { pthread_join(threadObj[t].threadID, NULL); } - for (int t = 0; t < args->threadNum; ++t) { + for (int t = 0; t < _args->threadNum; ++t) { taos_close(threadObj[t].taos); } free(threadObj); } -void source_dir(TAOS* con, SShellArguments* args) { - shellGetDirectoryFileList(args->dir); +void source_dir(TAOS* con, SShellArguments* _args) { + shellGetDirectoryFileList(_args->dir); int64_t start = taosGetTimestampMs(); if (shellTablesSQLFile[0] != 0) { @@ -276,7 +276,7 @@ void source_dir(TAOS* con, SShellArguments* args) { fprintf(stdout, "import %s finished, time spent %.2f seconds\n", shellTablesSQLFile, (end - start) / 1000.0); } - shellRunImportThreads(args); + shellRunImportThreads(_args); int64_t end = taosGetTimestampMs(); - fprintf(stdout, "import %s finished, time spent %.2f seconds\n", args->dir, (end - start) / 1000.0); + fprintf(stdout, "import %s finished, time spent %.2f seconds\n", _args->dir, (end - start) / 1000.0); } diff --git a/src/kit/shell/src/shellLinux.c b/src/kit/shell/src/shellLinux.c index 37050c416c39d0624e620bf2e4a5fc7b7dfdc071..4eead252fd4c47893ba966c1686d375fd7b9b6dc 100644 --- a/src/kit/shell/src/shellLinux.c +++ b/src/kit/shell/src/shellLinux.c @@ -415,7 +415,7 @@ void set_terminal_mode() { } } -void get_history_path(char *history) { snprintf(history, TSDB_FILENAME_LEN, "%s/%s", getenv("HOME"), HISTORY_FILE); } +void get_history_path(char *_history) { snprintf(_history, TSDB_FILENAME_LEN, "%s/%s", getenv("HOME"), HISTORY_FILE); } void clearScreen(int ecmd_pos, int cursor_pos) { struct winsize w; diff --git a/src/kit/taosdemo/CMakeLists.txt b/src/kit/taosdemo/CMakeLists.txt index 4e38a8842e2f3d182dc4d038a7b44a619205b7f7..5f75be0e19065a70cf53f5e81285be2c25f1fb3e 100644 --- a/src/kit/taosdemo/CMakeLists.txt +++ b/src/kit/taosdemo/CMakeLists.txt @@ -10,7 +10,11 @@ IF (GIT_FOUND) COMMAND ${GIT_EXECUTABLE} log --pretty=oneline -n 1 ${CMAKE_CURRENT_LIST_DIR}/taosdemo.c RESULT_VARIABLE RESULT OUTPUT_VARIABLE TAOSDEMO_COMMIT_SHA1) - STRING(SUBSTRING "${TAOSDEMO_COMMIT_SHA1}" 0 7 TAOSDEMO_COMMIT_SHA1) + IF ("${TAOSDEMO_COMMIT_SHA1}" STREQUAL "") + MESSAGE("taosdemo's latest commit in short is:" ${TAOSDEMO_COMMIT_SHA1}) + ELSE () + STRING(SUBSTRING "${TAOSDEMO_COMMIT_SHA1}" 0 7 TAOSDEMO_COMMIT_SHA1) + ENDIF () EXECUTE_PROCESS( COMMAND ${GIT_EXECUTABLE} status -z -s ${CMAKE_CURRENT_LIST_DIR}/taosdemo.c RESULT_VARIABLE RESULT diff --git a/src/kit/taosdemo/async-sub.json b/src/kit/taosdemo/async-sub.json new file mode 100644 index 0000000000000000000000000000000000000000..a30a1be45cd8bcc6a6fadffd7473df7df067e839 --- /dev/null +++ b/src/kit/taosdemo/async-sub.json @@ -0,0 +1,41 @@ +{ + "filetype": "subscribe", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "databases": "test", + "specified_table_query": { + "concurrent": 1, + "mode": "async", + "interval": 1000, + "restart": "yes", + "keepProgress": "yes", + "resubAfterConsume": 10, + "sqls": [ + { + "sql": "select col1 from meters where col1 > 1;", + "result": "./subscribe_res0.txt" + }, + { + "sql": "select col2 from meters where col2 > 1;", + "result": "./subscribe_res2.txt" + } + ] + }, + "super_table_query": { + "stblname": "meters", + "threads": 1, + "mode": "sync", + "interval": 1000, + "restart": "yes", + "keepProgress": "yes", + "sqls": [ + { + "sql": "select col1 from xxxx where col1 > 10;", + "result": "./subscribe_res1.txt" + } + ] + } +} diff --git a/src/kit/taosdemo/subscribe.json b/src/kit/taosdemo/subscribe.json index fd33a2e2e2515ac268764c0a7f3f8356e998becd..9faf03a03d03b8baeffeb6a4397d1727dde0c594 100644 --- a/src/kit/taosdemo/subscribe.json +++ b/src/kit/taosdemo/subscribe.json @@ -1,17 +1,37 @@ { - "filetype":"subscribe", + "filetype": "subscribe", "cfgdir": "/etc/taos", "host": "127.0.0.1", "port": 6030, "user": "root", "password": "taosdata", - "databases": "dbx", - "specified_table_query": - {"concurrent":1, "mode":"sync", "interval":5000, "restart":"yes", "keepProgress":"yes", - "sqls": [{"sql": "select avg(col1) from stb01 where col1 > 1;", "result": "./subscribe_res0.txt"}] - }, - "super_table_query": - {"stblname": "stb", "threads":1, "mode":"sync", "interval":10000, "restart":"yes", "keepProgress":"yes", - "sqls": [{"sql": "select col1 from xxxx where col1 > 10;", "result": "./subscribe_res1.txt"}] - } + "databases": "test", + "specified_table_query": { + "concurrent": 1, + "mode": "sync", + "interval": 1000, + "restart": "yes", + "keepProgress": "yes", + "resubAfterConsume": 10, + "sqls": [ + { + "sql": "select avg(col1) from meters where col1 > 1;", + "result": "./subscribe_res0.txt" + } + ] + }, + "super_table_query": { + "stblname": "meters", + "threads": 1, + "mode": "sync", + "interval": 1000, + "restart": "yes", + "keepProgress": "yes", + "sqls": [ + { + "sql": "select col1 from xxxx where col1 > 10;", + "result": "./subscribe_res1.txt" + } + ] + } } diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index 8dea4995ee3a5d6430b5f485cba68fa5c5ccbe55..d946f961c33cb203f91b2e000004be1d789a2a17 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -19,6 +19,7 @@ */ #include +#include #define _GNU_SOURCE #define CURL_STATICLIB @@ -52,6 +53,8 @@ #include "taoserror.h" #include "tutil.h" +#define STMT_IFACE_ENABLED 1 + #define REQ_EXTRA_BUF_LEN 1024 #define RESP_BUF_LEN 4096 @@ -61,6 +64,8 @@ extern char configDir[]; #define QUERY_JSON_NAME "query.json" #define SUBSCRIBE_JSON_NAME "subscribe.json" +#define STR_INSERT_INTO "INSERT INTO " + enum TEST_MODE { INSERT_TEST, // 0 QUERY_TEST, // 1 @@ -68,6 +73,10 @@ enum TEST_MODE { INVAID_TEST }; +#define MAX_RECORDS_PER_REQ 32766 + +#define HEAD_BUFF_LEN 1024*24 // 16*1024 + (192+32)*2 + insert into .. + #define MAX_SQL_SIZE 65536 #define BUFFER_SIZE (65536*2) #define COND_BUF_LEN BUFFER_SIZE - 30 @@ -112,17 +121,30 @@ typedef enum TALBE_EXISTS_EN { TBL_EXISTS_BUTT } TALBE_EXISTS_EN; -enum MODE { +enum enumSYNC_MODE { SYNC_MODE, ASYNC_MODE, MODE_BUT }; -typedef enum enum_INSERT_MODE { +enum enum_TAOS_INTERFACE { + TAOSC_IFACE, + REST_IFACE, + STMT_IFACE, + INTERFACE_BUT +}; + +typedef enum enumQUERY_CLASS { + SPECIFIED_CLASS, + STABLE_CLASS, + CLASS_BUT +} QUERY_CLASS; + +typedef enum enum_PROGRESSIVE_OR_INTERLACE { PROGRESSIVE_INSERT_MODE, INTERLACE_INSERT_MODE, INVALID_INSERT_MODE -} INSERT_MODE; +} PROG_OR_INTERLACE_MODE; typedef enum enumQUERY_TYPE { NO_INSERT_TYPE, @@ -181,11 +203,14 @@ typedef struct { } SColDes; /* Used by main to communicate with parse_opt. */ +static char *g_dupstr = NULL; + typedef struct SArguments_S { char * metaFile; uint32_t test_mode; char * host; uint16_t port; + uint16_t iface; char * user; char * password; char * database; @@ -207,13 +232,13 @@ typedef struct SArguments_S { uint32_t num_of_threads; uint64_t insert_interval; int64_t query_times; - uint64_t interlace_rows; - uint64_t num_of_RPR; // num_of_records_per_req + uint32_t interlace_rows; + uint32_t num_of_RPR; // num_of_records_per_req uint64_t max_sql_len; - uint64_t num_of_tables; - uint64_t num_of_DPT; + int64_t num_of_tables; + int64_t num_of_DPT; int abort; - int disorderRatio; // 0: no disorder, >0: x% + uint32_t disorderRatio; // 0: no disorder, >0: x% int disorderRange; // ms or us by database precision uint32_t method_of_delete; char ** arg_list; @@ -225,29 +250,30 @@ typedef struct SColumn_S { char field[TSDB_COL_NAME_LEN + 1]; char dataType[MAX_TB_NAME_SIZE]; uint32_t dataLen; - char note[128]; + char note[128]; } StrColumn; typedef struct SSuperTable_S { char sTblName[MAX_TB_NAME_SIZE+1]; + char dataSource[MAX_TB_NAME_SIZE+1]; // rand_gen or sample + char childTblPrefix[MAX_TB_NAME_SIZE]; + char insertMode[MAX_TB_NAME_SIZE]; // taosc, rest + uint16_t childTblExists; int64_t childTblCount; - bool childTblExists; // 0: no, 1: yes uint64_t batchCreateTableNum; // 0: no batch, > 0: batch table number in one sql uint8_t autoCreateTable; // 0: create sub table, 1: auto create sub table - char childTblPrefix[MAX_TB_NAME_SIZE]; - char dataSource[MAX_TB_NAME_SIZE+1]; // rand_gen or sample - char insertMode[MAX_TB_NAME_SIZE]; // taosc, rest + uint16_t iface; // 0: taosc, 1: rest, 2: stmt int64_t childTblLimit; - uint64_t childTblOffset; + uint64_t childTblOffset; // int multiThreadWriteOneTbl; // 0: no, 1: yes - uint64_t interlaceRows; // + uint32_t interlaceRows; // int disorderRatio; // 0: no disorder, >0: x% int disorderRange; // ms or us by database precision uint64_t maxSqlLen; // uint64_t insertInterval; // insert interval, will override global insert interval - uint64_t insertRows; + int64_t insertRows; int64_t timeStampStep; char startTimestamp[MAX_TB_NAME_SIZE]; char sampleFormat[MAX_TB_NAME_SIZE]; // csv, json @@ -256,7 +282,7 @@ typedef struct SSuperTable_S { uint32_t columnCount; StrColumn columns[MAX_COLUMN_COUNT]; - uint32_t tagCount; + uint32_t tagCount; StrColumn tags[MAX_TAG_COUNT]; char* childTblName; @@ -281,7 +307,7 @@ typedef struct SSuperTable_S { typedef struct { char name[TSDB_DB_NAME_LEN + 1]; char create_time[32]; - int32_t ntables; + int64_t ntables; int32_t vgroups; int16_t replica; int16_t quorum; @@ -353,16 +379,21 @@ typedef struct SDbs_S { typedef struct SpecifiedQueryInfo_S { uint64_t queryInterval; // 0: unlimit > 0 loop/s - uint64_t concurrent; - uint64_t sqlCount; + uint32_t concurrent; + int sqlCount; uint32_t asyncMode; // 0: sync, 1: async uint64_t subscribeInterval; // ms uint64_t queryTimes; - int subscribeRestart; + bool subscribeRestart; int subscribeKeepProgress; char sql[MAX_QUERY_SQL_COUNT][MAX_QUERY_SQL_LENGTH+1]; char result[MAX_QUERY_SQL_COUNT][MAX_FILE_NAME_LEN+1]; + int resubAfterConsume[MAX_QUERY_SQL_COUNT]; + int endAfterConsume[MAX_QUERY_SQL_COUNT]; TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT]; + char topic[MAX_QUERY_SQL_COUNT][32]; + int consumed[MAX_QUERY_SQL_COUNT]; + TAOS_RES* res[MAX_QUERY_SQL_COUNT]; uint64_t totalQueried; } SpecifiedQueryInfo; @@ -372,14 +403,16 @@ typedef struct SuperQueryInfo_S { uint32_t threadCnt; uint32_t asyncMode; // 0: sync, 1: async uint64_t subscribeInterval; // ms - int subscribeRestart; + bool subscribeRestart; int subscribeKeepProgress; uint64_t queryTimes; - uint64_t childTblCount; + int64_t childTblCount; char childTblPrefix[MAX_TB_NAME_SIZE]; - uint64_t sqlCount; + int sqlCount; char sql[MAX_QUERY_SQL_COUNT][MAX_QUERY_SQL_LENGTH+1]; char result[MAX_QUERY_SQL_COUNT][MAX_FILE_NAME_LEN+1]; + int resubAfterConsume; + int endAfterConsume; TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT]; char* childTblName; @@ -397,25 +430,28 @@ typedef struct SQueryMetaInfo_S { char queryMode[MAX_TB_NAME_SIZE]; // taosc, rest SpecifiedQueryInfo specifiedQueryInfo; - SuperQueryInfo superQueryInfo; + SuperQueryInfo superQueryInfo; uint64_t totalQueried; } SQueryMetaInfo; typedef struct SThreadInfo_S { TAOS * taos; + TAOS_STMT *stmt; int threadID; char db_name[MAX_DB_NAME_SIZE+1]; uint32_t time_precision; - char fp[4096]; + char filePath[4096]; + FILE *fp; char tb_prefix[MAX_TB_NAME_SIZE]; uint64_t start_table_from; uint64_t end_table_to; - uint64_t ntables; + int64_t ntables; uint64_t data_of_rate; int64_t start_time; char* cols; bool use_metric; SSuperTable* superTblInfo; + char *buffer; // sql cmd buffer // for async insert tsem_t lock_sem; @@ -437,8 +473,10 @@ typedef struct SThreadInfo_S { uint64_t maxDelay; uint64_t minDelay; - // query + // seq of query or subscribe uint64_t querySeq; // sequence number of sql command + TAOS_SUB* tsub; + } threadInfo; #ifdef WINDOWS @@ -514,11 +552,14 @@ static int taosRandom() #endif // ifdef Windows +static void prompt(); static int createDatabasesAndStables(); static void createChildTables(); static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet); -static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port, - char* sqlstr, char *resultFile); +static int postProceSql(char *host, struct sockaddr_in *pServAddr, + uint16_t port, char* sqlstr, threadInfo *pThreadInfo); +static int64_t getTSRandTail(int64_t timeStampStep, int32_t seq, + int disorderRatio, int disorderRange); /* ************ Global variables ************ */ @@ -534,6 +575,7 @@ SArguments g_args = { 0, // test_mode "127.0.0.1", // host 6030, // port + TAOSC_IFACE, // iface "root", // user #ifdef _TD_POWER_ "powerdb", // password @@ -579,7 +621,7 @@ SArguments g_args = { static SDbs g_Dbs; -static int g_totalChildTables = 0; +static int64_t g_totalChildTables = 0; static SQueryMetaInfo g_queryInfo; static FILE * g_fpOfInsertResult = NULL; @@ -650,6 +692,12 @@ static void printHelp() { "The host to connect to TDengine. Default is localhost."); printf("%s%s%s%s\n", indent, "-p", indent, "The TCP/IP port number to use for the connection. Default is 0."); + printf("%s%s%s%s\n", indent, "-I", indent, +#if STMT_IFACE_ENABLED == 1 + "The interface (taosc, rest, and stmt) taosdemo uses. Default is 'taosc'."); +#else + "The interface (taosc, rest) taosdemo uses. Default is 'taosc'."); +#endif printf("%s%s%s%s\n", indent, "-d", indent, "Destination database. Default is 'test'."); printf("%s%s%s%s\n", indent, "-a", indent, @@ -666,8 +714,9 @@ static void printHelp() { "The data_type of columns, default: INT,INT,INT,INT."); printf("%s%s%s%s\n", indent, "-w", indent, "The length of data_type 'BINARY' or 'NCHAR'. Default is 16"); - printf("%s%s%s%s\n", indent, "-l", indent, - "The number of columns per record. Default is 4."); + printf("%s%s%s%s%d\n", indent, "-l", indent, + "The number of columns per record. Default is 4. Max values is ", + MAX_NUM_DATATYPE); printf("%s%s%s%s\n", indent, "-T", indent, "The number of threads. Default is 10."); printf("%s%s%s%s\n", indent, "-i", indent, @@ -711,7 +760,6 @@ static bool isStringNumber(char *input) } static void parse_args(int argc, char *argv[], SArguments *arguments) { - char **sptr; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-f") == 0) { @@ -723,7 +771,6 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { exit(EXIT_FAILURE); } tstrncpy(configDir, argv[++i], TSDB_FILENAME_LEN); - } else if (strcmp(argv[i], "-h") == 0) { if (argc == i+1) { printHelp(); @@ -739,6 +786,25 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { exit(EXIT_FAILURE); } arguments->port = atoi(argv[++i]); + } else if (strcmp(argv[i], "-I") == 0) { + if (argc == i+1) { + printHelp(); + errorPrint("%s", "\n\t-I need a valid string following!\n"); + exit(EXIT_FAILURE); + } + ++i; + if (0 == strcasecmp(argv[i], "taosc")) { + arguments->iface = TAOSC_IFACE; + } else if (0 == strcasecmp(argv[i], "rest")) { + arguments->iface = REST_IFACE; +#if STMT_IFACE_ENABLED == 1 + } else if (0 == strcasecmp(argv[i], "stmt")) { + arguments->iface = STMT_IFACE; +#endif + } else { + errorPrint("%s", "\n\t-I need a valid string following!\n"); + exit(EXIT_FAILURE); + } } else if (strcmp(argv[i], "-u") == 0) { if (argc == i+1) { printHelp(); @@ -768,16 +834,16 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->sqlFile = argv[++i]; } else if (strcmp(argv[i], "-q") == 0) { - if ((argc == i+1) || - (!isStringNumber(argv[i+1]))) { + if ((argc == i+1) + || (!isStringNumber(argv[i+1]))) { printHelp(); - errorPrint("%s", "\n\t-q need a number following!\nQuery mode -- 0: SYNC, 1: ASYNC. Default is SYNC.\n"); + errorPrint("%s", "\n\t-q need a number following!\nQuery mode -- 0: SYNC, not-0: ASYNC. Default is SYNC.\n"); exit(EXIT_FAILURE); } arguments->async_mode = atoi(argv[++i]); } else if (strcmp(argv[i], "-T") == 0) { - if ((argc == i+1) || - (!isStringNumber(argv[i+1]))) { + if ((argc == i+1) + || (!isStringNumber(argv[i+1]))) { printHelp(); errorPrint("%s", "\n\t-T need a number following!\n"); exit(EXIT_FAILURE); @@ -792,24 +858,24 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->insert_interval = atoi(argv[++i]); } else if (strcmp(argv[i], "-qt") == 0) { - if ((argc == i+1) || - (!isStringNumber(argv[i+1]))) { + if ((argc == i+1) + || (!isStringNumber(argv[i+1]))) { printHelp(); errorPrint("%s", "\n\t-qt need a number following!\n"); exit(EXIT_FAILURE); } arguments->query_times = atoi(argv[++i]); } else if (strcmp(argv[i], "-B") == 0) { - if ((argc == i+1) || - (!isStringNumber(argv[i+1]))) { + if ((argc == i+1) + || (!isStringNumber(argv[i+1]))) { printHelp(); errorPrint("%s", "\n\t-B need a number following!\n"); exit(EXIT_FAILURE); } arguments->interlace_rows = atoi(argv[++i]); } else if (strcmp(argv[i], "-r") == 0) { - if ((argc == i+1) || - (!isStringNumber(argv[i+1]))) { + if ((argc == i+1) + || (!isStringNumber(argv[i+1]))) { printHelp(); errorPrint("%s", "\n\t-r need a number following!\n"); exit(EXIT_FAILURE); @@ -839,15 +905,31 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } arguments->database = argv[++i]; } else if (strcmp(argv[i], "-l") == 0) { - if ((argc == i+1) || - (!isStringNumber(argv[i+1]))) { - printHelp(); - errorPrint("%s", "\n\t-l need a number following!\n"); - exit(EXIT_FAILURE); + if (argc == i+1) { + if (!isStringNumber(argv[i+1])) { + printHelp(); + errorPrint("%s", "\n\t-l need a number following!\n"); + exit(EXIT_FAILURE); + } } arguments->num_of_CPR = atoi(argv[++i]); + + if (arguments->num_of_CPR > MAX_NUM_DATATYPE) { + printf("WARNING: max acceptible columns count is %d\n", MAX_NUM_DATATYPE); + prompt(); + arguments->num_of_CPR = MAX_NUM_DATATYPE; + } + + for (int col = arguments->num_of_CPR; col < MAX_NUM_DATATYPE; col++) { + arguments->datatype[col] = NULL; + } + } else if (strcmp(argv[i], "-b") == 0) { - sptr = arguments->datatype; + if (argc == i+1) { + printHelp(); + errorPrint("%s", "\n\t-b need valid string following!\n"); + exit(EXIT_FAILURE); + } ++i; if (strstr(argv[i], ",") == NULL) { // only one col @@ -859,17 +941,18 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { && strcasecmp(argv[i], "BIGINT") && strcasecmp(argv[i], "DOUBLE") && strcasecmp(argv[i], "BINARY") + && strcasecmp(argv[i], "TIMESTAMP") && strcasecmp(argv[i], "NCHAR")) { printHelp(); errorPrint("%s", "-b: Invalid data_type!\n"); exit(EXIT_FAILURE); } - sptr[0] = argv[i]; + arguments->datatype[0] = argv[i]; } else { // more than one col int index = 0; - char *dupstr = strdup(argv[i]); - char *running = dupstr; + g_dupstr = strdup(argv[i]); + char *running = g_dupstr; char *token = strsep(&running, ","); while(token != NULL) { if (strcasecmp(token, "INT") @@ -880,18 +963,18 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { && strcasecmp(token, "BIGINT") && strcasecmp(token, "DOUBLE") && strcasecmp(token, "BINARY") + && strcasecmp(token, "TIMESTAMP") && strcasecmp(token, "NCHAR")) { printHelp(); - free(dupstr); + free(g_dupstr); errorPrint("%s", "-b: Invalid data_type!\n"); exit(EXIT_FAILURE); } - sptr[index++] = token; + arguments->datatype[index++] = token; token = strsep(&running, ","); if (index >= MAX_NUM_DATATYPE) break; } - free(dupstr); - sptr[index] = NULL; + arguments->datatype[index] = NULL; } } else if (strcmp(argv[i], "-w") == 0) { if ((argc == i+1) || @@ -982,6 +1065,19 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } } + int columnCount; + for (columnCount = 0; columnCount < MAX_NUM_DATATYPE; columnCount ++) { + if (g_args.datatype[columnCount] == NULL) { + break; + } + } + + if (0 == columnCount) { + perror("data type error!"); + exit(-1); + } + g_args.num_of_CPR = columnCount; + if (((arguments->debug_print) && (arguments->metaFile == NULL)) || arguments->verbose_print) { printf("###################################################################\n"); @@ -991,7 +1087,8 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { arguments->port ); printf("# User: %s\n", arguments->user); printf("# Password: %s\n", arguments->password); - printf("# Use metric: %s\n", arguments->use_metric ? "true" : "false"); + printf("# Use metric: %s\n", + arguments->use_metric ? "true" : "false"); if (*(arguments->datatype)) { printf("# Specified data type: "); for (int i = 0; i < MAX_NUM_DATATYPE; i++) @@ -1003,15 +1100,15 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } printf("# Insertion interval: %"PRIu64"\n", arguments->insert_interval); - printf("# Number of records per req: %"PRIu64"\n", + printf("# Number of records per req: %u\n", arguments->num_of_RPR); printf("# Max SQL length: %"PRIu64"\n", arguments->max_sql_len); printf("# Length of Binary: %d\n", arguments->len_of_binary); printf("# Number of Threads: %d\n", arguments->num_of_threads); - printf("# Number of Tables: %"PRIu64"\n", + printf("# Number of Tables: %"PRId64"\n", arguments->num_of_tables); - printf("# Number of Data per Table: %"PRIu64"\n", + printf("# Number of Data per Table: %"PRId64"\n", arguments->num_of_DPT); printf("# Database name: %s\n", arguments->database); printf("# Table prefix: %s\n", arguments->tb_prefix); @@ -1025,16 +1122,12 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { printf("# Print debug info: %d\n", arguments->debug_print); printf("# Print verbose info: %d\n", arguments->verbose_print); printf("###################################################################\n"); - if (!arguments->answer_yes) { - printf("Press enter key to continue\n\n"); - (void) getchar(); - } + + prompt(); } } static bool getInfoFromJsonFile(char* file); -//static int generateOneRowDataForStb(SSuperTable* stbInfo); -//static int getDataIntoMemForStb(SSuperTable* stbInfo); static void init_rand_data(); static void tmfclose(FILE *fp) { if (NULL != fp) { @@ -1053,7 +1146,7 @@ static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet) { TAOS_RES *res = NULL; int32_t code = -1; - for (i = 0; i < 5; i++) { + for (i = 0; i < 5 /* retry */; i++) { if (NULL != res) { taos_free_result(res); res = NULL; @@ -1066,10 +1159,11 @@ static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet) { } } + verbosePrint("%s() LN%d - command: %s\n", __func__, __LINE__, command); if (code != 0) { if (!quiet) { - debugPrint("%s() LN%d - command: %s\n", __func__, __LINE__, command); - errorPrint("Failed to run %s, reason: %s\n", command, taos_errstr(res)); + errorPrint("Failed to execute %s, reason: %s\n", + command, taos_errstr(res)); } taos_free_result(res); //taos_close(taos); @@ -1086,24 +1180,22 @@ static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet) { return 0; } -static void appendResultBufToFile(char *resultBuf, char *resultFile) +static void appendResultBufToFile(char *resultBuf, threadInfo *pThreadInfo) { - FILE *fp = NULL; - if (resultFile[0] != 0) { - fp = fopen(resultFile, "at"); - if (fp == NULL) { + pThreadInfo->fp = fopen(pThreadInfo->filePath, "at"); + if (pThreadInfo->fp == NULL) { errorPrint( "%s() LN%d, failed to open result file: %s, result will not save to file\n", - __func__, __LINE__, resultFile); + __func__, __LINE__, pThreadInfo->filePath); return; - } } - fprintf(fp, "%s", resultBuf); - tmfclose(fp); + fprintf(pThreadInfo->fp, "%s", resultBuf); + tmfclose(pThreadInfo->fp); + pThreadInfo->fp = NULL; } -static void appendResultToFile(TAOS_RES *res, char* resultFile) { +static void fetchResult(TAOS_RES *res, threadInfo* pThreadInfo) { TAOS_ROW row = NULL; int num_rows = 0; int num_fields = taos_field_count(res); @@ -1121,10 +1213,11 @@ static void appendResultToFile(TAOS_RES *res, char* resultFile) { // fetch the records row by row while((row = taos_fetch_row(res))) { - if (totalLen >= 100*1024*1024 - 32000) { - appendResultBufToFile(databuf, resultFile); - totalLen = 0; - memset(databuf, 0, 100*1024*1024); + if ((strlen(pThreadInfo->filePath) > 0) + && (totalLen >= 100*1024*1024 - 32000)) { + appendResultBufToFile(databuf, pThreadInfo); + totalLen = 0; + memset(databuf, 0, 100*1024*1024); } num_rows++; int len = taos_print_row(temp, row, fields, num_fields); @@ -1134,11 +1227,17 @@ static void appendResultToFile(TAOS_RES *res, char* resultFile) { totalLen += len; } - appendResultBufToFile(databuf, resultFile); + verbosePrint("%s() LN%d, databuf=%s resultFile=%s\n", + __func__, __LINE__, databuf, pThreadInfo->filePath); + if (strlen(pThreadInfo->filePath) > 0) { + appendResultBufToFile(databuf, pThreadInfo); + } free(databuf); } -static void selectAndGetResult(threadInfo *pThreadInfo, char *command, char* resultFileName) { +static void selectAndGetResult( + threadInfo *pThreadInfo, char *command) +{ if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", strlen("taosc"))) { TAOS_RES *res = taos_query(pThreadInfo->taos, command); if (res == NULL || taos_errno(res) != 0) { @@ -1148,14 +1247,14 @@ static void selectAndGetResult(threadInfo *pThreadInfo, char *command, char* res return; } - appendResultToFile(res, resultFileName); + fetchResult(res, pThreadInfo); taos_free_result(res); } else if (0 == strncasecmp(g_queryInfo.queryMode, "rest", strlen("rest"))) { int retCode = postProceSql( g_queryInfo.host, &(g_queryInfo.serv_addr), g_queryInfo.port, - g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq], - resultFileName); + command, + pThreadInfo); if (0 != retCode) { printf("====restful return fail, threadID[%d]\n", pThreadInfo->threadID); } @@ -1280,16 +1379,20 @@ static void init_rand_data() { static int printfInsertMeta() { SHOW_PARSE_RESULT_START(); - printf("host: \033[33m%s:%u\033[0m\n", g_Dbs.host, g_Dbs.port); + printf("interface: \033[33m%s\033[0m\n", + (g_args.iface==TAOSC_IFACE)?"taosc":(g_args.iface==REST_IFACE)?"rest":"stmt"); + printf("host: \033[33m%s:%u\033[0m\n", + g_Dbs.host, g_Dbs.port); printf("user: \033[33m%s\033[0m\n", g_Dbs.user); printf("password: \033[33m%s\033[0m\n", g_Dbs.password); printf("configDir: \033[33m%s\033[0m\n", configDir); printf("resultFile: \033[33m%s\033[0m\n", g_Dbs.resultFile); printf("thread num of insert data: \033[33m%d\033[0m\n", g_Dbs.threadCount); - printf("thread num of create table: \033[33m%d\033[0m\n", g_Dbs.threadCountByCreateTbl); + printf("thread num of create table: \033[33m%d\033[0m\n", + g_Dbs.threadCountByCreateTbl); printf("top insert interval: \033[33m%"PRIu64"\033[0m\n", g_args.insert_interval); - printf("number of records per req: \033[33m%"PRIu64"\033[0m\n", + printf("number of records per req: \033[33m%u\033[0m\n", g_args.num_of_RPR); printf("max sql length: \033[33m%"PRIu64"\033[0m\n", g_args.max_sql_len); @@ -1298,7 +1401,8 @@ static int printfInsertMeta() { for (int i = 0; i < g_Dbs.dbCount; i++) { printf("database[\033[33m%d\033[0m]:\n", i); - printf(" database[%d] name: \033[33m%s\033[0m\n", i, g_Dbs.db[i].dbName); + printf(" database[%d] name: \033[33m%s\033[0m\n", + i, g_Dbs.db[i].dbName); if (0 == g_Dbs.db[i].drop) { printf(" drop: \033[33mno\033[0m\n"); } else { @@ -1306,40 +1410,51 @@ static int printfInsertMeta() { } if (g_Dbs.db[i].dbCfg.blocks > 0) { - printf(" blocks: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.blocks); + printf(" blocks: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.blocks); } if (g_Dbs.db[i].dbCfg.cache > 0) { - printf(" cache: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.cache); + printf(" cache: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.cache); } if (g_Dbs.db[i].dbCfg.days > 0) { - printf(" days: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.days); + printf(" days: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.days); } if (g_Dbs.db[i].dbCfg.keep > 0) { - printf(" keep: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.keep); + printf(" keep: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.keep); } if (g_Dbs.db[i].dbCfg.replica > 0) { - printf(" replica: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.replica); + printf(" replica: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.replica); } if (g_Dbs.db[i].dbCfg.update > 0) { - printf(" update: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.update); + printf(" update: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.update); } if (g_Dbs.db[i].dbCfg.minRows > 0) { - printf(" minRows: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.minRows); + printf(" minRows: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.minRows); } if (g_Dbs.db[i].dbCfg.maxRows > 0) { - printf(" maxRows: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.maxRows); + printf(" maxRows: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.maxRows); } if (g_Dbs.db[i].dbCfg.comp > 0) { printf(" comp: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.comp); } if (g_Dbs.db[i].dbCfg.walLevel > 0) { - printf(" walLevel: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.walLevel); + printf(" walLevel: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.walLevel); } if (g_Dbs.db[i].dbCfg.fsync > 0) { - printf(" fsync: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.fsync); + printf(" fsync: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.fsync); } if (g_Dbs.db[i].dbCfg.quorum > 0) { - printf(" quorum: \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.quorum); + printf(" quorum: \033[33m%d\033[0m\n", + g_Dbs.db[i].dbCfg.quorum); } if (g_Dbs.db[i].dbCfg.precision[0] != 0) { if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2)) @@ -1363,7 +1478,8 @@ static int printfInsertMeta() { if (PRE_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) { printf(" autoCreateTable: \033[33m%s\033[0m\n", "no"); - } else if (AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) { + } else if (AUTO_CREATE_SUBTBL == + g_Dbs.db[i].superTbls[j].autoCreateTable) { printf(" autoCreateTable: \033[33m%s\033[0m\n", "yes"); } else { printf(" autoCreateTable: \033[33m%s\033[0m\n", "error"); @@ -1377,14 +1493,15 @@ static int printfInsertMeta() { printf(" childTblExists: \033[33m%s\033[0m\n", "error"); } - printf(" childTblCount: \033[33m%"PRIu64"\033[0m\n", + printf(" childTblCount: \033[33m%"PRId64"\033[0m\n", g_Dbs.db[i].superTbls[j].childTblCount); printf(" childTblPrefix: \033[33m%s\033[0m\n", g_Dbs.db[i].superTbls[j].childTblPrefix); printf(" dataSource: \033[33m%s\033[0m\n", g_Dbs.db[i].superTbls[j].dataSource); - printf(" insertMode: \033[33m%s\033[0m\n", - g_Dbs.db[i].superTbls[j].insertMode); + printf(" iface: \033[33m%s\033[0m\n", + (g_Dbs.db[i].superTbls[j].iface==TAOSC_IFACE)?"taosc": + (g_Dbs.db[i].superTbls[j].iface==REST_IFACE)?"rest":"stmt"); if (g_Dbs.db[i].superTbls[j].childTblLimit > 0) { printf(" childTblLimit: \033[33m%"PRId64"\033[0m\n", g_Dbs.db[i].superTbls[j].childTblLimit); @@ -1393,7 +1510,7 @@ static int printfInsertMeta() { printf(" childTblOffset: \033[33m%"PRIu64"\033[0m\n", g_Dbs.db[i].superTbls[j].childTblOffset); } - printf(" insertRows: \033[33m%"PRIu64"\033[0m\n", + printf(" insertRows: \033[33m%"PRId64"\033[0m\n", g_Dbs.db[i].superTbls[j].insertRows); /* if (0 == g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl) { @@ -1402,7 +1519,7 @@ static int printfInsertMeta() { printf(" multiThreadWriteOneTbl: \033[33myes\033[0m\n"); } */ - printf(" interlaceRows: \033[33m%"PRIu64"\033[0m\n", + printf(" interlaceRows: \033[33m%u\033[0m\n", g_Dbs.db[i].superTbls[j].interlaceRows); if (g_Dbs.db[i].superTbls[j].interlaceRows > 0) { @@ -1480,7 +1597,7 @@ static void printfInsertMetaToFile(FILE* fp) { fprintf(fp, "resultFile: %s\n", g_Dbs.resultFile); fprintf(fp, "thread num of insert data: %d\n", g_Dbs.threadCount); fprintf(fp, "thread num of create table: %d\n", g_Dbs.threadCountByCreateTbl); - fprintf(fp, "number of records per req: %"PRIu64"\n", g_args.num_of_RPR); + fprintf(fp, "number of records per req: %u\n", g_args.num_of_RPR); fprintf(fp, "max sql length: %"PRIu64"\n", g_args.max_sql_len); fprintf(fp, "database count: %d\n", g_Dbs.dbCount); @@ -1532,21 +1649,26 @@ static void printfInsertMetaToFile(FILE* fp) { if (g_Dbs.db[i].dbCfg.precision[0] != 0) { if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2)) || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) { - fprintf(fp, " precision: %s\n", g_Dbs.db[i].dbCfg.precision); + fprintf(fp, " precision: %s\n", + g_Dbs.db[i].dbCfg.precision); } else { - fprintf(fp, " precision error: %s\n", g_Dbs.db[i].dbCfg.precision); + fprintf(fp, " precision error: %s\n", + g_Dbs.db[i].dbCfg.precision); } } - fprintf(fp, " super table count: %"PRIu64"\n", g_Dbs.db[i].superTblCount); + fprintf(fp, " super table count: %"PRIu64"\n", + g_Dbs.db[i].superTblCount); for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { fprintf(fp, " super table[%d]:\n", j); - fprintf(fp, " stbName: %s\n", g_Dbs.db[i].superTbls[j].sTblName); + fprintf(fp, " stbName: %s\n", + g_Dbs.db[i].superTbls[j].sTblName); if (PRE_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) { fprintf(fp, " autoCreateTable: %s\n", "no"); - } else if (AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) { + } else if (AUTO_CREATE_SUBTBL + == g_Dbs.db[i].superTbls[j].autoCreateTable) { fprintf(fp, " autoCreateTable: %s\n", "yes"); } else { fprintf(fp, " autoCreateTable: %s\n", "error"); @@ -1554,23 +1676,25 @@ static void printfInsertMetaToFile(FILE* fp) { if (TBL_NO_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists) { fprintf(fp, " childTblExists: %s\n", "no"); - } else if (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists) { + } else if (TBL_ALREADY_EXISTS + == g_Dbs.db[i].superTbls[j].childTblExists) { fprintf(fp, " childTblExists: %s\n", "yes"); } else { fprintf(fp, " childTblExists: %s\n", "error"); } - fprintf(fp, " childTblCount: %"PRIu64"\n", + fprintf(fp, " childTblCount: %"PRId64"\n", g_Dbs.db[i].superTbls[j].childTblCount); fprintf(fp, " childTblPrefix: %s\n", g_Dbs.db[i].superTbls[j].childTblPrefix); fprintf(fp, " dataSource: %s\n", g_Dbs.db[i].superTbls[j].dataSource); - fprintf(fp, " insertMode: %s\n", - g_Dbs.db[i].superTbls[j].insertMode); - fprintf(fp, " insertRows: %"PRIu64"\n", + fprintf(fp, " iface: %s\n", + (g_Dbs.db[i].superTbls[j].iface==TAOSC_IFACE)?"taosc": + (g_Dbs.db[i].superTbls[j].iface==REST_IFACE)?"rest":"stmt"); + fprintf(fp, " insertRows: %"PRId64"\n", g_Dbs.db[i].superTbls[j].insertRows); - fprintf(fp, " interlace rows: %"PRIu64"\n", + fprintf(fp, " interlace rows: %u\n", g_Dbs.db[i].superTbls[j].interlaceRows); if (g_Dbs.db[i].superTbls[j].interlaceRows > 0) { fprintf(fp, " stable insert interval: %"PRIu64"\n", @@ -1583,10 +1707,12 @@ static void printfInsertMetaToFile(FILE* fp) { fprintf(fp, " multiThreadWriteOneTbl: yes\n"); } */ - fprintf(fp, " interlaceRows: %"PRIu64"\n", + fprintf(fp, " interlaceRows: %u\n", g_Dbs.db[i].superTbls[j].interlaceRows); - fprintf(fp, " disorderRange: %d\n", g_Dbs.db[i].superTbls[j].disorderRange); - fprintf(fp, " disorderRatio: %d\n", g_Dbs.db[i].superTbls[j].disorderRatio); + fprintf(fp, " disorderRange: %d\n", + g_Dbs.db[i].superTbls[j].disorderRange); + fprintf(fp, " disorderRatio: %d\n", + g_Dbs.db[i].superTbls[j].disorderRatio); fprintf(fp, " maxSqlLen: %"PRIu64"\n", g_Dbs.db[i].superTbls[j].maxSqlLen); @@ -1594,23 +1720,29 @@ static void printfInsertMetaToFile(FILE* fp) { g_Dbs.db[i].superTbls[j].timeStampStep); fprintf(fp, " startTimestamp: %s\n", g_Dbs.db[i].superTbls[j].startTimestamp); - fprintf(fp, " sampleFormat: %s\n", g_Dbs.db[i].superTbls[j].sampleFormat); - fprintf(fp, " sampleFile: %s\n", g_Dbs.db[i].superTbls[j].sampleFile); - fprintf(fp, " tagsFile: %s\n", g_Dbs.db[i].superTbls[j].tagsFile); + fprintf(fp, " sampleFormat: %s\n", + g_Dbs.db[i].superTbls[j].sampleFormat); + fprintf(fp, " sampleFile: %s\n", + g_Dbs.db[i].superTbls[j].sampleFile); + fprintf(fp, " tagsFile: %s\n", + g_Dbs.db[i].superTbls[j].tagsFile); - fprintf(fp, " columnCount: %d\n ", g_Dbs.db[i].superTbls[j].columnCount); + fprintf(fp, " columnCount: %d\n ", + g_Dbs.db[i].superTbls[j].columnCount); for (int k = 0; k < g_Dbs.db[i].superTbls[j].columnCount; k++) { //printf("dataType:%s, dataLen:%d\t", g_Dbs.db[i].superTbls[j].columns[k].dataType, g_Dbs.db[i].superTbls[j].columns[k].dataLen); if ((0 == strncasecmp( g_Dbs.db[i].superTbls[j].columns[k].dataType, "binary", strlen("binary"))) - || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType, + || (0 == strncasecmp( + g_Dbs.db[i].superTbls[j].columns[k].dataType, "nchar", strlen("nchar")))) { fprintf(fp, "column[%d]:%s(%d) ", k, g_Dbs.db[i].superTbls[j].columns[k].dataType, g_Dbs.db[i].superTbls[j].columns[k].dataLen); } else { - fprintf(fp, "column[%d]:%s ", k, g_Dbs.db[i].superTbls[j].columns[k].dataType); + fprintf(fp, "column[%d]:%s ", + k, g_Dbs.db[i].superTbls[j].columns[k].dataType); } } fprintf(fp, "\n"); @@ -1623,7 +1755,8 @@ static void printfInsertMetaToFile(FILE* fp) { "binary", strlen("binary"))) || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType, "nchar", strlen("nchar")))) { - fprintf(fp, "tag[%d]:%s(%d) ", k, g_Dbs.db[i].superTbls[j].tags[k].dataType, + fprintf(fp, "tag[%d]:%s(%d) ", + k, g_Dbs.db[i].superTbls[j].tags[k].dataType, g_Dbs.db[i].superTbls[j].tags[k].dataLen); } else { fprintf(fp, "tag[%d]:%s ", k, g_Dbs.db[i].superTbls[j].tags[k].dataType); @@ -1650,7 +1783,7 @@ static void printfQueryMeta() { if ((SUBSCRIBE_TEST == g_args.test_mode) || (QUERY_TEST == g_args.test_mode)) { printf("specified table query info: \n"); - printf("sqlCount: \033[33m%"PRIu64"\033[0m\n", + printf("sqlCount: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.sqlCount); if (g_queryInfo.specifiedQueryInfo.sqlCount > 0) { printf("specified tbl query times:\n"); @@ -1659,7 +1792,7 @@ static void printfQueryMeta() { printf("query interval: \033[33m%"PRIu64" ms\033[0m\n", g_queryInfo.specifiedQueryInfo.queryInterval); printf("top query times:\033[33m%"PRIu64"\033[0m\n", g_args.query_times); - printf("concurrent: \033[33m%"PRIu64"\033[0m\n", + printf("concurrent: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.concurrent); printf("mod: \033[33m%s\033[0m\n", (g_queryInfo.specifiedQueryInfo.asyncMode)?"async":"sync"); @@ -1670,15 +1803,15 @@ static void printfQueryMeta() { printf("keepProgress: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.subscribeKeepProgress); - for (uint64_t i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { - printf(" sql[%"PRIu64"]: \033[33m%s\033[0m\n", + for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { + printf(" sql[%d]: \033[33m%s\033[0m\n", i, g_queryInfo.specifiedQueryInfo.sql[i]); } printf("\n"); } printf("super table query info:\n"); - printf("sqlCount: \033[33m%"PRIu64"\033[0m\n", + printf("sqlCount: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.sqlCount); if (g_queryInfo.superQueryInfo.sqlCount > 0) { @@ -1686,7 +1819,7 @@ static void printfQueryMeta() { g_queryInfo.superQueryInfo.queryInterval); printf("threadCnt: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.threadCnt); - printf("childTblCount: \033[33m%"PRIu64"\033[0m\n", + printf("childTblCount: \033[33m%"PRId64"\033[0m\n", g_queryInfo.superQueryInfo.childTblCount); printf("stable name: \033[33m%s\033[0m\n", g_queryInfo.superQueryInfo.sTblName); @@ -1868,7 +2001,7 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { formatTimestamp(dbInfos[count]->create_time, *(int64_t*)row[TSDB_SHOW_DB_CREATED_TIME_INDEX], TSDB_TIME_PRECISION_MILLI); - dbInfos[count]->ntables = *((int32_t *)row[TSDB_SHOW_DB_NTABLES_INDEX]); + dbInfos[count]->ntables = *((int64_t *)row[TSDB_SHOW_DB_NTABLES_INDEX]); dbInfos[count]->vgroups = *((int32_t *)row[TSDB_SHOW_DB_VGROUPS_INDEX]); dbInfos[count]->replica = *((int16_t *)row[TSDB_SHOW_DB_REPLICA_INDEX]); dbInfos[count]->quorum = *((int16_t *)row[TSDB_SHOW_DB_QUORUM_INDEX]); @@ -1919,7 +2052,7 @@ static void printfDbInfoForQueryToFile( fprintf(fp, "================ database[%d] ================\n", index); fprintf(fp, "name: %s\n", dbInfos->name); fprintf(fp, "created_time: %s\n", dbInfos->create_time); - fprintf(fp, "ntables: %d\n", dbInfos->ntables); + fprintf(fp, "ntables: %"PRId64"\n", dbInfos->ntables); fprintf(fp, "vgroups: %d\n", dbInfos->vgroups); fprintf(fp, "replica: %d\n", dbInfos->replica); fprintf(fp, "quorum: %d\n", dbInfos->quorum); @@ -1956,13 +2089,13 @@ static void printfQuerySystemInfo(TAOS * taos) { // show variables res = taos_query(taos, "show variables;"); - //appendResultToFile(res, filename); + //fetchResult(res, filename); xDumpResultToFile(filename, res); // show dnodes res = taos_query(taos, "show dnodes;"); xDumpResultToFile(filename, res); - //appendResultToFile(res, filename); + //fetchResult(res, filename); // show databases res = taos_query(taos, "show databases;"); @@ -1998,7 +2131,7 @@ static void printfQuerySystemInfo(TAOS * taos) { } static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port, - char* sqlstr, char *resultFile) + char* sqlstr, threadInfo *pThreadInfo) { char *req_fmt = "POST %s HTTP/1.1\r\nHost: %s:%d\r\nAccept: */*\r\nAuthorization: Basic %s\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n%s"; @@ -2134,8 +2267,8 @@ static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port response_buf[RESP_BUF_LEN - 1] = '\0'; printf("Response:\n%s\n", response_buf); - if (resultFile) { - appendResultBufToFile(response_buf, resultFile); + if (strlen(pThreadInfo->filePath) > 0) { + appendResultBufToFile(response_buf, pThreadInfo); } free(request_buf); @@ -2316,7 +2449,7 @@ static int calcRowLen(SSuperTable* superTbls) { static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, char* dbName, char* sTblName, char** childTblNameOfSuperTbl, - uint64_t* childTblCountOfSuperTbl, int64_t limit, uint64_t offset) { + int64_t* childTblCountOfSuperTbl, int64_t limit, uint64_t offset) { char command[BUFFER_SIZE] = "\0"; char limitBuf[100] = "\0"; @@ -2345,8 +2478,8 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, exit(-1); } - int childTblCount = (limit < 0)?10000:limit; - int count = 0; + int64_t childTblCount = (limit < 0)?10000:limit; + int64_t count = 0; if (childTblName == NULL) { childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN); if (NULL == childTblName) { @@ -2393,7 +2526,7 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, static int getAllChildNameOfSuperTable(TAOS * taos, char* dbName, char* sTblName, char** childTblNameOfSuperTbl, - uint64_t* childTblCountOfSuperTbl) { + int64_t* childTblCountOfSuperTbl) { return getChildNameOfSuperTableWithLimitAndOffset(taos, dbName, sTblName, childTblNameOfSuperTbl, childTblCountOfSuperTbl, @@ -2627,8 +2760,6 @@ static int createSuperTable( snprintf(command, BUFFER_SIZE, "create table if not exists %s.%s (ts timestamp%s) tags %s", dbName, superTbl->sTblName, cols, tags); - verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, command); - if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) { errorPrint( "create supertable %s failed!\n\n", superTbl->sTblName); @@ -2651,7 +2782,6 @@ static int createDatabasesAndStables() { for (int i = 0; i < g_Dbs.dbCount; i++) { if (g_Dbs.db[i].drop) { sprintf(command, "drop database if exists %s;", g_Dbs.db[i].dbName); - verbosePrint("%s() %d command: %s\n", __func__, __LINE__, command); if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) { taos_close(taos); return -1; @@ -2724,7 +2854,6 @@ static int createDatabasesAndStables() { " precision \'%s\';", g_Dbs.db[i].dbCfg.precision); } - debugPrint("%s() %d command: %s\n", __func__, __LINE__, command); if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) { taos_close(taos); errorPrint( "\ncreate database %s failed!\n\n", g_Dbs.db[i].dbName); @@ -2738,11 +2867,9 @@ static int createDatabasesAndStables() { int validStbCount = 0; - for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { + for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) { sprintf(command, "describe %s.%s;", g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].sTblName); - verbosePrint("%s() %d command: %s\n", __func__, __LINE__, command); - ret = queryDbExec(taos, command, NO_INSERT_TYPE, true); if ((ret != 0) || (g_Dbs.db[i].drop)) { @@ -2750,7 +2877,7 @@ static int createDatabasesAndStables() { &g_Dbs.db[i].superTbls[j]); if (0 != ret) { - errorPrint("create super table %d failed!\n\n", j); + errorPrint("create super table %"PRIu64" failed!\n\n", j); continue; } } @@ -2778,13 +2905,13 @@ static void* createTable(void *sarg) threadInfo *pThreadInfo = (threadInfo *)sarg; SSuperTable* superTblInfo = pThreadInfo->superTblInfo; - int64_t lastPrintTime = taosGetTimestampMs(); + uint64_t lastPrintTime = taosGetTimestampMs(); int buff_len; buff_len = BUFFER_SIZE / 8; - char *buffer = calloc(buff_len, 1); - if (buffer == NULL) { + pThreadInfo->buffer = calloc(buff_len, 1); + if (pThreadInfo->buffer == NULL) { errorPrint("%s() LN%d, Memory allocated failed!\n", __func__, __LINE__); exit(-1); } @@ -2799,7 +2926,7 @@ static void* createTable(void *sarg) for (uint64_t i = pThreadInfo->start_table_from; i <= pThreadInfo->end_table_to; i++) { if (0 == g_Dbs.use_metric) { - snprintf(buffer, buff_len, + snprintf(pThreadInfo->buffer, buff_len, "create table if not exists %s.%s%"PRIu64" %s;", pThreadInfo->db_name, g_args.tb_prefix, i, @@ -2808,13 +2935,13 @@ static void* createTable(void *sarg) if (superTblInfo == NULL) { errorPrint("%s() LN%d, use metric, but super table info is NULL\n", __func__, __LINE__); - free(buffer); + free(pThreadInfo->buffer); exit(-1); } else { if (0 == len) { batchNum = 0; - memset(buffer, 0, buff_len); - len += snprintf(buffer + len, + memset(pThreadInfo->buffer, 0, buff_len); + len += snprintf(pThreadInfo->buffer + len, buff_len - len, "create table "); } char* tagsValBuf = NULL; @@ -2826,10 +2953,10 @@ static void* createTable(void *sarg) i % superTblInfo->tagSampleCount); } if (NULL == tagsValBuf) { - free(buffer); + free(pThreadInfo->buffer); return NULL; } - len += snprintf(buffer + len, + len += snprintf(pThreadInfo->buffer + len, buff_len - len, "if not exists %s.%s%"PRIu64" using %s.%s tags %s ", pThreadInfo->db_name, superTblInfo->childTblPrefix, @@ -2846,14 +2973,14 @@ static void* createTable(void *sarg) } len = 0; - verbosePrint("%s() LN%d %s\n", __func__, __LINE__, buffer); - if (0 != queryDbExec(pThreadInfo->taos, buffer, NO_INSERT_TYPE, false)){ - errorPrint( "queryDbExec() failed. buffer:\n%s\n", buffer); - free(buffer); + if (0 != queryDbExec(pThreadInfo->taos, pThreadInfo->buffer, + NO_INSERT_TYPE, false)){ + errorPrint( "queryDbExec() failed. buffer:\n%s\n", pThreadInfo->buffer); + free(pThreadInfo->buffer); return NULL; } - int64_t currentPrintTime = taosGetTimestampMs(); + uint64_t currentPrintTime = taosGetTimestampMs(); if (currentPrintTime - lastPrintTime > 30*1000) { printf("thread[%d] already create %"PRIu64" - %"PRIu64" tables\n", pThreadInfo->threadID, pThreadInfo->start_table_from, i); @@ -2862,22 +2989,22 @@ static void* createTable(void *sarg) } if (0 != len) { - verbosePrint("%s() %d buffer: %s\n", __func__, __LINE__, buffer); - if (0 != queryDbExec(pThreadInfo->taos, buffer, NO_INSERT_TYPE, false)) { - errorPrint( "queryDbExec() failed. buffer:\n%s\n", buffer); + if (0 != queryDbExec(pThreadInfo->taos, pThreadInfo->buffer, + NO_INSERT_TYPE, false)) { + errorPrint( "queryDbExec() failed. buffer:\n%s\n", pThreadInfo->buffer); } } - free(buffer); + free(pThreadInfo->buffer); return NULL; } static int startMultiThreadCreateChildTable( - char* cols, int threads, uint64_t startFrom, uint64_t ntables, + char* cols, int threads, uint64_t tableFrom, int64_t ntables, char* db_name, SSuperTable* superTblInfo) { pthread_t *pids = malloc(threads * sizeof(pthread_t)); - threadInfo *infos = malloc(threads * sizeof(threadInfo)); + threadInfo *infos = calloc(1, threads * sizeof(threadInfo)); if ((NULL == pids) || (NULL == infos)) { printf("malloc failed\n"); @@ -2888,28 +3015,28 @@ static int startMultiThreadCreateChildTable( threads = 1; } - uint64_t a = ntables / threads; + int64_t a = ntables / threads; if (a < 1) { threads = ntables; a = 1; } - uint64_t b = 0; + int64_t b = 0; b = ntables % threads; for (int64_t i = 0; i < threads; i++) { - threadInfo *t_info = infos + i; - t_info->threadID = i; - tstrncpy(t_info->db_name, db_name, MAX_DB_NAME_SIZE); - t_info->superTblInfo = superTblInfo; + threadInfo *pThreadInfo = infos + i; + pThreadInfo->threadID = i; + tstrncpy(pThreadInfo->db_name, db_name, MAX_DB_NAME_SIZE); + pThreadInfo->superTblInfo = superTblInfo; verbosePrint("%s() %d db_name: %s\n", __func__, __LINE__, db_name); - t_info->taos = taos_connect( + pThreadInfo->taos = taos_connect( g_Dbs.host, g_Dbs.user, g_Dbs.password, db_name, g_Dbs.port); - if (t_info->taos == NULL) { + if (pThreadInfo->taos == NULL) { errorPrint( "%s() LN%d, Failed to connect to TDengine, reason:%s\n", __func__, __LINE__, taos_errstr(NULL)); free(pids); @@ -2917,14 +3044,14 @@ static int startMultiThreadCreateChildTable( return -1; } - t_info->start_table_from = startFrom; - t_info->ntables = iend_table_to = i < b ? startFrom + a : startFrom + a - 1; - startFrom = t_info->end_table_to + 1; - t_info->use_metric = true; - t_info->cols = cols; - t_info->minDelay = UINT64_MAX; - pthread_create(pids + i, NULL, createTable, t_info); + pThreadInfo->start_table_from = tableFrom; + pThreadInfo->ntables = iend_table_to = i < b ? tableFrom + a : tableFrom + a - 1; + tableFrom = pThreadInfo->end_table_to + 1; + pThreadInfo->use_metric = true; + pThreadInfo->cols = cols; + pThreadInfo->minDelay = UINT64_MAX; + pthread_create(pids + i, NULL, createTable, pThreadInfo); } for (int i = 0; i < threads; i++) { @@ -2932,8 +3059,8 @@ static int startMultiThreadCreateChildTable( } for (int i = 0; i < threads; i++) { - threadInfo *t_info = infos + i; - taos_close(t_info->taos); + threadInfo *pThreadInfo = infos + i; + taos_close(pThreadInfo->taos); } free(pids); @@ -2946,61 +3073,61 @@ static void createChildTables() { char tblColsBuf[MAX_SQL_SIZE]; int len; - for (int i = 0; i < g_Dbs.dbCount; i++) { - if (g_Dbs.use_metric) { - if (g_Dbs.db[i].superTblCount > 0) { - // with super table - for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { - if ((AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) - || (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists)) { - continue; - } - - verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, - g_Dbs.db[i].superTbls[j].colsOfCreateChildTable); - int startFrom = 0; - g_totalChildTables += g_Dbs.db[i].superTbls[j].childTblCount; - - verbosePrint("%s() LN%d: create %d child tables from %d\n", - __func__, __LINE__, g_totalChildTables, startFrom); - startMultiThreadCreateChildTable( - g_Dbs.db[i].superTbls[j].colsOfCreateChildTable, - g_Dbs.threadCountByCreateTbl, - startFrom, - g_Dbs.db[i].superTbls[j].childTblCount, - g_Dbs.db[i].dbName, &(g_Dbs.db[i].superTbls[j])); + for (int i = 0; i < g_Dbs.dbCount; i++) { + if (g_Dbs.use_metric) { + if (g_Dbs.db[i].superTblCount > 0) { + // with super table + for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { + if ((AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) + || (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists)) { + continue; + } + verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, + g_Dbs.db[i].superTbls[j].colsOfCreateChildTable); + uint64_t startFrom = 0; + g_totalChildTables += g_Dbs.db[i].superTbls[j].childTblCount; + + verbosePrint("%s() LN%d: create %"PRId64" child tables from %"PRIu64"\n", + __func__, __LINE__, g_totalChildTables, startFrom); + + startMultiThreadCreateChildTable( + g_Dbs.db[i].superTbls[j].colsOfCreateChildTable, + g_Dbs.threadCountByCreateTbl, + startFrom, + g_Dbs.db[i].superTbls[j].childTblCount, + g_Dbs.db[i].dbName, &(g_Dbs.db[i].superTbls[j])); + } + } + } else { + // normal table + len = snprintf(tblColsBuf, MAX_SQL_SIZE, "(TS TIMESTAMP"); + for (int j = 0; j < g_args.num_of_CPR; j++) { + if ((strncasecmp(g_args.datatype[j], "BINARY", strlen("BINARY")) == 0) + || (strncasecmp(g_args.datatype[j], + "NCHAR", strlen("NCHAR")) == 0)) { + snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, + ", COL%d %s(%d)", j, g_args.datatype[j], g_args.len_of_binary); + } else { + snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, + ", COL%d %s", j, g_args.datatype[j]); + } + len = strlen(tblColsBuf); + } + + snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, ")"); + + verbosePrint("%s() LN%d: dbName: %s num of tb: %"PRId64" schema: %s\n", + __func__, __LINE__, + g_Dbs.db[i].dbName, g_args.num_of_tables, tblColsBuf); + startMultiThreadCreateChildTable( + tblColsBuf, + g_Dbs.threadCountByCreateTbl, + 0, + g_args.num_of_tables, + g_Dbs.db[i].dbName, + NULL); } - } - } else { - // normal table - len = snprintf(tblColsBuf, MAX_SQL_SIZE, "(TS TIMESTAMP"); - for (int j = 0; j < g_args.num_of_CPR; j++) { - if ((strncasecmp(g_args.datatype[j], "BINARY", strlen("BINARY")) == 0) - || (strncasecmp(g_args.datatype[j], - "NCHAR", strlen("NCHAR")) == 0)) { - snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, - ", COL%d %s(%d)", j, g_args.datatype[j], g_args.len_of_binary); - } else { - snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, - ", COL%d %s", j, g_args.datatype[j]); - } - len = strlen(tblColsBuf); - } - - snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, ")"); - - verbosePrint("%s() LN%d: dbName: %s num of tb: %"PRIu64" schema: %s\n", - __func__, __LINE__, - g_Dbs.db[i].dbName, g_args.num_of_tables, tblColsBuf); - startMultiThreadCreateChildTable( - tblColsBuf, - g_Dbs.threadCountByCreateTbl, - 0, - g_args.num_of_tables, - g_Dbs.db[i].dbName, - NULL); } - } } /* @@ -3071,10 +3198,12 @@ static int readTagFromCsvFileToMem(SSuperTable * superTblInfo) { return 0; } +#if 0 int readSampleFromJsonFileToMem(SSuperTable * superTblInfo) { // TODO return 0; } +#endif /* Read 10000 lines at most. If more than 10000 lines, continue to read after using @@ -3392,17 +3521,6 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } g_args.interlace_rows = interlaceRows->valueint; - - // rows per table need be less than insert batch - if (g_args.interlace_rows > g_args.num_of_RPR) { - printf("NOTICE: interlace rows value %"PRIu64" > num_of_records_per_req %"PRIu64"\n\n", - g_args.interlace_rows, g_args.num_of_RPR); - printf(" interlace rows value will be set to num_of_records_per_req %"PRIu64"\n\n", - g_args.num_of_RPR); - printf(" press Enter key to continue or Ctrl-C to stop."); - (void)getchar(); - g_args.interlace_rows = g_args.num_of_RPR; - } } else if (!interlaceRows) { g_args.interlace_rows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req } else { @@ -3433,10 +3551,17 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { errorPrint("%s() LN%d, failed to read json, num_of_records_per_req input mistake\n", __func__, __LINE__); goto PARSE_OVER; + } else if (numRecPerReq->valueint > MAX_RECORDS_PER_REQ) { + printf("NOTICE: number of records per request value %"PRIu64" > %d\n\n", + numRecPerReq->valueint, MAX_RECORDS_PER_REQ); + printf(" number of records per request value will be set to %d\n\n", + MAX_RECORDS_PER_REQ); + prompt(); + numRecPerReq->valueint = MAX_RECORDS_PER_REQ; } g_args.num_of_RPR = numRecPerReq->valueint; } else if (!numRecPerReq) { - g_args.num_of_RPR = UINT64_MAX; + g_args.num_of_RPR = MAX_RECORDS_PER_REQ; } else { errorPrint("%s() LN%d, failed to read json, num_of_records_per_req not found\n", __func__, __LINE__); @@ -3455,12 +3580,22 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_args.answer_yes = false; } } else if (!answerPrompt) { - g_args.answer_yes = false; + g_args.answer_yes = true; // default is no, mean answer_yes. } else { - printf("ERROR: failed to read json, confirm_parameter_prompt not found\n"); + errorPrint("%s", "failed to read json, confirm_parameter_prompt input mistake\n"); goto PARSE_OVER; } + // rows per table need be less than insert batch + if (g_args.interlace_rows > g_args.num_of_RPR) { + printf("NOTICE: interlace rows value %u > num_of_records_per_req %u\n\n", + g_args.interlace_rows, g_args.num_of_RPR); + printf(" interlace rows value will be set to num_of_records_per_req %u\n\n", + g_args.num_of_RPR); + prompt(); + g_args.interlace_rows = g_args.num_of_RPR; + } + cJSON* dbs = cJSON_GetObjectItem(root, "databases"); if (!dbs || dbs->type != cJSON_Array) { printf("ERROR: failed to read json, databases not found\n"); @@ -3686,36 +3821,40 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { // dbinfo cJSON *stbName = cJSON_GetObjectItem(stbInfo, "name"); - if (!stbName || stbName->type != cJSON_String || stbName->valuestring == NULL) { + if (!stbName || stbName->type != cJSON_String + || stbName->valuestring == NULL) { errorPrint("%s() LN%d, failed to read json, stb name not found\n", __func__, __LINE__); goto PARSE_OVER; } - tstrncpy(g_Dbs.db[i].superTbls[j].sTblName, stbName->valuestring, MAX_TB_NAME_SIZE); + tstrncpy(g_Dbs.db[i].superTbls[j].sTblName, stbName->valuestring, + MAX_TB_NAME_SIZE); cJSON *prefix = cJSON_GetObjectItem(stbInfo, "childtable_prefix"); if (!prefix || prefix->type != cJSON_String || prefix->valuestring == NULL) { printf("ERROR: failed to read json, childtable_prefix not found\n"); goto PARSE_OVER; } - tstrncpy(g_Dbs.db[i].superTbls[j].childTblPrefix, prefix->valuestring, MAX_DB_NAME_SIZE); + tstrncpy(g_Dbs.db[i].superTbls[j].childTblPrefix, prefix->valuestring, + MAX_DB_NAME_SIZE); - cJSON *autoCreateTbl = cJSON_GetObjectItem(stbInfo, "auto_create_table"); // yes, no, null + cJSON *autoCreateTbl = cJSON_GetObjectItem(stbInfo, "auto_create_table"); if (autoCreateTbl && autoCreateTbl->type == cJSON_String && autoCreateTbl->valuestring != NULL) { - if (0 == strncasecmp(autoCreateTbl->valuestring, "yes", 3)) { - g_Dbs.db[i].superTbls[j].autoCreateTable = AUTO_CREATE_SUBTBL; - } else if (0 == strncasecmp(autoCreateTbl->valuestring, "no", 2)) { - g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL; - } else { - g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL; - } + if ((0 == strncasecmp(autoCreateTbl->valuestring, "yes", 3)) + && (TBL_ALREADY_EXISTS != g_Dbs.db[i].superTbls[j].childTblExists)) { + g_Dbs.db[i].superTbls[j].autoCreateTable = AUTO_CREATE_SUBTBL; + } else if (0 == strncasecmp(autoCreateTbl->valuestring, "no", 2)) { + g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL; + } else { + g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL; + } } else if (!autoCreateTbl) { - g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL; + g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL; } else { - printf("ERROR: failed to read json, auto_create_table not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, auto_create_table not found\n"); + goto PARSE_OVER; } cJSON* batchCreateTbl = cJSON_GetObjectItem(stbInfo, "batch_create_tbl_num"); @@ -3749,6 +3888,10 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { goto PARSE_OVER; } + if (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists) { + g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL; + } + cJSON* count = cJSON_GetObjectItem(stbInfo, "childtable_count"); if (!count || count->type != cJSON_Number || 0 >= count->valueint) { errorPrint("%s() LN%d, failed to read json, childtable_count input mistake\n", @@ -3770,15 +3913,26 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { goto PARSE_OVER; } - cJSON *insertMode = cJSON_GetObjectItem(stbInfo, "insert_mode"); // taosc , rest - if (insertMode && insertMode->type == cJSON_String - && insertMode->valuestring != NULL) { - tstrncpy(g_Dbs.db[i].superTbls[j].insertMode, - insertMode->valuestring, MAX_DB_NAME_SIZE); - } else if (!insertMode) { - tstrncpy(g_Dbs.db[i].superTbls[j].insertMode, "taosc", MAX_DB_NAME_SIZE); + cJSON *stbIface = cJSON_GetObjectItem(stbInfo, "insert_mode"); // taosc , rest, stmt + if (stbIface && stbIface->type == cJSON_String + && stbIface->valuestring != NULL) { + if (0 == strcasecmp(stbIface->valuestring, "taosc")) { + g_Dbs.db[i].superTbls[j].iface= TAOSC_IFACE; + } else if (0 == strcasecmp(stbIface->valuestring, "rest")) { + g_Dbs.db[i].superTbls[j].iface= REST_IFACE; +#if STMT_IFACE_ENABLED == 1 + } else if (0 == strcasecmp(stbIface->valuestring, "stmt")) { + g_Dbs.db[i].superTbls[j].iface= STMT_IFACE; +#endif + } else { + errorPrint("%s() LN%d, failed to read json, insert_mode %s not recognized\n", + __func__, __LINE__, stbIface->valuestring); + goto PARSE_OVER; + } + } else if (!stbIface) { + g_Dbs.db[i].superTbls[j].iface = TAOSC_IFACE; } else { - printf("ERROR: failed to read json, insert_mode not found\n"); + errorPrint("%s", "failed to read json, insert_mode not found\n"); goto PARSE_OVER; } @@ -3797,7 +3951,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON* childTbl_offset = cJSON_GetObjectItem(stbInfo, "childtable_offset"); if ((childTbl_offset) && (g_Dbs.db[i].drop != true) && (g_Dbs.db[i].superTbls[j].childTblExists == TBL_ALREADY_EXISTS)) { - if (childTbl_offset->type != cJSON_Number || 0 > childTbl_offset->valueint) { + if ((childTbl_offset->type != cJSON_Number) + || (0 > childTbl_offset->valueint)) { printf("ERROR: failed to read json, childtable_offset\n"); goto PARSE_OVER; } @@ -3853,7 +4008,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } cJSON *tagsFile = cJSON_GetObjectItem(stbInfo, "tags_file"); - if (tagsFile && tagsFile->type == cJSON_String && tagsFile->valuestring != NULL) { + if ((tagsFile && tagsFile->type == cJSON_String) + && (tagsFile->valuestring != NULL)) { tstrncpy(g_Dbs.db[i].superTbls[j].tagsFile, tagsFile->valuestring, MAX_FILE_NAME_LEN); if (0 == g_Dbs.db[i].superTbls[j].tagsFile[0]) { @@ -3869,9 +4025,9 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { goto PARSE_OVER; } - cJSON* maxSqlLen = cJSON_GetObjectItem(stbInfo, "max_sql_len"); - if (maxSqlLen && maxSqlLen->type == cJSON_Number) { - int32_t len = maxSqlLen->valueint; + cJSON* stbMaxSqlLen = cJSON_GetObjectItem(stbInfo, "max_sql_len"); + if (stbMaxSqlLen && stbMaxSqlLen->type == cJSON_Number) { + int32_t len = stbMaxSqlLen->valueint; if (len > TSDB_MAX_ALLOWED_SQL_LEN) { len = TSDB_MAX_ALLOWED_SQL_LEN; } else if (len < 5) { @@ -3881,7 +4037,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!maxSqlLen) { g_Dbs.db[i].superTbls[j].maxSqlLen = g_args.max_sql_len; } else { - errorPrint("%s() LN%d, failed to read json, maxSqlLen input mistake\n", + errorPrint("%s() LN%d, failed to read json, stbMaxSqlLen input mistake\n", __func__, __LINE__); goto PARSE_OVER; } @@ -3903,25 +4059,25 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { goto PARSE_OVER; } */ - cJSON* interlaceRows = cJSON_GetObjectItem(stbInfo, "interlace_rows"); - if (interlaceRows && interlaceRows->type == cJSON_Number) { - if (interlaceRows->valueint < 0) { + cJSON* stbInterlaceRows = cJSON_GetObjectItem(stbInfo, "interlace_rows"); + if (stbInterlaceRows && stbInterlaceRows->type == cJSON_Number) { + if (stbInterlaceRows->valueint < 0) { errorPrint("%s() LN%d, failed to read json, interlace rows input mistake\n", __func__, __LINE__); goto PARSE_OVER; } - g_Dbs.db[i].superTbls[j].interlaceRows = interlaceRows->valueint; + g_Dbs.db[i].superTbls[j].interlaceRows = stbInterlaceRows->valueint; // rows per table need be less than insert batch if (g_Dbs.db[i].superTbls[j].interlaceRows > g_args.num_of_RPR) { - printf("NOTICE: db[%d].superTbl[%d]'s interlace rows value %"PRIu64" > num_of_records_per_req %"PRIu64"\n\n", - i, j, g_Dbs.db[i].superTbls[j].interlaceRows, g_args.num_of_RPR); - printf(" interlace rows value will be set to num_of_records_per_req %"PRIu64"\n\n", + printf("NOTICE: db[%d].superTbl[%d]'s interlace rows value %u > num_of_records_per_req %u\n\n", + i, j, g_Dbs.db[i].superTbls[j].interlaceRows, g_args.num_of_RPR); - printf(" press Enter key to continue or Ctrl-C to stop."); - (void)getchar(); + printf(" interlace rows value will be set to num_of_records_per_req %u\n\n", + g_args.num_of_RPR); + prompt(); g_Dbs.db[i].superTbls[j].interlaceRows = g_args.num_of_RPR; } - } else if (!interlaceRows) { + } else if (!stbInterlaceRows) { g_Dbs.db[i].superTbls[j].interlaceRows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req } else { errorPrint( @@ -4062,7 +4218,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON* gQueryTimes = cJSON_GetObjectItem(root, "query_times"); if (gQueryTimes && gQueryTimes->type == cJSON_Number) { - if (gQueryTimes->valueint < 0) { + if (gQueryTimes->valueint <= 0) { errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", __func__, __LINE__); goto PARSE_OVER; @@ -4113,9 +4269,10 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON* specifiedQueryTimes = cJSON_GetObjectItem(specifiedQuery, "query_times"); if (specifiedQueryTimes && specifiedQueryTimes->type == cJSON_Number) { - if (specifiedQueryTimes->valueint < 0) { - errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", - __func__, __LINE__); + if (specifiedQueryTimes->valueint <= 0) { + errorPrint( + "%s() LN%d, failed to read json, query_times: %"PRId64", need be a valid (>0) number\n", + __func__, __LINE__, specifiedQueryTimes->valueint); goto PARSE_OVER; } @@ -4131,7 +4288,8 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON* concurrent = cJSON_GetObjectItem(specifiedQuery, "concurrent"); if (concurrent && concurrent->type == cJSON_Number) { if (concurrent->valueint <= 0) { - errorPrint("%s() LN%d, query sqlCount %"PRIu64" or concurrent %"PRIu64" is not correct.\n", + errorPrint( + "%s() LN%d, query sqlCount %d or concurrent %d is not correct.\n", __func__, __LINE__, g_queryInfo.specifiedQueryInfo.sqlCount, g_queryInfo.specifiedQueryInfo.concurrent); @@ -4170,15 +4328,15 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON* restart = cJSON_GetObjectItem(specifiedQuery, "restart"); if (restart && restart->type == cJSON_String && restart->valuestring != NULL) { if (0 == strcmp("yes", restart->valuestring)) { - g_queryInfo.specifiedQueryInfo.subscribeRestart = 1; + g_queryInfo.specifiedQueryInfo.subscribeRestart = true; } else if (0 == strcmp("no", restart->valuestring)) { - g_queryInfo.specifiedQueryInfo.subscribeRestart = 0; + g_queryInfo.specifiedQueryInfo.subscribeRestart = false; } else { printf("ERROR: failed to read json, subscribe restart error\n"); goto PARSE_OVER; } } else { - g_queryInfo.specifiedQueryInfo.subscribeRestart = 1; + g_queryInfo.specifiedQueryInfo.subscribeRestart = true; } cJSON* keepProgress = cJSON_GetObjectItem(specifiedQuery, "keepProgress"); @@ -4198,24 +4356,28 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { } // sqls - cJSON* superSqls = cJSON_GetObjectItem(specifiedQuery, "sqls"); - if (!superSqls) { + cJSON* specifiedSqls = cJSON_GetObjectItem(specifiedQuery, "sqls"); + if (!specifiedSqls) { g_queryInfo.specifiedQueryInfo.sqlCount = 0; - } else if (superSqls->type != cJSON_Array) { + } else if (specifiedSqls->type != cJSON_Array) { errorPrint("%s() LN%d, failed to read json, super sqls not found\n", __func__, __LINE__); goto PARSE_OVER; } else { - int superSqlSize = cJSON_GetArraySize(superSqls); - if (superSqlSize > MAX_QUERY_SQL_COUNT) { - errorPrint("%s() LN%d, failed to read json, query sql size overflow, max is %d\n", - __func__, __LINE__, MAX_QUERY_SQL_COUNT); + int superSqlSize = cJSON_GetArraySize(specifiedSqls); + if (superSqlSize * g_queryInfo.specifiedQueryInfo.concurrent + > MAX_QUERY_SQL_COUNT) { + errorPrint("%s() LN%d, failed to read json, query sql(%d) * concurrent(%d) overflow, max is %d\n", + __func__, __LINE__, + superSqlSize, + g_queryInfo.specifiedQueryInfo.concurrent, + MAX_QUERY_SQL_COUNT); goto PARSE_OVER; } g_queryInfo.specifiedQueryInfo.sqlCount = superSqlSize; for (int j = 0; j < superSqlSize; ++j) { - cJSON* sql = cJSON_GetArrayItem(superSqls, j); + cJSON* sql = cJSON_GetArrayItem(specifiedSqls, j); if (sql == NULL) continue; cJSON *sqlStr = cJSON_GetObjectItem(sql, "sql"); @@ -4223,13 +4385,39 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { printf("ERROR: failed to read json, sql not found\n"); goto PARSE_OVER; } - tstrncpy(g_queryInfo.specifiedQueryInfo.sql[j], sqlStr->valuestring, MAX_QUERY_SQL_LENGTH); + tstrncpy(g_queryInfo.specifiedQueryInfo.sql[j], + sqlStr->valuestring, MAX_QUERY_SQL_LENGTH); + + cJSON* endAfterConsume = + cJSON_GetObjectItem(specifiedQuery, "endAfterConsume"); + if (endAfterConsume + && endAfterConsume->type == cJSON_Number) { + g_queryInfo.specifiedQueryInfo.endAfterConsume[j] + = endAfterConsume->valueint; + } else if (!endAfterConsume) { + // default value is -1, which mean infinite loop + g_queryInfo.specifiedQueryInfo.endAfterConsume[j] = -1; + } + + cJSON* resubAfterConsume = + cJSON_GetObjectItem(specifiedQuery, "resubAfterConsume"); + if (resubAfterConsume + && resubAfterConsume->type == cJSON_Number) { + g_queryInfo.specifiedQueryInfo.resubAfterConsume[j] + = resubAfterConsume->valueint; + } else if (!resubAfterConsume) { + // default value is -1, which mean do not resub + g_queryInfo.specifiedQueryInfo.resubAfterConsume[j] = -1; + } cJSON *result = cJSON_GetObjectItem(sql, "result"); - if (NULL != result && result->type == cJSON_String && result->valuestring != NULL) { - tstrncpy(g_queryInfo.specifiedQueryInfo.result[j], result->valuestring, MAX_FILE_NAME_LEN); + if ((NULL != result) && (result->type == cJSON_String) + && (result->valuestring != NULL)) { + tstrncpy(g_queryInfo.specifiedQueryInfo.result[j], + result->valuestring, MAX_FILE_NAME_LEN); } else if (NULL == result) { - memset(g_queryInfo.specifiedQueryInfo.result[j], 0, MAX_FILE_NAME_LEN); + memset(g_queryInfo.specifiedQueryInfo.result[j], + 0, MAX_FILE_NAME_LEN); } else { printf("ERROR: failed to read json, super query result file not found\n"); goto PARSE_OVER; @@ -4257,9 +4445,9 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON* superQueryTimes = cJSON_GetObjectItem(superQuery, "query_times"); if (superQueryTimes && superQueryTimes->type == cJSON_Number) { - if (superQueryTimes->valueint < 0) { - errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", - __func__, __LINE__); + if (superQueryTimes->valueint <= 0) { + errorPrint("%s() LN%d, failed to read json, query_times: %"PRId64", need be a valid (>0) number\n", + __func__, __LINE__, superQueryTimes->valueint); goto PARSE_OVER; } g_queryInfo.superQueryInfo.queryTimes = superQueryTimes->valueint; @@ -4336,43 +4524,65 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { if (subrestart && subrestart->type == cJSON_String && subrestart->valuestring != NULL) { if (0 == strcmp("yes", subrestart->valuestring)) { - g_queryInfo.superQueryInfo.subscribeRestart = 1; + g_queryInfo.superQueryInfo.subscribeRestart = true; } else if (0 == strcmp("no", subrestart->valuestring)) { - g_queryInfo.superQueryInfo.subscribeRestart = 0; + g_queryInfo.superQueryInfo.subscribeRestart = false; } else { printf("ERROR: failed to read json, subscribe restart error\n"); goto PARSE_OVER; } } else { - g_queryInfo.superQueryInfo.subscribeRestart = 1; + g_queryInfo.superQueryInfo.subscribeRestart = true; } - cJSON* subkeepProgress = cJSON_GetObjectItem(superQuery, "keepProgress"); - if (subkeepProgress && - subkeepProgress->type == cJSON_String - && subkeepProgress->valuestring != NULL) { - if (0 == strcmp("yes", subkeepProgress->valuestring)) { + cJSON* superkeepProgress = cJSON_GetObjectItem(superQuery, "keepProgress"); + if (superkeepProgress && + superkeepProgress->type == cJSON_String + && superkeepProgress->valuestring != NULL) { + if (0 == strcmp("yes", superkeepProgress->valuestring)) { g_queryInfo.superQueryInfo.subscribeKeepProgress = 1; - } else if (0 == strcmp("no", subkeepProgress->valuestring)) { + } else if (0 == strcmp("no", superkeepProgress->valuestring)) { g_queryInfo.superQueryInfo.subscribeKeepProgress = 0; } else { - printf("ERROR: failed to read json, subscribe keepProgress error\n"); + printf("ERROR: failed to read json, subscribe super table keepProgress error\n"); goto PARSE_OVER; } } else { g_queryInfo.superQueryInfo.subscribeKeepProgress = 0; } - // sqls - cJSON* subsqls = cJSON_GetObjectItem(superQuery, "sqls"); - if (!subsqls) { + cJSON* superEndAfterConsume = + cJSON_GetObjectItem(superQuery, "endAfterConsume"); + if (superEndAfterConsume + && superEndAfterConsume->type == cJSON_Number) { + g_queryInfo.superQueryInfo.endAfterConsume = + superEndAfterConsume->valueint; + } else if (!superEndAfterConsume) { + // default value is -1, which mean do not resub + g_queryInfo.superQueryInfo.endAfterConsume = -1; + } + + cJSON* superResubAfterConsume = + cJSON_GetObjectItem(superQuery, "endAfterConsume"); + if (superResubAfterConsume + && superResubAfterConsume->type == cJSON_Number) { + g_queryInfo.superQueryInfo.endAfterConsume = + superResubAfterConsume->valueint; + } else if (!superResubAfterConsume) { + // default value is -1, which mean do not resub + g_queryInfo.superQueryInfo.endAfterConsume = -1; + } + + // supert table sqls + cJSON* superSqls = cJSON_GetObjectItem(superQuery, "sqls"); + if (!superSqls) { g_queryInfo.superQueryInfo.sqlCount = 0; - } else if (subsqls->type != cJSON_Array) { + } else if (superSqls->type != cJSON_Array) { errorPrint("%s() LN%d: failed to read json, super sqls not found\n", __func__, __LINE__); goto PARSE_OVER; } else { - int superSqlSize = cJSON_GetArraySize(subsqls); + int superSqlSize = cJSON_GetArraySize(superSqls); if (superSqlSize > MAX_QUERY_SQL_COUNT) { errorPrint("%s() LN%d, failed to read json, query sql size overflow, max is %d\n", __func__, __LINE__, MAX_QUERY_SQL_COUNT); @@ -4381,7 +4591,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { g_queryInfo.superQueryInfo.sqlCount = superSqlSize; for (int j = 0; j < superSqlSize; ++j) { - cJSON* sql = cJSON_GetArrayItem(subsqls, j); + cJSON* sql = cJSON_GetArrayItem(superSqls, j); if (sql == NULL) continue; cJSON *sqlStr = cJSON_GetObjectItem(sql, "sql"); @@ -4493,7 +4703,7 @@ static void prepareSampleData() { static void postFreeResource() { tmfclose(g_fpOfInsertResult); for (int i = 0; i < g_Dbs.dbCount; i++) { - for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { + for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) { if (0 != g_Dbs.db[i].superTbls[j].colsOfCreateChildTable) { free(g_Dbs.db[i].superTbls[j].colsOfCreateChildTable); g_Dbs.db[i].superTbls[j].colsOfCreateChildTable = NULL; @@ -4541,16 +4751,22 @@ static int getRowDataFromSample( return dataLen; } -static int64_t generateRowData(char* recBuf, int64_t timestamp, SSuperTable* stbInfo) { +static int64_t generateStbRowData( + SSuperTable* stbInfo, + char* recBuf, int64_t timestamp) +{ int64_t dataLen = 0; char *pstr = recBuf; int64_t maxLen = MAX_DATA_SIZE; - dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "(%" PRId64 ",", timestamp); + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, + "(%" PRId64 ",", timestamp); for (int i = 0; i < stbInfo->columnCount; i++) { - if ((0 == strncasecmp(stbInfo->columns[i].dataType, "BINARY", strlen("BINARY"))) - || (0 == strncasecmp(stbInfo->columns[i].dataType, "NCHAR", strlen("NCHAR")))) { + if ((0 == strncasecmp(stbInfo->columns[i].dataType, + "BINARY", strlen("BINARY"))) + || (0 == strncasecmp(stbInfo->columns[i].dataType, + "NCHAR", strlen("NCHAR")))) { if (stbInfo->columns[i].dataLen > TSDB_MAX_BINARY_LEN) { errorPrint( "binary or nchar length overflow, max size:%u\n", (uint32_t)TSDB_MAX_BINARY_LEN); @@ -4566,23 +4782,23 @@ static int64_t generateRowData(char* recBuf, int64_t timestamp, SSuperTable* stb dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "\'%s\',", buf); tmfree(buf); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "INT", 3)) { + "INT", strlen("INT"))) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "%d,", rand_int()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "BIGINT", 6)) { + "BIGINT", strlen("BIGINT"))) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "%"PRId64",", rand_bigint()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "FLOAT", 5)) { + "FLOAT", strlen("FLOAT"))) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "%f,", rand_float()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "DOUBLE", 6)) { + "DOUBLE", strlen("DOUBLE"))) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "%f,", rand_double()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "SMALLINT", 8)) { + "SMALLINT", strlen("SMALLINT"))) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "%d,", rand_smallint()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, @@ -4612,46 +4828,38 @@ static int64_t generateRowData(char* recBuf, int64_t timestamp, SSuperTable* stb } static int64_t generateData(char *recBuf, char **data_type, - int num_of_cols, int64_t timestamp, int lenOfBinary) { + int64_t timestamp, int lenOfBinary) { memset(recBuf, 0, MAX_DATA_SIZE); char *pstr = recBuf; pstr += sprintf(pstr, "(%" PRId64, timestamp); - int c = 0; - for (; c < MAX_NUM_DATATYPE; c++) { - if (data_type[c] == NULL) { - break; - } - } - - if (0 == c) { - perror("data type error!"); - exit(-1); - } + int columnCount = g_args.num_of_CPR; - for (int i = 0; i < c; i++) { - if (strcasecmp(data_type[i % c], "TINYINT") == 0) { + for (int i = 0; i < columnCount; i++) { + if (strcasecmp(data_type[i % columnCount], "TINYINT") == 0) { pstr += sprintf(pstr, ",%d", rand_tinyint() ); - } else if (strcasecmp(data_type[i % c], "SMALLINT") == 0) { + } else if (strcasecmp(data_type[i % columnCount], "SMALLINT") == 0) { pstr += sprintf(pstr, ",%d", rand_smallint()); - } else if (strcasecmp(data_type[i % c], "INT") == 0) { + } else if (strcasecmp(data_type[i % columnCount], "INT") == 0) { pstr += sprintf(pstr, ",%d", rand_int()); - } else if (strcasecmp(data_type[i % c], "BIGINT") == 0) { + } else if (strcasecmp(data_type[i % columnCount], "BIGINT") == 0) { + pstr += sprintf(pstr, ",%" PRId64, rand_bigint()); + } else if (strcasecmp(data_type[i % columnCount], "TIMESTAMP") == 0) { pstr += sprintf(pstr, ",%" PRId64, rand_bigint()); - } else if (strcasecmp(data_type[i % c], "FLOAT") == 0) { + } else if (strcasecmp(data_type[i % columnCount], "FLOAT") == 0) { pstr += sprintf(pstr, ",%10.4f", rand_float()); - } else if (strcasecmp(data_type[i % c], "DOUBLE") == 0) { + } else if (strcasecmp(data_type[i % columnCount], "DOUBLE") == 0) { double t = rand_double(); pstr += sprintf(pstr, ",%20.8f", t); - } else if (strcasecmp(data_type[i % c], "BOOL") == 0) { - bool b = taosRandom() & 1; + } else if (strcasecmp(data_type[i % columnCount], "BOOL") == 0) { + bool b = rand_bool() & 1; pstr += sprintf(pstr, ",%s", b ? "true" : "false"); - } else if (strcasecmp(data_type[i % c], "BINARY") == 0) { + } else if (strcasecmp(data_type[i % columnCount], "BINARY") == 0) { char *s = malloc(lenOfBinary); rand_string(s, lenOfBinary); pstr += sprintf(pstr, ",\"%s\"", s); free(s); - } else if (strcasecmp(data_type[i % c], "NCHAR") == 0) { + } else if (strcasecmp(data_type[i % columnCount], "NCHAR") == 0) { char *s = malloc(lenOfBinary); rand_string(s, lenOfBinary); pstr += sprintf(pstr, ",\"%s\"", s); @@ -4698,160 +4906,214 @@ static int prepareSampleDataForSTable(SSuperTable *superTblInfo) { return 0; } -static int64_t execInsert(threadInfo *pThreadInfo, char *buffer, uint64_t k) +static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k) { - int affectedRows; - SSuperTable* superTblInfo = pThreadInfo->superTblInfo; + int32_t affectedRows; + SSuperTable* superTblInfo = pThreadInfo->superTblInfo; - verbosePrint("[%d] %s() LN%d %s\n", pThreadInfo->threadID, - __func__, __LINE__, buffer); - if (superTblInfo) { - if (0 == strncasecmp(superTblInfo->insertMode, "taosc", strlen("taosc"))) { - affectedRows = queryDbExec(pThreadInfo->taos, buffer, INSERT_TYPE, false); - } else if (0 == strncasecmp(superTblInfo->insertMode, "rest", strlen("rest"))) { - if (0 != postProceSql(g_Dbs.host, &g_Dbs.serv_addr, g_Dbs.port, - buffer, NULL /* not set result file */)) { - affectedRows = -1; - printf("========restful return fail, threadID[%d]\n", - pThreadInfo->threadID); - } else { - affectedRows = k; - } - } else { - errorPrint("%s() LN%d: unknown insert mode: %s\n", - __func__, __LINE__, superTblInfo->insertMode); - affectedRows = 0; + verbosePrint("[%d] %s() LN%d %s\n", pThreadInfo->threadID, + __func__, __LINE__, pThreadInfo->buffer); + + uint16_t iface; + if (superTblInfo) + iface = superTblInfo->iface; + else + iface = g_args.iface; + + debugPrint("[%d] %s() LN%d %s\n", pThreadInfo->threadID, + __func__, __LINE__, + (g_args.iface==TAOSC_IFACE)? + "taosc":(g_args.iface==REST_IFACE)?"rest":"stmt"); + + switch(iface) { + case TAOSC_IFACE: + affectedRows = queryDbExec( + pThreadInfo->taos, + pThreadInfo->buffer, INSERT_TYPE, false); + break; + + case REST_IFACE: + if (0 != postProceSql(g_Dbs.host, &g_Dbs.serv_addr, g_Dbs.port, + pThreadInfo->buffer, pThreadInfo)) { + affectedRows = -1; + printf("========restful return fail, threadID[%d]\n", + pThreadInfo->threadID); + } else { + affectedRows = k; + } + break; + +#if STMT_IFACE_ENABLED == 1 + case STMT_IFACE: + debugPrint("%s() LN%d, stmt=%p", __func__, __LINE__, pThreadInfo->stmt); + if (0 != taos_stmt_execute(pThreadInfo->stmt)) { + errorPrint("%s() LN%d, failied to execute insert statement\n", + __func__, __LINE__); + exit(-1); + } + affectedRows = k; + break; +#endif + + default: + errorPrint("%s() LN%d: unknown insert mode: %d\n", + __func__, __LINE__, superTblInfo->iface); + affectedRows = 0; } - } else { - affectedRows = queryDbExec(pThreadInfo->taos, buffer, INSERT_TYPE, false); - } - return affectedRows; + return affectedRows; } -static void getTableName(char *pTblName, threadInfo* pThreadInfo, uint64_t tableSeq) +static void getTableName(char *pTblName, + threadInfo* pThreadInfo, uint64_t tableSeq) { - SSuperTable* superTblInfo = pThreadInfo->superTblInfo; - if (superTblInfo) { - if (superTblInfo->childTblLimit > 0) { - snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s", - superTblInfo->childTblName + - (tableSeq - superTblInfo->childTblOffset) * TSDB_TABLE_NAME_LEN); + SSuperTable* superTblInfo = pThreadInfo->superTblInfo; + if (superTblInfo) { + if (AUTO_CREATE_SUBTBL != superTblInfo->autoCreateTable) { + if (superTblInfo->childTblLimit > 0) { + snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s", + superTblInfo->childTblName + + (tableSeq - superTblInfo->childTblOffset) * TSDB_TABLE_NAME_LEN); + } else { + verbosePrint("[%d] %s() LN%d: from=%"PRIu64" count=%"PRId64" seq=%"PRIu64"\n", + pThreadInfo->threadID, __func__, __LINE__, + pThreadInfo->start_table_from, + pThreadInfo->ntables, tableSeq); + snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s", + superTblInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN); + } + } else { + snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s%"PRIu64"", + superTblInfo->childTblPrefix, tableSeq); + } } else { - - verbosePrint("[%d] %s() LN%d: from=%"PRIu64" count=%"PRIu64" seq=%"PRIu64"\n", - pThreadInfo->threadID, __func__, __LINE__, - pThreadInfo->start_table_from, - pThreadInfo->ntables, tableSeq); - snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s", - superTblInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN); + snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s%"PRIu64"", + g_args.tb_prefix, tableSeq); } - } else { - snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s%"PRIu64"", - g_args.tb_prefix, tableSeq); - } } -static int64_t generateDataTail( - SSuperTable* superTblInfo, - uint64_t batch, char* buffer, int64_t remainderBufLen, int64_t insertRows, - int64_t startFrom, int64_t startTime, int64_t *pSamplePos, int64_t *dataLen) { - uint64_t len = 0; - uint32_t ncols_per_record = 1; // count first col ts +static int32_t generateDataTailWithoutStb( + uint32_t batch, char* buffer, + int64_t remainderBufLen, int64_t insertRows, + uint64_t recordFrom, int64_t startTime, + /* int64_t *pSamplePos, */int64_t *dataLen) { + uint64_t len = 0; char *pstr = buffer; - if (superTblInfo == NULL) { - uint32_t datatypeSeq = 0; - while(g_args.datatype[datatypeSeq]) { - datatypeSeq ++; - ncols_per_record ++; - } - } - - verbosePrint("%s() LN%d batch=%"PRIu64"\n", __func__, __LINE__, batch); + verbosePrint("%s() LN%d batch=%d\n", __func__, __LINE__, batch); - uint64_t k = 0; + int32_t k = 0; for (k = 0; k < batch;) { char data[MAX_DATA_SIZE]; memset(data, 0, MAX_DATA_SIZE); int64_t retLen = 0; - if (superTblInfo) { - if (0 == strncasecmp(superTblInfo->dataSource, - "sample", strlen("sample"))) { - retLen = getRowDataFromSample( - data, - remainderBufLen, - startTime + superTblInfo->timeStampStep * k, - superTblInfo, - pSamplePos); - } else if (0 == strncasecmp(superTblInfo->dataSource, - "rand", strlen("rand"))) { - - int64_t randTail = superTblInfo->timeStampStep * k; - if (superTblInfo->disorderRatio > 0) { - int rand_num = taosRandom() % 100; - if(rand_num < superTblInfo->disorderRatio) { - randTail = (randTail + (taosRandom() % superTblInfo->disorderRange + 1)) * (-1); - debugPrint("rand data generated, back %"PRId64"\n", randTail); - } - } + char **data_type = g_args.datatype; + int lenOfBinary = g_args.len_of_binary; - int64_t d = startTime - + randTail; - retLen = generateRowData( - data, - d, - superTblInfo); - } + retLen = generateData(data, data_type, + startTime + getTSRandTail( + (int64_t) DEFAULT_TIMESTAMP_STEP, k, + g_args.disorderRatio, + g_args.disorderRange), + lenOfBinary); - if (retLen > remainderBufLen) { + if (len > remainderBufLen) break; - } - pstr += snprintf(pstr , retLen + 1, "%s", data); - k++; - len += retLen; - remainderBufLen -= retLen; - } else { - char **data_type = g_args.datatype; - int lenOfBinary = g_args.len_of_binary; + pstr += sprintf(pstr, "%s", data); + k++; + len += retLen; + remainderBufLen -= retLen; - int64_t randTail = DEFAULT_TIMESTAMP_STEP * k; + verbosePrint("%s() LN%d len=%"PRIu64" k=%d \nbuffer=%s\n", + __func__, __LINE__, len, k, buffer); - if (g_args.disorderRatio != 0) { - int rand_num = taosRandom() % 100; - if (rand_num < g_args.disorderRatio) { - randTail = (randTail + (taosRandom() % g_args.disorderRange + 1)) * (-1); + recordFrom ++; + + if (recordFrom >= insertRows) { + break; + } + } - debugPrint("rand data generated, back %"PRId64"\n", randTail); + *dataLen = len; + return k; +} + +static int64_t getTSRandTail(int64_t timeStampStep, int32_t seq, + int disorderRatio, int disorderRange) +{ + int64_t randTail = timeStampStep * seq; + if (disorderRatio > 0) { + int rand_num = taosRandom() % 100; + if(rand_num < disorderRatio) { + randTail = (randTail + + (taosRandom() % disorderRange + 1)) * (-1); + debugPrint("rand data generated, back %"PRId64"\n", randTail); } - } else { - randTail = DEFAULT_TIMESTAMP_STEP * k; - } + } - retLen = generateData(data, data_type, - ncols_per_record, - startTime + randTail, - lenOfBinary); + return randTail; +} - if (len > remainderBufLen) - break; +static int32_t generateStbDataTail( + SSuperTable* superTblInfo, + uint32_t batch, char* buffer, + int64_t remainderBufLen, int64_t insertRows, + uint64_t recordFrom, int64_t startTime, + int64_t *pSamplePos, int64_t *dataLen) { + uint64_t len = 0; + + char *pstr = buffer; - pstr += sprintf(pstr, "%s", data); - k++; - len += retLen; - remainderBufLen -= retLen; + bool tsRand; + if (0 == strncasecmp(superTblInfo->dataSource, "rand", strlen("rand"))) { + tsRand = true; + } else { + tsRand = false; + } + verbosePrint("%s() LN%d batch=%u\n", __func__, __LINE__, batch); + + int32_t k = 0; + for (k = 0; k < batch;) { + char data[MAX_DATA_SIZE]; + memset(data, 0, MAX_DATA_SIZE); + + int64_t retLen = 0; + + if (tsRand) { + retLen = generateStbRowData(superTblInfo, data, + startTime + getTSRandTail( + superTblInfo->timeStampStep, k, + superTblInfo->disorderRatio, + superTblInfo->disorderRange) + ); + } else { + retLen = getRowDataFromSample( + data, + remainderBufLen, + startTime + superTblInfo->timeStampStep * k, + superTblInfo, + pSamplePos); + } + + if (retLen > remainderBufLen) { + break; } - verbosePrint("%s() LN%d len=%"PRIu64" k=%"PRIu64" \nbuffer=%s\n", + pstr += snprintf(pstr , retLen + 1, "%s", data); + k++; + len += retLen; + remainderBufLen -= retLen; + + verbosePrint("%s() LN%d len=%"PRIu64" k=%u \nbuffer=%s\n", __func__, __LINE__, len, k, buffer); - startFrom ++; + recordFrom ++; - if (startFrom >= insertRows) { + if (recordFrom >= insertRows) { break; } } @@ -4860,17 +5122,41 @@ static int64_t generateDataTail( return k; } -static int generateSQLHead(char *tableName, int32_t tableSeq, - threadInfo* pThreadInfo, SSuperTable* superTblInfo, + +static int generateSQLHeadWithoutStb(char *tableName, + char *dbName, char *buffer, int remainderBufLen) { int len; -#define HEAD_BUFF_LEN 1024*24 // 16*1024 + (192+32)*2 + insert into .. char headBuf[HEAD_BUFF_LEN]; - if (superTblInfo) { - if (AUTO_CREATE_SUBTBL == superTblInfo->autoCreateTable) { + len = snprintf( + headBuf, + HEAD_BUFF_LEN, + "%s.%s values", + dbName, + tableName); + + if (len > remainderBufLen) + return -1; + + tstrncpy(buffer, headBuf, len + 1); + + return len; +} + +static int generateStbSQLHead( + SSuperTable* superTblInfo, + char *tableName, int32_t tableSeq, + char *dbName, + char *buffer, int remainderBufLen) +{ + int len; + + char headBuf[HEAD_BUFF_LEN]; + + if (AUTO_CREATE_SUBTBL == superTblInfo->autoCreateTable) { char* tagsValBuf = NULL; if (0 == superTblInfo->tagSource) { tagsValBuf = generateTagVaulesForStb(superTblInfo, tableSeq); @@ -4889,9 +5175,9 @@ static int generateSQLHead(char *tableName, int32_t tableSeq, headBuf, HEAD_BUFF_LEN, "%s.%s using %s.%s tags %s values", - pThreadInfo->db_name, + dbName, tableName, - pThreadInfo->db_name, + dbName, superTblInfo->sTblName, tagsValBuf); tmfree(tagsValBuf); @@ -4900,22 +5186,14 @@ static int generateSQLHead(char *tableName, int32_t tableSeq, headBuf, HEAD_BUFF_LEN, "%s.%s values", - pThreadInfo->db_name, + dbName, tableName); } else { len = snprintf( headBuf, HEAD_BUFF_LEN, "%s.%s values", - pThreadInfo->db_name, - tableName); - } - } else { - len = snprintf( - headBuf, - HEAD_BUFF_LEN, - "%s.%s values", - pThreadInfo->db_name, + dbName, tableName); } @@ -4927,20 +5205,24 @@ static int generateSQLHead(char *tableName, int32_t tableSeq, return len; } -static int64_t generateInterlaceDataBuffer( - char *tableName, uint64_t batchPerTbl, uint64_t i, uint64_t batchPerTblTimes, +static int32_t generateStbInterlaceData( + SSuperTable *superTblInfo, + char *tableName, uint32_t batchPerTbl, + uint64_t i, + uint32_t batchPerTblTimes, uint64_t tableSeq, threadInfo *pThreadInfo, char *buffer, - uint64_t insertRows, + int64_t insertRows, int64_t startTime, uint64_t *pRemainderBufLen) { assert(buffer); char *pstr = buffer; - SSuperTable* superTblInfo = pThreadInfo->superTblInfo; - int headLen = generateSQLHead(tableName, tableSeq, pThreadInfo, - superTblInfo, pstr, *pRemainderBufLen); + int headLen = generateStbSQLHead( + superTblInfo, + tableName, tableSeq, pThreadInfo->db_name, + pstr, *pRemainderBufLen); if (headLen <= 0) { return 0; @@ -4954,29 +5236,25 @@ static int64_t generateInterlaceDataBuffer( int64_t dataLen = 0; - verbosePrint("[%d] %s() LN%d i=%"PRIu64" batchPerTblTimes=%"PRIu64" batchPerTbl = %"PRIu64"\n", + verbosePrint("[%d] %s() LN%d i=%"PRIu64" batchPerTblTimes=%u batchPerTbl = %u\n", pThreadInfo->threadID, __func__, __LINE__, i, batchPerTblTimes, batchPerTbl); - if (superTblInfo) { - if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) { + if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) { startTime = taosGetTimestamp(pThreadInfo->time_precision); - } - } else { - startTime = 1500000000000; } - int64_t k = generateDataTail( - superTblInfo, - batchPerTbl, pstr, *pRemainderBufLen, insertRows, 0, - startTime, - &(pThreadInfo->samplePos), &dataLen); + int32_t k = generateStbDataTail( + superTblInfo, + batchPerTbl, pstr, *pRemainderBufLen, insertRows, 0, + startTime, + &(pThreadInfo->samplePos), &dataLen); if (k == batchPerTbl) { pstr += dataLen; *pRemainderBufLen -= dataLen; } else { - debugPrint("%s() LN%d, generated data tail: %"PRIu64", not equal batch per table: %"PRIu64"\n", + debugPrint("%s() LN%d, generated data tail: %u, not equal batch per table: %u\n", __func__, __LINE__, k, batchPerTbl); pstr -= headLen; pstr[0] = '\0'; @@ -4986,34 +5264,363 @@ static int64_t generateInterlaceDataBuffer( return k; } -static int64_t generateProgressiveDataBuffer( +static int64_t generateInterlaceDataWithoutStb( + char *tableName, uint32_t batch, + uint64_t tableSeq, + char *dbName, char *buffer, + int64_t insertRows, + int64_t startTime, + uint64_t *pRemainderBufLen) +{ + assert(buffer); + char *pstr = buffer; + + int headLen = generateSQLHeadWithoutStb( + tableName, dbName, + pstr, *pRemainderBufLen); + + if (headLen <= 0) { + return 0; + } + + pstr += headLen; + *pRemainderBufLen -= headLen; + + int64_t dataLen = 0; + + int32_t k = generateDataTailWithoutStb( + batch, pstr, *pRemainderBufLen, insertRows, 0, + startTime, + &dataLen); + + if (k == batch) { + pstr += dataLen; + *pRemainderBufLen -= dataLen; + } else { + debugPrint("%s() LN%d, generated data tail: %d, not equal batch per table: %u\n", + __func__, __LINE__, k, batch); + pstr -= headLen; + pstr[0] = '\0'; + k = 0; + } + + return k; +} + +#if STMT_IFACE_ENABLED == 1 +static int32_t prepareStmtBindArrayByType(TAOS_BIND *bind, + char *dataType, int32_t dataLen, char **ptr) +{ + if (0 == strncasecmp(dataType, + "BINARY", strlen("BINARY"))) { + if (dataLen > TSDB_MAX_BINARY_LEN) { + errorPrint( "binary length overflow, max size:%u\n", + (uint32_t)TSDB_MAX_BINARY_LEN); + return -1; + } + char *bind_binary = (char *)*ptr; + rand_string(bind_binary, dataLen); + + bind->buffer_type = TSDB_DATA_TYPE_BINARY; + bind->buffer_length = dataLen; + bind->buffer = bind_binary; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + } else if (0 == strncasecmp(dataType, + "NCHAR", strlen("NCHAR"))) { + if (dataLen > TSDB_MAX_BINARY_LEN) { + errorPrint( "nchar length overflow, max size:%u\n", + (uint32_t)TSDB_MAX_BINARY_LEN); + return -1; + } + char *bind_nchar = (char *)*ptr; + rand_string(bind_nchar, dataLen); + + bind->buffer_type = TSDB_DATA_TYPE_NCHAR; + bind->buffer_length = strlen(bind_nchar); + bind->buffer = bind_nchar; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + } else if (0 == strncasecmp(dataType, + "INT", strlen("INT"))) { + int32_t *bind_int = (int32_t *)*ptr; + + *bind_int = rand_int(); + bind->buffer_type = TSDB_DATA_TYPE_INT; + bind->buffer_length = sizeof(int32_t); + bind->buffer = bind_int; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + } else if (0 == strncasecmp(dataType, + "BIGINT", strlen("BIGINT"))) { + int64_t *bind_bigint = (int64_t *)*ptr; + + *bind_bigint = rand_bigint(); + bind->buffer_type = TSDB_DATA_TYPE_BIGINT; + bind->buffer_length = sizeof(int64_t); + bind->buffer = bind_bigint; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + } else if (0 == strncasecmp(dataType, + "FLOAT", strlen("FLOAT"))) { + float *bind_float = (float *) *ptr; + + *bind_float = rand_float(); + bind->buffer_type = TSDB_DATA_TYPE_FLOAT; + bind->buffer_length = sizeof(float); + bind->buffer = bind_float; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + } else if (0 == strncasecmp(dataType, + "DOUBLE", strlen("DOUBLE"))) { + double *bind_double = (double *)*ptr; + + *bind_double = rand_double(); + bind->buffer_type = TSDB_DATA_TYPE_DOUBLE; + bind->buffer_length = sizeof(double); + bind->buffer = bind_double; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + } else if (0 == strncasecmp(dataType, + "SMALLINT", strlen("SMALLINT"))) { + int16_t *bind_smallint = (int16_t *)*ptr; + + *bind_smallint = rand_smallint(); + bind->buffer_type = TSDB_DATA_TYPE_SMALLINT; + bind->buffer_length = sizeof(int16_t); + bind->buffer = bind_smallint; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + } else if (0 == strncasecmp(dataType, + "TINYINT", strlen("TINYINT"))) { + int8_t *bind_tinyint = (int8_t *)*ptr; + + *bind_tinyint = rand_tinyint(); + bind->buffer_type = TSDB_DATA_TYPE_TINYINT; + bind->buffer_length = sizeof(int8_t); + bind->buffer = bind_tinyint; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + *ptr += bind->buffer_length; + } else if (0 == strncasecmp(dataType, + "BOOL", strlen("BOOL"))) { + int8_t *bind_bool = (int8_t *)*ptr; + + *bind_bool = rand_bool(); + bind->buffer_type = TSDB_DATA_TYPE_BOOL; + bind->buffer_length = sizeof(int8_t); + bind->buffer = bind_bool; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + } else if (0 == strncasecmp(dataType, + "TIMESTAMP", strlen("TIMESTAMP"))) { + int64_t *bind_ts2 = (int64_t *) *ptr; + + *bind_ts2 = rand_bigint(); + bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + bind->buffer_length = sizeof(int64_t); + bind->buffer = bind_ts2; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + *ptr += bind->buffer_length; + } else { + errorPrint( "No support data type: %s\n", + dataType); + return -1; + } + + return 0; +} + +static int32_t prepareStmtWithoutStb( + TAOS_STMT *stmt, char *tableName, - int64_t tableSeq, - threadInfo *pThreadInfo, char *buffer, + uint32_t batch, int64_t insertRows, - int64_t startFrom, int64_t startTime, int64_t *pSamplePos, - int64_t *pRemainderBufLen) + int64_t recordFrom, + int64_t startTime) { - SSuperTable* superTblInfo = pThreadInfo->superTblInfo; + int ret = taos_stmt_set_tbname(stmt, tableName); + if (ret != 0) { + errorPrint("failed to execute taos_stmt_set_tbname(%s). return 0x%x. reason: %s\n", + tableName, ret, taos_errstr(NULL)); + return ret; + } - int ncols_per_record = 1; // count first col ts + char **data_type = g_args.datatype; - if (superTblInfo == NULL) { - int datatypeSeq = 0; - while(g_args.datatype[datatypeSeq]) { - datatypeSeq ++; - ncols_per_record ++; + char *bindArray = malloc(sizeof(TAOS_BIND) * (g_args.num_of_CPR + 1)); + if (bindArray == NULL) { + errorPrint("Failed to allocate %d bind params\n", + (g_args.num_of_CPR + 1)); + return -1; } - } + int32_t k = 0; + for (k = 0; k < batch;) { + /* columnCount + 1 (ts) */ + char data[MAX_DATA_SIZE]; + memset(data, 0, MAX_DATA_SIZE); + + char *ptr = data; + TAOS_BIND *bind = (TAOS_BIND *)(bindArray + 0); + + int64_t *bind_ts; + + bind_ts = (int64_t *)ptr; + bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + *bind_ts = startTime + getTSRandTail( + (int64_t)DEFAULT_TIMESTAMP_STEP, k, + g_args.disorderRatio, + g_args.disorderRange); + bind->buffer_length = sizeof(int64_t); + bind->buffer = bind_ts; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + ptr += bind->buffer_length; + + for (int i = 0; i < g_args.num_of_CPR; i ++) { + bind = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * (i + 1))); + if ( -1 == prepareStmtBindArrayByType( + bind, + data_type[i], + g_args.len_of_binary, + &ptr)) { + return -1; + } + } + taos_stmt_bind_param(stmt, (TAOS_BIND *)bindArray); + // if msg > 3MB, break + taos_stmt_add_batch(stmt); + + k++; + recordFrom ++; + if (recordFrom >= insertRows) { + break; + } + } + + free(bindArray); + return k; +} + +static int32_t prepareStbStmt(SSuperTable *stbInfo, + TAOS_STMT *stmt, + char *tableName, uint32_t batch, + uint64_t insertRows, + uint64_t recordFrom, + int64_t startTime, char *buffer) +{ + int ret = taos_stmt_set_tbname(stmt, tableName); + if (ret != 0) { + errorPrint("failed to execute taos_stmt_set_tbname(%s). return 0x%x. reason: %s\n", + tableName, ret, taos_errstr(NULL)); + return ret; + } + + char *bindArray = malloc(sizeof(TAOS_BIND) * (stbInfo->columnCount + 1)); + if (bindArray == NULL) { + errorPrint("Failed to allocate %d bind params\n", + (stbInfo->columnCount + 1)); + return -1; + } + + bool tsRand; + if (0 == strncasecmp(stbInfo->dataSource, "rand", strlen("rand"))) { + tsRand = true; + } else { + tsRand = false; + } + + uint32_t k; + for (k = 0; k < batch;) { + /* columnCount + 1 (ts) */ + char data[MAX_DATA_SIZE]; + memset(data, 0, MAX_DATA_SIZE); + + char *ptr = data; + TAOS_BIND *bind = (TAOS_BIND *)(bindArray + 0); + + int64_t *bind_ts; + + bind_ts = (int64_t *)ptr; + bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + if (tsRand) { + *bind_ts = startTime + getTSRandTail( + stbInfo->timeStampStep, k, + stbInfo->disorderRatio, + stbInfo->disorderRange); + } else { + *bind_ts = startTime + stbInfo->timeStampStep * k; + } + bind->buffer_length = sizeof(int64_t); + bind->buffer = bind_ts; + bind->length = &bind->buffer_length; + bind->is_null = NULL; + + ptr += bind->buffer_length; + + for (int i = 0; i < stbInfo->columnCount; i ++) { + bind = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * (i + 1))); + if ( -1 == prepareStmtBindArrayByType( + bind, + stbInfo->columns[i].dataType, + stbInfo->columns[i].dataLen, + &ptr)) { + return -1; + } + } + taos_stmt_bind_param(stmt, (TAOS_BIND *)bindArray); + // if msg > 3MB, break + taos_stmt_add_batch(stmt); + + k++; + recordFrom ++; + if (recordFrom >= insertRows) { + break; + } + } + + free(bindArray); + return k; +} +#endif + +static int32_t generateStbProgressiveData( + SSuperTable *superTblInfo, + char *tableName, + int64_t tableSeq, + char *dbName, char *buffer, + int64_t insertRows, + uint64_t recordFrom, int64_t startTime, int64_t *pSamplePos, + int64_t *pRemainderBufLen) +{ assert(buffer != NULL); char *pstr = buffer; - int64_t k = 0; - memset(buffer, 0, *pRemainderBufLen); - int64_t headLen = generateSQLHead(tableName, tableSeq, pThreadInfo, superTblInfo, + int64_t headLen = generateStbSQLHead( + superTblInfo, + tableName, tableSeq, dbName, buffer, *pRemainderBufLen); if (headLen <= 0) { @@ -5023,29 +5630,64 @@ static int64_t generateProgressiveDataBuffer( *pRemainderBufLen -= headLen; int64_t dataLen; - k = generateDataTail(superTblInfo, - g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, startFrom, + + return generateStbDataTail(superTblInfo, + g_args.num_of_RPR, pstr, *pRemainderBufLen, + insertRows, recordFrom, startTime, pSamplePos, &dataLen); +} - return k; +static int32_t generateProgressiveDataWithoutStb( + char *tableName, + /* int64_t tableSeq, */ + threadInfo *pThreadInfo, char *buffer, + int64_t insertRows, + uint64_t recordFrom, int64_t startTime, /*int64_t *pSamplePos, */ + int64_t *pRemainderBufLen) +{ + assert(buffer != NULL); + char *pstr = buffer; + + memset(buffer, 0, *pRemainderBufLen); + + int64_t headLen = generateSQLHeadWithoutStb( + tableName, pThreadInfo->db_name, + buffer, *pRemainderBufLen); + + if (headLen <= 0) { + return 0; + } + pstr += headLen; + *pRemainderBufLen -= headLen; + + int64_t dataLen; + + return generateDataTailWithoutStb( + g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, recordFrom, + startTime, + /*pSamplePos, */&dataLen); } static void printStatPerThread(threadInfo *pThreadInfo) { - fprintf(stderr, "====thread[%d] completed total inserted rows: %"PRIu64 ", total affected rows: %"PRIu64". %.2f records/second====\n", + fprintf(stderr, "====thread[%d] completed total inserted rows: %"PRIu64 ", total affected rows: %"PRIu64". %.2f records/second====\n", pThreadInfo->threadID, pThreadInfo->totalInsertRows, pThreadInfo->totalAffectedRows, (double)(pThreadInfo->totalAffectedRows / (pThreadInfo->totalDelay/1000.0))); } +// sync write interlace data static void* syncWriteInterlace(threadInfo *pThreadInfo) { debugPrint("[%d] %s() LN%d: ### interlace write\n", pThreadInfo->threadID, __func__, __LINE__); - uint64_t insertRows; - uint64_t interlaceRows; + int64_t insertRows; + uint32_t interlaceRows; + uint64_t maxSqlLen; + int64_t nTimeStampStep; + uint64_t insert_interval; SSuperTable* superTblInfo = pThreadInfo->superTblInfo; @@ -5058,45 +5700,48 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { } else { interlaceRows = superTblInfo->interlaceRows; } + maxSqlLen = superTblInfo->maxSqlLen; + nTimeStampStep = superTblInfo->timeStampStep; + insert_interval = superTblInfo->insertInterval; } else { insertRows = g_args.num_of_DPT; interlaceRows = g_args.interlace_rows; + maxSqlLen = g_args.max_sql_len; + nTimeStampStep = DEFAULT_TIMESTAMP_STEP; + insert_interval = g_args.insert_interval; } + debugPrint("[%d] %s() LN%d: start_table_from=%"PRIu64" ntables=%"PRId64" insertRows=%"PRIu64"\n", + pThreadInfo->threadID, __func__, __LINE__, + pThreadInfo->start_table_from, + pThreadInfo->ntables, insertRows); + if (interlaceRows > insertRows) interlaceRows = insertRows; if (interlaceRows > g_args.num_of_RPR) interlaceRows = g_args.num_of_RPR; - int insertMode; + uint32_t batchPerTbl = interlaceRows; + uint32_t batchPerTblTimes; - if (interlaceRows > 0) { - insertMode = INTERLACE_INSERT_MODE; + if ((interlaceRows > 0) && (pThreadInfo->ntables > 1)) { + batchPerTblTimes = + g_args.num_of_RPR / interlaceRows; } else { - insertMode = PROGRESSIVE_INSERT_MODE; + batchPerTblTimes = 1; } - // TODO: prompt tbl count multple interlace rows and batch - // - - uint64_t maxSqlLen = superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len; - char* buffer = calloc(maxSqlLen, 1); - if (NULL == buffer) { + pThreadInfo->buffer = calloc(maxSqlLen, 1); + if (NULL == pThreadInfo->buffer) { errorPrint( "%s() LN%d, Failed to alloc %"PRIu64" Bytes, reason:%s\n", __func__, __LINE__, maxSqlLen, strerror(errno)); return NULL; } - char tableName[TSDB_TABLE_NAME_LEN]; - pThreadInfo->totalInsertRows = 0; pThreadInfo->totalAffectedRows = 0; - int64_t nTimeStampStep = superTblInfo?superTblInfo->timeStampStep:DEFAULT_TIMESTAMP_STEP; - - uint64_t insert_interval = - superTblInfo?superTblInfo->insertInterval:g_args.insert_interval; uint64_t st = 0; uint64_t et = UINT64_MAX; @@ -5105,71 +5750,98 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { uint64_t endTs; uint64_t tableSeq = pThreadInfo->start_table_from; - - debugPrint("[%d] %s() LN%d: start_table_from=%"PRIu64" ntables=%"PRIu64" insertRows=%"PRIu64"\n", - pThreadInfo->threadID, __func__, __LINE__, pThreadInfo->start_table_from, - pThreadInfo->ntables, insertRows); - int64_t startTime = pThreadInfo->start_time; - assert(pThreadInfo->ntables > 0); - - uint64_t batchPerTbl = interlaceRows; - uint64_t batchPerTblTimes; - - if ((interlaceRows > 0) && (pThreadInfo->ntables > 1)) { - batchPerTblTimes = - g_args.num_of_RPR / interlaceRows; - } else { - batchPerTblTimes = 1; - } - uint64_t generatedRecPerTbl = 0; bool flagSleep = true; uint64_t sleepTimeTotal = 0; - char *strInsertInto = "insert into "; - int nInsertBufLen = strlen(strInsertInto); - while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) { if ((flagSleep) && (insert_interval)) { st = taosGetTimestampMs(); flagSleep = false; } // generate data - memset(buffer, 0, maxSqlLen); + memset(pThreadInfo->buffer, 0, maxSqlLen); uint64_t remainderBufLen = maxSqlLen; - char *pstr = buffer; + char *pstr = pThreadInfo->buffer; - int len = snprintf(pstr, nInsertBufLen + 1, "%s", strInsertInto); + int len = snprintf(pstr, + strlen(STR_INSERT_INTO) + 1, "%s", STR_INSERT_INTO); pstr += len; remainderBufLen -= len; - uint64_t recOfBatch = 0; + uint32_t recOfBatch = 0; + + for (uint32_t i = 0; i < batchPerTblTimes; i ++) { + char tableName[TSDB_TABLE_NAME_LEN]; - for (uint64_t i = 0; i < batchPerTblTimes; i ++) { getTableName(tableName, pThreadInfo, tableSeq); if (0 == strlen(tableName)) { errorPrint("[%d] %s() LN%d, getTableName return null\n", pThreadInfo->threadID, __func__, __LINE__); - free(buffer); + free(pThreadInfo->buffer); return NULL; } uint64_t oldRemainderLen = remainderBufLen; - int64_t generated = generateInterlaceDataBuffer( - tableName, batchPerTbl, i, batchPerTblTimes, - tableSeq, - pThreadInfo, pstr, - insertRows, - startTime, - &remainderBufLen); - - debugPrint("[%d] %s() LN%d, generated records is %"PRId64"\n", + + int32_t generated; + if (superTblInfo) { + if (superTblInfo->iface == STMT_IFACE) { +#if STMT_IFACE_ENABLED == 1 + generated = prepareStbStmt(superTblInfo, + pThreadInfo->stmt, + tableName, + batchPerTbl, + insertRows, i, + startTime, + pThreadInfo->buffer); +#else + generated = -1; +#endif + } else { + generated = generateStbInterlaceData( + superTblInfo, + tableName, batchPerTbl, i, + batchPerTblTimes, + tableSeq, + pThreadInfo, pstr, + insertRows, + startTime, + &remainderBufLen); + } + } else { + if (g_args.iface == STMT_IFACE) { + debugPrint("[%d] %s() LN%d, tableName:%s, batch:%d startTime:%"PRId64"\n", + pThreadInfo->threadID, + __func__, __LINE__, + tableName, batchPerTbl, startTime); +#if STMT_IFACE_ENABLED == 1 + generated = prepareStmtWithoutStb( + pThreadInfo->stmt, tableName, + batchPerTbl, + insertRows, i, + startTime); +#else + generated = -1; +#endif + } else { + generated = generateInterlaceDataWithoutStb( + tableName, batchPerTbl, + tableSeq, + pThreadInfo->db_name, pstr, + insertRows, + startTime, + &remainderBufLen); + } + } + + debugPrint("[%d] %s() LN%d, generated records is %d\n", pThreadInfo->threadID, __func__, __LINE__, generated); if (generated < 0) { - errorPrint("[%d] %s() LN%d, generated records is %"PRId64"\n", + errorPrint("[%d] %s() LN%d, generated records is %d\n", pThreadInfo->threadID, __func__, __LINE__, generated); goto free_of_interlace; } else if (generated == 0) { @@ -5178,15 +5850,15 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { tableSeq ++; recOfBatch += batchPerTbl; + pstr += (oldRemainderLen - remainderBufLen); -// startTime += batchPerTbl * superTblInfo->timeStampStep; pThreadInfo->totalInsertRows += batchPerTbl; - verbosePrint("[%d] %s() LN%d batchPerTbl=%"PRId64" recOfBatch=%"PRId64"\n", + + verbosePrint("[%d] %s() LN%d batchPerTbl=%d recOfBatch=%d\n", pThreadInfo->threadID, __func__, __LINE__, batchPerTbl, recOfBatch); - if (insertMode == INTERLACE_INSERT_MODE) { - if (tableSeq == pThreadInfo->start_table_from + pThreadInfo->ntables) { + if (tableSeq == pThreadInfo->start_table_from + pThreadInfo->ntables) { // turn to first table tableSeq = pThreadInfo->start_table_from; generatedRecPerTbl += batchPerTbl; @@ -5198,13 +5870,12 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { if (generatedRecPerTbl >= insertRows) break; - int remainRows = insertRows - generatedRecPerTbl; + int64_t remainRows = insertRows - generatedRecPerTbl; if ((remainRows > 0) && (batchPerTbl > remainRows)) batchPerTbl = remainRows; if (pThreadInfo->ntables * batchPerTbl < g_args.num_of_RPR) break; - } } verbosePrint("[%d] %s() LN%d generatedRecPerTbl=%"PRId64" insertRows=%"PRId64"\n", @@ -5215,15 +5886,22 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { break; } - verbosePrint("[%d] %s() LN%d recOfBatch=%"PRIu64" totalInsertRows=%"PRIu64"\n", + verbosePrint("[%d] %s() LN%d recOfBatch=%d totalInsertRows=%"PRIu64"\n", pThreadInfo->threadID, __func__, __LINE__, recOfBatch, pThreadInfo->totalInsertRows); verbosePrint("[%d] %s() LN%d, buffer=%s\n", - pThreadInfo->threadID, __func__, __LINE__, buffer); + pThreadInfo->threadID, __func__, __LINE__, pThreadInfo->buffer); startTs = taosGetTimestampMs(); - int64_t affectedRows = execInsert(pThreadInfo, buffer, recOfBatch); + if (recOfBatch == 0) { + errorPrint("[%d] %s() LN%d try inserting records of batch is %d\n", + pThreadInfo->threadID, __func__, __LINE__, + recOfBatch); + errorPrint("%s\n", "\tPlease check if the batch or the buffer length is proper value!\n"); + goto free_of_interlace; + } + int64_t affectedRows = execInsert(pThreadInfo, recOfBatch); endTs = taosGetTimestampMs(); uint64_t delay = endTs - startTs; @@ -5239,9 +5917,9 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { pThreadInfo->totalDelay += delay; if (recOfBatch != affectedRows) { - errorPrint("[%d] %s() LN%d execInsert insert %"PRIu64", affected rows: %"PRId64"\n%s\n", + errorPrint("[%d] %s() LN%d execInsert insert %d, affected rows: %"PRId64"\n%s\n", pThreadInfo->threadID, __func__, __LINE__, - recOfBatch, affectedRows, buffer); + recOfBatch, affectedRows, pThreadInfo->buffer); goto free_of_interlace; } @@ -5260,8 +5938,8 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { et = taosGetTimestampMs(); if (insert_interval > (et - st) ) { - int sleepTime = insert_interval - (et -st); - performancePrint("%s() LN%d sleep: %d ms for insert interval\n", + uint64_t sleepTime = insert_interval - (et -st); + performancePrint("%s() LN%d sleep: %"PRId64" ms for insert interval\n", __func__, __LINE__, sleepTime); taosMsleep(sleepTime); // ms sleepTimeTotal += insert_interval; @@ -5270,27 +5948,26 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { } free_of_interlace: - tmfree(buffer); + tmfree(pThreadInfo->buffer); printStatPerThread(pThreadInfo); return NULL; } -// sync insertion -/* - 1 thread: 100 tables * 2000 rows/s - 1 thread: 10 tables * 20000 rows/s - 6 thread: 300 tables * 2000 rows/s - - 2 taosinsertdata , 1 thread: 10 tables * 20000 rows/s -*/ +// sync insertion progressive data static void* syncWriteProgressive(threadInfo *pThreadInfo) { debugPrint("%s() LN%d: ### progressive write\n", __func__, __LINE__); SSuperTable* superTblInfo = pThreadInfo->superTblInfo; uint64_t maxSqlLen = superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len; + int64_t timeStampStep = + superTblInfo?superTblInfo->timeStampStep:DEFAULT_TIMESTAMP_STEP; + int64_t insertRows = + (superTblInfo)?superTblInfo->insertRows:g_args.num_of_DPT; + verbosePrint("%s() LN%d insertRows=%"PRId64"\n", + __func__, __LINE__, insertRows); - char* buffer = calloc(maxSqlLen, 1); - if (NULL == buffer) { + pThreadInfo->buffer = calloc(maxSqlLen, 1); + if (NULL == pThreadInfo->buffer) { errorPrint( "Failed to alloc %"PRIu64" Bytes, reason:%s\n", maxSqlLen, strerror(errno)); @@ -5301,34 +5978,17 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { uint64_t startTs = taosGetTimestampMs(); uint64_t endTs; - int64_t timeStampStep = - superTblInfo?superTblInfo->timeStampStep:DEFAULT_TIMESTAMP_STEP; -/* int insert_interval = - superTblInfo?superTblInfo->insertInterval:g_args.insert_interval; - uint64_t st = 0; - uint64_t et = 0xffffffff; - */ - pThreadInfo->totalInsertRows = 0; pThreadInfo->totalAffectedRows = 0; pThreadInfo->samplePos = 0; - for (uint64_t tableSeq = - pThreadInfo->start_table_from; tableSeq <= pThreadInfo->end_table_to; - tableSeq ++) { + for (uint64_t tableSeq = pThreadInfo->start_table_from; + tableSeq <= pThreadInfo->end_table_to; + tableSeq ++) { int64_t start_time = pThreadInfo->start_time; - uint64_t insertRows = (superTblInfo)?superTblInfo->insertRows:g_args.num_of_DPT; - verbosePrint("%s() LN%d insertRows=%"PRId64"\n", __func__, __LINE__, insertRows); - for (uint64_t i = 0; i < insertRows;) { - /* - if (insert_interval) { - st = taosGetTimestampMs(); - } - */ - char tableName[TSDB_TABLE_NAME_LEN]; getTableName(tableName, pThreadInfo, tableSeq); verbosePrint("%s() LN%d: tid=%d seq=%"PRId64" tableName=%s\n", @@ -5336,19 +5996,57 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { pThreadInfo->threadID, tableSeq, tableName); int64_t remainderBufLen = maxSqlLen; - char *pstr = buffer; - int nInsertBufLen = strlen("insert into "); + char *pstr = pThreadInfo->buffer; - int len = snprintf(pstr, nInsertBufLen + 1, "%s", "insert into "); + int len = snprintf(pstr, + strlen(STR_INSERT_INTO) + 1, "%s", STR_INSERT_INTO); pstr += len; remainderBufLen -= len; - int64_t generated = generateProgressiveDataBuffer( - tableName, tableSeq, pThreadInfo, pstr, insertRows, - i, start_time, - &(pThreadInfo->samplePos), - &remainderBufLen); + int32_t generated; + if (superTblInfo) { + if (superTblInfo->iface == STMT_IFACE) { +#if STMT_IFACE_ENABLED == 1 + generated = prepareStbStmt( + superTblInfo, + pThreadInfo->stmt, + tableName, + g_args.num_of_RPR, + insertRows, i, start_time, pstr); +#else + generated = -1; +#endif + } else { + generated = generateStbProgressiveData( + superTblInfo, + tableName, tableSeq, pThreadInfo->db_name, pstr, + insertRows, i, start_time, + &(pThreadInfo->samplePos), + &remainderBufLen); + } + } else { + if (g_args.iface == STMT_IFACE) { +#if STMT_IFACE_ENABLED == 1 + generated = prepareStmtWithoutStb( + pThreadInfo->stmt, + tableName, + g_args.num_of_RPR, + insertRows, i, + start_time); +#else + generated = -1; +#endif + } else { + generated = generateProgressiveDataWithoutStb( + tableName, + /* tableSeq, */ + pThreadInfo, pstr, insertRows, + i, start_time, + /* &(pThreadInfo->samplePos), */ + &remainderBufLen); + } + } if (generated > 0) i += generated; else @@ -5359,13 +6057,13 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { startTs = taosGetTimestampMs(); - int64_t affectedRows = execInsert(pThreadInfo, buffer, generated); + int32_t affectedRows = execInsert(pThreadInfo, generated); endTs = taosGetTimestampMs(); uint64_t delay = endTs - startTs; performancePrint("%s() LN%d, insert execution time is %"PRId64"ms\n", __func__, __LINE__, delay); - verbosePrint("[%d] %s() LN%d affectedRows=%"PRId64"\n", + verbosePrint("[%d] %s() LN%d affectedRows=%d\n", pThreadInfo->threadID, __func__, __LINE__, affectedRows); @@ -5375,7 +6073,7 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { pThreadInfo->totalDelay += delay; if (affectedRows < 0) { - errorPrint("%s() LN%d, affected rows: %"PRId64"\n", + errorPrint("%s() LN%d, affected rows: %d\n", __func__, __LINE__, affectedRows); goto free_of_progressive; } @@ -5393,32 +6091,19 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { if (i >= insertRows) break; -/* - if (insert_interval) { - et = taosGetTimestampMs(); - - if (insert_interval > ((et - st)) ) { - int sleep_time = insert_interval - (et -st); - performancePrint("%s() LN%d sleep: %d ms for insert interval\n", - __func__, __LINE__, sleep_time); - taosMsleep(sleep_time); // ms - } - } - */ } // num_of_DPT - if (g_args.verbose_print) { - if ((tableSeq == pThreadInfo->ntables - 1) && superTblInfo && + if ((g_args.verbose_print) && + (tableSeq == pThreadInfo->ntables - 1) && (superTblInfo) && (0 == strncasecmp( superTblInfo->dataSource, "sample", strlen("sample")))) { verbosePrint("%s() LN%d samplePos=%"PRId64"\n", __func__, __LINE__, pThreadInfo->samplePos); - } } } // tableSeq free_of_progressive: - tmfree(buffer); + tmfree(pThreadInfo->buffer); printStatPerThread(pThreadInfo); return NULL; } @@ -5428,7 +6113,7 @@ static void* syncWrite(void *sarg) { threadInfo *pThreadInfo = (threadInfo *)sarg; SSuperTable* superTblInfo = pThreadInfo->superTblInfo; - int interlaceRows; + uint32_t interlaceRows; if (superTblInfo) { if ((superTblInfo->interlaceRows == 0) @@ -5448,7 +6133,6 @@ static void* syncWrite(void *sarg) { // progressive mode return syncWriteProgressive(pThreadInfo); } - } static void callBack(void *param, TAOS_RES *res, int code) { @@ -5486,10 +6170,12 @@ static void callBack(void *param, TAOS_RES *res, int code) { int rand_num = taosRandom() % 100; if (0 != pThreadInfo->superTblInfo->disorderRatio && rand_num < pThreadInfo->superTblInfo->disorderRatio) { - int64_t d = pThreadInfo->lastTs - (taosRandom() % pThreadInfo->superTblInfo->disorderRange + 1); - generateRowData(data, d, pThreadInfo->superTblInfo); + int64_t d = pThreadInfo->lastTs + - (taosRandom() % pThreadInfo->superTblInfo->disorderRange + 1); + generateStbRowData(pThreadInfo->superTblInfo, data, d); } else { - generateRowData(data, pThreadInfo->lastTs += 1000, pThreadInfo->superTblInfo); + generateStbRowData(pThreadInfo->superTblInfo, + data, pThreadInfo->lastTs += 1000); } pstr += sprintf(pstr, "%s", data); pThreadInfo->counter++; @@ -5557,24 +6243,6 @@ static int convertHostToServAddr(char *host, uint16_t port, struct sockaddr_in * static void startMultiThreadInsertData(int threads, char* db_name, char* precision,SSuperTable* superTblInfo) { - pthread_t *pids = malloc(threads * sizeof(pthread_t)); - assert(pids != NULL); - - threadInfo *infos = malloc(threads * sizeof(threadInfo)); - assert(infos != NULL); - - memset(pids, 0, threads * sizeof(pthread_t)); - memset(infos, 0, threads * sizeof(threadInfo)); - - //TAOS* taos; - //if (0 == strncasecmp(superTblInfo->insertMode, "taosc", 5)) { - // taos = taos_connect(g_Dbs.host, g_Dbs.user, g_Dbs.password, db_name, g_Dbs.port); - // if (NULL == taos) { - // printf("connect to server fail, reason: %s\n", taos_errstr(NULL)); - // exit(-1); - // } - //} - int32_t timePrec = TSDB_TIME_PRECISION_MILLI; if (0 != precision[0]) { if (0 == strncasecmp(precision, "ms", 2)) { @@ -5626,17 +6294,17 @@ static void startMultiThreadInsertData(int threads, char* db_name, } } - TAOS* taos = taos_connect( + TAOS* taos0 = taos_connect( g_Dbs.host, g_Dbs.user, g_Dbs.password, db_name, g_Dbs.port); - if (NULL == taos) { + if (NULL == taos0) { errorPrint("%s() LN%d, connect to server fail , reason: %s\n", __func__, __LINE__, taos_errstr(NULL)); exit(-1); } - int ntables = 0; - int startFrom; + int64_t ntables = 0; + uint64_t tableFrom; if (superTblInfo) { int64_t limit; @@ -5663,110 +6331,159 @@ static void startMultiThreadInsertData(int threads, char* db_name, } ntables = limit; - startFrom = offset; + tableFrom = offset; if ((superTblInfo->childTblExists != TBL_NO_EXISTS) && ((superTblInfo->childTblOffset + superTblInfo->childTblLimit ) > superTblInfo->childTblCount)) { printf("WARNING: specified offset + limit > child table count!\n"); - if (!g_args.answer_yes) { - printf(" Press enter key to continue or Ctrl-C to stop\n\n"); - (void)getchar(); - } + prompt(); } if ((superTblInfo->childTblExists != TBL_NO_EXISTS) && (0 == superTblInfo->childTblLimit)) { printf("WARNING: specified limit = 0, which cannot find table name to insert or query! \n"); - if (!g_args.answer_yes) { - printf(" Press enter key to continue or Ctrl-C to stop\n\n"); - (void)getchar(); - } + prompt(); } superTblInfo->childTblName = (char*)calloc(1, limit * TSDB_TABLE_NAME_LEN); if (superTblInfo->childTblName == NULL) { errorPrint("%s() LN%d, alloc memory failed!\n", __func__, __LINE__); - taos_close(taos); + taos_close(taos0); exit(-1); } - uint64_t childTblCount; + int64_t childTblCount; getChildNameOfSuperTableWithLimitAndOffset( - taos, + taos0, db_name, superTblInfo->sTblName, &superTblInfo->childTblName, &childTblCount, limit, offset); } else { ntables = g_args.num_of_tables; - startFrom = 0; + tableFrom = 0; } - taos_close(taos); + taos_close(taos0); - uint64_t a = ntables / threads; + int64_t a = ntables / threads; if (a < 1) { threads = ntables; a = 1; } - uint64_t b = 0; + int64_t b = 0; if (threads != 0) { b = ntables % threads; } if ((superTblInfo) - && (0 == strncasecmp(superTblInfo->insertMode, "rest", strlen("rest")))) { - if (convertHostToServAddr(g_Dbs.host, g_Dbs.port, &(g_Dbs.serv_addr)) != 0) - exit(-1); + && (superTblInfo->iface == REST_IFACE)) { + if (convertHostToServAddr( + g_Dbs.host, g_Dbs.port, &(g_Dbs.serv_addr)) != 0) { + exit(-1); + } } + pthread_t *pids = malloc(threads * sizeof(pthread_t)); + assert(pids != NULL); + + threadInfo *infos = calloc(1, threads * sizeof(threadInfo)); + assert(infos != NULL); + + memset(pids, 0, threads * sizeof(pthread_t)); + memset(infos, 0, threads * sizeof(threadInfo)); + for (int i = 0; i < threads; i++) { - threadInfo *t_info = infos + i; - t_info->threadID = i; - tstrncpy(t_info->db_name, db_name, MAX_DB_NAME_SIZE); - t_info->time_precision = timePrec; - t_info->superTblInfo = superTblInfo; + threadInfo *pThreadInfo = infos + i; + pThreadInfo->threadID = i; + tstrncpy(pThreadInfo->db_name, db_name, MAX_DB_NAME_SIZE); + pThreadInfo->time_precision = timePrec; + pThreadInfo->superTblInfo = superTblInfo; - t_info->start_time = start_time; - t_info->minDelay = UINT64_MAX; + pThreadInfo->start_time = start_time; + pThreadInfo->minDelay = UINT64_MAX; if ((NULL == superTblInfo) || - (0 == strncasecmp(superTblInfo->insertMode, "taosc", 5))) { + (superTblInfo->iface != REST_IFACE)) { //t_info->taos = taos; - t_info->taos = taos_connect( + pThreadInfo->taos = taos_connect( g_Dbs.host, g_Dbs.user, g_Dbs.password, db_name, g_Dbs.port); - if (NULL == t_info->taos) { + if (NULL == pThreadInfo->taos) { errorPrint( - "connect to server fail from insert sub thread, reason: %s\n", + "%s() LN%d, connect to server fail from insert sub thread, reason: %s\n", + __func__, __LINE__, taos_errstr(NULL)); + free(infos); exit(-1); } + +#if STMT_IFACE_ENABLED == 1 + if ((g_args.iface == STMT_IFACE) + || ((superTblInfo) && (superTblInfo->iface == STMT_IFACE))) { + + int columnCount; + if (superTblInfo) { + columnCount = superTblInfo->columnCount; + } else { + columnCount = g_args.num_of_CPR; + } + + pThreadInfo->stmt = taos_stmt_init(pThreadInfo->taos); + if (NULL == pThreadInfo->stmt) { + errorPrint( + "%s() LN%d, failed init stmt, reason: %s\n", + __func__, __LINE__, + taos_errstr(NULL)); + free(pids); + free(infos); + exit(-1); + } + + char buffer[3000]; + char *pstr = buffer; + pstr += sprintf(pstr, "INSERT INTO ? values(?"); + + for (int col = 0; col < columnCount; col ++) { + pstr += sprintf(pstr, ",?"); + } + pstr += sprintf(pstr, ")"); + + int ret = taos_stmt_prepare(pThreadInfo->stmt, buffer, 0); + if (ret != 0){ + errorPrint("failed to execute taos_stmt_prepare. return 0x%x. reason: %s\n", + ret, taos_errstr(NULL)); + free(pids); + free(infos); + exit(-1); + } + } +#endif } else { - t_info->taos = NULL; + pThreadInfo->taos = NULL; } /* if ((NULL == superTblInfo) || (0 == superTblInfo->multiThreadWriteOneTbl)) { */ - t_info->start_table_from = startFrom; - t_info->ntables = iend_table_to = i < b ? startFrom + a : startFrom + a - 1; - startFrom = t_info->end_table_to + 1; + pThreadInfo->start_table_from = tableFrom; + pThreadInfo->ntables = iend_table_to = i < b ? tableFrom + a : tableFrom + a - 1; + tableFrom = pThreadInfo->end_table_to + 1; /* } else { - t_info->start_table_from = 0; - t_info->ntables = superTblInfo->childTblCount; - t_info->start_time = t_info->start_time + rand_int() % 10000 - rand_tinyint(); + pThreadInfo->start_table_from = 0; + pThreadInfo->ntables = superTblInfo->childTblCount; + pThreadInfo->start_time = pThreadInfo->start_time + rand_int() % 10000 - rand_tinyint(); } */ - tsem_init(&(t_info->lock_sem), 0, 0); + tsem_init(&(pThreadInfo->lock_sem), 0, 0); if (ASYNC_MODE == g_Dbs.asyncMode) { - pthread_create(pids + i, NULL, asyncWrite, t_info); + pthread_create(pids + i, NULL, asyncWrite, pThreadInfo); } else { - pthread_create(pids + i, NULL, syncWrite, t_info); + pthread_create(pids + i, NULL, syncWrite, pThreadInfo); } } @@ -5781,27 +6498,34 @@ static void startMultiThreadInsertData(int threads, char* db_name, double avgDelay = 0; for (int i = 0; i < threads; i++) { - threadInfo *t_info = infos + i; + threadInfo *pThreadInfo = infos + i; - tsem_destroy(&(t_info->lock_sem)); - taos_close(t_info->taos); + tsem_destroy(&(pThreadInfo->lock_sem)); + +#if STMT_IFACE_ENABLED == 1 + if (pThreadInfo->stmt) { + taos_stmt_close(pThreadInfo->stmt); + } +#endif + tsem_destroy(&(pThreadInfo->lock_sem)); + taos_close(pThreadInfo->taos); debugPrint("%s() LN%d, [%d] totalInsert=%"PRIu64" totalAffected=%"PRIu64"\n", __func__, __LINE__, - t_info->threadID, t_info->totalInsertRows, - t_info->totalAffectedRows); + pThreadInfo->threadID, pThreadInfo->totalInsertRows, + pThreadInfo->totalAffectedRows); if (superTblInfo) { - superTblInfo->totalAffectedRows += t_info->totalAffectedRows; - superTblInfo->totalInsertRows += t_info->totalInsertRows; + superTblInfo->totalAffectedRows += pThreadInfo->totalAffectedRows; + superTblInfo->totalInsertRows += pThreadInfo->totalInsertRows; } else { - g_args.totalAffectedRows += t_info->totalAffectedRows; - g_args.totalInsertRows += t_info->totalInsertRows; + g_args.totalAffectedRows += pThreadInfo->totalAffectedRows; + g_args.totalInsertRows += pThreadInfo->totalInsertRows; } - totalDelay += t_info->totalDelay; - cntDelay += t_info->cntDelay; - if (t_info->maxDelay > maxDelay) maxDelay = t_info->maxDelay; - if (t_info->minDelay < minDelay) minDelay = t_info->minDelay; + totalDelay += pThreadInfo->totalDelay; + cntDelay += pThreadInfo->cntDelay; + if (pThreadInfo->maxDelay > maxDelay) maxDelay = pThreadInfo->maxDelay; + if (pThreadInfo->minDelay < minDelay) minDelay = pThreadInfo->minDelay; } cntDelay -= 1; @@ -5857,41 +6581,41 @@ static void startMultiThreadInsertData(int threads, char* db_name, static void *readTable(void *sarg) { #if 1 - threadInfo *rinfo = (threadInfo *)sarg; - TAOS *taos = rinfo->taos; + threadInfo *pThreadInfo = (threadInfo *)sarg; + TAOS *taos = pThreadInfo->taos; char command[BUFFER_SIZE] = "\0"; - uint64_t sTime = rinfo->start_time; - char *tb_prefix = rinfo->tb_prefix; - FILE *fp = fopen(rinfo->fp, "a"); + uint64_t sTime = pThreadInfo->start_time; + char *tb_prefix = pThreadInfo->tb_prefix; + FILE *fp = fopen(pThreadInfo->filePath, "a"); if (NULL == fp) { - errorPrint( "fopen %s fail, reason:%s.\n", rinfo->fp, strerror(errno)); + errorPrint( "fopen %s fail, reason:%s.\n", pThreadInfo->filePath, strerror(errno)); return NULL; } - int num_of_DPT; -/* if (rinfo->superTblInfo) { - num_of_DPT = rinfo->superTblInfo->insertRows; // nrecords_per_table; + int64_t num_of_DPT; +/* if (pThreadInfo->superTblInfo) { + num_of_DPT = pThreadInfo->superTblInfo->insertRows; // nrecords_per_table; } else { */ num_of_DPT = g_args.num_of_DPT; // } - int num_of_tables = rinfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1; - int totalData = num_of_DPT * num_of_tables; + int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1; + int64_t totalData = num_of_DPT * num_of_tables; bool do_aggreFunc = g_Dbs.do_aggreFunc; int n = do_aggreFunc ? (sizeof(aggreFunc) / sizeof(aggreFunc[0])) : 2; if (!do_aggreFunc) { printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n"); } - printf("%d records:\n", totalData); + printf("%"PRId64" records:\n", totalData); fprintf(fp, "| QFunctions | QRecords | QSpeed(R/s) | QLatency(ms) |\n"); - for (uint64_t j = 0; j < n; j++) { + for (int j = 0; j < n; j++) { double totalT = 0; uint64_t count = 0; - for (uint64_t i = 0; i < num_of_tables; i++) { - sprintf(command, "select %s from %s%"PRIu64" where ts>= %" PRIu64, + for (int64_t i = 0; i < num_of_tables; i++) { + sprintf(command, "select %s from %s%"PRId64" where ts>= %" PRIu64, aggreFunc[j], tb_prefix, i, sTime); double t = taosGetTimestampMs(); @@ -5916,7 +6640,7 @@ static void *readTable(void *sarg) { taos_free_result(pSql); } - fprintf(fp, "|%10s | %10d | %12.2f | %10.2f |\n", + fprintf(fp, "|%10s | %"PRId64" | %12.2f | %10.2f |\n", aggreFunc[j][0] == '*' ? " * " : aggreFunc[j], totalData, (double)(num_of_tables * num_of_DPT) / totalT, totalT * 1000); printf("select %10s took %.6f second(s)\n", aggreFunc[j], totalT * 1000); @@ -5929,38 +6653,38 @@ static void *readTable(void *sarg) { static void *readMetric(void *sarg) { #if 1 - threadInfo *rinfo = (threadInfo *)sarg; - TAOS *taos = rinfo->taos; + threadInfo *pThreadInfo = (threadInfo *)sarg; + TAOS *taos = pThreadInfo->taos; char command[BUFFER_SIZE] = "\0"; - FILE *fp = fopen(rinfo->fp, "a"); + FILE *fp = fopen(pThreadInfo->filePath, "a"); if (NULL == fp) { - printf("fopen %s fail, reason:%s.\n", rinfo->fp, strerror(errno)); + printf("fopen %s fail, reason:%s.\n", pThreadInfo->filePath, strerror(errno)); return NULL; } - int num_of_DPT = rinfo->superTblInfo->insertRows; - int num_of_tables = rinfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1; - int totalData = num_of_DPT * num_of_tables; + int64_t num_of_DPT = pThreadInfo->superTblInfo->insertRows; + int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1; + int64_t totalData = num_of_DPT * num_of_tables; bool do_aggreFunc = g_Dbs.do_aggreFunc; int n = do_aggreFunc ? (sizeof(aggreFunc) / sizeof(aggreFunc[0])) : 2; if (!do_aggreFunc) { printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n"); } - printf("%d records:\n", totalData); - fprintf(fp, "Querying On %d records:\n", totalData); + printf("%"PRId64" records:\n", totalData); + fprintf(fp, "Querying On %"PRId64" records:\n", totalData); for (int j = 0; j < n; j++) { char condition[COND_BUF_LEN] = "\0"; char tempS[64] = "\0"; - int m = 10 < num_of_tables ? 10 : num_of_tables; + int64_t m = 10 < num_of_tables ? 10 : num_of_tables; - for (int i = 1; i <= m; i++) { + for (int64_t i = 1; i <= m; i++) { if (i == 1) { - sprintf(tempS, "t1 = %d", i); + sprintf(tempS, "t1 = %"PRId64"", i); } else { - sprintf(tempS, " or t1 = %d ", i); + sprintf(tempS, " or t1 = %"PRId64" ", i); } strncat(condition, tempS, COND_BUF_LEN - 1); @@ -6000,6 +6724,13 @@ static void *readMetric(void *sarg) { return NULL; } +static void prompt() +{ + if (!g_args.answer_yes) { + printf(" Press enter key to continue or Ctrl-C to stop\n\n"); + (void)getchar(); + } +} static int insertTestProcess() { @@ -6020,10 +6751,7 @@ static int insertTestProcess() { if (g_fpOfInsertResult) printfInsertMetaToFile(g_fpOfInsertResult); - if (!g_args.answer_yes) { - printf("Press enter key to continue\n\n"); - (void)getchar(); - } + prompt(); init_rand_data(); @@ -6046,22 +6774,21 @@ static int insertTestProcess() { end = taosGetTimestampMs(); if (g_totalChildTables > 0) { - fprintf(stderr, "Spent %.4f seconds to create %d tables with %d thread(s)\n\n", + fprintf(stderr, "Spent %.4f seconds to create %"PRId64" tables with %d thread(s)\n\n", (end - start)/1000.0, g_totalChildTables, g_Dbs.threadCountByCreateTbl); if (g_fpOfInsertResult) { fprintf(g_fpOfInsertResult, - "Spent %.4f seconds to create %d tables with %d thread(s)\n\n", + "Spent %.4f seconds to create %"PRId64" tables with %d thread(s)\n\n", (end - start)/1000.0, g_totalChildTables, g_Dbs.threadCountByCreateTbl); } } - taosMsleep(1000); // create sub threads for inserting data //start = taosGetTimestampMs(); for (int i = 0; i < g_Dbs.dbCount; i++) { if (g_Dbs.use_metric) { if (g_Dbs.db[i].superTblCount > 0) { - for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { + for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) { SSuperTable* superTblInfo = &g_Dbs.db[i].superTbls[j]; @@ -6134,23 +6861,22 @@ static void *specifiedTableQuery(void *sarg) { uint64_t lastPrintTime = taosGetTimestampMs(); uint64_t startTs = taosGetTimestampMs(); + if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') { + sprintf(pThreadInfo->filePath, "%s-%d", + g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq], + pThreadInfo->threadID); + } + while(queryTimes --) { if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) < (int64_t)g_queryInfo.specifiedQueryInfo.queryInterval) { taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval - (et - st)); // ms } - char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; - if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != 0) { - sprintf(tmpFile, "%s-%d", - g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq], - pThreadInfo->threadID); - } - st = taosGetTimestampMs(); selectAndGetResult(pThreadInfo, - g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq], tmpFile); + g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq]); et = taosGetTimestampMs(); printf("=thread[%"PRId64"] use %s complete one sql, Spent %10.3f s\n", @@ -6236,13 +6962,12 @@ static void *superTableQuery(void *sarg) { for (int j = 0; j < g_queryInfo.superQueryInfo.sqlCount; j++) { memset(sqlstr,0,sizeof(sqlstr)); replaceChildTblName(g_queryInfo.superQueryInfo.sql[j], sqlstr, i); - char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; - if (g_queryInfo.superQueryInfo.result[j][0] != 0) { - sprintf(tmpFile, "%s-%d", + if (g_queryInfo.superQueryInfo.result[j][0] != '\0') { + sprintf(pThreadInfo->filePath, "%s-%d", g_queryInfo.superQueryInfo.result[j], pThreadInfo->threadID); } - selectAndGetResult(pThreadInfo, sqlstr, tmpFile); + selectAndGetResult(pThreadInfo, sqlstr); totalQueried++; g_queryInfo.superQueryInfo.totalQueried ++; @@ -6295,12 +7020,11 @@ static int queryTestProcess() { &g_queryInfo.superQueryInfo.childTblCount); } - if (!g_args.answer_yes) { - printf("Press enter key to continue\n\n"); - (void)getchar(); - } + prompt(); - printfQuerySystemInfo(taos); + if (g_args.debug_print || g_args.verbose_print) { + printfQuerySystemInfo(taos); + } if (0 == strncasecmp(g_queryInfo.queryMode, "rest", strlen("rest"))) { if (convertHostToServAddr( @@ -6312,7 +7036,7 @@ static int queryTestProcess() { threadInfo *infos = NULL; //==== create sub threads for query from specify table int nConcurrent = g_queryInfo.specifiedQueryInfo.concurrent; - int nSqlCount = g_queryInfo.specifiedQueryInfo.sqlCount; + uint64_t nSqlCount = g_queryInfo.specifiedQueryInfo.sqlCount; uint64_t startTs = taosGetTimestampMs(); @@ -6326,32 +7050,32 @@ static int queryTestProcess() { ERROR_EXIT("memory allocation failed for create threads\n"); } - for (int i = 0; i < nConcurrent; i++) { - for (int j = 0; j < nSqlCount; j++) { - threadInfo *t_info = infos + i * nSqlCount + j; - t_info->threadID = i * nSqlCount + j; - t_info->querySeq = j; + for (uint64_t i = 0; i < nSqlCount; i++) { + for (int j = 0; j < nConcurrent; j++) { + uint64_t seq = i * nConcurrent + j; + threadInfo *pThreadInfo = infos + seq; + pThreadInfo->threadID = seq; + pThreadInfo->querySeq = i; - if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) { + if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) { - char sqlStr[MAX_TB_NAME_SIZE*2]; - sprintf(sqlStr, "use %s", g_queryInfo.dbName); - verbosePrint("%s() %d sqlStr: %s\n", __func__, __LINE__, sqlStr); - if (0 != queryDbExec(taos, sqlStr, NO_INSERT_TYPE, false)) { - taos_close(taos); - free(infos); - free(pids); - errorPrint( "use database %s failed!\n\n", - g_queryInfo.dbName); - return -1; - } - } + char sqlStr[MAX_TB_NAME_SIZE*2]; + sprintf(sqlStr, "use %s", g_queryInfo.dbName); + if (0 != queryDbExec(taos, sqlStr, NO_INSERT_TYPE, false)) { + taos_close(taos); + free(infos); + free(pids); + errorPrint( "use database %s failed!\n\n", + g_queryInfo.dbName); + return -1; + } + } - t_info->taos = NULL;// TODO: workaround to use separate taos connection; + pThreadInfo->taos = NULL;// TODO: workaround to use separate taos connection; - pthread_create(pids + i * nSqlCount + j, NULL, specifiedTableQuery, - t_info); - } + pthread_create(pids + seq, NULL, specifiedTableQuery, + pThreadInfo); + } } } else { g_queryInfo.specifiedQueryInfo.concurrent = 0; @@ -6374,31 +7098,31 @@ static int queryTestProcess() { ERROR_EXIT("memory allocation failed for create threads\n"); } - uint64_t ntables = g_queryInfo.superQueryInfo.childTblCount; + int64_t ntables = g_queryInfo.superQueryInfo.childTblCount; int threads = g_queryInfo.superQueryInfo.threadCnt; - uint64_t a = ntables / threads; + int64_t a = ntables / threads; if (a < 1) { threads = ntables; a = 1; } - uint64_t b = 0; + int64_t b = 0; if (threads != 0) { b = ntables % threads; } - uint64_t startFrom = 0; + uint64_t tableFrom = 0; for (int i = 0; i < threads; i++) { - threadInfo *t_info = infosOfSub + i; - t_info->threadID = i; + threadInfo *pThreadInfo = infosOfSub + i; + pThreadInfo->threadID = i; - t_info->start_table_from = startFrom; - t_info->ntables = iend_table_to = i < b ? startFrom + a : startFrom + a - 1; - startFrom = t_info->end_table_to + 1; - t_info->taos = NULL; // TODO: workaround to use separate taos connection; - pthread_create(pidsOfSub + i, NULL, superTableQuery, t_info); + pThreadInfo->start_table_from = tableFrom; + pThreadInfo->ntables = iend_table_to = i < b ? tableFrom + a : tableFrom + a - 1; + tableFrom = pThreadInfo->end_table_to + 1; + pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection; + pthread_create(pidsOfSub + i, NULL, superTableQuery, pThreadInfo); } g_queryInfo.superQueryInfo.threadCnt = threads; @@ -6436,30 +7160,58 @@ static int queryTestProcess() { return 0; } -static void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) { +static void stable_sub_callback( + TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) { + if (res == NULL || taos_errno(res) != 0) { + errorPrint("%s() LN%d, failed to subscribe result, code:%d, reason:%s\n", + __func__, __LINE__, code, taos_errstr(res)); + return; + } + + if (param) + fetchResult(res, (threadInfo *)param); + // tao_unscribe() will free result. +} + +static void specified_sub_callback( + TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) { if (res == NULL || taos_errno(res) != 0) { errorPrint("%s() LN%d, failed to subscribe result, code:%d, reason:%s\n", __func__, __LINE__, code, taos_errstr(res)); return; } - appendResultToFile(res, (char*)param); + if (param) + fetchResult(res, (threadInfo *)param); // tao_unscribe() will free result. } static TAOS_SUB* subscribeImpl( - TAOS *taos, char *sql, char* topic, char* resultFileName) { + QUERY_CLASS class, + threadInfo *pThreadInfo, + char *sql, char* topic, bool restart, uint64_t interval) +{ TAOS_SUB* tsub = NULL; - if (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode) { - tsub = taos_subscribe(taos, - g_queryInfo.specifiedQueryInfo.subscribeRestart, - topic, sql, subscribe_callback, (void*)resultFileName, + if ((SPECIFIED_CLASS == class) + && (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode)) { + tsub = taos_subscribe( + pThreadInfo->taos, + restart, + topic, sql, specified_sub_callback, (void*)pThreadInfo, g_queryInfo.specifiedQueryInfo.subscribeInterval); + } else if ((STABLE_CLASS == class) + && (ASYNC_MODE == g_queryInfo.superQueryInfo.asyncMode)) { + tsub = taos_subscribe( + pThreadInfo->taos, + restart, + topic, sql, stable_sub_callback, (void*)pThreadInfo, + g_queryInfo.superQueryInfo.subscribeInterval); } else { - tsub = taos_subscribe(taos, - g_queryInfo.specifiedQueryInfo.subscribeRestart, - topic, sql, NULL, NULL, 0); + tsub = taos_subscribe( + pThreadInfo->taos, + restart, + topic, sql, NULL, NULL, interval); } if (tsub == NULL) { @@ -6474,23 +7226,25 @@ static void *superSubscribe(void *sarg) { threadInfo *pThreadInfo = (threadInfo *)sarg; char subSqlstr[MAX_QUERY_SQL_LENGTH]; TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT] = {0}; + uint64_t tsubSeq; - if (g_queryInfo.superQueryInfo.sqlCount == 0) - return NULL; + if (pThreadInfo->ntables > MAX_QUERY_SQL_COUNT) { + errorPrint("The table number(%"PRId64") of the thread is more than max query sql count: %d\n", + pThreadInfo->ntables, + MAX_QUERY_SQL_COUNT); + exit(-1); + } if (pThreadInfo->taos == NULL) { - TAOS * taos = NULL; - taos = taos_connect(g_queryInfo.host, + pThreadInfo->taos = taos_connect(g_queryInfo.host, g_queryInfo.user, g_queryInfo.password, g_queryInfo.dbName, g_queryInfo.port); - if (taos == NULL) { + if (pThreadInfo->taos == NULL) { errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", pThreadInfo->threadID, taos_errstr(NULL)); return NULL; - } else { - pThreadInfo->taos = taos; } } @@ -6503,59 +7257,111 @@ static void *superSubscribe(void *sarg) { return NULL; } - //int64_t st = 0; - //int64_t et = 0; - do { - //if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) < g_queryInfo.specifiedQueryInfo.queryInterval) { - // taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval- (et - st)); // ms - // //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to); - //} + char topic[32] = {0}; + for (uint64_t i = pThreadInfo->start_table_from; + i <= pThreadInfo->end_table_to; i++) { - //st = taosGetTimestampMs(); - char topic[32] = {0}; - for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { - sprintf(topic, "taosdemo-subscribe-%d", i); - memset(subSqlstr,0,sizeof(subSqlstr)); - replaceChildTblName(g_queryInfo.superQueryInfo.sql[i], subSqlstr, i); - char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; - if (g_queryInfo.superQueryInfo.result[i][0] != 0) { - sprintf(tmpFile, "%s-%d", - g_queryInfo.superQueryInfo.result[i], pThreadInfo->threadID); - } - tsub[i] = subscribeImpl(pThreadInfo->taos, subSqlstr, topic, tmpFile); - if (NULL == tsub[i]) { + tsubSeq = i - pThreadInfo->start_table_from; + verbosePrint("%s() LN%d, [%d], start=%"PRId64" end=%"PRId64" i=%"PRIu64"\n", + __func__, __LINE__, + pThreadInfo->threadID, + pThreadInfo->start_table_from, + pThreadInfo->end_table_to, i); + sprintf(topic, "taosdemo-subscribe-%"PRIu64"-%"PRIu64"", + i, pThreadInfo->querySeq); + memset(subSqlstr, 0, sizeof(subSqlstr)); + replaceChildTblName( + g_queryInfo.superQueryInfo.sql[pThreadInfo->querySeq], + subSqlstr, i); + if (g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq][0] != 0) { + sprintf(pThreadInfo->filePath, "%s-%d", + g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq], + pThreadInfo->threadID); + } + + debugPrint("%s() LN%d, [%d] subSqlstr: %s\n", + __func__, __LINE__, pThreadInfo->threadID, subSqlstr); + tsub[tsubSeq] = subscribeImpl( + STABLE_CLASS, + pThreadInfo, subSqlstr, topic, + g_queryInfo.superQueryInfo.subscribeRestart, + g_queryInfo.superQueryInfo.subscribeInterval); + if (NULL == tsub[tsubSeq]) { taos_close(pThreadInfo->taos); return NULL; } - } - //et = taosGetTimestampMs(); - //printf("========thread[%"PRIu64"] complete all sqls to super table once queries duration:%.4fs\n", taosGetSelfPthreadId(), (double)(et - st)/1000.0); - } while(0); + } // start loop to consume result + int consumed[MAX_QUERY_SQL_COUNT]; + for (int i = 0; i < MAX_QUERY_SQL_COUNT; i++) { + consumed[i] = 0; + } TAOS_RES* res = NULL; - while(1) { - for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { + + uint64_t st = 0, et = 0; + + while ((g_queryInfo.superQueryInfo.endAfterConsume == -1) + || (g_queryInfo.superQueryInfo.endAfterConsume < + consumed[pThreadInfo->end_table_to - pThreadInfo->start_table_from])) { + + for (uint64_t i = pThreadInfo->start_table_from; + i <= pThreadInfo->end_table_to; i++) { + tsubSeq = i - pThreadInfo->start_table_from; if (ASYNC_MODE == g_queryInfo.superQueryInfo.asyncMode) { - continue; + continue; } - res = taos_consume(tsub[i]); + st = taosGetTimestampMs(); + performancePrint("st: %"PRIu64" et: %"PRIu64" st-et: %"PRIu64"\n", st, et, (st - et)); + res = taos_consume(tsub[tsubSeq]); + et = taosGetTimestampMs(); + performancePrint("st: %"PRIu64" et: %"PRIu64" delta: %"PRIu64"\n", st, et, (et - st)); + if (res) { - char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; - if (g_queryInfo.superQueryInfo.result[i][0] != 0) { - sprintf(tmpFile, "%s-%d", - g_queryInfo.superQueryInfo.result[i], - pThreadInfo->threadID); - } - appendResultToFile(res, tmpFile); + if (g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq][0] != 0) { + sprintf(pThreadInfo->filePath, "%s-%d", + g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq], + pThreadInfo->threadID); + fetchResult(res, pThreadInfo); + } + if (g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq][0] != 0) { + sprintf(pThreadInfo->filePath, "%s-%d", + g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq], + pThreadInfo->threadID); + fetchResult(res, pThreadInfo); + } + consumed[tsubSeq] ++; + + if ((g_queryInfo.superQueryInfo.resubAfterConsume != -1) + && (consumed[tsubSeq] >= + g_queryInfo.superQueryInfo.resubAfterConsume)) { + printf("keepProgress:%d, resub super table query: %"PRIu64"\n", + g_queryInfo.superQueryInfo.subscribeKeepProgress, + pThreadInfo->querySeq); + taos_unsubscribe(tsub[tsubSeq], + g_queryInfo.superQueryInfo.subscribeKeepProgress); + consumed[tsubSeq]= 0; + tsub[tsubSeq] = subscribeImpl( + STABLE_CLASS, + pThreadInfo, subSqlstr, topic, + g_queryInfo.superQueryInfo.subscribeRestart, + g_queryInfo.superQueryInfo.subscribeInterval + ); + if (NULL == tsub[tsubSeq]) { + taos_close(pThreadInfo->taos); + return NULL; + } + } } } } taos_free_result(res); - for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { - taos_unsubscribe(tsub[i], g_queryInfo.superQueryInfo.subscribeKeepProgress); + for (uint64_t i = pThreadInfo->start_table_from; + i <= pThreadInfo->end_table_to; i++) { + tsubSeq = i - pThreadInfo->start_table_from; + taos_unsubscribe(tsub[tsubSeq], 0); } taos_close(pThreadInfo->taos); @@ -6564,90 +7370,101 @@ static void *superSubscribe(void *sarg) { static void *specifiedSubscribe(void *sarg) { threadInfo *pThreadInfo = (threadInfo *)sarg; - TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT] = {0}; - - if (g_queryInfo.specifiedQueryInfo.sqlCount == 0) - return NULL; +// TAOS_SUB* tsub = NULL; if (pThreadInfo->taos == NULL) { - TAOS * taos = NULL; - taos = taos_connect(g_queryInfo.host, + pThreadInfo->taos = taos_connect(g_queryInfo.host, g_queryInfo.user, g_queryInfo.password, g_queryInfo.dbName, g_queryInfo.port); - if (taos == NULL) { + if (pThreadInfo->taos == NULL) { errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", pThreadInfo->threadID, taos_errstr(NULL)); return NULL; - } else { - pThreadInfo->taos = taos; } } char sqlStr[MAX_TB_NAME_SIZE*2]; sprintf(sqlStr, "use %s", g_queryInfo.dbName); - debugPrint("%s() %d sqlStr: %s\n", __func__, __LINE__, sqlStr); if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) { taos_close(pThreadInfo->taos); return NULL; } - //int64_t st = 0; - //int64_t et = 0; - do { - //if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) < g_queryInfo.specifiedQueryInfo.queryInterval) { - // taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval- (et - st)); // ms - // //printf("========sleep duration:%"PRIu64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to); - //} - - //st = taosGetTimestampMs(); - char topic[32] = {0}; - for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { - sprintf(topic, "taosdemo-subscribe-%d", i); - char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; - if (g_queryInfo.specifiedQueryInfo.result[i][0] != 0) { - sprintf(tmpFile, "%s-%d", - g_queryInfo.specifiedQueryInfo.result[i], pThreadInfo->threadID); - } - tsub[i] = subscribeImpl(pThreadInfo->taos, - g_queryInfo.specifiedQueryInfo.sql[i], topic, tmpFile); - if (NULL == tsub[i]) { - taos_close(pThreadInfo->taos); - return NULL; - } - } - //et = taosGetTimestampMs(); - //printf("========thread[%"PRIu64"] complete all sqls to super table once queries duration:%.4fs\n", taosGetSelfPthreadId(), (double)(et - st)/1000.0); - } while(0); + sprintf(g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID], + "taosdemo-subscribe-%"PRIu64"-%d", + pThreadInfo->querySeq, + pThreadInfo->threadID); + if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') { + sprintf(pThreadInfo->filePath, "%s-%d", + g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq], + pThreadInfo->threadID); + } + g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] = subscribeImpl( + SPECIFIED_CLASS, pThreadInfo, + g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq], + g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID], + g_queryInfo.specifiedQueryInfo.subscribeRestart, + g_queryInfo.specifiedQueryInfo.subscribeInterval); + if (NULL == g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]) { + taos_close(pThreadInfo->taos); + return NULL; + } // start loop to consume result - TAOS_RES* res = NULL; - while(1) { - for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { + + g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0; + while((g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq] == -1) + || (g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] < + g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq])) { + if (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode) { continue; } - res = taos_consume(tsub[i]); - if (res) { - char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; - if (g_queryInfo.specifiedQueryInfo.result[i][0] != 0) { - sprintf(tmpFile, "%s-%d", - g_queryInfo.specifiedQueryInfo.result[i], pThreadInfo->threadID); - } - appendResultToFile(res, tmpFile); - } - } - } - taos_free_result(res); + g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID] = taos_consume( + g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]); + if (g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID]) { + if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] + != 0) { + sprintf(pThreadInfo->filePath, "%s-%d", + g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq], + pThreadInfo->threadID); + fetchResult( + g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID], + pThreadInfo); + } - for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { - taos_unsubscribe(tsub[i], - g_queryInfo.specifiedQueryInfo.subscribeKeepProgress); + g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] ++; + if ((g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq] != -1) + && (g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] >= + g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq])) { + printf("keepProgress:%d, resub specified query: %"PRIu64"\n", + g_queryInfo.specifiedQueryInfo.subscribeKeepProgress, + pThreadInfo->querySeq); + g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0; + taos_unsubscribe(g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID], + g_queryInfo.specifiedQueryInfo.subscribeKeepProgress); + g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] = + subscribeImpl( + SPECIFIED_CLASS, + pThreadInfo, + g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq], + g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID], + g_queryInfo.specifiedQueryInfo.subscribeRestart, + g_queryInfo.specifiedQueryInfo.subscribeInterval); + if (NULL == g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]) { + taos_close(pThreadInfo->taos); + return NULL; + } + } + } } - + taos_free_result(g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID]); + taos_unsubscribe(g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->querySeq], 0); taos_close(pThreadInfo->taos); + return NULL; } @@ -6656,10 +7473,7 @@ static int subscribeTestProcess() { printfQueryMeta(); resetAfterAnsiEscape(); - if (!g_args.answer_yes) { - printf("Press enter key to continue\n\n"); - (void) getchar(); - } + prompt(); TAOS * taos = NULL; taos = taos_connect(g_queryInfo.host, @@ -6685,89 +7499,126 @@ static int subscribeTestProcess() { pthread_t *pids = NULL; threadInfo *infos = NULL; - //==== create sub threads for query from super table - if ((g_queryInfo.specifiedQueryInfo.sqlCount <= 0) || - (g_queryInfo.specifiedQueryInfo.concurrent <= 0)) { - errorPrint("%s() LN%d, query sqlCount %"PRIu64" or concurrent %"PRIu64" is not correct.\n", + + pthread_t *pidsOfStable = NULL; + threadInfo *infosOfStable = NULL; + + //==== create threads for query for specified table + if (g_queryInfo.specifiedQueryInfo.sqlCount <= 0) { + debugPrint("%s() LN%d, sepcified query sqlCount %d.\n", __func__, __LINE__, - g_queryInfo.specifiedQueryInfo.sqlCount, - g_queryInfo.specifiedQueryInfo.concurrent); - exit(-1); - } + g_queryInfo.specifiedQueryInfo.sqlCount); + } else { + if (g_queryInfo.specifiedQueryInfo.concurrent <= 0) { + errorPrint("%s() LN%d, sepcified query sqlCount %d.\n", + __func__, __LINE__, + g_queryInfo.specifiedQueryInfo.sqlCount); + exit(-1); + } - pids = malloc(g_queryInfo.specifiedQueryInfo.concurrent * sizeof(pthread_t)); - infos = malloc(g_queryInfo.specifiedQueryInfo.concurrent * sizeof(threadInfo)); - if ((NULL == pids) || (NULL == infos)) { - errorPrint("%s() LN%d, malloc failed for create threads\n", __func__, __LINE__); - exit(-1); - } + pids = malloc( + g_queryInfo.specifiedQueryInfo.sqlCount * + g_queryInfo.specifiedQueryInfo.concurrent * + sizeof(pthread_t)); + infos = malloc( + g_queryInfo.specifiedQueryInfo.sqlCount * + g_queryInfo.specifiedQueryInfo.concurrent * + sizeof(threadInfo)); + if ((NULL == pids) || (NULL == infos)) { + errorPrint("%s() LN%d, malloc failed for create threads\n", __func__, __LINE__); + exit(-1); + } - for (int i = 0; i < g_queryInfo.specifiedQueryInfo.concurrent; i++) { - threadInfo *t_info = infos + i; - t_info->threadID = i; - t_info->taos = NULL; // TODO: workaround to use separate taos connection; - pthread_create(pids + i, NULL, specifiedSubscribe, t_info); + for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { + for (int j = 0; j < g_queryInfo.specifiedQueryInfo.concurrent; j++) { + uint64_t seq = i * g_queryInfo.specifiedQueryInfo.concurrent + j; + threadInfo *pThreadInfo = infos + seq; + pThreadInfo->threadID = seq; + pThreadInfo->querySeq = i; + pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection; + pthread_create(pids + seq, NULL, specifiedSubscribe, pThreadInfo); + } + } } - //==== create sub threads for query from sub table - pthread_t *pidsOfSub = NULL; - threadInfo *infosOfSub = NULL; - if ((g_queryInfo.superQueryInfo.sqlCount > 0) + //==== create threads for super table query + if (g_queryInfo.superQueryInfo.sqlCount <= 0) { + debugPrint("%s() LN%d, super table query sqlCount %d.\n", + __func__, __LINE__, + g_queryInfo.superQueryInfo.sqlCount); + } else { + if ((g_queryInfo.superQueryInfo.sqlCount > 0) && (g_queryInfo.superQueryInfo.threadCnt > 0)) { - pidsOfSub = malloc(g_queryInfo.superQueryInfo.threadCnt * + pidsOfStable = malloc( + g_queryInfo.superQueryInfo.sqlCount * + g_queryInfo.superQueryInfo.threadCnt * sizeof(pthread_t)); - infosOfSub = malloc(g_queryInfo.superQueryInfo.threadCnt * + infosOfStable = malloc( + g_queryInfo.superQueryInfo.sqlCount * + g_queryInfo.superQueryInfo.threadCnt * sizeof(threadInfo)); - if ((NULL == pidsOfSub) || (NULL == infosOfSub)) { - errorPrint("%s() LN%d, malloc failed for create threads\n", + if ((NULL == pidsOfStable) || (NULL == infosOfStable)) { + errorPrint("%s() LN%d, malloc failed for create threads\n", __func__, __LINE__); - // taos_close(taos); - exit(-1); - } - - uint64_t ntables = g_queryInfo.superQueryInfo.childTblCount; - int threads = g_queryInfo.superQueryInfo.threadCnt; + // taos_close(taos); + exit(-1); + } - uint64_t a = ntables / threads; - if (a < 1) { - threads = ntables; - a = 1; - } + int64_t ntables = g_queryInfo.superQueryInfo.childTblCount; + int threads = g_queryInfo.superQueryInfo.threadCnt; - uint64_t b = 0; - if (threads != 0) { - b = ntables % threads; - } + int64_t a = ntables / threads; + if (a < 1) { + threads = ntables; + a = 1; + } - uint64_t startFrom = 0; - for (int i = 0; i < threads; i++) { - threadInfo *t_info = infosOfSub + i; - t_info->threadID = i; + int64_t b = 0; + if (threads != 0) { + b = ntables % threads; + } - t_info->start_table_from = startFrom; - t_info->ntables = iend_table_to = i < b ? startFrom + a : startFrom + a - 1; - startFrom = t_info->end_table_to + 1; - t_info->taos = NULL; // TODO: workaround to use separate taos connection; - pthread_create(pidsOfSub + i, NULL, superSubscribe, t_info); - } + for (uint64_t i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { + uint64_t tableFrom = 0; + for (int j = 0; j < threads; j++) { + uint64_t seq = i * threads + j; + threadInfo *pThreadInfo = infosOfStable + seq; + pThreadInfo->threadID = seq; + pThreadInfo->querySeq = i; + + pThreadInfo->start_table_from = tableFrom; + pThreadInfo->ntables = jend_table_to = jend_table_to + 1; + pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection; + pthread_create(pidsOfStable + seq, + NULL, superSubscribe, pThreadInfo); + } + } - g_queryInfo.superQueryInfo.threadCnt = threads; + g_queryInfo.superQueryInfo.threadCnt = threads; - for (int i = 0; i < g_queryInfo.superQueryInfo.threadCnt; i++) { - pthread_join(pidsOfSub[i], NULL); + for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { + for (int j = 0; j < threads; j++) { + uint64_t seq = i * threads + j; + pthread_join(pidsOfStable[seq], NULL); + } + } } } - for (int i = 0; i < g_queryInfo.specifiedQueryInfo.concurrent; i++) { - pthread_join(pids[i], NULL); + for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { + for (int j = 0; j < g_queryInfo.specifiedQueryInfo.concurrent; j++) { + uint64_t seq = i * g_queryInfo.specifiedQueryInfo.concurrent + j; + pthread_join(pids[seq], NULL); + } } tmfree((char*)pids); tmfree((char*)infos); - tmfree((char*)pidsOfSub); - tmfree((char*)infosOfSub); + tmfree((char*)pidsOfStable); + tmfree((char*)infosOfStable); // taos_close(taos); return 0; } @@ -6818,7 +7669,7 @@ static void setParaFromArg(){ g_Dbs.threadCountByCreateTbl = g_args.num_of_threads; g_Dbs.dbCount = 1; - g_Dbs.db[0].drop = 1; + g_Dbs.db[0].drop = true; tstrncpy(g_Dbs.db[0].dbName, g_args.database, MAX_DB_NAME_SIZE); g_Dbs.db[0].dbCfg.replica = g_args.replica; @@ -6857,7 +7708,7 @@ static void setParaFromArg(){ tstrncpy(g_Dbs.db[0].superTbls[0].childTblPrefix, g_args.tb_prefix, MAX_TB_NAME_SIZE); tstrncpy(g_Dbs.db[0].superTbls[0].dataSource, "rand", MAX_TB_NAME_SIZE); - tstrncpy(g_Dbs.db[0].superTbls[0].insertMode, "taosc", MAX_TB_NAME_SIZE); + g_Dbs.db[0].superTbls[0].iface = g_args.iface; tstrncpy(g_Dbs.db[0].superTbls[0].startTimestamp, "2017-07-14 10:40:00.000", MAX_TB_NAME_SIZE); g_Dbs.db[0].superTbls[0].timeStampStep = DEFAULT_TIMESTAMP_STEP; @@ -6880,17 +7731,21 @@ static void setParaFromArg(){ if (g_Dbs.db[0].superTbls[0].columnCount > g_args.num_of_CPR) { g_Dbs.db[0].superTbls[0].columnCount = g_args.num_of_CPR; } else { - for (int i = g_Dbs.db[0].superTbls[0].columnCount; i < g_args.num_of_CPR; i++) { - tstrncpy(g_Dbs.db[0].superTbls[0].columns[i].dataType, "INT", MAX_TB_NAME_SIZE); + for (int i = g_Dbs.db[0].superTbls[0].columnCount; + i < g_args.num_of_CPR; i++) { + tstrncpy(g_Dbs.db[0].superTbls[0].columns[i].dataType, + "INT", MAX_TB_NAME_SIZE); g_Dbs.db[0].superTbls[0].columns[i].dataLen = 0; g_Dbs.db[0].superTbls[0].columnCount++; } } - tstrncpy(g_Dbs.db[0].superTbls[0].tags[0].dataType, "INT", MAX_TB_NAME_SIZE); + tstrncpy(g_Dbs.db[0].superTbls[0].tags[0].dataType, + "INT", MAX_TB_NAME_SIZE); g_Dbs.db[0].superTbls[0].tags[0].dataLen = 0; - tstrncpy(g_Dbs.db[0].superTbls[0].tags[1].dataType, "BINARY", MAX_TB_NAME_SIZE); + tstrncpy(g_Dbs.db[0].superTbls[0].tags[1].dataType, + "BINARY", MAX_TB_NAME_SIZE); g_Dbs.db[0].superTbls[0].tags[1].dataLen = g_args.len_of_binary; g_Dbs.db[0].superTbls[0].tagCount = 2; } else { @@ -6966,7 +7821,6 @@ static void querySqlFile(TAOS* taos, char* sqlFile) } memcpy(cmd + cmd_len, line, read_len); - verbosePrint("%s() LN%d cmd: %s\n", __func__, __LINE__, cmd); if (0 != queryDbExec(taos, cmd, NO_INSERT_TYPE, false)) { errorPrint("%s() LN%d, queryDbExec %s failed!\n", __func__, __LINE__, cmd); @@ -7016,47 +7870,47 @@ static void queryResult() { // query data pthread_t read_id; - threadInfo *rInfo = malloc(sizeof(threadInfo)); - assert(rInfo); - rInfo->start_time = 1500000000000; // 2017-07-14 10:40:00.000 - rInfo->start_table_from = 0; + threadInfo *pThreadInfo = malloc(sizeof(threadInfo)); + assert(pThreadInfo); + pThreadInfo->start_time = 1500000000000; // 2017-07-14 10:40:00.000 + pThreadInfo->start_table_from = 0; - //rInfo->do_aggreFunc = g_Dbs.do_aggreFunc; + //pThreadInfo->do_aggreFunc = g_Dbs.do_aggreFunc; if (g_args.use_metric) { - rInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount; - rInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1; - rInfo->superTblInfo = &g_Dbs.db[0].superTbls[0]; - tstrncpy(rInfo->tb_prefix, + pThreadInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount; + pThreadInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1; + pThreadInfo->superTblInfo = &g_Dbs.db[0].superTbls[0]; + tstrncpy(pThreadInfo->tb_prefix, g_Dbs.db[0].superTbls[0].childTblPrefix, MAX_TB_NAME_SIZE); } else { - rInfo->ntables = g_args.num_of_tables; - rInfo->end_table_to = g_args.num_of_tables -1; - tstrncpy(rInfo->tb_prefix, g_args.tb_prefix, MAX_TB_NAME_SIZE); + pThreadInfo->ntables = g_args.num_of_tables; + pThreadInfo->end_table_to = g_args.num_of_tables -1; + tstrncpy(pThreadInfo->tb_prefix, g_args.tb_prefix, MAX_TB_NAME_SIZE); } - rInfo->taos = taos_connect( + pThreadInfo->taos = taos_connect( g_Dbs.host, g_Dbs.user, g_Dbs.password, g_Dbs.db[0].dbName, g_Dbs.port); - if (rInfo->taos == NULL) { + if (pThreadInfo->taos == NULL) { errorPrint( "Failed to connect to TDengine, reason:%s\n", taos_errstr(NULL)); - free(rInfo); + free(pThreadInfo); exit(-1); } - tstrncpy(rInfo->fp, g_Dbs.resultFile, MAX_FILE_NAME_LEN); + tstrncpy(pThreadInfo->filePath, g_Dbs.resultFile, MAX_FILE_NAME_LEN); if (!g_Dbs.use_metric) { - pthread_create(&read_id, NULL, readTable, rInfo); + pthread_create(&read_id, NULL, readTable, pThreadInfo); } else { - pthread_create(&read_id, NULL, readMetric, rInfo); + pthread_create(&read_id, NULL, readMetric, pThreadInfo); } pthread_join(read_id, NULL); - taos_close(rInfo->taos); - free(rInfo); + taos_close(pThreadInfo->taos); + free(pThreadInfo); } static void testCmdLine() { @@ -7110,6 +7964,9 @@ int main(int argc, char *argv[]) { } else { testCmdLine(); } + + if (g_dupstr) + free(g_dupstr); } return 0; diff --git a/src/kit/taosdump/taosdump.c b/src/kit/taosdump/taosdump.c index f80ac069a02e3df028f3356e2d13d58c219108e9..15db83297c491c43ded56e23c9c6033600b2d2f7 100644 --- a/src/kit/taosdump/taosdump.c +++ b/src/kit/taosdump/taosdump.c @@ -1017,7 +1017,7 @@ int taosDumpOut(struct arguments *arguments) { sprintf(command, "use %s", dbInfos[0]->name); result = taos_query(taos, command); - int32_t code = taos_errno(result); + code = taos_errno(result); if (code != 0) { fprintf(stderr, "invalid database %s\n", dbInfos[0]->name); goto _exit_failure; diff --git a/src/mnode/inc/mnodeAcct.h b/src/mnode/inc/mnodeAcct.h index 595dcca413f41eafa83e791394fd295e2b2ab525..522070e90990eed599d659d7a0356c0853fe0676 100644 --- a/src/mnode/inc/mnodeAcct.h +++ b/src/mnode/inc/mnodeAcct.h @@ -35,6 +35,8 @@ void mnodeDropDbFromAcct(SAcctObj *pAcct, SDbObj *pDb); void mnodeAddUserToAcct(SAcctObj *pAcct, SUserObj *pUser); void mnodeDropUserFromAcct(SAcctObj *pAcct, SUserObj *pUser); +int32_t mnodeCompactAccts(); + #ifdef __cplusplus } #endif diff --git a/src/mnode/inc/mnodeCluster.h b/src/mnode/inc/mnodeCluster.h index a5af544dc289c085f34c4864e1529ecd7cd7a2bd..db258ae6d6b0b7b89c0c8ed09b6175f940922742 100644 --- a/src/mnode/inc/mnodeCluster.h +++ b/src/mnode/inc/mnodeCluster.h @@ -25,6 +25,8 @@ void mnodeCleanupCluster(); void mnodeUpdateClusterId(); const char* mnodeGetClusterId(); +int32_t mnodeCompactCluster(); + #ifdef __cplusplus } #endif diff --git a/src/mnode/inc/mnodeDb.h b/src/mnode/inc/mnodeDb.h index da0865833db29fc41249791c85a937d82d450124..0fa1a15e2d7531d941f6236517385d1e97922c6e 100644 --- a/src/mnode/inc/mnodeDb.h +++ b/src/mnode/inc/mnodeDb.h @@ -41,6 +41,8 @@ void mnodeDecDbRef(SDbObj *pDb); bool mnodeCheckIsMonitorDB(char *db, char *monitordb); void mnodeDropAllDbs(SAcctObj *pAcct); +int32_t mnodeCompactDbs(); + // util func void mnodeAddSuperTableIntoDb(SDbObj *pDb); void mnodeRemoveSuperTableFromDb(SDbObj *pDb); diff --git a/src/mnode/inc/mnodeDef.h b/src/mnode/inc/mnodeDef.h index ed1de1b87a475cf5a2264abb4b8787c0841d1b63..e052f34a33b2a74dcd858721694225859f1581b8 100644 --- a/src/mnode/inc/mnodeDef.h +++ b/src/mnode/inc/mnodeDef.h @@ -249,7 +249,7 @@ typedef struct SAcctObj { } SAcctObj; typedef struct { - char db[TSDB_DB_NAME_LEN]; + char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; int8_t type; int16_t numOfColumns; int32_t index; diff --git a/src/mnode/inc/mnodeDnode.h b/src/mnode/inc/mnodeDnode.h index fa1995254e9598614cebfef57221b3ff4238b6f1..2db794a173894a325dda5e2444b8a49729c445ac 100644 --- a/src/mnode/inc/mnodeDnode.h +++ b/src/mnode/inc/mnodeDnode.h @@ -77,6 +77,7 @@ void * mnodeGetDnodeByEp(char *ep); void mnodeUpdateDnode(SDnodeObj *pDnode); int32_t mnodeDropDnode(SDnodeObj *pDnode, void *pMsg); +int32_t mnodeCompactDnodes(); extern int32_t tsAccessSquence; #ifdef __cplusplus diff --git a/src/mnode/inc/mnodeMnode.h b/src/mnode/inc/mnodeMnode.h index ffdec02eb6ca3fcb2b6cd230fb93ebb26dea26de..66e9eb1e0e5da6092d6fa8c9840e4f4d5472c07b 100644 --- a/src/mnode/inc/mnodeMnode.h +++ b/src/mnode/inc/mnodeMnode.h @@ -50,6 +50,7 @@ char* mnodeGetMnodeMasterEp(); void mnodeGetMnodeInfos(void *mnodes); void mnodeUpdateMnodeEpSet(SMInfos *pMnodes); +int32_t mnodeCompactMnodes(); #ifdef __cplusplus } #endif diff --git a/src/mnode/inc/mnodeSdb.h b/src/mnode/inc/mnodeSdb.h index e4e4a7a054ff194a578dbaad75b2ae17bfe6f1ad..2ae0c47902677944e000bfdb564bc1d65f9daf99 100644 --- a/src/mnode/inc/mnodeSdb.h +++ b/src/mnode/inc/mnodeSdb.h @@ -92,6 +92,7 @@ void sdbUpdateMnodeRoles(); int32_t sdbGetReplicaNum(); int32_t sdbInsertRow(SSdbRow *pRow); +int32_t sdbInsertCompactRow(SSdbRow *pRow); int32_t sdbDeleteRow(SSdbRow *pRow); int32_t sdbUpdateRow(SSdbRow *pRow); int32_t sdbInsertRowToQueue(SSdbRow *pRow); @@ -106,6 +107,7 @@ int32_t sdbGetId(void *pTable); uint64_t sdbGetVersion(); bool sdbCheckRowDeleted(void *pTable, void *pRow); +int32_t mnodeCompactWal(); #ifdef __cplusplus } #endif diff --git a/src/mnode/inc/mnodeTable.h b/src/mnode/inc/mnodeTable.h index bf04f26a90b6264bc226db0d64d4b808bb1f99b2..c583a60c7a1f26fd798d78ce15eb6fa060a9d151 100644 --- a/src/mnode/inc/mnodeTable.h +++ b/src/mnode/inc/mnodeTable.h @@ -36,6 +36,7 @@ void mnodeCancelGetNextSuperTable(void *pIter); void mnodeDropAllChildTables(SDbObj *pDropDb); void mnodeDropAllSuperTables(SDbObj *pDropDb); void mnodeDropAllChildTablesInVgroups(SVgObj *pVgroup); +int32_t mnodeCompactTables(); #ifdef __cplusplus } diff --git a/src/mnode/inc/mnodeUser.h b/src/mnode/inc/mnodeUser.h index 156bc7aaebefb9accc59aa76979b7086c5cce9ae..b8f08051203e229e5fee17982ab5a47de20c41a9 100644 --- a/src/mnode/inc/mnodeUser.h +++ b/src/mnode/inc/mnodeUser.h @@ -33,6 +33,8 @@ char * mnodeGetUserFromMsg(void *pMnodeMsg); int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg); void mnodeDropAllUsers(SAcctObj *pAcct); +int32_t mnodeCompactUsers(); + #ifdef __cplusplus } #endif diff --git a/src/mnode/inc/mnodeVgroup.h b/src/mnode/inc/mnodeVgroup.h index 7b798c23f8b3414d40e504990bb75812d829102a..73b0e6ae1bb2e05876deb2486db7c5d1cb25e65b 100644 --- a/src/mnode/inc/mnodeVgroup.h +++ b/src/mnode/inc/mnodeVgroup.h @@ -32,6 +32,7 @@ void mnodeDropAllDbVgroups(SDbObj *pDropDb); void mnodeSendDropAllDbVgroupsMsg(SDbObj *pDropDb); void mnodeDropAllDnodeVgroups(SDnodeObj *pDropDnode); //void mnodeUpdateAllDbVgroups(SDbObj *pAlterDb); +int32_t mnodeCompactVgroups(); void * mnodeGetNextVgroup(void *pIter, SVgObj **pVgroup); void mnodeCancelGetNextVgroup(void *pIter); diff --git a/src/mnode/src/mnodeAcct.c b/src/mnode/src/mnodeAcct.c index afe474df6b7d8d4bd1945523a95d839bcd29e247..64cfa28917cf6923230f0b7f70500c921c0d5a84 100644 --- a/src/mnode/src/mnodeAcct.c +++ b/src/mnode/src/mnodeAcct.c @@ -238,6 +238,32 @@ static int32_t mnodeCreateRootAcct() { return sdbInsertRow(&row); } +int32_t mnodeCompactAccts() { + void *pIter = NULL; + SAcctObj *pAcct = NULL; + + mInfo("start to compact accts table..."); + + while (1) { + pIter = mnodeGetNextAcct(pIter, &pAcct); + if (pAcct == NULL) break; + + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsAcctSdb, + .pObj = pAcct, + }; + + mInfo("compact accts %s", pAcct->user); + + sdbInsertCompactRow(&row); + } + + mInfo("end to compact accts table..."); + + return 0; +} + #ifndef _ACCT int32_t acctInit() { return TSDB_CODE_SUCCESS; } diff --git a/src/mnode/src/mnodeCluster.c b/src/mnode/src/mnodeCluster.c index 169d2ebd9dae1bcc34ea24dd3770951f9cbb442b..553e8446ab449cb3eab8bcc3c15bef8715fe978a 100644 --- a/src/mnode/src/mnodeCluster.c +++ b/src/mnode/src/mnodeCluster.c @@ -237,3 +237,27 @@ static int32_t mnodeRetrieveClusters(SShowObj *pShow, char *data, int32_t rows, pShow->numOfReads += numOfRows; return numOfRows; } + +int32_t mnodeCompactCluster() { + SClusterObj *pCluster = NULL; + void *pIter; + + mInfo("start to compact cluster table..."); + + pIter = mnodeGetNextCluster(NULL, &pCluster); + while (pCluster) { + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsClusterSdb, + .pObj = pCluster, + }; + + sdbInsertCompactRow(&row); + + pIter = mnodeGetNextCluster(pIter, &pCluster); + } + + mInfo("end to compact cluster table..."); + + return 0; +} \ No newline at end of file diff --git a/src/mnode/src/mnodeDb.c b/src/mnode/src/mnodeDb.c index 8af20aa862d3b126cfd3332e42423e7b08414b63..5e06faaad92f9e85ea3bfb9864c72d31ab798f2f 100644 --- a/src/mnode/src/mnodeDb.c +++ b/src/mnode/src/mnodeDb.c @@ -389,7 +389,7 @@ static void mnodeSetDefaultDbCfg(SDbCfg *pCfg) { if (pCfg->compression < 0) pCfg->compression = tsCompression; if (pCfg->walLevel < 0) pCfg->walLevel = tsWAL; if (pCfg->replications < 0) pCfg->replications = tsReplications; - if (pCfg->quorum < 0) pCfg->quorum = tsQuorum; + if (pCfg->quorum < 0) pCfg->quorum = MIN(tsQuorum, pCfg->replications); if (pCfg->update < 0) pCfg->update = tsUpdate; if (pCfg->cacheLastRow < 0) pCfg->cacheLastRow = tsCacheLastRow; if (pCfg->dbType < 0) pCfg->dbType = 0; @@ -1271,3 +1271,30 @@ void mnodeDropAllDbs(SAcctObj *pAcct) { mInfo("acct:%s, all dbs:%d is dropped from sdb", pAcct->user, numOfDbs); } + +int32_t mnodeCompactDbs() { + void *pIter = NULL; + SDbObj *pDb = NULL; + + mInfo("start to compact dbs table..."); + + while (1) { + pIter = mnodeGetNextDb(pIter, &pDb); + if (pDb == NULL) break; + + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsDbSdb, + .pObj = pDb, + .rowSize = sizeof(SDbObj), + }; + + mInfo("compact dbs %s", pDb->name); + + sdbInsertCompactRow(&row); + } + + mInfo("end to compact dbs table..."); + + return 0; +} \ No newline at end of file diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c index b513da29f44fce09d40dfe58aea63acc192f2178..51f16e4bc63e8b12ac31c3e1ad9ac605b72c56ca 100644 --- a/src/mnode/src/mnodeDnode.c +++ b/src/mnode/src/mnodeDnode.c @@ -522,13 +522,13 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) { pStatus->lastReboot = htonl(pStatus->lastReboot); pStatus->numOfCores = htons(pStatus->numOfCores); - uint32_t version = htonl(pStatus->version); - if (version != tsVersion) { + uint32_t _version = htonl(pStatus->version); + if (_version != tsVersion) { pDnode = mnodeGetDnodeByEp(pStatus->dnodeEp); if (pDnode != NULL && pDnode->status != TAOS_DN_STATUS_READY) { pDnode->offlineReason = TAOS_DN_OFF_VERSION_NOT_MATCH; } - mError("dnode:%d, status msg version:%d not equal with cluster:%d", pStatus->dnodeId, version, tsVersion); + mError("dnode:%d, status msg version:%d not equal with cluster:%d", pStatus->dnodeId, _version, tsVersion); return TSDB_CODE_MND_INVALID_MSG_VERSION; } @@ -1270,3 +1270,30 @@ char* dnodeRoles[] = { "vnode", "any" }; + +int32_t mnodeCompactDnodes() { + SDnodeObj *pDnode = NULL; + void * pIter = NULL; + + mInfo("start to compact dnodes table..."); + + while (1) { + pIter = mnodeGetNextDnode(pIter, &pDnode); + if (pDnode == NULL) break; + + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsDnodeSdb, + .pObj = pDnode, + .rowSize = sizeof(SDnodeObj), + }; + + mInfo("compact dnode %d", pDnode->dnodeId); + + sdbInsertCompactRow(&row); + } + + mInfo("end to compact dnodes table..."); + + return 0; +} \ No newline at end of file diff --git a/src/mnode/src/mnodeMain.c b/src/mnode/src/mnodeMain.c index 7ef0488c420dd470c3afc5d7ca8ac7a518ccdc73..8ce798c8ec2271ecb236d49278f07f974e4bb043 100644 --- a/src/mnode/src/mnodeMain.c +++ b/src/mnode/src/mnodeMain.c @@ -57,6 +57,18 @@ static SStep tsMnodeSteps[] = { {"show", mnodeInitShow, mnodeCleanUpShow} }; +static SStep tsMnodeCompactSteps[] = { + {"cluster", mnodeCompactCluster, NULL}, + {"dnodes", mnodeCompactDnodes, NULL}, + {"mnodes", mnodeCompactMnodes, NULL}, + {"accts", mnodeCompactAccts, NULL}, + {"users", mnodeCompactUsers, NULL}, + {"dbs", mnodeCompactDbs, NULL}, + {"vgroups", mnodeCompactVgroups, NULL}, + {"tables", mnodeCompactTables, NULL}, + +}; + static void mnodeInitTimer(); static void mnodeCleanupTimer(); static bool mnodeNeedStart() ; @@ -71,6 +83,11 @@ static int32_t mnodeInitComponents() { return dnodeStepInit(tsMnodeSteps, stepSize); } +int32_t mnodeCompactComponents() { + int32_t stepSize = sizeof(tsMnodeCompactSteps) / sizeof(SStep); + return dnodeStepInit(tsMnodeCompactSteps, stepSize); +} + int32_t mnodeStartSystem() { if (tsMgmtIsRunning) { mInfo("mnode module already started..."); @@ -104,7 +121,7 @@ int32_t mnodeStartSystem() { int32_t mnodeInitSystem() { mnodeInitTimer(); - if (mnodeNeedStart()) { + if (mnodeNeedStart() || tsCompactMnodeWal) { return mnodeStartSystem(); } return 0; diff --git a/src/mnode/src/mnodeMnode.c b/src/mnode/src/mnodeMnode.c index ca6d6400ae62016eab7504e64638dc000fd44e2c..ddc9ea59c41a793707ba76c06f6a89abcf60a5ca 100644 --- a/src/mnode/src/mnodeMnode.c +++ b/src/mnode/src/mnodeMnode.c @@ -566,3 +566,30 @@ static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, vo return numOfRows; } + +int32_t mnodeCompactMnodes() { + void *pIter = NULL; + SMnodeObj *pMnode = NULL; + + mInfo("start to compact mnodes table..."); + + while (1) { + pIter = mnodeGetNextMnode(pIter, &pMnode); + if (pMnode == NULL) break; + + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsMnodeSdb, + .pObj = pMnode, + .rowSize = sizeof(SMnodeObj), + }; + + mInfo("compact mnode %d", pMnode->mnodeId); + + sdbInsertCompactRow(&row); + } + + mInfo("end to compact mnodes table..."); + + return 0; +} \ No newline at end of file diff --git a/src/mnode/src/mnodeProfile.c b/src/mnode/src/mnodeProfile.c index 459d981138f05fde00c11f71e0b75048f2fc360d..cbf713af6514ce305d91e7edc6710ba0d51eeeec 100644 --- a/src/mnode/src/mnodeProfile.c +++ b/src/mnode/src/mnodeProfile.c @@ -123,8 +123,9 @@ SConnObj *mnodeAccquireConn(int32_t connId, char *user, uint32_t ip, uint16_t po if (/* pConn->ip != ip || */ pConn->port != port /* || strcmp(pConn->user, user) != 0 */) { mDebug("connId:%d, incoming conn user:%s ip:%s:%u, not match exist conn user:%s ip:%s:%u", connId, user, taosIpStr(ip), port, pConn->user, taosIpStr(pConn->ip), pConn->port); - taosCacheRelease(tsMnodeConnCache, (void **)&pConn, false); - return NULL; + pConn->port = port; + //taosCacheRelease(tsMnodeConnCache, (void **)&pConn, false); + //return NULL; } // mDebug("connId:%d, is incoming, user:%s ip:%s:%u", connId, pConn->user, taosIpStr(pConn->ip), pConn->port); diff --git a/src/mnode/src/mnodeSdb.c b/src/mnode/src/mnodeSdb.c index 505d3c519c6d659d32eb2dfe3f18f50757a0a0de..ac3e5d86ecfd57b3b06f49b39bcb991ff06423d5 100644 --- a/src/mnode/src/mnodeSdb.c +++ b/src/mnode/src/mnodeSdb.c @@ -20,6 +20,7 @@ #include "tutil.h" #include "tref.h" #include "tbn.h" +#include "tfs.h" #include "tqueue.h" #include "twal.h" #include "tsync.h" @@ -450,6 +451,12 @@ int32_t sdbInit() { } tsSdbMgmt.status = SDB_STATUS_SERVING; + + if (tsCompactMnodeWal) { + mnodeCompactWal(); + exit(EXIT_SUCCESS); + } + return TSDB_CODE_SUCCESS; } @@ -683,7 +690,7 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void * pthread_mutex_unlock(&tsSdbMgmt.mutex); // from app, row is created - if (pRow != NULL) { + if (pRow != NULL && tsCompactMnodeWal != 1) { // forward to peers pRow->processedCount = 0; int32_t syncCode = syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false); @@ -706,19 +713,21 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void * actStr[action], sdbGetKeyStr(pTable, pHead->cont), pHead->version); // even it is WAL/FWD, it shall be called to update version in sync - syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false); + if (tsCompactMnodeWal != 1) { + syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false); + } // from wal or forward msg, row not created, should add into hash if (action == SDB_ACTION_INSERT) { return sdbPerformInsertAction(pHead, pTable); } else if (action == SDB_ACTION_DELETE) { - if (qtype == TAOS_QTYPE_FWD) { + //if (qtype == TAOS_QTYPE_FWD) { // Drop database/stable may take a long time and cause a timeout, so we confirm first then reput it into queue - sdbWriteFwdToQueue(1, hparam, TAOS_QTYPE_QUERY, unused); - return TSDB_CODE_SUCCESS; - } else { + // sdbWriteFwdToQueue(1, hparam, TAOS_QTYPE_QUERY, unused); + // return TSDB_CODE_SUCCESS; + //} else { return sdbPerformDeleteAction(pHead, pTable); - } + //} } else if (action == SDB_ACTION_UPDATE) { return sdbPerformUpdateAction(pHead, pTable); } else { @@ -726,6 +735,12 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void * } } +int32_t sdbInsertCompactRow(SSdbRow *pRow) { + SSdbTable *pTable = pRow->pTable; + if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE; + return sdbWriteRowToQueue(pRow, SDB_ACTION_INSERT); +} + int32_t sdbInsertRow(SSdbRow *pRow) { SSdbTable *pTable = pRow->pTable; if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE; @@ -1138,3 +1153,46 @@ static void *sdbWorkerFp(void *pWorker) { int32_t sdbGetReplicaNum() { return tsSdbMgmt.cfg.replica; } + +int32_t mnodeCompactWal() { + sdbInfo("vgId:1, start compact mnode wal..."); + + // close old wal + walFsync(tsSdbMgmt.wal, true); + walClose(tsSdbMgmt.wal); + + // reset version,then compacted wal log can start from version 1 + tsSdbMgmt.version = 0; + + // change wal to wal_tmp dir + SWalCfg walCfg = {.vgId = 1, .walLevel = TAOS_WAL_FSYNC, .keep = TAOS_WAL_KEEP, .fsyncPeriod = 0}; + char temp[TSDB_FILENAME_LEN] = {0}; + sprintf(temp, "%s/wal", tsMnodeTmpDir); + tsSdbMgmt.wal = walOpen(temp, &walCfg); + walRenew(tsSdbMgmt.wal); + + // compact memory tables info to wal tmp dir + if (mnodeCompactComponents() != 0) { + tfsRmdir(tsMnodeTmpDir); + return -1; + } + + // close wal + walFsync(tsSdbMgmt.wal, true); + walClose(tsSdbMgmt.wal); + + // rename old wal to wal_bak + if (taosRename(tsMnodeDir, tsMnodeBakDir) != 0) { + return -1; + } + + // rename wal_tmp to wal + if (taosRename(tsMnodeTmpDir, tsMnodeDir) != 0) { + return -1; + } + + // del wal_tmp dir + sdbInfo("vgId:1, compact mnode wal success"); + + return 0; +} \ No newline at end of file diff --git a/src/mnode/src/mnodeShow.c b/src/mnode/src/mnodeShow.c index 03772f2724c87c74da2f3ab7128705d90c5bb1ad..5fe22826b7d0a2270300bacc3d1ae8f59d346a54 100644 --- a/src/mnode/src/mnodeShow.c +++ b/src/mnode/src/mnodeShow.c @@ -129,7 +129,7 @@ static int32_t mnodeProcessShowMsg(SMnodeMsg *pMsg) { SShowObj *pShow = calloc(1, showObjSize); pShow->type = pShowMsg->type; pShow->payloadLen = htons(pShowMsg->payloadLen); - tstrncpy(pShow->db, pShowMsg->db, TSDB_DB_NAME_LEN); + tstrncpy(pShow->db, pShowMsg->db, TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN); memcpy(pShow->payload, pShowMsg->payload, pShow->payloadLen); pShow = mnodePutShowObj(pShow); @@ -253,10 +253,6 @@ static int32_t mnodeProcessHeartBeatMsg(SMnodeMsg *pMsg) { int32_t connId = htonl(pHBMsg->connId); SConnObj *pConn = mnodeAccquireConn(connId, connInfo.user, connInfo.clientIp, connInfo.clientPort); - if (pConn == NULL) { - pHBMsg->pid = htonl(pHBMsg->pid); - pConn = mnodeCreateConn(connInfo.user, connInfo.clientIp, connInfo.clientPort, pHBMsg->pid, pHBMsg->appName); - } if (pConn == NULL) { // do not close existing links, otherwise diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c index 2a8e941fcbca384d019fa00bb6a16f68960508f0..5710601e5c057282637bd6c67ac5d7b1e41d7341 100644 --- a/src/mnode/src/mnodeTable.c +++ b/src/mnode/src/mnodeTable.c @@ -966,6 +966,11 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) { pMsg->rpcMsg.ahandle, pDrop->name, pSTable->uid, pSTable->numOfTables, taosHashGetSize(pSTable->vgHash)); return mnodeProcessDropSuperTableMsg(pMsg); } else { + // user specify the "DROP STABLE" sql statement, but it is actually a normal table, return error msg. + if (pDrop->supertable) { + return TSDB_CODE_MND_INVALID_TABLE_TYPE; + } + SCTableObj *pCTable = (SCTableObj *)pMsg->pTable; mInfo("msg:%p, app:%p table:%s, start to drop ctable, vgId:%d tid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle, pDrop->name, pCTable->vgId, pCTable->tid, pCTable->uid); @@ -1189,8 +1194,8 @@ static int32_t mnodeFindSuperTableTagIndex(SSTableObj *pStable, const char *tagN static int32_t mnodeAddSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; - mLInfo("msg:%p, app:%p stable %s, add tag result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, - tstrerror(code)); + mLInfo("msg:%p, app:%p stable %s, add tag result:%s, numOfTags:%d", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, + tstrerror(code), pStable->numOfTags); return code; } @@ -1674,12 +1679,9 @@ static int32_t mnodeSetSchemaFromSuperTable(SSchema *pSchema, SSTableObj *pTable return (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema); } -static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) { +static int32_t mnodeDoGetSuperTableMeta(SMnodeMsg *pMsg, STableMetaMsg* pMeta) { SSTableObj *pTable = (SSTableObj *)pMsg->pTable; - STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)); - if (pMeta == NULL) { - return TSDB_CODE_MND_OUT_OF_MEMORY; - } + pMeta->uid = htobe64(pTable->uid); pMeta->sversion = htons(pTable->sversion); pMeta->tversion = htons(pTable->tversion); @@ -1690,6 +1692,18 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) { pMeta->contLen = sizeof(STableMetaMsg) + mnodeSetSchemaFromSuperTable(pMeta->schema, pTable); tstrncpy(pMeta->tableFname, pTable->info.tableId, sizeof(pMeta->tableFname)); + return TSDB_CODE_SUCCESS; +} + +static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) { + SSTableObj *pTable = (SSTableObj *)pMsg->pTable; + STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)); + if (pMeta == NULL) { + return TSDB_CODE_MND_OUT_OF_MEMORY; + } + + mnodeDoGetSuperTableMeta(pMsg, pMeta); + pMsg->rpcRsp.len = pMeta->contLen; pMeta->contLen = htons(pMeta->contLen); @@ -1700,11 +1714,7 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) { - SSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont; - int32_t numOfTable = htonl(pInfo->numOfTables); - - // reserve space +static int32_t calculateVgroupMsgLength(SSTableVgroupMsg* pInfo, int32_t numOfTable) { int32_t contLen = sizeof(SSTableVgroupRspMsg) + 32 * sizeof(SVgroupMsg) + sizeof(SVgroupsMsg); for (int32_t i = 0; i < numOfTable; ++i) { char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i; @@ -1716,6 +1726,75 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) { mnodeDecTableRef(pTable); } + return contLen; +} + +static char* serializeVgroupInfo(SSTableObj *pTable, char* name, char* msg, SMnodeMsg* pMsgBody, void* handle) { + SName sn = {0}; + tNameFromString(&sn, name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE); + const char* tableName = tNameGetTableName(&sn); + + strncpy(msg, tableName, TSDB_TABLE_NAME_LEN); + msg += TSDB_TABLE_NAME_LEN; + + if (pTable->vgHash == NULL) { + mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsgBody, handle, name); + mnodeDecTableRef(pTable); + + // even this super table has no corresponding table, still return + SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg; + pVgroupMsg->numOfVgroups = 0; + + msg += sizeof(SVgroupsMsg); + } else { + SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg; + mDebug("msg:%p, app:%p stable:%s, hash:%p sizeOfVgList:%d will be returned", pMsgBody, handle, + pTable->info.tableId, pTable->vgHash, taosHashGetSize(pTable->vgHash)); + + int32_t *pVgId = taosHashIterate(pTable->vgHash, NULL); + int32_t vgSize = 0; + while (pVgId) { + SVgObj *pVgroup = mnodeGetVgroup(*pVgId); + pVgId = taosHashIterate(pTable->vgHash, pVgId); + if (pVgroup == NULL) { + continue; + } + + pVgroupMsg->vgroups[vgSize].vgId = htonl(pVgroup->vgId); + pVgroupMsg->vgroups[vgSize].numOfEps = 0; + + for (int32_t vn = 0; vn < pVgroup->numOfVnodes; ++vn) { + SDnodeObj *pDnode = pVgroup->vnodeGid[vn].pDnode; + if (pDnode == NULL) break; + + tstrncpy(pVgroupMsg->vgroups[vgSize].epAddr[vn].fqdn, pDnode->dnodeFqdn, TSDB_FQDN_LEN); + pVgroupMsg->vgroups[vgSize].epAddr[vn].port = htons(pDnode->dnodePort); + + pVgroupMsg->vgroups[vgSize].numOfEps++; + } + + vgSize++; + mnodeDecVgroupRef(pVgroup); + } + + taosHashCancelIterate(pTable->vgHash, pVgId); + mnodeDecTableRef(pTable); + + pVgroupMsg->numOfVgroups = htonl(vgSize); + + // one table is done, try the next table + msg += sizeof(SVgroupsMsg) + vgSize * sizeof(SVgroupMsg); + } + + return msg; +} + +static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) { + SSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont; + int32_t numOfTable = htonl(pInfo->numOfTables); + + // calculate the required space. + int32_t contLen = calculateVgroupMsgLength(pInfo, numOfTable); SSTableVgroupRspMsg *pRsp = rpcMallocCont(contLen); if (pRsp == NULL) { return TSDB_CODE_MND_OUT_OF_MEMORY; @@ -1726,62 +1805,16 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) { for (int32_t i = 0; i < numOfTable; ++i) { char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i; + SSTableObj *pTable = mnodeGetSuperTable(stableName); if (pTable == NULL) { mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, stableName); mnodeDecTableRef(pTable); continue; } - if (pTable->vgHash == NULL) { - mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, - stableName); - mnodeDecTableRef(pTable); - // even this super table has no corresponding table, still return - pRsp->numOfTables++; - - SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg; - pVgroupMsg->numOfVgroups = 0; - - msg += sizeof(SVgroupsMsg); - } else { - SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg; - mDebug("msg:%p, app:%p stable:%s, hash:%p sizeOfVgList:%d will be returned", pMsg, pMsg->rpcMsg.ahandle, - pTable->info.tableId, pTable->vgHash, taosHashGetSize(pTable->vgHash)); - - int32_t *pVgId = taosHashIterate(pTable->vgHash, NULL); - int32_t vgSize = 0; - while (pVgId) { - SVgObj *pVgroup = mnodeGetVgroup(*pVgId); - pVgId = taosHashIterate(pTable->vgHash, pVgId); - if (pVgroup == NULL) continue; - - pVgroupMsg->vgroups[vgSize].vgId = htonl(pVgroup->vgId); - pVgroupMsg->vgroups[vgSize].numOfEps = 0; - - for (int32_t vn = 0; vn < pVgroup->numOfVnodes; ++vn) { - SDnodeObj *pDnode = pVgroup->vnodeGid[vn].pDnode; - if (pDnode == NULL) break; - - tstrncpy(pVgroupMsg->vgroups[vgSize].epAddr[vn].fqdn, pDnode->dnodeFqdn, TSDB_FQDN_LEN); - pVgroupMsg->vgroups[vgSize].epAddr[vn].port = htons(pDnode->dnodePort); - - pVgroupMsg->vgroups[vgSize].numOfEps++; - } - - vgSize++; - mnodeDecVgroupRef(pVgroup); - } - - taosHashCancelIterate(pTable->vgHash, pVgId); - mnodeDecTableRef(pTable); - - pVgroupMsg->numOfVgroups = htonl(vgSize); - - // one table is done, try the next table - msg += sizeof(SVgroupsMsg) + vgSize * sizeof(SVgroupMsg); - pRsp->numOfTables++; - } + msg = serializeVgroupInfo(pTable, stableName, msg, pMsg, pMsg->rpcMsg.ahandle); + pRsp->numOfTables++; } if (pRsp->numOfTables != numOfTable) { @@ -2415,9 +2448,9 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) { pMeta->vgroup.numOfEps++; mnodeDecDnodeRef(pDnode); } - pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId); - mDebug("msg:%p, app:%p table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d sid:%d", pMsg, pMsg->rpcMsg.ahandle, + pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId); + mDebug("msg:%p, app:%p table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d tid:%d", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->uid, pTable->vgId, pTable->tid); return TSDB_CODE_SUCCESS; @@ -2811,56 +2844,137 @@ static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg) { static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) { SMultiTableInfoMsg *pInfo = pMsg->rpcMsg.pCont; - pInfo->numOfTables = htonl(pInfo->numOfTables); - int32_t totalMallocLen = 4 * 1024 * 1024; // first malloc 4 MB, subsequent reallocation as twice - SMultiTableMeta *pMultiMeta = rpcMallocCont(totalMallocLen); + pInfo->numOfTables = htonl(pInfo->numOfTables); + pInfo->numOfVgroups = htonl(pInfo->numOfVgroups); + + int32_t contLen = pMsg->rpcMsg.contLen - sizeof(SMultiTableInfoMsg); + + int32_t num = 0; + int32_t code = TSDB_CODE_SUCCESS; + char* str = strndup(pInfo->tableNames, contLen); + char** nameList = strsplit(str, ",", &num); + SArray* pList = taosArrayInit(4, POINTER_BYTES); + SMultiTableMeta *pMultiMeta = NULL; + + if (num != pInfo->numOfTables + pInfo->numOfVgroups) { + mError("msg:%p, app:%p, failed to get multi-tableMeta, msg inconsistent", pMsg, pMsg->rpcMsg.ahandle); + code = TSDB_CODE_MND_INVALID_TABLE_NAME; + goto _end; + } + + // first malloc 80KB, subsequent reallocation will expand the size as twice of the original size + int32_t totalMallocLen = sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16); + pMultiMeta = rpcMallocCont(totalMallocLen); if (pMultiMeta == NULL) { - return TSDB_CODE_MND_OUT_OF_MEMORY; + code = TSDB_CODE_MND_OUT_OF_MEMORY; + goto _end; } pMultiMeta->contLen = sizeof(SMultiTableMeta); pMultiMeta->numOfTables = 0; - for (int32_t t = 0; t < pInfo->numOfTables; ++t) { - char * tableId = (char *)(pInfo->tableIds + t * TSDB_TABLE_FNAME_LEN); - SCTableObj *pTable = mnodeGetChildTable(tableId); - if (pTable == NULL) continue; + int32_t t = 0; + for (; t < pInfo->numOfTables; ++t) { + char *fullName = nameList[t]; + + pMsg->pTable = mnodeGetTable(fullName); + if (pMsg->pTable == NULL) { + mError("msg:%p, app:%p table:%s, failed to get table meta, table not exist", pMsg, pMsg->rpcMsg.ahandle, fullName); + code = TSDB_CODE_MND_INVALID_TABLE_NAME; + goto _end; + } + + if (pMsg->pDb == NULL) { + pMsg->pDb = mnodeGetDbByTableName(fullName); + } - if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableName(tableId); if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) { - mnodeDecTableRef(pTable); - continue; + mnodeDecTableRef(pMsg->pTable); + code = TSDB_CODE_APP_NOT_READY; + goto _end; } - int availLen = totalMallocLen - pMultiMeta->contLen; - if (availLen <= sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)) { + int remain = totalMallocLen - pMultiMeta->contLen; + if (remain <= sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)) { totalMallocLen *= 2; pMultiMeta = rpcReallocCont(pMultiMeta, totalMallocLen); if (pMultiMeta == NULL) { - mnodeDecTableRef(pTable); - return TSDB_CODE_MND_OUT_OF_MEMORY; - } else { - t--; - mnodeDecTableRef(pTable); - continue; + mnodeDecTableRef(pMsg->pTable); + code = TSDB_CODE_MND_OUT_OF_MEMORY; + goto _end; + } + } + + STableMetaMsg *pMeta = (STableMetaMsg *)((char*) pMultiMeta + pMultiMeta->contLen); + + if (pMsg->pTable->type == TSDB_SUPER_TABLE) { + code = mnodeDoGetSuperTableMeta(pMsg, pMeta); + taosArrayPush(pList, &fullName); // keep the full name for each super table for retrieve vgroup list + } else { + code = mnodeDoGetChildTableMeta(pMsg, pMeta); + if (pMsg->pVgroup != NULL) { + mnodeDecVgroupRef(pMsg->pVgroup); + pMsg->pVgroup = NULL; } } - STableMetaMsg *pMeta = (STableMetaMsg *)(pMultiMeta->metas + pMultiMeta->contLen); - int32_t code = mnodeDoGetChildTableMeta(pMsg, pMeta); + mnodeDecTableRef(pMsg->pTable); + pMsg->pTable = NULL; + if (code == TSDB_CODE_SUCCESS) { - pMultiMeta->numOfTables ++; + pMultiMeta->numOfTables++; pMultiMeta->contLen += pMeta->contLen; + } else { + // ignore error and continue. + // Otherwise the client may found that the responding message is inconsistent. +// goto _end; } + } - mnodeDecTableRef(pTable); + char* msg = (char*) pMultiMeta + pMultiMeta->contLen; + + // add the additional super table names that needs the vgroup info + for(;t < num; ++t) { + taosArrayPush(pList, &nameList[t]); + } + + // add the pVgroupList into the pList + int32_t numOfVgroupList = (int32_t) taosArrayGetSize(pList); + pMultiMeta->numOfVgroup = htonl(numOfVgroupList); + + for(int32_t i = 0; i < numOfVgroupList; ++i) { + char* name = taosArrayGetP(pList, i); + + SSTableObj *pTable = mnodeGetSuperTable(name); + if (pTable == NULL) { + mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, name); + code = TSDB_CODE_MND_INVALID_TABLE_NAME; + goto _end; + } + + msg = serializeVgroupInfo(pTable, name, msg, pMsg, pMsg->rpcMsg.ahandle); } + pMultiMeta->contLen = (int32_t) (msg - (char*) pMultiMeta); + + pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables); pMsg->rpcRsp.rsp = pMultiMeta; pMsg->rpcRsp.len = pMultiMeta->contLen; + code = TSDB_CODE_SUCCESS; - return TSDB_CODE_SUCCESS; + _end: + tfree(str); + tfree(nameList); + taosArrayDestroy(pList); + pMsg->pTable = NULL; + pMsg->pVgroup = NULL; + + if (code != TSDB_CODE_SUCCESS) { + rpcFreeCont(pMultiMeta); + } + + return code; } static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) { @@ -3242,3 +3356,65 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro return numOfRows; } + +static int32_t mnodeCompactSuperTables() { + void *pIter = NULL; + SSTableObj *pTable = NULL; + + mInfo("start to compact super table..."); + + while (1) { + pIter = mnodeGetNextSuperTable(pIter, &pTable); + if (pTable == NULL) break; + + int32_t schemaSize = (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema); + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsSuperTableSdb, + .pObj = pTable, + .rowSize = sizeof(SSTableObj) + schemaSize, + }; + + //mInfo("compact super %" PRIu64, pTable->uid); + + sdbInsertCompactRow(&row); + } + + mInfo("end to compact super table..."); + + return 0; +} + +static int32_t mnodeCompactChildTables() { + void *pIter = NULL; + SCTableObj *pTable = NULL; + + mInfo("start to compact child table..."); + + while (1) { + pIter = mnodeGetNextChildTable(pIter, &pTable); + if (pTable == NULL) break; + + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pObj = pTable, + .pTable = tsChildTableSdb, + }; + + //mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid); + + sdbInsertCompactRow(&row); + } + + mInfo("end to compact child table..."); + + return 0; +} + +int32_t mnodeCompactTables() { + mnodeCompactSuperTables(); + + mnodeCompactChildTables(); + + return 0; +} \ No newline at end of file diff --git a/src/mnode/src/mnodeUser.c b/src/mnode/src/mnodeUser.c index e77c1b3e59ca9a75a2a8f97f024320ee1c61d7d0..c5c54791cf828661e146b121765806a630ea8baa 100644 --- a/src/mnode/src/mnodeUser.c +++ b/src/mnode/src/mnodeUser.c @@ -617,3 +617,30 @@ static int32_t mnodeProcessAuthMsg(SMnodeMsg *pMsg) { return mnodeRetriveAuth(pAuthMsg->user, &pAuthRsp->spi, &pAuthRsp->encrypt, pAuthRsp->secret, pAuthRsp->ckey); } + +int32_t mnodeCompactUsers() { + void *pIter = NULL; + SUserObj *pUser = NULL; + + mInfo("start to compact users table..."); + + while (1) { + pIter = mnodeGetNextUser(pIter, &pUser); + if (pUser == NULL) break; + + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsUserSdb, + .pObj = pUser, + .rowSize = sizeof(SUserObj), + }; + + mInfo("compact users %s", pUser->user); + + sdbInsertCompactRow(&row); + } + + mInfo("end to compact users table..."); + + return 0; +} \ No newline at end of file diff --git a/src/mnode/src/mnodeVgroup.c b/src/mnode/src/mnodeVgroup.c index 7222c8d1a0f711d12f3d3d575b1f4c909d123746..a64d2564841241c7f49b7da82a48b51d27783c1a 100644 --- a/src/mnode/src/mnodeVgroup.c +++ b/src/mnode/src/mnodeVgroup.c @@ -121,7 +121,7 @@ static int32_t mnodeVgroupActionDelete(SSdbRow *pRow) { SVgObj *pVgroup = pRow->pObj; if (pVgroup->pDb == NULL) { - mError("vgId:%d, db:%s is not exist while insert into hash", pVgroup->vgId, pVgroup->dbName); + mError("vgId:%d, db:%s is not exist while delete from hash", pVgroup->vgId, pVgroup->dbName); return TSDB_CODE_MND_VGROUP_NOT_EXIST; } @@ -1302,3 +1302,30 @@ void mnodeSetVgidVer(int8_t *cver, uint64_t iver) { cver[1] = (int8_t)((int32_t)(iver % 100000) / 100); cver[2] = (int8_t)(iver % 100); } + +int32_t mnodeCompactVgroups() { + void *pIter = NULL; + SVgObj *pVgroup = NULL; + + mInfo("start to compact vgroups table..."); + + while (1) { + pIter = mnodeGetNextVgroup(pIter, &pVgroup); + if (pVgroup == NULL) break; + + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsVgroupSdb, + .pObj = pVgroup, + .rowSize = sizeof(SVgObj), + }; + + mInfo("compact vgroups %d", pVgroup->vgId); + + sdbInsertCompactRow(&row); + } + + mInfo("end to compact vgroups table..."); + + return 0; +} \ No newline at end of file diff --git a/src/os/inc/osDir.h b/src/os/inc/osDir.h index bdc65e452068cf34fd3969ada6ac69fbf5035217..7afe1264512bbffd34d9278ffb37034a473b827f 100644 --- a/src/os/inc/osDir.h +++ b/src/os/inc/osDir.h @@ -21,6 +21,7 @@ extern "C" { #endif void taosRemoveDir(char *rootDir); +bool taosDirExist(const char* dirname); int32_t taosMkDir(const char *pathname, mode_t mode); void taosRemoveOldLogFiles(char *rootDir, int32_t keepDays); int32_t taosRename(char *oldName, char *newName); diff --git a/src/os/inc/osMips64.h b/src/os/inc/osMips64.h new file mode 100644 index 0000000000000000000000000000000000000000..ed7b08a31116d20a8eaaaacfa3a9a64ea75dbcee --- /dev/null +++ b/src/os/inc/osMips64.h @@ -0,0 +1,87 @@ +/* + * 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 TDENGINE_OS_MIPS64_H +#define TDENGINE_OS_MIPS64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/os/src/detail/osDir.c b/src/os/src/detail/osDir.c index 2a2e2519b5dadf94ee8641064735e92267394a87..c467c64872d4b660af5cebb19b017f1528b55055 100644 --- a/src/os/src/detail/osDir.c +++ b/src/os/src/detail/osDir.c @@ -45,6 +45,10 @@ void taosRemoveDir(char *rootDir) { uInfo("dir:%s is removed", rootDir); } +bool taosDirExist(const char* dirname) { + return access(dirname, F_OK) == 0; +} + int taosMkDir(const char *path, mode_t mode) { int code = mkdir(path, 0755); if (code < 0 && errno == EEXIST) code = 0; diff --git a/src/os/src/detail/osMemory.c b/src/os/src/detail/osMemory.c index 291a54b6695106ba3b457d148b1439e283d6ceff..d8194feab4011501097fdcce937d88b87ea41af0 100644 --- a/src/os/src/detail/osMemory.c +++ b/src/os/src/detail/osMemory.c @@ -62,7 +62,7 @@ static void* taosRandomRealloc(void* ptr, size_t size, const char* file, uint32_ static char* taosRandomStrdup(const char* str, const char* file, uint32_t line) { size_t len = strlen(str); - return taosRandomAllocFail(len + 1, file, line) ? NULL : taosStrdupImp(str); + return taosRandomAllocFail(len + 1, file, line) ? NULL : tstrdup(str); } static char* taosRandomStrndup(const char* str, size_t size, const char* file, uint32_t line) { @@ -70,11 +70,11 @@ static char* taosRandomStrndup(const char* str, size_t size, const char* file, u if (len > size) { len = size; } - return taosRandomAllocFail(len + 1, file, line) ? NULL : taosStrndupImp(str, len); + return taosRandomAllocFail(len + 1, file, line) ? NULL : tstrndup(str, len); } static ssize_t taosRandomGetline(char **lineptr, size_t *n, FILE *stream, const char* file, uint32_t line) { - return taosRandomAllocFail(*n, file, line) ? -1 : taosGetlineImp(lineptr, n, stream); + return taosRandomAllocFail(*n, file, line) ? -1 : tgetline(lineptr, n, stream); } //////////////////////////////////////////////////////////////////////////////// @@ -242,7 +242,7 @@ static char* taosStrndupDetectLeak(const char* str, size_t size, const char* fil static ssize_t taosGetlineDetectLeak(char **lineptr, size_t *n, FILE *stream, const char* file, uint32_t line) { char* buf = NULL; size_t bufSize = 0; - ssize_t size = taosGetlineImp(&buf, &bufSize, stream); + ssize_t size = tgetline(&buf, &bufSize, stream); if (size != -1) { if (*n < size + 1) { void* p = taosReallocDetectLeak(*lineptr, size + 1, file, line); @@ -372,7 +372,7 @@ void taosFreeMem(void* ptr, const char* file, uint32_t line) { char* taosStrdupMem(const char* str, const char* file, uint32_t line) { switch (allocMode) { case TAOS_ALLOC_MODE_DEFAULT: - return taosStrdupImp(str); + return tstrdup(str); case TAOS_ALLOC_MODE_RANDOM_FAIL: return taosRandomStrdup(str, file, line); @@ -380,13 +380,13 @@ char* taosStrdupMem(const char* str, const char* file, uint32_t line) { case TAOS_ALLOC_MODE_DETECT_LEAK: return taosStrdupDetectLeak(str, file, line); } - return taosStrdupImp(str); + return tstrdup(str); } char* taosStrndupMem(const char* str, size_t size, const char* file, uint32_t line) { switch (allocMode) { case TAOS_ALLOC_MODE_DEFAULT: - return taosStrndupImp(str, size); + return tstrndup(str, size); case TAOS_ALLOC_MODE_RANDOM_FAIL: return taosRandomStrndup(str, size, file, line); @@ -394,13 +394,13 @@ char* taosStrndupMem(const char* str, size_t size, const char* file, uint32_t li case TAOS_ALLOC_MODE_DETECT_LEAK: return taosStrndupDetectLeak(str, size, file, line); } - return taosStrndupImp(str, size); + return tstrndup(str, size); } ssize_t taosGetlineMem(char **lineptr, size_t *n, FILE *stream, const char* file, uint32_t line) { switch (allocMode) { case TAOS_ALLOC_MODE_DEFAULT: - return taosGetlineImp(lineptr, n, stream); + return tgetline(lineptr, n, stream); case TAOS_ALLOC_MODE_RANDOM_FAIL: return taosRandomGetline(lineptr, n, stream, file, line); @@ -408,7 +408,7 @@ ssize_t taosGetlineMem(char **lineptr, size_t *n, FILE *stream, const char* file case TAOS_ALLOC_MODE_DETECT_LEAK: return taosGetlineDetectLeak(lineptr, n, stream, file, line); } - return taosGetlineImp(lineptr, n, stream); + return tgetline(lineptr, n, stream); } static void taosCloseAllocLog() { @@ -517,4 +517,4 @@ void* taosTZfree(void* ptr) { free((void*)((char*)ptr - sizeof(size_t))); } return NULL; -} \ No newline at end of file +} diff --git a/src/os/src/detail/osSignal.c b/src/os/src/detail/osSignal.c index 4467a607b2c9b235d925d2dca2f06e7875fcd0dc..33cc39e112da1f9348dbefe85a7f9ec879c88cd1 100644 --- a/src/os/src/detail/osSignal.c +++ b/src/os/src/detail/osSignal.c @@ -25,14 +25,14 @@ typedef void (*FLinuxSignalHandler)(int32_t signum, siginfo_t *sigInfo, void *context); void taosSetSignal(int32_t signum, FSignalHandler sigfp) { - struct sigaction act = {{0}}; + struct sigaction act; memset(&act, 0, sizeof(act)); #if 1 act.sa_flags = SA_SIGINFO; act.sa_sigaction = (FLinuxSignalHandler)sigfp; -#else - act.sa_handler = sigfp; -#endif - sigaction(signum, &act, NULL); +#else + act.sa_handler = sigfp; +#endif + sigaction(signum, &act, NULL); } void taosIgnSignal(int32_t signum) { diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index d9d070218e2a64e5f2535c073db4852b0a8960ef..67e0c2642e42f66229c437e603f7062edf571f34 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -87,12 +87,12 @@ static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t time int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } -int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t daylight) { +int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { /* parse datatime string in with tz */ if (strnchr(timestr, 'T', len, false) != NULL) { return parseTimeWithTz(timestr, time, timePrec); } else { - return (*parseLocaltimeFp[daylight])(timestr, time, timePrec); + return (*parseLocaltimeFp[day_light])(timestr, time, timePrec); } } diff --git a/src/os/src/windows/wSemphone.c b/src/os/src/windows/wSemphone.c index a3f0367ee1179f74769c8883afe5ee47237ac32b..878ceba791c04277a05328ec160a43bb5a0e6efa 100644 --- a/src/os/src/windows/wSemphone.c +++ b/src/os/src/windows/wSemphone.c @@ -14,6 +14,7 @@ */ #define _DEFAULT_SOURCE + #include "os.h" #include "taosdef.h" #include "tglobal.h" @@ -24,7 +25,7 @@ bool taosCheckPthreadValid(pthread_t thread) { return thread.p != NULL; } -void taosResetPthread(pthread_t *thread) { thread->p = 0; } +void taosResetPthread(pthread_t* thread) { thread->p = 0; } int64_t taosGetPthreadId(pthread_t thread) { #ifdef PTW32_VERSION @@ -34,27 +35,24 @@ int64_t taosGetPthreadId(pthread_t thread) { #endif } -int64_t taosGetSelfPthreadId() { - return GetCurrentThreadId(); -} +int64_t taosGetSelfPthreadId() { return GetCurrentThreadId(); } -bool taosComparePthread(pthread_t first, pthread_t second) { - return first.p == second.p; -} +bool taosComparePthread(pthread_t first, pthread_t second) { return first.p == second.p; } -int32_t taosGetPId() { - return GetCurrentProcessId(); -} +int32_t taosGetPId() { return GetCurrentProcessId(); } -int32_t taosGetCurrentAPPName(char *name, int32_t* len) { +int32_t taosGetCurrentAPPName(char* name, int32_t* len) { char filepath[1024] = {0}; GetModuleFileName(NULL, filepath, MAX_PATH); - *strrchr(filepath,'.') = '\0'; + char* sub = strrchr(filepath, '.'); + if (sub != NULL) { + *sub = '\0'; + } strcpy(name, filepath); if (len != NULL) { - *len = (int32_t) strlen(filepath); + *len = (int32_t)strlen(filepath); } return 0; diff --git a/src/os/tests/test.cpp b/src/os/tests/test.cpp index 12e9546ff184589a139de8dfd8a5f8a9a392a7b3..6b04540615da139f9dc9472115b9d46ec52b634a 100644 --- a/src/os/tests/test.cpp +++ b/src/os/tests/test.cpp @@ -4,7 +4,7 @@ #include #include "taos.h" -#include "tstoken.h" +#include "ttoken.h" #include "tutil.h" int main(int argc, char** argv) { diff --git a/src/plugins/http/src/httpGzip.c b/src/plugins/http/src/httpGzip.c index ecda0e1fe0232362f3537b7749cdc18a6537b892..6a6e995c182f9c248e84b53588ee383ada8194e1 100644 --- a/src/plugins/http/src/httpGzip.c +++ b/src/plugins/http/src/httpGzip.c @@ -132,10 +132,10 @@ int32_t ehttp_gzip_write(ehttp_gzip_t *gzip, const char *buf, int32_t len) { if (ret != Z_STREAM_END) continue; } - int32_t len = (int32_t)(gzip->gzip->next_out - (z_const Bytef *)gzip->chunk); + int32_t _len = (int32_t)(gzip->gzip->next_out - (z_const Bytef *)gzip->chunk); gzip->gzip->next_out[0] = '\0'; - gzip->callbacks.on_data(gzip, gzip->arg, gzip->chunk, len); + gzip->callbacks.on_data(gzip, gzip->arg, gzip->chunk, _len); gzip->gzip->next_out = (z_const Bytef *)gzip->chunk; gzip->gzip->avail_out = gzip->conf.chunk_size; } diff --git a/src/plugins/http/src/httpParser.c b/src/plugins/http/src/httpParser.c index 18cea56cfe6e0d1e8a4f833a920e5473536e1c7e..599991da634cbb2226d59e9361de86c23f05e757 100644 --- a/src/plugins/http/src/httpParser.c +++ b/src/plugins/http/src/httpParser.c @@ -163,9 +163,9 @@ static int32_t httpOnRequestLine(HttpParser *pParser, char *method, char *target // parse decode method for (int32_t i = 0; i < tsHttpServer.methodScannerLen; i++) { - HttpDecodeMethod *method = tsHttpServer.methodScanner[i]; - if (strcmp(method->module, pParser->path[0].str) == 0) { - pContext->decodeMethod = method; + HttpDecodeMethod *_method = tsHttpServer.methodScanner[i]; + if (strcmp(_method->module, pParser->path[0].str) == 0) { + pContext->decodeMethod = _method; break; } } diff --git a/src/plugins/http/src/httpResp.c b/src/plugins/http/src/httpResp.c index 063f2bb04e4760d683434d9e6a600791c2a57888..4fcf236fce94da5062ae5063d081ca71aa8f2a98 100644 --- a/src/plugins/http/src/httpResp.c +++ b/src/plugins/http/src/httpResp.c @@ -165,7 +165,7 @@ void httpSendTaosdInvalidSqlErrorResp(HttpContext *pContext, char *errMsg) { } } - httpSendErrorRespImp(pContext, httpCode, "Bad Request", TSDB_CODE_TSC_INVALID_SQL & 0XFFFF, temp); + httpSendErrorRespImp(pContext, httpCode, "Bad Request", TSDB_CODE_TSC_INVALID_OPERATION & 0XFFFF, temp); } void httpSendSuccResp(HttpContext *pContext, char *desc) { diff --git a/src/plugins/http/src/httpServer.c b/src/plugins/http/src/httpServer.c index 4dcf3d550177ff6747a2af1c0c9ff561a3b0dd29..9d98d3f11300fa8143f9a32718c6a865b9a59a97 100644 --- a/src/plugins/http/src/httpServer.c +++ b/src/plugins/http/src/httpServer.c @@ -269,7 +269,11 @@ static void *httpAcceptHttpConnection(void *arg) { sprintf(pContext->ipstr, "%s:%u", taosInetNtoa(clientAddr.sin_addr), htons(clientAddr.sin_port)); struct epoll_event event; +#ifndef _TD_NINGSI_60 event.events = EPOLLIN | EPOLLPRI | EPOLLWAKEUP | EPOLLERR | EPOLLHUP | EPOLLRDHUP; +#else + event.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLRDHUP; +#endif event.data.ptr = pContext; if (epoll_ctl(pThread->pollFd, EPOLL_CTL_ADD, connFd, &event) < 0) { httpError("context:%p, fd:%d, ip:%s, thread:%s, failed to add http fd for epoll, error:%s", pContext, connFd, diff --git a/src/plugins/http/src/httpSql.c b/src/plugins/http/src/httpSql.c index b345c1531f1f6904470a2e9dbae361834ef32fff..5a0480b6943d385b94acc0860534db09a5c24353 100644 --- a/src/plugins/http/src/httpSql.c +++ b/src/plugins/http/src/httpSql.c @@ -263,7 +263,7 @@ void httpProcessSingleSqlCallBackImp(void *param, TAOS_RES *result, int32_t code if (code != TSDB_CODE_SUCCESS) { SSqlObj *pObj = (SSqlObj *)result; - if (code == TSDB_CODE_TSC_INVALID_SQL) { + if (code == TSDB_CODE_TSC_INVALID_OPERATION) { terrno = code; httpError("context:%p, fd:%d, user:%s, query error, code:%s, sqlObj:%p, error:%s", pContext, pContext->fd, pContext->user, tstrerror(code), pObj, taos_errstr(pObj)); diff --git a/src/plugins/http/src/httpTgHandle.c b/src/plugins/http/src/httpTgHandle.c index c1d006ff5a0c2cb5037ee6833b58d2ba749196e5..69ac3e19c5483d3514d95530404f9a67e6fd11cc 100644 --- a/src/plugins/http/src/httpTgHandle.c +++ b/src/plugins/http/src/httpTgHandle.c @@ -209,7 +209,7 @@ void tgParseSchemaMetric(cJSON *metric) { parsedOk = false; goto ParseEnd; } - int32_t nameLen = (int32_t)strlen(field->valuestring); + nameLen = (int32_t)strlen(field->valuestring); if (nameLen == 0 || nameLen >= TSDB_TABLE_NAME_LEN) { parsedOk = false; goto ParseEnd; diff --git a/src/plugins/http/src/httpUtil.c b/src/plugins/http/src/httpUtil.c index 399a33954d5670a7e928f856a898dcde1e4ac4eb..a8031d3fd85714d43735c5f18a60c6c388a7d69b 100644 --- a/src/plugins/http/src/httpUtil.c +++ b/src/plugins/http/src/httpUtil.c @@ -237,6 +237,11 @@ void httpFreeMultiCmds(HttpContext *pContext) { JsonBuf *httpMallocJsonBuf(HttpContext *pContext) { if (pContext->jsonBuf == NULL) { pContext->jsonBuf = (JsonBuf *)malloc(sizeof(JsonBuf)); + if (pContext->jsonBuf == NULL) { + return NULL; + } + + memset(pContext->jsonBuf, 0, sizeof(JsonBuf)); } if (!pContext->jsonBuf->pContext) { diff --git a/src/plugins/monitor/src/monMain.c b/src/plugins/monitor/src/monMain.c index 94af8e3ecd6623f791f6ad797176a59ca2605c2b..d9f7d81ebd3eefe77569deb30b75c227ff79e04f 100644 --- a/src/plugins/monitor/src/monMain.c +++ b/src/plugins/monitor/src/monMain.c @@ -417,3 +417,13 @@ void monExecuteSQL(char *sql) { monDebug("execute sql:%s", sql); taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "sql"); } + +void monExecuteSQLWithResultCallback(char *sql, MonExecuteSQLCbFP callback, void* param) { + if (tsMonitor.conn == NULL) { + callback(param, NULL, TSDB_CODE_MON_CONNECTION_INVALID); + return; + } + + monDebug("execute sql:%s", sql); + taos_query_a(tsMonitor.conn, sql, callback, param); +} diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index 6ad23e219b75dbd1d5e1e23cb10cc0570e18555f..5079824ad7e4d7b43af062611cd4e39a7d31062c 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -70,13 +70,13 @@ typedef struct SResultRowPool { SArray* pData; // SArray } SResultRowPool; -typedef struct SSqlGroupbyExpr { +typedef struct SGroupbyExpr { int16_t tableIndex; SArray* columnInfo; // SArray, group by columns information - int16_t numOfGroupCols; + int16_t numOfGroupCols; // todo remove it int16_t orderIndex; // order by column index int16_t orderType; // order by type: asc/desc -} SSqlGroupbyExpr; +} SGroupbyExpr; typedef struct SResultRow { int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer @@ -217,7 +217,7 @@ typedef struct SQueryAttr { int32_t intermediateResultRowSize; // intermediate result row size, in case of top-k query. int32_t maxTableColumnWidth; int32_t tagLen; // tag value length of current query - SSqlGroupbyExpr* pGroupbyExpr; + SGroupbyExpr* pGroupbyExpr; SExprInfo* pExpr1; SExprInfo* pExpr2; @@ -303,7 +303,8 @@ enum OPERATOR_TYPE_E { OP_GlobalAggregate = 18, // global merge for the multi-way data sources. OP_Filter = 19, OP_Distinct = 20, - OP_StateWindow = 21, + OP_Join = 21, + OP_StateWindow = 22, }; typedef struct SOperatorInfo { @@ -316,7 +317,8 @@ typedef struct SOperatorInfo { SExprInfo *pExpr; SQueryRuntimeEnv *pRuntimeEnv; - struct SOperatorInfo *upstream; + struct SOperatorInfo **upstream; // upstream pointer list + int32_t numOfUpstream; // number of upstream. The value is always ONE expect for join operator __operator_fn_t exec; __optr_cleanup_fn_t cleanup; } SOperatorInfo; @@ -364,7 +366,7 @@ typedef struct SQueryParam { SColIndex *pGroupColIndex; SColumnInfo *pTagColumnInfo; - SSqlGroupbyExpr *pGroupbyExpr; + SGroupbyExpr *pGroupbyExpr; int32_t tableScanOperator; SArray *pOperator; } SQueryParam; @@ -506,6 +508,8 @@ typedef struct SMultiwayMergeInfo { bool groupMix; } SMultiwayMergeInfo; +void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream); + SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime); SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime); SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); @@ -527,12 +531,20 @@ SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SEx SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param); SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger); -SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, + int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter); + +SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUpstream, SSchema* pSchema, int32_t numOfOutput); SSDataBlock* doGlobalAggregate(void* param, bool* newgroup); SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup); SSDataBlock* doSLimit(void* param, bool* newgroup); +int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId); +void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock); +bool doFilterDataBlock(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t numOfRows, int8_t* p); +void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p); + SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows); void* destroyOutputBuf(SSDataBlock* pBlock); @@ -549,13 +561,14 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, SSqlExpr **pExpr, SExprInfo *prevExpr); -SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code); -SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs, +SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code); +SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs, SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId, char* sql, uint64_t *qId); int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start, int32_t prevResultLen, void* merger); +int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId); void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters); STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf); diff --git a/src/query/inc/qFill.h b/src/query/inc/qFill.h index 00ac86caf4a079e01ad239496370d97ac28e84f2..caa0c55b3ff1a805975a6258ca360e5099f4894e 100644 --- a/src/query/inc/qFill.h +++ b/src/query/inc/qFill.h @@ -62,7 +62,7 @@ typedef struct SFillInfo { SFillColInfo* pFillCol; // column info for fill operations SFillTagColInfo* pTags; // tags value for filling gap - void* handle; // for dubug purpose + void* handle; // for debug purpose } SFillInfo; typedef struct SPoint { @@ -82,8 +82,6 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey) void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const struct SSDataBlock* pInput); -void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* pInput); - bool taosFillHasMoreResults(SFillInfo* pFillInfo); int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t maxNumOfRows); diff --git a/src/query/inc/qHistogram.h b/src/query/inc/qHistogram.h index 7742d151a06456a8b3c10e8b1f0aeba6203a28b7..3b5c2b4cfb9bac638c7d86988f8ac14d7419f83c 100644 --- a/src/query/inc/qHistogram.h +++ b/src/query/inc/qHistogram.h @@ -40,7 +40,7 @@ typedef struct SHeapEntry { } SHeapEntry; typedef struct SHistogramInfo { - int32_t numOfElems; + int64_t numOfElems; int32_t numOfEntries; int32_t maxEntries; double min; diff --git a/src/query/inc/qPlan.h b/src/query/inc/qPlan.h index 8f35565e4bccd4896ec49ddb30f7236ac4b4650c..30c0f8db4e43f33e8ac69e2bcde50ca77abac4d2 100644 --- a/src/query/inc/qPlan.h +++ b/src/query/inc/qPlan.h @@ -16,7 +16,38 @@ #ifndef TDENGINE_QPLAN_H #define TDENGINE_QPLAN_H -//TODO refactor +struct SQueryInfo; + +typedef struct SQueryNodeBasicInfo { + int32_t type; + char *name; +} SQueryNodeBasicInfo; + +typedef struct SQueryTableInfo { + char *tableName; + STableId id; +} SQueryTableInfo; + +typedef struct SQueryNode { + SQueryNodeBasicInfo info; + SQueryTableInfo tableInfo; + SSchema *pSchema; // the schema of the input SSDatablock + int32_t numOfCols; // number of input columns + SExprInfo *pExpr; // the query functions or sql aggregations + int32_t numOfOutput; // number of result columns, which is also the number of pExprs + + void *pExtInfo; // additional information + // previous operator to generated result for current node to process + // in case of join, multiple prev nodes exist. + SArray *pPrevNodes;// upstream nodes + struct SQueryNode *nextNode; +} SQueryNode; + +SQueryNode* qCreateQueryPlan(struct SQueryInfo* pQueryInfo); +void* qDestroyQueryPlan(SQueryNode* pQueryNode); + +char* queryPlanToString(SQueryNode* pQueryNode); + SArray* createTableScanPlan(SQueryAttr* pQueryAttr); SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr); SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr); diff --git a/src/query/inc/qSqlparser.h b/src/query/inc/qSqlparser.h index 026ae1d976957883da0c6c4658cda2412d35b00b..34665a0ebae960f8a7ba63ec1d9c1f8458b9d8f4 100644 --- a/src/query/inc/qSqlparser.h +++ b/src/query/inc/qSqlparser.h @@ -22,8 +22,8 @@ extern "C" { #include "taos.h" #include "taosmsg.h" -#include "tstoken.h" #include "tstrbuild.h" +#include "ttoken.h" #include "tvariant.h" #define ParseTOKENTYPE SStrToken @@ -112,14 +112,18 @@ typedef struct SSqlNode { struct tSqlExpr *pHaving; // having clause [optional] } SSqlNode; -typedef struct STableNamePair { - SStrToken name; +typedef struct SRelElementPair { + union { + SStrToken tableName; + SArray *pSubquery; + }; + SStrToken aliasName; -} STableNamePair; +} SRelElementPair; typedef struct SRelationInfo { int32_t type; // nested query|table name list - SArray *list; // SArray|SArray + SArray *list; // SArray } SRelationInfo; typedef struct SCreatedTableInfo { @@ -259,8 +263,9 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int SArray *tVariantListAppendToken(SArray *pList, SStrToken *pAliasToken, uint8_t sortOrder); SRelationInfo *setTableNameList(SRelationInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias); -SRelationInfo *setSubquery(SRelationInfo* pFromInfo, SArray* pSqlNode); +//SRelationInfo *setSubquery(SRelationInfo* pFromInfo, SRelElementPair* p); void *destroyRelationInfo(SRelationInfo* pFromInfo); +SRelationInfo *addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrToken* pAlias); // sql expr leaf node tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType); diff --git a/src/query/inc/qUtil.h b/src/query/inc/qUtil.h index 3ca6d967463ff86de82112bb86307715c73715cd..0756e4178598f09ecdc784b07e226b9054edcfef 100644 --- a/src/query/inc/qUtil.h +++ b/src/query/inc/qUtil.h @@ -47,6 +47,9 @@ void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, in SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset); +void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr); +void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols); + static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) { assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size); return pResultRowInfo->pResult[slot]; diff --git a/src/query/inc/sql.y b/src/query/inc/sql.y index 66979d0dea9ff19ece50a5aa24ffdcf95f2a34da..ba16eef763adc48b0492aedbaa825b23c3a74e0a 100644 --- a/src/query/inc/sql.y +++ b/src/query/inc/sql.y @@ -28,7 +28,7 @@ #include #include "qSqlparser.h" #include "tcmdtype.h" -#include "tstoken.h" +#include "ttoken.h" #include "ttokendef.h" #include "tutil.h" #include "tvariant.h" @@ -512,7 +512,13 @@ distinct(X) ::= . { X.n = 0;} %type from {SRelationInfo*} %destructor from {destroyRelationInfo($$);} from(A) ::= FROM tablelist(X). {A = X;} -from(A) ::= FROM LP union(Y) RP. {A = setSubquery(NULL, Y);} +from(A) ::= FROM sub(X). {A = X;} + +%type sub {SRelationInfo*} +%destructor sub {destroyRelationInfo($$);} +sub(A) ::= LP union(Y) RP. {A = addSubqueryElem(NULL, Y, NULL);} +sub(A) ::= LP union(Y) RP ids(Z). {A = addSubqueryElem(NULL, Y, &Z);} +sub(A) ::= sub(X) COMMA LP union(Y) RP ids(Z).{A = addSubqueryElem(X, Y, &Z);} %type tablelist {SRelationInfo*} %destructor tablelist {destroyRelationInfo($$);} diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index e99f1359045475774b3c918b4c8ad5ac19c914fc..bdb5b15426d83080bba0a87d5d1545bd37eaeffa 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -166,7 +166,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable) { if (!isValidDataType(dataType)) { qError("Illegal data type %d or data type length %d", dataType, dataBytes); - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY || @@ -353,7 +353,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI *interBytes = (*bytes); } else { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } return TSDB_CODE_SUCCESS; @@ -3704,7 +3704,7 @@ char *getArithColumnData(void *param, const char* name, int32_t colId) { } } - assert(index >= 0 /*&& colId >= 0*/); + assert(index >= 0); return pSupport->data[index] + pSupport->offset * pSupport->colList[index].bytes; } @@ -4013,7 +4013,13 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si continue; } +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4025,8 +4031,14 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) { continue; } - + +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4038,8 +4050,14 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) { continue; } - + +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4051,8 +4069,14 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) { continue; } - + +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = (double) val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = (double)val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4064,8 +4088,14 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) { continue; } - + +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = (double)val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4077,8 +4107,14 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) { continue; } - + +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4091,7 +4127,13 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si continue; } +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4104,7 +4146,13 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si continue; } +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4117,7 +4165,13 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si continue; } +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4129,8 +4183,14 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) { continue; } - + +#ifndef _TD_NINGSI_60 SPoint1 st = {.key = tsList[i], .val = (double) val[i]}; +#else + SPoint1 st; + st.key = tsList[i]; + st.val = (double) val[i]; +#endif pInfo->dOutput += twa_get_area(pInfo->p, st); pInfo->p = st; } @@ -4783,7 +4843,7 @@ static void mergeTableBlockDist(STableBlockDist* pDist, const STableBlockDist* p pDist->dataBlockInfos = taosArrayInit(4, sizeof(SFileBlockInfo)); } - taosArrayPushBatch(pDist->dataBlockInfos, pSrc->dataBlockInfos->pData, (int32_t) taosArrayGetSize(pSrc->dataBlockInfos)); + taosArrayAddBatch(pDist->dataBlockInfos, pSrc->dataBlockInfos->pData, (int32_t) taosArrayGetSize(pSrc->dataBlockInfos)); } void block_func_merge(SQLFunctionCtx* pCtx) { diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 1603768152f8ec185edf49a366aafc8b43d80dbd..7683465800ef484d9ff6b7d12abedb3ed7e23b7c 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -33,6 +33,8 @@ #define SET_MASTER_SCAN_FLAG(runtime) ((runtime)->scanFlag = MASTER_SCAN) #define SET_REVERSE_SCAN_FLAG(runtime) ((runtime)->scanFlag = REVERSE_SCAN) +#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey)) + #define SWITCH_ORDER(n) (((n) = ((n) == TSDB_ORDER_ASC) ? TSDB_ORDER_DESC : TSDB_ORDER_ASC)) #define SDATA_BLOCK_INITIALIZER (SDataBlockInfo) {{0}, 0} @@ -115,6 +117,8 @@ int64_t genQueryId(void) { uid |= sid; + qDebug("gen qid:0x%"PRIx64, uid); + return uid; } @@ -167,6 +171,8 @@ static void setBlockStatisInfo(SQLFunctionCtx *pCtx, SSDataBlock* pSDataBlock, S static void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo); static bool hasMainOutput(SQueryAttr *pQueryAttr); +static SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int32_t* numOfFilterCols); + static int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, STableQueryInfo *pTableQueryInfo); static void releaseQueryBuf(size_t numOfTables); static int32_t binarySearchForKey(char *pValue, int num, TSKEY key, int order); @@ -174,8 +180,6 @@ static STsdbQueryCond createTsdbQueryCond(SQueryAttr* pQueryAttr, STimeWindow* w static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo); static void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInfo* pDownstream); -static int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, - SSingleColumnFilterInfo** pFilterInfo, uint64_t qId); static void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols); static int32_t getNumOfScanTimes(SQueryAttr* pQueryAttr); @@ -193,8 +197,8 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator); static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock); -static int32_t getGroupbyColumnIndex(SSqlGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock); -static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *bInfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex); +static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock); +static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *binf, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex); static void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size); static void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win); @@ -1426,7 +1430,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasic return TSDB_CODE_SUCCESS; } -static int32_t getGroupbyColumnIndex(SSqlGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock) { +static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock) { for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols; ++k) { SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, k); if (TSDB_COL_IS_TAG(pColIndex->flag)) { @@ -1716,38 +1720,40 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf case OP_MultiTableTimeInterval: { pRuntimeEnv->proot = createMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); break; } case OP_TimeWindow: { pRuntimeEnv->proot = createTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); break; } case OP_Groupby: { pRuntimeEnv->proot = createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); break; } case OP_SessionWindow: { pRuntimeEnv->proot = createSWindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); break; } case OP_MultiTableAggregate: { pRuntimeEnv->proot = createMultiTableAggOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); break; } case OP_Aggregate: { pRuntimeEnv->proot = createAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); - if (pRuntimeEnv->proot->upstream->operatorType != OP_DummyInput) { - setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + + int32_t opType = pRuntimeEnv->proot->upstream[0]->operatorType; + if (opType != OP_DummyInput && opType != OP_Join) { + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); } break; } @@ -1756,7 +1762,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf SOperatorInfo* prev = pRuntimeEnv->proot; if (i == 0) { pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, prev, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); - if (pRuntimeEnv->proot != NULL && pRuntimeEnv->proot->operatorType != OP_DummyInput) { // TODO refactor + if (pRuntimeEnv->proot != NULL && prev->operatorType != OP_DummyInput && prev->operatorType != OP_Join) { // TODO refactor setTableScanFilterOperatorInfo(prev->info, pRuntimeEnv->proot); } } else { @@ -1768,7 +1774,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf } case OP_StateWindow: { pRuntimeEnv->proot = createStatewindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); break; } @@ -1778,12 +1784,25 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf } case OP_Filter: { // todo refactor - assert(pQueryAttr->havingNum > 0); - if (pQueryAttr->stableQuery) { - pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3, pQueryAttr->numOfExpr3); - } else { - pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); - } + int32_t numOfFilterCols = 0; +// if (pQueryAttr->numOfFilterCols > 0) { +// pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, +// pQueryAttr->numOfOutput, pQueryAttr->tableCols, pQueryAttr->numOfFilterCols); +// } else { + if (pQueryAttr->stableQuery) { + SColumnInfo* pColInfo = + extractColumnFilterInfo(pQueryAttr->pExpr3, pQueryAttr->numOfExpr3, &numOfFilterCols); + pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3, + pQueryAttr->numOfExpr3, pColInfo, numOfFilterCols); + freeColumnInfo(pColInfo, pQueryAttr->numOfExpr3); + } else { + SColumnInfo* pColInfo = + extractColumnFilterInfo(pQueryAttr->pExpr1, pQueryAttr->numOfOutput, &numOfFilterCols); + pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, + pQueryAttr->numOfOutput, pColInfo, numOfFilterCols); + freeColumnInfo(pColInfo, pQueryAttr->numOfOutput); + } +// } break; } @@ -1990,6 +2009,37 @@ static bool isFirstLastRowQuery(SQueryAttr *pQueryAttr) { return false; } +static bool isCachedLastQuery(SQueryAttr *pQueryAttr) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionID = pQueryAttr->pExpr1[i].base.functionId; + if (functionID == TSDB_FUNC_LAST || functionID == TSDB_FUNC_LAST_DST) { + continue; + } + + return false; + } + + if (pQueryAttr->order.order != TSDB_ORDER_DESC || !TSWINDOW_IS_EQUAL(pQueryAttr->window, TSWINDOW_DESC_INITIALIZER)) { + return false; + } + + if (pQueryAttr->groupbyColumn) { + return false; + } + + if (pQueryAttr->interval.interval > 0) { + return false; + } + + if (pQueryAttr->numOfFilterCols > 0 || pQueryAttr->havingNum > 0) { + return false; + } + + return true; +} + + + /** * The following 4 kinds of query are treated as the tags query * tagprj, tid_tag query, count(tbname), 'abc' (user defined constant value column) query @@ -2097,7 +2147,7 @@ static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { if (hasFirstLastFunc && status == BLK_DATA_NO_NEEDED) { if(!hasOtherFunc) { return BLK_DATA_DISCARD; - } else{ + } else { return BLK_DATA_ALL_NEEDED; } } @@ -2372,6 +2422,105 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key, bool asc return TS_JOIN_TS_EQUAL; } +bool doFilterDataBlock(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t numOfRows, int8_t* p) { + bool all = true; + + for (int32_t i = 0; i < numOfRows; ++i) { + bool qualified = false; + + for (int32_t k = 0; k < numOfFilterCols; ++k) { + char* pElem = (char*)pFilterInfo[k].pData + pFilterInfo[k].info.bytes * i; + + qualified = false; + for (int32_t j = 0; j < pFilterInfo[k].numOfFilters; ++j) { + SColumnFilterElem* pFilterElem = &pFilterInfo[k].pFilters[j]; + + bool isnull = isNull(pElem, pFilterInfo[k].info.type); + if (isnull) { + if (pFilterElem->fp == isNullOperator) { + qualified = true; + break; + } else { + continue; + } + } else { + if (pFilterElem->fp == notNullOperator) { + qualified = true; + break; + } else if (pFilterElem->fp == isNullOperator) { + continue; + } + } + + if (pFilterElem->fp(pFilterElem, pElem, pElem, pFilterInfo[k].info.type)) { + qualified = true; + break; + } + } + + if (!qualified) { + break; + } + } + + p[i] = qualified ? 1 : 0; + if (!qualified) { + all = false; + } + } + + return all; +} + +void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p) { + int32_t len = 0; + int32_t start = 0; + for (int32_t j = 0; j < numOfRows; ++j) { + if (p[j] == 1) { + len++; + } else { + if (len > 0) { + int32_t cstart = j - len; + for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, i); + + int16_t bytes = pColumnInfoData->info.bytes; + memmove(((char*)pColumnInfoData->pData) + start * bytes, pColumnInfoData->pData + cstart * bytes, + len * bytes); + } + + start += len; + len = 0; + } + } + } + + if (len > 0) { + int32_t cstart = numOfRows - len; + for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, i); + + int16_t bytes = pColumnInfoData->info.bytes; + memmove(pColumnInfoData->pData + start * bytes, pColumnInfoData->pData + cstart * bytes, len * bytes); + } + + start += len; + len = 0; + } + + pBlock->info.rows = start; + pBlock->pBlockStatis = NULL; // clean the block statistics info + + if (start > 0) { + SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, 0); + if (pColumnInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && + pColumnInfoData->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + pBlock->info.window.skey = *(int64_t*)pColumnInfoData->pData; + pBlock->info.window.ekey = *(int64_t*)(pColumnInfoData->pData + TSDB_KEYSIZE * (start - 1)); + } + } +} + void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock, bool ascQuery) { int32_t numOfRows = pBlock->info.rows; @@ -2404,97 +2553,11 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf // save the cursor status pRuntimeEnv->current->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf); } else { - for (int32_t i = 0; i < numOfRows; ++i) { - bool qualified = false; - - for (int32_t k = 0; k < numOfFilterCols; ++k) { - char* pElem = (char*)pFilterInfo[k].pData + pFilterInfo[k].info.bytes * i; - - qualified = false; - for (int32_t j = 0; j < pFilterInfo[k].numOfFilters; ++j) { - SColumnFilterElem* pFilterElem = &pFilterInfo[k].pFilters[j]; - - bool isnull = isNull(pElem, pFilterInfo[k].info.type); - if (isnull) { - if (pFilterElem->fp == isNullOperator) { - qualified = true; - break; - } else { - continue; - } - } else { - if (pFilterElem->fp == notNullOperator) { - qualified = true; - break; - } else if (pFilterElem->fp == isNullOperator) { - continue; - } - } - - if (pFilterElem->fp(pFilterElem, pElem, pElem, pFilterInfo[k].info.type)) { - qualified = true; - break; - } - } - - if (!qualified) { - break; - } - } - - p[i] = qualified ? 1 : 0; - if (!qualified) { - all = false; - } - } + all = doFilterDataBlock(pFilterInfo, numOfFilterCols, numOfRows, p); } if (!all) { - int32_t start = 0; - int32_t len = 0; - for (int32_t j = 0; j < numOfRows; ++j) { - if (p[j] == 1) { - len++; - } else { - if (len > 0) { - int32_t cstart = j - len; - for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { - SColumnInfoData *pColumnInfoData = taosArrayGet(pBlock->pDataBlock, i); - - int16_t bytes = pColumnInfoData->info.bytes; - memmove(((char*)pColumnInfoData->pData) + start * bytes, pColumnInfoData->pData + cstart * bytes, len * bytes); - } - - start += len; - len = 0; - } - } - } - - if (len > 0) { - int32_t cstart = numOfRows - len; - for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { - SColumnInfoData *pColumnInfoData = taosArrayGet(pBlock->pDataBlock, i); - - int16_t bytes = pColumnInfoData->info.bytes; - memmove(pColumnInfoData->pData + start * bytes, pColumnInfoData->pData + cstart * bytes, len * bytes); - } - - start += len; - len = 0; - } - - pBlock->info.rows = start; - pBlock->pBlockStatis = NULL; // clean the block statistics info - - if (start > 0) { - SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, 0); - if (pColumnInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && - pColumnInfoData->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { - pBlock->info.window.skey = *(int64_t*)pColumnInfoData->pData; - pBlock->info.window.ekey = *(int64_t*)(pColumnInfoData->pData + TSDB_KEYSIZE * (start - 1)); - } - } + doCompactSDataBlock(pBlock, numOfRows, p); } tfree(p); @@ -2522,7 +2585,7 @@ static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSData return status; } -static void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock) { +void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock) { if (numOfFilterCols > 0 && pFilterInfo[0].pData != NULL) { return; } @@ -3927,6 +3990,15 @@ void queryCostStatis(SQInfo *pQInfo) { // return true; //} +void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream) { + if (p->upstream == NULL) { + assert(p->numOfUpstream == 0); + } + + p->upstream = realloc(p->upstream, POINTER_BYTES * (p->numOfUpstream + 1)); + p->upstream[p->numOfUpstream++] = pUpstream; +} + static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo); static int32_t setupQueryHandle(void* tsdb, SQueryRuntimeEnv* pRuntimeEnv, int64_t qId, bool isSTableQuery) { @@ -3976,6 +4048,8 @@ static int32_t setupQueryHandle(void* tsdb, SQueryRuntimeEnv* pRuntimeEnv, int64 } } } + } else if (isCachedLastQuery(pQueryAttr)) { + pRuntimeEnv->pQueryHandle = tsdbQueryCacheLast(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef); } else if (pQueryAttr->pointInterpQuery) { pRuntimeEnv->pQueryHandle = tsdbQueryRowsInExternalWindow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef); } else { @@ -4156,12 +4230,12 @@ static void doCloseAllTimeWindow(SQueryRuntimeEnv* pRuntimeEnv) { } static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; + SOperatorInfo *pOperator = (SOperatorInfo*) param; - STableScanInfo* pTableScanInfo = pOperator->info; - SSDataBlock* pBlock = &pTableScanInfo->block; + STableScanInfo *pTableScanInfo = pOperator->info; + SSDataBlock *pBlock = &pTableScanInfo->block; SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; - SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; STableGroupInfo *pTableGroupInfo = &pOperator->pRuntimeEnv->tableqinfoGroupInfo; *newgroup = false; @@ -4221,7 +4295,7 @@ static SSDataBlock* doTableScan(void* param, bool *newgroup) { } if (++pTableScanInfo->current >= pTableScanInfo->times) { - if (pTableScanInfo->reverseTimes <= 0) { + if (pTableScanInfo->reverseTimes <= 0 || isTsdbCacheLastRow(pTableScanInfo->pQueryHandle)) { return NULL; } else { break; @@ -4609,13 +4683,14 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, pOperator->blockingOptr = true; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doGlobalAggregate; pOperator->cleanup = destroyGlobalAggOperatorInfo; + appendUpstream(pOperator, upstream); + return pOperator; } @@ -4680,7 +4755,7 @@ static SSDataBlock* doAggregate(void* param, bool* newgroup) { SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; - SOperatorInfo* upstream = pOperator->upstream; + SOperatorInfo* upstream = pOperator->upstream[0]; while(1) { SSDataBlock* pBlock = upstream->exec(upstream, newgroup); @@ -4735,7 +4810,7 @@ static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) { SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; - SOperatorInfo* upstream = pOperator->upstream; + SOperatorInfo* upstream = pOperator->upstream[0]; while(1) { SSDataBlock* pBlock = upstream->exec(upstream, newgroup); @@ -4819,7 +4894,7 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) { bool prevVal = *newgroup; // The upstream exec may change the value of the newgroup, so use a local variable instead. - SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + SSDataBlock* pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); if (pBlock == NULL) { assert(*newgroup == false); @@ -4853,7 +4928,7 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) { } pRes->info.rows = getNumOfResult(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); - if (pRes->info.rows >= pRuntimeEnv->resultInfo.threshold) { + if (pRes->info.rows >= 1000/*pRuntimeEnv->resultInfo.threshold*/) { break; } } @@ -4873,7 +4948,7 @@ static SSDataBlock* doLimit(void* param, bool* newgroup) { SSDataBlock* pBlock = NULL; while (1) { - pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); if (pBlock == NULL) { setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); pOperator->status = OP_EXEC_DONE; @@ -4913,27 +4988,6 @@ static SSDataBlock* doLimit(void* param, bool* newgroup) { return pBlock; } - -bool doFilterData(SColumnInfoData* p, int32_t rid, SColumnFilterElem *filterElem, __filter_func_t fp) { - char* input = p->pData + p->info.bytes * rid; - bool isnull = isNull(input, p->info.type); - if (isnull) { - return (fp == isNullOperator) ? true : false; - } else { - if (fp == notNullOperator) { - return true; - } else if (fp == isNullOperator) { - return false; - } - } - - if (fp(filterElem, input, input, p->info.type)) { - return true; - } - - return false; -} - static SSDataBlock* doFilter(void* param, bool* newgroup) { SOperatorInfo *pOperator = (SOperatorInfo *)param; if (pOperator->status == OP_EXEC_DONE) { @@ -4944,7 +4998,7 @@ static SSDataBlock* doFilter(void* param, bool* newgroup) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; while (1) { - SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + SSDataBlock *pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); if (pBlock == NULL) { break; } @@ -4986,7 +5040,7 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { int32_t order = pQueryAttr->order.order; STimeWindow win = pQueryAttr->window; - SOperatorInfo* upstream = pOperator->upstream; + SOperatorInfo* upstream = pOperator->upstream[0]; while(1) { SSDataBlock* pBlock = upstream->exec(upstream, newgroup); @@ -5039,7 +5093,7 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) { SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; - SOperatorInfo* upstream = pOperator->upstream; + SOperatorInfo* upstream = pOperator->upstream[0]; while(1) { SSDataBlock* pBlock = upstream->exec(upstream, newgroup); @@ -5163,7 +5217,7 @@ static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) { SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t order = pQueryAttr->order.order; STimeWindow win = pQueryAttr->window; - SOperatorInfo* upstream = pOperator->upstream; + SOperatorInfo* upstream = pOperator->upstream[0]; while (1) { SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { @@ -5220,7 +5274,7 @@ static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { int32_t order = pQueryAttr->order.order; STimeWindow win = pQueryAttr->window; - SOperatorInfo* upstream = pOperator->upstream; + SOperatorInfo* upstream = pOperator->upstream[0]; while(1) { SSDataBlock* pBlock = upstream->exec(upstream, newgroup); @@ -5271,7 +5325,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { return pInfo->binfo.pRes; } - SOperatorInfo* upstream = pOperator->upstream; + SOperatorInfo* upstream = pOperator->upstream[0]; while(1) { SSDataBlock* pBlock = upstream->exec(upstream, newgroup); @@ -5340,7 +5394,7 @@ static SSDataBlock* doFill(void* param, bool* newgroup) { } while(1) { - SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + SSDataBlock* pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); if (*newgroup) { assert(pBlock != NULL); } @@ -5416,7 +5470,15 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) { pOperator->cleanup(pOperator->info, pOperator->numOfOutput); } - destroyOperatorInfo(pOperator->upstream); + if (pOperator->upstream != NULL) { + for(int32_t i = 0; i < pOperator->numOfUpstream; ++i) { + destroyOperatorInfo(pOperator->upstream[i]); + } + + tfree(pOperator->upstream); + pOperator->numOfUpstream = 0; + } + tfree(pOperator->info); tfree(pOperator); } @@ -5441,13 +5503,14 @@ SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpera pOperator->blockingOptr = true; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doAggregate; pOperator->cleanup = destroyAggOperatorInfo; + appendUpstream(pOperator, upstream); + return pOperator; } @@ -5527,13 +5590,13 @@ SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SO pOperator->blockingOptr = true; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doSTableAggregate; pOperator->cleanup = destroyAggOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5557,63 +5620,62 @@ SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doArithmeticOperation; pOperator->cleanup = destroyArithOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } -SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, - int32_t numOfOutput) { - SFilterOperatorInfo* pInfo = calloc(1, sizeof(SFilterOperatorInfo)); +SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int32_t* numOfFilterCols) { + SColumnInfo* pCols = calloc(numOfOutput, sizeof(SColumnInfo)); - { - SColumnInfo* pCols = calloc(numOfOutput, sizeof(SColumnInfo)); + int32_t numOfFilter = 0; + for(int32_t i = 0; i < numOfOutput; ++i) { + if (pExpr[i].base.flist.numOfFilters > 0) { + numOfFilter += 1; + } - int32_t numOfFilter = 0; - for(int32_t i = 0; i < numOfOutput; ++i) { - if (pExpr[i].base.flist.numOfFilters > 0) { - numOfFilter += 1; - } + pCols[i].type = pExpr[i].base.resType; + pCols[i].bytes = pExpr[i].base.resBytes; + pCols[i].colId = pExpr[i].base.resColId; - pCols[i].type = pExpr[i].base.resType; - pCols[i].bytes = pExpr[i].base.resBytes; - pCols[i].colId = pExpr[i].base.resColId; + pCols[i].flist.numOfFilters = pExpr[i].base.flist.numOfFilters; + pCols[i].flist.filterInfo = calloc(pCols[i].flist.numOfFilters, sizeof(SColumnFilterInfo)); + memcpy(pCols[i].flist.filterInfo, pExpr[i].base.flist.filterInfo, pCols[i].flist.numOfFilters * sizeof(SColumnFilterInfo)); + } - pCols[i].flist.numOfFilters = pExpr[i].base.flist.numOfFilters; - pCols[i].flist.filterInfo = calloc(pCols[i].flist.numOfFilters, sizeof(SColumnFilterInfo)); - memcpy(pCols[i].flist.filterInfo, pExpr[i].base.flist.filterInfo, pCols[i].flist.numOfFilters * sizeof(SColumnFilterInfo)); - } + assert(numOfFilter > 0); - assert(numOfFilter > 0); - doCreateFilterInfo(pCols, numOfOutput, numOfFilter, &pInfo->pFilterInfo, 0); - pInfo->numOfFilterCols = numOfFilter; + *numOfFilterCols = numOfFilter; + return pCols; +} - for(int32_t i = 0; i < numOfOutput; ++i) { - tfree(pCols[i].flist.filterInfo); - } +SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, + int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter) { + SFilterOperatorInfo* pInfo = calloc(1, sizeof(SFilterOperatorInfo)); - tfree(pCols); - } + assert(numOfFilter > 0 && pCols != NULL); + doCreateFilterInfo(pCols, numOfOutput, numOfFilter, &pInfo->pFilterInfo, 0); + pInfo->numOfFilterCols = numOfFilter; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "ConditionOperator"; + pOperator->name = "FilterOperator"; pOperator->operatorType = OP_Filter; pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->numOfOutput = numOfOutput; pOperator->pExpr = pExpr; - pOperator->upstream = upstream; pOperator->exec = doFilter; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->cleanup = destroyConditionOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5628,10 +5690,10 @@ SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI pOperator->operatorType = OP_Limit; pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; - pOperator->upstream = upstream; pOperator->exec = doLimit; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5649,7 +5711,6 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp pOperator->operatorType = OP_TimeWindow; pOperator->blockingOptr = true; pOperator->status = OP_IN_EXECUTING; - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->info = pInfo; @@ -5657,6 +5718,7 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp pOperator->exec = doIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { @@ -5671,13 +5733,14 @@ SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpe pOperator->operatorType = OP_StateWindow; pOperator->blockingOptr = true; pOperator->status = OP_IN_EXECUTING; - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doStateWindowAgg; pOperator->cleanup = destroyStateWindowOperatorInfo; + + appendUpstream(pOperator, upstream); return pOperator; } @@ -5695,7 +5758,6 @@ SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato pOperator->operatorType = OP_SessionWindow; pOperator->blockingOptr = true; pOperator->status = OP_IN_EXECUTING; - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->info = pInfo; @@ -5703,6 +5765,7 @@ SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato pOperator->exec = doSessionWindowAgg; pOperator->cleanup = destroySWindowOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5718,7 +5781,6 @@ SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRunti pOperator->operatorType = OP_MultiTableTimeInterval; pOperator->blockingOptr = true; pOperator->status = OP_IN_EXECUTING; - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->info = pInfo; @@ -5727,6 +5789,7 @@ SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRunti pOperator->exec = doSTableIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5743,7 +5806,6 @@ SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato pOperator->blockingOptr = true; pOperator->status = OP_IN_EXECUTING; pOperator->operatorType = OP_Groupby; - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->info = pInfo; @@ -5751,6 +5813,7 @@ SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato pOperator->exec = hashGroupbyAggregate; pOperator->cleanup = destroyGroupbyOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5780,8 +5843,6 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->operatorType = OP_Fill; - - pOperator->upstream = upstream; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; pOperator->info = pInfo; @@ -5790,6 +5851,7 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn pOperator->exec = doFill; pOperator->cleanup = destroySFillOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5828,11 +5890,12 @@ SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperator pOperator->operatorType = OP_SLimit; pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; - pOperator->upstream = upstream; pOperator->exec = doSLimit; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->cleanup = destroySlimitOperatorInfo; + + appendUpstream(pOperator, upstream); return pOperator; } @@ -5999,7 +6062,7 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) { pRes->info.rows = 0; SSDataBlock* pBlock = NULL; while(1) { - pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup); if (pBlock == NULL) { setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); pOperator->status = OP_EXEC_DONE; @@ -6060,12 +6123,13 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->operatorType = OP_Distinct; - pOperator->upstream = upstream; pOperator->numOfOutput = numOfOutput; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = hashDistinct; pOperator->cleanup = destroyDistinctOperatorInfo; + + appendUpstream(pOperator, upstream); return pOperator; } @@ -6612,7 +6676,7 @@ static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SCol return TSDB_CODE_SUCCESS; } -// TODO tag length should be passed from client +// TODO tag length should be passed from client, refactor int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo, SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg) { *pExprInfo = NULL; @@ -6783,13 +6847,13 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t nu return TSDB_CODE_SUCCESS; } -SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code) { +SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code) { if (pQueryMsg->numOfGroupCols == 0) { return NULL; } // using group by tag columns - SSqlGroupbyExpr *pGroupbyExpr = (SSqlGroupbyExpr *)calloc(1, sizeof(SSqlGroupbyExpr)); + SGroupbyExpr *pGroupbyExpr = (SGroupbyExpr *)calloc(1, sizeof(SGroupbyExpr)); if (pGroupbyExpr == NULL) { *code = TSDB_CODE_QRY_OUT_OF_MEMORY; return NULL; @@ -6807,8 +6871,7 @@ SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex * return pGroupbyExpr; } -static int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, - SSingleColumnFilterInfo** pFilterInfo, uint64_t qId) { +int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId) { *pFilterInfo = calloc(1, sizeof(SSingleColumnFilterInfo) * numOfFilterCols); if (pFilterInfo == NULL) { return TSDB_CODE_QRY_OUT_OF_MEMORY; @@ -6865,7 +6928,7 @@ void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFil return NULL; } -static int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId) { +int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId) { for (int32_t i = 0; i < pQueryAttr->numOfCols; ++i) { if (pQueryAttr->tableCols[i].flist.numOfFilters > 0) { pQueryAttr->numOfFilterCols++; @@ -6950,7 +7013,7 @@ FORCE_INLINE bool checkQIdEqual(void *qHandle, uint64_t qId) { return ((SQInfo *)qHandle)->qId == qId; } -SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs, +SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs, SExprInfo* pSecExprs, STableGroupInfo* pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId, char* sql, uint64_t *qId) { int16_t numOfCols = pQueryMsg->numOfCols; @@ -7254,7 +7317,7 @@ static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) { pTableqinfoGroupInfo->numOfTables = 0; } -static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) { +void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) { if (pExprInfo == NULL) { assert(numOfExpr == 0); return NULL; @@ -7278,6 +7341,20 @@ static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) { return NULL; } +void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols) { + if (pColumnInfo != NULL) { + assert(numOfCols >= 0); + + for (int32_t i = 0; i < numOfCols; i++) { + freeColumnFilterInfo(pColumnInfo[i].flist.filterInfo, pColumnInfo[i].flist.numOfFilters); + } + + tfree(pColumnInfo); + } + + return NULL; +} + void freeQInfo(SQInfo *pQInfo) { if (!isValidQInfo(pQInfo)) { return; @@ -7462,13 +7539,7 @@ void freeQueryAttr(SQueryAttr* pQueryAttr) { tfree(pQueryAttr->tagColList); tfree(pQueryAttr->pFilterInfo); - if (pQueryAttr->tableCols != NULL) { - for (int32_t i = 0; i < pQueryAttr->numOfCols; i++) { - SColumnInfo* column = pQueryAttr->tableCols + i; - freeColumnFilterInfo(column->flist.filterInfo, column->flist.numOfFilters); - } - tfree(pQueryAttr->tableCols); - } + pQueryAttr->tableCols = freeColumnInfo(pQueryAttr->tableCols, pQueryAttr->numOfCols); if (pQueryAttr->pGroupbyExpr != NULL) { taosArrayDestroy(pQueryAttr->pGroupbyExpr->columnInfo); diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index fa572029fc043fc13b9822f1e688696ca9a0a225..7dd73c9fe48be39ee3a7a879348076ac3fbe9f44 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -363,10 +363,6 @@ SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int3 pFillInfo->rowSize = setTagColumnInfo(pFillInfo, pFillInfo->numOfCols, pFillInfo->alloc); assert(pFillInfo->rowSize > 0); - for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) { - pFillInfo->pData[i] = malloc(pFillInfo->pFillCol[i].col.bytes * pFillInfo->alloc); - } - return pFillInfo; } @@ -392,10 +388,6 @@ void* taosDestroyFillInfo(SFillInfo* pFillInfo) { tfree(pFillInfo->pTags[i].tagVal); } - for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) { - tfree(pFillInfo->pData[i]); - } - tfree(pFillInfo->pTags); tfree(pFillInfo->pData); @@ -417,17 +409,6 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey) pFillInfo->index = 0; pFillInfo->numOfRows = numOfRows; - - // ensure the space - if (pFillInfo->alloc < numOfRows) { - for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) { - char* tmp = realloc(pFillInfo->pData[i], numOfRows*pFillInfo->pFillCol[i].col.bytes); - assert(tmp != NULL); // todo handle error - - memset(tmp, 0, numOfRows*pFillInfo->pFillCol[i].col.bytes); - pFillInfo->pData[i] = tmp; - } - } } void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) { @@ -435,16 +416,7 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) SFillColInfo* pCol = &pFillInfo->pFillCol[i]; SColumnInfoData* pColData = taosArrayGet(pInput->pDataBlock, i); -// pFillInfo->pData[i] = pColData->pData; - if (pInput->info.rows > pFillInfo->alloc) { - char* t = realloc(pFillInfo->pData[i], pColData->info.bytes * pInput->info.rows); - assert(t != NULL); - - pFillInfo->pData[i] = t; - pFillInfo->alloc = pInput->info.rows; - } - - memcpy(pFillInfo->pData[i], pColData->pData, pColData->info.bytes * pInput->info.rows); + pFillInfo->pData[i] = pColData->pData; if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { // copy the tag value to tag value buffer SFillTagColInfo* pTag = &pFillInfo->pTags[pCol->tagIndex]; @@ -454,31 +426,6 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) } } -void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* pInput) { - assert(pFillInfo->numOfRows == pInput->num); - - for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) { - SFillColInfo* pCol = &pFillInfo->pFillCol[i]; - - const char* data = pInput->data + pCol->col.offset * pInput->num; - if (pInput->num > pFillInfo->alloc) { - char* t = realloc(pFillInfo->pData[i], (size_t)(pCol->col.bytes * pInput->num)); - assert(t != NULL); - - pFillInfo->pData[i] = t; - pFillInfo->alloc = (int32_t)pInput->num; - } - - memcpy(pFillInfo->pData[i], data, (size_t)(pCol->col.bytes * pInput->num)); - - if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { // copy the tag value to tag value buffer - SFillTagColInfo* pTag = &pFillInfo->pTags[pCol->tagIndex]; - assert (pTag->col.colId == pCol->col.colId); - memcpy(pTag->tagVal, data, pCol->col.bytes); // TODO not memcpy?? - } - } -} - bool taosFillHasMoreResults(SFillInfo* pFillInfo) { int32_t remain = taosNumOfRemainRows(pFillInfo); if (remain > 0) { diff --git a/src/query/src/qHistogram.c b/src/query/src/qHistogram.c index ae25a752347edc4f7c53aade845716d637f9edd7..5fa35d0ee586e72401bca1d984006c39e2e84e98 100644 --- a/src/query/src/qHistogram.c +++ b/src/query/src/qHistogram.c @@ -446,7 +446,7 @@ void tHistogramDestroy(SHistogramInfo** pHisto) { } void tHistogramPrint(SHistogramInfo* pHisto) { - printf("total entries: %d, elements: %d\n", pHisto->numOfEntries, pHisto->numOfElems); + printf("total entries: %d, elements: %"PRId64 "\n", pHisto->numOfEntries, pHisto->numOfElems); #if defined(USE_ARRAYLIST) for (int32_t i = 0; i < pHisto->numOfEntries; ++i) { printf("%d: (%f, %" PRId64 ")\n", i + 1, pHisto->elems[i].val, pHisto->elems[i].num); diff --git a/src/query/src/qPlan.c b/src/query/src/qPlan.c index 7ed0e103276e12f3509d4a2bfeb8af22443bf3de..ca41a926153c3889cf72b4274ca7ac989e0f7df4 100644 --- a/src/query/src/qPlan.c +++ b/src/query/src/qPlan.c @@ -1,44 +1,523 @@ #include "os.h" -#include "tsclient.h" +#include "tschemautil.h" +#include "qPlan.h" +#include "qExecutor.h" #include "qUtil.h" #include "texpr.h" +#include "tscUtil.h" +#include "tsclient.h" + +#define QNODE_TAGSCAN 1 +#define QNODE_TABLESCAN 2 +#define QNODE_PROJECT 3 +#define QNODE_AGGREGATE 4 +#define QNODE_GROUPBY 5 +#define QNODE_LIMIT 6 +#define QNODE_JOIN 7 +#define QNODE_DISTINCT 8 +#define QNODE_SORT 9 +#define QNODE_UNIONALL 10 +#define QNODE_TIMEWINDOW 11 +#define QNODE_SESSIONWINDOW 12 +#define QNODE_FILL 13 + +typedef struct SFillEssInfo { + int32_t fillType; // fill type + int64_t *val; // fill value +} SFillEssInfo; + +typedef struct SJoinCond { + bool tagExists; // denote if tag condition exists or not + SColumn *tagCond[2]; + SColumn *colCond[2]; +} SJoinCond; + +static SQueryNode* createQueryNode(int32_t type, const char* name, SQueryNode** prev, + int32_t numOfPrev, SExprInfo** pExpr, int32_t numOfOutput, SQueryTableInfo* pTableInfo, + void* pExtInfo) { + SQueryNode* pNode = calloc(1, sizeof(SQueryNode)); + + pNode->info.type = type; + pNode->info.name = strdup(name); + + if (pTableInfo->id.uid != 0) { // it is a true table + pNode->tableInfo.id = pTableInfo->id; + pNode->tableInfo.tableName = strdup(pTableInfo->tableName); + } + + pNode->numOfOutput = numOfOutput; + pNode->pExpr = calloc(numOfOutput, sizeof(SExprInfo)); + for(int32_t i = 0; i < numOfOutput; ++i) { + tscExprAssign(&pNode->pExpr[i], pExpr[i]); + } + + pNode->pPrevNodes = taosArrayInit(4, POINTER_BYTES); + for(int32_t i = 0; i < numOfPrev; ++i) { + taosArrayPush(pNode->pPrevNodes, &prev[i]); + } + + switch(type) { + case QNODE_TABLESCAN: { + STimeWindow* window = calloc(1, sizeof(STimeWindow)); + memcpy(window, pExtInfo, sizeof(STimeWindow)); + pNode->pExtInfo = window; + break; + } + + case QNODE_TIMEWINDOW: { + SInterval* pInterval = calloc(1, sizeof(SInterval)); + pNode->pExtInfo = pInterval; + memcpy(pInterval, pExtInfo, sizeof(SInterval)); + break; + } + + case QNODE_GROUPBY: { + SGroupbyExpr* p = (SGroupbyExpr*) pExtInfo; + SGroupbyExpr* pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr)); + + pGroupbyExpr->tableIndex = p->tableIndex; + pGroupbyExpr->orderType = p->orderType; + pGroupbyExpr->orderIndex = p->orderIndex; + pGroupbyExpr->numOfGroupCols = p->numOfGroupCols; + pGroupbyExpr->columnInfo = taosArrayDup(p->columnInfo); + pNode->pExtInfo = pGroupbyExpr; + break; + } + + case QNODE_FILL: { // todo !! + pNode->pExtInfo = pExtInfo; + break; + } + + case QNODE_LIMIT: { + pNode->pExtInfo = calloc(1, sizeof(SLimitVal)); + memcpy(pNode->pExtInfo, pExtInfo, sizeof(SLimitVal)); + break; + } + } + return pNode; +} + +static SQueryNode* doAddTableColumnNode(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SQueryTableInfo* info, + SArray* pExprs, SArray* tableCols) { + if (pQueryInfo->onlyTagQuery) { + int32_t num = (int32_t) taosArrayGetSize(pExprs); + SQueryNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, info, NULL); + + if (pQueryInfo->distinctTag) { + pNode = createQueryNode(QNODE_DISTINCT, "Distinct", &pNode, 1, pExprs->pData, num, info, NULL); + } + + return pNode; + } + + STimeWindow* window = &pQueryInfo->window; + SQueryNode* pNode = createQueryNode(QNODE_TABLESCAN, "TableScan", NULL, 0, NULL, 0, + info, window); + if (pQueryInfo->projectionQuery) { + int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs); + pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExprs->pData, numOfOutput, info, NULL); + } else { + // table source column projection, generate the projection expr + int32_t numOfCols = (int32_t) taosArrayGetSize(tableCols); + SExprInfo** pExpr = calloc(numOfCols, POINTER_BYTES); + SSchema* pSchema = pTableMetaInfo->pTableMeta->schema; + + for (int32_t i = 0; i < numOfCols; ++i) { + SColumn* pCol = taosArrayGetP(tableCols, i); + + SColumnIndex index = {.tableIndex = 0, .columnIndex = pCol->columnIndex}; + SExprInfo* p = tscExprCreate(pQueryInfo, TSDB_FUNC_PRJ, &index, 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)); + + pExpr[i] = p; + } + + pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExpr, numOfCols, info, NULL); + for (int32_t i = 0; i < numOfCols; ++i) { + destroyQueryFuncExpr(pExpr[i], 1); + } + tfree(pExpr); + } + + return pNode; +} + +static SQueryNode* doCreateQueryPlanForOneTableImpl(SQueryInfo* pQueryInfo, SQueryNode* pNode, SQueryTableInfo* info, + SArray* pExprs) { + // check for aggregation + if (pQueryInfo->interval.interval > 0) { + int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs); + + pNode = createQueryNode(QNODE_TIMEWINDOW, "TimeWindowAgg", &pNode, 1, pExprs->pData, numOfOutput, info, + &pQueryInfo->interval); + } else if (pQueryInfo->groupbyColumn) { + int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs); + pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, pExprs->pData, numOfOutput, info, + &pQueryInfo->groupbyExpr); + } else if (pQueryInfo->sessionWindow.gap > 0) { + pNode = createQueryNode(QNODE_SESSIONWINDOW, "SessionWindowAgg", &pNode, 1, NULL, 0, info, NULL); + } else if (pQueryInfo->simpleAgg) { + int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs); + pNode = createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, pExprs->pData, numOfOutput, info, NULL); + } + + if (pQueryInfo->havingFieldNum > 0 || pQueryInfo->arithmeticOnAgg) { + int32_t numOfExpr = (int32_t) taosArrayGetSize(pQueryInfo->exprList1); + pNode = + createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pQueryInfo->exprList1->pData, numOfExpr, info, NULL); + } + + if (pQueryInfo->fillType != TSDB_FILL_NONE) { + SFillEssInfo* pInfo = calloc(1, sizeof(SFillEssInfo)); + pInfo->fillType = pQueryInfo->fillType; + pInfo->val = calloc(pNode->numOfOutput, sizeof(int64_t)); + memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfOutput); + + pNode = createQueryNode(QNODE_FILL, "Fill", &pNode, 1, NULL, 0, info, pInfo); + } + + + if (pQueryInfo->limit.limit != -1 || pQueryInfo->limit.offset != 0) { + pNode = createQueryNode(QNODE_LIMIT, "Limit", &pNode, 1, NULL, 0, info, &pQueryInfo->limit); + } + + return pNode; +} + +static SQueryNode* doCreateQueryPlanForOneTable(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs, + SArray* tableCols) { + char name[TSDB_TABLE_FNAME_LEN] = {0}; + tNameExtractFullName(&pTableMetaInfo->name, name); + + SQueryTableInfo info = {.tableName = strdup(name), .id = pTableMetaInfo->pTableMeta->id,}; + + // handle the only tag query + SQueryNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, pExprs, tableCols); + if (pQueryInfo->onlyTagQuery) { + tfree(info.tableName); + return pNode; + } + + SQueryNode* pNode1 = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pExprs); + tfree(info.tableName); + return pNode1; +} + +SArray* createQueryPlanImpl(SQueryInfo* pQueryInfo) { + SArray* upstream = NULL; + + if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // subquery in the from clause + upstream = taosArrayInit(4, POINTER_BYTES); + + size_t size = taosArrayGetSize(pQueryInfo->pUpstream); + for(int32_t i = 0; i < size; ++i) { + SQueryInfo* pq = taosArrayGet(pQueryInfo->pUpstream, i); + SArray* p = createQueryPlanImpl(pq); + taosArrayAddBatch(upstream, p->pData, (int32_t) taosArrayGetSize(p)); + } + } + + if (pQueryInfo->numOfTables > 1) { // it is a join query + // 1. separate the select clause according to table + upstream = taosArrayInit(5, POINTER_BYTES); + + for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { + STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[i]; + uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; + + SArray* exprList = taosArrayInit(4, POINTER_BYTES); + if (tscExprCopy(exprList, pQueryInfo->exprList, uid, true) != 0) { + terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; + exit(-1); + } + + // 2. create the query execution node + char name[TSDB_TABLE_FNAME_LEN] = {0}; + tNameExtractFullName(&pTableMetaInfo->name, name); + SQueryTableInfo info = {.tableName = strdup(name), .id = pTableMetaInfo->pTableMeta->id,}; + + // 3. get the required table column list + SArray* tableColumnList = taosArrayInit(4, sizeof(SColumn)); + tscColumnListCopy(tableColumnList, pQueryInfo->colList, uid); + + // 4. add the projection query node + SQueryNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, exprList, tableColumnList); + taosArrayPush(upstream, &pNode); + } + + // 3. add the join node here + SQueryTableInfo info = {0}; + int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList); + SQueryNode* pNode = createQueryNode(QNODE_JOIN, "Join", upstream->pData, pQueryInfo->numOfTables, + pQueryInfo->exprList->pData, num, &info, NULL); + + // 4. add the aggregation or projection execution node + pNode = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pQueryInfo->exprList); + upstream = taosArrayInit(5, POINTER_BYTES); + taosArrayPush(upstream, &pNode); + } else { // only one table, normal query process + STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; + SQueryNode* pNode = doCreateQueryPlanForOneTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList, pQueryInfo->colList); + upstream = taosArrayInit(5, POINTER_BYTES); + taosArrayPush(upstream, &pNode); + } + + return upstream; +} -#define QNODE_PROJECT 1 -#define QNODE_FILTER 2 -#define QNODE_RELATION 3 -#define QNODE_AGGREGATE 4 -#define QNODE_GROUPBY 5 -#define QNODE_LIMIT 6 -#define QNODE_JOIN 7 -#define QNODE_DIST 8 -#define QNODE_SORT 9 -#define QNODE_UNIONALL 10 -#define QNODE_TIMEWINDOW 11 - -typedef struct SQueryNode { - int32_t type; // the type of logic node - char *name; // the name of logic node - - SSchema *pSchema; // the schema of the input SSDatablock - int32_t numOfCols; // number of input columns - SExprInfo *pExpr; // the query functions or sql aggregations - int32_t numOfOutput; // number of result columns, which is also the number of pExprs - - // previous operator to generated result for current node to process - // in case of join, multiple prev nodes exist. - struct SQueryNode* prevNode; - struct SQueryNode* nextNode; -} SQueryNode; - -// TODO create the query plan SQueryNode* qCreateQueryPlan(SQueryInfo* pQueryInfo) { - return NULL; + SArray* upstream = createQueryPlanImpl(pQueryInfo); + assert(taosArrayGetSize(upstream) == 1); + + SQueryNode* p = taosArrayGetP(upstream, 0); + taosArrayDestroy(upstream); + + return p; } -char* queryPlanToString() { +static void doDestroyQueryNode(SQueryNode* pQueryNode) { + tfree(pQueryNode->pExtInfo); + tfree(pQueryNode->pSchema); + tfree(pQueryNode->info.name); + + tfree(pQueryNode->tableInfo.tableName); + + pQueryNode->pExpr = destroyQueryFuncExpr(pQueryNode->pExpr, pQueryNode->numOfOutput); + + if (pQueryNode->pPrevNodes != NULL) { + int32_t size = (int32_t) taosArrayGetSize(pQueryNode->pPrevNodes); + for(int32_t i = 0; i < size; ++i) { + SQueryNode* p = taosArrayGetP(pQueryNode->pPrevNodes, i); + doDestroyQueryNode(p); + } + + taosArrayDestroy(pQueryNode->pPrevNodes); + } + + tfree(pQueryNode); +} + +void* qDestroyQueryPlan(SQueryNode* pQueryNode) { + if (pQueryNode == NULL) { + return NULL; + } + + doDestroyQueryNode(pQueryNode); return NULL; } +bool hasAliasName(SExprInfo* pExpr) { + assert(pExpr != NULL); + return strncmp(pExpr->base.token, pExpr->base.aliasName, tListLen(pExpr->base.aliasName)) != 0; +} + +static int32_t doPrintPlan(char* buf, SQueryNode* pQueryNode, int32_t level, int32_t totalLen) { + if (level > 0) { + sprintf(buf + totalLen, "%*c", level, ' '); + totalLen += level; + } + + int32_t len1 = sprintf(buf + totalLen, "%s(", pQueryNode->info.name); + int32_t len = len1 + totalLen; + + switch(pQueryNode->info.type) { + case QNODE_TABLESCAN: { + STimeWindow* win = (STimeWindow*)pQueryNode->pExtInfo; + len1 = sprintf(buf + len, "%s #0x%" PRIx64 ") time_range: %" PRId64 " - %" PRId64 "\n", + pQueryNode->tableInfo.tableName, pQueryNode->tableInfo.id.uid, win->skey, win->ekey); + len += len1; + break; + } + + case QNODE_PROJECT: { + len1 = sprintf(buf + len, "cols: "); + len += len1; + + for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) { + SSqlExpr* p = &pQueryNode->pExpr[i].base; + len1 = sprintf(buf + len, "[%s #%d]", p->aliasName, p->resColId); + len += len1; + + if (i < pQueryNode->numOfOutput - 1) { + len1 = sprintf(buf + len, ", "); + len += len1; + } + } + + len1 = sprintf(buf + len, ")"); + len += len1; + + //todo print filter info + len1 = sprintf(buf + len, " filters:(nil)\n"); + len += len1; + break; + } + + case QNODE_AGGREGATE: { + for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) { + SSqlExpr* pExpr = &pQueryNode->pExpr[i].base; + if (hasAliasName(&pQueryNode->pExpr[i])) { + len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->aliasName); + } else { + len1 = sprintf(buf + len,"[%s]", pExpr->token); + } + + len += len1; + if (i < pQueryNode->numOfOutput - 1) { + len1 = sprintf(buf + len, ", "); + len += len1; + } + } + + len1 = sprintf(buf + len, ")\n"); + len += len1; + break; + } + + case QNODE_TIMEWINDOW: { + for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) { + SSqlExpr* pExpr = &pQueryNode->pExpr[i].base; + if (hasAliasName(&pQueryNode->pExpr[i])) { + len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->aliasName); + } else { + len1 = sprintf(buf + len,"[%s]", pExpr->token); + } + + len += len1; + if (i < pQueryNode->numOfOutput - 1) { + len1 = sprintf(buf + len,", "); + len += len1; + } + } + + len1 = sprintf(buf + len,") "); + len += len1; + + SInterval* pInterval = pQueryNode->pExtInfo; + len1 = sprintf(buf + len, "interval:%" PRId64 "(%c), sliding:%" PRId64 "(%c), offset:%" PRId64 "\n", + pInterval->interval, pInterval->intervalUnit, pInterval->sliding, pInterval->slidingUnit, + pInterval->offset); + len += len1; + + break; + } + + case QNODE_GROUPBY: { // todo hide the invisible column + for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) { + SSqlExpr* pExpr = &pQueryNode->pExpr[i].base; + + if (hasAliasName(&pQueryNode->pExpr[i])) { + len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->aliasName); + } else { + len1 = sprintf(buf + len,"[%s]", pExpr->token); + } + + len += len1; + if (i < pQueryNode->numOfOutput - 1) { + len1 = sprintf(buf + len,", "); + len += len1; + } + } + + SGroupbyExpr* pGroupbyExpr = pQueryNode->pExtInfo; + SColIndex* pIndex = taosArrayGet(pGroupbyExpr->columnInfo, 0); + + len1 = sprintf(buf + len,") groupby_col: [%s #%d]\n", pIndex->name, pIndex->colId); + len += len1; + + break; + } + + case QNODE_FILL: { + SFillEssInfo* pEssInfo = pQueryNode->pExtInfo; + len1 = sprintf(buf + len,"%d", pEssInfo->fillType); + len += len1; + + if (pEssInfo->fillType == TSDB_FILL_SET_VALUE) { + len1 = sprintf(buf + len,", val:"); + len += len1; + + // todo get the correct fill data type + for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) { + len1 = sprintf(buf + len,"%"PRId64, pEssInfo->val[i]); + len += len1; + + if (i < pQueryNode->numOfOutput - 1) { + len1 = sprintf(buf + len,", "); + len += len1; + } + } + } + + len1 = sprintf(buf + len,")\n"); + len += len1; + break; + } + + case QNODE_LIMIT: { + SLimitVal* pVal = pQueryNode->pExtInfo; + len1 = sprintf(buf + len,"limit: %"PRId64", offset: %"PRId64")\n", pVal->limit, pVal->offset); + len += len1; + break; + } + + case QNODE_DISTINCT: + case QNODE_TAGSCAN: { + len1 = sprintf(buf + len,"cols: "); + len += len1; + + for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) { + SSqlExpr* p = &pQueryNode->pExpr[i].base; + len1 = sprintf(buf + len,"[%s #%d]", p->aliasName, p->resColId); + len += len1; + + if (i < pQueryNode->numOfOutput - 1) { + len1 = sprintf(buf + len,", "); + len += len1; + } + } + + len1 = sprintf(buf + len,")\n"); + len += len1; + + break; + } + + case QNODE_JOIN: { + // print join condition + len1 = sprintf(buf + len, ")\n"); + len += len1; + break; + } + } + + return len; +} + +int32_t queryPlanToStringImpl(char* buf, SQueryNode* pQueryNode, int32_t level, int32_t totalLen) { + int32_t len = doPrintPlan(buf, pQueryNode, level, totalLen); + + for(int32_t i = 0; i < taosArrayGetSize(pQueryNode->pPrevNodes); ++i) { + SQueryNode* p1 = taosArrayGetP(pQueryNode->pPrevNodes, i); + int32_t len1 = queryPlanToStringImpl(buf, p1, level + 1, len); + len = len1; + } + + return len; +} + +char* queryPlanToString(SQueryNode* pQueryNode) { + assert(pQueryNode); + + char* buf = calloc(1, 4096); + + int32_t len = sprintf(buf, "===== logic plan =====\n"); + queryPlanToStringImpl(buf, pQueryNode, 0, len); + return buf; +} + SQueryNode* queryPlanFromString() { return NULL; } @@ -144,8 +623,13 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) { taosArrayPush(plan, &op); } } else { // diff/add/multiply/subtract/division - op = OP_Arithmetic; - taosArrayPush(plan, &op); + if (pQueryAttr->numOfFilterCols > 0 && pQueryAttr->vgId == 0) { // todo refactor + op = OP_Filter; + taosArrayPush(plan, &op); + } else { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } } if (pQueryAttr->limit.limit > 0 || pQueryAttr->limit.offset > 0) { diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index 8432edc6ee12061692588b7bcc1de1e759fd9bb4..efe35ba72b51a4bbc7c2b838eced738de3eedd6f 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -13,13 +13,13 @@ * along with this program. If not, see . */ -#include "os.h" #include "qSqlparser.h" +#include "os.h" #include "taosdef.h" #include "taosmsg.h" #include "tcmdtype.h" -#include "tstoken.h" #include "tstrbuild.h" +#include "ttoken.h" #include "ttokendef.h" #include "tutil.h" @@ -38,7 +38,7 @@ SSqlInfo qSqlParse(const char *pStr) { goto abort_parse; } - t0.n = tSQLGetToken((char *)&pStr[i], &t0.type); + t0.n = tGetToken((char *)&pStr[i], &t0.type); t0.z = (char *)(pStr + i); i += t0.n; @@ -229,7 +229,6 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) { pExpr->flags &= ~(1 << EXPR_FLAG_TS_ERROR); } - switch (optrType) { case TK_PLUS: { pExpr->value.i64 = pLeft->value.i64 + pRight->value.i64; @@ -325,7 +324,6 @@ static FORCE_INLINE int32_t tStrTokenCompare(SStrToken* left, SStrToken* right) return (left->type == right->type && left->n == right->n && strncasecmp(left->z, right->z, left->n) == 0) ? 0 : 1; } - int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) { if ((left == NULL && right) || (left && right == NULL)) { return 1; @@ -389,8 +387,6 @@ int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) { return 0; } - - tSqlExpr *tSqlExprClone(tSqlExpr *pSrc) { tSqlExpr *pExpr = calloc(1, sizeof(tSqlExpr)); @@ -536,11 +532,11 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, SStrToken* pAlias) { if (pRelationInfo == NULL) { pRelationInfo = calloc(1, sizeof(SRelationInfo)); - pRelationInfo->list = taosArrayInit(4, sizeof(STableNamePair)); + pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair)); } pRelationInfo->type = SQL_NODE_FROM_TABLELIST; - STableNamePair p = {.name = *pName}; + SRelElementPair p = {.tableName = *pName}; if (pAlias != NULL) { p.aliasName = *pAlias; } else { @@ -551,18 +547,6 @@ SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, return pRelationInfo; } -SRelationInfo* setSubquery(SRelationInfo* pRelationInfo, SArray* pList) { - if (pRelationInfo == NULL) { - pRelationInfo = calloc(1, sizeof(SRelationInfo)); - pRelationInfo->list = taosArrayInit(4, POINTER_BYTES); - } - - pRelationInfo->type = SQL_NODE_FROM_SUBQUERY; - taosArrayPush(pRelationInfo->list, &pList); - - return pRelationInfo; -} - void* destroyRelationInfo(SRelationInfo* pRelationInfo) { if (pRelationInfo == NULL) { return NULL; @@ -573,7 +557,7 @@ void* destroyRelationInfo(SRelationInfo* pRelationInfo) { } else { size_t size = taosArrayGetSize(pRelationInfo->list); for(int32_t i = 0; i < size; ++i) { - SArray* pa = taosArrayGetP(pRelationInfo->list, 0); + SArray* pa = taosArrayGetP(pRelationInfo->list, i); destroyAllSqlNode(pa); } taosArrayDestroy(pRelationInfo->list); @@ -583,6 +567,24 @@ void* destroyRelationInfo(SRelationInfo* pRelationInfo) { return NULL; } +SRelationInfo* addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrToken* pAlias) { + if (pRelationInfo == NULL) { + pRelationInfo = calloc(1, sizeof(SRelationInfo)); + pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair)); + } + + pRelationInfo->type = SQL_NODE_FROM_SUBQUERY; + + SRelElementPair p = {.pSubquery = pSub}; + if (pAlias != NULL) { + p.aliasName = *pAlias; + } else { + TPARSER_SET_NONE_TOKEN(p.aliasName); + } + + taosArrayPush(pRelationInfo->list, &p); + return pRelationInfo; +} void tSetDbName(SStrToken *pCpxName, SStrToken *pDb) { pCpxName->type = pDb->type; @@ -592,14 +594,14 @@ void tSetDbName(SStrToken *pCpxName, SStrToken *pDb) { void tSetColumnInfo(TAOS_FIELD *pField, SStrToken *pName, TAOS_FIELD *pType) { int32_t maxLen = sizeof(pField->name) / sizeof(pField->name[0]); - - // truncate the column name - if ((int32_t)pName->n >= maxLen) { - pName->n = maxLen - 1; - } - strncpy(pField->name, pName->z, pName->n); - pField->name[pName->n] = 0; + // column name is too long, set the it to be invalid. + if ((int32_t) pName->n >= maxLen) { + pName->n = -1; + } else { + strncpy(pField->name, pName->z, pName->n); + pField->name[pName->n] = 0; + } pField->type = pType->type; if(!isValidDataType(pField->type)){ diff --git a/src/query/src/sql.c b/src/query/src/sql.c index 363941950f46043270b39468aa00a0c56fa44629..9909ef2e13d7d3515ced362b933d883e36ef0698 100644 --- a/src/query/src/sql.c +++ b/src/query/src/sql.c @@ -1,29 +1,9 @@ -/* -** 2000-05-29 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** Driver template for the LEMON parser generator. -** -** The "lemon" program processes an LALR(1) input grammar file, then uses -** this template to construct a parser. The "lemon" program inserts text -** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the -** interstitial "-" characters) contained in this template is changed into -** the value of the %name directive from the grammar. Otherwise, the content -** of this template is copied straight through into the generate parser -** source file. -** -** The following is the concatenation of all %include directives from the -** input grammar file: +/* Driver template for the LEMON parser generator. +** The author disclaims copyright to this source code. */ +/* First off, code is included that follows the "include" declaration +** in the input grammar file. */ #include -/************ Begin %include sections from the grammar ************************/ #include #include @@ -32,93 +12,82 @@ #include #include "qSqlparser.h" #include "tcmdtype.h" -#include "tstoken.h" +#include "ttoken.h" #include "ttokendef.h" #include "tutil.h" #include "tvariant.h" -/**************** End of %include directives **********************************/ -/* These constants specify the various numeric values for terminal symbols -** in a format understandable to "makeheaders". This section is blank unless -** "lemon" is run with the "-m" command-line option. -***************** Begin makeheaders token definitions *************************/ -/**************** End makeheaders token definitions ***************************/ - -/* The next sections is a series of control #defines. +/* Next is all token values, in a form suitable for use by makeheaders. +** This section will be null unless lemon is run with the -m switch. +*/ +/* +** These constants (all generated automatically by the parser generator) +** specify the various kinds of tokens (terminals) that the parser +** understands. +** +** Each symbol here is a terminal symbol in the grammar. +*/ +/* Make sure the INTERFACE macro is defined. +*/ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/* The next thing included is series of defines which control ** various aspects of the generated parser. -** YYCODETYPE is the data type used to store the integer codes -** that represent terminal and non-terminal symbols. -** "unsigned char" is used if there are fewer than -** 256 symbols. Larger types otherwise. -** YYNOCODE is a number of type YYCODETYPE that is not used for -** any terminal or nonterminal symbol. +** YYCODETYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 terminals +** and nonterminals. "int" is used otherwise. +** YYNOCODE is a number of type YYCODETYPE which corresponds +** to no legal terminal or nonterminal number. This +** number is used to fill in empty slots of the hash +** table. ** YYFALLBACK If defined, this indicates that one or more tokens -** (also known as: "terminal symbols") have fall-back -** values which should be used if the original symbol -** would not parse. This permits keywords to sometimes -** be used as identifiers, for example. -** YYACTIONTYPE is the data type used for "action codes" - numbers -** that indicate what to do in response to the next -** token. -** ParseTOKENTYPE is the data type used for minor type for terminal -** symbols. Background: A "minor type" is a semantic -** value associated with a terminal or non-terminal -** symbols. For example, for an "ID" terminal symbol, -** the minor type might be the name of the identifier. -** Each non-terminal can have a different minor type. -** Terminal symbols all have the same minor type, though. -** This macros defines the minor type for terminal -** symbols. -** YYMINORTYPE is the data type used for all minor types. +** have fall-back values which should be used if the +** original value of the token will not parse. +** YYACTIONTYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 rules and +** states combined. "int" is used otherwise. +** ParseTOKENTYPE is the data type used for minor tokens given +** directly to the parser from the tokenizer. +** YYMINORTYPE is the data type used for all minor tokens. ** This is typically a union of many types, one of ** which is ParseTOKENTYPE. The entry in the union -** for terminal symbols is called "yy0". +** for base tokens is called "yy0". ** YYSTACKDEPTH is the maximum depth of the parser's stack. If ** zero the stack is dynamically sized using realloc() ** ParseARG_SDECL A static variable declaration for the %extra_argument ** ParseARG_PDECL A parameter declaration for the %extra_argument ** ParseARG_STORE Code to store %extra_argument into yypParser ** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. ** YYNSTATE the combined number of states. ** YYNRULE the number of rules in the grammar -** YYNTOKEN Number of terminal symbols -** YY_MAX_SHIFT Maximum value for shift actions -** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions -** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions -** YY_ERROR_ACTION The yy_action[] code for syntax error -** YY_ACCEPT_ACTION The yy_action[] code for accept -** YY_NO_ACTION The yy_action[] code for no-op -** YY_MIN_REDUCE Minimum value for reduce actions -** YY_MAX_REDUCE Maximum value for reduce actions +** YYERRORSYMBOL is the code number of the error symbol. If not +** defined, then do no error processing. */ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 266 +#define YYNOCODE 267 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SStrToken typedef union { int yyinit; ParseTOKENTYPE yy0; - SSqlNode* yy6; - SLimitVal yy74; - SCreateDbInfo yy122; - SSessionWindowVal yy139; - TAOS_FIELD yy153; - SWindowStateVal yy158; - int64_t yy179; - SCreateAcctInfo yy211; - tVariant yy216; - SRelationInfo* yy254; - SArray* yy291; - int yy382; - SIntervalVal yy400; - SCreateTableSql* yy412; - tSqlExpr* yy436; - SCreatedTableInfo yy446; + TAOS_FIELD yy27; + SWindowStateVal yy76; + SCreateDbInfo yy114; + SSqlNode* yy124; + SCreateAcctInfo yy183; + SCreatedTableInfo yy192; + SArray* yy193; + SCreateTableSql* yy270; + int yy312; + SRelationInfo* yy332; + SIntervalVal yy392; + tVariant yy442; + SSessionWindowVal yy447; + tSqlExpr* yy454; + int64_t yy473; + SLimitVal yy482; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -127,19 +96,16 @@ typedef union { #define ParseARG_PDECL ,SSqlInfo* pInfo #define ParseARG_FETCH SSqlInfo* pInfo = yypParser->pInfo #define ParseARG_STORE yypParser->pInfo = pInfo +#define YYNSTATE 523 +#define YYNRULE 275 #define YYFALLBACK 1 -#define YYNSTATE 321 -#define YYNRULE 272 -#define YYNTOKEN 188 -#define YY_MAX_SHIFT 320 -#define YY_MIN_SHIFTREDUCE 516 -#define YY_MAX_SHIFTREDUCE 787 -#define YY_ERROR_ACTION 788 -#define YY_ACCEPT_ACTION 789 -#define YY_NO_ACTION 790 -#define YY_MIN_REDUCE 791 -#define YY_MAX_REDUCE 1062 -/************* End control #defines *******************************************/ +#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) +#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) +#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) + +/* The yyzerominor constant is used to initialize instances of +** YYMINORTYPE objects to zero. */ +static const YYMINORTYPE yyzerominor = { 0 }; /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. @@ -162,35 +128,33 @@ typedef union { ** Suppose the action integer is N. Then the action is determined as ** follows ** -** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead +** 0 <= N < YYNSTATE Shift N. That is, push the lookahead ** token onto the stack and goto state N. ** -** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then -** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE. +** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. ** -** N == YY_ERROR_ACTION A syntax error has occurred. +** N == YYNSTATE+YYNRULE A syntax error has occurred. ** -** N == YY_ACCEPT_ACTION The parser accepts its input. +** N == YYNSTATE+YYNRULE+1 The parser accepts its input. ** -** N == YY_NO_ACTION No such action. Denotes unused +** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused ** slots in the yy_action[] table. ** -** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE -** and YY_MAX_REDUCE -** ** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as either: +** Given state S and lookahead X, the action is computed as ** -** (A) N = yy_action[ yy_shift_ofst[S] + X ] -** (B) N = yy_default[S] +** yy_action[ yy_shift_ofst[S] + X ] ** -** The (A) formula is preferred. The B formula is used instead if -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X. +** If the index value yy_shift_ofst[S]+X is out of range or if the value +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table +** and that yy_default[S] should be used instead. ** -** The formulas above are for computing the action when the lookahead is +** The formula above is for computing the action when the lookahead is ** a terminal symbol. If the lookahead is a non-terminal (as occurs after ** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array. +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of +** YY_SHIFT_USE_DFLT. ** ** The following are the tables generated in this section: ** @@ -202,271 +166,298 @@ typedef union { ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. -** -*********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (683) +*/ +#define YY_ACTTAB_COUNT (811) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 932, 564, 208, 318, 213, 959, 671, 142, 672, 565, - /* 10 */ 789, 320, 17, 47, 48, 142, 51, 52, 30, 185, - /* 20 */ 219, 41, 185, 50, 268, 55, 53, 57, 54, 1043, - /* 30 */ 938, 216, 1044, 46, 45, 183, 185, 44, 43, 42, - /* 40 */ 47, 48, 225, 51, 52, 215, 1044, 219, 41, 564, - /* 50 */ 50, 268, 55, 53, 57, 54, 950, 565, 224, 210, - /* 60 */ 46, 45, 935, 142, 44, 43, 42, 48, 956, 51, - /* 70 */ 52, 30, 246, 219, 41, 992, 50, 268, 55, 53, - /* 80 */ 57, 54, 135, 993, 938, 263, 46, 45, 284, 230, - /* 90 */ 44, 43, 42, 517, 518, 519, 520, 521, 522, 523, - /* 100 */ 524, 525, 526, 527, 528, 529, 319, 643, 86, 209, - /* 110 */ 70, 564, 222, 47, 48, 935, 51, 52, 304, 565, - /* 120 */ 219, 41, 564, 50, 268, 55, 53, 57, 54, 265, - /* 130 */ 565, 79, 731, 46, 45, 294, 293, 44, 43, 42, - /* 140 */ 47, 49, 926, 51, 52, 837, 251, 219, 41, 169, - /* 150 */ 50, 268, 55, 53, 57, 54, 317, 316, 127, 232, - /* 160 */ 46, 45, 291, 290, 44, 43, 42, 23, 282, 313, - /* 170 */ 312, 281, 280, 279, 311, 278, 310, 309, 308, 277, - /* 180 */ 307, 306, 898, 30, 886, 887, 888, 889, 890, 891, - /* 190 */ 892, 893, 894, 895, 896, 897, 899, 900, 51, 52, - /* 200 */ 189, 950, 219, 41, 924, 50, 268, 55, 53, 57, - /* 210 */ 54, 1040, 18, 83, 25, 46, 45, 211, 231, 44, - /* 220 */ 43, 42, 218, 746, 223, 30, 735, 935, 738, 194, - /* 230 */ 741, 218, 746, 226, 12, 735, 195, 738, 85, 741, - /* 240 */ 82, 119, 118, 193, 921, 922, 29, 925, 55, 53, - /* 250 */ 57, 54, 269, 936, 204, 205, 46, 45, 267, 938, - /* 260 */ 44, 43, 42, 204, 205, 238, 287, 228, 23, 935, - /* 270 */ 313, 312, 74, 242, 241, 311, 1054, 310, 309, 308, - /* 280 */ 36, 307, 306, 284, 906, 46, 45, 904, 905, 44, - /* 290 */ 43, 42, 907, 142, 909, 910, 908, 314, 911, 912, - /* 300 */ 104, 98, 109, 245, 737, 68, 740, 108, 114, 117, - /* 310 */ 107, 201, 667, 682, 69, 664, 111, 665, 30, 666, - /* 320 */ 5, 33, 159, 938, 30, 56, 30, 158, 93, 88, - /* 330 */ 92, 30, 747, 736, 56, 739, 28, 229, 743, 274, - /* 340 */ 286, 747, 81, 233, 234, 74, 923, 743, 750, 106, - /* 350 */ 177, 175, 173, 36, 304, 742, 71, 172, 122, 121, - /* 360 */ 120, 80, 934, 1039, 742, 288, 689, 292, 935, 846, - /* 370 */ 935, 217, 296, 169, 249, 935, 44, 43, 42, 133, - /* 380 */ 131, 130, 838, 1, 157, 1038, 169, 3, 170, 712, - /* 390 */ 713, 686, 679, 733, 247, 61, 695, 703, 31, 24, - /* 400 */ 137, 60, 704, 767, 64, 748, 20, 19, 653, 19, - /* 410 */ 271, 202, 31, 655, 31, 6, 744, 60, 62, 273, - /* 420 */ 654, 668, 39, 84, 60, 65, 97, 96, 67, 734, - /* 430 */ 642, 203, 14, 13, 1003, 103, 102, 116, 115, 1002, - /* 440 */ 16, 15, 669, 187, 670, 745, 937, 188, 190, 184, - /* 450 */ 191, 192, 198, 220, 199, 197, 182, 196, 243, 186, - /* 460 */ 134, 999, 998, 221, 295, 153, 958, 966, 985, 968, - /* 470 */ 136, 140, 257, 984, 951, 250, 154, 933, 132, 252, - /* 480 */ 143, 212, 931, 694, 254, 261, 155, 305, 152, 150, - /* 490 */ 148, 146, 144, 948, 156, 266, 849, 66, 276, 37, - /* 500 */ 63, 180, 58, 145, 34, 285, 264, 262, 845, 260, - /* 510 */ 1059, 94, 1058, 1056, 160, 289, 147, 1053, 100, 1052, - /* 520 */ 258, 1050, 161, 867, 35, 32, 38, 181, 834, 110, - /* 530 */ 832, 256, 112, 113, 830, 829, 235, 171, 827, 826, - /* 540 */ 825, 824, 823, 822, 174, 176, 819, 817, 815, 813, - /* 550 */ 178, 810, 179, 253, 40, 248, 72, 75, 255, 105, - /* 560 */ 986, 297, 298, 299, 300, 301, 206, 302, 227, 275, - /* 570 */ 303, 315, 787, 236, 207, 200, 89, 237, 90, 786, - /* 580 */ 239, 240, 785, 773, 772, 244, 249, 674, 828, 821, - /* 590 */ 164, 820, 868, 123, 162, 167, 163, 165, 166, 168, - /* 600 */ 124, 125, 126, 902, 812, 4, 811, 270, 2, 8, - /* 610 */ 73, 76, 151, 149, 696, 699, 139, 138, 77, 914, - /* 620 */ 701, 78, 214, 259, 85, 705, 141, 26, 9, 749, - /* 630 */ 27, 7, 10, 11, 751, 21, 22, 272, 87, 606, - /* 640 */ 602, 600, 599, 598, 595, 568, 283, 91, 31, 59, - /* 650 */ 645, 644, 641, 590, 588, 580, 586, 582, 584, 578, - /* 660 */ 576, 609, 608, 607, 605, 95, 99, 604, 101, 603, - /* 670 */ 601, 597, 596, 60, 566, 533, 531, 791, 790, 790, - /* 680 */ 790, 128, 129, + /* 0 */ 506, 47, 46, 523, 31, 45, 44, 43, 505, 242, + /* 10 */ 799, 326, 48, 49, 345, 52, 53, 246, 245, 223, + /* 20 */ 42, 8, 51, 274, 56, 54, 58, 55, 136, 134, + /* 30 */ 133, 398, 47, 46, 138, 61, 45, 44, 43, 48, + /* 40 */ 49, 509, 52, 53, 31, 302, 223, 42, 435, 51, + /* 50 */ 274, 56, 54, 58, 55, 234, 342, 119, 118, 47, + /* 60 */ 46, 17, 16, 45, 44, 43, 48, 49, 29, 52, + /* 70 */ 53, 280, 250, 223, 42, 383, 51, 274, 56, 54, + /* 80 */ 58, 55, 323, 322, 130, 298, 47, 46, 435, 508, + /* 90 */ 45, 44, 43, 48, 50, 497, 52, 53, 257, 256, + /* 100 */ 223, 42, 506, 51, 274, 56, 54, 58, 55, 71, + /* 110 */ 505, 382, 463, 47, 46, 465, 464, 45, 44, 43, + /* 120 */ 462, 221, 460, 459, 461, 236, 458, 457, 297, 296, + /* 130 */ 406, 384, 418, 417, 416, 415, 414, 413, 412, 411, + /* 140 */ 410, 409, 408, 407, 405, 404, 522, 521, 520, 519, + /* 150 */ 518, 517, 516, 515, 514, 513, 512, 511, 510, 325, + /* 160 */ 62, 49, 212, 52, 53, 6, 232, 223, 42, 86, + /* 170 */ 51, 274, 56, 54, 58, 55, 132, 380, 145, 379, + /* 180 */ 47, 46, 506, 63, 45, 44, 43, 52, 53, 279, + /* 190 */ 505, 223, 42, 87, 51, 274, 56, 54, 58, 55, + /* 200 */ 401, 400, 30, 394, 47, 46, 131, 13, 45, 44, + /* 210 */ 43, 88, 31, 85, 397, 45, 44, 43, 61, 24, + /* 220 */ 288, 319, 318, 287, 286, 285, 317, 284, 316, 315, + /* 230 */ 314, 283, 313, 312, 222, 370, 233, 89, 381, 292, + /* 240 */ 374, 377, 373, 376, 222, 370, 31, 354, 381, 269, + /* 250 */ 374, 440, 373, 294, 106, 105, 435, 31, 15, 14, + /* 260 */ 56, 54, 58, 55, 19, 65, 207, 208, 47, 46, + /* 270 */ 273, 399, 45, 44, 43, 31, 207, 208, 275, 300, + /* 280 */ 299, 197, 478, 506, 477, 25, 66, 293, 198, 378, + /* 290 */ 435, 505, 188, 122, 121, 196, 289, 24, 227, 319, + /* 300 */ 318, 435, 219, 363, 317, 31, 316, 315, 314, 61, + /* 310 */ 313, 312, 473, 107, 101, 112, 226, 145, 472, 435, + /* 320 */ 111, 117, 120, 110, 77, 471, 180, 178, 176, 114, + /* 330 */ 100, 99, 37, 175, 125, 124, 123, 57, 480, 334, + /* 340 */ 476, 483, 475, 482, 369, 481, 213, 57, 188, 435, + /* 350 */ 371, 656, 277, 375, 369, 249, 32, 69, 220, 363, + /* 360 */ 371, 393, 68, 204, 437, 32, 145, 372, 84, 237, + /* 370 */ 238, 5, 34, 162, 386, 359, 358, 372, 161, 96, + /* 380 */ 91, 95, 72, 368, 271, 364, 82, 20, 350, 20, + /* 390 */ 351, 347, 21, 75, 61, 140, 74, 70, 251, 77, + /* 400 */ 31, 253, 32, 109, 253, 3, 173, 37, 310, 453, + /* 410 */ 1, 160, 426, 172, 454, 235, 172, 333, 172, 395, + /* 420 */ 145, 342, 342, 188, 335, 320, 470, 230, 469, 332, + /* 430 */ 290, 468, 228, 217, 362, 83, 467, 215, 214, 211, + /* 440 */ 324, 466, 456, 452, 442, 451, 450, 479, 449, 448, + /* 450 */ 436, 474, 447, 474, 446, 445, 32, 441, 474, 474, + /* 460 */ 439, 229, 438, 104, 102, 98, 94, 60, 425, 424, + /* 470 */ 423, 422, 421, 420, 90, 88, 23, 278, 419, 22, + /* 480 */ 276, 12, 385, 7, 11, 361, 10, 337, 144, 355, + /* 490 */ 28, 27, 352, 265, 218, 81, 253, 349, 80, 76, + /* 500 */ 348, 141, 142, 331, 346, 79, 26, 330, 343, 255, + /* 510 */ 9, 329, 248, 244, 243, 328, 241, 327, 2, 135, + /* 520 */ 240, 4, 504, 503, 321, 129, 498, 455, 128, 307, + /* 530 */ 496, 311, 127, 126, 489, 309, 308, 170, 304, 306, + /* 540 */ 290, 305, 171, 108, 403, 155, 169, 167, 303, 168, + /* 550 */ 203, 210, 166, 93, 165, 41, 281, 443, 231, 92, + /* 560 */ 259, 151, 209, 154, 152, 262, 270, 800, 264, 267, + /* 570 */ 153, 357, 260, 216, 258, 800, 800, 800, 800, 261, + /* 580 */ 800, 266, 800, 800, 800, 268, 800, 800, 800, 800, + /* 590 */ 353, 800, 301, 272, 150, 800, 149, 78, 73, 59, + /* 600 */ 148, 252, 147, 64, 182, 146, 67, 507, 181, 391, + /* 610 */ 502, 501, 500, 800, 800, 800, 499, 179, 800, 177, + /* 620 */ 800, 495, 494, 800, 493, 492, 491, 490, 360, 800, + /* 630 */ 800, 800, 800, 800, 800, 800, 392, 800, 310, 800, + /* 640 */ 800, 225, 800, 800, 254, 341, 156, 800, 800, 800, + /* 650 */ 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, + /* 660 */ 800, 800, 800, 800, 40, 800, 174, 800, 239, 800, + /* 670 */ 488, 487, 116, 115, 486, 113, 485, 184, 39, 33, + /* 680 */ 800, 36, 444, 164, 434, 800, 433, 103, 432, 295, + /* 690 */ 163, 430, 429, 97, 428, 427, 291, 35, 800, 183, + /* 700 */ 800, 38, 800, 800, 800, 282, 402, 159, 158, 396, + /* 710 */ 157, 800, 263, 143, 139, 344, 340, 339, 338, 336, + /* 720 */ 137, 247, 800, 800, 800, 800, 800, 800, 800, 800, + /* 730 */ 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, + /* 740 */ 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, + /* 750 */ 800, 800, 800, 800, 800, 800, 800, 800, 390, 389, + /* 760 */ 224, 388, 387, 800, 800, 800, 800, 800, 800, 800, + /* 770 */ 800, 800, 484, 431, 800, 800, 800, 800, 800, 800, + /* 780 */ 800, 356, 800, 800, 800, 800, 800, 800, 800, 800, + /* 790 */ 800, 189, 199, 185, 200, 202, 201, 195, 194, 187, + /* 800 */ 193, 191, 190, 206, 205, 367, 366, 365, 192, 186, + /* 810 */ 18, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 192, 1, 191, 192, 211, 192, 5, 192, 7, 9, - /* 10 */ 189, 190, 254, 13, 14, 192, 16, 17, 192, 254, - /* 20 */ 20, 21, 254, 23, 24, 25, 26, 27, 28, 264, - /* 30 */ 237, 263, 264, 33, 34, 254, 254, 37, 38, 39, - /* 40 */ 13, 14, 234, 16, 17, 263, 264, 20, 21, 1, - /* 50 */ 23, 24, 25, 26, 27, 28, 235, 9, 211, 233, - /* 60 */ 33, 34, 236, 192, 37, 38, 39, 14, 255, 16, - /* 70 */ 17, 192, 251, 20, 21, 260, 23, 24, 25, 26, - /* 80 */ 27, 28, 192, 260, 237, 262, 33, 34, 79, 68, - /* 90 */ 37, 38, 39, 45, 46, 47, 48, 49, 50, 51, - /* 100 */ 52, 53, 54, 55, 56, 57, 58, 5, 198, 61, - /* 110 */ 110, 1, 233, 13, 14, 236, 16, 17, 81, 9, - /* 120 */ 20, 21, 1, 23, 24, 25, 26, 27, 28, 258, - /* 130 */ 9, 260, 105, 33, 34, 33, 34, 37, 38, 39, - /* 140 */ 13, 14, 232, 16, 17, 197, 256, 20, 21, 201, - /* 150 */ 23, 24, 25, 26, 27, 28, 65, 66, 67, 138, - /* 160 */ 33, 34, 141, 142, 37, 38, 39, 88, 89, 90, - /* 170 */ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - /* 180 */ 101, 102, 210, 192, 212, 213, 214, 215, 216, 217, - /* 190 */ 218, 219, 220, 221, 222, 223, 224, 225, 16, 17, - /* 200 */ 254, 235, 20, 21, 0, 23, 24, 25, 26, 27, - /* 210 */ 28, 254, 44, 198, 104, 33, 34, 251, 192, 37, - /* 220 */ 38, 39, 1, 2, 233, 192, 5, 236, 7, 61, - /* 230 */ 9, 1, 2, 211, 104, 5, 68, 7, 108, 9, - /* 240 */ 110, 73, 74, 75, 229, 230, 231, 232, 25, 26, - /* 250 */ 27, 28, 15, 227, 33, 34, 33, 34, 37, 237, - /* 260 */ 37, 38, 39, 33, 34, 136, 233, 68, 88, 236, - /* 270 */ 90, 91, 104, 144, 145, 95, 237, 97, 98, 99, - /* 280 */ 112, 101, 102, 79, 210, 33, 34, 213, 214, 37, - /* 290 */ 38, 39, 218, 192, 220, 221, 222, 211, 224, 225, - /* 300 */ 62, 63, 64, 135, 5, 137, 7, 69, 70, 71, - /* 310 */ 72, 143, 2, 37, 198, 5, 78, 7, 192, 9, - /* 320 */ 62, 63, 64, 237, 192, 104, 192, 69, 70, 71, - /* 330 */ 72, 192, 111, 5, 104, 7, 104, 138, 117, 107, - /* 340 */ 141, 111, 238, 33, 34, 104, 230, 117, 111, 76, - /* 350 */ 62, 63, 64, 112, 81, 134, 252, 69, 70, 71, - /* 360 */ 72, 260, 236, 254, 134, 233, 105, 233, 236, 197, - /* 370 */ 236, 60, 233, 201, 113, 236, 37, 38, 39, 62, - /* 380 */ 63, 64, 197, 199, 200, 254, 201, 195, 196, 125, - /* 390 */ 126, 115, 109, 1, 105, 109, 105, 105, 109, 116, - /* 400 */ 109, 109, 105, 105, 109, 105, 109, 109, 105, 109, - /* 410 */ 105, 254, 109, 105, 109, 104, 117, 109, 132, 105, - /* 420 */ 105, 111, 253, 109, 109, 130, 139, 140, 104, 37, - /* 430 */ 106, 254, 139, 140, 228, 139, 140, 76, 77, 228, - /* 440 */ 139, 140, 5, 254, 7, 117, 237, 254, 254, 254, - /* 450 */ 254, 254, 254, 228, 254, 254, 254, 254, 192, 254, - /* 460 */ 192, 228, 228, 228, 228, 239, 192, 192, 261, 192, - /* 470 */ 192, 192, 192, 261, 235, 235, 192, 235, 60, 257, - /* 480 */ 249, 257, 192, 117, 257, 257, 192, 103, 240, 242, - /* 490 */ 244, 246, 248, 250, 192, 123, 192, 129, 192, 192, - /* 500 */ 131, 192, 128, 247, 192, 192, 127, 122, 192, 121, - /* 510 */ 192, 192, 192, 192, 192, 192, 245, 192, 192, 192, - /* 520 */ 120, 192, 192, 192, 192, 192, 192, 192, 192, 192, - /* 530 */ 192, 119, 192, 192, 192, 192, 192, 192, 192, 192, - /* 540 */ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - /* 550 */ 192, 192, 192, 118, 133, 193, 193, 193, 193, 87, - /* 560 */ 193, 86, 50, 83, 85, 54, 193, 84, 193, 193, - /* 570 */ 82, 79, 5, 146, 193, 193, 198, 5, 198, 5, - /* 580 */ 146, 5, 5, 90, 89, 136, 113, 105, 193, 193, - /* 590 */ 203, 193, 209, 194, 208, 205, 207, 206, 204, 202, - /* 600 */ 194, 194, 194, 226, 193, 195, 193, 107, 199, 104, - /* 610 */ 114, 109, 241, 243, 105, 105, 109, 104, 104, 226, - /* 620 */ 105, 104, 1, 104, 108, 105, 104, 109, 124, 105, - /* 630 */ 109, 104, 124, 104, 111, 104, 104, 107, 76, 9, - /* 640 */ 5, 5, 5, 5, 5, 80, 15, 76, 109, 16, - /* 650 */ 5, 5, 105, 5, 5, 5, 5, 5, 5, 5, - /* 660 */ 5, 5, 5, 5, 5, 140, 140, 5, 140, 5, - /* 670 */ 5, 5, 5, 109, 80, 60, 59, 0, 265, 265, - /* 680 */ 265, 21, 21, 265, 265, 265, 265, 265, 265, 265, - /* 690 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 700 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 710 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 720 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 730 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 740 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 750 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 760 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 770 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 780 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 790 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 800 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 810 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 820 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 830 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 840 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 850 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 860 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - /* 870 */ 265, + /* 0 */ 1, 33, 34, 0, 192, 37, 38, 39, 9, 136, + /* 10 */ 189, 190, 13, 14, 109, 16, 17, 144, 145, 20, + /* 20 */ 21, 116, 23, 24, 25, 26, 27, 28, 62, 63, + /* 30 */ 64, 105, 33, 34, 192, 109, 37, 38, 39, 13, + /* 40 */ 14, 59, 16, 17, 192, 233, 20, 21, 236, 23, + /* 50 */ 24, 25, 26, 27, 28, 68, 235, 76, 77, 33, + /* 60 */ 34, 139, 140, 37, 38, 39, 13, 14, 104, 16, + /* 70 */ 17, 107, 251, 20, 21, 1, 23, 24, 25, 26, + /* 80 */ 27, 28, 65, 66, 67, 233, 33, 34, 236, 60, + /* 90 */ 37, 38, 39, 13, 14, 80, 16, 17, 256, 257, + /* 100 */ 20, 21, 1, 23, 24, 25, 26, 27, 28, 110, + /* 110 */ 9, 37, 210, 33, 34, 213, 214, 37, 38, 39, + /* 120 */ 218, 60, 220, 221, 222, 138, 224, 225, 141, 142, + /* 130 */ 210, 105, 212, 213, 214, 215, 216, 217, 218, 219, + /* 140 */ 220, 221, 222, 223, 224, 225, 45, 46, 47, 48, + /* 150 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 160 */ 109, 14, 61, 16, 17, 104, 68, 20, 21, 198, + /* 170 */ 23, 24, 25, 26, 27, 28, 21, 5, 192, 7, + /* 180 */ 33, 34, 1, 132, 37, 38, 39, 16, 17, 105, + /* 190 */ 9, 20, 21, 109, 23, 24, 25, 26, 27, 28, + /* 200 */ 229, 230, 231, 232, 33, 34, 21, 104, 37, 38, + /* 210 */ 39, 108, 192, 110, 105, 37, 38, 39, 109, 88, + /* 220 */ 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + /* 230 */ 99, 100, 101, 102, 1, 2, 138, 198, 5, 141, + /* 240 */ 7, 5, 9, 7, 1, 2, 192, 261, 5, 263, + /* 250 */ 7, 5, 9, 233, 139, 140, 236, 192, 139, 140, + /* 260 */ 25, 26, 27, 28, 44, 109, 33, 34, 33, 34, + /* 270 */ 37, 232, 37, 38, 39, 192, 33, 34, 15, 33, + /* 280 */ 34, 61, 5, 1, 7, 104, 130, 233, 68, 117, + /* 290 */ 236, 9, 254, 73, 74, 75, 15, 88, 233, 90, + /* 300 */ 91, 236, 264, 265, 95, 192, 97, 98, 99, 109, + /* 310 */ 101, 102, 5, 62, 63, 64, 233, 192, 5, 236, + /* 320 */ 69, 70, 71, 72, 104, 5, 62, 63, 64, 78, + /* 330 */ 139, 140, 112, 69, 70, 71, 72, 104, 2, 37, + /* 340 */ 5, 5, 7, 7, 111, 9, 233, 104, 254, 236, + /* 350 */ 117, 0, 105, 117, 111, 135, 109, 137, 264, 265, + /* 360 */ 117, 105, 104, 143, 106, 109, 192, 134, 238, 33, + /* 370 */ 34, 62, 63, 64, 111, 125, 126, 134, 69, 70, + /* 380 */ 71, 72, 252, 105, 259, 105, 261, 109, 105, 109, + /* 390 */ 105, 105, 109, 105, 109, 109, 105, 198, 105, 104, + /* 400 */ 192, 113, 109, 76, 113, 195, 196, 112, 81, 197, + /* 410 */ 199, 200, 197, 201, 197, 192, 201, 115, 201, 192, + /* 420 */ 192, 235, 235, 254, 192, 211, 5, 211, 5, 230, + /* 430 */ 79, 5, 211, 211, 265, 261, 5, 251, 251, 191, + /* 440 */ 192, 5, 5, 5, 236, 5, 5, 111, 5, 5, + /* 450 */ 227, 237, 5, 237, 5, 5, 109, 105, 237, 237, + /* 460 */ 5, 234, 5, 140, 140, 140, 76, 16, 80, 5, + /* 470 */ 5, 5, 5, 5, 76, 108, 104, 107, 9, 104, + /* 480 */ 107, 104, 111, 104, 124, 105, 124, 255, 104, 261, + /* 490 */ 109, 109, 105, 104, 1, 104, 113, 105, 104, 114, + /* 500 */ 105, 104, 109, 89, 105, 109, 104, 90, 105, 109, + /* 510 */ 104, 5, 136, 5, 146, 5, 5, 5, 199, 60, + /* 520 */ 146, 195, 193, 193, 79, 194, 193, 226, 194, 54, + /* 530 */ 193, 103, 194, 194, 193, 82, 84, 205, 50, 85, + /* 540 */ 79, 83, 202, 87, 226, 240, 204, 203, 86, 206, + /* 550 */ 193, 193, 207, 198, 208, 133, 193, 209, 193, 198, + /* 560 */ 118, 244, 193, 241, 243, 119, 127, 266, 120, 258, + /* 570 */ 242, 193, 258, 258, 258, 266, 266, 266, 266, 193, + /* 580 */ 266, 121, 266, 266, 266, 122, 266, 266, 266, 266, + /* 590 */ 117, 266, 228, 123, 245, 266, 246, 193, 193, 128, + /* 600 */ 247, 193, 248, 131, 192, 249, 129, 192, 192, 250, + /* 610 */ 192, 192, 192, 266, 266, 266, 192, 192, 266, 192, + /* 620 */ 266, 192, 192, 266, 192, 192, 192, 192, 262, 266, + /* 630 */ 266, 266, 266, 266, 266, 266, 235, 266, 81, 266, + /* 640 */ 266, 228, 266, 266, 235, 235, 239, 266, 266, 266, + /* 650 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 660 */ 266, 266, 266, 266, 253, 266, 192, 266, 192, 266, + /* 670 */ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + /* 680 */ 266, 192, 192, 192, 192, 266, 192, 192, 192, 192, + /* 690 */ 192, 192, 192, 192, 192, 192, 192, 192, 266, 192, + /* 700 */ 266, 192, 266, 266, 266, 192, 192, 192, 192, 192, + /* 710 */ 192, 266, 192, 192, 192, 192, 192, 192, 192, 192, + /* 720 */ 192, 192, 266, 266, 266, 266, 266, 266, 266, 266, + /* 730 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 740 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 750 */ 266, 266, 266, 266, 266, 266, 266, 266, 228, 228, + /* 760 */ 228, 228, 228, 266, 266, 266, 266, 266, 266, 266, + /* 770 */ 266, 266, 237, 237, 266, 266, 266, 266, 266, 266, + /* 780 */ 266, 262, 266, 266, 266, 266, 266, 266, 266, 266, + /* 790 */ 266, 254, 254, 254, 254, 254, 254, 254, 254, 254, + /* 800 */ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, + /* 810 */ 254, }; -#define YY_SHIFT_COUNT (320) -#define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (677) -static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 168, 79, 79, 180, 180, 9, 221, 230, 121, 121, - /* 10 */ 121, 121, 121, 121, 121, 121, 121, 0, 48, 230, - /* 20 */ 310, 310, 310, 310, 110, 241, 121, 121, 121, 204, - /* 30 */ 121, 121, 273, 9, 37, 37, 683, 683, 683, 230, - /* 40 */ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, - /* 50 */ 230, 230, 230, 230, 230, 230, 230, 230, 230, 310, - /* 60 */ 310, 102, 102, 102, 102, 102, 102, 102, 121, 121, - /* 70 */ 121, 276, 121, 241, 241, 121, 121, 121, 121, 264, - /* 80 */ 264, 283, 241, 121, 121, 121, 121, 121, 121, 121, - /* 90 */ 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - /* 100 */ 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - /* 110 */ 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - /* 120 */ 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - /* 130 */ 121, 121, 121, 121, 418, 418, 418, 366, 366, 366, - /* 140 */ 418, 366, 418, 368, 369, 374, 372, 379, 385, 388, - /* 150 */ 400, 412, 435, 421, 418, 418, 418, 384, 9, 9, - /* 160 */ 418, 418, 472, 475, 512, 480, 479, 511, 483, 488, - /* 170 */ 384, 418, 492, 492, 418, 492, 418, 492, 418, 418, - /* 180 */ 683, 683, 27, 100, 127, 100, 100, 53, 182, 223, - /* 190 */ 223, 223, 223, 238, 258, 288, 252, 252, 252, 252, - /* 200 */ 21, 129, 339, 339, 299, 328, 130, 199, 91, 317, - /* 210 */ 289, 261, 291, 292, 297, 298, 300, 392, 311, 237, - /* 220 */ 286, 295, 303, 305, 308, 314, 315, 232, 287, 293, - /* 230 */ 296, 324, 301, 1, 437, 361, 567, 427, 572, 574, - /* 240 */ 434, 576, 577, 493, 495, 449, 473, 500, 505, 496, - /* 250 */ 482, 502, 509, 513, 510, 507, 514, 515, 517, 621, - /* 260 */ 519, 520, 522, 518, 504, 521, 508, 524, 527, 523, - /* 270 */ 529, 500, 531, 530, 532, 516, 562, 630, 635, 636, - /* 280 */ 637, 638, 639, 565, 631, 571, 525, 539, 539, 633, - /* 290 */ 526, 528, 539, 645, 646, 547, 539, 648, 649, 650, - /* 300 */ 651, 652, 653, 654, 655, 656, 657, 658, 659, 662, - /* 310 */ 664, 665, 666, 667, 564, 594, 660, 661, 615, 617, - /* 320 */ 677, +#define YY_SHIFT_USE_DFLT (-128) +#define YY_SHIFT_COUNT (326) +#define YY_SHIFT_MIN (-127) +#define YY_SHIFT_MAX (557) +static const short yy_shift_ofst[] = { + /* 0 */ 220, 131, 131, 209, 209, 461, 233, 243, 181, 282, + /* 10 */ 282, 282, 282, 282, 282, 282, 282, 282, -1, 101, + /* 20 */ 243, 336, 336, 336, 336, 295, 295, 282, 282, 282, + /* 30 */ 351, 282, 282, 327, 461, 557, 557, -128, -128, -128, + /* 40 */ 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + /* 50 */ 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + /* 60 */ 336, 336, 246, 246, 246, 246, 246, 246, 246, 282, + /* 70 */ 282, 282, 302, 282, 282, 282, 295, 295, 282, 282, + /* 80 */ 282, 282, 250, 250, -95, 295, 282, 282, 282, 282, + /* 90 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + /* 100 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + /* 110 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + /* 120 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + /* 130 */ 282, 282, 282, 282, 282, 282, 282, 459, 459, 459, + /* 140 */ 473, 473, 473, 459, 473, 459, 477, 472, 471, 470, + /* 150 */ 439, 463, 460, 448, 446, 442, 422, 459, 459, 459, + /* 160 */ 428, 461, 461, 459, 459, 456, 462, 488, 458, 454, + /* 170 */ 475, 452, 453, 428, 459, 445, 445, 459, 445, 459, + /* 180 */ 445, 459, 459, -128, -128, 26, 53, 80, 53, 53, + /* 190 */ 147, 171, 235, 235, 235, 235, 251, 309, 264, -32, + /* 200 */ -32, -32, -32, -13, -127, 178, 178, 236, 172, 103, + /* 210 */ 98, 17, -34, 293, 291, 288, 286, 285, 283, 280, + /* 220 */ 278, 74, 61, 263, 51, 156, 256, 247, 109, 84, + /* 230 */ -74, -36, 191, 119, 115, 258, -78, 335, 277, -19, + /* 240 */ 512, 374, 511, 510, 368, 508, 506, 417, 414, 376, + /* 250 */ 383, 373, 406, 385, 403, 402, 400, 396, 399, 397, + /* 260 */ 395, 393, 394, 392, 391, 493, 389, 387, 384, 382, + /* 270 */ 362, 381, 360, 380, 379, 371, 377, 373, 375, 370, + /* 280 */ 372, 367, 398, 469, 468, 467, 466, 465, 464, 388, + /* 290 */ 281, 390, 325, 347, 347, 451, 324, 323, 347, 457, + /* 300 */ 455, 352, 347, 450, 449, 447, 444, 443, 441, 440, + /* 310 */ 438, 437, 436, 431, 426, 423, 421, 320, 313, 307, + /* 320 */ 200, 15, 185, 155, 29, -18, 3, }; -#define YY_REDUCE_COUNT (181) -#define YY_REDUCE_MIN (-242) -#define YY_REDUCE_MAX (413) +#define YY_REDUCE_USE_DFLT (-189) +#define YY_REDUCE_COUNT (184) +#define YY_REDUCE_MIN (-188) +#define YY_REDUCE_MAX (556) static const short yy_reduce_ofst[] = { - /* 0 */ -179, -28, -28, 74, 74, 15, -232, -218, -174, -177, - /* 10 */ -129, -121, -9, 33, 132, 134, 139, -187, -189, -235, - /* 20 */ -207, -153, 22, 86, -110, -34, -185, 101, -192, -90, - /* 30 */ 26, 126, -52, 116, 172, 185, 104, 184, 192, -242, - /* 40 */ -219, -54, -43, 109, 131, 157, 177, 189, 193, 194, - /* 50 */ 195, 196, 197, 198, 200, 201, 202, 203, 205, 39, - /* 60 */ 209, 206, 211, 225, 233, 234, 235, 236, 266, 268, - /* 70 */ 274, 169, 275, 239, 240, 277, 278, 279, 280, 207, - /* 80 */ 212, 226, 242, 284, 290, 294, 302, 304, 306, 307, - /* 90 */ 309, 312, 313, 316, 318, 319, 320, 321, 322, 323, - /* 100 */ 325, 326, 327, 329, 330, 331, 332, 333, 334, 335, - /* 110 */ 336, 337, 338, 340, 341, 342, 343, 344, 345, 346, - /* 120 */ 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - /* 130 */ 357, 358, 359, 360, 362, 363, 364, 222, 224, 227, - /* 140 */ 365, 228, 367, 243, 231, 244, 256, 245, 271, 246, - /* 150 */ 370, 247, 371, 248, 373, 375, 376, 377, 378, 380, - /* 160 */ 381, 382, 383, 386, 389, 387, 391, 394, 390, 397, - /* 170 */ 393, 395, 399, 406, 396, 407, 398, 408, 411, 413, - /* 180 */ 409, 410, + /* 0 */ -179, -80, -80, -98, -98, -29, 94, 38, -158, 113, + /* 10 */ -14, 125, 83, 65, 54, 20, -148, -188, 232, 248, + /* 20 */ 169, 222, 221, 216, 214, 187, 186, 228, 174, 227, + /* 30 */ 39, 223, 208, 217, 199, 215, 212, 130, 211, 210, + /* 40 */ 556, 555, 554, 553, 552, 551, 550, 549, 548, 547, + /* 50 */ 546, 545, 544, 543, 542, 541, 540, 539, 538, 537, + /* 60 */ 536, 535, 534, 533, 532, 531, 530, 413, 364, 529, + /* 70 */ 528, 527, 411, 526, 525, 524, 410, 409, 523, 522, + /* 80 */ 521, 520, 519, 366, 407, 401, 518, 517, 516, 515, + /* 90 */ 514, 513, 509, 507, 505, 504, 503, 502, 501, 500, + /* 100 */ 499, 498, 497, 496, 495, 494, 492, 491, 490, 489, + /* 110 */ 487, 486, 485, 484, 483, 482, 481, 480, 479, 478, + /* 120 */ 476, 474, 435, 434, 433, 432, 430, 429, 427, 425, + /* 130 */ 424, 420, 419, 418, 416, 415, 412, 408, 405, 404, + /* 140 */ 316, 315, 314, 386, 311, 378, 359, 356, 354, 353, + /* 150 */ 350, 349, 317, 321, 328, 322, 305, 369, 365, 363, + /* 160 */ 318, 361, 355, 358, 357, 348, 346, 345, 344, 343, + /* 170 */ 342, 332, 340, 301, 341, 339, 338, 337, 334, 333, + /* 180 */ 331, 330, 329, 319, 326, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 788, 901, 847, 913, 835, 844, 1046, 1046, 788, 788, - /* 10 */ 788, 788, 788, 788, 788, 788, 788, 960, 807, 1046, - /* 20 */ 788, 788, 788, 788, 788, 788, 788, 788, 788, 844, - /* 30 */ 788, 788, 850, 844, 850, 850, 955, 885, 903, 788, - /* 40 */ 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, - /* 50 */ 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, - /* 60 */ 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, - /* 70 */ 788, 962, 965, 788, 788, 967, 788, 788, 788, 989, - /* 80 */ 989, 953, 788, 788, 788, 788, 788, 788, 788, 788, - /* 90 */ 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, - /* 100 */ 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, - /* 110 */ 833, 788, 831, 788, 788, 788, 788, 788, 788, 788, - /* 120 */ 788, 788, 788, 788, 788, 788, 788, 818, 788, 788, - /* 130 */ 788, 788, 788, 788, 809, 809, 809, 788, 788, 788, - /* 140 */ 809, 788, 809, 996, 1000, 994, 982, 990, 981, 977, - /* 150 */ 975, 973, 972, 1004, 809, 809, 809, 848, 844, 844, - /* 160 */ 809, 809, 866, 864, 862, 854, 860, 856, 858, 852, - /* 170 */ 836, 809, 842, 842, 809, 842, 809, 842, 809, 809, - /* 180 */ 885, 903, 788, 1005, 788, 1045, 995, 1035, 1034, 1041, - /* 190 */ 1033, 1032, 1031, 788, 788, 788, 1027, 1028, 1030, 1029, - /* 200 */ 788, 788, 1037, 1036, 788, 788, 788, 788, 788, 788, - /* 210 */ 788, 788, 788, 788, 788, 788, 788, 788, 1007, 788, - /* 220 */ 1001, 997, 788, 788, 788, 788, 788, 788, 788, 788, - /* 230 */ 788, 915, 788, 788, 788, 788, 788, 788, 788, 788, - /* 240 */ 788, 788, 788, 788, 788, 788, 952, 788, 788, 788, - /* 250 */ 788, 963, 788, 788, 788, 788, 788, 788, 788, 788, - /* 260 */ 788, 788, 788, 991, 788, 983, 788, 788, 788, 788, - /* 270 */ 788, 927, 788, 788, 788, 788, 788, 788, 788, 788, - /* 280 */ 788, 788, 788, 788, 788, 788, 788, 1057, 1055, 788, - /* 290 */ 788, 788, 1051, 788, 788, 788, 1049, 788, 788, 788, - /* 300 */ 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, - /* 310 */ 788, 788, 788, 788, 869, 788, 816, 814, 788, 805, - /* 320 */ 788, + /* 0 */ 798, 633, 579, 645, 567, 576, 781, 781, 798, 798, + /* 10 */ 798, 798, 798, 798, 798, 798, 798, 798, 692, 539, + /* 20 */ 781, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 30 */ 576, 798, 798, 582, 576, 582, 582, 687, 617, 635, + /* 40 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 50 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 60 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 70 */ 798, 798, 694, 700, 697, 798, 798, 798, 702, 798, + /* 80 */ 798, 798, 724, 724, 685, 798, 798, 798, 798, 798, + /* 90 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 100 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 110 */ 798, 798, 798, 565, 798, 563, 798, 798, 798, 798, + /* 120 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 130 */ 550, 798, 798, 798, 798, 798, 798, 541, 541, 541, + /* 140 */ 798, 798, 798, 541, 798, 541, 731, 735, 729, 717, + /* 150 */ 725, 716, 712, 710, 708, 707, 739, 541, 541, 541, + /* 160 */ 580, 576, 576, 541, 541, 598, 596, 594, 586, 592, + /* 170 */ 588, 590, 584, 568, 541, 574, 574, 541, 574, 541, + /* 180 */ 574, 541, 541, 617, 635, 798, 740, 798, 780, 730, + /* 190 */ 770, 769, 776, 768, 767, 766, 798, 798, 798, 762, + /* 200 */ 763, 765, 764, 798, 798, 772, 771, 798, 798, 798, + /* 210 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 220 */ 798, 798, 742, 798, 736, 732, 798, 798, 798, 798, + /* 230 */ 798, 798, 798, 798, 798, 647, 798, 798, 798, 798, + /* 240 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 250 */ 684, 798, 798, 798, 798, 798, 696, 695, 798, 798, + /* 260 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 726, + /* 270 */ 798, 718, 798, 798, 798, 798, 798, 659, 798, 798, + /* 280 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 290 */ 798, 798, 798, 792, 790, 798, 798, 798, 786, 798, + /* 300 */ 798, 798, 784, 798, 798, 798, 798, 798, 798, 798, + /* 310 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 320 */ 601, 798, 548, 546, 798, 537, 798, 797, 796, 795, + /* 330 */ 783, 782, 655, 693, 689, 691, 690, 688, 701, 698, + /* 340 */ 699, 683, 682, 681, 703, 686, 706, 705, 709, 711, + /* 350 */ 714, 713, 715, 704, 728, 727, 720, 721, 723, 722, + /* 360 */ 719, 759, 778, 779, 777, 775, 774, 773, 758, 757, + /* 370 */ 756, 753, 752, 751, 748, 754, 750, 747, 755, 749, + /* 380 */ 746, 745, 744, 743, 741, 761, 760, 738, 737, 734, + /* 390 */ 733, 680, 665, 660, 657, 664, 663, 662, 661, 658, + /* 400 */ 654, 653, 581, 634, 632, 631, 630, 629, 628, 627, + /* 410 */ 626, 625, 624, 623, 622, 621, 620, 619, 618, 613, + /* 420 */ 609, 607, 606, 605, 602, 575, 578, 577, 794, 793, + /* 430 */ 791, 789, 788, 787, 785, 667, 668, 649, 652, 651, + /* 440 */ 650, 648, 666, 600, 599, 597, 595, 587, 593, 589, + /* 450 */ 591, 585, 583, 570, 569, 646, 616, 644, 643, 642, + /* 460 */ 641, 640, 639, 638, 637, 636, 615, 614, 612, 611, + /* 470 */ 610, 608, 604, 603, 670, 679, 678, 677, 676, 675, + /* 480 */ 674, 673, 672, 671, 669, 566, 564, 562, 561, 560, + /* 490 */ 559, 558, 557, 556, 555, 554, 553, 573, 552, 551, + /* 500 */ 549, 547, 545, 544, 543, 572, 571, 542, 540, 538, + /* 510 */ 536, 535, 534, 533, 532, 531, 530, 529, 528, 527, + /* 520 */ 526, 525, 524, }; -/********** End of lemon-generated parsing tables *****************************/ -/* The next table maps tokens (terminal symbols) into fallback tokens. -** If a construct like the following: +/* The next table maps tokens into fallback tokens. If a construct +** like the following: ** ** %fallback ID X Y Z. ** @@ -474,10 +465,6 @@ static const YYACTIONTYPE yy_default[] = { ** and Z. Whenever one of the tokens X, Y, or Z is input to the parser ** but it does not parse, the type of the token is changed to ID and ** the parse is retried before an error is thrown. -** -** This feature can be used, for example, to cause some keywords in a language -** to revert to identifiers if they keyword does not apply in the context where -** it appears. */ #ifdef YYFALLBACK static const YYCODETYPE yyFallback[] = { @@ -683,13 +670,9 @@ static const YYCODETYPE yyFallback[] = { ** + The semantic value stored at this level of the stack. This is ** the information used by the action routines in the grammar. ** It is sometimes called the "minor" token. -** -** After the "shift" half of a SHIFTREDUCE action, the stateno field -** actually contains the reduce action for the second half of the -** SHIFTREDUCE. */ struct yyStackEntry { - YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */ + YYACTIONTYPE stateno; /* The state-number */ YYCODETYPE major; /* The major token value. This is the code ** number for the token at this stack level */ YYMINORTYPE minor; /* The user-supplied minor token value. This @@ -700,21 +683,17 @@ typedef struct yyStackEntry yyStackEntry; /* The state of the parser is completely contained in an instance of ** the following structure */ struct yyParser { - yyStackEntry *yytos; /* Pointer to top element of the stack */ + int yyidx; /* Index of top element in stack */ #ifdef YYTRACKMAXSTACKDEPTH - int yyhwm; /* High-water mark of the stack */ + int yyidxMax; /* Maximum value of yyidx */ #endif -#ifndef YYNOERRORRECOVERY int yyerrcnt; /* Shifts left before out of the error */ -#endif ParseARG_SDECL /* A place to hold %extra_argument */ #if YYSTACKDEPTH<=0 int yystksz; /* Current side of the stack */ yyStackEntry *yystack; /* The parser's stack */ - yyStackEntry yystk0; /* First stack entry */ #else yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ - yyStackEntry *yystackEnd; /* Last entry in the stack */ #endif }; typedef struct yyParser yyParser; @@ -751,277 +730,79 @@ void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ } #endif /* NDEBUG */ -#if defined(YYCOVERAGE) || !defined(NDEBUG) +#ifndef NDEBUG /* For tracing shifts, the names of all terminals and nonterminals ** are required. The following table supplies these names */ static const char *const yyTokenName[] = { - /* 0 */ "$", - /* 1 */ "ID", - /* 2 */ "BOOL", - /* 3 */ "TINYINT", - /* 4 */ "SMALLINT", - /* 5 */ "INTEGER", - /* 6 */ "BIGINT", - /* 7 */ "FLOAT", - /* 8 */ "DOUBLE", - /* 9 */ "STRING", - /* 10 */ "TIMESTAMP", - /* 11 */ "BINARY", - /* 12 */ "NCHAR", - /* 13 */ "OR", - /* 14 */ "AND", - /* 15 */ "NOT", - /* 16 */ "EQ", - /* 17 */ "NE", - /* 18 */ "ISNULL", - /* 19 */ "NOTNULL", - /* 20 */ "IS", - /* 21 */ "LIKE", - /* 22 */ "GLOB", - /* 23 */ "BETWEEN", - /* 24 */ "IN", - /* 25 */ "GT", - /* 26 */ "GE", - /* 27 */ "LT", - /* 28 */ "LE", - /* 29 */ "BITAND", - /* 30 */ "BITOR", - /* 31 */ "LSHIFT", - /* 32 */ "RSHIFT", - /* 33 */ "PLUS", - /* 34 */ "MINUS", - /* 35 */ "DIVIDE", - /* 36 */ "TIMES", - /* 37 */ "STAR", - /* 38 */ "SLASH", - /* 39 */ "REM", - /* 40 */ "CONCAT", - /* 41 */ "UMINUS", - /* 42 */ "UPLUS", - /* 43 */ "BITNOT", - /* 44 */ "SHOW", - /* 45 */ "DATABASES", - /* 46 */ "TOPICS", - /* 47 */ "MNODES", - /* 48 */ "DNODES", - /* 49 */ "ACCOUNTS", - /* 50 */ "USERS", - /* 51 */ "MODULES", - /* 52 */ "QUERIES", - /* 53 */ "CONNECTIONS", - /* 54 */ "STREAMS", - /* 55 */ "VARIABLES", - /* 56 */ "SCORES", - /* 57 */ "GRANTS", - /* 58 */ "VNODES", - /* 59 */ "IPTOKEN", - /* 60 */ "DOT", - /* 61 */ "CREATE", - /* 62 */ "TABLE", - /* 63 */ "STABLE", - /* 64 */ "DATABASE", - /* 65 */ "TABLES", - /* 66 */ "STABLES", - /* 67 */ "VGROUPS", - /* 68 */ "DROP", - /* 69 */ "TOPIC", - /* 70 */ "DNODE", - /* 71 */ "USER", - /* 72 */ "ACCOUNT", - /* 73 */ "USE", - /* 74 */ "DESCRIBE", - /* 75 */ "ALTER", - /* 76 */ "PASS", - /* 77 */ "PRIVILEGE", - /* 78 */ "LOCAL", - /* 79 */ "IF", - /* 80 */ "EXISTS", - /* 81 */ "PPS", - /* 82 */ "TSERIES", - /* 83 */ "DBS", - /* 84 */ "STORAGE", - /* 85 */ "QTIME", - /* 86 */ "CONNS", - /* 87 */ "STATE", - /* 88 */ "KEEP", - /* 89 */ "CACHE", - /* 90 */ "REPLICA", - /* 91 */ "QUORUM", - /* 92 */ "DAYS", - /* 93 */ "MINROWS", - /* 94 */ "MAXROWS", - /* 95 */ "BLOCKS", - /* 96 */ "CTIME", - /* 97 */ "WAL", - /* 98 */ "FSYNC", - /* 99 */ "COMP", - /* 100 */ "PRECISION", - /* 101 */ "UPDATE", - /* 102 */ "CACHELAST", - /* 103 */ "PARTITIONS", - /* 104 */ "LP", - /* 105 */ "RP", - /* 106 */ "UNSIGNED", - /* 107 */ "TAGS", - /* 108 */ "USING", - /* 109 */ "COMMA", - /* 110 */ "AS", - /* 111 */ "NULL", - /* 112 */ "SELECT", - /* 113 */ "UNION", - /* 114 */ "ALL", - /* 115 */ "DISTINCT", - /* 116 */ "FROM", - /* 117 */ "VARIABLE", - /* 118 */ "INTERVAL", - /* 119 */ "SESSION", - /* 120 */ "STATE_WINDOW", - /* 121 */ "FILL", - /* 122 */ "SLIDING", - /* 123 */ "ORDER", - /* 124 */ "BY", - /* 125 */ "ASC", - /* 126 */ "DESC", - /* 127 */ "GROUP", - /* 128 */ "HAVING", - /* 129 */ "LIMIT", - /* 130 */ "OFFSET", - /* 131 */ "SLIMIT", - /* 132 */ "SOFFSET", - /* 133 */ "WHERE", - /* 134 */ "NOW", - /* 135 */ "RESET", - /* 136 */ "QUERY", - /* 137 */ "SYNCDB", - /* 138 */ "ADD", - /* 139 */ "COLUMN", - /* 140 */ "TAG", - /* 141 */ "CHANGE", - /* 142 */ "SET", - /* 143 */ "KILL", - /* 144 */ "CONNECTION", - /* 145 */ "STREAM", - /* 146 */ "COLON", - /* 147 */ "ABORT", - /* 148 */ "AFTER", - /* 149 */ "ATTACH", - /* 150 */ "BEFORE", - /* 151 */ "BEGIN", - /* 152 */ "CASCADE", - /* 153 */ "CLUSTER", - /* 154 */ "CONFLICT", - /* 155 */ "COPY", - /* 156 */ "DEFERRED", - /* 157 */ "DELIMITERS", - /* 158 */ "DETACH", - /* 159 */ "EACH", - /* 160 */ "END", - /* 161 */ "EXPLAIN", - /* 162 */ "FAIL", - /* 163 */ "FOR", - /* 164 */ "IGNORE", - /* 165 */ "IMMEDIATE", - /* 166 */ "INITIALLY", - /* 167 */ "INSTEAD", - /* 168 */ "MATCH", - /* 169 */ "KEY", - /* 170 */ "OF", - /* 171 */ "RAISE", - /* 172 */ "REPLACE", - /* 173 */ "RESTRICT", - /* 174 */ "ROW", - /* 175 */ "STATEMENT", - /* 176 */ "TRIGGER", - /* 177 */ "VIEW", - /* 178 */ "SEMI", - /* 179 */ "NONE", - /* 180 */ "PREV", - /* 181 */ "LINEAR", - /* 182 */ "IMPORT", - /* 183 */ "TBNAME", - /* 184 */ "JOIN", - /* 185 */ "INSERT", - /* 186 */ "INTO", - /* 187 */ "VALUES", - /* 188 */ "error", - /* 189 */ "program", - /* 190 */ "cmd", - /* 191 */ "dbPrefix", - /* 192 */ "ids", - /* 193 */ "cpxName", - /* 194 */ "ifexists", - /* 195 */ "alter_db_optr", - /* 196 */ "alter_topic_optr", - /* 197 */ "acct_optr", - /* 198 */ "ifnotexists", - /* 199 */ "db_optr", - /* 200 */ "topic_optr", - /* 201 */ "pps", - /* 202 */ "tseries", - /* 203 */ "dbs", - /* 204 */ "streams", - /* 205 */ "storage", - /* 206 */ "qtime", - /* 207 */ "users", - /* 208 */ "conns", - /* 209 */ "state", - /* 210 */ "keep", - /* 211 */ "tagitemlist", - /* 212 */ "cache", - /* 213 */ "replica", - /* 214 */ "quorum", - /* 215 */ "days", - /* 216 */ "minrows", - /* 217 */ "maxrows", - /* 218 */ "blocks", - /* 219 */ "ctime", - /* 220 */ "wal", - /* 221 */ "fsync", - /* 222 */ "comp", - /* 223 */ "prec", - /* 224 */ "update", - /* 225 */ "cachelast", - /* 226 */ "partitions", - /* 227 */ "typename", - /* 228 */ "signed", - /* 229 */ "create_table_args", - /* 230 */ "create_stable_args", - /* 231 */ "create_table_list", - /* 232 */ "create_from_stable", - /* 233 */ "columnlist", - /* 234 */ "tagNamelist", - /* 235 */ "select", - /* 236 */ "column", - /* 237 */ "tagitem", - /* 238 */ "selcollist", - /* 239 */ "from", - /* 240 */ "where_opt", - /* 241 */ "interval_opt", - /* 242 */ "session_option", - /* 243 */ "windowstate_option", - /* 244 */ "fill_opt", - /* 245 */ "sliding_opt", - /* 246 */ "groupby_opt", - /* 247 */ "orderby_opt", - /* 248 */ "having_opt", - /* 249 */ "slimit_opt", - /* 250 */ "limit_opt", - /* 251 */ "union", - /* 252 */ "sclp", - /* 253 */ "distinct", - /* 254 */ "expr", - /* 255 */ "as", - /* 256 */ "tablelist", - /* 257 */ "tmvar", - /* 258 */ "sortlist", - /* 259 */ "sortitem", - /* 260 */ "item", - /* 261 */ "sortorder", - /* 262 */ "grouplist", - /* 263 */ "exprlist", - /* 264 */ "expritem", + "$", "ID", "BOOL", "TINYINT", + "SMALLINT", "INTEGER", "BIGINT", "FLOAT", + "DOUBLE", "STRING", "TIMESTAMP", "BINARY", + "NCHAR", "OR", "AND", "NOT", + "EQ", "NE", "ISNULL", "NOTNULL", + "IS", "LIKE", "GLOB", "BETWEEN", + "IN", "GT", "GE", "LT", + "LE", "BITAND", "BITOR", "LSHIFT", + "RSHIFT", "PLUS", "MINUS", "DIVIDE", + "TIMES", "STAR", "SLASH", "REM", + "CONCAT", "UMINUS", "UPLUS", "BITNOT", + "SHOW", "DATABASES", "TOPICS", "MNODES", + "DNODES", "ACCOUNTS", "USERS", "MODULES", + "QUERIES", "CONNECTIONS", "STREAMS", "VARIABLES", + "SCORES", "GRANTS", "VNODES", "IPTOKEN", + "DOT", "CREATE", "TABLE", "STABLE", + "DATABASE", "TABLES", "STABLES", "VGROUPS", + "DROP", "TOPIC", "DNODE", "USER", + "ACCOUNT", "USE", "DESCRIBE", "ALTER", + "PASS", "PRIVILEGE", "LOCAL", "IF", + "EXISTS", "PPS", "TSERIES", "DBS", + "STORAGE", "QTIME", "CONNS", "STATE", + "KEEP", "CACHE", "REPLICA", "QUORUM", + "DAYS", "MINROWS", "MAXROWS", "BLOCKS", + "CTIME", "WAL", "FSYNC", "COMP", + "PRECISION", "UPDATE", "CACHELAST", "PARTITIONS", + "LP", "RP", "UNSIGNED", "TAGS", + "USING", "COMMA", "AS", "NULL", + "SELECT", "UNION", "ALL", "DISTINCT", + "FROM", "VARIABLE", "INTERVAL", "SESSION", + "STATE_WINDOW", "FILL", "SLIDING", "ORDER", + "BY", "ASC", "DESC", "GROUP", + "HAVING", "LIMIT", "OFFSET", "SLIMIT", + "SOFFSET", "WHERE", "NOW", "RESET", + "QUERY", "SYNCDB", "ADD", "COLUMN", + "TAG", "CHANGE", "SET", "KILL", + "CONNECTION", "STREAM", "COLON", "ABORT", + "AFTER", "ATTACH", "BEFORE", "BEGIN", + "CASCADE", "CLUSTER", "CONFLICT", "COPY", + "DEFERRED", "DELIMITERS", "DETACH", "EACH", + "END", "EXPLAIN", "FAIL", "FOR", + "IGNORE", "IMMEDIATE", "INITIALLY", "INSTEAD", + "MATCH", "KEY", "OF", "RAISE", + "REPLACE", "RESTRICT", "ROW", "STATEMENT", + "TRIGGER", "VIEW", "SEMI", "NONE", + "PREV", "LINEAR", "IMPORT", "TBNAME", + "JOIN", "INSERT", "INTO", "VALUES", + "error", "program", "cmd", "dbPrefix", + "ids", "cpxName", "ifexists", "alter_db_optr", + "alter_topic_optr", "acct_optr", "ifnotexists", "db_optr", + "topic_optr", "pps", "tseries", "dbs", + "streams", "storage", "qtime", "users", + "conns", "state", "keep", "tagitemlist", + "cache", "replica", "quorum", "days", + "minrows", "maxrows", "blocks", "ctime", + "wal", "fsync", "comp", "prec", + "update", "cachelast", "partitions", "typename", + "signed", "create_table_args", "create_stable_args", "create_table_list", + "create_from_stable", "columnlist", "tagNamelist", "select", + "column", "tagitem", "selcollist", "from", + "where_opt", "interval_opt", "session_option", "windowstate_option", + "fill_opt", "sliding_opt", "groupby_opt", "orderby_opt", + "having_opt", "slimit_opt", "limit_opt", "union", + "sclp", "distinct", "expr", "as", + "tablelist", "sub", "tmvar", "sortlist", + "sortitem", "item", "sortorder", "grouplist", + "exprlist", "expritem", }; -#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ +#endif /* NDEBUG */ #ifndef NDEBUG /* For tracing reduce actions, the names of all rules are required. @@ -1200,179 +981,135 @@ static const char *const yyRuleName[] = { /* 170 */ "distinct ::= DISTINCT", /* 171 */ "distinct ::=", /* 172 */ "from ::= FROM tablelist", - /* 173 */ "from ::= FROM LP union RP", - /* 174 */ "tablelist ::= ids cpxName", - /* 175 */ "tablelist ::= ids cpxName ids", - /* 176 */ "tablelist ::= tablelist COMMA ids cpxName", - /* 177 */ "tablelist ::= tablelist COMMA ids cpxName ids", - /* 178 */ "tmvar ::= VARIABLE", - /* 179 */ "interval_opt ::= INTERVAL LP tmvar RP", - /* 180 */ "interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP", - /* 181 */ "interval_opt ::=", - /* 182 */ "session_option ::=", - /* 183 */ "session_option ::= SESSION LP ids cpxName COMMA tmvar RP", - /* 184 */ "windowstate_option ::=", - /* 185 */ "windowstate_option ::= STATE_WINDOW LP ids RP", - /* 186 */ "fill_opt ::=", - /* 187 */ "fill_opt ::= FILL LP ID COMMA tagitemlist RP", - /* 188 */ "fill_opt ::= FILL LP ID RP", - /* 189 */ "sliding_opt ::= SLIDING LP tmvar RP", - /* 190 */ "sliding_opt ::=", - /* 191 */ "orderby_opt ::=", - /* 192 */ "orderby_opt ::= ORDER BY sortlist", - /* 193 */ "sortlist ::= sortlist COMMA item sortorder", - /* 194 */ "sortlist ::= item sortorder", - /* 195 */ "item ::= ids cpxName", - /* 196 */ "sortorder ::= ASC", - /* 197 */ "sortorder ::= DESC", - /* 198 */ "sortorder ::=", - /* 199 */ "groupby_opt ::=", - /* 200 */ "groupby_opt ::= GROUP BY grouplist", - /* 201 */ "grouplist ::= grouplist COMMA item", - /* 202 */ "grouplist ::= item", - /* 203 */ "having_opt ::=", - /* 204 */ "having_opt ::= HAVING expr", - /* 205 */ "limit_opt ::=", - /* 206 */ "limit_opt ::= LIMIT signed", - /* 207 */ "limit_opt ::= LIMIT signed OFFSET signed", - /* 208 */ "limit_opt ::= LIMIT signed COMMA signed", - /* 209 */ "slimit_opt ::=", - /* 210 */ "slimit_opt ::= SLIMIT signed", - /* 211 */ "slimit_opt ::= SLIMIT signed SOFFSET signed", - /* 212 */ "slimit_opt ::= SLIMIT signed COMMA signed", - /* 213 */ "where_opt ::=", - /* 214 */ "where_opt ::= WHERE expr", - /* 215 */ "expr ::= LP expr RP", - /* 216 */ "expr ::= ID", - /* 217 */ "expr ::= ID DOT ID", - /* 218 */ "expr ::= ID DOT STAR", - /* 219 */ "expr ::= INTEGER", - /* 220 */ "expr ::= MINUS INTEGER", - /* 221 */ "expr ::= PLUS INTEGER", - /* 222 */ "expr ::= FLOAT", - /* 223 */ "expr ::= MINUS FLOAT", - /* 224 */ "expr ::= PLUS FLOAT", - /* 225 */ "expr ::= STRING", - /* 226 */ "expr ::= NOW", - /* 227 */ "expr ::= VARIABLE", - /* 228 */ "expr ::= PLUS VARIABLE", - /* 229 */ "expr ::= MINUS VARIABLE", - /* 230 */ "expr ::= BOOL", - /* 231 */ "expr ::= NULL", - /* 232 */ "expr ::= ID LP exprlist RP", - /* 233 */ "expr ::= ID LP STAR RP", - /* 234 */ "expr ::= expr IS NULL", - /* 235 */ "expr ::= expr IS NOT NULL", - /* 236 */ "expr ::= expr LT expr", - /* 237 */ "expr ::= expr GT expr", - /* 238 */ "expr ::= expr LE expr", - /* 239 */ "expr ::= expr GE expr", - /* 240 */ "expr ::= expr NE expr", - /* 241 */ "expr ::= expr EQ expr", - /* 242 */ "expr ::= expr BETWEEN expr AND expr", - /* 243 */ "expr ::= expr AND expr", - /* 244 */ "expr ::= expr OR expr", - /* 245 */ "expr ::= expr PLUS expr", - /* 246 */ "expr ::= expr MINUS expr", - /* 247 */ "expr ::= expr STAR expr", - /* 248 */ "expr ::= expr SLASH expr", - /* 249 */ "expr ::= expr REM expr", - /* 250 */ "expr ::= expr LIKE expr", - /* 251 */ "expr ::= expr IN LP exprlist RP", - /* 252 */ "exprlist ::= exprlist COMMA expritem", - /* 253 */ "exprlist ::= expritem", - /* 254 */ "expritem ::= expr", - /* 255 */ "expritem ::=", - /* 256 */ "cmd ::= RESET QUERY CACHE", - /* 257 */ "cmd ::= SYNCDB ids REPLICA", - /* 258 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", - /* 259 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", - /* 260 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", - /* 261 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", - /* 262 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", - /* 263 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", - /* 264 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", - /* 265 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", - /* 266 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", - /* 267 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", - /* 268 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", - /* 269 */ "cmd ::= KILL CONNECTION INTEGER", - /* 270 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", - /* 271 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", + /* 173 */ "from ::= FROM sub", + /* 174 */ "sub ::= LP union RP", + /* 175 */ "sub ::= LP union RP ids", + /* 176 */ "sub ::= sub COMMA LP union RP ids", + /* 177 */ "tablelist ::= ids cpxName", + /* 178 */ "tablelist ::= ids cpxName ids", + /* 179 */ "tablelist ::= tablelist COMMA ids cpxName", + /* 180 */ "tablelist ::= tablelist COMMA ids cpxName ids", + /* 181 */ "tmvar ::= VARIABLE", + /* 182 */ "interval_opt ::= INTERVAL LP tmvar RP", + /* 183 */ "interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP", + /* 184 */ "interval_opt ::=", + /* 185 */ "session_option ::=", + /* 186 */ "session_option ::= SESSION LP ids cpxName COMMA tmvar RP", + /* 187 */ "windowstate_option ::=", + /* 188 */ "windowstate_option ::= STATE_WINDOW LP ids RP", + /* 189 */ "fill_opt ::=", + /* 190 */ "fill_opt ::= FILL LP ID COMMA tagitemlist RP", + /* 191 */ "fill_opt ::= FILL LP ID RP", + /* 192 */ "sliding_opt ::= SLIDING LP tmvar RP", + /* 193 */ "sliding_opt ::=", + /* 194 */ "orderby_opt ::=", + /* 195 */ "orderby_opt ::= ORDER BY sortlist", + /* 196 */ "sortlist ::= sortlist COMMA item sortorder", + /* 197 */ "sortlist ::= item sortorder", + /* 198 */ "item ::= ids cpxName", + /* 199 */ "sortorder ::= ASC", + /* 200 */ "sortorder ::= DESC", + /* 201 */ "sortorder ::=", + /* 202 */ "groupby_opt ::=", + /* 203 */ "groupby_opt ::= GROUP BY grouplist", + /* 204 */ "grouplist ::= grouplist COMMA item", + /* 205 */ "grouplist ::= item", + /* 206 */ "having_opt ::=", + /* 207 */ "having_opt ::= HAVING expr", + /* 208 */ "limit_opt ::=", + /* 209 */ "limit_opt ::= LIMIT signed", + /* 210 */ "limit_opt ::= LIMIT signed OFFSET signed", + /* 211 */ "limit_opt ::= LIMIT signed COMMA signed", + /* 212 */ "slimit_opt ::=", + /* 213 */ "slimit_opt ::= SLIMIT signed", + /* 214 */ "slimit_opt ::= SLIMIT signed SOFFSET signed", + /* 215 */ "slimit_opt ::= SLIMIT signed COMMA signed", + /* 216 */ "where_opt ::=", + /* 217 */ "where_opt ::= WHERE expr", + /* 218 */ "expr ::= LP expr RP", + /* 219 */ "expr ::= ID", + /* 220 */ "expr ::= ID DOT ID", + /* 221 */ "expr ::= ID DOT STAR", + /* 222 */ "expr ::= INTEGER", + /* 223 */ "expr ::= MINUS INTEGER", + /* 224 */ "expr ::= PLUS INTEGER", + /* 225 */ "expr ::= FLOAT", + /* 226 */ "expr ::= MINUS FLOAT", + /* 227 */ "expr ::= PLUS FLOAT", + /* 228 */ "expr ::= STRING", + /* 229 */ "expr ::= NOW", + /* 230 */ "expr ::= VARIABLE", + /* 231 */ "expr ::= PLUS VARIABLE", + /* 232 */ "expr ::= MINUS VARIABLE", + /* 233 */ "expr ::= BOOL", + /* 234 */ "expr ::= NULL", + /* 235 */ "expr ::= ID LP exprlist RP", + /* 236 */ "expr ::= ID LP STAR RP", + /* 237 */ "expr ::= expr IS NULL", + /* 238 */ "expr ::= expr IS NOT NULL", + /* 239 */ "expr ::= expr LT expr", + /* 240 */ "expr ::= expr GT expr", + /* 241 */ "expr ::= expr LE expr", + /* 242 */ "expr ::= expr GE expr", + /* 243 */ "expr ::= expr NE expr", + /* 244 */ "expr ::= expr EQ expr", + /* 245 */ "expr ::= expr BETWEEN expr AND expr", + /* 246 */ "expr ::= expr AND expr", + /* 247 */ "expr ::= expr OR expr", + /* 248 */ "expr ::= expr PLUS expr", + /* 249 */ "expr ::= expr MINUS expr", + /* 250 */ "expr ::= expr STAR expr", + /* 251 */ "expr ::= expr SLASH expr", + /* 252 */ "expr ::= expr REM expr", + /* 253 */ "expr ::= expr LIKE expr", + /* 254 */ "expr ::= expr IN LP exprlist RP", + /* 255 */ "exprlist ::= exprlist COMMA expritem", + /* 256 */ "exprlist ::= expritem", + /* 257 */ "expritem ::= expr", + /* 258 */ "expritem ::=", + /* 259 */ "cmd ::= RESET QUERY CACHE", + /* 260 */ "cmd ::= SYNCDB ids REPLICA", + /* 261 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", + /* 262 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", + /* 263 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", + /* 264 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", + /* 265 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", + /* 266 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", + /* 267 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", + /* 268 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", + /* 269 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", + /* 270 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", + /* 271 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", + /* 272 */ "cmd ::= KILL CONNECTION INTEGER", + /* 273 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", + /* 274 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", }; #endif /* NDEBUG */ #if YYSTACKDEPTH<=0 /* -** Try to increase the size of the parser stack. Return the number -** of errors. Return 0 on success. +** Try to increase the size of the parser stack. */ -static int yyGrowStack(yyParser *p){ +static void yyGrowStack(yyParser *p){ int newSize; - int idx; yyStackEntry *pNew; newSize = p->yystksz*2 + 100; - idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; - if( p->yystack==&p->yystk0 ){ - pNew = malloc(newSize*sizeof(pNew[0])); - if( pNew ) pNew[0] = p->yystk0; - }else{ - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - } + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); if( pNew ){ p->yystack = pNew; - p->yytos = &p->yystack[idx]; + p->yystksz = newSize; #ifndef NDEBUG if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", - yyTracePrompt, p->yystksz, newSize); + fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", + yyTracePrompt, p->yystksz); } #endif - p->yystksz = newSize; } - return pNew==0; } #endif -/* Datatype of the argument to the memory allocated passed as the -** second argument to ParseAlloc() below. This can be changed by -** putting an appropriate #define in the %include section of the input -** grammar. -*/ -#ifndef YYMALLOCARGTYPE -# define YYMALLOCARGTYPE size_t -#endif - -/* Initialize a new parser that has already been allocated. -*/ -void ParseInit(void *yypParser){ - yyParser *pParser = (yyParser*)yypParser; -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyhwm = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yytos = NULL; - pParser->yystack = NULL; - pParser->yystksz = 0; - if( yyGrowStack(pParser) ){ - pParser->yystack = &pParser->yystk0; - pParser->yystksz = 1; - } -#endif -#ifndef YYNOERRORRECOVERY - pParser->yyerrcnt = -1; -#endif - pParser->yytos = pParser->yystack; - pParser->yystack[0].stateno = 0; - pParser->yystack[0].major = 0; -#if YYSTACKDEPTH>0 - pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1]; -#endif -} - -#ifndef Parse_ENGINEALWAYSONSTACK /* ** This function allocates a new parser. ** The only argument is a pointer to a function which works like @@ -1385,21 +1122,27 @@ void ParseInit(void *yypParser){ ** A pointer to a parser. This pointer is used in subsequent calls ** to Parse and ParseFree. */ -void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ +void *ParseAlloc(void *(*mallocProc)(size_t)){ yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); - if( pParser ) ParseInit(pParser); + pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); + if( pParser ){ + pParser->yyidx = -1; +#ifdef YYTRACKMAXSTACKDEPTH + pParser->yyidxMax = 0; +#endif +#if YYSTACKDEPTH<=0 + pParser->yystack = NULL; + pParser->yystksz = 0; + yyGrowStack(pParser); +#endif + } return pParser; } -#endif /* Parse_ENGINEALWAYSONSTACK */ - -/* The following function deletes the "minor type" or semantic value -** associated with a symbol. The symbol can be either a terminal -** or nonterminal. "yymajor" is the symbol code, and "yypminor" is -** a pointer to the value to be deleted. The code used to do the -** deletions is derived from the %destructor and/or %token_destructor -** directives of the input grammar. +/* The following function deletes the value associated with a +** symbol. The symbol can be either a terminal or nonterminal. +** "yymajor" is the symbol code, and "yypminor" is a pointer to +** the value. */ static void yy_destructor( yyParser *yypParser, /* The parser */ @@ -1415,10 +1158,9 @@ static void yy_destructor( ** being destroyed before it is finished parsing. ** ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are *not* used + ** which appear on the RHS of the rule, but which are not used ** inside the C code. */ -/********* Begin destructor definitions ***************************************/ case 210: /* keep */ case 211: /* tagitemlist */ case 233: /* columnlist */ @@ -1426,54 +1168,54 @@ static void yy_destructor( case 244: /* fill_opt */ case 246: /* groupby_opt */ case 247: /* orderby_opt */ - case 258: /* sortlist */ - case 262: /* grouplist */ + case 259: /* sortlist */ + case 263: /* grouplist */ { -taosArrayDestroy((yypminor->yy291)); +taosArrayDestroy((yypminor->yy193)); } break; case 231: /* create_table_list */ { -destroyCreateTableSql((yypminor->yy412)); +destroyCreateTableSql((yypminor->yy270)); } break; case 235: /* select */ { -destroySqlNode((yypminor->yy6)); +destroySqlNode((yypminor->yy124)); } break; case 238: /* selcollist */ case 252: /* sclp */ - case 263: /* exprlist */ + case 264: /* exprlist */ { -tSqlExprListDestroy((yypminor->yy291)); +tSqlExprListDestroy((yypminor->yy193)); } break; case 239: /* from */ case 256: /* tablelist */ + case 257: /* sub */ { -destroyRelationInfo((yypminor->yy254)); +destroyRelationInfo((yypminor->yy332)); } break; case 240: /* where_opt */ case 248: /* having_opt */ case 254: /* expr */ - case 264: /* expritem */ + case 265: /* expritem */ { -tSqlExprDestroy((yypminor->yy436)); +tSqlExprDestroy((yypminor->yy454)); } break; case 251: /* union */ { -destroyAllSqlNode((yypminor->yy291)); +destroyAllSqlNode((yypminor->yy193)); } break; - case 259: /* sortitem */ + case 260: /* sortitem */ { -tVariantDestroy(&(yypminor->yy216)); +tVariantDestroy(&(yypminor->yy442)); } break; -/********* End destructor definitions *****************************************/ default: break; /* If no destructor action specified: do nothing */ } } @@ -1483,53 +1225,51 @@ tVariantDestroy(&(yypminor->yy216)); ** ** If there is a destructor routine associated with the token which ** is popped from the stack, then call it. +** +** Return the major token number for the symbol popped. */ -static void yy_pop_parser_stack(yyParser *pParser){ - yyStackEntry *yytos; - assert( pParser->yytos!=0 ); - assert( pParser->yytos > pParser->yystack ); - yytos = pParser->yytos--; +static int yy_pop_parser_stack(yyParser *pParser){ + YYCODETYPE yymajor; + yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; + + if( pParser->yyidx<0 ) return 0; #ifndef NDEBUG - if( yyTraceFILE ){ + if( yyTraceFILE && pParser->yyidx>=0 ){ fprintf(yyTraceFILE,"%sPopping %s\n", yyTracePrompt, yyTokenName[yytos->major]); } #endif - yy_destructor(pParser, yytos->major, &yytos->minor); -} - -/* -** Clear all secondary memory allocations from the parser -*/ -void ParseFinalize(void *p){ - yyParser *pParser = (yyParser*)p; - while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); -#endif + yymajor = yytos->major; + yy_destructor(pParser, yymajor, &yytos->minor); + pParser->yyidx--; + return yymajor; } -#ifndef Parse_ENGINEALWAYSONSTACK /* -** Deallocate and destroy a parser. Destructors are called for +** Deallocate and destroy a parser. Destructors are all called for ** all stack elements before shutting the parser down. ** -** If the YYPARSEFREENEVERNULL macro exists (for example because it -** is defined in a %include section of the input grammar) then it is -** assumed that the input pointer is never NULL. +** Inputs: +**
    +**
  • A pointer to the parser. This should be a pointer +** obtained from ParseAlloc. +**
  • A pointer to a function used to reclaim memory obtained +** from malloc. +**
*/ void ParseFree( void *p, /* The parser to be deleted */ void (*freeProc)(void*) /* Function used to reclaim memory */ ){ -#ifndef YYPARSEFREENEVERNULL - if( p==0 ) return; + yyParser *pParser = (yyParser*)p; + if( pParser==0 ) return; + while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + free(pParser->yystack); #endif - ParseFinalize(p); - (*freeProc)(p); + (*freeProc)((void*)pParser); } -#endif /* Parse_ENGINEALWAYSONSTACK */ /* ** Return the peak depth of the stack for a parser. @@ -1537,70 +1277,33 @@ void ParseFree( #ifdef YYTRACKMAXSTACKDEPTH int ParseStackPeak(void *p){ yyParser *pParser = (yyParser*)p; - return pParser->yyhwm; -} -#endif - -/* This array of booleans keeps track of the parser statement -** coverage. The element yycoverage[X][Y] is set when the parser -** is in state X and has a lookahead token Y. In a well-tested -** systems, every element of this matrix should end up being set. -*/ -#if defined(YYCOVERAGE) -static unsigned char yycoverage[YYNSTATE][YYNTOKEN]; -#endif - -/* -** Write into out a description of every state/lookahead combination that -** -** (1) has not been used by the parser, and -** (2) is not a syntax error. -** -** Return the number of missed state/lookahead combinations. -*/ -#if defined(YYCOVERAGE) -int ParseCoverage(FILE *out){ - int stateno, iLookAhead, i; - int nMissed = 0; - for(stateno=0; statenoyyidxMax; } #endif /* ** Find the appropriate action for a parser given the terminal ** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. */ -static unsigned int yy_find_shift_action( +static int yy_find_shift_action( yyParser *pParser, /* The parser */ YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; - int stateno = pParser->yytos->stateno; + int stateno = pParser->yystack[pParser->yyidx].stateno; - if( stateno>YY_MAX_SHIFT ) return stateno; - assert( stateno <= YY_SHIFT_COUNT ); -#if defined(YYCOVERAGE) - yycoverage[stateno][iLookAhead] = 1; -#endif - do{ - i = yy_shift_ofst[stateno]; - assert( i>=0 && i+YYNTOKEN<=sizeof(yy_lookahead)/sizeof(yy_lookahead[0]) ); - assert( iLookAhead!=YYNOCODE ); - assert( iLookAhead < YYNTOKEN ); - i += iLookAhead; - if( yy_lookahead[i]!=iLookAhead ){ + if( stateno>YY_SHIFT_COUNT + || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ + return yy_default[stateno]; + } + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + if( iLookAhead>0 ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ if( iLookAhead=YY_ACTTAB_COUNT j0 + yy_lookahead[j]==YYWILDCARD ){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], - yyTokenName[YYWILDCARD]); + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); } #endif /* NDEBUG */ return yy_action[j]; } } #endif /* YYWILDCARD */ - return yy_default[stateno]; - }else{ - return yy_action[i]; } - }while(1); + return yy_default[stateno]; + }else{ + return yy_action[i]; + } } /* ** Find the appropriate action for a parser given the non-terminal ** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. */ static int yy_find_reduce_action( int stateno, /* Current state number */ @@ -1663,6 +1367,7 @@ static int yy_find_reduce_action( assert( stateno<=YY_REDUCE_COUNT ); #endif i = yy_reduce_ofst[stateno]; + assert( i!=YY_REDUCE_USE_DFLT ); assert( iLookAhead!=YYNOCODE ); i += iLookAhead; #ifdef YYERRORSYMBOL @@ -1679,42 +1384,20 @@ static int yy_find_reduce_action( /* ** The following routine is called if the stack overflows. */ -static void yyStackOverflow(yyParser *yypParser){ +static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ ParseARG_FETCH; + yypParser->yyidx--; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); } #endif - while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will execute if the parser ** stack every overflows */ -/******** Begin %stack_overflow code ******************************************/ -/******** End %stack_overflow code ********************************************/ ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ } -/* -** Print tracing information for a SHIFT action -*/ -#ifndef NDEBUG -static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){ - if( yyTraceFILE ){ - if( yyNewStateyytos->major], - yyNewState); - }else{ - fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n", - yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major], - yyNewState - YY_MIN_REDUCE); - } - } -} -#else -# define yyTraceShift(X,Y,Z) -#endif - /* ** Perform a shift action. */ @@ -1722,320 +1405,327 @@ static void yy_shift( yyParser *yypParser, /* The parser to be shifted */ int yyNewState, /* The new state to shift in */ int yyMajor, /* The major token to shift in */ - ParseTOKENTYPE yyMinor /* The minor token to shift in */ + YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ ){ yyStackEntry *yytos; - yypParser->yytos++; + yypParser->yyidx++; #ifdef YYTRACKMAXSTACKDEPTH - if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); + if( yypParser->yyidx>yypParser->yyidxMax ){ + yypParser->yyidxMax = yypParser->yyidx; } #endif #if YYSTACKDEPTH>0 - if( yypParser->yytos>yypParser->yystackEnd ){ - yypParser->yytos--; - yyStackOverflow(yypParser); + if( yypParser->yyidx>=YYSTACKDEPTH ){ + yyStackOverflow(yypParser, yypMinor); return; } #else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ - if( yyGrowStack(yypParser) ){ - yypParser->yytos--; - yyStackOverflow(yypParser); + if( yypParser->yyidx>=yypParser->yystksz ){ + yyGrowStack(yypParser); + if( yypParser->yyidx>=yypParser->yystksz ){ + yyStackOverflow(yypParser, yypMinor); return; } } #endif - if( yyNewState > YY_MAX_SHIFT ){ - yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; - } - yytos = yypParser->yytos; + yytos = &yypParser->yystack[yypParser->yyidx]; yytos->stateno = (YYACTIONTYPE)yyNewState; yytos->major = (YYCODETYPE)yyMajor; - yytos->minor.yy0 = yyMinor; - yyTraceShift(yypParser, yyNewState, "Shift"); + yytos->minor = *yypMinor; +#ifndef NDEBUG + if( yyTraceFILE && yypParser->yyidx>0 ){ + int i; + fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); + fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); + for(i=1; i<=yypParser->yyidx; i++) + fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); + fprintf(yyTraceFILE,"\n"); + } +#endif } /* The following table contains information about every rule that ** is used during the reduce. */ static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - signed char nrhs; /* Negative of the number of RHS symbols in the rule */ + YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ + unsigned char nrhs; /* Number of right-hand side symbols in the rule */ } yyRuleInfo[] = { - { 189, -1 }, /* (0) program ::= cmd */ - { 190, -2 }, /* (1) cmd ::= SHOW DATABASES */ - { 190, -2 }, /* (2) cmd ::= SHOW TOPICS */ - { 190, -2 }, /* (3) cmd ::= SHOW MNODES */ - { 190, -2 }, /* (4) cmd ::= SHOW DNODES */ - { 190, -2 }, /* (5) cmd ::= SHOW ACCOUNTS */ - { 190, -2 }, /* (6) cmd ::= SHOW USERS */ - { 190, -2 }, /* (7) cmd ::= SHOW MODULES */ - { 190, -2 }, /* (8) cmd ::= SHOW QUERIES */ - { 190, -2 }, /* (9) cmd ::= SHOW CONNECTIONS */ - { 190, -2 }, /* (10) cmd ::= SHOW STREAMS */ - { 190, -2 }, /* (11) cmd ::= SHOW VARIABLES */ - { 190, -2 }, /* (12) cmd ::= SHOW SCORES */ - { 190, -2 }, /* (13) cmd ::= SHOW GRANTS */ - { 190, -2 }, /* (14) cmd ::= SHOW VNODES */ - { 190, -3 }, /* (15) cmd ::= SHOW VNODES IPTOKEN */ - { 191, 0 }, /* (16) dbPrefix ::= */ - { 191, -2 }, /* (17) dbPrefix ::= ids DOT */ - { 193, 0 }, /* (18) cpxName ::= */ - { 193, -2 }, /* (19) cpxName ::= DOT ids */ - { 190, -5 }, /* (20) cmd ::= SHOW CREATE TABLE ids cpxName */ - { 190, -5 }, /* (21) cmd ::= SHOW CREATE STABLE ids cpxName */ - { 190, -4 }, /* (22) cmd ::= SHOW CREATE DATABASE ids */ - { 190, -3 }, /* (23) cmd ::= SHOW dbPrefix TABLES */ - { 190, -5 }, /* (24) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - { 190, -3 }, /* (25) cmd ::= SHOW dbPrefix STABLES */ - { 190, -5 }, /* (26) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - { 190, -3 }, /* (27) cmd ::= SHOW dbPrefix VGROUPS */ - { 190, -4 }, /* (28) cmd ::= SHOW dbPrefix VGROUPS ids */ - { 190, -5 }, /* (29) cmd ::= DROP TABLE ifexists ids cpxName */ - { 190, -5 }, /* (30) cmd ::= DROP STABLE ifexists ids cpxName */ - { 190, -4 }, /* (31) cmd ::= DROP DATABASE ifexists ids */ - { 190, -4 }, /* (32) cmd ::= DROP TOPIC ifexists ids */ - { 190, -3 }, /* (33) cmd ::= DROP DNODE ids */ - { 190, -3 }, /* (34) cmd ::= DROP USER ids */ - { 190, -3 }, /* (35) cmd ::= DROP ACCOUNT ids */ - { 190, -2 }, /* (36) cmd ::= USE ids */ - { 190, -3 }, /* (37) cmd ::= DESCRIBE ids cpxName */ - { 190, -5 }, /* (38) cmd ::= ALTER USER ids PASS ids */ - { 190, -5 }, /* (39) cmd ::= ALTER USER ids PRIVILEGE ids */ - { 190, -4 }, /* (40) cmd ::= ALTER DNODE ids ids */ - { 190, -5 }, /* (41) cmd ::= ALTER DNODE ids ids ids */ - { 190, -3 }, /* (42) cmd ::= ALTER LOCAL ids */ - { 190, -4 }, /* (43) cmd ::= ALTER LOCAL ids ids */ - { 190, -4 }, /* (44) cmd ::= ALTER DATABASE ids alter_db_optr */ - { 190, -4 }, /* (45) cmd ::= ALTER TOPIC ids alter_topic_optr */ - { 190, -4 }, /* (46) cmd ::= ALTER ACCOUNT ids acct_optr */ - { 190, -6 }, /* (47) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - { 192, -1 }, /* (48) ids ::= ID */ - { 192, -1 }, /* (49) ids ::= STRING */ - { 194, -2 }, /* (50) ifexists ::= IF EXISTS */ - { 194, 0 }, /* (51) ifexists ::= */ - { 198, -3 }, /* (52) ifnotexists ::= IF NOT EXISTS */ - { 198, 0 }, /* (53) ifnotexists ::= */ - { 190, -3 }, /* (54) cmd ::= CREATE DNODE ids */ - { 190, -6 }, /* (55) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - { 190, -5 }, /* (56) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - { 190, -5 }, /* (57) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - { 190, -5 }, /* (58) cmd ::= CREATE USER ids PASS ids */ - { 201, 0 }, /* (59) pps ::= */ - { 201, -2 }, /* (60) pps ::= PPS INTEGER */ - { 202, 0 }, /* (61) tseries ::= */ - { 202, -2 }, /* (62) tseries ::= TSERIES INTEGER */ - { 203, 0 }, /* (63) dbs ::= */ - { 203, -2 }, /* (64) dbs ::= DBS INTEGER */ - { 204, 0 }, /* (65) streams ::= */ - { 204, -2 }, /* (66) streams ::= STREAMS INTEGER */ - { 205, 0 }, /* (67) storage ::= */ - { 205, -2 }, /* (68) storage ::= STORAGE INTEGER */ - { 206, 0 }, /* (69) qtime ::= */ - { 206, -2 }, /* (70) qtime ::= QTIME INTEGER */ - { 207, 0 }, /* (71) users ::= */ - { 207, -2 }, /* (72) users ::= USERS INTEGER */ - { 208, 0 }, /* (73) conns ::= */ - { 208, -2 }, /* (74) conns ::= CONNS INTEGER */ - { 209, 0 }, /* (75) state ::= */ - { 209, -2 }, /* (76) state ::= STATE ids */ - { 197, -9 }, /* (77) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - { 210, -2 }, /* (78) keep ::= KEEP tagitemlist */ - { 212, -2 }, /* (79) cache ::= CACHE INTEGER */ - { 213, -2 }, /* (80) replica ::= REPLICA INTEGER */ - { 214, -2 }, /* (81) quorum ::= QUORUM INTEGER */ - { 215, -2 }, /* (82) days ::= DAYS INTEGER */ - { 216, -2 }, /* (83) minrows ::= MINROWS INTEGER */ - { 217, -2 }, /* (84) maxrows ::= MAXROWS INTEGER */ - { 218, -2 }, /* (85) blocks ::= BLOCKS INTEGER */ - { 219, -2 }, /* (86) ctime ::= CTIME INTEGER */ - { 220, -2 }, /* (87) wal ::= WAL INTEGER */ - { 221, -2 }, /* (88) fsync ::= FSYNC INTEGER */ - { 222, -2 }, /* (89) comp ::= COMP INTEGER */ - { 223, -2 }, /* (90) prec ::= PRECISION STRING */ - { 224, -2 }, /* (91) update ::= UPDATE INTEGER */ - { 225, -2 }, /* (92) cachelast ::= CACHELAST INTEGER */ - { 226, -2 }, /* (93) partitions ::= PARTITIONS INTEGER */ - { 199, 0 }, /* (94) db_optr ::= */ - { 199, -2 }, /* (95) db_optr ::= db_optr cache */ - { 199, -2 }, /* (96) db_optr ::= db_optr replica */ - { 199, -2 }, /* (97) db_optr ::= db_optr quorum */ - { 199, -2 }, /* (98) db_optr ::= db_optr days */ - { 199, -2 }, /* (99) db_optr ::= db_optr minrows */ - { 199, -2 }, /* (100) db_optr ::= db_optr maxrows */ - { 199, -2 }, /* (101) db_optr ::= db_optr blocks */ - { 199, -2 }, /* (102) db_optr ::= db_optr ctime */ - { 199, -2 }, /* (103) db_optr ::= db_optr wal */ - { 199, -2 }, /* (104) db_optr ::= db_optr fsync */ - { 199, -2 }, /* (105) db_optr ::= db_optr comp */ - { 199, -2 }, /* (106) db_optr ::= db_optr prec */ - { 199, -2 }, /* (107) db_optr ::= db_optr keep */ - { 199, -2 }, /* (108) db_optr ::= db_optr update */ - { 199, -2 }, /* (109) db_optr ::= db_optr cachelast */ - { 200, -1 }, /* (110) topic_optr ::= db_optr */ - { 200, -2 }, /* (111) topic_optr ::= topic_optr partitions */ - { 195, 0 }, /* (112) alter_db_optr ::= */ - { 195, -2 }, /* (113) alter_db_optr ::= alter_db_optr replica */ - { 195, -2 }, /* (114) alter_db_optr ::= alter_db_optr quorum */ - { 195, -2 }, /* (115) alter_db_optr ::= alter_db_optr keep */ - { 195, -2 }, /* (116) alter_db_optr ::= alter_db_optr blocks */ - { 195, -2 }, /* (117) alter_db_optr ::= alter_db_optr comp */ - { 195, -2 }, /* (118) alter_db_optr ::= alter_db_optr wal */ - { 195, -2 }, /* (119) alter_db_optr ::= alter_db_optr fsync */ - { 195, -2 }, /* (120) alter_db_optr ::= alter_db_optr update */ - { 195, -2 }, /* (121) alter_db_optr ::= alter_db_optr cachelast */ - { 196, -1 }, /* (122) alter_topic_optr ::= alter_db_optr */ - { 196, -2 }, /* (123) alter_topic_optr ::= alter_topic_optr partitions */ - { 227, -1 }, /* (124) typename ::= ids */ - { 227, -4 }, /* (125) typename ::= ids LP signed RP */ - { 227, -2 }, /* (126) typename ::= ids UNSIGNED */ - { 228, -1 }, /* (127) signed ::= INTEGER */ - { 228, -2 }, /* (128) signed ::= PLUS INTEGER */ - { 228, -2 }, /* (129) signed ::= MINUS INTEGER */ - { 190, -3 }, /* (130) cmd ::= CREATE TABLE create_table_args */ - { 190, -3 }, /* (131) cmd ::= CREATE TABLE create_stable_args */ - { 190, -3 }, /* (132) cmd ::= CREATE STABLE create_stable_args */ - { 190, -3 }, /* (133) cmd ::= CREATE TABLE create_table_list */ - { 231, -1 }, /* (134) create_table_list ::= create_from_stable */ - { 231, -2 }, /* (135) create_table_list ::= create_table_list create_from_stable */ - { 229, -6 }, /* (136) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - { 230, -10 }, /* (137) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - { 232, -10 }, /* (138) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - { 232, -13 }, /* (139) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - { 234, -3 }, /* (140) tagNamelist ::= tagNamelist COMMA ids */ - { 234, -1 }, /* (141) tagNamelist ::= ids */ - { 229, -5 }, /* (142) create_table_args ::= ifnotexists ids cpxName AS select */ - { 233, -3 }, /* (143) columnlist ::= columnlist COMMA column */ - { 233, -1 }, /* (144) columnlist ::= column */ - { 236, -2 }, /* (145) column ::= ids typename */ - { 211, -3 }, /* (146) tagitemlist ::= tagitemlist COMMA tagitem */ - { 211, -1 }, /* (147) tagitemlist ::= tagitem */ - { 237, -1 }, /* (148) tagitem ::= INTEGER */ - { 237, -1 }, /* (149) tagitem ::= FLOAT */ - { 237, -1 }, /* (150) tagitem ::= STRING */ - { 237, -1 }, /* (151) tagitem ::= BOOL */ - { 237, -1 }, /* (152) tagitem ::= NULL */ - { 237, -2 }, /* (153) tagitem ::= MINUS INTEGER */ - { 237, -2 }, /* (154) tagitem ::= MINUS FLOAT */ - { 237, -2 }, /* (155) tagitem ::= PLUS INTEGER */ - { 237, -2 }, /* (156) tagitem ::= PLUS FLOAT */ - { 235, -14 }, /* (157) select ::= SELECT selcollist from where_opt interval_opt session_option windowstate_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ - { 235, -3 }, /* (158) select ::= LP select RP */ - { 251, -1 }, /* (159) union ::= select */ - { 251, -4 }, /* (160) union ::= union UNION ALL select */ - { 190, -1 }, /* (161) cmd ::= union */ - { 235, -2 }, /* (162) select ::= SELECT selcollist */ - { 252, -2 }, /* (163) sclp ::= selcollist COMMA */ - { 252, 0 }, /* (164) sclp ::= */ - { 238, -4 }, /* (165) selcollist ::= sclp distinct expr as */ - { 238, -2 }, /* (166) selcollist ::= sclp STAR */ - { 255, -2 }, /* (167) as ::= AS ids */ - { 255, -1 }, /* (168) as ::= ids */ - { 255, 0 }, /* (169) as ::= */ - { 253, -1 }, /* (170) distinct ::= DISTINCT */ - { 253, 0 }, /* (171) distinct ::= */ - { 239, -2 }, /* (172) from ::= FROM tablelist */ - { 239, -4 }, /* (173) from ::= FROM LP union RP */ - { 256, -2 }, /* (174) tablelist ::= ids cpxName */ - { 256, -3 }, /* (175) tablelist ::= ids cpxName ids */ - { 256, -4 }, /* (176) tablelist ::= tablelist COMMA ids cpxName */ - { 256, -5 }, /* (177) tablelist ::= tablelist COMMA ids cpxName ids */ - { 257, -1 }, /* (178) tmvar ::= VARIABLE */ - { 241, -4 }, /* (179) interval_opt ::= INTERVAL LP tmvar RP */ - { 241, -6 }, /* (180) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ - { 241, 0 }, /* (181) interval_opt ::= */ - { 242, 0 }, /* (182) session_option ::= */ - { 242, -7 }, /* (183) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - { 243, 0 }, /* (184) windowstate_option ::= */ - { 243, -4 }, /* (185) windowstate_option ::= STATE_WINDOW LP ids RP */ - { 244, 0 }, /* (186) fill_opt ::= */ - { 244, -6 }, /* (187) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - { 244, -4 }, /* (188) fill_opt ::= FILL LP ID RP */ - { 245, -4 }, /* (189) sliding_opt ::= SLIDING LP tmvar RP */ - { 245, 0 }, /* (190) sliding_opt ::= */ - { 247, 0 }, /* (191) orderby_opt ::= */ - { 247, -3 }, /* (192) orderby_opt ::= ORDER BY sortlist */ - { 258, -4 }, /* (193) sortlist ::= sortlist COMMA item sortorder */ - { 258, -2 }, /* (194) sortlist ::= item sortorder */ - { 260, -2 }, /* (195) item ::= ids cpxName */ - { 261, -1 }, /* (196) sortorder ::= ASC */ - { 261, -1 }, /* (197) sortorder ::= DESC */ - { 261, 0 }, /* (198) sortorder ::= */ - { 246, 0 }, /* (199) groupby_opt ::= */ - { 246, -3 }, /* (200) groupby_opt ::= GROUP BY grouplist */ - { 262, -3 }, /* (201) grouplist ::= grouplist COMMA item */ - { 262, -1 }, /* (202) grouplist ::= item */ - { 248, 0 }, /* (203) having_opt ::= */ - { 248, -2 }, /* (204) having_opt ::= HAVING expr */ - { 250, 0 }, /* (205) limit_opt ::= */ - { 250, -2 }, /* (206) limit_opt ::= LIMIT signed */ - { 250, -4 }, /* (207) limit_opt ::= LIMIT signed OFFSET signed */ - { 250, -4 }, /* (208) limit_opt ::= LIMIT signed COMMA signed */ - { 249, 0 }, /* (209) slimit_opt ::= */ - { 249, -2 }, /* (210) slimit_opt ::= SLIMIT signed */ - { 249, -4 }, /* (211) slimit_opt ::= SLIMIT signed SOFFSET signed */ - { 249, -4 }, /* (212) slimit_opt ::= SLIMIT signed COMMA signed */ - { 240, 0 }, /* (213) where_opt ::= */ - { 240, -2 }, /* (214) where_opt ::= WHERE expr */ - { 254, -3 }, /* (215) expr ::= LP expr RP */ - { 254, -1 }, /* (216) expr ::= ID */ - { 254, -3 }, /* (217) expr ::= ID DOT ID */ - { 254, -3 }, /* (218) expr ::= ID DOT STAR */ - { 254, -1 }, /* (219) expr ::= INTEGER */ - { 254, -2 }, /* (220) expr ::= MINUS INTEGER */ - { 254, -2 }, /* (221) expr ::= PLUS INTEGER */ - { 254, -1 }, /* (222) expr ::= FLOAT */ - { 254, -2 }, /* (223) expr ::= MINUS FLOAT */ - { 254, -2 }, /* (224) expr ::= PLUS FLOAT */ - { 254, -1 }, /* (225) expr ::= STRING */ - { 254, -1 }, /* (226) expr ::= NOW */ - { 254, -1 }, /* (227) expr ::= VARIABLE */ - { 254, -2 }, /* (228) expr ::= PLUS VARIABLE */ - { 254, -2 }, /* (229) expr ::= MINUS VARIABLE */ - { 254, -1 }, /* (230) expr ::= BOOL */ - { 254, -1 }, /* (231) expr ::= NULL */ - { 254, -4 }, /* (232) expr ::= ID LP exprlist RP */ - { 254, -4 }, /* (233) expr ::= ID LP STAR RP */ - { 254, -3 }, /* (234) expr ::= expr IS NULL */ - { 254, -4 }, /* (235) expr ::= expr IS NOT NULL */ - { 254, -3 }, /* (236) expr ::= expr LT expr */ - { 254, -3 }, /* (237) expr ::= expr GT expr */ - { 254, -3 }, /* (238) expr ::= expr LE expr */ - { 254, -3 }, /* (239) expr ::= expr GE expr */ - { 254, -3 }, /* (240) expr ::= expr NE expr */ - { 254, -3 }, /* (241) expr ::= expr EQ expr */ - { 254, -5 }, /* (242) expr ::= expr BETWEEN expr AND expr */ - { 254, -3 }, /* (243) expr ::= expr AND expr */ - { 254, -3 }, /* (244) expr ::= expr OR expr */ - { 254, -3 }, /* (245) expr ::= expr PLUS expr */ - { 254, -3 }, /* (246) expr ::= expr MINUS expr */ - { 254, -3 }, /* (247) expr ::= expr STAR expr */ - { 254, -3 }, /* (248) expr ::= expr SLASH expr */ - { 254, -3 }, /* (249) expr ::= expr REM expr */ - { 254, -3 }, /* (250) expr ::= expr LIKE expr */ - { 254, -5 }, /* (251) expr ::= expr IN LP exprlist RP */ - { 263, -3 }, /* (252) exprlist ::= exprlist COMMA expritem */ - { 263, -1 }, /* (253) exprlist ::= expritem */ - { 264, -1 }, /* (254) expritem ::= expr */ - { 264, 0 }, /* (255) expritem ::= */ - { 190, -3 }, /* (256) cmd ::= RESET QUERY CACHE */ - { 190, -3 }, /* (257) cmd ::= SYNCDB ids REPLICA */ - { 190, -7 }, /* (258) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - { 190, -7 }, /* (259) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - { 190, -7 }, /* (260) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - { 190, -7 }, /* (261) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - { 190, -8 }, /* (262) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - { 190, -9 }, /* (263) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - { 190, -7 }, /* (264) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - { 190, -7 }, /* (265) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - { 190, -7 }, /* (266) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - { 190, -7 }, /* (267) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - { 190, -8 }, /* (268) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - { 190, -3 }, /* (269) cmd ::= KILL CONNECTION INTEGER */ - { 190, -5 }, /* (270) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - { 190, -5 }, /* (271) cmd ::= KILL QUERY INTEGER COLON INTEGER */ + { 189, 1 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 2 }, + { 190, 3 }, + { 191, 0 }, + { 191, 2 }, + { 193, 0 }, + { 193, 2 }, + { 190, 5 }, + { 190, 5 }, + { 190, 4 }, + { 190, 3 }, + { 190, 5 }, + { 190, 3 }, + { 190, 5 }, + { 190, 3 }, + { 190, 4 }, + { 190, 5 }, + { 190, 5 }, + { 190, 4 }, + { 190, 4 }, + { 190, 3 }, + { 190, 3 }, + { 190, 3 }, + { 190, 2 }, + { 190, 3 }, + { 190, 5 }, + { 190, 5 }, + { 190, 4 }, + { 190, 5 }, + { 190, 3 }, + { 190, 4 }, + { 190, 4 }, + { 190, 4 }, + { 190, 4 }, + { 190, 6 }, + { 192, 1 }, + { 192, 1 }, + { 194, 2 }, + { 194, 0 }, + { 198, 3 }, + { 198, 0 }, + { 190, 3 }, + { 190, 6 }, + { 190, 5 }, + { 190, 5 }, + { 190, 5 }, + { 201, 0 }, + { 201, 2 }, + { 202, 0 }, + { 202, 2 }, + { 203, 0 }, + { 203, 2 }, + { 204, 0 }, + { 204, 2 }, + { 205, 0 }, + { 205, 2 }, + { 206, 0 }, + { 206, 2 }, + { 207, 0 }, + { 207, 2 }, + { 208, 0 }, + { 208, 2 }, + { 209, 0 }, + { 209, 2 }, + { 197, 9 }, + { 210, 2 }, + { 212, 2 }, + { 213, 2 }, + { 214, 2 }, + { 215, 2 }, + { 216, 2 }, + { 217, 2 }, + { 218, 2 }, + { 219, 2 }, + { 220, 2 }, + { 221, 2 }, + { 222, 2 }, + { 223, 2 }, + { 224, 2 }, + { 225, 2 }, + { 226, 2 }, + { 199, 0 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 199, 2 }, + { 200, 1 }, + { 200, 2 }, + { 195, 0 }, + { 195, 2 }, + { 195, 2 }, + { 195, 2 }, + { 195, 2 }, + { 195, 2 }, + { 195, 2 }, + { 195, 2 }, + { 195, 2 }, + { 195, 2 }, + { 196, 1 }, + { 196, 2 }, + { 227, 1 }, + { 227, 4 }, + { 227, 2 }, + { 228, 1 }, + { 228, 2 }, + { 228, 2 }, + { 190, 3 }, + { 190, 3 }, + { 190, 3 }, + { 190, 3 }, + { 231, 1 }, + { 231, 2 }, + { 229, 6 }, + { 230, 10 }, + { 232, 10 }, + { 232, 13 }, + { 234, 3 }, + { 234, 1 }, + { 229, 5 }, + { 233, 3 }, + { 233, 1 }, + { 236, 2 }, + { 211, 3 }, + { 211, 1 }, + { 237, 1 }, + { 237, 1 }, + { 237, 1 }, + { 237, 1 }, + { 237, 1 }, + { 237, 2 }, + { 237, 2 }, + { 237, 2 }, + { 237, 2 }, + { 235, 14 }, + { 235, 3 }, + { 251, 1 }, + { 251, 4 }, + { 190, 1 }, + { 235, 2 }, + { 252, 2 }, + { 252, 0 }, + { 238, 4 }, + { 238, 2 }, + { 255, 2 }, + { 255, 1 }, + { 255, 0 }, + { 253, 1 }, + { 253, 0 }, + { 239, 2 }, + { 239, 2 }, + { 257, 3 }, + { 257, 4 }, + { 257, 6 }, + { 256, 2 }, + { 256, 3 }, + { 256, 4 }, + { 256, 5 }, + { 258, 1 }, + { 241, 4 }, + { 241, 6 }, + { 241, 0 }, + { 242, 0 }, + { 242, 7 }, + { 243, 0 }, + { 243, 4 }, + { 244, 0 }, + { 244, 6 }, + { 244, 4 }, + { 245, 4 }, + { 245, 0 }, + { 247, 0 }, + { 247, 3 }, + { 259, 4 }, + { 259, 2 }, + { 261, 2 }, + { 262, 1 }, + { 262, 1 }, + { 262, 0 }, + { 246, 0 }, + { 246, 3 }, + { 263, 3 }, + { 263, 1 }, + { 248, 0 }, + { 248, 2 }, + { 250, 0 }, + { 250, 2 }, + { 250, 4 }, + { 250, 4 }, + { 249, 0 }, + { 249, 2 }, + { 249, 4 }, + { 249, 4 }, + { 240, 0 }, + { 240, 2 }, + { 254, 3 }, + { 254, 1 }, + { 254, 3 }, + { 254, 3 }, + { 254, 1 }, + { 254, 2 }, + { 254, 2 }, + { 254, 1 }, + { 254, 2 }, + { 254, 2 }, + { 254, 1 }, + { 254, 1 }, + { 254, 1 }, + { 254, 2 }, + { 254, 2 }, + { 254, 1 }, + { 254, 1 }, + { 254, 4 }, + { 254, 4 }, + { 254, 3 }, + { 254, 4 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 5 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 3 }, + { 254, 5 }, + { 264, 3 }, + { 264, 1 }, + { 265, 1 }, + { 265, 0 }, + { 190, 3 }, + { 190, 3 }, + { 190, 7 }, + { 190, 7 }, + { 190, 7 }, + { 190, 7 }, + { 190, 8 }, + { 190, 9 }, + { 190, 7 }, + { 190, 7 }, + { 190, 7 }, + { 190, 7 }, + { 190, 8 }, + { 190, 3 }, + { 190, 5 }, + { 190, 5 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -2043,66 +1733,43 @@ static void yy_accept(yyParser*); /* Forward Declaration */ /* ** Perform a reduce action and the shift that must immediately ** follow the reduce. -** -** The yyLookahead and yyLookaheadToken parameters provide reduce actions -** access to the lookahead token (if any). The yyLookahead will be YYNOCODE -** if the lookahead token has already been consumed. As this procedure is -** only called from one place, optimizing compilers will in-line it, which -** means that the extra parameters have no performance impact. */ static void yy_reduce( yyParser *yypParser, /* The parser */ - unsigned int yyruleno, /* Number of the rule by which to reduce */ - int yyLookahead, /* Lookahead token, or YYNOCODE if none */ - ParseTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ + int yyruleno /* Number of the rule by which to reduce */ ){ int yygoto; /* The next state */ int yyact; /* The next action */ + YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ ParseARG_FETCH; - (void)yyLookahead; - (void)yyLookaheadToken; - yymsp = yypParser->yytos; + yymsp = &yypParser->yystack[yypParser->yyidx]; #ifndef NDEBUG - if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfo[yyruleno].nrhs; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno); - }else{ - fprintf(yyTraceFILE, "%sReduce %d [%s].\n", - yyTracePrompt, yyruleno, yyRuleName[yyruleno]); - } + if( yyTraceFILE && yyruleno>=0 + && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, + yyRuleName[yyruleno]); } #endif /* NDEBUG */ - /* Check that the stack is large enough to grow by a single entry - ** if the RHS of the rule is empty. This ensures that there is room - ** enough on the stack to push the LHS value */ - if( yyRuleInfo[yyruleno].nrhs==0 ){ -#ifdef YYTRACKMAXSTACKDEPTH - if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); - return; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); - return; - } - yymsp = yypParser->yytos; - } -#endif - } + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + ** + ** 2007-01-16: The wireshark project (www.wireshark.org) reports that + ** without this code, their parser segfaults. I'm not sure what there + ** parser is doing to make this happen. This is the second bug report + ** from wireshark this week. Clearly they are stressing Lemon in ways + ** that it has not been previously stressed... (SQLite ticket #2172) + */ + /*memset(&yygotominor, 0, sizeof(yygotominor));*/ + yygotominor = yyzerominor; + switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -2113,12 +1780,7 @@ static void yy_reduce( ** #line ** break; */ -/********** Begin reduce actions **********************************************/ - YYMINORTYPE yylhsminor; case 0: /* program ::= cmd */ - case 130: /* cmd ::= CREATE TABLE create_table_args */ yytestcase(yyruleno==130); - case 131: /* cmd ::= CREATE TABLE create_stable_args */ yytestcase(yyruleno==131); - case 132: /* cmd ::= CREATE STABLE create_stable_args */ yytestcase(yyruleno==132); {} break; case 1: /* cmd ::= SHOW DATABASES */ @@ -2167,17 +1829,16 @@ static void yy_reduce( { setShowOptions(pInfo, TSDB_MGMT_TABLE_VNODES, &yymsp[0].minor.yy0, 0); } break; case 16: /* dbPrefix ::= */ -{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.type = 0;} +{yygotominor.yy0.n = 0; yygotominor.yy0.type = 0;} break; case 17: /* dbPrefix ::= ids DOT */ -{yylhsminor.yy0 = yymsp[-1].minor.yy0; } - yymsp[-1].minor.yy0 = yylhsminor.yy0; +{yygotominor.yy0 = yymsp[-1].minor.yy0; } break; case 18: /* cpxName ::= */ -{yymsp[1].minor.yy0.n = 0; } +{yygotominor.yy0.n = 0; } break; case 19: /* cpxName ::= DOT ids */ -{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n += 1; } +{yygotominor.yy0 = yymsp[0].minor.yy0; yygotominor.yy0.n += 1; } break; case 20: /* cmd ::= SHOW CREATE TABLE ids cpxName */ { @@ -2288,39 +1949,36 @@ static void yy_reduce( break; case 44: /* cmd ::= ALTER DATABASE ids alter_db_optr */ case 45: /* cmd ::= ALTER TOPIC ids alter_topic_optr */ yytestcase(yyruleno==45); -{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy122, &t);} +{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy114, &t);} break; case 46: /* cmd ::= ALTER ACCOUNT ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy211);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy183);} break; case 47: /* cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy211);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy183);} break; case 48: /* ids ::= ID */ case 49: /* ids ::= STRING */ yytestcase(yyruleno==49); -{yylhsminor.yy0 = yymsp[0].minor.yy0; } - yymsp[0].minor.yy0 = yylhsminor.yy0; +{yygotominor.yy0 = yymsp[0].minor.yy0; } break; case 50: /* ifexists ::= IF EXISTS */ -{ yymsp[-1].minor.yy0.n = 1;} + case 52: /* ifnotexists ::= IF NOT EXISTS */ yytestcase(yyruleno==52); +{ yygotominor.yy0.n = 1;} break; case 51: /* ifexists ::= */ case 53: /* ifnotexists ::= */ yytestcase(yyruleno==53); case 171: /* distinct ::= */ yytestcase(yyruleno==171); -{ yymsp[1].minor.yy0.n = 0;} - break; - case 52: /* ifnotexists ::= IF NOT EXISTS */ -{ yymsp[-2].minor.yy0.n = 1;} +{ yygotominor.yy0.n = 0;} break; case 54: /* cmd ::= CREATE DNODE ids */ { setDCLSqlElems(pInfo, TSDB_SQL_CREATE_DNODE, 1, &yymsp[0].minor.yy0);} break; case 55: /* cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy211);} +{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy183);} break; case 56: /* cmd ::= CREATE DATABASE ifnotexists ids db_optr */ case 57: /* cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ yytestcase(yyruleno==57); -{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy122, &yymsp[-2].minor.yy0);} +{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy114, &yymsp[-2].minor.yy0);} break; case 58: /* cmd ::= CREATE USER ids PASS ids */ { setCreateUserSql(pInfo, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);} @@ -2334,7 +1992,7 @@ static void yy_reduce( case 71: /* users ::= */ yytestcase(yyruleno==71); case 73: /* conns ::= */ yytestcase(yyruleno==73); case 75: /* state ::= */ yytestcase(yyruleno==75); -{ yymsp[1].minor.yy0.n = 0; } +{ yygotominor.yy0.n = 0; } break; case 60: /* pps ::= PPS INTEGER */ case 62: /* tseries ::= TSERIES INTEGER */ yytestcase(yyruleno==62); @@ -2345,24 +2003,23 @@ static void yy_reduce( case 72: /* users ::= USERS INTEGER */ yytestcase(yyruleno==72); case 74: /* conns ::= CONNS INTEGER */ yytestcase(yyruleno==74); case 76: /* state ::= STATE ids */ yytestcase(yyruleno==76); -{ yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } +{ yygotominor.yy0 = yymsp[0].minor.yy0; } break; case 77: /* acct_optr ::= pps tseries storage streams qtime dbs users conns state */ { - yylhsminor.yy211.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; - yylhsminor.yy211.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; - yylhsminor.yy211.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; - yylhsminor.yy211.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; - yylhsminor.yy211.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; - yylhsminor.yy211.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy211.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy211.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; - yylhsminor.yy211.stat = yymsp[0].minor.yy0; -} - yymsp[-8].minor.yy211 = yylhsminor.yy211; + yygotominor.yy183.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; + yygotominor.yy183.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; + yygotominor.yy183.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; + yygotominor.yy183.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; + yygotominor.yy183.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; + yygotominor.yy183.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; + yygotominor.yy183.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; + yygotominor.yy183.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; + yygotominor.yy183.stat = yymsp[0].minor.yy0; +} break; case 78: /* keep ::= KEEP tagitemlist */ -{ yymsp[-1].minor.yy291 = yymsp[0].minor.yy291; } +{ yygotominor.yy193 = yymsp[0].minor.yy193; } break; case 79: /* cache ::= CACHE INTEGER */ case 80: /* replica ::= REPLICA INTEGER */ yytestcase(yyruleno==80); @@ -2379,237 +2036,201 @@ static void yy_reduce( case 91: /* update ::= UPDATE INTEGER */ yytestcase(yyruleno==91); case 92: /* cachelast ::= CACHELAST INTEGER */ yytestcase(yyruleno==92); case 93: /* partitions ::= PARTITIONS INTEGER */ yytestcase(yyruleno==93); -{ yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } +{ yygotominor.yy0 = yymsp[0].minor.yy0; } break; case 94: /* db_optr ::= */ -{setDefaultCreateDbOption(&yymsp[1].minor.yy122); yymsp[1].minor.yy122.dbType = TSDB_DB_TYPE_DEFAULT;} +{setDefaultCreateDbOption(&yygotominor.yy114); yygotominor.yy114.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 95: /* db_optr ::= db_optr cache */ -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 96: /* db_optr ::= db_optr replica */ case 113: /* alter_db_optr ::= alter_db_optr replica */ yytestcase(yyruleno==113); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 97: /* db_optr ::= db_optr quorum */ case 114: /* alter_db_optr ::= alter_db_optr quorum */ yytestcase(yyruleno==114); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 98: /* db_optr ::= db_optr days */ -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 99: /* db_optr ::= db_optr minrows */ -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } break; case 100: /* db_optr ::= db_optr maxrows */ -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } break; case 101: /* db_optr ::= db_optr blocks */ case 116: /* alter_db_optr ::= alter_db_optr blocks */ yytestcase(yyruleno==116); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 102: /* db_optr ::= db_optr ctime */ -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 103: /* db_optr ::= db_optr wal */ case 118: /* alter_db_optr ::= alter_db_optr wal */ yytestcase(yyruleno==118); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 104: /* db_optr ::= db_optr fsync */ case 119: /* alter_db_optr ::= alter_db_optr fsync */ yytestcase(yyruleno==119); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 105: /* db_optr ::= db_optr comp */ case 117: /* alter_db_optr ::= alter_db_optr comp */ yytestcase(yyruleno==117); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 106: /* db_optr ::= db_optr prec */ -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.precision = yymsp[0].minor.yy0; } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.precision = yymsp[0].minor.yy0; } break; case 107: /* db_optr ::= db_optr keep */ case 115: /* alter_db_optr ::= alter_db_optr keep */ yytestcase(yyruleno==115); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.keep = yymsp[0].minor.yy291; } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.keep = yymsp[0].minor.yy193; } break; case 108: /* db_optr ::= db_optr update */ case 120: /* alter_db_optr ::= alter_db_optr update */ yytestcase(yyruleno==120); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 109: /* db_optr ::= db_optr cachelast */ case 121: /* alter_db_optr ::= alter_db_optr cachelast */ yytestcase(yyruleno==121); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 110: /* topic_optr ::= db_optr */ case 122: /* alter_topic_optr ::= alter_db_optr */ yytestcase(yyruleno==122); -{ yylhsminor.yy122 = yymsp[0].minor.yy122; yylhsminor.yy122.dbType = TSDB_DB_TYPE_TOPIC; } - yymsp[0].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[0].minor.yy114; yygotominor.yy114.dbType = TSDB_DB_TYPE_TOPIC; } break; case 111: /* topic_optr ::= topic_optr partitions */ case 123: /* alter_topic_optr ::= alter_topic_optr partitions */ yytestcase(yyruleno==123); -{ yylhsminor.yy122 = yymsp[-1].minor.yy122; yylhsminor.yy122.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy122 = yylhsminor.yy122; +{ yygotominor.yy114 = yymsp[-1].minor.yy114; yygotominor.yy114.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 112: /* alter_db_optr ::= */ -{ setDefaultCreateDbOption(&yymsp[1].minor.yy122); yymsp[1].minor.yy122.dbType = TSDB_DB_TYPE_DEFAULT;} +{ setDefaultCreateDbOption(&yygotominor.yy114); yygotominor.yy114.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 124: /* typename ::= ids */ { yymsp[0].minor.yy0.type = 0; - tSetColumnType (&yylhsminor.yy153, &yymsp[0].minor.yy0); + tSetColumnType (&yygotominor.yy27, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy153 = yylhsminor.yy153; break; case 125: /* typename ::= ids LP signed RP */ { - if (yymsp[-1].minor.yy179 <= 0) { + if (yymsp[-1].minor.yy473 <= 0) { yymsp[-3].minor.yy0.type = 0; - tSetColumnType(&yylhsminor.yy153, &yymsp[-3].minor.yy0); + tSetColumnType(&yygotominor.yy27, &yymsp[-3].minor.yy0); } else { - yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy179; // negative value of name length - tSetColumnType(&yylhsminor.yy153, &yymsp[-3].minor.yy0); + yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy473; // negative value of name length + tSetColumnType(&yygotominor.yy27, &yymsp[-3].minor.yy0); } } - yymsp[-3].minor.yy153 = yylhsminor.yy153; break; case 126: /* typename ::= ids UNSIGNED */ { yymsp[-1].minor.yy0.type = 0; yymsp[-1].minor.yy0.n = ((yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z); - tSetColumnType (&yylhsminor.yy153, &yymsp[-1].minor.yy0); + tSetColumnType (&yygotominor.yy27, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy153 = yylhsminor.yy153; break; case 127: /* signed ::= INTEGER */ -{ yylhsminor.yy179 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[0].minor.yy179 = yylhsminor.yy179; - break; - case 128: /* signed ::= PLUS INTEGER */ -{ yymsp[-1].minor.yy179 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + case 128: /* signed ::= PLUS INTEGER */ yytestcase(yyruleno==128); +{ yygotominor.yy473 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 129: /* signed ::= MINUS INTEGER */ -{ yymsp[-1].minor.yy179 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} + case 130: /* cmd ::= CREATE TABLE create_table_args */ yytestcase(yyruleno==130); + case 131: /* cmd ::= CREATE TABLE create_stable_args */ yytestcase(yyruleno==131); + case 132: /* cmd ::= CREATE STABLE create_stable_args */ yytestcase(yyruleno==132); +{ yygotominor.yy473 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} break; case 133: /* cmd ::= CREATE TABLE create_table_list */ -{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy412;} +{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy270;} break; case 134: /* create_table_list ::= create_from_stable */ { SCreateTableSql* pCreateTable = calloc(1, sizeof(SCreateTableSql)); pCreateTable->childTableInfo = taosArrayInit(4, sizeof(SCreatedTableInfo)); - taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy446); + taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy192); pCreateTable->type = TSQL_CREATE_TABLE_FROM_STABLE; - yylhsminor.yy412 = pCreateTable; + yygotominor.yy270 = pCreateTable; } - yymsp[0].minor.yy412 = yylhsminor.yy412; break; case 135: /* create_table_list ::= create_table_list create_from_stable */ { - taosArrayPush(yymsp[-1].minor.yy412->childTableInfo, &yymsp[0].minor.yy446); - yylhsminor.yy412 = yymsp[-1].minor.yy412; + taosArrayPush(yymsp[-1].minor.yy270->childTableInfo, &yymsp[0].minor.yy192); + yygotominor.yy270 = yymsp[-1].minor.yy270; } - yymsp[-1].minor.yy412 = yylhsminor.yy412; break; case 136: /* create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ { - yylhsminor.yy412 = tSetCreateTableInfo(yymsp[-1].minor.yy291, NULL, NULL, TSQL_CREATE_TABLE); - setSqlInfo(pInfo, yylhsminor.yy412, NULL, TSDB_SQL_CREATE_TABLE); + yygotominor.yy270 = tSetCreateTableInfo(yymsp[-1].minor.yy193, NULL, NULL, TSQL_CREATE_TABLE); + setSqlInfo(pInfo, yygotominor.yy270, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-4].minor.yy0, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy412 = yylhsminor.yy412; break; case 137: /* create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ { - yylhsminor.yy412 = tSetCreateTableInfo(yymsp[-5].minor.yy291, yymsp[-1].minor.yy291, NULL, TSQL_CREATE_STABLE); - setSqlInfo(pInfo, yylhsminor.yy412, NULL, TSDB_SQL_CREATE_TABLE); + yygotominor.yy270 = tSetCreateTableInfo(yymsp[-5].minor.yy193, yymsp[-1].minor.yy193, NULL, TSQL_CREATE_STABLE); + setSqlInfo(pInfo, yygotominor.yy270, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy412 = yylhsminor.yy412; break; case 138: /* create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; - yylhsminor.yy446 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy291, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); + yygotominor.yy192 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy193, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy446 = yylhsminor.yy446; break; case 139: /* create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ { yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; yymsp[-11].minor.yy0.n += yymsp[-10].minor.yy0.n; - yylhsminor.yy446 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy291, yymsp[-1].minor.yy291, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); + yygotominor.yy192 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy193, yymsp[-1].minor.yy193, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); } - yymsp[-12].minor.yy446 = yylhsminor.yy446; break; case 140: /* tagNamelist ::= tagNamelist COMMA ids */ -{taosArrayPush(yymsp[-2].minor.yy291, &yymsp[0].minor.yy0); yylhsminor.yy291 = yymsp[-2].minor.yy291; } - yymsp[-2].minor.yy291 = yylhsminor.yy291; +{taosArrayPush(yymsp[-2].minor.yy193, &yymsp[0].minor.yy0); yygotominor.yy193 = yymsp[-2].minor.yy193; } break; case 141: /* tagNamelist ::= ids */ -{yylhsminor.yy291 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy291, &yymsp[0].minor.yy0);} - yymsp[0].minor.yy291 = yylhsminor.yy291; +{yygotominor.yy193 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yygotominor.yy193, &yymsp[0].minor.yy0);} break; case 142: /* create_table_args ::= ifnotexists ids cpxName AS select */ { - yylhsminor.yy412 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy6, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, yylhsminor.yy412, NULL, TSDB_SQL_CREATE_TABLE); + yygotominor.yy270 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy124, TSQL_CREATE_STREAM); + setSqlInfo(pInfo, yygotominor.yy270, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-3].minor.yy0.n += yymsp[-2].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-3].minor.yy0, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy412 = yylhsminor.yy412; break; case 143: /* columnlist ::= columnlist COMMA column */ -{taosArrayPush(yymsp[-2].minor.yy291, &yymsp[0].minor.yy153); yylhsminor.yy291 = yymsp[-2].minor.yy291; } - yymsp[-2].minor.yy291 = yylhsminor.yy291; +{taosArrayPush(yymsp[-2].minor.yy193, &yymsp[0].minor.yy27); yygotominor.yy193 = yymsp[-2].minor.yy193; } break; case 144: /* columnlist ::= column */ -{yylhsminor.yy291 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy291, &yymsp[0].minor.yy153);} - yymsp[0].minor.yy291 = yylhsminor.yy291; +{yygotominor.yy193 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yygotominor.yy193, &yymsp[0].minor.yy27);} break; case 145: /* column ::= ids typename */ { - tSetColumnInfo(&yylhsminor.yy153, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy153); + tSetColumnInfo(&yygotominor.yy27, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy27); } - yymsp[-1].minor.yy153 = yylhsminor.yy153; break; case 146: /* tagitemlist ::= tagitemlist COMMA tagitem */ -{ yylhsminor.yy291 = tVariantListAppend(yymsp[-2].minor.yy291, &yymsp[0].minor.yy216, -1); } - yymsp[-2].minor.yy291 = yylhsminor.yy291; +{ yygotominor.yy193 = tVariantListAppend(yymsp[-2].minor.yy193, &yymsp[0].minor.yy442, -1); } break; case 147: /* tagitemlist ::= tagitem */ -{ yylhsminor.yy291 = tVariantListAppend(NULL, &yymsp[0].minor.yy216, -1); } - yymsp[0].minor.yy291 = yylhsminor.yy291; +{ yygotominor.yy193 = tVariantListAppend(NULL, &yymsp[0].minor.yy442, -1); } break; case 148: /* tagitem ::= INTEGER */ case 149: /* tagitem ::= FLOAT */ yytestcase(yyruleno==149); case 150: /* tagitem ::= STRING */ yytestcase(yyruleno==150); case 151: /* tagitem ::= BOOL */ yytestcase(yyruleno==151); -{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy216, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy216 = yylhsminor.yy216; +{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yygotominor.yy442, &yymsp[0].minor.yy0); } break; case 152: /* tagitem ::= NULL */ -{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy216, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy216 = yylhsminor.yy216; +{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yygotominor.yy442, &yymsp[0].minor.yy0); } break; case 153: /* tagitem ::= MINUS INTEGER */ case 154: /* tagitem ::= MINUS FLOAT */ yytestcase(yyruleno==154); @@ -2619,406 +2240,350 @@ static void yy_reduce( yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = yymsp[0].minor.yy0.type; toTSDBType(yymsp[-1].minor.yy0.type); - tVariantCreate(&yylhsminor.yy216, &yymsp[-1].minor.yy0); + tVariantCreate(&yygotominor.yy442, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy216 = yylhsminor.yy216; break; case 157: /* select ::= SELECT selcollist from where_opt interval_opt session_option windowstate_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ { - yylhsminor.yy6 = tSetQuerySqlNode(&yymsp[-13].minor.yy0, yymsp[-12].minor.yy291, yymsp[-11].minor.yy254, yymsp[-10].minor.yy436, yymsp[-4].minor.yy291, yymsp[-3].minor.yy291, &yymsp[-9].minor.yy400, &yymsp[-8].minor.yy139, &yymsp[-7].minor.yy158, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy291, &yymsp[0].minor.yy74, &yymsp[-1].minor.yy74, yymsp[-2].minor.yy436); + yygotominor.yy124 = tSetQuerySqlNode(&yymsp[-13].minor.yy0, yymsp[-12].minor.yy193, yymsp[-11].minor.yy332, yymsp[-10].minor.yy454, yymsp[-4].minor.yy193, yymsp[-3].minor.yy193, &yymsp[-9].minor.yy392, &yymsp[-8].minor.yy447, &yymsp[-7].minor.yy76, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy193, &yymsp[0].minor.yy482, &yymsp[-1].minor.yy482, yymsp[-2].minor.yy454); } - yymsp[-13].minor.yy6 = yylhsminor.yy6; break; case 158: /* select ::= LP select RP */ -{yymsp[-2].minor.yy6 = yymsp[-1].minor.yy6;} +{yygotominor.yy124 = yymsp[-1].minor.yy124;} break; case 159: /* union ::= select */ -{ yylhsminor.yy291 = setSubclause(NULL, yymsp[0].minor.yy6); } - yymsp[0].minor.yy291 = yylhsminor.yy291; +{ yygotominor.yy193 = setSubclause(NULL, yymsp[0].minor.yy124); } break; case 160: /* union ::= union UNION ALL select */ -{ yylhsminor.yy291 = appendSelectClause(yymsp[-3].minor.yy291, yymsp[0].minor.yy6); } - yymsp[-3].minor.yy291 = yylhsminor.yy291; +{ yygotominor.yy193 = appendSelectClause(yymsp[-3].minor.yy193, yymsp[0].minor.yy124); } break; case 161: /* cmd ::= union */ -{ setSqlInfo(pInfo, yymsp[0].minor.yy291, NULL, TSDB_SQL_SELECT); } +{ setSqlInfo(pInfo, yymsp[0].minor.yy193, NULL, TSDB_SQL_SELECT); } break; case 162: /* select ::= SELECT selcollist */ { - yylhsminor.yy6 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy291, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + yygotominor.yy124 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy193, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } - yymsp[-1].minor.yy6 = yylhsminor.yy6; break; case 163: /* sclp ::= selcollist COMMA */ -{yylhsminor.yy291 = yymsp[-1].minor.yy291;} - yymsp[-1].minor.yy291 = yylhsminor.yy291; +{yygotominor.yy193 = yymsp[-1].minor.yy193;} break; case 164: /* sclp ::= */ - case 191: /* orderby_opt ::= */ yytestcase(yyruleno==191); -{yymsp[1].minor.yy291 = 0;} + case 194: /* orderby_opt ::= */ yytestcase(yyruleno==194); +{yygotominor.yy193 = 0;} break; case 165: /* selcollist ::= sclp distinct expr as */ { - yylhsminor.yy291 = tSqlExprListAppend(yymsp[-3].minor.yy291, yymsp[-1].minor.yy436, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); + yygotominor.yy193 = tSqlExprListAppend(yymsp[-3].minor.yy193, yymsp[-1].minor.yy454, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); } - yymsp[-3].minor.yy291 = yylhsminor.yy291; break; case 166: /* selcollist ::= sclp STAR */ { tSqlExpr *pNode = tSqlExprCreateIdValue(NULL, TK_ALL); - yylhsminor.yy291 = tSqlExprListAppend(yymsp[-1].minor.yy291, pNode, 0, 0); + yygotominor.yy193 = tSqlExprListAppend(yymsp[-1].minor.yy193, pNode, 0, 0); } - yymsp[-1].minor.yy291 = yylhsminor.yy291; break; case 167: /* as ::= AS ids */ -{ yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } - break; - case 168: /* as ::= ids */ -{ yylhsminor.yy0 = yymsp[0].minor.yy0; } - yymsp[0].minor.yy0 = yylhsminor.yy0; + case 168: /* as ::= ids */ yytestcase(yyruleno==168); +{ yygotominor.yy0 = yymsp[0].minor.yy0; } break; case 169: /* as ::= */ -{ yymsp[1].minor.yy0.n = 0; } +{ yygotominor.yy0.n = 0; } break; case 170: /* distinct ::= DISTINCT */ -{ yylhsminor.yy0 = yymsp[0].minor.yy0; } - yymsp[0].minor.yy0 = yylhsminor.yy0; +{ yygotominor.yy0 = yymsp[0].minor.yy0; } break; case 172: /* from ::= FROM tablelist */ -{yymsp[-1].minor.yy254 = yymsp[0].minor.yy254;} + case 173: /* from ::= FROM sub */ yytestcase(yyruleno==173); +{yygotominor.yy332 = yymsp[0].minor.yy332;} + break; + case 174: /* sub ::= LP union RP */ +{yygotominor.yy332 = addSubqueryElem(NULL, yymsp[-1].minor.yy193, NULL);} break; - case 173: /* from ::= FROM LP union RP */ -{yymsp[-3].minor.yy254 = setSubquery(NULL, yymsp[-1].minor.yy291);} + case 175: /* sub ::= LP union RP ids */ +{yygotominor.yy332 = addSubqueryElem(NULL, yymsp[-2].minor.yy193, &yymsp[0].minor.yy0);} break; - case 174: /* tablelist ::= ids cpxName */ + case 176: /* sub ::= sub COMMA LP union RP ids */ +{yygotominor.yy332 = addSubqueryElem(yymsp[-5].minor.yy332, yymsp[-2].minor.yy193, &yymsp[0].minor.yy0);} + break; + case 177: /* tablelist ::= ids cpxName */ { yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy254 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); + yygotominor.yy332 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); } - yymsp[-1].minor.yy254 = yylhsminor.yy254; break; - case 175: /* tablelist ::= ids cpxName ids */ + case 178: /* tablelist ::= ids cpxName ids */ { yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy254 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yygotominor.yy332 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy254 = yylhsminor.yy254; break; - case 176: /* tablelist ::= tablelist COMMA ids cpxName */ + case 179: /* tablelist ::= tablelist COMMA ids cpxName */ { yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy254 = setTableNameList(yymsp[-3].minor.yy254, &yymsp[-1].minor.yy0, NULL); + yygotominor.yy332 = setTableNameList(yymsp[-3].minor.yy332, &yymsp[-1].minor.yy0, NULL); } - yymsp[-3].minor.yy254 = yylhsminor.yy254; break; - case 177: /* tablelist ::= tablelist COMMA ids cpxName ids */ + case 180: /* tablelist ::= tablelist COMMA ids cpxName ids */ { yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy254 = setTableNameList(yymsp[-4].minor.yy254, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yygotominor.yy332 = setTableNameList(yymsp[-4].minor.yy332, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-4].minor.yy254 = yylhsminor.yy254; break; - case 178: /* tmvar ::= VARIABLE */ -{yylhsminor.yy0 = yymsp[0].minor.yy0;} - yymsp[0].minor.yy0 = yylhsminor.yy0; + case 181: /* tmvar ::= VARIABLE */ +{yygotominor.yy0 = yymsp[0].minor.yy0;} break; - case 179: /* interval_opt ::= INTERVAL LP tmvar RP */ -{yymsp[-3].minor.yy400.interval = yymsp[-1].minor.yy0; yymsp[-3].minor.yy400.offset.n = 0;} + case 182: /* interval_opt ::= INTERVAL LP tmvar RP */ +{yygotominor.yy392.interval = yymsp[-1].minor.yy0; yygotominor.yy392.offset.n = 0;} break; - case 180: /* interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ -{yymsp[-5].minor.yy400.interval = yymsp[-3].minor.yy0; yymsp[-5].minor.yy400.offset = yymsp[-1].minor.yy0;} + case 183: /* interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ +{yygotominor.yy392.interval = yymsp[-3].minor.yy0; yygotominor.yy392.offset = yymsp[-1].minor.yy0;} break; - case 181: /* interval_opt ::= */ -{memset(&yymsp[1].minor.yy400, 0, sizeof(yymsp[1].minor.yy400));} + case 184: /* interval_opt ::= */ +{memset(&yygotominor.yy392, 0, sizeof(yygotominor.yy392));} break; - case 182: /* session_option ::= */ -{yymsp[1].minor.yy139.col.n = 0; yymsp[1].minor.yy139.gap.n = 0;} + case 185: /* session_option ::= */ +{yygotominor.yy447.col.n = 0; yygotominor.yy447.gap.n = 0;} break; - case 183: /* session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ + case 186: /* session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - yymsp[-6].minor.yy139.col = yymsp[-4].minor.yy0; - yymsp[-6].minor.yy139.gap = yymsp[-1].minor.yy0; + yygotominor.yy447.col = yymsp[-4].minor.yy0; + yygotominor.yy447.gap = yymsp[-1].minor.yy0; } break; - case 184: /* windowstate_option ::= */ -{yymsp[1].minor.yy158.col.n = 0;} + case 187: /* windowstate_option ::= */ +{yygotominor.yy76.col.n = 0;} break; - case 185: /* windowstate_option ::= STATE_WINDOW LP ids RP */ + case 188: /* windowstate_option ::= STATE_WINDOW LP ids RP */ { - yymsp[-3].minor.yy158.col = yymsp[-1].minor.yy0; + yygotominor.yy76.col = yymsp[-1].minor.yy0; } break; - case 186: /* fill_opt ::= */ -{ yymsp[1].minor.yy291 = 0; } + case 189: /* fill_opt ::= */ +{ yygotominor.yy193 = 0; } break; - case 187: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */ + case 190: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */ { tVariant A = {0}; toTSDBType(yymsp[-3].minor.yy0.type); tVariantCreate(&A, &yymsp[-3].minor.yy0); - tVariantListInsert(yymsp[-1].minor.yy291, &A, -1, 0); - yymsp[-5].minor.yy291 = yymsp[-1].minor.yy291; + tVariantListInsert(yymsp[-1].minor.yy193, &A, -1, 0); + yygotominor.yy193 = yymsp[-1].minor.yy193; } break; - case 188: /* fill_opt ::= FILL LP ID RP */ + case 191: /* fill_opt ::= FILL LP ID RP */ { toTSDBType(yymsp[-1].minor.yy0.type); - yymsp[-3].minor.yy291 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); + yygotominor.yy193 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); } break; - case 189: /* sliding_opt ::= SLIDING LP tmvar RP */ -{yymsp[-3].minor.yy0 = yymsp[-1].minor.yy0; } + case 192: /* sliding_opt ::= SLIDING LP tmvar RP */ +{yygotominor.yy0 = yymsp[-1].minor.yy0; } break; - case 190: /* sliding_opt ::= */ -{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = NULL; yymsp[1].minor.yy0.type = 0; } + case 193: /* sliding_opt ::= */ +{yygotominor.yy0.n = 0; yygotominor.yy0.z = NULL; yygotominor.yy0.type = 0; } break; - case 192: /* orderby_opt ::= ORDER BY sortlist */ -{yymsp[-2].minor.yy291 = yymsp[0].minor.yy291;} + case 195: /* orderby_opt ::= ORDER BY sortlist */ +{yygotominor.yy193 = yymsp[0].minor.yy193;} break; - case 193: /* sortlist ::= sortlist COMMA item sortorder */ + case 196: /* sortlist ::= sortlist COMMA item sortorder */ { - yylhsminor.yy291 = tVariantListAppend(yymsp[-3].minor.yy291, &yymsp[-1].minor.yy216, yymsp[0].minor.yy382); + yygotominor.yy193 = tVariantListAppend(yymsp[-3].minor.yy193, &yymsp[-1].minor.yy442, yymsp[0].minor.yy312); } - yymsp[-3].minor.yy291 = yylhsminor.yy291; break; - case 194: /* sortlist ::= item sortorder */ + case 197: /* sortlist ::= item sortorder */ { - yylhsminor.yy291 = tVariantListAppend(NULL, &yymsp[-1].minor.yy216, yymsp[0].minor.yy382); + yygotominor.yy193 = tVariantListAppend(NULL, &yymsp[-1].minor.yy442, yymsp[0].minor.yy312); } - yymsp[-1].minor.yy291 = yylhsminor.yy291; break; - case 195: /* item ::= ids cpxName */ + case 198: /* item ::= ids cpxName */ { toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - tVariantCreate(&yylhsminor.yy216, &yymsp[-1].minor.yy0); + tVariantCreate(&yygotominor.yy442, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy216 = yylhsminor.yy216; - break; - case 196: /* sortorder ::= ASC */ -{ yymsp[0].minor.yy382 = TSDB_ORDER_ASC; } break; - case 197: /* sortorder ::= DESC */ -{ yymsp[0].minor.yy382 = TSDB_ORDER_DESC;} + case 199: /* sortorder ::= ASC */ + case 201: /* sortorder ::= */ yytestcase(yyruleno==201); +{ yygotominor.yy312 = TSDB_ORDER_ASC; } break; - case 198: /* sortorder ::= */ -{ yymsp[1].minor.yy382 = TSDB_ORDER_ASC; } + case 200: /* sortorder ::= DESC */ +{ yygotominor.yy312 = TSDB_ORDER_DESC;} break; - case 199: /* groupby_opt ::= */ -{ yymsp[1].minor.yy291 = 0;} + case 202: /* groupby_opt ::= */ +{ yygotominor.yy193 = 0;} break; - case 200: /* groupby_opt ::= GROUP BY grouplist */ -{ yymsp[-2].minor.yy291 = yymsp[0].minor.yy291;} + case 203: /* groupby_opt ::= GROUP BY grouplist */ +{ yygotominor.yy193 = yymsp[0].minor.yy193;} break; - case 201: /* grouplist ::= grouplist COMMA item */ + case 204: /* grouplist ::= grouplist COMMA item */ { - yylhsminor.yy291 = tVariantListAppend(yymsp[-2].minor.yy291, &yymsp[0].minor.yy216, -1); + yygotominor.yy193 = tVariantListAppend(yymsp[-2].minor.yy193, &yymsp[0].minor.yy442, -1); } - yymsp[-2].minor.yy291 = yylhsminor.yy291; break; - case 202: /* grouplist ::= item */ + case 205: /* grouplist ::= item */ { - yylhsminor.yy291 = tVariantListAppend(NULL, &yymsp[0].minor.yy216, -1); + yygotominor.yy193 = tVariantListAppend(NULL, &yymsp[0].minor.yy442, -1); } - yymsp[0].minor.yy291 = yylhsminor.yy291; break; - case 203: /* having_opt ::= */ - case 213: /* where_opt ::= */ yytestcase(yyruleno==213); - case 255: /* expritem ::= */ yytestcase(yyruleno==255); -{yymsp[1].minor.yy436 = 0;} + case 206: /* having_opt ::= */ + case 216: /* where_opt ::= */ yytestcase(yyruleno==216); + case 258: /* expritem ::= */ yytestcase(yyruleno==258); +{yygotominor.yy454 = 0;} break; - case 204: /* having_opt ::= HAVING expr */ - case 214: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==214); -{yymsp[-1].minor.yy436 = yymsp[0].minor.yy436;} + case 207: /* having_opt ::= HAVING expr */ + case 217: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==217); + case 257: /* expritem ::= expr */ yytestcase(yyruleno==257); +{yygotominor.yy454 = yymsp[0].minor.yy454;} break; - case 205: /* limit_opt ::= */ - case 209: /* slimit_opt ::= */ yytestcase(yyruleno==209); -{yymsp[1].minor.yy74.limit = -1; yymsp[1].minor.yy74.offset = 0;} + case 208: /* limit_opt ::= */ + case 212: /* slimit_opt ::= */ yytestcase(yyruleno==212); +{yygotominor.yy482.limit = -1; yygotominor.yy482.offset = 0;} break; - case 206: /* limit_opt ::= LIMIT signed */ - case 210: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==210); -{yymsp[-1].minor.yy74.limit = yymsp[0].minor.yy179; yymsp[-1].minor.yy74.offset = 0;} + case 209: /* limit_opt ::= LIMIT signed */ + case 213: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==213); +{yygotominor.yy482.limit = yymsp[0].minor.yy473; yygotominor.yy482.offset = 0;} break; - case 207: /* limit_opt ::= LIMIT signed OFFSET signed */ -{ yymsp[-3].minor.yy74.limit = yymsp[-2].minor.yy179; yymsp[-3].minor.yy74.offset = yymsp[0].minor.yy179;} + case 210: /* limit_opt ::= LIMIT signed OFFSET signed */ +{ yygotominor.yy482.limit = yymsp[-2].minor.yy473; yygotominor.yy482.offset = yymsp[0].minor.yy473;} break; - case 208: /* limit_opt ::= LIMIT signed COMMA signed */ -{ yymsp[-3].minor.yy74.limit = yymsp[0].minor.yy179; yymsp[-3].minor.yy74.offset = yymsp[-2].minor.yy179;} + case 211: /* limit_opt ::= LIMIT signed COMMA signed */ +{ yygotominor.yy482.limit = yymsp[0].minor.yy473; yygotominor.yy482.offset = yymsp[-2].minor.yy473;} break; - case 211: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ -{yymsp[-3].minor.yy74.limit = yymsp[-2].minor.yy179; yymsp[-3].minor.yy74.offset = yymsp[0].minor.yy179;} + case 214: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ +{yygotominor.yy482.limit = yymsp[-2].minor.yy473; yygotominor.yy482.offset = yymsp[0].minor.yy473;} break; - case 212: /* slimit_opt ::= SLIMIT signed COMMA signed */ -{yymsp[-3].minor.yy74.limit = yymsp[0].minor.yy179; yymsp[-3].minor.yy74.offset = yymsp[-2].minor.yy179;} + case 215: /* slimit_opt ::= SLIMIT signed COMMA signed */ +{yygotominor.yy482.limit = yymsp[0].minor.yy473; yygotominor.yy482.offset = yymsp[-2].minor.yy473;} break; - case 215: /* expr ::= LP expr RP */ -{yylhsminor.yy436 = yymsp[-1].minor.yy436; yylhsminor.yy436->token.z = yymsp[-2].minor.yy0.z; yylhsminor.yy436->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 218: /* expr ::= LP expr RP */ +{yygotominor.yy454 = yymsp[-1].minor.yy454; yygotominor.yy454->token.z = yymsp[-2].minor.yy0.z; yygotominor.yy454->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} break; - case 216: /* expr ::= ID */ -{ yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} - yymsp[0].minor.yy436 = yylhsminor.yy436; + case 219: /* expr ::= ID */ +{ yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} break; - case 217: /* expr ::= ID DOT ID */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 220: /* expr ::= ID DOT ID */ +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} break; - case 218: /* expr ::= ID DOT STAR */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 221: /* expr ::= ID DOT STAR */ +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} break; - case 219: /* expr ::= INTEGER */ -{ yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} - yymsp[0].minor.yy436 = yylhsminor.yy436; + case 222: /* expr ::= INTEGER */ +{ yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} break; - case 220: /* expr ::= MINUS INTEGER */ - case 221: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==221); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} - yymsp[-1].minor.yy436 = yylhsminor.yy436; + case 223: /* expr ::= MINUS INTEGER */ + case 224: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==224); +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} break; - case 222: /* expr ::= FLOAT */ -{ yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} - yymsp[0].minor.yy436 = yylhsminor.yy436; + case 225: /* expr ::= FLOAT */ +{ yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} break; - case 223: /* expr ::= MINUS FLOAT */ - case 224: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==224); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} - yymsp[-1].minor.yy436 = yylhsminor.yy436; + case 226: /* expr ::= MINUS FLOAT */ + case 227: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==227); +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} break; - case 225: /* expr ::= STRING */ -{ yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} - yymsp[0].minor.yy436 = yylhsminor.yy436; + case 228: /* expr ::= STRING */ +{ yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} break; - case 226: /* expr ::= NOW */ -{ yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } - yymsp[0].minor.yy436 = yylhsminor.yy436; + case 229: /* expr ::= NOW */ +{ yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } break; - case 227: /* expr ::= VARIABLE */ -{ yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} - yymsp[0].minor.yy436 = yylhsminor.yy436; + case 230: /* expr ::= VARIABLE */ +{ yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} break; - case 228: /* expr ::= PLUS VARIABLE */ - case 229: /* expr ::= MINUS VARIABLE */ yytestcase(yyruleno==229); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_VARIABLE; yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_VARIABLE);} - yymsp[-1].minor.yy436 = yylhsminor.yy436; + case 231: /* expr ::= PLUS VARIABLE */ + case 232: /* expr ::= MINUS VARIABLE */ yytestcase(yyruleno==232); +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_VARIABLE; yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_VARIABLE);} break; - case 230: /* expr ::= BOOL */ -{ yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} - yymsp[0].minor.yy436 = yylhsminor.yy436; + case 233: /* expr ::= BOOL */ +{ yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} break; - case 231: /* expr ::= NULL */ -{ yylhsminor.yy436 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} - yymsp[0].minor.yy436 = yylhsminor.yy436; + case 234: /* expr ::= NULL */ +{ yygotominor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} break; - case 232: /* expr ::= ID LP exprlist RP */ -{ yylhsminor.yy436 = tSqlExprCreateFunction(yymsp[-1].minor.yy291, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy436 = yylhsminor.yy436; + case 235: /* expr ::= ID LP exprlist RP */ +{ yygotominor.yy454 = tSqlExprCreateFunction(yymsp[-1].minor.yy193, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } break; - case 233: /* expr ::= ID LP STAR RP */ -{ yylhsminor.yy436 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy436 = yylhsminor.yy436; + case 236: /* expr ::= ID LP STAR RP */ +{ yygotominor.yy454 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } break; - case 234: /* expr ::= expr IS NULL */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, NULL, TK_ISNULL);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 237: /* expr ::= expr IS NULL */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, NULL, TK_ISNULL);} break; - case 235: /* expr ::= expr IS NOT NULL */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-3].minor.yy436, NULL, TK_NOTNULL);} - yymsp[-3].minor.yy436 = yylhsminor.yy436; + case 238: /* expr ::= expr IS NOT NULL */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-3].minor.yy454, NULL, TK_NOTNULL);} break; - case 236: /* expr ::= expr LT expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_LT);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 239: /* expr ::= expr LT expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_LT);} break; - case 237: /* expr ::= expr GT expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_GT);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 240: /* expr ::= expr GT expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_GT);} break; - case 238: /* expr ::= expr LE expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_LE);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 241: /* expr ::= expr LE expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_LE);} break; - case 239: /* expr ::= expr GE expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_GE);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 242: /* expr ::= expr GE expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_GE);} break; - case 240: /* expr ::= expr NE expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_NE);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 243: /* expr ::= expr NE expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_NE);} break; - case 241: /* expr ::= expr EQ expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_EQ);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 244: /* expr ::= expr EQ expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_EQ);} break; - case 242: /* expr ::= expr BETWEEN expr AND expr */ -{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy436); yylhsminor.yy436 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy436, yymsp[-2].minor.yy436, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy436, TK_LE), TK_AND);} - yymsp[-4].minor.yy436 = yylhsminor.yy436; + case 245: /* expr ::= expr BETWEEN expr AND expr */ +{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy454); yygotominor.yy454 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy454, yymsp[-2].minor.yy454, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy454, TK_LE), TK_AND);} break; - case 243: /* expr ::= expr AND expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_AND);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 246: /* expr ::= expr AND expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_AND);} break; - case 244: /* expr ::= expr OR expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_OR); } - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 247: /* expr ::= expr OR expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_OR); } break; - case 245: /* expr ::= expr PLUS expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_PLUS); } - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 248: /* expr ::= expr PLUS expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_PLUS); } break; - case 246: /* expr ::= expr MINUS expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_MINUS); } - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 249: /* expr ::= expr MINUS expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_MINUS); } break; - case 247: /* expr ::= expr STAR expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_STAR); } - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 250: /* expr ::= expr STAR expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_STAR); } break; - case 248: /* expr ::= expr SLASH expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_DIVIDE);} - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 251: /* expr ::= expr SLASH expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_DIVIDE);} break; - case 249: /* expr ::= expr REM expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_REM); } - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 252: /* expr ::= expr REM expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_REM); } break; - case 250: /* expr ::= expr LIKE expr */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-2].minor.yy436, yymsp[0].minor.yy436, TK_LIKE); } - yymsp[-2].minor.yy436 = yylhsminor.yy436; + case 253: /* expr ::= expr LIKE expr */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_LIKE); } break; - case 251: /* expr ::= expr IN LP exprlist RP */ -{yylhsminor.yy436 = tSqlExprCreate(yymsp[-4].minor.yy436, (tSqlExpr*)yymsp[-1].minor.yy291, TK_IN); } - yymsp[-4].minor.yy436 = yylhsminor.yy436; + case 254: /* expr ::= expr IN LP exprlist RP */ +{yygotominor.yy454 = tSqlExprCreate(yymsp[-4].minor.yy454, (tSqlExpr*)yymsp[-1].minor.yy193, TK_IN); } break; - case 252: /* exprlist ::= exprlist COMMA expritem */ -{yylhsminor.yy291 = tSqlExprListAppend(yymsp[-2].minor.yy291,yymsp[0].minor.yy436,0, 0);} - yymsp[-2].minor.yy291 = yylhsminor.yy291; + case 255: /* exprlist ::= exprlist COMMA expritem */ +{yygotominor.yy193 = tSqlExprListAppend(yymsp[-2].minor.yy193,yymsp[0].minor.yy454,0, 0);} break; - case 253: /* exprlist ::= expritem */ -{yylhsminor.yy291 = tSqlExprListAppend(0,yymsp[0].minor.yy436,0, 0);} - yymsp[0].minor.yy291 = yylhsminor.yy291; + case 256: /* exprlist ::= expritem */ +{yygotominor.yy193 = tSqlExprListAppend(0,yymsp[0].minor.yy454,0, 0);} break; - case 254: /* expritem ::= expr */ -{yylhsminor.yy436 = yymsp[0].minor.yy436;} - yymsp[0].minor.yy436 = yylhsminor.yy436; - break; - case 256: /* cmd ::= RESET QUERY CACHE */ + case 259: /* cmd ::= RESET QUERY CACHE */ { setDCLSqlElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} break; - case 257: /* cmd ::= SYNCDB ids REPLICA */ + case 260: /* cmd ::= SYNCDB ids REPLICA */ { setDCLSqlElems(pInfo, TSDB_SQL_SYNC_DB_REPLICA, 1, &yymsp[-1].minor.yy0);} break; - case 258: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + case 261: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy291, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy193, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 259: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + case 262: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3029,14 +2594,14 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 260: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + case 263: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy291, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy193, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 261: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + case 264: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3047,7 +2612,7 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 262: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + case 265: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -3061,26 +2626,26 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 263: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + case 266: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ { yymsp[-6].minor.yy0.n += yymsp[-5].minor.yy0.n; toTSDBType(yymsp[-2].minor.yy0.type); SArray* A = tVariantListAppendToken(NULL, &yymsp[-2].minor.yy0, -1); - A = tVariantListAppend(A, &yymsp[0].minor.yy216, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy442, -1); SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-6].minor.yy0, NULL, A, TSDB_ALTER_TABLE_UPDATE_TAG_VAL, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 264: /* cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + case 267: /* cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy291, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy193, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 265: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + case 268: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3091,14 +2656,14 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 266: /* cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + case 269: /* cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy291, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy193, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 267: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + case 270: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3109,7 +2674,7 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 268: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + case 271: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -3123,36 +2688,43 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 269: /* cmd ::= KILL CONNECTION INTEGER */ + case 272: /* cmd ::= KILL CONNECTION INTEGER */ {setKillSql(pInfo, TSDB_SQL_KILL_CONNECTION, &yymsp[0].minor.yy0);} break; - case 270: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ + case 273: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSql(pInfo, TSDB_SQL_KILL_STREAM, &yymsp[-2].minor.yy0);} break; - case 271: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ + case 274: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSql(pInfo, TSDB_SQL_KILL_QUERY, &yymsp[-2].minor.yy0);} break; default: break; -/********** End reduce actions ************************************************/ }; - assert( yyrulenoYY_MAX_SHIFT && yyact<=YY_MAX_SHIFTREDUCE) ); - - /* It is not possible for a REDUCE to be followed by an error */ - assert( yyact!=YY_ERROR_ACTION ); - - yymsp += yysize+1; - yypParser->yytos = yymsp; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yyTraceShift(yypParser, yyact, "... then shift"); + yypParser->yyidx -= yysize; + yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); + if( yyact < YYNSTATE ){ +#ifdef NDEBUG + /* If we are not debugging and the reduce action popped at least + ** one element off the stack, then we can push the new element back + ** onto the stack here, and skip the stack overflow test in yy_shift(). + ** That gives a significant speed improvement. */ + if( yysize ){ + yypParser->yyidx++; + yymsp -= yysize-1; + yymsp->stateno = (YYACTIONTYPE)yyact; + yymsp->major = (YYCODETYPE)yygoto; + yymsp->minor = yygotominor; + }else +#endif + { + yy_shift(yypParser,yyact,yygoto,&yygotominor); + } + }else{ + assert( yyact == YYNSTATE + YYNRULE + 1 ); + yy_accept(yypParser); + } } /* @@ -3168,11 +2740,9 @@ static void yy_parse_failed( fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); } #endif - while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will be executed whenever the ** parser fails */ -/************ Begin %parse_failure code ***************************************/ -/************ End %parse_failure code *****************************************/ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } #endif /* YYNOERRORRECOVERY */ @@ -3183,11 +2753,10 @@ static void yy_parse_failed( static void yy_syntax_error( yyParser *yypParser, /* The parser */ int yymajor, /* The major type of the error token */ - ParseTOKENTYPE yyminor /* The minor type of the error token */ + YYMINORTYPE yyminor /* The minor type of the error token */ ){ ParseARG_FETCH; -#define TOKEN yyminor -/************ Begin %syntax_error code ****************************************/ +#define TOKEN (yyminor.yy0) pInfo->valid = false; int32_t outputBufLen = tListLen(pInfo->msg); @@ -3210,7 +2779,6 @@ static void yy_syntax_error( } assert(len <= outputBufLen); -/************ End %syntax_error code ******************************************/ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } @@ -3226,15 +2794,10 @@ static void yy_accept( fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); } #endif -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; -#endif - assert( yypParser->yytos==yypParser->yystack ); + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will be executed whenever the ** parser accepts */ -/*********** Begin %parse_accept code *****************************************/ -/*********** End %parse_accept code *******************************************/ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } @@ -3264,52 +2827,50 @@ void Parse( ParseARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; - unsigned int yyact; /* The parser action. */ -#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + int yyact; /* The parser action. */ int yyendofinput; /* True if we are at the end of input */ -#endif #ifdef YYERRORSYMBOL int yyerrorhit = 0; /* True if yymajor has invoked an error */ #endif yyParser *yypParser; /* The parser */ + /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; - assert( yypParser->yytos!=0 ); -#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) - yyendofinput = (yymajor==0); + if( yypParser->yyidx<0 ){ +#if YYSTACKDEPTH<=0 + if( yypParser->yystksz <=0 ){ + /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ + yyminorunion = yyzerominor; + yyStackOverflow(yypParser, &yyminorunion); + return; + } #endif + yypParser->yyidx = 0; + yypParser->yyerrcnt = -1; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; + } + yyminorunion.yy0 = yyminor; + yyendofinput = (yymajor==0); ParseARG_STORE; #ifndef NDEBUG if( yyTraceFILE ){ - int stateno = yypParser->yytos->stateno; - if( stateno < YY_MIN_REDUCE ){ - fprintf(yyTraceFILE,"%sInput '%s' in state %d\n", - yyTracePrompt,yyTokenName[yymajor],stateno); - }else{ - fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n", - yyTracePrompt,yyTokenName[yymajor],stateno-YY_MIN_REDUCE); - } + fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); } #endif do{ yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyact >= YY_MIN_REDUCE ){ - yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,yyminor); - }else if( yyact <= YY_MAX_SHIFTREDUCE ){ - yy_shift(yypParser,yyact,yymajor,yyminor); -#ifndef YYNOERRORRECOVERY + if( yyactyyerrcnt--; -#endif yymajor = YYNOCODE; - }else if( yyact==YY_ACCEPT_ACTION ){ - yypParser->yytos--; - yy_accept(yypParser); - return; + }else if( yyact < YYNSTATE + YYNRULE ){ + yy_reduce(yypParser,yyact-YYNSTATE); }else{ assert( yyact == YY_ERROR_ACTION ); - yyminorunion.yy0 = yyminor; #ifdef YYERRORSYMBOL int yymx; #endif @@ -3339,9 +2900,9 @@ void Parse( ** */ if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminor); + yy_syntax_error(yypParser,yymajor,yyminorunion); } - yymx = yypParser->yytos->major; + yymx = yypParser->yystack[yypParser->yyidx].major; if( yymx==YYERRORSYMBOL || yyerrorhit ){ #ifndef NDEBUG if( yyTraceFILE ){ @@ -3349,26 +2910,26 @@ void Parse( yyTracePrompt,yyTokenName[yymajor]); } #endif - yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); + yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); yymajor = YYNOCODE; }else{ - while( yypParser->yytos >= yypParser->yystack - && yymx != YYERRORSYMBOL - && (yyact = yy_find_reduce_action( - yypParser->yytos->stateno, - YYERRORSYMBOL)) >= YY_MIN_REDUCE + while( + yypParser->yyidx >= 0 && + yymx != YYERRORSYMBOL && + (yyact = yy_find_reduce_action( + yypParser->yystack[yypParser->yyidx].stateno, + YYERRORSYMBOL)) >= YYNSTATE ){ yy_pop_parser_stack(yypParser); } - if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ + if( yypParser->yyidx < 0 || yymajor==0 ){ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yy_parse_failed(yypParser); -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; -#endif yymajor = YYNOCODE; }else if( yymx!=YYERRORSYMBOL ){ - yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor); + YYMINORTYPE u2; + u2.YYERRSYMDT = 0; + yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); } } yypParser->yyerrcnt = 3; @@ -3381,7 +2942,7 @@ void Parse( ** Applications can set this macro (for example inside %include) if ** they intend to abandon the parse upon the first syntax error seen. */ - yy_syntax_error(yypParser,yymajor, yyminor); + yy_syntax_error(yypParser,yymajor,yyminorunion); yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yymajor = YYNOCODE; @@ -3396,31 +2957,16 @@ void Parse( ** three input tokens have been successfully shifted. */ if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor, yyminor); + yy_syntax_error(yypParser,yymajor,yyminorunion); } yypParser->yyerrcnt = 3; yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); if( yyendofinput ){ yy_parse_failed(yypParser); -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; -#endif } yymajor = YYNOCODE; #endif } - }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack ); -#ifndef NDEBUG - if( yyTraceFILE ){ - yyStackEntry *i; - char cDiv = '['; - fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt); - for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){ - fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]); - cDiv = ' '; - } - fprintf(yyTraceFILE,"]\n"); - } -#endif + }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); return; } diff --git a/src/query/tests/CMakeLists.txt b/src/query/tests/CMakeLists.txt index 1856223391ae719ef98492160da9810826b983a9..f8b6daaa9073f8cbcac590fe81cebfd569b7942a 100644 --- a/src/query/tests/CMakeLists.txt +++ b/src/query/tests/CMakeLists.txt @@ -13,3 +13,10 @@ IF (HEADER_GTEST_INCLUDE_DIR AND LIB_GTEST_STATIC_DIR) ADD_EXECUTABLE(queryTest ${SOURCE_LIST}) TARGET_LINK_LIBRARIES(queryTest taos query gtest pthread gcov) ENDIF() + +SET_SOURCE_FILES_PROPERTIES(./astTest.cpp PROPERTIES COMPILE_FLAGS -w) +SET_SOURCE_FILES_PROPERTIES(./histogramTest.cpp PROPERTIES COMPILE_FLAGS -w) +SET_SOURCE_FILES_PROPERTIES(./percentileTest.cpp PROPERTIES COMPILE_FLAGS -w) +SET_SOURCE_FILES_PROPERTIES(./resultBufferTest.cpp PROPERTIES COMPILE_FLAGS -w) +SET_SOURCE_FILES_PROPERTIES(./tsBufTest.cpp PROPERTIES COMPILE_FLAGS -w) +SET_SOURCE_FILES_PROPERTIES(./unitTest.cpp PROPERTIES COMPILE_FLAGS -w) diff --git a/src/query/tests/tsBufTest.cpp b/src/query/tests/tsBufTest.cpp index 8ca636b8348cd08eddd98d5c1c24de15d4eaa2b4..dd7f03a494ac37229b117c678fc461d455067850 100644 --- a/src/query/tests/tsBufTest.cpp +++ b/src/query/tests/tsBufTest.cpp @@ -3,10 +3,10 @@ #include #include +#include "qTsbuf.h" #include "taos.h" #include "tsdb.h" -#include "qTsbuf.h" -#include "tstoken.h" +#include "ttoken.h" #include "tutil.h" namespace { diff --git a/src/query/tests/unitTest.cpp b/src/query/tests/unitTest.cpp index 3406d8309023118d16cfc4dfbdab58defc6f005a..33ba8200d3afb9cff00f150ab5bef799f3fa1e86 100644 --- a/src/query/tests/unitTest.cpp +++ b/src/query/tests/unitTest.cpp @@ -21,7 +21,7 @@ int32_t testValidateName(char* name) { token.n = strlen(name); token.type = 0; - tSQLGetToken(name, &token.type); + tGetToken(name, &token.type); return tscValidateName(&token); } } @@ -99,47 +99,47 @@ TEST(testCase, db_table_name) { EXPECT_EQ(testValidateName(t4), TSDB_CODE_SUCCESS); char t5[] = "table.'def'"; - EXPECT_EQ(testValidateName(t5), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t5), TSDB_CODE_TSC_INVALID_OPERATION); char t6[] = "'table'.'def'"; - EXPECT_EQ(testValidateName(t6), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t6), TSDB_CODE_TSC_INVALID_OPERATION); char t7[] = "'_ab1234'.'def'"; EXPECT_EQ(testValidateName(t7), TSDB_CODE_SUCCESS); printf("%s\n", t7); char t8[] = "'_ab&^%1234'.'def'"; - EXPECT_EQ(testValidateName(t8), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t8), TSDB_CODE_TSC_INVALID_OPERATION); char t9[] = "'_123'.'gtest中文'"; - EXPECT_EQ(testValidateName(t9), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t9), TSDB_CODE_TSC_INVALID_OPERATION); char t10[] = "abc.'gtest中文'"; - EXPECT_EQ(testValidateName(t10), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t10), TSDB_CODE_TSC_INVALID_OPERATION); char t10_1[] = "abc.'中文gtest'"; - EXPECT_EQ(testValidateName(t10_1), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t10_1), TSDB_CODE_TSC_INVALID_OPERATION); char t11[] = "'192.168.0.1'.abc"; - EXPECT_EQ(testValidateName(t11), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t11), TSDB_CODE_TSC_INVALID_OPERATION); char t12[] = "192.168.0.1.abc"; - EXPECT_EQ(testValidateName(t12), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t12), TSDB_CODE_TSC_INVALID_OPERATION); char t13[] = "abc."; - EXPECT_EQ(testValidateName(t13), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t13), TSDB_CODE_TSC_INVALID_OPERATION); char t14[] = ".abc"; - EXPECT_EQ(testValidateName(t14), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t14), TSDB_CODE_TSC_INVALID_OPERATION); char t15[] = ".'abc'"; - EXPECT_EQ(testValidateName(t15), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t15), TSDB_CODE_TSC_INVALID_OPERATION); char t16[] = ".abc'"; - EXPECT_EQ(testValidateName(t16), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t16), TSDB_CODE_TSC_INVALID_OPERATION); char t17[] = "123a.\"abc\""; - EXPECT_EQ(testValidateName(t17), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t17), TSDB_CODE_TSC_INVALID_OPERATION); printf("%s\n", t17); char t18[] = "a.\"abc\""; @@ -147,13 +147,13 @@ TEST(testCase, db_table_name) { printf("%s\n", t18); char t19[] = "'_ab1234'.'def'.'ab123'"; - EXPECT_EQ(testValidateName(t19), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t19), TSDB_CODE_TSC_INVALID_OPERATION); char t20[] = "'_ab1234*&^'"; - EXPECT_EQ(testValidateName(t20), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t20), TSDB_CODE_TSC_INVALID_OPERATION); char t21[] = "'1234_abc'"; - EXPECT_EQ(testValidateName(t21), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t21), TSDB_CODE_TSC_INVALID_OPERATION); // =======Containing capital letters================= @@ -167,10 +167,10 @@ TEST(testCase, db_table_name) { EXPECT_EQ(testValidateName(t32), TSDB_CODE_SUCCESS); char t33[] = "'ABC.def"; - EXPECT_EQ(testValidateName(t33), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t33), TSDB_CODE_TSC_INVALID_OPERATION); char t33_0[] = "abc.DEF'"; - EXPECT_EQ(testValidateName(t33_0), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t33_0), TSDB_CODE_TSC_INVALID_OPERATION); char t34[] = "'ABC.def'"; //int32_t tmp0 = testValidateName(t34); @@ -193,136 +193,136 @@ TEST(testCase, db_table_name) { // do not use key words char t39[] = "table.'DEF'"; - EXPECT_EQ(testValidateName(t39), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t39), TSDB_CODE_TSC_INVALID_OPERATION); char t40[] = "'table'.'DEF'"; - EXPECT_EQ(testValidateName(t40), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t40), TSDB_CODE_TSC_INVALID_OPERATION); char t41[] = "'_abXYZ1234'.'deFF'"; EXPECT_EQ(testValidateName(t41), TSDB_CODE_SUCCESS); char t42[] = "'_abDEF&^%1234'.'DIef'"; - EXPECT_EQ(testValidateName(t42), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t42), TSDB_CODE_TSC_INVALID_OPERATION); char t43[] = "'_123'.'Gtest中文'"; - EXPECT_EQ(testValidateName(t43), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t43), TSDB_CODE_TSC_INVALID_OPERATION); char t44[] = "'aABC'.'Gtest中文'"; - EXPECT_EQ(testValidateName(t44), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t44), TSDB_CODE_TSC_INVALID_OPERATION); char t45[] = "'ABC'."; - EXPECT_EQ(testValidateName(t45), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t45), TSDB_CODE_TSC_INVALID_OPERATION); char t46[] = ".'ABC'"; - EXPECT_EQ(testValidateName(t46), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t46), TSDB_CODE_TSC_INVALID_OPERATION); char t47[] = "a.\"aTWc\""; EXPECT_EQ(testValidateName(t47), TSDB_CODE_SUCCESS); // ================has space ================= char t60[] = " ABC "; - EXPECT_EQ(testValidateName(t60), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t60), TSDB_CODE_TSC_INVALID_OPERATION); char t60_1[] = " ABC "; - EXPECT_EQ(testValidateName(t60_1), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t60_1), TSDB_CODE_TSC_INVALID_OPERATION); char t61[] = "' ABC '"; - EXPECT_EQ(testValidateName(t61), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t61), TSDB_CODE_TSC_INVALID_OPERATION); char t61_1[] = "' ABC '"; - EXPECT_EQ(testValidateName(t61_1), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t61_1), TSDB_CODE_TSC_INVALID_OPERATION); char t62[] = " ABC . def "; - EXPECT_EQ(testValidateName(t62), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t62), TSDB_CODE_TSC_INVALID_OPERATION); char t63[] = "' ABC . def "; - EXPECT_EQ(testValidateName(t63), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t63), TSDB_CODE_TSC_INVALID_OPERATION); char t63_0[] = " abc . DEF ' "; - EXPECT_EQ(testValidateName(t63_0), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t63_0), TSDB_CODE_TSC_INVALID_OPERATION); char t64[] = " ' ABC . def ' "; //int32_t tmp1 = testValidateName(t64); - EXPECT_EQ(testValidateName(t64), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t64), TSDB_CODE_TSC_INVALID_OPERATION); char t65[] = " ' ABC '. def "; - EXPECT_EQ(testValidateName(t65), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t65), TSDB_CODE_TSC_INVALID_OPERATION); char t66[] = "' ABC '.' DEF '"; - EXPECT_EQ(testValidateName(t66), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t66), TSDB_CODE_TSC_INVALID_OPERATION); char t67[] = "abc . ' DEF '"; - EXPECT_EQ(testValidateName(t67), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t67), TSDB_CODE_TSC_INVALID_OPERATION); char t68[] = "' abc '.' DEF '"; - EXPECT_EQ(testValidateName(t68), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t68), TSDB_CODE_TSC_INVALID_OPERATION); // do not use key words char t69[] = "table.'DEF'"; - EXPECT_EQ(testValidateName(t69), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t69), TSDB_CODE_TSC_INVALID_OPERATION); char t70[] = "'table'.'DEF'"; - EXPECT_EQ(testValidateName(t70), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t70), TSDB_CODE_TSC_INVALID_OPERATION); char t71[] = "'_abXYZ1234 '.' deFF '"; - EXPECT_EQ(testValidateName(t71), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t71), TSDB_CODE_TSC_INVALID_OPERATION); char t72[] = "'_abDEF&^%1234'.' DIef'"; - EXPECT_EQ(testValidateName(t72), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t72), TSDB_CODE_TSC_INVALID_OPERATION); char t73[] = "'_123'.' Gtest中文'"; - EXPECT_EQ(testValidateName(t73), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t73), TSDB_CODE_TSC_INVALID_OPERATION); char t74[] = "' aABC'.'Gtest中文'"; - EXPECT_EQ(testValidateName(t74), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t74), TSDB_CODE_TSC_INVALID_OPERATION); char t75[] = "' ABC '."; - EXPECT_EQ(testValidateName(t75), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t75), TSDB_CODE_TSC_INVALID_OPERATION); char t76[] = ".' ABC'"; - EXPECT_EQ(testValidateName(t76), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t76), TSDB_CODE_TSC_INVALID_OPERATION); char t77[] = " a . \"aTWc\" "; - EXPECT_EQ(testValidateName(t77), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t77), TSDB_CODE_TSC_INVALID_OPERATION); char t78[] = " a.\"aTWc \""; - EXPECT_EQ(testValidateName(t78), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t78), TSDB_CODE_TSC_INVALID_OPERATION); // ===============muti string by space =================== // There's no such case. //char t160[] = "A BC"; - //EXPECT_EQ(testValidateName(t160), TSDB_CODE_TSC_INVALID_SQL); + //EXPECT_EQ(testValidateName(t160), TSDB_CODE_TSC_INVALID_OPERATION); //printf("end:%s\n", t160); // There's no such case. //char t161[] = "' A BC '"; - //EXPECT_EQ(testValidateName(t161), TSDB_CODE_TSC_INVALID_SQL); + //EXPECT_EQ(testValidateName(t161), TSDB_CODE_TSC_INVALID_OPERATION); char t162[] = " AB C . de f "; - EXPECT_EQ(testValidateName(t162), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t162), TSDB_CODE_TSC_INVALID_OPERATION); char t163[] = "' AB C . de f "; - EXPECT_EQ(testValidateName(t163), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t163), TSDB_CODE_TSC_INVALID_OPERATION); char t163_0[] = " ab c . DE F ' "; - EXPECT_EQ(testValidateName(t163_0), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t163_0), TSDB_CODE_TSC_INVALID_OPERATION); char t164[] = " ' AB C . de f ' "; //int32_t tmp2 = testValidateName(t164); - EXPECT_EQ(testValidateName(t164), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t164), TSDB_CODE_TSC_INVALID_OPERATION); char t165[] = " ' A BC '. de f "; - EXPECT_EQ(testValidateName(t165), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t165), TSDB_CODE_TSC_INVALID_OPERATION); char t166[] = "' AB C '.' DE F '"; - EXPECT_EQ(testValidateName(t166), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t166), TSDB_CODE_TSC_INVALID_OPERATION); char t167[] = "ab c . ' D EF '"; - EXPECT_EQ(testValidateName(t167), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t167), TSDB_CODE_TSC_INVALID_OPERATION); char t168[] = "' a bc '.' DE F '"; - EXPECT_EQ(testValidateName(t168), TSDB_CODE_TSC_INVALID_SQL); + EXPECT_EQ(testValidateName(t168), TSDB_CODE_TSC_INVALID_OPERATION); } @@ -691,32 +691,32 @@ TEST(testCase, tGetToken_Test) { char* s = ".123 "; uint32_t type = 0; - int32_t len = tSQLGetToken(s, &type); + int32_t len = tGetToken(s, &type); EXPECT_EQ(type, TK_FLOAT); EXPECT_EQ(len, strlen(s) - 1); char s1[] = "1.123e10 "; - len = tSQLGetToken(s1, &type); + len = tGetToken(s1, &type); EXPECT_EQ(type, TK_FLOAT); EXPECT_EQ(len, strlen(s1) - 1); char s4[] = "0xff "; - len = tSQLGetToken(s4, &type); + len = tGetToken(s4, &type); EXPECT_EQ(type, TK_HEX); EXPECT_EQ(len, strlen(s4) - 1); // invalid data type char s2[] = "e10 "; - len = tSQLGetToken(s2, &type); + len = tGetToken(s2, &type); EXPECT_FALSE(type == TK_FLOAT); char s3[] = "1.1.1.1"; - len = tSQLGetToken(s3, &type); + len = tGetToken(s3, &type); EXPECT_EQ(type, TK_IPTOKEN); EXPECT_EQ(len, strlen(s3)); char s5[] = "0x "; - len = tSQLGetToken(s5, &type); + len = tGetToken(s5, &type); EXPECT_FALSE(type == TK_HEX); } diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 08e7551a2e8fe72a24825362c17cf413509de9c3..605f7d2a326f9b2a66865d9ad0edc2987eb57f81 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1471,7 +1471,7 @@ static int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen) { * only the compressed size is less than the value of contLen - overhead, the compression is applied * The first four bytes is set to 0, the second four bytes are utilized to keep the original length of message */ - if (compLen < contLen - overhead) { + if (compLen > 0 && compLen < contLen - overhead) { SRpcComp *pComp = (SRpcComp *)pCont; pComp->reserved = 0; pComp->contLen = htonl(contLen); diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index 09857610d20b5bb219c86035941d53bc8d0a987b..029629eff0e10f5bc8812f3df8998b24a507931d 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -576,7 +576,7 @@ static void *taosProcessTcpData(void *param) { } while (pThreadObj->pHead) { - SFdObj *pFdObj = pThreadObj->pHead; + pFdObj = pThreadObj->pHead; pThreadObj->pHead = pFdObj->next; taosReportBrokenLink(pFdObj); } diff --git a/src/sync/src/syncMain.c b/src/sync/src/syncMain.c index e5f2d94c4a9696500e0aef7b9593c6cc0daf2792..493d5f117ac4d213da2703ed60825209f19f46b4 100644 --- a/src/sync/src/syncMain.c +++ b/src/sync/src/syncMain.c @@ -389,17 +389,17 @@ int32_t syncForwardToPeer(int64_t rid, void *data, void *mhandle, int32_t qtype, return code; } -void syncConfirmForward(int64_t rid, uint64_t version, int32_t code, bool force) { +void syncConfirmForward(int64_t rid, uint64_t _version, int32_t code, bool force) { SSyncNode *pNode = syncAcquireNode(rid); if (pNode == NULL) return; SSyncPeer *pPeer = pNode->pMaster; if (pPeer && (pNode->quorum > 1 || force)) { SFwdRsp rsp; - syncBuildSyncFwdRsp(&rsp, pNode->vgId, version, code); + syncBuildSyncFwdRsp(&rsp, pNode->vgId, _version, code); if (taosWriteMsg(pPeer->peerFd, &rsp, sizeof(SFwdRsp)) == sizeof(SFwdRsp)) { - sTrace("%s, forward-rsp is sent, code:0x%x hver:%" PRIu64, pPeer->id, code, version); + sTrace("%s, forward-rsp is sent, code:0x%x hver:%" PRIu64, pPeer->id, code, _version); } else { sDebug("%s, failed to send forward-rsp, restart", pPeer->id); syncRestartConnection(pPeer); @@ -709,7 +709,7 @@ static void syncChooseMaster(SSyncNode *pNode) { } static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { - int32_t onlineNum = 0; + int32_t onlineNum = 0, arbOnlineNum = 0; int32_t masterIndex = -1; int32_t replica = pNode->replica; @@ -723,13 +723,15 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { SSyncPeer *pArb = pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]; if (pArb && pArb->role != TAOS_SYNC_ROLE_OFFLINE) { onlineNum++; + ++arbOnlineNum; replica = pNode->replica + 1; } if (onlineNum <= replica * 0.5) { if (nodeRole != TAOS_SYNC_ROLE_UNSYNCED) { - if (nodeRole == TAOS_SYNC_ROLE_MASTER && onlineNum == replica * 0.5 && onlineNum >= 1) { + if (nodeRole == TAOS_SYNC_ROLE_MASTER && onlineNum == replica * 0.5 && ((replica > 2 && onlineNum - arbOnlineNum > 1) || pNode->replica < 3)) { sInfo("vgId:%d, self keep work as master, online:%d replica:%d", pNode->vgId, onlineNum, replica); + masterIndex = pNode->selfIndex; } else { nodeRole = TAOS_SYNC_ROLE_UNSYNCED; sInfo("vgId:%d, self change to unsynced state, online:%d replica:%d", pNode->vgId, onlineNum, replica); @@ -1002,6 +1004,7 @@ static void syncProcessForwardFromPeer(char *cont, SSyncPeer *pPeer) { if (nodeRole == TAOS_SYNC_ROLE_SLAVE) { // nodeVersion = pHead->version; code = (*pNode->writeToCacheFp)(pNode->vgId, pHead, TAOS_QTYPE_FWD, NULL); + syncConfirmForward(pNode->rid, pHead->version, code, false); } else { if (nodeSStatus != TAOS_SYNC_STATUS_INIT) { code = syncSaveIntoBuffer(pPeer, pHead); @@ -1302,14 +1305,14 @@ static void syncProcessBrokenLink(int64_t rid) { syncReleasePeer(pPeer); } -static int32_t syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle) { +static int32_t syncSaveFwdInfo(SSyncNode *pNode, uint64_t _version, void *mhandle) { SSyncFwds *pSyncFwds = pNode->pSyncFwds; int64_t time = taosGetTimestampMs(); if (pSyncFwds->fwds >= SYNC_MAX_FWDS) { // pSyncFwds->first = (pSyncFwds->first + 1) % SYNC_MAX_FWDS; // pSyncFwds->fwds--; - sError("vgId:%d, failed to save fwd info, hver:%" PRIu64 " fwds:%d", pNode->vgId, version, pSyncFwds->fwds); + sError("vgId:%d, failed to save fwd info, hver:%" PRIu64 " fwds:%d", pNode->vgId, _version, pSyncFwds->fwds); return TSDB_CODE_SYN_TOO_MANY_FWDINFO; } @@ -1319,12 +1322,12 @@ static int32_t syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + pSyncFwds->last; memset(pFwdInfo, 0, sizeof(SFwdInfo)); - pFwdInfo->version = version; + pFwdInfo->version = _version; pFwdInfo->mhandle = mhandle; pFwdInfo->time = time; pSyncFwds->fwds++; - sTrace("vgId:%d, fwd info is saved, hver:%" PRIu64 " fwds:%d ", pNode->vgId, version, pSyncFwds->fwds); + sTrace("vgId:%d, fwd info is saved, hver:%" PRIu64 " fwds:%d ", pNode->vgId, _version, pSyncFwds->fwds); return 0; } @@ -1404,7 +1407,7 @@ static void syncMonitorFwdInfos(void *param, void *tmrId) { 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) < 2000) break; + if (ABS(time - pFwdInfo->time) < 10000) break; sDebug("vgId:%d, forward info expired, hver:%" PRIu64 " curtime:%" PRIu64 " savetime:%" PRIu64, pNode->vgId, pFwdInfo->version, time, pFwdInfo->time); diff --git a/src/sync/src/syncMsg.c b/src/sync/src/syncMsg.c index 3348f1ec337e1b7c292d231360765c914936625c..64d4e72fac3b05911044098e43b6a4689a2f57f3 100644 --- a/src/sync/src/syncMsg.c +++ b/src/sync/src/syncMsg.c @@ -61,13 +61,13 @@ void syncBuildSyncFwdMsg(SSyncHead *pHead, int32_t vgId, int32_t len) { syncBuildHead(pHead); } -void syncBuildSyncFwdRsp(SFwdRsp *pMsg, int32_t vgId, uint64_t version, int32_t code) { +void syncBuildSyncFwdRsp(SFwdRsp *pMsg, int32_t vgId, uint64_t _version, int32_t code) { pMsg->head.type = TAOS_SMSG_SYNC_FWD_RSP; pMsg->head.vgId = vgId; pMsg->head.len = sizeof(SFwdRsp) - sizeof(SSyncHead); syncBuildHead(&pMsg->head); - pMsg->version = version; + pMsg->version = _version; pMsg->code = code; } diff --git a/src/tsdb/inc/tsdbBuffer.h b/src/tsdb/inc/tsdbBuffer.h index 414ace00097d95742080a8f173177d5e44497237..4e18ac711a159cd97fd6255c5be0e8aa6ff4abaf 100644 --- a/src/tsdb/inc/tsdbBuffer.h +++ b/src/tsdb/inc/tsdbBuffer.h @@ -28,8 +28,9 @@ typedef struct { int bufBlockSize; int tBufBlocks; int nBufBlocks; + int nRecycleBlocks; int64_t index; - SList* bufBlockList; + SList* bufBlockList; } STsdbBufPool; #define TSDB_BUFFER_RESERVE 1024 // Reseve 1K as commit threshold @@ -39,5 +40,7 @@ void tsdbFreeBufPool(STsdbBufPool* pBufPool); int tsdbOpenBufPool(STsdbRepo* pRepo); void tsdbCloseBufPool(STsdbRepo* pRepo); SListNode* tsdbAllocBufBlockFromPool(STsdbRepo* pRepo); +int tsdbExpendPool(STsdbRepo* pRepo, int32_t oldTotalBlocks); +void tsdbRecycleBufferBlock(STsdbBufPool* pPool, SListNode *pNode); #endif /* _TD_TSDB_BUFFER_H_ */ \ No newline at end of file diff --git a/src/tsdb/inc/tsdbMeta.h b/src/tsdb/inc/tsdbMeta.h index cc916fa689a89f96e36c4419f1b2d413516ed5fc..45bbd5a7c6911fed4ea7309a77d3ac144109a34b 100644 --- a/src/tsdb/inc/tsdbMeta.h +++ b/src/tsdb/inc/tsdbMeta.h @@ -36,6 +36,12 @@ typedef struct STable { char* sql; void* cqhandle; SRWLatch latch; // TODO: implementa latch functions + + SDataCol *lastCols; + int16_t maxColNum; + int16_t restoreColumnNum; + bool hasRestoreLastColumn; + int lastColSVersion; T_REF_DECLARE() } STable; @@ -69,7 +75,7 @@ void tsdbFreeMeta(STsdbMeta* pMeta); int tsdbOpenMeta(STsdbRepo* pRepo); int tsdbCloseMeta(STsdbRepo* pRepo); STable* tsdbGetTableByUid(STsdbMeta* pMeta, uint64_t uid); -STSchema* tsdbGetTableSchemaByVersion(STable* pTable, int16_t version); +STSchema* tsdbGetTableSchemaByVersion(STable* pTable, int16_t _version); int tsdbWLockRepoMeta(STsdbRepo* pRepo); int tsdbRLockRepoMeta(STsdbRepo* pRepo); int tsdbUnlockRepoMeta(STsdbRepo* pRepo); @@ -78,6 +84,11 @@ void tsdbUnRefTable(STable* pTable); void tsdbUpdateTableSchema(STsdbRepo* pRepo, STable* pTable, STSchema* pSchema, bool insertAct); int tsdbRestoreTable(STsdbRepo* pRepo, void* cont, int contLen); void tsdbOrgMeta(STsdbRepo* pRepo); +int tsdbInitColIdCacheWithSchema(STable* pTable, STSchema* pSchema); +int16_t tsdbGetLastColumnsIndexByColId(STable* pTable, int16_t colId); +int tsdbUpdateLastColSchema(STable *pTable, STSchema *pNewSchema); +STSchema* tsdbGetTableLatestSchema(STable *pTable); +void tsdbFreeLastColumns(STable* pTable); static FORCE_INLINE int tsdbCompareSchemaVersion(const void *key1, const void *key2) { if (*(int16_t *)key1 < schemaVersion(*(STSchema **)key2)) { @@ -89,16 +100,16 @@ static FORCE_INLINE int tsdbCompareSchemaVersion(const void *key1, const void *k } } -static FORCE_INLINE STSchema* tsdbGetTableSchemaImpl(STable* pTable, bool lock, bool copy, int16_t version) { +static FORCE_INLINE STSchema* tsdbGetTableSchemaImpl(STable* pTable, bool lock, bool copy, int16_t _version) { STable* pDTable = (TABLE_TYPE(pTable) == TSDB_CHILD_TABLE) ? pTable->pSuper : pTable; STSchema* pSchema = NULL; STSchema* pTSchema = NULL; if (lock) TSDB_RLOCK_TABLE(pDTable); - if (version < 0) { // get the latest version of schema + if (_version < 0) { // get the latest version of schema pTSchema = pDTable->schema[pDTable->numOfSchemas - 1]; } else { // get the schema with version - void* ptr = taosbsearch(&version, pDTable->schema, pDTable->numOfSchemas, sizeof(STSchema*), + void* ptr = taosbsearch(&_version, pDTable->schema, pDTable->numOfSchemas, sizeof(STSchema*), tsdbCompareSchemaVersion, TD_EQ); if (ptr == NULL) { terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION; diff --git a/src/tsdb/inc/tsdbint.h b/src/tsdb/inc/tsdbint.h index 074ff20f2298918f1fa0698be0a291081ead8f05..e74c3238e2ac1d70087c615e4a3e6310a0cb3050 100644 --- a/src/tsdb/inc/tsdbint.h +++ b/src/tsdb/inc/tsdbint.h @@ -71,6 +71,14 @@ struct STsdbRepo { uint8_t state; STsdbCfg config; + + STsdbCfg save_config; // save apply config + bool config_changed; // config changed flag + pthread_mutex_t save_mutex; // protect save config + + uint8_t hasCachedLastRow; + uint8_t hasCachedLastColumn; + STsdbAppH appH; STsdbStat stat; STsdbMeta* tsdbMeta; @@ -95,6 +103,7 @@ int tsdbUnlockRepo(STsdbRepo* pRepo); STsdbMeta* tsdbGetMeta(STsdbRepo* pRepo); int tsdbCheckCommit(STsdbRepo* pRepo); int tsdbRestoreInfo(STsdbRepo* pRepo); +int tsdbCacheLastData(STsdbRepo *pRepo, STsdbCfg* oldCfg); void tsdbGetRootDir(int repoid, char dirName[]); void tsdbGetDataDir(int repoid, char dirName[]); diff --git a/src/tsdb/src/tsdbBuffer.c b/src/tsdb/src/tsdbBuffer.c index 1798a21b9963c7641dd99dc7fa11a5dd977e0e3c..429ea8e0ceb2c687b53ebd0a9d61d02d2a1f3686 100644 --- a/src/tsdb/src/tsdbBuffer.c +++ b/src/tsdb/src/tsdbBuffer.c @@ -70,6 +70,7 @@ int tsdbOpenBufPool(STsdbRepo *pRepo) { pPool->tBufBlocks = pCfg->totalBlocks; pPool->nBufBlocks = 0; pPool->index = 0; + pPool->nRecycleBlocks = 0; for (int i = 0; i < pCfg->totalBlocks; i++) { STsdbBufBlock *pBufBlock = tsdbNewBufBlock(pPool->bufBlockSize); @@ -156,4 +157,46 @@ _err: return NULL; } -static void tsdbFreeBufBlock(STsdbBufBlock *pBufBlock) { tfree(pBufBlock); } \ No newline at end of file +static void tsdbFreeBufBlock(STsdbBufBlock *pBufBlock) { tfree(pBufBlock); } + +int tsdbExpendPool(STsdbRepo* pRepo, int32_t oldTotalBlocks) { + if (oldTotalBlocks == pRepo->config.totalBlocks) { + return TSDB_CODE_SUCCESS; + } + + int err = TSDB_CODE_SUCCESS; + + if (tsdbLockRepo(pRepo) < 0) return terrno; + STsdbBufPool* pPool = pRepo->pPool; + + if (pRepo->config.totalBlocks > oldTotalBlocks) { + for (int i = 0; i < pRepo->config.totalBlocks - oldTotalBlocks; i++) { + STsdbBufBlock *pBufBlock = tsdbNewBufBlock(pPool->bufBlockSize); + if (pBufBlock == NULL) goto err; + + if (tdListAppend(pPool->bufBlockList, (void *)(&pBufBlock)) < 0) { + tsdbFreeBufBlock(pBufBlock); + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + err = TSDB_CODE_TDB_OUT_OF_MEMORY; + goto err; + } + + pPool->nBufBlocks++; + } + pthread_cond_signal(&pPool->poolNotEmpty); + } else { + pPool->nRecycleBlocks = oldTotalBlocks - pRepo->config.totalBlocks; + } + +err: + tsdbUnlockRepo(pRepo); + return err; +} + +void tsdbRecycleBufferBlock(STsdbBufPool* pPool, SListNode *pNode) { + STsdbBufBlock *pBufBlock = NULL; + tdListNodeGetData(pPool->bufBlockList, pNode, (void *)(&pBufBlock)); + tsdbFreeBufBlock(pBufBlock); + free(pNode); + pPool->nBufBlocks--; +} \ No newline at end of file diff --git a/src/tsdb/src/tsdbCommit.c b/src/tsdb/src/tsdbCommit.c index 4351cce51c09f86fc06cee59c94b800c44e60b1c..734b47a718cbf43fc24982dd3bbc6f862c94afd2 100644 --- a/src/tsdb/src/tsdbCommit.c +++ b/src/tsdb/src/tsdbCommit.c @@ -90,6 +90,9 @@ static int tsdbApplyRtn(STsdbRepo *pRepo); static int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn); void *tsdbCommitData(STsdbRepo *pRepo) { + if (pRepo->imem == NULL) { + return NULL; + } tsdbStartCommit(pRepo); // Commit to update meta file @@ -958,11 +961,11 @@ static int tsdbWriteBlockInfo(SCommitH *pCommih) { } static int tsdbWriteBlockIdx(SCommitH *pCommih) { - SBlockIdx *pBlkIdx; + SBlockIdx *pBlkIdx = NULL; SDFile * pHeadf = TSDB_COMMIT_HEAD_FILE(pCommih); size_t nidx = taosArrayGetSize(pCommih->aBlkIdx); - int tlen = 0, size; - int64_t offset; + int tlen = 0, size = 0; + int64_t offset = 0; if (nidx <= 0) { // All data are deleted @@ -1149,7 +1152,7 @@ static int tsdbCommitAddBlock(SCommitH *pCommith, const SBlock *pSupBlock, const return -1; } - if (pSubBlocks && taosArrayPushBatch(pCommith->aSubBlk, pSubBlocks, nSubBlocks) == NULL) { + if (pSubBlocks && taosArrayAddBatch(pCommith->aSubBlk, pSubBlocks, nSubBlocks) == NULL) { terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; return -1; } diff --git a/src/tsdb/src/tsdbCommitQueue.c b/src/tsdb/src/tsdbCommitQueue.c index 9e8e4acd7ebea2209bf08798eb80f300a72927ab..abea79bc4f46129055af868af459c147dd93793f 100644 --- a/src/tsdb/src/tsdbCommitQueue.c +++ b/src/tsdb/src/tsdbCommitQueue.c @@ -112,6 +112,44 @@ int tsdbScheduleCommit(STsdbRepo *pRepo) { return 0; } +static void tsdbApplyRepoConfig(STsdbRepo *pRepo) { + pthread_mutex_lock(&pRepo->save_mutex); + + pRepo->config_changed = false; + STsdbCfg * pSaveCfg = &pRepo->save_config; + STsdbCfg oldCfg; + int32_t oldTotalBlocks = pRepo->config.totalBlocks; + + memcpy(&oldCfg, &(pRepo->config), sizeof(STsdbCfg)); + + pRepo->config.compression = pRepo->save_config.compression; + pRepo->config.keep = pRepo->save_config.keep; + pRepo->config.keep1 = pRepo->save_config.keep1; + pRepo->config.keep2 = pRepo->save_config.keep2; + pRepo->config.cacheLastRow = pRepo->save_config.cacheLastRow; + pRepo->config.totalBlocks = pRepo->save_config.totalBlocks; + + pthread_mutex_unlock(&pRepo->save_mutex); + + tsdbInfo("vgId:%d apply new config: compression(%d), keep(%d,%d,%d), totalBlocks(%d), cacheLastRow(%d->%d),totalBlocks(%d->%d)", + REPO_ID(pRepo), + pSaveCfg->compression, pSaveCfg->keep,pSaveCfg->keep1, pSaveCfg->keep2, + pSaveCfg->totalBlocks, oldCfg.cacheLastRow, pSaveCfg->cacheLastRow, oldTotalBlocks, pSaveCfg->totalBlocks); + + int err = tsdbExpendPool(pRepo, oldTotalBlocks); + if (!TAOS_SUCCEEDED(err)) { + tsdbError("vgId:%d expand pool from %d to %d fail,reason:%s", + REPO_ID(pRepo), oldTotalBlocks, pSaveCfg->totalBlocks, tstrerror(err)); + } + + if (oldCfg.cacheLastRow != pRepo->config.cacheLastRow) { + if (tsdbLockRepo(pRepo) < 0) return; + tsdbCacheLastData(pRepo, &oldCfg); + tsdbUnlockRepo(pRepo); + } + +} + static void *tsdbLoopCommit(void *arg) { SCommitQueue *pQueue = &tsCommitQueue; SListNode * pNode = NULL; @@ -138,6 +176,11 @@ static void *tsdbLoopCommit(void *arg) { pRepo = ((SCommitReq *)pNode->data)->pRepo; + // check if need to apply new config + if (pRepo->config_changed) { + tsdbApplyRepoConfig(pRepo); + } + tsdbCommitData(pRepo); listNodeFree(pNode); } diff --git a/src/tsdb/src/tsdbFS.c b/src/tsdb/src/tsdbFS.c index f6e721e3d3a5df205d3abfa908e7678e27e121d1..fd9b5e77e3fba01d49fc6f8f962730f1b8fbc9ec 100644 --- a/src/tsdb/src/tsdbFS.c +++ b/src/tsdb/src/tsdbFS.c @@ -957,10 +957,10 @@ static int tsdbRestoreMeta(STsdbRepo *pRepo) { regfree(®ex); return -1; } else { - uint32_t version = 0; + uint32_t _version = 0; if (strcmp(bname, "meta") != 0) { - sscanf(bname, "meta-ver%" PRIu32, &version); - pfs->cstatus->meta.version = version; + sscanf(bname, "meta-ver%" PRIu32, &_version); + pfs->cstatus->meta.version = _version; } pfs->cstatus->pmf = &(pfs->cstatus->mf); @@ -1103,10 +1103,10 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { int tvid, tfid; TSDB_FILE_T ttype; uint32_t tversion; - char bname[TSDB_FILENAME_LEN]; + char _bname[TSDB_FILENAME_LEN]; - tfsbasename(pf, bname); - tsdbParseDFilename(bname, &tvid, &tfid, &ttype, &tversion); + tfsbasename(pf, _bname); + tsdbParseDFilename(_bname, &tvid, &tfid, &ttype, &tversion); ASSERT(tvid == REPO_ID(pRepo)); diff --git a/src/tsdb/src/tsdbFile.c b/src/tsdb/src/tsdbFile.c index 5db993e46346dcbde81507faa774d431a1607781..50fa393e9fc9060941e181f8043d84070d036f98 100644 --- a/src/tsdb/src/tsdbFile.c +++ b/src/tsdb/src/tsdbFile.c @@ -410,7 +410,7 @@ int tsdbUpdateDFileHeader(SDFile *pDFile) { int tsdbLoadDFileHeader(SDFile *pDFile, SDFInfo *pInfo) { char buf[TSDB_FILE_HEAD_SIZE] = "\0"; - uint32_t version; + uint32_t _version; ASSERT(TSDB_FILE_OPENED(pDFile)); @@ -428,7 +428,7 @@ int tsdbLoadDFileHeader(SDFile *pDFile, SDFInfo *pInfo) { } void *pBuf = buf; - pBuf = taosDecodeFixedU32(pBuf, &version); + pBuf = taosDecodeFixedU32(pBuf, &_version); pBuf = tsdbDecodeDFInfo(pBuf, pInfo); return 0; } @@ -660,12 +660,12 @@ int tsdbScanAndTryFixDFileSet(STsdbRepo *pRepo, SDFileSet *pSet) { return 0; } -int tsdbParseDFilename(const char *fname, int *vid, int *fid, TSDB_FILE_T *ftype, uint32_t *version) { +int tsdbParseDFilename(const char *fname, int *vid, int *fid, TSDB_FILE_T *ftype, uint32_t *_version) { char *p = NULL; - *version = 0; + *_version = 0; *ftype = TSDB_FILE_MAX; - sscanf(fname, "v%df%d.%m[a-z]-ver%" PRIu32, vid, fid, &p, version); + sscanf(fname, "v%df%d.%m[a-z]-ver%" PRIu32, vid, fid, &p, _version); for (TSDB_FILE_T i = 0; i < TSDB_FILE_MAX; i++) { if (strcmp(p, TSDB_FNAME_SUFFIX[i]) == 0) { *ftype = i; diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c index 99929f3542160cc53b99571f73d699e1abcbf171..afbedd5b2fd231606902db104916e4ff4f10ba67 100644 --- a/src/tsdb/src/tsdbMain.c +++ b/src/tsdb/src/tsdbMain.c @@ -26,6 +26,8 @@ static STsdbRepo *tsdbNewRepo(STsdbCfg *pCfg, STsdbAppH *pAppH); static void tsdbFreeRepo(STsdbRepo *pRepo); static void tsdbStartStream(STsdbRepo *pRepo); static void tsdbStopStream(STsdbRepo *pRepo); +static int tsdbRestoreLastColumns(STsdbRepo *pRepo, STable *pTable, SReadH* pReadh); +static int tsdbRestoreLastRow(STsdbRepo *pRepo, STable *pTable, SReadH* pReadh, SBlockIdx *pIdx); // Function declaration int32_t tsdbCreateRepo(int repoid) { @@ -203,6 +205,74 @@ void tsdbReportStat(void *repo, int64_t *totalPoints, int64_t *totalStorage, int int32_t tsdbConfigRepo(STsdbRepo *repo, STsdbCfg *pCfg) { // TODO: think about multithread cases + if (tsdbCheckAndSetDefaultCfg(pCfg) < 0) return -1; + + STsdbCfg * pRCfg = &repo->config; + + ASSERT(pRCfg->tsdbId == pCfg->tsdbId); + ASSERT(pRCfg->cacheBlockSize == pCfg->cacheBlockSize); + ASSERT(pRCfg->daysPerFile == pCfg->daysPerFile); + ASSERT(pRCfg->minRowsPerFileBlock == pCfg->minRowsPerFileBlock); + ASSERT(pRCfg->maxRowsPerFileBlock == pCfg->maxRowsPerFileBlock); + ASSERT(pRCfg->precision == pCfg->precision); + + bool configChanged = false; + if (pRCfg->compression != pCfg->compression) { + configChanged = true; + } + if (pRCfg->keep != pCfg->keep) { + configChanged = true; + } + if (pRCfg->keep1 != pCfg->keep1) { + configChanged = true; + } + if (pRCfg->keep2 != pCfg->keep2) { + configChanged = true; + } + if (pRCfg->cacheLastRow != pCfg->cacheLastRow) { + configChanged = true; + } + if (pRCfg->totalBlocks != pCfg->totalBlocks) { + configChanged = true; + } + + if (!configChanged) { + tsdbError("vgId:%d no config changed", REPO_ID(repo)); + } + + int code = pthread_mutex_lock(&repo->save_mutex); + if (code != 0) { + tsdbError("vgId:%d failed to lock tsdb save config mutex since %s", REPO_ID(repo), strerror(errno)); + terrno = TAOS_SYSTEM_ERROR(code); + return -1; + } + + STsdbCfg * pSaveCfg = &repo->save_config; + *pSaveCfg = repo->config; + + pSaveCfg->compression = pCfg->compression; + pSaveCfg->keep = pCfg->keep; + pSaveCfg->keep1 = pCfg->keep1; + pSaveCfg->keep2 = pCfg->keep2; + pSaveCfg->cacheLastRow = pCfg->cacheLastRow; + pSaveCfg->totalBlocks = pCfg->totalBlocks; + + tsdbInfo("vgId:%d old config: compression(%d), keep(%d,%d,%d), cacheLastRow(%d),totalBlocks(%d)", + REPO_ID(repo), + pRCfg->compression, pRCfg->keep, pRCfg->keep1,pRCfg->keep2, + pRCfg->cacheLastRow, pRCfg->totalBlocks); + tsdbInfo("vgId:%d new config: compression(%d), keep(%d,%d,%d), cacheLastRow(%d),totalBlocks(%d)", + REPO_ID(repo), + pSaveCfg->compression, pSaveCfg->keep,pSaveCfg->keep1, pSaveCfg->keep2, + pSaveCfg->cacheLastRow,pSaveCfg->totalBlocks); + + repo->config_changed = true; + + pthread_mutex_unlock(&repo->save_mutex); + + // schedule a commit msg then the new config will be applied immediatly + tsdbAsyncCommit(repo); + return 0; #if 0 STsdbRepo *pRepo = (STsdbRepo *)repo; @@ -447,8 +517,10 @@ static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg) { if (pCfg->update != 0) pCfg->update = 1; // update cacheLastRow - if (pCfg->cacheLastRow != 0) pCfg->cacheLastRow = 1; - + if (pCfg->cacheLastRow != 0) { + if (pCfg->cacheLastRow > 3) + pCfg->cacheLastRow = 1; + } return 0; } @@ -474,6 +546,16 @@ static STsdbRepo *tsdbNewRepo(STsdbCfg *pCfg, STsdbAppH *pAppH) { return NULL; } + code = pthread_mutex_init(&(pRepo->save_mutex), NULL); + if (code != 0) { + terrno = TAOS_SYSTEM_ERROR(code); + tsdbFreeRepo(pRepo); + return NULL; + } + pRepo->config_changed = false; + atomic_store_8(&pRepo->hasCachedLastRow, 0); + atomic_store_8(&pRepo->hasCachedLastColumn, 0); + code = tsem_init(&(pRepo->readyToCommit), 0, 1); if (code != 0) { code = errno; @@ -542,13 +624,180 @@ static void tsdbStopStream(STsdbRepo *pRepo) { } } +static int tsdbRestoreLastColumns(STsdbRepo *pRepo, STable *pTable, SReadH* pReadh) { + //tsdbInfo("tsdbRestoreLastColumns of table %s", pTable->name->data); + + STSchema *pSchema = tsdbGetTableLatestSchema(pTable); + if (pSchema == NULL) { + tsdbError("tsdbGetTableLatestSchema of table %s fail", pTable->name->data); + return 0; + } + + SBlock* pBlock; + int numColumns; + int32_t blockIdx; + SDataStatis* pBlockStatis = NULL; + SDataRow row = NULL; + // restore last column data with last schema + + int err = 0; + + numColumns = schemaNCols(pSchema); + if (numColumns <= pTable->restoreColumnNum) { + pTable->hasRestoreLastColumn = true; + return 0; + } + if (pTable->lastColSVersion != schemaVersion(pSchema)) { + if (tsdbInitColIdCacheWithSchema(pTable, pSchema) < 0) { + return -1; + } + } + + row = taosTMalloc(dataRowMaxBytesFromSchema(pSchema)); + if (row == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + err = -1; + goto out; + } + tdInitDataRow(row, pSchema); + + // first load block index info + if (tsdbLoadBlockInfo(pReadh, NULL) < 0) { + err = -1; + goto out; + } + + pBlockStatis = calloc(numColumns, sizeof(SDataStatis)); + if (pBlockStatis == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + err = -1; + goto out; + } + memset(pBlockStatis, 0, numColumns * sizeof(SDataStatis)); + for(int32_t i = 0; i < numColumns; ++i) { + STColumn *pCol = schemaColAt(pSchema, i); + pBlockStatis[i].colId = pCol->colId; + } + + // load block from backward + SBlockIdx *pIdx = pReadh->pBlkIdx; + blockIdx = (int32_t)(pIdx->numOfBlocks - 1); + + while (numColumns > pTable->restoreColumnNum && blockIdx >= 0) { + bool loadStatisData = false; + pBlock = pReadh->pBlkInfo->blocks + blockIdx; + blockIdx -= 1; + + // load block data + if (tsdbLoadBlockData(pReadh, pBlock, NULL) < 0) { + err = -1; + goto out; + } + + // file block with sub-blocks has no statistics data + if (pBlock->numOfSubBlocks <= 1) { + tsdbLoadBlockStatis(pReadh, pBlock); + tsdbGetBlockStatis(pReadh, pBlockStatis, (int)numColumns); + loadStatisData = true; + } + + for (int16_t i = 0; i < numColumns && numColumns > pTable->restoreColumnNum; ++i) { + STColumn *pCol = schemaColAt(pSchema, i); + // ignore loaded columns + if (pTable->lastCols[i].bytes != 0) { + continue; + } + + // ignore block which has no not-null colId column + if (loadStatisData && pBlockStatis[i].numOfNull == pBlock->numOfRows) { + continue; + } + + // OK,let's load row from backward to get not-null column + for (int32_t rowId = pBlock->numOfRows - 1; rowId >= 0; rowId--) { + SDataCol *pDataCol = pReadh->pDCols[0]->cols + i; + tdAppendColVal(row, tdGetColDataOfRow(pDataCol, rowId), pCol->type, pCol->bytes, pCol->offset); + //SDataCol *pDataCol = readh.pDCols[0]->cols + j; + void* value = tdGetRowDataOfCol(row, (int8_t)pCol->type, TD_DATA_ROW_HEAD_SIZE + pCol->offset); + if (isNull(value, pCol->type)) { + continue; + } + + int16_t idx = tsdbGetLastColumnsIndexByColId(pTable, pCol->colId); + if (idx == -1) { + tsdbError("tsdbRestoreLastColumns restore vgId:%d,table:%s cache column %d fail", REPO_ID(pRepo), pTable->name->data, pCol->colId); + continue; + } + // save not-null column + SDataCol *pLastCol = &(pTable->lastCols[idx]); + pLastCol->pData = malloc(pCol->bytes); + pLastCol->bytes = pCol->bytes; + pLastCol->colId = pCol->colId; + memcpy(pLastCol->pData, value, pCol->bytes); + + // save row ts(in column 0) + pDataCol = pReadh->pDCols[0]->cols + 0; + pCol = schemaColAt(pSchema, 0); + tdAppendColVal(row, tdGetColDataOfRow(pDataCol, rowId), pCol->type, pCol->bytes, pCol->offset); + pLastCol->ts = dataRowKey(row); + + pTable->restoreColumnNum += 1; + + tsdbDebug("tsdbRestoreLastColumns restore vgId:%d,table:%s cache column %d, %" PRId64, REPO_ID(pRepo), pTable->name->data, pLastCol->colId, pLastCol->ts); + break; + } + } + } + +out: + taosTZfree(row); + tfree(pBlockStatis); + + if (err == 0 && numColumns <= pTable->restoreColumnNum) { + pTable->hasRestoreLastColumn = true; + } + + return err; +} + +static int tsdbRestoreLastRow(STsdbRepo *pRepo, STable *pTable, SReadH* pReadh, SBlockIdx *pIdx) { + ASSERT(pTable->lastRow == NULL); + if (tsdbLoadBlockInfo(pReadh, NULL) < 0) { + return -1; + } + + SBlock* pBlock = pReadh->pBlkInfo->blocks + pIdx->numOfBlocks - 1; + + if (tsdbLoadBlockData(pReadh, pBlock, NULL) < 0) { + return -1; + } + + // Get the data in row + + STSchema *pSchema = tsdbGetTableSchema(pTable); + pTable->lastRow = taosTMalloc(dataRowMaxBytesFromSchema(pSchema)); + if (pTable->lastRow == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + return -1; + } + + tdInitDataRow(pTable->lastRow, pSchema); + for (int icol = 0; icol < schemaNCols(pSchema); icol++) { + STColumn *pCol = schemaColAt(pSchema, icol); + SDataCol *pDataCol = pReadh->pDCols[0]->cols + icol; + tdAppendColVal(pTable->lastRow, tdGetColDataOfRow(pDataCol, pBlock->numOfRows - 1), pCol->type, pCol->bytes, + pCol->offset); + } + + return 0; +} + int tsdbRestoreInfo(STsdbRepo *pRepo) { SFSIter fsiter; SReadH readh; SDFileSet *pSet; STsdbMeta *pMeta = pRepo->tsdbMeta; STsdbCfg * pCfg = REPO_CFG(pRepo); - SBlock * pBlock; if (tsdbInitReadH(&readh, pRepo) < 0) { return -1; @@ -556,6 +805,14 @@ int tsdbRestoreInfo(STsdbRepo *pRepo) { tsdbFSIterInit(&fsiter, REPO_FS(pRepo), TSDB_FS_ITER_BACKWARD); + if (CACHE_LAST_NULL_COLUMN(pCfg)) { + for (int i = 1; i < pMeta->maxTables; i++) { + STable *pTable = pMeta->tables[i]; + if (pTable == NULL) continue; + pTable->restoreColumnNum = 0; + } + } + while ((pSet = tsdbFSIterNext(&fsiter)) != NULL) { if (tsdbSetAndOpenReadFSet(&readh, pSet) < 0) { tsdbDestroyReadH(&readh); @@ -571,6 +828,8 @@ int tsdbRestoreInfo(STsdbRepo *pRepo) { STable *pTable = pMeta->tables[i]; if (pTable == NULL) continue; + //tsdbInfo("tsdbRestoreInfo restore vgId:%d,table:%s", REPO_ID(pRepo), pTable->name->data); + if (tsdbSetReadTable(&readh, pTable) < 0) { tsdbDestroyReadH(&readh); return -1; @@ -581,42 +840,155 @@ int tsdbRestoreInfo(STsdbRepo *pRepo) { if (pIdx && lastKey < pIdx->maxKey) { pTable->lastKey = pIdx->maxKey; - if (pCfg->cacheLastRow) { - if (tsdbLoadBlockInfo(&readh, NULL) < 0) { - tsdbDestroyReadH(&readh); - return -1; - } - - pBlock = readh.pBlkInfo->blocks + pIdx->numOfBlocks - 1; - - if (tsdbLoadBlockData(&readh, pBlock, NULL) < 0) { - tsdbDestroyReadH(&readh); - return -1; - } - - // Get the data in row - ASSERT(pTable->lastRow == NULL); - STSchema *pSchema = tsdbGetTableSchema(pTable); - pTable->lastRow = taosTMalloc(dataRowMaxBytesFromSchema(pSchema)); - if (pTable->lastRow == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - tsdbDestroyReadH(&readh); - return -1; - } - - tdInitDataRow(pTable->lastRow, pSchema); - for (int icol = 0; icol < schemaNCols(pSchema); icol++) { - STColumn *pCol = schemaColAt(pSchema, icol); - SDataCol *pDataCol = readh.pDCols[0]->cols + icol; - tdAppendColVal(pTable->lastRow, tdGetColDataOfRow(pDataCol, pBlock->numOfRows - 1), pCol->type, pCol->bytes, - pCol->offset); - } + if (CACHE_LAST_ROW(pCfg) && tsdbRestoreLastRow(pRepo, pTable, &readh, pIdx) != 0) { + tsdbDestroyReadH(&readh); + return -1; } } + // restore NULL columns + if (pIdx && CACHE_LAST_NULL_COLUMN(pCfg) && !pTable->hasRestoreLastColumn) { + if (tsdbRestoreLastColumns(pRepo, pTable, &readh) != 0) { + tsdbDestroyReadH(&readh); + return -1; + } + } } } tsdbDestroyReadH(&readh); + if (CACHE_LAST_ROW(pCfg)) { + atomic_store_8(&pRepo->hasCachedLastRow, 1); + } + if (CACHE_LAST_NULL_COLUMN(pCfg)) { + atomic_store_8(&pRepo->hasCachedLastColumn, 1); + } + return 0; } + +int tsdbCacheLastData(STsdbRepo *pRepo, STsdbCfg* oldCfg) { + bool cacheLastRow = false, cacheLastCol = false; + SFSIter fsiter; + SReadH readh; + SDFileSet *pSet; + STsdbMeta *pMeta = pRepo->tsdbMeta; + int tableNum = 0; + int maxTableIdx = 0; + int cacheLastRowTableNum = 0; + int cacheLastColTableNum = 0; + + bool need_free_last_row = CACHE_LAST_ROW(oldCfg) && !CACHE_LAST_ROW(&(pRepo->config)); + bool need_free_last_col = CACHE_LAST_NULL_COLUMN(oldCfg) && !CACHE_LAST_NULL_COLUMN(&(pRepo->config)); + + if (CACHE_LAST_ROW(&(pRepo->config)) || CACHE_LAST_NULL_COLUMN(&(pRepo->config))) { + tsdbInfo("tsdbCacheLastData cache last data since cacheLast option changed"); + cacheLastRow = !CACHE_LAST_ROW(oldCfg) && CACHE_LAST_ROW(&(pRepo->config)); + cacheLastCol = !CACHE_LAST_NULL_COLUMN(oldCfg) && CACHE_LAST_NULL_COLUMN(&(pRepo->config)); + } + + // calc max table idx and table num + for (int i = 1; i < pMeta->maxTables; i++) { + STable *pTable = pMeta->tables[i]; + if (pTable == NULL) continue; + tableNum += 1; + maxTableIdx = i; + if (cacheLastCol) { + pTable->restoreColumnNum = 0; + } + } + + // if close last option,need to free data + if (need_free_last_row || need_free_last_col) { + if (need_free_last_row) { + atomic_store_8(&pRepo->hasCachedLastRow, 0); + } + if (need_free_last_col) { + atomic_store_8(&pRepo->hasCachedLastColumn, 0); + } + tsdbInfo("free cache last data since cacheLast option changed"); + for (int i = 1; i < maxTableIdx; i++) { + STable *pTable = pMeta->tables[i]; + if (pTable == NULL) continue; + if (need_free_last_row) { + taosTZfree(pTable->lastRow); + pTable->lastRow = NULL; + pTable->lastKey = TSKEY_INITIAL_VAL; + } + if (need_free_last_col) { + tsdbFreeLastColumns(pTable); + } + } + } + + if (!cacheLastRow && !cacheLastCol) { + return 0; + } + + cacheLastRowTableNum = cacheLastRow ? tableNum : 0; + cacheLastColTableNum = cacheLastCol ? tableNum : 0; + + if (tsdbInitReadH(&readh, pRepo) < 0) { + return -1; + } + + tsdbFSIterInit(&fsiter, REPO_FS(pRepo), TSDB_FS_ITER_BACKWARD); + + while ((pSet = tsdbFSIterNext(&fsiter)) != NULL && (cacheLastRowTableNum > 0 || cacheLastColTableNum > 0)) { + if (tsdbSetAndOpenReadFSet(&readh, pSet) < 0) { + tsdbDestroyReadH(&readh); + return -1; + } + + if (tsdbLoadBlockIdx(&readh) < 0) { + tsdbDestroyReadH(&readh); + return -1; + } + + for (int i = 1; i <= maxTableIdx; i++) { + STable *pTable = pMeta->tables[i]; + if (pTable == NULL) continue; + + //tsdbInfo("tsdbRestoreInfo restore vgId:%d,table:%s", REPO_ID(pRepo), pTable->name->data); + + if (tsdbSetReadTable(&readh, pTable) < 0) { + tsdbDestroyReadH(&readh); + return -1; + } + + SBlockIdx *pIdx = readh.pBlkIdx; + + if (pIdx && cacheLastRowTableNum > 0 && pTable->lastRow == NULL) { + pTable->lastKey = pIdx->maxKey; + + if (tsdbRestoreLastRow(pRepo, pTable, &readh, pIdx) != 0) { + tsdbDestroyReadH(&readh); + return -1; + } + cacheLastRowTableNum -= 1; + } + + // restore NULL columns + if (pIdx && cacheLastColTableNum > 0 && !pTable->hasRestoreLastColumn) { + if (tsdbRestoreLastColumns(pRepo, pTable, &readh) != 0) { + tsdbDestroyReadH(&readh); + return -1; + } + if (pTable->hasRestoreLastColumn) { + cacheLastColTableNum -= 1; + } + } + } + } + + tsdbDestroyReadH(&readh); + + if (cacheLastRow) { + atomic_store_8(&pRepo->hasCachedLastRow, 1); + } + if (cacheLastCol) { + atomic_store_8(&pRepo->hasCachedLastColumn, 1); + } + + return 0; +} \ No newline at end of file diff --git a/src/tsdb/src/tsdbMemTable.c b/src/tsdb/src/tsdbMemTable.c index 20ec426018a39e554fb03e9bb11399dbce1f3fcc..79dbb8be5d8719d7a9df7fe71695d013dffdefc1 100644 --- a/src/tsdb/src/tsdbMemTable.c +++ b/src/tsdb/src/tsdbMemTable.c @@ -98,17 +98,26 @@ int tsdbUnRefMemTable(STsdbRepo *pRepo, SMemTable *pMemTable) { STsdbBufPool *pBufPool = pRepo->pPool; SListNode *pNode = NULL; + bool recycleBlocks = pBufPool->nRecycleBlocks > 0; if (tsdbLockRepo(pRepo) < 0) return -1; while ((pNode = tdListPopHead(pMemTable->bufBlockList)) != NULL) { - tdListAppendNode(pBufPool->bufBlockList, pNode); + if (pBufPool->nRecycleBlocks > 0) { + tsdbRecycleBufferBlock(pBufPool, pNode); + pBufPool->nRecycleBlocks -= 1; + } else { + tdListAppendNode(pBufPool->bufBlockList, pNode); + } } - int code = pthread_cond_signal(&pBufPool->poolNotEmpty); - if (code != 0) { - if (tsdbUnlockRepo(pRepo) < 0) return -1; - tsdbError("vgId:%d failed to signal pool not empty since %s", REPO_ID(pRepo), strerror(code)); - terrno = TAOS_SYSTEM_ERROR(code); - return -1; + if (!recycleBlocks) { + int code = pthread_cond_signal(&pBufPool->poolNotEmpty); + if (code != 0) { + if (tsdbUnlockRepo(pRepo) < 0) return -1; + tsdbError("vgId:%d failed to signal pool not empty since %s", REPO_ID(pRepo), strerror(code)); + terrno = TAOS_SYSTEM_ERROR(code); + return -1; + } } + if (tsdbUnlockRepo(pRepo) < 0) return -1; for (int i = 0; i < pMemTable->maxTables; i++) { @@ -265,7 +274,7 @@ void *tsdbAllocBytes(STsdbRepo *pRepo, int bytes) { int tsdbAsyncCommit(STsdbRepo *pRepo) { tsem_wait(&(pRepo->readyToCommit)); - ASSERT(pRepo->imem == NULL); + //ASSERT(pRepo->imem == NULL); if (pRepo->mem == NULL) { tsem_post(&(pRepo->readyToCommit)); return 0; @@ -955,11 +964,63 @@ static void tsdbFreeRows(STsdbRepo *pRepo, void **rows, int rowCounter) { } } +static void updateTableLatestColumn(STsdbRepo *pRepo, STable *pTable, SDataRow row) { + tsdbDebug("vgId:%d updateTableLatestColumn, %s row version:%d", REPO_ID(pRepo), pTable->name->data, dataRowVersion(row)); + + STSchema* pSchema = tsdbGetTableLatestSchema(pTable); + if (tsdbUpdateLastColSchema(pTable, pSchema) < 0) { + return; + } + + pSchema = tsdbGetTableSchemaByVersion(pTable, dataRowVersion(row)); + if (pSchema == NULL) { + return; + } + + SDataCol *pLatestCols = pTable->lastCols; + + for (int16_t j = 0; j < schemaNCols(pSchema); j++) { + STColumn *pTCol = schemaColAt(pSchema, j); + // ignore not exist colId + int16_t idx = tsdbGetLastColumnsIndexByColId(pTable, pTCol->colId); + if (idx == -1) { + continue; + } + + void* value = tdGetRowDataOfCol(row, (int8_t)pTCol->type, TD_DATA_ROW_HEAD_SIZE + pSchema->columns[j].offset); + if (isNull(value, pTCol->type)) { + continue; + } + + SDataCol *pDataCol = &(pLatestCols[idx]); + if (pDataCol->pData == NULL) { + pDataCol->pData = malloc(pSchema->columns[j].bytes); + pDataCol->bytes = pSchema->columns[j].bytes; + } else if (pDataCol->bytes < pSchema->columns[j].bytes) { + pDataCol->pData = realloc(pDataCol->pData, pSchema->columns[j].bytes); + pDataCol->bytes = pSchema->columns[j].bytes; + } + + memcpy(pDataCol->pData, value, pDataCol->bytes); + //tsdbInfo("updateTableLatestColumn vgId:%d cache column %d for %d,%s", REPO_ID(pRepo), j, pDataCol->bytes, (char*)pDataCol->pData); + pDataCol->ts = dataRowKey(row); + } +} + static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SDataRow row) { STsdbCfg *pCfg = &pRepo->config; + // if cacheLastRow config has been reset, free the lastRow + if (!pCfg->cacheLastRow && pTable->lastRow != NULL) { + taosTZfree(pTable->lastRow); + TSDB_WLOCK_TABLE(pTable); + pTable->lastRow = NULL; + pTable->lastKey = TSKEY_INITIAL_VAL; + TSDB_WUNLOCK_TABLE(pTable); + } + if (tsdbGetTableLastKeyImpl(pTable) < dataRowKey(row)) { - if (pCfg->cacheLastRow || pTable->lastRow != NULL) { + if (CACHE_LAST_ROW(pCfg) || pTable->lastRow != NULL) { SDataRow nrow = pTable->lastRow; if (taosTSizeof(nrow) < dataRowLen(row)) { SDataRow orow = nrow; @@ -984,7 +1045,10 @@ static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SDataRow } else { pTable->lastKey = dataRowKey(row); } - } + if (CACHE_LAST_NULL_COLUMN(pCfg)) { + updateTableLatestColumn(pRepo, pTable, row); + } + } return 0; } diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c index 3e6263b9d323f367ae0c10522dac1240eaf4d70f..324a7c79c5b7dbfa69bbdf240301c3c710f90b59 100644 --- a/src/tsdb/src/tsdbMeta.c +++ b/src/tsdb/src/tsdbMeta.c @@ -531,8 +531,8 @@ STable *tsdbGetTableByUid(STsdbMeta *pMeta, uint64_t uid) { return *(STable **)ptr; } -STSchema *tsdbGetTableSchemaByVersion(STable *pTable, int16_t version) { - return tsdbGetTableSchemaImpl(pTable, true, false, version); +STSchema *tsdbGetTableSchemaByVersion(STable *pTable, int16_t _version) { + return tsdbGetTableSchemaImpl(pTable, true, false, _version); } int tsdbWLockRepoMeta(STsdbRepo *pRepo) { @@ -589,6 +589,131 @@ void tsdbUnRefTable(STable *pTable) { } } +void tsdbFreeLastColumns(STable* pTable) { + if (pTable->lastCols == NULL) { + return; + } + + for (int i = 0; i < pTable->maxColNum; ++i) { + if (pTable->lastCols[i].bytes == 0) { + continue; + } + tfree(pTable->lastCols[i].pData); + pTable->lastCols[i].bytes = 0; + pTable->lastCols[i].pData = NULL; + } + tfree(pTable->lastCols); + pTable->lastCols = NULL; + pTable->maxColNum = 0; + pTable->lastColSVersion = -1; + pTable->restoreColumnNum = 0; +} + +int16_t tsdbGetLastColumnsIndexByColId(STable* pTable, int16_t colId) { + if (pTable->lastCols == NULL) { + return -1; + } + for (int16_t i = 0; i < pTable->maxColNum; ++i) { + if (pTable->lastCols[i].colId == colId) { + return i; + } + } + + return -1; +} + +int tsdbInitColIdCacheWithSchema(STable* pTable, STSchema* pSchema) { + ASSERT(pTable->lastCols == NULL); + + int16_t numOfColumn = pSchema->numOfCols; + + pTable->lastCols = (SDataCol*)malloc(numOfColumn * sizeof(SDataCol)); + if (pTable->lastCols == NULL) { + return -1; + } + + for (int16_t i = 0; i < numOfColumn; ++i) { + STColumn *pCol = schemaColAt(pSchema, i); + SDataCol* pDataCol = &(pTable->lastCols[i]); + pDataCol->bytes = 0; + pDataCol->pData = NULL; + pDataCol->colId = pCol->colId; + } + + pTable->lastColSVersion = schemaVersion(pSchema); + pTable->maxColNum = numOfColumn; + pTable->restoreColumnNum = 0; + return 0; +} + +STSchema* tsdbGetTableLatestSchema(STable *pTable) { + return tsdbGetTableSchemaByVersion(pTable, -1); +} + +int tsdbUpdateLastColSchema(STable *pTable, STSchema *pNewSchema) { + if (pTable->lastColSVersion == schemaVersion(pNewSchema)) { + return 0; + } + + tsdbInfo("tsdbUpdateLastColSchema:%s,%d->%d", pTable->name->data, pTable->lastColSVersion, schemaVersion(pNewSchema)); + + int16_t numOfCols = pNewSchema->numOfCols; + SDataCol *lastCols = (SDataCol*)malloc(numOfCols * sizeof(SDataCol)); + if (lastCols == NULL) { + return -1; + } + + TSDB_WLOCK_TABLE(pTable); + + for (int16_t i = 0; i < numOfCols; ++i) { + STColumn *pCol = schemaColAt(pNewSchema, i); + int16_t idx = tsdbGetLastColumnsIndexByColId(pTable, pCol->colId); + + SDataCol* pDataCol = &(lastCols[i]); + if (idx != -1) { + // move col data to new last column array + SDataCol* pOldDataCol = &(pTable->lastCols[idx]); + memcpy(pDataCol, pOldDataCol, sizeof(SDataCol)); + } else { + // init new colid data + pDataCol->colId = pCol->colId; + pDataCol->bytes = 0; + pDataCol->pData = NULL; + } + } + + SDataCol *oldLastCols = pTable->lastCols; + int16_t oldLastColNum = pTable->maxColNum; + + pTable->lastColSVersion = schemaVersion(pNewSchema); + pTable->lastCols = lastCols; + pTable->maxColNum = numOfCols; + + if (oldLastCols == NULL) { + TSDB_WUNLOCK_TABLE(pTable); + return 0; + } + + // free old schema last column datas + for (int16_t i = 0; i < oldLastColNum; ++i) { + SDataCol* pDataCol = &(oldLastCols[i]); + if (pDataCol->bytes == 0) { + continue; + } + int16_t idx = tsdbGetLastColumnsIndexByColId(pTable, pDataCol->colId); + if (idx != -1) { + continue; + } + + // free not exist column data + tfree(pDataCol->pData); + } + TSDB_WUNLOCK_TABLE(pTable); + tfree(oldLastCols); + + return 0; +} + void tsdbUpdateTableSchema(STsdbRepo *pRepo, STable *pTable, STSchema *pSchema, bool insertAct) { ASSERT(TABLE_TYPE(pTable) != TSDB_STREAM_TABLE && TABLE_TYPE(pTable) != TSDB_SUPER_TABLE); STsdbMeta *pMeta = pRepo->tsdbMeta; @@ -672,6 +797,10 @@ static STable *tsdbNewTable() { pTable->lastKey = TSKEY_INITIAL_VAL; + pTable->lastCols = NULL; + pTable->restoreColumnNum = 0; + pTable->maxColNum = 0; + pTable->lastColSVersion = -1; return pTable; } @@ -785,8 +914,10 @@ static void tsdbFreeTable(STable *pTable) { kvRowFree(pTable->tagVal); tSkipListDestroy(pTable->pIndex); - taosTZfree(pTable->lastRow); + taosTZfree(pTable->lastRow); tfree(pTable->sql); + + tsdbFreeLastColumns(pTable); free(pTable); } } @@ -891,9 +1022,9 @@ static void tsdbRemoveTableFromMeta(STsdbRepo *pRepo, STable *pTable, bool rmFro maxCols = 0; maxRowBytes = 0; for (int i = 0; i < pMeta->maxTables; i++) { - STable *pTable = pMeta->tables[i]; - if (pTable != NULL) { - pSchema = tsdbGetTableSchemaImpl(pTable, false, false, -1); + STable *_pTable = pMeta->tables[i]; + if (_pTable != NULL) { + pSchema = tsdbGetTableSchemaImpl(_pTable, false, false, -1); maxCols = MAX(maxCols, schemaNCols(pSchema)); maxRowBytes = MAX(maxRowBytes, schemaTLen(pSchema)); } diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 9df25409de62f9b2579d43800fd6a5709bd41f1a..0a39dba021c92510e9e6d5f1420fe88792645cad 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -62,6 +62,7 @@ typedef struct SLoadCompBlockInfo { int32_t fileId; } SLoadCompBlockInfo; + typedef struct STableCheckInfo { STableId tableId; TSKEY lastKey; @@ -107,7 +108,7 @@ typedef struct STsdbQueryHandle { SArray* pTableCheckInfo; // SArray int32_t activeIndex; bool checkFiles; // check file stage - bool cachelastrow; // check if last row cached + int8_t cachelastrow; // check if last row cached bool loadExternalRow; // load time window external data rows bool currentLoadExternalRows; // current load external rows int32_t loadType; // block load type @@ -117,7 +118,6 @@ typedef struct STsdbQueryHandle { SFSIter fileIter; SReadH rhelper; STableBlockInfo* pDataBlockInfo; - SDataCols *pDataCols; // in order to hold current file data block int32_t allocSize; // allocated data block size SMemRef *pMemRef; @@ -138,6 +138,7 @@ typedef struct STableGroupSupporter { static STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList); static int32_t checkForCachedLastRow(STsdbQueryHandle* pQueryHandle, STableGroupInfo *groupList); +static int32_t checkForCachedLast(STsdbQueryHandle* pQueryHandle); static int32_t tsdbGetCachedLastRow(STable* pTable, SDataRow* pRes, TSKEY* lastKey); static void changeQueryHandleForInterpQuery(TsdbQueryHandleT pHandle); @@ -512,6 +513,8 @@ void tsdbResetQueryHandleForNewTable(TsdbQueryHandleT queryHandle, STsdbQueryCon pQueryHandle->next = doFreeColumnInfoData(pQueryHandle->next); } + + TsdbQueryHandleT tsdbQueryLastRow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, uint64_t qId, SMemRef* pMemRef) { pCond->twindow = updateLastrowForEachGroup(groupList); @@ -528,10 +531,30 @@ TsdbQueryHandleT tsdbQueryLastRow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STable } assert(pCond->order == TSDB_ORDER_ASC && pCond->twindow.skey <= pCond->twindow.ekey); - pQueryHandle->type = TSDB_QUERY_TYPE_LAST; + if (pQueryHandle->cachelastrow) { + pQueryHandle->type = TSDB_QUERY_TYPE_LAST; + } + + return pQueryHandle; +} + + +TsdbQueryHandleT tsdbQueryCacheLast(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, uint64_t qId, SMemRef* pMemRef) { + STsdbQueryHandle *pQueryHandle = (STsdbQueryHandle*) tsdbQueryTables(tsdb, pCond, groupList, qId, pMemRef); + int32_t code = checkForCachedLast(pQueryHandle); + if (code != TSDB_CODE_SUCCESS) { // set the numOfTables to be 0 + terrno = code; + return NULL; + } + + if (pQueryHandle->cachelastrow) { + pQueryHandle->type = TSDB_QUERY_TYPE_LAST; + } + return pQueryHandle; } + SArray* tsdbGetQueriedTableList(TsdbQueryHandleT *pHandle) { assert(pHandle != NULL); @@ -2460,6 +2483,159 @@ static bool loadCachedLastRow(STsdbQueryHandle* pQueryHandle) { return false; } + + +static bool loadCachedLast(STsdbQueryHandle* pQueryHandle) { + // the last row is cached in buffer, return it directly. + // here note that the pQueryHandle->window must be the TS_INITIALIZER + int32_t tgNumOfCols = (int32_t)QH_GET_NUM_OF_COLS(pQueryHandle); + size_t numOfTables = taosArrayGetSize(pQueryHandle->pTableCheckInfo); + int32_t numOfRows = 0; + assert(numOfTables > 0 && tgNumOfCols > 0); + SQueryFilePos* cur = &pQueryHandle->cur; + TSKEY priKey = TSKEY_INITIAL_VAL; + int32_t priIdx = -1; + SColumnInfoData* pColInfo = NULL; + + while (++pQueryHandle->activeIndex < numOfTables) { + STableCheckInfo* pCheckInfo = taosArrayGet(pQueryHandle->pTableCheckInfo, pQueryHandle->activeIndex); + STable* pTable = pCheckInfo->pTableObj; + char* pData = NULL; + + int32_t numOfCols = pTable->maxColNum; + + if (pTable->lastCols == NULL || pTable->maxColNum <= 0) { + tsdbWarn("no last cached for table, uid:%" PRIu64 ",tid:%d", pTable->tableId.uid, pTable->tableId.tid); + continue; + } + + int32_t i = 0, j = 0; + while(i < tgNumOfCols && j < numOfCols) { + pColInfo = taosArrayGet(pQueryHandle->pColumns, i); + if (pTable->lastCols[j].colId < pColInfo->info.colId) { + j++; + continue; + } else if (pTable->lastCols[j].colId > pColInfo->info.colId) { + i++; + continue; + } + + pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes; + + if (pTable->lastCols[j].bytes > 0) { + void* value = pTable->lastCols[j].pData; + switch (pColInfo->info.type) { + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + memcpy(pData, value, varDataTLen(value)); + break; + case TSDB_DATA_TYPE_NULL: + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_UTINYINT: + *(uint8_t *)pData = *(uint8_t *)value; + break; + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_USMALLINT: + *(uint16_t *)pData = *(uint16_t *)value; + break; + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_UINT: + *(uint32_t *)pData = *(uint32_t *)value; + break; + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_UBIGINT: + *(uint64_t *)pData = *(uint64_t *)value; + break; + case TSDB_DATA_TYPE_FLOAT: + SET_FLOAT_PTR(pData, value); + break; + case TSDB_DATA_TYPE_DOUBLE: + SET_DOUBLE_PTR(pData, value); + break; + case TSDB_DATA_TYPE_TIMESTAMP: + if (pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + priKey = tdGetKey(*(TKEY *)value); + priIdx = i; + + i++; + j++; + continue; + } else { + *(TSKEY *)pData = *(TSKEY *)value; + } + break; + default: + memcpy(pData, value, pColInfo->info.bytes); + } + + for (int32_t n = 0; n < tgNumOfCols; ++n) { + if (n == i) { + continue; + } + + pColInfo = taosArrayGet(pQueryHandle->pColumns, n); + pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;; + + if (pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + *(TSKEY *)pData = pTable->lastCols[j].ts; + continue; + } + + if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) { + setVardataNull(pData, pColInfo->info.type); + } else { + setNull(pData, pColInfo->info.type, pColInfo->info.bytes); + } + } + + numOfRows++; + assert(numOfRows < pQueryHandle->outputCapacity); + } + + i++; + j++; + } + + // leave the real ts column as the last row, because last function only (not stable) use the last row as res + if (priKey != TSKEY_INITIAL_VAL) { + pColInfo = taosArrayGet(pQueryHandle->pColumns, priIdx); + pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes; + + *(TSKEY *)pData = priKey; + + for (int32_t n = 0; n < tgNumOfCols; ++n) { + if (n == priIdx) { + continue; + } + + pColInfo = taosArrayGet(pQueryHandle->pColumns, n); + pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;; + + assert (pColInfo->info.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX); + + if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) { + setVardataNull(pData, pColInfo->info.type); + } else { + setNull(pData, pColInfo->info.type, pColInfo->info.bytes); + } + } + + numOfRows++; + } + + if (numOfRows > 0) { + cur->rows = numOfRows; + cur->mixBlock = true; + + return true; + } + } + + return false; +} + + static bool loadDataBlockFromTableSeq(STsdbQueryHandle* pQueryHandle) { size_t numOfTables = taosArrayGetSize(pQueryHandle->pTableCheckInfo); assert(numOfTables > 0); @@ -2496,8 +2672,12 @@ bool tsdbNextDataBlock(TsdbQueryHandleT pHandle) { int64_t stime = taosGetTimestampUs(); int64_t elapsedTime = stime; - if (pQueryHandle->type == TSDB_QUERY_TYPE_LAST && pQueryHandle->cachelastrow) { - return loadCachedLastRow(pQueryHandle); + if (pQueryHandle->type == TSDB_QUERY_TYPE_LAST) { + if (pQueryHandle->cachelastrow == 1) { + return loadCachedLastRow(pQueryHandle); + } else if (pQueryHandle->cachelastrow == 2) { + return loadCachedLast(pQueryHandle); + } } if (pQueryHandle->loadType == BLOCK_LOAD_TABLE_SEQ_ORDER) { @@ -2695,6 +2875,10 @@ int32_t tsdbGetCachedLastRow(STable* pTable, SDataRow* pRes, TSKEY* lastKey) { return TSDB_CODE_SUCCESS; } +bool isTsdbCacheLastRow(TsdbQueryHandleT* pQueryHandle) { + return ((STsdbQueryHandle *)pQueryHandle)->cachelastrow > 0; +} + int32_t checkForCachedLastRow(STsdbQueryHandle* pQueryHandle, STableGroupInfo *groupList) { assert(pQueryHandle != NULL && groupList != NULL); @@ -2706,11 +2890,15 @@ int32_t checkForCachedLastRow(STsdbQueryHandle* pQueryHandle, STableGroupInfo *g STableKeyInfo* pInfo = (STableKeyInfo*)taosArrayGet(group, 0); - int32_t code = tsdbGetCachedLastRow(pInfo->pTable, &pRow, &key); - if (code != TSDB_CODE_SUCCESS) { - pQueryHandle->cachelastrow = false; - } else { - pQueryHandle->cachelastrow = (pRow != NULL); + int32_t code = 0; + + if (((STable*)pInfo->pTable)->lastRow) { + code = tsdbGetCachedLastRow(pInfo->pTable, &pRow, &key); + if (code != TSDB_CODE_SUCCESS) { + pQueryHandle->cachelastrow = 0; + } else { + pQueryHandle->cachelastrow = 1; + } } // update the tsdb query time range @@ -2724,6 +2912,26 @@ int32_t checkForCachedLastRow(STsdbQueryHandle* pQueryHandle, STableGroupInfo *g return code; } +int32_t checkForCachedLast(STsdbQueryHandle* pQueryHandle) { + assert(pQueryHandle != NULL); + + int32_t code = 0; + + if (pQueryHandle->pTsdb && atomic_load_8(&pQueryHandle->pTsdb->hasCachedLastColumn)){ + pQueryHandle->cachelastrow = 2; + } + + // update the tsdb query time range + if (pQueryHandle->cachelastrow) { + pQueryHandle->window = TSWINDOW_INITIALIZER; + pQueryHandle->checkFiles = false; + pQueryHandle->activeIndex = -1; // start from -1 + } + + return code; +} + + STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList) { STimeWindow window = {INT64_MAX, INT64_MIN}; diff --git a/src/util/inc/hash.h b/src/util/inc/hash.h index b6b49693f60b15a51eaa35c95555d0f35d36f017..cd4850e47e855cde4c1a7c281edb0afc23404370 100644 --- a/src/util/inc/hash.h +++ b/src/util/inc/hash.h @@ -148,6 +148,7 @@ int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj); size_t taosHashGetMemSize(const SHashObj *pHashObj); void *taosHashIterate(SHashObj *pHashObj, void *p); + void taosHashCancelIterate(SHashObj *pHashObj, void *p); #ifdef __cplusplus diff --git a/src/util/inc/tarray.h b/src/util/inc/tarray.h index f2e268c2d4dfe210dfbfd9b94ee74a4f87848361..bc25776caaae50e320b036f662ed4780fd36d90f 100644 --- a/src/util/inc/tarray.h +++ b/src/util/inc/tarray.h @@ -50,7 +50,15 @@ void* taosArrayInit(size_t size, size_t elemSize); * @param nEles * @return */ -void *taosArrayPushBatch(SArray *pArray, const void *pData, int nEles); +void *taosArrayAddBatch(SArray *pArray, const void *pData, int nEles); + +/** + * add all element from the source array list into the destination + * @param pArray + * @param pInput + * @return + */ +void* taosArrayAddAll(SArray* pArray, const SArray* pInput); /** * @@ -59,7 +67,7 @@ void *taosArrayPushBatch(SArray *pArray, const void *pData, int nEles); * @return */ static FORCE_INLINE void* taosArrayPush(SArray* pArray, const void* pData) { - return taosArrayPushBatch(pArray, pData, 1); + return taosArrayAddBatch(pArray, pData, 1); } /** diff --git a/src/util/inc/tskiplist.h b/src/util/inc/tskiplist.h index 2c4d1a86ef7446f49a2c1a97e25db558f933bd57..17f5940b4998c8a5b5e277e153cf7485c3cd6129 100644 --- a/src/util/inc/tskiplist.h +++ b/src/util/inc/tskiplist.h @@ -96,6 +96,7 @@ typedef struct tSkipListState { } tSkipListState; typedef struct SSkipList { + unsigned int seed; __compar_fn_t comparFn; __sl_key_fn_t keyFn; pthread_rwlock_t *lock; diff --git a/src/util/inc/tstoken.h b/src/util/inc/ttoken.h similarity index 93% rename from src/util/inc/tstoken.h rename to src/util/inc/ttoken.h index ab1ef7b279a37d218364ddba6a5afc7dbfa59f57..3bf030a9ebf96a27f16b27eb6d55505212274ba6 100644 --- a/src/util/inc/tstoken.h +++ b/src/util/inc/ttoken.h @@ -37,13 +37,21 @@ typedef struct SStrToken { char *z; } SStrToken; +/** + * check if it is a number or not + * @param pToken + * @return + */ +#define isNumber(tk) \ +((tk)->type == TK_INTEGER || (tk)->type == TK_FLOAT || (tk)->type == TK_HEX || (tk)->type == TK_BIN) + /** * tokenizer for sql string * @param z * @param tokenType * @return */ -uint32_t tSQLGetToken(char *z, uint32_t *tokenType); +uint32_t tGetToken(char *z, uint32_t *tokenType); /** * enhanced tokenizer for sql string. @@ -61,21 +69,12 @@ SStrToken tStrGetToken(char *str, int32_t *i, bool isPrevOptr); * @param len * @return */ -bool isKeyWord(const char *z, int32_t len); - -/** - * check if it is a number or not - * @param pToken - * @return - */ -#define isNumber(tk) \ -((tk)->type == TK_INTEGER || (tk)->type == TK_FLOAT || (tk)->type == TK_HEX || (tk)->type == TK_BIN) - +bool taosIsKeyWordToken(const char *z, int32_t len); /** * check if it is a token or not - * @param pToken - * @return token type, if it is not a number, TK_ILLEGAL will return + * @param pToken + * @return token type, if it is not a number, TK_ILLEGAL will return */ static FORCE_INLINE int32_t tGetNumericStringType(const SStrToken* pToken) { const char* z = pToken->z; @@ -182,6 +181,9 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SStrToken* pToken) { void taosCleanupKeywordsTable(); +SStrToken tscReplaceStrToken(char **str, SStrToken *token, const char* newToken); + + #ifdef __cplusplus } #endif diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c index f4587b33e75c556d6dbc03e1577436afb728cba7..45cb878668e2058c92c1ba2821a88886b87e2044 100644 --- a/src/util/src/tarray.c +++ b/src/util/src/tarray.c @@ -56,7 +56,7 @@ static int32_t taosArrayResize(SArray* pArray) { return 0; } -void* taosArrayPushBatch(SArray* pArray, const void* pData, int nEles) { +void* taosArrayAddBatch(SArray* pArray, const void* pData, int nEles) { if (pArray == NULL || pData == NULL) { return NULL; } @@ -82,6 +82,10 @@ void* taosArrayPushBatch(SArray* pArray, const void* pData, int nEles) { return dst; } +void* taosArrayAddAll(SArray* pArray, const SArray* pInput) { + return taosArrayAddBatch(pArray, pInput->pData, (int32_t) taosArrayGetSize(pInput)); +} + void* taosArrayPop(SArray* pArray) { assert( pArray != NULL ); diff --git a/src/util/src/tcache.c b/src/util/src/tcache.c index 57d45cc8c00dab5b760f8e915b967e37217f9b64..569f9b01bda6d3a8cf5de6ba4b089e7bab49ca9f 100644 --- a/src/util/src/tcache.c +++ b/src/util/src/tcache.c @@ -613,7 +613,7 @@ void doCleanupDataCache(SCacheObj *pCacheObj) { // todo memory leak if there are object with refcount greater than 0 in hash table? taosHashCleanup(pCacheObj->pHashTable); - taosTrashcanEmpty(pCacheObj, true); + taosTrashcanEmpty(pCacheObj, false); __cache_lock_destroy(pCacheObj); diff --git a/src/util/src/tcrc32c.c b/src/util/src/tcrc32c.c index 4009973a9f1edff03fda114d7998030c35f550f1..d2b63eb9ee7dd9a3119866bcf2d61b893192b14b 100644 --- a/src/util/src/tcrc32c.c +++ b/src/util/src/tcrc32c.c @@ -18,7 +18,7 @@ 3. This notice may not be removed or altered from any source distribution. */ -#ifndef _TD_ARM_ +#if !defined(_TD_ARM_) && !defined(_TD_MIPS_) #include #endif diff --git a/src/util/src/tdes.c b/src/util/src/tdes.c index 6e003756a36581cafa41f610dd95dd045f274f60..f72ddcaa3bb1c63e06310f574dcaa765ed112046 100644 --- a/src/util/src/tdes.c +++ b/src/util/src/tdes.c @@ -155,26 +155,26 @@ void generate_key(unsigned char* key) { } } -void print_key_set(key_set key_set) { +void print_key_set(key_set _key_set) { int i; printf("K: \n"); for (i = 0; i < 8; i++) { - printf("%02X : ", key_set.k[i]); - print_char_as_binary(key_set.k[i]); + printf("%02X : ", _key_set.k[i]); + print_char_as_binary(_key_set.k[i]); printf("\n"); } printf("\nC: \n"); for (i = 0; i < 4; i++) { - printf("%02X : ", key_set.c[i]); - print_char_as_binary(key_set.c[i]); + printf("%02X : ", _key_set.c[i]); + print_char_as_binary(_key_set.c[i]); printf("\n"); } printf("\nD: \n"); for (i = 0; i < 4; i++) { - printf("%02X : ", key_set.d[i]); - print_char_as_binary(key_set.d[i]); + printf("%02X : ", _key_set.d[i]); + print_char_as_binary(_key_set.d[i]); printf("\n"); } printf("\n"); diff --git a/src/util/src/terror.c b/src/util/src/terror.c index bc5c51313745721fd44878ec0de0f38ed8131a8f..887b231ec6161ee99e5c64330595345a01ab34c0 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -83,7 +83,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_REF_ALREADY_EXIST, "Ref is already there" TAOS_DEFINE_ERROR(TSDB_CODE_REF_NOT_EXIST, "Ref is not there") //client -TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_SQL, "Invalid SQL statement") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_OPERATION, "Invalid operation") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_QHANDLE, "Invalid qhandle") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TIME_STAMP, "Invalid combination of client/service time") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_VALUE, "Invalid value in client") @@ -227,6 +227,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_BALANCING, "Database is balancing TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_SYNCED, "Database suspended") TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, "Database write operation denied") TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_SYNCING, "Database is syncing") +TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_TSDB_STATE, "Invalid tsdb state") // tsdb TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INVALID_TABLE_ID, "Invalid table ID") @@ -250,6 +251,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TDB_TABLE_RECONFIGURE, "Need to reconfigure t TAOS_DEFINE_ERROR(TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO, "Invalid information to create table") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_AVAIL_DISK, "No available disk") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_MESSED_MSG, "TSDB messed message") +TAOS_DEFINE_ERROR(TSDB_CODE_TDB_IVLD_TAG_VAL, "TSDB invalid tag value") // query TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_QHANDLE, "Invalid handle") diff --git a/src/util/src/tskiplist.c b/src/util/src/tskiplist.c index e3798162e8e949d65c6c6382574a43d94a474ee6..842ded19a652fdfad7cb6b35c536f760ae866618 100644 --- a/src/util/src/tskiplist.c +++ b/src/util/src/tskiplist.c @@ -50,6 +50,7 @@ SSkipList *tSkipListCreate(uint8_t maxLevel, uint8_t keyType, uint16_t keyLen, _ pSkipList->len = keyLen; pSkipList->flags = flags; pSkipList->keyFn = fn; + pSkipList->seed = rand(); if (comparFn == NULL) { pSkipList->comparFn = getKeyComparFunc(keyType); } else { @@ -545,7 +546,12 @@ static FORCE_INLINE int32_t getSkipListNodeRandomHeight(SSkipList *pSkipList) { const uint32_t factor = 4; int32_t n = 1; + +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) while ((rand() % factor) == 0 && n <= pSkipList->maxLevel) { +#else + while ((rand_r(&(pSkipList->seed)) % factor) == 0 && n <= pSkipList->maxLevel) { +#endif n++; } diff --git a/src/query/src/qTokenizer.c b/src/util/src/ttokenizer.c similarity index 94% rename from src/query/src/qTokenizer.c rename to src/util/src/ttokenizer.c index 7029cbfc3c5de6c60465c3455133e54ed8ee3e46..e9bbda1f9bbdfb79874d9bae8937a9241e02bfcb 100644 --- a/src/query/src/qTokenizer.c +++ b/src/util/src/ttokenizer.c @@ -18,7 +18,7 @@ #include "hash.h" #include "hashfunc.h" #include "taosdef.h" -#include "tstoken.h" +#include "ttoken.h" #include "ttokendef.h" #include "tutil.h" @@ -248,7 +248,7 @@ static void doInitKeywordsTable(void) { static pthread_once_t keywordsHashTableInit = PTHREAD_ONCE_INIT; -int tSQLKeywordCode(const char* z, int n) { +static int32_t tKeywordCode(const char* z, int n) { pthread_once(&keywordsHashTableInit, doInitKeywordsTable); char key[512] = {0}; @@ -272,7 +272,7 @@ int tSQLKeywordCode(const char* z, int n) { * Return the length of the token that begins at z[0]. * Store the token type in *type before returning. */ -uint32_t tSQLGetToken(char* z, uint32_t* tokenId) { +uint32_t tGetToken(char* z, uint32_t* tokenId) { uint32_t i; switch (*z) { case ' ': @@ -404,12 +404,12 @@ uint32_t tSQLGetToken(char* z, uint32_t* tokenId) { int delim = z[0]; bool strEnd = false; for (i = 1; z[i]; i++) { - if (z[i] == '\\') { + if (z[i] == '\\') { // ignore the escaped character that follows this backslash i++; continue; } - if (z[i] == delim ) { + if (z[i] == delim) { if (z[i + 1] == delim) { i++; } else { @@ -552,7 +552,7 @@ uint32_t tSQLGetToken(char* z, uint32_t* tokenId) { } for (i = 1; ((z[i] & 0x80) == 0) && isIdChar[(uint8_t) z[i]]; i++) { } - *tokenId = tSQLKeywordCode(z, i); + *tokenId = tKeywordCode(z, i); return i; } } @@ -561,6 +561,27 @@ uint32_t tSQLGetToken(char* z, uint32_t* tokenId) { return 0; } +SStrToken tscReplaceStrToken(char **str, SStrToken *token, const char* newToken) { + char *src = *str; + size_t nsize = strlen(newToken); + int32_t size = (int32_t)strlen(*str) - token->n + (int32_t)nsize + 1; + int32_t bsize = (int32_t)((uint64_t)token->z - (uint64_t)src); + SStrToken ntoken; + + *str = calloc(1, size); + + strncpy(*str, src, bsize); + strcat(*str, newToken); + strcat(*str, token->z + token->n); + + ntoken.n = (uint32_t)nsize; + ntoken.z = *str + bsize; + + tfree(src); + + return ntoken; +} + SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) { SStrToken t0 = {0}; @@ -585,7 +606,7 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) { t = str[++(*i)]; } - t0.n = tSQLGetToken(&str[*i], &t0.type); + t0.n = tGetToken(&str[*i], &t0.type); break; // not support user specfied ignored symbol list @@ -614,7 +635,7 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) { // support parse the 'db.tbl' format, notes: There should be no space on either side of the dot! if ('.' == str[*i + t0.n]) { - len = tSQLGetToken(&str[*i + t0.n + 1], &type); + len = tGetToken(&str[*i + t0.n + 1], &type); // only id and string are valid if ((TK_STRING != t0.type) && (TK_ID != t0.type)) { @@ -629,7 +650,7 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) { } else { // support parse the -/+number format if ((isPrevOptr) && (t0.type == TK_MINUS || t0.type == TK_PLUS)) { - len = tSQLGetToken(&str[*i + t0.n], &type); + len = tGetToken(&str[*i + t0.n], &type); if (type == TK_INTEGER || type == TK_FLOAT) { t0.type = type; t0.n += len; @@ -643,7 +664,9 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) { return t0; } -bool isKeyWord(const char* z, int32_t len) { return (tSQLKeywordCode((char*)z, len) != TK_ID); } +bool taosIsKeyWordToken(const char* z, int32_t len) { + return (tKeywordCode((char*)z, len) != TK_ID); +} void taosCleanupKeywordsTable() { void* m = keywordHashTable; diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c index 0921c5ce48d3cd525bb4d741585de10425e10b76..fdf215a966582254978daf5997234efa9d2cfb8b 100644 --- a/src/vnode/src/vnodeMain.c +++ b/src/vnode/src/vnodeMain.c @@ -120,12 +120,14 @@ int32_t vnodeDrop(int32_t vgId) { vDebug("vgId:%d, failed to drop, vnode not find", vgId); return TSDB_CODE_VND_INVALID_VGROUP_ID; } + if (pVnode->dropped) { + vnodeRelease(pVnode); + return TSDB_CODE_SUCCESS; + } vInfo("vgId:%d, vnode will be dropped, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode); pVnode->dropped = 1; - // remove from hash, so new messages wont be consumed - vnodeRemoveFromHash(pVnode); vnodeRelease(pVnode); vnodeCleanupInMWorker(pVnode); @@ -170,29 +172,31 @@ static int32_t vnodeAlterImp(SVnodeObj *pVnode, SCreateVnodeMsg *pVnodeCfg) { vDebug("vgId:%d, tsdbchanged:%d syncchanged:%d while alter vnode", pVnode->vgId, tsdbCfgChanged, syncCfgChanged); - if (/*tsdbCfgChanged || */syncCfgChanged) { + if (tsdbCfgChanged || syncCfgChanged) { // vnode in non-ready state and still needs to return success instead of TSDB_CODE_VND_INVALID_STATUS // dbCfgVersion can be corrected by status msg - if (!vnodeSetUpdatingStatus(pVnode)) { - vDebug("vgId:%d, vnode is not ready, do alter operation later", pVnode->vgId); - pVnode->dbCfgVersion = dbCfgVersion; - pVnode->vgCfgVersion = vgCfgVersion; - pVnode->syncCfg = syncCfg; - pVnode->tsdbCfg = tsdbCfg; - return TSDB_CODE_SUCCESS; - } + if (syncCfgChanged) { + if (!vnodeSetUpdatingStatus(pVnode)) { + vDebug("vgId:%d, vnode is not ready, do alter operation later", pVnode->vgId); + pVnode->dbCfgVersion = dbCfgVersion; + pVnode->vgCfgVersion = vgCfgVersion; + pVnode->syncCfg = syncCfg; + pVnode->tsdbCfg = tsdbCfg; + return TSDB_CODE_SUCCESS; + } - code = syncReconfig(pVnode->sync, &pVnode->syncCfg); - if (code != TSDB_CODE_SUCCESS) { - pVnode->dbCfgVersion = dbCfgVersion; - pVnode->vgCfgVersion = vgCfgVersion; - pVnode->syncCfg = syncCfg; - pVnode->tsdbCfg = tsdbCfg; - vnodeSetReadyStatus(pVnode); - return code; + code = syncReconfig(pVnode->sync, &pVnode->syncCfg); + if (code != TSDB_CODE_SUCCESS) { + pVnode->dbCfgVersion = dbCfgVersion; + pVnode->vgCfgVersion = vgCfgVersion; + pVnode->syncCfg = syncCfg; + pVnode->tsdbCfg = tsdbCfg; + vnodeSetReadyStatus(pVnode); + return code; + } } - if (pVnode->tsdb) { + if (tsdbCfgChanged && pVnode->tsdb) { code = tsdbConfigRepo(pVnode->tsdb, &pVnode->tsdbCfg); if (code != TSDB_CODE_SUCCESS) { pVnode->dbCfgVersion = dbCfgVersion; @@ -329,11 +333,11 @@ int32_t vnodeOpen(int32_t vgId) { vnodeCleanUp(pVnode); return terrno; } else if (tsdbGetState(pVnode->tsdb) != TSDB_STATE_OK) { - vError("vgId:%d, failed to open tsdb, replica:%d reason:%s", pVnode->vgId, pVnode->syncCfg.replica, - tstrerror(terrno)); + vError("vgId:%d, failed to open tsdb(state: %d), replica:%d reason:%s", pVnode->vgId, + tsdbGetState(pVnode->tsdb), pVnode->syncCfg.replica, tstrerror(terrno)); if (pVnode->syncCfg.replica <= 1) { vnodeCleanUp(pVnode); - return terrno; + return TSDB_CODE_VND_INVALID_TSDB_STATE; } else { pVnode->fversion = 0; pVnode->version = 0; @@ -423,6 +427,10 @@ int32_t vnodeOpen(int32_t vgId) { int32_t vnodeClose(int32_t vgId) { SVnodeObj *pVnode = vnodeAcquire(vgId); if (pVnode == NULL) return 0; + if (pVnode->dropped) { + vnodeRelease(pVnode); + return 0; + } vDebug("vgId:%d, vnode will be closed, pVnode:%p", pVnode->vgId, pVnode); vnodeRemoveFromHash(pVnode); @@ -446,7 +454,11 @@ void vnodeDestroy(SVnodeObj *pVnode) { } if (pVnode->tsdb) { - code = tsdbCloseRepo(pVnode->tsdb, 1); + // the deleted vnode does not need to commit, so as to speed up the deletion + int toCommit = 1; + if (pVnode->dropped) toCommit = 0; + + code = tsdbCloseRepo(pVnode->tsdb, toCommit); pVnode->tsdb = NULL; } @@ -508,6 +520,8 @@ void vnodeCleanUp(SVnodeObj *pVnode) { vnodeSetClosingStatus(pVnode); + vnodeRemoveFromHash(pVnode); + // stop replication module if (pVnode->sync > 0) { int64_t sync = pVnode->sync; diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index b28bdbf130aaef8b3e3ffc8cda0653e46d0efc29..3964975e355db3ced1c86e28611ef202dd24d9e3 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -117,14 +117,17 @@ static SVReadMsg *vnodeBuildVReadMsg(SVnodeObj *pVnode, void *pCont, int32_t con } int32_t vnodeWriteToRQueue(void *vparam, void *pCont, int32_t contLen, int8_t qtype, void *rparam) { + SVnodeObj *pVnode = vparam; + if (pVnode->dropped) { + return TSDB_CODE_APP_NOT_READY; + } + SVReadMsg *pRead = vnodeBuildVReadMsg(vparam, pCont, contLen, qtype, rparam); if (pRead == NULL) { assert(terrno != 0); return terrno; } - SVnodeObj *pVnode = vparam; - int32_t code = vnodeCheckRead(pVnode); if (code != TSDB_CODE_SUCCESS) { taosFreeQitem(pRead); @@ -354,7 +357,7 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { // kill current query and free corresponding resources. if (pRetrieve->free == 1) { - vWarn("vgId:%d, QInfo:%"PRIu64 "-%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, pRetrieve->qId, *handle); + vWarn("vgId:%d, QInfo:%"PRIx64 "-%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, pRetrieve->qId, *handle); qKillQuery(*handle); qReleaseQInfo(pVnode->qMgmt, (void **)&handle, true); diff --git a/src/vnode/src/vnodeStatus.c b/src/vnode/src/vnodeStatus.c index c482d1fd1a44497b2ba3ff8482d4d1f66bb11ff5..1eaddc3d25fef5d8753ef1f645413326360fa101 100644 --- a/src/vnode/src/vnodeStatus.c +++ b/src/vnode/src/vnodeStatus.c @@ -66,6 +66,9 @@ static bool vnodeSetClosingStatusImp(SVnodeObj* pVnode) { } bool vnodeSetClosingStatus(SVnodeObj* pVnode) { + if (pVnode->status == TAOS_VN_STATUS_CLOSING) + return true; + while (!vnodeSetClosingStatusImp(pVnode)) { taosMsleep(1); } diff --git a/src/vnode/src/vnodeSync.c b/src/vnode/src/vnodeSync.c index aa4cf0fc15bd9db749888699baf90a97bfbeb39f..4197428fec6b5d24e7791b2a5f8cb7df229cbca5 100644 --- a/src/vnode/src/vnodeSync.c +++ b/src/vnode/src/vnodeSync.c @@ -55,6 +55,11 @@ void vnodeNotifyRole(int32_t vgId, int8_t role) { vTrace("vgId:%d, vnode not found while notify role", vgId); return; } + if (pVnode->dropped) { + vTrace("vgId:%d, vnode dropped while notify role", vgId); + vnodeRelease(pVnode); + return; + } vInfo("vgId:%d, sync role changed from %s to %s", pVnode->vgId, syncRole[pVnode->role], syncRole[role]); pVnode->role = role; @@ -75,6 +80,11 @@ void vnodeCtrlFlow(int32_t vgId, int32_t level) { vTrace("vgId:%d, vnode not found while flow ctrl", vgId); return; } + if (pVnode->dropped) { + vTrace("vgId:%d, vnode dropped while flow ctrl", vgId); + vnodeRelease(pVnode); + return; + } if (pVnode->flowctrlLevel != level) { vDebug("vgId:%d, set flowctrl level from %d to %d", pVnode->vgId, pVnode->flowctrlLevel, level); @@ -116,10 +126,14 @@ void vnodeStopSyncFile(int32_t vgId, uint64_t fversion) { } void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code) { - void *pVnode = vnodeAcquire(vgId); + SVnodeObj *pVnode = vnodeAcquire(vgId); if (pVnode == NULL) { vError("vgId:%d, vnode not found while confirm forward", vgId); - return; + } + + if (code == TSDB_CODE_SYN_CONFIRM_EXPIRED && pVnode->status == TAOS_VN_STATUS_CLOSING) { + vDebug("vgId:%d, db:%s, vnode is closing while confirm forward", vgId, pVnode->db); + code = TSDB_CODE_VND_IS_CLOSING; } dnodeSendRpcVWriteRsp(pVnode, wparam, code); @@ -130,6 +144,7 @@ int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rpara SVnodeObj *pVnode = vnodeAcquire(vgId); if (pVnode == NULL) { vError("vgId:%d, vnode not found while write to cache", vgId); + vnodeRelease(pVnode); return TSDB_CODE_VND_INVALID_VGROUP_ID; } @@ -162,4 +177,4 @@ int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver) { void vnodeConfirmForward(void *vparam, uint64_t version, int32_t code, bool force) { SVnodeObj *pVnode = vparam; syncConfirmForward(pVnode->sync, version, code, force); -} \ No newline at end of file +} diff --git a/src/vnode/src/vnodeWrite.c b/src/vnode/src/vnodeWrite.c index def9cf3b32121206f270fdbe9c131ddad668a7e5..16089c8e91bdab66af664a9b6c8b7fc0a5dabf04 100644 --- a/src/vnode/src/vnodeWrite.c +++ b/src/vnode/src/vnodeWrite.c @@ -317,12 +317,13 @@ int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rpar void vnodeFreeFromWQueue(void *vparam, SVWriteMsg *pWrite) { SVnodeObj *pVnode = vparam; + if (pVnode) { + int32_t queued = atomic_sub_fetch_32(&pVnode->queuedWMsg, 1); + int64_t queuedSize = atomic_sub_fetch_64(&pVnode->queuedWMsgSize, pWrite->pHead.len); - int32_t queued = atomic_sub_fetch_32(&pVnode->queuedWMsg, 1); - int64_t queuedSize = atomic_sub_fetch_64(&pVnode->queuedWMsgSize, pWrite->pHead.len); - - vTrace("vgId:%d, msg:%p, app:%p, free from vwqueue, queued:%d size:%" PRId64, pVnode->vgId, pWrite, - pWrite->rpcMsg.ahandle, queued, queuedSize); + vTrace("vgId:%d, msg:%p, app:%p, free from vwqueue, queued:%d size:%" PRId64, pVnode->vgId, pWrite, + pWrite->rpcMsg.ahandle, queued, queuedSize); + } taosFreeQitem(pWrite); vnodeRelease(pVnode); @@ -339,8 +340,11 @@ static void vnodeFlowCtrlMsgToWQueue(void *param, void *tmrId) { if (pWrite->processedCount >= 100) { vError("vgId:%d, msg:%p, failed to process since %s, retry:%d", pVnode->vgId, pWrite, tstrerror(code), pWrite->processedCount); - pWrite->processedCount = 1; - dnodeSendRpcVWriteRsp(pWrite->pVnode, pWrite, code); + void *handle = pWrite->rpcMsg.handle; + taosFreeQitem(pWrite); + vnodeRelease(pVnode); + SRpcMsg rpcRsp = {.handle = handle, .code = code}; + rpcSendResponse(&rpcRsp); } else { code = vnodePerformFlowCtrl(pWrite); if (code == 0) { @@ -371,8 +375,8 @@ static int32_t vnodePerformFlowCtrl(SVWriteMsg *pWrite) { taosMsleep(ms); return 0; } else { - void *unUsed = NULL; - taosTmrReset(vnodeFlowCtrlMsgToWQueue, 100, pWrite, tsDnodeTmr, &unUsed); + void *unUsedTimerId = NULL; + taosTmrReset(vnodeFlowCtrlMsgToWQueue, 100, pWrite, tsDnodeTmr, &unUsedTimerId); vTrace("vgId:%d, msg:%p, app:%p, perform flowctrl, retry:%d", pVnode->vgId, pWrite, pWrite->rpcMsg.ahandle, pWrite->processedCount); @@ -385,4 +389,6 @@ void vnodeWaitWriteCompleted(SVnodeObj *pVnode) { vTrace("vgId:%d, queued wmsg num:%d", pVnode->vgId, pVnode->queuedWMsg); taosMsleep(10); } + + taosMsleep(900); } diff --git a/src/wal/src/walWrite.c b/src/wal/src/walWrite.c index 4368ddd7d35c444c0b6e32fb5897801bba6e615d..b884546a08674fef7c2c42f104c5200e0d5efff8 100644 --- a/src/wal/src/walWrite.c +++ b/src/wal/src/walWrite.c @@ -199,7 +199,7 @@ int32_t walRestore(void *handle, void *pVnode, FWalWrite writeFp) { snprintf(walName, sizeof(pWal->name), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, fileId); wInfo("vgId:%d, file:%s, will be restored", pWal->vgId, walName); - int32_t code = walRestoreWalFile(pWal, pVnode, writeFp, walName, fileId); + code = walRestoreWalFile(pWal, pVnode, writeFp, walName, fileId); if (code != TSDB_CODE_SUCCESS) { wError("vgId:%d, file:%s, failed to restore since %s", pWal->vgId, walName, tstrerror(code)); continue; @@ -426,10 +426,12 @@ static int32_t walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp, ch #endif offset = offset + sizeof(SWalHead) + pHead->len; - wTrace("vgId:%d, restore wal, fileId:%" PRId64 " hver:%" PRIu64 " wver:%" PRIu64 " len:%d", pWal->vgId, - fileId, pHead->version, pWal->version, pHead->len); + wTrace("vgId:%d, restore wal, fileId:%" PRId64 " hver:%" PRIu64 " wver:%" PRIu64 " len:%d offset:%" PRId64, + pWal->vgId, fileId, pHead->version, pWal->version, pHead->len, offset); pWal->version = pHead->version; + + //wInfo("writeFp: %ld", offset); (*writeFp)(pVnode, pHead, TAOS_QTYPE_WAL, NULL); } diff --git a/tests/How-To-Run-Test-And-How-To-Add-New-Test-Case.md b/tests/How-To-Run-Test-And-How-To-Add-New-Test-Case.md index b476c118a79a3845b88652ca229e08463077bfbe..6845d091b5f300bac0656078492467dc3db67830 100644 --- a/tests/How-To-Run-Test-And-How-To-Add-New-Test-Case.md +++ b/tests/How-To-Run-Test-And-How-To-Add-New-Test-Case.md @@ -8,8 +8,8 @@ 3. mkdir debug; cd debug; cmake ..; make ; sudo make install -4. pip install ../src/connector/python/linux/python2 ; pip3 install - ../src/connector/python/linux/python3 +4. pip install ../src/connector/python ; pip3 install + ../src/connector/python 5. pip install numpy; pip3 install numpy (numpy is required only if you need to run querySort.py) diff --git a/tests/Jenkinsfile b/tests/Jenkinsfile index 93db09ad6ce0e6888c64a4c334930b93e4f1f450..2f2b9f693312b296451fea436ceb1d25a1bb81c7 100644 --- a/tests/Jenkinsfile +++ b/tests/Jenkinsfile @@ -21,7 +21,7 @@ def pre_test(){ cmake .. > /dev/null make > /dev/null make install > /dev/null - pip3 install ${WKC}/src/connector/python/linux/python3/ + pip3 install ${WKC}/src/connector/python ''' return 1 } @@ -37,7 +37,7 @@ pipeline { stage('Parallel test stage') { parallel { stage('pytest') { - agent{label '184'} + agent{label 'slad1'} steps { pre_test() sh ''' @@ -62,7 +62,7 @@ pipeline { } stage('test_crash_gen') { - agent{label "185"} + agent{label "slad2"} steps { pre_test() sh ''' @@ -149,7 +149,7 @@ pipeline { } stage('test_valgrind') { - agent{label "186"} + agent{label "slad3"} steps { pre_test() diff --git a/tests/comparisonTest/tdengine/tdengineTest.c b/tests/comparisonTest/tdengine/tdengineTest.c index 1298aa8323b0f876e3c64ff88323031b8d529648..d1cf3a1f98d7fa600cbaf9bcadad42428a799234 100644 --- a/tests/comparisonTest/tdengine/tdengineTest.c +++ b/tests/comparisonTest/tdengine/tdengineTest.c @@ -189,8 +189,8 @@ void writeDataImp(void *param) { counter++; if (counter >= arguments.rowsPerRequest) { - TAOS_RES *result = taos_query(taos, sql); - int32_t code = taos_errno(result); + result = taos_query(taos, sql); + code = taos_errno(result); if (code != 0) { printf("thread:%d error:%d reason:%s\n", pThread->threadId, code, taos_errstr(taos)); } @@ -207,8 +207,8 @@ void writeDataImp(void *param) { } if (counter > 0) { - TAOS_RES *result = taos_query(taos, sql); - int32_t code = taos_errno(result); + result = taos_query(taos, sql); + code = taos_errno(result); if (code != 0) { printf("thread:%d error:%d reason:%s\n", pThread->threadId, code, taos_errstr(taos)); } diff --git a/tests/examples/c/CMakeLists.txt b/tests/examples/c/CMakeLists.txt index 954fe468b1b8fc88ce93fa2474e2f69a33415e6f..7f941b8c87a2c256a82aa37f9e937a41cd9a4c77 100644 --- a/tests/examples/c/CMakeLists.txt +++ b/tests/examples/c/CMakeLists.txt @@ -5,6 +5,8 @@ IF (TD_LINUX) AUX_SOURCE_DIRECTORY(. SRC) ADD_EXECUTABLE(demo apitest.c) TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread ) + ADD_EXECUTABLE(subscribe subscribe.c) + TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread ) ADD_EXECUTABLE(epoll epoll.c) TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread ) ENDIF () diff --git a/tests/examples/c/apitest.c b/tests/examples/c/apitest.c index f20c0321c455da9c430aa3a4eb1d32af7d71da8b..0ca92eaf1d018bc8b370706752cf0d139a9bfaf8 100644 --- a/tests/examples/c/apitest.c +++ b/tests/examples/c/apitest.c @@ -7,7 +7,6 @@ #include #include - static void prepare_data(TAOS* taos) { TAOS_RES *result; result = taos_query(taos, "drop database if exists test;"); @@ -69,7 +68,6 @@ static void prepare_data(TAOS* taos) { usleep(1000000); } - static int print_result(TAOS_RES* res, int blockFetch) { TAOS_ROW row = NULL; int num_fields = taos_num_fields(res); @@ -99,7 +97,6 @@ static int print_result(TAOS_RES* res, int blockFetch) { return nRows; } - static void check_row_count(int line, TAOS_RES* res, int expected) { int actual = print_result(res, expected % 2); if (actual != expected) { @@ -109,7 +106,6 @@ static void check_row_count(int line, TAOS_RES* res, int expected) { } } - static void verify_query(TAOS* taos) { prepare_data(taos); @@ -153,7 +149,6 @@ static void verify_query(TAOS* taos) { taos_free_result(res); } - void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) { int rows = print_result(res, *(int*)param); printf("%d rows consumed in subscribe_callback\n", rows); @@ -235,10 +230,10 @@ static void verify_subscribe(TAOS* taos) { taos_unsubscribe(tsub, 0); } - void verify_prepare(TAOS* taos) { TAOS_RES* result = taos_query(taos, "drop database if exists test;"); taos_free_result(result); + usleep(100000); result = taos_query(taos, "create database test;"); @@ -248,6 +243,7 @@ void verify_prepare(TAOS* taos) { taos_free_result(result); return; } + taos_free_result(result); usleep(100000); @@ -369,6 +365,7 @@ void verify_prepare(TAOS* taos) { taos_stmt_add_batch(stmt); } if (taos_stmt_execute(stmt) != 0) { + taos_stmt_close(stmt); printf("\033[31mfailed to execute insert statement.\033[0m\n"); return; } @@ -381,6 +378,7 @@ void verify_prepare(TAOS* taos) { v.v2 = 15; taos_stmt_bind_param(stmt, params + 2); if (taos_stmt_execute(stmt) != 0) { + taos_stmt_close(stmt); printf("\033[31mfailed to execute select statement.\033[0m\n"); return; } diff --git a/tests/examples/c/makefile b/tests/examples/c/makefile index b06fe551dbde4b16e3ea197ca4c2bc1711ef63bb..304623c27af27cd23a301af134647fb3b9746d64 100644 --- a/tests/examples/c/makefile +++ b/tests/examples/c/makefile @@ -22,6 +22,7 @@ clean: rm $(ROOT)asyncdemo rm $(ROOT)demo rm $(ROOT)prepare + rm $(ROOT)batchprepare rm $(ROOT)stream rm $(ROOT)subscribe rm $(ROOT)apitest diff --git a/tests/fuzz/sql-fuzzer.c b/tests/fuzz/sql-fuzzer.c new file mode 100644 index 0000000000000000000000000000000000000000..3eb0eed2e76bfb41c26b7456a94b3d91148034ba --- /dev/null +++ b/tests/fuzz/sql-fuzzer.c @@ -0,0 +1,15 @@ +#include "qSqlparser.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size){ + char *new_str = (char *)malloc(size+1); + if (new_str == NULL){ + return 0; + } + memcpy(new_str, data, size); + new_str[size] = '\0'; + + qSqlParse(new_str); + + free(new_str); + return 0; +} diff --git a/tests/mas/Jenkinsfile b/tests/mas/Jenkinsfile new file mode 100644 index 0000000000000000000000000000000000000000..b2a1a5e1167844e777909cc9688186d85b90a707 --- /dev/null +++ b/tests/mas/Jenkinsfile @@ -0,0 +1,309 @@ +def pre_test(){ + + sh ''' + sudo rmtaos||echo 'no taosd installed' + ''' + sh ''' + cd ${WKC} + git reset --hard + git checkout $BRANCH_NAME + git pull + git submodule update + cd ${WK} + git reset --hard + git checkout $BRANCH_NAME + git pull + export TZ=Asia/Harbin + date + rm -rf ${WK}/debug + mkdir debug + cd debug + cmake .. > /dev/null + make > /dev/null + make install > /dev/null + pip3 install ${WKC}/src/connector/python/linux/python3/ + ''' + return 1 +} +pipeline { + agent none + environment{ + + WK = '/var/lib/jenkins/workspace/TDinternal' + WKC= '/var/lib/jenkins/workspace/TDinternal/community' + } + + stages { + stage('Parallel test stage') { + parallel { + stage('pytest') { + agent{label 'slam1'} + steps { + pre_test() + sh ''' + cd ${WKC}/tests + find pytest -name '*'sql|xargs rm -rf + ./test-all.sh pytest + date''' + } + } + stage('test_b1') { + agent{label 'slam2'} + steps { + pre_test() + + sh ''' + cd ${WKC}/tests + ./test-all.sh b1 + date''' + + + } + } + + stage('test_crash_gen') { + agent{label "slam3"} + steps { + pre_test() + sh ''' + cd ${WKC}/tests/pytest + ''' + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${WKC}/tests/pytest + ./crash_gen.sh -a -p -t 4 -s 2000 + ''' + } + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${WKC}/tests/pytest + rm -rf /var/lib/taos/* + rm -rf /var/log/taos/* + ./handle_crash_gen_val_log.sh + ''' + } + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${WKC}/tests/pytest + rm -rf /var/lib/taos/* + rm -rf /var/log/taos/* + ./handle_taosd_val_log.sh + ''' + } + + sh''' + systemctl start taosd + sleep 10 + ''' + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${WKC}/tests/gotest + bash batchtest.sh + ''' + } + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${WKC}/tests/examples/python/PYTHONConnectorChecker + python3 PythonChecker.py + ''' + } + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${WKC}/tests/examples/JDBC/JDBCDemo/ + mvn clean package assembly:single -DskipTests >/dev/null + java -jar target/JDBCDemo-SNAPSHOT-jar-with-dependencies.jar -host 127.0.0.1 + ''' + } + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${WKC}/src/connector/jdbc + mvn clean package -Dmaven.test.skip=true >/dev/null + cd ${WKC}/tests/examples/JDBC/JDBCDemo/ + java --class-path=../../../../src/connector/jdbc/target:$JAVA_HOME/jre/lib/ext -jar target/JDBCDemo-SNAPSHOT-jar-with-dependencies.jar -host 127.0.0.1 + ''' + } + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cp -rf ${WKC}/tests/examples/nodejs ${JENKINS_HOME}/workspace/ + cd ${JENKINS_HOME}/workspace/nodejs + node nodejsChecker.js host=localhost + ''' + } + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${JENKINS_HOME}/workspace/C#NET/src/CheckC# + dotnet run + ''' + } + sh ''' + systemctl stop taosd + cd ${WKC}/tests + ./test-all.sh b2 + date + ''' + sh ''' + cd ${WKC}/tests + ./test-all.sh full unit + date''' + } + } + + stage('test_valgrind') { + agent{label "slam4"} + + steps { + pre_test() + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${WKC}/tests/pytest + nohup taosd >/dev/null & + sleep 10 + python3 concurrent_inquiry.py -c 1 + + ''' + } + sh ''' + cd ${WKC}/tests + ./test-all.sh full jdbc + date''' + sh ''' + cd ${WKC}/tests/pytest + ./valgrind-test.sh 2>&1 > mem-error-out.log + ./handle_val_log.sh + + date + cd ${WKC}/tests + ./test-all.sh b3 + date''' + sh ''' + date + cd ${WKC}/tests + ./test-all.sh full example + date''' + } + } + + stage('arm64_build'){ + agent{label 'arm64'} + steps{ + sh ''' + cd ${WK} + git fetch + git checkout develop + git pull + cd ${WKC} + git fetch + git checkout develop + git pull + git submodule update + cd ${WKC}/packaging + ./release.sh -v cluster -c aarch64 -n 2.0.0.0 -m 2.0.0.0 + + ''' + } + } + stage('arm32_build'){ + agent{label 'arm32'} + steps{ + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + sh ''' + cd ${WK} + git fetch + git checkout develop + git pull + cd ${WKC} + git fetch + git checkout develop + git pull + git submodule update + cd ${WKC}/packaging + ./release.sh -v cluster -c aarch32 -n 2.0.0.0 -m 2.0.0.0 + + ''' + } + + } + } + } + } + + } + post { + success { + emailext ( + subject: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", + body: ''' + + + + + + + + + + + + +

+ 构建信息 +
+
    +
    +
  • 构建名称>>分支:${PROJECT_NAME}
  • +
  • 构建结果: Successful
  • +
  • 构建编号:${BUILD_NUMBER}
  • +
  • 触发用户:${CAUSE}
  • +
  • 变更概要:${CHANGES}
  • +
  • 构建地址:${BUILD_URL}
  • +
  • 构建日志:${BUILD_URL}console
  • +
  • 变更集:${JELLY_SCRIPT}
  • +
    +
+
+ + ''', + to: "yqliu@taosdata.com,pxiao@taosdata.com", + from: "support@taosdata.com" + ) + } + failure { + emailext ( + subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", + body: ''' + + + + + + + + + + + + +

+ 构建信息 +
+
    +
    +
  • 构建名称>>分支:${PROJECT_NAME}
  • +
  • 构建结果: Successful
  • +
  • 构建编号:${BUILD_NUMBER}
  • +
  • 触发用户:${CAUSE}
  • +
  • 变更概要:${CHANGES}
  • +
  • 构建地址:${BUILD_URL}
  • +
  • 构建日志:${BUILD_URL}console
  • +
  • 变更集:${JELLY_SCRIPT}
  • +
    +
+
+ + ''', + to: "yqliu@taosdata.com,pxiao@taosdata.com", + from: "support@taosdata.com" + ) + } + } +} \ No newline at end of file diff --git a/tests/perftest-scripts/perftest-query.sh b/tests/perftest-scripts/perftest-query.sh index 9a160846838c76a4bc1f9f6f0b2d08a0f62fc1da..bf62f401bffa1cd4d3189d551d02c8a3e227be4b 100755 --- a/tests/perftest-scripts/perftest-query.sh +++ b/tests/perftest-scripts/perftest-query.sh @@ -64,18 +64,25 @@ function runQueryPerfTest { [ -f $PERFORMANCE_TEST_REPORT ] && rm $PERFORMANCE_TEST_REPORT nohup $WORK_DIR/TDengine/debug/build/bin/taosd -c /etc/taosperf/ > /dev/null 2>&1 & echoInfo "Wait TDengine to start" - sleep 300 + sleep 60 echoInfo "Run Performance Test" cd $WORK_DIR/TDengine/tests/pytest python3 query/queryPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT + mkdir -p /var/lib/perf/ + mkdir -p /var/log/perf/ + rm -rf /var/lib/perf/* + rm -rf /var/log/perf/* + nohup $WORK_DIR/TDengine/debug/build/bin/taosd -c /etc/perf/ > /dev/null 2>&1 & + echoInfo "Wait TDengine to start" + sleep 10 + echoInfo "Run Performance Test" + cd $WORK_DIR/TDengine/tests/pytest + python3 insert/insertFromCSVPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT - - python3 perfbenchmark/joinPerformance.py | tee -a $PERFORMANCE_TEST_REPORT - } diff --git a/tests/pytest/cluster/clusterEnvSetup/basic.py b/tests/pytest/cluster/clusterEnvSetup/basic.py deleted file mode 100644 index dc7e07fd5cea3473270afa6cb2ddbfba6c2402e4..0000000000000000000000000000000000000000 --- a/tests/pytest/cluster/clusterEnvSetup/basic.py +++ /dev/null @@ -1,119 +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 os -import taos -import random -import argparse - -class BuildDockerCluser: - - def __init__(self, hostName, user, password, configDir, numOfNodes, clusterVersion, dockerDir, removeFlag): - self.hostName = hostName - self.user = user - self.password = password - self.configDir = configDir - self.numOfNodes = numOfNodes - self.clusterVersion = clusterVersion - self.dockerDir = dockerDir - self.removeFlag = removeFlag - - def getConnection(self): - self.conn = taos.connect( - host = self.hostName, - user = self.user, - password = self.password, - config = self.configDir) - - def createDondes(self): - self.cursor = self.conn.cursor() - for i in range(2, self.numOfNodes + 1): - self.cursor.execute("create dnode tdnode%d" % i) - - def startArbitrator(self): - print("start arbitrator") - os.system("docker exec -d $(docker ps|grep tdnode1|awk '{print $1}') tarbitrator") - - def run(self): - if self.numOfNodes < 2 or self.numOfNodes > 10: - print("the number of nodes must be between 2 and 10") - exit(0) - print("remove Flag value %s" % self.removeFlag) - if self.removeFlag == False: - os.system("./cleanClusterEnv.sh -d %s" % self.dockerDir) - os.system("./buildClusterEnv.sh -n %d -v %s -d %s" % (self.numOfNodes, self.clusterVersion, self.dockerDir)) - self.getConnection() - self.createDondes() - self.startArbitrator() - -parser = argparse.ArgumentParser() -parser.add_argument( - '-H', - '--host', - action='store', - default='tdnode1', - type=str, - help='host name to be connected (default: tdnode1)') -parser.add_argument( - '-u', - '--user', - action='store', - default='root', - type=str, - help='user (default: root)') -parser.add_argument( - '-p', - '--password', - action='store', - default='taosdata', - type=str, - help='password (default: taosdata)') -parser.add_argument( - '-c', - '--config-dir', - action='store', - default='/etc/taos', - type=str, - help='configuration directory (default: /etc/taos)') -parser.add_argument( - '-n', - '--num-of-nodes', - action='store', - default=2, - type=int, - help='number of nodes in the cluster (default: 2, min: 2, max: 5)') -parser.add_argument( - '-v', - '--version', - action='store', - default='2.0.18.1', - type=str, - help='the version of the cluster to be build, Default is 2.0.17.1') -parser.add_argument( - '-d', - '--docker-dir', - action='store', - default='/data', - type=str, - help='the data dir for docker, default is /data') -parser.add_argument( - '--flag', - action='store_true', - help='remove docker containers flag, default: True') - -args = parser.parse_args() -cluster = BuildDockerCluser(args.host, args.user, args.password, args.config_dir, args.num_of_nodes, args.version, args.docker_dir, args.flag) -cluster.run() - -# usage 1: python3 basic.py -n 2 --flag (flag is True) -# usage 2: python3 basic.py -n 2 (flag should be False when it is not specified) \ No newline at end of file diff --git a/tests/pytest/cluster/clusterEnvSetup/cleanClusterEnv.sh b/tests/pytest/cluster/clusterEnvSetup/cleanClusterEnv.sh deleted file mode 100755 index 675cae5fef850947c2c53899ef1863dc00b55422..0000000000000000000000000000000000000000 --- a/tests/pytest/cluster/clusterEnvSetup/cleanClusterEnv.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -echo "Executing cleanClusterEnv.sh" -CURR_DIR=`pwd` - -if [ $# != 2 ]; then - echo "argument list need input : " - echo " -d docker dir" - exit 1 -fi - -DOCKER_DIR= -while getopts "d:" arg -do - case $arg in - d) - DOCKER_DIR=$OPTARG - ;; - ?) - echo "unkonwn argument" - ;; - esac -done - -function removeDockerContainers { - cd $DOCKER_DIR - docker-compose down --remove-orphans -} - -function cleanEnv { - echo "Clean up docker environment" - for i in {1..10} - do - rm -rf $DOCKER_DIR/node$i/data/* - rm -rf $DOCKER_DIR/node$i/log/* - done -} - -removeDockerContainers -cleanEnv \ No newline at end of file diff --git a/tests/pytest/cluster/clusterEnvSetup/node4.yml b/tests/pytest/cluster/clusterEnvSetup/node4.yml deleted file mode 100644 index f542c22c4537dd6dc2c529dff39ba93c5c0ec3a4..0000000000000000000000000000000000000000 --- a/tests/pytest/cluster/clusterEnvSetup/node4.yml +++ /dev/null @@ -1,62 +0,0 @@ -version: '3.7' - -services: - td2.0-node4: - build: - context: . - args: - - PACKAGE=${PACKAGE} - - TARBITRATORPKG=${TARBITRATORPKG} - - EXTRACTDIR=${DIR} - - EXTRACTDIR2=${DIR2} - - DATADIR=${DATADIR} - image: 'tdengine:${VERSION}' - container_name: 'tdnode4' - cap_add: - - ALL - stdin_open: true - tty: true - environment: - TZ: "Asia/Shanghai" - command: > - sh -c "ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && - echo $TZ > /etc/timezone && - mkdir /coredump && - echo 'kernel.core_pattern=/coredump/core_%e_%p' >> /etc/sysctl.conf && - sysctl -p && - exec my-main-application" - extra_hosts: - - "tdnode2:172.27.0.8" - - "tdnode3:172.27.0.9" - - "tdnode4:172.27.0.10" - - "tdnode5:172.27.0.11" - - "tdnode6:172.27.0.12" - - "tdnode7:172.27.0.13" - - "tdnode8:172.27.0.14" - - "tdnode9:172.27.0.15" - - "tdnode10:172.27.0.16" - volumes: - # bind data directory - - type: bind - source: ${DATADIR}/node4/data - target: /var/lib/taos - # bind log directory - - type: bind - source: ${DATADIR}/node4/log - target: /var/log/taos - # bind configuration - - type: bind - source: ${DATADIR}/node4/cfg - target: /etc/taos - # bind core dump path - - type: bind - source: ${DATADIR}/node4/core - target: /coredump - - type: bind - source: ${DATADIR} - target: /root - hostname: tdnode4 - networks: - taos_update_net: - ipv4_address: 172.27.0.10 - command: taosd \ No newline at end of file diff --git a/tests/pytest/cluster/clusterEnvSetup/node5.yml b/tests/pytest/cluster/clusterEnvSetup/node5.yml deleted file mode 100644 index dd5941ac769273031c98bca3248adcf633240088..0000000000000000000000000000000000000000 --- a/tests/pytest/cluster/clusterEnvSetup/node5.yml +++ /dev/null @@ -1,62 +0,0 @@ -version: '3.7' - -services: - td2.0-node5: - build: - context: . - args: - - PACKAGE=${PACKAGE} - - TARBITRATORPKG=${TARBITRATORPKG} - - EXTRACTDIR=${DIR} - - EXTRACTDIR2=${DIR2} - - DATADIR=${DATADIR} - image: 'tdengine:${VERSION}' - container_name: 'tdnode5' - cap_add: - - ALL - stdin_open: true - tty: true - environment: - TZ: "Asia/Shanghai" - command: > - sh -c "ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && - echo $TZ > /etc/timezone && - mkdir /coredump && - echo 'kernel.core_pattern=/coredump/core_%e_%p' >> /etc/sysctl.conf && - sysctl -p && - exec my-main-application" - extra_hosts: - - "tdnode2:172.27.0.8" - - "tdnode3:172.27.0.9" - - "tdnode4:172.27.0.10" - - "tdnode5:172.27.0.11" - - "tdnode6:172.27.0.12" - - "tdnode7:172.27.0.13" - - "tdnode8:172.27.0.14" - - "tdnode9:172.27.0.15" - - "tdnode10:172.27.0.16" - volumes: - # bind data directory - - type: bind - source: ${DATADIR}/node5/data - target: /var/lib/taos - # bind log directory - - type: bind - source: ${DATADIR}/node5/log - target: /var/log/taos - # bind configuration - - type: bind - source: ${DATADIR}/node5/cfg - target: /etc/taos - # bind core dump path - - type: bind - source: ${DATADIR}/node5/core - target: /coredump - - type: bind - source: ${DATADIR} - target: /root - hostname: tdnode5 - networks: - taos_update_net: - ipv4_address: 172.27.0.11 - command: taosd \ No newline at end of file diff --git a/tests/pytest/concurrent_inquiry.sh b/tests/pytest/concurrent_inquiry.sh index e5918792f462c3a215e33d513dfb5a1fb9ded7f5..6ac15fb46fd727ca56b1aef7e7137ef822e5244a 100755 --- a/tests/pytest/concurrent_inquiry.sh +++ b/tests/pytest/concurrent_inquiry.sh @@ -48,7 +48,7 @@ fi PYTHON_EXEC=python3.8 # First we need to set up a path for Python to find our own TAOS modules, so that "import" can work. -export PYTHONPATH=$(pwd)/../../src/connector/python/linux/python3:$(pwd) +export PYTHONPATH=$(pwd)/../../src/connector/python:$(pwd) # Then let us set up the library path so that our compiled SO file can be loaded by Python export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIB_DIR diff --git a/tests/pytest/crash_gen.sh b/tests/pytest/crash_gen.sh index 0af09634df5a5c418797ae4bd352c319fcbc74fa..127e13c5be1ea562cbe536bbb05f6ecd5844b0ea 100755 --- a/tests/pytest/crash_gen.sh +++ b/tests/pytest/crash_gen.sh @@ -48,7 +48,7 @@ fi PYTHON_EXEC=python3.8 # First we need to set up a path for Python to find our own TAOS modules, so that "import" can work. -export PYTHONPATH=$(pwd)/../../src/connector/python/linux/python3:$(pwd) +export PYTHONPATH=$(pwd)/../../src/connector/python:$(pwd) # Then let us set up the library path so that our compiled SO file can be loaded by Python export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIB_DIR diff --git a/tests/pytest/crash_gen/__init__.py b/tests/pytest/crash_gen/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fe03bde35473600b27359b81aace21277224fac1 --- /dev/null +++ b/tests/pytest/crash_gen/__init__.py @@ -0,0 +1,2 @@ +# Helpful Ref: https://stackoverflow.com/questions/24100558/how-can-i-split-a-module-into-multiple-files-without-breaking-a-backwards-compa/24100645 +from crash_gen.service_manager import ServiceManager, TdeInstance, TdeSubProcess diff --git a/tests/pytest/crash_gen/crash_gen_main.py b/tests/pytest/crash_gen/crash_gen_main.py index 44295e8bee72bd4af398569887da69ab06234be5..644aa799164acd4b44224ebd9ed30e39e722371c 100755 --- a/tests/pytest/crash_gen/crash_gen_main.py +++ b/tests/pytest/crash_gen/crash_gen_main.py @@ -1,6 +1,6 @@ # -----!/usr/bin/python3.7 ################################################################### -# Copyright (c) 2016 by TAOS Technologies, Inc. +# Copyright (c) 2016-2021 by TAOS Technologies, Inc. # All rights reserved. # # This file is proprietary and confidential to TAOS Technologies. @@ -15,7 +15,7 @@ # https://stackoverflow.com/questions/33533148/how-do-i-specify-that-the-return-type-of-a-method-is-the-same-as-the-class-itsel from __future__ import annotations -from typing import Set +from typing import Any, Set, Tuple from typing import Dict from typing import List from typing import Optional # Type hinting, ref: https://stackoverflow.com/questions/19202633/python-3-type-hinting-for-none @@ -24,29 +24,34 @@ import textwrap import time import datetime import random -import logging import threading -import copy import argparse -import getopt import sys import os +import io import signal import traceback -import resource +import requests # from guppy import hpy import gc +import taos -from crash_gen.service_manager import ServiceManager, TdeInstance -from crash_gen.misc import Logging, Status, CrashGenError, Dice, Helper, Progress -from crash_gen.db import DbConn, MyTDSql, DbConnNative, DbManager -import crash_gen.settings +from .shared.types import TdColumns, TdTags -import taos -import requests +# from crash_gen import ServiceManager, TdeInstance, TdeSubProcess +# from crash_gen import ServiceManager, Config, DbConn, DbConnNative, Dice, DbManager, Status, Logging, Helper, \ +# CrashGenError, Progress, MyTDSql, \ +# TdeInstance -crash_gen.settings.init() +from .service_manager import ServiceManager, TdeInstance + +from .shared.config import Config +from .shared.db import DbConn, DbManager, DbConnNative, MyTDSql +from .shared.misc import Dice, Logging, Helper, Status, CrashGenError, Progress +from .shared.types import TdDataType + +# Config.init() # Require Python 3 if sys.version_info[0] < 3: @@ -56,8 +61,8 @@ if sys.version_info[0] < 3: # Command-line/Environment Configurations, will set a bit later # ConfigNameSpace = argparse.Namespace -gConfig: argparse.Namespace -gSvcMgr: ServiceManager # TODO: refactor this hack, use dep injection +# gConfig: argparse.Namespace +gSvcMgr: Optional[ServiceManager] # TODO: refactor this hack, use dep injection # logger: logging.Logger gContainer: Container @@ -80,20 +85,20 @@ class WorkerThread: self._stepGate = threading.Event() # Let us have a DB connection of our own - if (gConfig.per_thread_db_connection): # type: ignore + if (Config.getConfig().per_thread_db_connection): # type: ignore # print("connector_type = {}".format(gConfig.connector_type)) tInst = gContainer.defTdeInstance - if gConfig.connector_type == 'native': + if Config.getConfig().connector_type == 'native': self._dbConn = DbConn.createNative(tInst.getDbTarget()) - elif gConfig.connector_type == 'rest': + elif Config.getConfig().connector_type == 'rest': self._dbConn = DbConn.createRest(tInst.getDbTarget()) - elif gConfig.connector_type == 'mixed': + elif Config.getConfig().connector_type == 'mixed': if Dice.throw(2) == 0: # 1/2 chance - self._dbConn = DbConn.createNative() + self._dbConn = DbConn.createNative(tInst.getDbTarget()) else: - self._dbConn = DbConn.createRest() + self._dbConn = DbConn.createRest(tInst.getDbTarget()) else: - raise RuntimeError("Unexpected connector type: {}".format(gConfig.connector_type)) + raise RuntimeError("Unexpected connector type: {}".format(Config.getConfig().connector_type)) # self._dbInUse = False # if "use db" was executed already @@ -122,14 +127,14 @@ class WorkerThread: # self.isSleeping = False Logging.info("Starting to run thread: {}".format(self._tid)) - if (gConfig.per_thread_db_connection): # type: ignore + if (Config.getConfig().per_thread_db_connection): # type: ignore Logging.debug("Worker thread openning database connection") self._dbConn.open() self._doTaskLoop() # clean up - if (gConfig.per_thread_db_connection): # type: ignore + if (Config.getConfig().per_thread_db_connection): # type: ignore if self._dbConn.isOpen: #sometimes it is not open self._dbConn.close() else: @@ -157,7 +162,7 @@ class WorkerThread: # Before we fetch the task and run it, let's ensure we properly "use" the database (not needed any more) try: - if (gConfig.per_thread_db_connection): # most likely TRUE + if (Config.getConfig().per_thread_db_connection): # most likely TRUE if not self._dbConn.isOpen: # might have been closed during server auto-restart self._dbConn.open() # self.useDb() # might encounter exceptions. TODO: catch @@ -231,7 +236,7 @@ class WorkerThread: return self.getDbConn().getQueryResult() def getDbConn(self) -> DbConn : - if (gConfig.per_thread_db_connection): + if (Config.getConfig().per_thread_db_connection): return self._dbConn else: return self._tc.getDbManager().getDbConn() @@ -253,7 +258,7 @@ class ThreadCoordinator: self._pool = pool # self._wd = wd self._te = None # prepare for every new step - self._dbManager = dbManager + self._dbManager = dbManager # type: Optional[DbManager] # may be freed self._executedTasks: List[Task] = [] # in a given step self._lock = threading.RLock() # sync access for a few things @@ -265,9 +270,13 @@ class ThreadCoordinator: self._stepStartTime = None # Track how long it takes to execute each step def getTaskExecutor(self): + if self._te is None: + raise CrashGenError("Unexpected empty TE") return self._te def getDbManager(self) -> DbManager: + if self._dbManager is None: + raise ChildProcessError("Unexpected empty _dbManager") return self._dbManager def crossStepBarrier(self, timeout=None): @@ -278,7 +287,7 @@ class ThreadCoordinator: self._execStats.registerFailure("User Interruption") def _runShouldEnd(self, transitionFailed, hasAbortedTask, workerTimeout): - maxSteps = gConfig.max_steps # type: ignore + maxSteps = Config.getConfig().max_steps # type: ignore if self._curStep >= (maxSteps - 1): # maxStep==10, last curStep should be 9 return True if self._runStatus != Status.STATUS_RUNNING: @@ -383,7 +392,7 @@ class ThreadCoordinator: hasAbortedTask = False workerTimeout = False while not self._runShouldEnd(transitionFailed, hasAbortedTask, workerTimeout): - if not gConfig.debug: # print this only if we are not in debug mode + if not Config.getConfig().debug: # print this only if we are not in debug mode Progress.emit(Progress.STEP_BOUNDARY) # print(".", end="", flush=True) # if (self._curStep % 2) == 0: # print memory usage once every 10 steps @@ -468,7 +477,7 @@ class ThreadCoordinator: self._pool = None self._te = None self._dbManager = None - self._executedTasks = None + self._executedTasks = [] self._lock = None self._stepBarrier = None self._execStats = None @@ -507,18 +516,18 @@ class ThreadCoordinator: ''' Initialize multiple databases, invoked at __ini__() time ''' self._dbs = [] # type: List[Database] dbc = self.getDbManager().getDbConn() - if gConfig.max_dbs == 0: + if Config.getConfig().max_dbs == 0: self._dbs.append(Database(0, dbc)) else: baseDbNumber = int(datetime.datetime.now().timestamp( # Don't use Dice/random, as they are deterministic - )*333) % 888 if gConfig.dynamic_db_table_names else 0 - for i in range(gConfig.max_dbs): + )*333) % 888 if Config.getConfig().dynamic_db_table_names else 0 + for i in range(Config.getConfig().max_dbs): self._dbs.append(Database(baseDbNumber + i, dbc)) def pickDatabase(self): idxDb = 0 - if gConfig.max_dbs != 0 : - idxDb = Dice.throw(gConfig.max_dbs) # 0 to N-1 + if Config.getConfig().max_dbs != 0 : + idxDb = Dice.throw(Config.getConfig().max_dbs) # 0 to N-1 db = self._dbs[idxDb] # type: Database return db @@ -562,7 +571,7 @@ class ThreadPool: workerThread._thread.join() def cleanup(self): - self.threadList = None # maybe clean up each? + self.threadList = [] # maybe clean up each? # A queue of continguous POSITIVE integers, used by DbManager to generate continuous numbers # for new table names @@ -672,7 +681,7 @@ class AnyState: # Each sub state tells us the "info", about itself, so we can determine # on things like canDropDB() - def getInfo(self): + def getInfo(self) -> List[Any]: raise RuntimeError("Must be overriden by child classes") def equals(self, other): @@ -700,7 +709,7 @@ class AnyState: def canDropDb(self): # If user requests to run up to a number of DBs, # we'd then not do drop_db operations any more - if gConfig.max_dbs > 0 or gConfig.use_shadow_db : + if Config.getConfig().max_dbs > 0 or Config.getConfig().use_shadow_db : return False return self._info[self.CAN_DROP_DB] @@ -708,7 +717,7 @@ class AnyState: return self._info[self.CAN_CREATE_FIXED_SUPER_TABLE] def canDropFixedSuperTable(self): - if gConfig.use_shadow_db: # duplicate writes to shaddow DB, in which case let's disable dropping s-table + if Config.getConfig().use_shadow_db: # duplicate writes to shaddow DB, in which case let's disable dropping s-table return False return self._info[self.CAN_DROP_FIXED_SUPER_TABLE] @@ -910,7 +919,7 @@ class StateMechine: # May be slow, use cautionsly... def getTaskTypes(self): # those that can run (directly/indirectly) from the current state - def typesToStrings(types): + def typesToStrings(types) -> List: ss = [] for t in types: ss.append(t.__name__) @@ -1029,13 +1038,14 @@ class StateMechine: # ref: # https://eli.thegreenplace.net/2010/01/22/weighted-random-generation-in-python/ - def _weighted_choice_sub(self, weights): + def _weighted_choice_sub(self, weights) -> int: # TODO: use our dice to ensure it being determinstic? rnd = random.random() * sum(weights) for i, w in enumerate(weights): rnd -= w if rnd < 0: return i + raise CrashGenError("Unexpected no choice") class Database: ''' We use this to represent an actual TDengine database inside a service instance, @@ -1047,8 +1057,8 @@ class Database: ''' _clsLock = threading.Lock() # class wide lock _lastInt = 101 # next one is initial integer - _lastTick = 0 - _lastLaggingTick = 0 # lagging tick, for out-of-sequence (oos) data insertions + _lastTick = None # Optional[datetime] + _lastLaggingTick = None # Optional[datetime] # lagging tick, for out-of-sequence (oos) data insertions def __init__(self, dbNum: int, dbc: DbConn): # TODO: remove dbc self._dbNum = dbNum # we assign a number to databases, for our testing purpose @@ -1104,7 +1114,7 @@ class Database: t3 = datetime.datetime(2012, 1, 1) # default "keep" is 10 years t4 = datetime.datetime.fromtimestamp( t3.timestamp() + elSec2) # see explanation above - Logging.info("Setting up TICKS to start from: {}".format(t4)) + Logging.debug("Setting up TICKS to start from: {}".format(t4)) return t4 @classmethod @@ -1113,14 +1123,14 @@ class Database: Fetch a timestamp tick, with some random factor, may not be unique. ''' with cls._clsLock: # prevent duplicate tick - if cls._lastLaggingTick==0 or cls._lastTick==0 : # not initialized + if cls._lastLaggingTick is None or cls._lastTick is None : # not initialized # 10k at 1/20 chance, should be enough to avoid overlaps tick = cls.setupLastTick() cls._lastTick = tick cls._lastLaggingTick = tick + datetime.timedelta(0, -60*2) # lagging behind 2 minutes, should catch up fast # if : # should be quite a bit into the future - if gConfig.mix_oos_data and Dice.throw(20) == 0: # if asked to do so, and 1 in 20 chance, return lagging tick + if Config.isSet('mix_oos_data') and Dice.throw(20) == 0: # if asked to do so, and 1 in 20 chance, return lagging tick cls._lastLaggingTick += datetime.timedelta(0, 1) # pick the next sequence from the lagging tick sequence return cls._lastLaggingTick else: # regular @@ -1302,10 +1312,10 @@ class Task(): ]: return True # These are the ALWAYS-ACCEPTABLE ones # This case handled below already. - # elif (errno in [ 0x0B ]) and gConfig.auto_start_service: + # elif (errno in [ 0x0B ]) and Settings.getConfig().auto_start_service: # return True # We may get "network unavilable" when restarting service - elif gConfig.ignore_errors: # something is specified on command line - moreErrnos = [int(v, 0) for v in gConfig.ignore_errors.split(',')] + elif Config.getConfig().ignore_errors: # something is specified on command line + moreErrnos = [int(v, 0) for v in Config.getConfig().ignore_errors.split(',')] if errno in moreErrnos: return True elif errno == 0x200 : # invalid SQL, we need to div in a bit more @@ -1341,7 +1351,7 @@ class Task(): self._executeInternal(te, wt) # TODO: no return value? except taos.error.ProgrammingError as err: errno2 = Helper.convertErrno(err.errno) - if (gConfig.continue_on_exception): # user choose to continue + if (Config.getConfig().continue_on_exception): # user choose to continue self.logDebug("[=] Continue after TAOS exception: errno=0x{:X}, msg: {}, SQL: {}".format( errno2, err, wt.getDbConn().getLastSql())) self._err = err @@ -1356,7 +1366,7 @@ class Task(): self.__class__.__name__, errno2, err, wt.getDbConn().getLastSql()) self.logDebug(errMsg) - if gConfig.debug: + if Config.getConfig().debug: # raise # so that we see full stack traceback.print_exc() print( @@ -1370,13 +1380,13 @@ class Task(): self._err = e self._aborted = True traceback.print_exc() - except BaseException as e: + except BaseException as e2: self.logInfo("Python base exception encountered") - self._err = e + # self._err = e2 # Exception/BaseException incompatible! self._aborted = True traceback.print_exc() - except BaseException: # TODO: what is this again??!! - raise RuntimeError("Punt") + # except BaseException: # TODO: what is this again??!! + # raise RuntimeError("Punt") # self.logDebug( # "[=] Unexpected exception, SQL: {}".format( # wt.getDbConn().getLastSql())) @@ -1421,11 +1431,11 @@ class Task(): class ExecutionStats: def __init__(self): # total/success times for a task - self._execTimes: Dict[str, [int, int]] = {} + self._execTimes: Dict[str, List[int]] = {} self._tasksInProgress = 0 self._lock = threading.Lock() - self._firstTaskStartTime = None - self._execStartTime = None + self._firstTaskStartTime = 0.0 + self._execStartTime = 0.0 self._errors = {} self._elapsedTime = 0.0 # total elapsed time self._accRunTime = 0.0 # accumulated run time @@ -1470,7 +1480,7 @@ class ExecutionStats: self._tasksInProgress -= 1 if self._tasksInProgress == 0: # all tasks have stopped self._accRunTime += (time.time() - self._firstTaskStartTime) - self._firstTaskStartTime = None + self._firstTaskStartTime = 0.0 def registerFailure(self, reason): self._failed = True @@ -1554,7 +1564,7 @@ class StateTransitionTask(Task): def getRegTableName(cls, i): if ( StateTransitionTask._baseTableNumber is None): # Set it one time StateTransitionTask._baseTableNumber = Dice.throw( - 999) if gConfig.dynamic_db_table_names else 0 + 999) if Config.getConfig().dynamic_db_table_names else 0 return "reg_table_{}".format(StateTransitionTask._baseTableNumber + i) def execute(self, wt: WorkerThread): @@ -1574,14 +1584,14 @@ class TaskCreateDb(StateTransitionTask): def _executeInternal(self, te: TaskExecutor, wt: WorkerThread): # was: self.execWtSql(wt, "create database db") repStr = "" - if gConfig.num_replicas != 1: - # numReplica = Dice.throw(gConfig.max_replicas) + 1 # 1,2 ... N - numReplica = gConfig.num_replicas # fixed, always + if Config.getConfig().num_replicas != 1: + # numReplica = Dice.throw(Settings.getConfig().max_replicas) + 1 # 1,2 ... N + numReplica = Config.getConfig().num_replicas # fixed, always repStr = "replica {}".format(numReplica) - updatePostfix = "update 1" if gConfig.verify_data else "" # allow update only when "verify data" is active + updatePostfix = "update 1" if Config.getConfig().verify_data else "" # allow update only when "verify data" is active dbName = self._db.getName() self.execWtSql(wt, "create database {} {} {} ".format(dbName, repStr, updatePostfix ) ) - if dbName == "db_0" and gConfig.use_shadow_db: + if dbName == "db_0" and Config.getConfig().use_shadow_db: self.execWtSql(wt, "create database {} {} {} ".format("db_s", repStr, updatePostfix ) ) class TaskDropDb(StateTransitionTask): @@ -1614,10 +1624,11 @@ class TaskCreateSuperTable(StateTransitionTask): sTable = self._db.getFixedSuperTable() # type: TdSuperTable # wt.execSql("use db") # should always be in place - sTable.create(wt.getDbConn(), - {'ts':'TIMESTAMP', 'speed':'INT', 'color':'BINARY(16)'}, {'b':'BINARY(200)', 'f':'FLOAT'}, - dropIfExists = True - ) + sTable.create(wt.getDbConn(), + {'ts': TdDataType.TIMESTAMP, 'speed': TdDataType.INT, 'color': TdDataType.BINARY16}, { + 'b': TdDataType.BINARY200, 'f': TdDataType.FLOAT}, + dropIfExists=True + ) # self.execWtSql(wt,"create table db.{} (ts timestamp, speed int) tags (b binary(200), f float) ".format(tblName)) # No need to create the regular tables, INSERT will do that # automatically @@ -1645,9 +1656,7 @@ class TdSuperTable: return dbc.existsSuperTable(self._stName) # TODO: odd semantic, create() method is usually static? - def create(self, dbc, cols: dict, tags: dict, - dropIfExists = False - ): + def create(self, dbc, cols: TdColumns, tags: TdTags, dropIfExists = False): '''Creating a super table''' dbName = self._dbName @@ -1658,17 +1667,17 @@ class TdSuperTable: dbc.execute("DROP TABLE {}".format(fullTableName)) else: # error raise CrashGenError("Cannot create super table, already exists: {}".format(self._stName)) - + # Now let's create sql = "CREATE TABLE {} ({})".format( fullTableName, - ",".join(['%s %s'%(k,v) for (k,v) in cols.items()])) - if tags is None : - sql += " TAGS (dummy int) " - else: + ",".join(['%s %s'%(k,v.value) for (k,v) in cols.items()])) + if tags : sql += " TAGS ({})".format( - ",".join(['%s %s'%(k,v) for (k,v) in tags.items()]) - ) + ",".join(['%s %s'%(k,v.value) for (k,v) in tags.items()]) + ) + else: + sql += " TAGS (dummy int) " dbc.execute(sql) def getRegTables(self, dbc: DbConn): @@ -1686,7 +1695,7 @@ class TdSuperTable: def hasRegTables(self, dbc: DbConn): return dbc.query("SELECT * FROM {}.{}".format(self._dbName, self._stName)) > 0 - def ensureTable(self, task: Task, dbc: DbConn, regTableName: str): + def ensureRegTable(self, task: Optional[Task], dbc: DbConn, regTableName: str): dbName = self._dbName sql = "select tbname from {}.{} where tbname in ('{}')".format(dbName, self._stName, regTableName) if dbc.query(sql) >= 1 : # reg table exists already @@ -1694,7 +1703,7 @@ class TdSuperTable: # acquire a lock first, so as to be able to *verify*. More details in TD-1471 fullTableName = dbName + '.' + regTableName - if task is not None: # optional lock + if task is not None: # TODO: what happens if we don't lock the table task.lockTable(fullTableName) Progress.emit(Progress.CREATE_TABLE_ATTEMPT) # ATTEMPT to create a new table # print("(" + fullTableName[-3:] + ")", end="", flush=True) @@ -1886,7 +1895,7 @@ class TaskDropSuperTable(StateTransitionTask): if Dice.throw(2) == 0: # print("_7_", end="", flush=True) tblSeq = list(range( - 2 + (self.LARGE_NUMBER_OF_TABLES if gConfig.larger_data else self.SMALL_NUMBER_OF_TABLES))) + 2 + (self.LARGE_NUMBER_OF_TABLES if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_TABLES))) random.shuffle(tblSeq) tickOutput = False # if we have spitted out a "d" character for "drop regular table" isSuccess = True @@ -1952,13 +1961,13 @@ class TaskRestartService(StateTransitionTask): @classmethod def canBeginFrom(cls, state: AnyState): - if gConfig.auto_start_service: + if Config.getConfig().auto_start_service: return state.canDropFixedSuperTable() # Basicallly when we have the super table return False # don't run this otherwise CHANCE_TO_RESTART_SERVICE = 200 def _executeInternal(self, te: TaskExecutor, wt: WorkerThread): - if not gConfig.auto_start_service: # only execute when we are in -a mode + if not Config.getConfig().auto_start_service: # only execute when we are in -a mode print("_a", end="", flush=True) return @@ -1980,12 +1989,12 @@ class TaskAddData(StateTransitionTask): activeTable: Set[int] = set() # We use these two files to record operations to DB, useful for power-off tests - fAddLogReady = None # type: TextIOWrapper - fAddLogDone = None # type: TextIOWrapper + fAddLogReady = None # type: Optional[io.TextIOWrapper] + fAddLogDone = None # type: Optional[io.TextIOWrapper] @classmethod def prepToRecordOps(cls): - if gConfig.record_ops: + if Config.getConfig().record_ops: if (cls.fAddLogReady is None): Logging.info( "Recording in a file operations to be performed...") @@ -2003,7 +2012,7 @@ class TaskAddData(StateTransitionTask): return state.canAddData() def _addDataInBatch(self, db, dbc, regTableName, te: TaskExecutor): - numRecords = self.LARGE_NUMBER_OF_RECORDS if gConfig.larger_data else self.SMALL_NUMBER_OF_RECORDS + numRecords = self.LARGE_NUMBER_OF_RECORDS if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_RECORDS fullTableName = db.getName() + '.' + regTableName sql = "INSERT INTO {} VALUES ".format(fullTableName) @@ -2015,21 +2024,23 @@ class TaskAddData(StateTransitionTask): dbc.execute(sql) def _addData(self, db: Database, dbc, regTableName, te: TaskExecutor): # implied: NOT in batches - numRecords = self.LARGE_NUMBER_OF_RECORDS if gConfig.larger_data else self.SMALL_NUMBER_OF_RECORDS + numRecords = self.LARGE_NUMBER_OF_RECORDS if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_RECORDS for j in range(numRecords): # number of records per table nextInt = db.getNextInt() nextTick = db.getNextTick() nextColor = db.getNextColor() - if gConfig.record_ops: + if Config.getConfig().record_ops: self.prepToRecordOps() + if self.fAddLogReady is None: + raise CrashGenError("Unexpected empty fAddLogReady") self.fAddLogReady.write("Ready to write {} to {}\n".format(nextInt, regTableName)) self.fAddLogReady.flush() - os.fsync(self.fAddLogReady) + os.fsync(self.fAddLogReady.fileno()) # TODO: too ugly trying to lock the table reliably, refactor... fullTableName = db.getName() + '.' + regTableName - if gConfig.verify_data: + if Config.getConfig().verify_data: self.lockTable(fullTableName) # print("_w" + str(nextInt % 100), end="", flush=True) # Trace what was written @@ -2042,7 +2053,7 @@ class TaskAddData(StateTransitionTask): dbc.execute(sql) # Quick hack, attach an update statement here. TODO: create an "update" task - if (not gConfig.use_shadow_db) and Dice.throw(5) == 0: # 1 in N chance, plus not using shaddow DB + if (not Config.getConfig().use_shadow_db) and Dice.throw(5) == 0: # 1 in N chance, plus not using shaddow DB nextInt = db.getNextInt() nextColor = db.getNextColor() sql = "INSERt INTO {} VALUES ('{}', {}, '{}');".format( # "INSERt" means "update" here @@ -2053,12 +2064,12 @@ class TaskAddData(StateTransitionTask): dbc.execute(sql) except: # Any exception at all - if gConfig.verify_data: + if Config.getConfig().verify_data: self.unlockTable(fullTableName) raise # Now read it back and verify, we might encounter an error if table is dropped - if gConfig.verify_data: # only if command line asks for it + if Config.getConfig().verify_data: # only if command line asks for it try: readBack = dbc.queryScalar("SELECT speed from {}.{} WHERE ts='{}'". format(db.getName(), regTableName, nextTick)) @@ -2085,17 +2096,19 @@ class TaskAddData(StateTransitionTask): # Successfully wrote the data into the DB, let's record it somehow te.recordDataMark(nextInt) - if gConfig.record_ops: + if Config.getConfig().record_ops: + if self.fAddLogDone is None: + raise CrashGenError("Unexpected empty fAddLogDone") self.fAddLogDone.write("Wrote {} to {}\n".format(nextInt, regTableName)) self.fAddLogDone.flush() - os.fsync(self.fAddLogDone) + os.fsync(self.fAddLogDone.fileno()) def _executeInternal(self, te: TaskExecutor, wt: WorkerThread): # ds = self._dbManager # Quite DANGEROUS here, may result in multi-thread client access db = self._db dbc = wt.getDbConn() - numTables = self.LARGE_NUMBER_OF_TABLES if gConfig.larger_data else self.SMALL_NUMBER_OF_TABLES - numRecords = self.LARGE_NUMBER_OF_RECORDS if gConfig.larger_data else self.SMALL_NUMBER_OF_RECORDS + numTables = self.LARGE_NUMBER_OF_TABLES if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_TABLES + numRecords = self.LARGE_NUMBER_OF_RECORDS if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_RECORDS tblSeq = list(range(numTables )) random.shuffle(tblSeq) # now we have random sequence for i in tblSeq: @@ -2110,7 +2123,7 @@ class TaskAddData(StateTransitionTask): regTableName = self.getRegTableName(i) # "db.reg_table_{}".format(i) fullTableName = dbName + '.' + regTableName # self._lockTable(fullTableName) # "create table" below. Stop it if the table is "locked" - sTable.ensureTable(self, wt.getDbConn(), regTableName) # Ensure the table exists + sTable.ensureRegTable(self, wt.getDbConn(), regTableName) # Ensure the table exists # self._unlockTable(fullTableName) if Dice.throw(1) == 0: # 1 in 2 chance @@ -2125,7 +2138,9 @@ class ThreadStacks: # stack info for all threads def __init__(self): self._allStacks = {} allFrames = sys._current_frames() - for th in threading.enumerate(): + for th in threading.enumerate(): + if th.ident is None: + continue stack = traceback.extract_stack(allFrames[th.ident]) self._allStacks[th.native_id] = stack @@ -2246,14 +2261,15 @@ class ClientManager: def run(self, svcMgr): # self._printLastNumbers() - global gConfig + # global gConfig # Prepare Tde Instance global gContainer tInst = gContainer.defTdeInstance = TdeInstance() # "subdir to hold the instance" - dbManager = DbManager(gConfig.connector_type, tInst.getDbTarget()) # Regular function - thPool = ThreadPool(gConfig.num_threads, gConfig.max_steps) + cfg = Config.getConfig() + dbManager = DbManager(cfg.connector_type, tInst.getDbTarget()) # Regular function + thPool = ThreadPool(cfg.num_threads, cfg.max_steps) self.tc = ThreadCoordinator(thPool, dbManager) Logging.info("Starting client instance: {}".format(tInst)) @@ -2266,7 +2282,8 @@ class ClientManager: # Release global variables - gConfig = None + # gConfig = None + Config.clearConfig() gSvcMgr = None logger = None @@ -2297,7 +2314,7 @@ class ClientManager: class MainExec: def __init__(self): self._clientMgr = None - self._svcMgr = None # type: ServiceManager + self._svcMgr = None # type: Optional[ServiceManager] signal.signal(signal.SIGTERM, self.sigIntHandler) signal.signal(signal.SIGINT, self.sigIntHandler) @@ -2317,7 +2334,7 @@ class MainExec: def runClient(self): global gSvcMgr - if gConfig.auto_start_service: + if Config.getConfig().auto_start_service: gSvcMgr = self._svcMgr = ServiceManager(1) # hack alert gSvcMgr.startTaosServices() # we start, don't run @@ -2326,26 +2343,18 @@ class MainExec: try: ret = self._clientMgr.run(self._svcMgr) # stop TAOS service inside except requests.exceptions.ConnectionError as err: - Logging.warning("Failed to open REST connection to DB: {}".format(err.getMessage())) + Logging.warning("Failed to open REST connection to DB: {}".format(err)) # don't raise return ret def runService(self): global gSvcMgr - gSvcMgr = self._svcMgr = ServiceManager(gConfig.num_dnodes) # save it in a global variable TODO: hack alert + gSvcMgr = self._svcMgr = ServiceManager(Config.getConfig().num_dnodes) # save it in a global variable TODO: hack alert gSvcMgr.run() # run to some end state gSvcMgr = self._svcMgr = None - def init(self): # TODO: refactor - global gContainer - gContainer = Container() # micky-mouse DI - - global gSvcMgr # TODO: refactor away - gSvcMgr = None - - # Super cool Python argument library: - # https://docs.python.org/3/library/argparse.html + def _buildCmdLineParser(self): parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=textwrap.dedent('''\ @@ -2466,20 +2475,29 @@ class MainExec: action='store_true', help='Continue execution after encountering unexpected/disallowed errors/exceptions (default: false)') - global gConfig - gConfig = parser.parse_args() - crash_gen.settings.gConfig = gConfig # TODO: fix this hack, consolidate this global var + return parser + + + def init(self): # TODO: refactor + global gContainer + gContainer = Container() # micky-mouse DI + + global gSvcMgr # TODO: refactor away + gSvcMgr = None + + parser = self._buildCmdLineParser() + Config.init(parser) # Sanity check for arguments - if gConfig.use_shadow_db and gConfig.max_dbs>1 : + if Config.getConfig().use_shadow_db and Config.getConfig().max_dbs>1 : raise CrashGenError("Cannot combine use-shadow-db with max-dbs of more than 1") - Logging.clsInit(gConfig) + Logging.clsInit(Config.getConfig().debug) Dice.seed(0) # initial seeding of dice def run(self): - if gConfig.run_tdengine: # run server + if Config.getConfig().run_tdengine: # run server try: self.runService() return 0 # success diff --git a/tests/pytest/crash_gen/service_manager.py b/tests/pytest/crash_gen/service_manager.py index cdbf2db4dab81ab07b51597eb0a2805cc931e34e..1cd65c1dde4e9c2027a82730cf4fc12290048bbe 100644 --- a/tests/pytest/crash_gen/service_manager.py +++ b/tests/pytest/crash_gen/service_manager.py @@ -1,25 +1,33 @@ +from __future__ import annotations + import os import io import sys +from enum import Enum import threading import signal import logging import time -import subprocess - -from typing import IO, List +from subprocess import PIPE, Popen, TimeoutExpired +from typing import BinaryIO, Generator, IO, List, NewType, Optional +import typing try: import psutil except: print("Psutil module needed, please install: sudo pip3 install psutil") sys.exit(-1) - from queue import Queue, Empty -from .misc import Logging, Status, CrashGenError, Dice, Helper, Progress -from .db import DbConn, DbTarget -import crash_gen.settings +from .shared.config import Config +from .shared.db import DbTarget, DbConn +from .shared.misc import Logging, Helper, CrashGenError, Status, Progress, Dice +from .shared.types import DirPath, IpcStream + +# from crash_gen.misc import CrashGenError, Dice, Helper, Logging, Progress, Status +# from crash_gen.db import DbConn, DbTarget +# from crash_gen.settings import Config +# from crash_gen.types import DirPath class TdeInstance(): """ @@ -68,7 +76,10 @@ class TdeInstance(): self._fepPort = fepPort self._tInstNum = tInstNum - self._smThread = ServiceManagerThread() + + # An "Tde Instance" will *contain* a "sub process" object, with will/may use a thread internally + # self._smThread = ServiceManagerThread() + self._subProcess = None # type: Optional[TdeSubProcess] def getDbTarget(self): return DbTarget(self.getCfgDir(), self.getHostAddr(), self._port) @@ -153,25 +164,25 @@ quorum 2 def getExecFile(self): # .../taosd return self._buildDir + "/build/bin/taosd" - def getRunDir(self): # TODO: rename to "root dir" ?! - return self._buildDir + self._subdir + def getRunDir(self) -> DirPath : # TODO: rename to "root dir" ?! + return DirPath(self._buildDir + self._subdir) - def getCfgDir(self): # path, not file - return self.getRunDir() + "/cfg" + def getCfgDir(self) -> DirPath : # path, not file + return DirPath(self.getRunDir() + "/cfg") - def getLogDir(self): - return self.getRunDir() + "/log" + def getLogDir(self) -> DirPath : + return DirPath(self.getRunDir() + "/log") def getHostAddr(self): return "127.0.0.1" def getServiceCmdLine(self): # to start the instance - cmdLine = [] - if crash_gen.settings.gConfig.track_memory_leaks: + if Config.getConfig().track_memory_leaks: Logging.info("Invoking VALGRIND on service...") - cmdLine = ['valgrind', '--leak-check=yes'] - cmdLine += ["exec " + self.getExecFile(), '-c', self.getCfgDir()] # used in subproce.Popen() - return cmdLine + return ['exec /usr/bin/valgrind', '--leak-check=yes', self.getExecFile(), '-c', self.getCfgDir()] + else: + # TODO: move "exec -c" into Popen(), we can both "use shell" and NOT fork so ask to lose kill control + return ["exec " + self.getExecFile(), '-c', self.getCfgDir()] # used in subproce.Popen() def _getDnodes(self, dbc): dbc.query("show dnodes") @@ -196,27 +207,46 @@ quorum 2 dbc.close() def getStatus(self): - return self._smThread.getStatus() + # return self._smThread.getStatus() + if self._subProcess is None: + return Status(Status.STATUS_EMPTY) + return self._subProcess.getStatus() - def getSmThread(self): - return self._smThread + # def getSmThread(self): + # return self._smThread def start(self): - if not self.getStatus().isStopped(): + if self.getStatus().isActive(): raise CrashGenError("Cannot start instance from status: {}".format(self.getStatus())) Logging.info("Starting TDengine instance: {}".format(self)) self.generateCfgFile() # service side generates config file, client does not self.rotateLogs() - self._smThread.start(self.getServiceCmdLine(), self.getLogDir()) # May raise exceptions + # self._smThread.start(self.getServiceCmdLine(), self.getLogDir()) # May raise exceptions + self._subProcess = TdeSubProcess(self.getServiceCmdLine(), self.getLogDir()) def stop(self): - self._smThread.stop() + self._subProcess.stop() + self._subProcess = None def isFirst(self): return self._tInstNum == 0 + def printFirst10Lines(self): + if self._subProcess is None: + Logging.warning("Incorrect TI status for procIpcBatch-10 operation") + return + self._subProcess.procIpcBatch(trimToTarget=10, forceOutput=True) + + def procIpcBatch(self): + if self._subProcess is None: + Logging.warning("Incorrect TI status for procIpcBatch operation") + return + self._subProcess.procIpcBatch() # may enounter EOF and change status to STOPPED + if self._subProcess.getStatus().isStopped(): + self._subProcess.stop() + self._subProcess = None class TdeSubProcess: """ @@ -225,42 +255,52 @@ class TdeSubProcess: It takes a TdeInstance object as its parameter, with the rationale being "a sub process runs an instance". + + We aim to ensure that this object has exactly the same life-cycle as the + underlying sub process. """ # RET_ALREADY_STOPPED = -1 # RET_TIME_OUT = -3 # RET_SUCCESS = -4 - def __init__(self): - self.subProcess = None # type: subprocess.Popen - # if tInst is None: - # raise CrashGenError("Empty instance not allowed in TdeSubProcess") - # self._tInst = tInst # Default create at ServiceManagerThread + def __init__(self, cmdLine: List[str], logDir: DirPath): + # Create the process + managing thread immediately - def __repr__(self): - if self.subProcess is None: - return '[TdeSubProc: Empty]' - return '[TdeSubProc: pid = {}]'.format(self.getPid()) + Logging.info("Attempting to start TAOS sub process...") + self._popen = self._start(cmdLine) # the actual sub process + self._smThread = ServiceManagerThread(self, logDir) # A thread to manage the sub process, mostly to process the IO + Logging.info("Successfully started TAOS process: {}".format(self)) - def getStdOut(self): - return self.subProcess.stdout - def getStdErr(self): - return self.subProcess.stderr - def isRunning(self): - return self.subProcess is not None + def __repr__(self): + # if self.subProcess is None: + # return '[TdeSubProc: Empty]' + return '[TdeSubProc: pid = {}, status = {}]'.format( + self.getPid(), self.getStatus() ) + + def getIpcStdOut(self) -> IpcStream : + if self._popen.universal_newlines : # alias of text_mode + raise CrashGenError("We need binary mode for STDOUT IPC") + # Logging.info("Type of stdout is: {}".format(type(self._popen.stdout))) + return typing.cast(IpcStream, self._popen.stdout) + + def getIpcStdErr(self) -> IpcStream : + if self._popen.universal_newlines : # alias of text_mode + raise CrashGenError("We need binary mode for STDERR IPC") + return typing.cast(IpcStream, self._popen.stderr) + + # Now it's always running, since we matched the life cycle + # def isRunning(self): + # return self.subProcess is not None def getPid(self): - return self.subProcess.pid + return self._popen.pid - def start(self, cmdLine): + def _start(self, cmdLine) -> Popen : ON_POSIX = 'posix' in sys.builtin_module_names - - # Sanity check - if self.subProcess: # already there - raise RuntimeError("Corrupt process state") - + # Prepare environment variables for coverage information # Ref: https://stackoverflow.com/questions/2231227/python-subprocess-popen-with-a-modified-environment myEnv = os.environ.copy() @@ -268,17 +308,13 @@ class TdeSubProcess: # print(myEnv) # print("Starting TDengine with env: ", myEnv.items()) - # print("Starting TDengine via Shell: {}".format(cmdLineStr)) - - useShell = True # Needed to pass environments into it - self.subProcess = subprocess.Popen( - # ' '.join(cmdLine) if useShell else cmdLine, - # shell=useShell, - ' '.join(cmdLine), - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - # bufsize=1, # not supported in binary mode + print("Starting TDengine: {}".format(cmdLine)) + + return Popen( + ' '.join(cmdLine), # ' '.join(cmdLine) if useShell else cmdLine, + shell=True, # Always use shell, since we need to pass ENV vars + stdout=PIPE, + stderr=PIPE, close_fds=ON_POSIX, env=myEnv ) # had text=True, which interferred with reading EOF @@ -288,7 +324,9 @@ class TdeSubProcess: def stop(self): """ - Stop a sub process, DO NOT return anything, process all conditions INSIDE + Stop a sub process, DO NOT return anything, process all conditions INSIDE. + + Calling function should immediately delete/unreference the object Common POSIX signal values (from man -7 signal): SIGHUP 1 @@ -306,29 +344,39 @@ class TdeSubProcess: SIGSEGV 11 SIGUSR2 12 """ - if not self.subProcess: - Logging.error("Sub process already stopped") + # self._popen should always be valid. + + Logging.info("Terminating TDengine service running as the sub process...") + if self.getStatus().isStopped(): + Logging.info("Service already stopped") + return + if self.getStatus().isStopping(): + Logging.info("Service is already being stopped, pid: {}".format(self.getPid())) return - retCode = self.subProcess.poll() # ret -N means killed with signal N, otherwise it's from exit(N) + self.setStatus(Status.STATUS_STOPPING) + + retCode = self._popen.poll() # ret -N means killed with signal N, otherwise it's from exit(N) if retCode: # valid return code, process ended # retCode = -retCode # only if valid Logging.warning("TSP.stop(): process ended itself") - self.subProcess = None + # self.subProcess = None return # process still alive, let's interrupt it - self._stopForSure(self.subProcess, self.STOP_SIGNAL) # success if no exception - self.subProcess = None + self._stopForSure(self._popen, self.STOP_SIGNAL) # success if no exception - # sub process should end, then IPC queue should end, causing IO thread to end + # sub process should end, then IPC queue should end, causing IO thread to end + self._smThread.stop() # stop for sure too + + self.setStatus(Status.STATUS_STOPPED) @classmethod - def _stopForSure(cls, proc: subprocess.Popen, sig: int): + def _stopForSure(cls, proc: Popen, sig: int): ''' Stop a process and all sub processes with a singal, and SIGKILL if necessary ''' - def doKillTdService(proc: subprocess.Popen, sig: int): + def doKillTdService(proc: Popen, sig: int): Logging.info("Killing sub-sub process {} with signal {}".format(proc.pid, sig)) proc.send_signal(sig) try: @@ -340,7 +388,7 @@ class TdeSubProcess: else: Logging.warning("TD service terminated, EXPECTING ret code {}, got {}".format(sig, -retCode)) return True # terminated successfully - except subprocess.TimeoutExpired as err: + except TimeoutExpired as err: Logging.warning("Failed to kill sub-sub process {} with signal {}".format(proc.pid, sig)) return False # failed to terminate @@ -349,22 +397,22 @@ class TdeSubProcess: Logging.info("Killing sub-sub process {} with signal {}".format(child.pid, sig)) child.send_signal(sig) try: - retCode = child.wait(20) - if (- retCode) == signal.SIGSEGV: # Crashed + retCode = child.wait(20) # type: ignore + if (- retCode) == signal.SIGSEGV: # type: ignore # Crashed Logging.warning("Process {} CRASHED, please check CORE file!".format(child.pid)) - elif (- retCode) == sig : + elif (- retCode) == sig : # type: ignore Logging.info("Sub-sub process terminated with expected return code {}".format(sig)) else: - Logging.warning("Process terminated, EXPECTING ret code {}, got {}".format(sig, -retCode)) + Logging.warning("Process terminated, EXPECTING ret code {}, got {}".format(sig, -retCode)) # type: ignore return True # terminated successfully except psutil.TimeoutExpired as err: Logging.warning("Failed to kill sub-sub process {} with signal {}".format(child.pid, sig)) return False # did not terminate - def doKill(proc: subprocess.Popen, sig: int): + def doKill(proc: Popen, sig: int): pid = proc.pid try: - topSubProc = psutil.Process(pid) + topSubProc = psutil.Process(pid) # Now that we are doing "exec -c", should not have children any more for child in topSubProc.children(recursive=True): # or parent.children() for recursive=False Logging.warning("Unexpected child to be killed") doKillChild(child, sig) @@ -389,19 +437,26 @@ class TdeSubProcess: return doKill(proc, sig) def hardKill(proc): - return doKill(proc, signal.SIGKILL) - - + return doKill(proc, signal.SIGKILL) pid = proc.pid Logging.info("Terminate running processes under {}, with SIG #{} and wait...".format(pid, sig)) if softKill(proc, sig): - return# success + return # success if sig != signal.SIGKILL: # really was soft above if hardKill(proc): - return + return raise CrashGenError("Failed to stop process, pid={}".format(pid)) + def getStatus(self): + return self._smThread.getStatus() + + def setStatus(self, status): + self._smThread.setStatus(status) + + def procIpcBatch(self, trimToTarget=0, forceOutput=False): + self._smThread.procIpcBatch(trimToTarget, forceOutput) + class ServiceManager: PAUSE_BETWEEN_IPC_CHECK = 1.2 # seconds between checks on STDOUT of sub process @@ -498,10 +553,10 @@ class ServiceManager: def isActive(self): """ Determine if the service/cluster is active at all, i.e. at least - one thread is not "stopped". + one instance is active """ for ti in self._tInsts: - if not ti.getStatus().isStopped(): + if ti.getStatus().isActive(): return True return False @@ -539,10 +594,10 @@ class ServiceManager: # while self.isRunning() or self.isRestarting() : # for as long as the svc mgr thread is still here status = ti.getStatus() if status.isRunning(): - th = ti.getSmThread() - th.procIpcBatch() # regular processing, + # th = ti.getSmThread() + ti.procIpcBatch() # regular processing, if status.isStopped(): - th.procIpcBatch() # one last time? + ti.procIpcBatch() # one last time? # self._updateThreadStatus() time.sleep(self.PAUSE_BETWEEN_IPC_CHECK) # pause, before next round @@ -572,7 +627,8 @@ class ServiceManager: if not ti.isFirst(): tFirst = self._getFirstInstance() tFirst.createDnode(ti.getDbTarget()) - ti.getSmThread().procIpcBatch(trimToTarget=10, forceOutput=True) # for printing 10 lines + ti.printFirst10Lines() + # ti.getSmThread().procIpcBatch(trimToTarget=10, forceOutput=True) # for printing 10 lines def stopTaosServices(self): with self._lock: @@ -618,21 +674,24 @@ class ServiceManagerThread: """ MAX_QUEUE_SIZE = 10000 - def __init__(self): + def __init__(self, subProc: TdeSubProcess, logDir: str): # Set the sub process - self._tdeSubProcess = None # type: TdeSubProcess + # self._tdeSubProcess = None # type: TdeSubProcess # Arrange the TDengine instance # self._tInstNum = tInstNum # instance serial number in cluster, ZERO based # self._tInst = tInst or TdeInstance() # Need an instance - self._thread = None # The actual thread, # type: threading.Thread - self._thread2 = None # watching stderr + # self._thread = None # type: Optional[threading.Thread] # The actual thread, # type: threading.Thread + # self._thread2 = None # type: Optional[threading.Thread] Thread # watching stderr self._status = Status(Status.STATUS_STOPPED) # The status of the underlying service, actually. + self._start(subProc, logDir) + def __repr__(self): - return "[SvcMgrThread: status={}, subProc={}]".format( - self.getStatus(), self._tdeSubProcess) + raise CrashGenError("SMT status moved to TdeSubProcess") + # return "[SvcMgrThread: status={}, subProc={}]".format( + # self.getStatus(), self._tdeSubProcess) def getStatus(self): ''' @@ -640,42 +699,45 @@ class ServiceManagerThread: ''' return self._status + def setStatus(self, statusVal: int): + self._status.set(statusVal) + # Start the thread (with sub process), and wait for the sub service # to become fully operational - def start(self, cmdLine : str, logDir: str): + def _start(self, subProc :TdeSubProcess, logDir: str): ''' Request the manager thread to start a new sub process, and manage it. :param cmdLine: the command line to invoke :param logDir: the logging directory, to hold stdout/stderr files ''' - if self._thread: - raise RuntimeError("Unexpected _thread") - if self._tdeSubProcess: - raise RuntimeError("TDengine sub process already created/running") + # if self._thread: + # raise RuntimeError("Unexpected _thread") + # if self._tdeSubProcess: + # raise RuntimeError("TDengine sub process already created/running") - Logging.info("Attempting to start TAOS service: {}".format(self)) + # Moved to TdeSubProcess + # Logging.info("Attempting to start TAOS service: {}".format(self)) self._status.set(Status.STATUS_STARTING) - self._tdeSubProcess = TdeSubProcess() - self._tdeSubProcess.start(cmdLine) # TODO: verify process is running + # self._tdeSubProcess = TdeSubProcess.start(cmdLine) # TODO: verify process is running - self._ipcQueue = Queue() + self._ipcQueue = Queue() # type: Queue self._thread = threading.Thread( # First thread captures server OUTPUT target=self.svcOutputReader, - args=(self._tdeSubProcess.getStdOut(), self._ipcQueue, logDir)) + args=(subProc.getIpcStdOut(), self._ipcQueue, logDir)) self._thread.daemon = True # thread dies with the program self._thread.start() time.sleep(0.01) if not self._thread.is_alive(): # What happened? - Logging.info("Failed to started process to monitor STDOUT") + Logging.info("Failed to start process to monitor STDOUT") self.stop() raise CrashGenError("Failed to start thread to monitor STDOUT") Logging.info("Successfully started process to monitor STDOUT") self._thread2 = threading.Thread( # 2nd thread captures server ERRORs target=self.svcErrorReader, - args=(self._tdeSubProcess.getStdErr(), self._ipcQueue, logDir)) + args=(subProc.getIpcStdErr(), self._ipcQueue, logDir)) self._thread2.daemon = True # thread dies with the program self._thread2.start() time.sleep(0.01) @@ -690,14 +752,14 @@ class ServiceManagerThread: Progress.emit(Progress.SERVICE_START_NAP) # print("_zz_", end="", flush=True) if self._status.isRunning(): - Logging.info("[] TDengine service READY to process requests") - Logging.info("[] TAOS service started: {}".format(self)) + Logging.info("[] TDengine service READY to process requests: pid={}".format(subProc.getPid())) + # Logging.info("[] TAOS service started: {}".format(self)) # self._verifyDnode(self._tInst) # query and ensure dnode is ready # Logging.debug("[] TAOS Dnode verified: {}".format(self)) return # now we've started # TODO: handle failure-to-start better? self.procIpcBatch(100, True) # display output before cronking out, trim to last 20 msgs, force output - raise RuntimeError("TDengine service did not start successfully: {}".format(self)) + raise RuntimeError("TDengine service DID NOT achieve READY status: pid={}".format(subProc.getPid())) def _verifyDnode(self, tInst: TdeInstance): dbc = DbConn.createNative(tInst.getDbTarget()) @@ -717,70 +779,45 @@ class ServiceManagerThread: break if not isValid: print("Failed to start dnode, sleep for a while") - time.sleep(600) + time.sleep(10.0) raise RuntimeError("Failed to start Dnode, expected port not found: {}". format(tInst.getPort())) dbc.close() def stop(self): # can be called from both main thread or signal handler - Logging.info("Terminating TDengine service running as the sub process...") - if self.getStatus().isStopped(): - Logging.info("Service already stopped") - return - if self.getStatus().isStopping(): - Logging.info("Service is already being stopped, pid: {}".format(self._tdeSubProcess.getPid())) - return - # Linux will send Control-C generated SIGINT to the TDengine process - # already, ref: + + # Linux will send Control-C generated SIGINT to the TDengine process already, ref: # https://unix.stackexchange.com/questions/176235/fork-and-how-signals-are-delivered-to-processes - if not self._tdeSubProcess: - raise RuntimeError("sub process object missing") - - self._status.set(Status.STATUS_STOPPING) - # retCode = self._tdeSubProcess.stop() - # try: - # retCode = self._tdeSubProcess.stop() - # # print("Attempted to stop sub process, got return code: {}".format(retCode)) - # if retCode == signal.SIGSEGV : # SGV - # Logging.error("[[--ERROR--]]: TDengine service SEGV fault (check core file!)") - # except subprocess.TimeoutExpired as err: - # Logging.info("Time out waiting for TDengine service process to exit") - if not self._tdeSubProcess.stop(): # everything withing - if self._tdeSubProcess.isRunning(): # still running, should now never happen - Logging.error("FAILED to stop sub process, it is still running... pid = {}".format( - self._tdeSubProcess.getPid())) - else: - self._tdeSubProcess = None # not running any more - self.join() # stop the thread, change the status, etc. + + self.join() # stop the thread, status change moved to TdeSubProcess # Check if it's really stopped outputLines = 10 # for last output if self.getStatus().isStopped(): self.procIpcBatch(outputLines) # one last time - Logging.debug("End of TDengine Service Output: {}".format(self)) + Logging.debug("End of TDengine Service Output") Logging.info("----- TDengine Service (managed by SMT) is now terminated -----\n") else: - print("WARNING: SMT did not terminate as expected: {}".format(self)) + print("WARNING: SMT did not terminate as expected") def join(self): # TODO: sanity check - if not self.getStatus().isStopping(): + s = self.getStatus() + if s.isStopping() or s.isStopped(): # we may be stopping ourselves, or have been stopped/killed by others + if self._thread or self._thread2 : + if self._thread: + self._thread.join() + self._thread = None + if self._thread2: # STD ERR thread + self._thread2.join() + self._thread2 = None + else: + Logging.warning("Joining empty thread, doing nothing") + else: raise RuntimeError( "SMT.Join(): Unexpected status: {}".format(self._status)) - if self._thread or self._thread2 : - if self._thread: - self._thread.join() - self._thread = None - if self._thread2: # STD ERR thread - self._thread2.join() - self._thread2 = None - else: - print("Joining empty thread, doing nothing") - - self._status.set(Status.STATUS_STOPPED) - def _trimQueue(self, targetSize): if targetSize <= 0: return # do nothing @@ -799,6 +836,10 @@ class ServiceManagerThread: TD_READY_MSG = "TDengine is initialized successfully" def procIpcBatch(self, trimToTarget=0, forceOutput=False): + ''' + Process a batch of STDOUT/STDERR data, until we read EMPTY from + the queue. + ''' self._trimQueue(trimToTarget) # trim if necessary # Process all the output generated by the underlying sub process, # managed by IO thread @@ -827,35 +868,59 @@ class ServiceManagerThread: print(pBar, end="", flush=True) print('\b\b\b\b', end="", flush=True) - def svcOutputReader(self, out: IO, queue, logDir: str): + BinaryChunk = NewType('BinaryChunk', bytes) # line with binary data, directly from STDOUT, etc. + TextChunk = NewType('TextChunk', str) # properly decoded, suitable for printing, etc. + + @classmethod + def _decodeBinaryChunk(cls, bChunk: bytes) -> Optional[TextChunk] : + try: + tChunk = bChunk.decode("utf-8").rstrip() + return cls.TextChunk(tChunk) + except UnicodeError: + print("\nNon-UTF8 server output: {}\n".format(bChunk.decode('cp437'))) + return None + + def _textChunkGenerator(self, streamIn: IpcStream, logDir: str, logFile: str + ) -> Generator[TextChunk, None, None]: + ''' + Take an input stream with binary data (likely from Popen), produced a generator of decoded + "text chunks". + + Side effect: it also save the original binary data in a log file. + ''' + os.makedirs(logDir, exist_ok=True) + logF = open(os.path.join(logDir, logFile), 'wb') + if logF is None: + Logging.error("Failed to open log file (binary write): {}/{}".format(logDir, logFile)) + return + for bChunk in iter(streamIn.readline, b''): + logF.write(bChunk) # Write to log file immediately + tChunk = self._decodeBinaryChunk(bChunk) # decode + if tChunk is not None: + yield tChunk # TODO: split into actual text lines + + # At the end... + streamIn.close() # Close the incoming stream + logF.close() # Close the log file + + def svcOutputReader(self, ipcStdOut: IpcStream, queue, logDir: str): ''' The infinite routine that processes the STDOUT stream for the sub process being managed. - :param out: the IO stream object used to fetch the data from - :param queue: the queue where we dump the roughly parsed line-by-line data + :param ipcStdOut: the IO stream object used to fetch the data from + :param queue: the queue where we dump the roughly parsed chunk-by-chunk text data :param logDir: where we should dump a verbatim output file ''' - os.makedirs(logDir, exist_ok=True) - logFile = os.path.join(logDir,'stdout.log') - fOut = open(logFile, 'wb') + # Important Reference: https://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python # print("This is the svcOutput Reader...") - # for line in out : - for line in iter(out.readline, b''): - fOut.write(line) - # print("Finished reading a line: {}".format(line)) - # print("Adding item to queue...") - try: - line = line.decode("utf-8").rstrip() - except UnicodeError: - print("\nNon-UTF8 server output: {}\n".format(line)) - - # This might block, and then causing "out" buffer to block - queue.put(line) + # stdOut.readline() # Skip the first output? TODO: remove? + for tChunk in self._textChunkGenerator(ipcStdOut, logDir, 'stdout.log') : + queue.put(tChunk) # tChunk garanteed not to be None self._printProgress("_i") if self._status.isStarting(): # we are starting, let's see if we have started - if line.find(self.TD_READY_MSG) != -1: # found + if tChunk.find(self.TD_READY_MSG) != -1: # found Logging.info("Waiting for the service to become FULLY READY") time.sleep(1.0) # wait for the server to truly start. TODO: remove this Logging.info("Service is now FULLY READY") # TODO: more ID info here? @@ -869,18 +934,17 @@ class ServiceManagerThread: print("_w", end="", flush=True) # queue.put(line) - # meaning sub process must have died - Logging.info("EOF for TDengine STDOUT: {}".format(self)) - out.close() # Close the stream - fOut.close() # Close the output file - - def svcErrorReader(self, err: IO, queue, logDir: str): - os.makedirs(logDir, exist_ok=True) - logFile = os.path.join(logDir,'stderr.log') - fErr = open(logFile, 'wb') - for line in iter(err.readline, b''): - fErr.write(line) - Logging.info("TDengine STDERR: {}".format(line)) - Logging.info("EOF for TDengine STDERR: {}".format(self)) - err.close() - fErr.close() \ No newline at end of file + # stdOut has no more data, meaning sub process must have died + Logging.info("EOF found TDengine STDOUT, marking the process as terminated") + self.setStatus(Status.STATUS_STOPPED) + + def svcErrorReader(self, ipcStdErr: IpcStream, queue, logDir: str): + # os.makedirs(logDir, exist_ok=True) + # logFile = os.path.join(logDir,'stderr.log') + # fErr = open(logFile, 'wb') + # for line in iter(err.readline, b''): + for tChunk in self._textChunkGenerator(ipcStdErr, logDir, 'stderr.log') : + queue.put(tChunk) # tChunk garanteed not to be None + # fErr.write(line) + Logging.info("TDengine STDERR: {}".format(tChunk)) + Logging.info("EOF for TDengine STDERR") diff --git a/tests/pytest/crash_gen/settings.py b/tests/pytest/crash_gen/settings.py deleted file mode 100644 index 3c4c91e6e077c325c53d15918624db783957fc20..0000000000000000000000000000000000000000 --- a/tests/pytest/crash_gen/settings.py +++ /dev/null @@ -1,8 +0,0 @@ -from __future__ import annotations -import argparse - -gConfig: argparse.Namespace - -def init(): - global gConfig - gConfig = [] \ No newline at end of file diff --git a/tests/pytest/crash_gen/shared/config.py b/tests/pytest/crash_gen/shared/config.py new file mode 100644 index 0000000000000000000000000000000000000000..7b9f7c3873a3b5d30cc36384bf7a486454c864cb --- /dev/null +++ b/tests/pytest/crash_gen/shared/config.py @@ -0,0 +1,42 @@ +from __future__ import annotations +import argparse + +from typing import Optional + +from .misc import CrashGenError + +# from crash_gen.misc import CrashGenError + +# gConfig: Optional[argparse.Namespace] + +class Config: + _config = None # type Optional[argparse.Namespace] + + @classmethod + def init(cls, parser: argparse.ArgumentParser): + if cls._config is not None: + raise CrashGenError("Config can only be initialized once") + cls._config = parser.parse_args() + # print(cls._config) + + @classmethod + def setConfig(cls, config: argparse.Namespace): + cls._config = config + + @classmethod + # TODO: check items instead of exposing everything + def getConfig(cls) -> argparse.Namespace: + if cls._config is None: + raise CrashGenError("invalid state") + return cls._config + + @classmethod + def clearConfig(cls): + cls._config = None + + @classmethod + def isSet(cls, cfgKey): + cfg = cls.getConfig() + if cfgKey not in cfg: + return False + return cfg.__getattribute__(cfgKey) \ No newline at end of file diff --git a/tests/pytest/crash_gen/db.py b/tests/pytest/crash_gen/shared/db.py similarity index 93% rename from tests/pytest/crash_gen/db.py rename to tests/pytest/crash_gen/shared/db.py index 62a369c41a7ed0d73ab847232a206c2cabb53d53..75931ace48ed65708c7dfa97d01a426a0baa8203 100644 --- a/tests/pytest/crash_gen/db.py +++ b/tests/pytest/crash_gen/shared/db.py @@ -1,24 +1,26 @@ from __future__ import annotations import sys +import os +import datetime import time import threading import requests from requests.auth import HTTPBasicAuth + import taos from util.sql import * from util.cases import * from util.dnodes import * from util.log import * -from .misc import Logging, CrashGenError, Helper, Dice -import os -import datetime import traceback # from .service_manager import TdeInstance -import crash_gen.settings +from .config import Config +from .misc import Logging, CrashGenError, Helper +from .types import QueryResult class DbConn: TYPE_NATIVE = "native-c" @@ -79,7 +81,7 @@ class DbConn: raise RuntimeError("Cannot query database until connection is open") nRows = self.query(sql) if nRows != 1: - raise taos.error.ProgrammingError( + raise CrashGenError( "Unexpected result for query: {}, rows = {}".format(sql, nRows), (CrashGenError.INVALID_EMPTY_RESULT if nRows==0 else CrashGenError.INVALID_MULTIPLE_RESULT) ) @@ -115,7 +117,7 @@ class DbConn: try: self.execute(sql) return True # ignore num of results, return success - except taos.error.ProgrammingError as err: + except taos.error.Error as err: return False # failed, for whatever TAOS reason # Not possile to reach here, non-TAOS exception would have been thrown @@ -126,7 +128,7 @@ class DbConn: def openByType(self): raise RuntimeError("Unexpected execution, should be overriden") - def getQueryResult(self): + def getQueryResult(self) -> QueryResult : raise RuntimeError("Unexpected execution, should be overriden") def getResultRows(self): @@ -221,7 +223,7 @@ class DbConnRest(DbConn): class MyTDSql: # Class variables _clsLock = threading.Lock() # class wide locking - longestQuery = None # type: str + longestQuery = '' # type: str longestQueryTime = 0.0 # seconds lqStartTime = 0.0 # lqEndTime = 0.0 # Not needed, as we have the two above already @@ -249,7 +251,13 @@ class MyTDSql: def _execInternal(self, sql): startTime = time.time() # Logging.debug("Executing SQL: " + sql) + # ret = None # TODO: use strong type here + # try: # Let's not capture the error, and let taos.error.ProgrammingError pass through ret = self._cursor.execute(sql) + # except taos.error.ProgrammingError as err: + # Logging.warning("Taos SQL execution error: {}, SQL: {}".format(err.msg, sql)) + # raise CrashGenError(err.msg) + # print("\nSQL success: {}".format(sql)) queryTime = time.time() - startTime # Record the query time @@ -261,7 +269,7 @@ class MyTDSql: cls.lqStartTime = startTime # Now write to the shadow database - if crash_gen.settings.gConfig.use_shadow_db: + if Config.isSet('use_shadow_db'): if sql[:11] == "INSERT INTO": if sql[:16] == "INSERT INTO db_0": sql2 = "INSERT INTO db_s" + sql[16:] @@ -453,31 +461,11 @@ class DbManager(): ''' Release the underlying DB connection upon deletion of DbManager ''' self.cleanUp() - def getDbConn(self): + def getDbConn(self) -> DbConn : + if self._dbConn is None: + raise CrashGenError("Unexpected empty DbConn") return self._dbConn - # TODO: not used any more, to delete - def pickAndAllocateTable(self): # pick any table, and "use" it - return self.tableNumQueue.pickAndAllocate() - - # TODO: Not used any more, to delete - def addTable(self): - with self._lock: - tIndex = self.tableNumQueue.push() - return tIndex - - # Not used any more, to delete - def releaseTable(self, i): # return the table back, so others can use it - self.tableNumQueue.release(i) - - # TODO: not used any more, delete - def getTableNameToDelete(self): - tblNum = self.tableNumQueue.pop() # TODO: race condition! - if (not tblNum): # maybe false - return False - - return "table_{}".format(tblNum) - def cleanUp(self): if self._dbConn: self._dbConn.close() diff --git a/tests/pytest/crash_gen/misc.py b/tests/pytest/crash_gen/shared/misc.py similarity index 90% rename from tests/pytest/crash_gen/misc.py rename to tests/pytest/crash_gen/shared/misc.py index 9774ec5455961392d82ea2b4b59c0657b5704f9a..90ad802ff1c130439cdc5f5587ecd0607e3e116b 100644 --- a/tests/pytest/crash_gen/misc.py +++ b/tests/pytest/crash_gen/shared/misc.py @@ -3,6 +3,7 @@ import random import logging import os import sys +from typing import Optional import taos @@ -39,14 +40,14 @@ class MyLoggingAdapter(logging.LoggerAdapter): class Logging: - logger = None + logger = None # type: Optional[MyLoggingAdapter] @classmethod def getLogger(cls): - return logger + return cls.logger @classmethod - def clsInit(cls, gConfig): # TODO: refactor away gConfig + def clsInit(cls, debugMode: bool): if cls.logger: return @@ -60,13 +61,9 @@ class Logging: # Logging adapter, to be used as a logger # print("setting logger variable") # global logger - cls.logger = MyLoggingAdapter(_logger, []) - - if (gConfig.debug): - cls.logger.setLevel(logging.DEBUG) # default seems to be INFO - else: - cls.logger.setLevel(logging.INFO) - + cls.logger = MyLoggingAdapter(_logger, {}) + cls.logger.setLevel(logging.DEBUG if debugMode else logging.INFO) # default seems to be INFO + @classmethod def info(cls, msg): cls.logger.info(msg) @@ -84,6 +81,7 @@ class Logging: cls.logger.error(msg) class Status: + STATUS_EMPTY = 99 STATUS_STARTING = 1 STATUS_RUNNING = 2 STATUS_STOPPING = 3 @@ -95,12 +93,16 @@ class Status: def __repr__(self): return "[Status: v={}]".format(self._status) - def set(self, status): + def set(self, status: int): self._status = status def get(self): return self._status + def isEmpty(self): + ''' Empty/Undefined ''' + return self._status == Status.STATUS_EMPTY + def isStarting(self): return self._status == Status.STATUS_STARTING @@ -117,6 +119,9 @@ class Status: def isStable(self): return self.isRunning() or self.isStopped() + def isActive(self): + return self.isStarting() or self.isRunning() or self.isStopping() + # Deterministic random number generator class Dice(): seeded = False # static, uninitialized diff --git a/tests/pytest/crash_gen/shared/types.py b/tests/pytest/crash_gen/shared/types.py new file mode 100644 index 0000000000000000000000000000000000000000..42fd2a1617cf729e4f23fc61a685027f738bc4a3 --- /dev/null +++ b/tests/pytest/crash_gen/shared/types.py @@ -0,0 +1,30 @@ +from typing import Any, BinaryIO, List, Dict, NewType +from enum import Enum + +DirPath = NewType('DirPath', str) + +QueryResult = NewType('QueryResult', List[List[Any]]) + +class TdDataType(Enum): + ''' + Use a Python Enum types of represent all the data types in TDengine. + + Ref: https://www.taosdata.com/cn/documentation/taos-sql#data-type + ''' + TIMESTAMP = 'TIMESTAMP' + INT = 'INT' + BIGINT = 'BIGINT' + FLOAT = 'FLOAT' + DOUBLE = 'DOUBLE' + BINARY = 'BINARY' + BINARY16 = 'BINARY(16)' # TODO: get rid of this hack + BINARY200 = 'BINARY(200)' + SMALLINT = 'SMALLINT' + TINYINT = 'TINYINT' + BOOL = 'BOOL' + NCHAR = 'NCHAR' + +TdColumns = Dict[str, TdDataType] +TdTags = Dict[str, TdDataType] + +IpcStream = NewType('IpcStream', BinaryIO) \ No newline at end of file diff --git a/tests/pytest/crash_gen/valgrind_taos.supp b/tests/pytest/crash_gen/valgrind_taos.supp index a00b2d830c2e4a3261fcb6fc9a1769b2b583799f..5f6604ba776b03eb5a00280cdf8ea2e8cde36f99 100644 --- a/tests/pytest/crash_gen/valgrind_taos.supp +++ b/tests/pytest/crash_gen/valgrind_taos.supp @@ -17496,4 +17496,25 @@ obj:/usr/bin/python3.8 obj:/usr/bin/python3.8 fun:PyVectorcall_Call +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:__libc_alloc_buffer_allocate + fun:alloc_buffer_allocate + fun:__resolv_conf_allocate + fun:__resolv_conf_load + fun:__resolv_conf_get_current + fun:__res_vinit + fun:maybe_init + fun:context_get + fun:context_get + fun:__resolv_context_get + fun:gaih_inet.constprop.0 + fun:getaddrinfo + fun:taosGetFqdn + fun:taosCheckGlobalCfg + fun:taos_init_imp } \ No newline at end of file diff --git a/tests/pytest/cluster/clusterEnvSetup/Dockerfile b/tests/pytest/dockerCluster/Dockerfile similarity index 100% rename from tests/pytest/cluster/clusterEnvSetup/Dockerfile rename to tests/pytest/dockerCluster/Dockerfile diff --git a/tests/pytest/dockerCluster/OneMnodeMultipleVnodesTest.py b/tests/pytest/dockerCluster/OneMnodeMultipleVnodesTest.py new file mode 100644 index 0000000000000000000000000000000000000000..ee663f89b0a6dd776c80033f177f63ec843eaa1e --- /dev/null +++ b/tests/pytest/dockerCluster/OneMnodeMultipleVnodesTest.py @@ -0,0 +1,39 @@ +################################################################### +# 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 basic import * +from util.sql import tdSql + + + +class TDTestCase: + + def init(self): + # tdLog.debug("start to execute %s" % __file__) + + self.numOfNodes = 5 + self.dockerDir = "/data" + cluster.init(self.numOfNodes, self.dockerDir) + cluster.prepardBuild() + for i in range(self.numOfNodes): + if i == 0: + cluster.cfg("role", "1", i + 1) + else: + cluster.cfg("role", "2", i + 1) + cluster.run() + +td = TDTestCase() +td.init() + + + diff --git a/tests/pytest/dockerCluster/__init__.py b/tests/pytest/dockerCluster/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/pytest/dockerCluster/basic.py b/tests/pytest/dockerCluster/basic.py new file mode 100644 index 0000000000000000000000000000000000000000..50914b0be9428ab77f479c9a18a099ecbd0a2d51 --- /dev/null +++ b/tests/pytest/dockerCluster/basic.py @@ -0,0 +1,152 @@ +################################################################### +# 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 os +import taos + +class BuildDockerCluser: + + def init(self, numOfNodes, dockerDir): + self.numOfNodes = numOfNodes + self.dockerDir = dockerDir + + self.hostName = "tdnode1" + self.user = "root" + self.password = "taosdata" + self.configDir = "/etc/taos" + self.dirs = ["data", "cfg", "log", "core"] + self.cfgDict = { + "numOfLogLines":"100000000", + "mnodeEqualVnodeNum":"0", + "walLevel":"1", + "numOfThreadsPerCore":"2.0", + "monitor":"0", + "vnodeBak":"1", + "dDebugFlag":"135", + "mDebugFlag":"135", + "sdbDebugFlag":"135", + "rpcDebugFlag":"135", + "tmrDebugFlag":"131", + "cDebugFlag":"135", + "httpDebugFlag":"135", + "monitorDebugFlag":"135", + "udebugFlag":"135", + "jnidebugFlag":"135", + "qdebugFlag":"135", + "maxSQLLength":"1048576" + } + + # execute command, and return the output + # ref: https://blog.csdn.net/wowocpp/article/details/80775650 + def execCmdAndGetOutput(self, cmd): + r = os.popen(cmd) + text = r.read() + r.close() + return text + + def execCmd(self, cmd): + if os.system(cmd) != 0: + quit() + + def getTaosdVersion(self): + cmd = "taosd -V |grep version|awk '{print $3}'" + taosdVersion = self.execCmdAndGetOutput(cmd) + cmd = "find %s -name '*server*.tar.gz' | awk -F- '{print $(NF-2)}'|sort|awk 'END {print}'" % self.dockerDir + packageVersion = self.execCmdAndGetOutput(cmd) + + if (taosdVersion is None or taosdVersion.isspace()) and (packageVersion is None or packageVersion.isspace()): + print("Please install taosd or have a install package ready") + quit() + else: + self.version = taosdVersion if taosdVersion >= packageVersion else packageVersion + return self.version.strip() + + def getConnection(self): + self.conn = taos.connect( + host = self.hostName, + user = self.user, + password = self.password, + config = self.configDir) + + def removeFile(self, rootDir, index, dir): + cmd = "rm -rf %s/node%d/%s/*" % (rootDir, index, dir) + self.execCmd(cmd) + + def clearEnv(self): + cmd = "cd %s && docker-compose down --remove-orphans" % self.dockerDir + self.execCmd(cmd) + for i in range(1, self.numOfNodes + 1): + self.removeFile(self.dockerDir, i, self.dirs[0]) + self.removeFile(self.dockerDir, i, self.dirs[1]) + self.removeFile(self.dockerDir, i, self.dirs[2]) + + def createDir(self, rootDir, index, dir): + cmd = "mkdir -p %s/node%d/%s" % (rootDir, index, dir) + self.execCmd(cmd) + + def createDirs(self): + for i in range(1, self.numOfNodes + 1): + for j in range(len(self.dirs)): + self.createDir(self.dockerDir, i, self.dirs[j]) + + def addExtraCfg(self, option, value): + self.cfgDict.update({option: value}) + + def cfg(self, option, value, nodeIndex): + cfgPath = "%s/node%d/cfg/taos.cfg" % (self.dockerDir, nodeIndex) + cmd = "echo '%s %s' >> %s" % (option, value, cfgPath) + self.execCmd(cmd) + + def updateLocalhosts(self): + cmd = "grep '172.27.0.7 *tdnode1' /etc/hosts" + result = self.execCmdAndGetOutput(cmd) + if result and not result.isspace(): + cmd = "echo '172.27.0.7 tdnode1' >> /etc/hosts" + self.execCmd(cmd) + + def deploy(self): + self.clearEnv() + self.createDirs() + for i in range(1, self.numOfNodes + 1): + self.cfg("firstEp", "tdnode1:6030", i) + + for key, value in self.cfgDict.items(): + self.cfg(key, value, i) + + def createDondes(self): + self.cursor = self.conn.cursor() + for i in range(2, self.numOfNodes + 1): + self.cursor.execute("create dnode tdnode%d" % i) + + def startArbitrator(self): + for i in range(1, self.numOfNodes + 1): + self.cfg("arbitrator", "tdnode1:6042", i) + cmd = "docker exec -d $(docker ps|grep tdnode1|awk '{print $1}') tarbitrator" + self.execCmd(cmd) + + def prepardBuild(self): + if self.numOfNodes < 2 or self.numOfNodes > 10: + print("the number of nodes must be between 2 and 10") + exit(0) + self.clearEnv() + self.createDirs() + self.updateLocalhosts() + self.deploy() + + def run(self): + cmd = "./buildClusterEnv.sh -n %d -v %s -d %s" % (self.numOfNodes, self.getTaosdVersion(), self.dockerDir) + self.execCmd(cmd) + self.getConnection() + self.createDondes() + +cluster = BuildDockerCluser() \ No newline at end of file diff --git a/tests/pytest/cluster/clusterEnvSetup/buildClusterEnv.sh b/tests/pytest/dockerCluster/buildClusterEnv.sh similarity index 69% rename from tests/pytest/cluster/clusterEnvSetup/buildClusterEnv.sh rename to tests/pytest/dockerCluster/buildClusterEnv.sh index 60c81cd82b916a290c190c44f7b96f53154c4731..7bd92cad72c4180d5405364ebe2fbd81a8a20386 100755 --- a/tests/pytest/cluster/clusterEnvSetup/buildClusterEnv.sh +++ b/tests/pytest/dockerCluster/buildClusterEnv.sh @@ -32,43 +32,14 @@ do esac done -function addTaoscfg { - for((i=1;i<=$NUM_OF_NODES;i++)) - do - touch $DOCKER_DIR/node$i/cfg/taos.cfg - echo 'firstEp tdnode1:6030' > $DOCKER_DIR/node$i/cfg/taos.cfg - echo 'fqdn tdnode'$i >> $DOCKER_DIR/node$i/cfg/taos.cfg - echo 'arbitrator tdnode1:6042' >> $DOCKER_DIR/node$i/cfg/taos.cfg - done -} - -function createDIR { - for((i=1;i<=$NUM_OF_NODES;i++)) - do - mkdir -p $DOCKER_DIR/node$i/data - mkdir -p $DOCKER_DIR/node$i/log - mkdir -p $DOCKER_DIR/node$i/cfg - mkdir -p $DOCKER_DIR/node$i/core - done -} - -function cleanEnv { - echo "Clean up docker environment" - for((i=1;i<=$NUM_OF_NODES;i++)) - do - rm -rf $DOCKER_DIR/node$i/data/* - rm -rf $DOCKER_DIR/node$i/log/* - done -} - function prepareBuild { - if [ -d $CURR_DIR/../../../../release ]; then + if [ -d $CURR_DIR/../../../release ]; then echo release exists - rm -rf $CURR_DIR/../../../../release/* + rm -rf $CURR_DIR/../../../release/* fi - cd $CURR_DIR/../../../../packaging + cd $CURR_DIR/../../../packaging if [[ "$CURR_DIR" == *"$IN_TDINTERNAL"* ]]; then if [ ! -e $DOCKER_DIR/TDengine-enterprise-server-$VERSION-Linux-x64.tar.gz ] || [ ! -e $DOCKER_DIR/TDengine-enterprise-arbitrator-$VERSION-Linux-x64.tar.gz ]; then @@ -76,17 +47,17 @@ function prepareBuild { echo "generating TDeninge enterprise packages" ./release.sh -v cluster -n $VERSION >> /dev/null 2>&1 - if [ ! -e $CURR_DIR/../../../../release/TDengine-enterprise-server-$VERSION-Linux-x64.tar.gz ]; then + if [ ! -e $CURR_DIR/../../../release/TDengine-enterprise-server-$VERSION-Linux-x64.tar.gz ]; then echo "no TDengine install package found" exit 1 fi - if [ ! -e $CURR_DIR/../../../../release/TDengine-enterprise-arbitrator-$VERSION-Linux-x64.tar.gz ]; then + if [ ! -e $CURR_DIR/../../../release/TDengine-enterprise-arbitrator-$VERSION-Linux-x64.tar.gz ]; then echo "no arbitrator install package found" exit 1 fi - cd $CURR_DIR/../../../../release + cd $CURR_DIR/../../../release mv TDengine-enterprise-server-$VERSION-Linux-x64.tar.gz $DOCKER_DIR mv TDengine-enterprise-arbitrator-$VERSION-Linux-x64.tar.gz $DOCKER_DIR fi @@ -96,17 +67,17 @@ function prepareBuild { echo "generating TDeninge community packages" ./release.sh -v edge -n $VERSION >> /dev/null 2>&1 - if [ ! -e $CURR_DIR/../../../../release/TDengine-server-$VERSION-Linux-x64.tar.gz ]; then + if [ ! -e $CURR_DIR/../../../release/TDengine-server-$VERSION-Linux-x64.tar.gz ]; then echo "no TDengine install package found" exit 1 fi - if [ ! -e $CURR_DIR/../../../../release/TDengine-arbitrator-$VERSION-Linux-x64.tar.gz ]; then + if [ ! -e $CURR_DIR/../../../release/TDengine-arbitrator-$VERSION-Linux-x64.tar.gz ]; then echo "no arbitrator install package found" exit 1 fi - cd $CURR_DIR/../../../../release + cd $CURR_DIR/../../../release mv TDengine-server-$VERSION-Linux-x64.tar.gz $DOCKER_DIR mv TDengine-arbitrator-$VERSION-Linux-x64.tar.gz $DOCKER_DIR fi @@ -147,13 +118,10 @@ function clusterUp { done docker_run=$docker_run" up -d" fi - echo $docker_run |sh + echo $docker_run |sh echo "docker compose finish" } -createDIR -cleanEnv -addTaoscfg prepareBuild clusterUp \ No newline at end of file diff --git a/tests/pytest/cluster/clusterEnvSetup/docker-compose.yml b/tests/pytest/dockerCluster/docker-compose.yml similarity index 94% rename from tests/pytest/cluster/clusterEnvSetup/docker-compose.yml rename to tests/pytest/dockerCluster/docker-compose.yml index d241062a2dd50fa82f934d9e915cddeb74505248..7855f3013687406f407cfb9a5aec27e0da78a5f5 100644 --- a/tests/pytest/cluster/clusterEnvSetup/docker-compose.yml +++ b/tests/pytest/dockerCluster/docker-compose.yml @@ -53,7 +53,7 @@ services: source: ${DATADIR}/node1/core target: /coredump - type: bind - source: /data + source: ${DATADIR} target: /root hostname: tdnode1 networks: @@ -90,6 +90,11 @@ services: - "tdnode3:172.27.0.9" - "tdnode4:172.27.0.10" - "tdnode5:172.27.0.11" + - "tdnode6:172.27.0.12" + - "tdnode7:172.27.0.13" + - "tdnode8:172.27.0.14" + - "tdnode9:172.27.0.15" + - "tdnode10:172.27.0.16" volumes: # bind data directory - type: bind diff --git a/tests/pytest/cluster/clusterEnvSetup/insert.json b/tests/pytest/dockerCluster/insert.json similarity index 100% rename from tests/pytest/cluster/clusterEnvSetup/insert.json rename to tests/pytest/dockerCluster/insert.json diff --git a/tests/pytest/cluster/clusterEnvSetup/node3.yml b/tests/pytest/dockerCluster/node3.yml similarity index 97% rename from tests/pytest/cluster/clusterEnvSetup/node3.yml rename to tests/pytest/dockerCluster/node3.yml index 18f1b37c1c029f50cc6e66e662ec2a42bc475c5e..86e37c2f308cdc240178cd3e660f4e31bef55b6e 100644 --- a/tests/pytest/cluster/clusterEnvSetup/node3.yml +++ b/tests/pytest/dockerCluster/node3.yml @@ -26,6 +26,7 @@ services: sysctl -p && exec my-main-application" extra_hosts: + - "tdnode1:172.27.0.7" - "tdnode2:172.27.0.8" - "tdnode3:172.27.0.9" - "tdnode4:172.27.0.10" diff --git a/tests/pytest/cluster/clusterEnvSetup/taosdemoWrapper.py b/tests/pytest/dockerCluster/taosdemoWrapper.py similarity index 100% rename from tests/pytest/cluster/clusterEnvSetup/taosdemoWrapper.py rename to tests/pytest/dockerCluster/taosdemoWrapper.py diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index 3528b01dbda4da7476fabb5763405091e2ea5cdd..be2cfee04b2e2405804fad8d24b77759b6f79b13 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -23,6 +23,7 @@ python3 ./test.py -f insert/insertIntoTwoTables.py python3 ./test.py -f insert/before_1970.py python3 bug2265.py python3 ./test.py -f insert/bug3654.py +python3 ./test.py -f insert/insertDynamicColBeforeVal.py #table python3 ./test.py -f table/alter_wal0.py @@ -37,6 +38,8 @@ python3 ./test.py -f table/boundary.py python3 ./test.py -f table/create.py python3 ./test.py -f table/del_stable.py +#stable +python3 ./test.py -f stable/insert.py # tag python3 ./test.py -f tag_lite/filter.py @@ -151,8 +154,7 @@ python3 test.py -f tools/taosdemoTestTblAlt.py python3 test.py -f tools/taosdemoTestSampleData.py python3 test.py -f tools/taosdemoTestInterlace.py python3 test.py -f tools/taosdemoTestQuery.py -python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJson.py -python3 test.py -f tools/taosdemoAllTest/taosdemoTestQueryWithJson.py + # update @@ -183,7 +185,7 @@ python3 ./test.py -f stable/query_after_reset.py # perfbenchmark python3 ./test.py -f perfbenchmark/bug3433.py #python3 ./test.py -f perfbenchmark/bug3589.py - +python3 ./test.py -f perfbenchmark/taosdemoInsert.py #query python3 ./test.py -f query/filter.py @@ -225,6 +227,8 @@ python3 ./test.py -f query/queryStddevWithGroupby.py python3 ./test.py -f query/querySecondtscolumnTowherenow.py python3 ./test.py -f query/queryFilterTswithDateUnit.py python3 ./test.py -f query/queryTscomputWithNow.py +python3 ./test.py -f query/computeErrorinWhere.py +python3 ./test.py -f query/queryTsisNull.py @@ -303,6 +307,7 @@ python3 ./test.py -f functions/function_top.py -r 1 python3 ./test.py -f functions/function_twa.py -r 1 python3 ./test.py -f functions/function_twa_test2.py python3 ./test.py -f functions/function_stddev_td2555.py +python3 ./test.py -f functions/showOfflineThresholdIs864000.py python3 ./test.py -f insert/metadataUpdate.py python3 ./test.py -f query/last_cache.py python3 ./test.py -f query/last_row_cache.py @@ -327,4 +332,7 @@ python3 ./test.py -f alter/alter_debugFlag.py python3 ./test.py -f query/queryBetweenAnd.py python3 ./test.py -f tag_lite/alter_tag.py +python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJson.py +python3 test.py -f tools/taosdemoAllTest/taosdemoTestQueryWithJson.py + #======================p4-end=============== diff --git a/tests/pytest/functions/showOfflineThresholdIs864000.py b/tests/pytest/functions/showOfflineThresholdIs864000.py new file mode 100644 index 0000000000000000000000000000000000000000..6cce869bf2144e37948c9eb6a3c9ca49352584ca --- /dev/null +++ b/tests/pytest/functions/showOfflineThresholdIs864000.py @@ -0,0 +1,36 @@ +################################################################### +# 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 +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(f"start to execute {__file__}") + tdSql.init(conn.cursor(), logSql) + + def run(self): + tdSql.query("show variables") + tdSql.checkData(51, 1, 864000) + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/hivemq-extension-test.py b/tests/pytest/hivemq-extension-test.py index 3d0b1ef83fe5841826ad0ab80384b5320662e104..9d293ea5edfc02ba4f22ee06c57735c62249f496 100644 --- a/tests/pytest/hivemq-extension-test.py +++ b/tests/pytest/hivemq-extension-test.py @@ -10,7 +10,7 @@ # ################################################################### # install pip -# pip install src/connector/python/linux/python2/ +# pip install src/connector/python/ import sys import os import os.path diff --git a/tests/pytest/insert/insertDynamicColBeforeVal.py b/tests/pytest/insert/insertDynamicColBeforeVal.py new file mode 100644 index 0000000000000000000000000000000000000000..4b596049d16a194b37b2e48e9c7dc521a20b3282 --- /dev/null +++ b/tests/pytest/insert/insertDynamicColBeforeVal.py @@ -0,0 +1,136 @@ +################################################################### +# 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 +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 run(self): + tdSql.prepare() + tdSql.execute("drop database if exists db") + tdSql.execute("create database if not exists db keep 3650") + tdSql.execute("use db") + + tdLog.printNoPrefix("==========step1:create table") + tdSql.execute( + "create table stb1 (ts timestamp, c11 int, c12 float ) TAGS(t11 int, t12 int )" + ) + + tdLog.printNoPrefix("==========step2:insert data with new syntax") + tdSql.execute( + "insert into t1 using stb1(t11, t12) tags(11, 12) (ts, c11, c12) values (now, 10, 20)" + ) + + # case for tag-value + tdSql.execute( + "insert into t2 using stb1(t11) tags(21) (ts, c11, c12) values (now-1m, 11, 21)" + ) + tdSql.execute( + "insert into t3 using stb1 tags(31, 32) (ts, c11, c12) values (now-2m, 12, 22)" + ) + tdSql.error( + "insert into t4 using stb1(t11, t12) (ts, c11, c12) values (now-3m, 13, 23)" + ) + tdSql.error( + "insert into t5 using stb1(t11, t12) tags() (ts, c11, c12) values (now-4m, 14, 24)" + ) + tdSql.error( + "insert into t6 using stb1(t11, t12) tags(41) (ts, c11, c12) values (now-5m, 15, 25)" + ) + tdSql.error( + "insert into t7 using stb1(t12) tags(51, 52) (ts, c11, c12) values (now-6m, 16, 26)" + ) + tdSql.execute( + "insert into t8 using stb1(t11, t12) tags('61', 62) (ts, c11, c12) values (now-7m, 17, 27)" + ) + + + # case for col-value + tdSql.execute( + "insert into t9 using stb1(t11, t12) tags(71, 72) values (now-8m, 18, 28)" + ) + tdSql.error( + "insert into t10 using stb1(t11, t12) tags(81, 82) (ts, c11, c12) values ()" + ) + tdSql.error( + "insert into t11 using stb1(t11, t12) tags(91, 92) (ts, c11, c12) " + ) + tdSql.error( + "insert into t12 using stb1(t11, t12) tags(101, 102) values (now-9m, 19)" + ) + tdSql.error( + "insert into t13 using stb1(t11, t12) tags(111, 112) (ts, c11) values (now-10m, 110, 210)" + ) + tdSql.error( + "insert into t14 using stb1(t11, t12) tags(121, 122) (ts, c11, c12) values (now-11m, 111)" + ) + tdSql.execute( + "insert into t15 using stb1(t11, t12) tags(131, 132) (ts, c11, c12) values (now-12m, NULL , 212)" + ) + tdSql.execute( + "insert into t16 using stb1(t11, t12) tags(141, 142) (ts, c11, c12) values (now-13m, 'NULL', 213)" + ) + tdSql.error( + "insert into t17 using stb1(t11, t12) tags(151, 152) (ts, c11, c12) values (now-14m, Nan, 214)" + ) + tdSql.error( + "insert into t18 using stb1(t11, t12) tags(161, 162) (ts, c11, c12) values (now-15m, 'NaN', 215)" + ) + tdSql.execute( + "insert into t19 using stb1(t11, t12) tags(171, 172) (ts, c11) values (now-16m, 216)" + ) + tdSql.error( + "insert into t20 using stb1(t11, t12) tags(181, 182) (c11, c12) values (117, 217)" + ) + + # multi-col_value + tdSql.execute( + "insert into t21 using stb1(t11, t12) tags(191, 192) (ts, c11, c12) values (now-17m, 118, 218)(now-18m, 119, 219)" + ) + tdSql.execute( + "insert into t22 using stb1(t11, t12) tags(201, 202) values (now-19m, 120, 220)(now-19m, 121, 221)" + ) + tdSql.error( + "insert into t23 using stb1(t11, t12) tags(211, 212) values (now-20m, 122, 222) (ts, c11, c12) values (now-21m, 123, 223)" + ) + tdSql.error( + "insert into t24 using stb1(t11, t12) tags(221, 222) (ts, c11, c12) values (now-22m, 124, 224) (ts, c11, c12) values (now-23m, 125, 225)" + ) + tdSql.execute( + "insert into t25 (ts, c11, c12) using stb1(t11, t12) tags(231, 232) values (now-24m, 126, 226)(now-25m, 127, 227)" + ) + tdSql.error( + "insert into t26 (ts, c11, c12) values (now-24m, 128, 228)(now-25m, 129, 229) using stb1(t11, t12) tags(241, 242) " + ) + tdSql.error( + "insert into t27 (ts, c11, c12) values (now-24m, 130, 230) using stb1(t11, t12) tags(251, 252) " + ) + + tdSql.query("show tables") + tdSql.checkRows(21) + + + 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/insertFromCSVPerformance.py b/tests/pytest/insert/insertFromCSVPerformance.py index 84fd1d7ccab85d7e4469c779f10f047160ee0565..e1f741bd1203e93cd25832866f97be2e87d2b37d 100644 --- a/tests/pytest/insert/insertFromCSVPerformance.py +++ b/tests/pytest/insert/insertFromCSVPerformance.py @@ -31,7 +31,7 @@ class insertFromCSVPerformace: self.host = "127.0.0.1" self.user = "root" self.password = "taosdata" - self.config = "/etc/taosperf" + self.config = "/etc/perf" self.conn = taos.connect( self.host, self.user, diff --git a/tests/pytest/insert/nchar-unicode.py b/tests/pytest/insert/nchar-unicode.py index c417a6bca20a47a2035fbc1c75854e43147e34e3..4afcf5b760baab67111beb83c42d6807a65bb830 100644 --- a/tests/pytest/insert/nchar-unicode.py +++ b/tests/pytest/insert/nchar-unicode.py @@ -57,12 +57,15 @@ class TDTestCase: # https://www.ltg.ed.ac.uk/~richard/unicode-sample.html # Basic Latin - data = r'! # $ % & ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~' + data = r'! # $ % & ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \\ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~' tdLog.info("insert Basic Latin %d length data: %s" % (len(data), data)) tdSql.execute("insert into tb values (now, '%s')" % data) tdSql.query("select * from tb") tdSql.checkRows(3) + + data = data.replace('\\\\', '\\') tdSql.checkData(2, 1, data) + # tdSql.execute("insert into tb values(now, 'abc')") # Latin-1 Supplement data = ' ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ' diff --git a/tests/pytest/perf_gen.py b/tests/pytest/perf_gen.py new file mode 100755 index 0000000000000000000000000000000000000000..f0402fbb6b86c3335f5b2a739bd7545886c8f0d1 --- /dev/null +++ b/tests/pytest/perf_gen.py @@ -0,0 +1,485 @@ +#!/usr/bin/python3.8 + +from abc import abstractmethod + +import time +from datetime import datetime + +from influxdb_client import InfluxDBClient, Point, WritePrecision, BucketsApi +from influxdb_client.client.write_api import SYNCHRONOUS + +import argparse +import textwrap +import subprocess +import sys + +import taos + +from crash_gen.crash_gen_main import Database, TdSuperTable +from crash_gen.service_manager import TdeInstance + +from crash_gen.shared.config import Config +from crash_gen.shared.db import DbConn +from crash_gen.shared.misc import Dice, Logging, Helper +from crash_gen.shared.types import TdDataType + + +# NUM_PROCESSES = 10 +# NUM_REPS = 1000 + +tick = int(time.time() - 5000000.0) # for now we will create max 5M record +value = 101 + +DB_NAME = 'mydb' +TIME_SERIES_NAME = 'widget' + +MAX_SHELF = 500 # shelf number runs up to this, non-inclusive +ITEMS_PER_SHELF = 5 +BATCH_SIZE = 2000 # Number of data points per request + +# None_RW: +# INFLUX_TOKEN='RRzVQZs8ERCpV9cS2RXqgtM_Y6FEZuJ7Tuk0aHtZItFTfcM9ajixtGDhW8HzqNIBmG3hmztw-P4sHOstfJvjFA==' +# DevOrg_RW: +# INFLUX_TOKEN='o1P8sEhBmXKhxBmNuiCyOUKv8d7qm5wUjMff9AbskBu2LcmNPQzU77NrAn5hDil8hZ0-y1AGWpzpL-4wqjFdkA==' +# DevOrg_All_Access +INFLUX_TOKEN='T2QTr4sloJhINH_oSrwSS-WIIZYjDfD123NK4ou3b7ajRs0c0IphCh3bNc0OsDZQRW1HyCby7opdEndVYFGTWQ==' +INFLUX_ORG="DevOrg" +INFLUX_BUCKET="Bucket01" + +def writeTaosBatch(dbc, tblName): + # Database.setupLastTick() + global value, tick + + data = [] + for i in range(0, 100): + data.append("('{}', {})".format(Database.getNextTick(), value) ) + value += 1 + + sql = "INSERT INTO {} VALUES {}".format(tblName, ''.join(data)) + dbc.execute(sql) + +class PerfGenError(taos.error.ProgrammingError): + pass + +class Benchmark(): + + # @classmethod + # def create(cls, dbType): + # if dbType == 'taos': + # return TaosBenchmark() + # elif dbType == 'influx': + # return InfluxBenchmark() + # else: + # raise RuntimeError("Unknown DB type: {}".format(dbType)) + + def __init__(self, dbType, loopCount = 0): + self._dbType = dbType + self._setLoopCount(loopCount) + + def _setLoopCount(self, loopCount): + cfgLoopCount = Config.getConfig().loop_count + if loopCount == 0: # use config + self._loopCount = cfgLoopCount + else: + if cfgLoopCount : + Logging.warning("Ignoring loop count for fixed-loop-count benchmarks: {}".format(cfgLoopCount)) + self._loopCount = loopCount + + @abstractmethod + def doIterate(self): + ''' + Execute the benchmark directly, without invoking sub processes, + effectively using one execution thread. + ''' + pass + + @abstractmethod + def prepare(self): + ''' + Preparation needed to run a certain benchmark + ''' + pass + + @abstractmethod + def execute(self): + ''' + Actually execute the benchmark + ''' + Logging.warning("Unexpected execution") + + @property + def name(self): + return self.__class__.__name__ + + def run(self): + print("Running benchmark: {}, class={} ...".format(self.name, self.__class__)) + startTime = time.time() + + # Prepare to execute the benchmark + self.prepare() + + # Actually execute the benchmark + self.execute() + + # if Config.getConfig().iterate_directly: # execute directly + # Logging.debug("Iterating...") + # self.doIterate() + # else: + # Logging.debug("Executing via sub process...") + # startTime = time.time() + # self.prepare() + # self.spawnProcesses() + # self.waitForProcecess() + # duration = time.time() - startTime + # Logging.info("Benchmark execution completed in {:.3f} seconds".format(duration)) + Logging.info("Benchmark {} finished in {:.3f} seconds".format( + self.name, time.time()-startTime)) + + def spawnProcesses(self): + self._subProcs = [] + for j in range(0, Config.getConfig().subprocess_count): + ON_POSIX = 'posix' in sys.builtin_module_names + tblName = 'cars_reg_{}'.format(j) + cmdLineStr = './perf_gen.sh -t {} -i -n {} -l {}'.format( + self._dbType, + tblName, + Config.getConfig().loop_count + ) + if Config.getConfig().debug: + cmdLineStr += ' -d' + subProc = subprocess.Popen(cmdLineStr, + shell = True, + close_fds = ON_POSIX) + self._subProcs.append(subProc) + + def waitForProcecess(self): + for sp in self._subProcs: + sp.wait(300) + + +class TaosBenchmark(Benchmark): + + def __init__(self, loopCount): + super().__init__('taos', loopCount) + # self._dbType = 'taos' + tInst = TdeInstance() + self._dbc = DbConn.createNative(tInst.getDbTarget()) + self._dbc.open() + self._sTable = TdSuperTable(TIME_SERIES_NAME + '_s', DB_NAME) + + def doIterate(self): + tblName = Config.getConfig().target_table_name + print("Benchmarking TAOS database (1 pass) for: {}".format(tblName)) + self._dbc.execute("USE {}".format(DB_NAME)) + + self._sTable.ensureRegTable(None, self._dbc, tblName) + try: + lCount = Config.getConfig().loop_count + print("({})".format(lCount)) + for i in range(0, lCount): + writeTaosBatch(self._dbc, tblName) + except taos.error.ProgrammingError as err: + Logging.error("Failed to write batch") + + def prepare(self): + self._dbc.execute("CREATE DATABASE IF NOT EXISTS {}".format(DB_NAME)) + self._dbc.execute("USE {}".format(DB_NAME)) + # Create the super table + self._sTable.drop(self._dbc, True) + self._sTable.create(self._dbc, + {'ts': TdDataType.TIMESTAMP, + 'temperature': TdDataType.INT, + 'pressure': TdDataType.INT, + 'notes': TdDataType.BINARY200 + }, + {'rack': TdDataType.INT, + 'shelf': TdDataType.INT, + 'barcode': TdDataType.BINARY16 + }) + + def execSql(self, sql): + try: + self._dbc.execute(sql) + except taos.error.ProgrammingError as err: + Logging.warning("SQL Error: 0x{:X}, {}, SQL: {}".format( + Helper.convertErrno(err.errno), err.msg, sql)) + raise + + def executeWrite(self): + # Sample: INSERT INTO t1 USING st TAGS(1) VALUES(now, 1) t2 USING st TAGS(2) VALUES(now, 2) + sqlPrefix = "INSERT INTO " + dataTemplate = "{} USING {} TAGS({},{},'barcode_{}') VALUES('{}',{},{},'{}') " + + stName = self._sTable.getName() + BATCH_SIZE = 2000 # number of items per request batch + ITEMS_PER_SHELF = 5 + + # rackSize = 10 # shelves per rack + # shelfSize = 100 # items per shelf + batchCount = self._loopCount // BATCH_SIZE + lastRack = 0 + for i in range(batchCount): + sql = sqlPrefix + for j in range(BATCH_SIZE): + n = i*BATCH_SIZE + j # serial number + # values first + # rtName = 'rt_' + str(n) # table name contains serial number, has info + temperature = 20 + (n % 10) + pressure = 70 + (n % 10) + # tags + shelf = (n // ITEMS_PER_SHELF) % MAX_SHELF # shelf number + rack = n // (ITEMS_PER_SHELF * MAX_SHELF) # rack number + barcode = rack + shelf + # table name + tableName = "reg_" + str(rack) + '_' + str(shelf) + # now the SQL + sql += dataTemplate.format(tableName, stName,# table name + rack, shelf, barcode, # tags + Database.getNextTick(), temperature, pressure, 'xxx') # values + lastRack = rack + self.execSql(sql) + Logging.info("Last Rack: {}".format(lastRack)) + +class TaosWriteBenchmark(TaosBenchmark): + def execute(self): + self.executeWrite() + +class Taos100kWriteBenchmark(TaosWriteBenchmark): + def __init__(self): + super().__init__(100*1000) + +class Taos10kWriteBenchmark(TaosWriteBenchmark): + def __init__(self): + super().__init__(10*1000) + +class Taos1mWriteBenchmark(TaosWriteBenchmark): + def __init__(self): + super().__init__(1000*1000) + +class Taos5mWriteBenchmark(TaosWriteBenchmark): + def __init__(self): + super().__init__(5*1000*1000) + +class Taos1kQueryBenchmark(TaosBenchmark): + def __init__(self): + super().__init__(1000) + +class Taos1MCreationBenchmark(TaosBenchmark): + def __init__(self): + super().__init__(1000000) + + +class InfluxBenchmark(Benchmark): + def __init__(self, loopCount): + super().__init__('influx', loopCount) + # self._dbType = 'influx' + + + # self._client = InfluxDBClient(host='localhost', port=8086) + + # def _writeBatch(self, tblName): + # global value, tick + # data = [] + # for i in range(0, 100): + # line = "{},device={} value={} {}".format( + # TIME_SERIES_NAME, + # tblName, + # value, + # tick*1000000000) + # # print(line) + # data.append(line) + # value += 1 + # tick +=1 + + # self._client.write(data, {'db':DB_NAME}, protocol='line') + + def executeWrite(self): + global tick # influx tick #TODO refactor + + lineTemplate = TIME_SERIES_NAME + ",rack={},shelf={},barcode='barcode_{}' temperature={},pressure={} {}" + + batchCount = self._loopCount // BATCH_SIZE + for i in range(batchCount): + lineBatch = [] + for j in range(BATCH_SIZE): + n = i*BATCH_SIZE + j # serial number + # values first + # rtName = 'rt_' + str(n) # table name contains serial number, has info + temperature = 20 + (n % 10) + pressure = 70 + (n % 10) + # tags + shelf = (n // ITEMS_PER_SHELF) % MAX_SHELF # shelf number + rack = n // (ITEMS_PER_SHELF * MAX_SHELF) # rack number + barcode = rack + shelf + # now the SQL + line = lineTemplate.format( + rack, shelf, barcode, # tags + temperature, pressure, # values + tick * 1000000000 ) + tick += 1 + lineBatch.append(line) + write_api = self._client.write_api(write_options=SYNCHRONOUS) + write_api.write(INFLUX_BUCKET, INFLUX_ORG, lineBatch) + # self._client.write(lineBatch, {'db':DB_NAME}, protocol='line') + + # def doIterate(self): + # tblName = Config.getConfig().target_table_name + # print("Benchmarking INFLUX database (1 pass) for: {}".format(tblName)) + + # for i in range(0, Config.getConfig().loop_count): + # self._writeBatch(tblName) + + def _getOrgIdByName(self, orgName): + """Find org by name. + + """ + orgApi = self._client.organizations_api() + orgs = orgApi.find_organizations() + for org in orgs: + if org.name == orgName: + return org.id + raise PerfGenError("Org not found with name: {}".format(orgName)) + + def _fetchAuth(self): + authApi = self._client.authorizations_api() + auths = authApi.find_authorizations() + for auth in auths: + if auth.token == INFLUX_TOKEN : + return auth + raise PerfGenError("No proper auth found") + + def _verifyPermissions(self, perms: list): + if list: + return #OK + raise PerfGenError("No permission found") + + def prepare(self): + self._client = InfluxDBClient( + url="http://127.0.0.1:8086", + token=INFLUX_TOKEN, + org=INFLUX_ORG) + + auth = self._fetchAuth() + + self._verifyPermissions(auth.permissions) + + bktApi = self._client.buckets_api() + # Delete + bkt = bktApi.find_bucket_by_name(INFLUX_BUCKET) + if bkt: + bktApi.delete_bucket(bkt) + # Recreate + + orgId = self._getOrgIdByName(INFLUX_ORG) + bktApi.create_bucket(bucket=None, bucket_name=INFLUX_BUCKET, org_id=orgId) + + # self._client.drop_database(DB_NAME) + # self._client.create_database(DB_NAME) + # self._client.switch_database(DB_NAME) + +class InfluxWriteBenchmark(InfluxBenchmark): + def execute(self): + return self.executeWrite() + +class Influx10kWriteBenchmark(InfluxWriteBenchmark): + def __init__(self): + super().__init__(10*1000) + +class Influx100kWriteBenchmark(InfluxWriteBenchmark): + def __init__(self): + super().__init__(100*1000) + +class Influx1mWriteBenchmark(InfluxWriteBenchmark): + def __init__(self): + super().__init__(1000*1000) + +class Influx5mWriteBenchmark(InfluxWriteBenchmark): + def __init__(self): + super().__init__(5*1000*1000) + +def _buildCmdLineParser(): + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description=textwrap.dedent('''\ + TDengine Performance Benchmarking Tool + --------------------------------------------------------------------- + + ''')) + + parser.add_argument( + '-b', + '--benchmark-name', + action='store', + default='Taos1kQuery', + type=str, + help='Benchmark to use (default: Taos1kQuery)') + + parser.add_argument( + '-d', + '--debug', + action='store_true', + help='Turn on DEBUG mode for more logging (default: false)') + + parser.add_argument( + '-i', + '--iterate-directly', + action='store_true', + help='Execution operations directly without sub-process (default: false)') + + parser.add_argument( + '-l', + '--loop-count', + action='store', + default=1000, + type=int, + help='Number of loops to perform, 100 operations per loop. (default: 1000)') + + parser.add_argument( + '-n', + '--target-table-name', + action='store', + default=None, + type=str, + help='Regular table name in target DB (default: None)') + + parser.add_argument( + '-s', + '--subprocess-count', + action='store', + default=4, + type=int, + help='Number of sub processes to spawn. (default: 10)') + + parser.add_argument( + '-t', + '--target-database', + action='store', + default='taos', + type=str, + help='Benchmark target: taos, influx (default: taos)') + + return parser + +def main(): + parser = _buildCmdLineParser() + Config.init(parser) + Logging.clsInit(Config.getConfig().debug) + Dice.seed(0) # initial seeding of dice + + bName = Config.getConfig().benchmark_name + bClassName = bName + 'Benchmark' + x = globals() + if bClassName in globals(): + bClass = globals()[bClassName] + bm = bClass() # Benchmark object + bm.run() + else: + raise PerfGenError("No such benchmark: {}".format(bName)) + + # bm = Benchmark.create(Config.getConfig().target_database) + # bm.run() + +if __name__ == "__main__": + main() + + diff --git a/tests/pytest/perf_gen.sh b/tests/pytest/perf_gen.sh new file mode 100755 index 0000000000000000000000000000000000000000..d28b5422f8ba4d4683c78020e45d2085385c4b4f --- /dev/null +++ b/tests/pytest/perf_gen.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# This is the script for us to try to cause the TDengine server or client to crash +# +# PREPARATION +# +# 1. Build an compile the TDengine source code that comes with this script, in the same directory tree +# 2. Please follow the direction in our README.md, and build TDengine in the build/ directory +# 3. Adjust the configuration file if needed under build/test/cfg/taos.cfg +# 4. Run the TDengine server instance: cd build; ./build/bin/taosd -c test/cfg +# 5. Make sure you have a working Python3 environment: run /usr/bin/python3 --version, and you should get 3.6 or above +# 6. Make sure you have the proper Python packages: # sudo apt install python3-setuptools python3-pip python3-distutils +# +# RUNNING THIS SCRIPT +# +# This script assumes the source code directory is intact, and that the binaries has been built in the +# build/ directory, as such, will will load the Python libraries in the directory tree, and also load +# the TDengine client shared library (so) file, in the build/directory, as evidenced in the env +# variables below. +# +# Running the script is simple, no parameter is needed (for now, but will change in the future). +# +# Happy Crashing... + + +# Due to the heavy path name assumptions/usage, let us require that the user be in the current directory +EXEC_DIR=`dirname "$0"` +if [[ $EXEC_DIR != "." ]] +then + echo "ERROR: Please execute `basename "$0"` in its own directory (for now anyway, pardon the dust)" + exit -1 +fi + +CURR_DIR=`pwd` +IN_TDINTERNAL="community" +if [[ "$CURR_DIR" == *"$IN_TDINTERNAL"* ]]; then + TAOS_DIR=$CURR_DIR/../../.. + TAOSD_DIR=`find $TAOS_DIR -name "taosd"|grep bin|head -n1` + LIB_DIR=`echo $TAOSD_DIR|rev|cut -d '/' -f 3,4,5,6,7|rev`/lib +else + TAOS_DIR=$CURR_DIR/../.. + TAOSD_DIR=`find $TAOS_DIR -name "taosd"|grep bin|head -n1` + LIB_DIR=`echo $TAOSD_DIR|rev|cut -d '/' -f 3,4,5,6|rev`/lib +fi + +# Now getting ready to execute Python +# The following is the default of our standard dev env (Ubuntu 20.04), modify/adjust at your own risk +PYTHON_EXEC=python3.8 + +# First we need to set up a path for Python to find our own TAOS modules, so that "import" can work. +export PYTHONPATH=$(pwd)/../../src/connector/python:$(pwd) + +# Then let us set up the library path so that our compiled SO file can be loaded by Python +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIB_DIR + +# Now we are all let, and let's see if we can find a crash. Note we pass all params +PERF_GEN_EXEC=perf_gen.py +$PYTHON_EXEC $PERF_GEN_EXEC $@ + + diff --git a/tests/pytest/perfbenchmark/taosdemoInsert.py b/tests/pytest/perfbenchmark/taosdemoInsert.py new file mode 100644 index 0000000000000000000000000000000000000000..59a8143d5a34014ecbdfe57c6ecc073c0eaeb39c --- /dev/null +++ b/tests/pytest/perfbenchmark/taosdemoInsert.py @@ -0,0 +1,387 @@ +################################################################### +# 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 taos +import sys +import os +import json +import argparse +import subprocess +import datetime +import re + + +from multiprocessing import cpu_count +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.dnodes import TDDnode + +class Taosdemo: + def __init__(self, clearCache, dbName, keep): + self.clearCache = clearCache + self.dbname = dbName + self.drop = "yes" + self.keep = keep + self.host = "127.0.0.1" + self.user = "root" + self.password = "taosdata" + # self.config = "/etc/taosperf" + # self.conn = taos.connect( + # self.host, + # self.user, + # self.password, + # self.config) + + # env config + def getBuildPath(self) -> str: + 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("/debug/build/bin")] + break + return buildPath + + def getExeToolsDir(self) -> str: + self.debugdir = self.getBuildPath() + "/debug/build/bin" + return self.debugdir + + def getCfgDir(self) -> str: + self.config = self.getBuildPath() + "/sim/dnode1/cfg" + return self.config + + # taodemo insert file config + def dbinfocfg(self) -> dict: + return { + "name": self.dbname, + "drop": self.drop, + "replica": 1, + "days": 10, + "cache": 16, + "blocks": 8, + "precision": "ms", + "keep": self.keep, + "minRows": 100, + "maxRows": 4096, + "comp": 2, + "walLevel": 1, + "cachelast": 0, + "quorum": 1, + "fsync": 3000, + "update": 0 + } + + def type_check(func): + def wrapper(self, **kwargs): + num_types = ["int", "float", "bigint", "tinyint", "smallint", "double"] + str_types = ["binary", "nchar"] + for k ,v in kwargs.items(): + if k.lower() not in num_types and k.lower() not in str_types: + return f"args {k} type error, not allowed" + elif not isinstance(v, (int, list, tuple)): + return f"value {v} type error, not allowed" + elif k.lower() in num_types and not isinstance(v, int): + return f"arg {v} takes 1 positional argument must be type int " + elif isinstance(v, (list,tuple)) and len(v) > 2: + return f"arg {v} takes from 1 to 2 positional arguments but more than 2 were given " + elif isinstance(v,(list,tuple)) and [ False for _ in v if not isinstance(_, int) ]: + return f"arg {v} takes from 1 to 2 positional arguments must be type int " + else: + pass + return func(self, **kwargs) + return wrapper + + @type_check + def column_tag_count(self, **column_tag) -> list : + init_column_tag = [] + for k, v in column_tag.items(): + if re.search(k, "int, float, bigint, tinyint, smallint, double", re.IGNORECASE): + init_column_tag.append({"type": k, "count": v}) + elif re.search(k, "binary, nchar", re.IGNORECASE): + if isinstance(v, int): + init_column_tag.append({"type": k, "count": v, "len":8}) + elif len(v) == 1: + init_column_tag.append({"type": k, "count": v[0], "len": 8}) + else: + init_column_tag.append({"type": k, "count": v[0], "len": v[1]}) + return init_column_tag + + def stbcfg(self, stb: str, child_tab_count: int, rows: int, prechildtab: str, columns: dict, tags: dict) -> dict: + return { + "name": stb, + "child_table_exists": "no", + "childtable_count": child_tab_count, + "childtable_prefix": prechildtab, + "auto_create_table": "no", + "batch_create_tbl_num": 10, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": rows, + "childtable_limit": 0, + "childtable_offset": 0, + "rows_per_tbl": 1, + "max_sql_len": 65480, + "disorder_ratio": 0, + "disorder_range": 1000, + "timestamp_step": 10, + "start_timestamp": f"{datetime.datetime.now():%F %X}", + "sample_format": "csv", + "sample_file": "./sample.csv", + "tags_file": "", + "columns": self.column_tag_count(**columns), + "tags": self.column_tag_count(**tags) + } + + def schemecfg(self,intcount=1,floatcount=0,bcount=0,tcount=0,scount=0,doublecount=0,binarycount=0,ncharcount=0): + return { + "INT": intcount, + "FLOAT": floatcount, + "BIGINT": bcount, + "TINYINT": tcount, + "SMALLINT": scount, + "DOUBLE": doublecount, + "BINARY": binarycount, + "NCHAR": ncharcount + } + + def insertcfg(self,db: dict, stbs: list) -> dict: + return { + "filetype": "insert", + "cfgdir": self.config, + "host": self.host, + "port": 6030, + "user": self.user, + "password": self.password, + "thread_count": cpu_count(), + "thread_count_create_tbl": cpu_count(), + "result_file": "/tmp/insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "num_of_records_per_req": 100, + "max_sql_len": 1024000, + "databases": [{ + "dbinfo": db, + "super_tables": stbs + }] + } + + def createinsertfile(self,db: dict, stbs: list) -> str: + date = datetime.datetime.now() + file_create_table = f"/tmp/insert_{date:%F-%H%M}.json" + + with open(file_create_table, 'w') as f: + json.dump(self.insertcfg(db, stbs), f) + + return file_create_table + + # taosdemo query file config + def querysqls(self, sql: str) -> list: + return [{"sql":sql,"result":""}] + + def querycfg(self, sql: str) -> dict: + return { + "filetype": "query", + "cfgdir": self.config, + "host": self.host, + "port": 6030, + "user": self.user, + "password": self.password, + "confirm_parameter_prompt": "yes", + "query_times": 10, + "query_mode": "taosc", + "databases": self.dbname, + "specified_table_query": { + "query_interval": 0, + "concurrent": cpu_count(), + "sqls": self.querysqls(sql) + } + } + + def createqueryfile(self, sql: str): + date = datetime.datetime.now() + file_query_table = f"/tmp/query_{date:%F-%H%M}.json" + + with open(file_query_table,"w") as f: + json.dump(self.querycfg(sql), f) + + return file_query_table + + # Execute taosdemo, and delete temporary files when finished + def taosdemotable(self, filepath: str, resultfile="/dev/null"): + taosdemopath = self.getBuildPath() + "/debug/build/bin" + with open(filepath,"r") as f: + filetype = json.load(f)["filetype"] + if filetype == "insert": + taosdemo_table_cmd = f"{taosdemopath}/taosdemo -f {filepath} > {resultfile} 2>&1" + else: + taosdemo_table_cmd = f"yes | {taosdemopath}/taosdemo -f {filepath} > {resultfile} 2>&1" + try: + _ = subprocess.check_output(taosdemo_table_cmd, shell=True).decode("utf-8") + except subprocess.CalledProcessError as e: + _ = e.output + + def droptmpfile(self, filepath: str): + drop_file_cmd = f"[ -f {filepath} ] && rm -f {filepath}" + try: + _ = subprocess.check_output(drop_file_cmd, shell=True).decode("utf-8") + except subprocess.CalledProcessError as e: + _ = e.output + + # TODO:需要完成TD-4153的数据插入和客户端请求的性能查询。 + def td4153insert(self): + + tdLog.printNoPrefix("========== start to create table and insert data ==========") + self.dbname = "td4153" + db = self.dbinfocfg() + stblist = [] + + columntype = self.schemecfg(intcount=1, ncharcount=100) + tagtype = self.schemecfg(intcount=1) + stbname = "stb1" + prechild = "t1" + stable = self.stbcfg( + stb=stbname, + prechildtab=prechild, + child_tab_count=2, + rows=10000, + columns=columntype, + tags=tagtype + ) + stblist.append(stable) + insertfile = self.createinsertfile(db=db, stbs=stblist) + + nmon_file = f"/tmp/insert_{datetime.datetime.now():%F-%H%M}.nmon" + cmd = f"nmon -s5 -F {nmon_file} -m /tmp/" + try: + _ = subprocess.check_output(cmd, shell=True).decode("utf-8") + except subprocess.CalledProcessError as e: + _ = e.output + + self.taosdemotable(insertfile) + self.droptmpfile(insertfile) + self.droptmpfile("/tmp/insert_res.txt") + + # In order to prevent too many performance files from being generated, the nmon file is deleted. + # and the delete statement can be cancelled during the actual test. + self.droptmpfile(nmon_file) + + cmd = f"ps -ef|grep -w nmon| grep -v grep | awk '{{print $2}}'" + try: + time.sleep(10) + _ = subprocess.check_output(cmd,shell=True).decode("utf-8") + except BaseException as e: + raise e + + def td4153query(self): + tdLog.printNoPrefix("========== start to query operation ==========") + + sqls = { + "select_all": "select * from stb1", + "select_join": "select * from t10, t11 where t10.ts=t11.ts" + } + for type, sql in sqls.items(): + result_file = f"/tmp/queryResult_{type}.log" + query_file = self.createqueryfile(sql) + try: + self.taosdemotable(query_file, resultfile=result_file) + except subprocess.CalledProcessError as e: + out_put = e.output + if result_file: + print(f"execute rows {type.split('_')[1]} sql, the sql is: {sql}") + max_sql_time_cmd = f''' + grep -o Spent.*s {result_file} |awk 'NR==1{{max=$2;next}}{{max=max>$2?max:$2}}END{{print "Max=",max,"s"}}' + ''' + max_sql_time = subprocess.check_output(max_sql_time_cmd, shell=True).decode("UTF-8") + print(f"{type.split('_')[1]} rows sql time : {max_sql_time}") + + min_sql_time_cmd = f''' + grep -o Spent.*s {result_file} |awk 'NR==1{{min=$2;next}}{{min=min<$2?min:$2}}END{{print "Min=",min,"s"}}' + ''' + min_sql_time = subprocess.check_output(min_sql_time_cmd, shell=True).decode("UTF-8") + print(f"{type.split('_')[1]} rows sql time : {min_sql_time}") + + avg_sql_time_cmd = f''' + grep -o Spent.*s {result_file} |awk '{{sum+=$2}}END{{print "Average=",sum/NR,"s"}}' + ''' + avg_sql_time = subprocess.check_output(avg_sql_time_cmd, shell=True).decode("UTF-8") + print(f"{type.split('_')[1]} rows sql time : {avg_sql_time}") + + self.droptmpfile(query_file) + self.droptmpfile(result_file) + + drop_query_tmt_file_cmd = " find ./ -name 'querySystemInfo-*' -type f -exec rm {} \; " + try: + _ = subprocess.check_output(drop_query_tmt_file_cmd, shell=True).decode("utf-8") + except subprocess.CalledProcessError as e: + _ = e.output + pass + + def td4153(self): + self.td4153insert() + self.td4153query() + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument( + '-r', + '--remove-cache', + action='store_true', + default=False, + help='clear cache before query (default: False)') + parser.add_argument( + '-d', + '--database-name', + action='store', + default='db', + type=str, + help='Database name to be created (default: db)') + parser.add_argument( + '-k', + '--keep-time', + action='store', + default=3650, + type=int, + help='Database keep parameters (default: 3650)') + + args = parser.parse_args() + taosdemo = Taosdemo(args.remove_cache, args.database_name, args.keep_time) + # taosdemo.conn = taos.connect( + # taosdemo.host, + # taosdemo.user, + # taosdemo.password, + # taosdemo.config + # ) + + debugdir = taosdemo.getExeToolsDir() + cfgdir = taosdemo.getCfgDir() + cmd = f"{debugdir}/taosd -c {cfgdir} >/dev/null 2>&1 &" + try: + _ = subprocess.check_output(cmd, shell=True).decode("utf-8") + except subprocess.CalledProcessError as e: + _ = e.output + + if taosdemo.clearCache: + # must be root permission + subprocess.check_output("echo 3 > /proc/sys/vm/drop_caches", shell=True).decode("utf-8") + + taosdemo.td4153() diff --git a/tests/pytest/query/computeErrorinWhere.py b/tests/pytest/query/computeErrorinWhere.py new file mode 100644 index 0000000000000000000000000000000000000000..4ceb1ab89f852743de98af65f73f502ab817005d --- /dev/null +++ b/tests/pytest/query/computeErrorinWhere.py @@ -0,0 +1,136 @@ +# 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 +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(f"start to execute {__file__}") + tdSql.init(conn.cursor(), logSql) + + def insertnow(self): + tdSql.execute("drop database if exists dbcom") + tdSql.execute("create database if not exists dbcom keep 36500") + tdSql.execute("use dbcom") + + tdSql.execute( + "create table stbcom (ts timestamp, c1 int, c2 tinyint, c3 smallint, c4 bigint, c5 float, c6 double) TAGS(t1 int)" + ) + tdSql.execute("create table tcom1 using stbcom tags(1)") + + # timestamp list: + # 0 -> "1970-01-01 08:00:00" | -28800000 -> "1970-01-01 00:00:00" | -946800000000 -> "1940-01-01 00:00:00" + # -631180800000 -> "1950-01-01 00:00:00" + + tdSql.execute("insert into tcom1 values (now-1d, 1, 11, 21, 31, 41.0, 51.1)") + tdSql.execute("insert into tcom1 values (now-2d, 2, 12, 22, 32, 42.0, 52.1)") + tdSql.execute("insert into tcom1 values (now-3d, 3, 13, 23, 33, 43.0, 53.1)") + tdSql.execute("insert into tcom1 values (now-4d, 4, 14, 24, 34, 44.0, 54.1)") + + def querycom(self): + tdSql.query("select * from tcom1 where c1=2-1") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c1=-1+2") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c1=1.0*1.0") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c1=1.0/1.0") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c1>1.0/1.0") + tdSql.checkRows(3) + tdSql.query("select * from tcom1 where c1<1.0/1.0") + tdSql.checkRows(0) + + tdSql.query("select * from tcom1 where c2=12-1") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c2=-1+12") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c2=11.0*1.0") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c2=11.0/1.0") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c2>11.0/1.0") + tdSql.checkRows(3) + tdSql.query("select * from tcom1 where c2<11.0/1.0") + tdSql.checkRows(0) + + tdSql.query("select * from tcom1 where c3=22-1") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c3=-1+22") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c3=21.0*1.0") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c3=21.0/1.0") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c3>21.0/1.0") + tdSql.checkRows(3) + tdSql.query("select * from tcom1 where c3<21.0/1.0") + tdSql.checkRows(0) + + tdSql.query("select * from tcom1 where c4=32-1") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c4=-1+32") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c4=31.0*1.0") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c4=31.0/1.0") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c4>31.0/1.0") + tdSql.checkRows(3) + tdSql.query("select * from tcom1 where c4<31.0/1.0") + tdSql.checkRows(0) + + tdSql.query("select * from tcom1 where c5=42-1") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c5=-1+42") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c5=41*1") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c5=41/1") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c5>41/1") + tdSql.checkRows(3) + tdSql.query("select * from tcom1 where c5<41/1") + tdSql.checkRows(0) + tdSql.query("select * from tcom1 where c5=42.000000008-1.0000000099999999999999") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c5=42.0008-1.0000099999999999999") + tdSql.checkRows(0) + + tdSql.query("select * from tcom1 where c6=52-0.9") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c6=-0.9+52") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c6=51.1*1") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c6=51.1/1") + tdSql.checkRows(1) + tdSql.query("select * from tcom1 where c6>51.1/1") + tdSql.checkRows(3) + tdSql.query("select * from tcom1 where c6<51.1/1") + tdSql.checkRows(0) + tdSql.query("select * from tcom1 where c6=52.100000000000008-1.000000000000009") + tdSql.checkRows(1) + + + def run(self): + self.insertnow() + self.querycom() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/query/queryTsisNull.py b/tests/pytest/query/queryTsisNull.py new file mode 100644 index 0000000000000000000000000000000000000000..df783f2fb86ab600ac579093a391d88cfd9370c5 --- /dev/null +++ b/tests/pytest/query/queryTsisNull.py @@ -0,0 +1,53 @@ +################################################################### +# 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 +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 run(self): + tdSql.prepare() + tdSql.execute("drop database if exists db") + tdSql.execute("create database if not exists db keep 3650") + tdSql.execute("use db") + + tdLog.printNoPrefix("==========step1:create table and insert data") + tdSql.execute( + "create table stb1 (ts timestamp, c1 timestamp , c2 int) TAGS(t1 int )" + ) + + tdLog.printNoPrefix("==========step2:query data where timestamp data is null") + tdSql.execute( + "insert into t1 using stb1(t1) tags(1) (ts, c1, c2) values (now-1m, null, 1)" + ) + tdSql.execute( + "insert into t1 using stb1(t1) tags(1) (ts, c2) values (now-2m, 2)" + ) + tdSql.query("select * from t1 where c1 is NULL") + tdSql.checkRows(2) + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/query/unionAllTest.py b/tests/pytest/query/unionAllTest.py index 1b69c8ac4d015a2ad8db72947022b7bd27e92756..3064e2f63e871e5c90d03d19bf125447714dd6cb 100644 --- a/tests/pytest/query/unionAllTest.py +++ b/tests/pytest/query/unionAllTest.py @@ -56,6 +56,34 @@ class TDTestCase: tdSql.query(sql) tdSql.checkRows(6) + tdSql.execute("create table stb(ts timestamp, options binary(7), city binary(10)) tags(type int)") + tdSql.execute("insert into tb1 using stb tags(1) values(%d, 'option1', 'beijing')" % self.ts) + tdSql.execute("insert into tb2 using stb tags(2) values(%d, 'option2', 'shanghai')" % self.ts) + + tdSql.query("select options from stb where type = 1 limit 1 union all select options from stb where type = 2 limit 1") + tdSql.checkData(0, 0, "option1") + tdSql.checkData(1, 0, "option2") + + tdSql.query("select 'dc' as options from stb where type = 1 limit 1 union all select 'ad' as options from stb where type = 2 limit 1") + tdSql.checkData(0, 0, "dc") + tdSql.checkData(1, 0, "ad") + + tdSql.query("select 'dc' as options from stb where type = 1 limit 1 union all select 'adc' as options from stb where type = 2 limit 1") + tdSql.checkData(0, 0, "dc") + tdSql.checkData(1, 0, "adc") + + tdSql.error("select 'dc' as options from stb where type = 1 limit 1 union all select 'ad' as city from stb where type = 2 limit 1") + + # for defect https://jira.taosdata.com:18080/browse/TD-4017 + tdSql.execute("alter table stb add column col int") + tdSql.execute("insert into tb1 values(%d, 'option1', 'beijing', 10)" % (self.ts + 1000)) + + tdSql.query("select 'dc' as options from stb where col > 10 limit 1") + tdSql.checkRows(0) + + tdSql.query("select 'dcs' as options from stb where col > 200 limit 1 union all select 'aaa' as options from stb limit 10") + tdSql.checkData(0, 0, 'aaa') + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/simpletest_no_sudo.sh b/tests/pytest/simpletest_no_sudo.sh index 61faf3df523f94562d1eeb2922ad4a4b3cc847e0..36edfc027fc12487a9e1d8fd66da623d219e8365 100755 --- a/tests/pytest/simpletest_no_sudo.sh +++ b/tests/pytest/simpletest_no_sudo.sh @@ -4,7 +4,7 @@ # 2. No files are needed outside the development tree, everything is done in the local source code directory # First we need to set up a path for Python to find our own TAOS modules, so that "import" can work. -export PYTHONPATH=$(pwd)/../../src/connector/python/linux/python3 +export PYTHONPATH=$(pwd)/../../src/connector/python # Then let us set up the library path so that our compiled SO file can be loaded by Python export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/../../build/build/lib diff --git a/tests/pytest/stable/insert.py b/tests/pytest/stable/insert.py index 0ef816da8d02fc6dcb48954435aad51342248e56..ef5635c77ce04ddd33354e1754dc70b2c9f8b6a5 100644 --- a/tests/pytest/stable/insert.py +++ b/tests/pytest/stable/insert.py @@ -72,6 +72,9 @@ class TDTestCase: tdSql.query("describe db.stb") tdSql.checkRows(3) + tdSql.error("drop stable if exists db.dev_01") + tdSql.error("drop stable if exists db.dev_02") + tdSql.execute("alter stable db.stb add tag t1 int") tdSql.query("describe db.stb") tdSql.checkRows(4) @@ -80,6 +83,13 @@ class TDTestCase: tdSql.query("show stables") tdSql.checkRows(1) + tdSql.error("drop stable if exists db.dev_001") + tdSql.error("drop stable if exists db.dev_002") + + for i in range(10): + tdSql.execute("drop stable if exists db.stb") + tdSql.query("show stables") + tdSql.checkRows(1) def stop(self): tdSql.close() diff --git a/tests/pytest/stream/cqSupportBefore1970.py b/tests/pytest/stream/cqSupportBefore1970.py index 75587d1743c7b57b6d53bb43c3c04bdc52e93aad..01ba5234fcabb96a4c3c7c28e405c316d6e7dc7d 100644 --- a/tests/pytest/stream/cqSupportBefore1970.py +++ b/tests/pytest/stream/cqSupportBefore1970.py @@ -75,7 +75,7 @@ class TDTestCase: self.insertnow() self.cq() self.querycq() - + # after wal and sync, check again tdSql.query("show dnodes") index = tdSql.getData(0, 0) diff --git a/tests/pytest/table/column_name.py b/tests/pytest/table/column_name.py index a180d3f752f36626c1c55adade24584a208dbe8d..0f24b98f3a9cd1d697c3972f5c8df5f49e82ca72 100644 --- a/tests/pytest/table/column_name.py +++ b/tests/pytest/table/column_name.py @@ -88,10 +88,9 @@ class TDTestCase: # TSIM: # TSIM: print =============== step4 tdLog.info('=============== step4') - # TSIM: sql create table $tb (ts timestamp, - # a0123456789012345678901234567890123456789 int) + # TSIM: sql create table $tb (ts timestamp, a0123456789012345678901234567890123456789 int) getMaxColNum = "grep -w '#define TSDB_COL_NAME_LEN' ../../src/inc/taosdef.h|awk '{print $3}'" - boundary = int(subprocess.check_output(getMaxColNum, shell=True)) + boundary = int(subprocess.check_output(getMaxColNum, shell=True)) - 1 tdLog.info("get max column name length is %d" % boundary) chars = string.ascii_uppercase + string.ascii_lowercase diff --git a/tests/pytest/test.py b/tests/pytest/test.py index c7781f20873066b02416049e8c472e07c0c3e328..65abd3ef93555b6747f022595b20c5989aa851cb 100644 --- a/tests/pytest/test.py +++ b/tests/pytest/test.py @@ -10,7 +10,7 @@ # ################################################################### # install pip -# pip install src/connector/python/linux/python2/ +# pip install src/connector/python/ # -*- coding: utf-8 -*- import sys diff --git a/tests/pytest/test.sh b/tests/pytest/test.sh index fbb9ba9879e0b22948fd448bba1bf5d0b7700497..4e74341f7075b50329a49aa3eccd09f68b733f20 100755 --- a/tests/pytest/test.sh +++ b/tests/pytest/test.sh @@ -13,7 +13,7 @@ else fi TAOSD_DIR=`find $TAOS_DIR -name "taosd"|grep bin|head -n1` LIB_DIR=`echo $TAOSD_DIR|rev|cut -d '/' -f 3,4,5,6|rev`/lib -export PYTHONPATH=$(pwd)/../../src/connector/python/linux/python3 +export PYTHONPATH=$(pwd)/../../src/connector/python export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIB_DIR if [[ "$1" == *"test.py"* ]]; then diff --git a/tests/pytest/testCompress.py b/tests/pytest/testCompress.py index 0f5d9ef3b1b6898fa724eb9330f413e60fedd22b..1ad032f05f7ae0216ceb74747d25d49ed2146362 100644 --- a/tests/pytest/testCompress.py +++ b/tests/pytest/testCompress.py @@ -10,7 +10,7 @@ # ################################################################### # install pip -# pip install src/connector/python/linux/python2/ +# pip install src/connector/python/ # -*- coding: utf-8 -*- import sys diff --git a/tests/pytest/testMinTablesPerVnode.py b/tests/pytest/testMinTablesPerVnode.py index 91cea833e7ad27e09defc9c43a6de820d05f8b33..a111113c07224377962d5acff66c058dde5e8439 100644 --- a/tests/pytest/testMinTablesPerVnode.py +++ b/tests/pytest/testMinTablesPerVnode.py @@ -10,7 +10,7 @@ # ################################################################### # install pip -# pip install src/connector/python/linux/python2/ +# pip install src/connector/python/ # -*- coding: utf-8 -*- import sys diff --git a/tests/pytest/testNoCompress.py b/tests/pytest/testNoCompress.py index e3b40b4426f80080cfe48928851ec1e08c552dd7..d41055c755264fbc503df4709b8bd3eedaa11b07 100644 --- a/tests/pytest/testNoCompress.py +++ b/tests/pytest/testNoCompress.py @@ -10,7 +10,7 @@ # ################################################################### # install pip -# pip install src/connector/python/linux/python2/ +# pip install src/connector/python/ # -*- coding: utf-8 -*- import sys diff --git a/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json b/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json index 8e40ad812d0ad0a9e243fc2e371a9be35fa0f7f2..c67582fb56288c978a4d86d7e862ee29f95f820c 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-1s1tnt1r.json @@ -55,8 +55,8 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1}, {"type": "BINARY", "len": 16, "count":1}, {"type": "BINARY", "len": 32, "count":1}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}] }, { "name": "stb1", @@ -81,8 +81,8 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":4}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1}, {"type": "BINARY", "len": 16, "count":1}, {"type": "BINARY", "len": 32, "count":1}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}] }] }] } diff --git a/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json b/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json index e741fd5c056c329a0a785b050dc2e94dd2dfd9ca..e3db5476b8d4cdb7cc8ea125fa0557b133b1c0b8 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-1s1tntmr.json @@ -55,8 +55,8 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1}, {"type": "BINARY", "len": 16, "count":1}, {"type": "BINARY", "len": 32, "count":1}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}] }, { "name": "stb1", @@ -81,8 +81,8 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1}, {"type": "BINARY", "len": 16, "count":1}, {"type": "BINARY", "len": 32, "count":1}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}] }] }] } diff --git a/tests/pytest/tools/taosdemoAllTest/insert-disorder.json b/tests/pytest/tools/taosdemoAllTest/insert-disorder.json index fddaa4b4b99d441fb81fcd350ad2d6a4279f9c4e..f2dca662fddc5991a9dcdb8371dc0e4086868190 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-disorder.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-disorder.json @@ -6,7 +6,7 @@ "user": "root", "password": "taosdata", "thread_count": 4, - "": 4, + "thread_count_create_tbl": 4, "result_file":"./insert_res.txt", "confirm_parameter_prompt": "no", "insert_interval": 0, diff --git a/tests/pytest/tools/taosdemoAllTest/insert-illegal-columns.json b/tests/pytest/tools/taosdemoAllTest/insert-illegal.json similarity index 89% rename from tests/pytest/tools/taosdemoAllTest/insert-illegal-columns.json rename to tests/pytest/tools/taosdemoAllTest/insert-illegal.json index 53735dc41342cde1cc9cb0a3376be07629464531..614402236ac2e1efa48d2647966f0c1cc425f475 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-illegal-columns.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-illegal.json @@ -11,8 +11,8 @@ "confirm_parameter_prompt": "no", "insert_interval": 0, "interlace_rows": 10, - "num_of_records_per_req": 100, - "max_sql_len": 10240000000, + "num_of_records_per_req": "-asdf", + "max_sql_len": 1024000, "databases": [{ "dbinfo": { "name": "db", @@ -41,12 +41,12 @@ "batch_create_tbl_num": 10, "data_source": "rand", "insert_mode": "taosc", - "insert_rows": 1000, + "insert_rows": 10000, "childtable_limit": 0, "childtable_offset":0, "multi_thread_write_one_tbl": "no", "interlace_rows": 0, - "insert_interval":0, + "insert_interval":-4, "max_sql_len": 1024000, "disorder_ratio": 0, "disorder_range": 1000, @@ -55,8 +55,8 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1005}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":7}] + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] }, { "name": "stb1", @@ -64,10 +64,10 @@ "childtable_count": 20, "childtable_prefix": "stb01_", "auto_create_table": "no", - "batch_create_tbl_num": 12, + "batch_create_tbl_num": "asdf", "data_source": "rand", "insert_mode": "taosc", - "insert_rows": 2000, + "insert_rows": 20000, "childtable_limit": 0, "childtable_offset":0, "multi_thread_write_one_tbl": "no", diff --git a/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json b/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json index c7c5150a060ff76221025def1d7c31194c52dfed..38975a75a7f1041ffec91d597c9fb28d8a95c7ce 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-interval-speed.json @@ -55,7 +55,7 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1}, {"type": "BINARY", "len": 16, "count":1}, {"type": "BINARY", "len": 32, "count":6}], "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] }, { @@ -81,8 +81,8 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":9}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1}, {"type": "BINARY", "len": 16, "count":1}, {"type": "BINARY", "len": 32, "count":1}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":1}] }] }] } diff --git a/tests/pytest/tools/taosdemoAllTest/insert-newdb.json b/tests/pytest/tools/taosdemoAllTest/insert-newdb.json index 72e380a66cb3cfd2b3bade57f000bbebbf29baf4..1a19ea00acb50a0140f55bde51ffe53429a099f0 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-newdb.json +++ b/tests/pytest/tools/taosdemoAllTest/insert-newdb.json @@ -55,7 +55,7 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":6}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1}, {"type": "BINARY", "len": 16, "count":1}, {"type": "BINARY", "len": 32, "count":1}], "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] }, { diff --git a/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar16384.json b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar16384.json new file mode 100644 index 0000000000000000000000000000000000000000..55be0198916e3737d185deaa231885fbfa607c66 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar16384.json @@ -0,0 +1,140 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "interlace_rows": 10, + "num_of_records_per_req": 10240000000, + "max_sql_len": 10240000000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 50, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb0", + "child_table_exists":"no", + "childtable_count": 1, + "childtable_prefix": "stb00_", + "auto_create_table": "no", + "batch_create_tbl_num": 10, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "BINARY", "len": 16374, "count":1}], + "tags": [{"type": "TINYINT", "count":12}, {"type": "BINARY", "len": 16, "count":2}] + }, + { + "name": "stb1", + "child_table_exists":"no", + "childtable_count": 1, + "childtable_prefix": "stb01_", + "auto_create_table": "no", + "batch_create_tbl_num": 12, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1, + "childtable_limit": 0, + "childtable_offset":0, + "multi_thread_write_one_tbl": "no", + "interlace_rows": 1000000, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "BINARY", "len": 16370, "count":1},{"type": "INT"}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + }, + { + "name": "stb2", + "child_table_exists":"no", + "childtable_count": 1, + "childtable_prefix": "stb01_", + "auto_create_table": "no", + "batch_create_tbl_num": 12, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1, + "childtable_limit": 0, + "childtable_offset":0, + "multi_thread_write_one_tbl": "no", + "interlace_rows": 1000000, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "BINARY", "len": 16375, "count":1},{"type": "INT"}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + }, + { + "name": "stb3", + "child_table_exists":"no", + "childtable_count": 1, + "childtable_prefix": "stb01_", + "auto_create_table": "no", + "batch_create_tbl_num": 12, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1, + "childtable_limit": 0, + "childtable_offset":0, + "multi_thread_write_one_tbl": "no", + "interlace_rows": 1000000, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "BINARY", "len": 16371, "count":1},{"type": "INT"}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + }] + }] +} diff --git a/tests/pytest/tools/taosdemoAllTest/insert-illegal-columns-count-0.json b/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json similarity index 82% rename from tests/pytest/tools/taosdemoAllTest/insert-illegal-columns-count-0.json rename to tests/pytest/tools/taosdemoAllTest/insertChildTab0.json index f6a103f001f312514b3c17df481f6c0daa35c410..1634e1cf065c1979d6e62c97daa56ba2bb3fe1e9 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-illegal-columns-count-0.json +++ b/tests/pytest/tools/taosdemoAllTest/insertChildTab0.json @@ -11,7 +11,7 @@ "confirm_parameter_prompt": "no", "insert_interval": 0, "interlace_rows": 10, - "num_of_records_per_req": 100, + "num_of_records_per_req": 10, "max_sql_len": 10240000000, "databases": [{ "dbinfo": { @@ -35,13 +35,13 @@ "super_tables": [{ "name": "stb0", "child_table_exists":"no", - "childtable_count": 10, + "childtable_count": 0, "childtable_prefix": "stb00_", "auto_create_table": "no", "batch_create_tbl_num": 10, "data_source": "rand", "insert_mode": "taosc", - "insert_rows": 1000, + "insert_rows": 1, "childtable_limit": 0, "childtable_offset":0, "multi_thread_write_one_tbl": "no", @@ -55,19 +55,19 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":0}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":7}] + "columns": [{"type": "BINARY", "len": 1, "count":1}], + "tags": [{"type": "TINYINT", "count":1}, {"type": "BINARY", "len": 16, "count":2}] }, { "name": "stb1", "child_table_exists":"no", - "childtable_count": 20, + "childtable_count": 10, "childtable_prefix": "stb01_", "auto_create_table": "no", "batch_create_tbl_num": 12, "data_source": "rand", "insert_mode": "taosc", - "insert_rows": 2000, + "insert_rows": 2, "childtable_limit": 0, "childtable_offset":0, "multi_thread_write_one_tbl": "no", @@ -81,7 +81,7 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "columns": [{"type": "BINARY", "len": 1, "count":1}], "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] }] }] diff --git a/tests/pytest/tools/taosdemoAllTest/insert-illegal-columns-lmax.json b/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json similarity index 81% rename from tests/pytest/tools/taosdemoAllTest/insert-illegal-columns-lmax.json rename to tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json index 17050278c8825fb4af9bbf8ed6edcc063a746007..f4e3ec8e9fad638910e644f624d6b4408163c340 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-illegal-columns-lmax.json +++ b/tests/pytest/tools/taosdemoAllTest/insertChildTabLess0.json @@ -11,7 +11,7 @@ "confirm_parameter_prompt": "no", "insert_interval": 0, "interlace_rows": 10, - "num_of_records_per_req": 100, + "num_of_records_per_req": 10, "max_sql_len": 10240000000, "databases": [{ "dbinfo": { @@ -35,13 +35,13 @@ "super_tables": [{ "name": "stb0", "child_table_exists":"no", - "childtable_count": 10, + "childtable_count": -1, "childtable_prefix": "stb00_", "auto_create_table": "no", "batch_create_tbl_num": 10, "data_source": "rand", "insert_mode": "taosc", - "insert_rows": 1000, + "insert_rows": 1, "childtable_limit": 0, "childtable_offset":0, "multi_thread_write_one_tbl": "no", @@ -55,19 +55,19 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1024}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":7}] + "columns": [{"type": "BINARY", "len": 1, "count":1}], + "tags": [{"type": "TINYINT", "count":1}, {"type": "BINARY", "len": 16, "count":2}] }, { "name": "stb1", "child_table_exists":"no", - "childtable_count": 20, + "childtable_count": 10, "childtable_prefix": "stb01_", "auto_create_table": "no", "batch_create_tbl_num": 12, "data_source": "rand", "insert_mode": "taosc", - "insert_rows": 2000, + "insert_rows": 2, "childtable_limit": 0, "childtable_offset":0, "multi_thread_write_one_tbl": "no", @@ -81,8 +81,8 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1004}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":7}] + "columns": [{"type": "BINARY", "len": 1, "count":1}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] }] }] } diff --git a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum1024.json b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum1024.json new file mode 100644 index 0000000000000000000000000000000000000000..42f6ef2f2fe90f7eac23778542475f152794a509 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNum1024.json @@ -0,0 +1,62 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "interlace_rows": 0, + "num_of_records_per_req": 1000, + "max_sql_len": 10240000000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 50, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb0", + "child_table_exists":"no", + "childtable_count": 10, + "childtable_prefix": "stb00_", + "auto_create_table": "no", + "batch_create_tbl_num": 10, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1000, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1004}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":7}] + }] + }] +} diff --git a/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge1024.json b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge1024.json new file mode 100644 index 0000000000000000000000000000000000000000..42461b2f6fba85093a6a45883608b49277669568 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/insertColumnsAndTagNumLarge1024.json @@ -0,0 +1,62 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "interlace_rows": 10000, + "num_of_records_per_req": 10000, + "max_sql_len": 10240000000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 50, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb0", + "child_table_exists":"no", + "childtable_count": 10, + "childtable_prefix": "stb00_", + "auto_create_table": "no", + "batch_create_tbl_num": 10, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1000, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1005}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":7}] + }] + }] +} diff --git a/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json b/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json new file mode 100644 index 0000000000000000000000000000000000000000..fd75f3b43ffa1e5f4c9cb7964ad218d15e0324fc --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/insertColumnsNum0.json @@ -0,0 +1,62 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "interlace_rows": 10, + "num_of_records_per_req": 100, + "max_sql_len": 10240000000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 50, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb0", + "child_table_exists":"no", + "childtable_count": 10, + "childtable_prefix": "stb00_", + "auto_create_table": "no", + "batch_create_tbl_num": 10, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1000, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":0}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":7}] + }] + }] +} diff --git a/tests/pytest/tools/taosdemoAllTest/insert-illegal-tags-count129.json b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json similarity index 77% rename from tests/pytest/tools/taosdemoAllTest/insert-illegal-tags-count129.json rename to tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json index 115c42b502951007aafa1b9c72de45bfcbb3f9fc..813eb9af0428d8455bda3c1a17ffdd61337cc617 100644 --- a/tests/pytest/tools/taosdemoAllTest/insert-illegal-tags-count129.json +++ b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReq0.json @@ -11,11 +11,11 @@ "confirm_parameter_prompt": "no", "insert_interval": 0, "interlace_rows": 10, - "num_of_records_per_req": 100, + "num_of_records_per_req": 0, "max_sql_len": 10240000000, "databases": [{ "dbinfo": { - "name": "db1", + "name": "db", "drop": "yes", "replica": 1, "days": 10, @@ -35,13 +35,13 @@ "super_tables": [{ "name": "stb0", "child_table_exists":"no", - "childtable_count": 10, + "childtable_count": 1, "childtable_prefix": "stb00_", "auto_create_table": "no", "batch_create_tbl_num": 10, "data_source": "rand", "insert_mode": "taosc", - "insert_rows": 1000, + "insert_rows": 1, "childtable_limit": 0, "childtable_offset":0, "multi_thread_write_one_tbl": "no", @@ -55,19 +55,19 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1}, {"type": "BIGINT", "count":1}, {"type": "float", "count":1}, {"type": "double", "count":1}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], - "tags": [{"type": "TINYINT", "count":127}, {"type": "BINARY", "len": 16, "count":2}] + "columns": [{"type": "BINARY", "len": 1, "count":1}], + "tags": [{"type": "TINYINT", "count":1}, {"type": "BINARY", "len": 16, "count":2}] }, { "name": "stb1", "child_table_exists":"no", - "childtable_count": 20, + "childtable_count": 2, "childtable_prefix": "stb01_", "auto_create_table": "no", "batch_create_tbl_num": 12, "data_source": "rand", "insert_mode": "taosc", - "insert_rows": 2000, + "insert_rows": 2, "childtable_limit": 0, "childtable_offset":0, "multi_thread_write_one_tbl": "no", @@ -81,7 +81,7 @@ "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", - "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "columns": [{"type": "BINARY", "len": 1, "count":1}], "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] }] }] diff --git a/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json new file mode 100644 index 0000000000000000000000000000000000000000..554115f3974b24746165e42e7309d9b4d3dd4a50 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json @@ -0,0 +1,88 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "interlace_rows": 10, + "num_of_records_per_req": -1, + "max_sql_len": 10240000000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 50, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb0", + "child_table_exists":"no", + "childtable_count": 1, + "childtable_prefix": "stb00_", + "auto_create_table": "no", + "batch_create_tbl_num": 10, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "BINARY", "len": 1, "count":1}], + "tags": [{"type": "TINYINT", "count":1}, {"type": "BINARY", "len": 16, "count":2}] + }, + { + "name": "stb1", + "child_table_exists":"no", + "childtable_count": 2, + "childtable_prefix": "stb01_", + "auto_create_table": "no", + "batch_create_tbl_num": 12, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "BINARY", "len": 1, "count":1}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + }] + }] +} diff --git a/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum1024.json b/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum1024.json new file mode 100644 index 0000000000000000000000000000000000000000..7c12a62764ecd129342d916092cf732fe202151f --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/insertSigcolumnsNum1024.json @@ -0,0 +1,62 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "interlace_rows": 10, + "num_of_records_per_req": 100, + "max_sql_len": 10240000000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 50, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb0", + "child_table_exists":"no", + "childtable_count": 10, + "childtable_prefix": "stb00_", + "auto_create_table": "no", + "batch_create_tbl_num": 10, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1000, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "DOUBLE", "count":1024}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":7}] + }] + }] +} diff --git a/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json b/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json new file mode 100644 index 0000000000000000000000000000000000000000..5cf8114472e00d5ebc90b5dc762f22f9698f7d76 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/insertTagsNumLarge128.json @@ -0,0 +1,62 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "interlace_rows": 10, + "num_of_records_per_req": 100, + "max_sql_len": 10240000000, + "databases": [{ + "dbinfo": { + "name": "db1", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 50, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb0", + "child_table_exists":"no", + "childtable_count": 10, + "childtable_prefix": "stb00_", + "auto_create_table": "no", + "batch_create_tbl_num": 10, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1000, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":1}, {"type": "BIGINT", "count":1}, {"type": "float", "count":1}, {"type": "double", "count":1}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "tags": [{"type": "TINYINT", "count":127}, {"type": "BINARY", "len": 16, "count":2}] + }] + }] +} diff --git a/tests/pytest/tools/taosdemoAllTest/insertTimestepMulRowsLargeint16.json b/tests/pytest/tools/taosdemoAllTest/insertTimestepMulRowsLargeint16.json new file mode 100644 index 0000000000000000000000000000000000000000..b563dcc94b3c69256f4b2a754e9244cef7874944 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/insertTimestepMulRowsLargeint16.json @@ -0,0 +1,65 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "localhost", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "databases": [ + { + "dbinfo": { + "name": "blf", + "drop": "yes" + }, + "super_tables": [ + { + "name": "p_0_topics", + "child_table_exists": "no", + "childtable_count": 10, + "childtable_prefix": "p_0_topics_", + "auto_create_table": "no", + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 525600, + "multi_thread_write_one_tbl": "no", + "interlace_rows": 1000, + "max_sql_len": 1048576, + "disorder_ratio": 0, + "disorder_range": 1000, + "timestamp_step": 60000, + "start_timestamp": "2019-10-01 00:00:00.000", + "sample_format": "csv", + "sample_file": "./sample.csv", + "tags_file": "", + "columns": [ + { + "type": "INT", + "count": 1 + }, + { + "type": "FLOAT", + "count": 1 + }, + { + "type": "BINARY", + "len": 12, + "count": 1 + } + ], + "tags": [ + { + "type": "BINARY", + "len": 12, + "count": 10 + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/pytest/tools/taosdemoAllTest/query-interrupt.json b/tests/pytest/tools/taosdemoAllTest/query-interrupt.json new file mode 100644 index 0000000000000000000000000000000000000000..643cbf09c83f7191620dee32787caa9f5754ad18 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/query-interrupt.json @@ -0,0 +1,62 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "interlace_rows": 100, + "num_of_records_per_req": 1000, + "max_sql_len": 1024000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 50, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb0", + "child_table_exists":"no", + "childtable_count": 100, + "childtable_prefix": "stb00_", + "auto_create_table": "no", + "batch_create_tbl_num": 20, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 150000, + "childtable_limit": -1, + "childtable_offset":0, + "multi_thread_write_one_tbl": "no", + "interlace_rows": 1000, + "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": "./sample.csv", + "tags_file": "", + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + }] + }] +} diff --git a/tests/pytest/tools/taosdemoAllTest/query-interrupt.py b/tests/pytest/tools/taosdemoAllTest/query-interrupt.py new file mode 100644 index 0000000000000000000000000000000000000000..270bfd8b60f559c370eb921cf74fe4f7b82ae06e --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/query-interrupt.py @@ -0,0 +1,88 @@ +################################################################### +# 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 subprocess +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): + tdSql.prepare() + buildPath = self.getBuildPath() + if (buildPath == ""): + tdLog.exit("taosd not found!") + else: + tdLog.info("taosd found in %s" % buildPath) + binPath = buildPath+ "/build/bin/" + + # # insert 1000w rows in stb0 + os.system("%staosdemo -f tools/taosdemoAllTest/query-interrupt.json -y " % binPath) + tdSql.execute("use db") + tdSql.query("select count (tbname) from stb0") + tdSql.checkData(0, 0,60) + tdSql.query("select count(*) from stb0") + tdSql.checkData(0, 0, 6000000) + os.system('%staosdemo -f tools/taosdemoAllTest/queryall.json -y & ' % binPath) + time.sleep(2) + query_pid = int(subprocess.getstatusoutput('ps aux|grep "taosdemoAllTest/queryall.json" |grep -v "grep"|awk \'{print $2}\'')[1]) + taosd_cpu_load_1 = float(subprocess.getstatusoutput('top -n 1 -b -p $(ps aux|grep "bin/taosd -c"|grep -v "grep" |awk \'{print $2}\')|awk \'END{print}\' |awk \'{print $9}\'')[1]) + if taosd_cpu_load_1 > 10.0 : + os.system("kill -9 %d" % query_pid) + time.sleep(5) + taosd_cpu_load_2 = float(subprocess.getstatusoutput('top -n 1 -b -p $(ps aux|grep "bin/taosd -c"|grep -v "grep" |awk \'{print $2}\')|awk \'END{print}\' |awk \'{print $9}\'')[1]) + if taosd_cpu_load_2 < 10.0 : + suc_kill = 60 + else: + suc_kill = 10 + print("taosd_cpu_load is higher than 10%") + else: + suc_kill = 20 + print("taosd_cpu_load is still less than 10%") + tdSql.query("select count (tbname) from stb0") + tdSql.checkData(0, 0, "%d" % suc_kill) + os.system("rm -rf querySystemInfo*") + os.system("rm -rf insert_res.txt") + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/tools/taosdemoAllTest/queryQps.json b/tests/pytest/tools/taosdemoAllTest/queryQps.json new file mode 100644 index 0000000000000000000000000000000000000000..67a1cf3eb39c045192b5d35f698e38506777cef2 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/queryQps.json @@ -0,0 +1,37 @@ +{ + "filetype": "query", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "confirm_parameter_prompt": "no", + "databases": "db", + "query_times": 1, + "specified_table_query": { + "query_interval": 0, + "concurrent": 1, + "sqls": [ + { + "sql": "select last_row(*) from stb00_0", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_99 ", + "result": "./query_res1.txt" + + }] + }, + "super_table_query": { + "stblname": "stb1", + "query_interval":0, + "threads": 1, + "sqls": [ + { + "sql": "select last_row(ts) from xxxx", + "result": "./query_res2.txt" + } + ] + } + } + \ No newline at end of file diff --git a/tests/pytest/tools/taosdemoAllTest/querySpeciMutisql100.json b/tests/pytest/tools/taosdemoAllTest/querySpeciMutisql100.json new file mode 100644 index 0000000000000000000000000000000000000000..4aa1c0b4dd1c8522ebac4b032387c974331f1a5d --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/querySpeciMutisql100.json @@ -0,0 +1,429 @@ +{ + "filetype": "query", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "confirm_parameter_prompt": "no", + "databases": "db", + "query_times": 2, + "specified_table_query": { + "query_interval": 1, + "concurrent": 3, + "sqls": [ + { + "sql": "select last_row(*) from stb00_0", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_1", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_2", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_3", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_4", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_5", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_6", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_7", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_8", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_9", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_10 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_11 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_12 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_13 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_14 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_15 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_16 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_17 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_18 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_19 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_20 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_21 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_22 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_23 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_24 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_25 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_26 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_27 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_28 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_29 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_30 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_31 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_32 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_33 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_34 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_35 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_36 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_37 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_38 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_39 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_40 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_41 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_42 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_43 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_44 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_45 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_46 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_47 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_48 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_49 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_50 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_51 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_52 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_53 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_54 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_55 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_56 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_57 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_58 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_59 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_60", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_61", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_62", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_63", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_64", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_65", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_66", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_67", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_68", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_69", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_70 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_71 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_72 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_73 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_74 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_75 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_76 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_77 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_78 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_79 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_80 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_81 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_82 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_83 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_84 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_85 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_86 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_87 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_88 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_89 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_90 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_91 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_92 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_93 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_94 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_95 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_96 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_97 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_98 ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from stb00_99 ", + "result": "./query_res0.txt" + + }] + }, + "super_table_query": { + "stblname": "stb1", + "query_interval": 1, + "threads": 3, + "sqls": [ + { + "sql": "select last_row(ts) from xxxx", + "result": "./query_res2.txt" + } + ] + } +} + \ No newline at end of file diff --git a/tests/pytest/tools/taosdemoAllTest/querySuperMutisql100.json b/tests/pytest/tools/taosdemoAllTest/querySuperMutisql100.json new file mode 100644 index 0000000000000000000000000000000000000000..c85713c94c3dd6fe5ee55bcc36badcce474a746e --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/querySuperMutisql100.json @@ -0,0 +1,419 @@ +{ + "filetype": "query", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "confirm_parameter_prompt": "no", + "databases": "db", + "query_times": 3, + "super_table_query": { + "stblname": "stb0", + "query_interval": 10000, + "concurrent": 9, + "sqls": [ + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select last_row(*) from xxxx ", + "result": "./query_res0.txt" + }, + { + "sql": "select * from xxxx ", + "result": "./query_res0.txt" + + }] + } + } + \ No newline at end of file diff --git a/tests/pytest/tools/taosdemoAllTest/queryall.json b/tests/pytest/tools/taosdemoAllTest/queryall.json new file mode 100644 index 0000000000000000000000000000000000000000..bbc3b9717c6afa8d54d5f48726afe6d4f87be528 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/queryall.json @@ -0,0 +1,14 @@ +{ + "filetype":"query", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "confirm_parameter_prompt": "no", + "databases": "db", + "specified_table_query": + {"query_interval":1, "concurrent":1, + "sqls": [{"sql": "select * from stb0", "result": ""}] + } +} \ No newline at end of file diff --git a/tests/pytest/tools/taosdemoAllTest/speciQueryInsertdata.json b/tests/pytest/tools/taosdemoAllTest/speciQueryInsertdata.json index ec9cb5a40da9a85928dcc7aea4abb6c96ab36976..79471be2044d3ea7c637b4b1e500cfcc8e6413a9 100644 --- a/tests/pytest/tools/taosdemoAllTest/speciQueryInsertdata.json +++ b/tests/pytest/tools/taosdemoAllTest/speciQueryInsertdata.json @@ -69,7 +69,7 @@ "insert_rows": 200, "childtable_limit": 0, "childtable_offset": 0, - "interlace_rows": 0, + "interlace_rows": 0 , "insert_interval": 0, "max_sql_len": 1024000, "disorder_ratio": 0, diff --git a/tests/pytest/tools/taosdemoAllTest/speciQueryRestful.json b/tests/pytest/tools/taosdemoAllTest/speciQueryRestful.json new file mode 100644 index 0000000000000000000000000000000000000000..bc3a66f43c598431b6f582f56f89cabb9bbe6efe --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/speciQueryRestful.json @@ -0,0 +1,38 @@ +{ + "filetype": "query", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "confirm_parameter_prompt": "no", + "databases": "db", + "query_times": 2, + "query_mode": "rest", + "specified_table_query": { + "query_interval": 1, + "concurrent": 3, + "sqls": [ + { + "sql": "select last_row(*) from db.stb0 ", + "result": "./query_res0.txt" + }, + { + "sql": "select count(*) from db.stb00_1", + "result": "./query_res1.txt" + } + ] + }, + "super_table_query": { + "stblname": "stb1", + "query_interval": 1, + "threads": 3, + "sqls": [ + { + "sql": "select last_row(ts) from xxxx", + "result": "./query_res2.txt" + } + ] + } + } + diff --git a/tests/pytest/tools/taosdemoAllTest/speciQuery.json b/tests/pytest/tools/taosdemoAllTest/speciQueryTaosc.json similarity index 96% rename from tests/pytest/tools/taosdemoAllTest/speciQuery.json rename to tests/pytest/tools/taosdemoAllTest/speciQueryTaosc.json index 5e99e80108d434da5b0010394e2aca97d58ea7a7..fece4e71c584ce18b14f70a54dbc7e9abd6130a5 100644 --- a/tests/pytest/tools/taosdemoAllTest/speciQuery.json +++ b/tests/pytest/tools/taosdemoAllTest/speciQueryTaosc.json @@ -8,6 +8,7 @@ "confirm_parameter_prompt": "no", "databases": "db", "query_times": 2, + "query_mode": "taosc", "specified_table_query": { "query_interval": 1, "concurrent": 3, diff --git a/tests/pytest/tools/taosdemoAllTest/sub.json b/tests/pytest/tools/taosdemoAllTest/sub.json new file mode 100644 index 0000000000000000000000000000000000000000..fe3c892a76bcc30678f60127d28ce79bf8682c18 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/sub.json @@ -0,0 +1,37 @@ +{ + "filetype":"subscribe", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "databases": "db", + "confirm_parameter_prompt": "no", + "specified_table_query": + { + "concurrent":1, + "mode":"sync", + "interval":0, + "restart":"yes", + "keepProgress":"yes", + "sqls": [ + { + "sql": "select * from stb00_0 ;", + "result": "./subscribe_res0.txt" + }] + }, + "super_table_query": + { + "stblname": "stb0", + "threads":1, + "mode":"sync", + "interval":10000, + "restart":"yes", + "keepProgress":"yes", + "sqls": [ + { + "sql": "select * from xxxx where ts > '2021-02-25 11:35:00.000' ;", + "result": "./subscribe_res1.txt" + }] + } + } \ No newline at end of file diff --git a/tests/pytest/tools/taosdemoAllTest/subInsertdata.json b/tests/pytest/tools/taosdemoAllTest/subInsertdata.json new file mode 100644 index 0000000000000000000000000000000000000000..7d14d0ad4b888fc099becb176e84af54bb769f50 --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/subInsertdata.json @@ -0,0 +1,61 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "interlace_rows": 0, + "num_of_records_per_req": 3000, + "max_sql_len": 1024000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 16, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb0", + "child_table_exists":"no", + "childtable_count": 1, + "childtable_prefix": "stb00_", + "auto_create_table": "no", + "batch_create_tbl_num": 10, + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1, + "childtable_limit": 0, + "childtable_offset": 0, + "interlace_rows": 0, + "insert_interval": 0, + "max_sql_len": 1024000, + "disorder_ratio": 0, + "disorder_range": 0, + "timestamp_step": 1000, + "start_timestamp": "2021-02-25 10:00:00.000", + "sample_format": "csv", + "sample_file": "./sample.csv", + "tags_file": "", + "columns": [{"type": "BINARY", "len":50, "count":1}, {"type": "BINARY", "len": 16, "count":1}, {"type": "INT"}, {"type": "DOUBLE", "count":1}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + }] + }] +} \ No newline at end of file diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestInsertWithJson.py b/tests/pytest/tools/taosdemoAllTest/taosdemoTestInsertWithJson.py index 2dd50bf63906f8e74ad9fffc6518d40ac017939a..5ecc4d70b293e131ae5037c3e1bc556f9e933a19 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestInsertWithJson.py +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestInsertWithJson.py @@ -153,19 +153,56 @@ class TDTestCase: tdSql.checkData(0, 0, 160) - # insert: let parament in json file is illegal ,i need know how to write exception. + # insert: let parament in json file is illegal, it'll expect error. tdSql.execute("drop database if exists db") - os.system("%staosdemo -f tools/taosdemoAllTest/insert-illegal-columns.json -y " % binPath) + os.system("%staosdemo -f tools/taosdemoAllTest/insertColumnsAndTagNumLarge1024.json -y " % binPath) tdSql.error("use db") - os.system("%staosdemo -f tools/taosdemoAllTest/insert-illegal-columns-lmax.json -y " % binPath) + tdSql.execute("drop database if exists db") + os.system("%staosdemo -f tools/taosdemoAllTest/insertSigcolumnsNum1024.json -y " % binPath) tdSql.error("select * from db.stb0") - os.system("%staosdemo -f tools/taosdemoAllTest/insert-illegal-columns-count-0.json -y " % binPath) - tdSql.execute("use db") + tdSql.execute("drop database if exists db") + os.system("%staosdemo -f tools/taosdemoAllTest/insertColumnsAndTagNum1024.json -y " % binPath) tdSql.query("select count(*) from db.stb0") - tdSql.checkData(0, 0, 10000) + tdSql.checkData(0, 0, 10000) tdSql.execute("drop database if exists db") - os.system("%staosdemo -f tools/taosdemoAllTest/insert-illegal-tags-count129.json -y " % binPath) + os.system("%staosdemo -f tools/taosdemoAllTest/insertColumnsNum0.json -y " % binPath) + tdSql.execute("use db") + tdSql.query("show stables like 'stb0%' ") + tdSql.checkData(0, 2, 11) + tdSql.execute("drop database if exists db") + os.system("%staosdemo -f tools/taosdemoAllTest/insertTagsNumLarge128.json -y " % binPath) tdSql.error("use db1") + tdSql.execute("drop database if exists db") + os.system("%staosdemo -f tools/taosdemoAllTest/insertBinaryLenLarge16374AllcolLar16384.json -y " % binPath) + tdSql.query("select count(*) from db.stb0") + tdSql.checkRows(1) + tdSql.query("select count(*) from db.stb1") + tdSql.checkRows(1) + tdSql.error("select * from db.stb3") + tdSql.error("select * from db.stb2") + tdSql.execute("drop database if exists db") + os.system("%staosdemo -f tools/taosdemoAllTest/insertNumOfrecordPerReq0.json -y " % binPath) + tdSql.error("select count(*) from db.stb0") + tdSql.execute("drop database if exists db") + os.system("%staosdemo -f tools/taosdemoAllTest/insertNumOfrecordPerReqless0.json -y " % binPath) + tdSql.error("use db") + tdSql.execute("drop database if exists db") + os.system("%staosdemo -f tools/taosdemoAllTest/insertChildTab0.json -y " % binPath) + tdSql.error("use db") + tdSql.execute("drop database if exists db") + os.system("%staosdemo -f tools/taosdemoAllTest/insertChildTabLess0.json -y " % binPath) + tdSql.error("use db") + tdSql.execute("drop database if exists blf") + os.system("%staosdemo -f tools/taosdemoAllTest/insertTimestepMulRowsLargeint16.json -y " % binPath) + tdSql.execute("use blf") + tdSql.query("select ts from blf.p_0_topics_7 limit 262800,1") + tdSql.checkData(0, 0, "2020-03-31 12:00:00.000") + tdSql.query("select first(ts) from blf.p_0_topics_2") + tdSql.checkData(0, 0, "2019-10-01 00:00:00") + tdSql.query("select last(ts) from blf.p_0_topics_6 ") + tdSql.checkData(0, 0, "2020-09-29 23:59:00") + + # insert: timestamp and step os.system("%staosdemo -f tools/taosdemoAllTest/insert-timestep.json -y " % binPath) diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py b/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py index 00b387e398bfba06efaeeaf1072905210b9ae99e..643cad942c6586486640ba125d520b46c93e3465 100644 --- a/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestQueryWithJson.py @@ -49,10 +49,9 @@ class TDTestCase: tdLog.info("taosd found in %s" % buildPath) binPath = buildPath+ "/build/bin/" - # insert: drop and child_table_exists combination test - # insert: using parament "childtable_offset and childtable_limit" to control table'offset point and offset + # query: query specified table and query super table os.system("%staosdemo -f tools/taosdemoAllTest/speciQueryInsertdata.json" % binPath) - os.system("%staosdemo -f tools/taosdemoAllTest/speciQuery.json" % binPath) + os.system("%staosdemo -f tools/taosdemoAllTest/speciQueryTaosc.json" % binPath) os.system("cat query_res0.txt* |sort -u > all_query_res0.txt") os.system("cat query_res1.txt* |sort -u > all_query_res1.txt") os.system("cat query_res2.txt* |sort -u > all_query_res2.txt") @@ -75,9 +74,55 @@ class TDTestCase: timest = d2.strftime("%Y-%m-%d %H:%M:%S.%f") tdSql.query("select last_row(ts) from stb1") tdSql.checkData(0, 0, "%s" % timest) + + # # delete useless files + # os.system("rm -rf ./insert_res.txt") + # os.system("rm -rf tools/taosdemoAllTest/*.py.sql") + # os.system("rm -rf ./querySystemInfo*") + # os.system("rm -rf ./query_res*") + # os.system("rm -rf ./all_query*") + # os.system("rm -rf ./test_query_res0.txt") + + + # # use restful api to query + # os.system("%staosdemo -f tools/taosdemoAllTest/speciQueryInsertdata.json" % binPath) + # os.system("%staosdemo -f tools/taosdemoAllTest/speciQueryRestful.json" % binPath) + # os.system("cat query_res0.txt* |sort -u > all_query_res0.txt") + # os.system("cat query_res1.txt* |sort -u > all_query_res1.txt") + # # os.system("cat query_res2.txt* |sort -u > all_query_res2.txt") + # tdSql.execute("use db") + # tdSql.execute('create table result0 using stb0 tags(121,43,"beijing","beijing","beijing","beijing","beijing")') + # os.system("python3 tools/taosdemoAllTest/convertResFile.py") + # tdSql.execute("insert into result0 file './test_query_res0.txt'") + # tdSql.query("select ts from result0") + # tdSql.checkData(0, 0, "2020-11-01 00:00:00.099000") + # tdSql.query("select count(*) from result0") + # tdSql.checkData(0, 0, 1) + # with open('./all_query_res1.txt','r+') as f1: + # result1 = int(f1.readline()) + # tdSql.query("select count(*) from stb00_1") + # tdSql.checkData(0, 0, "%d" % result1) + + # with open('./all_query_res2.txt','r+') as f2: + # result2 = int(f2.readline()) + # d2 = datetime.fromtimestamp(result2/1000) + # timest = d2.strftime("%Y-%m-%d %H:%M:%S.%f") + # tdSql.query("select last_row(ts) from stb1") + # tdSql.checkData(0, 0, "%s" % timest) + + + + # query times less than or equal to 100 + os.system("%staosdemo -f tools/taosdemoAllTest/querySpeciMutisql100.json" % binPath) + os.system("%staosdemo -f tools/taosdemoAllTest/querySuperMutisql100.json" % binPath) + + # query result print QPS + os.system("%staosdemo -f tools/taosdemoAllTest/queryQps.json" % binPath) + + # delete useless files os.system("rm -rf ./insert_res.txt") - os.system("rm -rf tools/taosdemoAllTest/taosdemoTestQuerytWithJson.py.sql") + os.system("rm -rf tools/taosdemoAllTest/*.py.sql") os.system("rm -rf ./querySystemInfo*") os.system("rm -rf ./query_res*") os.system("rm -rf ./all_query*") diff --git a/tests/pytest/tools/taosdemoAllTest/taosdemoTestSubWithJson.py b/tests/pytest/tools/taosdemoAllTest/taosdemoTestSubWithJson.py new file mode 100644 index 0000000000000000000000000000000000000000..1275b6a8b5d9345147ad36351d4269f0968fff5d --- /dev/null +++ b/tests/pytest/tools/taosdemoAllTest/taosdemoTestSubWithJson.py @@ -0,0 +1,99 @@ +################################################################### +# 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 +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * +import time +from datetime import datetime + +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/" + + # query: query specified table and query super table + # os.system("%staosdemo -f tools/taosdemoAllTest/subInsertdata.json" % binPath) + # os.system("%staosdemo -f tools/taosdemoAllTest/sub.json" % binPath) + # os.system("cat query_res0.txt* |sort -u > all_query_res0.txt") + # os.system("cat query_res1.txt* |sort -u > all_query_res1.txt") + # os.system("cat query_res2.txt* |sort -u > all_query_res2.txt") + # tdSql.execute("use db") + # tdSql.execute('create table result0 using stb0 tags(121,43,"beijing","beijing","beijing","beijing","beijing")') + # os.system("python3 tools/taosdemoAllTest/convertResFile.py") + # tdSql.execute("insert into result0 file './test_query_res0.txt'") + # tdSql.query("select ts from result0") + # tdSql.checkData(0, 0, "2020-11-01 00:00:00.099000") + # tdSql.query("select count(*) from result0") + # tdSql.checkData(0, 0, 1) + # with open('./all_query_res1.txt','r+') as f1: + # result1 = int(f1.readline()) + # tdSql.query("select count(*) from stb00_1") + # tdSql.checkData(0, 0, "%d" % result1) + + # with open('./all_query_res2.txt','r+') as f2: + # result2 = int(f2.readline()) + # d2 = datetime.fromtimestamp(result2/1000) + # timest = d2.strftime("%Y-%m-%d %H:%M:%S.%f") + # tdSql.query("select last_row(ts) from stb1") + # tdSql.checkData(0, 0, "%s" % timest) + + + # # query times less than or equal to 100 + # os.system("%staosdemo -f tools/taosdemoAllTest/QuerySpeciMutisql100.json" % binPath) + # os.system("%staosdemo -f tools/taosdemoAllTest/QuerySuperMutisql100.json" % binPath) + + + + + # delete useless files + # os.system("rm -rf ./insert_res.txt") + # os.system("rm -rf tools/taosdemoAllTest/*.py.sql") + # os.system("rm -rf ./querySystemInfo*") + # os.system("rm -rf ./query_res*") + # os.system("rm -rf ./all_query*") + # os.system("rm -rf ./test_query_res0.txt") + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/tools/taosdemoPerformance.py b/tests/pytest/tools/taosdemoPerformance.py index b50180e2b3452b8f6f4d0701fa595582cc5a7937..a45393e22284d675584c5dddd71fc507bcb2563f 100644 --- a/tests/pytest/tools/taosdemoPerformance.py +++ b/tests/pytest/tools/taosdemoPerformance.py @@ -24,7 +24,7 @@ class taosdemoPerformace: self.host = "127.0.0.1" self.user = "root" self.password = "taosdata" - self.config = "/etc/taosperf" + self.config = "/etc/perf" self.conn = taos.connect( self.host, self.user, @@ -77,7 +77,7 @@ class taosdemoPerformace: insert_data = { "filetype": "insert", - "cfgdir": "/etc/taosperf", + "cfgdir": "/etc/perf", "host": "127.0.0.1", "port": 6030, "user": "root", @@ -104,7 +104,7 @@ class taosdemoPerformace: return output def insertData(self): - os.system("taosdemo -f %s > taosdemoperf.txt" % self.generateJson()) + os.system("taosdemo -f %s > taosdemoperf.txt 2>&1" % self.generateJson()) self.createTableTime = self.getCMDOutput("grep 'Spent' taosdemoperf.txt | awk 'NR==1{print $2}'") self.insertRecordsTime = self.getCMDOutput("grep 'Spent' taosdemoperf.txt | awk 'NR==2{print $2}'") self.recordsPerSecond = self.getCMDOutput("grep 'Spent' taosdemoperf.txt | awk 'NR==2{print $16}'") diff --git a/tests/pytest/tools/taosdemoTestWithJson.py b/tests/pytest/tools/taosdemoTestWithJson.py index f57af9ce5c7ce890a0a93c6081702d93954af138..b2ecd5497620bf5a0f90dd2e8529890423fd82a1 100644 --- a/tests/pytest/tools/taosdemoTestWithJson.py +++ b/tests/pytest/tools/taosdemoTestWithJson.py @@ -23,32 +23,32 @@ 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): tdSql.prepare() buildPath = self.getBuildPath() - if (buildPath == ""): + if buildPath == "": tdLog.exit("taosd not found!") else: tdLog.info("taosd found in %s" % buildPath) - binPath = buildPath+ "/build/bin/" - os.system("yes | %staosdemo -f tools/insert.json" % binPath) + binPath = buildPath + "/build/bin/" + os.system("%staosdemo -f tools/insert.json -y" % binPath) tdSql.execute("use db01") tdSql.query("select count(*) from stb01") diff --git a/tests/script/api/batchprepare.c b/tests/script/api/batchprepare.c new file mode 100644 index 0000000000000000000000000000000000000000..92253be78c89e7f6420cead370e2e365534f152b --- /dev/null +++ b/tests/script/api/batchprepare.c @@ -0,0 +1,4200 @@ +// TAOS standard API example. The same syntax as MySQL, but only a subet +// to compile: gcc -o prepare prepare.c -ltaos + +#include +#include +#include +#include "taos.h" +#include +#include +#include + +typedef struct { + TAOS *taos; + int idx; +}T_par; + +void taosMsleep(int mseconds); + +unsigned long long getCurrentTime(){ + struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) { + perror("Failed to get current time in ms"); + exit(EXIT_FAILURE); + } + + return (uint64_t)tv.tv_sec * 1000000ULL + (uint64_t)tv.tv_usec; +} + + + + + +int stmt_scol_func1(TAOS_STMT *stmt) { + struct { + int64_t ts; + int8_t b; + int8_t v1; + int16_t v2; + int32_t v4; + int64_t v8; + float f4; + double f8; + char bin[40]; + char blob[80]; + } v = {0}; + + TAOS_BIND params[10]; + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(v.ts); + params[0].buffer = &v.ts; + params[0].length = ¶ms[0].buffer_length; + params[0].is_null = NULL; + + params[1].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[1].buffer_length = sizeof(v.v1); + params[1].buffer = &v.v1; + params[1].length = ¶ms[1].buffer_length; + params[1].is_null = NULL; + + params[2].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[2].buffer_length = sizeof(v.v2); + params[2].buffer = &v.v2; + params[2].length = ¶ms[2].buffer_length; + params[2].is_null = NULL; + + params[3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[3].buffer_length = sizeof(v.f4); + params[3].buffer = &v.f4; + params[3].length = ¶ms[3].buffer_length; + params[3].is_null = NULL; + + params[4].buffer_type = TSDB_DATA_TYPE_BINARY; + params[4].buffer_length = sizeof(v.bin); + params[4].buffer = v.bin; + params[4].length = ¶ms[4].buffer_length; + params[4].is_null = NULL; + + params[5].buffer_type = TSDB_DATA_TYPE_BINARY; + params[5].buffer_length = sizeof(v.bin); + params[5].buffer = v.bin; + params[5].length = ¶ms[5].buffer_length; + params[5].is_null = NULL; + + char *sql = "insert into ? (ts, v1,v2,f4,bin,bin2) values(?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + for (int zz = 0; zz < 10; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + exit(1); + } + v.ts = 1591060628000 + zz * 10; + for (int i = 0; i < 10; ++i) { + v.ts += 1; + + v.b = (int8_t)(i+zz*10) % 2; + v.v1 = (int8_t)(i+zz*10); + v.v2 = (int16_t)((i+zz*10) * 2); + v.v4 = (int32_t)((i+zz*10) * 4); + v.v8 = (int64_t)((i+zz*10) * 8); + v.f4 = (float)((i+zz*10) * 40); + v.f8 = (double)((i+zz*10) * 80); + for (int j = 0; j < sizeof(v.bin) - 1; ++j) { + v.bin[j] = (char)((i)%10 + '0'); + } + + taos_stmt_bind_param(stmt, params); + taos_stmt_add_batch(stmt); + } + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + return 0; +} + + + +int stmt_scol_func2(TAOS_STMT *stmt) { + struct { + int64_t ts; + int8_t b; + int8_t v1; + int16_t v2; + int32_t v4; + int64_t v8; + float f4; + double f8; + char bin[40]; + char blob[80]; + } v = {0}; + + TAOS_BIND params[10]; + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(v.ts); + params[0].buffer = &v.ts; + params[0].length = ¶ms[0].buffer_length; + params[0].is_null = NULL; + + params[1].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[1].buffer_length = sizeof(v.v1); + params[1].buffer = &v.v1; + params[1].length = ¶ms[1].buffer_length; + params[1].is_null = NULL; + + params[2].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[2].buffer_length = sizeof(v.v2); + params[2].buffer = &v.v2; + params[2].length = ¶ms[2].buffer_length; + params[2].is_null = NULL; + + params[3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[3].buffer_length = sizeof(v.f4); + params[3].buffer = &v.f4; + params[3].length = ¶ms[3].buffer_length; + params[3].is_null = NULL; + + params[4].buffer_type = TSDB_DATA_TYPE_BINARY; + params[4].buffer_length = sizeof(v.bin); + params[4].buffer = v.bin; + params[4].length = ¶ms[4].buffer_length; + params[4].is_null = NULL; + + params[5].buffer_type = TSDB_DATA_TYPE_BINARY; + params[5].buffer_length = sizeof(v.bin); + params[5].buffer = v.bin; + params[5].length = ¶ms[5].buffer_length; + params[5].is_null = NULL; + + char *sql = "insert into m0 (ts, v1,v2,f4,bin,bin2) values(?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + for (int zz = 0; zz < 10; zz++) { + v.ts = 1591060628000 + zz * 10; + for (int i = 0; i < 10; ++i) { + v.ts += 1; + + v.b = (int8_t)(i+zz*10) % 2; + v.v1 = (int8_t)(i+zz*10); + v.v2 = (int16_t)((i+zz*10) * 2); + v.v4 = (int32_t)((i+zz*10) * 4); + v.v8 = (int64_t)((i+zz*10) * 8); + v.f4 = (float)((i+zz*10) * 40); + v.f8 = (double)((i+zz*10) * 80); + for (int j = 0; j < sizeof(v.bin) - 1; ++j) { + v.bin[j] = (char)((i)%10 + '0'); + } + + taos_stmt_bind_param(stmt, params); + taos_stmt_add_batch(stmt); + } + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + return 0; +} + + + + +//300 tables 60 records +int stmt_scol_func3(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[60]; + int8_t v1[60]; + int16_t v2[60]; + int32_t v4[60]; + int64_t v8[60]; + float f4[60]; + double f8[60]; + char bin[60][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 900000 * 60); + + int *lb = malloc(60 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + char* is_null = malloc(sizeof(char) * 60); + char* no_null = malloc(sizeof(char) * 60); + + for (int i = 0; i < 60; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 9000000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.v1; + params[i+1].length = NULL; + params[i+1].is_null = no_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+2].buffer_length = sizeof(int16_t); + params[i+2].buffer = v.v2; + params[i+2].length = NULL; + params[i+2].is_null = no_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+3].buffer_length = sizeof(float); + params[i+3].buffer = v.f4; + params[i+3].length = NULL; + params[i+3].is_null = no_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+4].buffer_length = 40; + params[i+4].buffer = v.bin; + params[i+4].length = lb; + params[i+4].is_null = no_null; + params[i+4].num = 10; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+5].buffer_length = 40; + params[i+5].buffer = v.bin; + params[i+5].length = lb; + params[i+5].is_null = no_null; + params[i+5].num = 10; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 54000000; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? (ts, v1,v2,f4,bin,bin2) values(?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 2; l++) { + for (int zz = 0; zz < 300; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + +//10 tables 10 records single column bind +int stmt_scol_func4(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[60]; + int8_t v1[60]; + int16_t v2[60]; + int32_t v4[60]; + int64_t v8[60]; + float f4[60]; + double f8[60]; + char bin[60][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1000 * 60); + + int *lb = malloc(60 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1000*10); + char* is_null = malloc(sizeof(char) * 60); + char* no_null = malloc(sizeof(char) * 60); + + for (int i = 0; i < 60; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 10000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 2; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = no_null; + params[i+1].num = 2; + + params[i+2].buffer_type = TSDB_DATA_TYPE_INT; + params[i+2].buffer_length = sizeof(int32_t); + params[i+2].buffer = v.v4; + params[i+2].length = NULL; + params[i+2].is_null = no_null; + params[i+2].num = 2; + + params[i+3].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+3].buffer_length = sizeof(int64_t); + params[i+3].buffer = v.v8; + params[i+3].length = NULL; + params[i+3].is_null = no_null; + params[i+3].num = 2; + + params[i+4].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+4].buffer_length = sizeof(double); + params[i+4].buffer = v.f8; + params[i+4].length = NULL; + params[i+4].is_null = no_null; + params[i+4].num = 2; + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 60000; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? (ts,b,v4,v8,f8) values(?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 10; l++) { + for (int zz = 0; zz < 10; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + for (int col=0; col < 10; ++col) { + taos_stmt_bind_single_param_batch(stmt, params + id++, col); + } + + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + +int stmt_func1(TAOS_STMT *stmt) { + struct { + int64_t ts; + int8_t b; + int8_t v1; + int16_t v2; + int32_t v4; + int64_t v8; + float f4; + double f8; + char bin[40]; + char blob[80]; + } v = {0}; + + TAOS_BIND params[10]; + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(v.ts); + params[0].buffer = &v.ts; + params[0].length = ¶ms[0].buffer_length; + params[0].is_null = NULL; + + params[1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[1].buffer_length = sizeof(v.b); + params[1].buffer = &v.b; + params[1].length = ¶ms[1].buffer_length; + params[1].is_null = NULL; + + params[2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[2].buffer_length = sizeof(v.v1); + params[2].buffer = &v.v1; + params[2].length = ¶ms[2].buffer_length; + params[2].is_null = NULL; + + params[3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[3].buffer_length = sizeof(v.v2); + params[3].buffer = &v.v2; + params[3].length = ¶ms[3].buffer_length; + params[3].is_null = NULL; + + params[4].buffer_type = TSDB_DATA_TYPE_INT; + params[4].buffer_length = sizeof(v.v4); + params[4].buffer = &v.v4; + params[4].length = ¶ms[4].buffer_length; + params[4].is_null = NULL; + + params[5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[5].buffer_length = sizeof(v.v8); + params[5].buffer = &v.v8; + params[5].length = ¶ms[5].buffer_length; + params[5].is_null = NULL; + + params[6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[6].buffer_length = sizeof(v.f4); + params[6].buffer = &v.f4; + params[6].length = ¶ms[6].buffer_length; + params[6].is_null = NULL; + + params[7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[7].buffer_length = sizeof(v.f8); + params[7].buffer = &v.f8; + params[7].length = ¶ms[7].buffer_length; + params[7].is_null = NULL; + + params[8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[8].buffer_length = sizeof(v.bin); + params[8].buffer = v.bin; + params[8].length = ¶ms[8].buffer_length; + params[8].is_null = NULL; + + params[9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[9].buffer_length = sizeof(v.bin); + params[9].buffer = v.bin; + params[9].length = ¶ms[9].buffer_length; + params[9].is_null = NULL; + + int is_null = 1; + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + for (int zz = 0; zz < 10; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + v.ts = 1591060628000 + zz * 10; + for (int i = 0; i < 10; ++i) { + v.ts += 1; + for (int j = 1; j < 10; ++j) { + params[j].is_null = ((i == j) ? &is_null : 0); + } + v.b = (int8_t)(i+zz*10) % 2; + v.v1 = (int8_t)(i+zz*10); + v.v2 = (int16_t)((i+zz*10) * 2); + v.v4 = (int32_t)((i+zz*10) * 4); + v.v8 = (int64_t)((i+zz*10) * 8); + v.f4 = (float)((i+zz*10) * 40); + v.f8 = (double)((i+zz*10) * 80); + for (int j = 0; j < sizeof(v.bin) - 1; ++j) { + v.bin[j] = (char)((i+zz)%10 + '0'); + } + + taos_stmt_bind_param(stmt, params); + taos_stmt_add_batch(stmt); + } + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + return 0; +} + + +int stmt_func2(TAOS_STMT *stmt) { + struct { + int64_t ts; + int8_t b; + int8_t v1; + int16_t v2; + int32_t v4; + int64_t v8; + float f4; + double f8; + char bin[40]; + char blob[80]; + } v = {0}; + + TAOS_BIND params[10]; + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(v.ts); + params[0].buffer = &v.ts; + params[0].length = ¶ms[0].buffer_length; + params[0].is_null = NULL; + + params[1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[1].buffer_length = sizeof(v.b); + params[1].buffer = &v.b; + params[1].length = ¶ms[1].buffer_length; + params[1].is_null = NULL; + + params[2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[2].buffer_length = sizeof(v.v1); + params[2].buffer = &v.v1; + params[2].length = ¶ms[2].buffer_length; + params[2].is_null = NULL; + + params[3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[3].buffer_length = sizeof(v.v2); + params[3].buffer = &v.v2; + params[3].length = ¶ms[3].buffer_length; + params[3].is_null = NULL; + + params[4].buffer_type = TSDB_DATA_TYPE_INT; + params[4].buffer_length = sizeof(v.v4); + params[4].buffer = &v.v4; + params[4].length = ¶ms[4].buffer_length; + params[4].is_null = NULL; + + params[5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[5].buffer_length = sizeof(v.v8); + params[5].buffer = &v.v8; + params[5].length = ¶ms[5].buffer_length; + params[5].is_null = NULL; + + params[6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[6].buffer_length = sizeof(v.f4); + params[6].buffer = &v.f4; + params[6].length = ¶ms[6].buffer_length; + params[6].is_null = NULL; + + params[7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[7].buffer_length = sizeof(v.f8); + params[7].buffer = &v.f8; + params[7].length = ¶ms[7].buffer_length; + params[7].is_null = NULL; + + params[8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[8].buffer_length = sizeof(v.bin); + params[8].buffer = v.bin; + params[8].length = ¶ms[8].buffer_length; + params[8].is_null = NULL; + + params[9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[9].buffer_length = sizeof(v.bin); + params[9].buffer = v.bin; + params[9].length = ¶ms[9].buffer_length; + params[9].is_null = NULL; + + int is_null = 1; + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + for (int l = 0; l < 100; l++) { + for (int zz = 0; zz < 10; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + v.ts = 1591060628000 + zz * 100 * l; + for (int i = 0; i < zz; ++i) { + v.ts += 1; + for (int j = 1; j < 10; ++j) { + params[j].is_null = ((i == j) ? &is_null : 0); + } + v.b = (int8_t)(i+zz*10) % 2; + v.v1 = (int8_t)(i+zz*10); + v.v2 = (int16_t)((i+zz*10) * 2); + v.v4 = (int32_t)((i+zz*10) * 4); + v.v8 = (int64_t)((i+zz*10) * 8); + v.f4 = (float)((i+zz*10) * 40); + v.f8 = (double)((i+zz*10) * 80); + for (int j = 0; j < sizeof(v.bin) - 1; ++j) { + v.bin[j] = (char)((i+zz)%10 + '0'); + } + + taos_stmt_bind_param(stmt, params); + taos_stmt_add_batch(stmt); + } + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + } + + + return 0; +} + + + + +int stmt_func3(TAOS_STMT *stmt) { + struct { + int64_t ts; + int8_t b; + int8_t v1; + int16_t v2; + int32_t v4; + int64_t v8; + float f4; + double f8; + char bin[40]; + char blob[80]; + } v = {0}; + + TAOS_BIND params[10]; + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(v.ts); + params[0].buffer = &v.ts; + params[0].length = ¶ms[0].buffer_length; + params[0].is_null = NULL; + + params[1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[1].buffer_length = sizeof(v.b); + params[1].buffer = &v.b; + params[1].length = ¶ms[1].buffer_length; + params[1].is_null = NULL; + + params[2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[2].buffer_length = sizeof(v.v1); + params[2].buffer = &v.v1; + params[2].length = ¶ms[2].buffer_length; + params[2].is_null = NULL; + + params[3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[3].buffer_length = sizeof(v.v2); + params[3].buffer = &v.v2; + params[3].length = ¶ms[3].buffer_length; + params[3].is_null = NULL; + + params[4].buffer_type = TSDB_DATA_TYPE_INT; + params[4].buffer_length = sizeof(v.v4); + params[4].buffer = &v.v4; + params[4].length = ¶ms[4].buffer_length; + params[4].is_null = NULL; + + params[5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[5].buffer_length = sizeof(v.v8); + params[5].buffer = &v.v8; + params[5].length = ¶ms[5].buffer_length; + params[5].is_null = NULL; + + params[6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[6].buffer_length = sizeof(v.f4); + params[6].buffer = &v.f4; + params[6].length = ¶ms[6].buffer_length; + params[6].is_null = NULL; + + params[7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[7].buffer_length = sizeof(v.f8); + params[7].buffer = &v.f8; + params[7].length = ¶ms[7].buffer_length; + params[7].is_null = NULL; + + params[8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[8].buffer_length = sizeof(v.bin); + params[8].buffer = v.bin; + params[8].length = ¶ms[8].buffer_length; + params[8].is_null = NULL; + + params[9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[9].buffer_length = sizeof(v.bin); + params[9].buffer = v.bin; + params[9].length = ¶ms[9].buffer_length; + params[9].is_null = NULL; + + int is_null = 1; + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + for (int l = 0; l < 100; l++) { + for (int zz = 0; zz < 10; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + v.ts = 1591060628000 + zz * 100 * l; + for (int i = 0; i < zz; ++i) { + v.ts += 1; + for (int j = 1; j < 10; ++j) { + params[j].is_null = ((i == j) ? &is_null : 0); + } + v.b = (int8_t)(i+zz*10) % 2; + v.v1 = (int8_t)(i+zz*10); + v.v2 = (int16_t)((i+zz*10) * 2); + v.v4 = (int32_t)((i+zz*10) * 4); + v.v8 = (int64_t)((i+zz*10) * 8); + v.f4 = (float)((i+zz*10) * 40); + v.f8 = (double)((i+zz*10) * 80); + for (int j = 0; j < sizeof(v.bin) - 1; ++j) { + v.bin[j] = (char)((i+zz)%10 + '0'); + } + + taos_stmt_bind_param(stmt, params); + taos_stmt_add_batch(stmt); + } + } + } + + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + + return 0; +} + + + +//1 tables 10 records +int stmt_funcb_autoctb1(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[10]; + int8_t v1[10]; + int16_t v2[10]; + int32_t v4[10]; + int64_t v8[10]; + float f4[10]; + double f8[10]; + char bin[10][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1 * 10); + + int *lb = malloc(10 * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + +// int one_null = 1; + int one_not_null = 0; + + char* is_null = malloc(sizeof(char) * 10); + char* no_null = malloc(sizeof(char) * 10); + + for (int i = 0; i < 10; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 10; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 10; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 10; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 10; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 10; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 10; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 10; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = tts + i; + } + + + for (int i = 0; i < 1; ++i) { + tags[i+0].buffer_type = TSDB_DATA_TYPE_INT; + tags[i+0].buffer = v.v4; + tags[i+0].is_null = &one_not_null; + tags[i+0].length = NULL; + + tags[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+1].buffer = v.b; + tags[i+1].is_null = &one_not_null; + tags[i+1].length = NULL; + + tags[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + tags[i+2].buffer = v.v1; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+3].buffer = v.v2; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = NULL; + + tags[i+4].buffer_type = TSDB_DATA_TYPE_BIGINT; + tags[i+4].buffer = v.v8; + tags[i+4].is_null = &one_not_null; + tags[i+4].length = NULL; + + tags[i+5].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+5].buffer = v.f4; + tags[i+5].is_null = &one_not_null; + tags[i+5].length = NULL; + + tags[i+6].buffer_type = TSDB_DATA_TYPE_DOUBLE; + tags[i+6].buffer = v.f8; + tags[i+6].is_null = &one_not_null; + tags[i+6].length = NULL; + + tags[i+7].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+7].buffer = v.bin; + tags[i+7].is_null = &one_not_null; + tags[i+7].length = (uintptr_t *)lb; + + tags[i+8].buffer_type = TSDB_DATA_TYPE_NCHAR; + tags[i+8].buffer = v.bin; + tags[i+8].is_null = &one_not_null; + tags[i+8].length = (uintptr_t *)lb; + } + + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + exit(1); + } + + int id = 0; + for (int zz = 0; zz < 1; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname_tags(stmt, buf, tags); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + + +//1 tables 10 records +int stmt_funcb_autoctb2(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[10]; + int8_t v1[10]; + int16_t v2[10]; + int32_t v4[10]; + int64_t v8[10]; + float f4[10]; + double f8[10]; + char bin[10][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1 * 10); + + int *lb = malloc(10 * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + +// int one_null = 1; + int one_not_null = 0; + + char* is_null = malloc(sizeof(char) * 10); + char* no_null = malloc(sizeof(char) * 10); + + for (int i = 0; i < 10; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 10; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 10; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 10; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 10; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 10; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 10; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 10; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = tts + i; + } + + + for (int i = 0; i < 1; ++i) { + tags[i+0].buffer_type = TSDB_DATA_TYPE_INT; + tags[i+0].buffer = v.v4; + tags[i+0].is_null = &one_not_null; + tags[i+0].length = NULL; + + tags[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+1].buffer = v.b; + tags[i+1].is_null = &one_not_null; + tags[i+1].length = NULL; + + tags[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + tags[i+2].buffer = v.v1; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+3].buffer = v.v2; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = NULL; + + tags[i+4].buffer_type = TSDB_DATA_TYPE_BIGINT; + tags[i+4].buffer = v.v8; + tags[i+4].is_null = &one_not_null; + tags[i+4].length = NULL; + + tags[i+5].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+5].buffer = v.f4; + tags[i+5].is_null = &one_not_null; + tags[i+5].length = NULL; + + tags[i+6].buffer_type = TSDB_DATA_TYPE_DOUBLE; + tags[i+6].buffer = v.f8; + tags[i+6].is_null = &one_not_null; + tags[i+6].length = NULL; + + tags[i+7].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+7].buffer = v.bin; + tags[i+7].is_null = &one_not_null; + tags[i+7].length = (uintptr_t *)lb; + + tags[i+8].buffer_type = TSDB_DATA_TYPE_NCHAR; + tags[i+8].buffer = v.bin; + tags[i+8].is_null = &one_not_null; + tags[i+8].length = (uintptr_t *)lb; + } + + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? using stb1 tags(1,true,2,3,4,5.0,6.0,'a','b') values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + exit(1); + } + + int id = 0; + for (int zz = 0; zz < 1; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname_tags(stmt, buf, tags); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + + + +//1 tables 10 records +int stmt_funcb_autoctb3(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[10]; + int8_t v1[10]; + int16_t v2[10]; + int32_t v4[10]; + int64_t v8[10]; + float f4[10]; + double f8[10]; + char bin[10][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1 * 10); + + int *lb = malloc(10 * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + +// int one_null = 1; + int one_not_null = 0; + + char* is_null = malloc(sizeof(char) * 10); + char* no_null = malloc(sizeof(char) * 10); + + for (int i = 0; i < 10; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 10; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 10; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 10; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 10; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 10; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 10; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 10; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = tts + i; + } + + + for (int i = 0; i < 1; ++i) { + tags[i+0].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+0].buffer = v.b; + tags[i+0].is_null = &one_not_null; + tags[i+0].length = NULL; + + tags[i+1].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+1].buffer = v.v2; + tags[i+1].is_null = &one_not_null; + tags[i+1].length = NULL; + + tags[i+2].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+2].buffer = v.f4; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+3].buffer = v.bin; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = (uintptr_t *)lb; + } + + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? using stb1 tags(1,?,2,?,4,?,6.0,?,'b') values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + exit(1); + } + + int id = 0; + for (int zz = 0; zz < 1; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname_tags(stmt, buf, tags); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + + + + +//1 tables 10 records +int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[10]; + int8_t v1[10]; + int16_t v2[10]; + int32_t v4[10]; + int64_t v8[10]; + float f4[10]; + double f8[10]; + char bin[10][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1 * 10); + + int *lb = malloc(10 * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + +// int one_null = 1; + int one_not_null = 0; + + char* is_null = malloc(sizeof(char) * 10); + char* no_null = malloc(sizeof(char) * 10); + + for (int i = 0; i < 10; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 10; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 10; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 10; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 10; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 10; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 10; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 10; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = tts + i; + } + + + for (int i = 0; i < 1; ++i) { + tags[i+0].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+0].buffer = v.b; + tags[i+0].is_null = &one_not_null; + tags[i+0].length = NULL; + + tags[i+1].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+1].buffer = v.v2; + tags[i+1].is_null = &one_not_null; + tags[i+1].length = NULL; + + tags[i+2].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+2].buffer = v.f4; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+3].buffer = v.bin; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = (uintptr_t *)lb; + } + + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? using stb1 (id1,id2,id3,id4,id5,id6,id7,id8,id9) tags(1,?,2,?,4,?,6.0,?,'b') values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + return -1; + } + + int id = 0; + for (int zz = 0; zz < 1; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname_tags(stmt, buf, tags); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + + + +//1 tables 10 records +int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[10]; + int8_t v1[10]; + int16_t v2[10]; + int32_t v4[10]; + int64_t v8[10]; + float f4[10]; + double f8[10]; + char bin[10][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1 * 10); + + int *lb = malloc(10 * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + +// int one_null = 1; + int one_not_null = 0; + + char* is_null = malloc(sizeof(char) * 10); + char* no_null = malloc(sizeof(char) * 10); + + for (int i = 0; i < 10; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 10; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 10; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 10; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 10; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 10; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 10; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 10; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = tts + i; + } + + + for (int i = 0; i < 1; ++i) { + tags[i+0].buffer_type = TSDB_DATA_TYPE_INT; + tags[i+0].buffer = v.v4; + tags[i+0].is_null = &one_not_null; + tags[i+0].length = NULL; + + tags[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+1].buffer = v.b; + tags[i+1].is_null = &one_not_null; + tags[i+1].length = NULL; + + tags[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + tags[i+2].buffer = v.v1; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+3].buffer = v.v2; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = NULL; + + tags[i+4].buffer_type = TSDB_DATA_TYPE_BIGINT; + tags[i+4].buffer = v.v8; + tags[i+4].is_null = &one_not_null; + tags[i+4].length = NULL; + + tags[i+5].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+5].buffer = v.f4; + tags[i+5].is_null = &one_not_null; + tags[i+5].length = NULL; + + tags[i+6].buffer_type = TSDB_DATA_TYPE_DOUBLE; + tags[i+6].buffer = v.f8; + tags[i+6].is_null = &one_not_null; + tags[i+6].length = NULL; + + tags[i+7].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+7].buffer = v.bin; + tags[i+7].is_null = &one_not_null; + tags[i+7].length = (uintptr_t *)lb; + + tags[i+8].buffer_type = TSDB_DATA_TYPE_NCHAR; + tags[i+8].buffer = v.bin; + tags[i+8].is_null = &one_not_null; + tags[i+8].length = (uintptr_t *)lb; + } + + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + exit(1); + } + + int id = 0; + for (int zz = 0; zz < 1; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname_tags(stmt, buf, NULL); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); + return -1; + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + +//300 tables 60 records +int stmt_funcb1(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[60]; + int8_t v1[60]; + int16_t v2[60]; + int32_t v4[60]; + int64_t v8[60]; + float f4[60]; + double f8[60]; + char bin[60][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 900000 * 60); + + int *lb = malloc(60 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + char* is_null = malloc(sizeof(char) * 60); + char* no_null = malloc(sizeof(char) * 60); + + for (int i = 0; i < 60; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 9000000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[60*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 60; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 60; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 60; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 60; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 60; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 60; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 60; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 60; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 60; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 60; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 54000000; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 3000; l++) { + for (int zz = 0; zz < 300; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + +//1table 18000 reocrds +int stmt_funcb2(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[18000]; + int8_t v1[18000]; + int16_t v2[18000]; + int32_t v4[18000]; + int64_t v8[18000]; + float f4[18000]; + double f8[18000]; + char bin[18000][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 900000 * 60); + + int *lb = malloc(18000 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 3000*10); + char* is_null = malloc(sizeof(char) * 18000); + char* no_null = malloc(sizeof(char) * 18000); + + for (int i = 0; i < 18000; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 30000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[18000*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 18000; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 18000; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 18000; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 18000; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 18000; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 18000; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 18000; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 18000; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 18000; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 18000; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 54000000; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 10; l++) { + for (int zz = 0; zz < 300; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + ++id; + + } + + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + +//disorder +int stmt_funcb3(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[60]; + int8_t v1[60]; + int16_t v2[60]; + int32_t v4[60]; + int64_t v8[60]; + float f4[60]; + double f8[60]; + char bin[60][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 900000 * 60); + + int *lb = malloc(60 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + char* is_null = malloc(sizeof(char) * 60); + char* no_null = malloc(sizeof(char) * 60); + + for (int i = 0; i < 60; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 9000000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[60*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 60; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 60; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 60; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 60; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 60; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 60; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 60; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 60; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 60; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 60; + + } + + int64_t tts = 1591060628000; + int64_t ttt = 0; + for (int i = 0; i < 54000000; ++i) { + v.ts[i] = tts + i; + if (i > 0 && i%60 == 0) { + ttt = v.ts[i-1]; + v.ts[i-1] = v.ts[i-60]; + v.ts[i-60] = ttt; + } + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 3000; l++) { + for (int zz = 0; zz < 300; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + + +//samets +int stmt_funcb4(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[60]; + int8_t v1[60]; + int16_t v2[60]; + int32_t v4[60]; + int64_t v8[60]; + float f4[60]; + double f8[60]; + char bin[60][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 900000 * 60); + + int *lb = malloc(60 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + char* is_null = malloc(sizeof(char) * 60); + char* no_null = malloc(sizeof(char) * 60); + + for (int i = 0; i < 60; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 9000000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[60*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 60; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 60; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 60; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 60; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 60; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 60; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 60; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 60; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 60; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 60; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 54000000; ++i) { + v.ts[i] = tts; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 3000; l++) { + for (int zz = 0; zz < 300; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + + +//1table 18000 reocrds +int stmt_funcb5(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[18000]; + int8_t v1[18000]; + int16_t v2[18000]; + int32_t v4[18000]; + int64_t v8[18000]; + float f4[18000]; + double f8[18000]; + char bin[18000][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 900000 * 60); + + int *lb = malloc(18000 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 3000*10); + char* is_null = malloc(sizeof(char) * 18000); + char* no_null = malloc(sizeof(char) * 18000); + + for (int i = 0; i < 18000; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 30000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[18000*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 18000; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 18000; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 18000; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 18000; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 18000; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 18000; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 18000; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 18000; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 18000; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 18000; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 54000000; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into m0 values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 10; l++) { + for (int zz = 0; zz < 1; zz++) { + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + ++id; + + } + + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + +//1table 200000 reocrds +int stmt_funcb_ssz1(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int b[30000]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 30000 * 3000); + + int *lb = malloc(30000 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 3000*10); + char* no_null = malloc(sizeof(int) * 200000); + + for (int i = 0; i < 30000; ++i) { + lb[i] = 40; + no_null[i] = 0; + v.b[i] = (int8_t)(i % 2); + } + + for (int i = 0; i < 30000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[30000*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 30000; + + params[i+1].buffer_type = TSDB_DATA_TYPE_INT; + params[i+1].buffer_length = sizeof(int); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = no_null; + params[i+1].num = 30000; + } + + int64_t tts = 0; + for (int64_t i = 0; i < 90000000LL; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 10; l++) { + for (int zz = 0; zz < 300; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + ++id; + + } + + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(no_null); + + return 0; +} + + +//one table 60 records one time +int stmt_funcb_s1(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[60]; + int8_t v1[60]; + int16_t v2[60]; + int32_t v4[60]; + int64_t v8[60]; + float f4[60]; + double f8[60]; + char bin[60][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 900000 * 60); + + int *lb = malloc(60 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + char* is_null = malloc(sizeof(char) * 60); + char* no_null = malloc(sizeof(char) * 60); + + for (int i = 0; i < 60; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 9000000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[60*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 60; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 60; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 60; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 60; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 60; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 60; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 60; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 60; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 60; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 60; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 54000000; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 3000; l++) { + for (int zz = 0; zz < 300; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + } + + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + + + + + +//300 tables 60 records single column bind +int stmt_funcb_sc1(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[60]; + int8_t v1[60]; + int16_t v2[60]; + int32_t v4[60]; + int64_t v8[60]; + float f4[60]; + double f8[60]; + char bin[60][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 900000 * 60); + + int *lb = malloc(60 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + char* is_null = malloc(sizeof(char) * 60); + char* no_null = malloc(sizeof(char) * 60); + + for (int i = 0; i < 60; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 9000000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[60*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 60; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 60; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 60; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 60; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 60; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 60; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 60; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 60; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 60; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 60; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 54000000; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 3000; l++) { + for (int zz = 0; zz < 300; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + for (int col=0; col < 10; ++col) { + taos_stmt_bind_single_param_batch(stmt, params + id++, col); + } + + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + +//1 tables 60 records single column bind +int stmt_funcb_sc2(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[60]; + int8_t v1[60]; + int16_t v2[60]; + int32_t v4[60]; + int64_t v8[60]; + float f4[60]; + double f8[60]; + char bin[60][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 900000 * 60); + + int *lb = malloc(60 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 900000*10); + char* is_null = malloc(sizeof(char) * 60); + char* no_null = malloc(sizeof(char) * 60); + + for (int i = 0; i < 60; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 9000000; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[60*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 60; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 60; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 60; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 60; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 60; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 60; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 60; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 60; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 60; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 60; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 54000000; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int l = 0; l < 3000; l++) { + for (int zz = 0; zz < 300; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + for (int col=0; col < 10; ++col) { + taos_stmt_bind_single_param_batch(stmt, params + id++, col); + } + + taos_stmt_add_batch(stmt); + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + } + + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + +//10 tables [1...10] records single column bind +int stmt_funcb_sc3(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[60]; + int8_t v1[60]; + int16_t v2[60]; + int32_t v4[60]; + int64_t v8[60]; + float f4[60]; + double f8[60]; + char bin[60][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 60); + + int *lb = malloc(60 * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 60*10); + char* is_null = malloc(sizeof(char) * 60); + char* no_null = malloc(sizeof(char) * 60); + + for (int i = 0; i < 60; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + int g = 0; + for (int i = 0; i < 600; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = g%10+1; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = g%10+1; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = g%10+1; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = g%10+1; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = g%10+1; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = g%10+1; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = g%10+1; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = g%10+1; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = g%10+1; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = g%10+1; + ++g; + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 60; ++i) { + v.ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + } + + int id = 0; + for (int zz = 0; zz < 10; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x\n", code); + } + + for (int col=0; col < 10; ++col) { + taos_stmt_bind_single_param_batch(stmt, params + id++, col); + } + + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 3000*300*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*300*60)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + +void check_result(TAOS *taos, char *tname, int printr, int expected) { + char sql[255] = "SELECT * FROM "; + TAOS_RES *result; + + strcat(sql, tname); + + result = taos_query(taos, sql); + int code = taos_errno(result); + if (code != 0) { + printf("failed to query table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + exit(1); + } + + + TAOS_ROW row; + int rows = 0; + int num_fields = taos_num_fields(result); + TAOS_FIELD *fields = taos_fetch_fields(result); + char temp[256]; + + // fetch the records row by row + while ((row = taos_fetch_row(result))) { + rows++; + if (printr) { + memset(temp, 0, sizeof(temp)); + taos_print_row(temp, row, fields, num_fields); + printf("[%s]\n", temp); + } + } + + if (rows == expected) { + printf("%d rows are fetched as expectation\n", rows); + } else { + printf("!!!expect %d rows, but %d rows are fetched\n", expected, rows); + exit(1); + } + + taos_free_result(result); + +} + + + +//120table 60 record each table +int sql_perf1(TAOS *taos) { + char *sql[3000] = {0}; + TAOS_RES *result; + + for (int i = 0; i < 3000; i++) { + sql[i] = calloc(1, 1048576); + } + + int len = 0; + int tss = 0; + for (int l = 0; l < 3000; ++l) { + len = sprintf(sql[l], "insert into "); + for (int t = 0; t < 120; ++t) { + len += sprintf(sql[l] + len, "m%d values ", t); + for (int m = 0; m < 60; ++m) { + len += sprintf(sql[l] + len, "(%d, %d, %d, %d, %d, %d, %f, %f, \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\", \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\") ", tss++, m, m, m, m, m, m+1.0, m+1.0); + } + } + } + + + unsigned long long starttime = getCurrentTime(); + for (int i = 0; i < 3000; ++i) { + result = taos_query(taos, sql[i]); + int code = taos_errno(result); + if (code != 0) { + printf("failed to query table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + exit(1); + } + + taos_free_result(result); + } + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%.1f useconds\n", 3000*120*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*120*60)); + + for (int i = 0; i < 3000; i++) { + free(sql[i]); + } + + return 0; +} + + + + + +//one table 60 records one time +int sql_perf_s1(TAOS *taos) { + char **sql = calloc(1, sizeof(char*) * 360000); + TAOS_RES *result; + + for (int i = 0; i < 360000; i++) { + sql[i] = calloc(1, 9000); + } + + int len = 0; + int tss = 0; + int id = 0; + for (int t = 0; t < 120; ++t) { + for (int l = 0; l < 3000; ++l) { + len = sprintf(sql[id], "insert into m%d values ", t); + for (int m = 0; m < 60; ++m) { + len += sprintf(sql[id] + len, "(%d, %d, %d, %d, %d, %d, %f, %f, \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\", \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\") ", tss++, m, m, m, m, m, m+1.0, m+1.0); + } + if (len >= 9000) { + printf("sql:%s,len:%d\n", sql[id], len); + exit(1); + } + ++id; + } + } + + + unsigned long long starttime = getCurrentTime(); + for (int i = 0; i < 360000; ++i) { + result = taos_query(taos, sql[i]); + int code = taos_errno(result); + if (code != 0) { + printf("failed to query table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + exit(1); + } + + taos_free_result(result); + } + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%.1f useconds\n", 3000*120*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*120*60)); + + for (int i = 0; i < 360000; i++) { + free(sql[i]); + } + + free(sql); + + return 0; +} + + +//small record size +int sql_s_perf1(TAOS *taos) { + char *sql[3000] = {0}; + TAOS_RES *result; + + for (int i = 0; i < 3000; i++) { + sql[i] = calloc(1, 1048576); + } + + int len = 0; + int tss = 0; + for (int l = 0; l < 3000; ++l) { + len = sprintf(sql[l], "insert into "); + for (int t = 0; t < 120; ++t) { + len += sprintf(sql[l] + len, "m%d values ", t); + for (int m = 0; m < 60; ++m) { + len += sprintf(sql[l] + len, "(%d, %d) ", tss++, m%2); + } + } + } + + + unsigned long long starttime = getCurrentTime(); + for (int i = 0; i < 3000; ++i) { + result = taos_query(taos, sql[i]); + int code = taos_errno(result); + if (code != 0) { + printf("failed to query table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + exit(1); + } + + taos_free_result(result); + } + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%.1f useconds\n", 3000*120*60, (endtime-starttime)/1000000UL, (endtime-starttime)/(3000*120*60)); + + for (int i = 0; i < 3000; i++) { + free(sql[i]); + } + + return 0; +} + + +void prepare(TAOS *taos, int bigsize, int createChildTable) { + TAOS_RES *result; + int code; + + result = taos_query(taos, "drop database demo"); + taos_free_result(result); + + result = taos_query(taos, "create database demo keep 36500"); + code = taos_errno(result); + if (code != 0) { + printf("failed to create database, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + exit(1); + } + taos_free_result(result); + + result = taos_query(taos, "use demo"); + taos_free_result(result); + + if (createChildTable) { + // create table + for (int i = 0 ; i < 300; i++) { + char buf[1024]; + if (bigsize) { + sprintf(buf, "create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), bin2 binary(40))", i) ; + } else { + sprintf(buf, "create table m%d (ts timestamp, b int)", i) ; + } + result = taos_query(taos, buf); + code = taos_errno(result); + if (code != 0) { + printf("failed to create table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + exit(1); + } + taos_free_result(result); + } + } else { + char buf[1024]; + if (bigsize) { + sprintf(buf, "create stable stb1 (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), bin2 binary(40))" + " tags(id1 int, id2 bool, id3 tinyint, id4 smallint, id5 bigint, id6 float, id7 double, id8 binary(40), id9 nchar(40))") ; + } else { + sprintf(buf, "create stable stb1 (ts timestamp, b int) tags(id1 int, id2 bool, id3 tinyint, id4 smallint, id5 bigint, id6 float, id7 double, id8 binary(40), id9 nchar(40))") ; + } + + result = taos_query(taos, buf); + code = taos_errno(result); + if (code != 0) { + printf("failed to create table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + exit(1); + } + taos_free_result(result); + } + +} + + + +void preparem(TAOS *taos, int bigsize, int idx) { + TAOS_RES *result; + int code; + char dbname[32],sql[255]; + + sprintf(dbname, "demo%d", idx); + sprintf(sql, "drop database %s", dbname); + + + result = taos_query(taos, sql); + taos_free_result(result); + + sprintf(sql, "create database %s keep 36500", dbname); + result = taos_query(taos, sql); + code = taos_errno(result); + if (code != 0) { + printf("failed to create database, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + exit(1); + } + taos_free_result(result); + + sprintf(sql, "use %s", dbname); + result = taos_query(taos, sql); + taos_free_result(result); + + // create table + for (int i = 0 ; i < 300; i++) { + char buf[1024]; + if (bigsize) { + sprintf(buf, "create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), bin2 binary(40))", i) ; + } else { + sprintf(buf, "create table m%d (ts timestamp, b int)", i) ; + } + result = taos_query(taos, buf); + code = taos_errno(result); + if (code != 0) { + printf("failed to create table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + exit(1); + } + taos_free_result(result); + } + +} + + + +//void runcase(TAOS *taos, int idx) { +void* runcase(void *par) { + T_par* tpar = (T_par *)par; + TAOS *taos = tpar->taos; + int idx = tpar->idx; + + TAOS_STMT *stmt; + + (void)idx; + + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("10t+10records+specifycol start\n"); + stmt_scol_func1(stmt); + printf("10t+10records+specifycol end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 10); + check_result(taos, "m1", 1, 10); + check_result(taos, "m2", 1, 10); + check_result(taos, "m3", 1, 10); + check_result(taos, "m4", 1, 10); + check_result(taos, "m5", 1, 10); + check_result(taos, "m6", 1, 10); + check_result(taos, "m7", 1, 10); + check_result(taos, "m8", 1, 10); + check_result(taos, "m9", 1, 10); + printf("check result end\n"); + taos_stmt_close(stmt); +#endif + + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("1t+100records+specifycol start\n"); + stmt_scol_func2(stmt); + printf("1t+100records+specifycol end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 100); + printf("check result end\n"); + taos_stmt_close(stmt); +#endif + + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("300t+10r+bm+specifycol start\n"); + stmt_scol_func3(stmt); + printf("300t+10r+bm+specifycol end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 20); + check_result(taos, "m1", 1, 20); + check_result(taos, "m111", 1, 20); + check_result(taos, "m223", 1, 20); + check_result(taos, "m299", 1, 20); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("10t+2r+bm+specifycol start\n"); + stmt_scol_func4(stmt); + printf("10t+2r+bm+specifycol end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 20); + check_result(taos, "m1", 1, 20); + check_result(taos, "m2", 1, 20); + check_result(taos, "m3", 1, 20); + check_result(taos, "m4", 1, 20); + check_result(taos, "m5", 1, 20); + check_result(taos, "m6", 1, 20); + check_result(taos, "m7", 1, 20); + check_result(taos, "m8", 1, 20); + check_result(taos, "m9", 1, 20); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("10t+10records start\n"); + stmt_func1(stmt); + printf("10t+10records end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 10); + check_result(taos, "m1", 1, 10); + check_result(taos, "m2", 1, 10); + check_result(taos, "m3", 1, 10); + check_result(taos, "m4", 1, 10); + check_result(taos, "m5", 1, 10); + check_result(taos, "m6", 1, 10); + check_result(taos, "m7", 1, 10); + check_result(taos, "m8", 1, 10); + check_result(taos, "m9", 1, 10); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("10t+[0,1,2...9]records start\n"); + stmt_func2(stmt); + printf("10t+[0,1,2...9]records end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 0); + check_result(taos, "m1", 0, 100); + check_result(taos, "m2", 0, 200); + check_result(taos, "m3", 0, 300); + check_result(taos, "m4", 0, 400); + check_result(taos, "m5", 0, 500); + check_result(taos, "m6", 0, 600); + check_result(taos, "m7", 0, 700); + check_result(taos, "m8", 0, 800); + check_result(taos, "m9", 0, 900); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("10t+[0,100,200...900]records start\n"); + stmt_func3(stmt); + printf("10t+[0,100,200...900]records end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 0); + check_result(taos, "m1", 0, 100); + check_result(taos, "m2", 0, 200); + check_result(taos, "m3", 0, 300); + check_result(taos, "m4", 0, 400); + check_result(taos, "m5", 0, 500); + check_result(taos, "m6", 0, 600); + check_result(taos, "m7", 0, 700); + check_result(taos, "m8", 0, 800); + check_result(taos, "m9", 0, 900); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("300t+60r+bm start\n"); + stmt_funcb1(stmt); + printf("300t+60r+bm end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 180000); + check_result(taos, "m1", 0, 180000); + check_result(taos, "m111", 0, 180000); + check_result(taos, "m223", 0, 180000); + check_result(taos, "m299", 0, 180000); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("1t+10r+bm+autoctb start\n"); + stmt_funcb_autoctb1(stmt); + printf("1t+10r+bm+autoctb end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 10); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("1t+10r+bm+autoctb start\n"); + stmt_funcb_autoctb2(stmt); + printf("1t+10r+bm+autoctb end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 10); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("1t+10r+bm+autoctb start\n"); + stmt_funcb_autoctb3(stmt); + printf("1t+10r+bm+autoctb end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 10); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("1t+10r+bm+autoctb+e1 start\n"); + stmt_funcb_autoctb_e1(stmt); + printf("1t+10r+bm+autoctb+e1 end\n"); + printf("check result start\n"); + //check_result(taos, "m0", 1, 0); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("1t+10r+bm+autoctb+e2 start\n"); + stmt_funcb_autoctb_e2(stmt); + printf("1t+10r+bm+autoctb+e2 end\n"); + printf("check result start\n"); + //check_result(taos, "m0", 1, 0); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("1t+18000r+bm start\n"); + stmt_funcb2(stmt); + printf("1t+18000r+bm end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 180000); + check_result(taos, "m1", 0, 180000); + check_result(taos, "m111", 0, 180000); + check_result(taos, "m223", 0, 180000); + check_result(taos, "m299", 0, 180000); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("300t+60r+disorder+bm start\n"); + stmt_funcb3(stmt); + printf("300t+60r+disorder+bm end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 180000); + check_result(taos, "m1", 0, 180000); + check_result(taos, "m111", 0, 180000); + check_result(taos, "m223", 0, 180000); + check_result(taos, "m299", 0, 180000); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("300t+60r+samets+bm start\n"); + stmt_funcb4(stmt); + printf("300t+60r+samets+bm end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 1); + check_result(taos, "m1", 0, 1); + check_result(taos, "m111", 0, 1); + check_result(taos, "m223", 0, 1); + check_result(taos, "m299", 0, 1); + printf("check result end\n"); + taos_stmt_close(stmt); +#endif + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("1t+18000r+nodyntable+bm start\n"); + stmt_funcb5(stmt); + printf("1t+18000r+nodyntable+bm end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 180000); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("300t+60r+bm+sc start\n"); + stmt_funcb_sc1(stmt); + printf("300t+60r+bm+sc end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 180000); + check_result(taos, "m1", 0, 180000); + check_result(taos, "m111", 0, 180000); + check_result(taos, "m223", 0, 180000); + check_result(taos, "m299", 0, 180000); + printf("check result end\n"); + taos_stmt_close(stmt); +#endif + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("1t+60r+bm+sc start\n"); + stmt_funcb_sc2(stmt); + printf("1t+60r+bm+sc end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 180000); + check_result(taos, "m1", 0, 180000); + check_result(taos, "m111", 0, 180000); + check_result(taos, "m223", 0, 180000); + check_result(taos, "m299", 0, 180000); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("10t+[1...10]r+bm+sc start\n"); + stmt_funcb_sc3(stmt); + printf("10t+[1...10]r+bm+sc end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 1); + check_result(taos, "m1", 1, 2); + check_result(taos, "m2", 1, 3); + check_result(taos, "m3", 1, 4); + check_result(taos, "m4", 1, 5); + check_result(taos, "m5", 1, 6); + check_result(taos, "m6", 1, 7); + check_result(taos, "m7", 1, 8); + check_result(taos, "m8", 1, 9); + check_result(taos, "m9", 1, 10); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + +#if 1 + prepare(taos, 1, 1); + + stmt = taos_stmt_init(taos); + + printf("1t+60r+bm start\n"); + stmt_funcb_s1(stmt); + printf("1t+60r+bm end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 180000); + check_result(taos, "m1", 0, 180000); + check_result(taos, "m111", 0, 180000); + check_result(taos, "m223", 0, 180000); + check_result(taos, "m299", 0, 180000); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + +#if 1 + prepare(taos, 1, 1); + + (void)stmt; + printf("120t+60r+sql start\n"); + sql_perf1(taos); + printf("120t+60r+sql end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 180000); + check_result(taos, "m1", 0, 180000); + check_result(taos, "m34", 0, 180000); + check_result(taos, "m67", 0, 180000); + check_result(taos, "m99", 0, 180000); + printf("check result end\n"); +#endif + +#if 1 + prepare(taos, 1, 1); + + (void)stmt; + printf("1t+60r+sql start\n"); + sql_perf_s1(taos); + printf("1t+60r+sql end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 180000); + check_result(taos, "m1", 0, 180000); + check_result(taos, "m34", 0, 180000); + check_result(taos, "m67", 0, 180000); + check_result(taos, "m99", 0, 180000); + printf("check result end\n"); +#endif + + +#if 1 + preparem(taos, 0, idx); + + stmt = taos_stmt_init(taos); + + printf("1t+30000r+bm start\n"); + stmt_funcb_ssz1(stmt); + printf("1t+30000r+bm end\n"); + printf("check result start\n"); + check_result(taos, "m0", 0, 300000); + check_result(taos, "m1", 0, 300000); + check_result(taos, "m111", 0, 300000); + check_result(taos, "m223", 0, 300000); + check_result(taos, "m299", 0, 300000); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + return NULL; + +} + +int main(int argc, char *argv[]) +{ + TAOS *taos[4]; + + // connect to server + if (argc < 2) { + printf("please input server ip \n"); + return 0; + } + + taos[0] = taos_connect(argv[1], "root", "taosdata", NULL, 0); + if (taos == NULL) { + printf("failed to connect to db, reason:%s\n", taos_errstr(taos)); + exit(1); + } + + taos[1] = taos_connect(argv[1], "root", "taosdata", NULL, 0); + if (taos == NULL) { + printf("failed to connect to db, reason:%s\n", taos_errstr(taos)); + exit(1); + } + + taos[2] = taos_connect(argv[1], "root", "taosdata", NULL, 0); + if (taos == NULL) { + printf("failed to connect to db, reason:%s\n", taos_errstr(taos)); + exit(1); + } + + taos[3] = taos_connect(argv[1], "root", "taosdata", NULL, 0); + if (taos == NULL) { + printf("failed to connect to db, reason:%s\n", taos_errstr(taos)); + exit(1); + } + + pthread_t *pThreadList = (pthread_t *) calloc(sizeof(pthread_t), 4); + + pthread_attr_t thattr; + pthread_attr_init(&thattr); + pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); + T_par par[4]; + + par[0].taos = taos[0]; + par[0].idx = 0; + par[1].taos = taos[1]; + par[1].idx = 1; + par[2].taos = taos[2]; + par[2].idx = 2; + par[3].taos = taos[3]; + par[3].idx = 3; + + pthread_create(&(pThreadList[0]), &thattr, runcase, (void *)&par[0]); + //pthread_create(&(pThreadList[1]), &thattr, runcase, (void *)&par[1]); + //pthread_create(&(pThreadList[2]), &thattr, runcase, (void *)&par[2]); + //pthread_create(&(pThreadList[3]), &thattr, runcase, (void *)&par[3]); + + while(1) { + sleep(1); + } + return 0; +} + diff --git a/tests/script/api/makefile b/tests/script/api/makefile new file mode 100644 index 0000000000000000000000000000000000000000..5eeb1342887afc2c4f920aa673466eef7f7ae510 --- /dev/null +++ b/tests/script/api/makefile @@ -0,0 +1,19 @@ +# Copyright (c) 2017 by TAOS Technologies, Inc. +# todo: library dependency, header file dependency + +ROOT=./ +TARGET=exe +LFLAGS = '-Wl,-rpath,/usr/local/taos/driver/' -ltaos -lpthread -lm -lrt +CFLAGS = -O0 -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 + +all: $(TARGET) + +exe: + gcc $(CFLAGS) ./batchprepare.c -o $(ROOT)batchprepare $(LFLAGS) + gcc $(CFLAGS) ./stmtBatchTest.c -o $(ROOT)stmtBatchTest $(LFLAGS) + +clean: + rm $(ROOT)batchprepare + rm $(ROOT)stmtBatchTest diff --git a/tests/script/api/stmtBatchTest.c b/tests/script/api/stmtBatchTest.c new file mode 100644 index 0000000000000000000000000000000000000000..8bd296db6123a4602a95c4777b7ef1322a37d7ba --- /dev/null +++ b/tests/script/api/stmtBatchTest.c @@ -0,0 +1,3230 @@ +// TAOS standard API example. The same syntax as MySQL, but only a subet +// to compile: gcc -o prepare prepare.c -ltaos + +#include +#include +#include +#include "taos.h" +#include "taoserror.h" +#include +#include +#include + +#define MAX_ROWS_OF_PER_COLUMN 32770 +#define MAX_BINARY_DEF_LEN (1024*16) + +typedef struct { + int64_t *ts; + int8_t b[MAX_ROWS_OF_PER_COLUMN]; + int8_t v1[MAX_ROWS_OF_PER_COLUMN]; + int16_t v2[MAX_ROWS_OF_PER_COLUMN]; + int32_t v4[MAX_ROWS_OF_PER_COLUMN]; + int64_t v8[MAX_ROWS_OF_PER_COLUMN]; + float f4[MAX_ROWS_OF_PER_COLUMN]; + double f8[MAX_ROWS_OF_PER_COLUMN]; + //char br[MAX_ROWS_OF_PER_COLUMN][MAX_BINARY_DEF_LEN]; + //char nr[MAX_ROWS_OF_PER_COLUMN][MAX_BINARY_DEF_LEN]; + char *br; + char *nr; + int64_t ts2[MAX_ROWS_OF_PER_COLUMN]; +} sampleValue; + + +typedef struct { + TAOS *taos; + int idx; +} ThreadInfo; + +//void taosMsleep(int mseconds); + +int g_runTimes = 5; + + +unsigned long long getCurrentTime(){ + struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) { + perror("Failed to get current time in ms"); + exit(EXIT_FAILURE); + } + + return (uint64_t)tv.tv_sec * 1000000ULL + (uint64_t)tv.tv_usec; +} + +static int stmt_bind_case_001(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v->v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v->v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v->v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v->v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = rowsOfPerColum; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v->f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = rowsOfPerColum; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v->f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = rowsOfPerColum; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+8].buffer = v->br; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = rowsOfPerColum; + + params[i+9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[i+9].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+9].buffer = v->nr; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = rowsOfPerColum; + + params[i+10].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+10].buffer_length = sizeof(int64_t); + params[i+10].buffer = v->ts2; + params[i+10].length = NULL; + params[i+10].is_null = is_null; + params[i+10].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + +static int stmt_bind_case_002(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v->v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v->v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v->v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v->v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = rowsOfPerColum; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v->f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = rowsOfPerColum; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v->f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = rowsOfPerColum; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+8].buffer = v->br; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = rowsOfPerColum; + + params[i+9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[i+9].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+9].buffer = v->nr; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = rowsOfPerColum; + + params[i+10].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+10].buffer_length = sizeof(int64_t); + params[i+10].buffer = v->ts2; + params[i+10].length = NULL; + params[i+10].is_null = is_null; + params[i+10].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + +static int stmt_bind_case_003(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_INT; + params[i+1].buffer_length = sizeof(int32_t); + params[i+1].buffer = v->v4; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +static int stmt_bind_case_004(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum * 2)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * 2 * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum * 2; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v->v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v->v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v->v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v->v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = rowsOfPerColum; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v->f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = rowsOfPerColum; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v->f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = rowsOfPerColum; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+8].buffer = v->br; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = rowsOfPerColum; + + params[i+9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[i+9].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+9].buffer = v->nr; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = rowsOfPerColum; + + params[i+10].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+10].buffer_length = sizeof(int64_t); + params[i+10].buffer = v->ts2; + params[i+10].length = NULL; + params[i+10].is_null = is_null; + params[i+10].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum * 2; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + // ===================================start==============================================// + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + // ===================================end==============================================// + + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +static int stmt_bind_error_case_001(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum * 2)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * 2 * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum * 2; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v->v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v->v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v->v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v->v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = rowsOfPerColum; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v->f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = rowsOfPerColum; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v->f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = rowsOfPerColum; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+8].buffer = v->br; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = rowsOfPerColum; + + params[i+9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[i+9].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+9].buffer = v->nr; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = rowsOfPerColum; + + params[i+10].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+10].buffer_length = sizeof(int64_t); + params[i+10].buffer = v->ts2; + params[i+10].length = NULL; + params[i+10].is_null = is_null; + params[i+10].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum * 2; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + //------- add one batch ------// + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + //----------------------------// + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + + +static int stmt_bind_error_case_002(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum * 2)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * 2 * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum * 2; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v->v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v->v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v->v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v->v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = rowsOfPerColum; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v->f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = rowsOfPerColum; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v->f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = rowsOfPerColum; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+8].buffer = v->br; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = rowsOfPerColum; + + params[i+9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[i+9].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+9].buffer = v->nr; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = rowsOfPerColum; + + params[i+10].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+10].buffer_length = sizeof(int64_t); + params[i+10].buffer = v->ts2; + params[i+10].length = NULL; + params[i+10].is_null = is_null; + params[i+10].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum * 2; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + //code = taos_stmt_add_batch(stmt); + //if (code != 0) { + // printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + // return -1; + //} + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +static int stmt_bind_error_case_003(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum * 2)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * 2 * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum * 2; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v->v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v->v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v->v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v->v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = rowsOfPerColum; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v->f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = rowsOfPerColum; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v->f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = rowsOfPerColum; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+8].buffer = v->br; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = rowsOfPerColum; + + params[i+9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[i+9].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+9].buffer = v->nr; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = rowsOfPerColum; + + params[i+10].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+10].buffer_length = sizeof(int64_t); + params[i+10].buffer = v->ts2; + params[i+10].length = NULL; + params[i+10].is_null = is_null; + params[i+10].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum * 2; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + //==================add one=================// + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + //==========================================// + + for (int col=0; col < columnNum; ++col) { + + //==================add one=================// + if (1==col) { + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + //==========================================// + + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +static void checkResult(TAOS *taos, char *tname, int printr, int expected) { + char sql[255] = "SELECT * FROM "; + TAOS_RES *result; + + strcat(sql, tname); + + result = taos_query(taos, sql); + int code = taos_errno(result); + if (code != 0) { + printf("failed to query table: %s, reason:%s\n", tname, taos_errstr(result)); + taos_free_result(result); + return; + } + + TAOS_ROW row; + int rows = 0; + int num_fields = taos_num_fields(result); + TAOS_FIELD *fields = taos_fetch_fields(result); + char temp[256]; + + // fetch the records row by row + while ((row = taos_fetch_row(result))) { + rows++; + if (printr) { + memset(temp, 0, sizeof(temp)); + taos_print_row(temp, row, fields, num_fields); + printf("[%s]\n", temp); + } + } + + if (rows == expected) { + printf("%d rows are fetched as expectation from %s\n", rows, tname); + } else { + printf("!!!expect %d rows, but %d rows are fetched from %s\n", expected, rows, tname); + return; + } + + taos_free_result(result); + +} + + +static void prepareV(TAOS *taos, int schemaCase, int tableNum, int lenOfBinaryDef) { + TAOS_RES *result; + int code; + + result = taos_query(taos, "drop database if exists demo"); + taos_free_result(result); + + result = taos_query(taos, "create database demo"); + code = taos_errno(result); + if (code != 0) { + printf("failed to create database, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + + result = taos_query(taos, "use demo"); + taos_free_result(result); + + // create table + for (int i = 0 ; i < tableNum; i++) { + char buf[1024]; + if (schemaCase) { + sprintf(buf, "create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, br binary(%d), nr nchar(%d), ts2 timestamp)", i, lenOfBinaryDef, lenOfBinaryDef) ; + } else { + sprintf(buf, "create table m%d (ts timestamp, b int)", i) ; + } + + result = taos_query(taos, buf); + code = taos_errno(result); + if (code != 0) { + printf("failed to create table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + } + +} + +static void prepareV_long(TAOS *taos, int schemaCase, int tableNum, int lenOfBinaryDef) { + TAOS_RES *result; + int code; + + result = taos_query(taos, "drop database if exists demol"); + taos_free_result(result); + + result = taos_query(taos, "create database demol"); + code = taos_errno(result); + if (code != 0) { + printf("failed to create database, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + + result = taos_query(taos, "use demol"); + taos_free_result(result); + + // create table + for (int i = 0 ; i < tableNum; i++) { + char buf[1024]; + if (schemaCase) { + sprintf(buf, "create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, br binary(%d), nr nchar(%d), ts2 timestamp)", i, lenOfBinaryDef, lenOfBinaryDef) ; + } else { + sprintf(buf, "create table m%d (ts timestamp, b int)", i) ; + } + + result = taos_query(taos, buf); + code = taos_errno(result); + if (code != 0) { + printf("failed to create table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + } + +} + + + +static void prepareVcolumn(TAOS *taos, int schemaCase, int tableNum, int lenOfBinaryDef, char* dbName) { + TAOS_RES *result; + int code; + char sqlstr[1024] = {0}; + sprintf(sqlstr, "drop database if exists %s;", dbName); + result = taos_query(taos, sqlstr); + taos_free_result(result); + + sprintf(sqlstr, "create database %s;", dbName); + result = taos_query(taos, sqlstr); + code = taos_errno(result); + if (code != 0) { + printf("failed to create database, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + + sprintf(sqlstr, "use %s;", dbName); + result = taos_query(taos, sqlstr); + taos_free_result(result); + + // create table + for (int i = 0 ; i < tableNum; i++) { + char buf[1024]; + if (schemaCase) { + sprintf(buf, "create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, br binary(%d), nr nchar(%d), ts2 timestamp)", i, lenOfBinaryDef, lenOfBinaryDef) ; + } else { + sprintf(buf, "create table m%d (ts timestamp, b int)", i) ; + } + + result = taos_query(taos, buf); + code = taos_errno(result); + if (code != 0) { + printf("failed to create table, reason:%s\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + } + +} + +//void runcase(TAOS *taos, int idx) { +static void runCase(TAOS *taos) { + TAOS_STMT *stmt = NULL; + + int tableNum; + int lenOfBinaryDef; + int rowsOfPerColum; + int bingNum; + int lenOfBinaryAct; + int columnNum; + + int totalRowsPerTbl; + +//=======================================================================// +//=============================== single table ==========================// +//========== case 1: ======================// +#if 1 +{ + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 1; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 16; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 1 check result end\n\n"); +} +#endif + + //========== case 2: ======================// +#if 1 +{ + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 2 check result end\n\n"); +} +#endif + + //========== case 3: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 1; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 3 check result end\n\n"); + } +#endif + + //========== case 4: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 5; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 4 check result end\n\n"); + } +#endif + +//=======================================================================// +//=============================== multi tables ==========================// + //========== case 5: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 1; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 16; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 5 check result end\n\n"); + } +#endif + + //========== case 6: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 6 check result end\n\n"); + } +#endif + + //========== case 7: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 1; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 7 check result end\n\n"); + } +#endif + + //========== case 8: ======================// +#if 1 +{ + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 5; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 8 check result end\n\n"); +} +#endif + + //=======================================================================// + //=============================== multi-rows to single table ==========================// + //========== case 9: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 23740; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 16; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 9 check result end\n\n"); + } +#endif + + //========== case 10: ======================// +#if 1 + { + printf("====case 10 error test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 23741; // WAL size exceeds limit + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 16; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("====case 10 check result end\n\n"); + } +#endif + + + //========== case 11: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 32767; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 16; + columnNum = 2; + + prepareV(taos, 0, tableNum, lenOfBinaryDef); + stmt_bind_case_003(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 11 check result end\n\n"); + } +#endif + + //========== case 12: ======================// +#if 1 + { + printf("====case 12 error test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 32768; // invalid parameter + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 16; + columnNum = 2; + + prepareV(taos, 0, tableNum, lenOfBinaryDef); + stmt_bind_case_003(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("====case 12 check result end\n\n"); + } +#endif + + //=======================================================================// + //=============================== multi tables, multi bind one same table ==========================// + //========== case 13: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 1; + bingNum = 5; + lenOfBinaryDef = 40; + lenOfBinaryAct = 16; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 13 check result end\n\n"); + } +#endif + + //========== case 14: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 5; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 14 check result end\n\n"); + } +#endif + + + //========== case 15: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1000; + rowsOfPerColum = 10; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 8; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m111", 0, totalRowsPerTbl); + checkResult(taos, "m222", 0, totalRowsPerTbl); + checkResult(taos, "m333", 0, totalRowsPerTbl); + checkResult(taos, "m999", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 15 check result end\n\n"); + } +#endif + + //========== case 16: ======================// +#if 1 + { + printf("====case 16 error test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 10; + rowsOfPerColum = 10; + bingNum = 1; + lenOfBinaryDef = 100; + lenOfBinaryAct = 8; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_error_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m11", 0, totalRowsPerTbl); + //checkResult(taos, "m22", 0, totalRowsPerTbl); + //checkResult(taos, "m33", 0, totalRowsPerTbl); + //checkResult(taos, "m99", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("====case 16 check result end\n\n"); + } +#endif + + //========== case 17: ======================// +#if 1 + { + //printf("case 17 test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 10; + rowsOfPerColum = 10; + bingNum = 1; + lenOfBinaryDef = 100; + lenOfBinaryAct = 8; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_004(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum * 2; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m11", 0, totalRowsPerTbl); + //checkResult(taos, "m22", 0, totalRowsPerTbl); + //checkResult(taos, "m33", 0, totalRowsPerTbl); + //checkResult(taos, "m99", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 17 check result end\n\n"); + } +#endif + + //========== case 18: ======================// +#if 1 + { + printf("====case 18 error test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 10; + bingNum = 1; + lenOfBinaryDef = 100; + lenOfBinaryAct = 8; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_error_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m11", 0, totalRowsPerTbl); + //checkResult(taos, "m22", 0, totalRowsPerTbl); + //checkResult(taos, "m33", 0, totalRowsPerTbl); + //checkResult(taos, "m99", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("====case 18 check result end\n\n"); + } +#endif + + //========== case 19: ======================// +#if 1 + { + printf("====case 19 error test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 10; + bingNum = 1; + lenOfBinaryDef = 100; + lenOfBinaryAct = 8; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_error_case_003(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m11", 0, totalRowsPerTbl); + //checkResult(taos, "m22", 0, totalRowsPerTbl); + //checkResult(taos, "m33", 0, totalRowsPerTbl); + //checkResult(taos, "m99", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("====case 19 check result end\n\n"); + } +#endif + + return ; + +} + + +static int stmt_bind_case_001_long(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum, int64_t* startTs) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = *startTs; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v->v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v->v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v->v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v->v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = rowsOfPerColum; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v->f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = rowsOfPerColum; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v->f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = rowsOfPerColum; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+8].buffer = v->br; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = rowsOfPerColum; + + params[i+9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[i+9].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+9].buffer = v->nr; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = rowsOfPerColum; + + params[i+10].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+10].buffer_length = sizeof(int64_t); + params[i+10].buffer = v->ts2; + params[i+10].length = NULL; + params[i+10].is_null = is_null; + params[i+10].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; + } + + *startTs = tts + totalRowsPerTbl * tableNum; // return to next + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +static void runCase_long(TAOS *taos) { + TAOS_STMT *stmt = NULL; + + int tableNum; + int lenOfBinaryDef; + int rowsOfPerColum; + int bingNum; + int lenOfBinaryAct; + int columnNum; + + int totalRowsPerTbl; + +//=======================================================================// + //========== long case 14: ======================// +#if 0 + { + stmt = taos_stmt_init(taos); + + tableNum = 1000; + rowsOfPerColum = 10; + bingNum = 5000000; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 11; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("long case 14 check result end\n\n"); + } +#endif + + + //========== case 15: ======================// +#if 1 + { + printf("====long case 15 test start\n\n"); + + tableNum = 200; + rowsOfPerColum = 110; + bingNum = 100; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 8; + columnNum = 11; + + int64_t startTs = 1591060628000; + prepareV_long(taos, 1, tableNum, lenOfBinaryDef); + + totalRowsPerTbl = 0; + for (int i = 0; i < g_runTimes; i++) { + stmt = taos_stmt_init(taos); + stmt_bind_case_001_long(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum, &startTs); + + totalRowsPerTbl += rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m11", 0, totalRowsPerTbl); + checkResult(taos, "m22", 0, totalRowsPerTbl); + checkResult(taos, "m133", 0, totalRowsPerTbl); + checkResult(taos, "m199", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + } + + printf("====long case 15 check result end\n\n"); + } +#endif + + return; + +} + +/*=======================*/ +/* +test scene: insert into tb1 (ts,f1) values (?,?) +*/ +static int stmt_specifyCol_bind_case_001(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_INT; + params[i+2].buffer_length = sizeof(int32_t); + params[i+2].buffer = v->v4; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+3].buffer_length = sizeof(float); + params[i+3].buffer = v->f4; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+4].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+4].buffer = v->br; + params[i+4].length = lb; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + +// create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, br binary(%d), nr nchar(%d), ts2 timestamp) + char *sql = "insert into m0 (ts,b,v4,f4,br) values(?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + //char buf[32]; + //sprintf(buf, "m%d", zz); + //code = taos_stmt_set_tbname(stmt, buf); + //if (code != 0){ + // printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + // return -1; + //} + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +/*=======================*/ +/* +test scene: insert into ? (ts,f1) values (?,?) +*/ +static int stmt_specifyCol_bind_case_002(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_INT; + params[i+2].buffer_length = sizeof(int32_t); + params[i+2].buffer = v->v4; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+3].buffer_length = sizeof(float); + params[i+3].buffer = v->f4; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+4].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+4].buffer = v->br; + params[i+4].length = lb; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + +// create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, br binary(%d), nr nchar(%d), ts2 timestamp) + char *sql = "insert into ? (ts,b,v4,f4,br) values(?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +/*=======================*/ +/* +test scene: insert into tb1 (ts,f1) values (?,?) +*/ +static int stmt_specifyCol_bind_case_001_maxRows(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_INT; + params[i+1].buffer_length = sizeof(int32_t); + params[i+1].buffer = v->v4; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + +// create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, br binary(%d), nr nchar(%d), ts2 timestamp) + char *sql = "insert into m0 (ts,b,v4,f4,br) values(?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + //char buf[32]; + //sprintf(buf, "m%d", zz); + //code = taos_stmt_set_tbname(stmt, buf); + //if (code != 0){ + // printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + // return -1; + //} + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +static void SpecifyColumnBatchCase(TAOS *taos) { + TAOS_STMT *stmt = NULL; + + int tableNum; + int lenOfBinaryDef; + int rowsOfPerColum; + int bingNum; + int lenOfBinaryAct; + int columnNum; + + int totalRowsPerTbl; + +//=======================================================================// +//=============================== single table ==========================// +//========== case 1: ======================// +#if 1 +{ + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 1; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db1"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 1 check result end\n\n"); +} +#endif + + //========== case 2: ======================// +#if 1 +{ + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 15; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db2"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 2 check result end\n\n"); +} +#endif + + //========== case 2-1: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 32767; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 15; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db2_1"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 2-1 check result end\n\n"); + } +#endif + //========== case 2-2: ======================// +#if 1 + { + printf("====case 2-2 error test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 32768; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 15; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db2_2"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("====case 2-2 check result end\n\n"); + } +#endif + + + //========== case 3: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 1; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 20; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db3"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 3 check result end\n\n"); + } +#endif + + //========== case 4: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 5; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db4"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 4 check result end\n\n"); + } +#endif + +//=======================================================================// +//=============================== multi tables ==========================// + //========== case 5: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 1; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 16; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db5"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 5 check result end\n\n"); + } +#endif + + //========== case 6: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 20; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db6"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 6 check result end\n\n"); + } +#endif + + //========== case 7: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 1; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db7"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 7 check result end\n\n"); + } +#endif + + //========== case 8: ======================// +#if 1 +{ + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 5; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 40; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db8"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 8 check result end\n\n"); +} +#endif + + //=======================================================================// + //=============================== multi-rows to single table ==========================// + //========== case 9: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 23740; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db9"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 9 check result end\n\n"); + } +#endif + + //========== case 10: ======================// +#if 0 + { + printf("====case 10 error test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 23741; // WAL size exceeds limit + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareV(taos, 1, tableNum, lenOfBinaryDef); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("====case 10 check result end\n\n"); + } +#endif + + + //=======================================================================// + //=============================== multi tables, multi bind one same table ==========================// + //========== case 13: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 1; + bingNum = 5; + lenOfBinaryDef = 40; + lenOfBinaryAct = 28; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db13"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 13 check result end\n\n"); + } +#endif + + //========== case 14: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 5; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db14"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 14 check result end\n\n"); + } +#endif + + + //========== case 15: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1000; + rowsOfPerColum = 10; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db15"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m111", 0, totalRowsPerTbl); + checkResult(taos, "m222", 0, totalRowsPerTbl); + checkResult(taos, "m333", 0, totalRowsPerTbl); + checkResult(taos, "m500", 0, totalRowsPerTbl); + checkResult(taos, "m999", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 15 check result end\n\n"); + } +#endif + + //========== case 17: ======================// +#if 1 + { + //printf("case 17 test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 10; + rowsOfPerColum = 100; + bingNum = 1; + lenOfBinaryDef = 100; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db17"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m5", 0, totalRowsPerTbl); + checkResult(taos, "m8", 0, totalRowsPerTbl); + checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 17 check result end\n\n"); + } +#endif + + return ; + +} + +int main(int argc, char *argv[]) +{ + TAOS *taos; + char host[32] = "127.0.0.1"; + char* serverIp = NULL; + int threadNum = 1; + + // connect to server + if (argc == 1) { + serverIp = host; + } else if (argc == 2) { + serverIp = argv[1]; + } else if (argc == 3) { + serverIp = argv[1]; + threadNum = atoi(argv[2]); + } else if (argc == 4) { + serverIp = argv[1]; + threadNum = atoi(argv[2]); + g_runTimes = atoi(argv[3]); + } + + printf("server:%s, runTimes:%d\n\n", serverIp, g_runTimes); + +#if 0 + printf("server:%s, threadNum:%d, rows:%d\n\n", serverIp, threadNum, g_rows); + + pthread_t *pThreadList = (pthread_t *) calloc(sizeof(pthread_t), (size_t)threadNum); + ThreadInfo* threadInfo = (ThreadInfo *) calloc(sizeof(ThreadInfo), (size_t)threadNum); + + ThreadInfo* tInfo = threadInfo; + for (int i = 0; i < threadNum; i++) { + taos = taos_connect(serverIp, "root", "taosdata", NULL, 0); + if (taos == NULL) { + printf("failed to connect to TDengine, reason:%s\n", taos_errstr(taos)); + return -1; + } + + tInfo->taos = taos; + tInfo->idx = i; + if (0 == i) { + //pthread_create(&(pThreadList[0]), NULL, runCase, (void *)tInfo); + pthread_create(&(pThreadList[0]), NULL, SpecifyColumnBatchCase, (void *)tInfo); + } else if (1 == i){ + pthread_create(&(pThreadList[0]), NULL, runCase_long, (void *)tInfo); + } + tInfo++; + } + + for (int i = 0; i < threadNum; i++) { + pthread_join(pThreadList[i], NULL); + } + + free(pThreadList); + free(threadInfo); +#endif + + taos = taos_connect(serverIp, "root", "taosdata", NULL, 0); + if (taos == NULL) { + printf("failed to connect to TDengine, reason:%s\n", taos_errstr(taos)); + return -1; + } + + runCase(taos); + runCase_long(taos); + SpecifyColumnBatchCase(taos); + + return 0; +} + diff --git a/tests/script/general/parser/alter_stable.sim b/tests/script/general/parser/alter_stable.sim index 8a7f4fa924268fdace68881f86d30cbdbd131935..afdd7d3edf1ba4f2159569f497bf495cce8ec650 100644 --- a/tests/script/general/parser/alter_stable.sim +++ b/tests/script/general/parser/alter_stable.sim @@ -22,7 +22,7 @@ sql_error alter table mt1 change tag a 1 sql_error create table mtx1 (ts timestamp, c1 int) tags (123 int) -sql create table mt2 (ts timestamp, c1 int) tags (abc012345678901234567890123456789012345678901234567890123456789def int) +sql_error create table mt2 (ts timestamp, c1 int) tags (abc012345678901234567890123456789012345678901234567890123456789def int) sql create table mt3 (ts timestamp, c1 int) tags (abc012345678901234567890123456789012345678901234567890123456789 int) sql_error alter table mt3 change tag abc012345678901234567890123456789012345678901234567890123456789 abcdefg012345678901234567890123456789012345678901234567890123456789 sql alter table mt3 change tag abc012345678901234567890123456789012345678901234567890123456789 abcdefg0123456789012345678901234567890123456789 diff --git a/tests/script/general/parser/binary_escapeCharacter.sim b/tests/script/general/parser/binary_escapeCharacter.sim index f0589d154f9fc91da50e8d83e76da1d32939bcc1..176edd4e298d92689140644587622b20a267f63e 100644 --- a/tests/script/general/parser/binary_escapeCharacter.sim +++ b/tests/script/general/parser/binary_escapeCharacter.sim @@ -1,3 +1,4 @@ + system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 @@ -93,5 +94,15 @@ if $data41 != @udp005@ then print "[ERROR] expect: udp005, act:$data41" endi +print ---------------------> TD-3967 +sql insert into tb values(now, '\\abc\\\\'); +sql insert into tb values(now, '\\abc\\\\'); +sql insert into tb values(now, '\\\\'); + +print ------------->sim bug +# sql_error insert into tb values(now, '\\\'); +sql_error insert into tb values(now, '\'); +#sql_error insert into tb values(now, '\\\n'); +sql insert into tb values(now, '\n'); system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/general/parser/commit.sim b/tests/script/general/parser/commit.sim index dfe521b92bff36d50f3ec0b3ae8a82c2a9fff304..7c4c883fb137607611ad2599f013bdd0ed5675b1 100644 --- a/tests/script/general/parser/commit.sim +++ b/tests/script/general/parser/commit.sim @@ -68,7 +68,7 @@ while $loop <= $loops while $i < 10 sql select count(*) from $stb where t1 = $i if $data00 != $rowNum then - print expect $rowNum, actual: $data00 + print expect $rowNum , actual: $data00 return -1 endi $i = $i + 1 diff --git a/tests/script/general/parser/constCol.sim b/tests/script/general/parser/constCol.sim index 716d36e82bcc4d4505426b2c3784de03d2f77c30..66523517be92eb7bddcb248b54522143f27e09d5 100644 --- a/tests/script/general/parser/constCol.sim +++ b/tests/script/general/parser/constCol.sim @@ -358,6 +358,13 @@ if $data00 != 0.300000000 then return -1 endi +print =============================> td-3996 +sql select 'abc' as res from t1 where f1 < 0 +if $rows != 0 then + return -1 +endi + + print ======================udc with normal column group by sql_error select from t1 diff --git a/tests/script/general/parser/create_tb.sim b/tests/script/general/parser/create_tb.sim index eb6e4f71c3f752d0e54ba275f2e8f04dc5b08e65..ca57f401b9e68b0f597eef8c80862a67d8f22ddb 100644 --- a/tests/script/general/parser/create_tb.sim +++ b/tests/script/general/parser/create_tb.sim @@ -114,7 +114,11 @@ sql_error create table $tb (ts timestamp, $tag int) sql_error create table $tb (ts timestamp, $tags int) sql_error create table $tb (ts timestamp, $sint int) sql_error create table $tb (ts timestamp, $tint int) -sql_error create table $tb (ts timestamp, $nchar int) +sql_error create table $tb (ts timestamp, $nchar int) + +# too long column name +sql_error create table $tb (ts timestamp, abcde_123456789_123456789_123456789_123456789_123456789_123456789 int) +sql_error create table tx(ts timestamp, k int) tags(abcd5_123456789_123456789_123456789_123456789_123456789_123456789 int) print illegal_column_names test passed # case5: chinese_char_in_table_support diff --git a/tests/script/general/parser/dbtbnameValidate.sim b/tests/script/general/parser/dbtbnameValidate.sim index f2e6de81f1cd6bedf3b455bb35b68f669cd889e1..bc3bfefafb1a8317844e01c67b9a9146626222e6 100644 --- a/tests/script/general/parser/dbtbnameValidate.sim +++ b/tests/script/general/parser/dbtbnameValidate.sim @@ -119,4 +119,8 @@ if $rows != 4 then return -1 endi +print ================>td-4147 +sql_error create table tx(ts timestamp, a1234_0123456789_0123456789_0123456789_0123456789_0123456789_0123456789 int) + + system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/function.sim b/tests/script/general/parser/function.sim index 9165b7e98e0510c3fead45acbc1baeceb0b653a3..56ce15c36fbbe71753028f60a03d5cdf73a03571 100644 --- a/tests/script/general/parser/function.sim +++ b/tests/script/general/parser/function.sim @@ -393,6 +393,19 @@ if $rows != 24 then return -1 endi +print ========================> TD-3948 +sql drop table if exists meters +sql create stable meters (ts timestamp, current float, voltage int, phase float) tags (location binary(64), groupId int); +sql_error insert into td3948Err1(phase) using meters tags ("Beijng.Chaoyang", 2) (ts, current) values (now, 10.2); +sql_error insert into td3948Err2(phase, voltage) using meters tags ("Beijng.Chaoyang", 2) (ts, current) values (now, 10.2); +sql_error insert into td3948Err3(phase, current) using meters tags ("Beijng.Chaoyang", 2) (ts, current) values (now, 10.2); +sql insert into td3948 using meters tags ("Beijng.Chaoyang", 2) (ts, current) values (now, 10.2); +sql select count(ts) from td3948; +if $rows != 1 then + print expect 1, actual:$rows + return -1 +endi + print ========================> TD-2740 sql drop table if exists m1; sql create table m1(ts timestamp, k int) tags(a int); @@ -796,3 +809,5 @@ endi if $data00 != 1 then return -1 endi + +print ====================> TODO stddev + normal column filter diff --git a/tests/script/general/parser/last_cache.sim b/tests/script/general/parser/last_cache.sim new file mode 100644 index 0000000000000000000000000000000000000000..9d7da9ddbabbd668382740a230ecc9582c27fe84 --- /dev/null +++ b/tests/script/general/parser/last_cache.sim @@ -0,0 +1,71 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 0 +system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 4 +system sh/exec.sh -n dnode1 -s start + +sleep 100 +sql connect +print ======================== dnode1 start + +$db = testdb + +sql create database $db cachelast 2 +sql use $db + +sql create stable st2 (ts timestamp, f1 int, f2 double, f3 binary(10), f4 timestamp) tags (id int) + +sql create table tb1 using st2 tags (1); +sql create table tb2 using st2 tags (2); +sql create table tb3 using st2 tags (3); +sql create table tb4 using st2 tags (4); +sql create table tb5 using st2 tags (1); +sql create table tb6 using st2 tags (2); +sql create table tb7 using st2 tags (3); +sql create table tb8 using st2 tags (4); +sql create table tb9 using st2 tags (5); +sql create table tba using st2 tags (5); +sql create table tbb using st2 tags (5); +sql create table tbc using st2 tags (5); +sql create table tbd using st2 tags (5); +sql create table tbe using st2 tags (5); + +sql insert into tb1 values ("2021-05-09 10:10:10", 1, 2.0, '3', -1000) +sql insert into tb1 values ("2021-05-10 10:10:11", 4, 5.0, NULL, -2000) +sql insert into tb1 values ("2021-05-12 10:10:12", 6,NULL, NULL, -3000) + +sql insert into tb2 values ("2021-05-09 10:11:13",-1,-2.0,'-3', -1001) +sql insert into tb2 values ("2021-05-10 10:11:14",-4,-5.0, NULL, -2001) +sql insert into tb2 values ("2021-05-11 10:11:15",-6, -7, '-8', -3001) + +sql insert into tb3 values ("2021-05-09 10:12:17", 7, 8.0, '9' , -1002) +sql insert into tb3 values ("2021-05-09 10:12:17",10,11.0, NULL, -2002) +sql insert into tb3 values ("2021-05-09 10:12:18",12,NULL, NULL, -3002) + +sql insert into tb4 values ("2021-05-09 10:12:19",13,14.0,'15' , -1003) +sql insert into tb4 values ("2021-05-10 10:12:20",16,17.0, NULL, -2003) +sql insert into tb4 values ("2021-05-11 10:12:21",18,NULL, NULL, -3003) + +sql insert into tb5 values ("2021-05-09 10:12:22",19, 20, '21', -1004) +sql insert into tb6 values ("2021-05-11 10:12:23",22, 23, NULL, -2004) +sql insert into tb7 values ("2021-05-10 10:12:24",24,NULL, '25', -3004) +sql insert into tb8 values ("2021-05-11 10:12:25",26,NULL, '27', -4004) + +sql insert into tb9 values ("2021-05-09 10:12:26",28, 29, '30', -1005) +sql insert into tba values ("2021-05-10 10:12:27",31, 32, NULL, -2005) +sql insert into tbb values ("2021-05-10 10:12:28",33,NULL, '35', -3005) +sql insert into tbc values ("2021-05-11 10:12:29",36, 37, NULL, -4005) +sql insert into tbd values ("2021-05-11 10:12:29",NULL,NULL,NULL,NULL ) + +run general/parser/last_cache_query.sim + +system sh/exec.sh -n dnode1 -s stop -x SIGINT + +system sh/exec.sh -n dnode1 -s start + +run general/parser/last_cache_query.sim + +system sh/exec.sh -n dnode1 -s stop -x SIGINT + + + diff --git a/tests/script/general/parser/last_cache_query.sim b/tests/script/general/parser/last_cache_query.sim new file mode 100644 index 0000000000000000000000000000000000000000..2acd00058592c3d4f70600aad1b2ee41a688f1e1 --- /dev/null +++ b/tests/script/general/parser/last_cache_query.sim @@ -0,0 +1,416 @@ + +sleep 100 +sql connect + +$db = testdb + +sql use $db + +print "test tb1" + +sql select last(ts) from tb1 +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-12 10:10:12.000@ then + print $data00 + return -1 +endi + + +sql select last(f1) from tb1 +if $rows != 1 then + return -1 +endi +if $data00 != 6 then + print $data00 + return -1 +endi + +sql select last(*) from tb1 +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-12 10:10:12.000@ then + print $data00 + return -1 +endi +if $data01 != 6 then + return -1 +endi +if $data02 != 5.000000000 then + print $data02 + return -1 +endi +if $data03 != 3 then + return -1 +endi +if $data04 != @70-01-01 07:59:57.000@ then + return -1 +endi + + +sql select last(tb1.*,ts,f4) from tb1 +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-12 10:10:12.000@ then + print $data00 + return -1 +endi +if $data01 != 6 then + return -1 +endi +if $data02 != 5.000000000 then + print $data02 + return -1 +endi +if $data03 != 3 then + return -1 +endi +if $data04 != @70-01-01 07:59:57.000@ then + return -1 +endi +if $data05 != @21-05-12 10:10:12.000@ then + print $data00 + return -1 +endi +if $data06 != @70-01-01 07:59:57.000@ then + return -1 +endi + + + + +print "test tb2" + +sql select last(ts) from tb2 +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-11 10:11:15.000@ then + print $data00 + return -1 +endi + + +sql select last(f1) from tb2 +if $rows != 1 then + return -1 +endi +if $data00 != -6 then + print $data00 + return -1 +endi + +sql select last(*) from tb2 +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-11 10:11:15.000@ then + print $data00 + return -1 +endi +if $data01 != -6 then + return -1 +endi +if $data02 != -7.000000000 then + print $data02 + return -1 +endi +if $data03 != -8 then + return -1 +endi +if $data04 != @70-01-01 07:59:56.999@ then + if $data04 != @70-01-01 07:59:57.-01@ then + return -1 + endi +endi + + +sql select last(tb2.*,ts,f4) from tb2 +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-11 10:11:15.000@ then + print $data00 + return -1 +endi +if $data01 != -6 then + return -1 +endi +if $data02 != -7.000000000 then + print $data02 + return -1 +endi +if $data03 != -8 then + return -1 +endi +if $data04 != @70-01-01 07:59:56.999@ then + if $data04 != @70-01-01 07:59:57.-01@ then + return -1 + endi +endi +if $data05 != @21-05-11 10:11:15.000@ then + print $data00 + return -1 +endi +if $data06 != @70-01-01 07:59:56.999@ then + if $data04 != @70-01-01 07:59:57.-01@ then + return -1 + endi +endi + + + + + + + +print "test tbd" +sql select last(*) from tbd +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-11 10:12:29.000@ then + print $data00 + return -1 +endi +if $data01 != NULL then + return -1 +endi +if $data02 != NULL then + print $data02 + return -1 +endi +if $data03 != NULL then + return -1 +endi +if $data04 != NULL then + return -1 +endi + + + +print "test tbe" +sql select last(*) from tbe +if $rows != 0 then + return -1 +endi + + + + + +print "test stable" +sql select last(ts) from st2 +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-12 10:10:12.000@ then + print $data00 + return -1 +endi + + +sql select last(f1) from st2 +if $rows != 1 then + return -1 +endi +if $data00 != 6 then + print $data00 + return -1 +endi + +sql select last(*) from st2 +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-12 10:10:12.000@ then + print $data00 + return -1 +endi +if $data01 != 6 then + return -1 +endi +if $data02 != 37.000000000 then + print $data02 + return -1 +endi +if $data03 != 27 then + return -1 +endi +if $data04 != @70-01-01 07:59:57.000@ then + return -1 +endi + + +sql select last(st2.*,ts,f4) from st2 +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-12 10:10:12.000@ then + print $data00 + return -1 +endi +if $data01 != 6 then + return -1 +endi +if $data02 != 37.000000000 then + print $data02 + return -1 +endi +if $data03 != 27 then + return -1 +endi +if $data04 != @70-01-01 07:59:57.000@ then + return -1 +endi +if $data05 != @21-05-12 10:10:12.000@ then + print $data00 + return -1 +endi +if $data06 != @70-01-01 07:59:57.000@ then + return -1 +endi + + +sql select last(*) from st2 group by id +if $rows != 5 then + return -1 +endi +if $data00 != @21-05-12 10:10:12.000@ then + return -1 +endi +if $data01 != 6 then + return -1 +endi +if $data02 != 5.000000000 then + print $data02 + return -1 +endi +if $data03 != 21 then + return -1 +endi +if $data04 != @70-01-01 07:59:57.000@ then + return -1 +endi +if $data05 != 1 then + return -1 +endi +if $data10 != @21-05-11 10:12:23.000@ then + return -1 +endi +if $data11 != 22 then + return -1 +endi +if $data12 != 23.000000000 then + print $data02 + return -1 +endi +if $data13 != -8 then + return -1 +endi +if $data14 != @70-01-01 07:59:57.996@ then +if $data14 != @70-01-01 07:59:58.-04@ then + print $data14 + return -1 +endi +endi +if $data15 != 2 then + return -1 +endi +if $data20 != @21-05-10 10:12:24.000@ then + return -1 +endi +if $data21 != 24 then + return -1 +endi +if $data22 != 8.000000000 then + print $data02 + return -1 +endi +if $data23 != 25 then + return -1 +endi +if $data24 != @70-01-01 07:59:56.996@ then +if $data24 != @70-01-01 07:59:57.-04@ then + return -1 +endi +endi +if $data25 != 3 then + return -1 +endi +if $data30 != @21-05-11 10:12:25.000@ then + return -1 +endi +if $data31 != 26 then + return -1 +endi +if $data32 != 17.000000000 then + print $data02 + return -1 +endi +if $data33 != 27 then + return -1 +endi +if $data34 != @70-01-01 07:59:55.996@ then +if $data34 != @70-01-01 07:59:56.-04@ then + return -1 +endi +endi +if $data35 != 4 then + return -1 +endi +if $data40 != @21-05-11 10:12:29.000@ then + return -1 +endi +if $data41 != 36 then + return -1 +endi +if $data42 != 37.000000000 then + print $data02 + return -1 +endi +if $data43 != 35 then + return -1 +endi +if $data44 != @70-01-01 07:59:55.995@ then +if $data44 != @70-01-01 07:59:56.-05@ then + return -1 +endi +endi +if $data45 != 5 then + return -1 +endi + + +print "test tbn" +sql create table tbn (ts timestamp, f1 int, f2 double, f3 binary(10), f4 timestamp) +sql insert into tbn values ("2021-05-09 10:10:10", 1, 2.0, '3', -1000) +sql insert into tbn values ("2021-05-10 10:10:11", 4, 5.0, NULL, -2000) +sql insert into tbn values ("2021-05-12 10:10:12", 6,NULL, NULL, -3000) +sql insert into tbn values ("2021-05-13 10:10:12", NULL,NULL, NULL,NULL) + +sql select last(*) from tbn; +if $rows != 1 then + return -1 +endi +if $data00 != @21-05-13 10:10:12.000@ then + print $data00 + return -1 +endi +if $data01 != 6 then + return -1 +endi +if $data02 != 5.000000000 then + print $data02 + return -1 +endi +if $data03 != 3 then + return -1 +endi +if $data04 != @70-01-01 07:59:57.000@ then + return -1 +endi + diff --git a/tests/script/general/parser/nchar.sim b/tests/script/general/parser/nchar.sim index 786cee651b793b23ec8519be400554567af49852..84719efcab9a18e6f554cdfb84942adf1de5add9 100644 --- a/tests/script/general/parser/nchar.sim +++ b/tests/script/general/parser/nchar.sim @@ -1,6 +1,5 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start diff --git a/tests/script/general/parser/nestquery.sim b/tests/script/general/parser/nestquery.sim new file mode 100644 index 0000000000000000000000000000000000000000..9e2736833f56cb6224cc1a1b351b2171213f5f8f --- /dev/null +++ b/tests/script/general/parser/nestquery.sim @@ -0,0 +1,207 @@ +system sh/stop_dnodes.sh + +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 1 +system sh/exec.sh -n dnode1 -s start + +sleep 100 +sql connect + +print ======================== dnode1 start + +$dbPrefix = nest_query +$tbPrefix = nest_tb +$mtPrefix = nest_mt +$tbNum = 10 +$rowNum = 10000 +$totalNum = $tbNum * $rowNum + +print =============== nestquery.sim + +$i = 0 +$db = $dbPrefix . $i +$mt = $mtPrefix . $i + +sql drop database if exists $db +sql create database if not exists $db + +sql use $db +sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int) + +$half = $tbNum / 2 + +$i = 0 +while $i < $half + $tb = $tbPrefix . $i + + $nextSuffix = $i + $half + $tb1 = $tbPrefix . $nextSuffix + + sql create table $tb using $mt tags( $i ) + sql create table $tb1 using $mt tags( $nextSuffix ) + + $x = 0 + while $x < $rowNum + $y = $x * 60000 + $ms = 1600099200000 + $y + $c = $x / 100 + $c = $c * 100 + $c = $x - $c + $binary = 'binary . $c + $binary = $binary . ' + $nchar = 'nchar . $c + $nchar = $nchar . ' + sql insert into $tb values ($ms , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) $tb1 values ($ms , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) + $x = $x + 1 + endw + + $i = $i + 1 +endw + +sleep 100 + +$i = 1 +$tb = $tbPrefix . $i + +print ==============> simple nest query test +sql select count(*) from (select count(*) from nest_mt0) +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +sql select count(*) from (select count(*) from nest_mt0 group by tbname) +if $rows != 1 then + return -1 +endi + +if $data00 != 10 then + return -1 +endi + +sql select count(*) from (select count(*) from nest_mt0 interval(10h) group by tbname) +if $rows != 1 then + return -1 +endi + +if $data00 != 170 then + return -1 +endi + +sql select sum(a) from (select count(*) a from nest_mt0 interval(10h) group by tbname) +if $rows != 1 then + return -1 +endi + +if $data00 != 100000 then + return -1 +endi + +print =================> alias name test +sql select ts from (select count(*) a from nest_tb0 interval(1h)) +if $rows != 167 then + return -1 +endi + +if $data00 != @20-09-15 00:00:00.000@ then + return -1 +endi + +sql select count(a) from (select count(*) a from nest_tb0 interval(1h)) +if $rows != 1 then + return -1 +endi + +if $data00 != 167 then + return -1 +endi + +print ================>master query + filter +sql select t.* from (select count(*) a from nest_tb0 interval(10h)) t where t.a <= 520; +if $rows != 2 then + return -1 +endi + + +print ===================> nest query interval + + + +print ===================> complex query + + + +print ===================> group by + having + + + + + +print =========================> nest query join +sql select a.ts,a.k,b.ts from (select count(*) k from nest_tb0 interval(30a)) a, (select count(*) f from nest_tb1 interval(30a)) b where a.ts = b.ts ; +if $rows != 10000 then + return -1 +endi + +if $data00 != @20-09-15 00:00:00.000@ then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != @20-09-15 00:00:00.000@ then + return -1 +endi + +if $data10 != @20-09-15 00:01:00.000@ then + return -1 +endi + +if $data11 != 1 then + return -1 +endi + +if $data12 != @20-09-15 00:01:00.000@ then + return -1 +endi + +sql select sum(a.k), sum(b.f) from (select count(*) k from nest_tb0 interval(30a)) a, (select count(*) f from nest_tb1 interval(30a)) b where a.ts = b.ts ; +if $rows != 1 then + return -1 +endi + +if $data00 != 10000 then + return -1 +endi + +if $data01 != 10000 then + return -1 +endi + +sql select a.ts,a.k,b.ts,c.ts,c.ts,c.x from (select count(*) k from nest_tb0 interval(30a)) a, (select count(*) f from nest_tb1 interval(30a)) b, (select count(*) x from nest_tb2 interval(30a)) c where a.ts = b.ts and a.ts = c.ts +if $rows != 10000 then + return -1 +endi + +if $data00 != @20-09-15 00:00:00.000@ then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data02 != @20-09-15 00:00:00.000@ then + return -1 +endi + +if $data03 != @20-09-15 00:00:00.000@ then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/general/parser/select_with_tags.sim b/tests/script/general/parser/select_with_tags.sim index 7e5f31f7594bdde5e068e0d754ae863662696759..9d5214bfaaa6fdca44def066a85f49b87731c836 100644 --- a/tests/script/general/parser/select_with_tags.sim +++ b/tests/script/general/parser/select_with_tags.sim @@ -887,10 +887,16 @@ sql_error select tbname, t1 from select_tags_mt0 interval(1y); #valid sql: select first(c1), last(c2), count(*) from select_tags_mt0 group by tbname, t1; #valid sql: select first(c1), tbname, t1 from select_tags_mt0 group by t2; +print ==================================>TD-4231 +sql_error select t1,tbname from select_tags_mt0 where c1<0 +sql_error select t1,tbname from select_tags_mt0 where c1<0 and tbname in ('select_tags_tb12') + +sql select tbname from select_tags_mt0 where tbname in ('select_tags_tb12'); + sql_error select first(c1), last(c2), t1 from select_tags_mt0 group by tbname; sql_error select first(c1), last(c2), tbname, t2 from select_tags_mt0 group by tbname; sql_error select first(c1), count(*), t2, t1, tbname from select_tags_mt0 group by tbname; -# this sql is valid: select first(c1), t2 from select_tags_mt0 group by tbname; +#valid sql: select first(c1), t2 from select_tags_mt0 group by tbname; #sql select first(ts), tbname from select_tags_mt0 group by tbname; #sql select count(c1) from select_tags_mt0 where c1=99 group by tbname; diff --git a/tests/script/general/parser/testSuite.sim b/tests/script/general/parser/testSuite.sim index 62af4818e58b4466074c9d50d13e04bae8ec4ec2..afb76c799ecc2c7c55058cd4f0e287975c0d7d45 100644 --- a/tests/script/general/parser/testSuite.sim +++ b/tests/script/general/parser/testSuite.sim @@ -55,4 +55,9 @@ run general/parser/sliding.sim run general/parser/function.sim run general/parser/stableOp.sim run general/parser/having.sim -run general/parser/having_child.sim \ No newline at end of file +run general/parser/having_child.sim +run general/parser/slimit_alter_tags.sim +run general/parser/binary_escapeCharacter.sim +run general/parser/between_and.sim +run general/parser/last_cache.sim + diff --git a/tests/script/general/parser/union.sim b/tests/script/general/parser/union.sim index d50daea6566af4dd11c51e195e5b5a7f31ee4ad1..0cd3cba84d5843a423440e55db2bb6f1df946e06 100644 --- a/tests/script/general/parser/union.sim +++ b/tests/script/general/parser/union.sim @@ -139,6 +139,34 @@ if $data10 != 1 then return -1 endi +sql select 'ab' as options from union_tb1 limit 1 union all select 'dd' as options from union_tb0 limit 1; +if $rows != 2 then + return -1 +endi + +if $data00 != @ab@ then + return -1 +endi + +if $data10 != @dd@ then + return -1 +endi + + +sql select 'ab' as options from union_tb1 limit 1 union all select '1234567' as options from union_tb0 limit 1; +if $rows != 2 then + return -1 +endi + +if $data00 != @ab@ then + return -1 +endi + +if $data10 != @1234567@ then + return -1 +endi + + # mixed order sql select ts, c1 from union_tb1 order by ts asc limit 10 union all select ts, c1 from union_tb0 order by ts desc limit 2 union all select ts, c1 from union_tb2 order by ts asc limit 10 if $rows != 22 then @@ -421,8 +449,18 @@ if $data10 != @union_db0@ then return -1 endi +sql select 'aaa' as option from union_tb1 where c1 < 0 limit 1 union all select 'bbb' as option from union_tb0 limit 1 +if $rows != 1 then + return -1 +endi + +if $data00 != @bbb@ then + return -1 +endi + + sql_error show tables union all show tables sql_error show stables union all show stables sql_error show databases union all show databases -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/script/unique/arbitrator/dn3_mn1_vnode_nomaster.sim b/tests/script/unique/arbitrator/dn3_mn1_vnode_nomaster.sim index 8e15c4f527db044d52cd725714f15b98161da2ce..b9ee508f78602cee7d6c9f17dbc3e250e7014f72 100644 --- a/tests/script/unique/arbitrator/dn3_mn1_vnode_nomaster.sim +++ b/tests/script/unique/arbitrator/dn3_mn1_vnode_nomaster.sim @@ -158,7 +158,7 @@ if $dnode4Vtatus != offline then sleep 2000 goto wait_dnode4_vgroup_offline endi -if $dnode3Vtatus != master then +if $dnode3Vtatus != unsynced then sleep 2000 goto wait_dnode4_vgroup_offline endi diff --git a/tests/script/unique/cluster/cache.sim b/tests/script/unique/cluster/cache.sim index 33aaea425c783c8362b4372efad96d384b6dbc70..740eddfb0d36767631c08a60806ab2e38e6f364a 100644 --- a/tests/script/unique/cluster/cache.sim +++ b/tests/script/unique/cluster/cache.sim @@ -41,7 +41,7 @@ sql create dnode $hostname2 sleep 10000 sql show log.tables; -if $rows != 5 then +if $rows > 6 then return -1 endi diff --git a/tests/script/unique/dnode/monitor.sim b/tests/script/unique/dnode/monitor.sim index b9b5e41889675ed199b67efc327477271e2f2959..0b41a4137ca74046b24e84fb6202279f45eaa578 100644 --- a/tests/script/unique/dnode/monitor.sim +++ b/tests/script/unique/dnode/monitor.sim @@ -56,7 +56,7 @@ print $data30 print $data40 print $data50 -if $rows != 5 then +if $rows > 6 then return -1 endi diff --git a/tests/script/unique/dnode/monitor_bug.sim b/tests/script/unique/dnode/monitor_bug.sim index efdf5e94b9648a50860dfa79715f6df8cb4c2b3a..60c6524d9ce70c549cbea2964768888bf0d72fcb 100644 --- a/tests/script/unique/dnode/monitor_bug.sim +++ b/tests/script/unique/dnode/monitor_bug.sim @@ -19,7 +19,7 @@ sleep 3000 sql show dnodes print dnode1 openVnodes $data2_1 -if $data2_1 != 1 then +if $data2_1 > 2 then return -1 endi @@ -41,7 +41,7 @@ print dnode2 openVnodes $data2_2 if $data2_1 != 0 then goto show2 endi -if $data2_2 != 1 then +if $data2_2 > 2 then goto show2 endi @@ -55,7 +55,7 @@ print $data30 print $data40 print $data50 -if $rows != 4 then +if $rows > 5 then return -1 endi