diff --git a/.gitmodules b/.gitmodules index 0e65b02221be24495edbb3f8da136a0ac61ff812..346f5c00699e51eac39dbfaffdbf96656052b024 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "tests/examples/rust"] path = tests/examples/rust url = https://github.com/songtianyi/tdengine-rust-bindings.git +[submodule "deps/jemalloc"] + path = deps/jemalloc + url = https://github.com/jemalloc/jemalloc diff --git a/cmake/define.inc b/cmake/define.inc index 57351e547846055a6074c6e5c28a00796d2e4933..cc8bd0fc355847354b23453d2329bda88bfaa2b7 100755 --- a/cmake/define.inc +++ b/cmake/define.inc @@ -59,6 +59,11 @@ IF (TD_LINUX_64) MESSAGE(STATUS "linux64 is defined") SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ADD_DEFINITIONS(-DUSE_LIBICONV) + + IF (JEMALLOC_ENABLED) + ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc) + ENDIF () + ENDIF () IF (TD_LINUX_32) diff --git a/cmake/input.inc b/cmake/input.inc index 00e0e1bc0f00fd8ba8e679f93d5f75e1b75e6bcd..543114ad0956d24900ece70731da504acdf6a72d 100755 --- a/cmake/input.inc +++ b/cmake/input.inc @@ -72,3 +72,8 @@ IF (${RANDOM_NETWORK_FAIL} MATCHES "true") SET(TD_RANDOM_NETWORK_FAIL TRUE) MESSAGE(STATUS "build with random-network-fail enabled") ENDIF () + +IF (${JEMALLOC_ENABLED} MATCHES "true") + SET(TD_JEMALLOC_ENABLED TRUE) + MESSAGE(STATUS "build with jemalloc enabled") +ENDIF () diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index cfc17442f5c21c2d002ba42c45ce523c80eb957f..99152c6ce365768b3b782809cca5aacbec1ef7fd 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -18,3 +18,16 @@ ENDIF () IF (TD_DARWIN AND TD_MQTT) ADD_SUBDIRECTORY(MQTT-C) ENDIF () + +IF (TD_LINUX_64 AND JEMALLOC_ENABLED) + MESSAGE("setup dpes/jemalloc, current source dir:" ${CMAKE_CURRENT_SOURCE_DIR}) + MESSAGE("binary dir:" ${CMAKE_BINARY_DIR}) + include(ExternalProject) + ExternalProject_Add(jemalloc + PREFIX "jemalloc" + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jemalloc + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND ./autogen.sh COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/build/ + BUILD_COMMAND ${MAKE} + ) +ENDIF () diff --git a/deps/jemalloc b/deps/jemalloc new file mode 160000 index 0000000000000000000000000000000000000000..ea6b3e973b477b8061e0076bb257dbd7f3faa756 --- /dev/null +++ b/deps/jemalloc @@ -0,0 +1 @@ +Subproject commit ea6b3e973b477b8061e0076bb257dbd7f3faa756 diff --git a/documentation20/cn/03.architecture/02.replica/docs.md b/documentation20/cn/03.architecture/02.replica/docs.md index 8e1b1e3ab1513fbeaa5b9b805263485a13483b9b..59192ee0cc1fdeb130e2f541b424af284fbc916a 100644 --- a/documentation20/cn/03.architecture/02.replica/docs.md +++ b/documentation20/cn/03.architecture/02.replica/docs.md @@ -107,9 +107,9 @@ TDengine采取的是Master-Slave模式进行同步,与流行的RAFT一致性 ![replica-forward.png](page://images/architecture/replica-forward.png) -1. 应用对写请求做基本的合法性检查,通过,则给改请求包打上一个版本号(version, 单调递增) +1. 应用对写请求做基本的合法性检查,通过,则给该请求包打上一个版本号(version, 单调递增) 2. 应用将打上版本号的写请求封装一个WAL Head, 写入WAL(Write Ahead Log) -3. 应用调用API syncForwardToPeer,如多vnode B是slave状态,sync模块将包含WAL Head的数据包通过Forward消息发送给vnode B,否则就不转发。 +3. 应用调用API syncForwardToPeer,如果vnode B是slave状态,sync模块将包含WAL Head的数据包通过Forward消息发送给vnode B,否则就不转发。 4. vnode B收到Forward消息后,调用回调函数writeToCache, 交给应用处理 5. vnode B应用在写入成功后,都需要调用syncAckForward通知sync模块已经写入成功。 6. 如果quorum大于1,vnode B需要等待应用的回复确认,收到确认后,vnode B发送Forward Response消息给node A。 @@ -219,7 +219,7 @@ Arbitrator的程序tarbitrator.c在复制模块的同一目录, 编译整个系 不同之处: -- 选举流程不一样:Raft里任何一个节点是candidate时,主动向其他节点发出vote request, 如果超过半数回答Yes, 这个candidate就成为Leader,开始一个新的term. 而TDengine的实现里,节点上线、离线或角色改变都会触发状态消息在节点组类传播,等节点组里状态稳定一致之后才触发选举流程,因为状态稳定一致,基于同样的状态信息,每个节点做出的决定会是一致的,一旦某个节点符合成为master的条件,无需其他节点认可,它会自动将自己设为master。TDengine里,任何一个节点检测到其他节点或自己的角色发生改变,就会给节点组内其他节点进行广播的。Raft里不存在这样的机制,因此需要投票来解决。 +- 选举流程不一样:Raft里任何一个节点是candidate时,主动向其他节点发出vote request,如果超过半数回答Yes,这个candidate就成为Leader,开始一个新的term。而TDengine的实现里,节点上线、离线或角色改变都会触发状态消息在节点组内传播,等节点组里状态稳定一致之后才触发选举流程,因为状态稳定一致,基于同样的状态信息,每个节点做出的决定会是一致的,一旦某个节点符合成为master的条件,无需其他节点认可,它会自动将自己设为master。TDengine里,任何一个节点检测到其他节点或自己的角色发生改变,就会向节点组内其他节点进行广播。Raft里不存在这样的机制,因此需要投票来解决。 - 对WAL的一条记录,Raft用term + index来做唯一标识。但TDengine只用version(类似index),在TDengine实现里,仅仅用version是完全可行的, 因为TDengine的选举机制,没有term的概念。 如果整个虚拟节点组全部宕机,重启,但不是所有虚拟节点都上线,这个时候TDengine是不会选出master的,因为未上线的节点有可能有最高version的数据。而RAFT协议,只要超过半数上线,就会选出Leader。 diff --git a/documentation20/cn/03.architecture/docs.md b/documentation20/cn/03.architecture/docs.md index 3d6e5e4f2179d1199c6fcae889683fb5fff2de9e..2668967102986952793cd0f000f32ae4cc5e1125 100644 --- a/documentation20/cn/03.architecture/docs.md +++ b/documentation20/cn/03.architecture/docs.md @@ -343,7 +343,7 @@ TDengine采用数据驱动的方式让缓存中的数据写入硬盘进行持久 对于采集的数据,一般有保留时长,这个时长由系统配置参数keep决定。超过这个设置天数的数据文件,将被系统自动删除,释放存储空间。 -给定days与keep两个参数,一个vnode总的数据文件数为:keep/days。总的数据文件个数不宜过大,也不宜过小。10到100以内合适。基于这个原则,可以设置合理的days。 目前的版本,参数keep可以修改,但对于参数days,一但设置后,不可修改。 +给定days与keep两个参数,一个典型工作状态的vnode中总的数据文件数为:`向上取整(keep/days)+1`个。总的数据文件个数不宜过大,也不宜过小。10到100以内合适。基于这个原则,可以设置合理的days。 目前的版本,参数keep可以修改,但对于参数days,一但设置后,不可修改。 在每个数据文件里,一张表的数据是一块一块存储的。一张表可以有一到多个数据文件块。在一个文件块里,数据是列式存储的,占用的是一片连续的存储空间,这样大大提高读取速度。文件块的大小由系统参数maxRows(每块最大记录条数)决定,缺省值为4096。这个值不宜过大,也不宜过小。过大,定位具体时间段的数据的搜索时间会变长,影响读取速度;过小,数据块的索引太大,压缩效率偏低,也影响读取速度。 diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 9edeb78c6884c79932c464cfaa2ac3d70123d787..94849179936f909de1f344b6a1e61cb1a36a7940 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -516,7 +516,7 @@ conn.close() - _TDengineCursor_ 类 参考python中help(taos.TDengineCursor)。 - 这个类对应客户端进行的写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能夸线程共享使用,否则会导致返回结果出现错误。 + 这个类对应客户端进行的写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能跨线程共享使用,否则会导致返回结果出现错误。 - _connect_ 方法 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 0a0d694ee3da417ec0162cd9e4f8ddda9ab044f1..867aa18715f87a1dfc9ea36203d32382bb726e30 100644 --- a/documentation20/cn/12.taos-sql/01.error-code/docs.md +++ b/documentation20/cn/12.taos-sql/01.error-code/docs.md @@ -26,7 +26,7 @@ | 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_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 | diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md index b130e0544caae9a0e95f3a3f405498feb0a1075b..6bd007ff215bb378767f92e7669ee595aa754342 100644 --- a/documentation20/cn/12.taos-sql/docs.md +++ b/documentation20/cn/12.taos-sql/docs.md @@ -37,7 +37,7 @@ taos> DESCRIBE meters; - Epoch Time:时间戳也可以是一个长整数,表示从 1970-01-01 08:00:00.000 开始的毫秒数 - 时间可以加减,比如 now-2h,表明查询时刻向前推 2 个小时(最近 2 小时)。数字后面的时间单位可以是 u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。 比如 `select * from t1 where ts > now-2w and ts <= now-1w`,表示查询两周前整整一周的数据。在指定降频操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n(自然月) 和 y(自然年)。 -TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableMicrosecond 就可以支持微秒。 +TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传递的 PRECISION 参数就可以支持微秒。 在TDengine中,普通表的数据模型中可使用以下 10 种数据类型。 @@ -76,7 +76,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM 4) 一条SQL 语句的最大长度为65480个字符; - 5) 数据库还有更多与存储相关的配置参数,请参见 [服务端配置](https://www.taosdata.com/cn/documentation/taos-sql#management) 章节。 + 5) 数据库还有更多与存储相关的配置参数,请参见 [服务端配置](https://www.taosdata.com/cn/documentation/administrator#config) 章节。 - **显示系统当前参数** @@ -400,6 +400,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM tb2_name (tb2_field1_name, ...) [USING stb2_name TAGS (tag_value2, ...)] VALUES (field1_value1, ...) (field1_value2, ...) ...; ``` 以自动建表的方式,同时向表tb1_name和tb2_name中按列分别插入多条记录。 + 说明:`(tb1_field1_name, ...)`的部分可以省略掉,这样就是使用全列模式写入——也即在 VALUES 部分提供的数据,必须为数据表的每个列都显式地提供数据。全列写入速度会远快于指定列,因此建议尽可能采用全列写入方式,此时空列可以填入NULL。 从 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, ...) ...; @@ -423,9 +424,9 @@ Query OK, 1 row(s) in set (0.001029s) taos> SHOW TABLES; Query OK, 0 row(s) in set (0.000946s) -taos> INSERT INTO d1001 USING meters TAGS('Beijing.Chaoyang', 2); +taos> INSERT INTO d1001 USING meters TAGS('Beijing.Chaoyang', 2) VALUES('a'); -DB error: invalid SQL: keyword VALUES or FILE required +DB error: invalid SQL: 'a' (invalid timestamp) (0.039494s) taos> SHOW TABLES; table_name | created_time | columns | stable_name | diff --git a/packaging/deb/makedeb.sh b/packaging/deb/makedeb.sh index 28be037e6c56e6ea156bfd963053f83b0d403a68..e6ddb6d7428446abb8d3c375a62f6ce4640f3398 100755 --- a/packaging/deb/makedeb.sh +++ b/packaging/deb/makedeb.sh @@ -24,14 +24,14 @@ echo "compile_dir: ${compile_dir}" echo "pkg_dir: ${pkg_dir}" if [ -d ${pkg_dir} ]; then - rm -rf ${pkg_dir} + rm -rf ${pkg_dir} fi mkdir -p ${pkg_dir} cd ${pkg_dir} libfile="libtaos.so.${tdengine_ver}" -# create install dir +# create install dir install_home_path="/usr/local/taos" mkdir -p ${pkg_dir}${install_home_path} mkdir -p ${pkg_dir}${install_home_path}/bin @@ -42,7 +42,7 @@ mkdir -p ${pkg_dir}${install_home_path}/examples mkdir -p ${pkg_dir}${install_home_path}/include mkdir -p ${pkg_dir}${install_home_path}/init.d mkdir -p ${pkg_dir}${install_home_path}/script - + cp ${compile_dir}/../packaging/cfg/taos.cfg ${pkg_dir}${install_home_path}/cfg cp ${compile_dir}/../packaging/deb/taosd ${pkg_dir}${install_home_path}/init.d cp ${compile_dir}/../packaging/tools/post.sh ${pkg_dir}${install_home_path}/script @@ -54,7 +54,7 @@ cp ${compile_dir}/build/bin/taosdemo ${pkg_dir}${install_home_pat cp ${compile_dir}/build/bin/taosdump ${pkg_dir}${install_home_path}/bin cp ${compile_dir}/build/bin/taosd ${pkg_dir}${install_home_path}/bin cp ${compile_dir}/build/bin/taos ${pkg_dir}${install_home_path}/bin -cp ${compile_dir}/build/lib/${libfile} ${pkg_dir}${install_home_path}/driver +cp ${compile_dir}/build/lib/${libfile} ${pkg_dir}${install_home_path}/driver 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 @@ -67,7 +67,41 @@ 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 -cp ${compile_dir}/build/lib/taos-jdbcdriver*dist.* ${pkg_dir}${install_home_path}/connector ||: +cp ${compile_dir}/build/lib/taos-jdbcdriver*.* ${pkg_dir}${install_home_path}/connector ||: + +if [ -f ${compile_dir}/build/bin/jemalloc-config ]; then + install_user_local_path="/usr/local" + mkdir -p ${pkg_dir}${install_user_local_path}/{bin,lib,lib/pkgconfig,include/jemalloc,share/doc/jemalloc,share/man/man3} + cp ${compile_dir}/build/bin/jemalloc-config ${pkg_dir}${install_user_local_path}/bin/ + if [ -f ${compile_dir}/build/bin/jemalloc.sh ]; then + cp ${compile_dir}/build/bin/jemalloc.sh ${pkg_dir}${install_user_local_path}/bin/ + fi + if [ -f ${compile_dir}/build/bin/jeprof ]; then + cp ${compile_dir}/build/bin/jeprof ${pkg_dir}${install_user_local_path}/bin/ + fi + if [ -f ${compile_dir}/build/include/jemalloc/jemalloc.h ]; then + cp ${compile_dir}/build/include/jemalloc/jemalloc.h ${pkg_dir}${install_user_local_path}/include/jemalloc/ + fi + if [ -f ${compile_dir}/build/lib/libjemalloc.so.2 ]; then + cp ${compile_dir}/build/lib/libjemalloc.so.2 ${pkg_dir}${install_user_local_path}/lib/ + ln -sf libjemalloc.so.2 ${pkg_dir}${install_user_local_path}/lib/libjemalloc.so + fi + if [ -f ${compile_dir}/build/lib/libjemalloc.a ]; then + cp ${compile_dir}/build/lib/libjemalloc.a ${pkg_dir}${install_user_local_path}/lib/ + fi + if [ -f ${compile_dir}/build/lib/libjemalloc_pic.a ]; then + cp ${compile_dir}/build/lib/libjemalloc_pic.a ${pkg_dir}${install_user_local_path}/lib/ + fi + if [ -f ${compile_dir}/build/lib/pkgconfig/jemalloc.pc ]; then + cp ${compile_dir}/build/lib/pkgconfig/jemalloc.pc ${pkg_dir}${install_user_local_path}/lib/pkgconfig/ + fi + if [ -f ${compile_dir}/build/share/doc/jemalloc/jemalloc.html ]; then + cp ${compile_dir}/build/share/doc/jemalloc/jemalloc.html ${pkg_dir}${install_user_local_path}/share/doc/jemalloc/ + fi + if [ -f ${compile_dir}/build/share/man/man3/jemalloc.3 ]; then + cp ${compile_dir}/build/share/man/man3/jemalloc.3 ${pkg_dir}${install_user_local_path}/share/man/man3/ + fi +fi cp -r ${compile_dir}/../packaging/deb/DEBIAN ${pkg_dir}/ chmod 755 ${pkg_dir}/DEBIAN/* @@ -75,7 +109,7 @@ chmod 755 ${pkg_dir}/DEBIAN/* # modify version of control debver="Version: "$tdengine_ver sed -i "2c$debver" ${pkg_dir}/DEBIAN/control - + #get taos version, then set deb name @@ -90,7 +124,7 @@ fi if [ "$verType" == "beta" ]; then debname=${debname}-${verType}".deb" -elif [ "$verType" == "stable" ]; then +elif [ "$verType" == "stable" ]; then debname=${debname}".deb" else echo "unknow verType, nor stabel or beta" @@ -101,7 +135,7 @@ fi dpkg -b ${pkg_dir} $debname echo "make deb package success!" -cp ${pkg_dir}/*.deb ${output_dir} +cp ${pkg_dir}/*.deb ${output_dir} # clean tmep dir rm -rf ${pkg_dir} diff --git a/packaging/release.sh b/packaging/release.sh index 1e54bc28724dacf4a2835552eaca678f9ee3cd00..1d81f818a9b386e5520c5fa6b7499a7990cbe23a 100755 --- a/packaging/release.sh +++ b/packaging/release.sh @@ -6,7 +6,7 @@ set -e #set -x # release.sh -v [cluster | edge] -# -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] +# -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] # -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...] # -V [stable | beta] # -l [full | lite] @@ -22,11 +22,12 @@ cpuType=x64 # [aarch32 | aarch64 | x64 | x86 | mips64 ...] osType=Linux # [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...] pagMode=full # [full | lite] soMode=dynamic # [static | dynamic] +allocator=glibc # [glibc | jemalloc] dbName=taos # [taos | power] verNumber="" verNumberComp="2.0.0.0" -while getopts "hv:V:c:o:l:s:d:n:m:" arg +while getopts "hv:V:c:o:l:s:d:a:n:m:" arg do case $arg in v) @@ -53,6 +54,10 @@ do #echo "dbName=$OPTARG" dbName=$(echo $OPTARG) ;; + a) + #echo "allocator=$OPTARG" + allocator=$(echo $OPTARG) + ;; n) #echo "verNumber=$OPTARG" verNumber=$(echo $OPTARG) @@ -71,20 +76,21 @@ do echo " -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...] " echo " -V [stable | beta] " echo " -l [full | lite] " + echo " -a [glibc | jemalloc] " echo " -s [static | dynamic] " echo " -d [taos | power] " echo " -n [version number] " echo " -m [compatible version number] " exit 0 ;; - ?) #unknow option + ?) #unknow option echo "unkonw argument" exit 1 ;; esac done -echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} pagMode=${pagMode} soMode=${soMode} dbName=${dbName} verNumber=${verNumber} verNumberComp=${verNumberComp}" +echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} pagMode=${pagMode} soMode=${soMode} dbName=${dbName} allocator=${allocator} verNumber=${verNumber} verNumberComp=${verNumberComp}" curr_dir=$(pwd) @@ -118,7 +124,7 @@ function vercomp () { echo 0 exit 0 fi - + local IFS=. local i ver1=($1) ver2=($2) @@ -164,7 +170,7 @@ if [[ "$verMode" == "cluster" ]]; then else gitinfoOfInternal=NULL fi - + cd ${curr_dir} # 2. cmake executable file @@ -180,12 +186,18 @@ else fi cd ${compile_dir} +if [[ "$allocator" == "jemalloc" ]]; then + allocator_macro="-DJEMALLOC_ENABLED=true" +else + allocator_macro="" +fi + # check support cpu type if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" == "aarch32" ]] || [[ "$cpuType" == "mips64" ]] ; then if [ "$verMode" != "cluster" ]; then - cmake ../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} -DPAGMODE=${pagMode} + cmake ../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} -DPAGMODE=${pagMode} ${allocator_macro} else - cmake ../../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} + cmake ../../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} ${allocator_macro} fi else echo "input cpuType=${cpuType} error!!!" @@ -199,9 +211,9 @@ cd ${curr_dir} # 3. Call the corresponding script for packaging if [ "$osType" != "Darwin" ]; then if [[ "$verMode" != "cluster" ]] && [[ "$cpuType" == "x64" ]] && [[ "$dbName" == "taos" ]]; then - ret='0' + ret='0' command -v dpkg >/dev/null 2>&1 || { ret='1'; } - if [ "$ret" -eq 0 ]; then + if [ "$ret" -eq 0 ]; then echo "====do deb package for the ubuntu system====" output_dir="${top_dir}/debs" if [ -d ${output_dir} ]; then @@ -214,9 +226,9 @@ if [ "$osType" != "Darwin" ]; then echo "==========dpkg command not exist, so not release deb package!!!" fi - ret='0' + ret='0' command -v rpmbuild >/dev/null 2>&1 || { ret='1'; } - if [ "$ret" -eq 0 ]; then + if [ "$ret" -eq 0 ]; then echo "====do rpm package for the centos system====" output_dir="${top_dir}/rpms" if [ -d ${output_dir} ]; then @@ -229,11 +241,11 @@ if [ "$osType" != "Darwin" ]; then echo "==========rpmbuild command not exist, so not release rpm package!!!" fi fi - + echo "====do tar.gz package for all systems====" cd ${script_dir}/tools - - if [[ "$dbName" == "taos" ]]; then + + if [[ "$dbName" == "taos" ]]; then ${csudo} ./makepkg.sh ${compile_dir} ${verNumber} "${build_time}" ${cpuType} ${osType} ${verMode} ${verType} ${pagMode} ${csudo} ./makeclient.sh ${compile_dir} ${verNumber} "${build_time}" ${cpuType} ${osType} ${verMode} ${verType} ${pagMode} ${csudo} ./makearbi.sh ${compile_dir} ${verNumber} "${build_time}" ${cpuType} ${osType} ${verMode} ${verType} ${pagMode} diff --git a/packaging/rpm/makerpm.sh b/packaging/rpm/makerpm.sh index 678e75c500937330c5e7364b580d3146d7974d78..7c3272f8d05dc544c1b4b7ea9c605bfc3cc831d6 100755 --- a/packaging/rpm/makerpm.sh +++ b/packaging/rpm/makerpm.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Generate rpm package for centos +# Generate rpm package for centos set -e # set -x @@ -60,7 +60,7 @@ ${csudo} rpmbuild --define="_version ${tdengine_ver}" --define="_topdir ${pkg_di # copy rpm package to output_dir, and modify package name, then clean temp dir #${csudo} cp -rf RPMS/* ${output_dir} -cp_rpm_package ${pkg_dir}/RPMS +cp_rpm_package ${pkg_dir}/RPMS if [ "$verMode" == "cluster" ]; then @@ -74,7 +74,7 @@ fi if [ "$verType" == "beta" ]; then rpmname=${rpmname}-${verType}".rpm" -elif [ "$verType" == "stable" ]; then +elif [ "$verType" == "stable" ]; then rpmname=${rpmname}".rpm" else echo "unknow verType, nor stabel or beta" diff --git a/packaging/rpm/tdengine.spec b/packaging/rpm/tdengine.spec index 9910e20bfe8583a64067bbd3fded2c32e23f83d8..8a870286aba1793ec880af6dd0d8a21602ddc86e 100644 --- a/packaging/rpm/tdengine.spec +++ b/packaging/rpm/tdengine.spec @@ -1,4 +1,5 @@ %define homepath /usr/local/taos +%define userlocalpath /usr/local %define cfg_install_dir /etc/taos %define __strip /bin/true @@ -12,22 +13,22 @@ URL: www.taosdata.com AutoReqProv: no #BuildRoot: %_topdir/BUILDROOT -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root #Prefix: /usr/local/taos -#BuildRequires: -#Requires: +#BuildRequires: +#Requires: %description Big Data Platform Designed and Optimized for IoT -#"prep" Nothing needs to be done +#"prep" Nothing needs to be done #%prep #%setup -q -#%setup -T +#%setup -T -#"build" Nothing needs to be done +#"build" Nothing needs to be done #%build #%configure #make %{?_smp_mflags} @@ -75,9 +76,53 @@ 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 -cp %{_compiledir}/build/lib/taos-jdbcdriver*dist.* %{buildroot}%{homepath}/connector ||: +cp %{_compiledir}/build/lib/taos-jdbcdriver*.* %{buildroot}%{homepath}/connector ||: cp -r %{_compiledir}/../tests/examples/* %{buildroot}%{homepath}/examples + +if [ -f %{_compiledir}/build/bin/jemalloc-config ]; then + mkdir -p %{buildroot}%{userlocalpath}/bin + mkdir -p %{buildroot}%{userlocalpath}/lib + mkdir -p %{buildroot}%{userlocalpath}/lib/pkgconfig + mkdir -p %{buildroot}%{userlocalpath}/include + mkdir -p %{buildroot}%{userlocalpath}/include/jemalloc + mkdir -p %{buildroot}%{userlocalpath}/share + mkdir -p %{buildroot}%{userlocalpath}/share/doc + mkdir -p %{buildroot}%{userlocalpath}/share/doc/jemalloc + mkdir -p %{buildroot}%{userlocalpath}/share/man + mkdir -p %{buildroot}%{userlocalpath}/share/man/man3 + + cp %{_compiledir}/build/bin/jemalloc-config %{buildroot}%{userlocalpath}/bin/ + if [ -f %{_compiledir}/build/bin/jemalloc.sh ]; then + cp %{_compiledir}/build/bin/jemalloc.sh %{buildroot}%{userlocalpath}/bin/ + fi + if [ -f %{_compiledir}/build/bin/jeprof ]; then + cp %{_compiledir}/build/bin/jeprof %{buildroot}%{userlocalpath}/bin/ + fi + if [ -f %{_compiledir}/build/include/jemalloc/jemalloc.h ]; then + cp %{_compiledir}/build/include/jemalloc/jemalloc.h %{buildroot}%{userlocalpath}/include/jemalloc/ + fi + if [ -f %{_compiledir}/build/lib/libjemalloc.so.2 ]; then + cp %{_compiledir}/build/lib/libjemalloc.so.2 %{buildroot}%{userlocalpath}/lib/ + ln -sf libjemalloc.so.2 %{buildroot}%{userlocalpath}/lib/libjemalloc.so + fi + if [ -f %{_compiledir}/build/lib/libjemalloc.a ]; then + cp %{_compiledir}/build/lib/libjemalloc.a %{buildroot}%{userlocalpath}/lib/ + fi + if [ -f %{_compiledir}/build/lib/libjemalloc_pic.a ]; then + cp %{_compiledir}/build/lib/libjemalloc_pic.a %{buildroot}%{userlocalpath}/lib/ + fi + if [ -f %{_compiledir}/build/lib/pkgconfig/jemalloc.pc ]; then + cp %{_compiledir}/build/lib/pkgconfig/jemalloc.pc %{buildroot}%{userlocalpath}/lib/pkgconfig/ + fi + if [ -f %{_compiledir}/build/share/doc/jemalloc/jemalloc.html ]; then + cp %{_compiledir}/build/share/doc/jemalloc/jemalloc.html %{buildroot}%{userlocalpath}/share/doc/jemalloc/ + fi + if [ -f %{_compiledir}/build/share/man/man3/jemalloc.3 ]; then + cp %{_compiledir}/build/share/man/man3/jemalloc.3 %{buildroot}%{userlocalpath}/share/man/man3/ + fi +fi + #Scripts executed before installation %pre csudo="" @@ -103,7 +148,7 @@ fi # if taos.cfg already softlink, remove it if [ -f %{cfg_install_dir}/taos.cfg ]; then ${csudo} rm -f %{homepath}/cfg/taos.cfg || : -fi +fi # there can not libtaos.so*, otherwise ln -s error ${csudo} rm -f %{homepath}/driver/libtaos* || : @@ -116,18 +161,18 @@ if command -v sudo > /dev/null; then fi cd %{homepath}/script ${csudo} ./post.sh - + # Scripts executed before uninstall %preun csudo="" if command -v sudo > /dev/null; then csudo="sudo" fi -# only remove package to call preun.sh, not but update(2) +# only remove package to call preun.sh, not but update(2) if [ $1 -eq 0 ];then #cd %{homepath}/script #${csudo} ./preun.sh - + if [ -f %{homepath}/script/preun.sh ]; then cd %{homepath}/script ${csudo} ./preun.sh @@ -135,7 +180,7 @@ if [ $1 -eq 0 ];then bin_link_dir="/usr/bin" lib_link_dir="/usr/lib" inc_link_dir="/usr/include" - + data_link_dir="/usr/local/taos/data" log_link_dir="/usr/local/taos/log" cfg_link_dir="/usr/local/taos/cfg" @@ -149,20 +194,20 @@ if [ $1 -eq 0 ];then ${csudo} rm -f ${inc_link_dir}/taos.h || : ${csudo} rm -f ${inc_link_dir}/taoserror.h || : ${csudo} rm -f ${lib_link_dir}/libtaos.* || : - + ${csudo} rm -f ${log_link_dir} || : ${csudo} rm -f ${data_link_dir} || : - + pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}') if [ -n "$pid" ]; then ${csudo} kill -9 $pid || : - fi - fi + fi + fi fi - + # Scripts executed after uninstall %postun - + # clean build dir %clean csudo="" diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index 178a248cfe26e7df248665c744ba462f4eb8fd8b..325ac810539385f8a43fb655b76a8e211d65c872 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -59,11 +59,11 @@ initd_mod=0 service_mod=2 if pidof systemd &> /dev/null; then service_mod=0 -elif $(which service &> /dev/null); then +elif $(which service &> /dev/null); then service_mod=1 - service_config_dir="/etc/init.d" + service_config_dir="/etc/init.d" if $(which chkconfig &> /dev/null); then - initd_mod=1 + initd_mod=1 elif $(which insserv &> /dev/null); then initd_mod=2 elif $(which update-rc.d &> /dev/null); then @@ -71,7 +71,7 @@ elif $(which service &> /dev/null); then else service_mod=2 fi -else +else service_mod=2 fi @@ -103,7 +103,7 @@ elif echo $osinfo | grep -qwi "fedora" ; then os_type=2 else echo " osinfo: ${osinfo}" - echo " This is an officially unverified linux system," + echo " This is an officially unverified linux system," echo " if there are any problems with the installation and operation, " echo " please feel free to contact taosdata.com for support." os_type=1 @@ -138,7 +138,7 @@ do echo "Usage: `basename $0` -v [server | client] -e [yes | no]" exit 0 ;; - ?) #unknow option + ?) #unknow option echo "unkonw argument" exit 1 ;; @@ -157,9 +157,9 @@ function kill_process() { function install_main_path() { #create install main dir and all sub dir ${csudo} rm -rf ${install_main_dir} || : - ${csudo} mkdir -p ${install_main_dir} + ${csudo} mkdir -p ${install_main_dir} ${csudo} mkdir -p ${install_main_dir}/cfg - ${csudo} mkdir -p ${install_main_dir}/bin + ${csudo} mkdir -p ${install_main_dir}/bin ${csudo} mkdir -p ${install_main_dir}/connector ${csudo} mkdir -p ${install_main_dir}/driver ${csudo} mkdir -p ${install_main_dir}/examples @@ -168,10 +168,10 @@ function install_main_path() { if [ "$verMode" == "cluster" ]; then ${csudo} mkdir -p ${nginx_dir} fi - + if [[ -e ${script_dir}/email ]]; then - ${csudo} cp ${script_dir}/email ${install_main_dir}/ ||: - fi + ${csudo} cp ${script_dir}/email ${install_main_dir}/ ||: + fi } function install_bin() { @@ -207,29 +207,75 @@ function install_lib() { ${csudo} rm -f ${lib_link_dir}/libtaos.* || : ${csudo} rm -f ${lib64_link_dir}/libtaos.* || : #${csudo} rm -rf ${v15_java_app_dir} || : - ${csudo} cp -rf ${script_dir}/driver/* ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/* - + ${csudo} cp -rf ${script_dir}/driver/* ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/* + ${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.so.1 ${csudo} ln -s ${lib_link_dir}/libtaos.so.1 ${lib_link_dir}/libtaos.so - + if [[ -d ${lib64_link_dir} && ! -e ${lib64_link_dir}/libtaos.so ]]; then ${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib64_link_dir}/libtaos.so.1 || : ${csudo} ln -s ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so || : fi - - #if [ "$verMode" == "cluster" ]; then + + #if [ "$verMode" == "cluster" ]; then # # Compatible with version 1.5 # ${csudo} mkdir -p ${v15_java_app_dir} # ${csudo} ln -s ${install_main_dir}/connector/taos-jdbcdriver-1.0.2-dist.jar ${v15_java_app_dir}/JDBCDriver-1.0.2-dist.jar # ${csudo} chmod 777 ${v15_java_app_dir} || : #fi - + ${csudo} ldconfig } +function install_jemalloc() { + jemalloc_dir=${script_dir}/jemalloc + + if [ -d ${jemalloc_dir} ]; then + ${csudo} /usr/bin/install -c -d /usr/local/bin + + if [ -f ${jemalloc_dir}/bin/jemalloc-config ]; then + ${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc-config /usr/local/bin + fi + if [ -f ${jemalloc_dir}/bin/jemalloc.sh ]; then + ${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc.sh /usr/local/bin + fi + if [ -f ${jemalloc_dir}/bin/jeprof ]; then + ${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jeprof /usr/local/bin + fi + if [ -f ${jemalloc_dir}/include/jemalloc/jemalloc.h ]; then + ${csudo} /usr/bin/install -c -d /usr/local/include/jemalloc + ${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/include/jemalloc/jemalloc.h /usr/local/include/jemalloc + fi + if [ -f ${jemalloc_dir}/lib/libjemalloc.so.2 ]; then + ${csudo} /usr/bin/install -c -d /usr/local/lib + ${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.so.2 /usr/local/lib + ${csudo} ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so + ${csudo} /usr/bin/install -c -d /usr/local/lib + if [ -f ${jemalloc_dir}/lib/libjemalloc.a ]; then + ${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.a /usr/local/lib + fi + if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then + ${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc_pic.a /usr/local/lib + fi + if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then + ${csudo} /usr/bin/install -c -d /usr/local/lib/pkgconfig + ${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/lib/pkgconfig/jemalloc.pc /usr/local/lib/pkgconfig + fi + fi + if [ -f ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html ]; then + ${csudo} /usr/bin/install -c -d /usr/local/share/doc/jemalloc + ${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html /usr/local/share/doc/jemalloc + fi + if [ -f ${jemalloc_dir}/share/man/man3/jemalloc.3 ]; then + ${csudo} /usr/bin/install -c -d /usr/local/share/man/man3 + ${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/share/man/man3/jemalloc.3 /usr/local/share/man/man3 + fi + fi +} + function install_header() { ${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || : - ${csudo} cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/* + ${csudo} cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/* ${csudo} ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h ${csudo} ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h } @@ -246,13 +292,13 @@ function add_newHostname_to_hosts() { if [[ "$s" == "$localIp" ]]; then return fi - done + done ${csudo} echo "127.0.0.1 $1" >> /etc/hosts ||: } function set_hostname() { echo -e -n "${GREEN}Please enter one hostname(must not be 'localhost')${NC}:" - read newHostname + read newHostname while true; do if [[ ! -z "$newHostname" && "$newHostname" != "localhost" ]]; then break @@ -266,25 +312,25 @@ function set_hostname() { if [[ $retval != 0 ]]; then echo echo "set hostname fail!" - return + return fi #echo -e -n "$(hostnamectl status --static)" #echo -e -n "$(hostnamectl status --transient)" #echo -e -n "$(hostnamectl status --pretty)" - + #ubuntu/centos /etc/hostname if [[ -e /etc/hostname ]]; then ${csudo} echo $newHostname > /etc/hostname ||: fi - + #debian: #HOSTNAME=yourname if [[ -e /etc/sysconfig/network ]]; then ${csudo} sed -i -r "s/#*\s*(HOSTNAME=\s*).*/\1$newHostname/" /etc/sysconfig/network ||: fi ${csudo} sed -i -r "s/#*\s*(fqdn\s*).*/\1$newHostname/" ${cfg_install_dir}/taos.cfg - serverFqdn=$newHostname - + serverFqdn=$newHostname + if [[ -e /etc/hosts ]]; then add_newHostname_to_hosts $newHostname fi @@ -302,7 +348,7 @@ function is_correct_ipaddr() { return 0 fi done - + return 1 } @@ -316,13 +362,13 @@ function set_ipAsFqdn() { echo echo -e -n "${GREEN}Unable to get local ip, use 127.0.0.1${NC}" localFqdn="127.0.0.1" - # Write the local FQDN to configuration file - ${csudo} sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${cfg_install_dir}/taos.cfg + # Write the local FQDN to configuration file + ${csudo} sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${cfg_install_dir}/taos.cfg serverFqdn=$localFqdn echo return - fi - + fi + echo -e -n "${GREEN}Please choose an IP from local IP list${NC}:" echo echo -e -n "${GREEN}$iplist${NC}" @@ -331,15 +377,15 @@ function set_ipAsFqdn() { echo -e -n "${GREEN}Notes: if IP is used as the node name, data can NOT be migrated to other machine directly${NC}:" read localFqdn while true; do - if [ ! -z "$localFqdn" ]; then + if [ ! -z "$localFqdn" ]; then # Check if correct ip address is_correct_ipaddr $localFqdn retval=`echo $?` if [[ $retval != 0 ]]; then read -p "Please choose an IP from local IP list:" localFqdn else - # Write the local FQDN to configuration file - ${csudo} sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${cfg_install_dir}/taos.cfg + # Write the local FQDN to configuration file + ${csudo} sed -i -r "s/#*\s*(fqdn\s*).*/\1$localFqdn/" ${cfg_install_dir}/taos.cfg serverFqdn=$localFqdn break fi @@ -354,59 +400,59 @@ function local_fqdn_check() { echo echo -e -n "System hostname is: ${GREEN}$serverFqdn${NC}" echo - if [[ "$serverFqdn" == "" ]] || [[ "$serverFqdn" == "localhost" ]]; then + if [[ "$serverFqdn" == "" ]] || [[ "$serverFqdn" == "localhost" ]]; then echo -e -n "${GREEN}It is strongly recommended to configure a hostname for this machine ${NC}" echo - + while true do - read -r -p "Set hostname now? [Y/n] " input - if [ ! -n "$input" ]; then - set_hostname - break - else - case $input in - [yY][eE][sS]|[yY]) - set_hostname - break - ;; - - [nN][oO]|[nN]) - set_ipAsFqdn - break - ;; - - *) - echo "Invalid input..." - ;; - esac - fi + read -r -p "Set hostname now? [Y/n] " input + if [ ! -n "$input" ]; then + set_hostname + break + else + case $input in + [yY][eE][sS]|[yY]) + set_hostname + break + ;; + + [nN][oO]|[nN]) + set_ipAsFqdn + break + ;; + + *) + echo "Invalid input..." + ;; + esac + fi done fi } function install_config() { #${csudo} rm -f ${install_main_dir}/cfg/taos.cfg || : - + if [ ! -f ${cfg_install_dir}/taos.cfg ]; then ${csudo} mkdir -p ${cfg_install_dir} [ -f ${script_dir}/cfg/taos.cfg ] && ${csudo} cp ${script_dir}/cfg/taos.cfg ${cfg_install_dir} ${csudo} chmod 644 ${cfg_install_dir}/* - fi - + fi + ${csudo} cp -f ${script_dir}/cfg/taos.cfg ${install_main_dir}/cfg/taos.cfg.org ${csudo} ln -s ${cfg_install_dir}/taos.cfg ${install_main_dir}/cfg [ ! -z $1 ] && return 0 || : # only install client - + if ((${update_flag}==1)); then return 0 fi - + if [ "$interactiveFqdn" == "no" ]; then return 0 - fi - + fi + local_fqdn_check #FQDN_FORMAT="(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" @@ -424,8 +470,8 @@ function install_config() { if [ ! -z "$firstEp" ]; then # check the format of the firstEp #if [[ $firstEp == $FQDN_PATTERN ]]; then - # Write the first FQDN to configuration file - ${csudo} sed -i -r "s/#*\s*(firstEp\s*).*/\1$firstEp/" ${cfg_install_dir}/taos.cfg + # Write the first FQDN to configuration file + ${csudo} sed -i -r "s/#*\s*(firstEp\s*).*/\1$firstEp/" ${cfg_install_dir}/taos.cfg break #else # read -p "Please enter the correct FQDN:port: " firstEp @@ -433,9 +479,9 @@ function install_config() { else break fi - done + done - # user email + # user email #EMAIL_PATTERN='^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$' #EMAIL_PATTERN='^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$' #EMAIL_PATTERN="^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$" @@ -446,31 +492,31 @@ function install_config() { if [ ! -z "$emailAddr" ]; then # check the format of the emailAddr #if [[ "$emailAddr" =~ $EMAIL_PATTERN ]]; then - # Write the email address to temp file - email_file="${install_main_dir}/email" + # Write the email address to temp file + email_file="${install_main_dir}/email" ${csudo} bash -c "echo $emailAddr > ${email_file}" - break + break #else - # read -p "Please enter the correct email address: " emailAddr + # read -p "Please enter the correct email address: " emailAddr #fi else break fi - done + done } function install_log() { ${csudo} rm -rf ${log_dir} || : ${csudo} mkdir -p ${log_dir} && ${csudo} chmod 777 ${log_dir} - + ${csudo} ln -s ${log_dir} ${install_main_dir}/log } function install_data() { ${csudo} mkdir -p ${data_dir} - - ${csudo} ln -s ${data_dir} ${install_main_dir}/data + + ${csudo} ln -s ${data_dir} ${install_main_dir}/data } function install_connector() { @@ -485,26 +531,26 @@ function install_examples() { function clean_service_on_sysvinit() { #restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start" - #${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || : - + #${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || : + if pidof taosd &> /dev/null; then ${csudo} service taosd stop || : fi - + if pidof tarbitrator &> /dev/null; then ${csudo} service tarbitratord stop || : fi if ((${initd_mod}==1)); then - if [ -e ${service_config_dir}/taosd ]; then + if [ -e ${service_config_dir}/taosd ]; then ${csudo} chkconfig --del taosd || : fi - if [ -e ${service_config_dir}/tarbitratord ]; then + if [ -e ${service_config_dir}/tarbitratord ]; then ${csudo} chkconfig --del tarbitratord || : fi elif ((${initd_mod}==2)); then - if [ -e ${service_config_dir}/taosd ]; then + if [ -e ${service_config_dir}/taosd ]; then ${csudo} insserv -r taosd || : fi if [ -e ${service_config_dir}/tarbitratord ]; then @@ -518,10 +564,10 @@ function clean_service_on_sysvinit() { ${csudo} update-rc.d -f tarbitratord remove || : fi fi - + ${csudo} rm -f ${service_config_dir}/taosd || : ${csudo} rm -f ${service_config_dir}/tarbitratord || : - + if $(which init &> /dev/null); then ${csudo} init q || : fi @@ -544,10 +590,10 @@ function install_service_on_sysvinit() { ${csudo} cp -f ${script_dir}/init.d/tarbitratord.rpm ${install_main_dir}/init.d/tarbitratord ${csudo} cp ${script_dir}/init.d/tarbitratord.rpm ${service_config_dir}/tarbitratord && ${csudo} chmod a+x ${service_config_dir}/tarbitratord fi - + #restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start" #${csudo} grep -q -F "$restart_config_str" /etc/inittab || ${csudo} bash -c "echo '${restart_config_str}' >> /etc/inittab" - + if ((${initd_mod}==1)); then ${csudo} chkconfig --add taosd || : ${csudo} chkconfig --level 2345 taosd on || : @@ -572,7 +618,7 @@ function clean_service_on_systemd() { fi ${csudo} systemctl disable taosd &> /dev/null || echo &> /dev/null ${csudo} rm -f ${taosd_service_config} - + tarbitratord_service_config="${service_config_dir}/tarbitratord.service" if systemctl is-active --quiet tarbitratord; then echo "tarbitrator is running, stopping it..." @@ -580,7 +626,7 @@ function clean_service_on_systemd() { fi ${csudo} systemctl disable tarbitratord &> /dev/null || echo &> /dev/null ${csudo} rm -f ${tarbitratord_service_config} - + if [ "$verMode" == "cluster" ]; then nginx_service_config="${service_config_dir}/nginxd.service" if systemctl is-active --quiet nginxd; then @@ -588,8 +634,8 @@ function clean_service_on_systemd() { ${csudo} systemctl stop nginxd &> /dev/null || echo &> /dev/null fi ${csudo} systemctl disable nginxd &> /dev/null || echo &> /dev/null - ${csudo} rm -f ${nginx_service_config} - fi + ${csudo} rm -f ${nginx_service_config} + fi } # taos:2345:respawn:/etc/init.d/taosd start @@ -621,7 +667,7 @@ function install_service_on_systemd() { ${csudo} bash -c "echo '[Install]' >> ${taosd_service_config}" ${csudo} bash -c "echo 'WantedBy=multi-user.target' >> ${taosd_service_config}" ${csudo} systemctl enable taosd - + tarbitratord_service_config="${service_config_dir}/tarbitratord.service" ${csudo} bash -c "echo '[Unit]' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'Description=TDengine arbitrator service' >> ${tarbitratord_service_config}" @@ -643,9 +689,9 @@ function install_service_on_systemd() { ${csudo} bash -c "echo >> ${tarbitratord_service_config}" ${csudo} bash -c "echo '[Install]' >> ${tarbitratord_service_config}" ${csudo} bash -c "echo 'WantedBy=multi-user.target' >> ${tarbitratord_service_config}" - #${csudo} systemctl enable tarbitratord - - if [ "$verMode" == "cluster" ]; then + #${csudo} systemctl enable tarbitratord + + if [ "$verMode" == "cluster" ]; then nginx_service_config="${service_config_dir}/nginxd.service" ${csudo} bash -c "echo '[Unit]' >> ${nginx_service_config}" ${csudo} bash -c "echo 'Description=Nginx For TDengine Service' >> ${nginx_service_config}" @@ -674,7 +720,7 @@ function install_service_on_systemd() { ${csudo} systemctl enable nginxd fi ${csudo} systemctl start nginxd - fi + fi } function install_service() { @@ -757,7 +803,7 @@ function update_TDengine() { fi sleep 1 fi - + if [ "$verMode" == "cluster" ]; then if pidof nginx &> /dev/null; then if ((${service_mod}==0)); then @@ -770,12 +816,13 @@ function update_TDengine() { sleep 1 fi fi - + install_main_path install_log install_header install_lib + install_jemalloc if [ "$pagMode" != "lite" ]; then install_connector fi @@ -783,10 +830,10 @@ function update_TDengine() { if [ -z $1 ]; then install_bin install_service - install_config - + install_config + openresty_work=false - if [ "$verMode" == "cluster" ]; then + if [ "$verMode" == "cluster" ]; then # Check if openresty is installed # Check if nginx is installed successfully if type curl &> /dev/null; then @@ -797,7 +844,7 @@ function update_TDengine() { echo -e "\033[44;31;5mNginx for TDengine does not work! Please try again!\033[0m" fi fi - fi + fi #echo #echo -e "\033[44;32;1mTDengine is updated successfully!${NC}" @@ -816,7 +863,7 @@ function update_TDengine() { else echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos -h $serverFqdn${NC} in shell${NC}" fi - + echo echo -e "\033[44;32;1mTDengine is updated successfully!${NC}" else @@ -839,14 +886,14 @@ function install_TDengine() { tar -zxf taos.tar.gz echo -e "${GREEN}Start to install TDengine...${NC}" - - install_main_path - + + install_main_path + if [ -z $1 ]; then install_data - fi - - install_log + fi + + install_log install_header install_lib if [ "$pagMode" != "lite" ]; then @@ -871,8 +918,8 @@ function install_TDengine() { fi fi fi - - install_config + + install_config # Ask if to start the service #echo @@ -885,36 +932,36 @@ function install_TDengine() { echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} service taosd start${NC}" else echo -e "${GREEN_DARK}To start TDengine ${NC}: taosd${NC}" - fi + fi #if [ ${openresty_work} = 'true' ]; then # echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos${NC} in shell OR from ${GREEN_UNDERLINE}http://127.0.0.1:${nginx_port}${NC}" #else # echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos${NC} in shell${NC}" #fi - + if [ ! -z "$firstEp" ]; then - tmpFqdn=${firstEp%%:*} - substr=":" - if [[ $firstEp =~ $substr ]];then - tmpPort=${firstEp#*:} - else - tmpPort="" - fi - if [[ "$tmpPort" != "" ]];then - echo -e "${GREEN_DARK}To access TDengine ${NC}: taos -h $tmpFqdn -P $tmpPort${GREEN_DARK} to login into cluster, then${NC}" - else - echo -e "${GREEN_DARK}To access TDengine ${NC}: taos -h $tmpFqdn${GREEN_DARK} to login into cluster, then${NC}" - fi - echo -e "${GREEN_DARK}execute ${NC}: create dnode 'newDnodeFQDN:port'; ${GREEN_DARK}to add this new node${NC}" - echo + tmpFqdn=${firstEp%%:*} + substr=":" + if [[ $firstEp =~ $substr ]];then + tmpPort=${firstEp#*:} + else + tmpPort="" + fi + if [[ "$tmpPort" != "" ]];then + echo -e "${GREEN_DARK}To access TDengine ${NC}: taos -h $tmpFqdn -P $tmpPort${GREEN_DARK} to login into cluster, then${NC}" + else + echo -e "${GREEN_DARK}To access TDengine ${NC}: taos -h $tmpFqdn${GREEN_DARK} to login into cluster, then${NC}" + fi + echo -e "${GREEN_DARK}execute ${NC}: create dnode 'newDnodeFQDN:port'; ${GREEN_DARK}to add this new node${NC}" + echo elif [ ! -z "$serverFqdn" ]; then - echo -e "${GREEN_DARK}To access TDengine ${NC}: taos -h $serverFqdn${GREEN_DARK} to login into TDengine server${NC}" - echo + echo -e "${GREEN_DARK}To access TDengine ${NC}: taos -h $serverFqdn${GREEN_DARK} to login into TDengine server${NC}" + echo fi - + echo -e "\033[44;32;1mTDengine is installed successfully!${NC}" - echo + echo else # Only install client install_bin install_config @@ -945,6 +992,6 @@ elif [ "$verType" == "client" ]; then else install_TDengine client fi -else - echo "please input correct verType" +else + echo "please input correct verType" fi diff --git a/packaging/tools/make_install.sh b/packaging/tools/make_install.sh index d6ace0a0638bf6c8e78a3c87ce150f731ffca396..0c755d9f728208cbfc2302ef45d7537e437dbb5b 100755 --- a/packaging/tools/make_install.sh +++ b/packaging/tools/make_install.sh @@ -1,12 +1,12 @@ #!/bin/bash # -# This file is used to install TAOS time-series database on linux systems. The operating system +# This file is used to install TAOS time-series database on linux systems. The operating system # is required to use systemd to manage services at boot set -e # set -x -# -----------------------Variables definition--------------------- +# -----------------------Variables definition source_dir=$1 binary_dir=$2 osType=$3 @@ -71,9 +71,9 @@ if [ "$osType" != "Darwin" ]; then service_mod=0 elif $(which service &> /dev/null); then service_mod=1 - service_config_dir="/etc/init.d" + service_config_dir="/etc/init.d" if $(which chkconfig &> /dev/null); then - initd_mod=1 + initd_mod=1 elif $(which insserv &> /dev/null); then initd_mod=2 elif $(which update-rc.d &> /dev/null); then @@ -123,9 +123,9 @@ function kill_taosd() { function install_main_path() { #create install main dir and all sub dir ${csudo} rm -rf ${install_main_dir} || : - ${csudo} mkdir -p ${install_main_dir} + ${csudo} mkdir -p ${install_main_dir} ${csudo} mkdir -p ${install_main_dir}/cfg - ${csudo} mkdir -p ${install_main_dir}/bin + ${csudo} mkdir -p ${install_main_dir}/bin ${csudo} mkdir -p ${install_main_dir}/connector ${csudo} mkdir -p ${install_main_dir}/driver ${csudo} mkdir -p ${install_main_dir}/examples @@ -176,6 +176,49 @@ function install_bin() { [ -x ${install_main_dir}/bin/remove_client.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/rmtaos || : fi } +function install_jemalloc() { + if [ "$osType" != "Darwin" ]; then + /usr/bin/install -c -d /usr/local/bin + + if [ -f ${binary_dir}/build/bin/jemalloc-config ]; then + /usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc-config /usr/local/bin + fi + if [ -f ${binary_dir}/build/bin/jemalloc.sh ]; then + /usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc.sh /usr/local/bin + fi + if [ -f ${binary_dir}/build/bin/jeprof ]; then + /usr/bin/install -c -m 755 ${binary_dir}/build/bin/jeprof /usr/local/bin + fi + if [ -f ${binary_dir}/build/include/jemalloc/jemalloc.h ]; then + /usr/bin/install -c -d /usr/local/include/jemalloc + /usr/bin/install -c -m 644 ${binary_dir}/build/include/jemalloc/jemalloc.h /usr/local/include/jemalloc + fi + if [ -f ${binary_dir}/build/lib/libjemalloc.so.2 ]; then + /usr/bin/install -c -d /usr/local/lib + /usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.so.2 /usr/local/lib + ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so + /usr/bin/install -c -d /usr/local/lib + if [ -f ${binary_dir}/build/lib/libjemalloc.a ]; then + /usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.a /usr/local/lib + fi + if [ -f ${binary_dir}/build/lib/libjemalloc_pic.a ]; then + /usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc_pic.a /usr/local/lib + fi + if [ -f ${binary_dir}/build/lib/pkgconfig/jemalloc.pc ]; then + /usr/bin/install -c -d /usr/local/lib/pkgconfig + /usr/bin/install -c -m 644 ${binary_dir}/build/lib/pkgconfig/jemalloc.pc /usr/local/lib/pkgconfig + fi + fi + if [ -f ${binary_dir}/build/share/doc/jemalloc/jemalloc.html ]; then + /usr/bin/install -c -d /usr/local/share/doc/jemalloc + /usr/bin/install -c -m 644 ${binary_dir}/build/share/doc/jemalloc/jemalloc.html /usr/local/share/doc/jemalloc + fi + if [ -f ${binary_dir}/build/share/man/man3/jemalloc.3 ]; then + /usr/bin/install -c -d /usr/local/share/man/man3 + /usr/bin/install -c -m 644 ${binary_dir}/build/share/man/man3/jemalloc.3 /usr/local/share/man/man3 + fi + fi +} function install_lib() { # Remove links @@ -183,12 +226,12 @@ function install_lib() { if [ "$osType" != "Darwin" ]; then ${csudo} rm -f ${lib64_link_dir}/libtaos.* || : fi - + if [ "$osType" != "Darwin" ]; then ${csudo} cp ${binary_dir}/build/lib/libtaos.so.${verNumber} ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/* ${csudo} ln -sf ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.so.1 ${csudo} ln -sf ${lib_link_dir}/libtaos.so.1 ${lib_link_dir}/libtaos.so - + if [ -d "${lib64_link_dir}" ]; then ${csudo} ln -sf ${install_main_dir}/driver/libtaos.* ${lib64_link_dir}/libtaos.so.1 ${csudo} ln -sf ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so @@ -198,7 +241,9 @@ function install_lib() { ${csudo} ln -sf ${install_main_dir}/driver/libtaos.1.dylib ${lib_link_dir}/libtaos.1.dylib ${csudo} ln -sf ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib fi - + + install_jemalloc + if [ "$osType" != "Darwin" ]; then ${csudo} ldconfig fi @@ -206,26 +251,26 @@ function install_lib() { function install_header() { - ${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || : - ${csudo} cp -f ${source_dir}/src/inc/taos.h ${source_dir}/src/inc/taoserror.h ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/* + ${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || : + ${csudo} cp -f ${source_dir}/src/inc/taos.h ${source_dir}/src/inc/taoserror.h ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/* ${csudo} ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h ${csudo} ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h } function install_config() { #${csudo} rm -f ${install_main_dir}/cfg/taos.cfg || : - - if [ ! -f ${cfg_install_dir}/taos.cfg ]; then + + if [ ! -f ${cfg_install_dir}/taos.cfg ]; then ${csudo} mkdir -p ${cfg_install_dir} [ -f ${script_dir}/../cfg/taos.cfg ] && ${csudo} cp ${script_dir}/../cfg/taos.cfg ${cfg_install_dir} ${csudo} chmod 644 ${cfg_install_dir}/* - fi - + fi + ${csudo} cp -f ${script_dir}/../cfg/taos.cfg ${install_main_dir}/cfg/taos.cfg.org - ${csudo} ln -s ${cfg_install_dir}/taos.cfg ${install_main_dir}/cfg + ${csudo} ln -s ${cfg_install_dir}/taos.cfg ${install_main_dir}/cfg } -function install_log() { +function install_log() { ${csudo} rm -rf ${log_dir} || : if [ "$osType" != "Darwin" ]; then @@ -239,7 +284,7 @@ function install_log() { function install_data() { ${csudo} mkdir -p ${data_dir} - ${csudo} ln -s ${data_dir} ${install_main_dir}/data + ${csudo} ln -s ${data_dir} ${install_main_dir}/data } function install_connector() { @@ -254,8 +299,8 @@ function install_connector() { 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 ${binary_dir}/build/lib/*.jar ${install_main_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_dir}/connector/*.jar || echo &> /dev/null + + ${csudo} cp ${binary_dir}/build/lib/*.jar ${install_main_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_dir}/connector/*.jar || echo &> /dev/null } function install_examples() { @@ -264,8 +309,8 @@ function install_examples() { function clean_service_on_sysvinit() { #restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start" - #${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || : - + #${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || : + if pidof taosd &> /dev/null; then ${csudo} service taosd stop || : fi @@ -277,9 +322,9 @@ function clean_service_on_sysvinit() { elif ((${initd_mod}==3)); then ${csudo} update-rc.d -f taosd remove || : fi - + ${csudo} rm -f ${service_config_dir}/taosd || : - + if $(which init &> /dev/null); then ${csudo} init q || : fi @@ -298,10 +343,10 @@ function install_service_on_sysvinit() { ${csudo} cp -f ${script_dir}/../rpm/taosd ${install_main_dir}/init.d ${csudo} cp ${script_dir}/../rpm/taosd ${service_config_dir} && ${csudo} chmod a+x ${service_config_dir}/taosd fi - + #restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start" #${csudo} grep -q -F "$restart_config_str" /etc/inittab || ${csudo} bash -c "echo '${restart_config_str}' >> /etc/inittab" - + if ((${initd_mod}==1)); then ${csudo} chkconfig --add taosd || : ${csudo} chkconfig --level 2345 taosd on || : @@ -323,7 +368,7 @@ function clean_service_on_systemd() { ${csudo} systemctl disable taosd &> /dev/null || echo &> /dev/null ${csudo} rm -f ${taosd_service_config} -} +} # taos:2345:respawn:/etc/init.d/taosd start @@ -383,7 +428,7 @@ function update_TDengine() { sleep 1 fi fi - + install_main_path install_log @@ -431,16 +476,16 @@ function install_TDengine() { # Start to install if [ "$osType" != "Darwin" ]; then echo -e "${GREEN}Start to install TDEngine...${NC}" - else - echo -e "${GREEN}Start to install TDEngine Client ...${NC}" + else + echo -e "${GREEN}Start to install TDEngine Client ...${NC}" fi - install_main_path + install_main_path - if [ "$osType" != "Darwin" ]; then + if [ "$osType" != "Darwin" ]; then install_data fi - install_log + install_log install_header install_lib install_connector @@ -452,7 +497,7 @@ function install_TDengine() { install_service fi - install_config + install_config if [ "$osType" != "Darwin" ]; then # Ask if to start the service diff --git a/packaging/tools/makepkg.sh b/packaging/tools/makepkg.sh index e4d2d71b014293e1e328112e0d5e6e5677b772c0..624f72278a87be1d34d64d4e8b9381cbe663bede 100755 --- a/packaging/tools/makepkg.sh +++ b/packaging/tools/makepkg.sh @@ -30,12 +30,12 @@ else install_dir="${release_dir}/TDengine-server-${version}" fi -# Directories and files. +# Directories and files if [ "$pagMode" == "lite" ]; then - strip ${build_dir}/bin/taosd + strip ${build_dir}/bin/taosd strip ${build_dir}/bin/taos bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${script_dir}/remove.sh" -else +else bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${build_dir}/bin/taosdump ${build_dir}/bin/taosdemo ${build_dir}/bin/tarbitrator\ ${script_dir}/remove.sh ${script_dir}/set_core.sh ${script_dir}/startPre.sh ${script_dir}/taosd-dump-cfg.gdb" fi @@ -73,10 +73,43 @@ mkdir -p ${install_dir}/init.d && cp ${init_file_rpm} ${install_dir}/init.d/taos mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_deb} ${install_dir}/init.d/tarbitratord.deb || : mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_rpm} ${install_dir}/init.d/tarbitratord.rpm || : +if [ -f ${build_dir}/bin/jemalloc-config ]; then + mkdir -p ${install_dir}/jemalloc/{bin,lib,lib/pkgconfig,include/jemalloc,share/doc/jemalloc,share/man/man3} + cp ${build_dir}/bin/jemalloc-config ${install_dir}/jemalloc/bin + if [ -f ${build_dir}/bin/jemalloc.sh ]; then + cp ${build_dir}/bin/jemalloc.sh ${install_dir}/jemalloc/bin + fi + if [ -f ${build_dir}/bin/jeprof ]; then + cp ${build_dir}/bin/jeprof ${install_dir}/jemalloc/bin + fi + if [ -f ${build_dir}/include/jemalloc/jemalloc.h ]; then + cp ${build_dir}/include/jemalloc/jemalloc.h ${install_dir}/jemalloc/include/jemalloc + fi + if [ -f ${build_dir}/lib/libjemalloc.so.2 ]; then + cp ${build_dir}/lib/libjemalloc.so.2 ${install_dir}/jemalloc/lib + ln -sf libjemalloc.so.2 ${install_dir}/jemalloc/lib/libjemalloc.so + fi + if [ -f ${build_dir}/lib/libjemalloc.a ]; then + cp ${build_dir}/lib/libjemalloc.a ${install_dir}/jemalloc/lib + fi + if [ -f ${build_dir}/lib/libjemalloc_pic.a ]; then + cp ${build_dir}/lib/libjemalloc_pic.a ${install_dir}/jemalloc/lib + fi + if [ -f ${build_dir}/lib/pkgconfig/jemalloc.pc ]; then + cp ${build_dir}/lib/pkgconfig/jemalloc.pc ${install_dir}/jemalloc/lib/pkgconfig + fi + if [ -f ${build_dir}/share/doc/jemalloc/jemalloc.html ]; then + cp ${build_dir}/share/doc/jemalloc/jemalloc.html ${install_dir}/jemalloc/share/doc/jemalloc + fi + if [ -f ${build_dir}/share/man/man3/jemalloc.3 ]; then + cp ${build_dir}/share/man/man3/jemalloc.3 ${install_dir}/jemalloc/share/man/man3 + fi +fi + if [ "$verMode" == "cluster" ]; then sed 's/verMode=edge/verMode=cluster/g' ${install_dir}/bin/remove.sh >> remove_temp.sh mv remove_temp.sh ${install_dir}/bin/remove.sh - + mkdir -p ${install_dir}/nginxd && cp -r ${nginx_dir}/* ${install_dir}/nginxd cp ${nginx_dir}/png/taos.png ${install_dir}/nginxd/admin/images/taos.png rm -rf ${install_dir}/nginxd/png @@ -132,7 +165,7 @@ if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then 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 @@ -142,7 +175,7 @@ if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then cp -r ${examples_dir}/C# ${install_dir}/examples fi # Copy driver -mkdir -p ${install_dir}/driver +mkdir -p ${install_dir}/driver cp ${lib_files} ${install_dir}/driver # Copy connector @@ -168,7 +201,7 @@ fi # exit 1 -cd ${release_dir} +cd ${release_dir} if [ "$verMode" == "cluster" ]; then pkg_name=${install_dir}-${osType}-${cpuType} @@ -185,8 +218,8 @@ fi if [ "$verType" == "beta" ]; then pkg_name=${pkg_name}-${verType} -elif [ "$verType" == "stable" ]; then - pkg_name=${pkg_name} +elif [ "$verType" == "stable" ]; then + pkg_name=${pkg_name} else echo "unknow verType, nor stabel or beta" exit 1 diff --git a/src/client/inc/tscLocalMerge.h b/src/client/inc/tscGlobalmerge.h similarity index 55% rename from src/client/inc/tscLocalMerge.h rename to src/client/inc/tscGlobalmerge.h index 143922bb1fb6d6e10a157de5d90af2da5e221f76..a462d78ff0d0b57cc05bbe3bde273700e426ba4e 100644 --- a/src/client/inc/tscLocalMerge.h +++ b/src/client/inc/tscGlobalmerge.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef TDENGINE_TSCLOCALMERGE_H -#define TDENGINE_TSCLOCALMERGE_H +#ifndef TDENGINE_TSCGLOBALMERGE_H +#define TDENGINE_TSCGLOBALMERGE_H #ifdef __cplusplus extern "C" { @@ -24,7 +24,7 @@ extern "C" { #include "qFill.h" #include "taosmsg.h" #include "tlosertree.h" -#include "tsclient.h" +#include "qExecutor.h" #define MAX_NUM_OF_SUBQUERY_RETRY 3 @@ -38,40 +38,32 @@ typedef struct SLocalDataSource { tFilePage filePage; } SLocalDataSource; -typedef struct SLocalMerger { - SLocalDataSource ** pLocalDataSrc; +typedef struct SGlobalMerger { + 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 -} SLocalMerger; + SLoserTreeInfo *pLoserTree; + int32_t rowSize; // size of each intermediate result. + tOrderDescriptor *pDesc; + tExtMemBuffer **pExtMemBuffer; // disk-based buffer + char *buf; // temp buffer +} SGlobalMerger; + +struct SSqlObj; 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; + struct 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 tscCreateGlobalMergerEnv(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 tscDestroyGlobalMergerEnv(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,15 +73,13 @@ 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); - -void tscDestroyLocalMerger(SSqlObj *pSql); +int32_t tscCreateGlobalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc, + SQueryInfo *pQueryInfo, SGlobalMerger **pMerger, int64_t id); -//int32_t tscDoLocalMerge(SSqlObj *pSql); +void tscDestroyGlobalMerger(SGlobalMerger* pMerger); #ifdef __cplusplus } #endif -#endif // TDENGINE_TSCLOCALMERGE_H +#endif // TDENGINE_TSCGLOBALMERGE_H diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 0348606d6b5dbcbe2ccaf172a228cdb7da97374b..f747184ce017e9cb780ba2a61b87360cee0379d8 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -25,7 +25,8 @@ extern "C" { #include "qExtbuffer.h" #include "taosdef.h" #include "tbuffer.h" -#include "tscLocalMerge.h" +#include "tscGlobalmerge.h" +#include "tsched.h" #include "tsclient.h" #define UTIL_TABLE_IS_SUPER_TABLE(metaInfo) \ @@ -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); @@ -114,7 +110,7 @@ void* tscDestroyBlockArrayList(SArray* pDataBlockList); void* tscDestroyBlockHashTable(SHashObj* pBlockHashTable, bool removeMeta); int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock); -int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap); +int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBlockMap); int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int32_t startOffset, int32_t rowSize, SName* pName, STableMeta* pTableMeta, STableDataBlocks** dataBlocks, SArray* pBlockList); @@ -127,7 +123,9 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i */ 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); @@ -136,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); @@ -150,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); @@ -171,36 +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 *diffSize); -int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2); +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); @@ -275,11 +286,12 @@ void tscSVgroupInfoCopy(SVgroupInfo* dst, const SVgroupInfo* src); SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, int32_t cmd); void registerSqlObj(SSqlObj* pSql); +void tscInitResForMerge(SSqlRes* pRes); 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 +307,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); @@ -309,15 +326,20 @@ CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta); uint32_t tscGetTableMetaMaxSize(); 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, 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); char* strdup_throw(const char* str); +bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src); +SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg); + #ifdef __cplusplus } #endif diff --git a/src/client/inc/tschemautil.h b/src/client/inc/tschemautil.h deleted file mode 100644 index 0026a27e199289fa06dbcd8f10a2313bc61430ea..0000000000000000000000000000000000000000 --- a/src/client/inc/tschemautil.h +++ /dev/null @@ -1,93 +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 . - */ - -#ifndef TDENGINE_TSCHEMAUTIL_H -#define TDENGINE_TSCHEMAUTIL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "taosmsg.h" -#include "tsclient.h" -#include "ttoken.h" - -/** - * get the number of tags of this table - * @param pTableMeta - * @return - */ -int32_t tscGetNumOfTags(const STableMeta* pTableMeta); - -/** - * get the number of columns of this table - * @param pTableMeta - * @return - */ -int32_t tscGetNumOfColumns(const STableMeta* pTableMeta); - -/** - * get the basic info of this table - * @param pTableMeta - * @return - */ -STableComInfo tscGetTableInfo(const STableMeta* pTableMeta); - -/** - * get the schema - * @param pTableMeta - * @return - */ -SSchema* tscGetTableSchema(const STableMeta* pTableMeta); - -/** - * get the tag schema - * @param pMeta - * @return - */ -SSchema *tscGetTableTagSchema(const STableMeta *pMeta); - -/** - * get the column schema according to the column index - * @param pMeta - * @param colIndex - * @return - */ -SSchema *tscGetTableColumnSchema(const STableMeta *pMeta, int32_t colIndex); - -/** - * get the column schema according to the column id - * @param pTableMeta - * @param colId - * @return - */ -SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId); - -/** - * create the table meta from the msg - * @param pTableMetaMsg - * @param size size of the table meta - * @return - */ -STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg); - -bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src); -SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg); - -#ifdef __cplusplus -} -#endif - -#endif // TDENGINE_TSCHEMAUTIL_H diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 81443360f4a5bbd4f2917cff136fb926eafd009d..67fd34ffd7425cf921e927247149808540de3020 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -40,23 +40,9 @@ extern "C" { // forward declaration 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 { - uint8_t numOfTags; - uint8_t precision; - int16_t numOfColumns; - int32_t rowSize; -} STableComInfo; - typedef struct SNewVgroupInfo { int32_t vgId; int8_t inUse; @@ -72,34 +58,6 @@ typedef struct CChildTableMeta { uint64_t suid; // super table id } CChildTableMeta; -typedef struct STableMeta { - int32_t vgId; - STableId id; - uint8_t tableType; - char sTableName[TSDB_TABLE_FNAME_LEN]; // super table name - uint64_t suid; // super table id - int16_t sversion; - int16_t tversion; - STableComInfo tableInfo; - SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info -} STableMeta; - -typedef struct STableMetaInfo { - 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 - * 2. keep the vgroup index for multi-vnode insertion - */ - int32_t vgroupIndex; - SName name; - char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql - SArray *tagColList; // SArray, involved tag columns -} STableMetaInfo; - typedef struct SColumnIndex { int16_t tableIndex; int16_t columnIndex; @@ -117,44 +75,6 @@ typedef struct SInternalField { SExprInfo *pExpr; } SInternalField; -typedef struct SFieldInfo { - int16_t numOfOutput; // number of column in result - TAOS_FIELD* final; - SArray *internalField; // SArray -} SFieldInfo; - -typedef struct SCond { - uint64_t uid; - int32_t len; // length of tag query condition data - char * cond; -} SCond; - -typedef struct SJoinNode { - uint64_t uid; - int16_t tagColId; - SArray* tsJoin; - SArray* tagJoin; -} SJoinNode; - -typedef struct SJoinInfo { - bool hasJoin; - SJoinNode* joinTables[TSDB_MAX_JOIN_TABLE_NUM]; -} SJoinInfo; - -typedef struct STagCond { - // relation between tbname list and query condition, including : TK_AND or TK_OR - int16_t relType; - - // tbname query condition, only support tbname query condition on one table - SCond tbnameCond; - - // join condition, only support two tables join currently - SJoinInfo joinInfo; - - // for different table, the query condition must be seperated - SArray *pCond; -} STagCond; - typedef struct SParamInfo { int32_t idx; uint8_t type; @@ -197,92 +117,48 @@ typedef struct STableDataBlocks { SParamInfo *params; } STableDataBlocks; -typedef struct SQueryInfo { - int16_t command; // the command may be different for each subclause, so keep it seperately. - uint32_t type; // query/insert type - STimeWindow window; // the whole query time window - - SInterval interval; // tumble time window - SSessionWindow sessionWindow; // session time window - - SSqlGroupbyExpr groupbyExpr; // groupby tags info - SArray * colList; // SArray - SFieldInfo fieldsInfo; - SArray * exprList; // SArray - SLimitVal limit; - SLimitVal slimit; - STagCond tagCond; - - SOrderVal order; - int16_t fillType; // final result fill type - int16_t numOfTables; - STableMetaInfo **pTableMetaInfo; - struct STSBuf *tsBuf; - int64_t * fillVal; // default value for fill - char * msg; // pointer to the pCmd->payload to keep error message temporarily - int64_t clauseLimit; // limit for current sub clause - - int64_t prjOffset; // offset value in the original sql expression, only applied at client side - int64_t vgroupLimit; // table limit in case of super table projection query + global order + limit - - int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX - int16_t resColumnId; // result column id - bool distinctTag; // distinct tag or not - int32_t round; // 0/1/.... - 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; -} 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 + int32_t batchSize; // for parameter ('?') binding and batch processing + int32_t numOfParams; + + char msg[512]; // error message + uint32_t insertType; // insert data from [file|sql statement| bound statement] + uint64_t objectId; // sql object id + char *sql; // current sql statement position +} 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; - }; + int32_t count; // todo remove it - 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; char reserve3[2]; // fix bus error on arm32 uint32_t allocSize; 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 - 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 + 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 resColumnId; } SSqlCmd; typedef struct SResRec { @@ -317,7 +193,7 @@ typedef struct { TAOS_FIELD* final; SArithmeticSupport *pArithSup; // support the arithmetic expression calculation on agg functions - struct SLocalMerger *pLocalMerger; + struct SGlobalMerger *pMerger; } SSqlRes; typedef struct { @@ -443,8 +319,8 @@ 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 destroyTableNameList(SSqlCmd* pCmd); +void handleDownstreamOperator(SSqlObj** pSqlList, int32_t numOfUpstream, SQueryInfo* px, SSqlRes* pOutput); +void destroyTableNameList(SInsertStatementParam* pInsertParam); void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta); @@ -476,7 +352,7 @@ void waitForQueryRsp(void *param, TAOS_RES *tres, int code); void doAsyncQuery(STscObj *pObj, SSqlObj *pSql, __async_cb_func_t fp, void *param, const char *sqlstr, size_t sqlLen); void tscImportDataFromFile(SSqlObj *pSql); -void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen); +struct SGlobalMerger* tscInitResObjForLocalQuery(int32_t numOfRes, int32_t rowLen, uint64_t id); bool tscIsUpdateQuery(SSqlObj* pSql); char* tscGetSqlStr(SSqlObj* pSql); bool tscIsQueryWithLimit(SSqlObj* pSql); @@ -486,10 +362,10 @@ void tscSetBoundColumnInfo(SParsedDataColInfo *pColInfo, SSchema *pSchema, int32 char *tscGetErrorMsgPayload(SSqlCmd *pCmd); -int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql); +int32_t tscInvalidOperationMsg(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; @@ -505,7 +381,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 04bccc1a4a9e81c8dd9d70521f9916c304df3a53..d16b672f38fe1f7d9c36990f0eab28253f2d4d1b 100644 --- a/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h +++ b/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h @@ -218,11 +218,19 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(J /* * Class: com_taosdata_jdbc_TSDBJNIConnector - * Method: executeBatchImp + * 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 da7da17aa3ee29b31acbe2470edf052f1d9cb15b..324c436dce442f78b6daea314506c5c6b465f97f 100644 --- a/src/client/src/TSDBJNIConnector.c +++ b/src/client/src/TSDBJNIConnector.c @@ -749,7 +749,6 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI } jniDebug("jobj:%p, conn:%p, set stmt bind table name:%s", jobj, tsconn, name); - (*env)->ReleaseStringUTFChars(env, jname, name); return JNI_SUCCESS; } @@ -762,7 +761,7 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J return JNI_CONNECTION_NULL; } - TAOS_STMT* pStmt = (TAOS_STMT*) stmt; + TAOS_STMT *pStmt = (TAOS_STMT *)stmt; if (pStmt == NULL) { jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon); return JNI_SQL_NULL; @@ -777,14 +776,14 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J } len = (*env)->GetArrayLength(env, lengthList); - char *lengthArray = (char*) calloc(1, len); - (*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte*) lengthArray); + 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); + char *nullArray = (char *)calloc(1, len); + (*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte *)nullArray); if ((*env)->ExceptionCheck(env)) { } @@ -799,22 +798,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J b->length = (int32_t*)lengthArray; // set the length and is_null array - switch(dataType) { - case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_TIMESTAMP: - case TSDB_DATA_TYPE_BIGINT: { - int32_t bytes = tDataTypes[dataType].bytes; - for(int32_t i = 0; i < numOfRows; ++i) { - b->length[i] = bytes; - } - break; - } - - case TSDB_DATA_TYPE_NCHAR: - case TSDB_DATA_TYPE_BINARY: { - // do nothing + if (!IS_VAR_DATA_TYPE(dataType)) { + int32_t bytes = tDataTypes[dataType].bytes; + for (int32_t i = 0; i < numOfRows; ++i) { + b->length[i] = bytes; } } @@ -878,3 +865,74 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv 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..15276a38887523541cbe37ebf1add2152d2ffe80 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -22,7 +22,7 @@ #include "tscSubquery.h" #include "tscUtil.h" #include "tsched.h" -#include "tschemautil.h" +#include "qTableMeta.h" #include "tsclient.h" static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOfRows); @@ -58,7 +58,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para strntolower(pSql->sqlstr, sqlstr, (int32_t)sqlLen); 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 +69,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 +127,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; } @@ -219,7 +220,18 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) { tscResetForNextRetrieve(pRes); - // handle the sub queries of join query + // handle outer query based on the already retrieved nest query results. + 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 +243,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 +268,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 +330,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 +399,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 +426,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 +437,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 +448,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/tscLocalMerge.c b/src/client/src/tscGlobalmerge.c similarity index 63% rename from src/client/src/tscLocalMerge.c rename to src/client/src/tscGlobalmerge.c index e4a3ace6b5af128971a5bed21562082602754d97..d835b37c2497c241d52a243d34ab4ab63e76c12a 100644 --- a/src/client/src/tscLocalMerge.c +++ b/src/client/src/tscGlobalmerge.c @@ -13,17 +13,19 @@ * along with this program. If not, see . */ -#include "tscLocalMerge.h" -#include "tscSubquery.h" #include "os.h" #include "texpr.h" #include "tlosertree.h" + +#include "tscGlobalmerge.h" +#include "tscSubquery.h" #include "tscLog.h" -#include "tscUtil.h" -#include "tschemautil.h" -#include "tsclient.h" #include "qUtil.h" +#define COLMODEL_GET_VAL(data, schema, rowId, colId) \ + (data + (schema)->pFields[colId].offset * ((schema)->capacity) + (rowId) * (schema)->pFields[colId].field.bytes) + + typedef struct SCompareParam { SLocalDataSource **pLocalData; tOrderDescriptor * pDesc; @@ -31,9 +33,18 @@ typedef struct SCompareParam { int32_t groupOrderType; } SCompareParam; -bool needToMergeRv(SSDataBlock* pBlock, SArray* columnIndex, int32_t index, char **buf); +static bool needToMerge(SSDataBlock* pBlock, SArray* columnIndexList, int32_t index, char **buf) { + int32_t ret = 0; + size_t size = taosArrayGetSize(columnIndexList); + if (size > 0) { + ret = compare_aRv(pBlock, columnIndexList, (int32_t) size, index, buf, TSDB_ORDER_ASC); + } -int32_t treeComparator(const void *pLeft, const void *pRight, void *param) { + // if ret == 0, means the result belongs to the same group + return (ret == 0); +} + +static int32_t treeComparator(const void *pLeft, const void *pRight, void *param) { int32_t pLeftIdx = *(int32_t *)pLeft; int32_t pRightIdx = *(int32_t *)pRight; @@ -59,77 +70,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 tscCreateGlobalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc, + SQueryInfo* pQueryInfo, SGlobalMerger **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; + tscDestroyGlobalMergerEnv(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; + tscDestroyGlobalMergerEnv(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 +96,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; + tscDestroyGlobalMergerEnv(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; + tscDestroyGlobalMergerEnv(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 = (SGlobalMerger *) calloc(1, sizeof(SGlobalMerger)); + 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; + tscDestroyGlobalMergerEnv(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 +134,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 +147,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 +161,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 +172,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); + tscDestroyGlobalMergerEnv(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->nResultBufSize = pMemBuffer[0]->pageSize * 16; - pMerger->pResultBuf = (tFilePage *)calloc(1, pMerger->nResultBufSize + sizeof(tFilePage)); - - pMerger->resColModel = finalmodel; - pMerger->resColModel->capacity = pMerger->nResultBufSize; - pMerger->finalModel = pFFModel; - - if (finalmodel->rowSize > 0) { - pMerger->resColModel->capacity /= finalmodel->rowSize; - } + (*pMerger)->rowSize = pMemBuffer[0]->nElemSize; - assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pMerger->rowSize); + // todo fixed row size is larger than the minimum page size; + assert((*pMerger)->rowSize <= pMemBuffer[0]->pageSize); - 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)) { + if (pQueryInfo->orderProjectQuery) { 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,51 +310,39 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa return 0; } -void tscDestroyLocalMerger(SSqlObj *pSql) { - if (pSql == NULL) { +void tscDestroyGlobalMerger(SGlobalMerger* pMerger) { + if (pMerger == NULL) { return; } - SSqlRes *pRes = &(pSql->res); - if (pRes->pLocalMerger == NULL) { - return; + for (int32_t i = 0; i < pMerger->numOfBuffer; ++i) { + tfree(pMerger->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); + pMerger->numOfBuffer = 0; + tscDestroyGlobalMergerEnv(pMerger->pExtMemBuffer, pMerger->pDesc, pMerger->numOfVnode); - if (pLocalMerge->pLoserTree) { - tfree(pLocalMerge->pLoserTree->param); - tfree(pLocalMerge->pLoserTree); - } + pMerger->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 (pMerger->pLoserTree) { + tfree(pMerger->pLoserTree->param); + tfree(pMerger->pLoserTree); } - pLocalMerge->numOfBuffer = 0; - pLocalMerge->numOfCompleted = 0; - tfree(pLocalMerge->pTempBuffer); - - free(pLocalMerge); - - tscDebug("0x%"PRIx64" free local reducer finished", pSql->self); + tfree(pMerger->buf); + tfree(pMerger->pLocalDataSrc); + free(pMerger); } -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; } // primary timestamp column is involved in final result - if (pQueryInfo->interval.interval != 0 || tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { + if (pQueryInfo->interval.interval != 0 || pQueryInfo->orderProjectQuery) { numOfGroupByCols++; } @@ -474,13 +354,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 +382,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 +405,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 tscCreateGlobalMergerEnv(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 +443,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 +451,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 tscDestroyGlobalMergerEnv(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, int32_t numOfVnodes) { tOrderDescDestroy(pDesc); - for (int32_t i = 0; i < numOfVnodes; ++i) { pMemBuffer[i] = destoryExtMemBuffer(pMemBuffer[i]); } @@ -675,12 +480,12 @@ void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDe /** * - * @param pLocalMerge + * @param pMerger * @param pOneInterDataSrc * @param treeList * @return the number of remain input source. if ret == 0, all data has been handled */ -int32_t loadNewDataFromDiskFor(SLocalMerger *pLocalMerge, SLocalDataSource *pOneInterDataSrc, +int32_t loadNewDataFromDiskFor(SGlobalMerger *pMerger, SLocalDataSource *pOneInterDataSrc, bool *needAdjustLoserTree) { pOneInterDataSrc->rowIdx = 0; pOneInterDataSrc->pageId += 1; @@ -697,17 +502,17 @@ int32_t loadNewDataFromDiskFor(SLocalMerger *pLocalMerge, SLocalDataSource *pOne #endif *needAdjustLoserTree = true; } else { - pLocalMerge->numOfCompleted += 1; + pMerger->numOfCompleted += 1; pOneInterDataSrc->rowIdx = -1; pOneInterDataSrc->pageId = -1; *needAdjustLoserTree = true; } - return pLocalMerge->numOfBuffer; + return pMerger->numOfBuffer; } -void adjustLoserTreeFromNewData(SLocalMerger *pLocalMerge, SLocalDataSource *pOneInterDataSrc, +void adjustLoserTreeFromNewData(SGlobalMerger *pMerger, SLocalDataSource *pOneInterDataSrc, SLoserTreeInfo *pTree) { /* * load a new data page into memory for intermediate dataset source, @@ -715,7 +520,7 @@ void adjustLoserTreeFromNewData(SLocalMerger *pLocalMerge, SLocalDataSource *pOn */ bool needToAdjust = true; if (pOneInterDataSrc->filePage.num <= pOneInterDataSrc->rowIdx) { - loadNewDataFromDiskFor(pLocalMerge, pOneInterDataSrc, &needToAdjust); + loadNewDataFromDiskFor(pMerger, pOneInterDataSrc, &needToAdjust); } /* @@ -723,7 +528,7 @@ void adjustLoserTreeFromNewData(SLocalMerger *pLocalMerge, SLocalDataSource *pOn * if the loser tree is rebuild completed, we do not need to adjust */ if (needToAdjust) { - int32_t leafNodeIdx = pTree->pNode[0].index + pLocalMerge->numOfBuffer; + int32_t leafNodeIdx = pTree->pNode[0].index + pMerger->numOfBuffer; #ifdef _DEBUG_VIEW printf("before adjust:\t"); @@ -775,7 +580,7 @@ static void setTagValueForMultipleRows(SQLFunctionCtx* pCtx, int32_t numOfOutput } } -static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) { +static void doExecuteFinalMerge(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) { SMultiwayMergeInfo* pInfo = pOperator->info; SQLFunctionCtx* pCtx = pInfo->binfo.pCtx; @@ -787,7 +592,7 @@ static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, S for(int32_t i = 0; i < pBlock->info.rows; ++i) { if (pInfo->hasPrev) { - if (needToMergeRv(pBlock, pInfo->orderColumnList, i, pInfo->prevRow)) { + if (needToMerge(pBlock, pInfo->orderColumnList, i, pInfo->prevRow)) { for (int32_t j = 0; j < numOfExpr; ++j) { pCtx[j].pInput = add[j] + pCtx[j].inputBytes * i; } @@ -862,45 +667,27 @@ static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, S tfree(add); } -bool needToMergeRv(SSDataBlock* pBlock, SArray* columnIndexList, int32_t index, char **buf) { - int32_t ret = 0; - size_t size = taosArrayGetSize(columnIndexList); - if (size > 0) { - ret = compare_aRv(pBlock, columnIndexList, (int32_t) size, index, buf, TSDB_ORDER_ASC); - } - - // if ret == 0, means the result belongs to the same group - return (ret == 0); -} - -static bool isAllSourcesCompleted(SLocalMerger *pLocalMerge) { - return (pLocalMerge->numOfBuffer == pLocalMerge->numOfCompleted); +static bool isAllSourcesCompleted(SGlobalMerger *pMerger) { + return (pMerger->numOfBuffer == pMerger->numOfCompleted); } -void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen) { - SSqlRes *pRes = &pObj->res; - if (pRes->pLocalMerger != NULL) { - tscDestroyLocalMerger(pObj); +SGlobalMerger* tscInitResObjForLocalQuery(int32_t numOfRes, int32_t rowLen, uint64_t id) { + SGlobalMerger *pMerger = calloc(1, sizeof(SGlobalMerger)); + if (pMerger == NULL) { + tscDebug("0x%"PRIx64" free local reducer finished", id); + return NULL; } - pRes->qId = 1; // hack to pass the safety check in fetch_row function - pRes->numOfRows = 0; - pRes->row = 0; - - pRes->rspType = 0; // used as a flag to denote if taos_retrieved() has been called yet - 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; + pMerger->buf = calloc(1, size); + return pMerger; } +// todo remove it int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) { int32_t maxRowSize = MAX(rowSize, finalRowSize); char* pbuf = calloc(1, (size_t)(pOutput->num * maxRowSize)); @@ -910,12 +697,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,16 +731,13 @@ 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) - static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel *pModel, int32_t rowIndex, int32_t maxRows) { for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { 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); } @@ -968,10 +752,8 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) { SMultiwayMergeInfo *pInfo = pOperator->info; - SLocalMerger *pMerger = pInfo->pMerge; + SGlobalMerger *pMerger = pInfo->pMerge; SLoserTreeInfo *pTree = pMerger->pLoserTree; - SColumnModel *pModel = pMerger->pDesc->pColumnModel; - tFilePage *tmpBuffer = pMerger->pTempBuffer; pInfo->binfo.pRes->info.rows = 0; @@ -984,7 +766,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 +779,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 +801,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 +813,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"); @@ -1055,7 +836,7 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) { return (pInfo->binfo.pRes->info.rows > 0)? pInfo->binfo.pRes:NULL; } -static bool isSameGroupRv(SArray* orderColumnList, SSDataBlock* pBlock, char** dataCols) { +static bool isSameGroup(SArray* orderColumnList, SSDataBlock* pBlock, char** dataCols) { int32_t numOfCols = (int32_t) taosArrayGetSize(orderColumnList); for (int32_t i = 0; i < numOfCols; ++i) { SColIndex *pIndex = taosArrayGet(orderColumnList, i); @@ -1082,7 +863,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; @@ -1103,7 +884,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) { } } - doExecuteFinalMergeRv(pOperator, pOperator->numOfOutput, pAggInfo->pExistBlock); + doExecuteFinalMerge(pOperator, pOperator->numOfOutput, pAggInfo->pExistBlock); savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pAggInfo->pExistBlock, 0, &pAggInfo->hasGroupColData); @@ -1124,7 +905,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) { } if (pAggInfo->hasGroupColData) { - bool sameGroup = isSameGroupRv(pAggInfo->groupColumnList, pBlock, pAggInfo->currentGroupColData); + bool sameGroup = isSameGroup(pAggInfo->groupColumnList, pBlock, pAggInfo->currentGroupColData); if (!sameGroup) { *newgroup = true; pAggInfo->hasDataBlockForNewGroup = true; @@ -1138,7 +919,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) { setInputDataBlock(pOperator, pAggInfo->binfo.pCtx, pBlock, TSDB_ORDER_ASC); updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor); - doExecuteFinalMergeRv(pOperator, pOperator->numOfOutput, pBlock); + doExecuteFinalMerge(pOperator, pOperator->numOfOutput, pBlock); savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pBlock, 0, &pAggInfo->hasGroupColData); handleData = true; } @@ -1166,7 +947,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 +966,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 +974,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 +986,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 +1000,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/tscLocal.c b/src/client/src/tscLocal.c index 1be5e29230d6234015b8d443558bd9d3dd85ba7c..f97f54a6267d2754cb2edf2fd38ff6c075a2b285 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -20,7 +20,7 @@ #include "tname.h" #include "tscLog.h" #include "tscUtil.h" -#include "tschemautil.h" +#include "qTableMeta.h" #include "tsclient.h" #include "taos.h" #include "tscSubquery.h" @@ -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; @@ -71,7 +71,9 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { numOfRows = numOfRows + tscGetNumOfTags(pMeta); } - tscInitResObjForLocalQuery(pSql, totalNumOfRows, rowLen); + pSql->res.pMerger = tscInitResObjForLocalQuery(totalNumOfRows, rowLen, pSql->self); + tscInitResForMerge(&pSql->res); + SSchema *pSchema = tscGetTableSchema(pMeta); for (int32_t i = 0; i < numOfRows; ++i) { @@ -154,14 +156,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 +173,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Type", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = 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 +183,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Length", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = 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 +193,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Note", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pExpr = 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 +201,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 +392,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 +407,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 +420,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,12 +430,13 @@ 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) { } - tscInitResObjForLocalQuery(pSql, numOfRows, rowLen); + pSql->res.pMerger = tscInitResObjForLocalQuery(numOfRows, rowLen, pSql->self); + tscInitResForMerge(&pSql->res); TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0); char* dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * numOfRows; @@ -445,7 +448,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 +535,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 +556,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 +610,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 +637,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 +678,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 +707,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); @@ -730,7 +733,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; @@ -757,7 +760,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; @@ -784,7 +787,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; @@ -807,7 +810,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; @@ -859,7 +862,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; @@ -873,7 +876,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); @@ -882,7 +885,8 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa TAOS_FIELD f = tscCreateField((int8_t)type, columnName, (int16_t)valueLength); tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - tscInitResObjForLocalQuery(pSql, 1, (int32_t)valueLength); + pSql->res.pMerger = tscInitResObjForLocalQuery(1, (int32_t)valueLength, pSql->self); + tscInitResForMerge(&pSql->res); SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, 0); pInfo->pExpr = taosArrayGetP(pQueryInfo->exprList, 0); @@ -928,7 +932,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/tscParseInsert.c b/src/client/src/tscParseInsert.c index d96e25dd3799f24d5f846553b7e23161d7107419..cd9853df03bab1a953ee8fd79e66a52e84ba157c 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -23,7 +23,7 @@ #include "ttype.h" #include "hash.h" #include "tscUtil.h" -#include "tschemautil.h" +#include "qTableMeta.h" #include "tsclient.h" #include "ttokendef.h" #include "taosdef.h" @@ -38,8 +38,9 @@ enum { TSDB_USE_CLI_TS = 1, }; -static int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t * numOfRows); -static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SSchema* pSchema, char* str, char** end); +static int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t *numOfRows); +static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDataColInfo *pColInfo, SSchema *pSchema, + char *str, char **end); static int32_t tscToDouble(SStrToken *pToken, double *value, char **endPtr) { errno = 0; @@ -71,7 +72,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 } else { // strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm); if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(error, "invalid timestamp format", pToken->z); + return tscInvalidOperationMsg(error, "invalid timestamp format", pToken->z); } return TSDB_CODE_SUCCESS; @@ -103,11 +104,11 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 pTokenEnd += index; if (valueToken.n < 2) { - return tscInvalidSQLErrMsg(error, "value expected in timestamp", sToken.z); + return tscInvalidOperationMsg(error, "value expected in timestamp", sToken.z); } 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) { @@ -138,7 +139,7 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha char *endptr = NULL; if (IS_NUMERIC_TYPE(pSchema->type) && pToken->n == 0) { - return tscInvalidSQLErrMsg(msg, "invalid numeric data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid numeric data", pToken->z); } switch (pSchema->type) { @@ -161,7 +162,7 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha double dv = strtod(pToken->z, NULL); *(uint8_t *)payload = (int8_t)((dv == 0) ? TSDB_FALSE : TSDB_TRUE); } else { - return tscInvalidSQLErrMsg(msg, "invalid bool data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid bool data", pToken->z); } } break; @@ -173,9 +174,9 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true); if (ret != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(msg, "invalid tinyint data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid tinyint data", pToken->z); } else if (!IS_VALID_TINYINT(iv)) { - return tscInvalidSQLErrMsg(msg, "data overflow", pToken->z); + return tscInvalidOperationMsg(msg, "data overflow", pToken->z); } *((uint8_t *)payload) = (uint8_t)iv; @@ -189,9 +190,9 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false); if (ret != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(msg, "invalid unsigned tinyint data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid unsigned tinyint data", pToken->z); } else if (!IS_VALID_UTINYINT(iv)) { - return tscInvalidSQLErrMsg(msg, "unsigned tinyint data overflow", pToken->z); + return tscInvalidOperationMsg(msg, "unsigned tinyint data overflow", pToken->z); } *((uint8_t *)payload) = (uint8_t)iv; @@ -205,9 +206,9 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true); if (ret != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(msg, "invalid smallint data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid smallint data", pToken->z); } else if (!IS_VALID_SMALLINT(iv)) { - return tscInvalidSQLErrMsg(msg, "smallint data overflow", pToken->z); + return tscInvalidOperationMsg(msg, "smallint data overflow", pToken->z); } *((int16_t *)payload) = (int16_t)iv; @@ -221,9 +222,9 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false); if (ret != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(msg, "invalid unsigned smallint data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid unsigned smallint data", pToken->z); } else if (!IS_VALID_USMALLINT(iv)) { - return tscInvalidSQLErrMsg(msg, "unsigned smallint data overflow", pToken->z); + return tscInvalidOperationMsg(msg, "unsigned smallint data overflow", pToken->z); } *((uint16_t *)payload) = (uint16_t)iv; @@ -237,9 +238,9 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true); if (ret != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(msg, "invalid int data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid int data", pToken->z); } else if (!IS_VALID_INT(iv)) { - return tscInvalidSQLErrMsg(msg, "int data overflow", pToken->z); + return tscInvalidOperationMsg(msg, "int data overflow", pToken->z); } *((int32_t *)payload) = (int32_t)iv; @@ -253,9 +254,9 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false); if (ret != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(msg, "invalid unsigned int data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid unsigned int data", pToken->z); } else if (!IS_VALID_UINT(iv)) { - return tscInvalidSQLErrMsg(msg, "unsigned int data overflow", pToken->z); + return tscInvalidOperationMsg(msg, "unsigned int data overflow", pToken->z); } *((uint32_t *)payload) = (uint32_t)iv; @@ -269,9 +270,9 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true); if (ret != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(msg, "invalid bigint data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid bigint data", pToken->z); } else if (!IS_VALID_BIGINT(iv)) { - return tscInvalidSQLErrMsg(msg, "bigint data overflow", pToken->z); + return tscInvalidOperationMsg(msg, "bigint data overflow", pToken->z); } *((int64_t *)payload) = iv; @@ -284,9 +285,9 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false); if (ret != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(msg, "invalid unsigned bigint data", pToken->z); + return tscInvalidOperationMsg(msg, "invalid unsigned bigint data", pToken->z); } else if (!IS_VALID_UBIGINT((uint64_t)iv)) { - return tscInvalidSQLErrMsg(msg, "unsigned bigint data overflow", pToken->z); + return tscInvalidOperationMsg(msg, "unsigned bigint data overflow", pToken->z); } *((uint64_t *)payload) = iv; @@ -299,11 +300,11 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { double dv; if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) { - return tscInvalidSQLErrMsg(msg, "illegal float data", pToken->z); + return tscInvalidOperationMsg(msg, "illegal float data", pToken->z); } if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) { - return tscInvalidSQLErrMsg(msg, "illegal float data", pToken->z); + return tscInvalidOperationMsg(msg, "illegal float data", pToken->z); } // *((float *)payload) = (float)dv; @@ -317,11 +318,11 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { double dv; if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) { - return tscInvalidSQLErrMsg(msg, "illegal double data", pToken->z); + return tscInvalidOperationMsg(msg, "illegal double data", pToken->z); } if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) { - return tscInvalidSQLErrMsg(msg, "illegal double data", pToken->z); + return tscInvalidOperationMsg(msg, "illegal double data", pToken->z); } *((double *)payload) = dv; @@ -334,7 +335,7 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha setVardataNull(payload, TSDB_DATA_TYPE_BINARY); } else { // too long values will return invalid sql, not be truncated automatically if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) { //todo refactor - return tscInvalidSQLErrMsg(msg, "string data overflow", pToken->z); + return tscInvalidOperationMsg(msg, "string data overflow", pToken->z); } STR_WITH_SIZE_TO_VARSTR(payload, pToken->z, pToken->n); @@ -351,7 +352,7 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha if (!taosMbsToUcs4(pToken->z, pToken->n, varDataVal(payload), pSchema->bytes - VARSTR_HEADER_SIZE, &output)) { char buf[512] = {0}; snprintf(buf, tListLen(buf), "%s", strerror(errno)); - return tscInvalidSQLErrMsg(msg, buf, pToken->z); + return tscInvalidOperationMsg(msg, buf, pToken->z); } varDataSetLen(payload, output); @@ -368,7 +369,7 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } else { int64_t temp; if (tsParseTime(pToken, &temp, str, msg, timePrec) != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(msg, "invalid timestamp", pToken->z); + return tscInvalidOperationMsg(msg, "invalid timestamp", pToken->z); } *((int64_t *)payload) = temp; @@ -417,8 +418,8 @@ int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start) { return TSDB_CODE_SUCCESS; } -int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int16_t timePrec, int32_t *len, - char *tmpTokenBuf) { +int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, int32_t *len, + char *tmpTokenBuf, SInsertStatementParam* pInsertParam) { int32_t index = 0; SStrToken sToken = {0}; char *payload = pDataBlocks->pData + pDataBlocks->size; @@ -441,8 +442,8 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1 *str += index; if (sToken.type == TK_QUESTION) { - if (pCmd->insertType != TSDB_QUERY_TYPE_STMT_INSERT) { - return tscSQLSyntaxErrMsg(pCmd->payload, "? only allowed in binding insertion", *str); + if (pInsertParam->insertType != TSDB_QUERY_TYPE_STMT_INSERT) { + return tscSQLSyntaxErrMsg(pInsertParam->msg, "? only allowed in binding insertion", *str); } uint32_t offset = (uint32_t)(start - pDataBlocks->pData); @@ -450,14 +451,14 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1 continue; } - strcpy(pCmd->payload, "client out of memory"); + strcpy(pInsertParam->msg, "client out of memory"); return TSDB_CODE_TSC_OUT_OF_MEMORY; } int16_t type = sToken.type; if ((type != TK_NOW && type != TK_INTEGER && type != TK_STRING && type != TK_FLOAT && type != TK_BOOL && type != TK_NULL && type != TK_HEX && type != TK_OCT && type != TK_BIN) || (sToken.n == 0) || (type == TK_RP)) { - return tscSQLSyntaxErrMsg(pCmd->payload, "invalid data or symbol", sToken.z); + return tscSQLSyntaxErrMsg(pInsertParam->msg, "invalid data or symbol", sToken.z); } // Remove quotation marks @@ -487,13 +488,13 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1 } bool isPrimaryKey = (colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX); - int32_t ret = tsParseOneColumn(pSchema, &sToken, start, pCmd->payload, str, isPrimaryKey, timePrec); + int32_t ret = tsParseOneColumn(pSchema, &sToken, start, pInsertParam->msg, str, isPrimaryKey, timePrec); if (ret != TSDB_CODE_SUCCESS) { return ret; } if (isPrimaryKey && tsCheckTimestamp(pDataBlocks, start) != TSDB_CODE_SUCCESS) { - tscInvalidSQLErrMsg(pCmd->payload, "client time/server time can not be mixed up", sToken.z); + tscInvalidOperationMsg(pInsertParam->msg, "client time/server time can not be mixed up", sToken.z); return TSDB_CODE_TSC_INVALID_TIME_STAMP; } } @@ -536,7 +537,8 @@ static int32_t rowDataCompar(const void *lhs, const void *rhs) { } } -int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SSqlCmd* pCmd, int32_t* numOfRows, char *tmpTokenBuf) { +int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SInsertStatementParam *pInsertParam, + int32_t* numOfRows, char *tmpTokenBuf) { int32_t index = 0; int32_t code = 0; @@ -559,7 +561,7 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SSq int32_t tSize; code = tscAllocateMemIfNeed(pDataBlock, tinfo.rowSize, &tSize); if (code != TSDB_CODE_SUCCESS) { //TODO pass the correct error code to client - strcpy(pCmd->payload, "client out of memory"); + strcpy(pInsertParam->msg, "client out of memory"); return TSDB_CODE_TSC_OUT_OF_MEMORY; } @@ -568,7 +570,7 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SSq } int32_t len = 0; - code = tsParseOneRow(str, pDataBlock, pCmd, precision, &len, tmpTokenBuf); + code = tsParseOneRow(str, pDataBlock, precision, &len, tmpTokenBuf, pInsertParam); if (code != TSDB_CODE_SUCCESS) { // error message has been set in tsParseOneRow, return directly return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } @@ -578,7 +580,7 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SSq index = 0; sToken = tStrGetToken(*str, &index, false); if (sToken.n == 0 || sToken.type != TK_RP) { - tscSQLSyntaxErrMsg(pCmd->payload, ") expected", *str); + tscSQLSyntaxErrMsg(pInsertParam->msg, ") expected", *str); code = TSDB_CODE_TSC_SQL_SYNTAX_ERROR; return code; } @@ -589,7 +591,7 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SSq } if ((*numOfRows) <= 0) { - strcpy(pCmd->payload, "no any data points"); + strcpy(pInsertParam->msg, "no any data points"); return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } else { return TSDB_CODE_SUCCESS; @@ -647,7 +649,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; @@ -699,7 +701,7 @@ void tscSortRemoveDataBlockDupRows(STableDataBlocks *dataBuf) { dataBuf->prevTS = INT64_MIN; } -static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlocks* dataBuf, int32_t *totalNum) { +static int32_t doParseInsertStatement(SInsertStatementParam *pInsertParam, char **str, STableDataBlocks* dataBuf, int32_t *totalNum) { STableComInfo tinfo = tscGetTableInfo(dataBuf->pTableMeta); int32_t maxNumOfRows; @@ -708,11 +710,11 @@ static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlock return TSDB_CODE_TSC_OUT_OF_MEMORY; } - code = TSDB_CODE_TSC_INVALID_SQL; + 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); + code = tsParseValues(str, dataBuf, maxNumOfRows, pInsertParam, &numOfRows, tmpTokenBuf); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -720,7 +722,7 @@ static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlock for (uint32_t i = 0; i < dataBuf->numOfParams; ++i) { SParamInfo *param = dataBuf->params + i; if (param->idx == -1) { - param->idx = pCmd->numOfParams++; + param->idx = pInsertParam->numOfParams++; param->offset -= sizeof(SSubmitBlk); } } @@ -728,7 +730,7 @@ static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlock SSubmitBlk *pBlocks = (SSubmitBlk *)(dataBuf->pData); code = tsSetBlockInfo(pBlocks, dataBuf->pTableMeta, numOfRows); if (code != TSDB_CODE_SUCCESS) { - tscInvalidSQLErrMsg(pCmd->payload, "too many rows in sql, total number of rows should be less than 32767", *str); + tscInvalidOperationMsg(pInsertParam->msg, "too many rows in sql, total number of rows should be less than 32767", *str); return code; } @@ -747,12 +749,11 @@ 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); + SInsertStatementParam* pInsertParam = &pCmd->insertParam; char *sql = *sqlstr; - pSql->cmd.autoCreated = false; - // get the token of specified table index = 0; tableToken = tStrGetToken(sql, &index, false); @@ -773,6 +774,10 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC index = 0; sToken = tStrGetToken(sql, &index, false); + if (sToken.type == TK_ILLEGAL) { + return tscSQLSyntaxErrMsg(pCmd->payload, "unrecognized token", sToken.z); + } + if (sToken.type == TK_RP) { break; } @@ -786,7 +791,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_SQL_SYNTAX_ERROR; } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX); @@ -802,13 +807,13 @@ 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; } - tNameExtractFullName(&pSTableMetaInfo->name, pCmd->tagData.name); - pCmd->tagData.dataLen = 0; + tNameExtractFullName(&pSTableMetaInfo->name, pInsertParam->tagData.name); + pInsertParam->tagData.dataLen = 0; code = tscGetTableMeta(pSql, pSTableMetaInfo); if (code != TSDB_CODE_SUCCESS) { @@ -816,7 +821,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } if (!UTIL_TABLE_IS_SUPER_TABLE(pSTableMetaInfo)) { - return tscInvalidSQLErrMsg(pCmd->payload, "create table only from super table is allowed", sToken.z); + return tscInvalidOperationMsg(pInsertParam->msg, "create table only from super table is allowed", sToken.z); } SSchema *pTagSchema = tscGetTableTagSchema(pSTableMetaInfo->pTableMeta); @@ -829,7 +834,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC sToken = tStrGetToken(sql, &index, false); if (sToken.type != TK_TAGS && sToken.type != TK_LP) { tscDestroyBoundColumnInfo(&spd); - return tscInvalidSQLErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z); + return tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword TAGS expected", sToken.z); } // parse the bound tags column @@ -839,7 +844,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC * tags(tagVal1, tagVal2, ..., tagValn) values(v1, v2,... vn); */ char* end = NULL; - code = parseBoundColumns(pCmd, &spd, pTagSchema, sql, &end); + code = parseBoundColumns(pInsertParam, &spd, pTagSchema, sql, &end); if (code != TSDB_CODE_SUCCESS) { tscDestroyBoundColumnInfo(&spd); return code; @@ -860,7 +865,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC if (sToken.type != TK_LP) { tscDestroyBoundColumnInfo(&spd); - return tscInvalidSQLErrMsg(pCmd->payload, "( is expected", sToken.z); + return tscSQLSyntaxErrMsg(pInsertParam->msg, "( is expected", sToken.z); } SKVRowBuilder kvRowBuilder = {0}; @@ -879,7 +884,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_SQL_SYNTAX_ERROR; } if (sToken.n == 0 || sToken.type == TK_RP) { @@ -893,7 +898,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } char tagVal[TSDB_MAX_TAGS_LEN]; - code = tsParseOneColumn(pSchema, &sToken, tagVal, pCmd->payload, &sql, false, tinfo.precision); + code = tsParseOneColumn(pSchema, &sToken, tagVal, pInsertParam->msg, &sql, false, tinfo.precision); if (code != TSDB_CODE_SUCCESS) { tdDestroyKVRowBuilder(&kvRowBuilder); tscDestroyBoundColumnInfo(&spd); @@ -908,29 +913,29 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder); tdDestroyKVRowBuilder(&kvRowBuilder); if (row == NULL) { - return tscInvalidSQLErrMsg(pCmd->payload, "tag value expected", NULL); + return tscSQLSyntaxErrMsg(pInsertParam->msg, "tag value expected", NULL); } tdSortKVRowByColIdx(row); - pCmd->tagData.dataLen = kvRowLen(row); - if (pCmd->tagData.dataLen <= 0){ - return tscInvalidSQLErrMsg(pCmd->payload, "tag value expected", NULL); + pInsertParam->tagData.dataLen = kvRowLen(row); + if (pInsertParam->tagData.dataLen <= 0){ + return tscSQLSyntaxErrMsg(pInsertParam->msg, "tag value expected", NULL); } - char* pTag = realloc(pCmd->tagData.data, pCmd->tagData.dataLen); + char* pTag = realloc(pInsertParam->tagData.data, pInsertParam->tagData.dataLen); if (pTag == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } kvRowCpy(pTag, row); free(row); - pCmd->tagData.data = pTag; + pInsertParam->tagData.data = pTag; index = 0; sToken = tStrGetToken(sql, &index, false); sql += index; if (sToken.n == 0 || sToken.type != TK_RP) { - return tscSQLSyntaxErrMsg(pCmd->payload, ") expected", sToken.z); + return tscSQLSyntaxErrMsg(pInsertParam->msg, ") expected", sToken.z); } /* parse columns after super table tags values. @@ -943,7 +948,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC int numOfColsAfterTags = 0; if (sToken.type == TK_LP) { if (*boundColumn != NULL) { - return tscSQLSyntaxErrMsg(pCmd->payload, "bind columns again", sToken.z); + return tscSQLSyntaxErrMsg(pInsertParam->msg, "bind columns again", sToken.z); } else { *boundColumn = &sToken.z[0]; } @@ -961,7 +966,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } if (numOfColsAfterTags == 0 && (*boundColumn) != NULL) { - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } sToken = tStrGetToken(sql, &index, false); @@ -970,16 +975,16 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC sql = sToken.z; if (tscValidateName(&tableToken) != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(pCmd->payload, "invalid table name", *sqlstr); + return tscInvalidOperationMsg(pInsertParam->msg, "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_SQL_SYNTAX_ERROR; } code = tscGetTableMetaEx(pSql, pTableMetaInfo, true); @@ -988,20 +993,18 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } } else { - sql = sToken.z; - - if (sql == NULL) { - return TSDB_CODE_TSC_INVALID_SQL; + if (sToken.z == NULL) { + return tscSQLSyntaxErrMsg(pInsertParam->msg, "", sql); } + sql = sToken.z; code = tscGetTableMetaEx(pSql, pTableMetaInfo, false); - if (pCmd->curSql == NULL) { + if (pInsertParam->sql == NULL) { assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS); } } *sqlstr = sql; - return code; } @@ -1015,16 +1018,21 @@ int validateTableName(char *tblName, int len, SStrToken* psTblToken) { 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(SInsertStatementParam *pInsertParam, int32_t type, const char *sql) { + uint32_t *insertType = &pInsertParam->insertType; + if (*insertType == TSDB_QUERY_TYPE_STMT_INSERT && type == TSDB_QUERY_TYPE_INSERT) { + return TSDB_CODE_SUCCESS; + } + + if ((*insertType) != 0 && (*insertType) != type) { + return tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword VALUES and FILE are not allowed to mixed up", sql); } - pCmd->dataSourceType = type; + *insertType = type; return TSDB_CODE_SUCCESS; } -static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SSchema* pSchema, +static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDataColInfo* pColInfo, SSchema* pSchema, char* str, char **end) { pColInfo->numOfBound = 0; @@ -1040,7 +1048,7 @@ static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SS str += index; if (sToken.type != TK_LP) { - code = tscInvalidSQLErrMsg(pCmd->payload, "( is expected", sToken.z); + code = tscSQLSyntaxErrMsg(pInsertParam->msg, "( is expected", sToken.z); goto _clean; } @@ -1067,7 +1075,7 @@ static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SS for (int32_t t = 0; t < pColInfo->numOfCols; ++t) { if (strncmp(sToken.z, pSchema[t].name, sToken.n) == 0 && strlen(pSchema[t].name) == sToken.n) { if (pColInfo->cols[t].hasVal == true) { - code = tscInvalidSQLErrMsg(pCmd->payload, "duplicated column name", sToken.z); + code = tscInvalidOperationMsg(pInsertParam->msg, "duplicated column name", sToken.z); goto _clean; } @@ -1080,7 +1088,7 @@ static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SS } if (!findColumnIndex) { - code = tscInvalidSQLErrMsg(pCmd->payload, "invalid column/tag name", sToken.z); + code = tscInvalidOperationMsg(pInsertParam->msg, "invalid column/tag name", sToken.z); goto _clean; } } @@ -1089,11 +1097,25 @@ static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SS return TSDB_CODE_SUCCESS; _clean: - pCmd->curSql = NULL; - pCmd->parseFinished = 1; + pInsertParam->sql = NULL; return code; } +static int32_t getFileFullPath(SStrToken* pToken, char* output) { + char path[PATH_MAX] = {0}; + strncpy(path, pToken->z, pToken->n); + strdequote(path); + + wordexp_t full_path; + if (wordexp(path, &full_path, 0) != 0) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + tstrncpy(output, full_path.we_wordv[0], PATH_MAX); + wordfree(&full_path); + return TSDB_CODE_SUCCESS; +} + /** * parse insert sql * @param pSql @@ -1101,12 +1123,14 @@ static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SS */ int tsParseInsertSql(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; - char* str = pCmd->curSql; + + SInsertStatementParam* pInsertParam = &pCmd->insertParam; + char* str = pInsertParam->sql; 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); @@ -1116,21 +1140,17 @@ int tsParseInsertSql(SSqlObj *pSql) { return code; } - if ((code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) != TSDB_CODE_SUCCESS) { - return code; - } - - if (NULL == pCmd->pTableBlockHashList) { - pCmd->pTableBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); - if (NULL == pCmd->pTableBlockHashList) { + if (NULL == pInsertParam->pTableBlockHashList) { + pInsertParam->pTableBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + if (NULL == pInsertParam->pTableBlockHashList) { code = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _clean; } } else { - str = pCmd->curSql; + str = pInsertParam->sql; } - tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pCmd->pTableBlockHashList); + tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pInsertParam->pTableBlockHashList); while (1) { int32_t index = 0; @@ -1142,7 +1162,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(pInsertParam->insertType, TSDB_QUERY_TYPE_FILE_INSERT)) { goto _clean; } @@ -1151,24 +1171,24 @@ 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; } } - pCmd->curSql = sToken.z; + pInsertParam->sql = sToken.z; char buf[TSDB_TABLE_FNAME_LEN]; SStrToken sTblToken; sTblToken.z = buf; // Check if the table name available or not if (validateTableName(sToken.z, sToken.n, &sTblToken) != TSDB_CODE_SUCCESS) { - code = tscInvalidSQLErrMsg(pCmd->payload, "table name invalid", sToken.z); + code = tscInvalidOperationMsg(pInsertParam->msg, "table name invalid", sToken.z); goto _clean; } - if ((code = tscSetTableFullName(pTableMetaInfo, &sTblToken, pSql)) != TSDB_CODE_SUCCESS) { + if ((code = tscSetTableFullName(&pTableMetaInfo->name, &sTblToken, pSql)) != TSDB_CODE_SUCCESS) { goto _clean; } @@ -1183,12 +1203,12 @@ int tsParseInsertSql(SSqlObj *pSql) { } tscError("0x%"PRIx64" async insert parse error, code:%s", pSql->self, tstrerror(code)); - pCmd->curSql = NULL; + pInsertParam->sql = NULL; goto _clean; } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - code = tscInvalidSQLErrMsg(pCmd->payload, "insert data into super table is not supported", NULL); + code = tscInvalidOperationMsg(pInsertParam->msg, "insert data into super table is not supported", NULL); goto _clean; } @@ -1197,71 +1217,62 @@ int tsParseInsertSql(SSqlObj *pSql) { str += index; if (sToken.n == 0 || (sToken.type != TK_FILE && sToken.type != TK_VALUES)) { - code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES or FILE required", sToken.z); + code = tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword VALUES or FILE required", sToken.z); goto _clean; } STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); if (sToken.type == TK_FILE) { - if (validateDataSource(pCmd, DATA_FROM_DATA_FILE, sToken.z) != TSDB_CODE_SUCCESS) { + if (validateDataSource(pInsertParam, TSDB_QUERY_TYPE_FILE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) { goto _clean; } index = 0; sToken = tStrGetToken(str, &index, false); if (sToken.type != TK_STRING && sToken.type != TK_ID) { - code = tscInvalidSQLErrMsg(pCmd->payload, "file path is required following keyword FILE", sToken.z); + code = tscSQLSyntaxErrMsg(pInsertParam->msg, "file path is required following keyword FILE", sToken.z); goto _clean; } str += index; if (sToken.n == 0) { - code = tscInvalidSQLErrMsg(pCmd->payload, "file path is required following keyword FILE", sToken.z); + code = tscSQLSyntaxErrMsg(pInsertParam->msg, "file path is required following keyword FILE", sToken.z); goto _clean; } - strncpy(pCmd->payload, sToken.z, sToken.n); - strdequote(pCmd->payload); - - // todo refactor extract method - wordexp_t full_path; - if (wordexp(pCmd->payload, &full_path, 0) != 0) { - code = tscInvalidSQLErrMsg(pCmd->payload, "invalid filename", sToken.z); + code = getFileFullPath(&sToken, pCmd->payload); + if (code != TSDB_CODE_SUCCESS) { + tscInvalidOperationMsg(pInsertParam->msg, "invalid filename", sToken.z); goto _clean; } - - tstrncpy(pCmd->payload, full_path.we_wordv[0], pCmd->allocSize); - wordfree(&full_path); - } else { if (bindedColumns == NULL) { STableMeta *pTableMeta = pTableMetaInfo->pTableMeta; - - if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) { + if (validateDataSource(pInsertParam, 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(pInsertParam->pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE, sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta, &dataBuf, NULL); if (ret != TSDB_CODE_SUCCESS) { goto _clean; } - code = doParseInsertStatement(pCmd, &str, dataBuf, &totalNum); + code = doParseInsertStatement(pInsertParam, &str, dataBuf, &totalNum); if (code != TSDB_CODE_SUCCESS) { goto _clean; } } 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(pInsertParam, 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(pInsertParam->pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE, sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta, &dataBuf, NULL); if (ret != TSDB_CODE_SUCCESS) { @@ -1269,22 +1280,22 @@ int tsParseInsertSql(SSqlObj *pSql) { } SSchema *pSchema = tscGetTableSchema(pTableMeta); - code = parseBoundColumns(pCmd, &dataBuf->boundColumnInfo, pSchema, bindedColumns, NULL); + code = parseBoundColumns(pInsertParam, &dataBuf->boundColumnInfo, pSchema, bindedColumns, NULL); if (code != TSDB_CODE_SUCCESS) { goto _clean; } if (dataBuf->boundColumnInfo.cols[0].hasVal == false) { - code = tscInvalidSQLErrMsg(pCmd->payload, "primary timestamp column can not be null", NULL); + code = tscInvalidOperationMsg(pInsertParam->msg, "primary timestamp column can not be null", NULL); goto _clean; } if (sToken.type != TK_VALUES) { - code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES is expected", sToken.z); + code = tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword VALUES is expected", sToken.z); goto _clean; } - code = doParseInsertStatement(pCmd, &str, dataBuf, &totalNum); + code = doParseInsertStatement(pInsertParam, &str, dataBuf, &totalNum); if (code != TSDB_CODE_SUCCESS) { goto _clean; } @@ -1293,12 +1304,13 @@ int tsParseInsertSql(SSqlObj *pSql) { } // we need to keep the data blocks if there are parameters in the sql - if (pCmd->numOfParams > 0) { + if (pInsertParam->numOfParams > 0) { goto _clean; } - if ((pCmd->insertType != TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pCmd->pTableBlockHashList) > 0) { // merge according to vgId - if ((code = tscMergeTableDataBlocks(pSql, true)) != TSDB_CODE_SUCCESS) { + // merge according to vgId + if (!TSDB_QUERY_HAS_TYPE(pInsertParam->insertType, TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pInsertParam->pTableBlockHashList) > 0) { + if ((code = tscMergeTableDataBlocks(pInsertParam, true)) != TSDB_CODE_SUCCESS) { goto _clean; } } @@ -1307,8 +1319,7 @@ int tsParseInsertSql(SSqlObj *pSql) { goto _clean; _clean: - pCmd->curSql = NULL; - pCmd->parseFinished = 1; + pInsertParam->sql = NULL; return code; } @@ -1323,19 +1334,19 @@ int tsInsertInitialCheck(SSqlObj *pSql) { SStrToken sToken = tStrGetToken(pSql->sqlstr, &index, false); assert(sToken.type == TK_INSERT || sToken.type == TK_IMPORT); - pCmd->count = 0; + pCmd->count = 0; pCmd->command = TSDB_SQL_INSERT; + SInsertStatementParam* pInsertParam = &pCmd->insertParam; - 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) { - return tscInvalidSQLErrMsg(pCmd->payload, "keyword INTO is expected", sToken.z); + return tscSQLSyntaxErrMsg(pInsertParam->msg, "keyword INTO is expected", sToken.z); } - pCmd->curSql = sToken.z + sToken.n; + pInsertParam->sql = sToken.z + sToken.n; return TSDB_CODE_SUCCESS; } @@ -1343,45 +1354,49 @@ int tsParseSql(SSqlObj *pSql, bool initial) { int32_t ret = TSDB_CODE_SUCCESS; SSqlCmd* pCmd = &pSql->cmd; - if ((!pCmd->parseFinished) && (!initial)) { - tscDebug("0x%"PRIx64" resume to parse sql: %s", pSql->self, pCmd->curSql); + if (!initial) { + tscDebug("0x%"PRIx64" resume to parse sql: %s", pSql->self, pCmd->insertParam.sql); } - ret = tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE); + ret = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE); if (TSDB_CODE_SUCCESS != ret) { return ret; } if (tscIsInsertData(pSql->sqlstr)) { if (initial && ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS)) { + strncpy(pCmd->payload, pCmd->insertParam.msg, TSDB_DEFAULT_PAYLOAD_SIZE); 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 { + 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); } } + + if (ret != TSDB_CODE_SUCCESS) { + strncpy(pCmd->payload, pCmd->insertParam.msg, TSDB_DEFAULT_PAYLOAD_SIZE); + } } 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); } /* @@ -1393,30 +1408,25 @@ int tsParseSql(SSqlObj *pSql, bool initial) { return ret; } -static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlocks *pTableDataBlocks) { +static int doPackSendDataBlock(SSqlObj* pSql, SInsertStatementParam *pInsertParam, STableMeta* pTableMeta, int32_t numOfRows, STableDataBlocks *pTableDataBlocks) { int32_t code = TSDB_CODE_SUCCESS; - SSqlCmd *pCmd = &pSql->cmd; - pSql->res.numOfRows = 0; - - assert(pCmd->numOfClause == 1); - STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta; SSubmitBlk *pBlocks = (SSubmitBlk *)(pTableDataBlocks->pData); code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows); if (code != TSDB_CODE_SUCCESS) { - return tscInvalidSQLErrMsg(pCmd->payload, "too many rows in sql, total number of rows should be less than 32767", NULL); + return tscInvalidOperationMsg(pInsertParam->msg, "too many rows in sql, total number of rows should be less than 32767", NULL); } - if ((code = tscMergeTableDataBlocks(pSql, true)) != TSDB_CODE_SUCCESS) { + if ((code = tscMergeTableDataBlocks(pInsertParam, true)) != TSDB_CODE_SUCCESS) { return code; } - STableDataBlocks *pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0); + STableDataBlocks *pDataBlock = taosArrayGetP(pInsertParam->pDataBlocks, 0); if ((code = tscCopyDataBlockToPayload(pSql, pDataBlock)) != TSDB_CODE_SUCCESS) { return code; } - return tscBuildAndSendRequest(pSql, NULL); + return TSDB_CODE_SUCCESS; } typedef struct SImportFileSupport { @@ -1461,17 +1471,18 @@ 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); + SInsertStatementParam* pInsertParam = &pCmd->insertParam; + destroyTableNameList(pInsertParam); - pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); + pInsertParam->pDataBlocks = tscDestroyBlockArrayList(pInsertParam->pDataBlocks); - if (pCmd->pTableBlockHashList == NULL) { - pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); - if (pCmd->pTableBlockHashList == NULL) { + if (pInsertParam->pTableBlockHashList == NULL) { + pInsertParam->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); + if (pInsertParam->pTableBlockHashList == NULL) { code = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } @@ -1479,7 +1490,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(pInsertParam->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; @@ -1506,7 +1517,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow strtolower(line, line); int32_t len = 0; - code = tsParseOneRow(&lineptr, pTableDataBlock, pCmd, tinfo.precision, &len, tokenBuf); + code = tsParseOneRow(&lineptr, pTableDataBlock, tinfo.precision, &len, tokenBuf, pInsertParam); if (code != TSDB_CODE_SUCCESS || pTableDataBlock->numOfParams > 0) { pSql->res.code = code; break; @@ -1525,12 +1536,14 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow pParentSql->res.code = code; if (code == TSDB_CODE_SUCCESS) { if (count > 0) { - code = doPackSendDataBlock(pSql, count, pTableDataBlock); - if (code == TSDB_CODE_SUCCESS) { - return; - } else { + pSql->res.numOfRows = 0; + code = doPackSendDataBlock(pSql, pInsertParam, pTableMeta, count, pTableDataBlock); + if (code != TSDB_CODE_SUCCESS) { goto _error; } + + tscBuildAndSendRequest(pSql, NULL); + return; } else { taos_free_result(pSql); tfree(pSupporter); @@ -1561,8 +1574,9 @@ void tscImportDataFromFile(SSqlObj *pSql) { return; } - assert(pCmd->dataSourceType == DATA_FROM_DATA_FILE && strlen(pCmd->payload) != 0); - pCmd->active = pCmd->pQueryInfo[0]; + SInsertStatementParam* pInsertParam = &pCmd->insertParam; + assert(TSDB_QUERY_HAS_TYPE(pInsertParam->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 7794e3190cb0a679def32db34b91cef41b804cd2..f199a5798779523e90e95bfce468a68b8afb6c6d 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -46,10 +46,15 @@ typedef struct SNormalStmt { typedef struct SMultiTbStmt { bool nameSet; + bool tagSet; uint64_t currentUid; + char *sqlstr; uint32_t tbNum; SStrToken tbname; - SHashObj *pTableHash; + SStrToken stbname; + SStrToken values; + SArray *tags; + SHashObj *pTableHash; SHashObj *pTableBlockHashList; // data block for each table } SMultiTbStmt; @@ -283,9 +288,9 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) { 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) { + 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; @@ -297,7 +302,7 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) { } } } - + offset += schema[i].bytes; } @@ -308,7 +313,7 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) { int32_t fillTablesColumnsNull(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; - STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL); + STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL); STableDataBlocks* pOneTableBlock = *p; while(pOneTableBlock) { @@ -316,8 +321,8 @@ int32_t fillTablesColumnsNull(SSqlObj* pSql) { if (pBlocks->numOfRows > 0 && pOneTableBlock->boundColumnInfo.numOfBound < pOneTableBlock->boundColumnInfo.numOfCols) { fillColumnsNull(pOneTableBlock, pBlocks->numOfRows); } - - p = taosHashIterate(pCmd->pTableBlockHashList, p); + + p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p); if (p == NULL) { break; } @@ -775,7 +780,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, return TSDB_CODE_TSC_INVALID_VALUE; } } - + return TSDB_CODE_SUCCESS; } @@ -800,7 +805,7 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU 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"); @@ -829,23 +834,23 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU 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; - + if (pStmt->multiTbInsert) { - if (pCmd->pTableBlockHashList == NULL) { + 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->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid)); + + 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; @@ -853,15 +858,15 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { pBlock = *t1; } else { - 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); } 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) { return ret; @@ -900,16 +905,16 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c SSqlCmd* pCmd = &stmt->pSql->cmd; STscStmt* pStmt = (STscStmt*)stmt; int rowNum = bind->num; - + STableDataBlocks* pBlock = NULL; - + if (pStmt->multiTbInsert) { - if (pCmd->pTableBlockHashList == NULL) { + 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->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid)); + 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; @@ -917,15 +922,15 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c pBlock = *t1; } else { - 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); } 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) { return ret; @@ -954,7 +959,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c 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); @@ -965,7 +970,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c pCmd->batchSize += rowNum - 1; } else { SParamInfo* param = &pBlock->params[colIdx]; - + int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize); if (code != TSDB_CODE_SUCCESS) { tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx); @@ -990,13 +995,12 @@ static int insertStmtUpdateBatch(STscStmt* stmt) { tscError("too many record:%d", pCmd->batchSize); return TSDB_CODE_TSC_APP_ERROR; } - - assert(pCmd->numOfClause == 1); - if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) { + + if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) { return TSDB_CODE_SUCCESS; } - STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&stmt->mtb.currentUid, sizeof(stmt->mtb.currentUid)); + 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; @@ -1019,11 +1023,11 @@ static int insertStmtUpdateBatch(STscStmt* stmt) { static int insertStmtAddBatch(STscStmt* stmt) { SSqlCmd* pCmd = &stmt->pSql->cmd; ++pCmd->batchSize; - + if (stmt->multiTbInsert) { return insertStmtUpdateBatch(stmt); } - + return TSDB_CODE_SUCCESS; } @@ -1032,9 +1036,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; @@ -1045,7 +1049,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; } @@ -1056,22 +1060,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; @@ -1083,12 +1086,12 @@ static int insertStmtExecute(STscStmt* stmt) { fillTablesColumnsNull(stmt->pSql); - int code = tscMergeTableDataBlocks(stmt->pSql, false); + int code = tscMergeTableDataBlocks(&stmt->pSql->cmd.insertParam, 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; @@ -1106,15 +1109,15 @@ 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; } @@ -1122,32 +1125,32 @@ static int insertStmtExecute(STscStmt* stmt) { static void insertBatchClean(STscStmt* pStmt) { SSqlCmd *pCmd = &pStmt->pSql->cmd; SSqlObj *pSql = pStmt->pSql; - int32_t size = taosHashGetSize(pCmd->pTableBlockHashList); - + int32_t size = taosHashGetSize(pCmd->insertParam.pTableBlockHashList); + // data block reset pCmd->batchSize = 0; - + for(int32_t i = 0; i < size; ++i) { - if (pCmd->pTableNameList && pCmd->pTableNameList[i]) { - tfree(pCmd->pTableNameList[i]); + if (pCmd->insertParam.pTableNameList && pCmd->insertParam.pTableNameList[i]) { + tfree(pCmd->insertParam.pTableNameList[i]); } } - tfree(pCmd->pTableNameList); + tfree(pCmd->insertParam.pTableNameList); /* - STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL); + STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL); STableDataBlocks* pOneTableBlock = *p; - while (1) { + while (1) { SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData; - + pOneTableBlock->size = sizeof(SSubmitBlk); pBlocks->numOfRows = 0; - - p = taosHashIterate(pCmd->pTableBlockHashList, p); + + p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p); if (p == NULL) { break; } @@ -1156,34 +1159,34 @@ static void insertBatchClean(STscStmt* pStmt) { } */ - pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); - pCmd->numOfTables = 0; + pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks); + pCmd->insertParam.numOfTables = 0; - taosHashEmpty(pCmd->pTableBlockHashList); + taosHashEmpty(pCmd->insertParam.pTableBlockHashList); tscFreeSqlResult(pSql); tscFreeSubobj(pSql); tfree(pSql->pSubs); - pSql->subState.numOfSub = 0; + 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.pTableBlockHashList) <= 0) { // merge according to vgId + 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) { + if ((code = tscMergeTableDataBlocks(&pStmt->pSql->cmd.insertParam, false)) != TSDB_CODE_SUCCESS) { return code; } @@ -1192,15 +1195,193 @@ static int insertBatchStmtExecute(STscStmt* pStmt) { 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->insertParam.sql, &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->insertParam.sql, &index, false); + if (sToken.n > 0 && (sToken.type == TK_VALUES || sToken.type == TK_LP)) { + return TSDB_CODE_SUCCESS; + } + + if (sToken.n <= 0 || sToken.type != TK_USING) { + return tscSQLSyntaxErrMsg(pCmd->payload, "keywords USING is expected", sToken.z); + } + + sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) { + return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z); + } + pStmt->mtb.stbname = sToken; + + sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + if (sToken.n <= 0 || sToken.type != TK_TAGS) { + return tscSQLSyntaxErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z); + } + + sToken = tStrGetToken(pCmd->insertParam.sql, &index, false); + if (sToken.n <= 0 || sToken.type != TK_LP) { + return tscSQLSyntaxErrMsg(pCmd->payload, ") expected", sToken.z); + } + + pStmt->mtb.tags = taosArrayInit(4, sizeof(SStrToken)); + + int32_t loopCont = 1; + + while (loopCont) { + sToken = tStrGetToken(pCmd->insertParam.sql, &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->insertParam.sql, &index, false); + if (sToken.n <= 0 || (sToken.type != TK_VALUES && sToken.type != TK_LP)) { + 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; + } + + if (pStmt->mtb.sqlstr == NULL) { + pStmt->mtb.sqlstr = pSql->sqlstr; + } else { + tfree(pSql->sqlstr); + } + + pSql->sqlstr = str; + + return TSDB_CODE_SUCCESS; +} + //////////////////////////////////////////////////////////////////////////////// // interface functions @@ -1221,6 +1402,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; @@ -1253,7 +1435,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { } pStmt->last = STMT_PREPARE; - + SSqlObj* pSql = pStmt->pSql; size_t sqlLen = strlen(sql); @@ -1263,7 +1445,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); @@ -1287,39 +1469,20 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { if (tscIsInsertData(pSql->sqlstr)) { pStmt->isInsert = true; - pSql->cmd.numOfParams = 0; + pSql->cmd.insertParam.numOfParams = 0; pSql->cmd.batchSize = 0; registerSqlObj(pSql); - int32_t ret = TSDB_CODE_SUCCESS; - - if ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS) { + int32_t ret = stmtParseInsertTbTags(pSql, pStmt); + if (ret != 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_SQL; - } - 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); - } - - return TSDB_CODE_SUCCESS; + if (pStmt->multiTbInsert) { + return TSDB_CODE_SUCCESS; } - pStmt->multiTbInsert = false; memset(&pStmt->mtb, 0, sizeof(pStmt->mtb)); int32_t code = tsParseSql(pSql, true); @@ -1336,8 +1499,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { return normalStmtPrepare(pStmt); } - -int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) { +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; @@ -1376,44 +1538,57 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) { return TSDB_CODE_TSC_APP_ERROR; } - SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData; + SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData; pCmd->batchSize = pBlk->numOfRows; - taosHashPut(pCmd->pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES); - + 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; } - - pStmt->mtb.tbname = tscReplaceStrToken(&pSql->sqlstr, &pStmt->mtb.tbname, name); + + 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; tscDebug("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr); - pSql->cmd.parseFinished = 0; - pSql->cmd.numOfParams = 0; + pSql->cmd.insertParam.numOfParams = 0; pSql->cmd.batchSize = 0; - if (taosHashGetSize(pCmd->pTableBlockHashList) > 0) { - SHashObj* hashList = pCmd->pTableBlockHashList; - pCmd->pTableBlockHashList = NULL; + if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) > 0) { + SHashObj* hashList = pCmd->insertParam.pTableBlockHashList; + pCmd->insertParam.pTableBlockHashList = NULL; tscResetSqlCmd(pCmd, true); - pCmd->pTableBlockHashList = hashList; + 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, 0); + STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; STableDataBlocks* pBlock = NULL; - code = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk), + 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; @@ -1426,15 +1601,20 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) { 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) { @@ -1451,8 +1631,10 @@ int taos_stmt_close(TAOS_STMT* stmt) { if (pStmt->multiTbInsert) { taosHashCleanup(pStmt->mtb.pTableHash); pStmt->mtb.pTableBlockHashList = tscDestroyBlockHashTable(pStmt->mtb.pTableBlockHashList, true); - taosHashCleanup(pStmt->pSql->cmd.pTableBlockHashList); - pStmt->pSql->cmd.pTableBlockHashList = NULL; + taosHashCleanup(pStmt->pSql->cmd.insertParam.pTableBlockHashList); + pStmt->pSql->cmd.insertParam.pTableBlockHashList = NULL; + taosArrayDestroy(pStmt->mtb.tags); + tfree(pStmt->mtb.sqlstr); } } @@ -1467,7 +1649,7 @@ int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) { 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) { @@ -1482,7 +1664,7 @@ int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) { } pStmt->last = STMT_BIND; - + return insertStmtBindParam(pStmt, bind); } else { return normalStmtBindParam(pStmt, bind); @@ -1502,7 +1684,7 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) { 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; @@ -1512,7 +1694,7 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) { 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); @@ -1521,7 +1703,7 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) { } pStmt->last = STMT_BIND; - + return insertStmtBindParamBatch(pStmt, bind, -1); } @@ -1546,7 +1728,7 @@ int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, in 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); @@ -1567,7 +1749,7 @@ int taos_stmt_add_batch(TAOS_STMT* stmt) { 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); @@ -1575,10 +1757,10 @@ int taos_stmt_add_batch(TAOS_STMT* stmt) { } pStmt->last = STMT_ADD_BATCH; - + return insertStmtAddBatch(pStmt); } - + return TSDB_CODE_COM_OPS_NOT_SUPPORT; } @@ -1597,7 +1779,7 @@ int taos_stmt_execute(TAOS_STMT* stmt) { terrno = TSDB_CODE_TSC_DISCONNECTED; return TSDB_CODE_TSC_DISCONNECTED; } - + if (pStmt->isInsert) { if (pStmt->last != STMT_ADD_BATCH) { tscError("0x%"PRIx64" exec status error, last:%d", pStmt->pSql->self, pStmt->last); @@ -1605,7 +1787,7 @@ int taos_stmt_execute(TAOS_STMT* stmt) { } pStmt->last = STMT_EXECUTE; - + if (pStmt->multiTbInsert) { ret = insertBatchStmtExecute(pStmt); } else { @@ -1617,9 +1799,10 @@ int taos_stmt_execute(TAOS_STMT* stmt) { 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); @@ -1669,8 +1852,8 @@ int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) { if (pStmt->isInsert) { SSqlObj* pSql = pStmt->pSql; - SSqlCmd *pCmd = &pSql->cmd; - *nums = pCmd->numOfParams; + SSqlCmd *pCmd = &pSql->cmd; + *nums = pCmd->insertParam.numOfParams; return TSDB_CODE_SUCCESS; } else { SNormalStmt* normal = &pStmt->normal; @@ -1689,16 +1872,16 @@ 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 diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 61b659f96ccb2ca54e326e3178467ac5cfd6c6fd..f34434e66c697008d73b7870cc533003eed27652 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -28,23 +28,24 @@ #include "tname.h" #include "tscLog.h" #include "tscUtil.h" -#include "tschemautil.h" +#include "qTableMeta.h" #include "tsclient.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" #define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey)) -// -1 is tbname column index, so here use the -3 as the initial value -#define COLUMN_INDEX_INITIAL_VAL (-3) +// -1 is tbname column index, so here use the -2 as the initial value +#define COLUMN_INDEX_INITIAL_VAL (-2) #define COLUMN_INDEX_INITIALIZER \ { COLUMN_INDEX_INITIAL_VAL, COLUMN_INDEX_INITIAL_VAL } -#define COLUMN_INDEX_VALIDE(index) (((index).tableIndex >= 0) && ((index).columnIndex >= TSDB_BLOCK_DIST_COLUMN_INDEX)) +#define COLUMN_INDEX_VALIDE(index) (((index).tableIndex >= 0) && ((index).columnIndex >= TSDB_TBNAME_COLUMN_INDEX)) #define TBNAME_LIST_SEP "," typedef struct SColumnList { // todo refactor @@ -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, @@ -89,6 +90,7 @@ static int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCm static int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); static int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* offsetToken); static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSliding); +static int32_t validateStateWindowNode(SSqlCmd* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, bool isStable); static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem); @@ -111,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); @@ -126,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) { @@ -192,8 +195,8 @@ 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) { - return tscInvalidSQLErrMsg(dstBuffer, errMsg, NULL); +static int32_t invalidOperationMsg(char* dstBuffer, const char* errMsg) { + return tscInvalidOperationMsg(dstBuffer, errMsg, NULL); } static int setColumnFilterInfoForTimestamp(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tVariant* pVar) { @@ -208,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); } } @@ -228,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; } @@ -259,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; @@ -281,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) { @@ -319,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); @@ -333,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; @@ -350,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; @@ -362,17 +396,24 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { const char* msg2 = "name too long"; SCreateDbInfo* pCreateDB = &(pInfo->pMiscInfo->dbOpt); - if (tscValidateName(&pCreateDB->dbname) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + if (pCreateDB->dbname.n >= TSDB_DB_NAME_LEN) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } - int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), &(pCreateDB->dbname)); + char buf[TSDB_DB_NAME_LEN] = {0}; + SStrToken token = taosTokenDup(&pCreateDB->dbname, buf, tListLen(buf)); + + if (tscValidateName(&token) != TSDB_CODE_SUCCESS) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), &token); 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; @@ -382,7 +423,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); @@ -400,15 +441,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; @@ -418,7 +459,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); } } @@ -430,26 +471,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; } @@ -461,11 +502,11 @@ 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 tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken); } @@ -478,7 +519,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; @@ -492,7 +533,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); @@ -521,21 +562,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); @@ -549,10 +590,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); } } @@ -565,7 +606,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); @@ -605,56 +646,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; + if ((i + 1) < size && pQueryInfo->sibling == NULL) { + if ((code = tscAddQueryInfo(pCmd)) != TSDB_CODE_SUCCESS) { + return code; + } - // set the command/global limit parameters from the first subclause to the sqlcmd object - SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pCmd, 0); - pCmd->command = pQueryInfo1->command; - int32_t diffSize = 0; - - // 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); - - int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo, &diffSize); - if (ret != 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + pQueryInfo = pCmd->active; } } - if (diffSize) { - for (int32_t i = 1; i < pCmd->numOfClause; ++i) { - SQueryInfo* pQueryInfo2 = tscGetQueryInfo(pCmd, i); - tscFieldInfoSetSize(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo); - } + if ((code = normalizeVarDataTypeLength(pCmd)) != TSDB_CODE_SUCCESS) { + return code; } - pCmd->parseFinished = 1; + // 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 } @@ -682,20 +708,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"); } } @@ -704,10 +729,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; @@ -718,8 +743,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) { @@ -731,14 +756,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; } @@ -754,7 +779,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; @@ -764,11 +789,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); } } @@ -777,10 +802,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) { @@ -794,7 +819,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; @@ -808,7 +833,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') { @@ -819,21 +844,74 @@ 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. return checkInvalidExprForTimeWindow(pCmd, pQueryInfo); } +static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, bool isStable) { + + const char* msg1 = "invalid column name"; + const char* msg3 = "not support state_window with group by "; + const char* msg4 = "function not support for super table query"; + + SStrToken *col = &(pSqlNode->windowstateVal.col) ; + if (col->z == NULL || col->n <= 0) { + return TSDB_CODE_SUCCESS; + } + + if (pQueryInfo->colList == NULL) { + pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); + } + if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); + } + pQueryInfo->groupbyExpr.numOfGroupCols = 1; + + //TODO(dengyihao): check tag column + if (isStable) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); + } + + SColumnIndex index = COLUMN_INDEX_INITIALIZER; + if (getColumnIndexByName(pCmd, col, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { + 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 invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); + } + + 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 invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); + SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; + taosArrayPush(pGroupExpr->columnInfo, &colIndex); + pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC; + pQueryInfo->stateWindow = true; + return TSDB_CODE_SUCCESS; +} int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pSqlNode) { const char* msg1 = "gap should be fixed time window"; @@ -851,11 +929,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 @@ -866,13 +944,19 @@ 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 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 invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); + } pQueryInfo->sessionWindow.primaryColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; @@ -896,11 +980,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') { @@ -910,18 +994,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 @@ -949,7 +1033,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); @@ -958,25 +1042,25 @@ 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"; @@ -989,27 +1073,27 @@ int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pTableNam 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); @@ -1017,7 +1101,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; @@ -1026,15 +1110,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); } } @@ -1055,14 +1139,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; } @@ -1070,29 +1154,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; } @@ -1101,7 +1185,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; } @@ -1123,7 +1207,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; } @@ -1132,28 +1216,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; } } @@ -1162,7 +1246,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; } @@ -1171,7 +1255,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; } @@ -1180,7 +1264,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; } } @@ -1199,9 +1283,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); @@ -1212,18 +1294,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; } @@ -1236,19 +1318,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; } @@ -1257,7 +1339,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; } } @@ -1273,8 +1355,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); @@ -1282,17 +1364,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; } @@ -1304,20 +1386,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; } } @@ -1348,8 +1430,8 @@ static char* cloneCurrentDBName(SSqlObj* pSql) { /* length limitation, strstr cannot be applied */ static int32_t getDelimiterIndex(SStrToken* pTableName) { - for (uint32_t i = 0; i < pTableName->n; ++i) { - if (pTableName->z[i] == TS_PATH_DELIMITER[0]) { + for (uint32_t i = 0; i < pTableName->n; ++i) { + if (pTableName->z[i] == TS_PATH_DELIMITER[0]) { return i; } } @@ -1369,7 +1451,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); @@ -1383,12 +1465,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; } } @@ -1404,7 +1486,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) { @@ -1422,7 +1504,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; @@ -1432,15 +1514,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); @@ -1453,7 +1535,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 @@ -1464,7 +1546,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); } } @@ -1482,7 +1564,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 @@ -1495,40 +1577,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) { @@ -1550,8 +1629,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; @@ -1573,11 +1652,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; } @@ -1590,8 +1669,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; @@ -1606,7 +1685,7 @@ 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; @@ -1640,7 +1719,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) { @@ -1650,7 +1729,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) { @@ -1661,18 +1740,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); @@ -1680,17 +1759,17 @@ 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; } @@ -1698,11 +1777,11 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS // 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 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) { - addPrimaryTsColIntoResult(pQueryInfo); + addPrimaryTsColIntoResult(pQueryInfo, pCmd); } if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } return TSDB_CODE_SUCCESS; @@ -1731,7 +1810,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); @@ -1748,18 +1827,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)) { @@ -1778,7 +1855,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; @@ -1794,7 +1871,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; @@ -1812,7 +1889,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 @@ -1820,18 +1897,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 @@ -1848,7 +1925,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; @@ -1857,32 +1934,31 @@ 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); - } 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_TAGPRJ, &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; @@ -1899,7 +1975,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; @@ -1910,7 +1986,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) { @@ -1964,9 +2040,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; } @@ -1996,7 +2072,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; @@ -2005,43 +2081,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); @@ -2054,18 +2115,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) { @@ -2104,21 +2165,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 @@ -2126,9 +2187,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; @@ -2137,15 +2198,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); @@ -2153,32 +2214,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); @@ -2207,18 +2268,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; @@ -2227,7 +2288,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); @@ -2240,20 +2301,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}; @@ -2263,7 +2324,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; } } } @@ -2274,7 +2335,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) { @@ -2289,7 +2350,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++; } @@ -2308,21 +2369,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); @@ -2330,17 +2391,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; @@ -2356,7 +2417,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); @@ -2370,20 +2431,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)); @@ -2394,12 +2455,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); @@ -2417,12 +2478,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); @@ -2430,7 +2491,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); @@ -2439,7 +2500,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) { @@ -2455,7 +2516,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, @@ -2480,17 +2541,17 @@ 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,}; + SColumnIndex index = {.tableIndex = 0, .columnIndex = 0,}; pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); SSchema s = {.name = "block_dist", .type = TSDB_DATA_TYPE_BINARY}; @@ -2498,10 +2559,16 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col int16_t resType = 0; int16_t bytes = 0; getResultDataInfo(TSDB_DATA_TYPE_INT, 4, TSDB_FUNC_BLKINFO, 0, &resType, &bytes, &inter, 0, 0); - s.bytes = bytes; s.type = (uint8_t)resType; - SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, &s, TSDB_COL_TAG); + + SExprInfo* pExpr = tscExprInsert(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, resType, + bytes, getNewResColId(pCmd), bytes, 0); + tstrncpy(pExpr->base.aliasName, s.name, sizeof(pExpr->base.aliasName)); + + SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + insertResultField(pQueryInfo, 0, &ids, bytes, s.type, s.name, pExpr); + pExpr->base.numOfParams = 1; pExpr->base.param[0].i64 = pTableMetaInfo->pTableMeta->tableInfo.rowSize; pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; @@ -2510,7 +2577,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } default: - return TSDB_CODE_TSC_INVALID_SQL; + return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -2529,12 +2596,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); } } @@ -2546,14 +2615,6 @@ static bool isTablenameToken(SStrToken* token) { return (strncasecmp(TSQL_TBNAME_L, tmpToken.z, tmpToken.n) == 0 && tmpToken.n == strlen(TSQL_TBNAME_L)); } -static bool isTableBlockDistToken(SStrToken* token) { - SStrToken tmpToken = *token; - SStrToken tableToken = {0}; - - extractTableNameFromToken(&tmpToken, &tableToken); - - return (strncasecmp(TSQL_BLOCK_DIST, tmpToken.z, tmpToken.n) == 0 && tmpToken.n == strlen(TSQL_BLOCK_DIST_L)); -} static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken* pToken) { STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index)->pTableMeta; @@ -2583,8 +2644,6 @@ int32_t doGetColumnIndexByName(SSqlCmd* pCmd, SStrToken* pToken, SQueryInfo* pQu if (isTablenameToken(pToken)) { pIndex->columnIndex = TSDB_TBNAME_COLUMN_INDEX; - } else if (isTableBlockDistToken(pToken)) { - pIndex->columnIndex = TSDB_BLOCK_DIST_COLUMN_INDEX; } else if (strncasecmp(pToken->z, DEFAULT_PRIMARY_TIMESTAMP_COL_NAME, pToken->n) == 0) { pIndex->columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX; } else { @@ -2595,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; @@ -2610,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; } } @@ -2643,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; @@ -2654,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; @@ -2662,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); @@ -2676,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; @@ -2700,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); } } @@ -2723,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; @@ -2758,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); @@ -2770,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) { @@ -2781,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); } } @@ -2805,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); @@ -2814,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; @@ -2827,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; } @@ -2847,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. @@ -2880,31 +2938,34 @@ 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)) { + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); + return true; } return false; @@ -2930,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; @@ -2941,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) { @@ -3001,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; @@ -3022,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); @@ -3046,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; @@ -3062,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; @@ -3069,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); } } } @@ -3158,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) { @@ -3190,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; @@ -3218,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) { @@ -3236,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; } } @@ -3292,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 = @@ -3305,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); } } } @@ -3339,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; @@ -3348,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; @@ -3376,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); @@ -3405,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); @@ -3415,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; @@ -3429,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); } } } @@ -3438,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); @@ -3448,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; @@ -3461,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); } } } @@ -3469,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) { @@ -3503,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 @@ -3517,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}; @@ -3539,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; } } @@ -3609,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; } } @@ -3693,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; } @@ -3709,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; } @@ -3745,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); @@ -3761,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; @@ -3777,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); } } @@ -3806,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)); @@ -3828,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 @@ -3848,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]; @@ -3877,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); @@ -3890,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) { @@ -3908,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; @@ -3916,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; @@ -3935,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); @@ -3954,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; @@ -3984,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); } } @@ -3995,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); @@ -4111,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; } @@ -4166,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); @@ -4178,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); @@ -4188,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 @@ -4213,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); } } @@ -4221,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; @@ -4297,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)) { @@ -4355,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); @@ -4416,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) { @@ -4436,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); } } @@ -4446,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); } } } @@ -4494,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); @@ -4515,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); } } @@ -4539,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; @@ -4592,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; } @@ -4626,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; @@ -4639,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 = 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) { @@ -4727,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); } } } @@ -4752,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); } /* @@ -4760,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); @@ -4796,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; @@ -4826,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); } } @@ -4844,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); } } @@ -4905,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); } } @@ -4926,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; @@ -4937,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) { @@ -4952,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)); } @@ -4966,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); @@ -4986,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); } } } @@ -5005,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; @@ -5019,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); @@ -5079,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; } @@ -5100,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}; @@ -5164,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; @@ -5183,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); @@ -5216,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); @@ -5228,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; @@ -5236,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; @@ -5291,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); @@ -5315,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}; @@ -5338,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); } } @@ -5360,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; @@ -5385,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 { @@ -5405,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; } } @@ -5421,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; @@ -5456,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) && @@ -5464,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 { @@ -5473,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) { @@ -5486,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}, @@ -5515,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) { @@ -5526,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 = 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 = 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) { @@ -5549,13 +5617,13 @@ int32_t validateColumnName(char* name) { 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; } } @@ -5574,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"; @@ -5590,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) { @@ -5604,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 @@ -5627,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) { @@ -5660,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); } } @@ -5698,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); } } } @@ -5722,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); } } @@ -5754,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) { @@ -5794,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 @@ -5819,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); @@ -5846,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; @@ -5859,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]; @@ -5873,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; @@ -5890,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; } } } @@ -5898,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); @@ -5916,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) { @@ -5931,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; } @@ -5952,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; } @@ -6003,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); } /* @@ -6022,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; @@ -6032,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); } } @@ -6045,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) { @@ -6090,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; @@ -6108,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; @@ -6122,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); } } } @@ -6134,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) { @@ -6157,22 +6226,25 @@ static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) { int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { const char* msg1 = "functions/columns not allowed in group by query"; const char* msg2 = "projection query on columns not allowed"; - const char* msg3 = "group by not allowed on projection query"; + const char* msg3 = "group by/session/state_window not allowed on projection query"; const char* msg4 = "retrieve tags not compatible with group by or interval query"; const char* msg5 = "functions can not be mixed up"; // 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) && tscIsSessionWindowQuery(pQueryInfo)) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); + } if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { // check if all the tags prj columns belongs to the group by columns @@ -6183,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; /* @@ -6203,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; @@ -6243,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; @@ -6254,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 @@ -6288,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; @@ -6308,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); @@ -6378,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); } @@ -6387,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; } @@ -6401,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; @@ -6429,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; @@ -6443,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; @@ -6488,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) { @@ -6507,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; } @@ -6546,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; @@ -6575,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); } } @@ -6586,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); @@ -6604,13 +6676,13 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { if (!findColumnIndex) { tdDestroyKVRowBuilder(&kvRowBuilder); - return tscInvalidSQLErrMsg(pCmd->payload, "invalid tag name", sToken->z); + return tscInvalidOperationMsg(pCmd->payload, "invalid tag name", sToken->z); } } } else { if (schemaSize != valSize) { tdDestroyKVRowBuilder(&kvRowBuilder); - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } for (int32_t i = 0; i < valSize; ++i) { @@ -6621,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); } } @@ -6632,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); @@ -6662,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; } @@ -6674,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); } } @@ -6691,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; @@ -6702,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; } @@ -6728,46 +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; } /* @@ -6776,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); } } } @@ -6802,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); @@ -6822,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; @@ -6849,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; @@ -6873,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; @@ -6932,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 = @@ -6945,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); } } } @@ -6991,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); @@ -7003,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) { @@ -7025,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); @@ -7043,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); } } } @@ -7051,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); @@ -7068,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) { @@ -7087,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 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 doLoadAllTableMeta(SSqlObj* pSql, int32_t index, SSqlNode* pSqlNode, int32_t numOfTables) { +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; } @@ -7129,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; } @@ -7156,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); @@ -7181,36 +7428,85 @@ 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* msg5 = "too many columns in selection clause"; - // const char* msg6 = "too many tables in from clause"; - // const char* msg7 = "invalid table alias name"; - // const char* msg8 = "alias name too long"; + const char* msg4 = "interval query not supported, since the result of sub query not include valid timestamp column"; 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 && @@ -7219,71 +7515,80 @@ 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; + // validate the query filter condition info + if (pSqlNode->pWhere != NULL) { + if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } - current->pTableMetaInfo = calloc(1, POINTER_BYTES); - current->pTableMetaInfo[0] = pTableMetaInfo1; - current->numOfTables = 1; - current->order = pQueryInfo->order; + 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; + } + } - pCmd->pQueryInfo[0] = current; - pQueryInfo->pDownstream = current; + // validate the interval info + if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } else { + if (isTimeWindowQuery(pQueryInfo)) { + // check if the first column of the nest query result is timestamp column + SColumn* pCol = taosArrayGetP(pQueryInfo->colList, 0); + if (pCol->info.type != TSDB_DATA_TYPE_TIMESTAMP) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); + } - if (validateSelectNodeList(pCmd, current, pSqlNode->pSelNodeList, false, false, false) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; + if (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + } } + // set order by info + STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; + if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMeta)) != + TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } } 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 @@ -7291,7 +7596,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; @@ -7299,10 +7604,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"); } } @@ -7312,34 +7616,37 @@ 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_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 = tscSqlExprGet(pQueryInfo, 0); + 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 invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); } } } @@ -7348,25 +7655,24 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { // 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; } /* * transfer sql functions that need secondary merge into another format * in dealing with super table queries such as: count/first/last */ + if (validateSessionNode(pCmd, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { + 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; } } - if (validateSessionNode(pCmd, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } - // no result due to invalid query time range if (pQueryInfo->window.skey > pQueryInfo->window.ekey) { pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; @@ -7374,18 +7680,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; } @@ -7401,6 +7707,35 @@ 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); + pQueryInfo->orderProjectQuery = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0); + + SExprInfo** p = NULL; + int32_t numOfExpr = 0; + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 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 } @@ -7492,7 +7827,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 { @@ -7512,9 +7847,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; } } } @@ -7523,7 +7858,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; } } } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index a2afaf286fb3cc8e225d957a7a7f1beb5996a3c5..f997d487d1687ec41385651160bc7146019724ec 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -15,15 +15,15 @@ #include "os.h" #include "tcmdtype.h" +#include "tlockfree.h" #include "trpc.h" -#include "tscLocalMerge.h" +#include "tscGlobalmerge.h" #include "tscLog.h" #include "tscProfile.h" #include "tscUtil.h" -#include "tschemautil.h" +#include "qTableMeta.h" #include "tsclient.h" #include "ttimer.h" -#include "tlockfree.h" #include "qPlan.h" int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo) = {0}; @@ -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,6 @@ 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_STABLEVGROUP) { pRes->code = tscBuildMsg[pCmd->command](pSql, NULL); } @@ -506,7 +505,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 +538,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 +580,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 +590,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 +735,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 +754,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 +797,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); @@ -875,6 +856,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pQueryMsg->simpleAgg = query.simpleAgg; pQueryMsg->pointInterpQuery = query.pointInterpQuery; pQueryMsg->needReverseScan = query.needReverseScan; + pQueryMsg->stateWindow = query.stateWindow; pQueryMsg->numOfTags = htonl(numOfTags); pQueryMsg->sqlstrLen = htonl(sqlLen); @@ -929,7 +911,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); @@ -1050,8 +1032,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); @@ -1171,7 +1153,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); @@ -1192,9 +1174,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; @@ -1249,7 +1232,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; @@ -1266,7 +1249,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; @@ -1286,7 +1269,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); @@ -1360,7 +1343,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 @@ -1449,7 +1432,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; } @@ -1458,7 +1441,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); @@ -1507,7 +1490,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}; @@ -1527,7 +1510,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; @@ -1543,7 +1526,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); @@ -1567,7 +1550,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; } @@ -1591,7 +1574,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); @@ -1615,8 +1598,13 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) { return code; } + if (pRes->pMerger == 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); @@ -1627,21 +1615,13 @@ 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); - list[i] = *pExprInfo; - } - - pQueryInfo->pQInfo = createQueryInfoFromQueryNode(pQueryInfo, list, &tableGroupInfo, NULL, NULL, pRes->pLocalMerger, MERGE_STAGE); + pQueryInfo->pQInfo = createQInfoFromQueryNode(pQueryInfo, &tableGroupInfo, NULL, NULL, pRes->pMerger, MERGE_STAGE); } 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); @@ -1687,15 +1667,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); @@ -1708,64 +1689,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); @@ -1825,18 +1782,16 @@ int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return TSDB_CODE_SUCCESS; } -int tscProcessTableMetaRsp(SSqlObj *pSql) { - STableMetaMsg *pMetaMsg = (STableMetaMsg *)pSql->res.pRsp; - - pMetaMsg->tid = htonl(pMetaMsg->tid); - pMetaMsg->sversion = htons(pMetaMsg->sversion); - pMetaMsg->tversion = htons(pMetaMsg->tversion); +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->suid = pMetaMsg->suid; - pMetaMsg->contLen = htons(pMetaMsg->contLen); + + pMetaMsg->uid = htobe64(pMetaMsg->uid); +// 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, @@ -1871,23 +1826,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)); - assert(pTableMeta->tableType == TSDB_SUPER_TABLE || pTableMeta->tableType == TSDB_CHILD_TABLE || pTableMeta->tableType == TSDB_NORMAL_TABLE || pTableMeta->tableType == TSDB_STREAM_TABLE); + // 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); @@ -1897,37 +1863,37 @@ 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; } + 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); @@ -1936,109 +1902,137 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) { 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; + } - pMeta->sid = htonl(pMeta->sid); - pMeta->sversion = htons(pMeta->sversion); - pMeta->vgId = htonl(pMeta->vgId); - pMeta->uid = htobe64(pMeta->uid); + SName sn = {0}; + tNameFromString(&sn, pMetaMsg->tableFname, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE); - 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; + const char* tableName = tNameGetTableName(&sn); + size_t keyLen = strlen(tableName); + + 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; } @@ -2050,68 +2044,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; } @@ -2123,7 +2087,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); @@ -2164,8 +2128,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; @@ -2183,7 +2147,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); @@ -2249,7 +2213,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); @@ -2267,7 +2231,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}; @@ -2281,7 +2245,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); @@ -2341,7 +2305,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; } @@ -2355,8 +2319,6 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { tscSetResRawPtr(pRes, pQueryInfo); } - handleDownstreamOperator(pRes, pQueryInfo); - if (pSql->pSubscription != NULL) { int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput; @@ -2386,53 +2348,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(&pNewTableMetaInfo->name, &pTableMetaInfo->name); + + registerSqlObj(pNew); + + pNew->fp = tscTableMetaCallBack; + pNew->param = (void *)pSql->self; - tNameAssign(&pNewMeterMetaInfo->name, &pTableMetaInfo->name); + 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; - if (pSql->cmd.autoCreated) { - int32_t code = copyTagData(&pNew->cmd.tagData, &pSql->cmd.tagData); + { + 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.insertParam.tagData.dataLen != 0) { + pMsg = serializeTagData(&pSql->cmd.insertParam.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); + tscDebug("0x%"PRIx64" metaRid from 0x%" PRIx64 " to 0x%" PRIx64 , pSql->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 @@ -2441,7 +2480,7 @@ 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)); uint32_t size = tscGetTableMetaMaxSize(); @@ -2478,23 +2517,26 @@ int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) { if (pMeta->tableType == TSDB_CHILD_TABLE) { 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 @@ -2502,14 +2544,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; @@ -2522,11 +2564,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) { @@ -2538,11 +2579,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; } @@ -2553,13 +2592,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); @@ -2618,9 +2656,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; @@ -2638,7 +2675,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 e1a1ff7fd23a1da18cfb6982d602c49d9262a183..554ce351eb05a3196a08a79c3b3067df6de6aab8 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; } @@ -623,7 +627,7 @@ static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) { char *z = NULL; if (len > 0) { - z = strstr(pCmd->payload, "invalid SQL"); + z = strstr(pCmd->payload, "invalid operation"); if (z == NULL) { z = strstr(pCmd->payload, "syntax error"); } @@ -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}; - tGetToken(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 2207a1ed16b010105b1746fbb3ac72a198b6341a..73a3fbafc3c5bb897d26375a129526e083eaf0e8 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -13,7 +13,6 @@ * along with this program. If not, see . */ -#include #include "os.h" #include "taosmsg.h" #include "tscLog.h" @@ -37,7 +36,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 +88,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 +137,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 +196,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 +223,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 +272,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 +443,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 +493,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 +555,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,16 +613,16 @@ 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); @@ -632,14 +631,14 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p } 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 f02bd2254037ce7a10348b776e923ba2d5548c47..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; } @@ -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 f5a6e857fbd45ae486ba7298a6cb2da542572ac0..2f32e775d66e3c3e1cf45b1437f3fa82278346a6 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -21,7 +21,7 @@ #include "tcompare.h" #include "tscLog.h" #include "tscSubquery.h" -#include "tschemautil.h" +#include "qTableMeta.h" #include "tsclient.h" #include "qUtil.h" #include "qPlan.h" @@ -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 @@ -658,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)); } @@ -681,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); } @@ -707,8 +692,6 @@ void freeJoinSubqueryObj(SSqlObj* pSql) { } tfree(pSql->subState.states); - - pSql->subState.numOfSub = 0; } @@ -727,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) { @@ -820,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); @@ -835,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); @@ -867,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); } @@ -1109,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)); @@ -1231,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); @@ -1265,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) { @@ -1300,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)) { @@ -1397,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 @@ -1413,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); @@ -1422,7 +1404,6 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR } tscAsyncResultOnError(pParentSql); - return; } @@ -1488,6 +1469,8 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR SSqlRes* pRes1 = &pParentSql->pSubs[i]->res; + pParentSql->res.precision = pRes1->precision; + if (pRes1->row > 0 && pRes1->numOfRows > 0) { tscDebug("0x%"PRIx64" sub:0x%"PRIx64" index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql->self, pParentSql->pSubs[i]->self, i, pRes1->numOfRows, pRes1->numOfTotal); @@ -1522,7 +1505,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 @@ -1574,7 +1557,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { continue; } - SQueryInfo* p = tscGetQueryInfo(&pSub->cmd, 0); + SQueryInfo* p = tscGetQueryInfo(&pSub->cmd); orderedPrjQuery = tscNonOrderedProjectionQueryOnSTable(p, 0); if (orderedPrjQuery) { break; @@ -1598,7 +1581,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) { @@ -1655,7 +1638,6 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { } SSqlRes* pRes1 = &pSql1->res; - if (pRes1->row >= pRes1->numOfRows) { subquerySetState(pSql1, &pSql->subState, i, 0); } @@ -1673,7 +1655,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); @@ -1704,9 +1686,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; @@ -1714,7 +1696,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) { @@ -1728,11 +1710,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; @@ -1741,8 +1723,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) { @@ -1752,10 +1734,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) { @@ -1836,7 +1818,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); @@ -1859,15 +1841,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; @@ -1883,7 +1859,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; @@ -1896,9 +1872,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 @@ -1924,21 +1903,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); @@ -1965,12 +1944,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; } @@ -1981,7 +1960,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; @@ -2016,7 +1995,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; @@ -2104,7 +2083,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; } @@ -2165,7 +2144,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) { @@ -2197,7 +2176,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) { @@ -2248,7 +2227,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) { @@ -2298,8 +2277,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)); @@ -2311,15 +2290,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); @@ -2329,28 +2313,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); @@ -2359,7 +2346,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; @@ -2372,7 +2359,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); @@ -2386,7 +2373,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; @@ -2396,6 +2383,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); @@ -2403,7 +2405,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; @@ -2428,14 +2430,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; @@ -2448,9 +2448,9 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { assert(pState->numOfSub > 0); - int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, &pFinalModel, nBufferSize); + int32_t ret = tscCreateGlobalMergerEnv(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; @@ -2461,7 +2461,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); + tscDestroyGlobalMergerEnv(pMemoryBuf, pDesc,pState->numOfSub); tscAsyncResultOnError(pSql); return ret; @@ -2504,8 +2504,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) { @@ -2517,7 +2515,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); } @@ -2530,13 +2528,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); + tscDestroyGlobalMergerEnv(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); + tscDestroyGlobalMergerEnv(pMemoryBuf, pDesc, pState->numOfSub); doCleanupSubqueries(pSql, i); return pRes->code; } @@ -2604,7 +2602,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]); @@ -2701,13 +2699,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, + tscDestroyGlobalMergerEnv(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); @@ -2724,7 +2722,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]; @@ -2773,22 +2771,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 = tscCreateGlobalMerger(trsupport->pExtMemBuffer, pState->numOfSub, pDesc, pPQueryInfo, &pParentSql->res.pMerger, 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); @@ -2814,7 +2818,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) { @@ -2852,7 +2856,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); @@ -2861,7 +2865,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) && !(tscGetQueryInfo(&pParentSql->cmd, 0)->distinctTag)) { + 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); @@ -2904,7 +2908,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; @@ -2913,7 +2917,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); @@ -2939,10 +2943,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 @@ -2969,7 +2973,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; @@ -3041,8 +3044,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; } } @@ -3077,8 +3080,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); @@ -3090,15 +3093,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); @@ -3133,7 +3136,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) { @@ -3166,7 +3169,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; @@ -3216,7 +3219,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); @@ -3234,7 +3237,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) { @@ -3250,7 +3253,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); @@ -3266,7 +3269,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) { @@ -3284,7 +3287,7 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { return; } - tscRestoreFuncForSTableQuery(pQueryInfo); +// tscRestoreFuncForSTableQuery(pQueryInfo); int32_t rowSize = tscGetResRowLength(pQueryInfo->exprList); assert(numOfRes * rowSize > 0); @@ -3312,12 +3315,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; @@ -3363,8 +3366,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); @@ -3376,8 +3379,6 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { tscAsyncResultOnError(pSql); return; } - - tscRestoreFuncForSTableQuery(pQueryInfo); } assert (pRes->row >= pRes->numOfRows); @@ -3417,7 +3418,7 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql) { return pRes->tsrow; } - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); size_t size = tscNumOfFields(pQueryInfo); @@ -3450,7 +3451,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; @@ -3462,7 +3463,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); @@ -3486,7 +3487,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)) || @@ -3500,11 +3501,9 @@ 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) { +void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, 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; @@ -3522,13 +3521,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; } } @@ -3586,15 +3597,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 37e836dc1c31edf7b67bd857f7ea3f4318cf03df..8042f032c8a2fad85de23c4f2bbdc5c07670cdc3 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -16,21 +16,82 @@ #include "tscUtil.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" +#include "tscGlobalmerge.h" #include "tscLog.h" #include "tscProfile.h" #include "tscSubquery.h" -#include "tschemautil.h" +#include "tsched.h" +#include "qTableMeta.h" #include "tsclient.h" #include "ttimer.h" #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; } @@ -356,11 +434,14 @@ bool tscIsTWAQuery(SQueryInfo* pQueryInfo) { return false; } +bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo) { + return pQueryInfo->sessionWindow.gap > 0; +} 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; } @@ -396,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; } @@ -414,12 +524,13 @@ bool isSimpleAggregate(SQueryInfo* pQueryInfo) { } return false; + } bool isBlockDistQuery(SQueryInfo* pQueryInfo) { - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); - return (numOfExprs == 1 && pExpr->base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX); + size_t numOfExprs = tscNumOfExprs(pQueryInfo); + SExprInfo* pExpr = tscExprGet(pQueryInfo, 0); + return (numOfExprs == 1 && pExpr->base.functionId == TSDB_FUNC_BLKINFO); } void tscClearInterpInfo(SQueryInfo* pQueryInfo) { @@ -432,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)); @@ -587,58 +698,269 @@ 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; + STableQueryInfo *pTableQueryInfo; + SSqlObj *pSql; // refactor: remove it + int32_t numOfFilterCols; + SSingleColumnFilterInfo *pFilterInfo; } SDummyInputInfo; -SSDataBlock* doGetDataBlock(void* param, bool* newgroup) { - SOperatorInfo *pOperator = (SOperatorInfo*) param; - - SDummyInputInfo *pInput = pOperator->info; - char* pData = pInput->pRes->data; +typedef struct SJoinStatus { + SSDataBlock* pBlock; // point to the upstream block + int32_t index; + bool completed;// current upstream is completed or not +} SJoinStatus; - 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, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols) { 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; + // filter data if needed + if (numOfFilterCols > 0) { + doSetFilterColumnInfo(pFilterInfo, numOfFilterCols, pBlock); + int8_t* p = calloc(pBlock->info.rows, sizeof(int8_t)); + bool all = doFilterDataBlock(pFilterInfo, numOfFilterCols, pBlock->info.rows, p); + if (!all) { + doCompactSDataBlock(pBlock, pBlock->info.rows, p); + } + + tfree(p); + } + + // todo refactor: extract method + // set the timestamp range of current result data block + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, 0); + if (pColData->info.type == TSDB_DATA_TYPE_TIMESTAMP) { + pBlock->info.window.skey = ((int64_t*)pColData->pData)[0]; + pBlock->info.window.ekey = ((int64_t*)pColData->pData)[pBlock->info.rows-1]; + } + + 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; + if (pOperator->pRuntimeEnv != NULL) { + pOperator->pRuntimeEnv->current = pInput->pTableQueryInfo; + } + + pBlock->info.rows = pRes->numOfRows; + if (pRes->numOfRows != 0) { + doSetupSDataBlock(pRes, pBlock, pInput->pFilterInfo, pInput->numOfFilterCols); + *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, pInput->pFilterInfo, pInput->numOfFilterCols); *newgroup = false; return pBlock; } +static void fetchNextBlockIfCompleted(SOperatorInfo* pOperator, bool* newgroup) { + SJoinOperatorInfo* pJoinInfo = pOperator->info; + + 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; + break; + } + } + } +} + +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) { + fetchNextBlockIfCompleted(pOperator, newgroup); + if (pOperator->status == OP_EXEC_DONE) { + 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) { + fetchNextBlockIfCompleted(pOperator, newgroup); + if (pOperator->status == OP_EXEC_DONE) { + return pJoinInfo->pRes; + } + } + } 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) { + + fetchNextBlockIfCompleted(pOperator, newgroup); + if (pOperator->status == OP_EXEC_DONE) { + return pJoinInfo->pRes; + } + } + } + } else { + if ((++(st0->index)) >= st0->pBlock->info.rows) { + fetchNextBlockIfCompleted(pOperator, newgroup); + if (pOperator->status == OP_EXEC_DONE) { + return pJoinInfo->pRes; + } + } + } + } + } + + 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; @@ -649,15 +971,20 @@ 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); + STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX}; + SDummyInputInfo* pInfo = calloc(1, sizeof(SDummyInputInfo)); - pInfo->pRes = (SSqlRes*) pResult; + pInfo->pSql = pSql; + pInfo->pFilterInfo = pFilterInfo; + pInfo->numOfFilterCols = numOfFilterCols; + pInfo->pTableQueryInfo = createTmpTableQueryInfo(win); pInfo->block = calloc(numOfCols, sizeof(SSDataBlock)); pInfo->block->info.numOfCols = numOfCols; @@ -683,6 +1010,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; @@ -697,18 +1070,37 @@ 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); +static void createInputDataFilterInfo(SQueryInfo* px, int32_t numOfCol1, int32_t* numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo) { + 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; + } + + tableCols[i] = pCol->info; + } + + if ((*numOfFilterCols) > 0) { + doCreateFilterInfo(tableCols, numOfCol1, (*numOfFilterCols), pFilterInfo, 0); + } + + tfree(tableCols); +} + +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 numOfCols = (int32_t) taosArrayGetSize(px->colList); - SQueriedTableInfo info = {.colList = pColumnInfo, .numOfCols = numOfCols,}; - SSchema* pSchema = tscGetTableSchema(px->pTableMetaInfo[0]->pTableMeta); + STableMeta* pTableMeta = tscGetMetaInfo(px, 0)->pTableMeta; + SSchema* pSchema = tscGetTableSchema(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}; @@ -718,18 +1110,73 @@ 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 = pTableMeta->tableInfo.numOfColumns; + + int32_t numOfFilterCols = 0; + SSingleColumnFilterInfo* pFilterInfo = NULL; + createInputDataFilterInfo(px, numOfCol1, &numOfFilterCols, &pFilterInfo); + + 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) { + STableMeta* pTableMeta1 = tscGetMetaInfo(px, i)->pTableMeta; - 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); + SSchema* pSchema1 = tscGetTableSchema(pTableMeta1); + int32_t n = pTableMeta1->tableInfo.numOfColumns; - uint64_t qId = 0; - qTableQuery(px->pQInfo, &qId); - convertQueryResult(pRes, px); + int32_t numOfFilterCols1 = 0; + SSingleColumnFilterInfo* pFilterInfo1 = NULL; + createInputDataFilterInfo(px, numOfCol1, &numOfFilterCols1, &pFilterInfo1); + 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)); + } + + // update the exprinfo + int32_t numOfOutput = (int32_t)tscNumOfExprs(px); + 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, &tableGroupInfo, pSourceOperator, NULL, NULL, MASTER_SCAN); tfree(pColumnInfo); + tfree(schema); + + // set the pRuntimeEnv for pSourceOperator + pSourceOperator->pRuntimeEnv = &px->pQInfo->runtimeEnv; } + + uint64_t qId = 0; + qTableQuery(px->pQInfo, &qId); + convertQueryResult(pOutput, px); } static void tscDestroyResPointerInfo(SSqlRes* pRes) { @@ -762,26 +1209,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); @@ -791,48 +1241,63 @@ 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); +void destroyTableNameList(SInsertStatementParam* pInsertParam) { + if (pInsertParam->numOfTables == 0) { + assert(pInsertParam->pTableNameList == NULL); return; } - for(int32_t i = 0; i < pCmd->numOfTables; ++i) { - tfree(pCmd->pTableNameList[i]); + for(int32_t i = 0; i < pInsertParam->numOfTables; ++i) { + tfree(pInsertParam->pTableNameList[i]); } - pCmd->numOfTables = 0; - tfree(pCmd->pTableNameList); + pInsertParam->numOfTables = 0; + tfree(pInsertParam->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->insertParam.sql = NULL; + destroyTableNameList(&pCmd->insertParam); + + pCmd->insertParam.pTableBlockHashList = tscDestroyBlockHashTable(pCmd->insertParam.pTableBlockHashList, clearCachedMeta); + pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks); + tfree(pCmd->insertParam.tagData.data); + pCmd->insertParam.tagData.dataLen = 0; - pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList, removeMeta); - pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); - tscFreeQueryInfo(pCmd, removeMeta); + 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); + tscDestroyGlobalMerger(pRes->pMerger); + pRes->pMerger = NULL; + + tscDestroyResPointerInfo(pRes); memset(&pSql->res, 0, sizeof(SSqlRes)); } @@ -854,7 +1319,6 @@ void tscFreeSubobj(SSqlObj* pSql) { } tfree(pSql->subState.states); - pSql->subState.numOfSub = 0; } @@ -878,7 +1342,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){ @@ -925,9 +1388,6 @@ void tscFreeSqlObj(SSqlObj* pSql) { tscFreeSqlResult(pSql); tscResetSqlCmd(pCmd, false); - tfree(pCmd->tagData.data); - pCmd->tagData.dataLen = 0; - memset(pCmd->payload, 0, (size_t)pCmd->allocSize); tfree(pCmd->payload); pCmd->allocSize = 0; @@ -1022,14 +1482,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); @@ -1039,33 +1496,42 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) { } pTableMetaInfo->pTableMeta = tscTableMetaDup(pDataBlock->pTableMeta); - pTableMetaInfo->tableMetaSize = tscGetTableMetaSize(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); + + SMsgDesc* pMsgDesc = (SMsgDesc*) pCmd->payload; + pMsgDesc->numOfVnodes = htonl(1); // always for one vnode - assert(pCmd->allocSize >= (uint32_t)(pCmd->payloadLen + 100) && pCmd->payloadLen > 0); + 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; } @@ -1222,37 +1688,36 @@ static int32_t getRowExpandSize(STableMeta* pTableMeta) { return result; } -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); +static void extractTableNameList(SInsertStatementParam *pInsertParam, bool freeBlockMap) { + pInsertParam->numOfTables = (int32_t) taosHashGetSize(pInsertParam->pTableBlockHashList); + if (pInsertParam->pTableNameList == NULL) { + pInsertParam->pTableNameList = calloc(pInsertParam->numOfTables, POINTER_BYTES); } else { - memset(pCmd->pTableNameList, 0, pCmd->numOfTables * POINTER_BYTES); + memset(pInsertParam->pTableNameList, 0, pInsertParam->numOfTables * POINTER_BYTES); } - STableDataBlocks **p1 = taosHashIterate(pCmd->pTableBlockHashList, NULL); + STableDataBlocks **p1 = taosHashIterate(pInsertParam->pTableBlockHashList, NULL); int32_t i = 0; while(p1) { STableDataBlocks* pBlocks = *p1; - tfree(pCmd->pTableNameList[i]); + tfree(pInsertParam->pTableNameList[i]); - pCmd->pTableNameList[i++] = tNameDup(&pBlocks->tableName); - p1 = taosHashIterate(pCmd->pTableBlockHashList, p1); + pInsertParam->pTableNameList[i++] = tNameDup(&pBlocks->tableName); + p1 = taosHashIterate(pInsertParam->pTableBlockHashList, p1); } if (freeBlockMap) { - pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList, false); + pInsertParam->pTableBlockHashList = tscDestroyBlockHashTable(pInsertParam->pTableBlockHashList, false); } } -int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { +int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBlockMap) { const int INSERT_HEAD_SIZE = sizeof(SMsgDesc) + sizeof(SSubmitMsg); - SSqlCmd* pCmd = &pSql->cmd; 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(pInsertParam->pTableBlockHashList, NULL); STableDataBlocks* pOneTableBlock = *p; while(pOneTableBlock) { @@ -1265,7 +1730,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { 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); + tscError("0x%"PRIx64" failed to prepare the data block buffer for merging table data, code:%d", pInsertParam->objectId, ret); taosHashCleanup(pVnodeDataBlockHashList); tscDestroyBlockArrayList(pVnodeDataBlockList); return ret; @@ -1283,7 +1748,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { 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); + tscError("0x%"PRIx64" failed to allocate memory for merging submit block, size:%d", pInsertParam->objectId, dataBuf->nAllocSize); taosHashCleanup(pVnodeDataBlockHashList); tscDestroyBlockArrayList(pVnodeDataBlockList); @@ -1296,7 +1761,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { 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), + tscDebug("0x%"PRIx64" name:%s, name:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pInsertParam->objectId, 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); @@ -1308,7 +1773,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { pBlocks->schemaLen = 0; // erase the empty space reserved for binary data - int32_t finalLen = trimDataBlock(dataBuf->pData + dataBuf->size, pOneTableBlock, pCmd->submitSchema); + int32_t finalLen = trimDataBlock(dataBuf->pData + dataBuf->size, pOneTableBlock, pInsertParam->schemaAttached); assert(finalLen <= len); dataBuf->size += (finalLen + sizeof(SSubmitBlk)); @@ -1320,10 +1785,10 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { pBlocks->numOfRows = 0; }else { - tscDebug("0x%"PRIx64" table %s data block is empty", pSql->self, pOneTableBlock->tableName.tname); + tscDebug("0x%"PRIx64" table %s data block is empty", pInsertParam->objectId, pOneTableBlock->tableName.tname); } - p = taosHashIterate(pCmd->pTableBlockHashList, p); + p = taosHashIterate(pInsertParam->pTableBlockHashList, p); if (p == NULL) { break; } @@ -1331,10 +1796,10 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { pOneTableBlock = *p; } - extractTableNameList(pCmd, freeBlockMap); + extractTableNameList(pInsertParam, freeBlockMap); // free the table data blocks; - pCmd->pDataBlocks = pVnodeDataBlockList; + pInsertParam->pDataBlocks = pVnodeDataBlockList; taosHashCleanup(pVnodeDataBlockHashList); return TSDB_CODE_SUCCESS; @@ -1366,18 +1831,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; } @@ -1385,7 +1854,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; } @@ -1414,16 +1883,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; } } @@ -1464,6 +1931,7 @@ int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFi *diffSize = 1; if (pField2->bytes > pField1->bytes) { + assert(IS_VAR_DATA_TYPE(pField1->type)); pField1->bytes = pField2->bytes; } } @@ -1555,8 +2023,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)); @@ -1573,16 +2076,14 @@ static SExprInfo* doCreateSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SC p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX; p->colBytes = s->bytes; p->colType = s->type; - } else if (pColIndex->columnIndex == TSDB_BLOCK_DIST_COLUMN_INDEX) { - SSchema s = tGetBlockDistColumnSchema(); - - p->colInfo.colId = TSDB_BLOCK_DIST_COLUMN_INDEX; - p->colBytes = s.bytes; - p->colType = s.type; } else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX) { p->colInfo.colId = pColIndex->columnIndex; p->colBytes = size; p->colType = type; + } else if (functionId == TSDB_FUNC_BLKINFO) { + p->colInfo.colId = pColIndex->columnIndex; + p->colBytes = TSDB_MAX_BINARY_LEN; + p->colType = TSDB_DATA_TYPE_BINARY; } else { if (TSDB_COL_IS_TAG(colType)) { SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); @@ -1615,29 +2116,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; } @@ -1659,9 +2160,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; } @@ -1670,11 +2171,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 @@ -1685,14 +2186,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) { @@ -1703,23 +2204,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); } } @@ -1752,7 +2272,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; @@ -1864,6 +2384,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; @@ -1902,7 +2434,7 @@ static int32_t validateQuoteToken(SStrToken* 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; } @@ -1952,7 +2484,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); @@ -1971,14 +2503,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 @@ -1991,15 +2523,15 @@ int32_t tscValidateName(SStrToken* pToken) { 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; @@ -2008,11 +2540,11 @@ int32_t tscValidateName(SStrToken* pToken) { pToken->n = (uint32_t)(oldLen - (sep - pStr) - 1); 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 @@ -2047,7 +2579,7 @@ bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId, int32_t return false; } - if (colId == TSDB_TBNAME_COLUMN_INDEX || colId == TSDB_BLOCK_DIST_COLUMN_INDEX || (colId <= TSDB_UD_COLUMN_INDEX && numOfParams == 2)) { + if (colId == TSDB_TBNAME_COLUMN_INDEX || (colId <= TSDB_UD_COLUMN_INDEX && numOfParams == 2)) { return true; } @@ -2166,9 +2698,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)) { @@ -2220,14 +2752,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); } @@ -2244,8 +2771,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) { @@ -2254,7 +2781,7 @@ SQueryInfo* tscGetQueryInfoS(SSqlCmd* pCmd, int32_t subClauseIndex) { return NULL; } - pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); + pQueryInfo = tscGetQueryInfo(pCmd); } return pQueryInfo; @@ -2278,6 +2805,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)); @@ -2287,27 +2815,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; @@ -2315,10 +2833,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; } @@ -2326,9 +2854,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; @@ -2348,10 +2881,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) { @@ -2425,28 +3040,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; @@ -2510,6 +3126,15 @@ void tscResetForNextRetrieve(SSqlRes* pRes) { pRes->numOfRows = 0; } +void tscInitResForMerge(SSqlRes* pRes) { + pRes->qId = 1; // hack to pass the safety check in fetch_row function + pRes->rspType = 0; // used as a flag to denote if taos_retrieved() has been called yet + tscResetForNextRetrieve(pRes); + + assert(pRes->pMerger != NULL); + pRes->data = pRes->pMerger->buf; +} + void registerSqlObj(SSqlObj* pSql) { taosAcquireRef(tscRefId, pSql->pTscObj->rid); pSql->self = taosAddRef(tscObjRef, pSql); @@ -2531,16 +3156,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) { - tscError("0x%"PRIx64" new subquery failed, unable to malloc tag data, tableIndex:%d", pSql->self, 0); - free(pNew); - return NULL; - } - if (tscAddQueryInfo(pCmd) != TSDB_CODE_SUCCESS) { #ifdef __APPLE__ // to satisfy later tsem_destroy in taos_free_result @@ -2556,10 +3171,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); @@ -2568,14 +3181,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); @@ -2589,7 +3202,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); @@ -2617,7 +3230,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; @@ -2626,29 +3239,25 @@ 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->insertParam.pDataBlocks = NULL; - pnCmd->numOfTables = 0; - pnCmd->parseFinished = 1; - pnCmd->pTableNameList = NULL; - pnCmd->pTableBlockHashList = NULL; - pnCmd->tagData.data = NULL; - pnCmd->tagData.dataLen = 0; + pnCmd->insertParam.numOfTables = 0; + pnCmd->insertParam.pTableNameList = NULL; + pnCmd->insertParam.pTableBlockHashList = NULL; if (tscAddQueryInfo(pnCmd) != TSDB_CODE_SUCCESS) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } - SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pnCmd, 0); + SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pnCmd); pNewQueryInfo->command = pQueryInfo->command; pnCmd->active = pNewQueryInfo; @@ -2713,13 +3322,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; } @@ -2741,7 +3350,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t 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; @@ -2780,7 +3389,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); @@ -2807,7 +3416,11 @@ void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { tscHandleMasterSTableQuery(pSql); tscUnlockByThread(&pSql->squeryLock); } else if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) { - tscHandleMultivnodeInsert(pSql); + if (TSDB_QUERY_HAS_TYPE(pSql->cmd.insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) { + tscImportDataFromFile(pSql); + } else { + tscHandleMultivnodeInsert(pSql); + } } else if (pSql->cmd.command > TSDB_SQL_LOCAL) { tscProcessLocalCmd(pSql); } else { // send request to server directly @@ -2815,6 +3428,58 @@ void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { } } +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; + } + + 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); + } +} + +// 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; + + int32_t index = ps->subqueryIndex; + bool ret = subAndCheckDone(pSql, pParentSql, index); + + // TODO refactor + tfree(ps); + pSql->param = NULL; + + if (!ret) { + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, index); + return; + } + + 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 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) { @@ -2827,84 +3492,55 @@ void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { } if (taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // nest query. do execute it firstly - SQueryInfo* pq = taosArrayGetP(pQueryInfo->pUpstream, 0); + pSql->subState.numOfSub = (int32_t) taosArrayGetSize(pQueryInfo->pUpstream); - pSql->cmd.active = pq; - pSql->cmd.command = TSDB_SQL_SELECT; + pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES); + pSql->subState.states = calloc(pSql->subState.numOfSub, sizeof(int8_t)); - executeQuery(pSql, pq); + for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) { + SQueryInfo* pSub = taosArrayGetP(pQueryInfo->pUpstream, i); - // merge nest query result and generate final results - return; - } + pSql->cmd.active = pSub; + pSql->cmd.command = TSDB_SQL_SELECT; - pSql->cmd.active = pQueryInfo; - doExecuteQuery(pSql, pQueryInfo); -} + // TODO handle memory failure + SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj)); + if (pNew == NULL) { + terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; + // return NULL; + } -/** - * 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); - return; - } - - if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) { - tscImportDataFromFile(pSql); - } else { - SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); - uint16_t type = pQueryInfo->type; + pNew->pTscObj = pSql->pTscObj; + pNew->signature = pNew; + pNew->sqlstr = strdup(pSql->sqlstr); // todo refactor + pNew->fp = tscSubqueryCompleteCallback; - if ((pCmd->command == TSDB_SQL_SELECT) && (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_SUBQUERY)) && (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_STABLE_SUBQUERY))) { - tscAddIntoSqlList(pSql); - } - - if (TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_INSERT)) { // multi-vnodes insertion - tscHandleMultivnodeInsert(pSql); - return; - } - - 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); - } - } + 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) { @@ -2962,17 +3598,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; } @@ -3004,17 +3638,17 @@ int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* s return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } -int32_t tscInvalidSQLErrMsg(char* msg, const char* additionalInfo, const char* sql) { - const char* msgFormat1 = "invalid SQL: %s"; - const char* msgFormat2 = "invalid SQL: \'%s\' (%s)"; - const char* msgFormat3 = "invalid SQL: \'%s\'"; +int32_t tscInvalidOperationMsg(char* msg, const char* additionalInfo, const char* sql) { + const char* msgFormat1 = "invalid operation: %s"; + const char* msgFormat2 = "invalid operation: \'%s\' (%s)"; + const char* msgFormat3 = "invalid operation: \'%s\'"; const int32_t BACKWARD_CHAR_STEP = 0; 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 @@ -3026,7 +3660,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) { @@ -3048,7 +3682,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 @@ -3066,14 +3700,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 @@ -3129,11 +3764,7 @@ 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; @@ -3153,7 +3784,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 { @@ -3409,75 +4040,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; + + SExprInfo* px = calloc(1, sizeof(SExprInfo)); + (*pExpr)[i] = px; - SSqlExpr *pse = &pQueryAttr->pExpr2[i].base; + 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); } } } @@ -3488,7 +4138,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; @@ -3498,7 +4148,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; @@ -3562,7 +4212,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]; @@ -3580,7 +4230,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); @@ -3589,11 +4239,13 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt pQueryAttr->simpleAgg = isSimpleAggregate(pQueryInfo); pQueryAttr->needReverseScan = tscNeedReverseScan(pQueryInfo); pQueryAttr->stableQuery = QUERY_IS_STABLE_QUERY(pQueryInfo->type); - pQueryAttr->groupbyColumn = tscGroupbyColumn(pQueryInfo); + pQueryAttr->groupbyColumn = (!pQueryInfo->stateWindow) && tscGroupbyColumn(pQueryInfo); pQueryAttr->queryBlockDist = isBlockDistQuery(pQueryInfo); pQueryAttr->pointInterpQuery = tscIsPointInterpQuery(pQueryInfo); pQueryAttr->timeWindowInterpo = timeWindowInterpoRequired(pQueryInfo); pQueryAttr->distinctTag = pQueryInfo->distinctTag; + pQueryAttr->sw = pQueryInfo->sessionWindow; + pQueryAttr->stateWindow = pQueryInfo->stateWindow; pQueryAttr->numOfCols = numOfCols; pQueryAttr->numOfOutput = numOfOutput; @@ -3601,8 +4253,8 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt pQueryAttr->slimit = pQueryInfo->slimit; pQueryAttr->order = pQueryInfo->order; pQueryAttr->fillType = pQueryInfo->fillType; - pQueryAttr->groupbyColumn = tscGroupbyColumn(pQueryInfo); pQueryAttr->havingNum = pQueryInfo->havingFieldNum; + if (pQueryInfo->order.order == TSDB_ORDER_ASC) { // TODO refactor pQueryAttr->window = pQueryInfo->window; @@ -3615,7 +4267,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) { @@ -3626,8 +4278,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) { @@ -3653,13 +4305,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; } @@ -3684,19 +4340,141 @@ 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; } + +bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src) { + assert(pExisted != NULL && src != NULL); + if (pExisted->numOfEps != src->numOfEps) { + return false; + } + + for(int32_t i = 0; i < pExisted->numOfEps; ++i) { + if (pExisted->ep[i].port != src->epAddr[i].port) { + return false; + } + + if (strncmp(pExisted->ep[i].fqdn, src->epAddr[i].fqdn, tListLen(pExisted->ep[i].fqdn)) != 0) { + return false; + } + } + + return true; +} + +SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg) { + assert(pVgroupMsg != NULL); + + SNewVgroupInfo info = {0}; + info.numOfEps = pVgroupMsg->numOfEps; + info.vgId = pVgroupMsg->vgId; + info.inUse = 0; // 0 is the default value of inUse in case of multiple replica + + assert(info.numOfEps >= 1 && info.vgId >= 1); + for(int32_t i = 0; i < pVgroupMsg->numOfEps; ++i) { + tstrncpy(info.ep[i].fqdn, pVgroupMsg->epAddr[i].fqdn, TSDB_FQDN_LEN); + info.ep[i].port = pVgroupMsg->epAddr[i].port; + } + + return info; +} \ No newline at end of file diff --git a/src/common/inc/tname.h b/src/common/inc/tname.h index 48bec7fe4dfd04aa0080fd0b75ccdd84fe837761..8c970595523bbc2a8c9c0fe9edd53dd1f3499bd5 100644 --- a/src/common/inc/tname.h +++ b/src/common/inc/tname.h @@ -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,10 +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); bool tscValidateTableNameLength(size_t len); 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 d6bbc288adf92674b308e8d423d1b19cd58113c0..a1266bb2cb3d793088513a388568c74c94e9f54e 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -46,7 +46,7 @@ char tsEmail[TSDB_FQDN_LEN] = {0}; int32_t tsDnodeId = 0; // common -int32_t tsRpcTimer = 1000; +int32_t tsRpcTimer = 300; int32_t tsRpcMaxTime = 600; // seconds; int32_t tsRpcForceTcp = 0; //disable this, means query, show command use udp protocol as default int32_t tsMaxShellConns = 50000; diff --git a/src/common/src/tname.c b/src/common/src/tname.c index dc868d805790688c15192b2b282f42d4e6e8b957..c1c6ffa4b343dba47728055b50639ad12cfec9fe 100644 --- a/src/common/src/tname.c +++ b/src/common/src/tname.c @@ -33,15 +33,6 @@ size_t tableIdPrefix(const char* name, char* prefix, int32_t len) { return strlen(prefix); } -SSchema tGetBlockDistColumnSchema() { - SSchema s = {0}; - s.bytes = TSDB_MAX_BINARY_LEN;; - s.type = TSDB_DATA_TYPE_BINARY; - s.colId = TSDB_BLOCK_DIST_COLUMN_INDEX; - tstrncpy(s.name, TSQL_BLOCK_DIST_L, TSDB_COL_NAME_LEN); - return s; -} - SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const char* name) { SSchema s = {0}; diff --git a/src/connector/go b/src/connector/go index 8ce6d86558afc8c0b50c10f990fd2b4270cf06fc..7a26c432f8b4203e42344ff3290b9b9b01b983d5 160000 --- a/src/connector/go +++ b/src/connector/go @@ -1 +1 @@ -Subproject commit 8ce6d86558afc8c0b50c10f990fd2b4270cf06fc +Subproject commit 7a26c432f8b4203e42344ff3290b9b9b01b983d5 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 d6934b8e46c6a9dc3821ce06da1397532c747564..256e735285bd493f37c9e369a49b369e9e6b4b38 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 @@ -16,13 +16,13 @@ */ 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; +import com.taosdata.jdbc.utils.TaosInfo; + /** * JNI connector */ @@ -276,23 +276,14 @@ 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) { + Long stmt = prepareStmtImp(sql.getBytes(), this.taos); + if (stmt == TSDBConstants.JNI_TDENGINE_ERROR) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL); + } else if (stmt == TSDBConstants.JNI_CONNECTION_NULL) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); - } - - if (stmt == TSDBConstants.JNI_SQL_NULL) { + } else if (stmt == TSDBConstants.JNI_SQL_NULL) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL); - } - - if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) { + } else if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY); } @@ -310,6 +301,16 @@ public class TSDBJNIConnector { 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) { 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 71e07252a34003c3fcc4dceae80e897030e55926..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 @@ -41,6 +41,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat private boolean isPrepared; private ArrayList colData; + private ArrayList tableTags; + private int tagValueLength; + private String tableName; private long nativeStmtHandle = 0; @@ -63,8 +66,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat if (parameterCnt > 1) { // the table name is also a parameter, so ignore it. - this.colData = new ArrayList(parameterCnt - 1); - this.colData.addAll(Collections.nCopies(parameterCnt - 1, null)); + this.colData = new ArrayList(); + this.tableTags = new ArrayList(); } } @@ -562,11 +565,109 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat } }; + 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(); @@ -641,7 +742,122 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); this.nativeStmtHandle = connector.prepareStmt(rawSql); - connector.setBindTableName(this.nativeStmtHandle, this.tableName); + + 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) { diff --git a/src/connector/python/taos/__init__.py b/src/connector/python/taos/__init__.py index 973263573808232e4e71dc0158585624a8e7d2ab..52c6db311ecc4c2f944372ae3334fdc58cb6e779 100644 --- a/src/connector/python/taos/__init__.py +++ b/src/connector/python/taos/__init__.py @@ -2,6 +2,10 @@ from .connection import TDengineConnection from .cursor import TDengineCursor +# For some reason, the following is needed for VS Code (through PyLance) to +# recognize that "error" is a valid module of the "taos" package. +from .error import ProgrammingError + # Globals threadsafety = 0 paramstyle = 'pyformat' diff --git a/src/dnode/CMakeLists.txt b/src/dnode/CMakeLists.txt index dd18f0092024834c8cb0d230b27f5905ea2339df..f8d8f88438429f1c0be405825cef4ab9c1b130bc 100644 --- a/src/dnode/CMakeLists.txt +++ b/src/dnode/CMakeLists.txt @@ -10,8 +10,15 @@ INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc) INCLUDE_DIRECTORIES(inc) AUX_SOURCE_DIRECTORY(src SRC) +IF (TD_LINUX_64 AND JEMALLOC_ENABLED) + ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc) + SET(LINK_JEMALLOC "-L${CMAKE_BINARY_DIR}/build/lib -ljemalloc") +ELSE () + SET(LINK_JEMALLOC "") +ENDIF () + ADD_EXECUTABLE(taosd ${SRC}) -TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync) +TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync ${LINK_JEMALLOC}) IF (TD_SOMODE_STATIC) TARGET_LINK_LIBRARIES(taosd taos_static) diff --git a/src/dnode/src/dnodeMain.c b/src/dnode/src/dnodeMain.c index ee4dfcf85210d389651224796727d5b72ea8b9ac..64da11f3123b5eafd1de2ae9253fe5fc3090ad80 100644 --- a/src/dnode/src/dnodeMain.c +++ b/src/dnode/src/dnodeMain.c @@ -86,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; @@ -95,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() { @@ -219,14 +240,20 @@ static int32_t dnodeInitStorage() { if (tsCompactMnodeWal == 1) { sprintf(tsMnodeTmpDir, "%s/mnode_tmp", tsDataDir); - tfsRmdir(tsMnodeTmpDir); + 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); - //tfsRmdir(tsMnodeBakDir); + 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) { diff --git a/src/inc/taos.h b/src/inc/taos.h index 6dd695b320f71ff65b97715aed108c7d1b4e2f7e..d27828fc364fd795e238b33df464fdc3548b60e2 100644 --- a/src/inc/taos.h +++ b/src/inc/taos.h @@ -112,6 +112,7 @@ typedef struct 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); diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index f888d037b39f944fb15b7a7d24d11952a4e3ef1e..5bdd197aa9a76a72e5194f2c1591e52f47706dfb 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. @@ -242,7 +244,6 @@ do { \ #define TSDB_MAX_REPLICA 5 #define TSDB_TBNAME_COLUMN_INDEX (-1) -#define TSDB_BLOCK_DIST_COLUMN_INDEX (-2) #define TSDB_UD_COLUMN_INDEX (-1000) #define TSDB_RES_COL_ID (-5000) @@ -345,6 +346,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 0d32e17a4cd446b980f3bc464d12123dba6b9f19..ab15e851e76e1c7ad29a81a7cd1874a9e89d82ed 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") @@ -215,11 +215,11 @@ int32_t* taosGetErrno(); #define TSDB_CODE_VND_IS_FLOWCTRL TAOS_DEF_ERROR_CODE(0, 0x050C) //"Database memory is full for waiting commit") #define TSDB_CODE_VND_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x050D) //"Database is dropping") #define TSDB_CODE_VND_IS_BALANCING TAOS_DEF_ERROR_CODE(0, 0x050E) //"Database is balancing") +#define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0510) //"Database is closing") #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") diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index 3b7022fb88d34e0e71a3f70ace85d769e338b11e..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; @@ -471,6 +473,7 @@ typedef struct { bool simpleAgg; bool pointInterpQuery; // point interpolation query bool needReverseScan; // need reverse scan + bool stateWindow; // state window flag STimeWindow window; int32_t numOfTables; @@ -703,8 +706,9 @@ typedef struct { } STableInfoMsg; typedef struct { + int32_t numOfVgroups; int32_t numOfTables; - char tableIds[]; + char tableNames[]; } SMultiTableInfoMsg; typedef struct SSTableVgroupMsg { @@ -753,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 43e1ac2a19447fdf771b31d3dae76aa4f83442d3..05d29daad52c2eeeeee080b411ebedf4b7e8233f 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -215,7 +215,7 @@ typedef struct SDataBlockInfo { } SDataBlockInfo; typedef struct SFileBlockInfo { - int32_t numOfRows; + int32_t numBlocksOfStep; } SFileBlockInfo; typedef struct { @@ -229,11 +229,15 @@ typedef struct { SHashObj *map; // speedup acquire the tableQueryInfo by table uid } STableGroupInfo; +#define TSDB_BLOCK_DIST_STEP_ROWS 16 typedef struct { uint16_t rowSize; uint16_t numOfFiles; uint32_t numOfTables; uint64_t totalSize; + uint64_t totalRows; + int32_t maxRows; + int32_t minRows; int32_t firstSeekTimeUs; uint32_t numOfRowsInMemTable; SArray *dataBlockInfos; @@ -265,6 +269,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 ef3f8ed1fbcc754ad54dd7e9c232f610b37b98e8..e9585636fd97bd4bcb856317689aed615d275026 100644 --- a/src/inc/ttokendef.h +++ b/src/inc/ttokendef.h @@ -136,74 +136,74 @@ #define TK_VARIABLE 117 #define TK_INTERVAL 118 #define TK_SESSION 119 -#define TK_FILL 120 -#define TK_SLIDING 121 -#define TK_ORDER 122 -#define TK_BY 123 -#define TK_ASC 124 -#define TK_DESC 125 -#define TK_GROUP 126 -#define TK_HAVING 127 -#define TK_LIMIT 128 -#define TK_OFFSET 129 -#define TK_SLIMIT 130 -#define TK_SOFFSET 131 -#define TK_WHERE 132 -#define TK_NOW 133 -#define TK_RESET 134 -#define TK_QUERY 135 -#define TK_SYNCDB 136 -#define TK_ADD 137 -#define TK_COLUMN 138 -#define TK_TAG 139 -#define TK_CHANGE 140 -#define TK_SET 141 -#define TK_KILL 142 -#define TK_CONNECTION 143 -#define TK_STREAM 144 -#define TK_COLON 145 -#define TK_ABORT 146 -#define TK_AFTER 147 -#define TK_ATTACH 148 -#define TK_BEFORE 149 -#define TK_BEGIN 150 -#define TK_CASCADE 151 -#define TK_CLUSTER 152 -#define TK_CONFLICT 153 -#define TK_COPY 154 -#define TK_DEFERRED 155 -#define TK_DELIMITERS 156 -#define TK_DETACH 157 -#define TK_EACH 158 -#define TK_END 159 -#define TK_EXPLAIN 160 -#define TK_FAIL 161 -#define TK_FOR 162 -#define TK_IGNORE 163 -#define TK_IMMEDIATE 164 -#define TK_INITIALLY 165 -#define TK_INSTEAD 166 -#define TK_MATCH 167 -#define TK_KEY 168 -#define TK_OF 169 -#define TK_RAISE 170 -#define TK_REPLACE 171 -#define TK_RESTRICT 172 -#define TK_ROW 173 -#define TK_STATEMENT 174 -#define TK_TRIGGER 175 -#define TK_VIEW 176 -#define TK_SEMI 177 -#define TK_NONE 178 -#define TK_PREV 179 -#define TK_LINEAR 180 -#define TK_IMPORT 181 -#define TK_TBNAME 182 -#define TK_JOIN 183 -#define TK_INSERT 184 -#define TK_INTO 185 -#define TK_VALUES 186 - +#define TK_STATE_WINDOW 120 +#define TK_FILL 121 +#define TK_SLIDING 122 +#define TK_ORDER 123 +#define TK_BY 124 +#define TK_ASC 125 +#define TK_DESC 126 +#define TK_GROUP 127 +#define TK_HAVING 128 +#define TK_LIMIT 129 +#define TK_OFFSET 130 +#define TK_SLIMIT 131 +#define TK_SOFFSET 132 +#define TK_WHERE 133 +#define TK_NOW 134 +#define TK_RESET 135 +#define TK_QUERY 136 +#define TK_SYNCDB 137 +#define TK_ADD 138 +#define TK_COLUMN 139 +#define TK_TAG 140 +#define TK_CHANGE 141 +#define TK_SET 142 +#define TK_KILL 143 +#define TK_CONNECTION 144 +#define TK_STREAM 145 +#define TK_COLON 146 +#define TK_ABORT 147 +#define TK_AFTER 148 +#define TK_ATTACH 149 +#define TK_BEFORE 150 +#define TK_BEGIN 151 +#define TK_CASCADE 152 +#define TK_CLUSTER 153 +#define TK_CONFLICT 154 +#define TK_COPY 155 +#define TK_DEFERRED 156 +#define TK_DELIMITERS 157 +#define TK_DETACH 158 +#define TK_EACH 159 +#define TK_END 160 +#define TK_EXPLAIN 161 +#define TK_FAIL 162 +#define TK_FOR 163 +#define TK_IGNORE 164 +#define TK_IMMEDIATE 165 +#define TK_INITIALLY 166 +#define TK_INSTEAD 167 +#define TK_MATCH 168 +#define TK_KEY 169 +#define TK_OF 170 +#define TK_RAISE 171 +#define TK_REPLACE 172 +#define TK_RESTRICT 173 +#define TK_ROW 174 +#define TK_STATEMENT 175 +#define TK_TRIGGER 176 +#define TK_VIEW 177 +#define TK_SEMI 178 +#define TK_NONE 179 +#define TK_PREV 180 +#define TK_LINEAR 181 +#define TK_IMPORT 182 +#define TK_TBNAME 183 +#define TK_JOIN 184 +#define TK_INSERT 185 +#define TK_INTO 186 +#define TK_VALUES 187 #define TK_SPACE 300 #define TK_COMMENT 301 diff --git a/src/kit/shell/CMakeLists.txt b/src/kit/shell/CMakeLists.txt index d36c1e3fccc4ee7c5eae359f975e2ac1faa6c135..d9049454352efbd9344eae3c776f10c8f37fe090 100644 --- a/src/kit/shell/CMakeLists.txt +++ b/src/kit/shell/CMakeLists.txt @@ -11,10 +11,17 @@ IF (TD_LINUX) LIST(REMOVE_ITEM SRC ./src/shellDarwin.c) ADD_EXECUTABLE(shell ${SRC}) +IF (TD_LINUX_64 AND JEMALLOC_ENABLED) + ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc) + SET(LINK_JEMALLOC "-L${CMAKE_BINARY_DIR}/build/lib -ljemalloc") +ELSE () + SET(LINK_JEMALLOC "") +ENDIF () + IF (TD_SOMODE_STATIC) - TARGET_LINK_LIBRARIES(shell taos_static) + TARGET_LINK_LIBRARIES(shell taos_static ${LINK_JEMALLOC}) ELSE () - TARGET_LINK_LIBRARIES(shell taos) + TARGET_LINK_LIBRARIES(shell taos ${LINK_JEMALLOC}) ENDIF () SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos) diff --git a/src/kit/taosdemo/CMakeLists.txt b/src/kit/taosdemo/CMakeLists.txt index 5f75be0e19065a70cf53f5e81285be2c25f1fb3e..091eecfe270a20987a48f7223f57d2400169ac6d 100644 --- a/src/kit/taosdemo/CMakeLists.txt +++ b/src/kit/taosdemo/CMakeLists.txt @@ -55,14 +55,21 @@ ENDIF () MESSAGE("TD_VERSION_NUMBER is:" ${TD_VERSION_NUMBER}) ADD_DEFINITIONS(-DTD_VERNUMBER="${TD_VERSION_NUMBER}") +IF (TD_LINUX_64 AND JEMALLOC_ENABLED) + ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc) + SET(LINK_JEMALLOC "-L${CMAKE_BINARY_DIR}/build/lib -ljemalloc") +ELSE () + SET(LINK_JEMALLOC "") +ENDIF () + IF (TD_LINUX) AUX_SOURCE_DIRECTORY(. SRC) ADD_EXECUTABLE(taosdemo ${SRC}) IF (TD_SOMODE_STATIC) - TARGET_LINK_LIBRARIES(taosdemo taos_static cJson) + TARGET_LINK_LIBRARIES(taosdemo taos_static cJson ${LINK_JEMALLOC}) ELSE () - TARGET_LINK_LIBRARIES(taosdemo taos cJson) + TARGET_LINK_LIBRARIES(taosdemo taos cJson ${LINK_JEMALLOC}) ENDIF () ELSEIF (TD_WINDOWS) AUX_SOURCE_DIRECTORY(. SRC) @@ -71,7 +78,7 @@ ELSEIF (TD_WINDOWS) IF (TD_SOMODE_STATIC) TARGET_LINK_LIBRARIES(taosdemo taos_static cJson) ELSE () - TARGET_LINK_LIBRARIES(taosdemo taos cJson}) + TARGET_LINK_LIBRARIES(taosdemo taos cJson) ENDIF () ELSEIF (TD_DARWIN) # missing a few dependencies, such as diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index 888dc4a04e4fc31d1b775e2f078f123899a61fa5..6f5d407a7348b2fa7768f0266c5dcd79a6b4653f 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -53,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 @@ -253,12 +255,13 @@ typedef struct SColumn_S { 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 uint16_t iface; // 0: taosc, 1: rest, 2: stmt int64_t childTblLimit; uint64_t childTblOffset; @@ -377,7 +380,7 @@ typedef struct SDbs_S { typedef struct SpecifiedQueryInfo_S { uint64_t queryInterval; // 0: unlimit > 0 loop/s uint32_t concurrent; - uint64_t sqlCount; + int sqlCount; uint32_t asyncMode; // 0: sync, 1: async uint64_t subscribeInterval; // ms uint64_t queryTimes; @@ -386,6 +389,7 @@ typedef struct SpecifiedQueryInfo_S { 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]; @@ -404,10 +408,11 @@ typedef struct SuperQueryInfo_S { uint64_t queryTimes; 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; @@ -688,7 +693,11 @@ static void printHelp() { 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, @@ -788,8 +797,10 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { 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); @@ -826,7 +837,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { 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]); @@ -1054,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"); @@ -1076,7 +1100,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } printf("# Insertion interval: %"PRIu64"\n", arguments->insert_interval); - printf("# Number of records per req: %ud\n", + printf("# Number of records per req: %u\n", arguments->num_of_RPR); printf("# Max SQL length: %"PRIu64"\n", arguments->max_sql_len); @@ -1368,7 +1392,7 @@ static int printfInsertMeta() { 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%ud\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); @@ -1454,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"); @@ -1494,7 +1519,7 @@ static int printfInsertMeta() { printf(" multiThreadWriteOneTbl: \033[33myes\033[0m\n"); } */ - printf(" interlaceRows: \033[33m%ud\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) { @@ -1572,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: %ud\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); @@ -1669,7 +1694,7 @@ static void printfInsertMetaToFile(FILE* fp) { (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: %ud\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", @@ -1682,7 +1707,7 @@ static void printfInsertMetaToFile(FILE* fp) { fprintf(fp, " multiThreadWriteOneTbl: yes\n"); } */ - fprintf(fp, " interlaceRows: %ud\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); @@ -1758,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"); @@ -1778,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) { @@ -2885,8 +2910,8 @@ static void* createTable(void *sarg) 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); } @@ -2901,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, @@ -2910,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; @@ -2928,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, @@ -2948,9 +2973,10 @@ static void* createTable(void *sarg) } len = 0; - 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; } @@ -2963,12 +2989,13 @@ static void* createTable(void *sarg) } if (0 != len) { - 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; } @@ -3046,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 (uint64_t 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; - } + 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); + } - verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, - g_Dbs.db[i].superTbls[j].colsOfCreateChildTable); - uint64_t tableFrom = 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, tableFrom); - startMultiThreadCreateChildTable( - g_Dbs.db[i].superTbls[j].colsOfCreateChildTable, - g_Dbs.threadCountByCreateTbl, - tableFrom, - g_Dbs.db[i].superTbls[j].childTblCount, - g_Dbs.db[i].dbName, &(g_Dbs.db[i].superTbls[j])); + 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: %"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); } - } } /* @@ -3561,9 +3588,9 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { // rows per table need be less than insert batch if (g_args.interlace_rows > g_args.num_of_RPR) { - printf("NOTICE: interlace rows value %ud > num_of_records_per_req %ud\n\n", + 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 %ud\n\n", + 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; @@ -3794,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"); @@ -3857,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", @@ -3885,8 +3920,10 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { 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); @@ -3914,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; } @@ -3970,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]) { @@ -4030,10 +4069,10 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { 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 %ud > num_of_records_per_req %ud\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(" interlace rows value will be set to num_of_records_per_req %ud\n\n", + 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; @@ -4250,7 +4289,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { if (concurrent && concurrent->type == cJSON_Number) { if (concurrent->valueint <= 0) { errorPrint( - "%s() LN%d, query sqlCount %"PRIu64" or concurrent %d is not correct.\n", + "%s() LN%d, query sqlCount %d or concurrent %d is not correct.\n", __func__, __LINE__, g_queryInfo.specifiedQueryInfo.sqlCount, g_queryInfo.specifiedQueryInfo.concurrent); @@ -4349,16 +4388,27 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { 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) { + if ((resubAfterConsume) + && (resubAfterConsume->type == cJSON_Number) + && (resubAfterConsume->valueint >= 0)) { g_queryInfo.specifiedQueryInfo.resubAfterConsume[j] = resubAfterConsume->valueint; } else if (!resubAfterConsume) { - //printf("failed to read json, subscribe interval no found\n"); - //goto PARSE_OVER; - g_queryInfo.specifiedQueryInfo.resubAfterConsume[j] = 1; + // default value is -1, which mean do not resub + g_queryInfo.specifiedQueryInfo.resubAfterConsume[j] = -1; } cJSON *result = cJSON_GetObjectItem(sql, "result"); @@ -4502,16 +4552,27 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { g_queryInfo.superQueryInfo.subscribeKeepProgress = 0; } + 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, "resubAfterConsume"); - if (superResubAfterConsume - && superResubAfterConsume->type == cJSON_Number) { + if ((superResubAfterConsume) + && (superResubAfterConsume->type == cJSON_Number) + && (superResubAfterConsume->valueint >= 0)) { g_queryInfo.superQueryInfo.resubAfterConsume = superResubAfterConsume->valueint; } else if (!superResubAfterConsume) { - //printf("failed to read json, subscribe interval no found\n"); - ////goto PARSE_OVER; - g_queryInfo.superQueryInfo.resubAfterConsume = 1; + // default value is -1, which mean do not resub + g_queryInfo.superQueryInfo.resubAfterConsume = -1; } // supert table sqls @@ -4773,44 +4834,34 @@ static int64_t generateData(char *recBuf, char **data_type, 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; - } - } + int columnCount = g_args.num_of_CPR; - if (0 == c) { - perror("data type error!"); - exit(-1); - } - - 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 % c], "TIMESTAMP") == 0) { + } 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) { + } 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); @@ -4857,74 +4908,93 @@ static int prepareSampleDataForSTable(SSuperTable *superTblInfo) { return 0; } -static int64_t execInsert(threadInfo *pThreadInfo, 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, + verbosePrint("[%d] %s() LN%d %s\n", pThreadInfo->threadID, __func__, __LINE__, pThreadInfo->buffer); - if (superTblInfo) { - if (superTblInfo->iface == TAOSC_IFACE) { - affectedRows = queryDbExec( - pThreadInfo->taos, - pThreadInfo->buffer, INSERT_TYPE, false); - } else if (superTblInfo->iface == REST_IFACE) { - if (0 != postProceSql(g_Dbs.host, &g_Dbs.serv_addr, g_Dbs.port, - pThreadInfo->buffer, NULL /* not set result file */)) { - affectedRows = -1; - printf("========restful return fail, threadID[%d]\n", - pThreadInfo->threadID); - } else { - affectedRows = k; - } - } else if (superTblInfo->iface == 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; - } else { - errorPrint("%s() LN%d: unknown insert mode: %d\n", - __func__, __LINE__, superTblInfo->iface); - affectedRows = 0; + 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, pThreadInfo->buffer, INSERT_TYPE, false); - } - return affectedRows; + return affectedRows; } static void getTableName(char *pTblName, threadInfo* pThreadInfo, uint64_t tableSeq) { - SSuperTable* superTblInfo = pThreadInfo->superTblInfo; - if ((superTblInfo) - && (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); + 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=%"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); + 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 generateDataTailWithoutStb( +static int32_t generateDataTailWithoutStb( uint32_t batch, char* buffer, int64_t remainderBufLen, int64_t insertRows, uint64_t recordFrom, int64_t startTime, @@ -4935,7 +5005,7 @@ static int64_t generateDataTailWithoutStb( verbosePrint("%s() LN%d batch=%d\n", __func__, __LINE__, batch); - int64_t k = 0; + int32_t k = 0; for (k = 0; k < batch;) { char data[MAX_DATA_SIZE]; memset(data, 0, MAX_DATA_SIZE); @@ -4947,7 +5017,7 @@ static int64_t generateDataTailWithoutStb( retLen = generateData(data, data_type, startTime + getTSRandTail( - (int64_t)DEFAULT_TIMESTAMP_STEP, k, + (int64_t) DEFAULT_TIMESTAMP_STEP, k, g_args.disorderRatio, g_args.disorderRange), lenOfBinary); @@ -4960,7 +5030,7 @@ static int64_t generateDataTailWithoutStb( len += retLen; remainderBufLen -= retLen; - verbosePrint("%s() LN%d len=%"PRIu64" k=%"PRIu64" \nbuffer=%s\n", + verbosePrint("%s() LN%d len=%"PRIu64" k=%d \nbuffer=%s\n", __func__, __LINE__, len, k, buffer); recordFrom ++; @@ -5006,7 +5076,7 @@ static int32_t generateStbDataTail( } else { tsRand = false; } - verbosePrint("%s() LN%d batch=%ud\n", __func__, __LINE__, batch); + verbosePrint("%s() LN%d batch=%u\n", __func__, __LINE__, batch); int32_t k = 0; for (k = 0; k < batch;) { @@ -5040,7 +5110,7 @@ static int32_t generateStbDataTail( len += retLen; remainderBufLen -= retLen; - verbosePrint("%s() LN%d len=%"PRIu64" k=%ud \nbuffer=%s\n", + verbosePrint("%s() LN%d len=%"PRIu64" k=%u \nbuffer=%s\n", __func__, __LINE__, len, k, buffer); recordFrom ++; @@ -5168,7 +5238,7 @@ static int32_t generateStbInterlaceData( int64_t dataLen = 0; - verbosePrint("[%d] %s() LN%d i=%"PRIu64" batchPerTblTimes=%ud batchPerTbl = %ud\n", + verbosePrint("[%d] %s() LN%d i=%"PRIu64" batchPerTblTimes=%u batchPerTbl = %u\n", pThreadInfo->threadID, __func__, __LINE__, i, batchPerTblTimes, batchPerTbl); @@ -5186,7 +5256,7 @@ static int32_t generateStbInterlaceData( pstr += dataLen; *pRemainderBufLen -= dataLen; } else { - debugPrint("%s() LN%d, generated data tail: %ud, not equal batch per table: %ud\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'; @@ -5197,10 +5267,11 @@ static int32_t generateStbInterlaceData( } static int64_t generateInterlaceDataWithoutStb( - char *tableName, uint32_t batchPerTbl, + char *tableName, uint32_t batch, uint64_t tableSeq, char *dbName, char *buffer, int64_t insertRows, + int64_t startTime, uint64_t *pRemainderBufLen) { assert(buffer); @@ -5219,18 +5290,17 @@ static int64_t generateInterlaceDataWithoutStb( int64_t dataLen = 0; - int64_t startTime = 1500000000000; - int64_t k = generateDataTailWithoutStb( - batchPerTbl, pstr, *pRemainderBufLen, insertRows, 0, + int32_t k = generateDataTailWithoutStb( + batch, pstr, *pRemainderBufLen, insertRows, 0, startTime, &dataLen); - if (k == batchPerTbl) { + if (k == batch) { pstr += dataLen; *pRemainderBufLen -= dataLen; } else { - debugPrint("%s() LN%d, generated data tail: %"PRIu64", not equal batch per table: %ud\n", - __func__, __LINE__, k, batchPerTbl); + 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; @@ -5239,32 +5309,239 @@ static int64_t generateInterlaceDataWithoutStb( return k; } -static int32_t prepareStbStmt(SSuperTable *stbInfo, +#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, uint32_t batch, uint64_t insertRows, - uint64_t recordFrom, - int64_t startTime, char *buffer) + char *tableName, + uint32_t batch, + int64_t insertRows, + int64_t recordFrom, + int64_t startTime) { - uint32_t k; - int ret; - char *pstr = buffer; - pstr += sprintf(pstr, "INSERT INTO %s values(?", tableName); + 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 **data_type = g_args.datatype; + + 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; + } - for (int i = 0; i < stbInfo->columnCount; i++) { - pstr += sprintf(pstr, ",?"); + 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; + } } - pstr += sprintf(pstr, ")"); - ret = taos_stmt_prepare(stmt, buffer, 0); - if (ret != 0){ - errorPrint("failed to execute taos_stmt_prepare. return 0x%x. reason: %s\n", - ret, taos_errstr(NULL)); + 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", batch); + errorPrint("Failed to allocate %d bind params\n", + (stbInfo->columnCount + 1)); return -1; } @@ -5274,6 +5551,8 @@ static int32_t prepareStbStmt(SSuperTable *stbInfo, } else { tsRand = false; } + + uint32_t k; for (k = 0; k < batch;) { /* columnCount + 1 (ts) */ char data[MAX_DATA_SIZE]; @@ -5303,135 +5582,12 @@ static int32_t prepareStbStmt(SSuperTable *stbInfo, for (int i = 0; i < stbInfo->columnCount; i ++) { bind = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * (i + 1))); - if (0 == strncasecmp(stbInfo->columns[i].dataType, - "BINARY", strlen("BINARY"))) { - if (stbInfo->columns[i].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, stbInfo->columns[i].dataLen); - - bind->buffer_type = TSDB_DATA_TYPE_BINARY; - bind->buffer_length = stbInfo->columns[i].dataLen; - bind->buffer = bind_binary; - bind->length = &bind->buffer_length; - bind->is_null = NULL; - - ptr += bind->buffer_length; - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "NCHAR", strlen("NCHAR"))) { - if (stbInfo->columns[i].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, stbInfo->columns[i].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(stbInfo->columns[i].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(stbInfo->columns[i].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(stbInfo->columns[i].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(stbInfo->columns[i].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(stbInfo->columns[i].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(stbInfo->columns[i].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(stbInfo->columns[i].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(stbInfo->columns[i].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", - stbInfo->columns[i].dataType); - return -1; + if ( -1 == prepareStmtBindArrayByType( + bind, + stbInfo->columns[i].dataType, + stbInfo->columns[i].dataLen, + &ptr)) { + return -1; } } taos_stmt_bind_param(stmt, (TAOS_BIND *)bindArray); @@ -5445,8 +5601,10 @@ static int32_t prepareStbStmt(SSuperTable *stbInfo, } } + free(bindArray); return k; } +#endif static int32_t generateStbProgressiveData( SSuperTable *superTblInfo, @@ -5482,12 +5640,7 @@ static int32_t generateStbProgressiveData( pSamplePos, &dataLen); } -static int64_t prepareStmtWithoutStb(char *tableName) -{ - return -1; -} - -static int64_t generateProgressiveDataWithoutStb( +static int32_t generateProgressiveDataWithoutStb( char *tableName, /* int64_t tableSeq, */ threadInfo *pThreadInfo, char *buffer, @@ -5520,7 +5673,7 @@ static int64_t generateProgressiveDataWithoutStb( 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, @@ -5638,22 +5791,53 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { int32_t generated; if (superTblInfo) { - generated = generateStbInterlaceData( - superTblInfo, - tableName, batchPerTbl, i, - batchPerTblTimes, - tableSeq, - pThreadInfo, pstr, - insertRows, - startTime, - &remainderBufLen); + 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 { - generated = generateInterlaceDataWithoutStb( - tableName, batchPerTbl, - tableSeq, - pThreadInfo->db_name, pstr, - insertRows, - &remainderBufLen); + 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", @@ -5668,9 +5852,10 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { tableSeq ++; recOfBatch += batchPerTbl; + pstr += (oldRemainderLen - remainderBufLen); -// startTime += batchPerTbl * superTblInfo->timeStampStep; pThreadInfo->totalInsertRows += batchPerTbl; + verbosePrint("[%d] %s() LN%d batchPerTbl=%d recOfBatch=%d\n", pThreadInfo->threadID, __func__, __LINE__, batchPerTbl, recOfBatch); @@ -5824,10 +6009,16 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { int32_t generated; if (superTblInfo) { if (superTblInfo->iface == STMT_IFACE) { - generated = prepareStbStmt(superTblInfo, +#if STMT_IFACE_ENABLED == 1 + generated = prepareStbStmt( + superTblInfo, pThreadInfo->stmt, - tableName, g_args.num_of_RPR, + tableName, + g_args.num_of_RPR, insertRows, i, start_time, pstr); +#else + generated = -1; +#endif } else { generated = generateStbProgressiveData( superTblInfo, @@ -5838,7 +6029,16 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { } } else { if (g_args.iface == STMT_IFACE) { - generated = prepareStmtWithoutStb(tableName); +#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, @@ -5859,13 +6059,13 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { startTs = taosGetTimestampMs(); - int64_t affectedRows = execInsert(pThreadInfo, 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); @@ -5875,7 +6075,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; } @@ -6045,15 +6245,6 @@ static int convertHostToServAddr(char *host, uint16_t port, struct sockaddr_in * static void startMultiThreadInsertData(int threads, char* db_name, char* precision,SSuperTable* superTblInfo) { - //TAOS* taos; - //if (0 == strncasecmp(superTblInfo->iface, "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)) { @@ -6232,7 +6423,17 @@ static void startMultiThreadInsertData(int threads, char* db_name, exit(-1); } - if ((superTblInfo) && (superTblInfo->iface == STMT_IFACE)) { +#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( @@ -6243,7 +6444,26 @@ static void startMultiThreadInsertData(int threads, char* db_name, 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 { pThreadInfo->taos = NULL; } @@ -6284,9 +6504,11 @@ static void startMultiThreadInsertData(int threads, char* db_name, 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); @@ -6563,7 +6785,6 @@ static int insertTestProcess() { } } - taosMsleep(1000); // create sub threads for inserting data //start = taosGetTimestampMs(); for (int i = 0; i < g_Dbs.dbCount; i++) { @@ -6642,7 +6863,7 @@ static void *specifiedTableQuery(void *sarg) { uint64_t lastPrintTime = taosGetTimestampMs(); uint64_t startTs = taosGetTimestampMs(); - if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq] != NULL) { + if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') { sprintf(pThreadInfo->filePath, "%s-%d", g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq], pThreadInfo->threadID); @@ -6743,7 +6964,7 @@ 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); - if (g_queryInfo.superQueryInfo.result[j] != NULL) { + if (g_queryInfo.superQueryInfo.result[j][0] != '\0') { sprintf(pThreadInfo->filePath, "%s-%d", g_queryInfo.superQueryInfo.result[j], pThreadInfo->threadID); @@ -7082,7 +7303,10 @@ static void *superSubscribe(void *sarg) { uint64_t st = 0, et = 0; - while(1) { + 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; @@ -7111,7 +7335,7 @@ static void *superSubscribe(void *sarg) { } consumed[tsubSeq] ++; - if ((g_queryInfo.superQueryInfo.subscribeKeepProgress) + if ((g_queryInfo.superQueryInfo.resubAfterConsume != -1) && (consumed[tsubSeq] >= g_queryInfo.superQueryInfo.resubAfterConsume)) { printf("keepProgress:%d, resub super table query: %"PRIu64"\n", @@ -7174,7 +7398,7 @@ static void *specifiedSubscribe(void *sarg) { "taosdemo-subscribe-%"PRIu64"-%d", pThreadInfo->querySeq, pThreadInfo->threadID); - if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq] != NULL) { + if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') { sprintf(pThreadInfo->filePath, "%s-%d", g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq], pThreadInfo->threadID); @@ -7193,7 +7417,10 @@ static void *specifiedSubscribe(void *sarg) { // start loop to consume result g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0; - while(1) { + 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; } @@ -7201,15 +7428,18 @@ static void *specifiedSubscribe(void *sarg) { 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) { + 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); + fetchResult( + g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID], + pThreadInfo); } g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] ++; - if ((g_queryInfo.specifiedQueryInfo.subscribeKeepProgress) + 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", @@ -7218,16 +7448,17 @@ static void *specifiedSubscribe(void *sarg) { 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); + 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_close(pThreadInfo->taos); + return NULL; } } } @@ -7276,12 +7507,12 @@ static int subscribeTestProcess() { //==== create threads for query for specified table if (g_queryInfo.specifiedQueryInfo.sqlCount <= 0) { - debugPrint("%s() LN%d, sepcified query sqlCount %"PRIu64".\n", + debugPrint("%s() LN%d, sepcified query sqlCount %d.\n", __func__, __LINE__, g_queryInfo.specifiedQueryInfo.sqlCount); } else { if (g_queryInfo.specifiedQueryInfo.concurrent <= 0) { - errorPrint("%s() LN%d, sepcified query sqlCount %"PRIu64".\n", + errorPrint("%s() LN%d, sepcified query sqlCount %d.\n", __func__, __LINE__, g_queryInfo.specifiedQueryInfo.sqlCount); exit(-1); @@ -7314,7 +7545,7 @@ static int subscribeTestProcess() { //==== create threads for super table query if (g_queryInfo.superQueryInfo.sqlCount <= 0) { - debugPrint("%s() LN%d, super table query sqlCount %"PRIu64".\n", + debugPrint("%s() LN%d, super table query sqlCount %d.\n", __func__, __LINE__, g_queryInfo.superQueryInfo.sqlCount); } else { @@ -7440,7 +7671,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; diff --git a/src/mnode/src/mnodeDb.c b/src/mnode/src/mnodeDb.c index 5e06faaad92f9e85ea3bfb9864c72d31ab798f2f..b0ac1192bb8a5545c1e8f731fb92a0d69538eb18 100644 --- a/src/mnode/src/mnodeDb.c +++ b/src/mnode/src/mnodeDb.c @@ -1060,6 +1060,13 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) { newCfg.partitions = partitions; } +// community version can only change daysToKeep +// but enterprise version can change all daysToKeep options +#ifndef _STORAGE + newCfg.daysToKeep1 = newCfg.daysToKeep; + newCfg.daysToKeep2 = newCfg.daysToKeep; +#endif + return newCfg; } diff --git a/src/mnode/src/mnodeMain.c b/src/mnode/src/mnodeMain.c index d3511a4e62b56ab70050f51ad606a7297a2be6a1..8ce798c8ec2271ecb236d49278f07f974e4bb043 100644 --- a/src/mnode/src/mnodeMain.c +++ b/src/mnode/src/mnodeMain.c @@ -121,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/mnodeSdb.c b/src/mnode/src/mnodeSdb.c index 84e4f33ca7efe2cafca9ec64d8b7872cac827403..e9acd5b9bc69f0354f28009254c57c004fbb7995 100644 --- a/src/mnode/src/mnodeSdb.c +++ b/src/mnode/src/mnodeSdb.c @@ -656,8 +656,6 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void * dnodeReportStep("mnode-sdb", stepDesc, 0); } - if (qtype == TAOS_QTYPE_QUERY) return sdbPerformDeleteAction(pHead, pTable); - pthread_mutex_lock(&tsSdbMgmt.mutex); if (pHead->version == 0) { @@ -690,7 +688,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); @@ -713,19 +711,19 @@ 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) { - // 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 { - return sdbPerformDeleteAction(pHead, pTable); - //} + if (qtype == TAOS_QTYPE_FWD) { + // Drop database/stable may take a long time and cause a timeout, so we confirm first + syncConfirmForward(tsSdbMgmt.sync, pHead->version, TSDB_CODE_SUCCESS, false); + } + return sdbPerformDeleteAction(pHead, pTable); } else if (action == SDB_ACTION_UPDATE) { return sdbPerformUpdateAction(pHead, pTable); } else { @@ -1138,7 +1136,10 @@ static void *sdbWorkerFp(void *pWorker) { sdbConfirmForward(1, pRow, pRow->code); } else { if (qtype == TAOS_QTYPE_FWD) { - syncConfirmForward(tsSdbMgmt.sync, pRow->pHead.version, pRow->code, false); + int32_t action = pRow->pHead.msgType % 10; + if (action != SDB_ACTION_DELETE) { + syncConfirmForward(tsSdbMgmt.sync, pRow->pHead.version, pRow->code, false); + } } sdbFreeFromQueue(pRow); } diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c index 4e879537e431dba12a066d84abd3f867c6c00ada..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); @@ -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 *)(pMultiMeta->metas + pMultiMeta->contLen); - int32_t code = mnodeDoGetChildTableMeta(pMsg, pMeta); + 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; + } + } + + 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) { @@ -3261,7 +3375,7 @@ static int32_t mnodeCompactSuperTables() { .rowSize = sizeof(SSTableObj) + schemaSize, }; - mInfo("compact super %" PRIu64, pTable->uid); + //mInfo("compact super %" PRIu64, pTable->uid); sdbInsertCompactRow(&row); } @@ -3287,7 +3401,7 @@ static int32_t mnodeCompactChildTables() { .pTable = tsChildTableSdb, }; - mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid); + //mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid); sdbInsertCompactRow(&row); } 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/osMemory.h b/src/os/inc/osMemory.h index 27efd9f5051d9f87838980503ed60174de153ad4..793992c197a475b68046296b6683b5b2843b9d68 100644 --- a/src/os/inc/osMemory.h +++ b/src/os/inc/osMemory.h @@ -22,6 +22,10 @@ extern "C" { #endif +#ifdef TD_JEMALLOC_ENABLED +#include +#endif + typedef enum { TAOS_ALLOC_MODE_DEFAULT = 0, TAOS_ALLOC_MODE_RANDOM_FAIL = 1, 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/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/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/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/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/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index b9361650e99a0531033cf4f680860730266f68f3..b5b4fb58548f5067c26644cf63e0a5911b69ad8b 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -22,6 +22,7 @@ #include "qFill.h" #include "qResultbuf.h" #include "qSqlparser.h" +#include "qTableMeta.h" #include "qTsbuf.h" #include "query.h" #include "taosdef.h" @@ -70,14 +71,6 @@ typedef struct SResultRowPool { SArray* pData; // SArray } SResultRowPool; -typedef struct SSqlGroupbyExpr { - int16_t tableIndex; - SArray* columnInfo; // SArray, group by columns information - int16_t numOfGroupCols; - int16_t orderIndex; // order by column index - int16_t orderType; // order by type: asc/desc -} SSqlGroupbyExpr; - typedef struct SResultRow { int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer int32_t offset:29; // row index in buffer page @@ -196,6 +189,7 @@ typedef struct SQueryAttr { bool pointInterpQuery; // point interpolation query bool needReverseScan; // need reverse scan bool distinctTag; // distinct tag query + bool stateWindow; // window State on sub/normal table int32_t interBufSize; // intermediate buffer sizse int32_t havingNum; // having expr number @@ -216,7 +210,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; @@ -302,6 +296,8 @@ enum OPERATOR_TYPE_E { OP_GlobalAggregate = 18, // global merge for the multi-way data sources. OP_Filter = 19, OP_Distinct = 20, + OP_Join = 21, + OP_StateWindow = 22, }; typedef struct SOperatorInfo { @@ -314,7 +310,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; @@ -362,7 +359,7 @@ typedef struct SQueryParam { SColIndex *pGroupColIndex; SColumnInfo *pTagColumnInfo; - SSqlGroupbyExpr *pGroupbyExpr; + SGroupbyExpr *pGroupbyExpr; int32_t tableScanOperator; SArray *pOperator; } SQueryParam; @@ -465,6 +462,16 @@ typedef struct SSWindowOperatorInfo { int32_t start; // start row index } SSWindowOperatorInfo; +typedef struct SStateWindowOperatorInfo { + SOptrBasicInfo binfo; + STimeWindow curWindow; // current time window + int32_t numOfRows; // number of rows + int32_t colIndex; // start row index + int32_t start; + char* prevData; // previous data + +} SStateWindowOperatorInfo ; + typedef struct SDistinctOperatorInfo { SHashObj *pSet; SSDataBlock *pRes; @@ -473,10 +480,10 @@ typedef struct SDistinctOperatorInfo { int64_t outputCapacity; } SDistinctOperatorInfo; -struct SLocalMerger; +struct SGlobalMerger; typedef struct SMultiwayMergeInfo { - struct SLocalMerger *pMerge; + struct SGlobalMerger *pMerge; SOptrBasicInfo binfo; int32_t bufCapacity; int64_t seed; @@ -494,6 +501,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); @@ -512,14 +521,23 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows, void* merger, bool groupMix); +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); @@ -536,16 +554,19 @@ 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); +STableQueryInfo* createTmpTableQueryInfo(STimeWindow win); + int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, void *pQueryMsg); bool isQueryKilled(SQInfo *pQInfo); 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/qPlan.h b/src/query/inc/qPlan.h index 8f35565e4bccd4896ec49ddb30f7236ac4b4650c..60a50ca70c32b1aa3f10af4ed19231b77b50f677 100644 --- a/src/query/inc/qPlan.h +++ b/src/query/inc/qPlan.h @@ -16,7 +16,40 @@ #ifndef TDENGINE_QPLAN_H #define TDENGINE_QPLAN_H -//TODO refactor +#include "qExecutor.h" + +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 2bdff1f94fa702aa9c1da0b4da0a5b0804a43cdd..652191bf0fb402ab1114a2797176b0379dd5dba4 100644 --- a/src/query/inc/qSqlparser.h +++ b/src/query/inc/qSqlparser.h @@ -89,6 +89,10 @@ typedef struct SSessionWindowVal { SStrToken gap; } SSessionWindowVal; +typedef struct SWindowStateVal { + SStrToken col; +} SWindowStateVal; + struct SRelationInfo; typedef struct SSqlNode { @@ -100,6 +104,7 @@ typedef struct SSqlNode { SArray *fillType; // fill type[optional], SArray SIntervalVal interval; // (interval, interval_offset) [optional] SSessionWindowVal sessionVal; // session window [optional] + SWindowStateVal windowstateVal; // window_state(col) [optional] SStrToken sliding; // sliding window [optional] SLimitVal limit; // limit offset [optional] SLimitVal slimit; // group limit offset [optional] @@ -107,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 { @@ -138,7 +147,7 @@ typedef struct SCreateTableSql { } colInfo; SArray *childTableInfo; // SArray - SSqlNode *pSelect; + SSqlNode *pSelect; } SCreateTableSql; typedef struct SAlterTableInfo { @@ -254,8 +263,8 @@ 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); void *destroyRelationInfo(SRelationInfo* pFromInfo); +SRelationInfo *addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrToken* pAlias); // sql expr leaf node tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType); @@ -271,7 +280,7 @@ SArray *tSqlExprListAppend(SArray *pList, tSqlExpr *pNode, SStrToken *pDistinc void tSqlExprListDestroy(SArray *pList); SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere, - SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps, + SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps, SWindowStateVal *pw, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving); int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right); diff --git a/src/query/inc/qTableMeta.h b/src/query/inc/qTableMeta.h new file mode 100644 index 0000000000000000000000000000000000000000..4fc252b644efab0c6bfdb97b19c3af3ef9c68920 --- /dev/null +++ b/src/query/inc/qTableMeta.h @@ -0,0 +1,203 @@ +#ifndef TDENGINE_QTABLEUTIL_H +#define TDENGINE_QTABLEUTIL_H + +#include "tsdb.h" //todo tsdb should not be here +#include "qSqlparser.h" + +typedef struct SFieldInfo { + int16_t numOfOutput; // number of column in result + TAOS_FIELD* final; + SArray *internalField; // SArray +} SFieldInfo; + +typedef struct SCond { + uint64_t uid; + int32_t len; // length of tag query condition data + char * cond; +} SCond; + +typedef struct SJoinNode { + uint64_t uid; + int16_t tagColId; + SArray* tsJoin; + SArray* tagJoin; +} SJoinNode; + +typedef struct SJoinInfo { + bool hasJoin; + SJoinNode *joinTables[TSDB_MAX_JOIN_TABLE_NUM]; +} SJoinInfo; + +typedef struct STagCond { + // relation between tbname list and query condition, including : TK_AND or TK_OR + int16_t relType; + + // tbname query condition, only support tbname query condition on one table + SCond tbnameCond; + + // join condition, only support two tables join currently + SJoinInfo joinInfo; + + // for different table, the query condition must be seperated + SArray *pCond; +} STagCond; + +typedef struct SGroupbyExpr { + int16_t tableIndex; + SArray* columnInfo; // SArray, group by columns information + int16_t numOfGroupCols; // todo remove it + int16_t orderIndex; // order by column index + int16_t orderType; // order by type: asc/desc +} SGroupbyExpr; + +typedef struct STableComInfo { + uint8_t numOfTags; + uint8_t precision; + int16_t numOfColumns; + int32_t rowSize; +} STableComInfo; + +typedef struct STableMeta { + int32_t vgId; + STableId id; + uint8_t tableType; + char sTableName[TSDB_TABLE_FNAME_LEN]; // super table name + uint64_t suid; // super table id + int16_t sversion; + int16_t tversion; + STableComInfo tableInfo; + SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info +} STableMeta; + +typedef struct STableMetaInfo { + 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 + * 2. keep the vgroup index for multi-vnode insertion + */ + int32_t vgroupIndex; + SName name; + char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql + SArray *tagColList; // SArray, involved tag columns +} STableMetaInfo; + +struct SQInfo; // global merge operator +struct SQueryAttr; // query object + +typedef struct SQueryInfo { + int16_t command; // the command may be different for each subclause, so keep it seperately. + uint32_t type; // query/insert type + STimeWindow window; // the whole query time window + + SInterval interval; // tumble time window + SSessionWindow sessionWindow; // session time window + + 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; + + SOrderVal order; + int16_t fillType; // final result fill type + int16_t numOfTables; + STableMetaInfo **pTableMetaInfo; + struct STSBuf *tsBuf; + int64_t * fillVal; // default value for fill + char * msg; // pointer to the pCmd->payload to keep error message temporarily + int64_t clauseLimit; // limit for current sub clause + + int64_t prjOffset; // offset value in the original sql expression, only applied at client side + int64_t vgroupLimit; // table limit in case of super table projection query + global order + limit + + int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX + int16_t resColumnId; // result column id + bool distinctTag; // distinct tag or not + int32_t round; // 0/1/.... + int32_t bufLen; + char* buf; + struct SQInfo* pQInfo; // global merge operator + struct 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; + bool orderProjectQuery; + bool stateWindow; +} SQueryInfo; + +/** + * get the number of tags of this table + * @param pTableMeta + * @return + */ +int32_t tscGetNumOfTags(const STableMeta* pTableMeta); + +/** + * get the number of columns of this table + * @param pTableMeta + * @return + */ +int32_t tscGetNumOfColumns(const STableMeta* pTableMeta); + +/** + * get the basic info of this table + * @param pTableMeta + * @return + */ +STableComInfo tscGetTableInfo(const STableMeta* pTableMeta); + +/** + * get the schema + * @param pTableMeta + * @return + */ +SSchema* tscGetTableSchema(const STableMeta* pTableMeta); + +/** + * get the tag schema + * @param pMeta + * @return + */ +SSchema *tscGetTableTagSchema(const STableMeta *pMeta); + +/** + * get the column schema according to the column index + * @param pMeta + * @param colIndex + * @return + */ +SSchema *tscGetTableColumnSchema(const STableMeta *pMeta, int32_t colIndex); + +/** + * get the column schema according to the column id + * @param pTableMeta + * @param colId + * @return + */ +SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId); + +/** + * create the table meta from the msg + * @param pTableMetaMsg + * @param size size of the table meta + * @return + */ +STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg); + +#endif // TDENGINE_QTABLEUTIL_H 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 8ef8ef0e2b3080ce334686f7fdbb7105596356e5..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" @@ -456,8 +456,8 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). { //////////////////////// The SELECT statement ///////////////////////////////// %type select {SSqlNode*} %destructor select {destroySqlNode($$);} -select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). { - A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &S, F, &L, &G, N); +select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) windowstate_option(D) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). { + A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &D, &S, F, &L, &G, N); } select(A) ::= LP select(B) RP. {A = B;} @@ -475,7 +475,7 @@ cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); } // select client_version() // select server_state() select(A) ::= SELECT(T) selcollist(W). { - A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } // selcollist is a list of expressions that are to become the return @@ -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($$);} @@ -552,6 +558,11 @@ session_option(X) ::= SESSION LP ids(V) cpxName(Z) COMMA tmvar(Y) RP. { X.col = V; X.gap = Y; } +%type windowstate_option {SWindowStateVal} +windowstate_option(X) ::= . {X.col.n = 0;} +windowstate_option(X) ::= STATE_WINDOW LP ids(V) RP. { + X.col = V; +} %type fill_opt {SArray*} %destructor fill_opt {taosArrayDestroy($$);} diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 7b656d473afd0374ee48c6992a285a8fddec5b68..be0716ce9956cf4e8bc19935ce49c92958d7e84c 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -19,6 +19,7 @@ #include "texpr.h" #include "ttype.h" #include "tsdb.h" +#include "tglobal.h" #include "qAggMain.h" #include "qFill.h" @@ -166,7 +167,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 +354,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; @@ -2489,7 +2490,6 @@ static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) { tmp += POINTER_BYTES * pCtx->param[0].i64; size_t size = sizeof(tValuePair) + pCtx->tagInfo.tagsLen; -// assert(pCtx->param[0].i64 > 0); for (int32_t i = 0; i < pCtx->param[0].i64; ++i) { pTopBotInfo->res[i] = (tValuePair*) tmp; @@ -2498,7 +2498,6 @@ static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) { } } - bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const char *maxval) { SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); if (pResInfo == NULL) { @@ -2578,13 +2577,14 @@ static void top_function(SQLFunctionCtx *pCtx) { for (int32_t i = 0; i < pCtx->size; ++i) { char *data = GET_INPUT_DATA(pCtx, i); - TSKEY ts = GET_TS_DATA(pCtx, i); - if (pCtx->hasNull && isNull(data, pCtx->inputType)) { continue; } notNullElems++; + + // NOTE: Set the default timestamp if it is missing [todo refactor] + TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0; do_top_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0); } @@ -2657,13 +2657,13 @@ static void bottom_function(SQLFunctionCtx *pCtx) { for (int32_t i = 0; i < pCtx->size; ++i) { char *data = GET_INPUT_DATA(pCtx, i); - TSKEY ts = GET_TS_DATA(pCtx, i); - if (pCtx->hasNull && isNull(data, pCtx->inputType)) { continue; } - + notNullElems++; + // NOTE: Set the default timestamp if it is missing [todo refactor] + TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0; do_bottom_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0); } @@ -2741,7 +2741,7 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) { if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_INDEX) { __compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn; qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); - } else if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_INDEX) { + } else /*if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_INDEX)*/ { __compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn; qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); } @@ -3298,8 +3298,12 @@ static void col_project_function(SQLFunctionCtx *pCtx) { if (pCtx->numOfParams == 2) { return; } + if (pCtx->param[0].i64 == 1) { + SET_VAL(pCtx, pCtx->size, 1); + } else { + INC_INIT_VAL(pCtx, pCtx->size); + } - INC_INIT_VAL(pCtx, pCtx->size); char *pData = GET_INPUT_DATA_LIST(pCtx); if (pCtx->order == TSDB_ORDER_ASC) { @@ -3700,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; } @@ -4828,51 +4832,81 @@ void blockInfo_func(SQLFunctionCtx* pCtx) { pResInfo->hasResult = DATA_SET_FLAG; } -static void mergeTableBlockDist(STableBlockDist* pDist, const STableBlockDist* pSrc) { +static void mergeTableBlockDist(SResultRowCellInfo* pResInfo, const STableBlockDist* pSrc) { + STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo); assert(pDist != NULL && pSrc != NULL); + pDist->numOfTables += pSrc->numOfTables; pDist->numOfRowsInMemTable += pSrc->numOfRowsInMemTable; pDist->numOfFiles += pSrc->numOfFiles; pDist->totalSize += pSrc->totalSize; + pDist->totalRows += pSrc->totalRows; - if (pDist->dataBlockInfos == NULL) { - pDist->dataBlockInfos = taosArrayInit(4, sizeof(SFileBlockInfo)); + if (pResInfo->hasResult == DATA_SET_FLAG) { + pDist->maxRows = MAX(pDist->maxRows, pSrc->maxRows); + pDist->minRows = MIN(pDist->minRows, pSrc->minRows); + } else { + pDist->maxRows = pSrc->maxRows; + pDist->minRows = pSrc->minRows; + + int32_t numSteps = tsMaxRowsInFileBlock/TSDB_BLOCK_DIST_STEP_ROWS; + pDist->dataBlockInfos = taosArrayInit(numSteps, sizeof(SFileBlockInfo)); + taosArraySetSize(pDist->dataBlockInfos, numSteps); } - taosArrayPushBatch(pDist->dataBlockInfos, pSrc->dataBlockInfos->pData, (int32_t) taosArrayGetSize(pSrc->dataBlockInfos)); + size_t steps = taosArrayGetSize(pDist->dataBlockInfos); + for (int32_t i = 0; i < steps; ++i) { + int32_t srcNumBlocks = ((SFileBlockInfo*)taosArrayGet(pSrc->dataBlockInfos, i))->numBlocksOfStep; + SFileBlockInfo* blockInfo = (SFileBlockInfo*)taosArrayGet(pDist->dataBlockInfos, i); + blockInfo->numBlocksOfStep += srcNumBlocks; + } } void block_func_merge(SQLFunctionCtx* pCtx) { - SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); - - STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo); STableBlockDist info = {0}; - int32_t len = *(int32_t*) pCtx->pInput; blockDistInfoFromBinary(((char*)pCtx->pInput) + sizeof(int32_t), len, &info); - mergeTableBlockDist(pDist, &info); + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + mergeTableBlockDist(pResInfo, &info); + + pResInfo->numOfRes = 1; + pResInfo->hasResult = DATA_SET_FLAG; } -static int32_t doGetPercentile(const SArray* pArray, double rate) { - int32_t len = (int32_t)taosArrayGetSize(pArray); - if (len <= 0) { - return 0; +void getPercentiles(STableBlockDist *pTableBlockDist, int64_t totalBlocks, int32_t numOfPercents, + double* percents, int32_t* percentiles) { + if (totalBlocks == 0) { + for (int32_t i = 0; i < numOfPercents; ++i) { + percentiles[i] = 0; + } + return; } - assert(rate >= 0 && rate <= 1.0); - int idx = (int32_t)((len - 1) * rate); + SArray *blocksInfos = pTableBlockDist->dataBlockInfos; + size_t numSteps = taosArrayGetSize(blocksInfos); + size_t cumulativeBlocks = 0; - return ((SFileBlockInfo *)(taosArrayGet(pArray, idx)))->numOfRows; -} + int percentIndex = 0; + for (int32_t indexStep = 0; indexStep < numSteps; ++indexStep) { + int32_t numStepBlocks = ((SFileBlockInfo *)taosArrayGet(blocksInfos, indexStep))->numBlocksOfStep; + if (numStepBlocks == 0) continue; + cumulativeBlocks += numStepBlocks; -static int compareBlockInfo(const void *pLeft, const void *pRight) { - int32_t left = ((SFileBlockInfo *)pLeft)->numOfRows; - int32_t right = ((SFileBlockInfo *)pRight)->numOfRows; + while (percentIndex < numOfPercents) { + double blockRank = totalBlocks * percents[percentIndex]; + if (blockRank <= cumulativeBlocks) { + percentiles[percentIndex] = indexStep; + ++percentIndex; + } else { + break; + } + } + } - if (left > right) return 1; - if (left < right) return -1; - return 0; + for (int32_t i = 0; i < numOfPercents; ++i) { + percentiles[i] = (percentiles[i]+1) * TSDB_BLOCK_DIST_STEP_ROWS - TSDB_BLOCK_DIST_STEP_ROWS/2; + } } void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) { @@ -4880,40 +4914,41 @@ void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) { return; } - int64_t min = INT64_MAX, max = INT64_MIN, avg = 0; - SArray* blockInfos= pTableBlockDist->dataBlockInfos; - int64_t totalRows = 0, totalBlocks = taosArrayGetSize(blockInfos); + SArray* blockInfos = pTableBlockDist->dataBlockInfos; + uint64_t totalRows = pTableBlockDist->totalRows; + size_t numSteps = taosArrayGetSize(blockInfos); + int64_t totalBlocks = 0; + int64_t min = -1, max = -1, avg = 0; - for (size_t i = 0; i < taosArrayGetSize(blockInfos); i++) { + for (int32_t i = 0; i < numSteps; i++) { SFileBlockInfo *blockInfo = taosArrayGet(blockInfos, i); - int64_t rows = blockInfo->numOfRows; - - min = MIN(min, rows); - max = MAX(max, rows); - totalRows += rows; + int64_t blocks = blockInfo->numBlocksOfStep; + totalBlocks += blocks; } avg = totalBlocks > 0 ? (int64_t)(totalRows/totalBlocks) : 0; - taosArraySort(blockInfos, compareBlockInfo); + min = totalBlocks > 0 ? pTableBlockDist->minRows : 0; + max = totalBlocks > 0 ? pTableBlockDist->maxRows : 0; + + double percents[] = {0.05, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 0.95, 0.99}; + int32_t percentiles[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + assert(sizeof(percents)/sizeof(double) == sizeof(percentiles)/sizeof(int32_t)); + getPercentiles(pTableBlockDist, totalBlocks, sizeof(percents)/sizeof(double), percents, percentiles); uint64_t totalLen = pTableBlockDist->totalSize; int32_t rowSize = pTableBlockDist->rowSize; - + double compRatio = (totalRows>0) ? ((double)(totalLen)/(rowSize*totalRows)) : 1; int sz = sprintf(result + VARSTR_HEADER_SIZE, "summary: \n\t " "5th=[%d], 10th=[%d], 20th=[%d], 30th=[%d], 40th=[%d], 50th=[%d]\n\t " "60th=[%d], 70th=[%d], 80th=[%d], 90th=[%d], 95th=[%d], 99th=[%d]\n\t " "Min=[%"PRId64"(Rows)] Max=[%"PRId64"(Rows)] Avg=[%"PRId64"(Rows)] Stddev=[%.2f] \n\t " - "Rows=[%"PRId64"], Blocks=[%"PRId64"], Size=[%.3f(Kb)] Comp=[%.2f%%]\n\t " + "Rows=[%"PRIu64"], Blocks=[%"PRId64"], Size=[%.3f(Kb)] Comp=[%.2f]\n\t " "RowsInMem=[%d] \n\t SeekHeaderTime=[%d(us)]", - doGetPercentile(blockInfos, 0.05), doGetPercentile(blockInfos, 0.10), - doGetPercentile(blockInfos, 0.20), doGetPercentile(blockInfos, 0.30), - doGetPercentile(blockInfos, 0.40), doGetPercentile(blockInfos, 0.50), - doGetPercentile(blockInfos, 0.60), doGetPercentile(blockInfos, 0.70), - doGetPercentile(blockInfos, 0.80), doGetPercentile(blockInfos, 0.90), - doGetPercentile(blockInfos, 0.95), doGetPercentile(blockInfos, 0.99), + percentiles[0], percentiles[1], percentiles[2], percentiles[3], percentiles[4], percentiles[5], + percentiles[6], percentiles[7], percentiles[8], percentiles[9], percentiles[10], percentiles[11], min, max, avg, 0.0, - totalRows, totalBlocks, totalLen/1024.0, (double)(totalLen*100.0)/(rowSize*totalRows), + totalRows, totalBlocks, totalLen/1024.0, compRatio, pTableBlockDist->numOfRowsInMemTable, pTableBlockDist->firstSeekTimeUs); varDataSetLen(result, sz); UNUSED(sz); diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 40759c93c4f62721c2ba81d5c5eaed40492de328..25e7e446bd1f1114bae12fd05678474d40a32a5e 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} @@ -169,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); @@ -176,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); @@ -187,12 +189,16 @@ static void destroySFillOperatorInfo(void* param, int32_t numOfOutput); static void destroyGroupbyOperatorInfo(void* param, int32_t numOfOutput); static void destroyArithOperatorInfo(void* param, int32_t numOfOutput); static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput); +static void destroySWindowOperatorInfo(void* param, int32_t numOfOutput); +static void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput); +static void destroyAggOperatorInfo(void* param, int32_t numOfOutput); 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, SGroupbyOperatorInfo *pInfo, 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); @@ -729,7 +735,6 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx if (pCtx[k].preAggVals.isSet && forwardStep < numOfTotal) { pCtx[k].preAggVals.isSet = false; } - if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) { aAggs[functionId].xFunction(&pCtx[k]); } @@ -933,7 +938,7 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, setArithParams((SArithmeticSupport*)pCtx[i].param[1].pz, &pOperator->pExpr[i], pBlock); } else { SColIndex* pCol = &pOperator->pExpr[i].base.colInfo; - if (TSDB_COL_IS_NORMAL_COL(pCol->flag) || (pCol->colId == TSDB_BLOCK_DIST_COLUMN_INDEX) || + if (TSDB_COL_IS_NORMAL_COL(pCol->flag) || (pCtx[i].functionId == TSDB_FUNC_BLKINFO) || (TSDB_COL_IS_TAG(pCol->flag) && pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)) { SColIndex* pColIndex = &pOperator->pExpr[i].base.colInfo; SColumnInfoData* p = taosArrayGet(pBlock->pDataBlock, pColIndex->colIndex); @@ -945,7 +950,13 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, uint32_t status = aAggs[pCtx[i].functionId].status; if ((status & (TSDB_FUNCSTATE_SELECTIVITY | TSDB_FUNCSTATE_NEED_TS)) != 0) { SColumnInfoData* tsInfo = taosArrayGet(pBlock->pDataBlock, 0); - pCtx[i].ptsList = (int64_t*) tsInfo->pData; + // In case of the top/bottom query again the nest query result, which has no timestamp column + // don't set the ptsList attribute. + if (tsInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP) { + pCtx[i].ptsList = (int64_t*) tsInfo->pData; + } else { + pCtx[i].ptsList = NULL; + } } } else if (TSDB_COL_IS_UD_COL(pCol->flag) && (pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)) { SColIndex* pColIndex = &pOperator->pExpr[i].base.colInfo; @@ -1297,7 +1308,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn } int32_t ret = - setGroupResultOutputBuf(pRuntimeEnv, pInfo, pOperator->numOfOutput, val, type, bytes, item->groupIndex); + setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, val, type, bytes, item->groupIndex); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); } @@ -1336,12 +1347,16 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInf pInfo->start = j; } else if (tsList[j] - pInfo->prevTs <= gap) { pInfo->curWindow.ekey = tsList[j]; - pInfo->prevTs = tsList[j]; + //pInfo->prevTs = tsList[j]; pInfo->numOfRows += 1; - pInfo->start = j; + if (j == 0 && pInfo->start != 0) { + pInfo->numOfRows = 1; + pInfo->start = 0; + } } else { // start a new session window SResultRow* pResult = NULL; + pInfo->curWindow.ekey = pInfo->curWindow.skey; int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan, &pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput, pBInfo->rowCellInfoOffset); @@ -1362,6 +1377,7 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInf SResultRow* pResult = NULL; + pInfo->curWindow.ekey = pInfo->curWindow.skey; int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan, &pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput, pBInfo->rowCellInfoOffset); @@ -1389,12 +1405,12 @@ static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) { } } -static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOperatorInfo *pInfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex) { +static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *binfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex) { SDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf; - int32_t *rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset; - SResultRowInfo *pResultRowInfo = &pInfo->binfo.resultRowInfo; - SQLFunctionCtx *pCtx = pInfo->binfo.pCtx; + int32_t *rowCellInfoOffset = binfo->rowCellInfoOffset; + SResultRowInfo *pResultRowInfo = &binfo->resultRowInfo; + SQLFunctionCtx *pCtx = binfo->pCtx; // not assign result buffer yet, add new result buffer, TODO remove it char* d = pData; @@ -1420,7 +1436,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOp 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)) { @@ -1710,38 +1726,43 @@ 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); + int32_t opType = pRuntimeEnv->proot->upstream[0]->operatorType; + if (opType != OP_DummyInput && opType != OP_Join) { + 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; } @@ -1750,7 +1771,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 { @@ -1760,6 +1781,11 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf } break; } + case OP_StateWindow: { + pRuntimeEnv->proot = createStatewindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot); + break; + } case OP_Limit: { pRuntimeEnv->proot = createLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot); @@ -1767,12 +1793,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; } @@ -1979,6 +2018,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 @@ -2058,6 +2128,8 @@ static bool onlyFirstQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQu static bool onlyLastQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, TSDB_FUNC_LAST, TSDB_FUNC_LAST_DST); } +static bool notContainSessionOrStateWindow(SQueryAttr *pQueryAttr) { return !(pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow); } + static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { bool hasFirstLastFunc = false; bool hasOtherFunc = false; @@ -2084,7 +2156,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; } } @@ -2161,7 +2233,7 @@ static void changeExecuteScanOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bo } pQueryAttr->order.order = TSDB_ORDER_ASC; - } else if (onlyLastQuery(pQueryAttr)) { + } else if (onlyLastQuery(pQueryAttr) && notContainSessionOrStateWindow(pQueryAttr)) { if (QUERY_IS_ASC_QUERY(pQueryAttr)) { qDebug(msg, pQInfo, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); @@ -2359,6 +2431,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; @@ -2391,97 +2562,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); @@ -2509,7 +2594,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; } @@ -3140,7 +3225,7 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfOutput = pOperator->numOfOutput; - if (pQueryAttr->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQueryAttr) || pQueryAttr->sw.gap > 0) { + if (pQueryAttr->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQueryAttr) || pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow) { // for each group result, call the finalize function for each column if (pQueryAttr->groupbyColumn) { closeAllResultRows(pResultRowInfo); @@ -3206,6 +3291,25 @@ STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool return pTableQueryInfo; } +STableQueryInfo* createTmpTableQueryInfo(STimeWindow win) { + STableQueryInfo* pTableQueryInfo = calloc(1, sizeof(STableQueryInfo)); + + pTableQueryInfo->win = win; + pTableQueryInfo->lastKey = win.skey; + + pTableQueryInfo->pTable = NULL; + pTableQueryInfo->cur.vgroupIndex = -1; + + // set more initial size of interval/groupby query + int32_t initialSize = 16; + int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize, TSDB_DATA_TYPE_INT); + if (code != TSDB_CODE_SUCCESS) { + return NULL; + } + + return pTableQueryInfo; +} + void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo) { if (pTableQueryInfo == NULL) { return; @@ -3710,7 +3814,7 @@ void queryCostStatis(SQInfo *pQInfo) { // // int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock); // -// qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%"PRId64, GET_QID(pRuntimeEnv), +// qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numBlocksOfStep:%d, numOfRes:%d, lastKey:%"PRId64, GET_QID(pRuntimeEnv), // pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, pQuery->current->lastKey); //} @@ -3914,6 +4018,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) { @@ -3963,6 +4076,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 { @@ -4119,6 +4234,10 @@ static void updateTableIdInfo(STableQueryInfo* pTableQueryInfo, SSDataBlock* pBl int32_t step = GET_FORWARD_DIRECTION_FACTOR(order); pTableQueryInfo->lastKey = ((order == TSDB_ORDER_ASC)? pBlock->info.window.ekey:pBlock->info.window.skey) + step; + if (pTableQueryInfo->pTable == NULL) { + return; + } + STableIdInfo tidInfo = createTableIdInfo(pTableQueryInfo); STableIdInfo *idinfo = taosHashGet(pTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid)); if (idinfo != NULL) { @@ -4143,12 +4262,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; @@ -4208,7 +4327,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; @@ -4275,7 +4394,12 @@ static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) { STableBlockDist tableBlockDist = {0}; tableBlockDist.numOfTables = (int32_t)pOperator->pRuntimeEnv->tableqinfoGroupInfo.numOfTables; - tableBlockDist.dataBlockInfos = taosArrayInit(512, sizeof(SFileBlockInfo)); + + int32_t numRowSteps = tsMaxRowsInFileBlock / TSDB_BLOCK_DIST_STEP_ROWS; + tableBlockDist.dataBlockInfos = taosArrayInit(numRowSteps, sizeof(SFileBlockInfo)); + taosArraySetSize(tableBlockDist.dataBlockInfos, numRowSteps); + tableBlockDist.maxRows = INT_MIN; + tableBlockDist.minRows = INT_MAX; tsdbGetFileBlocksDistInfo(pTableScanInfo->pQueryHandle, &tableBlockDist); tableBlockDist.numOfRowsInMemTable = (int32_t) tsdbGetNumOfRowsInMemTable(pTableScanInfo->pQueryHandle); @@ -4357,7 +4481,7 @@ SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRu SColumnInfoData infoData = {{0}}; infoData.info.type = TSDB_DATA_TYPE_BINARY; infoData.info.bytes = 1024; - infoData.info.colId = TSDB_BLOCK_DIST_COLUMN_INDEX; + infoData.info.colId = 0; taosArrayPush(pInfo->block.pDataBlock, &infoData); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); @@ -4415,6 +4539,12 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf } else if (pDownstream->operatorType == OP_SessionWindow) { SSWindowOperatorInfo* pInfo = pDownstream->info; + pTableScanInfo->pCtx = pInfo->binfo.pCtx; + pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo; + pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset; + } else if (pDownstream->operatorType == OP_StateWindow) { + SStateWindowOperatorInfo* pInfo = pDownstream->info; + pTableScanInfo->pCtx = pInfo->binfo.pCtx; pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo; pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset; @@ -4526,7 +4656,6 @@ static void destroyGlobalAggOperatorInfo(void* param, int32_t numOfOutput) { tfree(pInfo->prevRow); tfree(pInfo->currentGroupColData); } - static void destroySlimitOperatorInfo(void* param, int32_t numOfOutput) { SSLimitOperatorInfo *pInfo = (SSLimitOperatorInfo*) param; taosArrayDestroy(pInfo->orderColumnList); @@ -4591,13 +4720,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; } @@ -4662,7 +4792,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); @@ -4717,7 +4847,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); @@ -4785,8 +4915,7 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) { updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows); arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); - - if (pTableQueryInfo != NULL) { // TODO refactor + if (pTableQueryInfo != NULL) { updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order); } @@ -4801,7 +4930,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); @@ -4829,13 +4958,12 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) { updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows); arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); - - if (pTableQueryInfo != NULL) { // TODO refactor + if (pTableQueryInfo != NULL) { updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order); } 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; } } @@ -4855,7 +4983,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; @@ -4895,27 +5023,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) { @@ -4926,7 +5033,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; } @@ -4968,7 +5075,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); @@ -5021,7 +5128,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); @@ -5052,6 +5159,130 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) { return pIntervalInfo->pRes; } + +static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { + SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + STableQueryInfo* item = pRuntimeEnv->current; + SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, pInfo->colIndex); + + SOptrBasicInfo* pBInfo = &pInfo->binfo; + + bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); + int16_t bytes = pColInfoData->info.bytes; + int16_t type = pColInfoData->info.type; + + SColumnInfoData* pTsColInfoData = taosArrayGet(pSDataBlock->pDataBlock, 0); + TSKEY* tsList = (TSKEY*)pTsColInfoData->pData; + + pInfo->numOfRows = 0; + for (int32_t j = 0; j < pSDataBlock->info.rows; ++j) { + char* val = ((char*)pColInfoData->pData) + bytes * j; + if (isNull(val, type)) { + continue; + } + if (pInfo->prevData == NULL) { + pInfo->prevData = malloc(bytes); + memcpy(pInfo->prevData, val, bytes); + pInfo->numOfRows = 1; + pInfo->curWindow.skey = tsList[j]; + pInfo->curWindow.ekey = tsList[j]; + pInfo->start = j; + + } else if (memcmp(pInfo->prevData, val, bytes) == 0) { + pInfo->curWindow.ekey = tsList[j]; + pInfo->numOfRows += 1; + //pInfo->start = j; + if (j == 0 && pInfo->start != 0) { + pInfo->numOfRows = 1; + pInfo->start = 0; + } + } else { + SResultRow* pResult = NULL; + pInfo->curWindow.ekey = pInfo->curWindow.skey; + int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan, + &pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput, + pBInfo->rowCellInfoOffset); + if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code + longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); + } + doApplyFunctions(pRuntimeEnv, pBInfo->pCtx, &pInfo->curWindow, pInfo->start, pInfo->numOfRows, tsList, + pSDataBlock->info.rows, pOperator->numOfOutput); + + pInfo->curWindow.skey = tsList[j]; + pInfo->curWindow.ekey = tsList[j]; + memcpy(pInfo->prevData, val, bytes); + pInfo->numOfRows = 1; + pInfo->start = j; + + } + } + SResultRow* pResult = NULL; + + pInfo->curWindow.ekey = pInfo->curWindow.skey; + int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan, + &pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput, + pBInfo->rowCellInfoOffset); + if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code + longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR); + } + + doApplyFunctions(pRuntimeEnv, pBInfo->pCtx, &pInfo->curWindow, pInfo->start, pInfo->numOfRows, tsList, + pSDataBlock->info.rows, pOperator->numOfOutput); +} +static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*) param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SStateWindowOperatorInfo* pWindowInfo = pOperator->info; + SOptrBasicInfo* pBInfo = &pWindowInfo->binfo; + + SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + if (pOperator->status == OP_RES_TO_RETURN) { + toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes); + + if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) { + pOperator->status = OP_EXEC_DONE; + } + + return pBInfo->pRes; + } + + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; + STimeWindow win = pQueryAttr->window; + SOperatorInfo* upstream = pOperator->upstream[0]; + while (1) { + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); + if (pBlock == NULL) { + break; + } + setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, pQueryAttr->order.order); + if (pWindowInfo->colIndex == -1) { + pWindowInfo->colIndex = getGroupbyColumnIndex(pRuntimeEnv->pQueryAttr->pGroupbyExpr, pBlock); + } + doStateWindowAggImpl(pOperator, pWindowInfo, pBlock); + } + + // restore the value + pQueryAttr->order.order = order; + pQueryAttr->window = win; + + pOperator->status = OP_RES_TO_RETURN; + closeAllResultRows(&pBInfo->resultRowInfo); + setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + finalizeQueryResult(pOperator, pBInfo->pCtx, &pBInfo->resultRowInfo, pBInfo->rowCellInfoOffset); + + initGroupResInfo(&pRuntimeEnv->groupResInfo, &pBInfo->resultRowInfo); + toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes); + + if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) { + pOperator->status = OP_EXEC_DONE; + } + + return pBInfo->pRes->info.rows == 0? NULL:pBInfo->pRes; +} static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { @@ -5061,6 +5292,7 @@ static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { SSWindowOperatorInfo* pWindowInfo = pOperator->info; SOptrBasicInfo* pBInfo = &pWindowInfo->binfo; + SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; if (pOperator->status == OP_RES_TO_RETURN) { toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes); @@ -5073,10 +5305,11 @@ static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { } SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + //pQueryAttr->order.order = TSDB_ORDER_ASC; 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); @@ -5127,7 +5360,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); @@ -5196,7 +5429,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); } @@ -5272,7 +5505,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); } @@ -5297,13 +5538,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 = destroyBasicOperatorInfo; + pOperator->cleanup = destroyAggOperatorInfo; + appendUpstream(pOperator, upstream); + return pOperator; } @@ -5321,6 +5563,19 @@ static void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) { SOptrBasicInfo* pInfo = (SOptrBasicInfo*) param; doDestroyBasicInfo(pInfo, numOfOutput); } +static void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput) { + SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*) param; + doDestroyBasicInfo(&pInfo->binfo, numOfOutput); + tfree(pInfo->prevData); +} +static void destroyAggOperatorInfo(void* param, int32_t numOfOutput) { + SAggOperatorInfo* pInfo = (SAggOperatorInfo*) param; + doDestroyBasicInfo(&pInfo->binfo, numOfOutput); +} +static void destroySWindowOperatorInfo(void* param, int32_t numOfOutput) { + SSWindowOperatorInfo* pInfo = (SSWindowOperatorInfo*) param; + doDestroyBasicInfo(&pInfo->binfo, numOfOutput); +} static void destroySFillOperatorInfo(void* param, int32_t numOfOutput) { SFillOperatorInfo* pInfo = (SFillOperatorInfo*) param; @@ -5370,13 +5625,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 = destroyBasicOperatorInfo; + pOperator->cleanup = destroyAggOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5400,63 +5655,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; } @@ -5471,10 +5725,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; } @@ -5492,7 +5746,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; @@ -5500,9 +5753,32 @@ 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) { + SStateWindowOperatorInfo* pInfo = calloc(1, sizeof(SStateWindowOperatorInfo)); + pInfo->colIndex = -1; + pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); + pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); + initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + pOperator->name = "StateWindowOperator"; + pOperator->operatorType = OP_StateWindow; + pOperator->blockingOptr = true; + pOperator->status = OP_IN_EXECUTING; + pOperator->pExpr = pExpr; + pOperator->numOfOutput = numOfOutput; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->exec = doStateWindowAgg; + pOperator->cleanup = destroyStateWindowOperatorInfo; + appendUpstream(pOperator, upstream); + return pOperator; + +} SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo)); @@ -5517,14 +5793,14 @@ 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; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doSessionWindowAgg; - pOperator->cleanup = destroyBasicOperatorInfo; + pOperator->cleanup = destroySWindowOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5540,7 +5816,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; @@ -5549,6 +5824,7 @@ SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRunti pOperator->exec = doSTableIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5565,7 +5841,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; @@ -5573,6 +5848,7 @@ SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato pOperator->exec = hashGroupbyAggregate; pOperator->cleanup = destroyGroupbyOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5602,8 +5878,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; @@ -5612,6 +5886,7 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn pOperator->exec = doFill; pOperator->cleanup = destroySFillOperatorInfo; + appendUpstream(pOperator, upstream); return pOperator; } @@ -5650,11 +5925,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; } @@ -5821,7 +6097,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; @@ -5882,12 +6158,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; } @@ -5897,10 +6174,7 @@ static int32_t getColumnIndexInSource(SQueriedTableInfo *pTableInfo, SSqlExpr *p if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { if (pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { return TSDB_TBNAME_COLUMN_INDEX; - } else if (pExpr->colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { - return TSDB_BLOCK_DIST_COLUMN_INDEX; } - while(j < pTableInfo->numOfTags) { if (pExpr->colInfo.colId == pTagCols[j].colId) { @@ -6434,7 +6708,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; @@ -6470,14 +6744,14 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp type = TSDB_DATA_TYPE_DOUBLE; bytes = tDataTypes[type].bytes; + } else if (pExprs[i].base.functionId == TSDB_FUNC_BLKINFO) { + SSchema s = {.type=TSDB_DATA_TYPE_BINARY, .bytes=TSDB_MAX_BINARY_LEN}; + type = s.type; + bytes = s.bytes; } else if (pExprs[i].base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX && pExprs[i].base.functionId == TSDB_FUNC_TAGPRJ) { // parse the normal column SSchema* s = tGetTbnameColumnSchema(); type = s->type; bytes = s->bytes; - } else if (pExprs[i].base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { - SSchema s = tGetBlockDistColumnSchema(); - type = s.type; - bytes = s.bytes; } else if (pExprs[i].base.colInfo.colId <= TSDB_UD_COLUMN_INDEX && pExprs[i].base.colInfo.colId > TSDB_RES_COL_ID) { // it is a user-defined constant value column assert(pExprs[i].base.functionId == TSDB_FUNC_PRJ); @@ -6490,7 +6764,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp } else { int32_t j = getColumnIndexInSource(pTableInfo, &pExprs[i].base, pTagCols); if (TSDB_COL_IS_TAG(pExprs[i].base.colInfo.flag)) { - if (j < TSDB_BLOCK_DIST_COLUMN_INDEX || j >= pTableInfo->numOfTags) { + if (j < TSDB_TBNAME_COLUMN_INDEX || j >= pTableInfo->numOfTags) { return TSDB_CODE_QRY_INVALID_MSG; } } else { @@ -6605,13 +6879,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; @@ -6629,8 +6903,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; @@ -6687,7 +6960,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++; @@ -6727,9 +7000,6 @@ static void doUpdateExprColumnIndex(SQueryAttr *pQueryAttr) { assert(f < pQueryAttr->numOfCols); } else if (pColIndex->colId <= TSDB_UD_COLUMN_INDEX) { // do nothing for user-defined constant value result columns - } else if (pColIndex->colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { - pColIndex->colIndex = 0;// only one source column, so it must be 0; - assert(pQueryAttr->numOfOutput == 1); } else { int32_t f = 0; for (f = 0; f < pQueryAttr->numOfTags; ++f) { @@ -6739,7 +7009,7 @@ static void doUpdateExprColumnIndex(SQueryAttr *pQueryAttr) { } } - assert(f < pQueryAttr->numOfTags || pColIndex->colId == TSDB_TBNAME_COLUMN_INDEX || pColIndex->colId == TSDB_BLOCK_DIST_COLUMN_INDEX); + assert(f < pQueryAttr->numOfTags || pColIndex->colId == TSDB_TBNAME_COLUMN_INDEX); } } } @@ -6772,7 +7042,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; @@ -6820,6 +7090,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr pQueryAttr->simpleAgg = pQueryMsg->simpleAgg; pQueryAttr->pointInterpQuery = pQueryMsg->pointInterpQuery; pQueryAttr->needReverseScan = pQueryMsg->needReverseScan; + pQueryAttr->stateWindow = pQueryMsg->stateWindow; pQueryAttr->vgId = vgId; pQueryAttr->tableCols = calloc(numOfCols, sizeof(SSingleColumnFilterInfo)); @@ -6931,7 +7202,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr colIdCheck(pQueryAttr, pQInfo->qId); // todo refactor - pQInfo->query.queryBlockDist = (numOfOutput == 1 && pExprs[0].base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX); + pQInfo->query.queryBlockDist = (numOfOutput == 1 && pExprs[0].base.functionId == TSDB_FUNC_BLKINFO); qDebug("qmsg:%p QInfo:0x%" PRIx64 "-%p created", pQueryMsg, pQInfo->qId, pQInfo); return pQInfo; @@ -7075,7 +7346,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; @@ -7099,6 +7370,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; @@ -7283,13 +7568,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/qPlan.c b/src/query/src/qPlan.c index 0554a887ec68ca3353b5e45c1067ea734ea98cfd..24531c7f4e6e9486cb2ad388ec50fa422606de52 100644 --- a/src/query/src/qPlan.c +++ b/src/query/src/qPlan.c @@ -1,44 +1,523 @@ #include "os.h" -#include "tsclient.h" +#include "qTableMeta.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; } @@ -113,6 +592,14 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) { op = OP_SessionWindow; taosArrayPush(plan, &op); + if (pQueryAttr->pExpr2 != NULL) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + } else if (pQueryAttr->stateWindow) { + op = OP_StateWindow; + taosArrayPush(plan, &op); + if (pQueryAttr->pExpr2 != NULL) { op = OP_Arithmetic; taosArrayPush(plan, &op); @@ -136,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 2459439b7b167a3624646168034c6152e2062d47..efe35ba72b51a4bbc7c2b838eced738de3eedd6f 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -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; @@ -725,7 +727,7 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) { */ SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere, SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, - SSessionWindowVal *pSession, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, + SSessionWindowVal *pSession, SWindowStateVal *pWindowStateVal, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *psLimit, tSqlExpr *pHaving) { assert(pSelNodeList != NULL); @@ -777,6 +779,12 @@ SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelat TPARSER_SET_NONE_TOKEN(pSqlNode->sessionVal.col); } + if (pWindowStateVal != NULL) { + pSqlNode->windowstateVal = *pWindowStateVal; + } else { + TPARSER_SET_NONE_TOKEN(pSqlNode->windowstateVal.col); + } + return pSqlNode; } diff --git a/src/client/src/tscSchemaUtil.c b/src/query/src/qTableMeta.c similarity index 57% rename from src/client/src/tscSchemaUtil.c rename to src/query/src/qTableMeta.c index 114fc8ee7383787a0448b237e4ef1f8dc8be31e0..d25d6b7004b1dcf52fca97e3d27465e92f8de4f2 100644 --- a/src/client/src/tscSchemaUtil.c +++ b/src/query/src/qTableMeta.c @@ -1,47 +1,32 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ #include "os.h" #include "taosmsg.h" -#include "tschemautil.h" +#include "qTableMeta.h" #include "ttokendef.h" #include "taosdef.h" #include "tutil.h" -#include "tsclient.h" int32_t tscGetNumOfTags(const STableMeta* pTableMeta) { assert(pTableMeta != NULL); - + STableComInfo tinfo = tscGetTableInfo(pTableMeta); - + if (pTableMeta->tableType == TSDB_NORMAL_TABLE) { assert(tinfo.numOfTags == 0); return 0; } - + if (pTableMeta->tableType == TSDB_SUPER_TABLE || pTableMeta->tableType == TSDB_CHILD_TABLE) { return tinfo.numOfTags; } - + assert(tinfo.numOfTags == 0); return 0; } int32_t tscGetNumOfColumns(const STableMeta* pTableMeta) { assert(pTableMeta != NULL); - + // table created according to super table, use data from super table STableComInfo tinfo = tscGetTableInfo(pTableMeta); return tinfo.numOfColumns; @@ -54,10 +39,10 @@ SSchema *tscGetTableSchema(const STableMeta *pTableMeta) { SSchema* tscGetTableTagSchema(const STableMeta* pTableMeta) { assert(pTableMeta != NULL && (pTableMeta->tableType == TSDB_SUPER_TABLE || pTableMeta->tableType == TSDB_CHILD_TABLE)); - + STableComInfo tinfo = tscGetTableInfo(pTableMeta); assert(tinfo.numOfTags > 0); - + return tscGetTableColumnSchema(pTableMeta, tinfo.numOfColumns); } @@ -68,7 +53,7 @@ STableComInfo tscGetTableInfo(const STableMeta* pTableMeta) { SSchema* tscGetTableColumnSchema(const STableMeta* pTableMeta, int32_t colIndex) { assert(pTableMeta != NULL); - + SSchema* pSchema = (SSchema*) pTableMeta->schema; return &pSchema[colIndex]; } @@ -88,7 +73,7 @@ SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId) { STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) { assert(pTableMetaMsg != NULL && pTableMetaMsg->numOfColumns >= 2 && pTableMetaMsg->numOfTags >= 0); - + int32_t schemaSize = (pTableMetaMsg->numOfColumns + pTableMetaMsg->numOfTags) * sizeof(SSchema); STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + schemaSize); @@ -97,11 +82,11 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) { pTableMeta->suid = pTableMetaMsg->suid; pTableMeta->tableInfo = (STableComInfo) { - .numOfTags = pTableMetaMsg->numOfTags, - .precision = pTableMetaMsg->precision, - .numOfColumns = pTableMetaMsg->numOfColumns, + .numOfTags = pTableMetaMsg->numOfTags, + .precision = pTableMetaMsg->precision, + .numOfColumns = pTableMetaMsg->numOfColumns, }; - + pTableMeta->id.tid = pTableMetaMsg->tid; pTableMeta->id.uid = pTableMetaMsg->uid; @@ -109,69 +94,14 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) { pTableMeta->tversion = pTableMetaMsg->tversion; tstrncpy(pTableMeta->sTableName, pTableMetaMsg->sTableName, TSDB_TABLE_FNAME_LEN); - + memcpy(pTableMeta->schema, pTableMetaMsg->schema, schemaSize); - + int32_t numOfTotalCols = pTableMeta->tableInfo.numOfColumns; for(int32_t i = 0; i < numOfTotalCols; ++i) { pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes; } - - return pTableMeta; -} - -bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src) { - assert(pExisted != NULL && src != NULL); - if (pExisted->numOfEps != src->numOfEps) { - return false; - } - - for(int32_t i = 0; i < pExisted->numOfEps; ++i) { - if (pExisted->ep[i].port != src->epAddr[i].port) { - return false; - } - - if (strncmp(pExisted->ep[i].fqdn, src->epAddr[i].fqdn, tListLen(pExisted->ep[i].fqdn)) != 0) { - return false; - } - } - return true; -} - -SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg) { - assert(pVgroupMsg != NULL); - - SNewVgroupInfo info = {0}; - info.numOfEps = pVgroupMsg->numOfEps; - info.vgId = pVgroupMsg->vgId; - info.inUse = 0; // 0 is the default value of inUse in case of multiple replica - - assert(info.numOfEps >= 1 && info.vgId >= 1); - for(int32_t i = 0; i < pVgroupMsg->numOfEps; ++i) { - tstrncpy(info.ep[i].fqdn, pVgroupMsg->epAddr[i].fqdn, TSDB_FQDN_LEN); - info.ep[i].port = pVgroupMsg->epAddr[i].port; - } - - return info; -} - -// todo refactor -UNUSED_FUNC static FORCE_INLINE char* skipSegments(char* input, char delim, int32_t num) { - for (int32_t i = 0; i < num; ++i) { - while (*input != 0 && *input++ != delim) { - }; - } - return input; -} - -UNUSED_FUNC static FORCE_INLINE size_t copy(char* dst, const char* src, char delimiter) { - size_t len = 0; - while (*src != delimiter && *src != 0) { - *dst++ = *src++; - len++; - } - - return len; + return pTableMeta; } diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index 7ff2d169623e99e676b21402b621161bcd49a2eb..7b08450d3b9461c5ccfc316485f12c5d4ea84111 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -581,6 +581,9 @@ void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) { tbufWriteUint32(bw, pDist->numOfTables); tbufWriteUint16(bw, pDist->numOfFiles); tbufWriteUint64(bw, pDist->totalSize); + tbufWriteUint64(bw, pDist->totalRows); + tbufWriteInt32(bw, pDist->maxRows); + tbufWriteInt32(bw, pDist->minRows); tbufWriteUint32(bw, pDist->numOfRowsInMemTable); tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos)); @@ -616,13 +619,16 @@ void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDi pDist->numOfTables = tbufReadUint32(&br); pDist->numOfFiles = tbufReadUint16(&br); pDist->totalSize = tbufReadUint64(&br); + pDist->totalRows = tbufReadUint64(&br); + pDist->maxRows = tbufReadInt32(&br); + pDist->minRows = tbufReadInt32(&br); pDist->numOfRowsInMemTable = tbufReadUint32(&br); - int64_t numOfBlocks = tbufReadUint64(&br); + int64_t numSteps = tbufReadUint64(&br); bool comp = tbufReadUint8(&br); uint32_t compLen = tbufReadUint32(&br); - size_t originalLen = (size_t) (numOfBlocks*sizeof(SFileBlockInfo)); + size_t originalLen = (size_t) (numSteps *sizeof(SFileBlockInfo)); char* outputBuf = NULL; if (comp) { @@ -633,12 +639,12 @@ void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDi int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf, (int32_t)originalLen , ONE_STAGE_COMP, NULL, 0); - assert(orignalLen == numOfBlocks*sizeof(SFileBlockInfo)); + assert(orignalLen == numSteps *sizeof(SFileBlockInfo)); } else { outputBuf = (char*) tbufReadBinary(&br, &originalLen); } - pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t) numOfBlocks, sizeof(SFileBlockInfo)); + pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t)numSteps, sizeof(SFileBlockInfo)); if (comp) { tfree(outputBuf); } diff --git a/src/query/src/sql.c b/src/query/src/sql.c index 5a5038be796dc6c244f08e7acfe7b5de30d71b28..55a6833cc1238a2a17f2c621c292b9b1b1322b29 100644 --- a/src/query/src/sql.c +++ b/src/query/src/sql.c @@ -25,11 +25,11 @@ #include /************ Begin %include sections from the grammar ************************/ -#include -#include #include #include #include +#include +#include #include "qSqlparser.h" #include "tcmdtype.h" #include "ttoken.h" @@ -97,27 +97,28 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 264 +#define YYNOCODE 267 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SStrToken typedef union { int yyinit; ParseTOKENTYPE yy0; - SCreateTableSql* yy14; - int yy20; - SSqlNode* yy116; - tSqlExpr* yy118; - SArray* yy159; - SIntervalVal yy184; - SCreatedTableInfo yy206; - SRelationInfo* yy236; - SSessionWindowVal yy249; - int64_t yy317; - SCreateDbInfo yy322; - SCreateAcctInfo yy351; - TAOS_FIELD yy407; - SLimitVal yy440; - tVariant yy488; + 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,17 +128,17 @@ typedef union { #define ParseARG_FETCH SSqlInfo* pInfo = yypParser->pInfo #define ParseARG_STORE yypParser->pInfo = pInfo #define YYFALLBACK 1 -#define YYNSTATE 317 -#define YYNRULE 270 -#define YYNTOKEN 187 -#define YY_MAX_SHIFT 316 -#define YY_MIN_SHIFTREDUCE 511 -#define YY_MAX_SHIFTREDUCE 780 -#define YY_ERROR_ACTION 781 -#define YY_ACCEPT_ACTION 782 -#define YY_NO_ACTION 783 -#define YY_MIN_REDUCE 784 -#define YY_MAX_REDUCE 1053 +#define YYNSTATE 327 +#define YYNRULE 275 +#define YYNTOKEN 188 +#define YY_MAX_SHIFT 326 +#define YY_MIN_SHIFTREDUCE 523 +#define YY_MAX_SHIFTREDUCE 797 +#define YY_ERROR_ACTION 798 +#define YY_ACCEPT_ACTION 799 +#define YY_NO_ACTION 800 +#define YY_MIN_REDUCE 801 +#define YY_MAX_REDUCE 1075 /************* End control #defines *******************************************/ /* Define the yytestcase() macro to be a no-op if is not already defined @@ -203,261 +204,266 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (685) +#define YY_ACTTAB_COUNT (700) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 925, 559, 206, 314, 211, 141, 952, 3, 168, 560, - /* 10 */ 782, 316, 134, 47, 48, 141, 51, 52, 30, 183, - /* 20 */ 217, 41, 183, 50, 264, 55, 53, 57, 54, 1034, - /* 30 */ 931, 214, 1035, 46, 45, 17, 183, 44, 43, 42, - /* 40 */ 47, 48, 223, 51, 52, 213, 1035, 217, 41, 559, - /* 50 */ 50, 264, 55, 53, 57, 54, 943, 560, 181, 208, - /* 60 */ 46, 45, 928, 222, 44, 43, 42, 48, 949, 51, - /* 70 */ 52, 244, 983, 217, 41, 249, 50, 264, 55, 53, - /* 80 */ 57, 54, 984, 638, 259, 85, 46, 45, 280, 931, - /* 90 */ 44, 43, 42, 512, 513, 514, 515, 516, 517, 518, - /* 100 */ 519, 520, 521, 522, 523, 524, 315, 943, 187, 207, - /* 110 */ 70, 290, 289, 47, 48, 30, 51, 52, 300, 919, - /* 120 */ 217, 41, 209, 50, 264, 55, 53, 57, 54, 44, - /* 130 */ 43, 42, 724, 46, 45, 674, 224, 44, 43, 42, - /* 140 */ 47, 49, 24, 51, 52, 228, 141, 217, 41, 559, - /* 150 */ 50, 264, 55, 53, 57, 54, 220, 560, 105, 928, - /* 160 */ 46, 45, 931, 300, 44, 43, 42, 23, 278, 309, - /* 170 */ 308, 277, 276, 275, 307, 274, 306, 305, 304, 273, - /* 180 */ 303, 302, 891, 30, 879, 880, 881, 882, 883, 884, - /* 190 */ 885, 886, 887, 888, 889, 890, 892, 893, 51, 52, - /* 200 */ 830, 1031, 217, 41, 167, 50, 264, 55, 53, 57, - /* 210 */ 54, 261, 18, 78, 230, 46, 45, 287, 286, 44, - /* 220 */ 43, 42, 216, 739, 221, 30, 728, 928, 731, 192, - /* 230 */ 734, 216, 739, 310, 1030, 728, 193, 731, 236, 734, - /* 240 */ 30, 118, 117, 191, 677, 559, 240, 239, 55, 53, - /* 250 */ 57, 54, 25, 560, 202, 203, 46, 45, 263, 931, - /* 260 */ 44, 43, 42, 202, 203, 74, 283, 61, 23, 928, - /* 270 */ 309, 308, 74, 36, 730, 307, 733, 306, 305, 304, - /* 280 */ 36, 303, 302, 899, 927, 662, 897, 898, 659, 62, - /* 290 */ 660, 900, 661, 902, 903, 901, 82, 904, 905, 103, - /* 300 */ 97, 108, 243, 917, 68, 30, 107, 113, 116, 106, - /* 310 */ 199, 5, 33, 157, 141, 110, 231, 232, 156, 92, - /* 320 */ 87, 91, 681, 226, 30, 56, 30, 914, 915, 29, - /* 330 */ 918, 729, 740, 732, 56, 175, 173, 171, 736, 1, - /* 340 */ 155, 740, 170, 121, 120, 119, 284, 736, 229, 928, - /* 350 */ 265, 46, 45, 69, 735, 44, 43, 42, 839, 666, - /* 360 */ 12, 667, 167, 735, 84, 288, 81, 292, 928, 215, - /* 370 */ 928, 313, 312, 126, 132, 130, 129, 80, 705, 706, - /* 380 */ 831, 79, 280, 929, 167, 916, 737, 245, 726, 684, - /* 390 */ 71, 31, 227, 994, 663, 282, 690, 247, 696, 697, - /* 400 */ 136, 760, 60, 20, 741, 19, 64, 648, 19, 241, - /* 410 */ 267, 31, 650, 6, 31, 269, 60, 1029, 649, 83, - /* 420 */ 28, 200, 60, 270, 727, 201, 65, 96, 95, 185, - /* 430 */ 14, 13, 993, 102, 101, 67, 218, 637, 16, 15, - /* 440 */ 664, 186, 665, 738, 115, 114, 743, 188, 182, 189, - /* 450 */ 190, 196, 197, 195, 180, 194, 184, 133, 1045, 990, - /* 460 */ 930, 989, 219, 291, 39, 951, 959, 944, 961, 135, - /* 470 */ 139, 976, 248, 975, 926, 131, 152, 151, 924, 153, - /* 480 */ 250, 154, 689, 210, 252, 150, 257, 145, 142, 842, - /* 490 */ 941, 143, 272, 144, 262, 37, 146, 66, 58, 178, - /* 500 */ 63, 260, 34, 258, 256, 281, 838, 147, 1050, 254, - /* 510 */ 93, 1049, 1047, 158, 285, 1044, 99, 148, 1043, 1041, - /* 520 */ 159, 860, 251, 35, 32, 38, 149, 179, 827, 109, - /* 530 */ 825, 111, 112, 823, 822, 233, 169, 820, 819, 818, - /* 540 */ 817, 816, 815, 172, 174, 40, 812, 810, 808, 806, - /* 550 */ 176, 803, 177, 301, 246, 72, 75, 104, 253, 977, - /* 560 */ 293, 294, 295, 296, 297, 204, 225, 298, 271, 299, - /* 570 */ 311, 780, 205, 198, 234, 88, 89, 235, 779, 237, - /* 580 */ 238, 778, 766, 765, 242, 247, 821, 814, 162, 266, - /* 590 */ 122, 861, 160, 165, 161, 164, 163, 166, 123, 124, - /* 600 */ 813, 805, 895, 125, 804, 2, 8, 73, 4, 669, - /* 610 */ 76, 691, 137, 212, 694, 86, 138, 77, 907, 255, - /* 620 */ 9, 698, 140, 26, 742, 7, 27, 11, 10, 21, - /* 630 */ 84, 744, 22, 268, 601, 597, 595, 594, 593, 590, - /* 640 */ 563, 279, 94, 90, 31, 59, 640, 639, 636, 585, - /* 650 */ 583, 98, 575, 581, 577, 579, 573, 571, 604, 603, - /* 660 */ 602, 600, 599, 100, 598, 596, 592, 591, 60, 561, - /* 670 */ 528, 784, 526, 783, 783, 783, 783, 783, 783, 127, - /* 680 */ 783, 783, 783, 783, 128, + /* 0 */ 969, 571, 211, 324, 934, 18, 217, 186, 188, 572, + /* 10 */ 799, 326, 192, 48, 49, 145, 52, 53, 220, 1057, + /* 20 */ 223, 42, 275, 51, 274, 56, 54, 58, 55, 1053, + /* 30 */ 650, 188, 948, 47, 46, 188, 228, 45, 44, 43, + /* 40 */ 48, 49, 1056, 52, 53, 219, 1057, 223, 42, 571, + /* 50 */ 51, 274, 56, 54, 58, 55, 960, 572, 300, 299, + /* 60 */ 47, 46, 948, 966, 45, 44, 43, 49, 31, 52, + /* 70 */ 53, 138, 250, 223, 42, 1067, 51, 274, 56, 54, + /* 80 */ 58, 55, 271, 290, 82, 1052, 47, 46, 89, 234, + /* 90 */ 45, 44, 43, 524, 525, 526, 527, 528, 529, 530, + /* 100 */ 531, 532, 533, 534, 535, 536, 325, 571, 290, 212, + /* 110 */ 71, 571, 944, 48, 49, 572, 52, 53, 760, 572, + /* 120 */ 223, 42, 936, 51, 274, 56, 54, 58, 55, 45, + /* 130 */ 44, 43, 741, 47, 46, 257, 256, 45, 44, 43, + /* 140 */ 48, 50, 145, 52, 53, 1, 160, 223, 42, 145, + /* 150 */ 51, 274, 56, 54, 58, 55, 323, 322, 130, 236, + /* 160 */ 47, 46, 297, 296, 45, 44, 43, 24, 288, 319, + /* 170 */ 318, 287, 286, 285, 317, 284, 316, 315, 314, 283, + /* 180 */ 313, 312, 908, 31, 896, 897, 898, 899, 900, 901, + /* 190 */ 902, 903, 904, 905, 906, 907, 909, 910, 52, 53, + /* 200 */ 847, 960, 223, 42, 172, 51, 274, 56, 54, 58, + /* 210 */ 55, 1005, 19, 86, 25, 47, 46, 214, 83, 45, + /* 220 */ 44, 43, 222, 756, 213, 310, 745, 945, 748, 197, + /* 230 */ 751, 222, 756, 230, 13, 745, 198, 748, 88, 751, + /* 240 */ 85, 122, 121, 196, 931, 932, 30, 935, 56, 54, + /* 250 */ 58, 55, 3, 173, 207, 208, 47, 46, 273, 948, + /* 260 */ 45, 44, 43, 207, 208, 242, 232, 747, 24, 750, + /* 270 */ 319, 318, 77, 246, 245, 317, 689, 316, 315, 314, + /* 280 */ 37, 313, 312, 62, 916, 47, 46, 914, 915, 45, + /* 290 */ 44, 43, 917, 942, 919, 920, 918, 145, 921, 922, + /* 300 */ 107, 101, 112, 249, 31, 69, 63, 111, 117, 120, + /* 310 */ 110, 204, 674, 109, 235, 671, 114, 672, 310, 673, + /* 320 */ 5, 34, 162, 1051, 70, 57, 31, 161, 96, 91, + /* 330 */ 95, 31, 757, 31, 57, 229, 233, 31, 753, 292, + /* 340 */ 746, 757, 749, 237, 238, 226, 31, 753, 945, 946, + /* 350 */ 180, 178, 176, 205, 693, 752, 933, 175, 125, 124, + /* 360 */ 123, 136, 134, 133, 752, 77, 1006, 227, 269, 320, + /* 370 */ 945, 84, 293, 37, 294, 945, 856, 945, 298, 754, + /* 380 */ 172, 945, 848, 960, 686, 72, 172, 302, 722, 723, + /* 390 */ 945, 8, 251, 743, 74, 948, 32, 75, 221, 215, + /* 400 */ 705, 206, 253, 713, 140, 253, 714, 61, 777, 758, + /* 410 */ 21, 65, 20, 20, 660, 678, 277, 679, 32, 662, + /* 420 */ 32, 675, 279, 61, 661, 190, 87, 29, 61, 744, + /* 430 */ 280, 191, 66, 100, 99, 15, 14, 119, 118, 106, + /* 440 */ 105, 68, 6, 649, 17, 16, 676, 193, 677, 187, + /* 450 */ 194, 195, 755, 201, 202, 200, 185, 199, 189, 947, + /* 460 */ 1016, 1015, 224, 1012, 1011, 247, 137, 40, 225, 301, + /* 470 */ 968, 979, 976, 977, 981, 139, 143, 961, 254, 998, + /* 480 */ 997, 943, 263, 156, 135, 157, 704, 258, 311, 941, + /* 490 */ 912, 306, 108, 303, 155, 150, 148, 958, 158, 159, + /* 500 */ 859, 67, 146, 216, 282, 38, 260, 183, 35, 267, + /* 510 */ 291, 64, 855, 1072, 97, 59, 1071, 1069, 163, 295, + /* 520 */ 1066, 103, 1065, 1063, 164, 877, 36, 272, 33, 270, + /* 530 */ 268, 39, 184, 844, 113, 842, 115, 116, 840, 839, + /* 540 */ 239, 174, 837, 836, 835, 834, 833, 832, 177, 179, + /* 550 */ 829, 827, 825, 266, 823, 181, 820, 182, 264, 252, + /* 560 */ 73, 78, 262, 261, 999, 259, 41, 304, 305, 307, + /* 570 */ 209, 231, 308, 309, 281, 321, 797, 240, 241, 210, + /* 580 */ 796, 92, 93, 203, 244, 243, 795, 783, 782, 838, + /* 590 */ 248, 253, 681, 276, 126, 171, 166, 878, 167, 165, + /* 600 */ 168, 169, 831, 170, 9, 127, 128, 830, 76, 129, + /* 610 */ 822, 821, 2, 26, 4, 255, 79, 706, 153, 151, + /* 620 */ 149, 147, 152, 154, 141, 924, 709, 142, 80, 218, + /* 630 */ 711, 81, 265, 761, 715, 144, 90, 10, 11, 27, + /* 640 */ 759, 28, 7, 12, 22, 88, 23, 613, 278, 609, + /* 650 */ 607, 606, 605, 602, 575, 289, 94, 32, 60, 98, + /* 660 */ 652, 651, 648, 102, 597, 595, 104, 587, 593, 589, + /* 670 */ 591, 585, 583, 616, 615, 614, 612, 611, 610, 608, + /* 680 */ 604, 603, 573, 540, 538, 61, 801, 800, 800, 800, + /* 690 */ 800, 800, 800, 800, 800, 800, 800, 800, 131, 132, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 191, 1, 190, 191, 210, 191, 191, 194, 195, 9, - /* 10 */ 188, 189, 191, 13, 14, 191, 16, 17, 191, 252, - /* 20 */ 20, 21, 252, 23, 24, 25, 26, 27, 28, 262, - /* 30 */ 236, 261, 262, 33, 34, 252, 252, 37, 38, 39, - /* 40 */ 13, 14, 233, 16, 17, 261, 262, 20, 21, 1, - /* 50 */ 23, 24, 25, 26, 27, 28, 234, 9, 252, 232, - /* 60 */ 33, 34, 235, 210, 37, 38, 39, 14, 253, 16, - /* 70 */ 17, 249, 258, 20, 21, 254, 23, 24, 25, 26, - /* 80 */ 27, 28, 258, 5, 260, 197, 33, 34, 79, 236, + /* 0 */ 192, 1, 191, 192, 0, 254, 211, 254, 254, 9, + /* 10 */ 189, 190, 254, 13, 14, 192, 16, 17, 264, 265, + /* 20 */ 20, 21, 15, 23, 24, 25, 26, 27, 28, 254, + /* 30 */ 5, 254, 237, 33, 34, 254, 211, 37, 38, 39, + /* 40 */ 13, 14, 265, 16, 17, 264, 265, 20, 21, 1, + /* 50 */ 23, 24, 25, 26, 27, 28, 235, 9, 33, 34, + /* 60 */ 33, 34, 237, 255, 37, 38, 39, 14, 192, 16, + /* 70 */ 17, 192, 251, 20, 21, 237, 23, 24, 25, 26, + /* 80 */ 27, 28, 259, 79, 261, 254, 33, 34, 198, 68, /* 90 */ 37, 38, 39, 45, 46, 47, 48, 49, 50, 51, - /* 100 */ 52, 53, 54, 55, 56, 57, 58, 234, 252, 61, - /* 110 */ 110, 33, 34, 13, 14, 191, 16, 17, 81, 231, - /* 120 */ 20, 21, 249, 23, 24, 25, 26, 27, 28, 37, - /* 130 */ 38, 39, 105, 33, 34, 109, 210, 37, 38, 39, - /* 140 */ 13, 14, 116, 16, 17, 68, 191, 20, 21, 1, - /* 150 */ 23, 24, 25, 26, 27, 28, 232, 9, 76, 235, - /* 160 */ 33, 34, 236, 81, 37, 38, 39, 88, 89, 90, + /* 100 */ 52, 53, 54, 55, 56, 57, 58, 1, 79, 61, + /* 110 */ 110, 1, 236, 13, 14, 9, 16, 17, 111, 9, + /* 120 */ 20, 21, 232, 23, 24, 25, 26, 27, 28, 37, + /* 130 */ 38, 39, 105, 33, 34, 256, 257, 37, 38, 39, + /* 140 */ 13, 14, 192, 16, 17, 199, 200, 20, 21, 192, + /* 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, 209, 191, 211, 212, 213, 214, 215, 216, - /* 190 */ 217, 218, 219, 220, 221, 222, 223, 224, 16, 17, - /* 200 */ 196, 252, 20, 21, 200, 23, 24, 25, 26, 27, - /* 210 */ 28, 256, 44, 258, 137, 33, 34, 140, 141, 37, - /* 220 */ 38, 39, 1, 2, 232, 191, 5, 235, 7, 61, - /* 230 */ 9, 1, 2, 210, 252, 5, 68, 7, 135, 9, - /* 240 */ 191, 73, 74, 75, 37, 1, 143, 144, 25, 26, - /* 250 */ 27, 28, 104, 9, 33, 34, 33, 34, 37, 236, - /* 260 */ 37, 38, 39, 33, 34, 104, 232, 109, 88, 235, - /* 270 */ 90, 91, 104, 112, 5, 95, 7, 97, 98, 99, - /* 280 */ 112, 101, 102, 209, 235, 2, 212, 213, 5, 131, - /* 290 */ 7, 217, 9, 219, 220, 221, 197, 223, 224, 62, - /* 300 */ 63, 64, 134, 0, 136, 191, 69, 70, 71, 72, - /* 310 */ 142, 62, 63, 64, 191, 78, 33, 34, 69, 70, - /* 320 */ 71, 72, 115, 68, 191, 104, 191, 228, 229, 230, - /* 330 */ 231, 5, 111, 7, 104, 62, 63, 64, 117, 198, - /* 340 */ 199, 111, 69, 70, 71, 72, 232, 117, 191, 235, - /* 350 */ 15, 33, 34, 197, 133, 37, 38, 39, 196, 5, - /* 360 */ 104, 7, 200, 133, 108, 232, 110, 232, 235, 60, - /* 370 */ 235, 65, 66, 67, 62, 63, 64, 237, 124, 125, - /* 380 */ 196, 258, 79, 226, 200, 229, 117, 105, 1, 105, - /* 390 */ 250, 109, 137, 227, 111, 140, 105, 113, 105, 105, - /* 400 */ 109, 105, 109, 109, 105, 109, 109, 105, 109, 191, - /* 410 */ 105, 109, 105, 104, 109, 105, 109, 252, 105, 109, - /* 420 */ 104, 252, 109, 107, 37, 252, 129, 138, 139, 252, - /* 430 */ 138, 139, 227, 138, 139, 104, 227, 106, 138, 139, - /* 440 */ 5, 252, 7, 117, 76, 77, 111, 252, 252, 252, - /* 450 */ 252, 252, 252, 252, 252, 252, 252, 191, 236, 227, - /* 460 */ 236, 227, 227, 227, 251, 191, 191, 234, 191, 191, - /* 470 */ 191, 259, 234, 259, 234, 60, 191, 238, 191, 191, - /* 480 */ 255, 191, 117, 255, 255, 239, 255, 244, 247, 191, - /* 490 */ 248, 246, 191, 245, 122, 191, 243, 128, 127, 191, - /* 500 */ 130, 126, 191, 121, 120, 191, 191, 242, 191, 119, - /* 510 */ 191, 191, 191, 191, 191, 191, 191, 241, 191, 191, - /* 520 */ 191, 191, 118, 191, 191, 191, 240, 191, 191, 191, - /* 530 */ 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, - /* 540 */ 191, 191, 191, 191, 191, 132, 191, 191, 191, 191, - /* 550 */ 191, 191, 191, 103, 192, 192, 192, 87, 192, 192, - /* 560 */ 86, 50, 83, 85, 54, 192, 192, 84, 192, 82, - /* 570 */ 79, 5, 192, 192, 145, 197, 197, 5, 5, 145, - /* 580 */ 5, 5, 90, 89, 135, 113, 192, 192, 202, 107, - /* 590 */ 193, 208, 207, 204, 206, 203, 205, 201, 193, 193, - /* 600 */ 192, 192, 225, 193, 192, 198, 104, 114, 194, 105, - /* 610 */ 109, 105, 104, 1, 105, 76, 109, 104, 225, 104, - /* 620 */ 123, 105, 104, 109, 105, 104, 109, 104, 123, 104, - /* 630 */ 108, 111, 104, 107, 9, 5, 5, 5, 5, 5, - /* 640 */ 80, 15, 139, 76, 109, 16, 5, 5, 105, 5, - /* 650 */ 5, 139, 5, 5, 5, 5, 5, 5, 5, 5, - /* 660 */ 5, 5, 5, 139, 5, 5, 5, 5, 109, 80, - /* 670 */ 60, 0, 59, 263, 263, 263, 263, 263, 263, 21, - /* 680 */ 263, 263, 263, 263, 21, 263, 263, 263, 263, 263, - /* 690 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 700 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 710 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 720 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 730 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 740 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 750 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 760 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 770 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 780 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 790 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 800 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 810 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 820 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 830 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 840 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 850 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 860 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 870 */ 263, 263, + /* 180 */ 101, 102, 210, 192, 212, 213, 214, 215, 216, 217, + /* 190 */ 218, 219, 220, 221, 222, 223, 224, 225, 16, 17, + /* 200 */ 197, 235, 20, 21, 201, 23, 24, 25, 26, 27, + /* 210 */ 28, 261, 44, 198, 104, 33, 34, 251, 261, 37, + /* 220 */ 38, 39, 1, 2, 233, 81, 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, 195, 196, 33, 34, 33, 34, 37, 237, + /* 260 */ 37, 38, 39, 33, 34, 136, 68, 5, 88, 7, + /* 270 */ 90, 91, 104, 144, 145, 95, 37, 97, 98, 99, + /* 280 */ 112, 101, 102, 109, 210, 33, 34, 213, 214, 37, + /* 290 */ 38, 39, 218, 192, 220, 221, 222, 192, 224, 225, + /* 300 */ 62, 63, 64, 135, 192, 137, 132, 69, 70, 71, + /* 310 */ 72, 143, 2, 76, 192, 5, 78, 7, 81, 9, + /* 320 */ 62, 63, 64, 254, 198, 104, 192, 69, 70, 71, + /* 330 */ 72, 192, 111, 192, 104, 234, 138, 192, 117, 141, + /* 340 */ 5, 111, 7, 33, 34, 233, 192, 117, 236, 227, + /* 350 */ 62, 63, 64, 254, 115, 134, 230, 69, 70, 71, + /* 360 */ 72, 62, 63, 64, 134, 104, 261, 233, 263, 211, + /* 370 */ 236, 238, 233, 112, 233, 236, 197, 236, 233, 117, + /* 380 */ 201, 236, 197, 235, 109, 252, 201, 233, 125, 126, + /* 390 */ 236, 116, 105, 1, 105, 237, 109, 105, 60, 251, + /* 400 */ 105, 254, 113, 105, 109, 113, 105, 109, 105, 105, + /* 410 */ 109, 109, 109, 109, 105, 5, 105, 7, 109, 105, + /* 420 */ 109, 111, 105, 109, 105, 254, 109, 104, 109, 37, + /* 430 */ 107, 254, 130, 139, 140, 139, 140, 76, 77, 139, + /* 440 */ 140, 104, 104, 106, 139, 140, 5, 254, 7, 254, + /* 450 */ 254, 254, 117, 254, 254, 254, 254, 254, 254, 237, + /* 460 */ 228, 228, 228, 228, 228, 192, 192, 253, 228, 228, + /* 470 */ 192, 192, 192, 192, 192, 192, 192, 235, 235, 262, + /* 480 */ 262, 235, 192, 239, 60, 192, 117, 258, 103, 192, + /* 490 */ 226, 85, 87, 86, 240, 245, 247, 250, 192, 192, + /* 500 */ 192, 129, 249, 258, 192, 192, 258, 192, 192, 258, + /* 510 */ 192, 131, 192, 192, 192, 128, 192, 192, 192, 192, + /* 520 */ 192, 192, 192, 192, 192, 192, 192, 123, 192, 127, + /* 530 */ 122, 192, 192, 192, 192, 192, 192, 192, 192, 192, + /* 540 */ 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + /* 550 */ 192, 192, 192, 121, 192, 192, 192, 192, 120, 193, + /* 560 */ 193, 193, 119, 193, 193, 118, 133, 50, 83, 54, + /* 570 */ 193, 193, 84, 82, 193, 79, 5, 146, 5, 193, + /* 580 */ 5, 198, 198, 193, 5, 146, 5, 90, 89, 193, + /* 590 */ 136, 113, 105, 107, 194, 202, 207, 209, 203, 208, + /* 600 */ 206, 204, 193, 205, 104, 194, 194, 193, 114, 194, + /* 610 */ 193, 193, 199, 104, 195, 109, 109, 105, 242, 244, + /* 620 */ 246, 248, 243, 241, 104, 226, 105, 109, 104, 1, + /* 630 */ 105, 104, 104, 111, 105, 104, 76, 124, 124, 109, + /* 640 */ 105, 109, 104, 104, 104, 108, 104, 9, 107, 5, + /* 650 */ 5, 5, 5, 5, 80, 15, 76, 109, 16, 140, + /* 660 */ 5, 5, 105, 140, 5, 5, 140, 5, 5, 5, + /* 670 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + /* 680 */ 5, 5, 80, 60, 59, 109, 0, 266, 266, 266, + /* 690 */ 266, 266, 266, 266, 266, 266, 266, 266, 21, 21, + /* 700 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 710 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 720 */ 266, 266, 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, 266, 266, + /* 760 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 770 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 780 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 790 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 800 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 810 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 820 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 830 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 840 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 850 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 860 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 870 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + /* 880 */ 266, 266, 266, 266, 266, 266, 266, 266, }; -#define YY_SHIFT_COUNT (316) +#define YY_SHIFT_COUNT (326) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (671) +#define YY_SHIFT_MAX (686) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 168, 79, 79, 180, 180, 9, 221, 230, 244, 244, - /* 10 */ 244, 244, 244, 244, 244, 244, 244, 0, 48, 230, - /* 20 */ 283, 283, 283, 283, 148, 161, 244, 244, 244, 303, - /* 30 */ 244, 244, 82, 9, 37, 37, 685, 685, 685, 230, + /* 0 */ 168, 79, 79, 180, 180, 29, 221, 230, 110, 106, + /* 10 */ 106, 106, 106, 106, 106, 106, 106, 106, 0, 48, + /* 20 */ 230, 310, 310, 310, 310, 261, 261, 106, 106, 106, + /* 30 */ 4, 106, 106, 237, 29, 144, 144, 700, 700, 700, /* 40 */ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, - /* 50 */ 230, 230, 230, 230, 230, 230, 230, 230, 230, 283, - /* 60 */ 283, 78, 78, 78, 78, 78, 78, 78, 244, 244, - /* 70 */ 244, 207, 244, 161, 161, 244, 244, 244, 254, 254, - /* 80 */ 26, 161, 244, 244, 244, 244, 244, 244, 244, 244, - /* 90 */ 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - /* 100 */ 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - /* 110 */ 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - /* 120 */ 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - /* 130 */ 244, 244, 244, 415, 415, 415, 365, 365, 365, 415, - /* 140 */ 365, 415, 369, 370, 371, 372, 375, 382, 384, 390, - /* 150 */ 404, 413, 415, 415, 415, 450, 9, 9, 415, 415, - /* 160 */ 470, 474, 511, 479, 478, 510, 483, 487, 450, 415, - /* 170 */ 491, 491, 415, 491, 415, 491, 415, 415, 685, 685, - /* 180 */ 27, 100, 127, 100, 100, 53, 182, 223, 223, 223, - /* 190 */ 223, 237, 249, 273, 318, 318, 318, 318, 77, 103, - /* 200 */ 92, 92, 269, 326, 256, 255, 306, 312, 282, 284, - /* 210 */ 291, 293, 294, 296, 299, 387, 309, 335, 158, 297, - /* 220 */ 302, 305, 307, 310, 313, 316, 289, 292, 295, 331, - /* 230 */ 300, 354, 435, 368, 566, 429, 572, 573, 434, 575, - /* 240 */ 576, 492, 494, 449, 472, 482, 502, 493, 504, 501, - /* 250 */ 506, 508, 509, 507, 513, 612, 515, 516, 518, 514, - /* 260 */ 497, 517, 505, 519, 521, 520, 523, 482, 525, 526, - /* 270 */ 528, 522, 539, 625, 630, 631, 632, 633, 634, 560, - /* 280 */ 626, 567, 503, 535, 535, 629, 512, 524, 535, 641, - /* 290 */ 642, 543, 535, 644, 645, 647, 648, 649, 650, 651, - /* 300 */ 652, 653, 654, 655, 656, 657, 659, 660, 661, 662, - /* 310 */ 559, 589, 658, 663, 610, 613, 671, + /* 50 */ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + /* 60 */ 310, 310, 25, 25, 25, 25, 25, 25, 25, 106, + /* 70 */ 106, 106, 239, 106, 106, 106, 261, 261, 106, 106, + /* 80 */ 106, 106, 263, 263, 275, 261, 106, 106, 106, 106, + /* 90 */ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + /* 100 */ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + /* 110 */ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + /* 120 */ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + /* 130 */ 106, 106, 106, 106, 106, 106, 106, 424, 424, 424, + /* 140 */ 369, 369, 369, 424, 369, 424, 372, 380, 387, 404, + /* 150 */ 402, 408, 432, 438, 443, 447, 433, 424, 424, 424, + /* 160 */ 385, 29, 29, 424, 424, 405, 407, 517, 485, 406, + /* 170 */ 515, 488, 491, 385, 424, 496, 496, 424, 496, 424, + /* 180 */ 496, 424, 424, 700, 700, 27, 100, 127, 100, 100, + /* 190 */ 53, 182, 223, 223, 223, 223, 238, 258, 288, 252, + /* 200 */ 252, 252, 252, 21, 129, 92, 92, 262, 335, 130, + /* 210 */ 198, 91, 299, 287, 289, 292, 295, 298, 301, 303, + /* 220 */ 304, 392, 338, 7, 174, 302, 309, 311, 314, 317, + /* 230 */ 319, 323, 294, 296, 300, 337, 305, 410, 441, 361, + /* 240 */ 571, 431, 573, 575, 439, 579, 581, 497, 499, 454, + /* 250 */ 478, 486, 500, 494, 487, 509, 506, 507, 512, 520, + /* 260 */ 521, 518, 524, 525, 527, 628, 528, 529, 531, 530, + /* 270 */ 513, 532, 514, 535, 538, 522, 539, 486, 540, 541, + /* 280 */ 542, 537, 560, 638, 644, 645, 646, 647, 648, 574, + /* 290 */ 640, 580, 519, 548, 548, 642, 523, 526, 548, 655, + /* 300 */ 656, 557, 548, 659, 660, 662, 663, 664, 665, 666, + /* 310 */ 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, + /* 320 */ 576, 602, 677, 678, 623, 625, 686, }; -#define YY_REDUCE_COUNT (179) -#define YY_REDUCE_MIN (-233) -#define YY_REDUCE_MAX (414) +#define YY_REDUCE_COUNT (184) +#define YY_REDUCE_MIN (-249) +#define YY_REDUCE_MAX (419) static const short yy_reduce_ofst[] = { - /* 0 */ -178, -27, -27, 74, 74, 99, -230, -216, -173, -176, - /* 10 */ -45, -76, -8, 34, 114, 133, 135, -185, -188, -233, - /* 20 */ -206, -147, -74, 23, -179, -127, -186, 123, -191, -112, - /* 30 */ 157, 49, 4, 156, 162, 184, 140, 141, -187, -217, - /* 40 */ -194, -144, -51, -18, 165, 169, 173, 177, 189, 195, - /* 50 */ 196, 197, 198, 199, 200, 201, 202, 203, 204, 222, - /* 60 */ 224, 166, 205, 209, 232, 234, 235, 236, 218, 266, - /* 70 */ 274, 213, 275, 233, 238, 277, 278, 279, 212, 214, - /* 80 */ 239, 240, 285, 287, 288, 290, 298, 301, 304, 308, - /* 90 */ 311, 314, 315, 317, 319, 320, 321, 322, 323, 324, - /* 100 */ 325, 327, 328, 329, 330, 332, 333, 334, 336, 337, - /* 110 */ 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, - /* 120 */ 348, 349, 350, 351, 352, 353, 355, 356, 357, 358, - /* 130 */ 359, 360, 361, 362, 363, 364, 225, 228, 229, 366, - /* 140 */ 231, 367, 242, 241, 245, 248, 243, 253, 265, 276, - /* 150 */ 286, 246, 373, 374, 376, 377, 378, 379, 380, 381, - /* 160 */ 383, 385, 388, 386, 391, 392, 389, 396, 393, 394, - /* 170 */ 397, 405, 395, 406, 408, 410, 409, 412, 407, 414, + /* 0 */ -179, -28, -28, 74, 74, 15, -246, -219, -121, -9, + /* 10 */ 105, -177, 112, 134, 139, 141, 145, 154, -192, -189, + /* 20 */ -223, -205, -175, 22, 158, -34, 148, -50, -43, 101, + /* 30 */ -110, 122, -124, 3, 126, 179, 185, 133, -54, 57, + /* 40 */ -249, -247, -242, -225, -169, 69, 99, 147, 171, 177, + /* 50 */ 193, 195, 196, 197, 199, 200, 201, 202, 203, 204, + /* 60 */ -162, 222, 232, 233, 234, 235, 236, 240, 241, 273, + /* 70 */ 274, 278, 214, 279, 280, 281, 242, 243, 282, 283, + /* 80 */ 284, 290, 217, 218, 244, 246, 293, 297, 306, 307, + /* 90 */ 308, 312, 313, 315, 316, 318, 320, 321, 322, 324, + /* 100 */ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + /* 110 */ 336, 339, 340, 341, 342, 343, 344, 345, 346, 347, + /* 120 */ 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + /* 130 */ 358, 359, 360, 362, 363, 364, 365, 366, 367, 368, + /* 140 */ 229, 245, 248, 370, 251, 371, 247, 253, 373, 249, + /* 150 */ 374, 250, 375, 379, 376, 382, 254, 377, 378, 381, + /* 160 */ 264, 383, 384, 386, 390, 388, 391, 389, 395, 394, + /* 170 */ 397, 398, 393, 399, 396, 400, 411, 409, 412, 414, + /* 180 */ 415, 417, 418, 413, 419, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 781, 894, 840, 906, 828, 837, 1037, 1037, 781, 781, - /* 10 */ 781, 781, 781, 781, 781, 781, 781, 953, 800, 1037, - /* 20 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 837, - /* 30 */ 781, 781, 843, 837, 843, 843, 948, 878, 896, 781, - /* 40 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, - /* 50 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, - /* 60 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, - /* 70 */ 781, 955, 958, 781, 781, 960, 781, 781, 980, 980, - /* 80 */ 946, 781, 781, 781, 781, 781, 781, 781, 781, 781, - /* 90 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, - /* 100 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 826, - /* 110 */ 781, 824, 781, 781, 781, 781, 781, 781, 781, 781, - /* 120 */ 781, 781, 781, 781, 781, 781, 811, 781, 781, 781, - /* 130 */ 781, 781, 781, 802, 802, 802, 781, 781, 781, 802, - /* 140 */ 781, 802, 987, 991, 985, 973, 981, 972, 968, 966, - /* 150 */ 965, 995, 802, 802, 802, 841, 837, 837, 802, 802, - /* 160 */ 859, 857, 855, 847, 853, 849, 851, 845, 829, 802, - /* 170 */ 835, 835, 802, 835, 802, 835, 802, 802, 878, 896, - /* 180 */ 781, 996, 781, 1036, 986, 1026, 1025, 1032, 1024, 1023, - /* 190 */ 1022, 781, 781, 781, 1018, 1019, 1021, 1020, 781, 781, - /* 200 */ 1028, 1027, 781, 781, 781, 781, 781, 781, 781, 781, - /* 210 */ 781, 781, 781, 781, 781, 781, 998, 781, 992, 988, - /* 220 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 908, - /* 230 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, - /* 240 */ 781, 781, 781, 781, 945, 781, 781, 781, 781, 956, - /* 250 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 982, - /* 260 */ 781, 974, 781, 781, 781, 781, 781, 920, 781, 781, - /* 270 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, - /* 280 */ 781, 781, 781, 1048, 1046, 781, 781, 781, 1042, 781, - /* 290 */ 781, 781, 1040, 781, 781, 781, 781, 781, 781, 781, - /* 300 */ 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, - /* 310 */ 862, 781, 809, 807, 781, 798, 781, + /* 0 */ 798, 911, 857, 923, 845, 854, 1059, 1059, 798, 798, + /* 10 */ 798, 798, 798, 798, 798, 798, 798, 798, 970, 817, + /* 20 */ 1059, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 30 */ 854, 798, 798, 860, 854, 860, 860, 965, 895, 913, + /* 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, 972, 978, 975, 798, 798, 798, 980, 798, + /* 80 */ 798, 798, 1002, 1002, 963, 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, 843, 798, 841, 798, 798, 798, 798, + /* 120 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 130 */ 828, 798, 798, 798, 798, 798, 798, 819, 819, 819, + /* 140 */ 798, 798, 798, 819, 798, 819, 1009, 1013, 1007, 995, + /* 150 */ 1003, 994, 990, 988, 986, 985, 1017, 819, 819, 819, + /* 160 */ 858, 854, 854, 819, 819, 876, 874, 872, 864, 870, + /* 170 */ 866, 868, 862, 846, 819, 852, 852, 819, 852, 819, + /* 180 */ 852, 819, 819, 895, 913, 798, 1018, 798, 1058, 1008, + /* 190 */ 1048, 1047, 1054, 1046, 1045, 1044, 798, 798, 798, 1040, + /* 200 */ 1041, 1043, 1042, 798, 798, 1050, 1049, 798, 798, 798, + /* 210 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 220 */ 798, 798, 1020, 798, 1014, 1010, 798, 798, 798, 798, + /* 230 */ 798, 798, 798, 798, 798, 925, 798, 798, 798, 798, + /* 240 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 250 */ 962, 798, 798, 798, 798, 798, 974, 973, 798, 798, + /* 260 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 1004, + /* 270 */ 798, 996, 798, 798, 798, 798, 798, 937, 798, 798, + /* 280 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 290 */ 798, 798, 798, 1070, 1068, 798, 798, 798, 1064, 798, + /* 300 */ 798, 798, 1062, 798, 798, 798, 798, 798, 798, 798, + /* 310 */ 798, 798, 798, 798, 798, 798, 798, 798, 798, 798, + /* 320 */ 879, 798, 826, 824, 798, 815, 798, }; /********** End of lemon-generated parsing tables *****************************/ @@ -597,6 +603,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* VARIABLE => nothing */ 0, /* INTERVAL => nothing */ 0, /* SESSION => nothing */ + 0, /* STATE_WINDOW => nothing */ 0, /* FILL => nothing */ 0, /* SLIDING => nothing */ 0, /* ORDER => nothing */ @@ -870,149 +877,152 @@ static const char *const yyTokenName[] = { /* 117 */ "VARIABLE", /* 118 */ "INTERVAL", /* 119 */ "SESSION", - /* 120 */ "FILL", - /* 121 */ "SLIDING", - /* 122 */ "ORDER", - /* 123 */ "BY", - /* 124 */ "ASC", - /* 125 */ "DESC", - /* 126 */ "GROUP", - /* 127 */ "HAVING", - /* 128 */ "LIMIT", - /* 129 */ "OFFSET", - /* 130 */ "SLIMIT", - /* 131 */ "SOFFSET", - /* 132 */ "WHERE", - /* 133 */ "NOW", - /* 134 */ "RESET", - /* 135 */ "QUERY", - /* 136 */ "SYNCDB", - /* 137 */ "ADD", - /* 138 */ "COLUMN", - /* 139 */ "TAG", - /* 140 */ "CHANGE", - /* 141 */ "SET", - /* 142 */ "KILL", - /* 143 */ "CONNECTION", - /* 144 */ "STREAM", - /* 145 */ "COLON", - /* 146 */ "ABORT", - /* 147 */ "AFTER", - /* 148 */ "ATTACH", - /* 149 */ "BEFORE", - /* 150 */ "BEGIN", - /* 151 */ "CASCADE", - /* 152 */ "CLUSTER", - /* 153 */ "CONFLICT", - /* 154 */ "COPY", - /* 155 */ "DEFERRED", - /* 156 */ "DELIMITERS", - /* 157 */ "DETACH", - /* 158 */ "EACH", - /* 159 */ "END", - /* 160 */ "EXPLAIN", - /* 161 */ "FAIL", - /* 162 */ "FOR", - /* 163 */ "IGNORE", - /* 164 */ "IMMEDIATE", - /* 165 */ "INITIALLY", - /* 166 */ "INSTEAD", - /* 167 */ "MATCH", - /* 168 */ "KEY", - /* 169 */ "OF", - /* 170 */ "RAISE", - /* 171 */ "REPLACE", - /* 172 */ "RESTRICT", - /* 173 */ "ROW", - /* 174 */ "STATEMENT", - /* 175 */ "TRIGGER", - /* 176 */ "VIEW", - /* 177 */ "SEMI", - /* 178 */ "NONE", - /* 179 */ "PREV", - /* 180 */ "LINEAR", - /* 181 */ "IMPORT", - /* 182 */ "TBNAME", - /* 183 */ "JOIN", - /* 184 */ "INSERT", - /* 185 */ "INTO", - /* 186 */ "VALUES", - /* 187 */ "error", - /* 188 */ "program", - /* 189 */ "cmd", - /* 190 */ "dbPrefix", - /* 191 */ "ids", - /* 192 */ "cpxName", - /* 193 */ "ifexists", - /* 194 */ "alter_db_optr", - /* 195 */ "alter_topic_optr", - /* 196 */ "acct_optr", - /* 197 */ "ifnotexists", - /* 198 */ "db_optr", - /* 199 */ "topic_optr", - /* 200 */ "pps", - /* 201 */ "tseries", - /* 202 */ "dbs", - /* 203 */ "streams", - /* 204 */ "storage", - /* 205 */ "qtime", - /* 206 */ "users", - /* 207 */ "conns", - /* 208 */ "state", - /* 209 */ "keep", - /* 210 */ "tagitemlist", - /* 211 */ "cache", - /* 212 */ "replica", - /* 213 */ "quorum", - /* 214 */ "days", - /* 215 */ "minrows", - /* 216 */ "maxrows", - /* 217 */ "blocks", - /* 218 */ "ctime", - /* 219 */ "wal", - /* 220 */ "fsync", - /* 221 */ "comp", - /* 222 */ "prec", - /* 223 */ "update", - /* 224 */ "cachelast", - /* 225 */ "partitions", - /* 226 */ "typename", - /* 227 */ "signed", - /* 228 */ "create_table_args", - /* 229 */ "create_stable_args", - /* 230 */ "create_table_list", - /* 231 */ "create_from_stable", - /* 232 */ "columnlist", - /* 233 */ "tagNamelist", - /* 234 */ "select", - /* 235 */ "column", - /* 236 */ "tagitem", - /* 237 */ "selcollist", - /* 238 */ "from", - /* 239 */ "where_opt", - /* 240 */ "interval_opt", - /* 241 */ "session_option", - /* 242 */ "fill_opt", - /* 243 */ "sliding_opt", - /* 244 */ "groupby_opt", - /* 245 */ "orderby_opt", - /* 246 */ "having_opt", - /* 247 */ "slimit_opt", - /* 248 */ "limit_opt", - /* 249 */ "union", - /* 250 */ "sclp", - /* 251 */ "distinct", - /* 252 */ "expr", - /* 253 */ "as", - /* 254 */ "tablelist", - /* 255 */ "tmvar", - /* 256 */ "sortlist", - /* 257 */ "sortitem", - /* 258 */ "item", - /* 259 */ "sortorder", - /* 260 */ "grouplist", - /* 261 */ "exprlist", - /* 262 */ "expritem", + /* 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 */ "sub", + /* 258 */ "tmvar", + /* 259 */ "sortlist", + /* 260 */ "sortitem", + /* 261 */ "item", + /* 262 */ "sortorder", + /* 263 */ "grouplist", + /* 264 */ "exprlist", + /* 265 */ "expritem", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -1177,7 +1187,7 @@ static const char *const yyRuleName[] = { /* 154 */ "tagitem ::= MINUS FLOAT", /* 155 */ "tagitem ::= PLUS INTEGER", /* 156 */ "tagitem ::= PLUS FLOAT", - /* 157 */ "select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt", + /* 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", /* 158 */ "select ::= LP select RP", /* 159 */ "union ::= select", /* 160 */ "union ::= union UNION ALL select", @@ -1193,103 +1203,108 @@ 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 */ "fill_opt ::=", - /* 185 */ "fill_opt ::= FILL LP ID COMMA tagitemlist RP", - /* 186 */ "fill_opt ::= FILL LP ID RP", - /* 187 */ "sliding_opt ::= SLIDING LP tmvar RP", - /* 188 */ "sliding_opt ::=", - /* 189 */ "orderby_opt ::=", - /* 190 */ "orderby_opt ::= ORDER BY sortlist", - /* 191 */ "sortlist ::= sortlist COMMA item sortorder", - /* 192 */ "sortlist ::= item sortorder", - /* 193 */ "item ::= ids cpxName", - /* 194 */ "sortorder ::= ASC", - /* 195 */ "sortorder ::= DESC", - /* 196 */ "sortorder ::=", - /* 197 */ "groupby_opt ::=", - /* 198 */ "groupby_opt ::= GROUP BY grouplist", - /* 199 */ "grouplist ::= grouplist COMMA item", - /* 200 */ "grouplist ::= item", - /* 201 */ "having_opt ::=", - /* 202 */ "having_opt ::= HAVING expr", - /* 203 */ "limit_opt ::=", - /* 204 */ "limit_opt ::= LIMIT signed", - /* 205 */ "limit_opt ::= LIMIT signed OFFSET signed", - /* 206 */ "limit_opt ::= LIMIT signed COMMA signed", - /* 207 */ "slimit_opt ::=", - /* 208 */ "slimit_opt ::= SLIMIT signed", - /* 209 */ "slimit_opt ::= SLIMIT signed SOFFSET signed", - /* 210 */ "slimit_opt ::= SLIMIT signed COMMA signed", - /* 211 */ "where_opt ::=", - /* 212 */ "where_opt ::= WHERE expr", - /* 213 */ "expr ::= LP expr RP", - /* 214 */ "expr ::= ID", - /* 215 */ "expr ::= ID DOT ID", - /* 216 */ "expr ::= ID DOT STAR", - /* 217 */ "expr ::= INTEGER", - /* 218 */ "expr ::= MINUS INTEGER", - /* 219 */ "expr ::= PLUS INTEGER", - /* 220 */ "expr ::= FLOAT", - /* 221 */ "expr ::= MINUS FLOAT", - /* 222 */ "expr ::= PLUS FLOAT", - /* 223 */ "expr ::= STRING", - /* 224 */ "expr ::= NOW", - /* 225 */ "expr ::= VARIABLE", - /* 226 */ "expr ::= PLUS VARIABLE", - /* 227 */ "expr ::= MINUS VARIABLE", - /* 228 */ "expr ::= BOOL", - /* 229 */ "expr ::= NULL", - /* 230 */ "expr ::= ID LP exprlist RP", - /* 231 */ "expr ::= ID LP STAR RP", - /* 232 */ "expr ::= expr IS NULL", - /* 233 */ "expr ::= expr IS NOT NULL", - /* 234 */ "expr ::= expr LT expr", - /* 235 */ "expr ::= expr GT expr", - /* 236 */ "expr ::= expr LE expr", - /* 237 */ "expr ::= expr GE expr", - /* 238 */ "expr ::= expr NE expr", - /* 239 */ "expr ::= expr EQ expr", - /* 240 */ "expr ::= expr BETWEEN expr AND expr", - /* 241 */ "expr ::= expr AND expr", - /* 242 */ "expr ::= expr OR expr", - /* 243 */ "expr ::= expr PLUS expr", - /* 244 */ "expr ::= expr MINUS expr", - /* 245 */ "expr ::= expr STAR expr", - /* 246 */ "expr ::= expr SLASH expr", - /* 247 */ "expr ::= expr REM expr", - /* 248 */ "expr ::= expr LIKE expr", - /* 249 */ "expr ::= expr IN LP exprlist RP", - /* 250 */ "exprlist ::= exprlist COMMA expritem", - /* 251 */ "exprlist ::= expritem", - /* 252 */ "expritem ::= expr", - /* 253 */ "expritem ::=", - /* 254 */ "cmd ::= RESET QUERY CACHE", - /* 255 */ "cmd ::= SYNCDB ids REPLICA", - /* 256 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", - /* 257 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", - /* 258 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", - /* 259 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", - /* 260 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", - /* 261 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", - /* 262 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", - /* 263 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", - /* 264 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", - /* 265 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", - /* 266 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", - /* 267 */ "cmd ::= KILL CONNECTION INTEGER", - /* 268 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", - /* 269 */ "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 */ @@ -1410,58 +1425,59 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 209: /* keep */ - case 210: /* tagitemlist */ - case 232: /* columnlist */ - case 233: /* tagNamelist */ - case 242: /* fill_opt */ - case 244: /* groupby_opt */ - case 245: /* orderby_opt */ - case 256: /* sortlist */ - case 260: /* grouplist */ + case 210: /* keep */ + case 211: /* tagitemlist */ + case 233: /* columnlist */ + case 234: /* tagNamelist */ + case 244: /* fill_opt */ + case 246: /* groupby_opt */ + case 247: /* orderby_opt */ + case 259: /* sortlist */ + case 263: /* grouplist */ { -taosArrayDestroy((yypminor->yy159)); +taosArrayDestroy((yypminor->yy193)); } break; - case 230: /* create_table_list */ + case 231: /* create_table_list */ { -destroyCreateTableSql((yypminor->yy14)); +destroyCreateTableSql((yypminor->yy270)); } break; - case 234: /* select */ + case 235: /* select */ { -destroySqlNode((yypminor->yy116)); +destroySqlNode((yypminor->yy124)); } break; - case 237: /* selcollist */ - case 250: /* sclp */ - case 261: /* exprlist */ + case 238: /* selcollist */ + case 252: /* sclp */ + case 264: /* exprlist */ { -tSqlExprListDestroy((yypminor->yy159)); +tSqlExprListDestroy((yypminor->yy193)); } break; - case 238: /* from */ - case 254: /* tablelist */ + case 239: /* from */ + case 256: /* tablelist */ + case 257: /* sub */ { -destroyRelationInfo((yypminor->yy236)); +destroyRelationInfo((yypminor->yy332)); } break; - case 239: /* where_opt */ - case 246: /* having_opt */ - case 252: /* expr */ - case 262: /* expritem */ + case 240: /* where_opt */ + case 248: /* having_opt */ + case 254: /* expr */ + case 265: /* expritem */ { -tSqlExprDestroy((yypminor->yy118)); +tSqlExprDestroy((yypminor->yy454)); } break; - case 249: /* union */ + case 251: /* union */ { -destroyAllSqlNode((yypminor->yy159)); +destroyAllSqlNode((yypminor->yy193)); } break; - case 257: /* sortitem */ + case 260: /* sortitem */ { -tVariantDestroy(&(yypminor->yy488)); +tVariantDestroy(&(yypminor->yy442)); } break; /********* End destructor definitions *****************************************/ @@ -1755,276 +1771,281 @@ 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 */ } yyRuleInfo[] = { - { 188, -1 }, /* (0) program ::= cmd */ - { 189, -2 }, /* (1) cmd ::= SHOW DATABASES */ - { 189, -2 }, /* (2) cmd ::= SHOW TOPICS */ - { 189, -2 }, /* (3) cmd ::= SHOW MNODES */ - { 189, -2 }, /* (4) cmd ::= SHOW DNODES */ - { 189, -2 }, /* (5) cmd ::= SHOW ACCOUNTS */ - { 189, -2 }, /* (6) cmd ::= SHOW USERS */ - { 189, -2 }, /* (7) cmd ::= SHOW MODULES */ - { 189, -2 }, /* (8) cmd ::= SHOW QUERIES */ - { 189, -2 }, /* (9) cmd ::= SHOW CONNECTIONS */ - { 189, -2 }, /* (10) cmd ::= SHOW STREAMS */ - { 189, -2 }, /* (11) cmd ::= SHOW VARIABLES */ - { 189, -2 }, /* (12) cmd ::= SHOW SCORES */ - { 189, -2 }, /* (13) cmd ::= SHOW GRANTS */ - { 189, -2 }, /* (14) cmd ::= SHOW VNODES */ - { 189, -3 }, /* (15) cmd ::= SHOW VNODES IPTOKEN */ - { 190, 0 }, /* (16) dbPrefix ::= */ - { 190, -2 }, /* (17) dbPrefix ::= ids DOT */ - { 192, 0 }, /* (18) cpxName ::= */ - { 192, -2 }, /* (19) cpxName ::= DOT ids */ - { 189, -5 }, /* (20) cmd ::= SHOW CREATE TABLE ids cpxName */ - { 189, -5 }, /* (21) cmd ::= SHOW CREATE STABLE ids cpxName */ - { 189, -4 }, /* (22) cmd ::= SHOW CREATE DATABASE ids */ - { 189, -3 }, /* (23) cmd ::= SHOW dbPrefix TABLES */ - { 189, -5 }, /* (24) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - { 189, -3 }, /* (25) cmd ::= SHOW dbPrefix STABLES */ - { 189, -5 }, /* (26) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - { 189, -3 }, /* (27) cmd ::= SHOW dbPrefix VGROUPS */ - { 189, -4 }, /* (28) cmd ::= SHOW dbPrefix VGROUPS ids */ - { 189, -5 }, /* (29) cmd ::= DROP TABLE ifexists ids cpxName */ - { 189, -5 }, /* (30) cmd ::= DROP STABLE ifexists ids cpxName */ - { 189, -4 }, /* (31) cmd ::= DROP DATABASE ifexists ids */ - { 189, -4 }, /* (32) cmd ::= DROP TOPIC ifexists ids */ - { 189, -3 }, /* (33) cmd ::= DROP DNODE ids */ - { 189, -3 }, /* (34) cmd ::= DROP USER ids */ - { 189, -3 }, /* (35) cmd ::= DROP ACCOUNT ids */ - { 189, -2 }, /* (36) cmd ::= USE ids */ - { 189, -3 }, /* (37) cmd ::= DESCRIBE ids cpxName */ - { 189, -5 }, /* (38) cmd ::= ALTER USER ids PASS ids */ - { 189, -5 }, /* (39) cmd ::= ALTER USER ids PRIVILEGE ids */ - { 189, -4 }, /* (40) cmd ::= ALTER DNODE ids ids */ - { 189, -5 }, /* (41) cmd ::= ALTER DNODE ids ids ids */ - { 189, -3 }, /* (42) cmd ::= ALTER LOCAL ids */ - { 189, -4 }, /* (43) cmd ::= ALTER LOCAL ids ids */ - { 189, -4 }, /* (44) cmd ::= ALTER DATABASE ids alter_db_optr */ - { 189, -4 }, /* (45) cmd ::= ALTER TOPIC ids alter_topic_optr */ - { 189, -4 }, /* (46) cmd ::= ALTER ACCOUNT ids acct_optr */ - { 189, -6 }, /* (47) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - { 191, -1 }, /* (48) ids ::= ID */ - { 191, -1 }, /* (49) ids ::= STRING */ - { 193, -2 }, /* (50) ifexists ::= IF EXISTS */ - { 193, 0 }, /* (51) ifexists ::= */ - { 197, -3 }, /* (52) ifnotexists ::= IF NOT EXISTS */ - { 197, 0 }, /* (53) ifnotexists ::= */ - { 189, -3 }, /* (54) cmd ::= CREATE DNODE ids */ - { 189, -6 }, /* (55) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - { 189, -5 }, /* (56) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - { 189, -5 }, /* (57) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - { 189, -5 }, /* (58) cmd ::= CREATE USER ids PASS ids */ - { 200, 0 }, /* (59) pps ::= */ - { 200, -2 }, /* (60) pps ::= PPS INTEGER */ - { 201, 0 }, /* (61) tseries ::= */ - { 201, -2 }, /* (62) tseries ::= TSERIES INTEGER */ - { 202, 0 }, /* (63) dbs ::= */ - { 202, -2 }, /* (64) dbs ::= DBS INTEGER */ - { 203, 0 }, /* (65) streams ::= */ - { 203, -2 }, /* (66) streams ::= STREAMS INTEGER */ - { 204, 0 }, /* (67) storage ::= */ - { 204, -2 }, /* (68) storage ::= STORAGE INTEGER */ - { 205, 0 }, /* (69) qtime ::= */ - { 205, -2 }, /* (70) qtime ::= QTIME INTEGER */ - { 206, 0 }, /* (71) users ::= */ - { 206, -2 }, /* (72) users ::= USERS INTEGER */ - { 207, 0 }, /* (73) conns ::= */ - { 207, -2 }, /* (74) conns ::= CONNS INTEGER */ - { 208, 0 }, /* (75) state ::= */ - { 208, -2 }, /* (76) state ::= STATE ids */ - { 196, -9 }, /* (77) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - { 209, -2 }, /* (78) keep ::= KEEP tagitemlist */ - { 211, -2 }, /* (79) cache ::= CACHE INTEGER */ - { 212, -2 }, /* (80) replica ::= REPLICA INTEGER */ - { 213, -2 }, /* (81) quorum ::= QUORUM INTEGER */ - { 214, -2 }, /* (82) days ::= DAYS INTEGER */ - { 215, -2 }, /* (83) minrows ::= MINROWS INTEGER */ - { 216, -2 }, /* (84) maxrows ::= MAXROWS INTEGER */ - { 217, -2 }, /* (85) blocks ::= BLOCKS INTEGER */ - { 218, -2 }, /* (86) ctime ::= CTIME INTEGER */ - { 219, -2 }, /* (87) wal ::= WAL INTEGER */ - { 220, -2 }, /* (88) fsync ::= FSYNC INTEGER */ - { 221, -2 }, /* (89) comp ::= COMP INTEGER */ - { 222, -2 }, /* (90) prec ::= PRECISION STRING */ - { 223, -2 }, /* (91) update ::= UPDATE INTEGER */ - { 224, -2 }, /* (92) cachelast ::= CACHELAST INTEGER */ - { 225, -2 }, /* (93) partitions ::= PARTITIONS INTEGER */ - { 198, 0 }, /* (94) db_optr ::= */ - { 198, -2 }, /* (95) db_optr ::= db_optr cache */ - { 198, -2 }, /* (96) db_optr ::= db_optr replica */ - { 198, -2 }, /* (97) db_optr ::= db_optr quorum */ - { 198, -2 }, /* (98) db_optr ::= db_optr days */ - { 198, -2 }, /* (99) db_optr ::= db_optr minrows */ - { 198, -2 }, /* (100) db_optr ::= db_optr maxrows */ - { 198, -2 }, /* (101) db_optr ::= db_optr blocks */ - { 198, -2 }, /* (102) db_optr ::= db_optr ctime */ - { 198, -2 }, /* (103) db_optr ::= db_optr wal */ - { 198, -2 }, /* (104) db_optr ::= db_optr fsync */ - { 198, -2 }, /* (105) db_optr ::= db_optr comp */ - { 198, -2 }, /* (106) db_optr ::= db_optr prec */ - { 198, -2 }, /* (107) db_optr ::= db_optr keep */ - { 198, -2 }, /* (108) db_optr ::= db_optr update */ - { 198, -2 }, /* (109) db_optr ::= db_optr cachelast */ - { 199, -1 }, /* (110) topic_optr ::= db_optr */ - { 199, -2 }, /* (111) topic_optr ::= topic_optr partitions */ - { 194, 0 }, /* (112) alter_db_optr ::= */ - { 194, -2 }, /* (113) alter_db_optr ::= alter_db_optr replica */ - { 194, -2 }, /* (114) alter_db_optr ::= alter_db_optr quorum */ - { 194, -2 }, /* (115) alter_db_optr ::= alter_db_optr keep */ - { 194, -2 }, /* (116) alter_db_optr ::= alter_db_optr blocks */ - { 194, -2 }, /* (117) alter_db_optr ::= alter_db_optr comp */ - { 194, -2 }, /* (118) alter_db_optr ::= alter_db_optr wal */ - { 194, -2 }, /* (119) alter_db_optr ::= alter_db_optr fsync */ - { 194, -2 }, /* (120) alter_db_optr ::= alter_db_optr update */ - { 194, -2 }, /* (121) alter_db_optr ::= alter_db_optr cachelast */ - { 195, -1 }, /* (122) alter_topic_optr ::= alter_db_optr */ - { 195, -2 }, /* (123) alter_topic_optr ::= alter_topic_optr partitions */ - { 226, -1 }, /* (124) typename ::= ids */ - { 226, -4 }, /* (125) typename ::= ids LP signed RP */ - { 226, -2 }, /* (126) typename ::= ids UNSIGNED */ - { 227, -1 }, /* (127) signed ::= INTEGER */ - { 227, -2 }, /* (128) signed ::= PLUS INTEGER */ - { 227, -2 }, /* (129) signed ::= MINUS INTEGER */ - { 189, -3 }, /* (130) cmd ::= CREATE TABLE create_table_args */ - { 189, -3 }, /* (131) cmd ::= CREATE TABLE create_stable_args */ - { 189, -3 }, /* (132) cmd ::= CREATE STABLE create_stable_args */ - { 189, -3 }, /* (133) cmd ::= CREATE TABLE create_table_list */ - { 230, -1 }, /* (134) create_table_list ::= create_from_stable */ - { 230, -2 }, /* (135) create_table_list ::= create_table_list create_from_stable */ - { 228, -6 }, /* (136) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - { 229, -10 }, /* (137) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - { 231, -10 }, /* (138) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - { 231, -13 }, /* (139) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - { 233, -3 }, /* (140) tagNamelist ::= tagNamelist COMMA ids */ - { 233, -1 }, /* (141) tagNamelist ::= ids */ - { 228, -5 }, /* (142) create_table_args ::= ifnotexists ids cpxName AS select */ - { 232, -3 }, /* (143) columnlist ::= columnlist COMMA column */ - { 232, -1 }, /* (144) columnlist ::= column */ - { 235, -2 }, /* (145) column ::= ids typename */ - { 210, -3 }, /* (146) tagitemlist ::= tagitemlist COMMA tagitem */ - { 210, -1 }, /* (147) tagitemlist ::= tagitem */ - { 236, -1 }, /* (148) tagitem ::= INTEGER */ - { 236, -1 }, /* (149) tagitem ::= FLOAT */ - { 236, -1 }, /* (150) tagitem ::= STRING */ - { 236, -1 }, /* (151) tagitem ::= BOOL */ - { 236, -1 }, /* (152) tagitem ::= NULL */ - { 236, -2 }, /* (153) tagitem ::= MINUS INTEGER */ - { 236, -2 }, /* (154) tagitem ::= MINUS FLOAT */ - { 236, -2 }, /* (155) tagitem ::= PLUS INTEGER */ - { 236, -2 }, /* (156) tagitem ::= PLUS FLOAT */ - { 234, -13 }, /* (157) select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ - { 234, -3 }, /* (158) select ::= LP select RP */ - { 249, -1 }, /* (159) union ::= select */ - { 249, -4 }, /* (160) union ::= union UNION ALL select */ - { 189, -1 }, /* (161) cmd ::= union */ - { 234, -2 }, /* (162) select ::= SELECT selcollist */ - { 250, -2 }, /* (163) sclp ::= selcollist COMMA */ - { 250, 0 }, /* (164) sclp ::= */ - { 237, -4 }, /* (165) selcollist ::= sclp distinct expr as */ - { 237, -2 }, /* (166) selcollist ::= sclp STAR */ - { 253, -2 }, /* (167) as ::= AS ids */ - { 253, -1 }, /* (168) as ::= ids */ - { 253, 0 }, /* (169) as ::= */ - { 251, -1 }, /* (170) distinct ::= DISTINCT */ - { 251, 0 }, /* (171) distinct ::= */ - { 238, -2 }, /* (172) from ::= FROM tablelist */ - { 238, -4 }, /* (173) from ::= FROM LP union RP */ - { 254, -2 }, /* (174) tablelist ::= ids cpxName */ - { 254, -3 }, /* (175) tablelist ::= ids cpxName ids */ - { 254, -4 }, /* (176) tablelist ::= tablelist COMMA ids cpxName */ - { 254, -5 }, /* (177) tablelist ::= tablelist COMMA ids cpxName ids */ - { 255, -1 }, /* (178) tmvar ::= VARIABLE */ - { 240, -4 }, /* (179) interval_opt ::= INTERVAL LP tmvar RP */ - { 240, -6 }, /* (180) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ - { 240, 0 }, /* (181) interval_opt ::= */ - { 241, 0 }, /* (182) session_option ::= */ - { 241, -7 }, /* (183) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - { 242, 0 }, /* (184) fill_opt ::= */ - { 242, -6 }, /* (185) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - { 242, -4 }, /* (186) fill_opt ::= FILL LP ID RP */ - { 243, -4 }, /* (187) sliding_opt ::= SLIDING LP tmvar RP */ - { 243, 0 }, /* (188) sliding_opt ::= */ - { 245, 0 }, /* (189) orderby_opt ::= */ - { 245, -3 }, /* (190) orderby_opt ::= ORDER BY sortlist */ - { 256, -4 }, /* (191) sortlist ::= sortlist COMMA item sortorder */ - { 256, -2 }, /* (192) sortlist ::= item sortorder */ - { 258, -2 }, /* (193) item ::= ids cpxName */ - { 259, -1 }, /* (194) sortorder ::= ASC */ - { 259, -1 }, /* (195) sortorder ::= DESC */ - { 259, 0 }, /* (196) sortorder ::= */ - { 244, 0 }, /* (197) groupby_opt ::= */ - { 244, -3 }, /* (198) groupby_opt ::= GROUP BY grouplist */ - { 260, -3 }, /* (199) grouplist ::= grouplist COMMA item */ - { 260, -1 }, /* (200) grouplist ::= item */ - { 246, 0 }, /* (201) having_opt ::= */ - { 246, -2 }, /* (202) having_opt ::= HAVING expr */ - { 248, 0 }, /* (203) limit_opt ::= */ - { 248, -2 }, /* (204) limit_opt ::= LIMIT signed */ - { 248, -4 }, /* (205) limit_opt ::= LIMIT signed OFFSET signed */ - { 248, -4 }, /* (206) limit_opt ::= LIMIT signed COMMA signed */ - { 247, 0 }, /* (207) slimit_opt ::= */ - { 247, -2 }, /* (208) slimit_opt ::= SLIMIT signed */ - { 247, -4 }, /* (209) slimit_opt ::= SLIMIT signed SOFFSET signed */ - { 247, -4 }, /* (210) slimit_opt ::= SLIMIT signed COMMA signed */ - { 239, 0 }, /* (211) where_opt ::= */ - { 239, -2 }, /* (212) where_opt ::= WHERE expr */ - { 252, -3 }, /* (213) expr ::= LP expr RP */ - { 252, -1 }, /* (214) expr ::= ID */ - { 252, -3 }, /* (215) expr ::= ID DOT ID */ - { 252, -3 }, /* (216) expr ::= ID DOT STAR */ - { 252, -1 }, /* (217) expr ::= INTEGER */ - { 252, -2 }, /* (218) expr ::= MINUS INTEGER */ - { 252, -2 }, /* (219) expr ::= PLUS INTEGER */ - { 252, -1 }, /* (220) expr ::= FLOAT */ - { 252, -2 }, /* (221) expr ::= MINUS FLOAT */ - { 252, -2 }, /* (222) expr ::= PLUS FLOAT */ - { 252, -1 }, /* (223) expr ::= STRING */ - { 252, -1 }, /* (224) expr ::= NOW */ - { 252, -1 }, /* (225) expr ::= VARIABLE */ - { 252, -2 }, /* (226) expr ::= PLUS VARIABLE */ - { 252, -2 }, /* (227) expr ::= MINUS VARIABLE */ - { 252, -1 }, /* (228) expr ::= BOOL */ - { 252, -1 }, /* (229) expr ::= NULL */ - { 252, -4 }, /* (230) expr ::= ID LP exprlist RP */ - { 252, -4 }, /* (231) expr ::= ID LP STAR RP */ - { 252, -3 }, /* (232) expr ::= expr IS NULL */ - { 252, -4 }, /* (233) expr ::= expr IS NOT NULL */ - { 252, -3 }, /* (234) expr ::= expr LT expr */ - { 252, -3 }, /* (235) expr ::= expr GT expr */ - { 252, -3 }, /* (236) expr ::= expr LE expr */ - { 252, -3 }, /* (237) expr ::= expr GE expr */ - { 252, -3 }, /* (238) expr ::= expr NE expr */ - { 252, -3 }, /* (239) expr ::= expr EQ expr */ - { 252, -5 }, /* (240) expr ::= expr BETWEEN expr AND expr */ - { 252, -3 }, /* (241) expr ::= expr AND expr */ - { 252, -3 }, /* (242) expr ::= expr OR expr */ - { 252, -3 }, /* (243) expr ::= expr PLUS expr */ - { 252, -3 }, /* (244) expr ::= expr MINUS expr */ - { 252, -3 }, /* (245) expr ::= expr STAR expr */ - { 252, -3 }, /* (246) expr ::= expr SLASH expr */ - { 252, -3 }, /* (247) expr ::= expr REM expr */ - { 252, -3 }, /* (248) expr ::= expr LIKE expr */ - { 252, -5 }, /* (249) expr ::= expr IN LP exprlist RP */ - { 261, -3 }, /* (250) exprlist ::= exprlist COMMA expritem */ - { 261, -1 }, /* (251) exprlist ::= expritem */ - { 262, -1 }, /* (252) expritem ::= expr */ - { 262, 0 }, /* (253) expritem ::= */ - { 189, -3 }, /* (254) cmd ::= RESET QUERY CACHE */ - { 189, -3 }, /* (255) cmd ::= SYNCDB ids REPLICA */ - { 189, -7 }, /* (256) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - { 189, -7 }, /* (257) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - { 189, -7 }, /* (258) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - { 189, -7 }, /* (259) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - { 189, -8 }, /* (260) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - { 189, -9 }, /* (261) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - { 189, -7 }, /* (262) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - { 189, -7 }, /* (263) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - { 189, -7 }, /* (264) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - { 189, -7 }, /* (265) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - { 189, -8 }, /* (266) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - { 189, -3 }, /* (267) cmd ::= KILL CONNECTION INTEGER */ - { 189, -5 }, /* (268) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - { 189, -5 }, /* (269) cmd ::= KILL QUERY INTEGER COLON INTEGER */ + { 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, -2 }, /* (173) from ::= FROM sub */ + { 257, -3 }, /* (174) sub ::= LP union RP */ + { 257, -4 }, /* (175) sub ::= LP union RP ids */ + { 257, -6 }, /* (176) sub ::= sub COMMA LP union RP ids */ + { 256, -2 }, /* (177) tablelist ::= ids cpxName */ + { 256, -3 }, /* (178) tablelist ::= ids cpxName ids */ + { 256, -4 }, /* (179) tablelist ::= tablelist COMMA ids cpxName */ + { 256, -5 }, /* (180) tablelist ::= tablelist COMMA ids cpxName ids */ + { 258, -1 }, /* (181) tmvar ::= VARIABLE */ + { 241, -4 }, /* (182) interval_opt ::= INTERVAL LP tmvar RP */ + { 241, -6 }, /* (183) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ + { 241, 0 }, /* (184) interval_opt ::= */ + { 242, 0 }, /* (185) session_option ::= */ + { 242, -7 }, /* (186) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ + { 243, 0 }, /* (187) windowstate_option ::= */ + { 243, -4 }, /* (188) windowstate_option ::= STATE_WINDOW LP ids RP */ + { 244, 0 }, /* (189) fill_opt ::= */ + { 244, -6 }, /* (190) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ + { 244, -4 }, /* (191) fill_opt ::= FILL LP ID RP */ + { 245, -4 }, /* (192) sliding_opt ::= SLIDING LP tmvar RP */ + { 245, 0 }, /* (193) sliding_opt ::= */ + { 247, 0 }, /* (194) orderby_opt ::= */ + { 247, -3 }, /* (195) orderby_opt ::= ORDER BY sortlist */ + { 259, -4 }, /* (196) sortlist ::= sortlist COMMA item sortorder */ + { 259, -2 }, /* (197) sortlist ::= item sortorder */ + { 261, -2 }, /* (198) item ::= ids cpxName */ + { 262, -1 }, /* (199) sortorder ::= ASC */ + { 262, -1 }, /* (200) sortorder ::= DESC */ + { 262, 0 }, /* (201) sortorder ::= */ + { 246, 0 }, /* (202) groupby_opt ::= */ + { 246, -3 }, /* (203) groupby_opt ::= GROUP BY grouplist */ + { 263, -3 }, /* (204) grouplist ::= grouplist COMMA item */ + { 263, -1 }, /* (205) grouplist ::= item */ + { 248, 0 }, /* (206) having_opt ::= */ + { 248, -2 }, /* (207) having_opt ::= HAVING expr */ + { 250, 0 }, /* (208) limit_opt ::= */ + { 250, -2 }, /* (209) limit_opt ::= LIMIT signed */ + { 250, -4 }, /* (210) limit_opt ::= LIMIT signed OFFSET signed */ + { 250, -4 }, /* (211) limit_opt ::= LIMIT signed COMMA signed */ + { 249, 0 }, /* (212) slimit_opt ::= */ + { 249, -2 }, /* (213) slimit_opt ::= SLIMIT signed */ + { 249, -4 }, /* (214) slimit_opt ::= SLIMIT signed SOFFSET signed */ + { 249, -4 }, /* (215) slimit_opt ::= SLIMIT signed COMMA signed */ + { 240, 0 }, /* (216) where_opt ::= */ + { 240, -2 }, /* (217) where_opt ::= WHERE expr */ + { 254, -3 }, /* (218) expr ::= LP expr RP */ + { 254, -1 }, /* (219) expr ::= ID */ + { 254, -3 }, /* (220) expr ::= ID DOT ID */ + { 254, -3 }, /* (221) expr ::= ID DOT STAR */ + { 254, -1 }, /* (222) expr ::= INTEGER */ + { 254, -2 }, /* (223) expr ::= MINUS INTEGER */ + { 254, -2 }, /* (224) expr ::= PLUS INTEGER */ + { 254, -1 }, /* (225) expr ::= FLOAT */ + { 254, -2 }, /* (226) expr ::= MINUS FLOAT */ + { 254, -2 }, /* (227) expr ::= PLUS FLOAT */ + { 254, -1 }, /* (228) expr ::= STRING */ + { 254, -1 }, /* (229) expr ::= NOW */ + { 254, -1 }, /* (230) expr ::= VARIABLE */ + { 254, -2 }, /* (231) expr ::= PLUS VARIABLE */ + { 254, -2 }, /* (232) expr ::= MINUS VARIABLE */ + { 254, -1 }, /* (233) expr ::= BOOL */ + { 254, -1 }, /* (234) expr ::= NULL */ + { 254, -4 }, /* (235) expr ::= ID LP exprlist RP */ + { 254, -4 }, /* (236) expr ::= ID LP STAR RP */ + { 254, -3 }, /* (237) expr ::= expr IS NULL */ + { 254, -4 }, /* (238) expr ::= expr IS NOT NULL */ + { 254, -3 }, /* (239) expr ::= expr LT expr */ + { 254, -3 }, /* (240) expr ::= expr GT expr */ + { 254, -3 }, /* (241) expr ::= expr LE expr */ + { 254, -3 }, /* (242) expr ::= expr GE expr */ + { 254, -3 }, /* (243) expr ::= expr NE expr */ + { 254, -3 }, /* (244) expr ::= expr EQ expr */ + { 254, -5 }, /* (245) expr ::= expr BETWEEN expr AND expr */ + { 254, -3 }, /* (246) expr ::= expr AND expr */ + { 254, -3 }, /* (247) expr ::= expr OR expr */ + { 254, -3 }, /* (248) expr ::= expr PLUS expr */ + { 254, -3 }, /* (249) expr ::= expr MINUS expr */ + { 254, -3 }, /* (250) expr ::= expr STAR expr */ + { 254, -3 }, /* (251) expr ::= expr SLASH expr */ + { 254, -3 }, /* (252) expr ::= expr REM expr */ + { 254, -3 }, /* (253) expr ::= expr LIKE expr */ + { 254, -5 }, /* (254) expr ::= expr IN LP exprlist RP */ + { 264, -3 }, /* (255) exprlist ::= exprlist COMMA expritem */ + { 264, -1 }, /* (256) exprlist ::= expritem */ + { 265, -1 }, /* (257) expritem ::= expr */ + { 265, 0 }, /* (258) expritem ::= */ + { 190, -3 }, /* (259) cmd ::= RESET QUERY CACHE */ + { 190, -3 }, /* (260) cmd ::= SYNCDB ids REPLICA */ + { 190, -7 }, /* (261) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + { 190, -7 }, /* (262) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + { 190, -7 }, /* (263) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + { 190, -7 }, /* (264) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + { 190, -8 }, /* (265) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + { 190, -9 }, /* (266) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + { 190, -7 }, /* (267) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + { 190, -7 }, /* (268) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + { 190, -7 }, /* (269) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + { 190, -7 }, /* (270) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + { 190, -8 }, /* (271) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + { 190, -3 }, /* (272) cmd ::= KILL CONNECTION INTEGER */ + { 190, -5 }, /* (273) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + { 190, -5 }, /* (274) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -2277,13 +2298,13 @@ 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.yy322, &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.yy351);} +{ 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.yy351);} +{ 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); @@ -2305,11 +2326,11 @@ static void yy_reduce( { 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.yy351);} +{ 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.yy322, &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);} @@ -2338,20 +2359,20 @@ static void yy_reduce( break; case 77: /* acct_optr ::= pps tseries storage streams qtime dbs users conns state */ { - yylhsminor.yy351.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; - yylhsminor.yy351.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; - yylhsminor.yy351.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; - yylhsminor.yy351.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; - yylhsminor.yy351.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; - yylhsminor.yy351.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy351.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy351.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; - yylhsminor.yy351.stat = yymsp[0].minor.yy0; -} - yymsp[-8].minor.yy351 = yylhsminor.yy351; + yylhsminor.yy183.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; + yylhsminor.yy183.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; + yylhsminor.yy183.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; + yylhsminor.yy183.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; + yylhsminor.yy183.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; + yylhsminor.yy183.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy183.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy183.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; + yylhsminor.yy183.stat = yymsp[0].minor.yy0; +} + yymsp[-8].minor.yy183 = yylhsminor.yy183; break; case 78: /* keep ::= KEEP tagitemlist */ -{ yymsp[-1].minor.yy159 = yymsp[0].minor.yy159; } +{ yymsp[-1].minor.yy193 = yymsp[0].minor.yy193; } break; case 79: /* cache ::= CACHE INTEGER */ case 80: /* replica ::= REPLICA INTEGER */ yytestcase(yyruleno==80); @@ -2371,234 +2392,234 @@ static void yy_reduce( { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } break; case 94: /* db_optr ::= */ -{setDefaultCreateDbOption(&yymsp[1].minor.yy322); yymsp[1].minor.yy322.dbType = TSDB_DB_TYPE_DEFAULT;} +{setDefaultCreateDbOption(&yymsp[1].minor.yy114); yymsp[1].minor.yy114.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 95: /* db_optr ::= db_optr cache */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 96: /* db_optr ::= db_optr replica */ case 113: /* alter_db_optr ::= alter_db_optr replica */ yytestcase(yyruleno==113); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 97: /* db_optr ::= db_optr quorum */ case 114: /* alter_db_optr ::= alter_db_optr quorum */ yytestcase(yyruleno==114); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 98: /* db_optr ::= db_optr days */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 99: /* db_optr ::= db_optr minrows */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 100: /* db_optr ::= db_optr maxrows */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 101: /* db_optr ::= db_optr blocks */ case 116: /* alter_db_optr ::= alter_db_optr blocks */ yytestcase(yyruleno==116); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 102: /* db_optr ::= db_optr ctime */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 103: /* db_optr ::= db_optr wal */ case 118: /* alter_db_optr ::= alter_db_optr wal */ yytestcase(yyruleno==118); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 104: /* db_optr ::= db_optr fsync */ case 119: /* alter_db_optr ::= alter_db_optr fsync */ yytestcase(yyruleno==119); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 105: /* db_optr ::= db_optr comp */ case 117: /* alter_db_optr ::= alter_db_optr comp */ yytestcase(yyruleno==117); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 106: /* db_optr ::= db_optr prec */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.precision = yymsp[0].minor.yy0; } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.precision = yymsp[0].minor.yy0; } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 107: /* db_optr ::= db_optr keep */ case 115: /* alter_db_optr ::= alter_db_optr keep */ yytestcase(yyruleno==115); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.keep = yymsp[0].minor.yy159; } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.keep = yymsp[0].minor.yy193; } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 108: /* db_optr ::= db_optr update */ case 120: /* alter_db_optr ::= alter_db_optr update */ yytestcase(yyruleno==120); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 109: /* db_optr ::= db_optr cachelast */ case 121: /* alter_db_optr ::= alter_db_optr cachelast */ yytestcase(yyruleno==121); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 110: /* topic_optr ::= db_optr */ case 122: /* alter_topic_optr ::= alter_db_optr */ yytestcase(yyruleno==122); -{ yylhsminor.yy322 = yymsp[0].minor.yy322; yylhsminor.yy322.dbType = TSDB_DB_TYPE_TOPIC; } - yymsp[0].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[0].minor.yy114; yylhsminor.yy114.dbType = TSDB_DB_TYPE_TOPIC; } + yymsp[0].minor.yy114 = yylhsminor.yy114; break; case 111: /* topic_optr ::= topic_optr partitions */ case 123: /* alter_topic_optr ::= alter_topic_optr partitions */ yytestcase(yyruleno==123); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy114 = yymsp[-1].minor.yy114; yylhsminor.yy114.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy114 = yylhsminor.yy114; break; case 112: /* alter_db_optr ::= */ -{ setDefaultCreateDbOption(&yymsp[1].minor.yy322); yymsp[1].minor.yy322.dbType = TSDB_DB_TYPE_DEFAULT;} +{ setDefaultCreateDbOption(&yymsp[1].minor.yy114); yymsp[1].minor.yy114.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 124: /* typename ::= ids */ { yymsp[0].minor.yy0.type = 0; - tSetColumnType (&yylhsminor.yy407, &yymsp[0].minor.yy0); + tSetColumnType (&yylhsminor.yy27, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy407 = yylhsminor.yy407; + yymsp[0].minor.yy27 = yylhsminor.yy27; break; case 125: /* typename ::= ids LP signed RP */ { - if (yymsp[-1].minor.yy317 <= 0) { + if (yymsp[-1].minor.yy473 <= 0) { yymsp[-3].minor.yy0.type = 0; - tSetColumnType(&yylhsminor.yy407, &yymsp[-3].minor.yy0); + tSetColumnType(&yylhsminor.yy27, &yymsp[-3].minor.yy0); } else { - yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy317; // negative value of name length - tSetColumnType(&yylhsminor.yy407, &yymsp[-3].minor.yy0); + yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy473; // negative value of name length + tSetColumnType(&yylhsminor.yy27, &yymsp[-3].minor.yy0); } } - yymsp[-3].minor.yy407 = yylhsminor.yy407; + yymsp[-3].minor.yy27 = yylhsminor.yy27; 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.yy407, &yymsp[-1].minor.yy0); + tSetColumnType (&yylhsminor.yy27, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy407 = yylhsminor.yy407; + yymsp[-1].minor.yy27 = yylhsminor.yy27; break; case 127: /* signed ::= INTEGER */ -{ yylhsminor.yy317 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[0].minor.yy317 = yylhsminor.yy317; +{ yylhsminor.yy473 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[0].minor.yy473 = yylhsminor.yy473; break; case 128: /* signed ::= PLUS INTEGER */ -{ yymsp[-1].minor.yy317 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +{ yymsp[-1].minor.yy473 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 129: /* signed ::= MINUS INTEGER */ -{ yymsp[-1].minor.yy317 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} +{ yymsp[-1].minor.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.yy14;} +{ 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.yy206); + taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy192); pCreateTable->type = TSQL_CREATE_TABLE_FROM_STABLE; - yylhsminor.yy14 = pCreateTable; + yylhsminor.yy270 = pCreateTable; } - yymsp[0].minor.yy14 = yylhsminor.yy14; + yymsp[0].minor.yy270 = yylhsminor.yy270; break; case 135: /* create_table_list ::= create_table_list create_from_stable */ { - taosArrayPush(yymsp[-1].minor.yy14->childTableInfo, &yymsp[0].minor.yy206); - yylhsminor.yy14 = yymsp[-1].minor.yy14; + taosArrayPush(yymsp[-1].minor.yy270->childTableInfo, &yymsp[0].minor.yy192); + yylhsminor.yy270 = yymsp[-1].minor.yy270; } - yymsp[-1].minor.yy14 = yylhsminor.yy14; + yymsp[-1].minor.yy270 = yylhsminor.yy270; break; case 136: /* create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ { - yylhsminor.yy14 = tSetCreateTableInfo(yymsp[-1].minor.yy159, NULL, NULL, TSQL_CREATE_TABLE); - setSqlInfo(pInfo, yylhsminor.yy14, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy270 = tSetCreateTableInfo(yymsp[-1].minor.yy193, NULL, NULL, TSQL_CREATE_TABLE); + setSqlInfo(pInfo, yylhsminor.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.yy14 = yylhsminor.yy14; + yymsp[-5].minor.yy270 = yylhsminor.yy270; break; case 137: /* create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ { - yylhsminor.yy14 = tSetCreateTableInfo(yymsp[-5].minor.yy159, yymsp[-1].minor.yy159, NULL, TSQL_CREATE_STABLE); - setSqlInfo(pInfo, yylhsminor.yy14, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy270 = tSetCreateTableInfo(yymsp[-5].minor.yy193, yymsp[-1].minor.yy193, NULL, TSQL_CREATE_STABLE); + setSqlInfo(pInfo, yylhsminor.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.yy14 = yylhsminor.yy14; + yymsp[-9].minor.yy270 = yylhsminor.yy270; 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.yy206 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy159, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); + yylhsminor.yy192 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy193, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy206 = yylhsminor.yy206; + yymsp[-9].minor.yy192 = yylhsminor.yy192; 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.yy206 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy159, yymsp[-1].minor.yy159, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); + yylhsminor.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.yy206 = yylhsminor.yy206; + yymsp[-12].minor.yy192 = yylhsminor.yy192; break; case 140: /* tagNamelist ::= tagNamelist COMMA ids */ -{taosArrayPush(yymsp[-2].minor.yy159, &yymsp[0].minor.yy0); yylhsminor.yy159 = yymsp[-2].minor.yy159; } - yymsp[-2].minor.yy159 = yylhsminor.yy159; +{taosArrayPush(yymsp[-2].minor.yy193, &yymsp[0].minor.yy0); yylhsminor.yy193 = yymsp[-2].minor.yy193; } + yymsp[-2].minor.yy193 = yylhsminor.yy193; break; case 141: /* tagNamelist ::= ids */ -{yylhsminor.yy159 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy159, &yymsp[0].minor.yy0);} - yymsp[0].minor.yy159 = yylhsminor.yy159; +{yylhsminor.yy193 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy193, &yymsp[0].minor.yy0);} + yymsp[0].minor.yy193 = yylhsminor.yy193; break; case 142: /* create_table_args ::= ifnotexists ids cpxName AS select */ { - yylhsminor.yy14 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy116, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, yylhsminor.yy14, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy270 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy124, TSQL_CREATE_STREAM); + setSqlInfo(pInfo, yylhsminor.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.yy14 = yylhsminor.yy14; + yymsp[-4].minor.yy270 = yylhsminor.yy270; break; case 143: /* columnlist ::= columnlist COMMA column */ -{taosArrayPush(yymsp[-2].minor.yy159, &yymsp[0].minor.yy407); yylhsminor.yy159 = yymsp[-2].minor.yy159; } - yymsp[-2].minor.yy159 = yylhsminor.yy159; +{taosArrayPush(yymsp[-2].minor.yy193, &yymsp[0].minor.yy27); yylhsminor.yy193 = yymsp[-2].minor.yy193; } + yymsp[-2].minor.yy193 = yylhsminor.yy193; break; case 144: /* columnlist ::= column */ -{yylhsminor.yy159 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy159, &yymsp[0].minor.yy407);} - yymsp[0].minor.yy159 = yylhsminor.yy159; +{yylhsminor.yy193 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy193, &yymsp[0].minor.yy27);} + yymsp[0].minor.yy193 = yylhsminor.yy193; break; case 145: /* column ::= ids typename */ { - tSetColumnInfo(&yylhsminor.yy407, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy407); + tSetColumnInfo(&yylhsminor.yy27, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy27); } - yymsp[-1].minor.yy407 = yylhsminor.yy407; + yymsp[-1].minor.yy27 = yylhsminor.yy27; break; case 146: /* tagitemlist ::= tagitemlist COMMA tagitem */ -{ yylhsminor.yy159 = tVariantListAppend(yymsp[-2].minor.yy159, &yymsp[0].minor.yy488, -1); } - yymsp[-2].minor.yy159 = yylhsminor.yy159; +{ yylhsminor.yy193 = tVariantListAppend(yymsp[-2].minor.yy193, &yymsp[0].minor.yy442, -1); } + yymsp[-2].minor.yy193 = yylhsminor.yy193; break; case 147: /* tagitemlist ::= tagitem */ -{ yylhsminor.yy159 = tVariantListAppend(NULL, &yymsp[0].minor.yy488, -1); } - yymsp[0].minor.yy159 = yylhsminor.yy159; +{ yylhsminor.yy193 = tVariantListAppend(NULL, &yymsp[0].minor.yy442, -1); } + yymsp[0].minor.yy193 = yylhsminor.yy193; 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.yy488, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy488 = yylhsminor.yy488; +{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy442, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy442 = yylhsminor.yy442; break; case 152: /* tagitem ::= NULL */ -{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy488, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy488 = yylhsminor.yy488; +{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy442, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy442 = yylhsminor.yy442; break; case 153: /* tagitem ::= MINUS INTEGER */ case 154: /* tagitem ::= MINUS FLOAT */ yytestcase(yyruleno==154); @@ -2608,56 +2629,56 @@ 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.yy488, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy442, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy488 = yylhsminor.yy488; + yymsp[-1].minor.yy442 = yylhsminor.yy442; break; - case 157: /* select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ + 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.yy116 = tSetQuerySqlNode(&yymsp[-12].minor.yy0, yymsp[-11].minor.yy159, yymsp[-10].minor.yy236, yymsp[-9].minor.yy118, yymsp[-4].minor.yy159, yymsp[-3].minor.yy159, &yymsp[-8].minor.yy184, &yymsp[-7].minor.yy249, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy159, &yymsp[0].minor.yy440, &yymsp[-1].minor.yy440, yymsp[-2].minor.yy118); + yylhsminor.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[-12].minor.yy116 = yylhsminor.yy116; + yymsp[-13].minor.yy124 = yylhsminor.yy124; break; case 158: /* select ::= LP select RP */ -{yymsp[-2].minor.yy116 = yymsp[-1].minor.yy116;} +{yymsp[-2].minor.yy124 = yymsp[-1].minor.yy124;} break; case 159: /* union ::= select */ -{ yylhsminor.yy159 = setSubclause(NULL, yymsp[0].minor.yy116); } - yymsp[0].minor.yy159 = yylhsminor.yy159; +{ yylhsminor.yy193 = setSubclause(NULL, yymsp[0].minor.yy124); } + yymsp[0].minor.yy193 = yylhsminor.yy193; break; case 160: /* union ::= union UNION ALL select */ -{ yylhsminor.yy159 = appendSelectClause(yymsp[-3].minor.yy159, yymsp[0].minor.yy116); } - yymsp[-3].minor.yy159 = yylhsminor.yy159; +{ yylhsminor.yy193 = appendSelectClause(yymsp[-3].minor.yy193, yymsp[0].minor.yy124); } + yymsp[-3].minor.yy193 = yylhsminor.yy193; break; case 161: /* cmd ::= union */ -{ setSqlInfo(pInfo, yymsp[0].minor.yy159, NULL, TSDB_SQL_SELECT); } +{ setSqlInfo(pInfo, yymsp[0].minor.yy193, NULL, TSDB_SQL_SELECT); } break; case 162: /* select ::= SELECT selcollist */ { - yylhsminor.yy116 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy159, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + yylhsminor.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.yy116 = yylhsminor.yy116; + yymsp[-1].minor.yy124 = yylhsminor.yy124; break; case 163: /* sclp ::= selcollist COMMA */ -{yylhsminor.yy159 = yymsp[-1].minor.yy159;} - yymsp[-1].minor.yy159 = yylhsminor.yy159; +{yylhsminor.yy193 = yymsp[-1].minor.yy193;} + yymsp[-1].minor.yy193 = yylhsminor.yy193; break; case 164: /* sclp ::= */ - case 189: /* orderby_opt ::= */ yytestcase(yyruleno==189); -{yymsp[1].minor.yy159 = 0;} + case 194: /* orderby_opt ::= */ yytestcase(yyruleno==194); +{yymsp[1].minor.yy193 = 0;} break; case 165: /* selcollist ::= sclp distinct expr as */ { - yylhsminor.yy159 = tSqlExprListAppend(yymsp[-3].minor.yy159, yymsp[-1].minor.yy118, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); + yylhsminor.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.yy159 = yylhsminor.yy159; + yymsp[-3].minor.yy193 = yylhsminor.yy193; break; case 166: /* selcollist ::= sclp STAR */ { tSqlExpr *pNode = tSqlExprCreateIdValue(NULL, TK_ALL); - yylhsminor.yy159 = tSqlExprListAppend(yymsp[-1].minor.yy159, pNode, 0, 0); + yylhsminor.yy193 = tSqlExprListAppend(yymsp[-1].minor.yy193, pNode, 0, 0); } - yymsp[-1].minor.yy159 = yylhsminor.yy159; + yymsp[-1].minor.yy193 = yylhsminor.yy193; break; case 167: /* as ::= AS ids */ { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } @@ -2674,332 +2695,348 @@ static void yy_reduce( yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 172: /* from ::= FROM tablelist */ -{yymsp[-1].minor.yy236 = yymsp[0].minor.yy236;} + case 173: /* from ::= FROM sub */ yytestcase(yyruleno==173); +{yymsp[-1].minor.yy332 = yymsp[0].minor.yy332;} + break; + case 174: /* sub ::= LP union RP */ +{yymsp[-2].minor.yy332 = addSubqueryElem(NULL, yymsp[-1].minor.yy193, NULL);} break; - case 173: /* from ::= FROM LP union RP */ -{yymsp[-3].minor.yy236 = setSubquery(NULL, yymsp[-1].minor.yy159);} + case 175: /* sub ::= LP union RP ids */ +{yymsp[-3].minor.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 */ +{yylhsminor.yy332 = addSubqueryElem(yymsp[-5].minor.yy332, yymsp[-2].minor.yy193, &yymsp[0].minor.yy0);} + yymsp[-5].minor.yy332 = yylhsminor.yy332; + break; + case 177: /* tablelist ::= ids cpxName */ { yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy236 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy332 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); } - yymsp[-1].minor.yy236 = yylhsminor.yy236; + yymsp[-1].minor.yy332 = yylhsminor.yy332; break; - case 175: /* tablelist ::= ids cpxName ids */ + case 178: /* tablelist ::= ids cpxName ids */ { yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy236 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy332 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy236 = yylhsminor.yy236; + yymsp[-2].minor.yy332 = yylhsminor.yy332; 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.yy236 = setTableNameList(yymsp[-3].minor.yy236, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy332 = setTableNameList(yymsp[-3].minor.yy332, &yymsp[-1].minor.yy0, NULL); } - yymsp[-3].minor.yy236 = yylhsminor.yy236; + yymsp[-3].minor.yy332 = yylhsminor.yy332; 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.yy236 = setTableNameList(yymsp[-4].minor.yy236, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy332 = setTableNameList(yymsp[-4].minor.yy332, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-4].minor.yy236 = yylhsminor.yy236; + yymsp[-4].minor.yy332 = yylhsminor.yy332; break; - case 178: /* tmvar ::= VARIABLE */ + case 181: /* tmvar ::= VARIABLE */ {yylhsminor.yy0 = yymsp[0].minor.yy0;} yymsp[0].minor.yy0 = yylhsminor.yy0; break; - case 179: /* interval_opt ::= INTERVAL LP tmvar RP */ -{yymsp[-3].minor.yy184.interval = yymsp[-1].minor.yy0; yymsp[-3].minor.yy184.offset.n = 0;} + case 182: /* interval_opt ::= INTERVAL LP tmvar RP */ +{yymsp[-3].minor.yy392.interval = yymsp[-1].minor.yy0; yymsp[-3].minor.yy392.offset.n = 0;} break; - case 180: /* interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ -{yymsp[-5].minor.yy184.interval = yymsp[-3].minor.yy0; yymsp[-5].minor.yy184.offset = yymsp[-1].minor.yy0;} + case 183: /* interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ +{yymsp[-5].minor.yy392.interval = yymsp[-3].minor.yy0; yymsp[-5].minor.yy392.offset = yymsp[-1].minor.yy0;} break; - case 181: /* interval_opt ::= */ -{memset(&yymsp[1].minor.yy184, 0, sizeof(yymsp[1].minor.yy184));} + case 184: /* interval_opt ::= */ +{memset(&yymsp[1].minor.yy392, 0, sizeof(yymsp[1].minor.yy392));} break; - case 182: /* session_option ::= */ -{yymsp[1].minor.yy249.col.n = 0; yymsp[1].minor.yy249.gap.n = 0;} + case 185: /* session_option ::= */ +{yymsp[1].minor.yy447.col.n = 0; yymsp[1].minor.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.yy249.col = yymsp[-4].minor.yy0; - yymsp[-6].minor.yy249.gap = yymsp[-1].minor.yy0; + yymsp[-6].minor.yy447.col = yymsp[-4].minor.yy0; + yymsp[-6].minor.yy447.gap = yymsp[-1].minor.yy0; +} + break; + case 187: /* windowstate_option ::= */ +{yymsp[1].minor.yy76.col.n = 0;} + break; + case 188: /* windowstate_option ::= STATE_WINDOW LP ids RP */ +{ + yymsp[-3].minor.yy76.col = yymsp[-1].minor.yy0; } break; - case 184: /* fill_opt ::= */ -{ yymsp[1].minor.yy159 = 0; } + case 189: /* fill_opt ::= */ +{ yymsp[1].minor.yy193 = 0; } break; - case 185: /* 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.yy159, &A, -1, 0); - yymsp[-5].minor.yy159 = yymsp[-1].minor.yy159; + tVariantListInsert(yymsp[-1].minor.yy193, &A, -1, 0); + yymsp[-5].minor.yy193 = yymsp[-1].minor.yy193; } break; - case 186: /* fill_opt ::= FILL LP ID RP */ + case 191: /* fill_opt ::= FILL LP ID RP */ { toTSDBType(yymsp[-1].minor.yy0.type); - yymsp[-3].minor.yy159 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); + yymsp[-3].minor.yy193 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); } break; - case 187: /* sliding_opt ::= SLIDING LP tmvar RP */ + case 192: /* sliding_opt ::= SLIDING LP tmvar RP */ {yymsp[-3].minor.yy0 = yymsp[-1].minor.yy0; } break; - case 188: /* sliding_opt ::= */ + case 193: /* sliding_opt ::= */ {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = NULL; yymsp[1].minor.yy0.type = 0; } break; - case 190: /* orderby_opt ::= ORDER BY sortlist */ -{yymsp[-2].minor.yy159 = yymsp[0].minor.yy159;} + case 195: /* orderby_opt ::= ORDER BY sortlist */ +{yymsp[-2].minor.yy193 = yymsp[0].minor.yy193;} break; - case 191: /* sortlist ::= sortlist COMMA item sortorder */ + case 196: /* sortlist ::= sortlist COMMA item sortorder */ { - yylhsminor.yy159 = tVariantListAppend(yymsp[-3].minor.yy159, &yymsp[-1].minor.yy488, yymsp[0].minor.yy20); + yylhsminor.yy193 = tVariantListAppend(yymsp[-3].minor.yy193, &yymsp[-1].minor.yy442, yymsp[0].minor.yy312); } - yymsp[-3].minor.yy159 = yylhsminor.yy159; + yymsp[-3].minor.yy193 = yylhsminor.yy193; break; - case 192: /* sortlist ::= item sortorder */ + case 197: /* sortlist ::= item sortorder */ { - yylhsminor.yy159 = tVariantListAppend(NULL, &yymsp[-1].minor.yy488, yymsp[0].minor.yy20); + yylhsminor.yy193 = tVariantListAppend(NULL, &yymsp[-1].minor.yy442, yymsp[0].minor.yy312); } - yymsp[-1].minor.yy159 = yylhsminor.yy159; + yymsp[-1].minor.yy193 = yylhsminor.yy193; break; - case 193: /* 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.yy488, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy442, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy488 = yylhsminor.yy488; + yymsp[-1].minor.yy442 = yylhsminor.yy442; break; - case 194: /* sortorder ::= ASC */ -{ yymsp[0].minor.yy20 = TSDB_ORDER_ASC; } + case 199: /* sortorder ::= ASC */ +{ yymsp[0].minor.yy312 = TSDB_ORDER_ASC; } break; - case 195: /* sortorder ::= DESC */ -{ yymsp[0].minor.yy20 = TSDB_ORDER_DESC;} + case 200: /* sortorder ::= DESC */ +{ yymsp[0].minor.yy312 = TSDB_ORDER_DESC;} break; - case 196: /* sortorder ::= */ -{ yymsp[1].minor.yy20 = TSDB_ORDER_ASC; } + case 201: /* sortorder ::= */ +{ yymsp[1].minor.yy312 = TSDB_ORDER_ASC; } break; - case 197: /* groupby_opt ::= */ -{ yymsp[1].minor.yy159 = 0;} + case 202: /* groupby_opt ::= */ +{ yymsp[1].minor.yy193 = 0;} break; - case 198: /* groupby_opt ::= GROUP BY grouplist */ -{ yymsp[-2].minor.yy159 = yymsp[0].minor.yy159;} + case 203: /* groupby_opt ::= GROUP BY grouplist */ +{ yymsp[-2].minor.yy193 = yymsp[0].minor.yy193;} break; - case 199: /* grouplist ::= grouplist COMMA item */ + case 204: /* grouplist ::= grouplist COMMA item */ { - yylhsminor.yy159 = tVariantListAppend(yymsp[-2].minor.yy159, &yymsp[0].minor.yy488, -1); + yylhsminor.yy193 = tVariantListAppend(yymsp[-2].minor.yy193, &yymsp[0].minor.yy442, -1); } - yymsp[-2].minor.yy159 = yylhsminor.yy159; + yymsp[-2].minor.yy193 = yylhsminor.yy193; break; - case 200: /* grouplist ::= item */ + case 205: /* grouplist ::= item */ { - yylhsminor.yy159 = tVariantListAppend(NULL, &yymsp[0].minor.yy488, -1); + yylhsminor.yy193 = tVariantListAppend(NULL, &yymsp[0].minor.yy442, -1); } - yymsp[0].minor.yy159 = yylhsminor.yy159; + yymsp[0].minor.yy193 = yylhsminor.yy193; break; - case 201: /* having_opt ::= */ - case 211: /* where_opt ::= */ yytestcase(yyruleno==211); - case 253: /* expritem ::= */ yytestcase(yyruleno==253); -{yymsp[1].minor.yy118 = 0;} + case 206: /* having_opt ::= */ + case 216: /* where_opt ::= */ yytestcase(yyruleno==216); + case 258: /* expritem ::= */ yytestcase(yyruleno==258); +{yymsp[1].minor.yy454 = 0;} break; - case 202: /* having_opt ::= HAVING expr */ - case 212: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==212); -{yymsp[-1].minor.yy118 = yymsp[0].minor.yy118;} + case 207: /* having_opt ::= HAVING expr */ + case 217: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==217); +{yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;} break; - case 203: /* limit_opt ::= */ - case 207: /* slimit_opt ::= */ yytestcase(yyruleno==207); -{yymsp[1].minor.yy440.limit = -1; yymsp[1].minor.yy440.offset = 0;} + case 208: /* limit_opt ::= */ + case 212: /* slimit_opt ::= */ yytestcase(yyruleno==212); +{yymsp[1].minor.yy482.limit = -1; yymsp[1].minor.yy482.offset = 0;} break; - case 204: /* limit_opt ::= LIMIT signed */ - case 208: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==208); -{yymsp[-1].minor.yy440.limit = yymsp[0].minor.yy317; yymsp[-1].minor.yy440.offset = 0;} + case 209: /* limit_opt ::= LIMIT signed */ + case 213: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==213); +{yymsp[-1].minor.yy482.limit = yymsp[0].minor.yy473; yymsp[-1].minor.yy482.offset = 0;} break; - case 205: /* limit_opt ::= LIMIT signed OFFSET signed */ -{ yymsp[-3].minor.yy440.limit = yymsp[-2].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[0].minor.yy317;} + case 210: /* limit_opt ::= LIMIT signed OFFSET signed */ +{ yymsp[-3].minor.yy482.limit = yymsp[-2].minor.yy473; yymsp[-3].minor.yy482.offset = yymsp[0].minor.yy473;} break; - case 206: /* limit_opt ::= LIMIT signed COMMA signed */ -{ yymsp[-3].minor.yy440.limit = yymsp[0].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[-2].minor.yy317;} + case 211: /* limit_opt ::= LIMIT signed COMMA signed */ +{ yymsp[-3].minor.yy482.limit = yymsp[0].minor.yy473; yymsp[-3].minor.yy482.offset = yymsp[-2].minor.yy473;} break; - case 209: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ -{yymsp[-3].minor.yy440.limit = yymsp[-2].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[0].minor.yy317;} + case 214: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ +{yymsp[-3].minor.yy482.limit = yymsp[-2].minor.yy473; yymsp[-3].minor.yy482.offset = yymsp[0].minor.yy473;} break; - case 210: /* slimit_opt ::= SLIMIT signed COMMA signed */ -{yymsp[-3].minor.yy440.limit = yymsp[0].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[-2].minor.yy317;} + case 215: /* slimit_opt ::= SLIMIT signed COMMA signed */ +{yymsp[-3].minor.yy482.limit = yymsp[0].minor.yy473; yymsp[-3].minor.yy482.offset = yymsp[-2].minor.yy473;} break; - case 213: /* expr ::= LP expr RP */ -{yylhsminor.yy118 = yymsp[-1].minor.yy118; yylhsminor.yy118->token.z = yymsp[-2].minor.yy0.z; yylhsminor.yy118->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 218: /* expr ::= LP expr RP */ +{yylhsminor.yy454 = yymsp[-1].minor.yy454; yylhsminor.yy454->token.z = yymsp[-2].minor.yy0.z; yylhsminor.yy454->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 214: /* expr ::= ID */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} - yymsp[0].minor.yy118 = yylhsminor.yy118; + case 219: /* expr ::= ID */ +{ yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 215: /* expr ::= ID DOT ID */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 220: /* expr ::= ID DOT ID */ +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 216: /* expr ::= ID DOT STAR */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 221: /* expr ::= ID DOT STAR */ +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 217: /* expr ::= INTEGER */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} - yymsp[0].minor.yy118 = yylhsminor.yy118; + case 222: /* expr ::= INTEGER */ +{ yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 218: /* expr ::= MINUS INTEGER */ - case 219: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==219); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} - yymsp[-1].minor.yy118 = yylhsminor.yy118; + 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; yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} + yymsp[-1].minor.yy454 = yylhsminor.yy454; break; - case 220: /* expr ::= FLOAT */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} - yymsp[0].minor.yy118 = yylhsminor.yy118; + case 225: /* expr ::= FLOAT */ +{ yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 221: /* expr ::= MINUS FLOAT */ - case 222: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==222); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} - yymsp[-1].minor.yy118 = yylhsminor.yy118; + 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; yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} + yymsp[-1].minor.yy454 = yylhsminor.yy454; break; - case 223: /* expr ::= STRING */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} - yymsp[0].minor.yy118 = yylhsminor.yy118; + case 228: /* expr ::= STRING */ +{ yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 224: /* expr ::= NOW */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } - yymsp[0].minor.yy118 = yylhsminor.yy118; + case 229: /* expr ::= NOW */ +{ yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 225: /* expr ::= VARIABLE */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} - yymsp[0].minor.yy118 = yylhsminor.yy118; + case 230: /* expr ::= VARIABLE */ +{ yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 226: /* expr ::= PLUS VARIABLE */ - case 227: /* expr ::= MINUS VARIABLE */ yytestcase(yyruleno==227); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_VARIABLE; yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_VARIABLE);} - yymsp[-1].minor.yy118 = yylhsminor.yy118; + 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; yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_VARIABLE);} + yymsp[-1].minor.yy454 = yylhsminor.yy454; break; - case 228: /* expr ::= BOOL */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} - yymsp[0].minor.yy118 = yylhsminor.yy118; + case 233: /* expr ::= BOOL */ +{ yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 229: /* expr ::= NULL */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} - yymsp[0].minor.yy118 = yylhsminor.yy118; + case 234: /* expr ::= NULL */ +{ yylhsminor.yy454 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 230: /* expr ::= ID LP exprlist RP */ -{ yylhsminor.yy118 = tSqlExprCreateFunction(yymsp[-1].minor.yy159, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy118 = yylhsminor.yy118; + case 235: /* expr ::= ID LP exprlist RP */ +{ yylhsminor.yy454 = tSqlExprCreateFunction(yymsp[-1].minor.yy193, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy454 = yylhsminor.yy454; break; - case 231: /* expr ::= ID LP STAR RP */ -{ yylhsminor.yy118 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy118 = yylhsminor.yy118; + case 236: /* expr ::= ID LP STAR RP */ +{ yylhsminor.yy454 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy454 = yylhsminor.yy454; break; - case 232: /* expr ::= expr IS NULL */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, NULL, TK_ISNULL);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 237: /* expr ::= expr IS NULL */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, NULL, TK_ISNULL);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 233: /* expr ::= expr IS NOT NULL */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-3].minor.yy118, NULL, TK_NOTNULL);} - yymsp[-3].minor.yy118 = yylhsminor.yy118; + case 238: /* expr ::= expr IS NOT NULL */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-3].minor.yy454, NULL, TK_NOTNULL);} + yymsp[-3].minor.yy454 = yylhsminor.yy454; break; - case 234: /* expr ::= expr LT expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_LT);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 239: /* expr ::= expr LT expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_LT);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 235: /* expr ::= expr GT expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_GT);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 240: /* expr ::= expr GT expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_GT);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 236: /* expr ::= expr LE expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_LE);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 241: /* expr ::= expr LE expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_LE);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 237: /* expr ::= expr GE expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_GE);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 242: /* expr ::= expr GE expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_GE);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 238: /* expr ::= expr NE expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_NE);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 243: /* expr ::= expr NE expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_NE);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 239: /* expr ::= expr EQ expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_EQ);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 244: /* expr ::= expr EQ expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_EQ);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 240: /* expr ::= expr BETWEEN expr AND expr */ -{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy118); yylhsminor.yy118 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy118, yymsp[-2].minor.yy118, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy118, TK_LE), TK_AND);} - yymsp[-4].minor.yy118 = yylhsminor.yy118; + case 245: /* expr ::= expr BETWEEN expr AND expr */ +{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy454); yylhsminor.yy454 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy454, yymsp[-2].minor.yy454, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy454, TK_LE), TK_AND);} + yymsp[-4].minor.yy454 = yylhsminor.yy454; break; - case 241: /* expr ::= expr AND expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_AND);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 246: /* expr ::= expr AND expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_AND);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 242: /* expr ::= expr OR expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_OR); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 247: /* expr ::= expr OR expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_OR); } + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 243: /* expr ::= expr PLUS expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_PLUS); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 248: /* expr ::= expr PLUS expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_PLUS); } + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 244: /* expr ::= expr MINUS expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_MINUS); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 249: /* expr ::= expr MINUS expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_MINUS); } + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 245: /* expr ::= expr STAR expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_STAR); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 250: /* expr ::= expr STAR expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_STAR); } + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 246: /* expr ::= expr SLASH expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_DIVIDE);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 251: /* expr ::= expr SLASH expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_DIVIDE);} + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 247: /* expr ::= expr REM expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_REM); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 252: /* expr ::= expr REM expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_REM); } + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 248: /* expr ::= expr LIKE expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_LIKE); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; + case 253: /* expr ::= expr LIKE expr */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-2].minor.yy454, yymsp[0].minor.yy454, TK_LIKE); } + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 249: /* expr ::= expr IN LP exprlist RP */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-4].minor.yy118, (tSqlExpr*)yymsp[-1].minor.yy159, TK_IN); } - yymsp[-4].minor.yy118 = yylhsminor.yy118; + case 254: /* expr ::= expr IN LP exprlist RP */ +{yylhsminor.yy454 = tSqlExprCreate(yymsp[-4].minor.yy454, (tSqlExpr*)yymsp[-1].minor.yy193, TK_IN); } + yymsp[-4].minor.yy454 = yylhsminor.yy454; break; - case 250: /* exprlist ::= exprlist COMMA expritem */ -{yylhsminor.yy159 = tSqlExprListAppend(yymsp[-2].minor.yy159,yymsp[0].minor.yy118,0, 0);} - yymsp[-2].minor.yy159 = yylhsminor.yy159; + case 255: /* exprlist ::= exprlist COMMA expritem */ +{yylhsminor.yy193 = tSqlExprListAppend(yymsp[-2].minor.yy193,yymsp[0].minor.yy454,0, 0);} + yymsp[-2].minor.yy193 = yylhsminor.yy193; break; - case 251: /* exprlist ::= expritem */ -{yylhsminor.yy159 = tSqlExprListAppend(0,yymsp[0].minor.yy118,0, 0);} - yymsp[0].minor.yy159 = yylhsminor.yy159; + case 256: /* exprlist ::= expritem */ +{yylhsminor.yy193 = tSqlExprListAppend(0,yymsp[0].minor.yy454,0, 0);} + yymsp[0].minor.yy193 = yylhsminor.yy193; break; - case 252: /* expritem ::= expr */ -{yylhsminor.yy118 = yymsp[0].minor.yy118;} - yymsp[0].minor.yy118 = yylhsminor.yy118; + case 257: /* expritem ::= expr */ +{yylhsminor.yy454 = yymsp[0].minor.yy454;} + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 254: /* cmd ::= RESET QUERY CACHE */ + case 259: /* cmd ::= RESET QUERY CACHE */ { setDCLSqlElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} break; - case 255: /* cmd ::= SYNCDB ids REPLICA */ + case 260: /* cmd ::= SYNCDB ids REPLICA */ { setDCLSqlElems(pInfo, TSDB_SQL_SYNC_DB_REPLICA, 1, &yymsp[-1].minor.yy0);} break; - case 256: /* 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.yy159, 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 257: /* 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; @@ -3010,14 +3047,14 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 258: /* 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.yy159, 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 259: /* 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; @@ -3028,7 +3065,7 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 260: /* 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; @@ -3042,26 +3079,26 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 261: /* 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.yy488, -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 262: /* 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.yy159, 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 263: /* 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; @@ -3072,14 +3109,14 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 264: /* 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.yy159, 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 265: /* 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; @@ -3090,7 +3127,7 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 266: /* 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; @@ -3104,13 +3141,13 @@ static void yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 267: /* cmd ::= KILL CONNECTION INTEGER */ + case 272: /* cmd ::= KILL CONNECTION INTEGER */ {setKillSql(pInfo, TSDB_SQL_KILL_CONNECTION, &yymsp[0].minor.yy0);} break; - case 268: /* 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 269: /* 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: diff --git a/src/query/tests/unitTest.cpp b/src/query/tests/unitTest.cpp index d2b058cf7cb9400c64149ff8f18f68788735ba96..33ba8200d3afb9cff00f150ab5bef799f3fa1e86 100644 --- a/src/query/tests/unitTest.cpp +++ b/src/query/tests/unitTest.cpp @@ -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); } diff --git a/src/tsdb/inc/tsdbCommit.h b/src/tsdb/inc/tsdbCommit.h index 9612d15018a6ae0936a936b226b9fd96b9d985e0..cde728b1705cd1eead065772978631fb4b36246d 100644 --- a/src/tsdb/inc/tsdbCommit.h +++ b/src/tsdb/inc/tsdbCommit.h @@ -40,6 +40,7 @@ int tsdbWriteBlockInfoImpl(SDFile *pHeadf, STable *pTable, SArray *pSupA, SArray int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf); int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, bool isLast, bool isSuper, void **ppBuf, void **ppCBuf); +int tsdbApplyRtn(STsdbRepo *pRepo); static FORCE_INLINE int tsdbGetFidLevel(int fid, SRtn *pRtn) { if (fid >= pRtn->maxFid) { diff --git a/src/tsdb/inc/tsdbint.h b/src/tsdb/inc/tsdbint.h index e148e87c18dde9536357ee36cdca92b6562f424e..049c1bdb6ea37121a202a931faa17a4ea36cf6dc 100644 --- a/src/tsdb/inc/tsdbint.h +++ b/src/tsdb/inc/tsdbint.h @@ -88,6 +88,7 @@ struct STsdbRepo { SMemTable* mem; SMemTable* imem; STsdbFS* fs; + SRtn rtn; tsem_t readyToCommit; pthread_mutex_t mutex; bool repoLocked; diff --git a/src/tsdb/src/tsdbCommit.c b/src/tsdb/src/tsdbCommit.c index c65272c17e74471f28fc2f0ec16fd3e5db23deaa..82cc6f07f77300aadd554a7c22c0cf77308b3e53 100644 --- a/src/tsdb/src/tsdbCommit.c +++ b/src/tsdb/src/tsdbCommit.c @@ -85,7 +85,6 @@ static void tsdbCloseCommitFile(SCommitH *pCommith, bool hasError); static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *pInfo); static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIter *pCommitIter, SDataCols *pTarget, TSKEY maxKey, int maxRows, int8_t update); -static int tsdbApplyRtn(STsdbRepo *pRepo); void *tsdbCommitData(STsdbRepo *pRepo) { if (pRepo->imem == NULL) { @@ -1210,7 +1209,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; } @@ -1489,7 +1488,7 @@ static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *p return false; } -static int tsdbApplyRtn(STsdbRepo *pRepo) { +int tsdbApplyRtn(STsdbRepo *pRepo) { SRtn rtn; SFSIter fsiter; STsdbFS * pfs = REPO_FS(pRepo); diff --git a/src/tsdb/src/tsdbFS.c b/src/tsdb/src/tsdbFS.c index fd9b5e77e3fba01d49fc6f8f962730f1b8fbc9ec..54372ae8c28d91a72243256a74a8fb53c317eab2 100644 --- a/src/tsdb/src/tsdbFS.c +++ b/src/tsdb/src/tsdbFS.c @@ -33,7 +33,9 @@ static int tsdbScanDataDir(STsdbRepo *pRepo); static bool tsdbIsTFileInFS(STsdbFS *pfs, const TFILE *pf); static int tsdbRestoreCurrent(STsdbRepo *pRepo); static int tsdbComparTFILE(const void *arg1, const void *arg2); -static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo); +static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo, int32_t *nExpired); +static int tsdbProcessExpiredFS(STsdbRepo *pRepo); +static int tsdbCreateMeta(STsdbRepo *pRepo); // ================== CURRENT file header info static int tsdbEncodeFSHeader(void **buf, SFSHeader *pHeader) { @@ -212,6 +214,8 @@ STsdbFS *tsdbNewFS(STsdbCfg *pCfg) { return NULL; } + pfs->intxn = false; + pfs->nstatus = tsdbNewFSStatus(maxFSet); if (pfs->nstatus == NULL) { tsdbFreeFS(pfs); @@ -234,22 +238,84 @@ void *tsdbFreeFS(STsdbFS *pfs) { return NULL; } +static int tsdbProcessExpiredFS(STsdbRepo *pRepo) { + tsdbStartFSTxn(pRepo, 0, 0); + if (tsdbCreateMeta(pRepo) < 0) { + tsdbError("vgId:%d failed to create meta since %s", REPO_ID(pRepo), tstrerror(terrno)); + return -1; + } + + if (tsdbApplyRtn(pRepo) < 0) { + tsdbEndFSTxnWithError(REPO_FS(pRepo)); + tsdbError("vgId:%d failed to apply rtn since %s", REPO_ID(pRepo), tstrerror(terrno)); + return -1; + } + if (tsdbEndFSTxn(pRepo) < 0) { + tsdbError("vgId:%d failed to end fs txn since %s", REPO_ID(pRepo), tstrerror(terrno)); + return -1; + } + return 0; +} + +static int tsdbCreateMeta(STsdbRepo *pRepo) { + STsdbFS *pfs = REPO_FS(pRepo); + SMFile * pOMFile = pfs->cstatus->pmf; + SMFile mf; + SDiskID did; + + if (pOMFile != NULL) { + // keep the old meta file + tsdbUpdateMFile(pfs, pOMFile); + return 0; + } + + // Create a new meta file + did.level = TFS_PRIMARY_LEVEL; + did.id = TFS_PRIMARY_ID; + tsdbInitMFile(&mf, did, REPO_ID(pRepo), FS_TXN_VERSION(REPO_FS(pRepo))); + + if (tsdbCreateMFile(&mf, true) < 0) { + tsdbError("vgId:%d failed to create META file since %s", REPO_ID(pRepo), tstrerror(terrno)); + return -1; + } + + tsdbInfo("vgId:%d meta file %s is created", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(&mf)); + + if (tsdbUpdateMFileHeader(&mf) < 0) { + tsdbError("vgId:%d failed to update META file header since %s, revert it", REPO_ID(pRepo), tstrerror(terrno)); + tsdbApplyMFileChange(&mf, pOMFile); + return -1; + } + + TSDB_FILE_FSYNC(&mf); + tsdbCloseMFile(&mf); + tsdbUpdateMFile(pfs, &mf); + + return 0; +} + int tsdbOpenFS(STsdbRepo *pRepo) { STsdbFS *pfs = REPO_FS(pRepo); char current[TSDB_FILENAME_LEN] = "\0"; + int nExpired = 0; ASSERT(pfs != NULL); tsdbGetTxnFname(REPO_ID(pRepo), TSDB_TXN_CURR_FILE, current); + tsdbGetRtnSnap(pRepo, &pRepo->rtn); if (access(current, F_OK) == 0) { if (tsdbOpenFSFromCurrent(pRepo) < 0) { tsdbError("vgId:%d failed to open FS since %s", REPO_ID(pRepo), tstrerror(terrno)); return -1; } - tsdbScanAndTryFixDFilesHeader(pRepo); + tsdbScanAndTryFixDFilesHeader(pRepo, &nExpired); + if (nExpired > 0) { + tsdbProcessExpiredFS(pRepo); + } } else { + // should skip expired fileset inside of the function if (tsdbRestoreCurrent(pRepo) < 0) { tsdbError("vgId:%d failed to restore current file since %s", REPO_ID(pRepo), tstrerror(terrno)); return -1; @@ -1110,6 +1176,11 @@ static int tsdbRestoreDFileSet(STsdbRepo *pRepo) { ASSERT(tvid == REPO_ID(pRepo)); + if (tfid < pRepo->rtn.minFid) { // skip file expired + ++index; + continue; + } + if (ftype == 0) { fset.fid = tfid; } else { @@ -1206,7 +1277,7 @@ static int tsdbComparTFILE(const void *arg1, const void *arg2) { } } -static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo) { +static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo, int32_t *nExpired) { STsdbFS * pfs = REPO_FS(pRepo); SFSStatus *pStatus = pfs->cstatus; SDFInfo info; @@ -1214,7 +1285,9 @@ static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo) { for (size_t i = 0; i < taosArrayGetSize(pStatus->df); i++) { SDFileSet fset; tsdbInitDFileSetEx(&fset, (SDFileSet *)taosArrayGet(pStatus->df, i)); - + if (fset.fid < pRepo->rtn.minFid) { + ++*nExpired; + } tsdbDebug("vgId:%d scan DFileSet %d header", REPO_ID(pRepo), fset.fid); if (tsdbOpenDFileSet(&fset, O_RDWR) < 0) { diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c index 324a7c79c5b7dbfa69bbdf240301c3c710f90b59..817469819700d6529389fca860b76feea3f1d5a4 100644 --- a/src/tsdb/src/tsdbMeta.c +++ b/src/tsdb/src/tsdbMeta.c @@ -68,7 +68,7 @@ int tsdbCreateTable(STsdbRepo *repo, STableCfg *pCfg) { TABLE_CHAR_NAME(pMeta->tables[tid]), TABLE_TID(pMeta->tables[tid]), TABLE_UID(pMeta->tables[tid])); return 0; } else { - tsdbError("vgId:%d table %s at tid %d uid %" PRIu64 + tsdbInfo("vgId:%d table %s at tid %d uid %" PRIu64 " exists, replace it with new table, this can be not reasonable", REPO_ID(pRepo), TABLE_CHAR_NAME(pMeta->tables[tid]), TABLE_TID(pMeta->tables[tid]), TABLE_UID(pMeta->tables[tid])); @@ -1055,10 +1055,7 @@ static int tsdbRemoveTableFromIndex(STsdbMeta *pMeta, STable *pTable) { STable *pSTable = pTable->pSuper; ASSERT(pSTable != NULL); - STSchema *pSchema = tsdbGetTableTagSchema(pTable); - STColumn *pCol = schemaColAt(pSchema, DEFAULT_TAG_INDEX_COLUMN); - - char * key = tdGetKVRowValOfCol(pTable->tagVal, pCol->colId); + char* key = getTagIndexKey(pTable); SArray *res = tSkipListGet(pSTable->pIndex, key); size_t size = taosArrayGetSize(res); diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 9df25409de62f9b2579d43800fd6a5709bd41f1a..1545d44395d6baca6f33c850e35796c96af8d52f 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); @@ -367,40 +368,39 @@ static STsdbQueryHandle* tsdbQueryTablesImpl(STsdbRepo* tsdb, STsdbQueryCond* pC goto out_of_memory; } - assert(pCond != NULL && pCond->numOfCols > 0 && pMemRef != NULL); + assert(pCond != NULL && pMemRef != NULL); if (ASCENDING_TRAVERSE(pCond->order)) { assert(pQueryHandle->window.skey <= pQueryHandle->window.ekey); } else { assert(pQueryHandle->window.skey >= pQueryHandle->window.ekey); } + if (pCond->numOfCols > 0) { + // allocate buffer in order to load data blocks from file + pQueryHandle->statis = calloc(pCond->numOfCols, sizeof(SDataStatis)); + if (pQueryHandle->statis == NULL) { + goto out_of_memory; + } - // allocate buffer in order to load data blocks from file - pQueryHandle->statis = calloc(pCond->numOfCols, sizeof(SDataStatis)); - if (pQueryHandle->statis == NULL) { - goto out_of_memory; - } - - pQueryHandle->pColumns = taosArrayInit(pCond->numOfCols, sizeof(SColumnInfoData)); // todo: use list instead of array? - if (pQueryHandle->pColumns == NULL) { - goto out_of_memory; - } + pQueryHandle->pColumns = + taosArrayInit(pCond->numOfCols, sizeof(SColumnInfoData)); // todo: use list instead of array? + if (pQueryHandle->pColumns == NULL) { + goto out_of_memory; + } - for (int32_t i = 0; i < pCond->numOfCols; ++i) { - SColumnInfoData colInfo = {{0}, 0}; + for (int32_t i = 0; i < pCond->numOfCols; ++i) { + SColumnInfoData colInfo = {{0}, 0}; - colInfo.info = pCond->colList[i]; - colInfo.pData = calloc(1, EXTRA_BYTES + pQueryHandle->outputCapacity * pCond->colList[i].bytes); - if (colInfo.pData == NULL) { - goto out_of_memory; + colInfo.info = pCond->colList[i]; + colInfo.pData = calloc(1, EXTRA_BYTES + pQueryHandle->outputCapacity * pCond->colList[i].bytes); + if (colInfo.pData == NULL) { + goto out_of_memory; + } + taosArrayPush(pQueryHandle->pColumns, &colInfo); + pQueryHandle->statis[i].colId = colInfo.info.colId; } - taosArrayPush(pQueryHandle->pColumns, &colInfo); - pQueryHandle->statis[i].colId = colInfo.info.colId; - } - if (pCond->numOfCols > 0) { pQueryHandle->defaultLoadColumn = getDefaultLoadColumns(pQueryHandle, true); } - STsdbMeta* pMeta = tsdbGetMeta(tsdb); assert(pMeta != NULL); @@ -512,6 +512,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 +530,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); @@ -2105,6 +2127,7 @@ int32_t tsdbGetFileBlocksDistInfo(TsdbQueryHandleT* queryHandle, STableBlockDist STsdbQueryHandle* pQueryHandle = (STsdbQueryHandle*) queryHandle; pTableBlockInfo->totalSize = 0; + pTableBlockInfo->totalRows = 0; STsdbFS* pFileHandle = REPO_FS(pQueryHandle->pTsdb); // find the start data block in file @@ -2178,7 +2201,12 @@ int32_t tsdbGetFileBlocksDistInfo(TsdbQueryHandleT* queryHandle, STableBlockDist pTableBlockInfo->totalSize += pBlock[j].len; int32_t numOfRows = pBlock[j].numOfRows; - taosArrayPush(pTableBlockInfo->dataBlockInfos, &numOfRows); + pTableBlockInfo->totalRows += numOfRows; + if (numOfRows > pTableBlockInfo->maxRows) pTableBlockInfo->maxRows = numOfRows; + if (numOfRows < pTableBlockInfo->minRows) pTableBlockInfo->minRows = numOfRows; + int32_t stepIndex = (numOfRows-1)/TSDB_BLOCK_DIST_STEP_ROWS; + SFileBlockInfo *blockInfo = (SFileBlockInfo*)taosArrayGet(pTableBlockInfo->dataBlockInfos, stepIndex); + blockInfo->numBlocksOfStep++; } } } @@ -2460,6 +2488,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 +2677,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 +2880,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 +2895,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 +2917,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/tsdb/src/tsdbSync.c b/src/tsdb/src/tsdbSync.c index 5a2756537e6a37c8b4a0e7c3e1f81199523df2eb..edcb84d091eb4a1bcb4cb23835a3c889eee35d54 100644 --- a/src/tsdb/src/tsdbSync.c +++ b/src/tsdb/src/tsdbSync.c @@ -424,24 +424,42 @@ static int32_t tsdbSyncRecvDFileSetArray(SSyncH *pSynch) { } if (tsdbSendDecision(pSynch, false) < 0) { - tsdbError("vgId:%d, filed to send decision since %s", REPO_ID(pRepo), tstrerror(terrno)); + tsdbError("vgId:%d, failed to send decision since %s", REPO_ID(pRepo), tstrerror(terrno)); return -1; } } else { // Need to copy from remote - tsdbInfo("vgId:%d, fileset:%d will be received", REPO_ID(pRepo), pSynch->pdf->fid); - - // Notify remote to send there file here - if (tsdbSendDecision(pSynch, true) < 0) { - tsdbError("vgId:%d, failed to send decision since %s", REPO_ID(pRepo), tstrerror(terrno)); - return -1; + int fidLevel = tsdbGetFidLevel(pSynch->pdf->fid, &(pSynch->rtn)); + if (fidLevel < 0) { // expired fileset + tsdbInfo("vgId:%d, fileset:%d will be skipped as expired", REPO_ID(pRepo), pSynch->pdf->fid); + if (tsdbSendDecision(pSynch, false) < 0) { + tsdbError("vgId:%d, failed to send decision since %s", REPO_ID(pRepo), tstrerror(terrno)); + return -1; + } + // Move forward + if (tsdbRecvDFileSetInfo(pSynch) < 0) { + tsdbError("vgId:%d, failed to recv fileset since %s", REPO_ID(pRepo), tstrerror(terrno)); + return -1; + } + if (pLSet) { + pLSet = tsdbFSIterNext(&fsiter); + } + // Next loop + continue; + } else { + tsdbInfo("vgId:%d, fileset:%d will be received", REPO_ID(pRepo), pSynch->pdf->fid); + // Notify remote to send there file here + if (tsdbSendDecision(pSynch, true) < 0) { + tsdbError("vgId:%d, failed to send decision since %s", REPO_ID(pRepo), tstrerror(terrno)); + return -1; + } } // Create local files and copy from remote SDiskID did; SDFileSet fset; - tfsAllocDisk(tsdbGetFidLevel(pSynch->pdf->fid, &(pSynch->rtn)), &(did.level), &(did.id)); + tfsAllocDisk(fidLevel, &(did.level), &(did.id)); if (did.level == TFS_UNDECIDED_LEVEL) { terrno = TSDB_CODE_TDB_NO_AVAIL_DISK; tsdbError("vgId:%d, failed allc disk since %s", REPO_ID(pRepo), tstrerror(terrno)); @@ -548,6 +566,13 @@ static int32_t tsdbSyncSendDFileSet(SSyncH *pSynch, SDFileSet *pSet) { STsdbRepo *pRepo = pSynch->pRepo; bool toSend = false; + // skip expired fileset + if (pSet && tsdbGetFidLevel(pSet->fid, &(pSynch->rtn)) < 0) { + tsdbInfo("vgId:%d, don't sync send since fileset:%d smaller than minFid:%d", REPO_ID(pRepo), pSet->fid, + pSynch->rtn.minFid); + return 0; + } + if (tsdbSendDFileSetInfo(pSynch, pSet) < 0) { tsdbError("vgId:%d, failed to send fileset:%d info since %s", REPO_ID(pRepo), pSet ? pSet->fid : -1, tstrerror(terrno)); return -1; 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..fc7b6b85841065044a0897ee3ebaa4d7cb84e53b 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); } /** @@ -98,6 +106,14 @@ void* taosArrayGetLast(const SArray* pArray); */ size_t taosArrayGetSize(const SArray* pArray); +/** + * set the size of array + * @param pArray + * @param size size of the array + * @return + */ +void taosArraySetSize(SArray* pArray, size_t size); + /** * insert data into array * @param pArray diff --git a/src/util/inc/ttoken.h b/src/util/inc/ttoken.h index d5e45e60a148726d0e71c38fcd8262d1d67a380a..f62329183f82a57bcf65d136aaec65d8babd5f71 100644 --- a/src/util/inc/ttoken.h +++ b/src/util/inc/ttoken.h @@ -37,8 +37,6 @@ typedef struct SStrToken { char *z; } SStrToken; -extern const char escapeChar[]; - /** * check if it is a number or not * @param pToken @@ -47,8 +45,6 @@ extern const char escapeChar[]; #define isNumber(tk) \ ((tk)->type == TK_INTEGER || (tk)->type == TK_FLOAT || (tk)->type == TK_HEX || (tk)->type == TK_BIN) -#define GET_ESCAPE_CHAR(c) (escapeChar[(uint8_t)(c)]) - /** * tokenizer for sql string * @param z @@ -187,6 +183,7 @@ void taosCleanupKeywordsTable(); SStrToken tscReplaceStrToken(char **str, SStrToken *token, const char* newToken); +SStrToken taosTokenDup(SStrToken* pToken, char* buf, int32_t len); #ifdef __cplusplus } diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c index f4587b33e75c556d6dbc03e1577436afb728cba7..5e7d9d14da870174964ae56627de96b2955e03f0 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 ); @@ -111,6 +115,11 @@ void* taosArrayGetLast(const SArray* pArray) { size_t taosArrayGetSize(const SArray* pArray) { return pArray->size; } +void taosArraySetSize(SArray* pArray, size_t size) { + assert(size <= pArray->capacity); + pArray->size = size; +} + void* taosArrayInsert(SArray* pArray, size_t index, void* pData) { if (pArray == NULL || pData == NULL) { return NULL; diff --git a/src/util/src/terror.c b/src/util/src/terror.c index d88393777ccd1de829e8f4e53f9f4563bc8f7235..382f872486485d93420d7f180dc11414f570132c 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") @@ -224,6 +224,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FULL, "Database memory is fu TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FLOWCTRL, "Database memory is full for waiting commit") TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_DROPPING, "Database is dropping") TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_BALANCING, "Database is balancing") +TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_CLOSING, "Database is closing") 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") diff --git a/src/util/src/ttokenizer.c b/src/util/src/ttokenizer.c index 93d4570ea8de5c41edcedce7fab3183d5f54f7e8..ea15ced8983206809190c70d3f94f1be2d4c67ac 100644 --- a/src/util/src/ttokenizer.c +++ b/src/util/src/ttokenizer.c @@ -141,6 +141,7 @@ static SKeyword keywordTable[] = { {"VARIABLE", TK_VARIABLE}, {"INTERVAL", TK_INTERVAL}, {"SESSION", TK_SESSION}, + {"STATE_WINDOW", TK_STATE_WINDOW}, {"FILL", TK_FILL}, {"SLIDING", TK_SLIDING}, {"ORDER", TK_ORDER}, @@ -232,18 +233,6 @@ static const char isIdChar[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ }; -const char escapeChar[] = { - /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 0x */ - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* 1x */ - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, /* 2x */ - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, /* 3x */ - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,/* 4x */ - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,/* 5x */ - 0x60, 0x07, 0x08, 0x63, 0x64, 0x65, 0x0C, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x0A, 0x6F,/* 6x */ - 0x70, 0x71, 0x0D, 0x73, 0x09, 0x75, 0x0B, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,/* 7x */ -}; - static void* keywordHashTable = NULL; static void doInitKeywordsTable(void) { @@ -593,7 +582,6 @@ SStrToken tscReplaceStrToken(char **str, SStrToken *token, const char* newToken) return ntoken; } - SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) { SStrToken t0 = {0}; @@ -686,3 +674,15 @@ void taosCleanupKeywordsTable() { taosHashCleanup(m); } } + +SStrToken taosTokenDup(SStrToken* pToken, char* buf, int32_t len) { + assert(pToken != NULL && buf != NULL); + SStrToken token = *pToken; + token.z = buf; + + assert(len > token.n); + strncpy(token.z, pToken->z, pToken->n); + token.z[token.n] = 0; + + return token; +} diff --git a/src/vnode/src/vnodeMgmt.c b/src/vnode/src/vnodeMgmt.c index 32f95321383981924c5b6496bd4302edca19da5e..7e6022fc872c3a2221514169ab00874011dc3cb9 100644 --- a/src/vnode/src/vnodeMgmt.c +++ b/src/vnode/src/vnodeMgmt.c @@ -91,18 +91,18 @@ static void vnodeIncRef(void *ptNode) { } void *vnodeAcquire(int32_t vgId) { - SVnodeObj **ppVnode = NULL; + SVnodeObj *pVnode = NULL; if (tsVnodesHash != NULL) { - ppVnode = taosHashGetClone(tsVnodesHash, &vgId, sizeof(int32_t), vnodeIncRef, NULL, sizeof(void *)); + taosHashGetClone(tsVnodesHash, &vgId, sizeof(int32_t), vnodeIncRef, &pVnode, sizeof(void *)); } - if (ppVnode == NULL || *ppVnode == NULL) { + if (pVnode == NULL) { terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; vDebug("vgId:%d, not exist", vgId); return NULL; } - return *ppVnode; + return pVnode; } void vnodeRelease(void *vparam) { diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index 2831090267004ba92cd08b91b0f968b144025256..3964975e355db3ced1c86e28611ef202dd24d9e3 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -357,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/vnodeWrite.c b/src/vnode/src/vnodeWrite.c index 16089c8e91bdab66af664a9b6c8b7fc0a5dabf04..555eda6d13eeb1dbbb83fbd89ee2672966aa8539 100644 --- a/src/vnode/src/vnodeWrite.c +++ b/src/vnode/src/vnodeWrite.c @@ -303,6 +303,17 @@ static int32_t vnodeWriteToWQueueImp(SVWriteMsg *pWrite) { } int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rparam) { + SVnodeObj *pVnode = vparam; + if (qtype == TAOS_QTYPE_RPC) { + if (!vnodeInReadyStatus(pVnode)) { + return TSDB_CODE_APP_NOT_READY; // it may be in deleting or closing state + } + + if (pVnode->role != TAOS_SYNC_ROLE_MASTER) { + return TSDB_CODE_APP_NOT_READY; + } + } + SVWriteMsg *pWrite = vnodeBuildVWriteMsg(vparam, wparam, qtype, rparam); if (pWrite == NULL) { assert(terrno != 0); diff --git a/src/wal/src/walWrite.c b/src/wal/src/walWrite.c index f865870d478882df64bd2308b87f448c4602c847..b884546a08674fef7c2c42f104c5200e0d5efff8 100644 --- a/src/wal/src/walWrite.c +++ b/src/wal/src/walWrite.c @@ -430,6 +430,8 @@ static int32_t walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp, ch 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/Jenkinsfile b/tests/Jenkinsfile index 2f2b9f693312b296451fea436ceb1d25a1bb81c7..0c1f651059714e6e32c3ec7e0a74ed22e05a6f3e 100644 --- a/tests/Jenkinsfile +++ b/tests/Jenkinsfile @@ -29,8 +29,8 @@ pipeline { agent none environment{ - WK = '/var/lib/jenkins/workspace/TDinternal' - WKC= '/var/lib/jenkins/workspace/TDinternal/community' + WK = '/data/lib/jenkins/workspace/TDinternal' + WKC= '/data/lib/jenkins/workspace/TDinternal/community' } stages { 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..b2411d1212de3cb930ce6d7032e6b1f8ec0dcc5d 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; } @@ -380,6 +377,470 @@ void verify_prepare(TAOS* taos) { v.v1 = 5; 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; + } + + result = taos_stmt_use_result(stmt); + + 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++; + taos_print_row(temp, row, fields, num_fields); + printf("%s\n", temp); + } + + taos_free_result(result); + taos_stmt_close(stmt); +} + + + + + +void verify_prepare2(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;"); + + int code = taos_errno(result); + if (code != 0) { + printf("\033[31mfailed to create database, reason:%s\033[0m\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + + usleep(100000); + taos_select_db(taos, "test"); + + // create table + const char* sql = "create table m1 (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10))"; + result = taos_query(taos, sql); + code = taos_errno(result); + if (code != 0) { + printf("\033[31mfailed to create table, reason:%s\033[0m\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + + // insert 10 records + struct { + int64_t ts[10]; + 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]; + char blob[10][80]; + } v; + + int32_t *t8_len = malloc(sizeof(int32_t) * 10); + int32_t *t16_len = malloc(sizeof(int32_t) * 10); + int32_t *t32_len = malloc(sizeof(int32_t) * 10); + int32_t *t64_len = malloc(sizeof(int32_t) * 10); + int32_t *float_len = malloc(sizeof(int32_t) * 10); + int32_t *double_len = malloc(sizeof(int32_t) * 10); + int32_t *bin_len = malloc(sizeof(int32_t) * 10); + int32_t *blob_len = malloc(sizeof(int32_t) * 10); + + TAOS_STMT* stmt = taos_stmt_init(taos); + TAOS_MULTI_BIND params[10]; + char is_null[10] = {0}; + + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(v.ts[0]); + params[0].buffer = v.ts; + params[0].length = t64_len; + params[0].is_null = is_null; + params[0].num = 10; + + params[1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[1].buffer_length = sizeof(v.b[0]); + params[1].buffer = v.b; + params[1].length = t8_len; + params[1].is_null = is_null; + params[1].num = 10; + + params[2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[2].buffer_length = sizeof(v.v1[0]); + params[2].buffer = v.v1; + params[2].length = t8_len; + params[2].is_null = is_null; + params[2].num = 10; + + params[3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[3].buffer_length = sizeof(v.v2[0]); + params[3].buffer = v.v2; + params[3].length = t16_len; + params[3].is_null = is_null; + params[3].num = 10; + + params[4].buffer_type = TSDB_DATA_TYPE_INT; + params[4].buffer_length = sizeof(v.v4[0]); + params[4].buffer = v.v4; + params[4].length = t32_len; + params[4].is_null = is_null; + params[4].num = 10; + + params[5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[5].buffer_length = sizeof(v.v8[0]); + params[5].buffer = v.v8; + params[5].length = t64_len; + params[5].is_null = is_null; + params[5].num = 10; + + params[6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[6].buffer_length = sizeof(v.f4[0]); + params[6].buffer = v.f4; + params[6].length = float_len; + params[6].is_null = is_null; + params[6].num = 10; + + params[7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[7].buffer_length = sizeof(v.f8[0]); + params[7].buffer = v.f8; + params[7].length = double_len; + params[7].is_null = is_null; + params[7].num = 10; + + params[8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[8].buffer_length = sizeof(v.bin[0]); + params[8].buffer = v.bin; + params[8].length = bin_len; + params[8].is_null = is_null; + params[8].num = 10; + + params[9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[9].buffer_length = sizeof(v.blob[0]); + params[9].buffer = v.blob; + params[9].length = blob_len; + params[9].is_null = is_null; + params[9].num = 10; + + + sql = "insert into ? values(?,?,?,?,?,?,?,?,?,?)"; + code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code); + } + + code = taos_stmt_set_tbname(stmt, "m1"); + if (code != 0){ + printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code); + } + + int64_t ts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = ts++; + is_null[i] = 0; + + v.b[i] = (int8_t)i % 2; + v.v1[i] = (int8_t)i; + v.v2[i] = (int16_t)(i * 2); + v.v4[i] = (int32_t)(i * 4); + v.v8[i] = (int64_t)(i * 8); + v.f4[i] = (float)(i * 40); + v.f8[i] = (double)(i * 80); + for (int j = 0; j < sizeof(v.bin[0]) - 1; ++j) { + v.bin[i][j] = (char)(i + '0'); + } + strcpy(v.blob[i], "一二三四五六七八九十"); + + t8_len[i] = sizeof(int8_t); + t16_len[i] = sizeof(int16_t); + t32_len[i] = sizeof(int32_t); + t64_len[i] = sizeof(int64_t); + float_len[i] = sizeof(float); + double_len[i] = sizeof(double); + bin_len[i] = sizeof(v.bin[0]); + blob_len[i] = (int32_t)strlen(v.blob[i]); + } + + taos_stmt_bind_param_batch(stmt, params); + taos_stmt_add_batch(stmt); + + if (taos_stmt_execute(stmt) != 0) { + printf("\033[31mfailed to execute insert statement.\033[0m\n"); + return; + } + taos_stmt_close(stmt); + + + + // query the records + stmt = taos_stmt_init(taos); + taos_stmt_prepare(stmt, "SELECT * FROM m1 WHERE v1 > ? AND v2 < ?", 0); + TAOS_BIND qparams[2]; + + int8_t v1 = 5; + int16_t v2 = 15; + qparams[0].buffer_type = TSDB_DATA_TYPE_TINYINT; + qparams[0].buffer_length = sizeof(v1); + qparams[0].buffer = &v1; + qparams[0].length = &qparams[0].buffer_length; + qparams[0].is_null = NULL; + + qparams[1].buffer_type = TSDB_DATA_TYPE_SMALLINT; + qparams[1].buffer_length = sizeof(v2); + qparams[1].buffer = &v2; + qparams[1].length = &qparams[1].buffer_length; + qparams[1].is_null = NULL; + + taos_stmt_bind_param(stmt, qparams); + if (taos_stmt_execute(stmt) != 0) { + printf("\033[31mfailed to execute select statement.\033[0m\n"); + return; + } + + result = taos_stmt_use_result(stmt); + + 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++; + taos_print_row(temp, row, fields, num_fields); + printf("%s\n", temp); + } + + taos_free_result(result); + taos_stmt_close(stmt); +} + + + +void verify_prepare3(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;"); + + int code = taos_errno(result); + if (code != 0) { + printf("\033[31mfailed to create database, reason:%s\033[0m\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + + usleep(100000); + taos_select_db(taos, "test"); + + // create table + const char* sql = "create stable st1 (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10)) tags (id1 int, id2 binary(40))"; + result = taos_query(taos, sql); + code = taos_errno(result); + if (code != 0) { + printf("\033[31mfailed to create table, reason:%s\033[0m\n", taos_errstr(result)); + taos_free_result(result); + return; + } + taos_free_result(result); + + TAOS_BIND tags[2]; + + int32_t id1 = 1; + char id2[40] = "abcdefghijklmnopqrstuvwxyz0123456789"; + uintptr_t id2_len = strlen(id2); + + tags[0].buffer_type = TSDB_DATA_TYPE_INT; + tags[0].buffer_length = sizeof(int); + tags[0].buffer = &id1; + tags[0].length = NULL; + tags[0].is_null = NULL; + + tags[1].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[1].buffer_length = sizeof(id2); + tags[1].buffer = id2; + tags[1].length = &id2_len; + tags[1].is_null = NULL; + + + // insert 10 records + struct { + int64_t ts[10]; + 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]; + char blob[10][80]; + } v; + + int32_t *t8_len = malloc(sizeof(int32_t) * 10); + int32_t *t16_len = malloc(sizeof(int32_t) * 10); + int32_t *t32_len = malloc(sizeof(int32_t) * 10); + int32_t *t64_len = malloc(sizeof(int32_t) * 10); + int32_t *float_len = malloc(sizeof(int32_t) * 10); + int32_t *double_len = malloc(sizeof(int32_t) * 10); + int32_t *bin_len = malloc(sizeof(int32_t) * 10); + int32_t *blob_len = malloc(sizeof(int32_t) * 10); + + TAOS_STMT* stmt = taos_stmt_init(taos); + TAOS_MULTI_BIND params[10]; + char is_null[10] = {0}; + + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(v.ts[0]); + params[0].buffer = v.ts; + params[0].length = t64_len; + params[0].is_null = is_null; + params[0].num = 10; + + params[1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[1].buffer_length = sizeof(v.b[0]); + params[1].buffer = v.b; + params[1].length = t8_len; + params[1].is_null = is_null; + params[1].num = 10; + + params[2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[2].buffer_length = sizeof(v.v1[0]); + params[2].buffer = v.v1; + params[2].length = t8_len; + params[2].is_null = is_null; + params[2].num = 10; + + params[3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[3].buffer_length = sizeof(v.v2[0]); + params[3].buffer = v.v2; + params[3].length = t16_len; + params[3].is_null = is_null; + params[3].num = 10; + + params[4].buffer_type = TSDB_DATA_TYPE_INT; + params[4].buffer_length = sizeof(v.v4[0]); + params[4].buffer = v.v4; + params[4].length = t32_len; + params[4].is_null = is_null; + params[4].num = 10; + + params[5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[5].buffer_length = sizeof(v.v8[0]); + params[5].buffer = v.v8; + params[5].length = t64_len; + params[5].is_null = is_null; + params[5].num = 10; + + params[6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[6].buffer_length = sizeof(v.f4[0]); + params[6].buffer = v.f4; + params[6].length = float_len; + params[6].is_null = is_null; + params[6].num = 10; + + params[7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[7].buffer_length = sizeof(v.f8[0]); + params[7].buffer = v.f8; + params[7].length = double_len; + params[7].is_null = is_null; + params[7].num = 10; + + params[8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[8].buffer_length = sizeof(v.bin[0]); + params[8].buffer = v.bin; + params[8].length = bin_len; + params[8].is_null = is_null; + params[8].num = 10; + + params[9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[9].buffer_length = sizeof(v.blob[0]); + params[9].buffer = v.blob; + params[9].length = blob_len; + params[9].is_null = is_null; + params[9].num = 10; + + + sql = "insert into ? using st1 tags(?,?) values(?,?,?,?,?,?,?,?,?,?)"; + code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code); + } + + code = taos_stmt_set_tbname_tags(stmt, "m1", tags); + if (code != 0){ + printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code); + } + + int64_t ts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = ts++; + is_null[i] = 0; + + v.b[i] = (int8_t)i % 2; + v.v1[i] = (int8_t)i; + v.v2[i] = (int16_t)(i * 2); + v.v4[i] = (int32_t)(i * 4); + v.v8[i] = (int64_t)(i * 8); + v.f4[i] = (float)(i * 40); + v.f8[i] = (double)(i * 80); + for (int j = 0; j < sizeof(v.bin[0]) - 1; ++j) { + v.bin[i][j] = (char)(i + '0'); + } + strcpy(v.blob[i], "一二三四五六七八九十"); + + t8_len[i] = sizeof(int8_t); + t16_len[i] = sizeof(int16_t); + t32_len[i] = sizeof(int32_t); + t64_len[i] = sizeof(int64_t); + float_len[i] = sizeof(float); + double_len[i] = sizeof(double); + bin_len[i] = sizeof(v.bin[0]); + blob_len[i] = (int32_t)strlen(v.blob[i]); + } + + + taos_stmt_bind_param_batch(stmt, params); + taos_stmt_add_batch(stmt); + + if (taos_stmt_execute(stmt) != 0) { + printf("\033[31mfailed to execute insert statement.\033[0m\n"); + return; + } + taos_stmt_close(stmt); + + // query the records + stmt = taos_stmt_init(taos); + taos_stmt_prepare(stmt, "SELECT * FROM m1 WHERE v1 > ? AND v2 < ?", 0); + + TAOS_BIND qparams[2]; + + int8_t v1 = 5; + int16_t v2 = 15; + qparams[0].buffer_type = TSDB_DATA_TYPE_TINYINT; + qparams[0].buffer_length = sizeof(v1); + qparams[0].buffer = &v1; + qparams[0].length = &qparams[0].buffer_length; + qparams[0].is_null = NULL; + + qparams[1].buffer_type = TSDB_DATA_TYPE_SMALLINT; + qparams[1].buffer_length = sizeof(v2); + qparams[1].buffer = &v2; + qparams[1].length = &qparams[1].buffer_length; + qparams[1].is_null = NULL; + + taos_stmt_bind_param(stmt, qparams); if (taos_stmt_execute(stmt) != 0) { printf("\033[31mfailed to execute select statement.\033[0m\n"); return; @@ -404,6 +865,8 @@ void verify_prepare(TAOS* taos) { taos_stmt_close(stmt); } + + void retrieve_callback(void *param, TAOS_RES *tres, int numOfRows) { if (numOfRows > 0) { @@ -495,6 +958,12 @@ int main(int argc, char *argv[]) { printf("************ verify prepare *************\n"); verify_prepare(taos); + printf("************ verify prepare2 *************\n"); + verify_prepare2(taos); + + printf("************ verify prepare3 *************\n"); + verify_prepare3(taos); + printf("************ verify stream *************\n"); verify_stream(taos); printf("done\n"); diff --git a/tests/examples/lua/OpenResty/conf/nginx.conf b/tests/examples/lua/OpenResty/conf/nginx.conf index 2f838c21fccd99ead5641fd7eea1e55b49851fa2..960cac606a49e5964a900f815eb76e7f228078eb 100644 --- a/tests/examples/lua/OpenResty/conf/nginx.conf +++ b/tests/examples/lua/OpenResty/conf/nginx.conf @@ -6,9 +6,9 @@ events { } http { - lua_package_path '$prefix/lua/?.lua;$prefix/rest/?.lua;/blah/?.lua;;'; + lua_package_path '$prefix/lua/?.lua;$prefix/rest/?.lua;$prefix/rest/?/init.lua;;'; lua_package_cpath "$prefix/so/?.so;;"; - lua_code_cache off; + lua_code_cache on; server { listen 7000; server_name restapi; diff --git a/tests/examples/lua/OpenResty/rest/config.lua b/tests/examples/lua/OpenResty/rest/config.lua new file mode 100644 index 0000000000000000000000000000000000000000..72a4fd8ec687430e5f3d0a798dc4fb3b2d95a942 --- /dev/null +++ b/tests/examples/lua/OpenResty/rest/config.lua @@ -0,0 +1,10 @@ +local config = { + host = "127.0.0.1", + port = 6030, + database = "", + user = "root", + password = "taosdata", + max_packet_size = 1024 * 1024 , + connection_pool_size = 64 +} +return config diff --git a/tests/examples/lua/OpenResty/rest/tdpool/init.lua b/tests/examples/lua/OpenResty/rest/tdpool/init.lua new file mode 100644 index 0000000000000000000000000000000000000000..ebf8e91756539cc8af5db38232a40bf42aeaa245 --- /dev/null +++ b/tests/examples/lua/OpenResty/rest/tdpool/init.lua @@ -0,0 +1,72 @@ +local _M = {} +local driver = require "luaconnector51" +local water_mark = 0 +local occupied = 0 +local connection_pool = {} + +function _M.new(o,config) + o = o or {} + o.connection_pool = connection_pool + o.water_mark = water_mark + o.occupied = occupied + if #connection_pool == 0 then + + for i = 1, config.connection_pool_size do + local res = driver.connect(config) + if res.code ~= 0 then + ngx.log(ngx.ERR, "connect--- failed:"..res.error) + return nil + else + local object = {obj = res.conn, state = 0} + table.insert(o.connection_pool,i, object) + ngx.log(ngx.INFO, "add connection, now pool size:"..#(o.connection_pool)) + end + end + + end + + return setmetatable(o, { __index = _M }) +end + +function _M:get_connection() + + local connection_obj + + for i = 1, #connection_pool do + connection_obj = connection_pool[i] + if connection_obj.state == 0 then + connection_obj.state = 1 + occupied = occupied +1 + if occupied > water_mark then + water_mark = occupied + end + return connection_obj["obj"] + end + end + + ngx.log(ngx.ERR,"ALERT! NO FREE CONNECTION.") + + return nil +end + +function _M:get_water_mark() + + return water_mark +end + +function _M:release_connection(conn) + + local connection_obj + + for i = 1, #connection_pool do + connection_obj = connection_pool[i] + + if connection_obj["obj"] == conn then + connection_obj["state"] = 0 + occupied = occupied -1 + return + end + end +end + +return _M diff --git a/tests/examples/lua/OpenResty/rest/test.lua b/tests/examples/lua/OpenResty/rest/test.lua index 179950cbe7cc294cd53a538baecefda28fe30bcc..48aeef3fb4dd8c9a0dc18e8039b4b8c781760666 100644 --- a/tests/examples/lua/OpenResty/rest/test.lua +++ b/tests/examples/lua/OpenResty/rest/test.lua @@ -1,26 +1,11 @@ local driver = require "luaconnector51" local cjson = require "cjson" +local Pool = require "tdpool" +local config = require "config" ngx.say("start time:"..os.time()) - -local config = { - host = "127.0.0.1", - port = 6030, - database = "", - user = "root", - password = "taosdata", - max_packet_size = 1024 * 1024 -} - -local conn -local res = driver.connect(config) -if res.code ~=0 then - ngx.say("connect--- failed: "..res.error) - return -else - conn = res.conn - ngx.say("connect--- pass.") -end +local pool = Pool.new(Pool,config) +local conn = pool:get_connection() local res = driver.query(conn,"drop database if exists nginx") if res.code ~=0 then @@ -51,7 +36,7 @@ else ngx.say("create table--- pass.") end -res = driver.query(conn,"insert into m1 values ('2019-09-01 00:00:00.001',0,'robotspace'), ('2019-09-01 00:00:00.002',1,'Hilink'),('2019-09-01 00:00:00.003',2,'Harmony')") +res = driver.query(conn,"insert into m1 values ('2019-09-01 00:00:00.001', 0, 'robotspace'), ('2019-09-01 00:00:00.002',1,'Hilink'),('2019-09-01 00:00:00.003',2,'Harmony')") if res.code ~=0 then ngx.say("insert records failed: "..res.error) return @@ -77,7 +62,29 @@ else end end -driver.close(conn) -ngx.say("end time:"..os.time()) ---ngx.log(ngx.ERR,"in test file.") +local flag = false +function query_callback(res) + if res.code ~=0 then + ngx.say("async_query_callback--- failed:"..res.error) + else + if(res.affected == 3) then + ngx.say("async_query_callback, insert records--- pass") + else + ngx.say("async_query_callback, insert records---failed: expect 3 affected records, actually affected "..res.affected) + end + end + flag = true +end + +driver.query_a(conn,"insert into m1 values ('2019-09-01 00:00:00.001', 3, 'robotspace'),('2019-09-01 00:00:00.006', 4, 'Hilink'),('2019-09-01 00:00:00.007', 6, 'Harmony')", query_callback) + +while not flag do +-- ngx.say("i am here once...") + ngx.sleep(0.001) -- time unit is second +end + +ngx.say("pool water_mark:"..pool:get_water_mark()) + +pool:release_connection(conn) +ngx.say("end time:"..os.time()) diff --git a/tests/examples/lua/OpenResty/so/luaconnector51.so b/tests/examples/lua/OpenResty/so/luaconnector51.so index 442de6e39f909e1aeb869988722b84795c048855..d8e4f00fec321ce5f48d4241176a59ee8df5d50c 100755 Binary files a/tests/examples/lua/OpenResty/so/luaconnector51.so and b/tests/examples/lua/OpenResty/so/luaconnector51.so differ diff --git a/tests/examples/lua/build.sh b/tests/examples/lua/build.sh index cbd47bdfd24ce210ab77a6a6259f030863dc7c5b..9d00c6842515415034ce0b5dc71d5d6af9ffc881 100755 --- a/tests/examples/lua/build.sh +++ b/tests/examples/lua/build.sh @@ -1,2 +1,8 @@ -gcc -std=c99 lua_connector.c -fPIC -shared -o luaconnector.so -Wall -ltaos +lua_header_installed=`apt-cache policy liblua5.3-dev|grep Installed|grep none > /dev/null; echo $?` +if [ "$lua_header_installed" = "0" ]; then + echo "If need, please input root password to install liblua5.3-dev for build the connector.." + sudo apt install -y liblua5.3-dev +fi + +gcc -std=c99 lua_connector.c -fPIC -shared -o luaconnector.so -Wall -ltaos -I/usr/include/lua5.3 diff --git a/tests/examples/lua/lua51/lua_connector51.c b/tests/examples/lua/lua51/lua_connector51.c index 9b932337febb204eada021ececa02bc59cf6d5db..fe2152945dc1915dca5de31458a8cbb2f007f4f2 100644 --- a/tests/examples/lua/lua51/lua_connector51.c +++ b/tests/examples/lua/lua51/lua_connector51.c @@ -13,6 +13,11 @@ struct cb_param{ void * stream; }; +struct async_query_callback_param{ + lua_State* state; + int callback; +}; + static int l_connect(lua_State *L){ TAOS * taos=NULL; const char* host; @@ -23,7 +28,7 @@ static int l_connect(lua_State *L){ luaL_checktype(L, 1, LUA_TTABLE); - lua_getfield(L,-1,"host"); + lua_getfield(L, 1,"host"); if (lua_isstring(L,-1)){ host = lua_tostring(L, -1); // printf("host = %s\n", host); @@ -178,6 +183,58 @@ static int l_query(lua_State *L){ return 1; } +void async_query_callback(void *param, TAOS_RES *result, int code){ + struct async_query_callback_param* p = (struct async_query_callback_param*) param; + + //printf("\nin c,numfields:%d\n", numFields); + //printf("\nin c, code:%d\n", code); + + lua_State *L = p->state; + lua_rawgeti(L, LUA_REGISTRYINDEX, p->callback); + lua_newtable(L); + int table_index = lua_gettop(L); + if( code < 0){ + printf("failed, reason:%s\n", taos_errstr(result)); + lua_pushinteger(L, -1); + lua_setfield(L, table_index, "code"); + lua_pushstring(L,"something is wrong");// taos_errstr(taos)); + lua_setfield(L, table_index, "error"); + }else{ + //printf("success to async query.\n"); + const int affectRows = taos_affected_rows(result); + //printf(" affect rows:%d\r\n", affectRows); + lua_pushinteger(L, 0); + lua_setfield(L, table_index, "code"); + lua_pushinteger(L, affectRows); + lua_setfield(L, table_index, "affected"); + } + + lua_call(L, 1, 0); +} + +static int l_async_query(lua_State *L){ + int r = luaL_ref(L, LUA_REGISTRYINDEX); + TAOS * taos = (TAOS*)lua_topointer(L,1); + const char * sqlstr = lua_tostring(L,2); + // int stime = luaL_checknumber(L,3); + + lua_newtable(L); + int table_index = lua_gettop(L); + + struct async_query_callback_param *p = malloc(sizeof(struct async_query_callback_param)); + p->state = L; + p->callback=r; + // printf("r:%d, L:%d\n",r,L); + taos_query_a(taos,sqlstr,async_query_callback,p); + + lua_pushnumber(L, 0); + lua_setfield(L, table_index, "code"); + lua_pushstring(L, "ok"); + lua_setfield(L, table_index, "error"); + + return 1; +} + void stream_cb(void *param, TAOS_RES *result, TAOS_ROW row){ struct cb_param* p = (struct cb_param*) param; TAOS_FIELD *fields = taos_fetch_fields(result); @@ -308,6 +365,7 @@ static int l_close(lua_State *L){ static const struct luaL_Reg lib[] = { {"connect", l_connect}, {"query", l_query}, + {"query_a",l_async_query}, {"close", l_close}, {"open_stream", l_open_stream}, {"close_stream", l_close_stream}, diff --git a/tests/examples/lua/lua_connector.c b/tests/examples/lua/lua_connector.c index 8078ed2665bb30bb8b1d142a21182509dbc49f65..8c2ea3e9e83237fc8ed9ebce687f5131352e4d14 100644 --- a/tests/examples/lua/lua_connector.c +++ b/tests/examples/lua/lua_connector.c @@ -13,6 +13,11 @@ struct cb_param{ void * stream; }; +struct async_query_callback_param{ + lua_State* state; + int callback; +}; + static int l_connect(lua_State *L){ TAOS * taos=NULL; const char* host; @@ -56,6 +61,7 @@ static int l_connect(lua_State *L){ lua_settop(L,0); taos_init(); + lua_newtable(L); int table_index = lua_gettop(L); @@ -177,6 +183,58 @@ static int l_query(lua_State *L){ return 1; } +void async_query_callback(void *param, TAOS_RES *result, int code){ + struct async_query_callback_param* p = (struct async_query_callback_param*) param; + + //printf("\nin c,numfields:%d\n", numFields); + //printf("\nin c, code:%d\n", code); + + lua_State *L = p->state; + lua_rawgeti(L, LUA_REGISTRYINDEX, p->callback); + lua_newtable(L); + int table_index = lua_gettop(L); + if( code < 0){ + printf("failed, reason:%s\n", taos_errstr(result)); + lua_pushinteger(L, -1); + lua_setfield(L, table_index, "code"); + lua_pushstring(L,"something is wrong");// taos_errstr(taos)); + lua_setfield(L, table_index, "error"); + }else{ + //printf("success to async query.\n"); + const int affectRows = taos_affected_rows(result); + //printf(" affect rows:%d\r\n", affectRows); + lua_pushinteger(L, 0); + lua_setfield(L, table_index, "code"); + lua_pushinteger(L, affectRows); + lua_setfield(L, table_index, "affected"); + } + + lua_call(L, 1, 0); +} + +static int l_async_query(lua_State *L){ + int r = luaL_ref(L, LUA_REGISTRYINDEX); + TAOS * taos = (TAOS*)lua_topointer(L,1); + const char * sqlstr = lua_tostring(L,2); + // int stime = luaL_checknumber(L,3); + + lua_newtable(L); + int table_index = lua_gettop(L); + + struct async_query_callback_param *p = malloc(sizeof(struct async_query_callback_param)); + p->state = L; + p->callback=r; + // printf("r:%d, L:%d\n",r,L); + taos_query_a(taos,sqlstr,async_query_callback,p); + + lua_pushnumber(L, 0); + lua_setfield(L, table_index, "code"); + lua_pushstring(L, "ok"); + lua_setfield(L, table_index, "error"); + + return 1; +} + void stream_cb(void *param, TAOS_RES *result, TAOS_ROW row){ struct cb_param* p = (struct cb_param*) param; TAOS_FIELD *fields = taos_fetch_fields(result); @@ -307,6 +365,7 @@ static int l_close(lua_State *L){ static const struct luaL_Reg lib[] = { {"connect", l_connect}, {"query", l_query}, + {"query_a",l_async_query}, {"close", l_close}, {"open_stream", l_open_stream}, {"close_stream", l_close_stream}, diff --git a/tests/examples/lua/test.lua b/tests/examples/lua/test.lua index 9f9c6934aa46d52e1578700b067193351120dbab..89c0904c6a04ecec79a95cb1f710136e93a4a00b 100644 --- a/tests/examples/lua/test.lua +++ b/tests/examples/lua/test.lua @@ -110,7 +110,25 @@ else end end -function callback(t) +function async_query_callback(res) + if res.code ~=0 then + print("async_query_callback--- failed:"..res.error) + return + else + + if(res.affected == 3) then + print("async_query_callback, insert records--- pass") + else + print("async_query_callback, insert records---failed: expect 3 affected records, actually affected "..res.affected) + end + + end +end + +driver.query_a(conn,"INSERT INTO therm1 VALUES ('2019-09-01 00:00:00.005', 100),('2019-09-01 00:00:00.006', 101),('2019-09-01 00:00:00.007', 102)", async_query_callback) + + +function stream_callback(t) print("------------------------") print("continuous query result:") for key, value in pairs(t) do @@ -119,7 +137,7 @@ function callback(t) end local stream -res = driver.open_stream(conn,"SELECT COUNT(*) as count, AVG(degree) as avg, MAX(degree) as max, MIN(degree) as min FROM thermometer interval(2s) sliding(2s);)",0,callback) +res = driver.open_stream(conn,"SELECT COUNT(*) as count, AVG(degree) as avg, MAX(degree) as max, MIN(degree) as min FROM thermometer interval(2s) sliding(2s);)",0, stream_callback) if res.code ~=0 then print("open stream--- failed:"..res.error) return @@ -146,4 +164,5 @@ while loop_index < 30 do end driver.close_stream(stream) + driver.close(conn) diff --git a/tests/mas/Jenkinsfile b/tests/mas/Jenkinsfile index b2a1a5e1167844e777909cc9688186d85b90a707..0e6e94a037d3ba1a187e6bdad2070e9dc4d4a32f 100644 --- a/tests/mas/Jenkinsfile +++ b/tests/mas/Jenkinsfile @@ -29,8 +29,8 @@ pipeline { agent none environment{ - WK = '/var/lib/jenkins/workspace/TDinternal' - WKC= '/var/lib/jenkins/workspace/TDinternal/community' + WK = '/data/lib/jenkins/workspace/TDinternal' + WKC= '/data/lib/jenkins/workspace/TDinternal/community' } stages { diff --git a/tests/pytest/connector/lua.py b/tests/pytest/connector/lua.py new file mode 100644 index 0000000000000000000000000000000000000000..23f0602e12fe378b97ebf493dcbdb0e9a0a9a8fd --- /dev/null +++ b/tests/pytest/connector/lua.py @@ -0,0 +1,73 @@ +################################################################### +# 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 * + + +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 isLuaInstalled(self): + if not which('lua'): + tdLog.exit("Lua not found!") + return False + else: + return True + + def run(self): + tdSql.prepare() +# tdLog.info("Check if Lua installed") +# if not self.isLuaInstalled(): +# sys.exit(1) + + buildPath = self.getBuildPath() + if (buildPath == ""): + tdLog.exit("taosd not found!") + else: + tdLog.info("taosd found in %s" % buildPath) + + targetPath = buildPath + "/../tests/examples/lua" + tdLog.info(targetPath) + currentPath = os.getcwd() + os.chdir(targetPath) + os.system('./build.sh') + os.system('lua test.lua') + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +#tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/crash_gen/crash_gen_main.py b/tests/pytest/crash_gen/crash_gen_main.py index 644aa799164acd4b44224ebd9ed30e39e722371c..b743eee2ef50c49da050cc78c77d0038acf0e507 100755 --- a/tests/pytest/crash_gen/crash_gen_main.py +++ b/tests/pytest/crash_gen/crash_gen_main.py @@ -37,6 +37,7 @@ import requests import gc import taos + from .shared.types import TdColumns, TdTags # from crash_gen import ServiceManager, TdeInstance, TdeSubProcess @@ -160,6 +161,7 @@ class WorkerThread: Logging.debug("[TRD] Thread Coordinator not running any more, worker thread now stopping...") break + # Before we fetch the task and run it, let's ensure we properly "use" the database (not needed any more) try: if (Config.getConfig().per_thread_db_connection): # most likely TRUE @@ -1362,9 +1364,12 @@ class Task(): Progress.emit(Progress.ACCEPTABLE_ERROR) self._err = err else: # not an acceptable error - errMsg = "[=] Unexpected Taos library exception ({}): errno=0x{:X}, msg: {}, SQL: {}".format( + shortTid = threading.get_ident() % 10000 + errMsg = "[=] Unexpected Taos library exception ({}): errno=0x{:X}, thread={}, msg: {}, SQL: {}".format( self.__class__.__name__, - errno2, err, wt.getDbConn().getLastSql()) + errno2, + shortTid, + err, wt.getDbConn().getLastSql()) self.logDebug(errMsg) if Config.getConfig().debug: # raise # so that we see full stack @@ -1411,21 +1416,31 @@ class Task(): def lockTable(self, ftName): # full table name # print(" <<" + ftName + '_', end="", flush=True) - with Task._lock: - if not ftName in Task._tableLocks: + with Task._lock: # SHORT lock! so we only protect lock creation + if not ftName in Task._tableLocks: # Create new lock and add to list, if needed Task._tableLocks[ftName] = threading.Lock() - Task._tableLocks[ftName].acquire() + # No lock protection, anybody can do this any time + lock = Task._tableLocks[ftName] + # Logging.info("Acquiring lock: {}, {}".format(ftName, lock)) + lock.acquire() + # Logging.info("Acquiring lock successful: {}".format(lock)) def unlockTable(self, ftName): # print('_' + ftName + ">> ", end="", flush=True) - with Task._lock: + with Task._lock: if not ftName in self._tableLocks: raise RuntimeError("Corrupt state, no such lock") lock = Task._tableLocks[ftName] if not lock.locked(): raise RuntimeError("Corrupte state, already unlocked") - lock.release() + + # Important note, we want to protect unlocking under the task level + # locking, because we don't want the lock to be deleted (maybe in the futur) + # while we unlock it + # Logging.info("Releasing lock: {}".format(lock)) + lock.release() + # Logging.info("Releasing lock successful: {}".format(lock)) class ExecutionStats: @@ -1696,6 +1711,11 @@ class TdSuperTable: return dbc.query("SELECT * FROM {}.{}".format(self._dbName, self._stName)) > 0 def ensureRegTable(self, task: Optional[Task], dbc: DbConn, regTableName: str): + ''' + Make sure a regular table exists for this super table, creating it if necessary. + If there is an associated "Task" that wants to do this, "lock" this table so that + others don't access it while we create it. + ''' dbName = self._dbName sql = "select tbname from {}.{} where tbname in ('{}')".format(dbName, self._stName, regTableName) if dbc.query(sql) >= 1 : # reg table exists already @@ -1703,18 +1723,24 @@ 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: # TODO: what happens if we don't lock the table - task.lockTable(fullTableName) + if task is not None: # Somethime thie operation is requested on behalf of a "task" + # Logging.info("Locking table for creation: {}".format(fullTableName)) + task.lockTable(fullTableName) # in which case we'll lock this table to ensure serialized access + # Logging.info("Table locked for creation".format(fullTableName)) Progress.emit(Progress.CREATE_TABLE_ATTEMPT) # ATTEMPT to create a new table # print("(" + fullTableName[-3:] + ")", end="", flush=True) try: sql = "CREATE TABLE {} USING {}.{} tags ({})".format( fullTableName, dbName, self._stName, self._getTagStrForSql(dbc) ) + # Logging.info("Creating regular with SQL: {}".format(sql)) dbc.execute(sql) + # Logging.info("Regular table created: {}".format(sql)) finally: if task is not None: + # Logging.info("Unlocking table after creation: {}".format(fullTableName)) task.unlockTable(fullTableName) # no matter what + # Logging.info("Table unlocked after creation: {}".format(fullTableName)) def _getTagStrForSql(self, dbc) : tags = self._getTags(dbc) @@ -2011,9 +2037,30 @@ class TaskAddData(StateTransitionTask): def canBeginFrom(cls, state: AnyState): return state.canAddData() + def _lockTableIfNeeded(self, fullTableName, extraMsg = ''): + if Config.getConfig().verify_data: + # Logging.info("Locking table: {}".format(fullTableName)) + self.lockTable(fullTableName) + # Logging.info("Table locked {}: {}".format(extraMsg, fullTableName)) + # print("_w" + str(nextInt % 100), end="", flush=True) # Trace what was written + else: + # Logging.info("Skipping locking table") + pass + + def _unlockTableIfNeeded(self, fullTableName): + if Config.getConfig().verify_data: + # Logging.info("Unlocking table: {}".format(fullTableName)) + self.unlockTable(fullTableName) + # Logging.info("Table unlocked: {}".format(fullTableName)) + else: + pass + # Logging.info("Skipping unlocking table") + def _addDataInBatch(self, db, dbc, regTableName, te: TaskExecutor): numRecords = self.LARGE_NUMBER_OF_RECORDS if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_RECORDS + fullTableName = db.getName() + '.' + regTableName + self._lockTableIfNeeded(fullTableName, 'batch') sql = "INSERT INTO {} VALUES ".format(fullTableName) for j in range(numRecords): # number of records per table @@ -2021,51 +2068,60 @@ class TaskAddData(StateTransitionTask): nextTick = db.getNextTick() nextColor = db.getNextColor() sql += "('{}', {}, '{}');".format(nextTick, nextInt, nextColor) - dbc.execute(sql) + + # Logging.info("Adding data in batch: {}".format(sql)) + try: + dbc.execute(sql) + finally: + # Logging.info("Data added in batch: {}".format(sql)) + self._unlockTableIfNeeded(fullTableName) + + def _addData(self, db: Database, dbc, regTableName, te: TaskExecutor): # implied: NOT in batches 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() + intToWrite = db.getNextInt() nextTick = db.getNextTick() nextColor = db.getNextColor() 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.write("Ready to write {} to {}\n".format(intToWrite, regTableName)) self.fAddLogReady.flush() os.fsync(self.fAddLogReady.fileno()) # TODO: too ugly trying to lock the table reliably, refactor... fullTableName = db.getName() + '.' + regTableName - if Config.getConfig().verify_data: - self.lockTable(fullTableName) - # print("_w" + str(nextInt % 100), end="", flush=True) # Trace what was written - + self._lockTableIfNeeded(fullTableName) # so that we are verify read-back. TODO: deal with exceptions before unlock + try: sql = "INSERT INTO {} VALUES ('{}', {}, '{}');".format( # removed: tags ('{}', {}) fullTableName, # ds.getFixedSuperTableName(), # ds.getNextBinary(), ds.getNextFloat(), - nextTick, nextInt, nextColor) + nextTick, intToWrite, nextColor) + # Logging.info("Adding data: {}".format(sql)) dbc.execute(sql) + # Logging.info("Data added: {}".format(sql)) + intWrote = intToWrite # Quick hack, attach an update statement here. TODO: create an "update" task if (not Config.getConfig().use_shadow_db) and Dice.throw(5) == 0: # 1 in N chance, plus not using shaddow DB - nextInt = db.getNextInt() + intToUpdate = db.getNextInt() # Updated, but should not succeed nextColor = db.getNextColor() sql = "INSERt INTO {} VALUES ('{}', {}, '{}');".format( # "INSERt" means "update" here fullTableName, - nextTick, nextInt, nextColor) + nextTick, intToUpdate, nextColor) # sql = "UPDATE {} set speed={}, color='{}' WHERE ts='{}'".format( # fullTableName, db.getNextInt(), db.getNextColor(), nextTick) dbc.execute(sql) + intWrote = intToUpdate # We updated, seems TDengine non-cluster accepts this. except: # Any exception at all - if Config.getConfig().verify_data: - self.unlockTable(fullTableName) + self._unlockTableIfNeeded(fullTableName) raise # Now read it back and verify, we might encounter an error if table is dropped @@ -2073,33 +2129,41 @@ class TaskAddData(StateTransitionTask): try: readBack = dbc.queryScalar("SELECT speed from {}.{} WHERE ts='{}'". format(db.getName(), regTableName, nextTick)) - if readBack != nextInt : + if readBack != intWrote : raise taos.error.ProgrammingError( "Failed to read back same data, wrote: {}, read: {}" - .format(nextInt, readBack), 0x999) + .format(intWrote, readBack), 0x999) except taos.error.ProgrammingError as err: errno = Helper.convertErrno(err.errno) - if errno in [CrashGenError.INVALID_EMPTY_RESULT, CrashGenError.INVALID_MULTIPLE_RESULT] : # not a single result + if errno == CrashGenError.INVALID_EMPTY_RESULT: # empty result raise taos.error.ProgrammingError( - "Failed to read back same data for tick: {}, wrote: {}, read: {}" - .format(nextTick, nextInt, "Empty Result" if errno == CrashGenError.INVALID_EMPTY_RESULT else "Multiple Result"), + "Failed to read back same data for tick: {}, wrote: {}, read: EMPTY" + .format(nextTick, intWrote), + errno) + elif errno == CrashGenError.INVALID_MULTIPLE_RESULT : # multiple results + raise taos.error.ProgrammingError( + "Failed to read back same data for tick: {}, wrote: {}, read: MULTIPLE RESULTS" + .format(nextTick, intWrote), errno) elif errno in [0x218, 0x362]: # table doesn't exist # do nothing - dummy = 0 + pass else: # Re-throw otherwise raise finally: - self.unlockTable(fullTableName) # Unlock the table no matter what + self._unlockTableIfNeeded(fullTableName) # Quite ugly, refactor lock/unlock + # Done with read-back verification, unlock the table now + else: + self._unlockTableIfNeeded(fullTableName) # Successfully wrote the data into the DB, let's record it somehow - te.recordDataMark(nextInt) + te.recordDataMark(intWrote) 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.write("Wrote {} to {}\n".format(intWrote, regTableName)) self.fAddLogDone.flush() os.fsync(self.fAddLogDone.fileno()) @@ -2137,15 +2201,16 @@ class TaskAddData(StateTransitionTask): class ThreadStacks: # stack info for all threads def __init__(self): self._allStacks = {} - allFrames = sys._current_frames() - for th in threading.enumerate(): + allFrames = sys._current_frames() # All current stack frames + for th in threading.enumerate(): # For each thread if th.ident is None: continue - stack = traceback.extract_stack(allFrames[th.ident]) - self._allStacks[th.native_id] = stack + stack = traceback.extract_stack(allFrames[th.ident]) # Get stack for a thread + shortTid = th.ident % 10000 + self._allStacks[shortTid] = stack # Was using th.native_id def print(self, filteredEndName = None, filterInternal = False): - for thNid, stack in self._allStacks.items(): # for each thread, stack frames top to bottom + for tIdent, stack in self._allStacks.items(): # for each thread, stack frames top to bottom lastFrame = stack[-1] if filteredEndName: # we need to filter out stacks that match this name if lastFrame.name == filteredEndName : # end did not match @@ -2157,7 +2222,7 @@ class ThreadStacks: # stack info for all threads '__init__']: # the thread that extracted the stack continue # ignore # Now print - print("\n<----- Thread Info for LWP/ID: {} (most recent call last) <-----".format(thNid)) + print("\n<----- Thread Info for LWP/ID: {} (most recent call last) <-----".format(tIdent)) stackFrame = 0 for frame in stack: # was using: reversed(stack) # print(frame) @@ -2376,7 +2441,7 @@ class MainExec: action='store', default=0, type=int, - help='Maximum number of DBs to keep, set to disable dropping DB. (default: 0)') + help='Number of DBs to use, set to disable dropping DB. (default: 0)') parser.add_argument( '-c', '--connector-type', diff --git a/tests/pytest/crash_gen/service_manager.py b/tests/pytest/crash_gen/service_manager.py index 1cd65c1dde4e9c2027a82730cf4fc12290048bbe..c6685ec4691aa6ddcc7b12f45c96cba4432ef327 100644 --- a/tests/pytest/crash_gen/service_manager.py +++ b/tests/pytest/crash_gen/service_manager.py @@ -179,7 +179,7 @@ quorum 2 def getServiceCmdLine(self): # to start the instance if Config.getConfig().track_memory_leaks: Logging.info("Invoking VALGRIND on service...") - return ['exec /usr/bin/valgrind', '--leak-check=yes', self.getExecFile(), '-c', self.getCfgDir()] + return ['exec 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() @@ -310,7 +310,7 @@ class TdeSubProcess: # print("Starting TDengine with env: ", myEnv.items()) print("Starting TDengine: {}".format(cmdLine)) - return Popen( + ret = Popen( ' '.join(cmdLine), # ' '.join(cmdLine) if useShell else cmdLine, shell=True, # Always use shell, since we need to pass ENV vars stdout=PIPE, @@ -318,6 +318,10 @@ class TdeSubProcess: close_fds=ON_POSIX, env=myEnv ) # had text=True, which interferred with reading EOF + time.sleep(0.01) # very brief wait, then let's check if sub process started successfully. + if ret.poll(): + raise CrashGenError("Sub process failed to start with command line: {}".format(cmdLine)) + return ret STOP_SIGNAL = signal.SIGINT # signal.SIGKILL/SIGINT # What signal to use (in kill) to stop a taosd process? SIG_KILL_RETCODE = 137 # ref: https://stackoverflow.com/questions/43268156/process-finished-with-exit-code-137-in-pycharm @@ -614,7 +618,7 @@ class ServiceManager: # Find if there's already a taosd service, and then kill it for proc in psutil.process_iter(): - if proc.name() == 'taosd': + if proc.name() == 'taosd' or proc.name() == 'memcheck-amd64-': # Regular or under Valgrind Logging.info("Killing an existing TAOSD process in 2 seconds... press CTRL-C to interrupt") time.sleep(2.0) proc.kill() diff --git a/tests/pytest/crash_gen/shared/misc.py b/tests/pytest/crash_gen/shared/misc.py index 90ad802ff1c130439cdc5f5587ecd0607e3e116b..78923bcc29ebb52df1c1a44d5e24ea5159962486 100644 --- a/tests/pytest/crash_gen/shared/misc.py +++ b/tests/pytest/crash_gen/shared/misc.py @@ -35,7 +35,8 @@ class LoggingFilter(logging.Filter): class MyLoggingAdapter(logging.LoggerAdapter): def process(self, msg, kwargs): - return "[{:04d}] {}".format(threading.get_ident() % 10000, msg), kwargs + shortTid = threading.get_ident() % 10000 + return "[{:04d}] {}".format(shortTid, msg), kwargs # return '[%s] %s' % (self.extra['connid'], msg), kwargs 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/fulltest.sh b/tests/pytest/fulltest.sh index d8e2a31e70bd14b8feef6c8a45df671473e68537..c5aba24867a0a45d216902fc685aa0153ddbff14 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -31,13 +31,15 @@ python3 ./test.py -f table/column_name.py python3 ./test.py -f table/column_num.py python3 ./test.py -f table/db_table.py python3 ./test.py -f table/create_sensitive.py -#python3 ./test.py -f table/tablename-boundary.py +python3 ./test.py -f table/tablename-boundary.py python3 ./test.py -f table/max_table_length.py python3 ./test.py -f table/alter_column.py 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 @@ -332,5 +334,7 @@ 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 +python3 ./test.py -f tag_lite/drop_auto_create.py +python3 test.py -f insert/insert_before_use_db.py #======================p4-end=============== diff --git a/tests/pytest/import_merge/importCSV.py b/tests/pytest/import_merge/importCSV.py index b4441949a1c8e83f15e07d76ceb49de0dc418afe..24ebffd48530e20a9a4f0cc13d4784e997ba4a75 100644 --- a/tests/pytest/import_merge/importCSV.py +++ b/tests/pytest/import_merge/importCSV.py @@ -82,6 +82,8 @@ class TDTestCase: tdSql.execute("import into tbx file \'%s\'"%(self.csvfile)) tdSql.query('select * from tbx') tdSql.checkRows(self.rows) + #TD-4447 import the same csv twice + tdSql.execute("import into tbx file \'%s\'"%(self.csvfile)) def stop(self): self.destroyCSVFile() diff --git a/tests/pytest/insert/insert_before_use_db.py b/tests/pytest/insert/insert_before_use_db.py new file mode 100644 index 0000000000000000000000000000000000000000..8cc02b3d4bde3fc6465c6011ade24fd8d15818be --- /dev/null +++ b/tests/pytest/insert/insert_before_use_db.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 -*- + +import sys +from util.log import * +from util.cases import * +from util.sql import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + tdSql.error('insert into tb values (now + 10m, 10)') + tdSql.prepare() + tdSql.error('insert into tb values (now + 10m, 10)') + tdSql.execute('drop database db') + tdSql.error('insert into tb values (now + 10m, 10)') + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/insert/nchar.py b/tests/pytest/insert/nchar.py index 3319aa3c565b76d4d7fb9c33b04549e090c8062b..5ad52b96a1555b3ccd622fd4bf88c7a0b26051b5 100644 --- a/tests/pytest/insert/nchar.py +++ b/tests/pytest/insert/nchar.py @@ -36,6 +36,10 @@ class TDTestCase: tdSql.checkData(1, 1, '涛思数据') tdSql.error("insert into tb values (now, 'taosdata001')") + + tdSql.error("insert into tb(now, 😀)") + tdSql.query("select * from tb") + tdSql.checkRows(2) def stop(self): tdSql.close() diff --git a/tests/pytest/smoketest.sh b/tests/pytest/smoketest.sh index 0eb850749fbb62f3d4149f6051dfd2851ed55a88..7f7cb2a89e0b3f808a505b37360d227a9b38acc7 100755 --- a/tests/pytest/smoketest.sh +++ b/tests/pytest/smoketest.sh @@ -35,3 +35,5 @@ python3.8 ./test.py $1 -s && sleep 1 python3.8 ./test.py $1 -f client/client.py python3.8 ./test.py $1 -s && sleep 1 +# connector +python3.8 ./test.py $1 -f connector/lua.py 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/table/tablename-boundary.py b/tests/pytest/table/tablename-boundary.py index 0755e7535577b32c52539ab46259b53096455808..dc22c3343b403a93587b7f626061caa62fbf30d1 100644 --- a/tests/pytest/table/tablename-boundary.py +++ b/tests/pytest/table/tablename-boundary.py @@ -14,6 +14,13 @@ class TDTestCase: tdLog.debug("start to execute %s" % __file__) tdSql.init(conn.cursor(), logSql) + self.ts = 1622100000000 + + def get_random_string(self, length): + letters = string.ascii_lowercase + result_str = ''.join(random.choice(letters) for i in range(length)) + return result_str + def run(self): tdSql.prepare() @@ -24,19 +31,62 @@ class TDTestCase: shell=True)) - 1 tdLog.info("table name max length is %d" % tableNameMaxLen) chars = string.ascii_uppercase + string.ascii_lowercase - tb_name = ''.join(random.choices(chars, k=tableNameMaxLen)) + tb_name = ''.join(random.choices(chars, k=tableNameMaxLen + 1)) tdLog.info('tb_name length %d' % len(tb_name)) tdLog.info('create table %s (ts timestamp, value int)' % tb_name) - tdSql.error( - 'create table %s (ts timestamp, speed binary(4089))' % - tb_name) + tdSql.error('create table %s (ts timestamp, speed binary(4089))' % tb_name) - tb_name = ''.join(random.choices(chars, k=191)) + tb_name = ''.join(random.choices(chars, k=tableNameMaxLen)) tdLog.info('tb_name length %d' % len(tb_name)) tdLog.info('create table %s (ts timestamp, value int)' % tb_name) tdSql.execute( 'create table %s (ts timestamp, speed binary(4089))' % tb_name) + + db_name = self.get_random_string(33) + tdSql.error("create database %s" % db_name) + + db_name = self.get_random_string(32) + tdSql.execute("create database %s" % db_name) + tdSql.execute("use %s" % db_name) + + tb_name = self.get_random_string(193) + tdSql.error("create table %s(ts timestamp, val int)" % tb_name) + + tb_name = self.get_random_string(192) + tdSql.execute("create table %s.%s(ts timestamp, val int)" % (db_name, tb_name)) + tdSql.query("show %s.tables" % db_name) + tdSql.checkRows(1) + tdSql.checkData(0, 0, tb_name) + + tdSql.execute("insert into %s.%s values(now, 1)" % (db_name, tb_name)) + tdSql.query("select * from %s.%s" %(db_name, tb_name)) + tdSql.checkRows(1) + + db_name = self.get_random_string(32) + tdSql.execute("create database %s update 1" % db_name) + + stb_name = self.get_random_string(192) + tdSql.execute("create table %s.%s(ts timestamp, val int) tags(id int)" % (db_name, stb_name)) + tb_name1 = self.get_random_string(192) + tdSql.execute("insert into %s.%s using %s.%s tags(1) values(%d, 1)(%d, 2)(%d, 3)" % (db_name, tb_name1, db_name, stb_name, self.ts, self.ts + 1, self.ts + 2)) + tb_name2 = self.get_random_string(192) + tdSql.execute("insert into %s.%s using %s.%s tags(2) values(%d, 1)(%d, 2)(%d, 3)" % (db_name, tb_name2, db_name, stb_name, self.ts, self.ts + 1, self.ts + 2)) + + tdSql.query("show %s.tables" % db_name) + tdSql.checkRows(2) + + tdSql.query("select * from %s.%s" % (db_name, stb_name)) + tdSql.checkRows(6) + + tdSql.execute("insert into %s.%s using %s.%s tags(1) values(%d, null)" % (db_name, tb_name1, db_name, stb_name, self.ts)) + + tdSql.query("select * from %s.%s" % (db_name, stb_name)) + tdSql.checkRows(6) + + + + def stop(self): tdSql.close() diff --git a/tests/pytest/tag_lite/drop_auto_create.py b/tests/pytest/tag_lite/drop_auto_create.py new file mode 100644 index 0000000000000000000000000000000000000000..f89b41008b167884f54cacde3eda11cbc81c0040 --- /dev/null +++ b/tests/pytest/tag_lite/drop_auto_create.py @@ -0,0 +1,47 @@ +################################################################### +# 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 * + + +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('create table m1(ts timestamp, k int) tags(a binary(12), b int, c double);') + tdSql.execute('insert into tm0 using m1(b,c) tags(1, 99) values(now, 1);') + tdSql.execute('insert into tm1 using m1(b,c) tags(2, 100) values(now, 2);') + tdLog.info("2 rows inserted") + tdSql.query('select * from m1;') + tdSql.checkRows(2) + tdSql.query('select *,tbname from m1;') + tdSql.execute("drop table tm0; ") + tdSql.query('select * from m1') + tdSql.checkRows(1) + + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/script/api/batchprepare.c b/tests/script/api/batchprepare.c index db48632cb7814229db4a973cc6b41e00d6e8ada4..55eb62d9bb4272fe7ab85a96561ebd9c87343ed0 100644 --- a/tests/script/api/batchprepare.c +++ b/tests/script/api/batchprepare.c @@ -840,6 +840,1026 @@ int stmt_func3(TAOS_STMT *stmt) { } + +//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); + free(tags); + + 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); + free(tags); + + 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); + free(tags); + + 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); + free(tags); + + 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); + free(tags); + + return 0; +} + + + //300 tables 60 records int stmt_funcb1(TAOS_STMT *stmt) { struct { @@ -2540,14 +3560,14 @@ int sql_s_perf1(TAOS *taos) { } -void prepare(TAOS *taos, int bigsize) { +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"); + 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)); @@ -2558,15 +3578,34 @@ void prepare(TAOS *taos, int bigsize) { result = taos_query(taos, "use demo"); taos_free_result(result); - - // create table - for (int i = 0 ; i < 300; i++) { + + 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 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) ; + 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 table m%d (ts timestamp, b int)", i) ; + 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) { @@ -2593,7 +3632,7 @@ void preparem(TAOS *taos, int bigsize, int idx) { result = taos_query(taos, sql); taos_free_result(result); - sprintf(sql, "create database %s", dbname); + sprintf(sql, "create database %s keep 36500", dbname); result = taos_query(taos, sql); code = taos_errno(result); if (code != 0) { @@ -2640,8 +3679,8 @@ void* runcase(void *par) { (void)idx; -#if 0 - prepare(taos, 1); +#if 1 + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2664,8 +3703,8 @@ void* runcase(void *par) { #endif -#if 0 - prepare(taos, 1); +#if 1 + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2679,8 +3718,8 @@ void* runcase(void *par) { #endif -#if 0 - prepare(taos, 1); +#if 1 + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2699,7 +3738,7 @@ void* runcase(void *par) { #endif #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2720,12 +3759,11 @@ void* runcase(void *par) { printf("check result end\n"); taos_stmt_close(stmt); - return NULL; #endif #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2749,7 +3787,7 @@ void* runcase(void *par) { #endif #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2773,7 +3811,7 @@ void* runcase(void *par) { #endif #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2798,7 +3836,7 @@ void* runcase(void *par) { #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2813,11 +3851,88 @@ void* runcase(void *par) { 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); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2836,7 +3951,7 @@ void* runcase(void *par) { #endif #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2856,7 +3971,7 @@ void* runcase(void *par) { #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2874,7 +3989,7 @@ void* runcase(void *par) { #endif #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2890,7 +4005,7 @@ void* runcase(void *par) { #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2908,7 +4023,7 @@ void* runcase(void *par) { #endif #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2927,7 +4042,7 @@ void* runcase(void *par) { #endif #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2952,7 +4067,7 @@ void* runcase(void *par) { #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -2972,7 +4087,7 @@ void* runcase(void *par) { #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); (void)stmt; printf("120t+60r+sql start\n"); @@ -2988,7 +4103,7 @@ void* runcase(void *par) { #endif #if 1 - prepare(taos, 1); + prepare(taos, 1, 1); (void)stmt; printf("1t+60r+sql start\n"); diff --git a/tests/script/api/stmtBatchTest.c b/tests/script/api/stmtBatchTest.c index 8bd296db6123a4602a95c4777b7ef1322a37d7ba..24291adfa0a64349d62b59455ce0db52e36bcf4f 100644 --- a/tests/script/api/stmtBatchTest.c +++ b/tests/script/api/stmtBatchTest.c @@ -1450,6 +1450,47 @@ static void prepareV_long(TAOS *taos, int schemaCase, int tableNum, int lenO } +static void prepareVcolumn_autoCreateTbl(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 + char buf[1024] = {0}; + //if (bigsize) { + sprintf(buf, "create stable stb1 (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, br binary(%d), nr nchar(%d), ts2 timestamp)" + " tags(id1 int, id2 bool, id3 tinyint, id4 smallint, id5 bigint, id6 float, id7 double, id8 binary(%d), id9 nchar(%d))", lenOfBinaryDef, lenOfBinaryDef, lenOfBinaryDef, lenOfBinaryDef) ; + //} 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); + return; + } + taos_free_result(result); +} + static void prepareVcolumn(TAOS *taos, int schemaCase, int tableNum, int lenOfBinaryDef, char* dbName) { TAOS_RES *result; @@ -3159,72 +3200,1278 @@ static void SpecifyColumnBatchCase(TAOS *taos) { } -int main(int argc, char *argv[]) -{ - TAOS *taos; - char host[32] = "127.0.0.1"; - char* serverIp = NULL; - int threadNum = 1; + +/*=======================*/ +/* +test scene: insert into tb1 (ts,f1) values (?,?) +*/ +static int stmt_specifyCol_bind_case_001_autoCreateTbl(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)); - // 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]); + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + 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); + int one_not_null = 0; + + 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; } - printf("server:%s, runTimes:%d\n\n", serverIp, g_runTimes); + 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; -#if 0 - printf("server:%s, threadNum:%d, rows:%d\n\n", serverIp, threadNum, g_rows); + 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; - pthread_t *pThreadList = (pthread_t *) calloc(sizeof(pthread_t), (size_t)threadNum); - ThreadInfo* threadInfo = (ThreadInfo *) calloc(sizeof(ThreadInfo), (size_t)threadNum); + 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; - 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; - } + 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; - 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++; + i+=columnNum; } - for (int i = 0; i < threadNum; i++) { - pthread_join(pThreadList[i], NULL); + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; } - free(pThreadList); - free(threadInfo); -#endif + 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->br; + 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->nr; + tags[i+8].is_null = &one_not_null; + tags[i+8].length = (uintptr_t *)lb; + } - taos = taos_connect(serverIp, "root", "taosdata", NULL, 0); - if (taos == NULL) { - printf("failed to connect to TDengine, reason:%s\n", taos_errstr(taos)); + + 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) using stb1 tags (?,?,?,?,?,?,?,?,?) values(?,?,?,?,?)"; + char *sql = "insert into ? using stb1 tags (?,?,?,?,?,?,?,?,?) (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_tags(stmt, buf, tags); + 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(tags); + free(is_null); + free(no_null); + + return 0; +} + +static int stmt_specifyCol_bind_case_002_autoCreateTbl(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); - runCase(taos); - runCase_long(taos); - SpecifyColumnBatchCase(taos); + 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_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + 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); + int one_not_null = 0; + + 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; + } + + 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+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+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+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_BIGINT; + tags[i+2].buffer = v->v8; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+3].buffer = v->f4; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = NULL; + + tags[i+4].buffer_type = TSDB_DATA_TYPE_DOUBLE; + tags[i+4].buffer = v->f8; + tags[i+4].is_null = &one_not_null; + tags[i+4].length = NULL; + + tags[i+5].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+5].buffer = v->br; + tags[i+5].is_null = &one_not_null; + tags[i+5].length = (uintptr_t *)lb; + + tags[i+6].buffer_type = TSDB_DATA_TYPE_NCHAR; + tags[i+6].buffer = v->nr; + tags[i+6].is_null = &one_not_null; + tags[i+6].length = (uintptr_t *)lb; + } + + + 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) using stb1 tags (?,?,?,?,?,?,?,?,?) values(?,?,?,?,?)"; + char *sql = "insert into ? using stb1 tags (33,?,99,?,?,?,?,?,?) (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_tags(stmt, buf, tags); + 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(tags); + free(is_null); + free(no_null); + + return 0; +} + +// some tags are null +static int stmt_specifyCol_bind_case_003_autoCreateTbl(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_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + 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); + int one_not_null = 0; + int one_is_null = 1; + + 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; + } + + 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_is_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_is_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_is_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->br; + 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->nr; + tags[i+8].is_null = &one_not_null; + tags[i+8].length = (uintptr_t *)lb; + } + + + 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) using stb1 tags (?,?,?,?,?,?,?,?,?) values(?,?,?,?,?)"; + char *sql = "insert into ? using stb1 tags (?,?,?,?,?,?,?,?,?) (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_tags(stmt, buf, tags); + 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(tags); + free(is_null); + free(no_null); + + return 0; +} + +// specify tags field, and not support , then is error case +static int stmt_specifyCol_bind_case_004_autoCreateTbl(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_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + 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); + int one_not_null = 0; + + 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; + } + + 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+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+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+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_BIGINT; + tags[i+2].buffer = v->v8; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+3].buffer = v->f4; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = NULL; + + tags[i+4].buffer_type = TSDB_DATA_TYPE_DOUBLE; + tags[i+4].buffer = v->f8; + tags[i+4].is_null = &one_not_null; + tags[i+4].length = NULL; + + tags[i+5].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+5].buffer = v->br; + tags[i+5].is_null = &one_not_null; + tags[i+5].length = (uintptr_t *)lb; + + tags[i+6].buffer_type = TSDB_DATA_TYPE_NCHAR; + tags[i+6].buffer = v->nr; + tags[i+6].is_null = &one_not_null; + tags[i+6].length = (uintptr_t *)lb; + } + + + 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) using stb1 tags (?,?,?,?,?,?,?,?,?) values(?,?,?,?,?)"; + char *sql = "insert into ? using stb1 (id1, id2, id3, id4, id5, id6, id7, id8, id9) tags (33,?,99,?,?,?,?,?,?) (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_tags(stmt, buf, tags); + 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(tags); + free(is_null); + free(no_null); + + return 0; +} + +static void SpecifyColumnBatchCase_autoCreateTbl(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_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db1"); + stmt_specifyCol_bind_case_001_autoCreateTbl(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_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db2"); + stmt_specifyCol_bind_case_001_autoCreateTbl(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_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db2_1"); + stmt_specifyCol_bind_case_001_autoCreateTbl(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_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db2_2"); + stmt_specifyCol_bind_case_001_autoCreateTbl(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_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db3"); + stmt_specifyCol_bind_case_001_autoCreateTbl(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_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db4"); + stmt_specifyCol_bind_case_001_autoCreateTbl(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-rows to single table ==========================// + //========== case 5: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 23740; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db5"); + stmt_specifyCol_bind_case_001_autoCreateTbl(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 5 check result end\n\n"); + } +#endif + +// ============== error test: 1.multi table, 2.specify some tags + //========== case 6: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 2; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db6"); + stmt_specifyCol_bind_case_001_autoCreateTbl(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 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 = 200; + rowsOfPerColum = 60; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db7"); + stmt_specifyCol_bind_case_001_autoCreateTbl(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m99", 0, totalRowsPerTbl); + checkResult(taos, "m139", 0, totalRowsPerTbl); + checkResult(taos, "m199", 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 = 1; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db8"); + stmt_specifyCol_bind_case_002_autoCreateTbl(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 8 check result end\n\n"); + } +#endif + + //========== case 9: ======================// + +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 10; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db9"); + stmt_specifyCol_bind_case_002_autoCreateTbl(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m6", 0, totalRowsPerTbl); + checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 9 check result end\n\n"); + } +#endif + + //========== case 10: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 23740; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db10"); + stmt_specifyCol_bind_case_003_autoCreateTbl(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 = 2; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db11"); + stmt_specifyCol_bind_case_003_autoCreateTbl(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 11 check result end\n\n"); + } +#endif + + //========== case 12: ======================// +#if 1 + { + stmt = taos_stmt_init(taos); + + tableNum = 200; + rowsOfPerColum = 60; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db12"); + stmt_specifyCol_bind_case_003_autoCreateTbl(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m99", 0, totalRowsPerTbl); + checkResult(taos, "m139", 0, totalRowsPerTbl); + checkResult(taos, "m199", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 12 check result end\n\n"); + } +#endif + + + //========== case 13: ======================// +#if 1 + { + printf("====case 13 error test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 8; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn_autoCreateTbl(taos, 1, tableNum, lenOfBinaryDef, "db13"); + stmt_specifyCol_bind_case_004_autoCreateTbl(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("====case 13 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); + SpecifyColumnBatchCase_autoCreateTbl(taos); return 0; } diff --git a/tests/script/fullGeneralSuite.sim b/tests/script/fullGeneralSuite.sim index cde51ebdbfc90f50bbe8d7941fd4f697d8b59ee5..2cd22362005de07eb2a02b1d0fadec9fc8bdca08 100644 --- a/tests/script/fullGeneralSuite.sim +++ b/tests/script/fullGeneralSuite.sim @@ -33,6 +33,7 @@ run general/compute/percentile.sim run general/compute/stddev.sim run general/compute/sum.sim run general/compute/top.sim +run general/compute/block_dist.sim run general/db/alter_option.sim run general/db/alter_tables_d2.sim run general/db/alter_tables_v1.sim diff --git a/tests/script/general/compute/block_dist.sim b/tests/script/general/compute/block_dist.sim new file mode 100644 index 0000000000000000000000000000000000000000..51cf903654fe6173a5f78cdfdbd9c63b301cfa07 --- /dev/null +++ b/tests/script/general/compute/block_dist.sim @@ -0,0 +1,94 @@ +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 2000 +sql connect + +$dbPrefix = m_di_db +$tbPrefix = m_di_tb +$mtPrefix = m_di_mt +$ntPrefix = m_di_nt +$tbNum = 1 +$rowNum = 2000 + +print =============== step1 +$i = 0 +$db = $dbPrefix . $i +$mt = $mtPrefix . $i +$nt = $ntPrefix . $i + +sql drop database $db -x step1 +step1: +sql create database $db +sql use $db +sql create table $mt (ts timestamp, tbcol int) TAGS(tgcol int) + +$i = 0 +while $i < $tbNum + $tb = $tbPrefix . $i + sql create table $tb using $mt tags( $i ) + + $x = 0 + while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + sql insert into $tb values ($ms , $x ) + $x = $x + 1 + endw + + $i = $i + 1 +endw + +sql create table $nt (ts timestamp, tbcol int) +$x = 0 +while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + sql insert into $nt values ($ms , $x ) + $x = $x + 1 +endw + +sleep 100 + +print =============== step2 +$i = 0 +$tb = $tbPrefix . $i + +sql select _block_dist() from $tb + +if $rows != 1 then + print expect 1, actual:$rows + return -1 +endi + +print =============== step3 +$i = 0 +$mt = $mtPrefix . $i +sql select _block_dist() from $mt + +if $rows != 1 then + print expect 1, actual:$rows + return -1 +endi + +print =============== step4 +$i = 0 +$nt = $ntPrefix . $i + +sql select _block_dist() from $nt + +if $rows != 1 then + print expect 1, actual:$rows + return -1 +endi + +print =============== clear +sql drop database $db +sql show databases +if $rows != 0 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/compute/testSuite.sim b/tests/script/general/compute/testSuite.sim index 6cd6badaeec40e6581c127cdf9328de70021a38d..91bf4bf0cda54d300f4d284c9e057616d4d54abe 100644 --- a/tests/script/general/compute/testSuite.sim +++ b/tests/script/general/compute/testSuite.sim @@ -14,3 +14,4 @@ run general/compute/percentile.sim run general/compute/stddev.sim run general/compute/sum.sim run general/compute/top.sim +run general/compute/block_dist.sim diff --git a/tests/script/general/parser/binary_escapeCharacter.sim b/tests/script/general/parser/binary_escapeCharacter.sim index b5bb10284b9b1b09456f4fe9dd3e07cb14a33721..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 diff --git a/tests/script/general/parser/function.sim b/tests/script/general/parser/function.sim index 65058333fb6a6dea4d0dd583b86f2927bdcc7979..ee5a750c88ede5e373c47796c1bc9d373f223e19 100644 --- a/tests/script/general/parser/function.sim +++ b/tests/script/general/parser/function.sim @@ -24,6 +24,9 @@ sql drop database if exists $db sql create database $db keep 36500 sql use $db +print =====================================> td-4481 +sql create database $db + print =====================================> test case for twa in single block sql create table t1 (ts timestamp, k float); @@ -809,3 +812,5 @@ endi if $data00 != 1 then return -1 endi + +print ====================> TODO stddev + normal column filter diff --git a/tests/script/general/parser/import_file.sim b/tests/script/general/parser/import_file.sim index a39d79af17ce55d452e5ba11cdf97535cf09897b..e9f0f1ed085cc75238681dc08b9601a8d591f6c4 100644 --- a/tests/script/general/parser/import_file.sim +++ b/tests/script/general/parser/import_file.sim @@ -18,6 +18,7 @@ system general/parser/gendata.sh sql create table tbx (ts TIMESTAMP, collect_area NCHAR(12), device_id BINARY(16), imsi BINARY(16), imei BINARY(16), mdn BINARY(10), net_type BINARY(4), mno NCHAR(4), province NCHAR(10), city NCHAR(16), alarm BINARY(2)) print ====== create tables success, starting import data +sql import into tbx file '~/data.sql' sql import into tbx file '~/data.sql' sql select count(*) from tbx 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..3d13ff504db8e86ceaed368b237e0a834987e53e --- /dev/null +++ b/tests/script/general/parser/nestquery.sim @@ -0,0 +1,206 @@ +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_db +$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/testSuite.sim b/tests/script/general/parser/testSuite.sim index 1294b093c27aaaa8ecbcafa50dfacb3b10f7dfdd..6265fc3a02822f3a5d2f5a8d52fcd1e7252c8585 100644 --- a/tests/script/general/parser/testSuite.sim +++ b/tests/script/general/parser/testSuite.sim @@ -54,9 +54,11 @@ run general/parser/timestamp.sim 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 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 +run general/parser/nestquery.sim diff --git a/tests/script/regressionSuite.sim b/tests/script/regressionSuite.sim index e5e2194e87537f8496c9f6c5832d1a7d71842494..d5742cd98ff4184d50c256309c807e0b19bbe1c2 100644 --- a/tests/script/regressionSuite.sim +++ b/tests/script/regressionSuite.sim @@ -32,6 +32,7 @@ run general/compute/percentile.sim run general/compute/stddev.sim run general/compute/sum.sim run general/compute/top.sim +run general/compute/block_dist.sim run general/db/alter_option.sim run general/db/alter_tables_d2.sim run general/db/alter_tables_v1.sim