diff --git a/cmake/define.inc b/cmake/define.inc index e825dce024..4115dd0c41 100755 --- a/cmake/define.inc +++ b/cmake/define.inc @@ -57,7 +57,7 @@ IF (TD_LINUX_64) ADD_DEFINITIONS(-D_M_X64) ADD_DEFINITIONS(-D_TD_LINUX_64) MESSAGE(STATUS "linux64 is defined") - SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ADD_DEFINITIONS(-DUSE_LIBICONV) ENDIF () @@ -65,7 +65,7 @@ IF (TD_LINUX_32) ADD_DEFINITIONS(-D_TD_LINUX_32) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "linux32 is defined") - SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -fsigned-char -munaligned-access -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -munaligned-access -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_ARM_64) @@ -73,7 +73,7 @@ IF (TD_ARM_64) ADD_DEFINITIONS(-D_TD_ARM_) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "arm64 is defined") - SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_ARM_32) @@ -81,7 +81,7 @@ IF (TD_ARM_32) ADD_DEFINITIONS(-D_TD_ARM_) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "arm32 is defined") - SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-incompatible-pointer-types ") + SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-incompatible-pointer-types ") ENDIF () IF (TD_MIPS_64) @@ -89,7 +89,7 @@ IF (TD_MIPS_64) ADD_DEFINITIONS(-D_TD_MIPS_64) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "mips64 is defined") - SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_MIPS_32) @@ -97,7 +97,7 @@ IF (TD_MIPS_32) ADD_DEFINITIONS(-D_TD_MIPS_32) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "mips32 is defined") - SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-Wall -Werror -fPIC -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_APLHINE) @@ -138,7 +138,7 @@ IF (TD_DARWIN_64) ADD_DEFINITIONS(-D_REENTRANT -D__USE_POSIX -D_LIBC_REENTRANT) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "darwin64 is defined") - SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -Wno-missing-braces -fPIC -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-Wall -Werror -Wno-missing-braces -fPIC -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") SET(DEBUG_FLAGS "-O0 -g3 -DDEBUG") SET(RELEASE_FLAGS "-Og") INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc) diff --git a/cmake/env.inc b/cmake/env.inc index efcc996176..3989993953 100755 --- a/cmake/env.inc +++ b/cmake/env.inc @@ -32,6 +32,7 @@ ENDIF () # # Set compiler options +SET(COMMON_C_FLAGS "${COMMON_FLAGS} -std=gnu99") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COMMON_FLAGS} ${DEBUG_FLAGS}") SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${COMMON_FLAGS} ${RELEASE_FLAGS}") diff --git a/cmake/version.inc b/cmake/version.inc index a560c7f598..0ee23f319a 100755 --- a/cmake/version.inc +++ b/cmake/version.inc @@ -4,7 +4,7 @@ PROJECT(TDengine) IF (DEFINED VERNUMBER) SET(TD_VER_NUMBER ${VERNUMBER}) ELSE () - SET(TD_VER_NUMBER "2.0.20.2") + SET(TD_VER_NUMBER "2.1.0.0") ENDIF () IF (DEFINED VERCOMPATIBLE) diff --git a/documentation20/cn/00.index/docs.md b/documentation20/cn/00.index/docs.md index aba10a14e3..50b31a55d3 100644 --- a/documentation20/cn/00.index/docs.md +++ b/documentation20/cn/00.index/docs.md @@ -117,9 +117,9 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专 ## 常用工具 * [TDengine样例导入工具](https://www.taosdata.com/blog/2020/01/18/1166.html) -* [TDengine性能对比测试工具](https://www.taosdata.com/blog/2020/01/18/1166.html) +* [TDengine写入性能测试工具](https://www.taosdata.com/blog/2020/01/18/1166.html) * [IDEA数据库管理工具可视化使用TDengine](https://www.taosdata.com/blog/2020/08/27/1767.html) -* [基于eletron开发的跨平台TDengine图形化管理工具](https://github.com/skye0207/TDengineGUI) +* [基于Electron开发的跨平台TDengine图形化管理工具](https://github.com/skye0207/TDengineGUI) * [DataX,支持TDengine的离线数据采集/同步工具](https://github.com/wgzhao/DataX)(文档:[读取插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/reader/tdenginereader.md)、[写入插件](https://github.com/wgzhao/DataX/blob/master/docs/src/main/sphinx/writer/tdenginewriter.md)) ## TDengine与其他数据库的对比测试 diff --git a/documentation20/cn/02.getting-started/01.docker/docs.md b/documentation20/cn/02.getting-started/01.docker/docs.md new file mode 100644 index 0000000000..30803d9777 --- /dev/null +++ b/documentation20/cn/02.getting-started/01.docker/docs.md @@ -0,0 +1,211 @@ +# 通过 Docker 快速体验 TDengine + +虽然并不推荐在生产环境中通过 Docker 来部署 TDengine 服务,但 Docker 工具能够很好地屏蔽底层操作系统的环境差异,很适合在开发测试或初次体验时用于安装运行 TDengine 的工具集。特别是,借助 Docker,能够比较方便地在 Mac OSX 和 Windows 系统上尝试 TDengine,而无需安装虚拟机或额外租用 Linux 服务器。 + +下文通过 Step by Step 风格的介绍,讲解如何通过 Docker 快速建立 TDengine 的单节点运行环境,以支持开发和测试。 + +## 下载 Docker + +Docker 工具自身的下载请参考 [Docker官网文档](https://docs.docker.com/get-docker/)。 + +安装完毕后可以在命令行终端查看 Docker 版本。如果版本号正常输出,则说明 Docker 环境已经安装成功。 + +```bash +$ docker -v +Docker version 20.10.5, build 55c4c88 +``` + +## 在 Docker 容器中运行 TDengine + +1,使用命令拉取 TDengine 镜像,并使它在后台运行。 + +```bash +$ docker run -d tdengine/tdengine +cdf548465318c6fc2ad97813f89cc60006393392401cae58a27b15ca9171f316 +``` + +- **docker run**:通过 Docker 运行一个容器。 +- **-d**:让容器在后台运行。 +- **tdengine/tdengine**:拉取的 TDengine 官方发布的应用镜像。 +- **cdf548465318c6fc2ad97813f89cc60006393392401cae58a27b15ca9171f316**:这个返回的长字符是容器 ID,我们可以通过容器 ID 来查看对应的容器。 + +2,确认容器是否已经正确运行。 + +```bash +$ docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS ··· +cdf548465318 tdengine/tdengine "taosd" 14 minutes ago Up 14 minutes ··· +``` + +- **docker ps**:列出所有正在运行状态的容器信息。 +- **CONTAINER ID**:容器 ID。 +- **IMAGE**:使用的镜像。 +- **COMMAND**:启动容器时运行的命令。 +- **CREATED**:容器创建时间。 +- **STATUS**:容器状态。UP 表示运行中。 + +3,进入 Docker 容器内,使用 TDengine。 + +```bash +$ docker exec -it cdf548465318 /bin/bash +root@cdf548465318:~/TDengine-server-2.0.13.0# +``` + +- **docker exec**:通过 docker exec 命令进入容器,如果退出,容器不会停止。 +- **-i**:进入交互模式。 +- **-t**:指定一个终端。 +- **cdf548465318**:容器 ID,需要根据 docker ps 指令返回的值进行修改。 +- **/bin/bash**:载入容器后运行 bash 来进行交互。 + +4,进入容器后,执行 taos shell 客户端程序。 + +```bash +$ root@cdf548465318:~/TDengine-server-2.0.13.0# taos + +Welcome to the TDengine shell from Linux, Client Version:2.0.13.0 +Copyright (c) 2020 by TAOS Data, Inc. All rights reserved. + +taos> +``` + +TDengine 终端成功连接服务端,打印出了欢迎消息和版本信息。如果失败,会有错误信息打印出来。 + +在 TDengine 终端中,可以通过 SQL 命令来创建/删除数据库、表、超级表等,并可以进行插入和查询操作。具体可以参考 [TAOS SQL 说明文档](https://www.taosdata.com/cn/documentation/taos-sql)。 + +## 通过 taosdemo 进一步了解 TDengine + +1,接上面的步骤,先退出 TDengine 终端程序。 + +```bash +$ taos> q +root@cdf548465318:~/TDengine-server-2.0.13.0# +``` + +2,在命令行界面执行 taosdemo。 + +```bash +$ root@cdf548465318:~/TDengine-server-2.0.13.0# taosdemo +################################################################### +# Server IP: localhost:0 +# User: root +# Password: taosdata +# Use metric: true +# Datatype of Columns: int int int int int int int float +# Binary Length(If applicable): -1 +# Number of Columns per record: 3 +# Number of Threads: 10 +# Number of Tables: 10000 +# Number of Data per Table: 100000 +# Records/Request: 1000 +# Database name: test +# Table prefix: t +# Delete method: 0 +# Test time: 2021-04-13 02:05:20 +################################################################### +``` + +回车后,该命令将新建一个数据库 test,并且自动创建一张超级表 meters,并以超级表 meters 为模版创建了 1 万张表,表名从 "t0" 到 "t9999"。每张表有 10 万条记录,每条记录有 f1,f2,f3 三个字段,时间戳 ts 字段从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:41:39 999"。每张表带有 areaid 和 loc 两个标签 TAG,areaid 被设置为 1 到 10,loc 被设置为 "beijing" 或 "shanghai"。 + +3,进入 TDengine 终端,查看 taosdemo 生成的数据。 + +- **进入命令行。** + +```bash +$ root@cdf548465318:~/TDengine-server-2.0.13.0# taos + +Welcome to the TDengine shell from Linux, Client Version:2.0.13.0 +Copyright (c) 2020 by TAOS Data, Inc. All rights reserved. + +taos> +``` + +- **查看数据库。** + +```bash +$ taos> show databases; + name | created_time | ntables | vgroups | ··· + test | 2021-04-13 02:14:15.950 | 10000 | 6 | ··· + log | 2021-04-12 09:36:37.549 | 4 | 1 | ··· + +``` + +- **查看超级表。** + +```bash +$ taos> use test; +Database changed. + +$ taos> show stables; + name | created_time | columns | tags | tables | +===================================================================================== + meters | 2021-04-13 02:14:15.955 | 4 | 2 | 10000 | +Query OK, 1 row(s) in set (0.001737s) + +``` + +- **查看表,限制输出十条。** + +```bash +$ taos> select * from test.t0 limit 10; + ts | f1 | f2 | f3 | +==================================================================== + 2017-07-14 02:40:01.000 | 3 | 9 | 0 | + 2017-07-14 02:40:02.000 | 0 | 1 | 2 | + 2017-07-14 02:40:03.000 | 7 | 2 | 3 | + 2017-07-14 02:40:04.000 | 9 | 4 | 5 | + 2017-07-14 02:40:05.000 | 1 | 2 | 5 | + 2017-07-14 02:40:06.000 | 6 | 3 | 2 | + 2017-07-14 02:40:07.000 | 4 | 7 | 8 | + 2017-07-14 02:40:08.000 | 4 | 6 | 6 | + 2017-07-14 02:40:09.000 | 5 | 7 | 7 | + 2017-07-14 02:40:10.000 | 1 | 5 | 0 | +Query OK, 10 row(s) in set (0.003638s) + +``` + +- **查看 t0 表的标签值。** + +```bash +$ taos> select areaid, loc from test.t0; + areaid | loc | +=========================== + 10 | shanghai | +Query OK, 1 row(s) in set (0.002904s) + +``` + +## 停止正在 Docker 中运行的 TDengine 服务 + +```bash +$ docker stop cdf548465318 +cdf548465318 +``` + +- **docker stop**:通过 docker stop 停止指定的正在运行中的 docker 镜像。 +- **cdf548465318**:容器 ID,根据 docker ps 指令返回的结果进行修改。 + +## 编程开发时连接在 Docker 中的 TDengine + +从 Docker 之外连接使用在 Docker 容器内运行的 TDengine 服务,有以下两个思路: + +1,通过端口映射(-p),将容器内部开放的网络端口映射到宿主机的指定端口上。通过挂载本地目录(-v),可以实现宿主机与容器内部的数据同步,防止容器删除后,数据丢失。 + +```bash +$ docker run -d -v /etc/taos:/etc/taos -p 6041:6041 tdengine/tdengine +526aa188da767ae94b244226a2b2eec2b5f17dd8eff592893d9ec0cd0f3a1ccd + +$ curl -u root:taosdata -d 'show databases' 127.0.0.1:6041/rest/sql +{"status":"succ","head":["name","created_time","ntables","vgroups","replica","quorum","days","keep1,keep2,keep(D)","cache(MB)","blocks","minrows","maxrows","wallevel","fsync","comp","precision","status"],"data":[],"rows":0} +``` + +- 第一条命令,启动一个运行了 TDengine 的 docker 容器,并且将容器的 6041 端口映射到宿主机的 6041 端口上。 +- 第二条命令,通过 RESTful 接口访问 TDengine,这时连接的是本机的 6041 端口,可见连接成功。 + +注意:在这个示例中,出于方便性考虑,只映射了 RESTful 需要的 6041 端口。如果希望以非 RESTful 方式连接 TDengine 服务,则需要映射从 6030 开始的共 11 个端口(完整的端口情况请参见 [TDengine 2.0 端口说明](https://www.taosdata.com/cn/documentation/faq#port))。在例子中,挂载本地目录也只是处理了配置文件所在的 /etc/taos 目录,而没有挂载数据存储目录。 + +2,直接通过 exec 命令,进入到 docker 容器中去做开发。也即,把程序代码放在 TDengine 服务端所在的同一个 Docker 容器中,连接容器本地的 TDengine 服务。 + +```bash +$ docker exec -it 526aa188da /bin/bash +``` + diff --git a/documentation20/cn/02.getting-started/docs.md b/documentation20/cn/02.getting-started/docs.md index b46322cef2..a98159d8c4 100644 --- a/documentation20/cn/02.getting-started/docs.md +++ b/documentation20/cn/02.getting-started/docs.md @@ -10,7 +10,9 @@ TDengine软件分为服务器、客户端和报警模块三部分,目前2.0版 ### 通过Docker容器运行 -请参考[TDengine官方Docker镜像的发布、下载和使用](https://www.taosdata.com/blog/2020/05/13/1509.html) +暂时不建议生产环境采用 Docker 来部署 TDengine 的客户端或服务端,但在开发环境下或初次尝试时,使用 Docker 方式部署是十分方便的。特别是,利用 Docker,可以方便地在 Mac OSX 和 Windows 环境下尝试 TDengine。 + +详细操作方法请参照 [通过Docker快速体验TDengine](https://www.taosdata.com/cn/documentation/getting-started/docker)。 ### 通过安装包安装 diff --git a/documentation20/cn/03.architecture/docs.md b/documentation20/cn/03.architecture/docs.md index 87553fa8ad..3d6e5e4f21 100644 --- a/documentation20/cn/03.architecture/docs.md +++ b/documentation20/cn/03.architecture/docs.md @@ -178,7 +178,7 @@ TDengine 分布式架构的逻辑结构图如下: **FQDN配置**:一个数据节点有一个或多个FQDN,可以在系统配置文件taos.cfg通过参数“fqdn"进行指定,如果没有指定,系统将自动获取计算机的hostname作为其FQDN。如果节点没有配置FQDN,可以直接将该节点的配置参数fqdn设置为它的IP地址。但不建议使用IP,因为IP地址可变,一旦变化,将让集群无法正常工作。一个数据节点的EP(End Point)由FQDN + Port组成。采用FQDN,需要保证DNS服务正常工作,或者在节点以及应用所在的节点配置好hosts文件。 -**端口配置:**一个数据节点对外的端口由TDengine的系统配置参数serverPort决定,对集群内部通讯的端口是serverPort+5。集群内数据节点之间的数据复制操作还占有一个TCP端口,是serverPort+10. 为支持多线程高效的处理UDP数据,每个对内和对外的UDP连接,都需要占用5个连续的端口。因此一个数据节点总的端口范围为serverPort到serverPort + 10,总共11个TCP/UDP端口。(另外还可能有 RESTful、Arbitrator 所使用的端口,那样的话就一共是 13 个。)使用时,需要确保防火墙将这些端口打开,以备使用。每个数据节点可以配置不同的serverPort。 +**端口配置:**一个数据节点对外的端口由TDengine的系统配置参数serverPort决定,对集群内部通讯的端口是serverPort+5。集群内数据节点之间的数据复制操作还占有一个TCP端口,是serverPort+10. 为支持多线程高效的处理UDP数据,每个对内和对外的UDP连接,都需要占用5个连续的端口。因此一个数据节点总的端口范围为serverPort到serverPort + 10,总共11个TCP/UDP端口。(另外还可能有 RESTful、Arbitrator 所使用的端口,那样的话就一共是 13 个。)使用时,需要确保防火墙将这些端口打开,以备使用。每个数据节点可以配置不同的serverPort。(详细的端口情况请参见 [TDengine 2.0 端口说明](https://www.taosdata.com/cn/documentation/faq#port)) **集群对外连接:** TDengine集群可以容纳单个、多个甚至几千个数据节点。应用只需要向集群中任何一个数据节点发起连接即可,连接需要提供的网络参数是一数据节点的End Point(FQDN加配置的端口号)。通过命令行CLI启动应用taos时,可以通过选项-h来指定数据节点的FQDN, -P来指定其配置的端口号,如果端口不配置,将采用TDengine的系统配置参数serverPort。 diff --git a/documentation20/cn/06.queries/docs.md b/documentation20/cn/06.queries/docs.md index a161778a72..5557134aac 100644 --- a/documentation20/cn/06.queries/docs.md +++ b/documentation20/cn/06.queries/docs.md @@ -12,7 +12,7 @@ TDengine 采用 SQL 作为查询语言。应用程序可以通过 C/C++, Java, G - 时间戳对齐的连接查询(Join Query: 隐式连接)操作 - 多种聚合/计算函数: count, max, min, avg, sum, twa, stddev, leastsquares, top, bottom, first, last, percentile, apercentile, last_row, spread, diff等 -例如:在TAOS Shell中,从表d1001中查询出vlotage > 215的记录,按时间降序排列,仅仅输出2条。 +例如:在TAOS Shell中,从表d1001中查询出voltage > 215的记录,按时间降序排列,仅仅输出2条。 ```mysql taos> select * from d1001 where voltage > 215 order by ts desc limit 2; ts | current | voltage | phase | diff --git a/documentation20/cn/07.advanced-features/docs.md b/documentation20/cn/07.advanced-features/docs.md index 650a2ca96b..1077f299ee 100644 --- a/documentation20/cn/07.advanced-features/docs.md +++ b/documentation20/cn/07.advanced-features/docs.md @@ -120,7 +120,7 @@ if (async) { } ``` -TDengine中的订阅既可以是同步的,也可以是异步的,上面的代码会根据从命令行获取的参数`async`的值来决定使用哪种方式。这里,同步的意思是用户程序要直接调用`taos_consume`来拉取数据,而异步则由API在内部的另一个线程中调用`taos_consume`,然后把拉取到的数据交给回调函数`subscribe_callback`去处理。 +TDengine中的订阅既可以是同步的,也可以是异步的,上面的代码会根据从命令行获取的参数`async`的值来决定使用哪种方式。这里,同步的意思是用户程序要直接调用`taos_consume`来拉取数据,而异步则由API在内部的另一个线程中调用`taos_consume`,然后把拉取到的数据交给回调函数`subscribe_callback`去处理。(注意,`subscribe_callback` 中不宜做较为耗时的操作,否则有可能导致客户端阻塞等不可控的问题。) 参数`taos`是一个已经建立好的数据库连接,在同步模式下无特殊要求。但在异步模式下,需要注意它不会被其它线程使用,否则可能导致不可预计的错误,因为回调函数在API的内部线程中被调用,而TDengine的部分API不是线程安全的。 diff --git a/documentation20/cn/08.connector/01.java/docs.md b/documentation20/cn/08.connector/01.java/docs.md index 3442a2248c..5eec33e2f1 100644 --- a/documentation20/cn/08.connector/01.java/docs.md +++ b/documentation20/cn/08.connector/01.java/docs.md @@ -16,7 +16,6 @@ TDengine 的 JDBC 驱动实现尽可能与关系型数据库驱动保持一致 * TDengine 目前不支持针对单条数据记录的删除操作。 * 目前不支持事务操作。 -* 目前不支持表间的 union 操作。 * 目前不支持嵌套查询(nested query)。 * 对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet 还没关闭的情况下执行了新的查询,taos-jdbcdriver 会自动关闭上一个 ResultSet。 @@ -447,7 +446,7 @@ Query OK, 1 row(s) in set (0.000141s) -## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本 +## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本 | taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 | | -------------------- | ----------------- | -------- | diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 6811315e7d..59f80b0a55 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -32,7 +32,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、 **Linux** -**1. 从涛思官网(https://www.taosdata.com/cn/all-downloads/)下载** +**1. 从[涛思官网](https://www.taosdata.com/cn/all-downloads/)下载** * X64硬件环境:TDengine-client-2.x.x.x-Linux-x64.tar.gz @@ -68,7 +68,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、 **Windows x64/x86** -**1. 从涛思官网(https://www.taosdata.com/cn/all-downloads/)下载 :** +**1. 从[涛思官网](https://www.taosdata.com/cn/all-downloads/)下载 :** * X64硬件环境:TDengine-client-2.X.X.X-Windows-x64.exe @@ -213,7 +213,7 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine - `int taos_result_precision(TAOS_RES *res)` - 返回结果集时间戳字段的精度,`0` 代表毫秒,`1` 代表微秒,`2` 代表纳秒。 + 返回结果集时间戳字段的精度,`0` 代表毫秒,`1` 代表微秒。 - `TAOS_ROW taos_fetch_row(TAOS_RES *res)` @@ -349,7 +349,7 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 * param:是应用提供的用于回调的一个参数,回调时,提供给应用 * callback: 第二个回调函数,会在连续查询自动停止时被调用。 - 返回值为NULL,表示创建成功,返回值不为空,表示成功。 + 返回值为NULL,表示创建失败;返回值不为空,表示成功。 - `void taos_close_stream (TAOS_STREAM *tstr)` @@ -377,6 +377,7 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 * res:查询结果集,注意结果集中可能没有记录 * param:调用 `taos_subscribe`时客户程序提供的附加参数 * code:错误码 + **注意**:在这个回调函数里不可以做耗时过长的处理,尤其是对于返回的结果集中数据较多的情况,否则有可能导致客户端阻塞等异常状态。如果必须进行复杂计算,则建议在另外的线程中进行处理。 * `TAOS_RES *taos_consume(TAOS_SUB *tsub)` @@ -743,7 +744,7 @@ HTTP请求URL采用`sqlutc`时,返回结果集的时间戳将采用UTC时间 下面仅列出一些与RESTful接口有关的配置参数,其他系统参数请看配置文件里的说明。注意:配置修改后,需要重启taosd服务才能生效 -- httpPort: 对外提供RESTful服务的端口号,默认绑定到6041 +- 对外提供RESTful服务的端口号,默认绑定到 6041(实际取值是 serverPort + 11,因此可以通过修改 serverPort 参数的设置来修改) - httpMaxThreads: 启动的线程数量,默认为2(2.0.17版本开始,默认值改为CPU核数的一半向下取整) - restfulRowLimit: 返回结果集(JSON格式)的最大条数,默认值为10240 - httpEnableCompress: 是否支持压缩,默认不支持,目前TDengine仅支持gzip压缩格式 diff --git a/documentation20/cn/10.cluster/docs.md b/documentation20/cn/10.cluster/docs.md index a430ce8277..62d709c279 100644 --- a/documentation20/cn/10.cluster/docs.md +++ b/documentation20/cn/10.cluster/docs.md @@ -55,12 +55,11 @@ arbitrator ha.taosdata.com:6042 | 4 | statusInterval | dnode向mnode报告状态时长 | | 5 | arbitrator | 系统中裁决器的end point | | 6 | timezone | 时区 | -| 7 | locale | 系统区位信息及编码格式 | -| 8 | charset | 字符集编码 | -| 9 | balance | 是否启动负载均衡 | -| 10 | maxTablesPerVnode | 每个vnode中能够创建的最大表个数 | -| 11 | maxVgroupsPerDb | 每个DB中能够使用的最大vgroup个数 | +| 7 | balance | 是否启动负载均衡 | +| 8 | maxTablesPerVnode | 每个vnode中能够创建的最大表个数 | +| 9 | maxVgroupsPerDb | 每个DB中能够使用的最大vgroup个数 | +备注:在 2.0.19.0 及更早的版本中,除以上 9 项参数外,dnode 加入集群时,还会要求 locale 和 charset 参数的取值也一致。 ## 启动第一个数据节点 diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md index cc8689786d..bfa0456c7d 100644 --- a/documentation20/cn/11.administrator/docs.md +++ b/documentation20/cn/11.administrator/docs.md @@ -100,8 +100,7 @@ taosd -C - firstEp: taosd启动时,主动连接的集群中首个dnode的end point, 默认值为localhost:6030。 - fqdn:数据节点的FQDN,缺省为操作系统配置的第一个hostname。如果习惯IP地址访问,可设置为该节点的IP地址。 -- serverPort:taosd启动后,对外服务的端口号,默认值为6030。 -- httpPort: RESTful服务使用的端口号,所有的HTTP请求(TCP)都需要向该接口发起查询/写入请求, 默认值为6041。 +- serverPort:taosd启动后,对外服务的端口号,默认值为6030。(RESTful服务使用的端口号是在此基础上+11,即默认值为6041。) - dataDir: 数据文件目录,所有的数据文件都将写入该目录。默认值:/var/lib/taos。 - logDir:日志文件目录,客户端和服务器的运行日志文件将写入该目录。默认值:/var/log/taos。 - arbitrator:系统中裁决器的end point, 缺省值为空。 @@ -115,7 +114,7 @@ taosd -C - queryBufferSize: 为所有并发查询占用保留的内存大小。计算规则可以根据实际应用可能的最大并发数和表的数字相乘,再乘 170 。单位为 MB(2.0.15 以前的版本中,此参数的单位是字节)。 - ratioOfQueryCores: 设置查询线程的最大数量。最小值0 表示只有1个查询线程;最大值2表示最大建立2倍CPU核数的查询线程。默认为1,表示最大和CPU核数相等的查询线程。该值可以为小数,即0.5表示最大建立CPU核数一半的查询线程。 -**注意:**对于端口,TDengine会使用从serverPort起13个连续的TCP和UDP端口号,请务必在防火墙打开。因此如果是缺省配置,需要打开从6030到6042共13个端口,而且必须TCP和UDP都打开。 +**注意:**对于端口,TDengine会使用从serverPort起13个连续的TCP和UDP端口号,请务必在防火墙打开。因此如果是缺省配置,需要打开从6030到6042共13个端口,而且必须TCP和UDP都打开。(详细的端口情况请参见 [TDengine 2.0 端口说明](https://www.taosdata.com/cn/documentation/faq#port)) 不同应用场景的数据往往具有不同的数据特征,比如保留天数、副本数、采集频次、记录大小、采集点的数量、压缩等都可完全不同。为获得在存储上的最高效率,TDengine提供如下存储相关的系统配置参数: @@ -150,7 +149,7 @@ TDengine集群中加入一个新的dnode时,涉及集群相关的一些参数 - maxTablesPerVnode: 每个vnode中能够创建的最大表个数。默认值:1000000。 - maxVgroupsPerDb: 每个数据库中能够使用的最大vgroup个数。 - arbitrator: 系统中裁决器的end point,缺省为空。 -- timezone、locale、charset 的配置见客户端配置。 +- timezone、locale、charset 的配置见客户端配置。(2.0.20.0 及以上的版本里,集群中加入新节点已不要求 locale 和 charset 参数取值一致) 为方便调试,可通过SQL语句临时调整每个dnode的日志配置,系统重启后会失效: @@ -463,41 +462,41 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下 | 关键字列表 | | | | | | ---------- | ----------- | ------------ | ---------- | --------- | -| ABLOCKS | CONNECTIONS | GT | MNODES | SLIDING | -| ABORT | COPY | ID | MODULES | SLIMIT | -| ACCOUNT | COUNT | IF | NCHAR | SMALLINT | -| ACCOUNTS | CREATE | IGNORE | NE | SPREAD | -| ADD | CTIME | IMMEDIATE | NONE | STABLE | -| AFTER | DATABASE | IMPORT | NOT | STABLES | -| ALL | DATABASES | IN | NOTNULL | STAR | -| ALTER | DAYS | INITIALLY | NOW | STATEMENT | -| AND | DEFERRED | INSERT | OF | STDDEV | -| AS | DELIMITERS | INSTEAD | OFFSET | STREAM | -| ASC | DESC | INTEGER | OR | STREAMS | -| ATTACH | DESCRIBE | INTERVAL | ORDER | STRING | -| AVG | DETACH | INTO | PASS | SUM | -| BEFORE | DIFF | IP | PERCENTILE | TABLE | -| BEGIN | DISTINCT | IS | PLUS | TABLES | -| BETWEEN | DIVIDE | ISNULL | PRAGMA | TAG | -| BIGINT | DNODE | JOIN | PREV | TAGS | -| BINARY | DNODES | KEEP | PRIVILEGE | TBLOCKS | -| BITAND | DOT | KEY | QUERIES | TBNAME | -| BITNOT | DOUBLE | KILL | QUERY | TIMES | -| BITOR | DROP | LAST | RAISE | TIMESTAMP | -| BOOL | EACH | LE | REM | TINYINT | -| BOTTOM | END | LEASTSQUARES | REPLACE | TOP | -| BY | EQ | LIKE | REPLICA | TRIGGER | -| CACHE | EXISTS | LIMIT | RESET | UMINUS | -| CASCADE | EXPLAIN | LINEAR | RESTRICT | UPLUS | -| CHANGE | FAIL | LOCAL | ROW | USE | -| CLOG | FILL | LP | ROWS | USER | -| CLUSTER | FIRST | LSHIFT | RP | USERS | -| COLON | FLOAT | LT | RSHIFT | USING | -| COLUMN | FOR | MATCH | SCORES | VALUES | -| COMMA | FROM | MAX | SELECT | VARIABLE | -| COMP | GE | METRIC | SEMI | VGROUPS | -| CONCAT | GLOB | METRICS | SET | VIEW | -| CONFIGS | GRANTS | MIN | SHOW | WAVG | -| CONFLICT | GROUP | MINUS | SLASH | WHERE | -| CONNECTION | | | | | +| ABLOCKS | CONNECTIONS | HAVING | MODULES | SMALLINT | +| ABORT | COPY | ID | NCHAR | SPREAD | +| ACCOUNT | COUNT | IF | NE | STABLE | +| ACCOUNTS | CREATE | IGNORE | NONE | STABLES | +| ADD | CTIME | IMMEDIATE | NOT | STAR | +| AFTER | DATABASE | IMPORT | NOTNULL | STATEMENT | +| ALL | DATABASES | IN | NOW | STDDEV | +| ALTER | DAYS | INITIALLY | OF | STREAM | +| AND | DEFERRED | INSERT | OFFSET | STREAMS | +| AS | DELIMITERS | INSTEAD | OR | STRING | +| ASC | DESC | INTEGER | ORDER | SUM | +| ATTACH | DESCRIBE | INTERVAL | PASS | TABLE | +| AVG | DETACH | INTO | PERCENTILE | TABLES | +| BEFORE | DIFF | IP | PLUS | TAG | +| BEGIN | DISTINCT | IS | PRAGMA | TAGS | +| BETWEEN | DIVIDE | ISNULL | PREV | TBLOCKS | +| BIGINT | DNODE | JOIN | PRIVILEGE | TBNAME | +| BINARY | DNODES | KEEP | QUERIES | TIMES | +| BITAND | DOT | KEY | QUERY | TIMESTAMP | +| BITNOT | DOUBLE | KILL | RAISE | TINYINT | +| BITOR | DROP | LAST | REM | TOP | +| BOOL | EACH | LE | REPLACE | TOPIC | +| BOTTOM | END | LEASTSQUARES | REPLICA | TRIGGER | +| BY | EQ | LIKE | RESET | UMINUS | +| CACHE | EXISTS | LIMIT | RESTRICT | UNION | +| CASCADE | EXPLAIN | LINEAR | ROW | UPLUS | +| CHANGE | FAIL | LOCAL | ROWS | USE | +| CLOG | FILL | LP | RP | USER | +| CLUSTER | FIRST | LSHIFT | RSHIFT | USERS | +| COLON | FLOAT | LT | SCORES | USING | +| COLUMN | FOR | MATCH | SELECT | VALUES | +| COMMA | FROM | MAX | SEMI | VARIABLE | +| COMP | GE | METRIC | SET | VGROUPS | +| CONCAT | GLOB | METRICS | SHOW | VIEW | +| CONFIGS | GRANTS | MIN | SLASH | WAVG | +| CONFLICT | GROUP | MINUS | SLIDING | WHERE | +| CONNECTION | GT | MNODES | SLIMIT | | diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md index 58191e0bd8..112ad99391 100644 --- a/documentation20/cn/12.taos-sql/docs.md +++ b/documentation20/cn/12.taos-sql/docs.md @@ -48,15 +48,15 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM | 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用于 NULL | | 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] | | 5 | DOUBLE | 8 | 双精度浮点型,有效位数 15-16,范围 [-1.7E308, 1.7E308] | -| 6 | BINARY | 自定义 | 用于记录 ASCII 型字符串。理论上,最长可以有 16374 字节,但由于每行数据最多 16K 字节,实际上限一般小于理论值。 binary 仅支持字符串输入,字符串两端使用单引号引用,否则英文全部自动转化为小写。使用时须指定大小,如 binary(20) 定义了最长为 20 个字符的字符串,每个字符占 1 byte 的存储空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 `\’`。 | +| 6 | BINARY | 自定义 | 记录单字节字符串,建议只用于处理 ASCII 可见字符,中文等多字节字符需使用 nchar。理论上,最长可以有 16374 字节,但由于每行数据最多 16K 字节,实际上限一般小于理论值。binary 仅支持字符串输入,字符串两端需使用单引号引用。使用时须指定大小,如 binary(20) 定义了最长为 20 个单字节字符的字符串,每个字符占 1 byte 的存储空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 `\’`。 | | 7 | SMALLINT | 2 | 短整型, 范围 [-32767, 32767], -32768 用于 NULL | | 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128 用于 NULL | | 9 | BOOL | 1 | 布尔型,{true, false} | -| 10 | NCHAR | 自定义 | 用于记录非 ASCII 型字符串,如中文字符。每个 nchar 字符占用 4 bytes 的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 `\’`。nchar 使用时须指定字符串大小,类型为 nchar(10) 的列表示此列的字符串最多存储 10 个 nchar 字符,会固定占用 40 bytes 的空间。如果用户字符串长度超出声明长度,将会报错。 | +| 10 | NCHAR | 自定义 | 记录包含多字节字符在内的字符串,如中文字符。每个 nchar 字符占用 4 bytes 的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 `\’`。nchar 使用时须指定字符串大小,类型为 nchar(10) 的列表示此列的字符串最多存储 10 个 nchar 字符,会固定占用 40 bytes 的空间。如果用户字符串长度超出声明长度,将会报错。 | **Tips**: 1. TDengine 对 SQL 语句中的英文字符不区分大小写,自动转化为小写执行。因此用户大小写敏感的字符串及密码,需要使用单引号将字符串引起来。 -2. 应避免使用 BINARY 类型来保存非 ASCII 型的字符串,会很容易导致数据乱码等错误。正确的做法是使用 NCHAR 类型来保存中文字符。 +2. **注意**,虽然 Binary 类型在底层存储上支持字节型的二进制字符,但不同编程语言对二进制数据的处理方式并不保证一致,因此建议在 Binary 类型中只存储 ASCII 可见字符,而避免存储不可见字符。多字节的数据,例如中文字符,则需要使用 nchar 类型进行保存。如果强行使用 Binary 类型保存中文字符,虽然有时也能正常读写,但并不带有字符集信息,很容易出现数据乱码甚至数据损坏等情况。 ## 数据库管理 @@ -409,16 +409,12 @@ SELECT select_expr [, select_expr ...] [FILL fill_val] [GROUP BY col_list] [ORDER BY col_list { DESC | ASC }] - [SLIMIT limit_val [, SOFFSET offset_val]] - [LIMIT limit_val [, OFFSET offset_val]] + [SLIMIT limit_val [SOFFSET offset_val]] + [LIMIT limit_val [OFFSET offset_val]] [>> export_file]; ``` -#### SELECT子句 - -一个选择子句可以是联合查询(UNION)和另一个查询的子查询(SUBQUERY)。 - -##### 通配符 +#### 通配符 通配符 * 可以用于代指全部列。对于普通表,结果中只有普通列。 ```mysql @@ -470,7 +466,7 @@ Query OK, 1 row(s) in set (0.020443s) ``` 在使用SQL函数来进行查询过程中,部分SQL函数支持通配符操作。其中的区别在于: -```count(\*)```函数只返回一列。```first```、```last```、```last_row```函数则是返回全部列。 +```count(*)```函数只返回一列。```first```、```last```、```last_row```函数则是返回全部列。 ```mysql taos> SELECT COUNT(*) FROM d1001; @@ -488,7 +484,7 @@ taos> SELECT FIRST(*) FROM d1001; Query OK, 1 row(s) in set (0.000849s) ``` -##### 标签列 +#### 标签列 从 2.0.14 版本开始,支持在普通表的查询中指定 _标签列_,且标签列的值会与普通列的数据一起返回。 ```mysql @@ -622,12 +618,15 @@ taos> SELECT COUNT(tbname) FROM meters WHERE groupId > 2; Query OK, 1 row(s) in set (0.001091s) ``` -- 可以使用 * 返回所有列,或指定列名。可以对数字列进行四则运算,可以给输出的列取列名 -- WHERE 语句可以使用各种逻辑判断来过滤数字值,或使用通配符来过滤字符串 +- 可以使用 * 返回所有列,或指定列名。可以对数字列进行四则运算,可以给输出的列取列名。 + * 暂不支持含列名的四则运算表达式用于条件过滤算子(例如,不支持 `where a*2>6;`,但可以写 `where a>6/2;`)。 + * 暂不支持含列名的四则运算表达式作为 SQL 函数的应用对象(例如,不支持 `select min(2*a) from t;`,但可以写 `select 2*min(a) from t;`)。 +- WHERE 语句可以使用各种逻辑判断来过滤数字值,或使用通配符来过滤字符串。 - 输出结果缺省按首列时间戳升序排序,但可以指定按降序排序( _c0 指首列时间戳)。使用 ORDER BY 对其他字段进行排序为非法操作。 - 参数 LIMIT 控制输出条数,OFFSET 指定从第几条开始输出。LIMIT/OFFSET 对结果集的执行顺序在 ORDER BY 之后。 -- 参数 SLIMIT 控制由 GROUP BY 指令划分的每个分组中的输出条数。 -- 通过”>>"输出结果可以导出到指定文件 + * 在有 GROUP BY 子句的情况下,LIMIT 参数控制的是每个分组中至多允许输出的条数。 +- 参数 SLIMIT 控制由 GROUP BY 指令划分的分组中,至多允许输出几个分组的数据。 +- 通过 ">>" 输出结果可以导出到指定文件。 ### 支持的条件过滤操作 @@ -647,6 +646,27 @@ Query OK, 1 row(s) in set (0.001091s) 2. 针对单一字段的过滤,如果是时间过滤条件,则一条语句中只支持设定一个;但针对其他的(普通)列或标签列,则可以使用 `OR` 关键字进行组合条件的查询过滤。例如:((value > 20 AND value < 30) OR (value < 12)) 。 3. 从 2.0.17 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。 + + +### UNION ALL 操作符 + +```mysql +SELECT ... +UNION ALL SELECT ... +[UNION ALL SELECT ...] +``` + +TDengine 支持 UNION ALL 操作符。也就是说,如果多个 SELECT 子句返回结果集的结构完全相同(列名、列类型、列数、顺序),那么可以通过 UNION ALL 把这些结果集合并到一起。目前只支持 UNION ALL 模式,也即在结果集的合并过程中是不去重的。 + ### SQL 示例 - 对于下面的例子,表tb1用以下语句创建 @@ -695,11 +715,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:应用全部字段。 - 适用于:表、超级表。 + 适用于:**表、超级表**。 说明: - 1)可以使用星号*来替代具体的字段,使用星号(*)返回全部记录数量。 + 1)可以使用星号\*来替代具体的字段,使用星号(\*)返回全部记录数量。 2)针对同一表的(不包含NULL值)字段查询结果均相同。 @@ -730,7 +750,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在timestamp、binary、nchar、bool字段。 - 适用于:表、超级表。 + 适用于:**表、超级表**。 示例: ```mysql @@ -757,7 +777,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 - 适用于:表。 + 适用于:**表**。 - **SUM** ```mysql @@ -769,7 +789,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 - 适用于:表、超级表。 + 适用于:**表、超级表**。 示例: ```mysql @@ -796,7 +816,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 - 适用于:表。(从 2.0.15.1 版本开始,本函数也支持超级表) + 适用于:**表**。(从 2.0.15.1 版本开始,本函数也支持**超级表**) 示例: ```mysql @@ -819,7 +839,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 说明:自变量是时间戳,因变量是该列的值。 - 适用于:表。 + 适用于:**表**。 示例: ```mysql @@ -842,6 +862,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:**表、超级表**。 + 示例: ```mysql taos> SELECT MIN(current), MIN(voltage) FROM meters; @@ -867,6 +889,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:**表、超级表**。 + 示例: ```mysql taos> SELECT MAX(current), MAX(voltage) FROM meters; @@ -892,6 +916,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:所有字段。 + 适用于:**表、超级表**。 + 说明: 1)如果要返回各个列的首个(时间戳最小)非NULL值,可以使用FIRST(\*); @@ -925,6 +951,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:所有字段。 + 适用于:**表、超级表**。 + 说明: 1)如果要返回各个列的最后(时间戳最大)一个非NULL值,可以使用LAST(\*); @@ -950,12 +978,14 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 ```mysql SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause]; ``` - 功能说明: 统计表/超级表中某列的值最大*k*个非NULL值。若多于k个列值并列最大,则返回时间戳小的。 + 功能说明: 统计表/超级表中某列的值最大 *k* 个非 NULL 值。如果多条数据取值一样,全部取用又会超出 k 条限制时,系统会从相同值中随机选取符合要求的数量返回。 返回结果数据类型:同应用的字段。 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:**表、超级表**。 + 说明: 1)*k*值取值范围1≤*k*≤100; @@ -984,12 +1014,14 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 ```mysql SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause]; ``` - 功能说明:统计表/超级表中某列的值最小*k*个非NULL值。若多于k个列值并列最小,则返回时间戳小的。 + 功能说明:统计表/超级表中某列的值最小 *k* 个非 NULL 值。如果多条数据取值一样,全部取用又会超出 k 条限制时,系统会从相同值中随机选取符合要求的数量返回。 返回结果数据类型:同应用的字段。 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:**表、超级表**。 + 说明: 1)*k*值取值范围1≤*k*≤100; @@ -1023,6 +1055,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:**表**。 + 说明:*P*值取值范围0≤*P*≤100,为0的时候等同于MIN,为100的时候等同于MAX。 示例: @@ -1038,12 +1072,14 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 ```mysql SELECT APERCENTILE(field_name, P) FROM { tb_name | stb_name } [WHERE clause]; ``` - 功能说明:统计表中某列的值百分比分位数,与PERCENTILE函数相似,但是返回近似结果。 + 功能说明:统计表/超级表中某列的值百分比分位数,与PERCENTILE函数相似,但是返回近似结果。 返回结果数据类型: 双精度浮点数Double。 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:**表、超级表**。 + 说明:*P*值取值范围0≤*P*≤100,为0的时候等同于MIN,为100的时候等同于MAX。推荐使用```APERCENTILE```函数,该函数性能远胜于```PERCENTILE```函数 ```mysql @@ -1058,12 +1094,14 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 ```mysql SELECT LAST_ROW(field_name) FROM { tb_name | stb_name }; ``` - 功能说明:返回表(超级表)的最后一条记录。 + 功能说明:返回表/超级表的最后一条记录。 返回结果数据类型:同应用的字段。 应用字段:所有字段。 + 适用于:**表、超级表**。 + 说明:与last函数不同,last_row不支持时间范围限制,强制返回最后一条记录。 示例: @@ -1092,6 +1130,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:**表**。 + 说明:输出结果行数是范围内总行数减一,第一行没有结果输出。 示例: @@ -1114,6 +1154,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在binary、nchar、bool类型字段。 + 适用于:**表、超级表**。 + 说明:可用于TIMESTAMP字段,此时表示记录的时间覆盖范围。 示例: @@ -1142,6 +1184,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:**表、超级表**。 + 说明: 1)支持两列或多列之间进行计算,可使用括号控制计算优先级; @@ -1216,6 +1260,7 @@ SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), P - 列名最大长度为 64,最多允许 1024 列,最少需要 2 列,第一列必须是时间戳 - 标签最多允许 128 个,可以 1 个,标签总长度不超过 16k 个字符 - SQL 语句最大长度 65480 个字符,但可通过系统配置参数 maxSQLLength 修改,最长可配置为 1M +- SELECT 语句的查询结果,最多允许返回 1024 列(语句中的函数调用可能也会占用一些列空间),超限时需要显式指定较少的返回数据列,以避免语句执行报错。 - 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制 ## TAOS SQL其他约定 diff --git a/documentation20/cn/13.faq/docs.md b/documentation20/cn/13.faq/docs.md index c01247d345..e561f91c94 100644 --- a/documentation20/cn/13.faq/docs.md +++ b/documentation20/cn/13.faq/docs.md @@ -102,7 +102,7 @@ TDengine 目前尚不支持删除功能,未来根据用户需求可能会支 批量插入。每条写入语句可以一张表同时插入多条记录,也可以同时插入多张表的多条记录。 -## 12. 最有效的写入数据的方法是什么?windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决? +## 12. windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决? Windows下插入nchar类的数据中如果有中文,请先确认系统的地区设置成了中国(在Control Panel里可以设置),这时cmd中的`taos`客户端应该已经可以正常工作了;如果是在IDE里开发Java应用,比如Eclipse, Intellij,请确认IDE里的文件编码为GBK(这是Java默认的编码类型),然后在生成Connection时,初始化客户端的配置,具体语句如下: ```JAVA @@ -166,3 +166,18 @@ TDengine 中时间戳的时区总是由客户端进行处理,而与服务端 2. 如果在 taos.cfg 中设置了 timezone 参数,则客户端会以这个配置文件中的设置为准。 3. 如果在 C/C++/Java/Python 等各种编程语言的 Connector Driver 中,在建立数据库连接时显式指定了 timezone,那么会以这个指定的时区设置为准。例如 Java Connector 的 JDBC URL 中就有 timezone 参数。 4. 在书写 SQL 语句时,也可以直接使用 Unix 时间戳(例如 `1554984068000`)或带有时区的时间戳字符串,也即以 RFC 3339 格式(例如 `2013-04-12T15:52:01.123+08:00`)或 ISO-8601 格式(例如 `2013-04-12T15:52:01.123+0800`)来书写时间戳,此时这些时间戳的取值将不再受其他时区设置的影响。 + +## 19. TDengine 都会用到哪些网络端口? + +在 TDengine 2.0 版本中,会用到以下这些网络端口(以默认端口 6030 为前提进行说明,如果修改了配置文件中的设置,那么这里列举的端口都会出现变化),管理员可以参考这里的信息调整防火墙设置: + +| 协议 | 默认端口 | 用途说明 | 修改方法 | +| --- | --------- | ------------------------------- | ------------------------------ | +| TCP | 6030 | 客户端与服务端之间通讯。 | 由配置文件设置 serverPort 决定。 | +| TCP | 6035 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 | +| TCP | 6040 | 多节点集群的节点间数据同步。 | 随 serverPort 端口变化。 | +| TCP | 6041 | 客户端与服务端之间的 RESTful 通讯。 | 随 serverPort 端口变化。 | +| TCP | 6042 | Arbitrator 的服务端口。 | 因 Arbitrator 启动参数设置变化。 | +| TCP | 6060 | 企业版内 Monitor 服务的网络端口。 | | +| UDP | 6030-6034 | 客户端与服务端之间通讯。 | 随 serverPort 端口变化。 | +| UDP | 6035-6039 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 | diff --git a/importSampleData/README.md b/importSampleData/README.md index ee3a6e073c..56c5be0da4 100644 --- a/importSampleData/README.md +++ b/importSampleData/README.md @@ -97,7 +97,7 @@ go build -o bin/taosimport app/main.go 是否保存统计信息到 tdengine 的 statistic 表中,1 是,0 否, 默认 0。 -* -savetb int +* -savetb string 当 save 为 1 时保存统计信息的表名, 默认 statistic。 diff --git a/importSampleData/app/main.go b/importSampleData/app/main.go index 61de6e740c..5fee49734d 100644 --- a/importSampleData/app/main.go +++ b/importSampleData/app/main.go @@ -7,7 +7,6 @@ import ( "encoding/json" "flag" "fmt" - "hash/crc32" "io" "log" "os" @@ -17,47 +16,55 @@ import ( "sync" "time" - dataimport "github.com/taosdata/TDengine/importSampleData/import" + dataImport "github.com/taosdata/TDengine/importSampleData/import" _ "github.com/taosdata/driver-go/taosSql" ) const ( - TIMESTAMP = "timestamp" - DATETIME = "datetime" - MILLISECOND = "millisecond" - DEFAULT_STARTTIME int64 = -1 - DEFAULT_INTERVAL int64 = 1 * 1000 - DEFAULT_DELAY int64 = -1 - DEFAULT_STATISTIC_TABLE = "statistic" + // 主键类型必须为 timestamp + TIMESTAMP = "timestamp" - JSON_FORMAT = "json" - CSV_FORMAT = "csv" - SUPERTABLE_PREFIX = "s_" - SUBTABLE_PREFIX = "t_" + // 样例数据中主键时间字段是 millisecond 还是 dateTime 格式 + DATETIME = "datetime" + MILLISECOND = "millisecond" - DRIVER_NAME = "taosSql" - STARTTIME_LAYOUT = "2006-01-02 15:04:05.000" - INSERT_PREFIX = "insert into " + DefaultStartTime int64 = -1 + DefaultInterval int64 = 1 * 1000 // 导入的记录时间间隔,该设置只会在指定 auto=1 之后生效,否则会根据样例数据自动计算间隔时间。单位为毫秒,默认 1000。 + DefaultDelay int64 = -1 // + + // 当 save 为 1 时保存统计信息的表名, 默认 statistic。 + DefaultStatisticTable = "statistic" + + // 样例数据文件格式,可以是 json 或 csv + JsonFormat = "json" + CsvFormat = "csv" + + SuperTablePrefix = "s_" // 超级表前缀 + SubTablePrefix = "t_" // 子表前缀 + + DriverName = "taosSql" + StartTimeLayout = "2006-01-02 15:04:05.000" + InsertPrefix = "insert into " ) var ( - cfg string - cases string - hnum int - vnum int - thread int - batch int - auto int - starttimestr string - interval int64 - host string - port int - user string - password string - dropdb int - db string - dbparam string + cfg string // 导入配置文件路径,包含样例数据文件相关描述及对应 TDengine 配置信息。默认使用 config/cfg.toml + cases string // 需要导入的场景名称,该名称可从 -cfg 指定的配置文件中 [usecase] 查看,可同时导入多个场景,中间使用逗号分隔,如:sensor_info,camera_detection,默认为 sensor_info + hnum int // 需要将样例数据进行横向扩展的倍数,假设原有样例数据包含 1 张子表 t_0 数据,指定 hnum 为 2 时会根据原有表名创建 t、t_1 两张子表。默认为 100。 + vnum int // 需要将样例数据进行纵向扩展的次数,如果设置为 0 代表将历史数据导入至当前时间后持续按照指定间隔导入。默认为 1000,表示将样例数据在时间轴上纵向复制1000 次 + thread int // 执行导入数据的线程数目,默认为 10 + batch int // 执行导入数据时的批量大小,默认为 100。批量是指一次写操作时,包含多少条记录 + auto int // 是否自动生成样例数据中的主键时间戳,1 是,0 否, 默认 0 + startTimeStr string // 导入的记录开始时间,格式为 "yyyy-MM-dd HH:mm:ss.SSS",不设置会使用样例数据中最小时间,设置后会忽略样例数据中的主键时间,会按照指定的 start 进行导入。如果 auto 为 1,则必须设置 start,默认为空 + interval int64 // 导入的记录时间间隔,该设置只会在指定 auto=1 之后生效,否则会根据样例数据自动计算间隔时间。单位为毫秒,默认 1000 + host string // 导入的 TDengine 服务器 IP,默认为 127.0.0.1 + port int // 导入的 TDengine 服务器端口,默认为 6030 + user string // 导入的 TDengine 用户名,默认为 root + password string // 导入的 TDengine 用户密码,默认为 taosdata + dropdb int // 导入数据之前是否删除数据库,1 是,0 否, 默认 0 + db string // 导入的 TDengine 数据库名称,默认为 test_yyyyMMdd + dbparam string // 当指定的数据库不存在时,自动创建数据库时可选项配置参数,如 days 10 cache 16000 ablocks 4,默认为空 dataSourceName string startTime int64 @@ -72,10 +79,10 @@ var ( lastStaticTime time.Time lastTotalRows int64 timeTicker *time.Ticker - delay int64 // default 10 milliseconds - tick int64 - save int - saveTable string + delay int64 // 当 vnum 设置为 0 时持续导入的时间间隔,默认为所有场景中最小记录间隔时间的一半,单位 ms。 + tick int64 // 打印统计信息的时间间隔,默认 2000 ms。 + save int // 是否保存统计信息到 tdengine 的 statistic 表中,1 是,0 否, 默认 0。 + saveTable string // 当 save 为 1 时保存统计信息的表名, 默认 statistic。 ) type superTableConfig struct { @@ -83,7 +90,7 @@ type superTableConfig struct { endTime int64 cycleTime int64 avgInterval int64 - config dataimport.CaseConfig + config dataImport.CaseConfig } type scaleTableInfo struct { @@ -92,14 +99,14 @@ type scaleTableInfo struct { insertRows int64 } -type tableRows struct { - tableName string // tableName - value string // values(...) -} +//type tableRows struct { +// tableName string // tableName +// value string // values(...) +//} type dataRows struct { rows []map[string]interface{} - config dataimport.CaseConfig + config dataImport.CaseConfig } func (rows dataRows) Len() int { @@ -107,9 +114,9 @@ func (rows dataRows) Len() int { } func (rows dataRows) Less(i, j int) bool { - itime := getPrimaryKey(rows.rows[i][rows.config.Timestamp]) - jtime := getPrimaryKey(rows.rows[j][rows.config.Timestamp]) - return itime < jtime + iTime := getPrimaryKey(rows.rows[i][rows.config.Timestamp]) + jTime := getPrimaryKey(rows.rows[j][rows.config.Timestamp]) + return iTime < jTime } func (rows dataRows) Swap(i, j int) { @@ -123,26 +130,26 @@ func getPrimaryKey(value interface{}) int64 { } func init() { - parseArg() //parse argument + parseArg() // parse argument if db == "" { - //db = "go" + // 导入的 TDengine 数据库名称,默认为 test_yyyyMMdd db = fmt.Sprintf("test_%s", time.Now().Format("20060102")) } - if auto == 1 && len(starttimestr) == 0 { + if auto == 1 && len(startTimeStr) == 0 { log.Fatalf("startTime must be set when auto is 1, the format is \"yyyy-MM-dd HH:mm:ss.SSS\" ") } - if len(starttimestr) != 0 { - t, err := time.ParseInLocation(STARTTIME_LAYOUT, strings.TrimSpace(starttimestr), time.Local) + if len(startTimeStr) != 0 { + t, err := time.ParseInLocation(StartTimeLayout, strings.TrimSpace(startTimeStr), time.Local) if err != nil { - log.Fatalf("param startTime %s error, %s\n", starttimestr, err) + log.Fatalf("param startTime %s error, %s\n", startTimeStr, err) } startTime = t.UnixNano() / 1e6 // as millisecond } else { - startTime = DEFAULT_STARTTIME + startTime = DefaultStartTime } dataSourceName = fmt.Sprintf("%s:%s@/tcp(%s:%d)/", user, password, host, port) @@ -154,9 +161,9 @@ func init() { func main() { - importConfig := dataimport.LoadConfig(cfg) + importConfig := dataImport.LoadConfig(cfg) - var caseMinumInterval int64 = -1 + var caseMinInterval int64 = -1 for _, userCase := range strings.Split(cases, ",") { caseConfig, ok := importConfig.UserCases[userCase] @@ -168,7 +175,7 @@ func main() { checkUserCaseConfig(userCase, &caseConfig) - //read file as map array + // read file as map array fileRows := readFile(caseConfig) log.Printf("case [%s] sample data file contains %d rows.\n", userCase, len(fileRows.rows)) @@ -177,31 +184,31 @@ func main() { continue } - _, exists := superTableConfigMap[caseConfig.Stname] + _, exists := superTableConfigMap[caseConfig.StName] if !exists { - superTableConfigMap[caseConfig.Stname] = &superTableConfig{config: caseConfig} + superTableConfigMap[caseConfig.StName] = &superTableConfig{config: caseConfig} } else { - log.Fatalf("the stname of case %s already exist.\n", caseConfig.Stname) + log.Fatalf("the stname of case %s already exist.\n", caseConfig.StName) } var start, cycleTime, avgInterval int64 = getSuperTableTimeConfig(fileRows) // set super table's startTime, cycleTime and avgInterval - superTableConfigMap[caseConfig.Stname].startTime = start - superTableConfigMap[caseConfig.Stname].avgInterval = avgInterval - superTableConfigMap[caseConfig.Stname].cycleTime = cycleTime + superTableConfigMap[caseConfig.StName].startTime = start + superTableConfigMap[caseConfig.StName].cycleTime = cycleTime + superTableConfigMap[caseConfig.StName].avgInterval = avgInterval - if caseMinumInterval == -1 || caseMinumInterval > avgInterval { - caseMinumInterval = avgInterval + if caseMinInterval == -1 || caseMinInterval > avgInterval { + caseMinInterval = avgInterval } - startStr := time.Unix(0, start*int64(time.Millisecond)).Format(STARTTIME_LAYOUT) + startStr := time.Unix(0, start*int64(time.Millisecond)).Format(StartTimeLayout) log.Printf("case [%s] startTime %s(%d), average dataInterval %d ms, cycleTime %d ms.\n", userCase, startStr, start, avgInterval, cycleTime) } - if DEFAULT_DELAY == delay { + if DefaultDelay == delay { // default delay - delay = caseMinumInterval / 2 + delay = caseMinInterval / 2 if delay < 1 { delay = 1 } @@ -218,7 +225,7 @@ func main() { createSuperTable(superTableConfigMap) log.Printf("create %d superTable ,used %d ms.\n", superTableNum, time.Since(start)/1e6) - //create sub table + // create sub table start = time.Now() createSubTable(subTableMap) log.Printf("create %d times of %d subtable ,all %d tables, used %d ms.\n", hnum, len(subTableMap), len(scaleTableMap), time.Since(start)/1e6) @@ -278,7 +285,7 @@ func staticSpeed() { defer connection.Close() if save == 1 { - connection.Exec("use " + db) + _, _ = connection.Exec("use " + db) _, err := connection.Exec("create table if not exists " + saveTable + "(ts timestamp, speed int)") if err != nil { log.Fatalf("create %s Table error: %s\n", saveTable, err) @@ -294,12 +301,12 @@ func staticSpeed() { total := getTotalRows(successRows) currentSuccessRows := total - lastTotalRows - speed := currentSuccessRows * 1e9 / int64(usedTime) + speed := currentSuccessRows * 1e9 / usedTime log.Printf("insert %d rows, used %d ms, speed %d rows/s", currentSuccessRows, usedTime/1e6, speed) if save == 1 { insertSql := fmt.Sprintf("insert into %s values(%d, %d)", saveTable, currentTime.UnixNano()/1e6, speed) - connection.Exec(insertSql) + _, _ = connection.Exec(insertSql) } lastStaticTime = currentTime @@ -327,12 +334,13 @@ func getSuperTableTimeConfig(fileRows dataRows) (start, cycleTime, avgInterval i } else { // use the sample data primary timestamp - sort.Sort(fileRows) // sort the file data by the primarykey + sort.Sort(fileRows) // sort the file data by the primaryKey minTime := getPrimaryKey(fileRows.rows[0][fileRows.config.Timestamp]) maxTime := getPrimaryKey(fileRows.rows[len(fileRows.rows)-1][fileRows.config.Timestamp]) start = minTime // default startTime use the minTime - if DEFAULT_STARTTIME != startTime { + // 设置了start时间的话 按照start来 + if DefaultStartTime != startTime { start = startTime } @@ -350,31 +358,21 @@ func getSuperTableTimeConfig(fileRows dataRows) (start, cycleTime, avgInterval i return } -func createStatisticTable() { - connection := getConnection() - defer connection.Close() - - _, err := connection.Exec("create table if not exist " + db + "." + saveTable + "(ts timestamp, speed int)") - if err != nil { - log.Fatalf("createStatisticTable error: %s\n", err) - } -} - func createSubTable(subTableMaps map[string]*dataRows) { connection := getConnection() defer connection.Close() - connection.Exec("use " + db) + _, _ = connection.Exec("use " + db) createTablePrefix := "create table if not exists " + var buffer bytes.Buffer for subTableName := range subTableMaps { - superTableName := getSuperTableName(subTableMaps[subTableName].config.Stname) - tagValues := subTableMaps[subTableName].rows[0] // the first rows values as tags + superTableName := getSuperTableName(subTableMaps[subTableName].config.StName) + firstRowValues := subTableMaps[subTableName].rows[0] // the first rows values as tags - buffers := bytes.Buffer{} - // create table t using supertTable tags(...); + // create table t using superTable tags(...); for i := 0; i < hnum; i++ { tableName := getScaleSubTableName(subTableName, i) @@ -384,21 +382,21 @@ func createSubTable(subTableMaps map[string]*dataRows) { } scaleTableNames = append(scaleTableNames, tableName) - buffers.WriteString(createTablePrefix) - buffers.WriteString(tableName) - buffers.WriteString(" using ") - buffers.WriteString(superTableName) - buffers.WriteString(" tags(") + buffer.WriteString(createTablePrefix) + buffer.WriteString(tableName) + buffer.WriteString(" using ") + buffer.WriteString(superTableName) + buffer.WriteString(" tags(") for _, tag := range subTableMaps[subTableName].config.Tags { - tagValue := fmt.Sprintf("%v", tagValues[strings.ToLower(tag.Name)]) - buffers.WriteString("'" + tagValue + "'") - buffers.WriteString(",") + tagValue := fmt.Sprintf("%v", firstRowValues[strings.ToLower(tag.Name)]) + buffer.WriteString("'" + tagValue + "'") + buffer.WriteString(",") } - buffers.Truncate(buffers.Len() - 1) - buffers.WriteString(")") + buffer.Truncate(buffer.Len() - 1) + buffer.WriteString(")") - createTableSql := buffers.String() - buffers.Reset() + createTableSql := buffer.String() + buffer.Reset() //log.Printf("create table: %s\n", createTableSql) _, err := connection.Exec(createTableSql) @@ -420,7 +418,7 @@ func createSuperTable(superTableConfigMap map[string]*superTableConfig) { if err != nil { log.Fatalf("drop database error: %s\n", err) } - log.Printf("dropDb: %s\n", dropDbSql) + log.Printf("dropdb: %s\n", dropDbSql) } createDbSql := "create database if not exists " + db + " " + dbparam @@ -431,7 +429,7 @@ func createSuperTable(superTableConfigMap map[string]*superTableConfig) { } log.Printf("createDb: %s\n", createDbSql) - connection.Exec("use " + db) + _, _ = connection.Exec("use " + db) prefix := "create table if not exists " var buffer bytes.Buffer @@ -464,7 +462,7 @@ func createSuperTable(superTableConfigMap map[string]*superTableConfig) { createSql := buffer.String() buffer.Reset() - //log.Printf("supertable: %s\n", createSql) + //log.Printf("superTable: %s\n", createSql) _, err = connection.Exec(createSql) if err != nil { log.Fatalf("create supertable error: %s\n", err) @@ -473,15 +471,15 @@ func createSuperTable(superTableConfigMap map[string]*superTableConfig) { } -func getScaleSubTableName(subTableName string, hnum int) string { - if hnum == 0 { +func getScaleSubTableName(subTableName string, hNum int) string { + if hNum == 0 { return subTableName } - return fmt.Sprintf("%s_%d", subTableName, hnum) + return fmt.Sprintf("%s_%d", subTableName, hNum) } -func getSuperTableName(stname string) string { - return SUPERTABLE_PREFIX + stname +func getSuperTableName(stName string) string { + return SuperTablePrefix + stName } /** @@ -499,7 +497,7 @@ func normalizationData(fileRows dataRows, minTime int64) int64 { row[fileRows.config.Timestamp] = getPrimaryKey(row[fileRows.config.Timestamp]) - minTime - subTableName := getSubTableName(tableValue, fileRows.config.Stname) + subTableName := getSubTableName(tableValue, fileRows.config.StName) value, ok := subTableMap[subTableName] if !ok { @@ -527,7 +525,7 @@ func normalizationDataWithSameInterval(fileRows dataRows, avgInterval int64) int continue } - subTableName := getSubTableName(tableValue, fileRows.config.Stname) + subTableName := getSubTableName(tableValue, fileRows.config.StName) value, ok := currSubTableMap[subTableName] if !ok { @@ -543,7 +541,7 @@ func normalizationDataWithSameInterval(fileRows dataRows, avgInterval int64) int } - var maxRows, tableRows int = 0, 0 + var maxRows, tableRows = 0, 0 for tableName := range currSubTableMap { tableRows = len(currSubTableMap[tableName].rows) subTableMap[tableName] = currSubTableMap[tableName] // add to global subTableMap @@ -556,7 +554,7 @@ func normalizationDataWithSameInterval(fileRows dataRows, avgInterval int64) int } func getSubTableName(subTableValue string, superTableName string) string { - return SUBTABLE_PREFIX + subTableValue + "_" + superTableName + return SubTablePrefix + subTableValue + "_" + superTableName } func insertData(threadIndex, start, end int, wg *sync.WaitGroup, successRows []int64) { @@ -564,25 +562,25 @@ func insertData(threadIndex, start, end int, wg *sync.WaitGroup, successRows []i defer connection.Close() defer wg.Done() - connection.Exec("use " + db) // use db + _, _ = connection.Exec("use " + db) // use db log.Printf("thread-%d start insert into [%d, %d) subtables.\n", threadIndex, start, end) num := 0 subTables := scaleTableNames[start:end] + var buffer bytes.Buffer for { var currSuccessRows int64 var appendRows int var lastTableName string - buffers := bytes.Buffer{} - buffers.WriteString(INSERT_PREFIX) + buffer.WriteString(InsertPrefix) for _, tableName := range subTables { subTableInfo := subTableMap[scaleTableMap[tableName].subTableName] subTableRows := int64(len(subTableInfo.rows)) - superTableConf := superTableConfigMap[subTableInfo.config.Stname] + superTableConf := superTableConfigMap[subTableInfo.config.StName] tableStartTime := superTableConf.startTime var tableEndTime int64 @@ -605,40 +603,35 @@ func insertData(threadIndex, start, end int, wg *sync.WaitGroup, successRows []i // append if lastTableName != tableName { - buffers.WriteString(tableName) - buffers.WriteString(" values") + buffer.WriteString(tableName) + buffer.WriteString(" values") } lastTableName = tableName - buffers.WriteString("(") - buffers.WriteString(fmt.Sprintf("%v", currentTime)) - buffers.WriteString(",") + buffer.WriteString("(") + buffer.WriteString(fmt.Sprintf("%v", currentTime)) + buffer.WriteString(",") - // fieldNum := len(subTableInfo.config.Fields) for _, field := range subTableInfo.config.Fields { - buffers.WriteString(getFieldValue(currentRow[strings.ToLower(field.Name)])) - buffers.WriteString(",") - // if( i != fieldNum -1){ - - // } + buffer.WriteString(getFieldValue(currentRow[strings.ToLower(field.Name)])) + buffer.WriteString(",") } - buffers.Truncate(buffers.Len() - 1) - buffers.WriteString(") ") + buffer.Truncate(buffer.Len() - 1) + buffer.WriteString(") ") appendRows++ insertRows++ if appendRows == batch { - // executebatch - insertSql := buffers.String() - connection.Exec("use " + db) + // executeBatch + insertSql := buffer.String() affectedRows := executeBatchInsert(insertSql, connection) successRows[threadIndex] += affectedRows currSuccessRows += affectedRows - buffers.Reset() - buffers.WriteString(INSERT_PREFIX) + buffer.Reset() + buffer.WriteString(InsertPrefix) lastTableName = "" appendRows = 0 } @@ -654,15 +647,14 @@ func insertData(threadIndex, start, end int, wg *sync.WaitGroup, successRows []i // left := len(rows) if appendRows > 0 { - // executebatch - insertSql := buffers.String() - connection.Exec("use " + db) + // executeBatch + insertSql := buffer.String() affectedRows := executeBatchInsert(insertSql, connection) successRows[threadIndex] += affectedRows currSuccessRows += affectedRows - buffers.Reset() + buffer.Reset() } // log.Printf("thread-%d finished insert %d rows, used %d ms.", threadIndex, currSuccessRows, time.Since(threadStartTime)/1e6) @@ -688,65 +680,10 @@ func insertData(threadIndex, start, end int, wg *sync.WaitGroup, successRows []i } -func buildSql(rows []tableRows) string { - - var lastTableName string - - buffers := bytes.Buffer{} - - for i, row := range rows { - if i == 0 { - lastTableName = row.tableName - buffers.WriteString(INSERT_PREFIX) - buffers.WriteString(row.tableName) - buffers.WriteString(" values") - buffers.WriteString(row.value) - continue - } - - if lastTableName == row.tableName { - buffers.WriteString(row.value) - } else { - buffers.WriteString(" ") - buffers.WriteString(row.tableName) - buffers.WriteString(" values") - buffers.WriteString(row.value) - lastTableName = row.tableName - } - } - - inserSql := buffers.String() - return inserSql -} - -func buildRow(tableName string, currentTime int64, subTableInfo *dataRows, currentRow map[string]interface{}) tableRows { - - tableRows := tableRows{tableName: tableName} - - buffers := bytes.Buffer{} - - buffers.WriteString("(") - buffers.WriteString(fmt.Sprintf("%v", currentTime)) - buffers.WriteString(",") - - for _, field := range subTableInfo.config.Fields { - buffers.WriteString(getFieldValue(currentRow[strings.ToLower(field.Name)])) - buffers.WriteString(",") - } - - buffers.Truncate(buffers.Len() - 1) - buffers.WriteString(")") - - insertSql := buffers.String() - tableRows.value = insertSql - - return tableRows -} - func executeBatchInsert(insertSql string, connection *sql.DB) int64 { - result, error := connection.Exec(insertSql) - if error != nil { - log.Printf("execute insertSql %s error, %s\n", insertSql, error) + result, err := connection.Exec(insertSql) + if err != nil { + log.Printf("execute insertSql %s error, %s\n", insertSql, err) return 0 } affected, _ := result.RowsAffected() @@ -754,7 +691,6 @@ func executeBatchInsert(insertSql string, connection *sql.DB) int64 { affected = 0 } return affected - // return 0 } func getFieldValue(fieldValue interface{}) string { @@ -762,7 +698,7 @@ func getFieldValue(fieldValue interface{}) string { } func getConnection() *sql.DB { - db, err := sql.Open(DRIVER_NAME, dataSourceName) + db, err := sql.Open(DriverName, dataSourceName) if err != nil { panic(err) } @@ -773,19 +709,11 @@ func getSubTableNameValue(suffix interface{}) string { return fmt.Sprintf("%v", suffix) } -func hash(s string) int { - v := int(crc32.ChecksumIEEE([]byte(s))) - if v < 0 { - return -v - } - return v -} - -func readFile(config dataimport.CaseConfig) dataRows { +func readFile(config dataImport.CaseConfig) dataRows { fileFormat := strings.ToLower(config.Format) - if fileFormat == JSON_FORMAT { + if fileFormat == JsonFormat { return readJSONFile(config) - } else if fileFormat == CSV_FORMAT { + } else if fileFormat == CsvFormat { return readCSVFile(config) } @@ -793,7 +721,7 @@ func readFile(config dataimport.CaseConfig) dataRows { return dataRows{} } -func readCSVFile(config dataimport.CaseConfig) dataRows { +func readCSVFile(config dataImport.CaseConfig) dataRows { var rows dataRows f, err := os.Open(config.FilePath) if err != nil { @@ -813,7 +741,7 @@ func readCSVFile(config dataimport.CaseConfig) dataRows { line := strings.ToLower(string(lineBytes)) titles := strings.Split(line, config.Separator) if len(titles) < 3 { - // need suffix、 primarykey and at least one other field + // need suffix、 primaryKey and at least one other field log.Printf("the first line of file %s should be title row, and at least 3 field.\n", config.FilePath) return rows } @@ -848,7 +776,7 @@ func readCSVFile(config dataimport.CaseConfig) dataRows { } // if the primary key valid - primaryKeyValue := getPrimaryKeyMillisec(config.Timestamp, config.TimestampType, config.TimestampTypeFormat, dataMap) + primaryKeyValue := getPrimaryKeyMilliSec(config.Timestamp, config.TimestampType, config.TimestampTypeFormat, dataMap) if primaryKeyValue == -1 { log.Printf("the Timestamp[%s] of line %d is not valid, will filtered.\n", config.Timestamp, lineNum) continue @@ -861,7 +789,7 @@ func readCSVFile(config dataimport.CaseConfig) dataRows { return rows } -func readJSONFile(config dataimport.CaseConfig) dataRows { +func readJSONFile(config dataImport.CaseConfig) dataRows { var rows dataRows f, err := os.Open(config.FilePath) @@ -899,7 +827,7 @@ func readJSONFile(config dataimport.CaseConfig) dataRows { continue } - primaryKeyValue := getPrimaryKeyMillisec(config.Timestamp, config.TimestampType, config.TimestampTypeFormat, line) + primaryKeyValue := getPrimaryKeyMilliSec(config.Timestamp, config.TimestampType, config.TimestampTypeFormat, line) if primaryKeyValue == -1 { log.Printf("the Timestamp[%s] of line %d is not valid, will filtered.\n", config.Timestamp, lineNum) continue @@ -916,7 +844,7 @@ func readJSONFile(config dataimport.CaseConfig) dataRows { /** * get primary key as millisecond , otherwise return -1 */ -func getPrimaryKeyMillisec(key string, valueType string, valueFormat string, line map[string]interface{}) int64 { +func getPrimaryKeyMilliSec(key string, valueType string, valueFormat string, line map[string]interface{}) int64 { if !existMapKeyAndNotEmpty(key, line) { return -1 } @@ -971,13 +899,13 @@ func existMapKeyAndNotEmpty(key string, maps map[string]interface{}) bool { return true } -func checkUserCaseConfig(caseName string, caseConfig *dataimport.CaseConfig) { +func checkUserCaseConfig(caseName string, caseConfig *dataImport.CaseConfig) { - if len(caseConfig.Stname) == 0 { + if len(caseConfig.StName) == 0 { log.Fatalf("the stname of case %s can't be empty\n", caseName) } - caseConfig.Stname = strings.ToLower(caseConfig.Stname) + caseConfig.StName = strings.ToLower(caseConfig.StName) if len(caseConfig.Tags) == 0 { log.Fatalf("the tags of case %s can't be empty\n", caseName) @@ -1029,24 +957,24 @@ func checkUserCaseConfig(caseName string, caseConfig *dataimport.CaseConfig) { } func parseArg() { - flag.StringVar(&cfg, "cfg", "config/cfg.toml", "configuration file which describes usecase and data format.") - flag.StringVar(&cases, "cases", "sensor_info", "usecase for dataset to be imported. Multiple choices can be separated by comma, for example, -cases sensor_info,camera_detection.") + flag.StringVar(&cfg, "cfg", "config/cfg.toml", "configuration file which describes useCase and data format.") + flag.StringVar(&cases, "cases", "sensor_info", "useCase for dataset to be imported. Multiple choices can be separated by comma, for example, -cases sensor_info,camera_detection.") flag.IntVar(&hnum, "hnum", 100, "magnification factor of the sample tables. For example, if hnum is 100 and in the sample data there are 10 tables, then 10x100=1000 tables will be created in the database.") flag.IntVar(&vnum, "vnum", 1000, "copies of the sample records in each table. If set to 0,this program will never stop simulating and importing data even if the timestamp has passed current time.") - flag.Int64Var(&delay, "delay", DEFAULT_DELAY, "the delay time interval(millisecond) to continue generating data when vnum set 0.") + flag.Int64Var(&delay, "delay", DefaultDelay, "the delay time interval(millisecond) to continue generating data when vnum set 0.") flag.Int64Var(&tick, "tick", 2000, "the tick time interval(millisecond) to print statistic info.") flag.IntVar(&save, "save", 0, "whether to save the statistical info into 'statistic' table. 0 is disabled and 1 is enabled.") - flag.StringVar(&saveTable, "savetb", DEFAULT_STATISTIC_TABLE, "the table to save 'statistic' info when save set 1.") + flag.StringVar(&saveTable, "savetb", DefaultStatisticTable, "the table to save 'statistic' info when save set 1.") flag.IntVar(&thread, "thread", 10, "number of threads to import data.") flag.IntVar(&batch, "batch", 100, "rows of records in one import batch.") - flag.IntVar(&auto, "auto", 0, "whether to use the starttime and interval specified by users when simulating the data. 0 is disabled and 1 is enabled.") - flag.StringVar(&starttimestr, "start", "", "the starting timestamp of simulated data, in the format of yyyy-MM-dd HH:mm:ss.SSS. If not specified, the ealiest timestamp in the sample data will be set as the starttime.") - flag.Int64Var(&interval, "interval", DEFAULT_INTERVAL, "time inteval between two consecutive records, in the unit of millisecond. Only valid when auto is 1.") + flag.IntVar(&auto, "auto", 0, "whether to use the startTime and interval specified by users when simulating the data. 0 is disabled and 1 is enabled.") + flag.StringVar(&startTimeStr, "start", "", "the starting timestamp of simulated data, in the format of yyyy-MM-dd HH:mm:ss.SSS. If not specified, the earliest timestamp in the sample data will be set as the startTime.") + flag.Int64Var(&interval, "interval", DefaultInterval, "time interval between two consecutive records, in the unit of millisecond. Only valid when auto is 1.") flag.StringVar(&host, "host", "127.0.0.1", "tdengine server ip.") flag.IntVar(&port, "port", 6030, "tdengine server port.") flag.StringVar(&user, "user", "root", "user name to login into the database.") flag.StringVar(&password, "password", "taosdata", "the import tdengine user password") - flag.IntVar(&dropdb, "dropdb", 0, "whether to drop the existing datbase. 1 is yes and 0 otherwise.") + flag.IntVar(&dropdb, "dropdb", 0, "whether to drop the existing database. 1 is yes and 0 otherwise.") flag.StringVar(&db, "db", "", "name of the database to store data.") flag.StringVar(&dbparam, "dbparam", "", "database configurations when it is created.") @@ -1066,7 +994,7 @@ func printArg() { fmt.Println("-thread:", thread) fmt.Println("-batch:", batch) fmt.Println("-auto:", auto) - fmt.Println("-start:", starttimestr) + fmt.Println("-start:", startTimeStr) fmt.Println("-interval:", interval) fmt.Println("-host:", host) fmt.Println("-port", port) diff --git a/importSampleData/data/sensor_info.csv b/importSampleData/data/sensor_info.csv index d049c8b004..c5ff898118 100644 --- a/importSampleData/data/sensor_info.csv +++ b/importSampleData/data/sensor_info.csv @@ -899,103 +899,103 @@ devid,location,color,devgroup,ts,temperature,humidity 8, haerbing, yellow, 2, 1575129697000, 31, 16.321497 8, haerbing, yellow, 2, 1575129698000, 25, 15.864515 8, haerbing, yellow, 2, 1575129699000, 25, 16.492443 -9, sijiazhuang, blue, 0, 1575129600000, 23, 16.002889 -9, sijiazhuang, blue, 0, 1575129601000, 26, 17.034610 -9, sijiazhuang, blue, 0, 1575129602000, 29, 12.892319 -9, sijiazhuang, blue, 0, 1575129603000, 34, 15.321807 -9, sijiazhuang, blue, 0, 1575129604000, 29, 12.562642 -9, sijiazhuang, blue, 0, 1575129605000, 32, 17.190246 -9, sijiazhuang, blue, 0, 1575129606000, 19, 15.361774 -9, sijiazhuang, blue, 0, 1575129607000, 26, 15.022364 -9, sijiazhuang, blue, 0, 1575129608000, 31, 14.837084 -9, sijiazhuang, blue, 0, 1575129609000, 25, 11.554289 -9, sijiazhuang, blue, 0, 1575129610000, 21, 15.313973 -9, sijiazhuang, blue, 0, 1575129611000, 27, 18.621783 -9, sijiazhuang, blue, 0, 1575129612000, 31, 18.018101 -9, sijiazhuang, blue, 0, 1575129613000, 23, 14.421450 -9, sijiazhuang, blue, 0, 1575129614000, 28, 10.833142 -9, sijiazhuang, blue, 0, 1575129615000, 33, 18.169837 -9, sijiazhuang, blue, 0, 1575129616000, 21, 18.772730 -9, sijiazhuang, blue, 0, 1575129617000, 24, 18.893146 -9, sijiazhuang, blue, 0, 1575129618000, 24, 10.290187 -9, sijiazhuang, blue, 0, 1575129619000, 23, 17.393345 -9, sijiazhuang, blue, 0, 1575129620000, 30, 12.949215 -9, sijiazhuang, blue, 0, 1575129621000, 19, 19.267621 -9, sijiazhuang, blue, 0, 1575129622000, 33, 14.831735 -9, sijiazhuang, blue, 0, 1575129623000, 21, 14.711125 -9, sijiazhuang, blue, 0, 1575129624000, 16, 17.168485 -9, sijiazhuang, blue, 0, 1575129625000, 17, 16.426433 -9, sijiazhuang, blue, 0, 1575129626000, 19, 13.879050 -9, sijiazhuang, blue, 0, 1575129627000, 21, 18.308168 -9, sijiazhuang, blue, 0, 1575129628000, 17, 10.845681 -9, sijiazhuang, blue, 0, 1575129629000, 20, 10.238272 -9, sijiazhuang, blue, 0, 1575129630000, 19, 19.424976 -9, sijiazhuang, blue, 0, 1575129631000, 31, 13.885909 -9, sijiazhuang, blue, 0, 1575129632000, 15, 19.264740 -9, sijiazhuang, blue, 0, 1575129633000, 30, 12.460645 -9, sijiazhuang, blue, 0, 1575129634000, 27, 17.608036 -9, sijiazhuang, blue, 0, 1575129635000, 25, 13.493812 -9, sijiazhuang, blue, 0, 1575129636000, 19, 10.955939 -9, sijiazhuang, blue, 0, 1575129637000, 24, 11.956587 -9, sijiazhuang, blue, 0, 1575129638000, 15, 19.141381 -9, sijiazhuang, blue, 0, 1575129639000, 24, 14.801530 -9, sijiazhuang, blue, 0, 1575129640000, 17, 14.347318 -9, sijiazhuang, blue, 0, 1575129641000, 29, 14.803237 -9, sijiazhuang, blue, 0, 1575129642000, 28, 10.342297 -9, sijiazhuang, blue, 0, 1575129643000, 29, 19.368282 -9, sijiazhuang, blue, 0, 1575129644000, 31, 17.491654 -9, sijiazhuang, blue, 0, 1575129645000, 18, 13.161736 -9, sijiazhuang, blue, 0, 1575129646000, 17, 16.067354 -9, sijiazhuang, blue, 0, 1575129647000, 18, 13.736465 -9, sijiazhuang, blue, 0, 1575129648000, 23, 19.103276 -9, sijiazhuang, blue, 0, 1575129649000, 29, 16.075892 -9, sijiazhuang, blue, 0, 1575129650000, 21, 10.728566 -9, sijiazhuang, blue, 0, 1575129651000, 15, 18.921849 -9, sijiazhuang, blue, 0, 1575129652000, 24, 16.914709 -9, sijiazhuang, blue, 0, 1575129653000, 19, 13.501651 -9, sijiazhuang, blue, 0, 1575129654000, 19, 13.538347 -9, sijiazhuang, blue, 0, 1575129655000, 16, 13.261095 -9, sijiazhuang, blue, 0, 1575129656000, 32, 16.315746 -9, sijiazhuang, blue, 0, 1575129657000, 27, 16.400939 -9, sijiazhuang, blue, 0, 1575129658000, 24, 13.321819 -9, sijiazhuang, blue, 0, 1575129659000, 27, 19.070181 -9, sijiazhuang, blue, 0, 1575129660000, 27, 13.040922 -9, sijiazhuang, blue, 0, 1575129661000, 32, 10.872530 -9, sijiazhuang, blue, 0, 1575129662000, 28, 16.428657 -9, sijiazhuang, blue, 0, 1575129663000, 32, 13.883854 -9, sijiazhuang, blue, 0, 1575129664000, 33, 14.299554 -9, sijiazhuang, blue, 0, 1575129665000, 30, 16.445130 -9, sijiazhuang, blue, 0, 1575129666000, 15, 18.059404 -9, sijiazhuang, blue, 0, 1575129667000, 21, 12.348847 -9, sijiazhuang, blue, 0, 1575129668000, 32, 13.315378 -9, sijiazhuang, blue, 0, 1575129669000, 17, 15.689507 -9, sijiazhuang, blue, 0, 1575129670000, 22, 15.591808 -9, sijiazhuang, blue, 0, 1575129671000, 27, 16.386065 -9, sijiazhuang, blue, 0, 1575129672000, 25, 10.564803 -9, sijiazhuang, blue, 0, 1575129673000, 20, 12.276544 -9, sijiazhuang, blue, 0, 1575129674000, 26, 15.828786 -9, sijiazhuang, blue, 0, 1575129675000, 18, 12.236420 -9, sijiazhuang, blue, 0, 1575129676000, 15, 19.439522 -9, sijiazhuang, blue, 0, 1575129677000, 19, 19.831531 -9, sijiazhuang, blue, 0, 1575129678000, 22, 17.115744 -9, sijiazhuang, blue, 0, 1575129679000, 29, 19.879456 -9, sijiazhuang, blue, 0, 1575129680000, 34, 10.207136 -9, sijiazhuang, blue, 0, 1575129681000, 16, 17.633523 -9, sijiazhuang, blue, 0, 1575129682000, 15, 14.227873 -9, sijiazhuang, blue, 0, 1575129683000, 34, 12.027768 -9, sijiazhuang, blue, 0, 1575129684000, 22, 11.376610 -9, sijiazhuang, blue, 0, 1575129685000, 21, 11.711299 -9, sijiazhuang, blue, 0, 1575129686000, 33, 14.281126 -9, sijiazhuang, blue, 0, 1575129687000, 31, 10.895302 -9, sijiazhuang, blue, 0, 1575129688000, 31, 13.971350 -9, sijiazhuang, blue, 0, 1575129689000, 15, 15.262790 -9, sijiazhuang, blue, 0, 1575129690000, 23, 12.440568 -9, sijiazhuang, blue, 0, 1575129691000, 32, 19.731267 -9, sijiazhuang, blue, 0, 1575129692000, 22, 10.518092 -9, sijiazhuang, blue, 0, 1575129693000, 34, 17.863021 -9, sijiazhuang, blue, 0, 1575129694000, 28, 11.478909 -9, sijiazhuang, blue, 0, 1575129695000, 16, 15.075524 -9, sijiazhuang, blue, 0, 1575129696000, 16, 10.292127 -9, sijiazhuang, blue, 0, 1575129697000, 22, 13.716012 -9, sijiazhuang, blue, 0, 1575129698000, 32, 10.906551 -9, sijiazhuang, blue, 0, 1575129699000, 19, 18.386868 \ No newline at end of file +9, shijiazhuang, blue, 0, 1575129600000, 23, 16.002889 +9, shijiazhuang, blue, 0, 1575129601000, 26, 17.034610 +9, shijiazhuang, blue, 0, 1575129602000, 29, 12.892319 +9, shijiazhuang, blue, 0, 1575129603000, 34, 15.321807 +9, shijiazhuang, blue, 0, 1575129604000, 29, 12.562642 +9, shijiazhuang, blue, 0, 1575129605000, 32, 17.190246 +9, shijiazhuang, blue, 0, 1575129606000, 19, 15.361774 +9, shijiazhuang, blue, 0, 1575129607000, 26, 15.022364 +9, shijiazhuang, blue, 0, 1575129608000, 31, 14.837084 +9, shijiazhuang, blue, 0, 1575129609000, 25, 11.554289 +9, shijiazhuang, blue, 0, 1575129610000, 21, 15.313973 +9, shijiazhuang, blue, 0, 1575129611000, 27, 18.621783 +9, shijiazhuang, blue, 0, 1575129612000, 31, 18.018101 +9, shijiazhuang, blue, 0, 1575129613000, 23, 14.421450 +9, shijiazhuang, blue, 0, 1575129614000, 28, 10.833142 +9, shijiazhuang, blue, 0, 1575129615000, 33, 18.169837 +9, shijiazhuang, blue, 0, 1575129616000, 21, 18.772730 +9, shijiazhuang, blue, 0, 1575129617000, 24, 18.893146 +9, shijiazhuang, blue, 0, 1575129618000, 24, 10.290187 +9, shijiazhuang, blue, 0, 1575129619000, 23, 17.393345 +9, shijiazhuang, blue, 0, 1575129620000, 30, 12.949215 +9, shijiazhuang, blue, 0, 1575129621000, 19, 19.267621 +9, shijiazhuang, blue, 0, 1575129622000, 33, 14.831735 +9, shijiazhuang, blue, 0, 1575129623000, 21, 14.711125 +9, shijiazhuang, blue, 0, 1575129624000, 16, 17.168485 +9, shijiazhuang, blue, 0, 1575129625000, 17, 16.426433 +9, shijiazhuang, blue, 0, 1575129626000, 19, 13.879050 +9, shijiazhuang, blue, 0, 1575129627000, 21, 18.308168 +9, shijiazhuang, blue, 0, 1575129628000, 17, 10.845681 +9, shijiazhuang, blue, 0, 1575129629000, 20, 10.238272 +9, shijiazhuang, blue, 0, 1575129630000, 19, 19.424976 +9, shijiazhuang, blue, 0, 1575129631000, 31, 13.885909 +9, shijiazhuang, blue, 0, 1575129632000, 15, 19.264740 +9, shijiazhuang, blue, 0, 1575129633000, 30, 12.460645 +9, shijiazhuang, blue, 0, 1575129634000, 27, 17.608036 +9, shijiazhuang, blue, 0, 1575129635000, 25, 13.493812 +9, shijiazhuang, blue, 0, 1575129636000, 19, 10.955939 +9, shijiazhuang, blue, 0, 1575129637000, 24, 11.956587 +9, shijiazhuang, blue, 0, 1575129638000, 15, 19.141381 +9, shijiazhuang, blue, 0, 1575129639000, 24, 14.801530 +9, shijiazhuang, blue, 0, 1575129640000, 17, 14.347318 +9, shijiazhuang, blue, 0, 1575129641000, 29, 14.803237 +9, shijiazhuang, blue, 0, 1575129642000, 28, 10.342297 +9, shijiazhuang, blue, 0, 1575129643000, 29, 19.368282 +9, shijiazhuang, blue, 0, 1575129644000, 31, 17.491654 +9, shijiazhuang, blue, 0, 1575129645000, 18, 13.161736 +9, shijiazhuang, blue, 0, 1575129646000, 17, 16.067354 +9, shijiazhuang, blue, 0, 1575129647000, 18, 13.736465 +9, shijiazhuang, blue, 0, 1575129648000, 23, 19.103276 +9, shijiazhuang, blue, 0, 1575129649000, 29, 16.075892 +9, shijiazhuang, blue, 0, 1575129650000, 21, 10.728566 +9, shijiazhuang, blue, 0, 1575129651000, 15, 18.921849 +9, shijiazhuang, blue, 0, 1575129652000, 24, 16.914709 +9, shijiazhuang, blue, 0, 1575129653000, 19, 13.501651 +9, shijiazhuang, blue, 0, 1575129654000, 19, 13.538347 +9, shijiazhuang, blue, 0, 1575129655000, 16, 13.261095 +9, shijiazhuang, blue, 0, 1575129656000, 32, 16.315746 +9, shijiazhuang, blue, 0, 1575129657000, 27, 16.400939 +9, shijiazhuang, blue, 0, 1575129658000, 24, 13.321819 +9, shijiazhuang, blue, 0, 1575129659000, 27, 19.070181 +9, shijiazhuang, blue, 0, 1575129660000, 27, 13.040922 +9, shijiazhuang, blue, 0, 1575129661000, 32, 10.872530 +9, shijiazhuang, blue, 0, 1575129662000, 28, 16.428657 +9, shijiazhuang, blue, 0, 1575129663000, 32, 13.883854 +9, shijiazhuang, blue, 0, 1575129664000, 33, 14.299554 +9, shijiazhuang, blue, 0, 1575129665000, 30, 16.445130 +9, shijiazhuang, blue, 0, 1575129666000, 15, 18.059404 +9, shijiazhuang, blue, 0, 1575129667000, 21, 12.348847 +9, shijiazhuang, blue, 0, 1575129668000, 32, 13.315378 +9, shijiazhuang, blue, 0, 1575129669000, 17, 15.689507 +9, shijiazhuang, blue, 0, 1575129670000, 22, 15.591808 +9, shijiazhuang, blue, 0, 1575129671000, 27, 16.386065 +9, shijiazhuang, blue, 0, 1575129672000, 25, 10.564803 +9, shijiazhuang, blue, 0, 1575129673000, 20, 12.276544 +9, shijiazhuang, blue, 0, 1575129674000, 26, 15.828786 +9, shijiazhuang, blue, 0, 1575129675000, 18, 12.236420 +9, shijiazhuang, blue, 0, 1575129676000, 15, 19.439522 +9, shijiazhuang, blue, 0, 1575129677000, 19, 19.831531 +9, shijiazhuang, blue, 0, 1575129678000, 22, 17.115744 +9, shijiazhuang, blue, 0, 1575129679000, 29, 19.879456 +9, shijiazhuang, blue, 0, 1575129680000, 34, 10.207136 +9, shijiazhuang, blue, 0, 1575129681000, 16, 17.633523 +9, shijiazhuang, blue, 0, 1575129682000, 15, 14.227873 +9, shijiazhuang, blue, 0, 1575129683000, 34, 12.027768 +9, shijiazhuang, blue, 0, 1575129684000, 22, 11.376610 +9, shijiazhuang, blue, 0, 1575129685000, 21, 11.711299 +9, shijiazhuang, blue, 0, 1575129686000, 33, 14.281126 +9, shijiazhuang, blue, 0, 1575129687000, 31, 10.895302 +9, shijiazhuang, blue, 0, 1575129688000, 31, 13.971350 +9, shijiazhuang, blue, 0, 1575129689000, 15, 15.262790 +9, shijiazhuang, blue, 0, 1575129690000, 23, 12.440568 +9, shijiazhuang, blue, 0, 1575129691000, 32, 19.731267 +9, shijiazhuang, blue, 0, 1575129692000, 22, 10.518092 +9, shijiazhuang, blue, 0, 1575129693000, 34, 17.863021 +9, shijiazhuang, blue, 0, 1575129694000, 28, 11.478909 +9, shijiazhuang, blue, 0, 1575129695000, 16, 15.075524 +9, shijiazhuang, blue, 0, 1575129696000, 16, 10.292127 +9, shijiazhuang, blue, 0, 1575129697000, 22, 13.716012 +9, shijiazhuang, blue, 0, 1575129698000, 32, 10.906551 +9, shijiazhuang, blue, 0, 1575129699000, 19, 18.386868 \ No newline at end of file diff --git a/importSampleData/go.mod b/importSampleData/go.mod new file mode 100644 index 0000000000..fa1d978e59 --- /dev/null +++ b/importSampleData/go.mod @@ -0,0 +1,8 @@ +module github.com/taosdata/TDengine/importSampleData + +go 1.13 + +require ( + github.com/pelletier/go-toml v1.9.0 // indirect + github.com/taosdata/driver-go v0.0.0-20210415143420-d99751356e28 // indirect +) diff --git a/importSampleData/import/import_config.go b/importSampleData/import/import_config.go index e7942cc505..fdaeeab7da 100644 --- a/importSampleData/import/import_config.go +++ b/importSampleData/import/import_config.go @@ -14,23 +14,23 @@ var ( once sync.Once ) -// Config inclue all scene import config +// Config include all scene import config type Config struct { UserCases map[string]CaseConfig } // CaseConfig include the sample data config and tdengine config type CaseConfig struct { - Format string - FilePath string - Separator string - Stname string - SubTableName string - Timestamp string - TimestampType string - TimestampTypeFormat string - Tags []FieldInfo - Fields []FieldInfo + Format string + FilePath string + Separator string + StName string + SubTableName string + Timestamp string + TimestampType string + TimestampTypeFormat string + Tags []FieldInfo + Fields []FieldInfo } // FieldInfo is field or tag info diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 9c7400c616..43006928a6 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,7 @@ name: tdengine base: core18 -version: '2.0.20.2' + +version: '2.1.0.0' icon: snap/gui/t-dengine.svg summary: an open-source big data platform designed and optimized for IoT. description: | @@ -72,7 +73,7 @@ parts: - usr/bin/taosd - usr/bin/taos - usr/bin/taosdemo - - usr/lib/libtaos.so.2.0.20.2 + - usr/lib/libtaos.so.2.1.0.0 - usr/lib/libtaos.so.1 - usr/lib/libtaos.so diff --git a/src/client/inc/tscLocalMerge.h b/src/client/inc/tscLocalMerge.h index 581cd37cbd..143922bb1f 100644 --- a/src/client/inc/tscLocalMerge.h +++ b/src/client/inc/tscLocalMerge.h @@ -44,23 +44,15 @@ typedef struct SLocalMerger { int32_t numOfCompleted; int32_t numOfVnode; SLoserTreeInfo * pLoserTree; - char * prevRowOfInput; tFilePage * pResultBuf; int32_t nResultBufSize; tFilePage * pTempBuffer; struct SQLFunctionCtx *pCtx; int32_t rowSize; // size of each intermediate result. - bool hasPrevRow; // cannot be released - bool hasUnprocessedRow; tOrderDescriptor * pDesc; SColumnModel * resColModel; SColumnModel* finalModel; tExtMemBuffer ** pExtMemBuffer; // disk-based buffer - SFillInfo* pFillInfo; // interpolation support structure - char* pFinalRes; // result data after interpo - tFilePage* discardData; - bool discard; - int32_t offset; // limit offset value bool orderPrjOnSTable; // projection query on stable } SLocalMerger; @@ -94,7 +86,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde void tscDestroyLocalMerger(SSqlObj *pSql); -int32_t tscDoLocalMerge(SSqlObj *pSql); +//int32_t tscDoLocalMerge(SSqlObj *pSql); #ifdef __cplusplus } diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index b80dcfb577..56d595ff1f 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -85,15 +85,13 @@ typedef struct SMergeTsCtx { int8_t compared; }SMergeTsCtx; - typedef struct SVgroupTableInfo { SVgroupInfo vgInfo; - SArray* itemList; //SArray + SArray *itemList; // SArray } SVgroupTableInfo; -static FORCE_INLINE SQueryInfo* tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex) { +static FORCE_INLINE SQueryInfo* tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex) { assert(pCmd != NULL && subClauseIndex >= 0); - if (pCmd->pQueryInfo == NULL || subClauseIndex >= pCmd->numOfClause) { return NULL; } @@ -101,6 +99,8 @@ static FORCE_INLINE SQueryInfo* tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t sub return pCmd->pQueryInfo[subClauseIndex]; } +SQueryInfo* tscGetActiveQueryInfo(SSqlCmd* pCmd); + 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); @@ -129,7 +129,13 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo); bool tscIsTWAQuery(SQueryInfo* pQueryInfo); bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo); bool tscGroupbyColumn(SQueryInfo* pQueryInfo); -bool tscIsTopbotQuery(SQueryInfo* pQueryInfo); +bool tscIsTopBotQuery(SQueryInfo* pQueryInfo); +bool hasTagValOutput(SQueryInfo* pQueryInfo); +bool timeWindowInterpoRequired(SQueryInfo *pQueryInfo); +bool isStabledev(SQueryInfo* pQueryInfo); +bool isTsCompQuery(SQueryInfo* pQueryInfo); +bool isSimpleAggregate(SQueryInfo* pQueryInfo); +bool isBlockDistQuery(SQueryInfo* pQueryInfo); int32_t tscGetTopbotQueryParam(SQueryInfo* pQueryInfo); bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex); @@ -143,7 +149,7 @@ bool tscQueryTags(SQueryInfo* pQueryInfo); bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t tableIndex); bool tscQueryBlockInfo(SQueryInfo* pQueryInfo); -SSqlExpr* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, +SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType); int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql); @@ -175,27 +181,29 @@ void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) int32_t tscGetResRowLength(SArray* pExprList); -SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol); -SSqlExpr* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol); -SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type, +SExprInfo* tscSqlExprUpdate(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, SColumnIndex* pIndex); +void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid); -SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index); +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); SColumn* tscColumnClone(const SColumn* src); -bool tscColumnExists(SArray* pColumnList, SColumnIndex* pColIndex); -SColumn* tscColumnListInsert(SArray* pColList, SColumnIndex* colIndex); -SArray* tscColumnListClone(const SArray* src, int16_t tableIndex); +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 convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo); + void tscDequoteAndTrimToken(SStrToken* pToken); int32_t tscValidateName(SStrToken* pToken); @@ -217,8 +225,11 @@ bool tscShouldBeFreed(SSqlObj* pSql); STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t subClauseIndex, int32_t tableIndex); STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex); -SQueryInfo *tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex); -SQueryInfo *tscGetQueryInfoDetailSafely(SSqlCmd *pCmd, int32_t subClauseIndex); +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); void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo); @@ -226,11 +237,7 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, SName* name, STableM SVgroupsInfo* vgroupList, SArray* pTagCols, SArray* pVgroupTables); STableMetaInfo* tscAddEmptyMetaInfo(SQueryInfo *pQueryInfo); -int32_t tscAddSubqueryInfo(SSqlCmd *pCmd); -void tscInitQueryInfo(SQueryInfo* pQueryInfo); - -void tscClearSubqueryInfo(SSqlCmd* pCmd); void tscFreeVgroupTableInfo(SArray* pVgroupTables); SArray* tscVgroupTableInfoDup(SArray* pVgroupTables); void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index); @@ -242,6 +249,8 @@ int tscGetTableMetaEx(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, bool creat void tscResetForNextRetrieve(SSqlRes* pRes); void tscDoQuery(SSqlObj* pSql); +void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo); +void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo); SVgroupsInfo* tscVgroupInfoClone(SVgroupsInfo *pInfo); void* tscVgroupInfoClear(SVgroupsInfo *pInfo); @@ -275,7 +284,7 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex); int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid); int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId); -void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex); +void tscPrintSelNodeList(SSqlObj* pSql, int32_t subClauseIndex); bool hasMoreVnodesToTry(SSqlObj *pSql); bool hasMoreClauseToTry(SSqlObj* pSql); @@ -300,7 +309,10 @@ CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta); uint32_t tscGetTableMetaMaxSize(); int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name, void* buf); STableMeta* tscTableMetaDup(STableMeta* pTableMeta); +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* malloc_throw(size_t size); void* calloc_throw(size_t nmemb, size_t size); diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 6d94d270a7..2dc99cc319 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -35,6 +35,7 @@ extern "C" { #include "qExecutor.h" #include "qSqlparser.h" #include "qTsbuf.h" +#include "qUtil.h" #include "tcmdtype.h" // forward declaration @@ -97,12 +98,22 @@ typedef struct STableMetaInfo { SArray *tagColList; // SArray, involved tag columns } STableMetaInfo; - typedef struct SColumnIndex { int16_t tableIndex; int16_t columnIndex; } SColumnIndex; +typedef struct SColumn { + uint64_t tableUid; + int32_t columnIndex; + SColumnInfo info; +} SColumn; + +typedef struct SInternalField { + TAOS_FIELD field; + bool visible; + SExprInfo *pExpr; +} SInternalField; typedef struct SFieldInfo { int16_t numOfOutput; // number of column in result @@ -110,43 +121,6 @@ typedef struct SFieldInfo { SArray *internalField; // SArray } SFieldInfo; -typedef struct SColumn { - SColumnIndex colIndex; - int32_t numOfFilters; - SColumnFilterInfo *filterInfo; -} SColumn; - -/* the structure for sql function in select clause */ -typedef struct SSqlExpr { - char aliasName[TSDB_COL_NAME_LEN]; // as aliasName - SColIndex colInfo; - uint64_t uid; // refactor use the pointer - int16_t functionId; // function id in aAgg array - int16_t resType; // return value type - int16_t resBytes; // length of return value - int32_t interBytes; // inter result buffer size - int16_t numOfParams; // argument value of each function - tVariant param[3]; // parameters are not more than 3 - int32_t offset; // sub result column value of arithmetic expression. - int16_t resColId; // result column id - SColumn *pFilter; // expr filter -} SSqlExpr; - -typedef struct SExprFilter { - tSqlExpr *pExpr; //used for having parse - SSqlExpr *pSqlExpr; - SArray *fp; - SColumn *pFilters; //having filter info -}SExprFilter; - -typedef struct SInternalField { - TAOS_FIELD field; - bool visible; - SExprInfo *pArithExprInfo; - SSqlExpr *pSqlExpr; - SExprFilter *pFieldFilters; -} SInternalField; - typedef struct SCond { uint64_t uid; int32_t len; // length of tag query condition data @@ -161,7 +135,7 @@ typedef struct SJoinNode { } SJoinNode; typedef struct SJoinInfo { - bool hasJoin; + bool hasJoin; SJoinNode* joinTables[TSDB_MAX_JOIN_TABLE_NUM]; } SJoinInfo; @@ -230,13 +204,14 @@ typedef struct SQueryInfo { SInterval interval; // tumble time window SSessionWindow sessionWindow; // session time window - SSqlGroupbyExpr groupbyExpr; // group by tags info + SSqlGroupbyExpr groupbyExpr; // groupby tags info SArray * colList; // SArray SFieldInfo fieldsInfo; - SArray * exprList; // SArray + SArray * exprList; // SArray SLimitVal limit; SLimitVal slimit; STagCond tagCond; + SOrderVal order; int16_t fillType; // final result fill type int16_t numOfTables; @@ -255,7 +230,15 @@ typedef struct SQueryInfo { int32_t round; // 0/1/.... int32_t bufLen; char* buf; - int32_t havingFieldNum; + 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 { @@ -270,8 +253,6 @@ typedef struct { }; uint32_t insertType; // TODO remove it - int32_t clauseIndex; // index of multiple subclause query - char * curSql; // current sql, resume position of sql after parsing paused int8_t parseFinished; char reserve2[3]; // fix bus error on arm32 @@ -281,22 +262,26 @@ typedef struct { 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 + 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 + 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 + SArray *pDataBlocks; // SArray. Merged submit block for each vgroup } SSqlCmd; typedef struct SResRec { @@ -439,7 +424,7 @@ void tscInitMsgsFp(); int tsParseSql(SSqlObj *pSql, bool initial); void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet); -int tscProcessSql(SSqlObj *pSql); +int tscBuildAndSendRequest(SSqlObj *pSql, SQueryInfo* pQueryInfo); int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex); void tscAsyncResultOnError(SSqlObj *pSql); @@ -454,6 +439,9 @@ void tscRestoreFuncForSTableQuery(SQueryInfo *pQueryInfo); 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 tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta); @@ -501,47 +489,6 @@ int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* s int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo); -static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t columnIndex, int32_t offset) { - SInternalField* pInfo = (SInternalField*) TARRAY_GET_ELEM(pFieldInfo->internalField, columnIndex); - - int32_t type = pInfo->field.type; - int32_t bytes = pInfo->field.bytes; - - char* pData = pRes->data + (int32_t)(offset * pRes->numOfRows + bytes * pRes->row); - UNUSED(pData); - -// user defined constant value output columns - if (pInfo->pSqlExpr != NULL && TSDB_COL_IS_UD_COL(pInfo->pSqlExpr->colInfo.flag)) { - if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) { - pData = pInfo->pSqlExpr->param[1].pz; - pRes->length[columnIndex] = pInfo->pSqlExpr->param[1].nLen; - pRes->tsrow[columnIndex] = (pInfo->pSqlExpr->param[1].nType == TSDB_DATA_TYPE_NULL) ? NULL : (unsigned char*)pData; - } else { - assert(bytes == tDataTypes[type].bytes); - - pRes->tsrow[columnIndex] = isNull(pData, type) ? NULL : (unsigned char*)&pInfo->pSqlExpr->param[1].i64; - pRes->length[columnIndex] = bytes; - } - } else { - if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) { - int32_t realLen = varDataLen(pData); - assert(realLen <= bytes - VARSTR_HEADER_SIZE); - - pRes->tsrow[columnIndex] = (isNull(pData, type)) ? NULL : (unsigned char*)((tstr *)pData)->data; - if (realLen < pInfo->pSqlExpr->resBytes - VARSTR_HEADER_SIZE) { // todo refactor - *(pData + realLen + VARSTR_HEADER_SIZE) = 0; - } - - pRes->length[columnIndex] = realLen; - } else { - assert(bytes == tDataTypes[type].bytes); - - pRes->tsrow[columnIndex] = isNull(pData, type) ? NULL : (unsigned char*)pData; - pRes->length[columnIndex] = bytes; - } - } -} - extern int32_t sentinel; extern SHashObj *tscVgroupMap; extern SHashObj *tscTableMetaInfo; diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 3f2a54fbdc..09b31e4b19 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -69,7 +69,8 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para return; } - tscDoQuery(pSql); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + executeQuery(pSql, pQueryInfo); } // TODO return the correct error code to client in tscQueueAsyncError @@ -179,7 +180,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) { tscFetchDatablockForSubquery(pSql); } else { - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } } @@ -193,8 +194,8 @@ static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOf tscProcessAsyncRetrieveImpl(param, tres, numOfRows, tscAsyncFetchRowsProxy); } -void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) { - SSqlObj *pSql = (SSqlObj *)taosa; +void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) { + SSqlObj *pSql = (SSqlObj *)tres; if (pSql == NULL || pSql->signature != pSql) { tscError("sql object is NULL"); tscQueueAsyncError(fp, param, TSDB_CODE_TSC_DISCONNECTED); @@ -206,18 +207,16 @@ void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) { // user-defined callback function is stored in fetchFp pSql->fetchFp = fp; - pSql->fp = tscAsyncFetchRowsProxy; + pSql->fp = tscAsyncFetchRowsProxy; + pSql->param = param; if (pRes->qId == 0) { - tscError("qhandle is NULL"); + tscError("qhandle is invalid"); pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE; - pSql->param = param; - tscAsyncResultOnError(pSql); return; } - pSql->param = param; tscResetForNextRetrieve(pRes); // handle the sub queries of join query @@ -255,8 +254,9 @@ void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) { if (pCmd->command != TSDB_SQL_RETRIEVE_LOCALMERGE && pCmd->command < TSDB_SQL_LOCAL) { pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; } - - tscProcessSql(pSql); + + SQueryInfo* pQueryInfo1 = tscGetActiveQueryInfo(&pSql->cmd); + tscBuildAndSendRequest(pSql, pQueryInfo1); } } @@ -323,7 +323,7 @@ static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableM SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); + SSqlExpr *pExpr = &(tscSqlExprGet(pQueryInfo, i)->base); pExpr->uid = pTableMetaInfo->pTableMeta->id.uid; if (pExpr->colInfo.colIndex >= 0) { @@ -344,7 +344,7 @@ static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableM // validate the table columns information for (int32_t i = 0; i < taosArrayGetSize(pQueryInfo->colList); ++i) { SColumn *pCol = taosArrayGetP(pQueryInfo->colList, i); - if (pCol->colIndex.columnIndex >= numOfCols) { + if (pCol->columnIndex >= numOfCols) { return pSql->retryReason; } } @@ -374,7 +374,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { tscDebug("0x%"PRIx64" get %s successfully", pSql->self, msg); if (pSql->pStream == NULL) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); // 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))) { @@ -396,8 +396,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { goto _error; } - // tscProcessSql can add error into async res - tscProcessSql(pSql); + // tscBuildAndSendRequest can add error into async res + tscBuildAndSendRequest(pSql, NULL); taosReleaseRef(tscObjRef, pSql->self); return; } else { // continue to process normal async query @@ -428,9 +428,9 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { goto _error; } - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } else { // in all other cases, simple retry - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } taosReleaseRef(tscObjRef, pSql->self); @@ -447,21 +447,29 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { } if (pCmd->insertType == TSDB_QUERY_TYPE_STMT_INSERT) { - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); code = tscGetTableMeta(pSql, pTableMetaInfo); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { taosReleaseRef(tscObjRef, pSql->self); return; } else { - assert(code == TSDB_CODE_SUCCESS); + assert(code == TSDB_CODE_SUCCESS); } (*pSql->fp)(pSql->param, pSql, code); - taosReleaseRef(tscObjRef, pSql->self); - return; + } else if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) { + if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) { + tscImportDataFromFile(pSql); + } else { + tscHandleMultivnodeInsert(pSql); + } + } else { + SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + executeQuery(pSql, pQueryInfo1); } - // proceed to invoke the tscDoQuery(); + taosReleaseRef(tscObjRef, pSql->self); + return; } } @@ -498,7 +506,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { return; } - tscDoQuery(pSql); +// tscDoQuery(pSql); taosReleaseRef(tscObjRef, pSql->self); diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index f88f6546f9..a7882ffa61 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -53,7 +53,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { SSqlRes *pRes = &pSql->res; // one column for each row - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -154,14 +154,14 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, pSql->cmd.numOfCols = numOfCols; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); 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->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false); rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE); @@ -171,7 +171,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Type", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), -1000, typeColLength, false); rowLen += typeColLength + VARSTR_HEADER_SIZE; @@ -181,7 +181,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Length", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), -1000, sizeof(int32_t), false); rowLen += sizeof(int32_t); @@ -191,7 +191,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Note", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), -1000, noteColLength, false); rowLen += noteColLength + VARSTR_HEADER_SIZE; @@ -199,7 +199,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, } static int32_t tscProcessDescribeTable(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL); @@ -389,7 +389,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const SColumnIndex index = {0}; pSql->cmd.numOfCols = 2; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); pQueryInfo->order.order = TSDB_ORDER_ASC; TAOS_FIELD f; @@ -404,7 +404,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); rowLen += f.bytes; @@ -417,7 +417,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false); rowLen += ddlLen + VARSTR_HEADER_SIZE; @@ -427,7 +427,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) { SSqlRes *pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); int32_t numOfRows = 1; if (strlen(ddl) == 0) { @@ -444,7 +444,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 = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result); tscFieldInfoUpdateOffset(pQueryInfo); @@ -552,7 +552,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 = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -606,7 +606,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch } static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -633,7 +633,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 = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -674,7 +674,7 @@ static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, } static int32_t tscProcessShowCreateTable(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); assert(pTableMetaInfo->pTableMeta != NULL); @@ -700,7 +700,7 @@ static int32_t tscProcessShowCreateTable(SSqlObj *pSql) { } static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -727,7 +727,7 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { return TSDB_CODE_TSC_ACTION_IN_PROGRESS; } static int32_t tscProcessCurrentUser(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resBytes = TSDB_USER_LEN + TSDB_DATA_TYPE_BINARY; @@ -754,7 +754,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) { extractDBName(pSql->pTscObj->db, db); pthread_mutex_unlock(&pSql->pTscObj->mutex); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resType = TSDB_DATA_TYPE_BINARY; @@ -781,7 +781,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) { static int32_t tscProcessServerVer(SSqlObj *pSql) { const char* v = pSql->pTscObj->sversion; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resType = TSDB_DATA_TYPE_BINARY; @@ -804,7 +804,7 @@ static int32_t tscProcessServerVer(SSqlObj *pSql) { } static int32_t tscProcessClientVer(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resType = TSDB_DATA_TYPE_BINARY; @@ -856,7 +856,7 @@ static int32_t tscProcessServStatus(SSqlObj *pSql) { return pSql->res.code; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); int32_t val = 1; @@ -870,7 +870,7 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa pCmd->numOfCols = 1; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); pQueryInfo->order.order = TSDB_ORDER_ASC; tscFieldInfoClear(&pQueryInfo->fieldsInfo); @@ -882,7 +882,7 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa tscInitResObjForLocalQuery(pSql, 1, (int32_t)valueLength); SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, 0); - pInfo->pSqlExpr = taosArrayGetP(pQueryInfo->exprList, 0); + pInfo->pExpr = taosArrayGetP(pQueryInfo->exprList, 0); memcpy(pRes->data, val, pInfo->field.bytes); } diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c index 97d52cc684..e4a3ace6b5 100644 --- a/src/client/src/tscLocalMerge.c +++ b/src/client/src/tscLocalMerge.c @@ -31,6 +31,8 @@ typedef struct SCompareParam { int32_t groupOrderType; } SCompareParam; +bool needToMergeRv(SSDataBlock* pBlock, SArray* columnIndex, int32_t index, char **buf); + int32_t treeComparator(const void *pLeft, const void *pRight, void *param) { int32_t pLeftIdx = *(int32_t *)pLeft; int32_t pRightIdx = *(int32_t *)pRight; @@ -57,121 +59,55 @@ int32_t treeComparator(const void *pLeft, const void *pRight, void *param) { } } -static void tscInitSqlContext(SSqlCmd *pCmd, SLocalMerger *pReducer, tOrderDescriptor *pDesc) { - /* - * the fields and offset attributes in pCmd and pModel may be different due to - * merge requirement. So, the final result in pRes structure is formatted in accordance with the pCmd object. - */ - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); +// 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) { - SQLFunctionCtx *pCtx = &pReducer->pCtx[i]; - SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); - pCtx->pOutput = pReducer->pResultBuf->data + pExpr->offset * pReducer->resColModel->capacity; - pCtx->order = pQueryInfo->order.order; - pCtx->functionId = pExpr->functionId; + pCtx[i].order = pQueryInfo->order.order; + pCtx[i].functionId = pExpr->base.functionId; - // input buffer hold only one point data - int16_t offset = getColumnModelOffset(pDesc->pColumnModel, i); - SSchema *pSchema = getColumnModelSchema(pDesc->pColumnModel, i); - - pCtx->pInput = pReducer->pTempBuffer->data + offset; + pCtx[i].order = pQueryInfo->order.order; + pCtx[i].functionId = pExpr->base.functionId; // input data format comes from pModel - pCtx->inputType = pSchema->type; - pCtx->inputBytes = pSchema->bytes; + pCtx[i].inputType = pSchema[i].type; + pCtx[i].inputBytes = pSchema[i].bytes; - // output data format yet comes from pCmd. - pCtx->outputBytes = pExpr->resBytes; - pCtx->outputType = pExpr->resType; + pCtx[i].outputBytes = pExpr->base.resBytes; + pCtx[i].outputType = pExpr->base.resType; - pCtx->size = 1; - pCtx->hasNull = true; - pCtx->currentStage = MERGE_STAGE; + // 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->functionId; + int32_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) { - pCtx->ptsOutputBuf = pReducer->pCtx[0].pOutput; - pCtx->param[2].i64 = pQueryInfo->order.order; - pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT; - pCtx->param[1].i64 = pQueryInfo->order.orderColId; + 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->param[0].i64 = pExpr->param[0].i64; - pCtx->param[0].nType = pExpr->param[0].nType; + 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->param[0].i64 = pExpr->param[0].i64; - pCtx->param[0].nType = pExpr->param[0].nType; - pCtx->numOfParams = 1; + 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->interBufBytes = pExpr->interBytes; - pCtx->resultInfo = calloc(1, pCtx->interBufBytes + sizeof(SResultRowCellInfo)); - pCtx->stableQuery = true; + pCtx[i].interBufBytes = pExpr->base.interBytes; + pCtx[i].stableQuery = true; } - - int16_t n = 0; - int16_t tagLen = 0; - SQLFunctionCtx **pTagCtx = calloc(pQueryInfo->fieldsInfo.numOfOutput, POINTER_BYTES); - - SQLFunctionCtx *pCtx = NULL; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TAG_DUMMY || pExpr->functionId == TSDB_FUNC_TS_DUMMY) { - tagLen += pExpr->resBytes; - pTagCtx[n++] = &pReducer->pCtx[i]; - } else if ((aAggs[pExpr->functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) { - pCtx = &pReducer->pCtx[i]; - } - } - - if (n == 0 || pCtx == NULL) { - free(pTagCtx); - } else { - pCtx->tagInfo.pTagCtxList = pTagCtx; - pCtx->tagInfo.numOfTagCols = n; - pCtx->tagInfo.tagsLen = tagLen; - } -} - -static SFillColInfo* createFillColInfo(SQueryInfo* pQueryInfo) { - int32_t numOfCols = (int32_t)tscNumOfFields(pQueryInfo); - int32_t offset = 0; - - SFillColInfo* pFillCol = calloc(numOfCols, sizeof(SFillColInfo)); - for(int32_t i = 0; i < numOfCols; ++i) { - SInternalField* pIField = taosArrayGet(pQueryInfo->fieldsInfo.internalField, i); - - if (pIField->pArithExprInfo == NULL) { - SSqlExpr* pExpr = pIField->pSqlExpr; - - pFillCol[i].col.bytes = pExpr->resBytes; - pFillCol[i].col.type = (int8_t)pExpr->resType; - pFillCol[i].col.colId = pExpr->colInfo.colId; - pFillCol[i].flag = pExpr->colInfo.flag; - pFillCol[i].col.offset = offset; - pFillCol[i].functionId = pExpr->functionId; - pFillCol[i].fillVal.i = pQueryInfo->fillVal[i]; - } else { - pFillCol[i].col.bytes = pIField->field.bytes; - pFillCol[i].col.type = (int8_t)pIField->field.type; - pFillCol[i].col.colId = -100; - pFillCol[i].flag = TSDB_COL_NORMAL; - pFillCol[i].col.offset = offset; - pFillCol[i].functionId = -1; - pFillCol[i].fillVal.i = pQueryInfo->fillVal[i]; - } - - offset += pFillCol[i].col.bytes; - } - - return pFillCol; } void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc, - SColumnModel *finalmodel, SColumnModel *pFFModel, SSqlObj* pSql) { + SColumnModel *finalmodel, SColumnModel *pFFModel, SSqlObj *pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; @@ -218,8 +154,8 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde size_t size = sizeof(SLocalMerger) + POINTER_BYTES * numOfFlush; - SLocalMerger *pReducer = (SLocalMerger *) calloc(1, size); - if (pReducer == NULL) { + SLocalMerger *pMerger = (SLocalMerger *) calloc(1, size); + if (pMerger == NULL) { tscError("0x%"PRIx64" failed to create local merge structure, out of memory", pSql->self); tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); @@ -227,15 +163,15 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde return; } - pReducer->pExtMemBuffer = pMemBuffer; - pReducer->pLocalDataSrc = (SLocalDataSource **)&pReducer[1]; - assert(pReducer->pLocalDataSrc != NULL); + pMerger->pExtMemBuffer = pMemBuffer; + pMerger->pLocalDataSrc = (SLocalDataSource **)&pMerger[1]; + assert(pMerger->pLocalDataSrc != NULL); - pReducer->numOfBuffer = numOfFlush; - pReducer->numOfVnode = numOfBuffer; + pMerger->numOfBuffer = numOfFlush; + pMerger->numOfVnode = numOfBuffer; - pReducer->pDesc = pDesc; - tscDebug("0x%"PRIx64" the number of merged leaves is: %d", pSql->self, pReducer->numOfBuffer); + pMerger->pDesc = pDesc; + tscDebug("0x%"PRIx64" the number of merged leaves is: %d", pSql->self, pMerger->numOfBuffer); int32_t idx = 0; for (int32_t i = 0; i < numOfBuffer; ++i) { @@ -246,11 +182,11 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde if (ds == NULL) { tscError("0x%"PRIx64" failed to create merge structure", pSql->self); pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - tfree(pReducer); + tfree(pMerger); return; } - pReducer->pLocalDataSrc[idx] = ds; + pMerger->pLocalDataSrc[idx] = ds; ds->pMemBuffer = pMemBuffer[i]; ds->flushoutIdx = j; @@ -263,7 +199,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde #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 = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); tscGetSrcColumnInfo(colInfo, pQueryInfo); @@ -283,99 +219,92 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde // no data actually, no need to merge result. if (idx == 0) { - tfree(pReducer); + tfree(pMerger); return; } - pReducer->numOfBuffer = idx; + pMerger->numOfBuffer = idx; SCompareParam *param = malloc(sizeof(SCompareParam)); if (param == NULL) { - tfree(pReducer); + tfree(pMerger); return; } - param->pLocalData = pReducer->pLocalDataSrc; - param->pDesc = pReducer->pDesc; - param->num = pReducer->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + param->pLocalData = pMerger->pLocalDataSrc; + param->pDesc = pMerger->pDesc; + param->num = pMerger->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage; + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); param->groupOrderType = pQueryInfo->groupbyExpr.orderType; - pReducer->orderPrjOnSTable = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0); + pMerger->orderPrjOnSTable = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0); - pRes->code = tLoserTreeCreate(&pReducer->pLoserTree, pReducer->numOfBuffer, param, treeComparator); - if (pReducer->pLoserTree == NULL || pRes->code != 0) { + pRes->code = tLoserTreeCreate(&pMerger->pLoserTree, pMerger->numOfBuffer, param, treeComparator); + if (pMerger->pLoserTree == NULL || pRes->code != 0) { tfree(param); - tfree(pReducer); + 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 - pReducer->pCtx = (SQLFunctionCtx *)calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SQLFunctionCtx)); - pReducer->rowSize = pMemBuffer[0]->nElemSize; + pMerger->pCtx = (SQLFunctionCtx *)calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SQLFunctionCtx)); + pMerger->rowSize = pMemBuffer[0]->nElemSize; - tscRestoreFuncForSTableQuery(pQueryInfo); tscFieldInfoUpdateOffset(pQueryInfo); - if (pReducer->rowSize > pMemBuffer[0]->pageSize) { + if (pMerger->rowSize > pMemBuffer[0]->pageSize) { assert(false); // todo fixed row size is larger than the minimum page size; } - pReducer->hasPrevRow = false; - pReducer->hasUnprocessedRow = false; - - pReducer->prevRowOfInput = (char *)calloc(1, pReducer->rowSize); - // used to keep the latest input row - pReducer->pTempBuffer = (tFilePage *)calloc(1, pReducer->rowSize + sizeof(tFilePage)); - pReducer->discardData = (tFilePage *)calloc(1, pReducer->rowSize + sizeof(tFilePage)); - pReducer->discard = false; + pMerger->pTempBuffer = (tFilePage *)calloc(1, pMerger->rowSize + sizeof(tFilePage)); - pReducer->nResultBufSize = pMemBuffer[0]->pageSize * 16; - pReducer->pResultBuf = (tFilePage *)calloc(1, pReducer->nResultBufSize + sizeof(tFilePage)); + pMerger->nResultBufSize = pMemBuffer[0]->pageSize * 16; + pMerger->pResultBuf = (tFilePage *)calloc(1, pMerger->nResultBufSize + sizeof(tFilePage)); - pReducer->resColModel = finalmodel; - pReducer->resColModel->capacity = pReducer->nResultBufSize; - pReducer->finalModel = pFFModel; + pMerger->resColModel = finalmodel; + pMerger->resColModel->capacity = pMerger->nResultBufSize; + pMerger->finalModel = pFFModel; - int32_t expandFactor = 1; if (finalmodel->rowSize > 0) { - bool topBotQuery = tscIsTopbotQuery(pQueryInfo); - if (topBotQuery) { - expandFactor = tscGetTopbotQueryParam(pQueryInfo); - pReducer->resColModel->capacity /= (finalmodel->rowSize * expandFactor); - pReducer->resColModel->capacity *= expandFactor; - } else { - pReducer->resColModel->capacity /= finalmodel->rowSize; - } + pMerger->resColModel->capacity /= finalmodel->rowSize; } - assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pReducer->rowSize); + assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pMerger->rowSize); - pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity); - - if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL || - pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) { - tfree(pReducer->pTempBuffer); - tfree(pReducer->discardData); - tfree(pReducer->pResultBuf); - tfree(pReducer->pFinalRes); - tfree(pReducer->prevRowOfInput); - tfree(pReducer->pLoserTree); + if (pMerger->pTempBuffer == NULL || pMerger->pLoserTree == NULL) { + tfree(pMerger->pTempBuffer); + tfree(pMerger->pLoserTree); tfree(param); - tfree(pReducer); + tfree(pMerger); pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; return; } - pReducer->pTempBuffer->num = 0; - + pMerger->pTempBuffer->num = 0; tscCreateResPointerInfo(pRes, pQueryInfo); - tscInitSqlContext(pCmd, pReducer, pDesc); + + 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; + } + } // we change the capacity of schema to denote that there is only one row in temp buffer - pReducer->pDesc->pColumnModel->capacity = 1; + pMerger->pDesc->pColumnModel->capacity = 1; // restore the limitation value at the last stage if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { @@ -383,23 +312,22 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde pQueryInfo->limit.offset = pQueryInfo->prjOffset; } - pReducer->offset = (int32_t)pQueryInfo->limit.offset; - - pRes->pLocalMerger = pReducer; + pRes->pLocalMerger = pMerger; pRes->numOfGroups = 0; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); +// 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); +// 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); - pReducer->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); - } +// 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); +// } } static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, @@ -500,62 +428,34 @@ void tscDestroyLocalMerger(SSqlObj *pSql) { return; } - SSqlCmd * pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - // there is no more result, so we release all allocated resource SLocalMerger *pLocalMerge = (SLocalMerger *)atomic_exchange_ptr(&pRes->pLocalMerger, NULL); - if (pLocalMerge != NULL) { - pLocalMerge->pFillInfo = taosDestroyFillInfo(pLocalMerge->pFillInfo); + tfree(pLocalMerge->pResultBuf); + tfree(pLocalMerge->pCtx); - if (pLocalMerge->pCtx != NULL) { - int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t i = 0; i < numOfExprs; ++i) { - SQLFunctionCtx *pCtx = &pLocalMerge->pCtx[i]; - - tVariantDestroy(&pCtx->tag); - tfree(pCtx->resultInfo); - - if (pCtx->tagInfo.pTagCtxList != NULL) { - tfree(pCtx->tagInfo.pTagCtxList); - } - } - - tfree(pLocalMerge->pCtx); - } - - tfree(pLocalMerge->prevRowOfInput); - - tfree(pLocalMerge->pTempBuffer); - tfree(pLocalMerge->pResultBuf); - - if (pLocalMerge->pLoserTree) { - tfree(pLocalMerge->pLoserTree->param); - tfree(pLocalMerge->pLoserTree); - } - - tfree(pLocalMerge->pFinalRes); - tfree(pLocalMerge->discardData); - - tscLocalReducerEnvDestroy(pLocalMerge->pExtMemBuffer, pLocalMerge->pDesc, pLocalMerge->resColModel, pLocalMerge->finalModel, - pLocalMerge->numOfVnode); - for (int32_t i = 0; i < pLocalMerge->numOfBuffer; ++i) { - tfree(pLocalMerge->pLocalDataSrc[i]); - } - - pLocalMerge->numOfBuffer = 0; - pLocalMerge->numOfCompleted = 0; - free(pLocalMerge); - } else { - tscDebug("0x%"PRIx64" already freed or another free function is invoked", pSql->self); + if (pLocalMerge->pLoserTree) { + tfree(pLocalMerge->pLoserTree->param); + tfree(pLocalMerge->pLoserTree); } + tscLocalReducerEnvDestroy(pLocalMerge->pExtMemBuffer, pLocalMerge->pDesc, pLocalMerge->resColModel, + pLocalMerge->finalModel, pLocalMerge->numOfVnode); + for (int32_t i = 0; i < pLocalMerge->numOfBuffer; ++i) { + tfree(pLocalMerge->pLocalDataSrc[i]); + } + + pLocalMerge->numOfBuffer = 0; + pLocalMerge->numOfCompleted = 0; + tfree(pLocalMerge->pTempBuffer); + + free(pLocalMerge); + tscDebug("0x%"PRIx64" free local reducer finished", pSql->self); } static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, SColumnModel *pModel) { int32_t numOfGroupByCols = 0; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { numOfGroupByCols = pQueryInfo->groupbyExpr.numOfGroupCols; @@ -575,11 +475,19 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { int32_t numOfInternalOutput = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); - int32_t startCols = numOfInternalOutput - pQueryInfo->groupbyExpr.numOfGroupCols; // the last "pQueryInfo->groupbyExpr.numOfGroupCols" columns are order-by columns for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) { - orderColIndexList[i] = startCols++; + SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i); + for(int32_t j = 0; j < numOfInternalOutput; ++j) { + SExprInfo* pExprInfo = tscSqlExprGet(pQueryInfo, j); + + int32_t functionId = pExprInfo->base.functionId; + if (pColIndex->colId == pExprInfo->base.colInfo.colId && (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG)) { + orderColIndexList[i] = j; + break; + } + } } if (pQueryInfo->interval.interval != 0) { @@ -596,8 +504,8 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm } else { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { orderColIndexList[0] = i; } } @@ -617,49 +525,6 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm } } -bool isSameGroup(SSqlCmd *pCmd, SLocalMerger *pReducer, char *pPrev, tFilePage *tmpBuffer) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - // disable merge procedure for column projection query - int16_t functionId = pReducer->pCtx[0].functionId; - if (pReducer->orderPrjOnSTable) { - return true; - } - - if (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_ARITHM) { - return false; - } - - tOrderDescriptor *pOrderDesc = pReducer->pDesc; - SColumnOrderInfo* orderInfo = &pOrderDesc->orderInfo; - - // no group by columns, all data belongs to one group - int32_t numOfCols = orderInfo->numOfCols; - if (numOfCols <= 0) { - return true; - } - - if (orderInfo->colIndex[numOfCols - 1] == PRIMARYKEY_TIMESTAMP_COL_INDEX) { - /* - * super table interval query - * if the order columns is the primary timestamp, all result data belongs to one group - */ - assert(pQueryInfo->interval.interval > 0); - if (numOfCols == 1) { - return true; - } - } else { // simple group by query - assert(pQueryInfo->interval.interval == 0); - } - - // only one row exists - int32_t index = orderInfo->colIndex[0]; - int32_t offset = (pOrderDesc->pColumnModel)->pFields[index].offset; - - int32_t ret = memcmp(pPrev + offset, tmpBuffer->data + offset, pOrderDesc->pColumnModel->rowSize - offset); - return ret == 0; -} - int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc, SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSizes) { SSqlCmd *pCmd = &pSql->cmd; @@ -669,7 +534,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr SColumnModel *pModel = NULL; *pFinalModel = NULL; - SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo * pQueryInfo = tscGetActiveQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); (*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pSql->subState.numOfSub); @@ -690,13 +555,13 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr int32_t rlen = 0; for (int32_t i = 0; i < size; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); - pSchema[i].bytes = pExpr->resBytes; - pSchema[i].type = (int8_t)pExpr->resType; - tstrncpy(pSchema[i].name, pExpr->aliasName, tListLen(pSchema[i].name)); + pSchema[i].bytes = pExpr->base.resBytes; + pSchema[i].type = (int8_t)pExpr->base.resType; + tstrncpy(pSchema[i].name, pExpr->base.aliasName, tListLen(pSchema[i].name)); - rlen += pExpr->resBytes; + rlen += pExpr->base.resBytes; } int32_t capacity = 0; @@ -729,17 +594,17 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr memset(pSchema, 0, sizeof(SSchema) * size); for (int32_t i = 0; i < size; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); SSchema p1 = {0}; - if (pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { p1 = *tGetTbnameColumnSchema(); - } else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) { - p1.bytes = pExpr->resBytes; - p1.type = (uint8_t) pExpr->resType; - tstrncpy(p1.name, pExpr->aliasName, tListLen(p1.name)); + } 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->colInfo.colIndex); + p1 = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex); } int32_t inter = 0; @@ -748,7 +613,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr // 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->functionId; + 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; @@ -875,834 +740,143 @@ void adjustLoserTreeFromNewData(SLocalMerger *pLocalMerge, SLocalDataSource *pOn } } -void savePrevRecordAndSetupFillInfo(SLocalMerger *pLocalMerge, SQueryInfo *pQueryInfo, SFillInfo *pFillInfo) { - // discard following dataset in the same group and reset the interpolation information - STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); +//TODO it is not ordered, fix it +static void savePrevOrderColumns(char** prevRow, SArray* pColumnList, SSDataBlock* pBlock, int32_t rowIndex, bool* hasPrev) { + int32_t size = (int32_t) taosArrayGetSize(pColumnList); - STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); + for(int32_t i = 0; i < size; ++i) { + SColIndex* index = taosArrayGet(pColumnList, i); + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, index->colIndex); + assert(index->colId == pColInfo->info.colId); - if (pFillInfo != NULL) { - int64_t stime = (pQueryInfo->window.skey < pQueryInfo->window.ekey) ? pQueryInfo->window.skey : pQueryInfo->window.ekey; - int64_t revisedSTime = taosTimeTruncate(stime, &pQueryInfo->interval, tinfo.precision); - - taosResetFillInfo(pFillInfo, revisedSTime); + memcpy(prevRow[i], pColInfo->pData + pColInfo->info.bytes * rowIndex, pColInfo->info.bytes); } - pLocalMerge->discard = true; - pLocalMerge->discardData->num = 0; - - SColumnModel *pModel = pLocalMerge->pDesc->pColumnModel; - tColModelAppend(pModel, pLocalMerge->discardData, pLocalMerge->prevRowOfInput, 0, 1, 1); + (*hasPrev) = true; } -static void genFinalResWithoutFill(SSqlRes* pRes, SLocalMerger *pLocalMerge, SQueryInfo* pQueryInfo) { - assert(pQueryInfo->interval.interval == 0 || pQueryInfo->fillType == TSDB_FILL_NONE); - - tFilePage * pBeforeFillData = pLocalMerge->pResultBuf; - - pRes->data = pLocalMerge->pFinalRes; - pRes->numOfRows = (int32_t) pBeforeFillData->num; - - if (pQueryInfo->limit.offset > 0) { - if (pQueryInfo->limit.offset < pRes->numOfRows) { - int32_t prevSize = (int32_t) pBeforeFillData->num; - tColModelErase(pLocalMerge->finalModel, pBeforeFillData, prevSize, 0, (int32_t)pQueryInfo->limit.offset - 1); - - /* remove the hole in column model */ - tColModelCompact(pLocalMerge->finalModel, pBeforeFillData, prevSize); - - pRes->numOfRows -= (int32_t) pQueryInfo->limit.offset; - pQueryInfo->limit.offset = 0; - } else { - pQueryInfo->limit.offset -= pRes->numOfRows; - pRes->numOfRows = 0; - } +static void setTagValueForMultipleRows(SQLFunctionCtx* pCtx, int32_t numOfOutput, int32_t numOfRows) { + if (numOfRows <= 1) { + return ; } - if (pRes->numOfRowsGroup >= pQueryInfo->limit.limit && pQueryInfo->limit.limit > 0) { - pRes->numOfRows = 0; - pBeforeFillData->num = 0; - pLocalMerge->discard = true; - return; - } - - pRes->numOfRowsGroup += pRes->numOfRows; - - // impose the limitation of output rows on the final result - if (pQueryInfo->limit.limit >= 0 && pRes->numOfRowsGroup > pQueryInfo->limit.limit) { - int32_t prevSize = (int32_t)pBeforeFillData->num; - int32_t overflow = (int32_t)(pRes->numOfRowsGroup - pQueryInfo->limit.limit); - assert(overflow < pRes->numOfRows); - - pRes->numOfRowsGroup = pQueryInfo->limit.limit; - pRes->numOfRows -= overflow; - pBeforeFillData->num -= overflow; - - tColModelCompact(pLocalMerge->finalModel, pBeforeFillData, prevSize); - - // set remain data to be discarded, and reset the interpolation information - savePrevRecordAndSetupFillInfo(pLocalMerge, pQueryInfo, pLocalMerge->pFillInfo); - } - - memcpy(pRes->data, pBeforeFillData->data, (size_t)(pRes->numOfRows * pLocalMerge->finalModel->rowSize)); - - pRes->numOfClauseTotal += pRes->numOfRows; - pBeforeFillData->num = 0; -} - -/* - * Note: pRes->pLocalMerge may be null, due to the fact that "tscDestroyLocalMerger" is called - * by "interuptHandler" function in shell - */ -static void doFillResult(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool doneOutput) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - tFilePage *pBeforeFillData = pLocalMerge->pResultBuf; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - SFillInfo *pFillInfo = pLocalMerge->pFillInfo; - - // todo extract function - int64_t actualETime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.ekey: pQueryInfo->window.skey; - - void** pResPages = malloc(POINTER_BYTES * pQueryInfo->fieldsInfo.numOfOutput); - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i); - pResPages[i] = calloc(1, pField->bytes * pLocalMerge->resColModel->capacity); - } - - while (1) { - int64_t newRows = taosFillResultDataBlock(pFillInfo, pResPages, pLocalMerge->resColModel->capacity); - - if (pQueryInfo->limit.offset < newRows) { - newRows -= pQueryInfo->limit.offset; - - if (pQueryInfo->limit.offset > 0) { - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i); - memmove(pResPages[i], ((char*)pResPages[i]) + pField->bytes * pQueryInfo->limit.offset, - (size_t)(newRows * pField->bytes)); - } - } - - pRes->data = pLocalMerge->pFinalRes; - pRes->numOfRows = (int32_t) newRows; - - pQueryInfo->limit.offset = 0; - break; - } else { - pQueryInfo->limit.offset -= newRows; - pRes->numOfRows = 0; - - if (!taosFillHasMoreResults(pFillInfo)) { - if (!doneOutput) { // reduce procedure has not completed yet, but current results for fill are exhausted - break; - } - - // all output in current group are completed - int32_t totalRemainRows = (int32_t)getNumOfResultsAfterFillGap(pFillInfo, actualETime, pLocalMerge->resColModel->capacity); - if (totalRemainRows <= 0) { - break; - } - } - } - } - - if (pRes->numOfRows > 0) { - int32_t currentTotal = (int32_t)(pRes->numOfRowsGroup + pRes->numOfRows); - - if (pQueryInfo->limit.limit >= 0 && currentTotal > pQueryInfo->limit.limit) { - int32_t overflow = (int32_t)(currentTotal - pQueryInfo->limit.limit); - - pRes->numOfRows -= overflow; - assert(pRes->numOfRows >= 0); - - /* set remain data to be discarded, and reset the interpolation information */ - savePrevRecordAndSetupFillInfo(pLocalMerge, pQueryInfo, pFillInfo); - } - - int32_t offset = 0; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i); - memcpy(pRes->data + offset * pRes->numOfRows, pResPages[i], (size_t)(pField->bytes * pRes->numOfRows)); - offset += pField->bytes; - } - - pRes->numOfRowsGroup += pRes->numOfRows; - pRes->numOfClauseTotal += pRes->numOfRows; - } - - pBeforeFillData->num = 0; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - tfree(pResPages[i]); - } - - tfree(pResPages); -} - -static void savePreviousRow(SLocalMerger *pLocalMerge, tFilePage *tmpBuffer) { - SColumnModel *pColumnModel = pLocalMerge->pDesc->pColumnModel; - assert(pColumnModel->capacity == 1 && tmpBuffer->num == 1); - - // copy to previous temp buffer - for (int32_t i = 0; i < pColumnModel->numOfCols; ++i) { - SSchema *pSchema = getColumnModelSchema(pColumnModel, i); - int16_t offset = getColumnModelOffset(pColumnModel, i); - - memcpy(pLocalMerge->prevRowOfInput + offset, tmpBuffer->data + offset, pSchema->bytes); - } - - tmpBuffer->num = 0; - pLocalMerge->hasPrevRow = true; -} - -static void doExecuteFinalMerge(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, bool needInit) { - // the tag columns need to be set before all functions execution - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t j = 0; j < size; ++j) { - SQLFunctionCtx *pCtx = &pLocalMerge->pCtx[j]; - - // tags/tags_dummy function, the tag field of SQLFunctionCtx is from the input buffer - int32_t functionId = pCtx->functionId; - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS_DUMMY) { - tVariantDestroy(&pCtx->tag); - char* input = pCtx->pInput; - - if (pCtx->inputType == TSDB_DATA_TYPE_BINARY || pCtx->inputType == TSDB_DATA_TYPE_NCHAR) { - assert(varDataLen(input) <= pCtx->inputBytes); - tVariantCreateFromBinary(&pCtx->tag, varDataVal(input), varDataLen(input), pCtx->inputType); - } else { - tVariantCreateFromBinary(&pCtx->tag, input, pCtx->inputBytes, pCtx->inputType); - } - - } else if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, j); - pCtx->param[0].i64 = pExpr->param[0].i64; - } - - pCtx->currentStage = MERGE_STAGE; - - if (needInit) { - aAggs[pCtx->functionId].init(pCtx); - } - } - - for (int32_t j = 0; j < size; ++j) { - int32_t functionId = pLocalMerge->pCtx[j].functionId; - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + for (int32_t k = 0; k < numOfOutput; ++k) { + if (pCtx[k].functionId != TSDB_FUNC_TAG) { continue; } - aAggs[functionId].mergeFunc(&pLocalMerge->pCtx[j]); - } -} + int32_t inc = numOfRows - 1; // tsdb_func_tag function only produce one row of result + char* src = pCtx[k].pOutput; -static void handleUnprocessedRow(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, tFilePage *tmpBuffer) { - if (pLocalMerge->hasUnprocessedRow) { - pLocalMerge->hasUnprocessedRow = false; - doExecuteFinalMerge(pCmd, pLocalMerge, true); - savePreviousRow(pLocalMerge, tmpBuffer); - } -} - -static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx) { - int64_t maxOutput = 0; - - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t j = 0; j < size; ++j) { - /* - * ts, tag, tagprj function can not decide the output number of current query - * the number of output result is decided by main output - */ - int32_t functionId = pCtx[j].functionId; - if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG) { - continue; - } - - SResultRowCellInfo* pResInfo = GET_RES_INFO(&pCtx[j]); - if (maxOutput < pResInfo->numOfRes) { - maxOutput = pResInfo->numOfRes; - } - } - - return maxOutput; -} - -/* - * in handling the top/bottom query, which produce more than one rows result, - * the tsdb_func_tags only fill the first row of results, the remain rows need to - * filled with the same result, which is the tags, specified in group by clause - * - */ -static void fillMultiRowsOfTagsVal(SQueryInfo *pQueryInfo, int32_t numOfRes, SLocalMerger *pLocalMerge) { - int32_t maxBufSize = 0; // find the max tags column length to prepare the buffer - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - - for (int32_t k = 0; k < size; ++k) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k); - if (maxBufSize < pExpr->resBytes && pExpr->functionId == TSDB_FUNC_TAG) { - maxBufSize = pExpr->resBytes; - } - } - - assert(maxBufSize >= 0); - - char *buf = malloc((size_t)maxBufSize); - for (int32_t k = 0; k < size; ++k) { - SQLFunctionCtx *pCtx = &pLocalMerge->pCtx[k]; - if (pCtx->functionId != TSDB_FUNC_TAG) { - continue; - } - - int32_t inc = numOfRes - 1; // tsdb_func_tag function only produce one row of result - memset(buf, 0, (size_t)maxBufSize); - memcpy(buf, pCtx->pOutput, (size_t)pCtx->outputBytes); - - char* next = pCtx->pOutput; for (int32_t i = 0; i < inc; ++i) { - next += pCtx->outputBytes; - memcpy(next, buf, (size_t)pCtx->outputBytes); + pCtx[k].pOutput += pCtx[k].outputBytes; + memcpy(pCtx[k].pOutput, src, (size_t)pCtx[k].outputBytes); } } - - free(buf); } -int32_t finalizeRes(SQueryInfo *pQueryInfo, SLocalMerger *pLocalMerge) { - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - - for (int32_t k = 0; k < size; ++k) { - SQLFunctionCtx* pCtx = &pLocalMerge->pCtx[k]; - aAggs[pCtx->functionId].xFinalize(pCtx); +static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) { + SMultiwayMergeInfo* pInfo = pOperator->info; + SQLFunctionCtx* pCtx = pInfo->binfo.pCtx; + + char** add = calloc(pBlock->info.numOfCols, POINTER_BYTES); + for(int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + add[i] = pCtx[i].pInput; + pCtx[i].size = 1; } - pLocalMerge->hasPrevRow = false; + for(int32_t i = 0; i < pBlock->info.rows; ++i) { + if (pInfo->hasPrev) { + if (needToMergeRv(pBlock, pInfo->orderColumnList, i, pInfo->prevRow)) { + for (int32_t j = 0; j < numOfExpr; ++j) { + pCtx[j].pInput = add[j] + pCtx[j].inputBytes * i; + } - int32_t numOfRes = (int32_t)getNumOfResultLocal(pQueryInfo, pLocalMerge->pCtx); - pLocalMerge->pResultBuf->num += numOfRes; - - fillMultiRowsOfTagsVal(pQueryInfo, numOfRes, pLocalMerge); - return numOfRes; -} - -/* - * points merge: - * points are merged according to the sort info, which is tags columns and timestamp column. - * In case of points without either tags columns or timestamp, such as - * results generated by simple aggregation function, we merge them all into one points - * *Exception*: column projection query, required no merge procedure - */ -bool needToMerge(SQueryInfo *pQueryInfo, SLocalMerger *pLocalMerge, tFilePage *tmpBuffer) { - int32_t ret = 0; // merge all result by default - - int16_t functionId = pLocalMerge->pCtx[0].functionId; - - // todo opt performance - if ((/*functionId == TSDB_FUNC_PRJ || */functionId == TSDB_FUNC_ARITHM) || (tscIsProjectionQueryOnSTable(pQueryInfo, 0) && pQueryInfo->distinctTag == false)) { // column projection query - ret = 1; // disable merge procedure - } else { - tOrderDescriptor *pDesc = pLocalMerge->pDesc; - if (pDesc->orderInfo.numOfCols > 0) { - if (pDesc->tsOrder == TSDB_ORDER_ASC) { // asc - // todo refactor comparator - ret = compare_a(pLocalMerge->pDesc, 1, 0, pLocalMerge->prevRowOfInput, 1, 0, tmpBuffer->data); - } else { // desc - ret = compare_d(pLocalMerge->pDesc, 1, 0, pLocalMerge->prevRowOfInput, 1, 0, tmpBuffer->data); - } - } - } - - /* if ret == 0, means the result belongs to the same group */ - return (ret == 0); -} - -static bool reachGroupResultLimit(SQueryInfo *pQueryInfo, SSqlRes *pRes) { - return (pRes->numOfGroups >= pQueryInfo->slimit.limit && pQueryInfo->slimit.limit >= 0); -} - -static bool saveGroupResultInfo(SSqlObj *pSql) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - if (pRes->numOfRowsGroup > 0) { - pRes->numOfGroups += 1; - } - - // the output group is limited by the slimit clause - if (reachGroupResultLimit(pQueryInfo, pRes)) { - return true; - } - - // pRes->pGroupRec = realloc(pRes->pGroupRec, pRes->numOfGroups*sizeof(SResRec)); - // pRes->pGroupRec[pRes->numOfGroups-1].numOfRows = pRes->numOfRows; - // pRes->pGroupRec[pRes->numOfGroups-1].numOfClauseTotal = pRes->numOfClauseTotal; - - return false; -} - - -bool doFilterFieldData(char *input, SExprFilter* pFieldFilters, int16_t type, bool* notSkipped) { - bool qualified = false; - - for(int32_t k = 0; k < pFieldFilters->pFilters->numOfFilters; ++k) { - __filter_func_t fp = taosArrayGetP(pFieldFilters->fp, k); - SColumnFilterElem filterElem = {.filterInfo = pFieldFilters->pFilters->filterInfo[k]}; - - bool isnull = isNull(input, type); - if (isnull) { - if (fp == isNullOperator) { - qualified = true; - break; + for (int32_t j = 0; j < numOfExpr; ++j) { + int32_t functionId = pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + aAggs[functionId].mergeFunc(&pCtx[j]); + } } else { - continue; + for(int32_t j = 0; j < numOfExpr; ++j) { // TODO refactor + int32_t functionId = pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + aAggs[functionId].xFinalize(&pCtx[j]); + } + + int32_t numOfRows = getNumOfResult(pOperator->pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput); + setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows); + + pInfo->binfo.pRes->info.rows += numOfRows; + + for(int32_t j = 0; j < numOfExpr; ++j) { + pCtx[j].pOutput += (pCtx[j].outputBytes * numOfRows); + if (pCtx[j].functionId == TSDB_FUNC_TOP || pCtx[j].functionId == TSDB_FUNC_BOTTOM) { + pCtx[j].ptsOutputBuf = pCtx[0].pOutput; + } + } + + for(int32_t j = 0; j < numOfExpr; ++j) { + aAggs[pCtx[j].functionId].init(&pCtx[j]); + } + + for (int32_t j = 0; j < numOfExpr; ++j) { + pCtx[j].pInput = add[j] + pCtx[j].inputBytes * i; + } + + for (int32_t j = 0; j < numOfExpr; ++j) { + int32_t functionId = pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + aAggs[functionId].mergeFunc(&pCtx[j]); + } } } else { - if (fp == notNullOperator) { - qualified = true; - break; - } else if (fp == isNullOperator) { - continue; + for (int32_t j = 0; j < numOfExpr; ++j) { + pCtx[j].pInput = add[j] + pCtx[j].inputBytes * i; + } + + for (int32_t j = 0; j < numOfExpr; ++j) { + int32_t functionId = pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + aAggs[functionId].mergeFunc(&pCtx[j]); } } - if (fp(&filterElem, input, input, type)) { - qualified = true; - break; + savePrevOrderColumns(pInfo->prevRow, pInfo->orderColumnList, pBlock, i, &pInfo->hasPrev); + } + + { + for(int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + pCtx[i].pInput = add[i]; } } - *notSkipped = qualified; - - return TSDB_CODE_SUCCESS; + tfree(add); } - -int32_t doHavingFilter(SQueryInfo* pQueryInfo, tFilePage* pOutput, bool* notSkipped) { - *notSkipped = true; - - if (pQueryInfo->havingFieldNum <= 0) { - return TSDB_CODE_SUCCESS; +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); } - //int32_t exprNum = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); - - size_t numOfOutput = tscNumOfFields(pQueryInfo); - for(int32_t i = 0; i < numOfOutput; ++i) { - SInternalField* pInterField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i); - SExprFilter* pFieldFilters = pInterField->pFieldFilters; - - if (pFieldFilters == NULL) { - continue; - } - - int32_t type = pInterField->field.type; - - char* pInput = pOutput->data + pOutput->num* pFieldFilters->pSqlExpr->offset; - - doFilterFieldData(pInput, pFieldFilters, type, notSkipped); - if (*notSkipped == false) { - return TSDB_CODE_SUCCESS; - } - } - - return TSDB_CODE_SUCCESS; -} - - - -/** - * - * @param pSql - * @param pLocalMerge - * @param noMoreCurrentGroupRes - * @return if current group is skipped, return false, and do NOT record it into pRes->numOfGroups - */ -bool genFinalResults(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool noMoreCurrentGroupRes) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - tFilePage * pResBuf = pLocalMerge->pResultBuf; - SColumnModel *pModel = pLocalMerge->resColModel; - - pRes->code = TSDB_CODE_SUCCESS; - - /* - * Ignore the output of the current group since this group is skipped by user - * We set the numOfRows to be 0 and discard the possible remain results. - */ - if (pQueryInfo->slimit.offset > 0) { - pRes->numOfRows = 0; - pQueryInfo->slimit.offset -= 1; - pLocalMerge->discard = !noMoreCurrentGroupRes; - - if (pLocalMerge->discard) { - SColumnModel *pInternModel = pLocalMerge->pDesc->pColumnModel; - tColModelAppend(pInternModel, pLocalMerge->discardData, pLocalMerge->pTempBuffer->data, 0, 1, 1); - } - - return false; - } - - tColModelCompact(pModel, pResBuf, pModel->capacity); - - if (tscIsSecondStageQuery(pQueryInfo)) { - doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalMerge->finalModel->rowSize); - } - - bool notSkipped = true; - - doHavingFilter(pQueryInfo, pResBuf, ¬Skipped); - - if (!notSkipped) { - pRes->numOfRows = 0; - pLocalMerge->discard = !noMoreCurrentGroupRes; - - if (pLocalMerge->discard) { - SColumnModel *pInternModel = pLocalMerge->pDesc->pColumnModel; - tColModelAppend(pInternModel, pLocalMerge->discardData, pLocalMerge->pTempBuffer->data, 0, 1, 1); - } - - return notSkipped; - } - - // no interval query, no fill operation - if (pQueryInfo->interval.interval == 0 || pQueryInfo->fillType == TSDB_FILL_NONE) { - genFinalResWithoutFill(pRes, pLocalMerge, pQueryInfo); - } else { - SFillInfo* pFillInfo = pLocalMerge->pFillInfo; - if (pFillInfo != NULL) { - TSKEY ekey = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.ekey: pQueryInfo->window.skey; - - taosFillSetStartInfo(pFillInfo, (int32_t)pResBuf->num, ekey); - taosFillCopyInputDataFromOneFilePage(pFillInfo, pResBuf); - } - - doFillResult(pSql, pLocalMerge, noMoreCurrentGroupRes); - } - - return true; -} - -void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalMerger *pLocalMerge) {// reset output buffer to the beginning - size_t t = tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t i = 0; i < t; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - pLocalMerge->pCtx[i].pOutput = pLocalMerge->pResultBuf->data + pExpr->offset * pLocalMerge->resColModel->capacity; - - if (pExpr->functionId == TSDB_FUNC_TOP || pExpr->functionId == TSDB_FUNC_BOTTOM || pExpr->functionId == TSDB_FUNC_DIFF) { - pLocalMerge->pCtx[i].ptsOutputBuf = pLocalMerge->pCtx[0].pOutput; - } - } - - memset(pLocalMerge->pResultBuf, 0, pLocalMerge->nResultBufSize + sizeof(tFilePage)); -} - -static void resetEnvForNewResultset(SSqlRes *pRes, SSqlCmd *pCmd, SLocalMerger *pLocalMerge) { - // In handling data in other groups, we need to reset the interpolation information for a new group data - pRes->numOfRows = 0; - pRes->numOfRowsGroup = 0; - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - pQueryInfo->limit.offset = pLocalMerge->offset; - - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - - // for group result interpolation, do not return if not data is generated - if (pQueryInfo->fillType != TSDB_FILL_NONE) { - TSKEY skey = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.skey:pQueryInfo->window.ekey;//MIN(pQueryInfo->window.skey, pQueryInfo->window.ekey); - int64_t newTime = taosTimeTruncate(skey, &pQueryInfo->interval, tinfo.precision); - taosResetFillInfo(pLocalMerge->pFillInfo, newTime); - } + // 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 doBuildFilledResultForGroup(SSqlObj *pSql) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - SLocalMerger *pLocalMerge = pRes->pLocalMerger; - SFillInfo *pFillInfo = pLocalMerge->pFillInfo; - - if (pFillInfo != NULL && taosFillHasMoreResults(pFillInfo)) { - assert(pQueryInfo->fillType != TSDB_FILL_NONE); - - tFilePage *pFinalDataBuf = pLocalMerge->pResultBuf; - int64_t etime = *(int64_t *)(pFinalDataBuf->data + TSDB_KEYSIZE * (pFillInfo->numOfRows - 1)); - - // the first column must be the timestamp column - int32_t rows = (int32_t) getNumOfResultsAfterFillGap(pFillInfo, etime, pLocalMerge->resColModel->capacity); - if (rows > 0) { // do fill gap - doFillResult(pSql, pLocalMerge, false); - } - - return true; - } else { - return false; - } -} - -static bool doHandleLastRemainData(SSqlObj *pSql) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SLocalMerger *pLocalMerge = pRes->pLocalMerger; - SFillInfo *pFillInfo = pLocalMerge->pFillInfo; - - bool prevGroupCompleted = (!pLocalMerge->discard) && pLocalMerge->hasUnprocessedRow; - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - if ((isAllSourcesCompleted(pLocalMerge) && !pLocalMerge->hasPrevRow) || pLocalMerge->pLocalDataSrc[0] == NULL || - prevGroupCompleted) { - // if fillType == TSDB_FILL_NONE, return directly - if (pQueryInfo->fillType != TSDB_FILL_NONE && - ((pRes->numOfRowsGroup < pQueryInfo->limit.limit && pQueryInfo->limit.limit > 0) || (pQueryInfo->limit.limit < 0))) { - int64_t etime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.ekey : pQueryInfo->window.skey; - - int32_t rows = (int32_t)getNumOfResultsAfterFillGap(pFillInfo, etime, pLocalMerge->resColModel->capacity); - if (rows > 0) { - doFillResult(pSql, pLocalMerge, true); - } - } - - /* - * 1. numOfRows == 0, means no interpolation results are generated. - * 2. if all local data sources are consumed, and no un-processed rows exist. - * - * No results will be generated and query completed. - */ - if (pRes->numOfRows > 0 || (isAllSourcesCompleted(pLocalMerge) && (!pLocalMerge->hasUnprocessedRow))) { - return true; - } - - // start to process result for a new group and save the result info of previous group - if (saveGroupResultInfo(pSql)) { - return true; - } - - resetEnvForNewResultset(pRes, pCmd, pLocalMerge); - } - - return false; -} - -static void doProcessResultInNextWindow(SSqlObj *pSql, int32_t numOfRes) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SLocalMerger *pLocalMerge = pRes->pLocalMerger; - SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - - for (int32_t k = 0; k < size; ++k) { - SQLFunctionCtx *pCtx = &pLocalMerge->pCtx[k]; - pCtx->pOutput += pCtx->outputBytes * numOfRes; - - // set the correct output timestamp column position - if (pCtx->functionId == TSDB_FUNC_TOP || pCtx->functionId == TSDB_FUNC_BOTTOM) { - pCtx->ptsOutputBuf = ((char *)pCtx->ptsOutputBuf + TSDB_KEYSIZE * numOfRes); - } - } - - doExecuteFinalMerge(pCmd, pLocalMerge, true); -} - -int32_t tscDoLocalMerge(SSqlObj *pSql) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - tscResetForNextRetrieve(pRes); - - if (pSql->signature != pSql || pRes == NULL || pRes->pLocalMerger == NULL) { // all data has been processed - if (pRes->code == TSDB_CODE_SUCCESS) { - return pRes->code; - } - - tscError("0x%"PRIx64" local merge abort due to error occurs, code:%s", pSql->self, tstrerror(pRes->code)); - return pRes->code; - } - - SLocalMerger *pLocalMerge = pRes->pLocalMerger; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - tFilePage *tmpBuffer = pLocalMerge->pTempBuffer; - - int32_t remain = 1; - if (tscIsTopbotQuery(pQueryInfo)) { - remain = tscGetTopbotQueryParam(pQueryInfo); - } - - if (doHandleLastRemainData(pSql)) { - return TSDB_CODE_SUCCESS; - } - - if (doBuildFilledResultForGroup(pSql)) { - return TSDB_CODE_SUCCESS; - } - - SLoserTreeInfo *pTree = pLocalMerge->pLoserTree; - - // clear buffer - handleUnprocessedRow(pCmd, pLocalMerge, tmpBuffer); - SColumnModel *pModel = pLocalMerge->pDesc->pColumnModel; - - while (1) { - if (isAllSourcesCompleted(pLocalMerge)) { - break; - } - -#ifdef _DEBUG_VIEW - printf("chosen data in pTree[0] = %d\n", pTree->pNode[0].index); -#endif - assert((pTree->pNode[0].index < pLocalMerge->numOfBuffer) && (pTree->pNode[0].index >= 0) && tmpBuffer->num == 0); - - // chosen from loser tree - SLocalDataSource *pOneDataSrc = pLocalMerge->pLocalDataSrc[pTree->pNode[0].index]; - - tColModelAppend(pModel, tmpBuffer, pOneDataSrc->filePage.data, pOneDataSrc->rowIdx, 1, - pOneDataSrc->pMemBuffer->pColumnModel->capacity); - -#if defined(_DEBUG_VIEW) - printf("chosen row:\t"); - SSrcColumnInfo colInfo[256] = {0}; - tscGetSrcColumnInfo(colInfo, pQueryInfo); - - tColModelDisplayEx(pModel, tmpBuffer->data, tmpBuffer->num, pModel->capacity, colInfo); -#endif - - if (pLocalMerge->discard) { - assert(pLocalMerge->hasUnprocessedRow == false); - - /* current record belongs to the same group of previous record, need to discard it */ - if (isSameGroup(pCmd, pLocalMerge, pLocalMerge->discardData->data, tmpBuffer)) { - tmpBuffer->num = 0; - pOneDataSrc->rowIdx += 1; - - adjustLoserTreeFromNewData(pLocalMerge, pOneDataSrc, pTree); - - // all inputs are exhausted, abort current process - if (isAllSourcesCompleted(pLocalMerge)) { - break; - } - - // data belongs to the same group needs to be discarded - continue; - } else { - pLocalMerge->discard = false; - pLocalMerge->discardData->num = 0; - - if (saveGroupResultInfo(pSql)) { - return TSDB_CODE_SUCCESS; - } - - resetEnvForNewResultset(pRes, pCmd, pLocalMerge); - } - } - - if (pLocalMerge->hasPrevRow) { - if (needToMerge(pQueryInfo, pLocalMerge, tmpBuffer)) { - // belong to the group of the previous row, continue process it - doExecuteFinalMerge(pCmd, pLocalMerge, false); - - // copy to buffer - savePreviousRow(pLocalMerge, tmpBuffer); - } else { - /* - * current row does not belong to the group of previous row. - * so the processing of previous group is completed. - */ - int32_t numOfRes = finalizeRes(pQueryInfo, pLocalMerge); - bool sameGroup = isSameGroup(pCmd, pLocalMerge, pLocalMerge->prevRowOfInput, tmpBuffer); - - tFilePage *pResBuf = pLocalMerge->pResultBuf; - - /* - * if the previous group does NOT generate any result (pResBuf->num == 0), - * continue to process results instead of return results. - */ - if ((!sameGroup && pResBuf->num > 0) || (pResBuf->num + remain >= pLocalMerge->resColModel->capacity)) { - // does not belong to the same group - bool notSkipped = genFinalResults(pSql, pLocalMerge, !sameGroup); - - // this row needs to discard, since it belongs to the group of previous - if (pLocalMerge->discard && sameGroup) { - pLocalMerge->hasUnprocessedRow = false; - tmpBuffer->num = 0; - } else { // current row does not belongs to the previous group, so it is not be handled yet. - pLocalMerge->hasUnprocessedRow = true; - } - - resetOutputBuf(pQueryInfo, pLocalMerge); - pOneDataSrc->rowIdx += 1; - - // here we do not check the return value - adjustLoserTreeFromNewData(pLocalMerge, pOneDataSrc, pTree); - - if (pRes->numOfRows == 0) { - handleUnprocessedRow(pCmd, pLocalMerge, tmpBuffer); - - if (!sameGroup) { - /* - * previous group is done, prepare for the next group - * If previous group is not skipped, keep it in pRes->numOfGroups - */ - if (notSkipped && saveGroupResultInfo(pSql)) { - return TSDB_CODE_SUCCESS; - } - - resetEnvForNewResultset(pRes, pCmd, pLocalMerge); - } - } else { - /* - * if next record belongs to a new group, we do not handle this record here. - * We start the process in a new round. - */ - if (sameGroup) { - handleUnprocessedRow(pCmd, pLocalMerge, tmpBuffer); - } - } - - // current group has no result, - if (pRes->numOfRows == 0) { - continue; - } else { - return TSDB_CODE_SUCCESS; - } - } else { // result buffer is not full - doProcessResultInNextWindow(pSql, numOfRes); - savePreviousRow(pLocalMerge, tmpBuffer); - } - } - } else { - doExecuteFinalMerge(pCmd, pLocalMerge, true); - savePreviousRow(pLocalMerge, tmpBuffer); // copy the processed row to buffer - } - - pOneDataSrc->rowIdx += 1; - adjustLoserTreeFromNewData(pLocalMerge, pOneDataSrc, pTree); - } - - if (pLocalMerge->hasPrevRow) { - finalizeRes(pQueryInfo, pLocalMerge); - } - - if (pLocalMerge->pResultBuf->num) { - genFinalResults(pSql, pLocalMerge, true); - } - - return TSDB_CODE_SUCCESS; -} - void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen) { SSqlRes *pRes = &pObj->res; if (pRes->pLocalMerger != NULL) { @@ -1741,8 +915,8 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_ arithSup.data = calloc(arithSup.numOfCols, POINTER_BYTES); for(int32_t k = 0; k < arithSup.numOfCols; ++k) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k); - arithSup.data[k] = (pOutput->data + pOutput->num* pExpr->offset); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k); + arithSup.data[k] = (pOutput->data + pOutput->num* pExpr->base.offset); } int32_t offset = 0; @@ -1751,12 +925,12 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_ SInternalField* pSup = TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i); // calculate the result from several other columns - if (pSup->pArithExprInfo != NULL) { - arithSup.pArithExpr = pSup->pArithExprInfo; - arithmeticTreeTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc); + if (pSup->pExpr->pExpr != NULL) { + arithSup.pExprInfo = pSup->pExpr; + arithmeticTreeTraverse(arithSup.pExprInfo->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc); } else { - SSqlExpr* pExpr = pSup->pSqlExpr; - memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, (size_t)(pExpr->resBytes * pOutput->num)); + SExprInfo* pExpr = pSup->pExpr; + memcpy(pbuf + pOutput->num * offset, pExpr->base.offset * pOutput->num + pOutput->data, (size_t)(pExpr->base.resBytes * pOutput->num)); } offset += pSup->field.bytes; @@ -1769,3 +943,364 @@ 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); + memmove(p, src, pColInfo->info.bytes); + } + + pBlock->info.rows += 1; +} + +SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*) param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SMultiwayMergeInfo *pInfo = pOperator->info; + + SLocalMerger *pMerger = pInfo->pMerge; + SLoserTreeInfo *pTree = pMerger->pLoserTree; + SColumnModel *pModel = pMerger->pDesc->pColumnModel; + tFilePage *tmpBuffer = pMerger->pTempBuffer; + + pInfo->binfo.pRes->info.rows = 0; + + while(1) { + if (isAllSourcesCompleted(pMerger)) { + break; + } + +#ifdef _DEBUG_VIEW + 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); + + // chosen from loser tree + SLocalDataSource *pOneDataSrc = pMerger->pLocalDataSrc[pTree->pNode[0].index]; + bool sameGroup = true; + if (pInfo->hasPrev) { + int32_t numOfCols = (int32_t)taosArrayGetSize(pInfo->orderColumnList); + + // if this row belongs to current result set group + for (int32_t i = 0; i < numOfCols; ++i) { + 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 * data = pInfo->prevRow[i]; + int32_t ret = columnValueAscendingComparator(data, newRow, pColInfo->info.type, pColInfo->info.bytes); + if (ret == 0) { + continue; + } else { + sameGroup = false; + *newgroup = true; + break; + } + } + } + + if (!sameGroup || !pInfo->hasPrev) { //save the data + int32_t numOfCols = (int32_t)taosArrayGetSize(pInfo->orderColumnList); + + for (int32_t i = 0; i < numOfCols; ++i) { + 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); + memcpy(pInfo->prevRow[i], curCol, pColInfo->info.bytes); + } + + pInfo->hasPrev = true; + } + + if (!sameGroup && pInfo->binfo.pRes->info.rows > 0) { + return pInfo->binfo.pRes; + } + + appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pModel, pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity); + +#if defined(_DEBUG_VIEW) + printf("chosen row:\t"); + SSrcColumnInfo colInfo[256] = {0}; + tscGetSrcColumnInfo(colInfo, pQueryInfo); + + tColModelDisplayEx(pModel, tmpBuffer->data, tmpBuffer->num, pModel->capacity, colInfo); +#endif + + pOneDataSrc->rowIdx += 1; + adjustLoserTreeFromNewData(pMerger, pOneDataSrc, pTree); + + if (pInfo->binfo.pRes->info.rows >= pInfo->bufCapacity) { + return pInfo->binfo.pRes; + } + } + + pOperator->status = OP_EXEC_DONE; + return (pInfo->binfo.pRes->info.rows > 0)? pInfo->binfo.pRes:NULL; +} + +static bool isSameGroupRv(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); + + SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, pIndex->colIndex); + assert(pIndex->colId == pColInfo->info.colId); + + char *data = dataCols[i]; + int32_t ret = columnValueAscendingComparator(data, pColInfo->pData, pColInfo->info.type, pColInfo->info.bytes); + if (ret == 0) { + continue; + } else { + return false; + } + } + + return true; +} + +SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*) param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SMultiwayMergeInfo *pAggInfo = pOperator->info; + SOperatorInfo *upstream = pOperator->upstream; + + *newgroup = false; + bool handleData = false; + pAggInfo->binfo.pRes->info.rows = 0; + + { + if (pAggInfo->hasDataBlockForNewGroup) { + pAggInfo->binfo.pRes->info.rows = 0; + pAggInfo->hasPrev = false; // now we start from a new group data set. + + // not belongs to the same group, return the result of current group; + setInputDataBlock(pOperator, pAggInfo->binfo.pCtx, pAggInfo->pExistBlock, TSDB_ORDER_ASC); + updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pAggInfo->pExistBlock->info.rows); + + { // reset output buffer + for(int32_t j = 0; j < pOperator->numOfOutput; ++j) { + aAggs[pAggInfo->binfo.pCtx[j].functionId].init(&pAggInfo->binfo.pCtx[j]); + } + } + + doExecuteFinalMergeRv(pOperator, pOperator->numOfOutput, pAggInfo->pExistBlock); + + savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pAggInfo->pExistBlock, 0, + &pAggInfo->hasGroupColData); + pAggInfo->pExistBlock = NULL; + pAggInfo->hasDataBlockForNewGroup = false; + handleData = true; + *newgroup = true; + } + } + + SSDataBlock* pBlock = NULL; + while(1) { + bool prev = *newgroup; + pBlock = upstream->exec(upstream, newgroup); + if (pBlock == NULL) { + *newgroup = prev; + break; + } + + if (pAggInfo->hasGroupColData) { + bool sameGroup = isSameGroupRv(pAggInfo->groupColumnList, pBlock, pAggInfo->currentGroupColData); + if (!sameGroup) { + *newgroup = true; + pAggInfo->hasDataBlockForNewGroup = true; + pAggInfo->pExistBlock = pBlock; + savePrevOrderColumns(pAggInfo->prevRow, pAggInfo->groupColumnList, pBlock, 0, &pAggInfo->hasPrev); + break; + } + } + + // not belongs to the same group, return the result of current group + setInputDataBlock(pOperator, pAggInfo->binfo.pCtx, pBlock, TSDB_ORDER_ASC); + updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor); + + doExecuteFinalMergeRv(pOperator, pOperator->numOfOutput, pBlock); + savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pBlock, 0, &pAggInfo->hasGroupColData); + handleData = true; + } + + if (handleData) { // data in current group is all handled + for(int32_t j = 0; j < pOperator->numOfOutput; ++j) { + int32_t functionId = pAggInfo->binfo.pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + + aAggs[functionId].xFinalize(&pAggInfo->binfo.pCtx[j]); + } + + int32_t numOfRows = getNumOfResult(pOperator->pRuntimeEnv, pAggInfo->binfo.pCtx, pOperator->numOfOutput); + pAggInfo->binfo.pRes->info.rows += numOfRows; + + setTagValueForMultipleRows(pAggInfo->binfo.pCtx, pOperator->numOfOutput, numOfRows); + } + + SSDataBlock* pRes = pAggInfo->binfo.pRes; + { + SColumnInfoData* pInfoData = taosArrayGet(pRes->pDataBlock, 0); + + 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)); + + if (pOperator->pRuntimeEnv->pQueryAttr->order.order == TSDB_ORDER_DESC) { + SWAP(w->skey, w->ekey, TSKEY); + assert(w->skey <= w->ekey); + } + } + } + + return (pRes->info.rows != 0)? pRes:NULL; +} + +static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) { + SSLimitOperatorInfo *pInfo = pOperator->info; + assert(pInfo->currentGroupOffset >= 0); + + SSDataBlock* pBlock = NULL; + if (pInfo->currentGroupOffset == 0) { + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + } + + 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); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + } + } + + return pBlock; + } + + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + while(1) { + if (*newgroup) { + pInfo->currentGroupOffset -= 1; + *newgroup = false; + } + + while ((*newgroup) == false) { + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + } + + // now we have got the first data block of the next group. + if (pInfo->currentGroupOffset == 0) { + return pBlock; + } + } + + return NULL; +} + +SSDataBlock* doSLimit(void* param, bool* newgroup) { + SOperatorInfo *pOperator = (SOperatorInfo *)param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SSLimitOperatorInfo *pInfo = pOperator->info; + + SSDataBlock *pBlock = NULL; + while (1) { + pBlock = skipGroupBlock(pOperator, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + if (*newgroup) { // a new group arrives + pInfo->groupTotal += 1; + pInfo->rowsTotal = 0; + pInfo->currentOffset = pInfo->limit.offset; + } + + assert(pInfo->currentGroupOffset == 0); + + if (pInfo->currentOffset >= pBlock->info.rows) { + pInfo->currentOffset -= pBlock->info.rows; + } else { + if (pInfo->currentOffset == 0) { + break; + } + + int32_t remain = (int32_t)(pBlock->info.rows - pInfo->currentOffset); + pBlock->info.rows = remain; + + // move the remain rows of this data block to the front. + for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + SColumnInfoData *pColInfoData = taosArrayGet(pBlock->pDataBlock, i); + + int16_t bytes = pColInfoData->info.bytes; + memmove(pColInfoData->pData, pColInfoData->pData + bytes * pInfo->currentOffset, remain * bytes); + } + + pInfo->currentOffset = 0; + break; + } + } + + if (pInfo->slimit.limit > 0 && pInfo->groupTotal > pInfo->slimit.limit) { // reach the group limit, abort + return NULL; + } + + if (pInfo->limit.limit > 0 && (pInfo->rowsTotal + pBlock->info.rows >= pInfo->limit.limit)) { + pBlock->info.rows = (int32_t)(pInfo->limit.limit - pInfo->rowsTotal); + pInfo->rowsTotal = pInfo->limit.limit; + + if (pInfo->slimit.limit > 0 && pInfo->groupTotal >= pInfo->slimit.limit) { + pOperator->status = OP_EXEC_DONE; + } + + // setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + } else { + pInfo->rowsTotal += pBlock->info.rows; + } + + return pBlock; +} diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index f17afa0f78..6107f8428d 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -68,7 +68,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 } else if (strncmp(pToken->z, "0", 1) == 0 && pToken->n == 1) { // do nothing } else if (pToken->type == TK_INTEGER) { - useconds = tsosStr2int64(pToken->z); + useconds = taosStr2int64(pToken->z); } else { // strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm); if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { @@ -740,7 +740,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC const int32_t STABLE_INDEX = 1; SSqlCmd * pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); char *sql = *sqlstr; @@ -821,6 +821,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC index = 0; 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); } @@ -833,6 +834,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC char* end = NULL; code = parseBoundColumns(pCmd, &spd, pTagSchema, sql, &end); if (code != TSDB_CODE_SUCCESS) { + tscDestroyBoundColumnInfo(&spd); return code; } @@ -850,11 +852,13 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC sql += index; if (sToken.type != TK_LP) { + tscDestroyBoundColumnInfo(&spd); return tscInvalidSQLErrMsg(pCmd->payload, "( is expected", sToken.z); } SKVRowBuilder kvRowBuilder = {0}; if (tdInitKVRowBuilder(&kvRowBuilder) < 0) { + tscDestroyBoundColumnInfo(&spd); return TSDB_CODE_TSC_OUT_OF_MEMORY; } @@ -867,6 +871,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; } @@ -884,6 +889,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC code = tsParseOneColumn(pSchema, &sToken, tagVal, pCmd->payload, &sql, false, tinfo.precision); if (code != TSDB_CODE_SUCCESS) { tdDestroyKVRowBuilder(&kvRowBuilder); + tscDestroyBoundColumnInfo(&spd); return code; } @@ -1093,7 +1099,7 @@ int tsParseInsertSql(SSqlObj *pSql) { int32_t totalNum = 0; int32_t code = TSDB_CODE_SUCCESS; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); assert(pQueryInfo != NULL); STableMetaInfo *pTableMetaInfo = (pQueryInfo->numOfTables == 0)? tscAddEmptyMetaInfo(pQueryInfo):tscGetMetaInfo(pQueryInfo, 0); @@ -1313,7 +1319,7 @@ int tsInsertInitialCheck(SSqlObj *pSql) { pCmd->count = 0; pCmd->command = TSDB_SQL_INSERT; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex); TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT | pCmd->insertType); @@ -1403,7 +1409,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock return code; } - return tscProcessSql(pSql); + return tscBuildAndSendRequest(pSql, NULL); } typedef struct SImportFileSupport { @@ -1549,6 +1555,7 @@ void tscImportDataFromFile(SSqlObj *pSql) { } assert(pCmd->dataSourceType == DATA_FROM_DATA_FILE && strlen(pCmd->payload) != 0); + pCmd->active = pCmd->pQueryInfo[0]; 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 4efaf7c2b5..c3c8986e2f 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -815,7 +815,7 @@ static int insertStmtExecute(STscStmt* stmt) { pRes->numOfRows = 0; pRes->numOfTotal = 0; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); // wait for the callback function to post the semaphore tsem_wait(&pSql->rspSem); diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c index be304632cc..777a136a6e 100644 --- a/src/client/src/tscProfile.c +++ b/src/client/src/tscProfile.c @@ -249,8 +249,8 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) { pQdesc->stime = htobe64(pSql->stime); pQdesc->queryId = htonl(pSql->queryId); //pQdesc->useconds = htobe64(pSql->res.useconds); - pQdesc->useconds = htobe64(now - pSql->stime); // use local time instead of sever rsp elapsed time - pQdesc->qHandle = htobe64(pSql->res.qId); + pQdesc->useconds = htobe64(now - pSql->stime); + pQdesc->qId = htobe64(pSql->res.qId); pHeartbeat->numOfQueries++; pQdesc++; diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 4cf1423c43..facd10b8b4 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -57,14 +57,14 @@ typedef struct SConvertFunc { int32_t execFuncId; } SConvertFunc; -static SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex); +static SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex); static int32_t setShowInfo(SSqlObj* pSql, SSqlInfo* pInfo); static char* getAccountId(SSqlObj* pSql); static bool has(SArray* pFieldList, int32_t startIdx, const char* name); static char* cloneCurrentDBName(SSqlObj* pSql); -static bool hasSpecifyDB(SStrToken* pTableName); +static int32_t getDelimiterIndex(SStrToken* pTableName); static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd); static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd); @@ -74,27 +74,27 @@ static void getColumnName(tSqlExprItem* pItem, char* resultFieldName, int32_t na 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, - int8_t type, char* fieldName, SSqlExpr* pSqlExpr); + int8_t type, char* fieldName, SExprInfo* pSqlExpr); static uint8_t convertOptr(SStrToken *pToken); -static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectList, bool isSTable, bool joinQuery, bool timeWindowQuery); +static int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelNodeList, bool isSTable, bool joinQuery, bool timeWindowQuery); static bool validateIpAddress(const char* ip, size_t size); static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool twQuery); -static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd); +static int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd); -static int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode); +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 addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem); -static int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql); -static int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySQL); -static int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode, SSchema* pSchema); +static int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql); +static int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); +static int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSchema* pSchema); static int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo); @@ -111,24 +111,25 @@ static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField); static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo); static bool hasNormalColumnFilter(SQueryInfo* pQueryInfo); -static int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t index, SQuerySqlNode* pQuerySqlNode, SSqlObj* pSql); +static int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t index, 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); static int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex); static int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); -static int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode); +static int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate); -static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex); +static SColumnList createColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex); 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 doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t index); -static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid); +static int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index); +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 bool isTimeWindowQuery(SQueryInfo* pQueryInfo) { return pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0; @@ -258,7 +259,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { return tscSQLSyntaxErrMsg(tscGetErrorMsgPayload(pCmd), NULL, pInfo->msg); } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex); if (pQueryInfo == NULL) { pRes->code = terrno; return pRes->code; @@ -426,17 +427,12 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { case TSDB_SQL_DESCRIBE_TABLE: { const char* msg1 = "invalid table name"; - const char* msg2 = "table name too long"; SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - if (!tscValidateTableNameLength(pToken->n)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); - } - // additional msg has been attached already code = tscSetTableFullName(pTableMetaInfo, pToken, pSql); if (code != TSDB_CODE_SUCCESS) { @@ -447,17 +443,12 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { } case TSDB_SQL_SHOW_CREATE_TABLE: { const char* msg1 = "invalid table name"; - const char* msg2 = "table name is too long"; SStrToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - if (!tscValidateTableNameLength(pToken->n)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); - } - code = tscSetTableFullName(pTableMetaInfo, pToken, pSql); if (code != TSDB_CODE_SUCCESS) { return code; @@ -617,36 +608,39 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { case TSDB_SQL_SELECT: { const char* msg1 = "columns in select clause not identical"; - for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) { - SQueryInfo* pqi = tscGetQueryInfoDetailSafely(pCmd, i); - if (pqi == NULL) { + 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; } } - assert(pCmd->numOfClause == pInfo->subclauseInfo.numOfClause); - for (int32_t i = pCmd->clauseIndex; i < pInfo->subclauseInfo.numOfClause; ++i) { - SQuerySqlNode* pQuerySqlNode = pInfo->subclauseInfo.pClause[i]; - tscTrace("%p start to parse %dth subclause, total:%d", pSql, i, pInfo->subclauseInfo.numOfClause); - if ((code = doValidateSqlNode(pSql, pQuerySqlNode, i)) != TSDB_CODE_SUCCESS) { + assert(pCmd->numOfClause == size); + for (int32_t i = pCmd->clauseIndex; 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) { return code; } - tscPrintSelectClause(pSql, i); + tscPrintSelNodeList(pSql, i); pCmd->clauseIndex += 1; } // restore the clause index pCmd->clauseIndex = 0; + // set the command/global limit parameters from the first subclause to the sqlcmd object - SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0); + 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 = tscGetQueryInfoDetail(pCmd, i); + SQueryInfo* pQueryInfo2 = tscGetQueryInfo(pCmd, i); int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo, &diffSize); if (ret != 0) { @@ -714,7 +708,7 @@ static bool isTopBottomQuery(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { return true; @@ -726,7 +720,7 @@ 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)->uid; + uint64_t uid = tscSqlExprGet(pQueryInfo, 0)->base.uid; int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL; for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { @@ -773,8 +767,8 @@ static int32_t checkInvalidExprForTimeWindow(SSqlCmd* pCmd, SQueryInfo* pQueryIn */ size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -790,7 +784,7 @@ static int32_t checkInvalidExprForTimeWindow(SSqlCmd* pCmd, SQueryInfo* pQueryIn return addPrimaryTsColumnForTimeWindowQuery(pQueryInfo); } -int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode) { +int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) { const char* msg2 = "interval cannot be less than 10 ms"; const char* msg3 = "sliding cannot be used without interval"; @@ -799,8 +793,8 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - if (!TPARSER_HAS_TOKEN(pQuerySqlNode->interval.interval)) { - if (TPARSER_HAS_TOKEN(pQuerySqlNode->sliding)) { + if (!TPARSER_HAS_TOKEN(pSqlNode->interval.interval)) { + if (TPARSER_HAS_TOKEN(pSqlNode->sliding)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } @@ -813,7 +807,7 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode } // interval is not null - SStrToken *t = &pQuerySqlNode->interval.interval; + 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; } @@ -830,11 +824,11 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode } } - if (parseIntervalOffset(pCmd, pQueryInfo, &pQuerySqlNode->interval.offset) != TSDB_CODE_SUCCESS) { + if (parseIntervalOffset(pCmd, pQueryInfo, &pSqlNode->interval.offset) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } - if (parseSlidingClause(pCmd, pQueryInfo, &pQuerySqlNode->sliding) != TSDB_CODE_SUCCESS) { + if (parseSlidingClause(pCmd, pQueryInfo, &pSqlNode->sliding) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } @@ -842,19 +836,19 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode return checkInvalidExprForTimeWindow(pCmd, pQueryInfo); } -int32_t parseSessionClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode * pQuerySqlNode) { +int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pSqlNode) { const char* msg1 = "gap should be fixed time window"; const char* msg2 = "only one type time window allowed"; const char* msg3 = "invalid column name"; const char* msg4 = "invalid time window"; // no session window - if (!TPARSER_HAS_TOKEN(pQuerySqlNode->sessionVal.gap)) { + if (!TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)) { return TSDB_CODE_SUCCESS; } - SStrToken* col = &pQuerySqlNode->sessionVal.col; - SStrToken* gap = &pQuerySqlNode->sessionVal.gap; + SStrToken* col = &pSqlNode->sessionVal.col; + SStrToken* gap = &pSqlNode->sessionVal.gap; char timeUnit = 0; if (parseNatualDuration(gap->z, gap->n, &pQueryInfo->sessionWindow.gap, &timeUnit) != TSDB_CODE_SUCCESS) { @@ -987,20 +981,30 @@ int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pTableNam const char* msg1 = "name too long"; const char* msg2 = "acctId too long"; const char* msg3 = "no acctId"; + const char* msg4 = "db name too long"; + const char* msg5 = "table name too long"; + SSqlCmd* pCmd = &pSql->cmd; int32_t code = TSDB_CODE_SUCCESS; - - if (hasSpecifyDB(pTableName)) { // db has been specified in sql string so we ignore current db path + int32_t idx = getDelimiterIndex(pTableName); + if (idx != -1) { // db has been specified in sql string so we ignore current db path char* acctId = getAccountId(pSql); if (acctId == NULL || strlen(acctId) <= 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } - + code = tNameSetAcctId(&pTableMetaInfo->name, acctId); if (code != 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } + if (idx >= TSDB_DB_NAME_LEN) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + } + + if (pTableName->n - 1 - idx >= TSDB_TABLE_NAME_LEN) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + } char name[TSDB_TABLE_FNAME_LEN] = {0}; strncpy(name, pTableName->z, pTableName->n); @@ -1345,14 +1349,13 @@ static char* cloneCurrentDBName(SSqlObj* pSql) { } /* length limitation, strstr cannot be applied */ -static bool hasSpecifyDB(SStrToken* pTableName) { +static int32_t getDelimiterIndex(SStrToken* pTableName) { for (uint32_t i = 0; i < pTableName->n; ++i) { if (pTableName->z[i] == TS_PATH_DELIMITER[0]) { - return true; + return i; } } - - return false; + return -1; } int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) { @@ -1406,20 +1409,17 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL; } -void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) { - SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscColumnListInsert(pQueryInfo->colList, &tsCol); +void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t tableUid) { + SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX}; + tscColumnListInsert(pQueryInfo->colList, PRIMARYKEY_TIMESTAMP_COL_INDEX, tableUid, &s); } -static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSqlExprItem* pItem) { +static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem) { const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables"; const char* msg2 = "invalid arithmetic expression in select clause"; const char* msg3 = "tag columns can not be used in arithmetic expression"; const char* msg4 = "columns from different table mixed up in arithmetic expression"; - // arithmetic function in select clause - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); - SColumnList columnList = {0}; int32_t arithmeticType = NON_ARITHMEIC_EXPR; @@ -1441,12 +1441,12 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t // expr string is set as the parameter of function SColumnIndex index = {.tableIndex = tableIndex}; - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double), + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(pQueryInfo), sizeof(double), false); char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->token.z; - size_t len = MIN(sizeof(pExpr->aliasName), pItem->pNode->token.n + 1); - tstrncpy(pExpr->aliasName, name, len); + size_t len = MIN(sizeof(pExpr->base.aliasName), pItem->pNode->token.n + 1); + tstrncpy(pExpr->base.aliasName, name, len); tExprNode* pNode = NULL; SArray* colList = taosArrayInit(10, sizeof(SColIndex)); @@ -1484,11 +1484,11 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t char* c = tbufGetData(&bw, false); // set the serialized binary string as the parameter of arithmetic expression - addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len); - insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr); + addExprParams(&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 - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pExpr->base.uid); tbufCloseWriter(&bw); taosArrayDestroy(colList); @@ -1510,41 +1510,41 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t int32_t slot = tscNumOfFields(pQueryInfo) - 1; SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot); - if (pInfo->pSqlExpr == NULL) { - SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo)); + if (pInfo->pExpr == NULL) { + SExprInfo* pExprInfo = calloc(1, sizeof(SExprInfo)); // arithmetic expression always return result in the format of double float - pArithExprInfo->bytes = sizeof(double); - pArithExprInfo->interBytes = sizeof(double); - pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE; + pExprInfo->base.resBytes = sizeof(double); + pExprInfo->base.interBytes = sizeof(double); + pExprInfo->base.resType = TSDB_DATA_TYPE_DOUBLE; - pArithExprInfo->base.functionId = TSDB_FUNC_ARITHM; - pArithExprInfo->base.numOfParams = 1; - pArithExprInfo->base.resColId = getNewResColId(pQueryInfo); + pExprInfo->base.functionId = TSDB_FUNC_ARITHM; + pExprInfo->base.numOfParams = 1; + pExprInfo->base.resColId = getNewResColId(pQueryInfo); - int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &pArithExprInfo->uid); + int32_t ret = exprTreeFromSqlExpr(pCmd, &pExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &(pExprInfo->base.uid)); if (ret != TSDB_CODE_SUCCESS) { - tExprTreeDestroy(pArithExprInfo->pExpr, NULL); + tExprTreeDestroy(pExprInfo->pExpr, NULL); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause"); } - pInfo->pArithExprInfo = pArithExprInfo; + pInfo->pExpr = pExprInfo; } SBufferWriter bw = tbufInitWriter(NULL, false); TRY(0) { - exprTreeToBinary(&bw, pInfo->pArithExprInfo->pExpr); + exprTreeToBinary(&bw, pInfo->pExpr->pExpr); } CATCH(code) { tbufCloseWriter(&bw); UNUSED(code); // TODO: other error handling } END_TRY - SSqlFuncMsg* pFuncMsg = &pInfo->pArithExprInfo->base; - pFuncMsg->arg[0].argBytes = (int16_t) tbufTell(&bw); - pFuncMsg->arg[0].argValue.pz = tbufGetData(&bw, true); - pFuncMsg->arg[0].argType = TSDB_DATA_TYPE_BINARY; + SSqlExpr* pSqlExpr = &pInfo->pExpr->base; + pSqlExpr->param[0].nLen = (int16_t) tbufTell(&bw); + pSqlExpr->param[0].pz = tbufGetData(&bw, true); + pSqlExpr->param[0].nType = TSDB_DATA_TYPE_BINARY; // tbufCloseWriter(&bw); // TODO there is a memory leak } @@ -1553,7 +1553,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t } static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSqlExprItem* pItem) { - SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex); + SExprInfo* pExpr = doAddProjectCol(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; @@ -1561,7 +1561,7 @@ static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumn SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex); char* colName = (pItem->aliasName == NULL) ? pSchema->name : pItem->aliasName; - tstrncpy(pExpr->aliasName, colName, sizeof(pExpr->aliasName)); + tstrncpy(pExpr->base.aliasName, colName, sizeof(pExpr->base.aliasName)); SColumnList ids = {0}; ids.num = 1; @@ -1572,15 +1572,15 @@ static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumn ids.num = 0; } - insertResultField(pQueryInfo, startPos, &ids, pExpr->resBytes, (int8_t)pExpr->resType, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, startPos, &ids, pExpr->base.resBytes, (int8_t)pExpr->base.resType, pExpr->base.aliasName, pExpr); } static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) { // primary timestamp column has been added already size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { return; } } @@ -1629,26 +1629,31 @@ static bool hasNoneUserDefineExpr(SQueryInfo* pQueryInfo) { return false; } +int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelNodeList, bool isSTable, bool joinQuery, + bool timeWindowQuery) { + assert(pSelNodeList != NULL && pCmd != NULL); + + const char* msg1 = "too many items in selection clause"; -int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectList, bool isSTable, bool joinQuery, bool timeWindowQuery) { - assert(pSelectList != NULL && pCmd != NULL); - const char* msg1 = "too many columns in selection clause"; const char* msg2 = "functions or others can not be mixed up"; const char* msg3 = "not support query expression"; + const char* msg4 = "only support distinct one tag"; const char* msg5 = "invalid function name"; - const char* msg6 = "only support distinct one tag"; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + // too many result columns not support order by in query + if (taosArrayGetSize(pSelNodeList) > TSDB_MAX_COLUMNS) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } if (pQueryInfo->colList == NULL) { pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); } bool hasDistinct = false; - size_t numOfExpr = taosArrayGetSize(pSelectList); + size_t numOfExpr = taosArrayGetSize(pSelNodeList); for (int32_t i = 0; i < numOfExpr; ++i) { int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); - tSqlExprItem* pItem = taosArrayGet(pSelectList, i); + tSqlExprItem* pItem = taosArrayGet(pSelNodeList, i); if (hasDistinct == false) { hasDistinct = (pItem->distinct == true); @@ -1672,7 +1677,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectLis return TSDB_CODE_TSC_INVALID_SQL; } } else if (type == SQL_NODE_EXPR) { - int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem); + int32_t code = handleArithmeticExpr(pCmd, pQueryInfo, i, pItem); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -1687,7 +1692,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectLis if (hasDistinct == true) { if (!isValidDistinctSql(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); } pQueryInfo->distinctTag = true; } @@ -1705,29 +1710,30 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectLis return TSDB_CODE_SUCCESS; } -int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes, - int8_t type, char* fieldName, SSqlExpr* pSqlExpr) { - - for (int32_t i = 0; i < pIdList->num; ++i) { - int32_t tableId = pIdList->ids[i].tableIndex; - STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[tableId]; - - int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - if (pIdList->ids[i].columnIndex >= numOfCols) { +int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pColList, int16_t bytes, + int8_t type, char* fieldName, SExprInfo* pSqlExpr) { + for (int32_t i = 0; i < pColList->num; ++i) { + int32_t tableIndex = pColList->ids[i].tableIndex; + STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[tableIndex]->pTableMeta; + + int32_t numOfCols = tscGetNumOfColumns(pTableMeta); + if (pColList->ids[i].columnIndex >= numOfCols) { continue; } - - tscColumnListInsert(pQueryInfo->colList, &(pIdList->ids[i])); + + uint64_t uid = pTableMeta->id.uid; + SSchema* pSchema = tscGetTableSchema(pTableMeta); + tscColumnListInsert(pQueryInfo->colList, pColList->ids[i].columnIndex, uid, &pSchema[pColList->ids[i].columnIndex]); } TAOS_FIELD f = tscCreateField(type, fieldName, bytes); SInternalField* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f); - pInfo->pSqlExpr = pSqlExpr; + pInfo->pExpr = pSqlExpr; return TSDB_CODE_SUCCESS; } -SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex) { +SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta); @@ -1739,7 +1745,7 @@ SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tabl if (functionId == TSDB_FUNC_TAGPRJ) { index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); } else { index.columnIndex = colIndex; } @@ -1749,26 +1755,26 @@ SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tabl (functionId == TSDB_FUNC_TAGPRJ)); } -SSqlExpr* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, +SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) { int16_t colId = getNewResColId(pQueryInfo); - SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type, + SExprInfo* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type, pColSchema->bytes, colId, pColSchema->bytes, TSDB_COL_IS_TAG(flag)); - tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName)); + tstrncpy(pExpr->base.aliasName, pColSchema->name, sizeof(pExpr->base.aliasName)); - SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex); + SColumnList ids = createColumnList(1, pIndex->tableIndex, pIndex->columnIndex); if (TSDB_COL_IS_TAG(flag)) { ids.num = 0; } insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr); - pExpr->colInfo.flag = flag; + pExpr->base.colInfo.flag = flag; STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); if (TSDB_COL_IS_TAG(flag)) { - tscColumnListInsert(pTableMetaInfo->tagColList, pIndex); + tscColumnListInsert(pTableMetaInfo->tagColList, pIndex->columnIndex, pTableMetaInfo->pTableMeta->id.uid, pColSchema); } return pExpr; @@ -1790,8 +1796,8 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum } for (int32_t j = 0; j < numOfTotalColumns; ++j) { - SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, j, pIndex->tableIndex); - tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName)); + SExprInfo* pExpr = doAddProjectCol(pQueryInfo, j, pIndex->tableIndex); + tstrncpy(pExpr->base.aliasName, pSchema[j].name, sizeof(pExpr->base.aliasName)); pIndex->columnIndex = j; SColumnList ids = {0}; @@ -1831,7 +1837,10 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t } // add the primary timestamp column even though it is not required by user - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[index.tableIndex]->pTableMeta; + if (pTableMeta->tableType != TSDB_TEMP_TABLE) { + tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMeta->id.uid); + } } else if (optr == TK_STRING || optr == TK_INTEGER || optr == TK_FLOAT) { // simple column projection query SColumnIndex index = COLUMN_INDEX_INITIALIZER; @@ -1840,12 +1849,12 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t index.tableIndex = 0; SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->value, &pItem->pNode->token, pItem->aliasName); - SSqlExpr* pExpr = + SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC); // NOTE: the first parameter is reserved for the tag column id during join query process. - pExpr->numOfParams = 2; - tVariantAssign(&pExpr->param[1], &pItem->pNode->value); + pExpr->base.numOfParams = 2; + tVariantAssign(&pExpr->base.param[1], &pItem->pNode->value); } else if (optr == TK_ID) { SColumnIndex index = COLUMN_INDEX_INITIALIZER; @@ -1872,7 +1881,8 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t } // add the primary timestamp column even though it is not required by user - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); } else { return TSDB_CODE_TSC_INVALID_SQL; } @@ -1902,30 +1912,30 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS bytes = pSchema->bytes; } - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, getNewResColId(pQueryInfo), bytes, false); - tstrncpy(pExpr->aliasName, name, tListLen(pExpr->aliasName)); + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, getNewResColId(pQueryInfo), bytes, false); + tstrncpy(pExpr->base.aliasName, name, tListLen(pExpr->base.aliasName)); if (cvtFunc.originFuncId == TSDB_FUNC_LAST_ROW && cvtFunc.originFuncId != functionID) { - pExpr->colInfo.flag |= TSDB_COL_NULL; + pExpr->base.colInfo.flag |= TSDB_COL_NULL; } // set reverse order scan data blocks for last query if (functionID == TSDB_FUNC_LAST) { - pExpr->numOfParams = 1; - pExpr->param[0].i64 = TSDB_ORDER_DESC; - pExpr->param[0].nType = TSDB_DATA_TYPE_INT; + pExpr->base.numOfParams = 1; + pExpr->base.param[0].i64 = TSDB_ORDER_DESC; + pExpr->base.param[0].nType = TSDB_DATA_TYPE_INT; } // for all queries, the timestamp column needs to be loaded - SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscColumnListInsert(pQueryInfo->colList, &index); + SSchema s = {.colId = PRIMARYKEY_TIMESTAMP_COL_INDEX, .bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP,}; + tscColumnListInsert(pQueryInfo->colList, PRIMARYKEY_TIMESTAMP_COL_INDEX, pExpr->base.uid, &s); // if it is not in the final result, do not add it - SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex); + SColumnList ids = createColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex); if (finalResult) { - insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, pExpr->base.aliasName, pExpr); } else { - tscColumnListInsert(pQueryInfo->colList, &(ids.ids[0])); + tscColumnListInsert(pQueryInfo->colList, ids.ids[0].columnIndex, pExpr->base.uid, pSchema); } return TSDB_CODE_SUCCESS; @@ -1958,14 +1968,14 @@ static void updateLastScanOrderIfNeeded(SQueryInfo* pQueryInfo) { if (pQueryInfo->sessionWindow.gap > 0 || tscGroupbyColumn(pQueryInfo)) { size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExpr; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId != TSDB_FUNC_LAST && pExpr->functionId != TSDB_FUNC_LAST_DST) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId != TSDB_FUNC_LAST && pExpr->base.functionId != TSDB_FUNC_LAST_DST) { continue; } - pExpr->numOfParams = 1; - pExpr->param->i64 = TSDB_ORDER_ASC; - pExpr->param->nType = TSDB_DATA_TYPE_INT; + pExpr->base.numOfParams = 1; + pExpr->base.param->i64 = TSDB_ORDER_ASC; + pExpr->base.param->nType = TSDB_DATA_TYPE_INT; } } } @@ -1991,7 +2001,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SSqlExpr* pExpr = NULL; + SExprInfo* pExpr = NULL; SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (pItem->pNode->pParam != NULL) { @@ -2001,7 +2011,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col if ((pToken->z == NULL || pToken->n == 0) && (TK_INTEGER != sqlOptr)) /*select count(1) from table*/ { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); - } + } + if (sqlOptr == TK_ALL) { // select table.* // check if the table name is valid or not @@ -2055,22 +2066,24 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); - getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1); + memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); + getColumnName(pItem, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1); - SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex); + SColumnList list = createColumnList(1, index.tableIndex, index.columnIndex); if (finalResult) { int32_t numOfOutput = tscNumOfFields(pQueryInfo); - insertResultField(pQueryInfo, numOfOutput, &ids, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, numOfOutput, &list, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, pExpr->base.aliasName, pExpr); } else { - for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i])); + for (int32_t i = 0; i < list.num; ++i) { + SSchema* ps = tscGetTableSchema(pTableMetaInfo->pTableMeta); + tscColumnListInsert(pQueryInfo->colList, list.ids[i].columnIndex, pTableMetaInfo->pTableMeta->id.uid, + &ps[list.ids[i].columnIndex]); } } // the time stamp may be always needed if (index.tableIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); } return TSDB_CODE_SUCCESS; @@ -2113,11 +2126,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // 2. check if sql function can be applied on this column data type pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); - int16_t colType = pSchema->type; - if (!IS_NUMERIC_TYPE(colType)) { + if (!IS_NUMERIC_TYPE(pSchema->type)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); - } else if (IS_UNSIGNED_NUMERIC_TYPE(colType) && functionId == TSDB_FUNC_DIFF) { + } else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && functionId == TSDB_FUNC_DIFF) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9); } @@ -2134,10 +2146,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col if (functionId == TSDB_FUNC_DIFF) { colIndex += 1; SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pQueryInfo), TSDB_KEYSIZE, false); - SColumnList ids = getColumnList(1, 0, 0); + SColumnList ids = createColumnList(1, 0, 0); insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].name, pExpr); } @@ -2146,7 +2158,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); } - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); if (functionId == TSDB_FUNC_LEASTSQR) { /* set the leastsquares parameters */ @@ -2155,33 +2167,31 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return TSDB_CODE_TSC_INVALID_SQL; } - addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES); + addExprParams(&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; } - addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); + addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); } - SColumnList ids = {0}; - ids.num = 1; - ids.ids[0] = index; - - memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); - getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1); - + 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); + if (finalResult) { int32_t numOfOutput = tscNumOfFields(pQueryInfo); - insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, (int32_t)pExpr->resType, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->base.resBytes, (int32_t)pExpr->base.resType, + pExpr->base.aliasName, pExpr); } else { - for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i])); - } + assert(ids.num == 1); + tscColumnListInsert(pQueryInfo->colList, ids.ids[0].columnIndex, pExpr->base.uid, pSchema); } - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pExpr->base.uid); return TSDB_CODE_SUCCESS; } case TSDB_FUNC_FIRST: @@ -2318,7 +2328,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); // functions can not be applied to tags if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { @@ -2326,8 +2336,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // 2. valid the column type - int16_t colType = pSchema[index.columnIndex].type; - if (!IS_NUMERIC_TYPE(colType)) { + if (!IS_NUMERIC_TYPE(pSchema->type)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -2338,12 +2347,12 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col tVariant* pVariant = &pParamElem[1].pNode->value; - int8_t resultType = pSchema[index.columnIndex].type; - int16_t resultSize = pSchema[index.columnIndex].bytes; + int8_t resultType = pSchema->type; + int16_t resultSize = pSchema->bytes; - char val[8] = {0}; - SSqlExpr* pExpr = NULL; - + char val[8] = {0}; + + SExprInfo* pExpr = NULL; if (functionId == TSDB_FUNC_PERCT || functionId == TSDB_FUNC_APERCT) { tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true); @@ -2360,11 +2369,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col * for dp = 0, it is actually min, * for dp = 100, it is max, */ - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + 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, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); + addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); } else { tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true); @@ -2378,29 +2387,30 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pQueryInfo), TSDB_KEYSIZE, false); - tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->aliasName)); + tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->base.aliasName)); const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX; - SColumnList ids = getColumnList(1, index.tableIndex, TS_COLUMN_INDEX); + SColumnList ids = createColumnList(1, index.tableIndex, TS_COLUMN_INDEX); insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].name, pExpr); colIndex += 1; // the first column is ts pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); - addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); + addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); } - memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); - getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1); - - SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex); + memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); + getColumnName(pItem, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1); + + // todo refactor: tscColumnListInsert part + SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + if (finalResult) { - insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->base.aliasName, pExpr); } else { - for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i])); - } + assert(ids.num == 1); + tscColumnListInsert(pQueryInfo->colList, ids.ids[0].columnIndex, pExpr->base.uid, pSchema); } return TSDB_CODE_SUCCESS; @@ -2450,9 +2460,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, + &pSchema[index.columnIndex]); SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - + SSchema s = {0}; if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { s = *tGetTbnameColumnSchema(); @@ -2492,10 +2503,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col s.bytes = bytes; s.type = (uint8_t)resType; - SSqlExpr* pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, &s, TSDB_COL_TAG); - pExpr->numOfParams = 1; - pExpr->param[0].i64 = pTableMetaInfo->pTableMeta->tableInfo.rowSize; - pExpr->param[0].nType = TSDB_DATA_TYPE_BIGINT; + SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, &s, TSDB_COL_TAG); + pExpr->base.numOfParams = 1; + pExpr->base.param[0].i64 = pTableMetaInfo->pTableMeta->tableInfo.rowSize; + pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; return TSDB_CODE_SUCCESS; } @@ -2507,7 +2518,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // todo refactor -static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) { +static SColumnList createColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) { assert(num == 1 && tableIndex >= 0); SColumnList columnList = {0}; @@ -2807,23 +2818,23 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t k = 0; k < size; ++k) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k); - int16_t functionId = aAggs[pExpr->functionId].stableFuncId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k); + int16_t functionId = aAggs[pExpr->base.functionId].stableFuncId; - int32_t colIndex = pExpr->colInfo.colIndex; + int32_t colIndex = pExpr->base.colInfo.colIndex; SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex); if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) || (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_STDDEV_DST) || (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) { - if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64, &type, &bytes, + 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; } - tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes); + tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->base.colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes); // todo refactor - pExpr->interBytes = interBytes; + pExpr->base.interBytes = interBytes; } } @@ -2840,14 +2851,14 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex); // the final result size and type in the same as query on single table. // so here, set the flag to be false; int32_t inter = 0; - int32_t functionId = pExpr->functionId; + int32_t functionId = pExpr->base.functionId; if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) { continue; } @@ -2860,7 +2871,7 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { functionId = TSDB_FUNC_STDDEV; } - getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &pExpr->resType, &pExpr->resBytes, + getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &pExpr->base.resType, &pExpr->base.resBytes, &inter, 0, false); } } @@ -2873,7 +2884,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) // filter sql function not supported by metric query yet. size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; if ((aAggs[functionId].status & TSDB_FUNCSTATE_STABLE) == 0) { invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); return true; @@ -2924,17 +2935,17 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo); assert(numOfExpr > 0); - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, startIdx); // ts function can be simultaneously used with any other functions. - int32_t functionID = pExpr->functionId; + int32_t functionID = pExpr->base.functionId; if (functionID == TSDB_FUNC_TS || functionID == TSDB_FUNC_TS_DUMMY) { startIdx++; } - int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId]; + int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->base.functionId]; - if (tscSqlExprGet(pQueryInfo, 0)->functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) { + if (tscSqlExprGet(pQueryInfo, 0)->base.functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) { return false; } @@ -2943,14 +2954,14 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = startIdx + 1; i < size; ++i) { - SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, i); - int16_t functionId = pExpr1->functionId; + int16_t functionId = pExpr1->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) { continue; } - if (functionId == TSDB_FUNC_PRJ && (pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->colInfo.flag))) { + if (functionId == TSDB_FUNC_PRJ && (pExpr1->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->base.colInfo.flag))) { continue; } @@ -2970,7 +2981,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool return true; } -int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) { +int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) { const char* msg1 = "too many columns in group by clause"; const char* msg2 = "invalid column name in group by clause"; const char* msg3 = "columns from one table allowed as group by columns"; @@ -3056,14 +3067,14 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) taosArrayPush(pGroupExpr->columnInfo, &colIndex); index.columnIndex = relIndex; - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); } else { // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); } - tscColumnListInsert(pQueryInfo->colList, &index); + 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); @@ -3080,33 +3091,29 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) } -static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) { - if (pColumn == NULL) { - return NULL; - } +static SColumnFilterInfo* addColumnFilterInfo(SColumnFilterList* filterList) { + int32_t size = (filterList->numOfFilters) + 1; - int32_t size = pColumn->numOfFilters + 1; - - char* tmp = (char*) realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size)); + char* tmp = (char*) realloc((void*)(filterList->filterInfo), sizeof(SColumnFilterInfo) * (size)); if (tmp != NULL) { - pColumn->filterInfo = (SColumnFilterInfo*)tmp; + filterList->filterInfo = (SColumnFilterInfo*)tmp; } else { return NULL; } - pColumn->numOfFilters++; + filterList->numOfFilters = size; - SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1]; + SColumnFilterInfo* pColFilterInfo = &(filterList->filterInfo[size - 1]); memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo)); return pColFilterInfo; } -static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, STableMeta* pTableMeta, SColumnFilterInfo* pColumnFilter, +static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t timePrecision, SColumnFilterInfo* pColumnFilter, int16_t colType, tSqlExpr* pExpr) { const char* msg = "not supported filter condition"; - tSqlExpr* pRight = pExpr->pRight; + tSqlExpr *pRight = pExpr->pRight; if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) { colType = TSDB_DATA_TYPE_BIGINT; @@ -3118,9 +3125,7 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, return retVal; } } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BIGINT == pRight->value.nType)) { - STableComInfo tinfo = tscGetTableInfo(pTableMeta); - - if ((tinfo.precision == TSDB_TIME_PRECISION_MILLI) && (pRight->flags & (1 << EXPR_FLAG_US_TIMESTAMP))) { + if ((timePrecision == TSDB_TIME_PRECISION_MILLI) && (pRight->flags & (1 << EXPR_FLAG_US_TIMESTAMP))) { pRight->value.i64 /= 1000; } } @@ -3264,7 +3269,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC const char* msg2 = "binary column not support this operator"; const char* msg3 = "bool column not support this operator"; - SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex); + SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex->columnIndex, pTableMeta->id.uid, pSchema); SColumnFilterInfo* pColFilter = NULL; /* @@ -3273,10 +3278,10 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC */ if (sqlOptr == TK_AND) { // this is a new filter condition on this column - if (pColumn->numOfFilters == 0) { - pColFilter = addColumnFilterInfo(pColumn); + if (pColumn->info.flist.numOfFilters == 0) { + pColFilter = addColumnFilterInfo(&pColumn->info.flist); } else { // update the existed column filter information, find the filter info here - pColFilter = &pColumn->filterInfo[0]; + pColFilter = &pColumn->info.flist.filterInfo[0]; } if (pColFilter == NULL) { @@ -3284,7 +3289,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC } } else if (sqlOptr == TK_OR) { // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2" - pColFilter = addColumnFilterInfo(pColumn); + pColFilter = addColumnFilterInfo(&pColumn->info.flist); if (pColFilter == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } @@ -3317,11 +3322,11 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC } } - pColumn->colIndex = *pIndex; + pColumn->columnIndex = pIndex->columnIndex; + pColumn->tableUid = pTableMeta->id.uid; - int16_t colType = pSchema->type; - - return doExtractColumnFilterInfo(pCmd, pQueryInfo, pTableMeta, pColFilter, colType, pExpr); + STableComInfo tinfo = tscGetTableInfo(pTableMeta); + return doExtractColumnFilterInfo(pCmd, pQueryInfo, tinfo.precision, pColFilter, pSchema->type, pExpr); } static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pTableCond, SStringBuilder* sb) { @@ -3383,9 +3388,9 @@ static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSq static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) { int32_t code = 0; const char* msg1 = "timestamp required for join tables"; + const char* msg2 = "only support one join tag for each table"; const char* msg3 = "type of join columns must be identical"; const char* msg4 = "invalid column name in join condition"; - const char* msg5 = "only support one join tag for each table"; if (pExpr == NULL) { return TSDB_CODE_SUCCESS; @@ -3396,7 +3401,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (code) { return code; } - + return checkAndSetJoinCondInfo(pCmd, pQueryInfo, pExpr->pRight); } @@ -3414,23 +3419,25 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (*leftNode == NULL) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - + (*leftNode)->uid = pTableMetaInfo->pTableMeta->id.uid; (*leftNode)->tagColId = pTagSchema1->colId; if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - if (!tscColumnExists(pTableMetaInfo->tagColList, &index)) { - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + if (!tscColumnExists(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid)) { + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema1); + if (taosArrayGetSize(pTableMetaInfo->tagColList) > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } } } int16_t leftIdx = index.tableIndex; - index = (SColumnIndex)COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); @@ -3450,11 +3457,13 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS (*rightNode)->tagColId = pTagSchema2->colId; if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - if (!tscColumnExists(pTableMetaInfo->tagColList, &index)) { - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMeta); + if (!tscColumnExists(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid)) { + + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema2); if (taosArrayGetSize(pTableMetaInfo->tagColList) > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } } } @@ -3468,16 +3477,16 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if ((*leftNode)->tagJoin == NULL) { (*leftNode)->tagJoin = taosArrayInit(2, sizeof(int16_t)); } - + if ((*rightNode)->tagJoin == NULL) { (*rightNode)->tagJoin = taosArrayInit(2, sizeof(int16_t)); - } - + } + taosArrayPush((*leftNode)->tagJoin, &rightIdx); taosArrayPush((*rightNode)->tagJoin, &leftIdx); - + pQueryInfo->tagCond.joinInfo.hasJoin = true; - + return TSDB_CODE_SUCCESS; } @@ -3548,15 +3557,15 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer // Not supported data type in arithmetic expression uint64_t id = -1; for(int32_t i = 0; i < inc; ++i) { - SSqlExpr* p1 = tscSqlExprGet(pQueryInfo, i + outputIndex); - int16_t t = p1->resType; + SExprInfo* p1 = tscSqlExprGet(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; } if (i == 0) { - id = p1->uid; - } else if (id != p1->uid) { + id = p1->base.uid; + } else if (id != p1->base.uid) { return TSDB_CODE_TSC_INVALID_SQL; } } @@ -3837,7 +3846,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql return TSDB_CODE_TSC_OUT_OF_MEMORY; } } - + int16_t leftIdx = index.tableIndex; if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { @@ -3855,20 +3864,20 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql return TSDB_CODE_TSC_OUT_OF_MEMORY; } } - + int16_t rightIdx = index.tableIndex; if ((*leftNode)->tsJoin == NULL) { (*leftNode)->tsJoin = taosArrayInit(2, sizeof(int16_t)); } - + if ((*rightNode)->tsJoin == NULL) { (*rightNode)->tsJoin = taosArrayInit(2, sizeof(int16_t)); - } - + } + taosArrayPush((*leftNode)->tsJoin, &rightIdx); taosArrayPush((*rightNode)->tsJoin, &leftIdx); - + /* * to release expression, e.g., m1.ts = m2.ts, * since this expression is used to set the join query type @@ -4128,8 +4137,8 @@ static bool validateFilterExpr(SQueryInfo* pQueryInfo) { for (int32_t i = 0; i < num; ++i) { SColumn* pCol = taosArrayGetP(pColList, i); - for (int32_t j = 0; j < pCol->numOfFilters; ++j) { - SColumnFilterInfo* pColFilter = &pCol->filterInfo[j]; + for (int32_t j = 0; j < pCol->info.flist.numOfFilters; ++j) { + SColumnFilterInfo* pColFilter = &pCol->info.flist.filterInfo[j]; int32_t lowerOptr = pColFilter->lowerRelOptr; int32_t upperOptr = pColFilter->upperRelOptr; @@ -4152,7 +4161,7 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE const char* msg0 = "invalid timestamp"; const char* msg1 = "only one time stamp window allowed"; int32_t code = 0; - + if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } @@ -4166,7 +4175,7 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE if (code) { return code; } - + return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight); } else { SColumnIndex index = COLUMN_INDEX_INITIALIZER; @@ -4256,18 +4265,22 @@ static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInf if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (left)", pQueryInfo); } + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + + SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); + tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (right)", pQueryInfo); } + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + + pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); + tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); } } */ @@ -4378,7 +4391,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE // TODO: more error handling } END_TRY - // add to source column list + // add to required table column list STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); int64_t uid = pTableMetaInfo->pTableMeta->id.uid; int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); @@ -4387,7 +4400,10 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE for(int32_t j = 0; j < num; ++j) { SColIndex* pIndex = taosArrayGet(colList, j); SColumnIndex index = {.tableIndex = i, .columnIndex = pIndex->colIndex - numOfCols}; - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + + SSchema* s = tscGetTableSchema(pTableMetaInfo->pTableMeta); + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, + &s[pIndex->colIndex]); } tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw); @@ -4417,10 +4433,10 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE int32_t validateJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { const char* msg1 = "timestamp required for join tables"; const char* msg2 = "tag required for join stables"; - + for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; - + SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; + if (node == NULL || node->tsJoin == NULL || taosArrayGetSize(node->tsJoin) <= 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); } @@ -4429,8 +4445,8 @@ int32_t validateJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; - + SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; + if (node == NULL || node->tagJoin == NULL || taosArrayGetSize(node->tagJoin) <= 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2); } @@ -4442,12 +4458,12 @@ int32_t validateJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { void mergeJoinNodesImpl(int8_t* r, int8_t* p, int16_t* tidx, SJoinNode** nodes, int32_t type) { - SJoinNode *node = nodes[*tidx]; + SJoinNode *node = nodes[*tidx]; SArray* arr = (type == 0) ? node->tsJoin : node->tagJoin; size_t size = taosArrayGetSize(arr); p[*tidx] = 1; - + for (int32_t j = 0; j < size; j++) { int16_t* idx = taosArrayGet(arr, j); r[*idx] = 1; @@ -4460,21 +4476,21 @@ void mergeJoinNodesImpl(int8_t* r, int8_t* p, int16_t* tidx, SJoinNode** nodes, int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { const char* msg1 = "not all join tables have same timestamp"; const char* msg2 = "not all join tables have same tag"; - + int8_t r[TSDB_MAX_JOIN_TABLE_NUM] = {0}; int8_t p[TSDB_MAX_JOIN_TABLE_NUM] = {0}; - + for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) { mergeJoinNodesImpl(r, p, &i, pQueryInfo->tagCond.joinInfo.joinTables, 0); - + taosArrayClear(pQueryInfo->tagCond.joinInfo.joinTables[i]->tsJoin); - + for (int32_t j = 0; j < TSDB_MAX_JOIN_TABLE_NUM; ++j) { if (r[j]) { taosArrayPush(pQueryInfo->tagCond.joinInfo.joinTables[i]->tsJoin, &j); } } - + memset(r, 0, sizeof(r)); memset(p, 0, sizeof(p)); } @@ -4482,20 +4498,20 @@ int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { if (taosArrayGetSize(pQueryInfo->tagCond.joinInfo.joinTables[0]->tsJoin) != pQueryInfo->numOfTables) { return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); } - + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) { mergeJoinNodesImpl(r, p, &i, pQueryInfo->tagCond.joinInfo.joinTables, 1); - + taosArrayClear(pQueryInfo->tagCond.joinInfo.joinTables[i]->tagJoin); - + for (int32_t j = 0; j < TSDB_MAX_JOIN_TABLE_NUM; ++j) { if (r[j]) { taosArrayPush(pQueryInfo->tagCond.joinInfo.joinTables[i]->tagJoin, &j); } } - + memset(r, 0, sizeof(r)); memset(p, 0, sizeof(p)); } @@ -4510,7 +4526,7 @@ int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { } -int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { +int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } @@ -4592,7 +4608,7 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql ret = mergeJoinNodes(pQueryInfo, pSql); if (ret) { goto PARSE_WHERE_EXIT; - } + } } PARSE_WHERE_EXIT: @@ -4721,16 +4737,34 @@ int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return TSDB_CODE_SUCCESS; } -int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySQL) { - SArray* pFillToken = pQuerySQL->fillType; +int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) { + SArray* pFillToken = pSqlNode->fillType; + if (pSqlNode->fillType == NULL) { + return TSDB_CODE_SUCCESS; + } + tVariantListItem* pItem = taosArrayGet(pFillToken, 0); const int32_t START_INTERPO_COL_IDX = 1; - const char* msg = "illegal value or data overflow"; const char* msg1 = "value is expected"; const char* msg2 = "invalid fill option"; const char* msg3 = "top/bottom not support fill"; + const char* msg4 = "illegal value or data overflow"; + const char* msg5 = "fill only available for interval query"; + + if ((!isTimeWindowQuery(pQueryInfo)) && (!tscIsPointInterpQuery(pQueryInfo))) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + } + + /* + * fill options are set at the end position, when all columns are set properly + * the columns may be increased due to group by operation + */ + if (checkQueryRangeForFill(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); @@ -4794,7 +4828,7 @@ int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQ 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), msg); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); } } @@ -4817,8 +4851,8 @@ int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQ size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TOP || pExpr->functionId == TSDB_FUNC_BOTTOM) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_TOP || pExpr->base.functionId == TSDB_FUNC_BOTTOM) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -4843,7 +4877,7 @@ static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) { } } -int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode, SSchema* pSchema) { +int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSchema* pSchema) { const char* msg0 = "only support order by primary timestamp"; const char* msg1 = "invalid column name"; const char* msg2 = "order by primary timestamp or first tag in groupby clause allowed"; @@ -4858,11 +4892,11 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQueryInfo->order.orderColId = 0; return TSDB_CODE_SUCCESS; } - if (pQuerySqlNode->pSortOrder == NULL) { + if (pSqlNode->pSortOrder == NULL) { return TSDB_CODE_SUCCESS; } - SArray* pSortorder = pQuerySqlNode->pSortOrder; + SArray* pSortorder = pSqlNode->pSortOrder; /* * for table query, there is only one or none order option is allowed, which is the @@ -4930,24 +4964,24 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* if (orderByTags) { pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - tVariantListItem* p1 = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->groupbyExpr.orderType = p1->sortOrder; } else if (isTopBottomQuery(pQueryInfo)) { /* order of top/bottom query in interval is not valid */ - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0); - assert(pExpr->functionId == TSDB_FUNC_TS); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + assert(pExpr->base.functionId == TSDB_FUNC_TS); pExpr = tscSqlExprGet(pQueryInfo, 1); - if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - tVariantListItem* p1 = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = p1->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; return TSDB_CODE_SUCCESS; } else { - tVariantListItem* p1 = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = p1->sortOrder; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; @@ -4960,7 +4994,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* } if (s == 2) { - tVariantListItem *pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem *pItem = taosArrayGet(pSqlNode->pSortOrder, 0); if (orderByTags) { pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); pQueryInfo->groupbyExpr.orderType = pItem->sortOrder; @@ -4969,7 +5003,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; } - pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 1); + pItem = taosArrayGet(pSqlNode->pSortOrder, 1); tVariant* pVar2 = &pItem->pVar; SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz}; if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { @@ -4996,21 +5030,21 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* if (isTopBottomQuery(pQueryInfo)) { /* order of top/bottom query in interval is not valid */ - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0); - assert(pExpr->functionId == TSDB_FUNC_TS); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + assert(pExpr->base.functionId == TSDB_FUNC_TS); pExpr = tscSqlExprGet(pQueryInfo, 1); - if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - tVariantListItem* pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; return TSDB_CODE_SUCCESS; } - tVariantListItem* pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = pItem->sortOrder; } @@ -5047,7 +5081,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SSqlCmd* pCmd = &pSql->cmd; SAlterTableInfo* pAlterSQL = pInfo->pAlterInfo; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, DEFAULT_TABLE_INDEX); @@ -5311,7 +5345,7 @@ int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functId = tscSqlExprGet(pQueryInfo, i)->base.functionId; if (!IS_STREAM_QUERY_VALID(aAggs[functId].status)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -5328,14 +5362,14 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t k = 0; k < size; ++k) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k); // projection query on primary timestamp, the selectivity function needs to be present. - if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + 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) { - SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j); - if ((aAggs[pEx->functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) { + SExprInfo* pEx = tscSqlExprGet(pQueryInfo, j); + if ((aAggs[pEx->base.functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) { hasSelectivity = true; break; } @@ -5346,8 +5380,8 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu } } - if ((pExpr->functionId == TSDB_FUNC_PRJ && pExpr->numOfParams == 0) || pExpr->functionId == TSDB_FUNC_DIFF || - pExpr->functionId == TSDB_FUNC_ARITHM) { + if ((pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.numOfParams == 0) || pExpr->base.functionId == TSDB_FUNC_DIFF || + pExpr->base.functionId == TSDB_FUNC_ARITHM) { isProjectionFunction = true; } } @@ -5535,10 +5569,14 @@ bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) { return true; } - return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0); + if (pQueryInfo->window.skey == INT64_MIN || pQueryInfo->window.ekey == INT64_MAX) { + return false; + } + + return !(pQueryInfo->window.skey != pQueryInfo->window.ekey && pQueryInfo->interval.interval == 0); } -int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySqlNode* pQuerySqlNode, SSqlObj* pSql) { +int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIndex, SSqlNode* pSqlNode, SSqlObj* pSql) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); const char* msg0 = "soffset/offset can not be less than 0"; @@ -5546,9 +5584,9 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn const char* msg2 = "slimit/soffset can not apply to projection query"; // handle the limit offset value, validate the limit - pQueryInfo->limit = pQuerySqlNode->limit; + pQueryInfo->limit = pSqlNode->limit; pQueryInfo->clauseLimit = pQueryInfo->limit.limit; - pQueryInfo->slimit = pQuerySqlNode->slimit; + pQueryInfo->slimit = pSqlNode->slimit; tscDebug("0x%"PRIx64" limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql->self, pQueryInfo->limit.limit, pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset); @@ -5733,32 +5771,33 @@ int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDbInfo* pCreateDbSql) { } void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) { - SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex); + SQueryInfo* pParentQueryInfo = tscGetQueryInfo(&pParentObj->cmd, subClauseIndex); if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex); - SSqlExpr* pExpr = NULL; + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, subClauseIndex); + SExprInfo* pExpr = NULL; size_t size = taosArrayGetSize(pQueryInfo->exprList); if (size > 0) { pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1); } - if (pExpr == NULL || pExpr->functionId != TSDB_FUNC_TAG) { + if (pExpr == NULL || pExpr->base.functionId != TSDB_FUNC_TAG) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pParentQueryInfo, tableIndex); - int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid); + uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; + int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, uid); SSchema* pTagSchema = tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, colId); int16_t colIndex = tscGetTagColIndexById(pTableMetaInfo->pTableMeta, colId); - SColumnIndex index = {.tableIndex = 0, .columnIndex = colIndex}; + SColumnIndex index = {.tableIndex = 0, .columnIndex = colIndex}; char* name = pTagSchema->name; int16_t type = pTagSchema->type; int16_t bytes = pTagSchema->bytes; pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(pQueryInfo), bytes, true); - pExpr->colInfo.flag = TSDB_COL_TAG; + pExpr->base.colInfo.flag = TSDB_COL_TAG; // NOTE: tag column does not add to source column list SColumnList ids = {0}; @@ -5766,21 +5805,20 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau int32_t relIndex = index.columnIndex; - pExpr->colInfo.colIndex = relIndex; + pExpr->base.colInfo.colIndex = relIndex; SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0); pColIndex->colIndex = relIndex; - index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex}; - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + tscColumnListInsert(pTableMetaInfo->tagColList, relIndex, uid, pTagSchema); } } } // limit the output to be 1 for each state value -static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) { +static void doLimitOutputNormalColOfGroupby(SExprInfo* pExpr) { int32_t outputRow = 1; - tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT); - pExpr->numOfParams = 1; + tVariantCreateFromBinary(&pExpr->base.param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT); + pExpr->base.numOfParams = 1; } void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) { @@ -5797,7 +5835,7 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) { int32_t numOfFields = tscNumOfFields(pQueryInfo); SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfFields - 1); - doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr); + doLimitOutputNormalColOfGroupby(pInfo->pExpr); pInfo->visible = false; } @@ -5810,25 +5848,25 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TAGPRJ || pExpr->functionId == TSDB_FUNC_TAG) { - pExpr->functionId = TSDB_FUNC_TAG_DUMMY; - tagLength += pExpr->resBytes; - } else if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { - pExpr->functionId = TSDB_FUNC_TS_DUMMY; - tagLength += pExpr->resBytes; + SExprInfo* pExpr = tscSqlExprGet(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; + } else if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + pExpr->base.functionId = TSDB_FUNC_TS_DUMMY; + tagLength += pExpr->base.resBytes; } } SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if ((pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) && - !(pExpr->functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->colInfo.flag))) { - SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex]; - getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64, &pExpr->resType, - &pExpr->resBytes, &pExpr->interBytes, tagLength, isSTable); + SExprInfo* pExpr = tscSqlExprGet(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]; + getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->base.functionId, (int32_t)pExpr->base.param[0].i64, &pExpr->base.resType, + &pExpr->base.resBytes, &pExpr->base.interBytes, tagLength, isSTable); } } } @@ -5837,17 +5875,17 @@ static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_PRJ && (!TSDB_COL_IS_UD_COL(pExpr->colInfo.flag) && (pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX))) { + 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; for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j); - if (pExpr->colInfo.colId == pColIndex->colId) { + if (pExpr->base.colInfo.colId == pColIndex->colId) { qualifiedCol = true; doLimitOutputNormalColOfGroupby(pExpr); - pExpr->numOfParams = 1; + pExpr->base.numOfParams = 1; break; } } @@ -5880,10 +5918,10 @@ static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_PRJ) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_PRJ) { hasColumnPrj = true; - } else if (pExpr->functionId == TSDB_FUNC_TAGPRJ) { + } else if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ) { hasTagPrj = true; } } @@ -5897,12 +5935,12 @@ static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId != TSDB_FUNC_TAGPRJ) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId != TSDB_FUNC_TAGPRJ) { continue; } - if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) { + if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->base.colInfo.colId)) { allInGroupby = false; break; } @@ -5916,9 +5954,9 @@ static void updateTagPrjFunction(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TAGPRJ) { - pExpr->functionId = TSDB_FUNC_TAG; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ) { + pExpr->base.functionId = TSDB_FUNC_TAG; } } } @@ -5939,18 +5977,18 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i); - if (pExpr->functionId == TSDB_FUNC_TAGPRJ || - (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { + SExprInfo* pExpr = taosArrayGetP(pQueryInfo->exprList, i); + if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ || + (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { tagTsColExists = true; // selectivity + ts/tag column break; } } for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i); + SExprInfo* pExpr = taosArrayGetP(pQueryInfo->exprList, i); - int16_t functionId = pExpr->functionId; + int16_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_ARITHM) { continue; @@ -5986,14 +6024,14 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) * Otherwise, return with error code. */ for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int16_t functionId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int16_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ || (aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == 0) { continue; } if ((functionId == TSDB_FUNC_LAST_ROW) || - (functionId == TSDB_FUNC_LAST_DST && (pExpr->colInfo.flag & TSDB_COL_NULL) != 0)) { + (functionId == TSDB_FUNC_LAST_DST && (pExpr->base.colInfo.flag & TSDB_COL_NULL) != 0)) { // do nothing } else { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -6027,34 +6065,30 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) } static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { - const char* msg2 = "interval not allowed in group by normal column"; + const char* msg1 = "interval not allowed in group by normal column"; STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - SSchema s = *tGetTbnameColumnSchema(); SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); - int16_t bytes = 0; - int16_t type = 0; - char* name = NULL; + + SSchema* tagSchema = NULL; + if (!UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { + tagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); + } + + SSchema* s = NULL; for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i); int16_t colIndex = pColIndex->colIndex; + if (colIndex == TSDB_TBNAME_COLUMN_INDEX) { - type = s.type; - bytes = s.bytes; - name = s.name; + s = tGetTbnameColumnSchema(); } else { if (TSDB_COL_IS_TAG(pColIndex->flag)) { - SSchema* tagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - - type = tagSchema[colIndex].type; - bytes = tagSchema[colIndex].bytes; - name = tagSchema[colIndex].name; + s = &tagSchema[colIndex]; } else { - type = pSchema[colIndex].type; - bytes = pSchema[colIndex].bytes; - name = pSchema[colIndex].name; + s = &pSchema[colIndex]; } } @@ -6062,34 +6096,33 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo if (TSDB_COL_IS_TAG(pColIndex->flag)) { SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; - SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, (int32_t)size - pQueryInfo->havingFieldNum, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(pQueryInfo), bytes, true); - - memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName)); - tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName)); - - pExpr->colInfo.flag = TSDB_COL_TAG; + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, s->type, s->bytes, + getNewResColId(pQueryInfo), s->bytes, true); + + memset(pExpr->base.aliasName, 0, sizeof(pExpr->base.aliasName)); + tstrncpy(pExpr->base.aliasName, s->name, sizeof(pExpr->base.aliasName)); + + pExpr->base.colInfo.flag = TSDB_COL_TAG; // NOTE: tag column does not add to source column list - SColumnList ids = getColumnList(1, 0, pColIndex->colIndex); - insertResultField(pQueryInfo, (int32_t)size - pQueryInfo->havingFieldNum, &ids, bytes, (int8_t)type, name, pExpr); + SColumnList ids = createColumnList(1, 0, pColIndex->colIndex); + insertResultField(pQueryInfo, (int32_t)size, &ids, s->bytes, (int8_t)s->type, s->name, pExpr); } else { // if this query is "group by" normal column, time window query is not allowed if (isTimeWindowQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } bool hasGroupColumn = false; for (int32_t j = 0; j < size; ++j) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j); - if (pExpr->colInfo.colId == pColIndex->colId) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, j); + if ((pExpr->base.functionId == TSDB_FUNC_PRJ) && pExpr->base.colInfo.colId == pColIndex->colId) { + hasGroupColumn = true; break; } } - /* - * if the group by column does not required by user, add this column into the final result set - * but invisible to user - */ + //if the group by column does not required by user, add an invisible column into the final result set. if (!hasGroupColumn) { doAddGroupColumnForSubquery(pQueryInfo, i); } @@ -6106,8 +6139,8 @@ static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) { int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfCols; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int32_t functionId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int32_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ) { tagProjection = true; @@ -6115,7 +6148,7 @@ static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) { } if (functionId == TSDB_FUNC_COUNT) { - assert(pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX); + assert(pExpr->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX); tableCounting = true; } } @@ -6146,6 +6179,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { // check if all the tags prj columns belongs to the group by columns if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) { + // It is a groupby aggregate query, the tag project function is not suitable for this case. updateTagPrjFunction(pQueryInfo); return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo); } @@ -6153,18 +6187,18 @@ 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); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int32_t functId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int32_t functId = pExpr->base.functionId; /* * group by normal columns. * Check if the column projection is identical to the group by column or not */ - if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (functId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) { bool qualified = false; for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j); - if (pColIndex->colId == pExpr->colInfo.colId) { + if (pColIndex->colId == pExpr->base.colInfo.colId) { qualified = true; break; } @@ -6180,7 +6214,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (functId == TSDB_FUNC_COUNT && pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -6189,10 +6223,6 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return TSDB_CODE_TSC_INVALID_SQL; } - /* - * group by tag function must be not changed the function name, otherwise, the group operation may fail to - * divide the subset of final result. - */ if (doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } @@ -6207,12 +6237,12 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return checkUpdateTagPrjFunctions(pQueryInfo, pCmd); } } -int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode) { +int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) { const char* msg1 = "only one expression allowed"; const char* msg2 = "invalid expression in select clause"; const char* msg3 = "invalid function"; - SArray* pExprList = pQuerySqlNode->pSelectList; + SArray* pExprList = pSqlNode->pSelNodeList; size_t size = taosArrayGetSize(pExprList); if (size != 1) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -6264,12 +6294,12 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode } SColumnIndex ind = {0}; - SSqlExpr* pExpr1 = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT, + 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); tSqlExprItem* item = taosArrayGet(pExprList, 0); const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[index].name; - tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName)); + tstrncpy(pExpr1->base.aliasName, name, tListLen(pExpr1->base.aliasName)); return TSDB_CODE_SUCCESS; } @@ -6358,8 +6388,8 @@ int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) { } // for debug purpose -void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex); +void tscPrintSelNodeList(SSqlObj* pSql, int32_t subClauseIndex) { + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, subClauseIndex); int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); if (size == 0) { @@ -6373,12 +6403,13 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) { offset += sprintf(str, "num:%d [", size); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); char tmpBuf[1024] = {0}; int32_t tmpLen = 0; tmpLen = - sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].name, pExpr->uid, pExpr->colInfo.colId); + sprintf(tmpBuf, "%s(uid:%" PRIu64 ", %d)", aAggs[pExpr->base.functionId].name, pExpr->base.uid, + pExpr->base.colInfo.colId); if (tmpLen + offset >= totalBufSize - 1) break; @@ -6400,7 +6431,7 @@ int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* p const char* msg1 = "invalid table name"; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; @@ -6459,7 +6490,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { SSqlCmd* pCmd = &pSql->cmd; SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); // two table: the first one is for current table, and the secondary is for the super table. if (pQueryInfo->numOfTables < 2) { @@ -6497,7 +6528,6 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { size_t valSize = taosArrayGetSize(pValList); - // too long tag values will return invalid sql, not be truncated automatically SSchema *pTagSchema = tscGetTableTagSchema(pStableMetaInfo->pTableMeta); STagData *pTag = &pCreateTableInfo->tagdata; @@ -6507,7 +6537,6 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SArray* pNameList = NULL; size_t nameSize = 0; int32_t schemaSize = tscGetNumOfTags(pStableMetaInfo->pTableMeta); @@ -6664,7 +6693,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { const char* msg7 = "time interval is required"; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); assert(pQueryInfo->numOfTables == 1); SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; @@ -6672,18 +6701,18 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { // if sql specifies db, use it, otherwise use default db SStrToken* pName = &(pCreateTable->name); - SQuerySqlNode* pQuerySqlNode = pCreateTable->pSelect; + SSqlNode* pSqlNode = pCreateTable->pSelect; if (tscValidateName(pName) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - SFromInfo* pFromInfo = pInfo->pCreateTableInfo->pSelect->from; - if (pFromInfo == NULL || taosArrayGetSize(pFromInfo->tableList) == 0) { + SRelationInfo* pFromInfo = pInfo->pCreateTableInfo->pSelect->from; + if (pFromInfo == NULL || taosArrayGetSize(pFromInfo->list) == 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); } - STableNamePair* p1 = taosArrayGet(pFromInfo->tableList, 0); + STableNamePair* p1 = taosArrayGet(pFromInfo->list, 0); SStrToken srcToken = {.z = p1->name.z, .n = p1->name.n, .type = TK_STRING}; if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -6700,18 +6729,18 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { } bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); - if (parseSelectClause(&pSql->cmd, 0, pQuerySqlNode->pSelectList, isSTable, false, false) != TSDB_CODE_SUCCESS) { + if (validateSelectNodeList(&pSql->cmd, pQueryInfo, pSqlNode->pSelNodeList, isSTable, false, false) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } - if (pQuerySqlNode->pWhere != NULL) { // query condition in stream computing - if (parseWhereClause(pQueryInfo, &pQuerySqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + if (pSqlNode->pWhere != NULL) { // query condition in stream computing + if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } } // set interval value - if (parseIntervalClause(pSql, pQueryInfo, pQuerySqlNode) != TSDB_CODE_SUCCESS) { + if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } @@ -6729,7 +6758,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { return code; } - if (pQuerySqlNode->sqlstr.n > TSDB_MAX_SAVED_SQL_LEN) { + if (pSqlNode->sqlstr.n > TSDB_MAX_SAVED_SQL_LEN) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); } @@ -6747,12 +6776,12 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { * check if fill operation is available, the fill operation is parsed and executed during query execution, * not here. */ - if (pQuerySqlNode->fillType != NULL) { + if (pSqlNode->fillType != NULL) { if (pQueryInfo->interval.interval == 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } - tVariantListItem* pItem = taosArrayGet(pQuerySqlNode->fillType, 0); + 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))) { @@ -6766,7 +6795,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { return TSDB_CODE_SUCCESS; } -static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { +int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { const char* msg3 = "start(end) time of query range required or time range too large"; if (pQueryInfo->interval.interval == 0) { @@ -6801,9 +6830,50 @@ static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return TSDB_CODE_SUCCESS; } +// TODO normalize the function expression and compare it +int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNodeList, tSqlExpr* pSqlExpr, + SExprInfo** pExpr) { + *pExpr = NULL; - int32_t tscInsertExprFields(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SInternalField** interField) { - tSqlExprItem item = {.pNode = pExpr, .aliasName = NULL, .distinct = false}; + size_t num = taosArrayGetSize(pSelectNodeList); + for(int32_t i = 0; i < num; ++i) { + tSqlExprItem* pItem = taosArrayGet(pSelectNodeList, i); + if (tSqlExprCompare(pItem->pNode, pSqlExpr) == 0) { // exists, not added it, + + SColumnIndex index = COLUMN_INDEX_INITIALIZER; + int32_t functionId = pSqlExpr->functionId; + if (pSqlExpr->pParam == NULL) { + index.columnIndex = 0; + index.tableIndex = 0; + } else { + tSqlExprItem* pParamElem = taosArrayGet(pSqlExpr->pParam, 0); + SStrToken* pToken = &pParamElem->pNode->colInfo; + getColumnIndexByName(pCmd, pToken, pQueryInfo, &index); + } + + size_t numOfNodeInSel = tscSqlExprNumOfExprs(pQueryInfo); + for(int32_t k = 0; k < numOfNodeInSel; ++k) { + SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, k); + + if (pExpr1->base.functionId != functionId) { + continue; + } + + if (pExpr1->base.colInfo.colIndex != index.columnIndex) { + continue; + } + + ++pQueryInfo->havingFieldNum; + *pExpr = pExpr1; + break; + } + + assert(*pExpr != NULL); + return TSDB_CODE_SUCCESS; + } + } + + tSqlExprItem item = {.pNode = pSqlExpr, .aliasName = NULL, .distinct = false}; int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); @@ -6815,129 +6885,51 @@ static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { ++pQueryInfo->havingFieldNum; size_t n = tscSqlExprNumOfExprs(pQueryInfo); - SSqlExpr* pSqlExpr = tscSqlExprGet(pQueryInfo, (int32_t)n - 1); + *pExpr = tscSqlExprGet(pQueryInfo, (int32_t)n - 1); - int32_t slot = tscNumOfFields(pQueryInfo) - 1; - SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot); - pInfo->visible = false; - - if (pInfo->pFieldFilters == NULL) { - SExprFilter* pFieldFilters = calloc(1, sizeof(SExprFilter)); - if (pFieldFilters == NULL) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - - SColumn* pFilters = calloc(1, sizeof(SColumn)); - if (pFilters == NULL) { - tfree(pFieldFilters); - - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - - pFieldFilters->pFilters = pFilters; - pFieldFilters->pSqlExpr = pSqlExpr; - pSqlExpr->pFilter = pFilters; - pInfo->pFieldFilters = pFieldFilters; - } - - pInfo->pFieldFilters->pExpr = pExpr; - - *interField = pInfo; + SInternalField* pField = taosArrayGet(pQueryInfo->fieldsInfo.internalField, n - 1); + pField->visible = false; return TSDB_CODE_SUCCESS; } -int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SInternalField** pField) { - SInternalField* pInfo = NULL; - - for (int32_t i = pQueryInfo->havingFieldNum - 1; i >= 0; --i) { - pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, pQueryInfo->fieldsInfo.numOfOutput - 1 - i); - - if (pInfo->pFieldFilters && 0 == tSqlExprCompare(pInfo->pFieldFilters->pExpr, pExpr)) { - *pField = pInfo; - return TSDB_CODE_SUCCESS; - } - } - - int32_t ret = tscInsertExprFields(pCmd, pQueryInfo, pExpr, &pInfo); - if (ret) { - return ret; - } - - *pField = pInfo; - - return TSDB_CODE_SUCCESS; -} - -static int32_t genExprFilter(SExprFilter * exprFilter) { - exprFilter->fp = taosArrayInit(4, sizeof(__filter_func_t)); - if (exprFilter->fp == NULL) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - - for (int32_t i = 0; i < exprFilter->pFilters->numOfFilters; ++i) { - SColumnFilterInfo *filterInfo = &exprFilter->pFilters->filterInfo[i]; - - int32_t lower = filterInfo->lowerRelOptr; - int32_t upper = filterInfo->upperRelOptr; - if (lower == TSDB_RELATION_INVALID && upper == TSDB_RELATION_INVALID) { - tscError("invalid rel optr"); - return TSDB_CODE_TSC_APP_ERROR; - } - - __filter_func_t ffp = getFilterOperator(lower, upper); - if (ffp == NULL) { - tscError("invalid filter info"); - return TSDB_CODE_TSC_APP_ERROR; - } - - taosArrayPush(exprFilter->fp, &ffp); - } - - return TSDB_CODE_SUCCESS; -} - -static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, int32_t sqlOptr) { +static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNodeList, tSqlExpr* pExpr, int32_t sqlOptr) { const char* msg1 = "non binary column not support like operator"; - const char* msg2 = "invalid operator for binary column in having clause"; + const char* msg2 = "invalid operator for binary column in having clause"; const char* msg3 = "invalid operator for bool column in having clause"; - SColumn* pColumn = NULL; SColumnFilterInfo* pColFilter = NULL; - SInternalField* pInfo = NULL; - + // TODO refactor: validate the expression /* * in case of TK_AND filter condition, we first find the corresponding column and build the query condition together * the already existed condition. */ + SExprInfo *expr = NULL; if (sqlOptr == TK_AND) { - int32_t ret = tscGetExprFilters(pCmd, pQueryInfo, pExpr->pLeft, &pInfo); + int32_t ret = tscGetExprFilters(pCmd, pQueryInfo, pSelectNodeList, pExpr->pLeft, &expr); if (ret) { return ret; } - pColumn = pInfo->pFieldFilters->pFilters; - // this is a new filter condition on this column - if (pColumn->numOfFilters == 0) { - pColFilter = addColumnFilterInfo(pColumn); + if (expr->base.flist.numOfFilters == 0) { + pColFilter = addColumnFilterInfo(&expr->base.flist); } else { // update the existed column filter information, find the filter info here - pColFilter = &pColumn->filterInfo[0]; + pColFilter = &expr->base.flist.filterInfo[0]; } if (pColFilter == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } } else if (sqlOptr == TK_OR) { - int32_t ret = tscGetExprFilters(pCmd, pQueryInfo, pExpr->pLeft, &pInfo); + int32_t ret = tscGetExprFilters(pCmd, pQueryInfo, pSelectNodeList, pExpr->pLeft, &expr); if (ret) { return ret; } - pColumn = pInfo->pFieldFilters->pFilters; - // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2" - pColFilter = addColumnFilterInfo(pColumn); + // TODO refactor + pColFilter = addColumnFilterInfo(&expr->base.flist); if (pColFilter == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } @@ -6946,23 +6938,23 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t } pColFilter->filterstr = - ((pInfo->field.type == TSDB_DATA_TYPE_BINARY || pInfo->field.type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0); + ((expr->base.resType == TSDB_DATA_TYPE_BINARY || expr->base.resType == TSDB_DATA_TYPE_NCHAR) ? 1 : 0); if (pColFilter->filterstr) { if (pExpr->tokenId != TK_EQ - && pExpr->tokenId != TK_NE - && pExpr->tokenId != TK_ISNULL - && pExpr->tokenId != TK_NOTNULL - && pExpr->tokenId != TK_LIKE - ) { + && pExpr->tokenId != TK_NE + && pExpr->tokenId != TK_ISNULL + && pExpr->tokenId != TK_NOTNULL + && pExpr->tokenId != TK_LIKE + ) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } } else { if (pExpr->tokenId == TK_LIKE) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - - if (pInfo->field.type == TSDB_DATA_TYPE_BOOL) { + + if (expr->base.resType == TSDB_DATA_TYPE_BOOL) { if (pExpr->tokenId != TK_EQ && pExpr->tokenId != TK_NE) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } @@ -6972,15 +6964,16 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - int32_t ret = doExtractColumnFilterInfo(pCmd, pQueryInfo, pTableMeta, pColFilter, pInfo->field.type, pExpr); + int32_t ret = doExtractColumnFilterInfo(pCmd, pQueryInfo, pTableMeta->tableInfo.precision, pColFilter, + expr->base.resType, pExpr); if (ret) { - return ret; + return ret; } - - return genExprFilter(pInfo->pFieldFilters); + + return TSDB_CODE_SUCCESS; } -int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, int32_t parentOptr) { +int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNodeList, tSqlExpr* pExpr, int32_t parentOptr) { if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } @@ -6991,12 +6984,12 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, in tSqlExpr* pRight = pExpr->pRight; if (pExpr->tokenId == TK_AND || pExpr->tokenId == TK_OR) { - int32_t ret = getHavingExpr(pCmd, pQueryInfo, pExpr->pLeft, pExpr->tokenId); + int32_t ret = getHavingExpr(pCmd, pQueryInfo, pSelectNodeList, pExpr->pLeft, pExpr->tokenId); if (ret != TSDB_CODE_SUCCESS) { return ret; } - return getHavingExpr(pCmd, pQueryInfo, pExpr->pRight, pExpr->tokenId); + return getHavingExpr(pCmd, pQueryInfo, pSelectNodeList, pExpr->pRight, pExpr->tokenId); } if (pLeft == NULL || pRight == NULL) { @@ -7009,14 +7002,12 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, in exchangeExpr(pExpr); - pLeft = pExpr->pLeft; + pLeft = pExpr->pLeft; pRight = pExpr->pRight; - - if (pLeft->type != SQL_NODE_SQLFUNCTION) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - + if (pRight->type != SQL_NODE_VALUE) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -7025,37 +7016,35 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, in return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - //if (pLeft->pParam == NULL || pLeft->pParam->nExpr < 1) { - // return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); - //} - if (pLeft->pParam) { size_t size = taosArrayGetSize(pLeft->pParam); for (int32_t i = 0; i < size; i++) { - tSqlExprItem* pParamElem = taosArrayGet(pLeft->pParam, i); - if (pParamElem->pNode->tokenId != TK_ALL && - pParamElem->pNode->tokenId != TK_ID && - pParamElem->pNode->tokenId != TK_STRING && - pParamElem->pNode->tokenId != TK_INTEGER && - pParamElem->pNode->tokenId != TK_FLOAT) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); - } - - if (pParamElem->pNode->tokenId == TK_ID && (pParamElem->pNode->colInfo.z == NULL && pParamElem->pNode->colInfo.n == 0)) { + tSqlExprItem* pParamItem = taosArrayGet(pLeft->pParam, i); + + tSqlExpr* pExpr1 = pParamItem->pNode; + if (pExpr1->tokenId != TK_ALL && + pExpr1->tokenId != TK_ID && + pExpr1->tokenId != TK_STRING && + pExpr1->tokenId != TK_INTEGER && + pExpr1->tokenId != TK_FLOAT) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - if (pParamElem->pNode->tokenId == TK_ID) { + if (pExpr1->tokenId == TK_ID && (pExpr1->colInfo.z == NULL && pExpr1->colInfo.n == 0)) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + if (pExpr1->tokenId == TK_ID) { SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) { + if ((getColumnIndexByName(pCmd, &pExpr1->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; - - if (index.columnIndex <= 0 || - index.columnIndex >= tscGetNumOfColumns(pTableMeta)) { + + if (index.columnIndex <= 0 || + index.columnIndex >= tscGetNumOfColumns(pTableMeta)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -7067,12 +7056,11 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, in return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - return handleExprInHavingClause(pCmd, pQueryInfo, pExpr, parentOptr); + return handleExprInHavingClause(pCmd, pQueryInfo, pSelectNodeList, pExpr, parentOptr); } - - -int32_t parseHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* pCmd, bool isSTable, int32_t joinQuery, int32_t timeWindowQuery) { +int32_t validateHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* pCmd, SArray* pSelectNodeList, + int32_t joinQuery, int32_t timeWindowQuery) { const char* msg1 = "having only works with group by"; const char* msg2 = "functions or others can not be mixed up"; const char* msg3 = "invalid expression in having clause"; @@ -7094,8 +7082,8 @@ int32_t parseHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* pCmd } int32_t ret = 0; - - if ((ret = getHavingExpr(pCmd, pQueryInfo, pExpr, TK_AND)) != TSDB_CODE_SUCCESS) { + + if ((ret = getHavingExpr(pCmd, pQueryInfo, pSelectNodeList, pExpr, TK_AND)) != TSDB_CODE_SUCCESS) { return ret; } @@ -7107,39 +7095,113 @@ int32_t parseHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* pCmd return TSDB_CODE_SUCCESS; } +static int32_t doLoadAllTableMeta(SSqlObj* pSql, int32_t index, 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"; + int32_t code = TSDB_CODE_SUCCESS; + SSqlCmd* pCmd = &pSql->cmd; + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, index); + for (int32_t i = 0; i < numOfTables; ++i) { + if (pQueryInfo->numOfTables <= i) { // more than one table + tscAddEmptyMetaInfo(pQueryInfo); + } -int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t index) { - assert(pQuerySqlNode != NULL && (pQuerySqlNode->from == NULL || taosArrayGetSize(pQuerySqlNode->from->tableList) > 0)); + STableNamePair *item = taosArrayGet(pSqlNode->from->list, i); + SStrToken *oriName = &item->name; + + if (oriName->type == TK_INTEGER || oriName->type == TK_FLOAT) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + tscDequoteAndTrimToken(oriName); + if (tscValidateName(oriName) != TSDB_CODE_SUCCESS) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); + code = tscSetTableFullName(pTableMetaInfo, oriName, pSql); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + SStrToken* aliasName = &item->aliasName; + if (TPARSER_HAS_TOKEN(*aliasName)) { + if (aliasName->type == TK_INTEGER || aliasName->type == TK_FLOAT) { + return invalidSqlErrMsg(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); + } + + strncpy(pTableMetaInfo->aliasName, aliasName->z, aliasName->n); + } else { + strncpy(pTableMetaInfo->aliasName, tNameGetTableName(&pTableMetaInfo->name), + tListLen(pTableMetaInfo->aliasName)); + } + + code = tscGetTableMeta(pSql, pTableMetaInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + + return TSDB_CODE_SUCCESS; +} + +static STableMeta* extractTempTableMetaFromNestQuery(SQueryInfo* pUpstream) { + int32_t numOfColumns = pUpstream->fieldsInfo.numOfOutput; + + STableMeta* meta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * numOfColumns); + meta->tableType = TSDB_TEMP_TABLE; + + STableComInfo *info = &meta->tableInfo; + info->numOfColumns = numOfColumns; + info->numOfTags = 0; + + int32_t n = 0; + for(int32_t i = 0; i < numOfColumns; ++i) { + SInternalField* pField = tscFieldInfoGetInternalField(&pUpstream->fieldsInfo, i); + if (pField->visible) { + meta->schema[n].bytes = pField->field.bytes; + meta->schema[n].type = pField->field.type; + meta->schema[n].colId = pField->pExpr->base.resColId; + tstrncpy(meta->schema[n].name, pField->pExpr->base.aliasName, TSDB_COL_NAME_LEN); + n += 1; + } + } + + return meta; +} + +int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { + assert(pSqlNode != NULL && (pSqlNode->from == NULL || taosArrayGetSize(pSqlNode->from->list) > 0)); - const char* msg0 = "invalid table name"; const char* msg1 = "point interpolation query needs timestamp"; - const char* msg2 = "fill only available for interval query"; + 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"; int32_t code = TSDB_CODE_SUCCESS; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, index); - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, index); + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (pTableMetaInfo == NULL) { pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo); } assert(pCmd->clauseIndex == index); - // too many result columns not support order by in query - if (taosArrayGetSize(pQuerySqlNode->pSelectList) > TSDB_MAX_COLUMNS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); - } - /* * handle the sql expression without from subclause * select current_database(); @@ -7147,199 +7209,177 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i * select client_version(); * select server_state(); */ - if (pQuerySqlNode->from == NULL) { - assert(pQuerySqlNode->fillType == NULL && pQuerySqlNode->pGroupby == NULL && pQuerySqlNode->pWhere == NULL && - pQuerySqlNode->pSortOrder == NULL); - return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySqlNode); + if (pSqlNode->from == NULL) { + assert(pSqlNode->fillType == NULL && pSqlNode->pGroupby == NULL && pSqlNode->pWhere == NULL && + pSqlNode->pSortOrder == NULL); + return doLocalQueryProcess(pCmd, pQueryInfo, pSqlNode); } - size_t fromSize = taosArrayGetSize(pQuerySqlNode->from->tableList); - if (fromSize > TSDB_MAX_JOIN_TABLE_NUM * 2) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); - } + 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); - pQueryInfo->command = TSDB_SQL_SELECT; - - // set all query tables, which are maybe more than one. - for (int32_t i = 0; i < fromSize; ++i) { - STableNamePair* item = taosArrayGet(pQuerySqlNode->from->tableList, i); - SStrToken* pTableItem = &item->name; - - if (pTableItem->type != TSDB_DATA_TYPE_BINARY) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + code = validateSqlNode(pSql, p, 0); + if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + return code; } - tscDequoteAndTrimToken(pTableItem); - - SStrToken tableName = {.z = pTableItem->z, .n = pTableItem->n, .type = TK_STRING}; - if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); - } - - if (pQueryInfo->numOfTables <= i) { // more than one table - tscAddEmptyMetaInfo(pQueryInfo); - } - - STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i); - code = tscSetTableFullName(pTableMetaInfo1, pTableItem, pSql); if (code != TSDB_CODE_SUCCESS) { return code; } - SStrToken* aliasName = &item->aliasName; - if (TPARSER_HAS_TOKEN(*aliasName)) { - if (aliasName->type != TSDB_DATA_TYPE_BINARY) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); - } + pQueryInfo = pCmd->pQueryInfo[0]; - tscDequoteAndTrimToken(aliasName); + SQueryInfo* current = calloc(1, sizeof(SQueryInfo)); - SStrToken aliasName1 = {.z = aliasName->z, .n = aliasName->n, .type = TK_STRING}; - if (tscValidateName(&aliasName1) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); - } + tscInitQueryInfo(current); + taosArrayPush(current->pUpstream, &pQueryInfo); - if (aliasName1.n >= TSDB_TABLE_NAME_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); - } + STableMeta* pTableMeta = extractTempTableMetaFromNestQuery(pQueryInfo); + STableMetaInfo* pTableMetaInfo1 = calloc(1, sizeof(STableMetaInfo)); + pTableMetaInfo1->pTableMeta = pTableMeta; - strncpy(pTableMetaInfo1->aliasName, aliasName1.z, aliasName1.n); - } else { - strncpy(pTableMetaInfo1->aliasName, tNameGetTableName(&pTableMetaInfo1->name), tListLen(pTableMetaInfo1->aliasName)); + current->pTableMetaInfo = calloc(1, POINTER_BYTES); + current->pTableMetaInfo[0] = pTableMetaInfo1; + current->numOfTables = 1; + current->order = pQueryInfo->order; + + pCmd->pQueryInfo[0] = current; + pQueryInfo->pDownstream = current; + + if (validateSelectNodeList(pCmd, current, pSqlNode->pSelNodeList, false, false, false) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; } - code = tscGetTableMeta(pSql, pTableMetaInfo1); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } - - assert(pQueryInfo->numOfTables == taosArrayGetSize(pQuerySqlNode->from->tableList)); - bool isSTable = false; - - if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - isSTable = true; - code = tscGetSTableVgroupInfo(pSql, index); - 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); - } + pQueryInfo->command = TSDB_SQL_SELECT; - // parse the group by clause in the first place - if (parseGroupbyClause(pQueryInfo, pQuerySqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } - - // set where info - STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - - if (pQuerySqlNode->pWhere != NULL) { - if (parseWhereClause(pQueryInfo, &pQuerySqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } - - pQuerySqlNode->pWhere = NULL; - if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) { - pQueryInfo->window.skey = pQueryInfo->window.skey / 1000; - pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000; - } - } else { // set the time rang - if (taosArrayGetSize(pQuerySqlNode->from->tableList) > 1) { // it is a join query, no where clause is not allowed. - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "condition missing for join query "); - } - } - - int32_t joinQuery = (pQuerySqlNode->from != NULL && taosArrayGetSize(pQuerySqlNode->from->tableList) > 1); - int32_t timeWindowQuery = - (TPARSER_HAS_TOKEN(pQuerySqlNode->interval.interval) || TPARSER_HAS_TOKEN(pQuerySqlNode->sessionVal.gap)); - - if (parseSelectClause(pCmd, index, pQuerySqlNode->pSelectList, isSTable, joinQuery, timeWindowQuery) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } - - // set order by info - if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } - - // set interval value - if (parseIntervalClause(pSql, pQueryInfo, pQuerySqlNode) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } else { - if (isTimeWindowQuery(pQueryInfo) && - (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) { - return TSDB_CODE_TSC_INVALID_SQL; - } - } - - // parse the having clause in the first place - if (parseHavingClause(pQueryInfo, pQuerySqlNode->pHaving, pCmd, isSTable, joinQuery, timeWindowQuery) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } - - /* - * transfer sql functions that need secondary merge into another format - * in dealing with super table queries such as: count/first/last - */ - if (isSTable) { - tscTansformFuncForSTableQuery(pQueryInfo); - - if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) { - return TSDB_CODE_TSC_INVALID_SQL; - } - } - - if (parseSessionClause(pCmd, pQueryInfo, pQuerySqlNode) != 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; - return TSDB_CODE_SUCCESS; - } - - if (!hasTimestampForPointInterpQuery(pQueryInfo)) { - return invalidSqlErrMsg(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); - } - } - - if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySqlNode, pSql)) != TSDB_CODE_SUCCESS) { - return code; - } - - if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) { - return code; - } - - updateLastScanOrderIfNeeded(pQueryInfo); - tscFieldInfoUpdateOffset(pQueryInfo); - - if (pQuerySqlNode->fillType != NULL) { - if (pQueryInfo->interval.interval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) { + size_t fromSize = taosArrayGetSize(pSqlNode->from->list); + if (fromSize > TSDB_MAX_JOIN_TABLE_NUM) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - /* - * fill options are set at the end position, when all columns are set properly - * the columns may be increased due to group by operation - */ - if ((code = checkQueryRangeForFill(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) { + // set all query tables, which are maybe more than one. + code = doLoadAllTableMeta(pSql, index, pSqlNode, (int32_t) fromSize); + if (code != TSDB_CODE_SUCCESS) { return code; } - if ((code = parseFillClause(pCmd, pQueryInfo, pQuerySqlNode)) != TSDB_CODE_SUCCESS) { + 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); + } + + // parse the group by clause in the first place + if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + // set where info + STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); + + if (pSqlNode->pWhere != NULL) { + if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + pSqlNode->pWhere = NULL; + if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) { + 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 "); + } + } + + int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1); + int32_t timeWindowQuery = + (TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)); + + if (validateSelectNodeList(pCmd, pQueryInfo, pSqlNode->pSelNodeList, isSTable, joinQuery, timeWindowQuery) != + TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + // set order by info + if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != + TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + // set interval value + if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } else { + if (isTimeWindowQuery(pQueryInfo) && + (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) { + return TSDB_CODE_TSC_INVALID_SQL; + } + } + + // 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; + } + + /* + * transfer sql functions that need secondary merge into another format + * in dealing with super table queries such as: count/first/last + */ + if (isSTable) { + tscTansformFuncForSTableQuery(pQueryInfo); + + if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) { + return TSDB_CODE_TSC_INVALID_SQL; + } + } + + 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; + return TSDB_CODE_SUCCESS; + } + + if (!hasTimestampForPointInterpQuery(pQueryInfo)) { + return invalidSqlErrMsg(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); + } + } + + if ((code = validateLimitNode(pCmd, pQueryInfo, index, pSqlNode, pSql)) != TSDB_CODE_SUCCESS) { + return code; + } + + if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) { + return code; + } + + updateLastScanOrderIfNeeded(pQueryInfo); + tscFieldInfoUpdateOffset(pQueryInfo); + + if ((code = validateFillNode(pCmd, pQueryInfo, pSqlNode)) != TSDB_CODE_SUCCESS) { return code; } } @@ -7347,7 +7387,7 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i return TSDB_CODE_SUCCESS; // Does not build query message here } -int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid) { +int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, uint64_t *uid) { tExprNode* pLeft = NULL; tExprNode* pRight= NULL; @@ -7361,6 +7401,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS if (pSqlExpr->pRight != NULL) { int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid); if (ret != TSDB_CODE_SUCCESS) { + tExprTreeDestroy(pLeft, NULL); return ret; } } @@ -7370,7 +7411,9 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS return TSDB_CODE_SUCCESS; } - if (pSqlExpr->pLeft == NULL) { + if (pSqlExpr->pLeft == NULL) { // it is the leaf node + assert(pSqlExpr->pRight == NULL); + if (pSqlExpr->type == SQL_NODE_VALUE) { *pExpr = calloc(1, sizeof(tExprNode)); (*pExpr)->nodeType = TSQL_NODE_VALUE; @@ -7389,15 +7432,15 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* p1 = taosArrayGetP(pQueryInfo->exprList, i); + SExprInfo* p1 = taosArrayGetP(pQueryInfo->exprList, i); - if (strcmp((*pExpr)->pSchema->name, p1->aliasName) == 0) { - (*pExpr)->pSchema->type = (uint8_t)p1->resType; - (*pExpr)->pSchema->bytes = p1->resBytes; - (*pExpr)->pSchema->colId = p1->resColId; + if (strcmp((*pExpr)->pSchema->name, p1->base.aliasName) == 0) { + (*pExpr)->pSchema->type = (uint8_t)p1->base.resType; + (*pExpr)->pSchema->bytes = p1->base.resBytes; + (*pExpr)->pSchema->colId = p1->base.resColId; if (uid != NULL) { - *uid = p1->uid; + *uid = p1->base.uid; } break; @@ -7476,7 +7519,7 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) { size_t numOfCols = taosArrayGetSize(pQueryInfo->colList); for (int32_t i = 0; i < numOfCols; ++i) { SColumn* pCol = taosArrayGetP(pQueryInfo->colList, i); - if (pCol->numOfFilters > 0) { + if (pCol->info.flist.numOfFilters > 0) { return true; } } @@ -7484,10 +7527,3 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) { return false; } - - - - - - - diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index d9405f300a..e570701ecd 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -24,6 +24,7 @@ #include "tsclient.h" #include "ttimer.h" #include "tlockfree.h" +#include "qPlan.h" int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo) = {0}; @@ -269,7 +270,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { assert(pHB->self == pObj->hbrid); pHB->retry = 0; - int32_t code = tscProcessSql(pHB); + int32_t code = tscBuildAndSendRequest(pHB, NULL); taosReleaseRef(tscObjRef, pObj->hbrid); if (code != TSDB_CODE_SUCCESS) { @@ -334,7 +335,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { return; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); 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); @@ -457,19 +458,16 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { (*pSql->fp)(pSql->param, pSql, rpcMsg->code); } - - if (shouldFree) { // in case of table-meta/vgrouplist query, automatically free it taosRemoveRef(tscObjRef, handle); tscDebug("0x%"PRIx64" sqlObj is automatically freed", pSql->self); } taosReleaseRef(tscObjRef, handle); - rpcFreeCont(rpcMsg->pCont); } -int doProcessSql(SSqlObj *pSql) { +int doBuildAndSendMsg(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; @@ -501,13 +499,16 @@ int doProcessSql(SSqlObj *pSql) { return TSDB_CODE_SUCCESS; } -int tscProcessSql(SSqlObj *pSql) { +int tscBuildAndSendRequest(SSqlObj *pSql, SQueryInfo* pQueryInfo) { char name[TSDB_TABLE_FNAME_LEN] = {0}; SSqlCmd *pCmd = &pSql->cmd; uint32_t type = 0; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + if (pQueryInfo == NULL) { + pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + } + STableMetaInfo *pTableMetaInfo = NULL; if (pQueryInfo != NULL) { @@ -532,15 +533,16 @@ int tscProcessSql(SSqlObj *pSql) { return (*tscProcessMsgRsp[pCmd->command])(pSql); } - return doProcessSql(pSql); + return doBuildAndSendMsg(pSql); } int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg *) pSql->cmd.payload; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); - pRetrieveMsg->free = htons(pQueryInfo->type); - pRetrieveMsg->qId = htobe64(pSql->res.qId); + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(&pSql->cmd); + + pRetrieveMsg->free = htons(pQueryInfo->type); + pRetrieveMsg->qId = htobe64(pSql->res.qId); // todo valid the vgroupId at the client side STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -579,7 +581,7 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; char* pMsg = pSql->cmd.payload; @@ -618,12 +620,12 @@ static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql, int32_t clauseIndex) { const static int32_t MIN_QUERY_MSG_PKT_SIZE = TSDB_MAX_BYTES_PER_ROW * 5; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo)); size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs * 2); + 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; @@ -647,8 +649,8 @@ static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql, int32_t clauseIndex) { tableSerialize + sqlLen + 4096 + pQueryInfo->bufLen; } -static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char *pMsg, int32_t *succeed) { - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0); +static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, char *pMsg, + int32_t *succeed) { TSKEY dfltKey = htobe64(pQueryMsg->window.skey); STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; @@ -727,318 +729,214 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char return pMsg; } +// TODO refactor +static int32_t serializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t numOfFilters, char** pMsg) { + // append the filter information after the basic column information + for (int32_t f = 0; f < numOfFilters; ++f) { + SColumnFilterInfo *pColFilter = &pColFilters[f]; + + SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)(*pMsg); + pFilterMsg->filterstr = htons(pColFilter->filterstr); + + (*pMsg) += sizeof(SColumnFilterInfo); + + if (pColFilter->filterstr) { + pFilterMsg->len = htobe64(pColFilter->len); + memcpy(*pMsg, (void *)pColFilter->pz, (size_t)(pColFilter->len + 1)); + (*pMsg) += (pColFilter->len + 1); // append the additional filter binary info + } else { + pFilterMsg->lowerBndi = htobe64(pColFilter->lowerBndi); + pFilterMsg->upperBndi = htobe64(pColFilter->upperBndi); + } + + pFilterMsg->lowerRelOptr = htons(pColFilter->lowerRelOptr); + pFilterMsg->upperRelOptr = htons(pColFilter->upperRelOptr); + + if (pColFilter->lowerRelOptr == TSDB_RELATION_INVALID && pColFilter->upperRelOptr == TSDB_RELATION_INVALID) { + tscError("invalid filter info"); + return TSDB_CODE_TSC_INVALID_SQL; + } + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo, char** pMsg, int64_t id, bool validateColumn) { + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + + // the queried table has been removed and a new table with the same name has already been created already + // return error msg + if (pExpr->uid != pTableMeta->id.uid) { + tscError("0x%"PRIx64" table has already been destroyed", id); + return TSDB_CODE_TSC_INVALID_TABLE_NAME; + } + + 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; + } + + assert(pExpr->resColId < 0); + SSqlExpr* pSqlExpr = (SSqlExpr *)(*pMsg); + + SColIndex* pIndex = &pSqlExpr->colInfo; + + pIndex->colId = htons(pExpr->colInfo.colId); + pIndex->colIndex = htons(pExpr->colInfo.colIndex); + pIndex->flag = htons(pExpr->colInfo.flag); + pSqlExpr->uid = htobe64(pExpr->uid); + pSqlExpr->colType = htons(pExpr->colType); + pSqlExpr->colBytes = htons(pExpr->colBytes); + pSqlExpr->resType = htons(pExpr->resType); + pSqlExpr->resBytes = htons(pExpr->resBytes); + pSqlExpr->functionId = htons(pExpr->functionId); + pSqlExpr->numOfParams = htons(pExpr->numOfParams); + pSqlExpr->resColId = htons(pExpr->resColId); + pSqlExpr->flist.numOfFilters = htons(pExpr->flist.numOfFilters); + + (*pMsg) += sizeof(SSqlExpr); + for (int32_t j = 0; j < pExpr->numOfParams; ++j) { // todo add log + pSqlExpr->param[j].nType = htons((uint16_t)pExpr->param[j].nType); + pSqlExpr->param[j].nLen = htons(pExpr->param[j].nLen); + + if (pExpr->param[j].nType == TSDB_DATA_TYPE_BINARY) { + memcpy((*pMsg), pExpr->param[j].pz, pExpr->param[j].nLen); + (*pMsg) += pExpr->param[j].nLen; + } else { + pSqlExpr->param[j].i64 = htobe64(pExpr->param[j].i64); + } + } + + serializeColFilterInfo(pExpr->flist.filterInfo, pExpr->flist.numOfFilters, pMsg); + + return TSDB_CODE_SUCCESS; +} + int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; + int32_t code = TSDB_CODE_SUCCESS; int32_t size = tscEstimateQueryMsgSize(pSql, pCmd->clauseIndex); if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) { - tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self); + tscError("%p failed to malloc for query msg", pSql); return TSDB_CODE_TSC_INVALID_SQL; // todo add test for this } - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); + + SQueryAttr query = {{0}}; + tscCreateQueryFromQueryInfo(pQueryInfo, &query, pSql); + + SArray* tableScanOperator = createTableScanPlan(&query); + SArray* queryOperator = createExecOperatorPlan(&query); + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; - size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList); - if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) { - tscError("0x%"PRIx64" illegal value of numOfCols in query msg: %" PRIu64 ", table cols:%d", pSql->self, (uint64_t)numOfSrcCols, - tscGetNumOfColumns(pTableMeta)); - - return TSDB_CODE_TSC_INVALID_SQL; - } - - if (pQueryInfo->interval.interval < 0) { - tscError("0x%"PRIx64" illegal value of aggregation time interval in query msg: %" PRId64, pSql->self, (int64_t)pQueryInfo->interval.interval); - return TSDB_CODE_TSC_INVALID_SQL; - } - - if (pQueryInfo->groupbyExpr.numOfGroupCols < 0) { - tscError("0x%"PRIx64" illegal value of numOfGroupCols in query msg: %d", pSql->self, pQueryInfo->groupbyExpr.numOfGroupCols); - return TSDB_CODE_TSC_INVALID_SQL; - } - SQueryTableMsg *pQueryMsg = (SQueryTableMsg *)pCmd->payload; tstrncpy(pQueryMsg->version, version, tListLen(pQueryMsg->version)); - int32_t numOfTags = (int32_t)taosArrayGetSize(pTableMetaInfo->tagColList); + int32_t numOfTags = query.numOfTags; int32_t sqlLen = (int32_t) strlen(pSql->sqlstr); - if (pQueryInfo->order.order == TSDB_ORDER_ASC) { - pQueryMsg->window.skey = htobe64(pQueryInfo->window.skey); - pQueryMsg->window.ekey = htobe64(pQueryInfo->window.ekey); + if (taosArrayGetSize(tableScanOperator) == 0) { + pQueryMsg->tableScanOperator = htonl(-1); } else { - pQueryMsg->window.skey = htobe64(pQueryInfo->window.ekey); - pQueryMsg->window.ekey = htobe64(pQueryInfo->window.skey); + int32_t* tablescanOp = taosArrayGet(tableScanOperator, 0); + pQueryMsg->tableScanOperator = htonl(*tablescanOp); } - pQueryMsg->order = htons(pQueryInfo->order.order); - pQueryMsg->orderColId = htons(pQueryInfo->order.orderColId); - pQueryMsg->fillType = htons(pQueryInfo->fillType); - pQueryMsg->limit = htobe64(pQueryInfo->limit.limit); - pQueryMsg->offset = htobe64(pQueryInfo->limit.offset); - pQueryMsg->numOfCols = htons((int16_t)taosArrayGetSize(pQueryInfo->colList)); - pQueryMsg->interval.interval = htobe64(pQueryInfo->interval.interval); - pQueryMsg->interval.sliding = htobe64(pQueryInfo->interval.sliding); - pQueryMsg->interval.offset = htobe64(pQueryInfo->interval.offset); - pQueryMsg->interval.intervalUnit = pQueryInfo->interval.intervalUnit; - pQueryMsg->interval.slidingUnit = pQueryInfo->interval.slidingUnit; - pQueryMsg->interval.offsetUnit = pQueryInfo->interval.offsetUnit; + pQueryMsg->window.skey = htobe64(query.window.skey); + pQueryMsg->window.ekey = htobe64(query.window.ekey); + + pQueryMsg->order = htons(query.order.order); + pQueryMsg->orderColId = htons(query.order.orderColId); + pQueryMsg->fillType = htons(query.fillType); + pQueryMsg->limit = htobe64(query.limit.limit); + pQueryMsg->offset = htobe64(query.limit.offset); + pQueryMsg->numOfCols = htons(query.numOfCols); + + pQueryMsg->interval.interval = htobe64(query.interval.interval); + pQueryMsg->interval.sliding = htobe64(query.interval.sliding); + pQueryMsg->interval.offset = htobe64(query.interval.offset); + pQueryMsg->interval.intervalUnit = query.interval.intervalUnit; + pQueryMsg->interval.slidingUnit = query.interval.slidingUnit; + pQueryMsg->interval.offsetUnit = query.interval.offsetUnit; + + pQueryMsg->stableQuery = query.stableQuery; + pQueryMsg->topBotQuery = query.topBotQuery; + pQueryMsg->groupbyColumn = query.groupbyColumn; + pQueryMsg->hasTagResults = query.hasTagResults; + pQueryMsg->timeWindowInterpo = query.timeWindowInterpo; + pQueryMsg->queryBlockDist = query.queryBlockDist; + pQueryMsg->stabledev = query.stabledev; + pQueryMsg->tsCompQuery = query.tsCompQuery; + pQueryMsg->simpleAgg = query.simpleAgg; + pQueryMsg->pointInterpQuery = query.pointInterpQuery; + pQueryMsg->needReverseScan = query.needReverseScan; + + pQueryMsg->numOfTags = htonl(numOfTags); + pQueryMsg->sqlstrLen = htonl(sqlLen); + pQueryMsg->sw.gap = htobe64(query.sw.gap); + pQueryMsg->sw.primaryColId = htonl(PRIMARYKEY_TIMESTAMP_COL_INDEX); + + pQueryMsg->secondStageOutput = htonl(query.numOfExpr2); + pQueryMsg->numOfOutput = htons((int16_t)query.numOfOutput); // this is the stage one output column number + pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols); pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType); pQueryMsg->tbnameCondLen = htonl(pQueryInfo->tagCond.tbnameCond.len); - pQueryMsg->numOfTags = htonl(numOfTags); pQueryMsg->queryType = htonl(pQueryInfo->type); - pQueryMsg->vgroupLimit = htobe64(pQueryInfo->vgroupLimit); - pQueryMsg->sqlstrLen = htonl(sqlLen); pQueryMsg->prevResultLen = htonl(pQueryInfo->bufLen); - pQueryMsg->sw.gap = htobe64(pQueryInfo->sessionWindow.gap); - pQueryMsg->sw.primaryColId = htonl(PRIMARYKEY_TIMESTAMP_COL_INDEX); - - size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo); - pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number // set column list ids size_t numOfCols = taosArrayGetSize(pQueryInfo->colList); - char *pMsg = (char *)(pQueryMsg->colList) + numOfCols * sizeof(SColumnInfo); - SSchema *pSchema = tscGetTableSchema(pTableMeta); - + char *pMsg = (char *)(pQueryMsg->tableCols) + numOfCols * sizeof(SColumnInfo); + for (int32_t i = 0; i < numOfCols; ++i) { - SColumn *pCol = taosArrayGetP(pQueryInfo->colList, i); - SSchema *pColSchema = &pSchema[pCol->colIndex.columnIndex]; + SColumnInfo *pCol = &query.tableCols[i]; - if (pCol->colIndex.columnIndex >= tscGetNumOfColumns(pTableMeta) || !isValidDataType(pColSchema->type)) { - char n[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(&pTableMetaInfo->name, n); - - - tscError("0x%"PRIx64" tid:%d uid:%" PRIu64" id:%s, column index out of range, numOfColumns:%d, index:%d, column name:%s", - pSql->self, pTableMeta->id.tid, pTableMeta->id.uid, n, tscGetNumOfColumns(pTableMeta), pCol->colIndex.columnIndex, - pColSchema->name); - return TSDB_CODE_TSC_INVALID_SQL; - } - - pQueryMsg->colList[i].colId = htons(pColSchema->colId); - pQueryMsg->colList[i].bytes = htons(pColSchema->bytes); - pQueryMsg->colList[i].type = htons(pColSchema->type); - pQueryMsg->colList[i].numOfFilters = htons(pCol->numOfFilters); + pQueryMsg->tableCols[i].colId = htons(pCol->colId); + pQueryMsg->tableCols[i].bytes = htons(pCol->bytes); + pQueryMsg->tableCols[i].type = htons(pCol->type); + pQueryMsg->tableCols[i].flist.numOfFilters = htons(pCol->flist.numOfFilters); // append the filter information after the basic column information - for (int32_t f = 0; f < pCol->numOfFilters; ++f) { - SColumnFilterInfo *pColFilter = &pCol->filterInfo[f]; + serializeColFilterInfo(pCol->flist.filterInfo, pCol->flist.numOfFilters, &pMsg); + } - SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)pMsg; - pFilterMsg->filterstr = htons(pColFilter->filterstr); - - pMsg += sizeof(SColumnFilterInfo); - - if (pColFilter->filterstr) { - pFilterMsg->len = htobe64(pColFilter->len); - memcpy(pMsg, (void *)pColFilter->pz, (size_t)(pColFilter->len + 1)); - pMsg += (pColFilter->len + 1); // append the additional filter binary info - } else { - pFilterMsg->lowerBndi = htobe64(pColFilter->lowerBndi); - pFilterMsg->upperBndi = htobe64(pColFilter->upperBndi); - } - - pFilterMsg->lowerRelOptr = htons(pColFilter->lowerRelOptr); - pFilterMsg->upperRelOptr = htons(pColFilter->upperRelOptr); - - if (pColFilter->lowerRelOptr == TSDB_RELATION_INVALID && pColFilter->upperRelOptr == TSDB_RELATION_INVALID) { - tscError("invalid filter info"); - return TSDB_CODE_TSC_INVALID_SQL; - } + for (int32_t i = 0; i < query.numOfOutput; ++i) { + code = serializeSqlExpr(&query.pExpr1[i].base, pTableMetaInfo, &pMsg, pSql->self, true); + if (code != TSDB_CODE_SUCCESS) { + goto _end; } } - SSqlFuncMsg *pSqlFuncExpr = (SSqlFuncMsg *)pMsg; - for (int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); - - // the queried table has been removed and a new table with the same name has already been created already - // return error msg - if (pExpr->uid != pTableMeta->id.uid) { - tscError("0x%"PRIx64" table has already been destroyed", pSql->self); - return TSDB_CODE_TSC_INVALID_TABLE_NAME; + for (int32_t i = 0; i < query.numOfExpr2; ++i) { + code = serializeSqlExpr(&query.pExpr2[i].base, pTableMetaInfo, &pMsg, pSql->self, false); + if (code != TSDB_CODE_SUCCESS) { + goto _end; } - - if (!tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId, pExpr->numOfParams)) { - tscError("0x%"PRIx64" table schema is not matched with parsed sql", pSql->self); - return TSDB_CODE_TSC_INVALID_SQL; - } - - assert(pExpr->resColId < 0); - - pSqlFuncExpr->colInfo.colId = htons(pExpr->colInfo.colId); - pSqlFuncExpr->colInfo.colIndex = htons(pExpr->colInfo.colIndex); - pSqlFuncExpr->colInfo.flag = htons(pExpr->colInfo.flag); - - if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) { - pSqlFuncExpr->colType = htons(pExpr->resType); - pSqlFuncExpr->colBytes = htons(pExpr->resBytes); - } else if (pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { - SSchema *s = tGetTbnameColumnSchema(); - - pSqlFuncExpr->colType = htons(s->type); - pSqlFuncExpr->colBytes = htons(s->bytes); - } else if (pExpr->colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { - SSchema s = tGetBlockDistColumnSchema(); - - pSqlFuncExpr->colType = htons(s.type); - pSqlFuncExpr->colBytes = htons(s.bytes); - } else { - SSchema* s = tscGetColumnSchemaById(pTableMeta, pExpr->colInfo.colId); - pSqlFuncExpr->colType = htons(s->type); - pSqlFuncExpr->colBytes = htons(s->bytes); - } - - pSqlFuncExpr->functionId = htons(pExpr->functionId); - pSqlFuncExpr->numOfParams = htons(pExpr->numOfParams); - pSqlFuncExpr->resColId = htons(pExpr->resColId); - if (pTableMeta->tableType != TSDB_SUPER_TABLE && pExpr->pFilter && pExpr->pFilter->numOfFilters > 0) { - pSqlFuncExpr->filterNum = htonl(pExpr->pFilter->numOfFilters); - } else { - pSqlFuncExpr->filterNum = 0; - } - - pMsg += sizeof(SSqlFuncMsg); - - if (pSqlFuncExpr->filterNum) { - pMsg += sizeof(SColumnFilterInfo) * pExpr->pFilter->numOfFilters; - - // append the filter information after the basic column information - for (int32_t f = 0; f < pExpr->pFilter->numOfFilters; ++f) { - SColumnFilterInfo *pColFilter = &pExpr->pFilter->filterInfo[f]; - - SColumnFilterInfo *pFilterMsg = &pSqlFuncExpr->filterInfo[f]; - pFilterMsg->filterstr = htons(pColFilter->filterstr); - - if (pColFilter->filterstr) { - pFilterMsg->len = htobe64(pColFilter->len); - memcpy(pMsg, (void *)pColFilter->pz, (size_t)(pColFilter->len + 1)); - pMsg += (pColFilter->len + 1); // append the additional filter binary info - } else { - pFilterMsg->lowerBndi = htobe64(pColFilter->lowerBndi); - pFilterMsg->upperBndi = htobe64(pColFilter->upperBndi); - } - - pFilterMsg->lowerRelOptr = htons(pColFilter->lowerRelOptr); - pFilterMsg->upperRelOptr = htons(pColFilter->upperRelOptr); - - if (pColFilter->lowerRelOptr == TSDB_RELATION_INVALID && pColFilter->upperRelOptr == TSDB_RELATION_INVALID) { - tscError("invalid filter info"); - return TSDB_CODE_TSC_INVALID_SQL; - } - } - } - - - for (int32_t j = 0; j < pExpr->numOfParams; ++j) { // todo add log - pSqlFuncExpr->arg[j].argType = htons((uint16_t)pExpr->param[j].nType); - pSqlFuncExpr->arg[j].argBytes = htons(pExpr->param[j].nLen); - - if (pExpr->param[j].nType == TSDB_DATA_TYPE_BINARY) { - memcpy(pMsg, pExpr->param[j].pz, pExpr->param[j].nLen); - pMsg += pExpr->param[j].nLen; - } else { - pSqlFuncExpr->arg[j].argValue.i64 = htobe64(pExpr->param[j].i64); - } - } - - pSqlFuncExpr = (SSqlFuncMsg *)pMsg; - } - - size_t output = tscNumOfFields(pQueryInfo); - - if (tscIsSecondStageQuery(pQueryInfo)) { - pQueryMsg->secondStageOutput = htonl((int32_t) output); - - SSqlFuncMsg *pSqlFuncExpr1 = (SSqlFuncMsg *)pMsg; - - for (int32_t i = 0; i < output; ++i) { - SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i); - SSqlExpr *pExpr = pField->pSqlExpr; - - // this should be switched to projection query - if (pExpr != NULL) { - // the queried table has been removed and a new table with the same name has already been created already - // return error msg - if (pExpr->uid != pTableMeta->id.uid) { - tscError("0x%"PRIx64" table has already been destroyed", pSql->self); - return TSDB_CODE_TSC_INVALID_TABLE_NAME; - } - - if (!tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId, pExpr->numOfParams)) { - tscError("0x%"PRIx64" table schema is not matched with parsed sql", pSql->self); - return TSDB_CODE_TSC_INVALID_SQL; - } - - pSqlFuncExpr1->numOfParams = 0; // no params for projection query - pSqlFuncExpr1->functionId = htons(TSDB_FUNC_PRJ); - pSqlFuncExpr1->colInfo.colId = htons(pExpr->resColId); - pSqlFuncExpr1->colInfo.flag = htons(TSDB_COL_NORMAL); - - bool assign = false; - for (int32_t f = 0; f < tscSqlExprNumOfExprs(pQueryInfo); ++f) { - SSqlExpr *pe = tscSqlExprGet(pQueryInfo, f); - if (pe == pExpr) { - pSqlFuncExpr1->colInfo.colIndex = htons(f); - pSqlFuncExpr1->colType = htons(pe->resType); - pSqlFuncExpr1->colBytes = htons(pe->resBytes); - assign = true; - break; - } - } - - assert(assign); - pMsg += sizeof(SSqlFuncMsg); - pSqlFuncExpr1 = (SSqlFuncMsg *)pMsg; - } else { - assert(pField->pArithExprInfo != NULL); - SExprInfo* pExprInfo = pField->pArithExprInfo; - - pSqlFuncExpr1->colInfo.colId = htons(pExprInfo->base.colInfo.colId); - pSqlFuncExpr1->functionId = htons(pExprInfo->base.functionId); - pSqlFuncExpr1->numOfParams = htons(pExprInfo->base.numOfParams); - pMsg += sizeof(SSqlFuncMsg); - - for (int32_t j = 0; j < pExprInfo->base.numOfParams; ++j) { - // todo add log - pSqlFuncExpr1->arg[j].argType = htons((uint16_t)pExprInfo->base.arg[j].argType); - pSqlFuncExpr1->arg[j].argBytes = htons(pExprInfo->base.arg[j].argBytes); - - if (pExprInfo->base.arg[j].argType == TSDB_DATA_TYPE_BINARY) { - memcpy(pMsg, pExprInfo->base.arg[j].argValue.pz, pExprInfo->base.arg[j].argBytes); - pMsg += pExprInfo->base.arg[j].argBytes; - } else { - pSqlFuncExpr1->arg[j].argValue.i64 = htobe64(pExprInfo->base.arg[j].argValue.i64); - } - } - - pSqlFuncExpr1 = (SSqlFuncMsg *)pMsg; - } - } - } else { - pQueryMsg->secondStageOutput = 0; } int32_t succeed = 1; - + // serialize the table info (sid, uid, tags) - pMsg = doSerializeTableInfo(pQueryMsg, pSql, pMsg, &succeed); + pMsg = doSerializeTableInfo(pQueryMsg, pSql, pTableMetaInfo, pMsg, &succeed); if (succeed == 0) { - return TSDB_CODE_TSC_APP_ERROR; + code = TSDB_CODE_TSC_APP_ERROR; + goto _end; } - SSqlGroupbyExpr *pGroupbyExpr = &pQueryInfo->groupbyExpr; + SSqlGroupbyExpr *pGroupbyExpr = query.pGroupbyExpr; if (pGroupbyExpr->numOfGroupCols > 0) { pQueryMsg->orderByIdx = htons(pGroupbyExpr->orderIndex); pQueryMsg->orderType = htons(pGroupbyExpr->orderType); for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) { SColIndex* pCol = taosArrayGet(pGroupbyExpr->columnInfo, j); - + *((int16_t *)pMsg) = htons(pCol->colId); pMsg += sizeof(pCol->colId); @@ -1047,48 +945,29 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { *((int16_t *)pMsg) += htons(pCol->flag); pMsg += sizeof(pCol->flag); - + memcpy(pMsg, pCol->name, tListLen(pCol->name)); pMsg += tListLen(pCol->name); } } - if (pQueryInfo->fillType != TSDB_FILL_NONE) { - for (int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) { - *((int64_t *)pMsg) = htobe64(pQueryInfo->fillVal[i]); - pMsg += sizeof(pQueryInfo->fillVal[0]); + if (query.fillType != TSDB_FILL_NONE) { + for (int32_t i = 0; i < query.numOfOutput; ++i) { + *((int64_t *)pMsg) = htobe64(query.fillVal[i]); + pMsg += sizeof(query.fillVal[0]); } } - - if (numOfTags != 0) { - int32_t numOfColumns = tscGetNumOfColumns(pTableMeta); - int32_t numOfTagColumns = tscGetNumOfTags(pTableMeta); - int32_t total = numOfTagColumns + numOfColumns; - - pSchema = tscGetTableTagSchema(pTableMeta); - - for (int32_t i = 0; i < numOfTags; ++i) { - SColumn *pCol = taosArrayGetP(pTableMetaInfo->tagColList, i); - SSchema *pColSchema = &pSchema[pCol->colIndex.columnIndex]; - if ((pCol->colIndex.columnIndex >= numOfTagColumns || pCol->colIndex.columnIndex < -1) || - (!isValidDataType(pColSchema->type))) { - char n[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(&pTableMetaInfo->name, n); + if (query.numOfTags > 0) { + for (int32_t i = 0; i < query.numOfTags; ++i) { + SColumnInfo* pTag = &query.tagColList[i]; - tscError("0x%"PRIx64" tid:%d uid:%" PRIu64 " id:%s, tag index out of range, totalCols:%d, numOfTags:%d, index:%d, column name:%s", - pSql->self, pTableMeta->id.tid, pTableMeta->id.uid, n, total, numOfTagColumns, pCol->colIndex.columnIndex, pColSchema->name); - - return TSDB_CODE_TSC_INVALID_SQL; - } - SColumnInfo* pTagCol = (SColumnInfo*) pMsg; - - pTagCol->colId = htons(pColSchema->colId); - pTagCol->bytes = htons(pColSchema->bytes); - pTagCol->type = htons(pColSchema->type); - pTagCol->numOfFilters = 0; - + pTagCol->colId = htons(pTag->colId); + pTagCol->bytes = htons(pTag->bytes); + pTagCol->type = htons(pTag->type); + pTagCol->flist.numOfFilters = 0; + pMsg += sizeof(SColumnInfo); } } @@ -1096,12 +975,12 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { // serialize tag column query condition if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0) { STagCond* pTagCond = &pQueryInfo->tagCond; - + SCond *pCond = tsGetSTableQueryCond(pTagCond, pTableMeta->id.uid); if (pCond != NULL && pCond->cond != NULL) { pQueryMsg->tagCondLen = htons(pCond->len); memcpy(pMsg, pCond->cond, pCond->len); - + pMsg += pCond->len; } } @@ -1118,21 +997,30 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } // compressed ts block - pQueryMsg->tsOffset = htonl((int32_t)(pMsg - pCmd->payload)); + pQueryMsg->tsBuf.tsOffset = htonl((int32_t)(pMsg - pCmd->payload)); if (pQueryInfo->tsBuf != NULL) { // note: here used the index instead of actual vnode id. int32_t vnodeIndex = pTableMetaInfo->vgroupIndex; - int32_t code = dumpFileBlockByGroupId(pQueryInfo->tsBuf, vnodeIndex, pMsg, &pQueryMsg->tsLen, &pQueryMsg->tsNumOfBlocks); + code = dumpFileBlockByGroupId(pQueryInfo->tsBuf, vnodeIndex, pMsg, &pQueryMsg->tsBuf.tsLen, &pQueryMsg->tsBuf.tsNumOfBlocks); if (code != TSDB_CODE_SUCCESS) { - return code; + goto _end; } - pMsg += pQueryMsg->tsLen; + pMsg += pQueryMsg->tsBuf.tsLen; - pQueryMsg->tsOrder = htonl(pQueryInfo->tsBuf->tsOrder); - pQueryMsg->tsLen = htonl(pQueryMsg->tsLen); - pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks); + pQueryMsg->tsBuf.tsOrder = htonl(pQueryInfo->tsBuf->tsOrder); + pQueryMsg->tsBuf.tsLen = htonl(pQueryMsg->tsBuf.tsLen); + pQueryMsg->tsBuf.tsNumOfBlocks = htonl(pQueryMsg->tsBuf.tsNumOfBlocks); + } + + int32_t numOfOperator = (int32_t) taosArrayGetSize(queryOperator); + pQueryMsg->numOfOperator = htonl(numOfOperator); + for(int32_t i = 0; i < numOfOperator; ++i) { + int32_t *operator = taosArrayGet(queryOperator, i); + *(int32_t*)pMsg = htonl(*operator); + + pMsg += sizeof(int32_t); } memcpy(pMsg, pSql->sqlstr, sqlLen); @@ -1143,11 +1031,15 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { tscDebug("0x%"PRIx64" msg built success, len:%d bytes", pSql->self, msgLen); pCmd->payloadLen = msgLen; pSql->cmd.msgType = TSDB_MSG_TYPE_QUERY; - + pQueryMsg->head.contLen = htonl(msgLen); assert(msgLen + minMsgSize() <= (int32_t)pCmd->allocSize); - return TSDB_CODE_SUCCESS; + _end: + freeQueryAttr(&query); + taosArrayDestroy(tableScanOperator); + taosArrayDestroy(queryOperator); + return code; } int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { @@ -1468,7 +1360,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSchema *pSchema; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); // Reallocate the payload size @@ -1537,7 +1429,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pMsg = (char *)pSchema; if (type == TSQL_CREATE_STREAM) { // check if it is a stream sql - SQuerySqlNode *pQuerySql = pInfo->pCreateTableInfo->pSelect; + SSqlNode *pQuerySql = pInfo->pCreateTableInfo->pSelect; strncpy(pMsg, pQuerySql->sqlstr.z, pQuerySql->sqlstr.n + 1); pCreateMsg->sqlLen = htons(pQuerySql->sqlstr.n + 1); @@ -1557,7 +1449,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscEstimateAlterTableMsgLength(SSqlCmd *pCmd) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); return minMsgSize() + sizeof(SAlterTableMsg) + sizeof(SSchema) * tscNumOfFields(pQueryInfo) + TSDB_EXTRA_PAYLOAD_SIZE; } @@ -1566,7 +1458,7 @@ int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int msgLen = 0; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -1615,7 +1507,7 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) { SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload; pCmd->payloadLen = htonl(pUpdateMsg->head.contLen); - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMeta *pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; SNewVgroupInfo vgroupInfo = {.vgId = -1}; @@ -1651,7 +1543,7 @@ int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg*)pCmd->payload; pRetrieveMsg->qId = htobe64(pSql->res.qId); pRetrieveMsg->free = htons(pQueryInfo->type); @@ -1675,7 +1567,7 @@ static int tscLocalResultCommonBuilder(SSqlObj *pSql, int32_t numOfRes) { pRes->row = 0; pRes->rspType = 1; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) { return pRes->code; } @@ -1723,16 +1615,32 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) { return code; } - pRes->code = tscDoLocalMerge(pSql); + // global aggregation may be the upstream for parent query + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(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); - if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - tscCreateResPointerInfo(pRes, pQueryInfo); - tscSetResRawPtr(pRes, pQueryInfo); + STableKeyInfo tableKeyInfo = {.pTable = NULL, .lastKey = INT64_MIN}; + + SArray* group = taosArrayInit(1, sizeof(STableKeyInfo)); + 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); } - pRes->row = 0; - pRes->completed = (pRes->numOfRows == 0); + uint64_t localQueryId = 0; + qTableQuery(pQueryInfo->pQInfo, &localQueryId); + convertQueryResult(pRes, pQueryInfo); + + handleDownstreamOperator(pRes, pQueryInfo); code = pRes->code; if (pRes->code == TSDB_CODE_SUCCESS) { @@ -1780,7 +1688,7 @@ int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableInfoMsg *pInfoMsg = (STableInfoMsg *)pCmd->payload; @@ -1850,7 +1758,7 @@ int tscBuildSTableVgroupMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; char* pMsg = pCmd->payload; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); SSTableVgroupMsg *pStableVgroupMsg = (SSTableVgroupMsg *)pMsg; pStableVgroupMsg->numOfTables = htonl(pQueryInfo->numOfTables); @@ -2162,8 +2070,7 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) { pInfo->vgroupList->numOfVgroups = pVgroupMsg->numOfVgroups; if (pInfo->vgroupList->numOfVgroups <= 0) { - //tfree(pInfo->vgroupList); - tscError("0x%"PRIx64" empty vgroup info", pSql->self); + 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 @@ -2213,7 +2120,7 @@ int tscProcessShowRsp(SSqlObj *pSql) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -2245,15 +2152,16 @@ int tscProcessShowRsp(SSqlObj *pSql) { SColumnIndex index = {0}; pSchema = pMetaMsg->schema; - + + uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; for (int16_t i = 0; i < pMetaMsg->numOfColumns; ++i, ++pSchema) { index.columnIndex = i; - tscColumnListInsert(pQueryInfo->colList, &index); + tscColumnListInsert(pQueryInfo->colList, i, uid, pSchema); TAOS_FIELD f = tscCreateField(pSchema->type, pSchema->name, pSchema->bytes); SInternalField* pInfo = tscFieldInfoAppend(pFieldInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, pTableSchema[i].type, pTableSchema[i].bytes, getNewResColId(pQueryInfo), pTableSchema[i].bytes, false); } @@ -2272,7 +2180,7 @@ static void createHbObj(STscObj* pObj) { pSql->fp = tscProcessHeartBeatRsp; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfoS(&pSql->cmd, 0); if (pQueryInfo == NULL) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; tfree(pSql); @@ -2365,7 +2273,7 @@ int tscProcessDropTableRsp(SSqlObj *pSql) { taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN)); tscDebug("0x%"PRIx64" remove table meta after drop table:%s, numOfRemain:%d", pSql->self, name, (int32_t) taosHashGetSize(tscTableMetaInfo)); - pTableMetaInfo->pTableMeta = NULL; + tfree(pTableMetaInfo->pTableMeta); return 0; } @@ -2400,11 +2308,12 @@ int tscProcessShowCreateRsp(SSqlObj *pSql) { int tscProcessQueryRsp(SSqlObj *pSql) { SSqlRes *pRes = &pSql->res; - SQueryTableRsp *pQuery = (SQueryTableRsp *)pRes->pRsp; - pQuery->qId = htobe64(pQuery->qId); - pRes->qId = pQuery->qId; + SQueryTableRsp *pQueryAttr = (SQueryTableRsp *)pRes->pRsp; + pQueryAttr->qId = htobe64(pQueryAttr->qId); + pRes->qId = pQueryAttr->qId; pRes->data = NULL; + tscResetForNextRetrieve(pRes); tscDebug("0x%"PRIx64" query rsp received, qId:0x%"PRIx64, pSql->self, pRes->qId); return 0; @@ -2429,7 +2338,7 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { pRes->completed = (pRetrieve->completed == 1); pRes->data = pRetrieve->data; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetActiveQueryInfo(pCmd); if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) { return pRes->code; } @@ -2443,6 +2352,8 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { tscSetResRawPtr(pRes, pQueryInfo); } + handleDownstreamOperator(pRes, pQueryInfo); + if (pSql->pSubscription != NULL) { int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput; @@ -2483,9 +2394,9 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn pNew->signature = pNew; pNew->cmd.command = TSDB_SQL_META; - tscAddSubqueryInfo(&pNew->cmd); + tscAddQueryInfo(&pNew->cmd); - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetailSafely(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd, 0); pNew->cmd.autoCreated = pSql->cmd.autoCreated; // create table if not exists if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE + pSql->cmd.payloadLen)) { @@ -2519,7 +2430,7 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn pSql->metaRid = pNew->self; - int32_t code = tscProcessSql(pNew); + 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 } @@ -2589,7 +2500,7 @@ int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool create int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) { SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); char name[TSDB_TABLE_FNAME_LEN] = {0}; @@ -2613,7 +2524,7 @@ int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) { } static bool allVgroupInfoRetrieved(SSqlCmd* pCmd, int32_t clauseIndex) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); if (pTableMetaInfo->vgroupList == NULL) { @@ -2640,13 +2551,13 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) { pNew->cmd.command = TSDB_SQL_STABLEVGROUP; // TODO TEST IT - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetailSafely(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd, 0); if (pNewQueryInfo == NULL) { tscFreeSqlObj(pNew); return code; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo *pMInfo = tscGetMetaInfo(pQueryInfo, i); STableMeta* pTableMeta = tscTableMetaDup(pMInfo->pTableMeta); @@ -2670,7 +2581,7 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) { pNew->fp = tscTableMetaCallBack; pNew->param = (void *)pSql->self; - code = tscProcessSql(pNew); + code = tscBuildAndSendRequest(pNew, NULL); if (code == TSDB_CODE_SUCCESS) { code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; } @@ -2746,7 +2657,7 @@ void tscInitMsgsFp() { tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_TABLE] = tscProcessShowCreateRsp; tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_DATABASE] = tscProcessShowCreateRsp; - + tscKeepConn[TSDB_SQL_SHOW] = 1; tscKeepConn[TSDB_SQL_RETRIEVE] = 1; tscKeepConn[TSDB_SQL_SELECT] = 1; diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 36d5cec06f..8dbb1c0a52 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -191,7 +191,7 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, pSql->fp = syncConnCallback; pSql->param = pSql; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); tsem_wait(&pSql->rspSem); if (pSql->res.code != TSDB_CODE_SUCCESS) { @@ -265,7 +265,7 @@ TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, if (taos) *taos = pObj; pSql->fetchFp = fp; - pSql->res.code = tscProcessSql(pSql); + pSql->res.code = tscBuildAndSendRequest(pSql, NULL); tscDebug("%p DB async connection is opening", taos); return pObj; } @@ -373,7 +373,7 @@ int taos_num_fields(TAOS_RES *res) { if (pSql == NULL || pSql->signature != pSql) return 0; int32_t num = 0; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pQueryInfo == NULL) { return num; } @@ -408,7 +408,7 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { SSqlRes *pRes = &pSql->res; if (pSql == NULL || pSql->signature != pSql) return 0; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pQueryInfo == NULL) { return NULL; } @@ -559,7 +559,7 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) { return true; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); if ((pQueryInfo == NULL) || tscIsTwoStageSTableQuery(pQueryInfo, 0)) { return true; @@ -578,7 +578,7 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) { pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; tscDebug("0x%"PRIx64" send msg to dnode to free qhandle ASAP before free sqlObj, command:%s", pSql->self, sqlCmd[pCmd->command]); - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return false; } @@ -672,7 +672,7 @@ char *taos_get_client_info() { return version; } static void tscKillSTableQuery(SSqlObj *pSql) { SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); if (!tscIsTwoStageSTableQuery(pQueryInfo, 0)) { return; @@ -723,7 +723,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 = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { assert(pSql->rpcRid <= 0); @@ -753,7 +753,7 @@ bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) { return true; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pQueryInfo == NULL) { return true; } @@ -932,7 +932,7 @@ static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t t int code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; char *str = (char *)tblNameList; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex); if (pQueryInfo == NULL) { pSql->res.code = terrno; return terrno; @@ -1047,7 +1047,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { /* * 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 tscProcessSql() + * 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; @@ -1060,7 +1060,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { tscDoQuery(pSql); - tscDebug("0x%"PRIx64" load multi table meta result:%d %s pObj:%p", pSql->self, pRes->code, taos_errstr(pSql), 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); } diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c index 13e311a0b3..17bf575b60 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -37,8 +37,8 @@ static int64_t getDelayValueAfterTimewindowClosed(SSqlStream* pStream, int64_t l static bool isProjectStream(SQueryInfo* pQueryInfo) { for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId != TSDB_FUNC_PRJ) { + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId != TSDB_FUNC_PRJ) { return false; } } @@ -89,7 +89,7 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) { return; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); code = tscGetTableMeta(pSql, pTableMetaInfo); @@ -102,7 +102,7 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) { } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) && (pTableMetaInfo->pVgroupTables == NULL) && (pTableMetaInfo->vgroupList == NULL || pTableMetaInfo->vgroupList->numOfVgroups <= 0)) { - tscDebug("%p empty vgroup list", pSql); + tscDebug("0x%"PRIx64" empty vgroup list", pSql->self); pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList); code = TSDB_CODE_TSC_APP_ERROR; } @@ -110,13 +110,13 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) { // failed to get table Meta or vgroup list, retry in 10sec. if (code == TSDB_CODE_SUCCESS) { tscTansformFuncForSTableQuery(pQueryInfo); - tscDebug("0x%"PRIx64" stream:%p, start stream query on:%s", pSql->self, pStream, tNameGetTableName(&pTableMetaInfo->name)); + tscDebug("0x%"PRIx64" stream:%p started to query table:%s", pSql->self, pStream, tNameGetTableName(&pTableMetaInfo->name)); pQueryInfo->command = TSDB_SQL_SELECT; - + pSql->fp = tscProcessStreamQueryCallback; pSql->fetchFp = tscProcessStreamQueryCallback; - tscDoQuery(pSql); + executeQuery(pSql, pQueryInfo); tscIncStreamExecutionCount(pStream); } else { setRetryInfo(pStream, code); @@ -138,8 +138,8 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) { pStream->numOfRes = 0; // reset the numOfRes. SSqlObj *pSql = pStream->pSql; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); - tscDebug("0x%"PRIx64" add into timer", pSql->self); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + tscDebug("0x%"PRIx64" timer launch query", pSql->self); if (pStream->isProject) { /* @@ -194,8 +194,8 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf SSqlStream *pStream = (SSqlStream *)param; if (tres == NULL || numOfRows < 0) { int64_t retryDelay = tscGetRetryDelayTime(pStream, pStream->interval.sliding, pStream->precision); - tscError("0x%"PRIx64" stream:%p, query data failed, code:0x%08x, retry in %" PRId64 "ms", pStream->pSql->self, pStream, numOfRows, - retryDelay); + 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); @@ -207,7 +207,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf tfree(pTableMetaInfo->pTableMeta); tscFreeSqlResult(pStream->pSql); - tscFreeSubobj(pStream->pSql); + tscFreeSubobj(pStream->pSql); tfree(pStream->pSql->pSubs); pStream->pSql->subState.numOfSub = 0; @@ -224,7 +224,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) { #if 0 SSqlObj * pSql = pStream->pSql; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pQueryInfo->fillType != TSDB_FILL_SET_VALUE && pQueryInfo->fillType != TSDB_FILL_NULL) { return; @@ -267,13 +267,14 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf if (pSql == NULL || numOfRows < 0) { int64_t retryDelayTime = tscGetRetryDelayTime(pStream, pStream->interval.sliding, pStream->precision); - tscError("0x%"PRIx64" stream:%p, retrieve data failed, code:0x%08x, retry in %" PRId64 "ms", pSql->self, pStream, numOfRows, retryDelayTime); + tscError("0x%"PRIx64" stream:%p, retrieve data failed, code:0x%08x, retry in %" PRId64 " ms", pSql->self, pStream, numOfRows, retryDelayTime); tscSetRetryTimer(pStream, pStream->pSql, retryDelayTime); return; } - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + STableMetaInfo *pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; if (numOfRows > 0) { // when reaching here the first execution of stream computing is successful. for(int32_t i = 0; i < numOfRows; ++i) { @@ -313,6 +314,10 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf pStream->numOfRes); tfree(pTableMetaInfo->pTableMeta); + if (pQueryInfo->pQInfo != NULL) { + qDestroyQueryInfo(pQueryInfo->pQInfo); + pQueryInfo->pQInfo = NULL; + } tscFreeSqlResult(pSql); tscFreeSubobj(pSql); @@ -345,10 +350,10 @@ static void tscSetRetryTimer(SSqlStream *pStream, SSqlObj *pSql, int64_t timer) return; } - tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 ", in %" PRId64 "ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream, + tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 "(ts window ekey), in %" PRId64 " ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream, now + timer, timer, delay, pStream->stime, etime); } else { - tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 ", in %" PRId64 "ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream, + tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 "(ts window ekey), in %" PRId64 " ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream, pStream->stime, timer, delay, pStream->stime - pStream->interval.interval, pStream->stime - 1); } @@ -406,7 +411,6 @@ static void tscSetNextLaunchTimer(SSqlStream *pStream, SSqlObj *pSql) { } } else { int64_t stime = taosTimeTruncate(pStream->stime - 1, &pStream->interval, pStream->precision); - //int64_t stime = taosGetIntervalStartTimestamp(pStream->stime - 1, pStream->interval.interval, pStream->interval.interval, pStream->interval.intervalUnit, pStream->precision); if (stime >= pStream->etime) { tscDebug("0x%"PRIx64" stream:%p, stime:%" PRId64 " is larger than end time: %" PRId64 ", stop the stream", pStream->pSql->self, pStream, pStream->stime, pStream->etime); @@ -440,7 +444,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) { int64_t minIntervalTime = (pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (!pStream->isProject && pQueryInfo->interval.interval == 0) { sprintf(pSql->cmd.payload, "the interval value is 0"); @@ -490,7 +494,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) { } static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pStream->isProject) { // no data in table, flush all data till now to destination meter, 10sec delay @@ -510,7 +514,7 @@ static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, in } else { return stime; } - + stime = taosTimeTruncate(stime, &pStream->interval, pStream->precision); } else { int64_t newStime = taosTimeTruncate(stime, &pStream->interval, pStream->precision); @@ -552,7 +556,7 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) { return; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); @@ -628,14 +632,14 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p strtolower(pSql->sqlstr, sqlstr); - tscDebugL("%p SQL: %s", pSql, pSql->sqlstr); + registerSqlObj(pSql); + + tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr); tsem_init(&pSql->rspSem, 0, 0); pSql->fp = tscCreateStream; pSql->fetchFp = tscCreateStream; - registerSqlObj(pSql); - int32_t code = tsParseSql(pSql, true); if (code == TSDB_CODE_SUCCESS) { tscCreateStream(pStream, pSql, code); diff --git a/src/client/src/tscSub.c b/src/client/src/tscSub.c index 7da98c7885..6928058f23 100644 --- a/src/client/src/tscSub.c +++ b/src/client/src/tscSub.c @@ -284,7 +284,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { } size_t numOfTables = taosArrayGetSize(tables); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); SArray* progress = taosArrayInit(numOfTables, sizeof(SSubscriptionProgress)); for( size_t i = 0; i < numOfTables; i++ ) { STidTags* tt = taosArrayGet( tables, i ); @@ -304,7 +304,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { } taosArrayDestroy(tables); - TSDB_QUERY_SET_TYPE(tscGetQueryInfoDetail(pCmd, 0)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY); + TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd, 0)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY); return 1; } @@ -487,11 +487,13 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) { if (pSql == NULL) { return NULL; } + if (pSub->pSql->self != 0) { taosReleaseRef(tscObjRef, pSub->pSql->self); } else { tscFreeSqlObj(pSub->pSql); } + pSub->pSql = pSql; pSql->pSubscription = pSub; } @@ -502,7 +504,7 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single table subscription size_t size = taosArrayGetSize(pSub->progress); @@ -555,7 +557,10 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) { pSql->fp = asyncCallback; pSql->fetchFp = asyncCallback; pSql->param = pSub; - tscDoQuery(pSql); + + pSql->cmd.active = pQueryInfo; + executeQuery(pSql, pQueryInfo); + tsem_wait(&pSub->sem); if (pRes->code != TSDB_CODE_SUCCESS) { diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index cc4eb751ff..67eea432e6 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -24,6 +24,7 @@ #include "tschemautil.h" #include "tsclient.h" #include "qUtil.h" +#include "qPlan.h" typedef struct SInsertSupporter { SSqlObj* pSql; @@ -69,7 +70,7 @@ static void subquerySetState(SSqlObj *pSql, SSubqueryState *subState, int idx, i pthread_mutex_lock(&subState->mutex); - tscDebug("subquery:%p,%d state set to %d", pSql, idx, state); + tscDebug("subquery:0x%"PRIx64",%d state set to %d", pSql->self, idx, state); subState->states[idx] = state; @@ -83,12 +84,18 @@ static bool allSubqueryDone(SSqlObj *pParentSql) { //lock in caller tscDebug("0x%"PRIx64" total subqueries: %d", pParentSql->self, subState->numOfSub); for (int i = 0; i < subState->numOfSub; i++) { + SSqlObj* pSub = pParentSql->pSubs[i]; if (0 == subState->states[i]) { - tscDebug("0x%"PRIx64" subquery:%p, index: %d NOT finished, abort query completion check", pParentSql->self, pParentSql->pSubs[i], i); + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index: %d NOT finished, abort query completion check", pParentSql->self, + pSub->self, i); done = false; break; } else { - tscDebug("0x%"PRIx64" subquery:%p, index: %d finished", pParentSql->self, pParentSql->pSubs[i], i); + if (pSub != NULL) { + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64", index: %d finished", pParentSql->self, pSub->self, i); + } else { + tscDebug("0x%"PRIx64" subquery:%p, index: %d finished", pParentSql->self, pSub, i); + } } } @@ -105,14 +112,15 @@ static bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx) { bool done = allSubqueryDone(pParentSql); if (done) { - tscDebug("0x%"PRIx64" subquery:%p,%d all subs already done", pParentSql->self, pSql, idx); + 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:%p,%d state set to 1", pParentSql->self, pSql, idx); + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64",%d state set to 1", pParentSql->self, pSql->self, idx); subState->states[idx] = 1; @@ -126,7 +134,7 @@ static bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx) { static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); win->skey = INT64_MAX; win->ekey = INT64_MIN; @@ -142,7 +150,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { int32_t equalNum = 0; int32_t stackidx = 0; SMergeTsCtx* ctx = NULL; - SMergeTsCtx* pctx = NULL; + SMergeTsCtx* pctx = NULL; SMergeTsCtx* mainCtx = NULL; STSElem cur; STSElem prev; @@ -151,10 +159,10 @@ 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 = tscGetQueryInfoDetail(&pSql->pSubs[i]->cmd, 0); + SQueryInfo* pSubQueryInfo = tscGetQueryInfo(&pSql->pSubs[i]->cmd, 0); pSubQueryInfo->tsBuf = output; - + SJoinSupporter* pSupporter = pSql->pSubs[i]->param; if (pSupporter->pTSBuf == NULL) { @@ -169,7 +177,8 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { return 0; } - tscDebug("0x%"PRIx64" sub:%p table idx:%d, input group number:%d", pSql->self, pSql->pSubs[i], i, pSupporter->pTSBuf->numOfGroups); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" table idx:%d, input group number:%d", pSql->self, + pSql->pSubs[i]->self, i, pSupporter->pTSBuf->numOfGroups); ctxlist[i].p = pSupporter; ctxlist[i].res = output; @@ -201,7 +210,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { mainCtx = pctx; - while (1) { + while (1) { pctx = mainCtx; prev = tsBufGetElem(pctx->p->pTSBuf); @@ -217,9 +226,9 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { int32_t skipped = 0; - for (int32_t i = 1; i < tableNum; ++i) { + for (int32_t i = 1; i < tableNum; ++i) { SMergeTsCtx* tctx = &ctxlist[i]; - + // find the data in supporter2 with the same tag value STSElem e2 = tsBufFindElemStartPosByTag(tctx->p->pTSBuf, &tag); @@ -235,7 +244,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { stackidx = 0; continue; } - + tableMIdx = taosArrayGet(tsCond, ++slot); equalNum = 1; @@ -260,7 +269,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { if (ret == 0) { if (++equalNum < tableNum) { pctx = ctx; - + if (++slot >= tableNum) { slot = 0; } @@ -268,14 +277,14 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { tableMIdx = taosArrayGet(tsCond, slot); continue; } - + assert(stackidx == tableNum); if (pLimit->offset == 0 || pQueryInfo->interval.interval > 0 || QUERY_IS_STABLE_QUERY(pQueryInfo->type)) { if (win->skey > prev.ts) { win->skey = prev.ts; } - + if (win->ekey < prev.ts) { win->ekey = prev.ts; } @@ -283,8 +292,8 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { for (int32_t i = 0; i < stackidx; ++i) { SMergeTsCtx* tctx = ctxStack[i]; prev = tsBufGetElem(tctx->p->pTSBuf); - - tsBufAppend(tctx->res, prev.id, prev.tag, (const char*)&prev.ts, sizeof(prev.ts)); + + tsBufAppend(tctx->res, prev.id, prev.tag, (const char*)&prev.ts, sizeof(prev.ts)); } } else { pLimit->offset -= 1;//offset apply to projection? @@ -292,35 +301,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { for (int32_t i = 0; i < stackidx; ++i) { SMergeTsCtx* tctx = ctxStack[i]; - - if (!tsBufNextPos(tctx->p->pTSBuf) && tctx == mainCtx) { - mergeDone = 1; - } - tctx->numOfInput++; - } - if (mergeDone) { - break; - } - - stackidx = 0; - equalNum = 1; - - ctxStack[stackidx++] = pctx; - } else if (ret > 0) { - if (!tsBufNextPos(ctx->p->pTSBuf) && ctx == mainCtx) { - mergeDone = 1; - break; - } - - ctx->numOfInput++; - stackidx--; - } else { - stackidx--; - - for (int32_t i = 0; i < stackidx; ++i) { - SMergeTsCtx* tctx = ctxStack[i]; - if (!tsBufNextPos(tctx->p->pTSBuf) && tctx == mainCtx) { mergeDone = 1; } @@ -331,9 +312,37 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { break; } - stackidx = 0; + stackidx = 0; equalNum = 1; - + + ctxStack[stackidx++] = pctx; + } else if (ret > 0) { + if (!tsBufNextPos(ctx->p->pTSBuf) && ctx == mainCtx) { + mergeDone = 1; + break; + } + + ctx->numOfInput++; + stackidx--; + } else { + stackidx--; + + for (int32_t i = 0; i < stackidx; ++i) { + SMergeTsCtx* tctx = ctxStack[i]; + + if (!tsBufNextPos(tctx->p->pTSBuf) && tctx == mainCtx) { + mergeDone = 1; + } + tctx->numOfInput++; + } + + if (mergeDone) { + break; + } + + stackidx = 0; + equalNum = 1; + ctxStack[stackidx++] = pctx; } @@ -345,7 +354,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { slot = 0; stackidx = 0; - + skipRemainValue(mainCtx->p->pTSBuf, &tag); } @@ -367,7 +376,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { for (int32_t i = 0; i < joinNum; ++i) { tsBufFlush(ctxlist[i].res); - + tsBufDestroy(ctxlist[i].p->pTSBuf); ctxlist[i].p->pTSBuf = NULL; } @@ -375,11 +384,11 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { TSKEY et = taosGetTimestampUs(); for (int32_t i = 0; i < joinNum; ++i) { - tscDebug("0x%"PRIx64" sub:%p tblidx:%d, input:%" PRId64 ", final:%" PRId64 " in %d vnodes for secondary query after ts blocks " + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" tblidx:%d, input:%" PRId64 ", final:%" PRId64 " in %d vnodes for secondary query after ts blocks " "intersecting, skey:%" PRId64 ", ekey:%" PRId64 ", numOfVnode:%d, elapsed time:%" PRId64 " us", - pSql->self, pSql->pSubs[i], i, ctxlist[i].numOfInput, ctxlist[i].res->numOfTotal, ctxlist[i].res->numOfGroups, win->skey, win->ekey, + pSql->self, pSql->pSubs[i]->self, i, ctxlist[i].numOfInput, ctxlist[i].res->numOfTotal, ctxlist[i].res->numOfGroups, win->skey, win->ekey, tsBufGetNumOfGroup(ctxlist[i].res), et - st); - } + } return ctxlist[0].res->numOfTotal; } @@ -395,7 +404,7 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { pSupporter->pObj = pSql; pSupporter->subqueryIndex = index; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); memcpy(&pSupporter->interval, &pQueryInfo->interval, sizeof(pSupporter->interval)); pSupporter->limit = pQueryInfo->limit; @@ -450,25 +459,6 @@ static void tscDestroyJoinSupporter(SJoinSupporter* pSupporter) { free(pSupporter); } -/* - * need the secondary query process - * In case of count(ts)/count(*)/spread(ts) query, that are only applied to - * primary timestamp column , the secondary query is not necessary - * - */ -static UNUSED_FUNC bool needSecondaryQuery(SQueryInfo* pQueryInfo) { - size_t numOfCols = taosArrayGetSize(pQueryInfo->colList); - - for (int32_t i = 0; i < numOfCols; ++i) { - SColumn* base = taosArrayGet(pQueryInfo->colList, i); - if (base->colIndex.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { - return true; - } - } - - return false; -} - static void filterVgroupTables(SQueryInfo* pQueryInfo, SArray* pVgroupTables) { int32_t num = 0; int32_t* list = NULL; @@ -569,7 +559,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { continue; } - SQueryInfo *pSubQueryInfo = tscGetQueryInfoDetail(&pPrevSub->cmd, 0); + SQueryInfo *pSubQueryInfo = tscGetQueryInfo(&pPrevSub->cmd, 0); STSBuf *pTsBuf = pSubQueryInfo->tsBuf; pSubQueryInfo->tsBuf = NULL; @@ -583,12 +573,11 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { success = false; break; } - tscClearSubqueryInfo(&pNew->cmd); pSql->pSubs[i] = pNew; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); 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 @@ -597,10 +586,11 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { tscTagCondCopy(&pQueryInfo->tagCond, &pSupporter->tagCond); - pQueryInfo->colList = pSupporter->colList; - pQueryInfo->exprList = pSupporter->exprList; - pQueryInfo->fieldsInfo = pSupporter->fieldsInfo; + pQueryInfo->colList = pSupporter->colList; + pQueryInfo->exprList = pSupporter->exprList; + pQueryInfo->fieldsInfo = pSupporter->fieldsInfo; pQueryInfo->groupbyExpr = pSupporter->groupInfo; + pQueryInfo->pUpstream = taosArrayInit(4, sizeof(POINTER_BYTES)); assert(pNew->subState.numOfSub == 0 && pNew->cmd.numOfClause == 1 && pQueryInfo->numOfTables == 1); @@ -620,22 +610,22 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { * during the timestamp intersection. */ pSupporter->limit = pQueryInfo->limit; - pQueryInfo->limit = pSupporter->limit; +// pQueryInfo->limit = pSupporter->limit; SColumnIndex index = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; SSchema* s = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, 0); - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0); - int16_t funcId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + int16_t funcId = pExpr->base.functionId; // add the invisible timestamp column - if ((pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) || + if ((pExpr->base.colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) || (funcId != TSDB_FUNC_TS && funcId != TSDB_FUNC_TS_DUMMY && funcId != TSDB_FUNC_PRJ)) { int16_t functionId = tscIsProjectionQuery(pQueryInfo)? TSDB_FUNC_PRJ : TSDB_FUNC_TS; tscAddFuncInSelectClause(pQueryInfo, 0, functionId, &index, s, TSDB_COL_NORMAL); - tscPrintSelectClause(pNew, 0); + tscPrintSelNodeList(pNew, 0); tscFieldInfoUpdateOffset(pQueryInfo); pExpr = tscSqlExprGet(pQueryInfo, 0); @@ -647,8 +637,8 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid); // set the tag column id for executor to extract correct tag value - pExpr->param[0] = (tVariant) {.i64 = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)}; - pExpr->numOfParams = 1; + pExpr->base.param[0] = (tVariant) {.i64 = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)}; + pExpr->base.numOfParams = 1; } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { @@ -685,7 +675,8 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { continue; } - tscDoQuery(pSql->pSubs[i]); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->pSubs[i]->cmd, 0); + executeQuery(pSql->pSubs[i], pQueryInfo); } return TSDB_CODE_SUCCESS; @@ -717,7 +708,7 @@ void freeJoinSubqueryObj(SSqlObj* pSql) { static int32_t quitAllSubquery(SSqlObj* pSqlSub, SSqlObj* pSqlObj, SJoinSupporter* pSupporter) { if (subAndCheckDone(pSqlSub, pSqlObj, pSupporter->subqueryIndex)) { - tscError("0x%"PRIx64" all subquery return and query failed, global code:%s", pSqlObj->self, tstrerror(pSqlObj->res.code)); + tscError("0x%"PRIx64" all subquery return and query failed, global code:%s", pSqlObj->self, tstrerror(pSqlObj->res.code)); freeJoinSubqueryObj(pSqlObj); return 0; } @@ -823,7 +814,7 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* tscClearSubqueryInfo(pCmd); tscFreeSqlResult(pSql); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); assert(pQueryInfo->numOfTables == 1); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -842,10 +833,12 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* // set the tags value for ts_comp function if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, 0); + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, 0); int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid); - pExpr->param->i64 = tagColId; - pExpr->numOfParams = 1; + pExpr->base.param[0].i64 = tagColId; + pExpr->base.param[0].nLen = sizeof(int64_t); + pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; + pExpr->base.numOfParams = 1; } // add the filter tag column @@ -855,7 +848,7 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* for (int32_t i = 0; i < s; ++i) { SColumn *pCol = taosArrayGetP(pSupporter->colList, i); - if (pCol->numOfFilters > 0) { // copy to the pNew->cmd.colList if it is filtered. + if (pCol->info.flist.numOfFilters > 0) { // copy to the pNew->cmd.colList if it is filtered. SColumn *p = tscColumnClone(pCol); taosArrayPush(pQueryInfo->colList, &p); } @@ -865,12 +858,12 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* size_t numOfCols = taosArrayGetSize(pQueryInfo->colList); tscDebug( - "%p subquery:%p tableIndex:%d, vgroupIndex:%d, numOfVgroups:%d, type:%d, ts_comp query to retrieve timestamps, " + "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, pSql, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pQueryInfo->type, + pParent->self, pSql->self, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pQueryInfo->type, tscSqlExprNumOfExprs(pQueryInfo), numOfCols, pQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } static bool checkForDuplicateTagVal(SSchema* pColSchema, SJoinSupporter* p1, SSqlObj* pPSqlObj) { @@ -910,12 +903,12 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar ctxlist[i].p = p; ctxlist[i].res = taosArrayInit(p->num, size); - + tscDebug("Join %d - num:%d", i, p->num); - + // sort according to the tag valu qsort(p->pIdTagList, p->num, p->tagSize, tagValCompar); - + if (!checkForDuplicateTagVal(pColSchema, p, pParentSql)) { for (int32_t j = 0; j <= i; j++) { taosArrayDestroy(ctxlist[j].res); @@ -968,9 +961,9 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar mergeDone = 0; continue; } - + tableMIdx = taosArrayGet(tagCond, slot); - + pctx = &ctxlist[*tableMIdx]; prev = (STidTags*) varDataVal(pctx->p->pIdTagList + pctx->idx * pctx->p->tagSize); @@ -980,10 +973,10 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar tableMIdx = taosArrayGet(tagCond, ++slot); equalNum = 1; - + while (1) { ctx = &ctxlist[*tableMIdx]; - + cur = (STidTags*) varDataVal(ctx->p->pIdTagList + ctx->idx * ctx->p->tagSize); assert(cur->tid != 0 && prev->tid != 0); @@ -995,7 +988,7 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar if (++equalNum < tableNum) { prev = cur; pctx = ctx; - + if (++slot >= tableNum) { slot = 0; } @@ -1008,7 +1001,7 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar *(int*) prev->tag, prev->tid, prev->uid, cur->tid, cur->uid); assert(stackidx == tableNum); - + for (int32_t i = 0; i < stackidx; ++i) { SMergeCtx* tctx = ctxStack[i]; prev = (STidTags*) varDataVal(tctx->p->pIdTagList + tctx->idx * tctx->p->tagSize); @@ -1018,7 +1011,7 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar for (int32_t i = 0; i < stackidx; ++i) { SMergeCtx* tctx = ctxStack[i]; - + if (++tctx->idx >= tctx->p->num) { mergeDone = 1; break; @@ -1031,19 +1024,19 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar stackidx = 0; equalNum = 1; - + prev = (STidTags*) varDataVal(pctx->p->pIdTagList + pctx->idx * pctx->p->tagSize); ctxStack[stackidx++] = pctx; } else if (ret > 0) { stackidx--; - + if (++ctx->idx >= ctx->p->num) { break; } } else { stackidx--; - + for (int32_t i = 0; i < stackidx; ++i) { SMergeCtx* tctx = ctxStack[i]; if (++tctx->idx >= tctx->p->num) { @@ -1056,9 +1049,9 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar break; } - stackidx = 0; + stackidx = 0; equalNum = 1; - + prev = (STidTags*) varDataVal(pctx->p->pIdTagList + pctx->idx * pctx->p->tagSize); ctxStack[stackidx++] = pctx; } @@ -1074,14 +1067,14 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar // reorganize the tid-tag value according to both the vgroup id and tag values // sort according to the tag value size_t num = taosArrayGetSize(ctxlist[i].res); - + qsort((ctxlist[i].res)->pData, num, size, tidTagsCompar); taosArrayPush(resList, &ctxlist[i].res); tscDebug("0x%"PRIx64" tags match complete, result num: %"PRIzu, pParentSql->self, num); } - + return TSDB_CODE_SUCCESS; } @@ -1110,7 +1103,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); // 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)); @@ -1191,7 +1184,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow // set the callback function pSql->fp = tscJoinQueryCallback; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } @@ -1231,14 +1224,14 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow // proceed to for ts_comp query SSqlCmd* pSubCmd = &pParentSql->pSubs[m]->cmd; SArray** s = taosArrayGet(resList, m); - - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pSubCmd, 0); - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + + SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pSubCmd, 0); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo1, 0); tscBuildVgroupTableInfo(pParentSql, pTableMetaInfo, *s); - + SSqlObj* psub = pParentSql->pSubs[m]; ((SJoinSupporter*)psub->param)->pVgroupTables = tscVgroupTableInfoDup(pTableMetaInfo->pVgroupTables); - + memset(pParentSql->subState.states, 0, sizeof(pParentSql->subState.states[0]) * pParentSql->subState.numOfSub); tscDebug("0x%"PRIx64" reset all sub states to 0", pParentSql->self); @@ -1266,7 +1259,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); assert(!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)); if (pParentSql->res.code != TSDB_CODE_SUCCESS) { @@ -1375,7 +1368,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow // set the callback function pSql->fp = tscJoinQueryCallback; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } @@ -1398,7 +1391,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 = tscGetQueryInfoDetail(&pParentSql->cmd, pParentSql->cmd.clauseIndex); + SQueryInfo* pPQueryInfo = tscGetQueryInfo(&pParentSql->cmd, pParentSql->cmd.clauseIndex); updateQueryTimeRange(pPQueryInfo, &win); //update the vgroup that involved in real data query @@ -1414,7 +1407,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); 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); @@ -1460,7 +1453,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR pSql->cmd.command = TSDB_SQL_SELECT; pSql->fp = tscJoinQueryCallback; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } else { tscDebug("0x%"PRIx64" no result in current subquery anymore", pSql->self); @@ -1468,7 +1461,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR } if (!subAndCheckDone(pSql, pParentSql, pSupporter->subqueryIndex)) { - tscDebug("0x%"PRIx64" sub:%p,%d completed, total:%d", pParentSql->self, tres, pSupporter->subqueryIndex, pState->numOfSub); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64",%d completed, total:%d", pParentSql->self, pSql->self, pSupporter->subqueryIndex, pState->numOfSub); return; } @@ -1490,16 +1483,16 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR SSqlRes* pRes1 = &pParentSql->pSubs[i]->res; if (pRes1->row > 0 && pRes1->numOfRows > 0) { - tscDebug("0x%"PRIx64" sub:%p index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql->self, pParentSql->pSubs[i], i, - pRes1->numOfRows, pRes1->numOfTotal); + 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); assert(pRes1->row < pRes1->numOfRows); } else { if (!stableQuery) { pRes1->numOfClauseTotal += pRes1->numOfRows; } - tscDebug("0x%"PRIx64" sub:%p index:%d numOfRows:%d total:%"PRId64, pParentSql->self, pParentSql->pSubs[i], i, - pRes1->numOfRows, pRes1->numOfTotal); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" index:%d numOfRows:%d total:%"PRId64, pParentSql->self, + pParentSql->pSubs[i]->self, i, pRes1->numOfRows, pRes1->numOfTotal); } } @@ -1523,8 +1516,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { SSqlRes *pRes = &pSub->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSub->cmd, 0); - + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSub->cmd, 0); if (!tscHasReachLimitation(pQueryInfo, pRes)) { if (pRes->row >= pRes->numOfRows) { // no data left in current result buffer @@ -1576,7 +1568,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { continue; } - SQueryInfo* p = tscGetQueryInfoDetail(&pSub->cmd, 0); + SQueryInfo* p = tscGetQueryInfo(&pSub->cmd, 0); orderedPrjQuery = tscNonOrderedProjectionQueryOnSTable(p, 0); if (orderedPrjQuery) { break; @@ -1600,7 +1592,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { continue; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSub->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSub->cmd, 0); if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && pSub->res.row >= pSub->res.numOfRows && pSub->res.completed) { @@ -1621,7 +1613,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { pSub->cmd.command = TSDB_SQL_SELECT; pSub->fp = tscJoinQueryCallback; - tscProcessSql(pSub); + tscBuildAndSendRequest(pSub, NULL); tryNextVnode = true; } else { tscDebug("0x%"PRIx64" no result in current subquery anymore", pSub->self); @@ -1675,13 +1667,13 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { pSupporter = (SJoinSupporter*)pSql1->param; // wait for all subqueries completed - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd1, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd1, 0); assert(pRes1->numOfRows >= 0 && pQueryInfo->numOfTables == 1); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (pRes1->row >= pRes1->numOfRows) { - tscDebug("0x%"PRIx64" subquery:%p retrieve data from vnode, subquery:%d, vgroupIndex:%d", pSql->self, pSql1, + tscDebug("0x%"PRIx64" subquery:0x%"PRIx64" retrieve data from vnode, subquery:%d, vgroupIndex:%d", pSql->self, pSql1->self, pSupporter->subqueryIndex, pTableMetaInfo->vgroupIndex); tscResetForNextRetrieve(pRes1); @@ -1691,7 +1683,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { pCmd1->command = (pCmd1->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; } - tscProcessSql(pSql1); + tscBuildAndSendRequest(pSql1, NULL); } } } @@ -1701,13 +1693,12 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - // the column transfer support struct has been built if (pRes->pColumnIndex != NULL) { return; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); int32_t numOfExprs = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * numOfExprs); @@ -1717,12 +1708,12 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { } for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); int32_t tableIndexOfSub = -1; for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j); - if (pTableMetaInfo->pTableMeta->id.uid == pExpr->uid) { + if (pTableMetaInfo->pTableMeta->id.uid == pExpr->base.uid) { tableIndexOfSub = j; break; } @@ -1731,12 +1722,12 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { assert(tableIndexOfSub >= 0 && tableIndexOfSub < pQueryInfo->numOfTables); SSqlCmd* pSubCmd = &pSql->pSubs[tableIndexOfSub]->cmd; - SQueryInfo* pSubQueryInfo = tscGetQueryInfoDetail(pSubCmd, 0); + SQueryInfo* pSubQueryInfo = tscGetQueryInfo(pSubCmd, 0); size_t numOfSubExpr = taosArrayGetSize(pSubQueryInfo->exprList); for (int32_t k = 0; k < numOfSubExpr; ++k) { - SSqlExpr* pSubExpr = tscSqlExprGet(pSubQueryInfo, k); - if (pExpr->functionId == pSubExpr->functionId && pExpr->colInfo.colId == pSubExpr->colInfo.colId) { + SExprInfo* pSubExpr = tscSqlExprGet(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; } @@ -1755,7 +1746,7 @@ 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 = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); assert(pQueryInfo->numOfTables == 1 && pSql->cmd.numOfClause == 1); @@ -1792,7 +1783,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY)) { pSql->fp = tidTagRetrieveCallback; pSql->cmd.command = TSDB_SQL_FETCH; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } @@ -1800,7 +1791,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { if (!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) { pSql->fp = tsCompRetrieveCallback; pSql->cmd.command = TSDB_SQL_FETCH; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } @@ -1821,7 +1812,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { pSql->fp = joinRetrieveFinalResCallback; // continue retrieve data pSql->cmd.command = TSDB_SQL_FETCH; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } else { // first retrieve from vnode during the secondary stage sub-query // set the command flag must be after the semaphore been correctly set. if (pParentSql->res.code == TSDB_CODE_SUCCESS) { @@ -1839,7 +1830,7 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter *pSupporter) { SSqlCmd * pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); pSql->res.qId = 0x1; assert(pSql->res.numOfRows == 0); @@ -1862,15 +1853,14 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter addGroupInfoForSubquery(pSql, pNew, 0, tableIndex); // refactor as one method - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); 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); - pCol->colIndex.tableIndex = 0; - } +// 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; @@ -1895,6 +1885,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter pNewQueryInfo->limit.limit = -1; pNewQueryInfo->limit.offset = 0; + taosArrayDestroy(pNewQueryInfo->pUpstream); pNewQueryInfo->order.orderColId = INT32_MIN; @@ -1941,12 +1932,12 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TS_COMP, &colIndex, &colSchema, TSDB_COL_NORMAL); // set the tags value for ts_comp function - SSqlExpr *pExpr = tscSqlExprGet(pNewQueryInfo, 0); + SExprInfo *pExpr = tscSqlExprGet(pNewQueryInfo, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid); - pExpr->param->i64 = tagColId; - pExpr->numOfParams = 1; + pExpr->base.param->i64 = tagColId; + pExpr->base.numOfParams = 1; } // add the filter tag column @@ -1956,7 +1947,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter for (int32_t i = 0; i < s; ++i) { SColumn *pCol = taosArrayGetP(pSupporter->colList, i); - if (pCol->numOfFilters > 0) { // copy to the pNew->cmd.colList if it is filtered. + if (pCol->info.flist.numOfFilters > 0) { // copy to the pNew->cmd.colList if it is filtered. SColumn *p = tscColumnClone(pCol); taosArrayPush(pNewQueryInfo->colList, &p); } @@ -1973,7 +1964,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter } } else { assert(0); - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); pNewQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY; } @@ -1984,7 +1975,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); assert((pQueryInfo->type & TSDB_QUERY_TYPE_SUBQUERY) == 0); int32_t code = TSDB_CODE_SUCCESS; @@ -2002,14 +1993,10 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { memset(pSql->subState.states, 0, sizeof(*pSql->subState.states) * pSql->subState.numOfSub); tscDebug("0x%"PRIx64" reset all sub states to 0", pSql->self); - - bool hasEmptySub = false; tscDebug("0x%"PRIx64" start subquery, total:%d", pSql->self, pQueryInfo->numOfTables); for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - SJoinSupporter *pSupporter = tscCreateJoinSupporter(pSql, i); - if (pSupporter == NULL) { // failed to create support struct, abort current query tscError("0x%"PRIx64" tableIndex:%d, failed to allocate join support object, abort further query", pSql->self, i); code = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -2025,14 +2012,13 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { SSqlObj* pSub = pSql->pSubs[i]; STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSub->cmd, 0, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) && (pTableMetaInfo->vgroupList->numOfVgroups == 0)) { - hasEmptySub = true; + pSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; break; } } - if (hasEmptySub) { // at least one subquery is empty, do nothing and return + if (pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) { // at least one subquery is empty, do nothing and return freeJoinSubqueryObj(pSql); - pSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; (*pSql->fp)(pSql->param, pSql, 0); } else { int fail = 0; @@ -2043,7 +2029,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { continue; } - if ((code = tscProcessSql(pSub)) != TSDB_CODE_SUCCESS) { + if ((code = tscBuildAndSendRequest(pSub, NULL)) != TSDB_CODE_SUCCESS) { pRes->code = code; (*pSub->fp)(pSub->param, pSub, 0); fail = 1; @@ -2112,12 +2098,12 @@ 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) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (TSDB_COL_IS_TAG(pExpr->colInfo.flag) || pExpr->functionId == TSDB_FUNC_PRJ) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag) || pExpr->base.functionId == TSDB_FUNC_PRJ) { continue; } - if (pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { key = *(TSKEY*) row[i]; continue; } @@ -2129,7 +2115,7 @@ void doAppendData(SInterResult* pInterResult, TAOS_ROW row, int32_t numOfCols, S SET_DOUBLE_NULL(&v); } - int32_t id = pExpr->colInfo.colId; + int32_t id = pExpr->base.colInfo.colId; int32_t numOfQueriedCols = (int32_t) taosArrayGetSize(pInterResult->pResult); SArray* p = NULL; @@ -2173,7 +2159,7 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { SFirstRoundQuerySup* pSup = param; SSqlObj* pParent = pSup->pParent; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); int32_t code = taos_errno(pSql); if (code != TSDB_CODE_SUCCESS) { @@ -2205,16 +2191,16 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { int32_t offset = 0; for (int32_t i = 0; i < numOfCols && offset < pSup->tagLen; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); // tag or group by column - if (TSDB_COL_IS_TAG(pExpr->colInfo.flag) || pExpr->functionId == TSDB_FUNC_PRJ) { + if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag) || pExpr->base.functionId == TSDB_FUNC_PRJ) { if (row[i] == NULL) { - setNull(p + offset, pExpr->resType, pExpr->resBytes); + setNull(p + offset, pExpr->base.resType, pExpr->base.resBytes); } else { memcpy(p + offset, row[i], length[i]); } - offset += pExpr->resBytes; + offset += pExpr->base.resBytes; } } @@ -2249,14 +2235,14 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { } } - if (!pRes->completed) { + if (!pRes->completed && numOfRows > 0) { taos_fetch_rows_a(tres, tscFirstRoundRetrieveCallback, param); return; } // set the parameters for the second round query process SSqlCmd *pPCmd = &pParent->cmd; - SQueryInfo *pQueryInfo1 = tscGetQueryInfoDetail(pPCmd, 0); + SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pPCmd, 0); int32_t resRows = pSup->numOfRows; if (pSup->numOfRows > 0) { @@ -2283,7 +2269,7 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { } pQueryInfo1->round = 1; - tscDoQuery(pParent); + executeQuery(pParent, pQueryInfo1); } void tscFirstRoundCallback(void* param, TAOS_RES* tres, int code) { @@ -2306,7 +2292,7 @@ void tscFirstRoundCallback(void* param, TAOS_RES* tres, int code) { } int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo* pTableMetaInfo1 = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); SFirstRoundQuerySup *pSup = calloc(1, sizeof(SFirstRoundQuerySup)); @@ -2322,7 +2308,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { tscClearSubqueryInfo(pCmd); tscFreeSqlResult(pSql); - SQueryInfo* pNewQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pCmd, 0); assert(pQueryInfo->numOfTables == 1); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pNewQueryInfo, 0); @@ -2351,68 +2337,66 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { int32_t index = 0; for(int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TS && pQueryInfo->interval.interval > 0) { - taosArrayPush(pSup->pColsInfo, &pExpr->resColId); + SExprInfo* pExpr = tscSqlExprGet(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->colInfo.colId); + SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); - SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TS, &colIndex, schema, TSDB_COL_NORMAL); - p->resColId = pExpr->resColId; // update the result column id - } else if (pExpr->functionId == TSDB_FUNC_STDDEV_DST) { - taosArrayPush(pSup->pColsInfo, &pExpr->resColId); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TS, &colIndex, schema, TSDB_COL_NORMAL); + 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); - SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->colInfo.colIndex}; + SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->base.colInfo.colIndex}; SSchema schema = {.type = TSDB_DATA_TYPE_DOUBLE, .bytes = sizeof(double)}; - tstrncpy(schema.name, pExpr->aliasName, tListLen(schema.name)); + tstrncpy(schema.name, pExpr->base.aliasName, tListLen(schema.name)); - SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_AVG, &colIndex, &schema, TSDB_COL_NORMAL); - p->resColId = pExpr->resColId; // update the result column id - } else if (pExpr->functionId == TSDB_FUNC_TAG) { - pSup->tagLen += pExpr->resBytes; - SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->colInfo.colIndex}; + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_AVG, &colIndex, &schema, TSDB_COL_NORMAL); + p->base.resColId = pExpr->base.resColId; // update the result column id + } else if (pExpr->base.functionId == TSDB_FUNC_TAG) { + pSup->tagLen += pExpr->base.resBytes; + SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->base.colInfo.colIndex}; SSchema* schema = NULL; - if (pExpr->colInfo.colId != TSDB_TBNAME_COLUMN_INDEX) { - schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->colInfo.colId); + if (pExpr->base.colInfo.colId != TSDB_TBNAME_COLUMN_INDEX) { + schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); } else { schema = tGetTbnameColumnSchema(); } - SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG); - p->resColId = pExpr->resColId; - } else if (pExpr->functionId == TSDB_FUNC_PRJ) { + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG); + p->base.resColId = pExpr->base.resColId; + } else if (pExpr->base.functionId == TSDB_FUNC_PRJ) { int32_t num = (int32_t) taosArrayGetSize(pNewQueryInfo->groupbyExpr.columnInfo); for(int32_t k = 0; k < num; ++k) { SColIndex* pIndex = taosArrayGet(pNewQueryInfo->groupbyExpr.columnInfo, k); - if (pExpr->colInfo.colId == pIndex->colId) { - pSup->tagLen += pExpr->resBytes; - taosArrayPush(pSup->pColsInfo, &pExpr->resColId); + if (pExpr->base.colInfo.colId == pIndex->colId) { + pSup->tagLen += pExpr->base.resBytes; + taosArrayPush(pSup->pColsInfo, &pExpr->base.resColId); SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pIndex->colIndex}; - SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->colInfo.colId); + SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); //doLimitOutputNormalColOfGroupby - SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_PRJ, &colIndex, schema, TSDB_COL_NORMAL); - p->numOfParams = 1; - p->param[0].i64 = 1; - p->param[0].nType = TSDB_DATA_TYPE_INT; - p->resColId = pExpr->resColId; // update the result column id + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_PRJ, &colIndex, schema, TSDB_COL_NORMAL); + p->base.numOfParams = 1; + p->base.param[0].i64 = 1; + p->base.param[0].nType = TSDB_DATA_TYPE_INT; + p->base.resColId = pExpr->base.resColId; // update the result column id } } } } - SColumnIndex columnIndex = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscInsertPrimaryTsSourceColumn(pNewQueryInfo, &columnIndex); - + tscInsertPrimaryTsSourceColumn(pNewQueryInfo, pTableMetaInfo->pTableMeta->id.uid); tscTansformFuncForSTableQuery(pNewQueryInfo); tscDebug( - "%p first round subquery:%p tableIndex:%d, vgroupIndex:%d, numOfVgroups:%d, type:%d, query to retrieve timestamps, " + "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, pNew, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pNewQueryInfo->type, + pSql->self, pNew->self, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo), index+1, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); tscHandleMasterSTableQuery(pNew); @@ -2445,7 +2429,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { const uint32_t nBufferSize = (1u << 16u); // 64KB - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); SSubqueryState *pState = &pSql->subState; @@ -2527,12 +2511,13 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { // todo handle multi-vnode situation if (pQueryInfo->tsBuf) { - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); pNewQueryInfo->tsBuf = tsBufClone(pQueryInfo->tsBuf); assert(pNewQueryInfo->tsBuf != NULL); } - tscDebug("0x%"PRIx64" sub:%p create subquery success. orderOfSub:%d", pSql->self, pNew, trs->subqueryIndex); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" create subquery success. orderOfSub:%d", pSql->self, pNew->self, + trs->subqueryIndex); } if (i < pState->numOfSub) { @@ -2555,7 +2540,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { SRetrieveSupport* pSupport = pSub->param; tscDebug("0x%"PRIx64" sub:%p launch subquery, orderOfSub:%d.", pSql->self, pSub, pSupport->subqueryIndex); - tscProcessSql(pSub); + tscBuildAndSendRequest(pSub, NULL); } return TSDB_CODE_SUCCESS; @@ -2635,7 +2620,7 @@ static int32_t tscReissueSubquery(SRetrieveSupport *oriTrs, SSqlObj *pSql, int32 return pParentSql->res.code; } - int32_t ret = tscProcessSql(pNew); + int32_t ret = tscBuildAndSendRequest(pNew, NULL); *sent = 1; @@ -2698,7 +2683,8 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO } if (!subAndCheckDone(pSql, pParentSql, subqueryIndex)) { - tscDebug("0x%"PRIx64" sub:%p,%d freed, not finished, total:%d", pParentSql->self, pSql, trsupport->subqueryIndex, pState->numOfSub); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64",%d freed, not finished, total:%d", pParentSql->self, + pSql->self, trsupport->subqueryIndex, pState->numOfSub); tscFreeRetrieveSup(pSql); return; @@ -2715,7 +2701,7 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO tscFreeRetrieveSup(pSql); // in case of second stage join subquery, invoke its callback function instead of regular QueueAsyncRes - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pParentSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pParentSql->cmd, 0); if (!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) { (*pParentSql->fp)(pParentSql->param, pParentSql, pParentSql->res.code); @@ -2732,15 +2718,15 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p tOrderDescriptor *pDesc = trsupport->pOrderDescriptor; SSubqueryState* pState = &pParentSql->subState; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; // data in from current vnode is stored in cache and disk uint32_t numOfRowsFromSubquery = (uint32_t)(trsupport->pExtMemBuffer[idx]->numOfTotalElems + trsupport->localBuffer->num); SVgroupsInfo* vgroupsInfo = pTableMetaInfo->vgroupList; - tscDebug("0x%"PRIx64" sub:%p all data retrieved from ep:%s, vgId:%d, numOfRows:%d, orderOfSub:%d", pParentSql->self, pSql, - vgroupsInfo->vgroups[0].epAddr[0].fqdn, vgroupsInfo->vgroups[0].vgId, numOfRowsFromSubquery, idx); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" all data retrieved from ep:%s, vgId:%d, numOfRows:%d, orderOfSub:%d", pParentSql->self, + pSql->self, vgroupsInfo->vgroups[0].epAddr[0].fqdn, vgroupsInfo->vgroups[0].vgId, numOfRowsFromSubquery, idx); tColModelCompact(pDesc->pColumnModel, trsupport->localBuffer, pDesc->pColumnModel->capacity); @@ -2768,7 +2754,8 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p } if (!subAndCheckDone(pSql, pParentSql, idx)) { - tscDebug("0x%"PRIx64" sub:%p orderOfSub:%d freed, not finished", pParentSql->self, pSql, trsupport->subqueryIndex); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d freed, not finished", pParentSql->self, pSql->self, + trsupport->subqueryIndex); tscFreeRetrieveSup(pSql); return; @@ -2780,7 +2767,7 @@ 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 = tscGetQueryInfoDetail(&pParentSql->cmd, 0); + SQueryInfo *pPQueryInfo = tscGetQueryInfo(&pParentSql->cmd, 0); tscClearInterpInfo(pPQueryInfo); tscCreateLocalMerger(trsupport->pExtMemBuffer, pState->numOfSub, pDesc, trsupport->pFinalColModel, trsupport->pFFColModel, pParentSql); @@ -2793,7 +2780,10 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p tscFreeRetrieveSup(pSql); // set the command flag must be after the semaphore been correctly set. - pParentSql->cmd.command = TSDB_SQL_RETRIEVE_LOCALMERGE; + if (pParentSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) { + pParentSql->cmd.command = TSDB_SQL_RETRIEVE_LOCALMERGE; + } + if (pParentSql->res.code == TSDB_CODE_SUCCESS) { (*pParentSql->fp)(pParentSql->param, pParentSql, 0); } else { @@ -2856,7 +2846,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR } SSqlRes * pRes = &pSql->res; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (numOfRows > 0) { assert(pRes->numOfRows == numOfRows); @@ -2908,8 +2898,9 @@ 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 = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); + pNew->cmd.active = pQueryInfo; pQueryInfo->type |= TSDB_QUERY_TYPE_STABLE_SUBQUERY; // clear the limit/offset info, since it should not be sent to vnode to be executed. @@ -2942,7 +2933,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) { SSqlObj* pParentSql = trsupport->pParentSql; SSqlObj* pSql = (SSqlObj *) tres; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); assert(pSql->cmd.numOfClause == 1 && pQueryInfo->numOfTables == 1); STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); @@ -3080,7 +3071,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) // clean up tableMeta in cache tscFreeQueryInfo(&pSql->cmd, false); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfoS(&pSql->cmd, 0); STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pParentObj->cmd, pSql->cmd.clauseIndex, 0); tscAddTableMetaInfo(pQueryInfo, &pMasterTableMetaInfo->name, NULL, NULL, NULL, NULL); @@ -3093,13 +3084,14 @@ 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", pParentObj->self, pParentObj->cmd.numOfTables); + 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) { char name[TSDB_TABLE_FNAME_LEN] = {0}; tNameExtractFullName(pParentObj->cmd.pTableNameList[i], name); taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN)); } + pParentObj->res.code = TSDB_CODE_SUCCESS; pParentObj->cmd.parseFinished = false; tscResetSqlCmd(&pParentObj->cmd, false); @@ -3119,7 +3111,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) return; } - tscDoQuery(pParentObj); + tscHandleMultivnodeInsert(pParentObj); } } @@ -3143,7 +3135,7 @@ int32_t tscHandleInsertRetry(SSqlObj* pParent, SSqlObj* pSql) { return code; // here the pSql may have been released already. } - return tscProcessSql(pSql); + return tscBuildAndSendRequest(pSql, NULL); } int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { @@ -3159,7 +3151,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { pSup->pSql = pSql; pSub->param = pSup; - tscDebug("0x%"PRIx64" sub:%p launch sub insert, orderOfSub:%d", pSql->self, pSub, i); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" launch sub insert, orderOfSub:%d", pSql->self, pSub->self, i); if (pSub->res.code != TSDB_CODE_SUCCESS) { tscHandleInsertRetry(pSql, pSub); } @@ -3242,7 +3234,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { for (int32_t j = 0; j < numOfSub; ++j) { SSqlObj *pSub = pSql->pSubs[j]; tscDebug("0x%"PRIx64" sub:%p launch sub insert, orderOfSub:%d", pSql->self, pSub, j); - tscProcessSql(pSub); + tscBuildAndSendRequest(pSub, NULL); } return TSDB_CODE_SUCCESS; @@ -3252,21 +3244,23 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { } static char* getResultBlockPosition(SSqlCmd* pCmd, SSqlRes* pRes, int32_t columnIndex, int16_t* bytes) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); SInternalField* pInfo = (SInternalField*) TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, columnIndex); - assert(pInfo->pSqlExpr != NULL); + assert(pInfo->pExpr->pExpr == NULL); - *bytes = pInfo->pSqlExpr->resBytes; - char* pData = pRes->data + pInfo->pSqlExpr->offset * pRes->numOfRows + pRes->row * (*bytes); - - return pData; + *bytes = pInfo->pExpr->base.resBytes; + if (pRes->data != NULL) { + return pRes->data + pInfo->pExpr->base.offset * pRes->numOfRows + pRes->row * (*bytes); + } else { + return ((char*)pRes->urow[columnIndex]) + pRes->row * (*bytes); + } } static void doBuildResFromSubqueries(SSqlObj* pSql) { SSqlRes* pRes = &pSql->res; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); int32_t numOfRes = INT32_MAX; for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { @@ -3284,6 +3278,7 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { return; } + tscRestoreFuncForSTableQuery(pQueryInfo); int32_t rowSize = tscGetResRowLength(pQueryInfo->exprList); assert(numOfRes * rowSize > 0); @@ -3303,6 +3298,19 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { int16_t bytes = 0; + tscRestoreFuncForSTableQuery(pQueryInfo); + tscFieldInfoUpdateOffset(pQueryInfo); + for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { + SSqlObj* pSub = pSql->pSubs[i]; + if (pSub == NULL) { + continue; + } + + SQueryInfo* pSubQueryInfo = pSub->cmd.pQueryInfo[0]; + tscRestoreFuncForSTableQuery(pSubQueryInfo); + tscFieldInfoUpdateOffset(pSubQueryInfo); + } + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { SColumnIndex* pIndex = &pRes->pColumnIndex[i]; @@ -3349,7 +3357,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { } if (pRes->tsrow == NULL) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); pRes->numOfCols = (int16_t) tscSqlExprNumOfExprs(pQueryInfo); pRes->tsrow = calloc(pRes->numOfCols, POINTER_BYTES); @@ -3379,18 +3387,18 @@ char *getArithmeticInputSrc(void *param, const char *name, int32_t colId) { SArithmeticSupport *pSupport = (SArithmeticSupport *) param; int32_t index = -1; - SSqlExpr* pExpr = NULL; + SExprInfo* pExpr = NULL; for (int32_t i = 0; i < pSupport->numOfCols; ++i) { pExpr = taosArrayGetP(pSupport->exprList, i); - if (strncmp(name, pExpr->aliasName, sizeof(pExpr->aliasName) - 1) == 0) { + if (strncmp(name, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1) == 0) { index = i; break; } } assert(index >= 0 && index < pSupport->numOfCols); - return pSupport->data[index] + pSupport->offset * pExpr->resBytes; + return pSupport->data[index] + pSupport->offset * pExpr->base.resBytes; } TAOS_ROW doSetResultRowData(SSqlObj *pSql) { @@ -3403,23 +3411,29 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql) { return pRes->tsrow; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); size_t size = tscNumOfFields(pQueryInfo); + + int32_t j = 0; for (int i = 0; i < size; ++i) { SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i); + if (!pInfo->visible) { + continue; + } int32_t type = pInfo->field.type; int32_t bytes = pInfo->field.bytes; if (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR) { - pRes->tsrow[i] = isNull(pRes->urow[i], type) ? NULL : pRes->urow[i]; + pRes->tsrow[j] = isNull(pRes->urow[i], type) ? NULL : pRes->urow[i]; } else { - pRes->tsrow[i] = isNull(pRes->urow[i], type) ? NULL : varDataVal(pRes->urow[i]); - pRes->length[i] = varDataLen(pRes->urow[i]); + pRes->tsrow[j] = isNull(pRes->urow[i], type) ? NULL : varDataVal(pRes->urow[i]); + pRes->length[j] = varDataLen(pRes->urow[i]); } ((char**) pRes->urow)[i] += bytes; + j += 1; } pRes->row++; // index increase one-step @@ -3430,7 +3444,7 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { bool hasData = true; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { bool allSubqueryExhausted = true; @@ -3442,7 +3456,7 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { SSqlRes *pRes1 = &pSql->pSubs[i]->res; SSqlCmd *pCmd1 = &pSql->pSubs[i]->cmd; - SQueryInfo *pQueryInfo1 = tscGetQueryInfoDetail(pCmd1, pCmd1->clauseIndex); + SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pCmd1, pCmd1->clauseIndex); assert(pQueryInfo1->numOfTables == 1); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo1, 0); @@ -3466,10 +3480,11 @@ static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { } SSqlRes * pRes1 = &pSql->pSubs[i]->res; - SQueryInfo *pQueryInfo1 = tscGetQueryInfoDetail(&pSql->pSubs[i]->cmd, 0); + SQueryInfo *pQueryInfo1 = tscGetQueryInfo(&pSql->pSubs[i]->cmd, 0); if ((pRes1->row >= pRes1->numOfRows && tscHasReachLimitation(pQueryInfo1, pRes1) && - tscIsProjectionQuery(pQueryInfo1)) || (pRes1->numOfRows == 0)) { + tscIsProjectionQuery(pQueryInfo1)) || + (pRes1->numOfRows == 0)) { hasData = false; break; } @@ -3478,3 +3493,118 @@ 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) { + assert(pQueryInfo != NULL); + int16_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput; + + SQInfo *pQInfo = (SQInfo *)calloc(1, sizeof(SQInfo)); + if (pQInfo == NULL) { + goto _cleanup; + } + + // to make sure third party won't overwrite this structure + pQInfo->signature = pQInfo; + + SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; + SQueryAttr *pQueryAttr = &pQInfo->query; + + pRuntimeEnv->pQueryAttr = pQueryAttr; + tscCreateQueryFromQueryInfo(pQueryInfo, pQueryAttr, NULL); + + 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; + + // keep the tag length + if (TSDB_COL_IS_TAG(pExprs[col].base.colInfo.flag)) { + pQueryAttr->tagLen += pExprs[col].base.resBytes; + } + } + + size_t numOfGroups = 0; + if (pTableGroupInfo->pGroupList != NULL) { + numOfGroups = taosArrayGetSize(pTableGroupInfo->pGroupList); + STableGroupInfo* pTableqinfo = &pQInfo->runtimeEnv.tableqinfoGroupInfo; + + pTableqinfo->pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES); + pTableqinfo->numOfTables = pTableGroupInfo->numOfTables; + pTableqinfo->map = taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); + } + + pQInfo->pBuf = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo)); + if (pQInfo->pBuf == NULL) { + goto _cleanup; + } + + pQInfo->dataReady = QUERY_RESULT_NOT_READY; + pQInfo->rspContext = NULL; + pQInfo->sql = sql; + + pthread_mutex_init(&pQInfo->lock, NULL); + tsem_init(&pQInfo->ready, 0, 0); + + int32_t index = 0; + for(int32_t i = 0; i < numOfGroups; ++i) { + SArray* pa = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); + + size_t s = taosArrayGetSize(pa); + SArray* p1 = taosArrayInit(s, POINTER_BYTES); + if (p1 == NULL) { + goto _cleanup; + } + + taosArrayPush(pRuntimeEnv->tableqinfoGroupInfo.pGroupList, &p1); + + STimeWindow window = pQueryAttr->window; + for(int32_t j = 0; j < s; ++j) { + STableKeyInfo* info = taosArrayGet(pa, j); + window.skey = info->lastKey; + + void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo); + STableQueryInfo* item = createTableQueryInfo(pQueryAttr, info->pTable, pQueryAttr->groupbyColumn, window, buf); + if (item == NULL) { + goto _cleanup; + } + + item->groupIndex = i; + taosArrayPush(p1, &item); + + STableId id = {.tid = 0, .uid = 0}; + taosHashPut(pRuntimeEnv->tableqinfoGroupInfo.map, &id.tid, sizeof(id.tid), &item, POINTER_BYTES); + index += 1; + } + } + + 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); + + SArray* pa = NULL; + if (stage == MASTER_SCAN) { + pa = createExecOperatorPlan(pQueryAttr); + } else { + pa = createGlobalMergePlan(pQueryAttr); + } + + STsBufInfo bufInfo = {0}; + SQueryParam param = {.pOperator = pa}; + /*int32_t code = */initQInfo(&bufInfo, NULL, pSourceOperator, pQInfo, ¶m, NULL, 0, merger); + taosArrayDestroy(pa); + + return pQInfo; + + _cleanup: + freeQInfo(pQInfo); + return NULL; +} diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 37875790dd..d2860d0c95 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -81,11 +81,11 @@ bool tscQueryTags(SQueryInfo* pQueryInfo) { int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfCols; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int32_t functId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int32_t functId = pExpr->base.functionId; // "select count(tbname)" query - if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { + if (functId == TSDB_FUNC_COUNT && pExpr->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { continue; } @@ -101,10 +101,9 @@ bool tscQueryBlockInfo(SQueryInfo* pQueryInfo) { int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfCols; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int32_t functId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int32_t functId = pExpr->base.functionId; - // "select count(tbname)" query if (functId == TSDB_FUNC_BLKINFO) { return true; } @@ -154,7 +153,7 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) { } for (int32_t i = 0; i < numOfExprs; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ && @@ -193,7 +192,7 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functionId = tscSqlExprGet(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) { @@ -207,11 +206,11 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) { bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); assert(pExpr != NULL); - int32_t functionId = pExpr->functionId; - if (functionId == TSDB_FUNC_TAG) { + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) { continue; } @@ -230,8 +229,8 @@ bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo) { size_t numOfOutput = tscNumOfFields(pQueryInfo); for(int32_t i = 0; i < numOfOutput; ++i) { - SExprInfo* pExprInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i)->pArithExprInfo; - if (pExprInfo != NULL) { + SExprInfo* pExprInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i)->pExpr; + if (pExprInfo->pExpr != NULL) { return true; } } @@ -254,16 +253,103 @@ bool tscGroupbyColumn(SQueryInfo* pQueryInfo) { return false; } +bool tscIsTopBotQuery(SQueryInfo* pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + if (pExpr->base.functionId == TSDB_FUNC_TS) { + continue; + } + + if (pExpr->base.functionId == TSDB_FUNC_TOP || pExpr->base.functionId == TSDB_FUNC_BOTTOM) { + return true; + } + } + + return false; +} + +bool isTsCompQuery(SQueryInfo* pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, 0); + if (numOfExprs != 1) { + return false; + } + + return pExpr1->base.functionId == TSDB_FUNC_TS_COMP; +} + +bool hasTagValOutput(SQueryInfo* pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + SExprInfo* pExpr1 = tscSqlExprGet(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); + if (pExpr == NULL) { + continue; + } + + // ts_comp column required the tag value for join filter + if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { + return true; + } + } + + return false; +} + +bool timeWindowInterpoRequired(SQueryInfo *pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_TWA || functionId == TSDB_FUNC_INTERP) { + return true; + } + } + + return false; +} + +bool isStabledev(SQueryInfo* pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_STDDEV_DST) { + return true; + } + } + + return false; +} + bool tscIsTWAQuery(SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } - int32_t functionId = pExpr->functionId; - if (functionId == TSDB_FUNC_TWA) { + if (pExpr->base.functionId == TSDB_FUNC_TWA) { return true; } } @@ -271,16 +357,58 @@ bool tscIsTWAQuery(SQueryInfo* pQueryInfo) { return false; } -bool tscIsTopbotQuery(SQueryInfo* pQueryInfo) { +bool tscNeedReverseScan(SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } - int32_t functionId = pExpr->functionId; - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG) { + continue; + } + + if ((functionId == TSDB_FUNC_FIRST || functionId == TSDB_FUNC_FIRST_DST) && pQueryInfo->order.order == TSDB_ORDER_DESC) { + return true; + } + + if (functionId == TSDB_FUNC_LAST || functionId == TSDB_FUNC_LAST_DST) { + // the scan order to acquire the last result of the specified column + int32_t order = (int32_t)pExpr->base.param[0].i64; + if (order != pQueryInfo->order.order) { + return true; + } + } + } + + return false; +} + +bool isSimpleAggregate(SQueryInfo* pQueryInfo) { + if (pQueryInfo->interval.interval > 0) { + return false; + } + + // Note:top/bottom query is fixed output query + if (tscIsTopBotQuery(pQueryInfo) || tscGroupbyColumn(pQueryInfo) || isTsCompQuery(pQueryInfo)) { + return true; + } + + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscSqlExprGet(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; } } @@ -288,24 +416,12 @@ bool tscIsTopbotQuery(SQueryInfo* pQueryInfo) { return false; } -int32_t tscGetTopbotQueryParam(SQueryInfo* pQueryInfo) { +bool isBlockDistQuery(SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr == NULL) { - continue; - } - - int32_t functionId = pExpr->functionId; - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { - return (int32_t) pExpr->param[0].i64; - } - } - - return 0; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + return (numOfExprs == 1 && pExpr->base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX); } - void tscClearInterpInfo(SQueryInfo* pQueryInfo) { if (!tscIsPointInterpQuery(pQueryInfo)) { return; @@ -353,23 +469,23 @@ void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo) { offset += pInfo->field.bytes; // generated the user-defined column result - if (pInfo->pSqlExpr != NULL && TSDB_COL_IS_UD_COL(pInfo->pSqlExpr->colInfo.flag)) { - if (pInfo->pSqlExpr->param[1].nType == TSDB_DATA_TYPE_NULL) { + if (pInfo->pExpr->pExpr == NULL && TSDB_COL_IS_UD_COL(pInfo->pExpr->base.colInfo.flag)) { + if (pInfo->pExpr->base.param[1].nType == TSDB_DATA_TYPE_NULL) { setNullN(pRes->urow[i], pInfo->field.type, pInfo->field.bytes, (int32_t) pRes->numOfRows); } else { if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR || pInfo->field.type == TSDB_DATA_TYPE_BINARY) { - assert(pInfo->pSqlExpr->param[1].nLen <= pInfo->field.bytes); + assert(pInfo->pExpr->base.param[1].nLen <= pInfo->field.bytes); for (int32_t k = 0; k < pRes->numOfRows; ++k) { char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; - memcpy(varDataVal(p), pInfo->pSqlExpr->param[1].pz, pInfo->pSqlExpr->param[1].nLen); - varDataSetLen(p, pInfo->pSqlExpr->param[1].nLen); + memcpy(varDataVal(p), pInfo->pExpr->base.param[1].pz, pInfo->pExpr->base.param[1].nLen); + varDataSetLen(p, pInfo->pExpr->base.param[1].nLen); } } else { for (int32_t k = 0; k < pRes->numOfRows; ++k) { char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; - memcpy(p, &pInfo->pSqlExpr->param[1].i64, pInfo->field.bytes); + memcpy(p, &pInfo->pExpr->base.param[1].i64, pInfo->field.bytes); } } } @@ -406,6 +522,216 @@ void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo) { } } +void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock) { + assert(pRes->numOfCols > 0); + + for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { + SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i); + + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, i); + + pRes->urow[i] = pColData->pData; + pRes->length[i] = pInfo->field.bytes; + + // generated the user-defined column result + if (pInfo->pExpr->pExpr == NULL && TSDB_COL_IS_UD_COL(pInfo->pExpr->base.colInfo.flag)) { + if (pInfo->pExpr->base.param[1].nType == TSDB_DATA_TYPE_NULL) { + setNullN(pRes->urow[i], pInfo->field.type, pInfo->field.bytes, (int32_t) pRes->numOfRows); + } else { + if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR || pInfo->field.type == TSDB_DATA_TYPE_BINARY) { + assert(pInfo->pExpr->base.param[1].nLen <= pInfo->field.bytes); + + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; + + memcpy(varDataVal(p), pInfo->pExpr->base.param[1].pz, pInfo->pExpr->base.param[1].nLen); + varDataSetLen(p, pInfo->pExpr->base.param[1].nLen); + } + } else { + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; + memcpy(p, &pInfo->pExpr->base.param[1].i64, pInfo->field.bytes); + } + } + } + + } else if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR) { + // convert unicode to native code in a temporary buffer extra one byte for terminated symbol + pRes->buffer[i] = realloc(pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); + + // string terminated char for binary data + memset(pRes->buffer[i], 0, pInfo->field.bytes * pRes->numOfRows); + + char* p = pRes->urow[i]; + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* dst = pRes->buffer[i] + k * pInfo->field.bytes; + + if (isNull(p, TSDB_DATA_TYPE_NCHAR)) { + memcpy(dst, p, varDataTLen(p)); + } else if (varDataLen(p) > 0) { + int32_t length = taosUcs4ToMbs(varDataVal(p), varDataLen(p), varDataVal(dst)); + varDataSetLen(dst, length); + + if (length == 0) { + tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)p); + } + } else { + varDataSetLen(dst, 0); + } + + p += pInfo->field.bytes; + } + + memcpy(pRes->urow[i], pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); + } + } +} + +static SColumnInfo* extractColumnInfoFromResult(STableMeta* pTableMeta, 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; + } + + return pColInfo; +} + +typedef struct SDummyInputInfo { + SSDataBlock *block; + SSqlRes *pRes; // refactor: remove it +} SDummyInputInfo; + +SSDataBlock* doGetDataBlock(void* param, bool* newgroup) { + SOperatorInfo *pOperator = (SOperatorInfo*) param; + + SDummyInputInfo *pInput = pOperator->info; + char* pData = pInput->pRes->data; + + SSDataBlock* pBlock = pInput->block; + pBlock->info.rows = pInput->pRes->numOfRows; + if (pBlock->info.rows == 0) { + return NULL; + } + + //TODO refactor + int32_t offset = 0; + 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]; + } + + offset += pColData->info.bytes; + } + + pInput->pRes->numOfRows = 0; + *newgroup = false; + return pBlock; +} + +static void destroyDummyInputOperator(void* param, int32_t numOfOutput) { + SDummyInputInfo* pInfo = (SDummyInputInfo*) param; + + // tricky + for(int32_t i = 0; i < numOfOutput; ++i) { + SColumnInfoData* pColInfoData = taosArrayGet(pInfo->block->pDataBlock, i); + pColInfoData->pData = NULL; + } + + pInfo->block = destroyOutputBuf(pInfo->block); + pInfo->pRes = 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) { + assert(numOfCols > 0); + SDummyInputInfo* pInfo = calloc(1, sizeof(SDummyInputInfo)); + + pInfo->pRes = (SSqlRes*) pResult; + + pInfo->block = calloc(numOfCols, sizeof(SSDataBlock)); + pInfo->block->info.numOfCols = numOfCols; + + pInfo->block->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData)); + for(int32_t i = 0; i < numOfCols; ++i) { + SColumnInfoData colData = {{0}}; + colData.info.bytes = pSchema[i].bytes; + colData.info.type = pSchema[i].type; + colData.info.colId = pSchema[i].colId; + + taosArrayPush(pInfo->block->pDataBlock, &colData); + } + + SOperatorInfo* pOptr = calloc(1, sizeof(SOperatorInfo)); + pOptr->name = "DummyInputOperator"; + pOptr->operatorType = OP_DummyInput; + pOptr->numOfOutput = numOfCols; + pOptr->blockingOptr = false; + pOptr->info = pInfo; + pOptr->exec = doGetDataBlock; + pOptr->cleanup = destroyDummyInputOperator; + return pOptr; +} + +void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo) { + // set the correct result + SSDataBlock* p = pQueryInfo->pQInfo->runtimeEnv.outputBuf; + pRes->numOfRows = (p != NULL)? p->info.rows: 0; + + if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) { + tscCreateResPointerInfo(pRes, pQueryInfo); + tscSetResRawPtrRv(pRes, pQueryInfo, p); + } + + pRes->row = 0; + 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); + + int32_t numOfCols = (int32_t) taosArrayGetSize(px->colList); + SQueriedTableInfo info = {.colList = pColumnInfo, .numOfCols = numOfCols,}; + SSchema* pSchema = tscGetTableSchema(px->pTableMetaInfo[0]->pTableMeta); + + STableGroupInfo tableGroupInfo = {.numOfTables = 1, .pGroupList = taosArrayInit(1, POINTER_BYTES),}; + tableGroupInfo.map = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); + + STableKeyInfo tableKeyInfo = {.pTable = NULL, .lastKey = INT64_MIN}; + + SArray* group = taosArrayInit(1, sizeof(STableKeyInfo)); + taosArrayPush(group, &tableKeyInfo); + + taosArrayPush(tableGroupInfo.pGroupList, &group); + + SOperatorInfo* pSourceOptr = createDummyInputOperator((char*)pRes, pSchema, numOfCols); + + 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); + + uint64_t qId = 0; + qTableQuery(px->pQInfo, &qId); + convertQueryResult(pRes, px); + + tfree(pColumnInfo); + } +} + static void tscDestroyResPointerInfo(SSqlRes* pRes) { if (pRes->buffer != NULL) { // free all buffers containing the multibyte string for (int i = 0; i < pRes->numOfCols; i++) { @@ -431,7 +757,7 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) { } tfree(pRes->final); - + pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free } @@ -441,10 +767,29 @@ void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeMeta) { } for (int32_t i = 0; i < pCmd->numOfClause; ++i) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 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; + } + + tfree(pUp); + } freeQueryInfoImpl(pQueryInfo); clearAllTableMetaInfo(pQueryInfo, removeMeta); + + if (pQueryInfo->pQInfo != NULL) { + qDestroyQueryInfo(pQueryInfo->pQInfo); + pQueryInfo->pQInfo = NULL; + } + tfree(pQueryInfo); } @@ -487,7 +832,7 @@ void tscFreeSqlResult(SSqlObj* pSql) { SSqlRes* pRes = &pSql->res; tscDestroyResPointerInfo(pRes); - + memset(&pSql->res, 0, sizeof(SSqlRes)); } @@ -720,6 +1065,10 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) { return TSDB_CODE_SUCCESS; } +SQueryInfo* tscGetActiveQueryInfo(SSqlCmd* pCmd) { + return pCmd->active; +} + /** * create the in-memory buffer for each table to keep the submitted data block * @param initialSize @@ -1044,12 +1393,7 @@ SInternalField* tscFieldInfoAppend(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) { assert(pFieldInfo != NULL); pFieldInfo->numOfOutput++; - struct SInternalField info = { - .pSqlExpr = NULL, - .pArithExprInfo = NULL, - .visible = true, - .pFieldFilters = NULL, - }; + struct SInternalField info = { .pExpr = NULL, .visible = true }; info.field = *pField; return taosArrayPush(pFieldInfo->internalField, &info); @@ -1057,12 +1401,7 @@ SInternalField* tscFieldInfoAppend(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) { SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIELD* field) { pFieldInfo->numOfOutput++; - struct SInternalField info = { - .pSqlExpr = NULL, - .pArithExprInfo = NULL, - .visible = true, - .pFieldFilters = NULL, - }; + struct SInternalField info = { .pExpr = NULL, .visible = true }; info.field = *field; return taosArrayInsert(pFieldInfo->internalField, index, &info); @@ -1071,14 +1410,14 @@ SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_F void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); - pExpr->offset = 0; + SExprInfo* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); + pExpr->base.offset = 0; for (int32_t i = 1; i < numOfExprs; ++i) { - SSqlExpr* prev = taosArrayGetP(pQueryInfo->exprList, i - 1); - SSqlExpr* p = taosArrayGetP(pQueryInfo->exprList, i); + SExprInfo* prev = taosArrayGetP(pQueryInfo->exprList, i - 1); + SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, i); - p->offset = prev->offset + prev->resBytes; + p->base.offset = prev->base.offset + prev->base.resBytes; } } @@ -1094,9 +1433,9 @@ TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) { int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) { SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, index); - assert(pInfo != NULL && pInfo->pSqlExpr != NULL); + assert(pInfo != NULL && pInfo->pExpr->pExpr == NULL); - return pInfo->pSqlExpr->offset; + return pInfo->pExpr->base.offset; } int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize) { @@ -1149,141 +1488,162 @@ int32_t tscGetResRowLength(SArray* pExprList) { int32_t size = 0; for(int32_t i = 0; i < num; ++i) { - SSqlExpr* pExpr = taosArrayGetP(pExprList, i); - size += pExpr->resBytes; + SExprInfo* pExpr = taosArrayGetP(pExprList, i); + size += pExpr->base.resBytes; } return size; } -static void destroyFilterInfo(SColumnFilterInfo* pFilterInfo, int32_t numOfFilters) { - for(int32_t i = 0; i < numOfFilters; ++i) { - if (pFilterInfo[i].filterstr) { - tfree(pFilterInfo[i].pz); +static void destroyFilterInfo(SColumnFilterList* pFilterList) { + for(int32_t i = 0; i < pFilterList->numOfFilters; ++i) { + if (pFilterList->filterInfo[i].filterstr) { + tfree(pFilterList->filterInfo[i].pz); } } - - tfree(pFilterInfo); + + tfree(pFilterList->filterInfo); + pFilterList->numOfFilters = 0; } -static void tscColumnDestroy(SColumn* pCol) { - destroyFilterInfo(pCol->filterInfo, pCol->numOfFilters); - free(pCol); -} +void* sqlExprDestroy(SExprInfo* pExpr) { + if (pExpr == NULL) { + return NULL; + } + SSqlExpr* p = &pExpr->base; + for(int32_t i = 0; i < tListLen(p->param); ++i) { + tVariantDestroy(&p->param[i]); + } + + if (p->flist.numOfFilters > 0) { + tfree(p->flist.filterInfo); + } + + if (pExpr->pExpr != NULL) { + tExprTreeDestroy(pExpr->pExpr, NULL); + } + + tfree(pExpr); + return NULL; +} void tscFieldInfoClear(SFieldInfo* pFieldInfo) { if (pFieldInfo == NULL) { return; } - for(int32_t i = 0; i < pFieldInfo->numOfOutput; ++i) { - SInternalField* pInfo = taosArrayGet(pFieldInfo->internalField, i); - - if (pInfo->pArithExprInfo != NULL) { - tExprTreeDestroy(pInfo->pArithExprInfo->pExpr, NULL); - - SSqlFuncMsg* pFuncMsg = &pInfo->pArithExprInfo->base; - for(int32_t j = 0; j < pFuncMsg->numOfParams; ++j) { - if (pFuncMsg->arg[j].argType == TSDB_DATA_TYPE_BINARY) { - tfree(pFuncMsg->arg[j].argValue.pz); - } + if (pFieldInfo->internalField != NULL) { + size_t num = taosArrayGetSize(pFieldInfo->internalField); + for (int32_t i = 0; i < num; ++i) { + SInternalField* pfield = taosArrayGet(pFieldInfo->internalField, i); + if (pfield->pExpr != NULL && pfield->pExpr->pExpr != NULL) { + sqlExprDestroy(pfield->pExpr); } - - tfree(pInfo->pArithExprInfo); - } - - if (pInfo->pFieldFilters != NULL) { - tscColumnDestroy(pInfo->pFieldFilters->pFilters); - tfree(pInfo->pFieldFilters); } } - + taosArrayDestroy(pFieldInfo->internalField); + tfree(pFieldInfo->final); memset(pFieldInfo, 0, sizeof(SFieldInfo)); } -static SSqlExpr* doCreateSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, - int16_t size, int16_t resColId, int16_t interSize, int32_t colType) { +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) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pColIndex->tableIndex); - SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr)); + SExprInfo* pExpr = calloc(1, sizeof(SExprInfo)); if (pExpr == NULL) { return NULL; } - pExpr->functionId = functionId; + SSqlExpr* p = &pExpr->base; + p->functionId = functionId; // set the correct columnIndex index if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) { - pExpr->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX; + SSchema* s = tGetTbnameColumnSchema(); + p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX; + p->colBytes = s->bytes; + p->colType = s->type; } else if (pColIndex->columnIndex == TSDB_BLOCK_DIST_COLUMN_INDEX) { - pExpr->colInfo.colId = 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) { - pExpr->colInfo.colId = pColIndex->columnIndex; + p->colInfo.colId = pColIndex->columnIndex; + p->colBytes = size; + p->colType = type; } else { if (TSDB_COL_IS_TAG(colType)) { SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - pExpr->colInfo.colId = pSchema[pColIndex->columnIndex].colId; - tstrncpy(pExpr->colInfo.name, pSchema[pColIndex->columnIndex].name, sizeof(pExpr->colInfo.name)); + p->colInfo.colId = pSchema[pColIndex->columnIndex].colId; + p->colBytes = pSchema[pColIndex->columnIndex].bytes; + p->colType = pSchema[pColIndex->columnIndex].type; + tstrncpy(p->colInfo.name, pSchema[pColIndex->columnIndex].name, sizeof(p->colInfo.name)); } else if (pTableMetaInfo->pTableMeta != NULL) { // in handling select database/version/server_status(), the pTableMeta is NULL SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->columnIndex); - pExpr->colInfo.colId = pSchema->colId; - tstrncpy(pExpr->colInfo.name, pSchema->name, sizeof(pExpr->colInfo.name)); + p->colInfo.colId = pSchema->colId; + p->colBytes = pSchema->bytes; + p->colType = pSchema->type; + tstrncpy(p->colInfo.name, pSchema->name, sizeof(p->colInfo.name)); } } - pExpr->colInfo.flag = colType; - pExpr->colInfo.colIndex = pColIndex->columnIndex; + p->colInfo.flag = colType; + p->colInfo.colIndex = pColIndex->columnIndex; - pExpr->resType = type; - pExpr->resBytes = size; - pExpr->resColId = resColId; - pExpr->interBytes = interSize; + p->resType = type; + p->resBytes = size; + p->resColId = resColId; + p->interBytes = interSize; if (pTableMetaInfo->pTableMeta) { - pExpr->uid = pTableMetaInfo->pTableMeta->id.uid; + p->uid = pTableMetaInfo->pTableMeta->id.uid; } return pExpr; } -SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscSqlExprInsert(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); } - SSqlExpr* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); + SExprInfo* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); taosArrayInsert(pQueryInfo->exprList, index, &pExpr); return pExpr; } -SSqlExpr* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) { - SSqlExpr* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); + SExprInfo* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); taosArrayPush(pQueryInfo->exprList, &pExpr); return pExpr; } -SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, +SExprInfo* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type, int16_t size) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, index); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, index); if (pExpr == NULL) { return NULL; } - pExpr->functionId = functionId; + SSqlExpr* pse = &pExpr->base; + pse->functionId = functionId; - pExpr->colInfo.colIndex = srcColumnIndex; - pExpr->colInfo.colId = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, srcColumnIndex)->colId; + pse->colInfo.colIndex = srcColumnIndex; + pse->colInfo.colId = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, srcColumnIndex)->colId; - pExpr->resType = type; - pExpr->resBytes = size; + pse->resType = type; + pse->resBytes = size; return pExpr; } @@ -1295,8 +1655,8 @@ bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t index) { int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_STDDEV_DST) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_STDDEV_DST) { return true; } } @@ -1319,32 +1679,18 @@ void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) assert(pExpr->numOfParams <= 3); } -SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index) { +SExprInfo* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index) { return taosArrayGetP(pQueryInfo->exprList, index); } -void* sqlExprDestroy(SSqlExpr* pExpr) { - if (pExpr == NULL) { - return NULL; - } - - for(int32_t i = 0; i < tListLen(pExpr->param); ++i) { - tVariantDestroy(&pExpr->param[i]); - } - - tfree(pExpr); - - return NULL; -} - /* - * NOTE: Does not release SSqlExprInfo here. + * NOTE: Does not release SExprInfo here. */ void tscSqlExprInfoDestroy(SArray* pExprInfo) { size_t size = taosArrayGetSize(pExprInfo); for(int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = taosArrayGetP(pExprInfo, i); + SExprInfo* pExpr = taosArrayGetP(pExprInfo, i); sqlExprDestroy(pExpr); } @@ -1356,46 +1702,36 @@ int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepco size_t size = taosArrayGetSize(src); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = taosArrayGetP(src, i); + SExprInfo* pExpr = taosArrayGetP(src, i); - if (pExpr->uid == uid) { - + if (pExpr->base.uid == uid) { if (deepcopy) { - SSqlExpr* p1 = calloc(1, sizeof(SSqlExpr)); - if (p1 == NULL) { - return -1; - } + SExprInfo* p1 = calloc(1, sizeof(SExprInfo)); + tscSqlExprAssign(p1, pExpr); - *p1 = *pExpr; - memset(p1->param, 0, sizeof(tVariant) * tListLen(p1->param)); - - for (int32_t j = 0; j < pExpr->numOfParams; ++j) { - tVariantAssign(&p1->param[j], &pExpr->param[j]); - } - taosArrayPush(dst, &p1); } else { taosArrayPush(dst, &pExpr); } + } } return 0; } -bool tscColumnExists(SArray* pColumnList, SColumnIndex* pColIndex) { +bool tscColumnExists(SArray* pColumnList, int32_t columnIndex, uint64_t uid) { // ignore the tbname columnIndex to be inserted into source list - if (pColIndex->columnIndex < 0) { + if (columnIndex < 0) { return false; } - + size_t numOfCols = taosArrayGetSize(pColumnList); - int16_t col = pColIndex->columnIndex; int32_t i = 0; while (i < numOfCols) { SColumn* pCol = taosArrayGetP(pColumnList, i); - if ((pCol->colIndex.columnIndex != col) || (pCol->colIndex.tableIndex != pColIndex->tableIndex)) { + if ((pCol->columnIndex != columnIndex) || (pCol->tableUid != uid)) { ++i; continue; } else { @@ -1410,22 +1746,38 @@ bool tscColumnExists(SArray* pColumnList, SColumnIndex* pColIndex) { return true; } +void tscSqlExprAssign(SExprInfo* dst, const SExprInfo* src) { + assert(dst != NULL && src != NULL); -SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) { + *dst = *src; + + if (src->base.flist.numOfFilters > 0) { + dst->base.flist.filterInfo = calloc(src->base.flist.numOfFilters, sizeof(SColumnFilterInfo)); + memcpy(dst->base.flist.filterInfo, src->base.flist.filterInfo, sizeof(SColumnFilterInfo) * src->base.flist.numOfFilters); + } + + dst->pExpr = exprdup(src->pExpr); + + memset(dst->base.param, 0, sizeof(tVariant) * tListLen(dst->base.param)); + for (int32_t j = 0; j < src->base.numOfParams; ++j) { + tVariantAssign(&dst->base.param[j], &src->base.param[j]); + } +} + +SColumn* tscColumnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema) { // ignore the tbname columnIndex to be inserted into source list - if (pColIndex->columnIndex < 0) { + if (columnIndex < 0) { return NULL; } size_t numOfCols = taosArrayGetSize(pColumnList); - int16_t col = pColIndex->columnIndex; int32_t i = 0; while (i < numOfCols) { SColumn* pCol = taosArrayGetP(pColumnList, i); - if (pCol->colIndex.columnIndex < col) { + if (pCol->columnIndex < columnIndex) { i++; - } else if (pCol->colIndex.tableIndex < pColIndex->tableIndex) { + } else if (pCol->tableUid < uid) { i++; } else { break; @@ -1438,18 +1790,28 @@ SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) { return NULL; } - b->colIndex = *pColIndex; + b->columnIndex = columnIndex; + b->tableUid = uid; + b->info.colId = pSchema->colId; + b->info.bytes = pSchema->bytes; + b->info.type = pSchema->type; + taosArrayInsert(pColumnList, i, &b); } else { SColumn* pCol = taosArrayGetP(pColumnList, i); - if (i < numOfCols && (pCol->colIndex.columnIndex > col || pCol->colIndex.tableIndex != pColIndex->tableIndex)) { + if (i < numOfCols && (pCol->columnIndex > columnIndex || pCol->tableUid != uid)) { SColumn* b = calloc(1, sizeof(SColumn)); if (b == NULL) { return NULL; } - b->colIndex = *pColIndex; + b->columnIndex = columnIndex; + b->tableUid = uid; + b->info.colId = pSchema->colId; + b->info.bytes = pSchema->bytes; + b->info.type = pSchema->type; + taosArrayInsert(pColumnList, i, &b); } } @@ -1467,22 +1829,29 @@ SColumn* tscColumnClone(const SColumn* src) { return NULL; } - dst->colIndex = src->colIndex; - dst->numOfFilters = src->numOfFilters; - dst->filterInfo = tFilterInfoDup(src->filterInfo, src->numOfFilters); - + dst->columnIndex = src->columnIndex; + dst->tableUid = src->tableUid; + dst->info.flist.numOfFilters = src->info.flist.numOfFilters; + dst->info.flist.filterInfo = tFilterInfoDup(src->info.flist.filterInfo, src->info.flist.numOfFilters); + dst->info.type = src->info.type; + dst->info.colId = src->info.colId; + dst->info.bytes = src->info.bytes; return dst; } +static void tscColumnDestroy(SColumn* pCol) { + destroyFilterInfo(&pCol->info.flist); + free(pCol); +} -void tscColumnListCopy(SArray* dst, const SArray* src, int16_t tableIndex) { +void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid) { assert(src != NULL && dst != NULL); size_t num = taosArrayGetSize(src); for (int32_t i = 0; i < num; ++i) { SColumn* pCol = taosArrayGetP(src, i); - if (pCol->colIndex.tableIndex == tableIndex || tableIndex < 0) { + if (pCol->tableUid == tableUid) { SColumn* p = tscColumnClone(pCol); taosArrayPush(dst, &p); } @@ -1704,7 +2073,7 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) { dest->tbnameCond.len = src->tbnameCond.len; dest->joinInfo.hasJoin = src->joinInfo.hasJoin; - + for (int32_t i = 0; i < TSDB_MAX_JOIN_TABLE_NUM; ++i) { if (src->joinInfo.joinTables[i]) { dest->joinInfo.joinTables[i] = calloc(1, sizeof(SJoinNode)); @@ -1721,7 +2090,7 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) { } } - + dest->relType = src->relType; if (src->pCond == NULL) { @@ -1793,16 +2162,16 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - pColInfo[i].functionId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + pColInfo[i].functionId = pExpr->base.functionId; - if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { + if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - int16_t index = pExpr->colInfo.colIndex; + int16_t index = pExpr->base.colInfo.colIndex; pColInfo[i].type = (index != -1) ? pTagSchema[index].type : TSDB_DATA_TYPE_BINARY; } else { - pColInfo[i].type = pSchema[pExpr->colInfo.colIndex].type; + pColInfo[i].type = pSchema[pExpr->base.colInfo.colIndex].type; } } } @@ -1852,7 +2221,7 @@ STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd* pCmd, int32_t clauseIndex, i assert(clauseIndex >= 0 && clauseIndex < pCmd->numOfClause); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); return tscGetMetaInfo(pQueryInfo, tableIndex); } @@ -1869,17 +2238,17 @@ STableMetaInfo* tscGetMetaInfo(SQueryInfo* pQueryInfo, int32_t tableIndex) { return pQueryInfo->pTableMetaInfo[tableIndex]; } -SQueryInfo* tscGetQueryInfoDetailSafely(SSqlCmd* pCmd, int32_t subClauseIndex) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex); +SQueryInfo* tscGetQueryInfoS(SSqlCmd* pCmd, int32_t subClauseIndex) { + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); int32_t ret = TSDB_CODE_SUCCESS; while ((pQueryInfo) == NULL) { - if ((ret = tscAddSubqueryInfo(pCmd)) != TSDB_CODE_SUCCESS) { + if ((ret = tscAddQueryInfo(pCmd)) != TSDB_CODE_SUCCESS) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return NULL; } - pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex); + pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); } return pQueryInfo; @@ -1908,18 +2277,20 @@ void tscInitQueryInfo(SQueryInfo* pQueryInfo) { pQueryInfo->fieldsInfo.internalField = taosArrayInit(4, sizeof(SInternalField)); assert(pQueryInfo->exprList == NULL); - pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES); - pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); - pQueryInfo->udColumnId = TSDB_UD_COLUMN_INDEX; - pQueryInfo->resColumnId = -1000; - pQueryInfo->limit.limit = -1; - pQueryInfo->limit.offset = 0; - pQueryInfo->slimit.limit = -1; - pQueryInfo->slimit.offset = 0; + 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); } -int32_t tscAddSubqueryInfo(SSqlCmd* pCmd) { +int32_t tscAddQueryInfo(SSqlCmd* pCmd) { assert(pCmd != NULL); // todo refactor: remove this structure @@ -1965,11 +2336,14 @@ static void freeQueryInfoImpl(SQueryInfo* pQueryInfo) { tfree(pQueryInfo->fillVal); tfree(pQueryInfo->buf); + + taosArrayDestroy(pQueryInfo->pUpstream); + pQueryInfo->pUpstream = NULL; } void tscClearSubqueryInfo(SSqlCmd* pCmd) { for (int32_t i = 0; i < pCmd->numOfClause; ++i) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, i); freeQueryInfoImpl(pQueryInfo); } } @@ -2042,7 +2416,7 @@ void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta) { for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); - if (removeMeta) { + if (removeMeta) { char name[TSDB_TABLE_FNAME_LEN] = {0}; tNameExtractFullName(&pTableMetaInfo->name, name); @@ -2096,7 +2470,7 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, SName* name, STableM } if (pTagCols != NULL) { - tscColumnListCopy(pTableMetaInfo->tagColList, pTagCols, -1); + tscColumnListCopy(pTableMetaInfo->tagColList, pTagCols, pTableMetaInfo->pTableMeta->id.uid); } pTableMetaInfo->pVgroupTables = tscVgroupTableInfoDup(pVgroupTables); @@ -2161,7 +2535,7 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, in return NULL; } - if (tscAddSubqueryInfo(pCmd) != TSDB_CODE_SUCCESS) { + if (tscAddQueryInfo(pCmd) != TSDB_CODE_SUCCESS) { #ifdef __APPLE__ // to satisfy later tsem_destroy in taos_free_result tsem_init(&pNew->rspSem, 0, 0); @@ -2176,7 +2550,7 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, in pNew->sqlstr = NULL; pNew->maxRetry = TSDB_MAX_REPLICA; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfoS(pCmd, 0); assert(pSql->cmd.clauseIndex == 0); STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0); @@ -2194,13 +2568,12 @@ static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pNewQueryInfo, int64_t ui } // set the field info in pNewQueryInfo object according to sqlExpr information - size_t numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo); - for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pNewQueryInfo, i); + for (int32_t i = 0; i < numOfOutput; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pNewQueryInfo, i); - TAOS_FIELD f = tscCreateField((int8_t) pExpr->resType, pExpr->aliasName, pExpr->resBytes); + TAOS_FIELD f = tscCreateField((int8_t) pExpr->base.resType, pExpr->base.aliasName, pExpr->base.resBytes); SInternalField* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f); - pInfo1->pSqlExpr = pExpr; + pInfo1->pExpr = pExpr; } // update the pSqlExpr pointer in SInternalField according the field name @@ -2209,12 +2582,12 @@ static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pNewQueryInfo, int64_t ui TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f); bool matched = false; - for (int32_t k1 = 0; k1 < numOfExprs; ++k1) { - SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1); + for (int32_t k1 = 0; k1 < numOfOutput; ++k1) { + SExprInfo* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1); - if (strcmp(field->name, pExpr1->aliasName) == 0) { // establish link according to the result field name + if (strcmp(field->name, pExpr1->base.aliasName) == 0) { // establish link according to the result field name SInternalField* pInfo = tscFieldInfoGetInternalField(&pNewQueryInfo->fieldsInfo, f); - pInfo->pSqlExpr = pExpr1; + pInfo->pExpr = pExpr1; matched = true; break; @@ -2237,8 +2610,9 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return NULL; } - - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, tableIndex); + + SQueryInfo* pQueryInfo = tscGetActiveQueryInfo(pCmd); + STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[tableIndex]; pNew->pTscObj = pSql->pTscObj; pNew->signature = pNew; @@ -2251,7 +2625,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t pnCmd->payload = NULL; pnCmd->allocSize = 0; - pnCmd->pQueryInfo = NULL; + pnCmd->pQueryInfo = NULL; pnCmd->numOfClause = 0; pnCmd->clauseIndex = 0; pnCmd->pDataBlocks = NULL; @@ -2263,15 +2637,16 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t pnCmd->tagData.data = NULL; pnCmd->tagData.dataLen = 0; - if (tscAddSubqueryInfo(pnCmd) != TSDB_CODE_SUCCESS) { + if (tscAddQueryInfo(pnCmd) != TSDB_CODE_SUCCESS) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } - SQueryInfo* pNewQueryInfo = tscGetQueryInfoDetail(pnCmd, 0); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pnCmd, 0); pNewQueryInfo->command = pQueryInfo->command; + pnCmd->active = pNewQueryInfo; + memcpy(&pNewQueryInfo->interval, &pQueryInfo->interval, sizeof(pNewQueryInfo->interval)); pNewQueryInfo->type = pQueryInfo->type; pNewQueryInfo->window = pQueryInfo->window; @@ -2326,18 +2701,18 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } - - tscColumnListCopy(pNewQueryInfo->colList, pQueryInfo->colList, (int16_t)tableIndex); + + uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; + tscColumnListCopy(pNewQueryInfo->colList, pQueryInfo->colList, uid); // set the correct query type if (pPrevSql != NULL) { - SQueryInfo* pPrevQueryInfo = tscGetQueryInfoDetail(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex); + SQueryInfo* pPrevQueryInfo = tscGetQueryInfo(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex); pNewQueryInfo->type = pPrevQueryInfo->type; } else { TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_SUBQUERY);// it must be the subquery } - uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; if (tscSqlExprCopy(pNewQueryInfo->exprList, pQueryInfo->exprList, uid, true) != 0) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; @@ -2392,22 +2767,22 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t assert(pFinalInfo->vgroupList != NULL); } + registerSqlObj(pNew); + if (cmd == TSDB_SQL_SELECT) { size_t size = taosArrayGetSize(pNewQueryInfo->colList); - tscDebug( - "%p new subquery:%p, tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%" PRIzu ", colList:%" PRIzu "," + 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, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo), + pSql->self, pNew->self, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo), size, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pFinalInfo->name), pNewQueryInfo->window.skey, pNewQueryInfo->window.ekey, pNewQueryInfo->order.order, pNewQueryInfo->limit.limit); - tscPrintSelectClause(pNew, 0); + tscPrintSelNodeList(pNew, 0); } else { tscDebug("0x%"PRIx64" new sub insertion: %p, vnodeIdx:%d", pSql->self, pNew, pTableMetaInfo->vgroupIndex); } - registerSqlObj(pNew); return pNew; _error: @@ -2415,7 +2790,54 @@ _error: return NULL; } +void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { + uint16_t type = pQueryInfo->type; + if (QUERY_IS_JOIN_QUERY(type) && !TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_SUBQUERY)) { + tscHandleMasterJoinQuery(pSql); + } else if (tscMultiRoundQuery(pQueryInfo, 0) && pQueryInfo->round == 0) { + tscHandleFirstRoundStableQuery(pSql); // todo lock? + } else if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query + tscLockByThread(&pSql->squeryLock); + tscHandleMasterSTableQuery(pSql); + tscUnlockByThread(&pSql->squeryLock); + } else if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) { + tscHandleMultivnodeInsert(pSql); + } else if (pSql->cmd.command > TSDB_SQL_LOCAL) { + tscProcessLocalCmd(pSql); + } else { // send request to server directly + tscBuildAndSendRequest(pSql, pQueryInfo); + } +} + +// do execute the query according to the query execution plan +void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { + if (pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) { + (*pSql->fp)(pSql->param, pSql, 0); + return; + } + + if (pSql->cmd.command == TSDB_SQL_SELECT) { + tscAddIntoSqlList(pSql); + } + + if (taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // nest query. do execute it firstly + SQueryInfo* pq = taosArrayGetP(pQueryInfo->pUpstream, 0); + + pSql->cmd.active = pq; + pSql->cmd.command = TSDB_SQL_SELECT; + + executeQuery(pSql, pq); + + // merge nest query result and generate final results + return; + } + + pSql->cmd.active = pQueryInfo; + doExecuteQuery(pSql, pQueryInfo); +} + /** + * 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 @@ -2438,27 +2860,22 @@ void tscDoQuery(SSqlObj* pSql) { if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) { tscImportDataFromFile(pSql); } else { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); uint16_t type = pQueryInfo->type; - - 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)) { - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } else { // secondary stage join query. if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query tscLockByThread(&pSql->squeryLock); tscHandleMasterSTableQuery(pSql); tscUnlockByThread(&pSql->squeryLock); } else { - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } } } @@ -2473,8 +2890,9 @@ void tscDoQuery(SSqlObj* pSql) { tscUnlockByThread(&pSql->squeryLock); return; } - - tscProcessSql(pSql); + + pCmd->active = pQueryInfo; + tscBuildAndSendRequest(pSql, NULL); } } @@ -2534,7 +2952,7 @@ bool tscIsQueryWithLimit(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; for (int32_t i = 0; i < pCmd->numOfClause; ++i) { - SQueryInfo* pqi = tscGetQueryInfoDetailSafely(pCmd, i); + SQueryInfo* pqi = tscGetQueryInfoS(pCmd, i); if (pqi == NULL) { continue; } @@ -2619,7 +3037,7 @@ bool hasMoreVnodesToTry(SSqlObj* pSql) { } assert(pRes->completed); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); // for normal table, no need to try any more if results are all retrieved from one vnode @@ -2644,7 +3062,7 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); /* * no result returned from the current virtual node anymore, try the next vnode if exists @@ -2690,7 +3108,7 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) { // set the callback function pSql->fp = fp; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } else { tscDebug("0x%"PRIx64" try all %d vnodes, query complete. current numOfRes:%" PRId64, pSql->self, totalVgroups, pRes->numOfClauseTotal); } @@ -2704,7 +3122,7 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) { assert(pCmd->clauseIndex < pCmd->numOfClause - 1); pCmd->clauseIndex++; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); pSql->cmd.command = pQueryInfo->command; @@ -2728,7 +3146,7 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) { if (pCmd->command > TSDB_SQL_LOCAL) { tscProcessLocalCmd(pSql); } else { - tscDoQuery(pSql); + executeQuery(pSql, pQueryInfo); } } @@ -2987,4 +3405,288 @@ STableMeta* tscTableMetaDup(STableMeta* pTableMeta) { return p; } +static int32_t createSecondaryExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo) { + if (!tscIsSecondStageQuery(pQueryInfo)) { + return TSDB_CODE_SUCCESS; + } + pQueryAttr->numOfExpr2 = tscNumOfFields(pQueryInfo); + pQueryAttr->pExpr2 = calloc(pQueryAttr->numOfExpr2, sizeof(SExprInfo)); + if (pQueryAttr->pExpr2 == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pQueryAttr->numOfExpr2; ++i) { + SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i); + SExprInfo* pExpr = pField->pExpr; + + SSqlExpr *pse = &pQueryAttr->pExpr2[i].base; + pse->uid = pTableMetaInfo->pTableMeta->id.uid; + pse->resColId = pExpr->base.resColId; + + if (pExpr->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; + + for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) { + if (pQueryAttr->pExpr1[j].base.resColId == pse->colInfo.colId) { + pse->colInfo.colIndex = j; + } + } + + pse->colInfo.flag = TSDB_COL_NORMAL; + pse->resType = pExpr->base.resType; + pse->resBytes = pExpr->base.resBytes; + + // TODO restore refactor + int32_t functionId = pExpr->base.functionId; + if (pExpr->base.functionId == TSDB_FUNC_FIRST_DST) { + functionId = TSDB_FUNC_FIRST; + } else if (pExpr->base.functionId == TSDB_FUNC_LAST_DST) { + functionId = TSDB_FUNC_LAST; + } else if (pExpr->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, + &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->resBytes = sizeof(double); + pse->resType = TSDB_DATA_TYPE_DOUBLE; + + pse->functionId = pExpr->base.functionId; + pse->numOfParams = pExpr->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); + } + } + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t createGlobalAggregateExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInfo) { + assert(tscIsTwoStageSTableQuery(pQueryInfo, 0)); + + pQueryAttr->numOfExpr3 = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + pQueryAttr->pExpr3 = calloc(pQueryAttr->numOfExpr3, sizeof(SExprInfo)); + if (pQueryAttr->pExpr3 == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pQueryAttr->numOfExpr3; ++i) { + SExprInfo* pExpr = &pQueryAttr->pExpr1[i]; + SSqlExpr* pse = &pQueryAttr->pExpr3[i].base; + + tscSqlExprAssign(&pQueryAttr->pExpr3[i], pExpr); + pse->colInfo.colId = pExpr->base.resColId; + pse->colInfo.colIndex = i; + + pse->colType = pExpr->base.resType; + pse->colBytes = pExpr->base.resBytes; + } + + { + for (int32_t i = 0; i < pQueryAttr->numOfExpr3; ++i) { + SExprInfo* pExpr = &pQueryAttr->pExpr1[i]; + SSqlExpr* pse = &pQueryAttr->pExpr3[i].base; + + // the final result size and type in the same as query on single table. + // so here, set the flag to be false; + int32_t inter = 0; + + int32_t functionId = pExpr->base.functionId; + if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) { + continue; + } + + if (functionId == TSDB_FUNC_FIRST_DST) { + functionId = TSDB_FUNC_FIRST; + } else if (functionId == TSDB_FUNC_LAST_DST) { + functionId = TSDB_FUNC_LAST; + } else if (functionId == TSDB_FUNC_STDDEV_DST) { + functionId = TSDB_FUNC_STDDEV; + } + + getResultDataInfo(pExpr->base.colType, pExpr->base.colBytes, functionId, 0, &pse->resType, &pse->resBytes, &inter, + 0, false); + } + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t createTagColumnInfo(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo) { + if (pTableMetaInfo->tagColList == NULL) { + return TSDB_CODE_SUCCESS; + } + + pQueryAttr->numOfTags = (int16_t)taosArrayGetSize(pTableMetaInfo->tagColList); + if (pQueryAttr->numOfTags == 0) { + return TSDB_CODE_SUCCESS; + } + + STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[0]->pTableMeta; + + int32_t numOfTagColumns = tscGetNumOfTags(pTableMeta); + + pQueryAttr->tagColList = calloc(pQueryAttr->numOfTags, sizeof(SColumnInfo)); + if (pQueryAttr->tagColList == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + SSchema* pSchema = tscGetTableTagSchema(pTableMeta); + for (int32_t i = 0; i < pQueryAttr->numOfTags; ++i) { + SColumn* pCol = taosArrayGetP(pTableMetaInfo->tagColList, i); + SSchema* pColSchema = &pSchema[pCol->columnIndex]; + + if ((pCol->columnIndex >= numOfTagColumns || pCol->columnIndex < TSDB_TBNAME_COLUMN_INDEX) || + (!isValidDataType(pColSchema->type))) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + SColumnInfo* pTagCol = &pQueryAttr->tagColList[i]; + + pTagCol->colId = pColSchema->colId; + pTagCol->bytes = pColSchema->bytes; + pTagCol->type = pColSchema->type; + pTagCol->flist.numOfFilters = 0; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr) { + memset(pQueryAttr, 0, sizeof(SQueryAttr)); + + int16_t numOfCols = (int16_t) taosArrayGetSize(pQueryInfo->colList); + int16_t numOfOutput = (int16_t) tscSqlExprNumOfExprs(pQueryInfo); + + pQueryAttr->topBotQuery = tscIsTopBotQuery(pQueryInfo); + pQueryAttr->hasTagResults = hasTagValOutput(pQueryInfo); + pQueryAttr->stabledev = isStabledev(pQueryInfo); + pQueryAttr->tsCompQuery = isTsCompQuery(pQueryInfo); + pQueryAttr->simpleAgg = isSimpleAggregate(pQueryInfo); + pQueryAttr->needReverseScan = tscNeedReverseScan(pQueryInfo); + pQueryAttr->stableQuery = QUERY_IS_STABLE_QUERY(pQueryInfo->type); + pQueryAttr->groupbyColumn = tscGroupbyColumn(pQueryInfo); + pQueryAttr->queryBlockDist = isBlockDistQuery(pQueryInfo); + pQueryAttr->pointInterpQuery = tscIsPointInterpQuery(pQueryInfo); + pQueryAttr->timeWindowInterpo = timeWindowInterpoRequired(pQueryInfo); + pQueryAttr->distinctTag = pQueryInfo->distinctTag; + + pQueryAttr->numOfCols = numOfCols; + pQueryAttr->numOfOutput = numOfOutput; + pQueryAttr->limit = pQueryInfo->limit; + 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; + } else { + pQueryAttr->window.skey = pQueryInfo->window.ekey; + pQueryAttr->window.ekey = pQueryInfo->window.skey; + } + + memcpy(&pQueryAttr->interval, &pQueryInfo->interval, sizeof(pQueryAttr->interval)); + + STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; + + pQueryAttr->pGroupbyExpr = calloc(1, sizeof(SSqlGroupbyExpr)); + *(pQueryAttr->pGroupbyExpr) = pQueryInfo->groupbyExpr; + + if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { + pQueryAttr->pGroupbyExpr->columnInfo = taosArrayDup(pQueryInfo->groupbyExpr.columnInfo); + } else { + assert(pQueryInfo->groupbyExpr.columnInfo == NULL); + } + + 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); + + if (pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_ARITHM) { + for (int32_t j = 0; j < pQueryAttr->pExpr1[i].base.numOfParams; ++j) { + buildArithmeticExprFromMsg(&pQueryAttr->pExpr1[i], NULL); + } + } + } + + pQueryAttr->tableCols = calloc(numOfCols, sizeof(SColumnInfo)); + for(int32_t i = 0; i < numOfCols; ++i) { + SColumn* pCol = taosArrayGetP(pQueryInfo->colList, i); + if (!isValidDataType(pCol->info.type) || pCol->info.type == TSDB_DATA_TYPE_NULL) { + assert(0); + } + + pQueryAttr->tableCols[i] = pCol->info; + pQueryAttr->tableCols[i].flist.filterInfo = tFilterInfoDup(pCol->info.flist.filterInfo, pQueryAttr->tableCols[i].flist.numOfFilters); + } + + // global aggregate query + if (pQueryAttr->stableQuery && (pQueryAttr->simpleAgg || pQueryAttr->interval.interval > 0) && tscIsTwoStageSTableQuery(pQueryInfo, 0)) { + createGlobalAggregateExpr(pQueryAttr, pQueryInfo); + } + + // for simple table, not for super table + int32_t code = createSecondaryExpr(pQueryAttr, pQueryInfo, pTableMetaInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + // tag column info + code = createTagColumnInfo(pQueryAttr, pQueryInfo, pTableMetaInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + if (pQueryAttr->fillType != TSDB_FILL_NONE) { + pQueryAttr->fillVal = calloc(pQueryAttr->numOfOutput, sizeof(int64_t)); + memcpy(pQueryAttr->fillVal, pQueryInfo->fillVal, pQueryAttr->numOfOutput * sizeof(int64_t)); + } + + pQueryAttr->srcRowSize = 0; + pQueryAttr->maxTableColumnWidth = 0; + for (int16_t i = 0; i < numOfCols; ++i) { + pQueryAttr->srcRowSize += pQueryAttr->tableCols[i].bytes; + if (pQueryAttr->maxTableColumnWidth < pQueryAttr->tableCols[i].bytes) { + pQueryAttr->maxTableColumnWidth = pQueryAttr->tableCols[i].bytes; + } + } + + pQueryAttr->interBufSize = getOutputInterResultBufSize(pQueryAttr); + + if (pQueryAttr->numOfCols <= 0 && !tscQueryTags(pQueryInfo) && !pQueryAttr->queryBlockDist) { + 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; + } + + 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; + } + + 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_SUCCESS; +} diff --git a/src/common/inc/tdataformat.h b/src/common/inc/tdataformat.h index e8c0760997..88d5b85010 100644 --- a/src/common/inc/tdataformat.h +++ b/src/common/inc/tdataformat.h @@ -15,10 +15,7 @@ #ifndef _TD_DATA_FORMAT_H_ #define _TD_DATA_FORMAT_H_ -#include -#include -#include - +#include "os.h" #include "talgo.h" #include "ttype.h" #include "tutil.h" diff --git a/src/common/inc/texpr.h b/src/common/inc/texpr.h index acfbffc01e..a0854ce81b 100644 --- a/src/common/inc/texpr.h +++ b/src/common/inc/texpr.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef TDENGINE_TAST_H -#define TDENGINE_TAST_H +#ifndef TDENGINE_TEXPR_H +#define TDENGINE_TEXPR_H #ifdef __cplusplus extern "C" { @@ -62,32 +62,32 @@ typedef struct tExprNode { uint8_t nodeType; union { struct { - uint8_t optr; // filter operator - uint8_t hasPK; // 0: do not contain primary filter, 1: contain - void * info; // support filter operation on this expression only available for leaf node - + uint8_t optr; // filter operator + uint8_t hasPK; // 0: do not contain primary filter, 1: contain + void *info; // support filter operation on this expression only available for leaf node struct tExprNode *pLeft; // left child pointer struct tExprNode *pRight; // right child pointer } _node; - struct SSchema *pSchema; - tVariant * pVal; + + struct SSchema *pSchema; + tVariant *pVal; }; } tExprNode; typedef struct SExprTraverseSupp { __result_filter_fn_t nodeFilterFn; __do_filter_suppl_fn_t setupInfoFn; - void * pExtInfo; + void *pExtInfo; } SExprTraverseSupp; void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)); +void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree); tExprNode* exprTreeFromBinary(const void* data, size_t size); tExprNode* exprTreeFromTableName(const char* tbnameCond); +tExprNode* exprdup(tExprNode* pTree); -void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree); - -bool exprTreeApplayFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param); +bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param); typedef void (*_arithmetic_operator_fn_t)(void *left, int32_t numLeft, int32_t leftType, void *right, int32_t numRight, int32_t rightType, void *output, int32_t order); @@ -99,4 +99,4 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, } #endif -#endif // TDENGINE_TAST_H +#endif // TDENGINE_TEXPR_H diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 26475834d5..2f4aa4c2b2 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -44,6 +44,7 @@ extern int32_t tsDnodeId; // common extern int tsRpcTimer; extern int tsRpcMaxTime; +extern int tsRpcForceTcp; // all commands go to tcp protocol if this is enabled extern int32_t tsMaxConnections; extern int32_t tsMaxShellConns; extern int32_t tsShellActivityTimer; diff --git a/src/common/inc/tname.h b/src/common/inc/tname.h index 465b298973..f37a4d9a36 100644 --- a/src/common/inc/tname.h +++ b/src/common/inc/tname.h @@ -41,6 +41,35 @@ typedef struct SResPair { double avg; } SResPair; +// the structure for sql function in select clause +typedef struct SSqlExpr { + char aliasName[TSDB_COL_NAME_LEN]; // as aliasName + SColIndex colInfo; + + uint64_t uid; // refactor use the pointer + + int16_t functionId; // function id in aAgg array + + int16_t resType; // return value type + int16_t resBytes; // length of return value + int32_t interBytes; // inter result buffer size + + int16_t colType; // table column type + int16_t colBytes; // table column bytes + + int16_t numOfParams; // argument value of each function + tVariant param[3]; // parameters are not more than 3 + int32_t offset; // sub result column value of arithmetic expression. + int16_t resColId; // result column id + + SColumnFilterList flist; +} SSqlExpr; + +typedef struct SExprInfo { + SSqlExpr base; + struct tExprNode *pExpr; +} SExprInfo; + #define TSDB_DB_NAME_T 1 #define TSDB_TABLE_NAME_T 2 diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index 1008c4cf8f..4334a0de26 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -15,6 +15,7 @@ #include "os.h" +#include "texpr.h" #include "exception.h" #include "taosdef.h" #include "taosmsg.h" @@ -145,25 +146,25 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { *pExpr = NULL; } -bool exprTreeApplayFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param) { +bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param) { tExprNode *pLeft = pExpr->_node.pLeft; tExprNode *pRight = pExpr->_node.pRight; //non-leaf nodes, recursively traverse the expression tree in the post-root order if (pLeft->nodeType == TSQL_NODE_EXPR && pRight->nodeType == TSQL_NODE_EXPR) { if (pExpr->_node.optr == TSDB_RELATION_OR) { // or - if (exprTreeApplayFilter(pLeft, pItem, param)) { + if (exprTreeApplyFilter(pLeft, pItem, param)) { return true; } // left child does not satisfy the query condition, try right child - return exprTreeApplayFilter(pRight, pItem, param); + return exprTreeApplyFilter(pRight, pItem, param); } else { // and - if (!exprTreeApplayFilter(pLeft, pItem, param)) { + if (!exprTreeApplyFilter(pLeft, pItem, param)) { return false; } - return exprTreeApplayFilter(pRight, pItem, param); + return exprTreeApplyFilter(pRight, pItem, param); } } @@ -463,3 +464,28 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { CLEANUP_EXECUTE_TO(anchor, false); return expr; } + +tExprNode* exprdup(tExprNode* pTree) { + if (pTree == 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; + } + + return pNode; +} + diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index c3c159ee45..db97c3a5af 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -48,6 +48,7 @@ int32_t tsDnodeId = 0; // common int32_t tsRpcTimer = 1000; int32_t tsRpcMaxTime = 600; // seconds; +int32_t tsRpcForceTcp = 0; //disable this, means query, show command use udp protocol as default int32_t tsMaxShellConns = 50000; int32_t tsMaxConnections = 5000; int32_t tsShellActivityTimer = 3; // second @@ -625,6 +626,16 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_MS; taosInitConfigOption(cfg); + cfg.option = "rpcForceTcp"; + cfg.ptr = &tsRpcForceTcp; + cfg.valType = TAOS_CFG_VTYPE_INT32; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT; + cfg.minValue = 0; + cfg.maxValue = 1; + cfg.ptrLength = 0; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + cfg.option = "rpcMaxTime"; cfg.ptr = &tsRpcMaxTime; cfg.valType = TAOS_CFG_VTYPE_INT32; @@ -921,7 +932,7 @@ static void doInitGlobalConfig(void) { cfg.valType = TAOS_CFG_VTYPE_INT32; cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT | TSDB_CFG_CTYPE_B_SHOW; cfg.minValue = -1; - cfg.maxValue = 10000000; + cfg.maxValue = 100000000.0f; cfg.ptrLength = 0; cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); diff --git a/src/common/src/tname.c b/src/common/src/tname.c index 787aa1e95b..f1ddc60637 100644 --- a/src/common/src/tname.c +++ b/src/common/src/tname.c @@ -68,6 +68,7 @@ bool tscValidateTableNameLength(size_t len) { return len < TSDB_TABLE_NAME_LEN; } +// TODO refactor SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFilters) { if (numOfFilters == 0) { assert(src == NULL); diff --git a/src/connector/go b/src/connector/go index 7a26c432f8..050667e5b4 160000 --- a/src/connector/go +++ b/src/connector/go @@ -1 +1 @@ -Subproject commit 7a26c432f8b4203e42344ff3290b9b9b01b983d5 +Subproject commit 050667e5b4d0eafa5387e4283e713559b421203f diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java index f58e3f8cd2..4e64b708c9 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java @@ -1,5 +1,8 @@ package com.taosdata.jdbc.rs; +import com.google.common.collect.Range; +import com.google.common.collect.RangeSet; +import com.google.common.collect.TreeRangeSet; import com.taosdata.jdbc.TSDBError; import com.taosdata.jdbc.TSDBErrorNumbers; import com.taosdata.jdbc.utils.Utils; @@ -10,6 +13,12 @@ import java.math.BigDecimal; import java.net.URL; import java.sql.*; import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class RestfulPreparedStatement extends RestfulStatement implements PreparedStatement { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java index 0ce4bd3dc1..052f34858d 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java @@ -103,6 +103,7 @@ public class Utils { */ private static String transformSql(String rawSql, Object[] paramArr, Map placeholderPosition, RangeSet clauseRangeSet) { String[] sqlArr = rawSql.split("\\?"); + return IntStream.range(0, sqlArr.length).mapToObj(index -> { if (index == paramArr.length) return sqlArr[index]; diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java index 9014e82a9e..efc83a6df1 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java @@ -345,6 +345,7 @@ public class InsertSpecialCharacterJniTest { } } + @Test public void testCase12() throws SQLException { final long now = System.currentTimeMillis(); diff --git a/src/dnode/src/dnodeCfg.c b/src/dnode/src/dnodeCfg.c index c573d709f5..586adacc98 100644 --- a/src/dnode/src/dnodeCfg.c +++ b/src/dnode/src/dnodeCfg.c @@ -158,7 +158,7 @@ static int32_t dnodeWriteCfg() { len += snprintf(content + len, maxLen - len, "}\n"); fwrite(content, 1, len, fp); - fsync(fileno(fp)); + taosFsync(fileno(fp)); fclose(fp); free(content); terrno = 0; diff --git a/src/dnode/src/dnodeEps.c b/src/dnode/src/dnodeEps.c index 9554651776..9b15353647 100644 --- a/src/dnode/src/dnodeEps.c +++ b/src/dnode/src/dnodeEps.c @@ -277,7 +277,7 @@ static int32_t dnodeWriteEps() { len += snprintf(content + len, maxLen - len, "}\n"); fwrite(content, 1, len, fp); - fsync(fileno(fp)); + taosFsync(fileno(fp)); fclose(fp); free(content); terrno = 0; diff --git a/src/dnode/src/dnodeMInfos.c b/src/dnode/src/dnodeMInfos.c index 0dca116d84..611c30b843 100644 --- a/src/dnode/src/dnodeMInfos.c +++ b/src/dnode/src/dnodeMInfos.c @@ -286,7 +286,7 @@ static int32_t dnodeWriteMInfos() { len += snprintf(content + len, maxLen - len, "}\n"); fwrite(content, 1, len, fp); - fsync(fileno(fp)); + taosFsync(fileno(fp)); fclose(fp); free(content); terrno = 0; diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index 024bc198df..e596ee67ec 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -22,7 +22,6 @@ extern "C" { #include #include -#include "osDef.h" #include "taos.h" #define TSDB__packed @@ -243,8 +242,9 @@ do { \ #define TSDB_MAX_REPLICA 5 #define TSDB_TBNAME_COLUMN_INDEX (-1) -#define TSDB_BLOCK_DIST_COLUMN_INDEX (-2) -#define TSDB_UD_COLUMN_INDEX (-100) +#define TSDB_BLOCK_DIST_COLUMN_INDEX (-2) +#define TSDB_UD_COLUMN_INDEX (-1000) +#define TSDB_RES_COL_ID (-5000) #define TSDB_MULTI_TABLEMETA_MAX_NUM 100000 // maximum batch size allowed to load table meta @@ -388,9 +388,10 @@ typedef enum { typedef enum { TSDB_SUPER_TABLE = 0, // super table TSDB_CHILD_TABLE = 1, // table created from super table - TSDB_NORMAL_TABLE = 2, // ordinary table - TSDB_STREAM_TABLE = 3, // table created from stream computing - TSDB_TABLE_MAX = 4 + TSDB_NORMAL_TABLE = 2, // ordinary table + TSDB_STREAM_TABLE = 3, // table created from stream computing + TSDB_TEMP_TABLE = 4, // temp table created by nest query + TSDB_TABLE_MAX = 5 } ETableType; typedef enum { diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index d7ac7dd277..3b7022fb88 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -399,7 +399,6 @@ typedef struct SColIndex { char name[TSDB_COL_NAME_LEN]; // TODO remove it } SColIndex; - typedef struct SColumnFilterInfo { int16_t lowerRelOptr; int16_t upperRelOptr; @@ -421,42 +420,13 @@ typedef struct SColumnFilterInfo { }; } SColumnFilterInfo; -/* sql function msg, to describe the message to vnode about sql function - * operations in select clause */ -typedef struct SSqlFuncMsg { - int16_t functionId; - int16_t numOfParams; - - int16_t resColId; // result column id, id of the current output column - int16_t colType; - int16_t colBytes; - - SColIndex colInfo; - struct ArgElem { - int16_t argType; - int16_t argBytes; - union { - double d; - int64_t i64; - char * pz; - } argValue; - } arg[3]; - - int32_t filterNum; - SColumnFilterInfo filterInfo[]; -} SSqlFuncMsg; - - -typedef struct SExprInfo { - SColumnFilterInfo * pFilter; - struct tExprNode* pExpr; - int16_t bytes; - int16_t type; - int32_t interBytes; - int64_t uid; - SSqlFuncMsg base; -} SExprInfo; - +typedef struct SColumnFilterList { + int16_t numOfFilters; + union{ + int64_t placeholder; + SColumnFilterInfo *filterInfo; + }; +} SColumnFilterList; /* * for client side struct, we only need the column id, type, bytes are not necessary * But for data in vnode side, we need all the following information. @@ -465,11 +435,7 @@ typedef struct SColumnInfo { int16_t colId; int16_t type; int16_t bytes; - int16_t numOfFilters; - union{ - int64_t placeholder; - SColumnFilterInfo *filters; - }; + SColumnFilterList flist; } SColumnInfo; typedef struct STableIdInfo { @@ -483,10 +449,29 @@ typedef struct STimeWindow { TSKEY ekey; } STimeWindow; +typedef struct { + int32_t tsOffset; // offset value in current msg body, NOTE: ts list is compressed + int32_t tsLen; // total length of ts comp block + int32_t tsNumOfBlocks; // ts comp block numbers + int32_t tsOrder; // ts comp block order +} STsBufInfo; + typedef struct { SMsgHead head; char version[TSDB_VERSION_LEN]; + bool stableQuery; // super table query or not + bool topBotQuery; // TODO used bitwise flag + bool groupbyColumn; // denote if this is a groupby normal column query + bool hasTagResults; // if there are tag values in final result or not + bool timeWindowInterpo;// if the time window start/end required interpolation + bool queryBlockDist; // if query data block distribution + bool stabledev; // super table stddev query + bool tsCompQuery; // is tscomp query + bool simpleAgg; + bool pointInterpQuery; // point interpolation query + bool needReverseScan; // need reverse scan + STimeWindow window; int32_t numOfTables; int16_t order; @@ -509,14 +494,13 @@ typedef struct { int16_t fillType; // interpolate type uint64_t fillVal; // default value array list int32_t secondStageOutput; - int32_t tsOffset; // offset value in current msg body, NOTE: ts list is compressed - int32_t tsLen; // total length of ts comp block - int32_t tsNumOfBlocks; // ts comp block numbers - int32_t tsOrder; // ts comp block order + STsBufInfo tsBuf; // tsBuf info int32_t numOfTags; // number of tags columns involved int32_t sqlstrLen; // sql query string int32_t prevResultLen; // previous result length - SColumnInfo colList[]; + int32_t numOfOperator; + int32_t tableScanOperator;// table scan operator. -1 means no scan operator + SColumnInfo tableCols[]; } SQueryTableMsg; typedef struct { @@ -827,7 +811,7 @@ typedef struct { uint32_t queryId; int64_t useconds; int64_t stime; - uint64_t qHandle; + uint64_t qId; } SQueryDesc; typedef struct { diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h index 85ee9f0443..1ba5131f6d 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -221,7 +221,7 @@ typedef struct { typedef struct { uint32_t numOfTables; - SArray * pGroupList; + SArray *pGroupList; SHashObj *map; // speedup acquire the tableQueryInfo by table uid } STableGroupInfo; diff --git a/src/inc/ttokendef.h b/src/inc/ttokendef.h index c7c4b5968b..e9f95660f7 100644 --- a/src/inc/ttokendef.h +++ b/src/inc/ttokendef.h @@ -205,13 +205,6 @@ #define TK_VALUES 186 - - - - - - - #define TK_SPACE 300 #define TK_COMMENT 301 #define TK_ILLEGAL 302 diff --git a/src/inc/ttype.h b/src/inc/ttype.h index 662a23bfdb..9949f31c59 100644 --- a/src/inc/ttype.h +++ b/src/inc/ttype.h @@ -5,6 +5,8 @@ extern "C" { #endif +#include +#include #include "taosdef.h" // ----------------- For variable data types such as TSDB_DATA_TYPE_BINARY and TSDB_DATA_TYPE_NCHAR diff --git a/src/kit/shell/src/shellCheck.c b/src/kit/shell/src/shellCheck.c index b88244ea01..8f7f475536 100644 --- a/src/kit/shell/src/shellCheck.c +++ b/src/kit/shell/src/shellCheck.c @@ -142,7 +142,7 @@ static void *shellCheckThreadFp(void *arg) { taos_free_result(pSql); } - fsync(fileno(fp)); + taosFsync(fileno(fp)); fclose(fp); return NULL; diff --git a/src/kit/shell/src/shellLinux.c b/src/kit/shell/src/shellLinux.c index 3f6b3da9bf..37050c416c 100644 --- a/src/kit/shell/src/shellLinux.c +++ b/src/kit/shell/src/shellLinux.c @@ -37,7 +37,7 @@ static struct argp_option options[] = { {"password", 'p', "PASSWORD", OPTION_ARG_OPTIONAL, "The password to use when connecting to the server."}, {"port", 'P', "PORT", 0, "The TCP/IP port number to use for the connection."}, {"user", 'u', "USER", 0, "The user name to use when connecting to the server."}, - {"user", 'A', "Auth", 0, "The user auth to use when connecting to the server."}, + {"auth", 'A', "Auth", 0, "The auth string to use when connecting to the server."}, {"config-dir", 'c', "CONFIG_DIR", 0, "Configuration directory."}, {"dump-config", 'C', 0, 0, "Dump configuration."}, {"commands", 's', "COMMANDS", 0, "Commands to run without enter the shell."}, diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index 99befbaf31..8284de5d68 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -68,12 +68,6 @@ enum TEST_MODE { INVAID_TEST }; -enum QUERY_MODE { - SYNC_QUERY_MODE, // 0 - ASYNC_QUERY_MODE, // 1 - INVALID_MODE -}; - #define MAX_SQL_SIZE 65536 #define BUFFER_SIZE (65536*2) #define MAX_USERNAME_SIZE 64 @@ -118,8 +112,8 @@ typedef enum TALBE_EXISTS_EN { } TALBE_EXISTS_EN; enum MODE { - SYNC, - ASYNC, + SYNC_MODE, + ASYNC_MODE, MODE_BUT }; @@ -205,7 +199,7 @@ typedef struct SArguments_S { bool verbose_print; bool performance_print; char * output_file; - uint32_t query_mode; + bool async_mode; char * datatype[MAX_NUM_DATATYPE + 1]; uint32_t len_of_binary; uint32_t num_of_CPR; @@ -343,7 +337,7 @@ typedef struct SDbs_S { bool use_metric; bool insert_only; bool do_aggreFunc; - bool queryMode; + bool asyncMode; uint32_t threadCount; uint32_t threadCountByCreateTbl; @@ -360,7 +354,7 @@ typedef struct SpecifiedQueryInfo_S { uint64_t queryInterval; // 0: unlimit > 0 loop/s uint64_t concurrent; uint64_t sqlCount; - uint32_t mode; // 0: sync, 1: async + uint32_t asyncMode; // 0: sync, 1: async uint64_t subscribeInterval; // ms uint64_t queryTimes; int subscribeRestart; @@ -375,7 +369,7 @@ typedef struct SuperQueryInfo_S { char sTblName[MAX_TB_NAME_SIZE+1]; uint64_t queryInterval; // 0: unlimit > 0 loop/s uint32_t threadCnt; - uint32_t mode; // 0: sync, 1: async + uint32_t asyncMode; // 0: sync, 1: async uint64_t subscribeInterval; // ms int subscribeRestart; int subscribeKeepProgress; @@ -777,7 +771,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { errorPrint("%s", "\n\t-q need a number following!\nQuery mode -- 0: SYNC, 1: ASYNC. Default is SYNC.\n"); exit(EXIT_FAILURE); } - arguments->query_mode = atoi(argv[++i]); + arguments->async_mode = atoi(argv[++i]); } else if (strcmp(argv[i], "-T") == 0) { if ((argc == i+1) || (!isStringNumber(argv[i+1]))) { @@ -1646,7 +1640,7 @@ static void printfQueryMeta() { printf("concurrent: \033[33m%"PRIu64"\033[0m\n", g_queryInfo.specifiedQueryInfo.concurrent); printf("mod: \033[33m%s\033[0m\n", - (g_queryInfo.specifiedQueryInfo.mode)?"async":"sync"); + (g_queryInfo.specifiedQueryInfo.asyncMode)?"async":"sync"); printf("interval: \033[33m%"PRIu64"\033[0m\n", g_queryInfo.specifiedQueryInfo.subscribeInterval); printf("restart: \033[33m%d\033[0m\n", @@ -1678,7 +1672,7 @@ static void printfQueryMeta() { g_queryInfo.superQueryInfo.queryTimes); printf("mod: \033[33m%s\033[0m\n", - (g_queryInfo.superQueryInfo.mode)?"async":"sync"); + (g_queryInfo.superQueryInfo.asyncMode)?"async":"sync"); printf("interval: \033[33m%"PRIu64"\033[0m\n", g_queryInfo.superQueryInfo.subscribeInterval); printf("restart: \033[33m%d\033[0m\n", @@ -4121,20 +4115,20 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { g_queryInfo.specifiedQueryInfo.concurrent = 1; } - cJSON* mode = cJSON_GetObjectItem(specifiedQuery, "mode"); - if (mode && mode->type == cJSON_String - && mode->valuestring != NULL) { - if (0 == strcmp("sync", mode->valuestring)) { - g_queryInfo.specifiedQueryInfo.mode = SYNC_QUERY_MODE; - } else if (0 == strcmp("async", mode->valuestring)) { - g_queryInfo.specifiedQueryInfo.mode = ASYNC_QUERY_MODE; + cJSON* specifiedAsyncMode = cJSON_GetObjectItem(specifiedQuery, "mode"); + if (specifiedAsyncMode && specifiedAsyncMode->type == cJSON_String + && specifiedAsyncMode->valuestring != NULL) { + if (0 == strcmp("sync", specifiedAsyncMode->valuestring)) { + g_queryInfo.specifiedQueryInfo.asyncMode = SYNC_MODE; + } else if (0 == strcmp("async", specifiedAsyncMode->valuestring)) { + g_queryInfo.specifiedQueryInfo.asyncMode = ASYNC_MODE; } else { - errorPrint("%s() LN%d, failed to read json, query mode input error\n", + errorPrint("%s() LN%d, failed to read json, async mode input error\n", __func__, __LINE__); goto PARSE_OVER; } } else { - g_queryInfo.specifiedQueryInfo.mode = SYNC_QUERY_MODE; + g_queryInfo.specifiedQueryInfo.asyncMode = SYNC_MODE; } cJSON* interval = cJSON_GetObjectItem(specifiedQuery, "interval"); @@ -4281,20 +4275,20 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { goto PARSE_OVER; } - cJSON* submode = cJSON_GetObjectItem(superQuery, "mode"); - if (submode && submode->type == cJSON_String - && submode->valuestring != NULL) { - if (0 == strcmp("sync", submode->valuestring)) { - g_queryInfo.superQueryInfo.mode = SYNC_QUERY_MODE; - } else if (0 == strcmp("async", submode->valuestring)) { - g_queryInfo.superQueryInfo.mode = ASYNC_QUERY_MODE; + cJSON* superAsyncMode = cJSON_GetObjectItem(superQuery, "mode"); + if (superAsyncMode && superAsyncMode->type == cJSON_String + && superAsyncMode->valuestring != NULL) { + if (0 == strcmp("sync", superAsyncMode->valuestring)) { + g_queryInfo.superQueryInfo.asyncMode = SYNC_MODE; + } else if (0 == strcmp("async", superAsyncMode->valuestring)) { + g_queryInfo.superQueryInfo.asyncMode = ASYNC_MODE; } else { - errorPrint("%s() LN%d, failed to read json, query mode input error\n", + errorPrint("%s() LN%d, failed to read json, async mode input error\n", __func__, __LINE__); goto PARSE_OVER; } } else { - g_queryInfo.superQueryInfo.mode = SYNC_QUERY_MODE; + g_queryInfo.superQueryInfo.asyncMode = SYNC_MODE; } cJSON* superInterval = cJSON_GetObjectItem(superQuery, "interval"); @@ -5748,10 +5742,10 @@ static void startMultiThreadInsertData(int threads, char* db_name, } */ tsem_init(&(t_info->lock_sem), 0, 0); - if (SYNC == g_Dbs.queryMode) { - pthread_create(pids + i, NULL, syncWrite, t_info); - } else { + if (ASYNC_MODE == g_Dbs.asyncMode) { pthread_create(pids + i, NULL, asyncWrite, t_info); + } else { + pthread_create(pids + i, NULL, syncWrite, t_info); } } @@ -6455,7 +6449,7 @@ static TAOS_SUB* subscribeImpl( TAOS *taos, char *sql, char* topic, char* resultFileName) { TAOS_SUB* tsub = NULL; - if (ASYNC_QUERY_MODE == g_queryInfo.specifiedQueryInfo.mode) { + if (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode) { tsub = taos_subscribe(taos, g_queryInfo.specifiedQueryInfo.subscribeRestart, topic, sql, subscribe_callback, (void*)resultFileName, @@ -6540,7 +6534,7 @@ static void *superSubscribe(void *sarg) { TAOS_RES* res = NULL; while(1) { for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { - if (ASYNC_QUERY_MODE == g_queryInfo.superQueryInfo.mode) { + if (ASYNC_MODE == g_queryInfo.superQueryInfo.asyncMode) { continue; } @@ -6629,7 +6623,7 @@ static void *specifiedSubscribe(void *sarg) { TAOS_RES* res = NULL; while(1) { for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { - if (ASYNC_QUERY_MODE == g_queryInfo.specifiedQueryInfo.mode) { + if (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode) { continue; } @@ -6852,7 +6846,7 @@ static void setParaFromArg(){ g_Dbs.db[0].superTbls[0].childTblCount = g_args.num_of_tables; g_Dbs.threadCount = g_args.num_of_threads; g_Dbs.threadCountByCreateTbl = g_args.num_of_threads; - g_Dbs.queryMode = g_args.query_mode; + g_Dbs.asyncMode = g_args.async_mode; g_Dbs.db[0].superTbls[0].autoCreateTable = PRE_CREATE_SUBTBL; g_Dbs.db[0].superTbls[0].childTblExists = TBL_NO_EXISTS; diff --git a/src/mnode/src/mnodeProfile.c b/src/mnode/src/mnodeProfile.c index 17a4282d05..459d981138 100644 --- a/src/mnode/src/mnodeProfile.c +++ b/src/mnode/src/mnodeProfile.c @@ -344,7 +344,7 @@ static int32_t mnodeGetQueryMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC pShow->bytes[cols] = 24; pSchema[cols].type = TSDB_DATA_TYPE_BINARY; - strcpy(pSchema[cols].name, "qhandle"); + strcpy(pSchema[cols].name, "qid"); pSchema[cols].bytes = htons(pShow->bytes[cols]); cols++; @@ -420,7 +420,7 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v cols++; char handleBuf[24] = {0}; - snprintf(handleBuf, tListLen(handleBuf), "%p", (void*)htobe64(pDesc->qHandle)); + snprintf(handleBuf, tListLen(handleBuf), "%"PRIu64, htobe64(pDesc->qId)); pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; STR_WITH_MAXSIZE_TO_VARSTR(pWrite, handleBuf, pShow->bytes[cols]); diff --git a/src/mnode/src/mnodeUser.c b/src/mnode/src/mnodeUser.c index 55ee39b6bc..e77c1b3e59 100644 --- a/src/mnode/src/mnodeUser.c +++ b/src/mnode/src/mnodeUser.c @@ -123,7 +123,7 @@ static void mnodePrintUserAuth() { mnodeDecUserRef(pUser); } - fsync(fileno(fp)); + taosFsync(fileno(fp)); fclose(fp); } diff --git a/src/os/CMakeLists.txt b/src/os/CMakeLists.txt index ab8b0f7678..4472c683c7 100644 --- a/src/os/CMakeLists.txt +++ b/src/os/CMakeLists.txt @@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(TDengine) IF (TD_LINUX) - ADD_SUBDIRECTORY(src/linux) + ADD_SUBDIRECTORY(src/linux) ELSEIF (TD_DARWIN) ADD_SUBDIRECTORY(src/darwin) ELSEIF (TD_WINDOWS) diff --git a/src/os/inc/os.h b/src/os/inc/os.h index c3e02b14db..6731ca6d7d 100644 --- a/src/os/inc/os.h +++ b/src/os/inc/os.h @@ -20,45 +20,9 @@ extern "C" { #endif -#ifdef _TD_DARWIN_64 -#include "osDarwin.h" -#endif - -#ifdef _TD_ARM_64 -#include "osArm64.h" -#endif - -#ifdef _TD_ARM_32 -#include "osArm32.h" -#endif - -#ifdef _TD_MIPS_64 -#include "osMips64.h" -#endif - -#ifdef _TD_LINUX_64 -#include "osLinux64.h" -#endif - -#ifdef _TD_LINUX_32 -#include "osLinux32.h" -#endif - -#ifdef _ALPINE -#include "osAlpine.h" -#endif - -#ifdef _TD_NINGSI_60 -#include "osNingsi.h" -#endif - -#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) -#include "osWindows.h" -#endif - +#include "osInc.h" #include "osDef.h" #include "osAtomic.h" -#include "osCommon.h" #include "osDir.h" #include "osFile.h" #include "osLz4.h" @@ -67,6 +31,7 @@ extern "C" { #include "osRand.h" #include "osSemphone.h" #include "osSignal.h" +#include "osSleep.h" #include "osSocket.h" #include "osString.h" #include "osSysinfo.h" diff --git a/src/os/inc/osAlpine.h b/src/os/inc/osAlpine.h deleted file mode 100644 index eba9459395..0000000000 --- a/src/os/inc/osAlpine.h +++ /dev/null @@ -1,92 +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_OS_ALPINE_H -#define TDENGINE_OS_ALPINE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef int(*__compar_fn_t)(const void *, const void *); -void error (int, int, const char *); -#ifndef PTHREAD_MUTEX_RECURSIVE_NP - #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/os/inc/osArm32.h b/src/os/inc/osArm32.h deleted file mode 100644 index 54835a1ca8..0000000000 --- a/src/os/inc/osArm32.h +++ /dev/null @@ -1,92 +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_OS_ARM32_H -#define TDENGINE_OS_ARM32_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TAOS_OS_FUNC_LZ4 - #define BUILDIN_CLZL(val) __builtin_clzll(val) - #define BUILDIN_CTZL(val) __builtin_ctzll(val) - #define BUILDIN_CLZ(val) __builtin_clz(val) - #define BUILDIN_CTZ(val) __builtin_ctz(val) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/os/inc/osArm64.h b/src/os/inc/osArm64.h deleted file mode 100644 index 76098f6846..0000000000 --- a/src/os/inc/osArm64.h +++ /dev/null @@ -1,87 +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_OS_ARM64_H -#define TDENGINE_OS_ARM64_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/os/inc/osAtomic.h b/src/os/inc/osAtomic.h index 803c351400..7affa444ee 100644 --- a/src/os/inc/osAtomic.h +++ b/src/os/inc/osAtomic.h @@ -20,7 +20,252 @@ extern "C" { #endif -#ifndef TAOS_OS_FUNC_ATOMIC +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + #define atomic_load_8(ptr) (*(char volatile*)(ptr)) + #define atomic_load_16(ptr) (*(short volatile*)(ptr)) + #define atomic_load_32(ptr) (*(long volatile*)(ptr)) + #define atomic_load_64(ptr) (*(__int64 volatile*)(ptr)) + #define atomic_load_ptr(ptr) (*(void* volatile*)(ptr)) + + #define atomic_store_8(ptr, val) ((*(char volatile*)(ptr)) = (char)(val)) + #define atomic_store_16(ptr, val) ((*(short volatile*)(ptr)) = (short)(val)) + #define atomic_store_32(ptr, val) ((*(long volatile*)(ptr)) = (long)(val)) + #define atomic_store_64(ptr, val) ((*(__int64 volatile*)(ptr)) = (__int64)(val)) + #define atomic_store_ptr(ptr, val) ((*(void* volatile*)(ptr)) = (void*)(val)) + + #define atomic_exchange_8(ptr, val) _InterlockedExchange8((char volatile*)(ptr), (char)(val)) + #define atomic_exchange_16(ptr, val) _InterlockedExchange16((short volatile*)(ptr), (short)(val)) + #define atomic_exchange_32(ptr, val) _InterlockedExchange((long volatile*)(ptr), (long)(val)) + #define atomic_exchange_64(ptr, val) _InterlockedExchange64((__int64 volatile*)(ptr), (__int64)(val)) + #ifdef _WIN64 + #define atomic_exchange_ptr(ptr, val) _InterlockedExchangePointer((void* volatile*)(ptr), (void*)(val)) + #else + #define atomic_exchange_ptr(ptr, val) _InlineInterlockedExchangePointer((void* volatile*)(ptr), (void*)(val)) + #endif + + #ifdef _TD_GO_DLL_ + #define atomic_val_compare_exchange_8 __sync_val_compare_and_swap + #else + #define atomic_val_compare_exchange_8(ptr, oldval, newval) _InterlockedCompareExchange8((char volatile*)(ptr), (char)(newval), (char)(oldval)) + #endif + #define atomic_val_compare_exchange_16(ptr, oldval, newval) _InterlockedCompareExchange16((short volatile*)(ptr), (short)(newval), (short)(oldval)) + #define atomic_val_compare_exchange_32(ptr, oldval, newval) _InterlockedCompareExchange((long volatile*)(ptr), (long)(newval), (long)(oldval)) + #define atomic_val_compare_exchange_64(ptr, oldval, newval) _InterlockedCompareExchange64((__int64 volatile*)(ptr), (__int64)(newval), (__int64)(oldval)) + #define atomic_val_compare_exchange_ptr(ptr, oldval, newval) _InterlockedCompareExchangePointer((void* volatile*)(ptr), (void*)(newval), (void*)(oldval)) + + char interlocked_add_fetch_8(char volatile *ptr, char val); + short interlocked_add_fetch_16(short volatile *ptr, short val); + long interlocked_add_fetch_32(long volatile *ptr, long val); + __int64 interlocked_add_fetch_64(__int64 volatile *ptr, __int64 val); + + char interlocked_and_fetch_8(char volatile* ptr, char val); + short interlocked_and_fetch_16(short volatile* ptr, short val); + long interlocked_and_fetch_32(long volatile* ptr, long val); + __int64 interlocked_and_fetch_64(__int64 volatile* ptr, __int64 val); + + __int64 interlocked_fetch_and_64(__int64 volatile* ptr, __int64 val); + + char interlocked_or_fetch_8(char volatile* ptr, char val); + short interlocked_or_fetch_16(short volatile* ptr, short val); + long interlocked_or_fetch_32(long volatile* ptr, long val); + __int64 interlocked_or_fetch_64(__int64 volatile* ptr, __int64 val); + + char interlocked_xor_fetch_8(char volatile* ptr, char val); + short interlocked_xor_fetch_16(short volatile* ptr, short val); + long interlocked_xor_fetch_32(long volatile* ptr, long val); + __int64 interlocked_xor_fetch_64(__int64 volatile* ptr, __int64 val); + + __int64 interlocked_fetch_xor_64(__int64 volatile* ptr, __int64 val); + + #define atomic_add_fetch_8(ptr, val) interlocked_add_fetch_8((char volatile*)(ptr), (char)(val)) + #define atomic_add_fetch_16(ptr, val) interlocked_add_fetch_16((short volatile*)(ptr), (short)(val)) + #define atomic_add_fetch_32(ptr, val) interlocked_add_fetch_32((long volatile*)(ptr), (long)(val)) + #define atomic_add_fetch_64(ptr, val) interlocked_add_fetch_64((__int64 volatile*)(ptr), (__int64)(val)) + #ifdef _TD_GO_DLL_ + #define atomic_fetch_add_8 __sync_fetch_and_ad + #define atomic_fetch_add_16 __sync_fetch_and_add + #else + #define atomic_fetch_add_8(ptr, val) _InterlockedExchangeAdd8((char volatile*)(ptr), (char)(val)) + #define atomic_fetch_add_16(ptr, val) _InterlockedExchangeAdd16((short volatile*)(ptr), (short)(val)) + #endif + #define atomic_fetch_add_8(ptr, val) _InterlockedExchangeAdd8((char volatile*)(ptr), (char)(val)) + #define atomic_fetch_add_16(ptr, val) _InterlockedExchangeAdd16((short volatile*)(ptr), (short)(val)) + #define atomic_fetch_add_32(ptr, val) _InterlockedExchangeAdd((long volatile*)(ptr), (long)(val)) + #define atomic_fetch_add_64(ptr, val) _InterlockedExchangeAdd64((__int64 volatile*)(ptr), (__int64)(val)) + + #define atomic_sub_fetch_8(ptr, val) interlocked_add_fetch_8((char volatile*)(ptr), -(char)(val)) + #define atomic_sub_fetch_16(ptr, val) interlocked_add_fetch_16((short volatile*)(ptr), -(short)(val)) + #define atomic_sub_fetch_32(ptr, val) interlocked_add_fetch_32((long volatile*)(ptr), -(long)(val)) + #define atomic_sub_fetch_64(ptr, val) interlocked_add_fetch_64((__int64 volatile*)(ptr), -(__int64)(val)) + + #define atomic_fetch_sub_8(ptr, val) _InterlockedExchangeAdd8((char volatile*)(ptr), -(char)(val)) + #define atomic_fetch_sub_16(ptr, val) _InterlockedExchangeAdd16((short volatile*)(ptr), -(short)(val)) + #define atomic_fetch_sub_32(ptr, val) _InterlockedExchangeAdd((long volatile*)(ptr), -(long)(val)) + #define atomic_fetch_sub_64(ptr, val) _InterlockedExchangeAdd64((__int64 volatile*)(ptr), -(__int64)(val)) + + #define atomic_and_fetch_8(ptr, val) interlocked_and_fetch_8((char volatile*)(ptr), (char)(val)) + #define atomic_and_fetch_16(ptr, val) interlocked_and_fetch_16((short volatile*)(ptr), (short)(val)) + #define atomic_and_fetch_32(ptr, val) interlocked_and_fetch_32((long volatile*)(ptr), (long)(val)) + #define atomic_and_fetch_64(ptr, val) interlocked_and_fetch_64((__int64 volatile*)(ptr), (__int64)(val)) + + #define atomic_fetch_and_8(ptr, val) _InterlockedAnd8((char volatile*)(ptr), (char)(val)) + #define atomic_fetch_and_16(ptr, val) _InterlockedAnd16((short volatile*)(ptr), (short)(val)) + #define atomic_fetch_and_32(ptr, val) _InterlockedAnd((long volatile*)(ptr), (long)(val)) + #define atomic_fetch_and_64(ptr, val) interlocked_fetch_and_64((__int64 volatile*)(ptr), (__int64)(val)) + + #define atomic_or_fetch_8(ptr, val) interlocked_or_fetch_8((char volatile*)(ptr), (char)(val)) + #define atomic_or_fetch_16(ptr, val) interlocked_or_fetch_16((short volatile*)(ptr), (short)(val)) + #define atomic_or_fetch_32(ptr, val) interlocked_or_fetch_32((long volatile*)(ptr), (long)(val)) + #define atomic_or_fetch_64(ptr, val) interlocked_or_fetch_64((__int64 volatile*)(ptr), (__int64)(val)) + + #define atomic_fetch_or_8(ptr, val) _InterlockedOr8((char volatile*)(ptr), (char)(val)) + #define atomic_fetch_or_16(ptr, val) _InterlockedOr16((short volatile*)(ptr), (short)(val)) + #define atomic_fetch_or_32(ptr, val) _InterlockedOr((long volatile*)(ptr), (long)(val)) + #define atomic_fetch_or_64(ptr, val) interlocked_fetch_or_64((__int64 volatile*)(ptr), (__int64)(val)) + + #define atomic_xor_fetch_8(ptr, val) interlocked_xor_fetch_8((char volatile*)(ptr), (char)(val)) + #define atomic_xor_fetch_16(ptr, val) interlocked_xor_fetch_16((short volatile*)(ptr), (short)(val)) + #define atomic_xor_fetch_32(ptr, val) interlocked_xor_fetch_32((long volatile*)(ptr), (long)(val)) + #define atomic_xor_fetch_64(ptr, val) interlocked_xor_fetch_64((__int64 volatile*)(ptr), (__int64)(val)) + + #define atomic_fetch_xor_8(ptr, val) _InterlockedXor8((char volatile*)(ptr), (char)(val)) + #define atomic_fetch_xor_16(ptr, val) _InterlockedXor16((short volatile*)(ptr), (short)(val)) + #define atomic_fetch_xor_32(ptr, val) _InterlockedXor((long volatile*)(ptr), (long)(val)) + #define atomic_fetch_xor_64(ptr, val) interlocked_fetch_xor_64((__int64 volatile*)(ptr), (__int64)(val)) + + #ifdef _WIN64 + #define atomic_add_fetch_ptr atomic_add_fetch_64 + #define atomic_fetch_add_ptr atomic_fetch_add_64 + #define atomic_sub_fetch_ptr atomic_sub_fetch_64 + #define atomic_fetch_sub_ptr atomic_fetch_sub_64 + #define atomic_and_fetch_ptr atomic_and_fetch_64 + #define atomic_fetch_and_ptr atomic_fetch_and_64 + #define atomic_or_fetch_ptr atomic_or_fetch_64 + #define atomic_fetch_or_ptr atomic_fetch_or_64 + #define atomic_xor_fetch_ptr atomic_xor_fetch_64 + #define atomic_fetch_xor_ptr atomic_fetch_xor_64 + #else + #define atomic_add_fetch_ptr atomic_add_fetch_32 + #define atomic_fetch_add_ptr atomic_fetch_add_32 + #define atomic_sub_fetch_ptr atomic_sub_fetch_32 + #define atomic_fetch_sub_ptr atomic_fetch_sub_32 + #define atomic_and_fetch_ptr atomic_and_fetch_32 + #define atomic_fetch_and_ptr atomic_fetch_and_32 + #define atomic_or_fetch_ptr atomic_or_fetch_32 + #define atomic_fetch_or_ptr atomic_fetch_or_32 + #define atomic_xor_fetch_ptr atomic_xor_fetch_32 + #define atomic_fetch_xor_ptr atomic_fetch_xor_32 + #endif +#elif defined(_TD_NINGSI_60) + /* + * type __sync_fetch_and_add (type *ptr, type value); + * type __sync_fetch_and_sub (type *ptr, type value); + * type __sync_fetch_and_or (type *ptr, type value); + * type __sync_fetch_and_and (type *ptr, type value); + * type __sync_fetch_and_xor (type *ptr, type value); + * type __sync_fetch_and_nand (type *ptr, type value); + * type __sync_add_and_fetch (type *ptr, type value); + * type __sync_sub_and_fetch (type *ptr, type value); + * type __sync_or_and_fetch (type *ptr, type value); + * type __sync_and_and_fetch (type *ptr, type value); + * type __sync_xor_and_fetch (type *ptr, type value); + * type __sync_nand_and_fetch (type *ptr, type value); + * + * bool __sync_bool_compare_and_swap (type*ptr, type oldval, type newval, ...) + * type __sync_val_compare_and_swap (type *ptr, type oldval, ?type newval, ...) + * */ + + #define atomic_load_8(ptr) __sync_fetch_and_add((ptr), 0) + #define atomic_load_16(ptr) __sync_fetch_and_add((ptr), 0) + #define atomic_load_32(ptr) __sync_fetch_and_add((ptr), 0) + #define atomic_load_64(ptr) __sync_fetch_and_add((ptr), 0) + #define atomic_load_ptr(ptr) __sync_fetch_and_add((ptr), 0) + + #define atomic_store_8(ptr, val) (*(ptr)=(val)) + #define atomic_store_16(ptr, val) (*(ptr)=(val)) + #define atomic_store_32(ptr, val) (*(ptr)=(val)) + #define atomic_store_64(ptr, val) (*(ptr)=(val)) + #define atomic_store_ptr(ptr, val) (*(ptr)=(val)) + + int8_t atomic_exchange_8_impl(int8_t* ptr, int8_t val ); + int16_t atomic_exchange_16_impl(int16_t* ptr, int16_t val ); + int32_t atomic_exchange_32_impl(int32_t* ptr, int32_t val ); + int64_t atomic_exchange_64_impl(int64_t* ptr, int64_t val ); + void* atomic_exchange_ptr_impl( void **ptr, void *val ); + + #define atomic_exchange_8(ptr, val) atomic_exchange_8_impl((int8_t*)ptr, (int8_t)val) + #define atomic_exchange_16(ptr, val) atomic_exchange_16_impl((int16_t*)ptr, (int16_t)val) + #define atomic_exchange_32(ptr, val) atomic_exchange_32_impl((int32_t*)ptr, (int32_t)val) + #define atomic_exchange_64(ptr, val) atomic_exchange_64_impl((int64_t*)ptr, (int64_t)val) + #define atomic_exchange_ptr(ptr, val) atomic_exchange_ptr_impl((void **)ptr, (void*)val) + + #define atomic_val_compare_exchange_8 __sync_val_compare_and_swap + #define atomic_val_compare_exchange_16 __sync_val_compare_and_swap + #define atomic_val_compare_exchange_32 __sync_val_compare_and_swap + #define atomic_val_compare_exchange_64 __sync_val_compare_and_swap + #define atomic_val_compare_exchange_ptr __sync_val_compare_and_swap + + #define atomic_add_fetch_8(ptr, val) __sync_add_and_fetch((ptr), (val)) + #define atomic_add_fetch_16(ptr, val) __sync_add_and_fetch((ptr), (val)) + #define atomic_add_fetch_32(ptr, val) __sync_add_and_fetch((ptr), (val)) + #define atomic_add_fetch_64(ptr, val) __sync_add_and_fetch((ptr), (val)) + #define atomic_add_fetch_ptr(ptr, val) __sync_add_and_fetch((ptr), (val)) + + #define atomic_fetch_add_8(ptr, val) __sync_fetch_and_add((ptr), (val)) + #define atomic_fetch_add_16(ptr, val) __sync_fetch_and_add((ptr), (val)) + #define atomic_fetch_add_32(ptr, val) __sync_fetch_and_add((ptr), (val)) + #define atomic_fetch_add_64(ptr, val) __sync_fetch_and_add((ptr), (val)) + #define atomic_fetch_add_ptr(ptr, val) __sync_fetch_and_add((ptr), (val)) + + #define atomic_sub_fetch_8(ptr, val) __sync_sub_and_fetch((ptr), (val)) + #define atomic_sub_fetch_16(ptr, val) __sync_sub_and_fetch((ptr), (val)) + #define atomic_sub_fetch_32(ptr, val) __sync_sub_and_fetch((ptr), (val)) + #define atomic_sub_fetch_64(ptr, val) __sync_sub_and_fetch((ptr), (val)) + #define atomic_sub_fetch_ptr(ptr, val) __sync_sub_and_fetch((ptr), (val)) + + #define atomic_fetch_sub_8(ptr, val) __sync_fetch_and_sub((ptr), (val)) + #define atomic_fetch_sub_16(ptr, val) __sync_fetch_and_sub((ptr), (val)) + #define atomic_fetch_sub_32(ptr, val) __sync_fetch_and_sub((ptr), (val)) + #define atomic_fetch_sub_64(ptr, val) __sync_fetch_and_sub((ptr), (val)) + #define atomic_fetch_sub_ptr(ptr, val) __sync_fetch_and_sub((ptr), (val)) + + #define atomic_and_fetch_8(ptr, val) __sync_and_and_fetch((ptr), (val)) + #define atomic_and_fetch_16(ptr, val) __sync_and_and_fetch((ptr), (val)) + #define atomic_and_fetch_32(ptr, val) __sync_and_and_fetch((ptr), (val)) + #define atomic_and_fetch_64(ptr, val) __sync_and_and_fetch((ptr), (val)) + #define atomic_and_fetch_ptr(ptr, val) __sync_and_and_fetch((ptr), (val)) + + #define atomic_fetch_and_8(ptr, val) __sync_fetch_and_and((ptr), (val)) + #define atomic_fetch_and_16(ptr, val) __sync_fetch_and_and((ptr), (val)) + #define atomic_fetch_and_32(ptr, val) __sync_fetch_and_and((ptr), (val)) + #define atomic_fetch_and_64(ptr, val) __sync_fetch_and_and((ptr), (val)) + #define atomic_fetch_and_ptr(ptr, val) __sync_fetch_and_and((ptr), (val)) + + #define atomic_or_fetch_8(ptr, val) __sync_or_and_fetch((ptr), (val)) + #define atomic_or_fetch_16(ptr, val) __sync_or_and_fetch((ptr), (val)) + #define atomic_or_fetch_32(ptr, val) __sync_or_and_fetch((ptr), (val)) + #define atomic_or_fetch_64(ptr, val) __sync_or_and_fetch((ptr), (val)) + #define atomic_or_fetch_ptr(ptr, val) __sync_or_and_fetch((ptr), (val)) + + #define atomic_fetch_or_8(ptr, val) __sync_fetch_and_or((ptr), (val)) + #define atomic_fetch_or_16(ptr, val) __sync_fetch_and_or((ptr), (val)) + #define atomic_fetch_or_32(ptr, val) __sync_fetch_and_or((ptr), (val)) + #define atomic_fetch_or_64(ptr, val) __sync_fetch_and_or((ptr), (val)) + #define atomic_fetch_or_ptr(ptr, val) __sync_fetch_and_or((ptr), (val)) + + #define atomic_xor_fetch_8(ptr, val) __sync_xor_and_fetch((ptr), (val)) + #define atomic_xor_fetch_16(ptr, val) __sync_xor_and_fetch((ptr), (val)) + #define atomic_xor_fetch_32(ptr, val) __sync_xor_and_fetch((ptr), (val)) + #define atomic_xor_fetch_64(ptr, val) __sync_xor_and_fetch((ptr), (val)) + #define atomic_xor_fetch_ptr(ptr, val) __sync_xor_and_fetch((ptr), (val)) + + #define atomic_fetch_xor_8(ptr, val) __sync_fetch_and_xor((ptr), (val)) + #define atomic_fetch_xor_16(ptr, val) __sync_fetch_and_xor((ptr), (val)) + #define atomic_fetch_xor_32(ptr, val) __sync_fetch_and_xor((ptr), (val)) + #define atomic_fetch_xor_64(ptr, val) __sync_fetch_and_xor((ptr), (val)) + #define atomic_fetch_xor_ptr(ptr, val) __sync_fetch_and_xor((ptr), (val)) + +#else #define atomic_load_8(ptr) __atomic_load_n((ptr), __ATOMIC_SEQ_CST) #define atomic_load_16(ptr) __atomic_load_n((ptr), __ATOMIC_SEQ_CST) #define atomic_load_32(ptr) __atomic_load_n((ptr), __ATOMIC_SEQ_CST) diff --git a/src/os/inc/osDarwin.h b/src/os/inc/osDarwin.h deleted file mode 100644 index 7c206afe7a..0000000000 --- a/src/os/inc/osDarwin.h +++ /dev/null @@ -1,127 +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_OS_DARWIN_H -#define TDENGINE_OS_DARWIN_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TAOS_OS_FUNC_FILE_SENDIFLE - -#define TAOS_OS_FUNC_SEMPHONE - typedef struct tsem_s *tsem_t; - int tsem_init(tsem_t *sem, int pshared, unsigned int value); - int tsem_wait(tsem_t *sem); - int tsem_post(tsem_t *sem); - int tsem_destroy(tsem_t *sem); - -#define TAOS_OS_FUNC_SOCKET_SETSOCKETOPT -#define TAOS_OS_FUNC_STRING_STR2INT64 -#define TAOS_OS_FUNC_SYSINFO -#define TAOS_OS_FUNC_TIMER -#define TAOS_OS_FUNC_SEMPHONE_PTHREAD - -// specific -#define htobe64 htonll -typedef int(*__compar_fn_t)(const void *, const void *); - -// for send function in tsocket.c -#if defined(MSG_NOSIGNAL) -#undef MSG_NOSIGNAL -#endif - -#define MSG_NOSIGNAL 0 - -#define SO_NO_CHECK 0x1234 -#define SOL_TCP 0x1234 -#define TCP_KEEPIDLE 0x1234 - -#ifndef PTHREAD_MUTEX_RECURSIVE_NP - #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE -#endif - -#define TAOS_OS_FUNC_PTHREAD_RWLOCK - -int64_t tsosStr2int64(char *str); - -#include "eok.h" - -void taos_block_sigalrm(void); - -#define TAOS_OS_DEF_EPOLL - #define TAOS_EPOLL_WAIT_TIME 500 - typedef int32_t SOCKET; - typedef SOCKET EpollFd; - #define EpollClose(pollFd) epoll_close(pollFd) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/os/inc/osDef.h b/src/os/inc/osDef.h index bbe0f98ec0..80617eec56 100644 --- a/src/os/inc/osDef.h +++ b/src/os/inc/osDef.h @@ -20,17 +20,109 @@ extern "C" { #endif +#if defined(_TD_DARWIN_64) + // specific + typedef int(*__compar_fn_t)(const void *, const void *); + + // for send function in tsocket.c + #if defined(MSG_NOSIGNAL) + #undef MSG_NOSIGNAL + #endif + + #define MSG_NOSIGNAL 0 + + #define SO_NO_CHECK 0x1234 + #define SOL_TCP 0x1234 + #define TCP_KEEPIDLE 0x1234 + + #ifndef PTHREAD_MUTEX_RECURSIVE_NP + #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE + #endif +#endif + +#if defined(_ALPINE) + typedef int(*__compar_fn_t)(const void *, const void *); + void error (int, int, const char *); + #ifndef PTHREAD_MUTEX_RECURSIVE_NP + #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE + #endif +#endif + +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + char *stpcpy (char *dest, const char *src); + char *stpncpy (char *dest, const char *src, size_t n); + + // specific + typedef int (*__compar_fn_t)(const void *, const void *); + #define ssize_t int + #define bzero(ptr, size) memset((ptr), 0, (size)) + #define strcasecmp _stricmp + #define strncasecmp _strnicmp + #define wcsncasecmp _wcsnicmp + #define strtok_r strtok_s + #define snprintf _snprintf + #define in_addr_t unsigned long + #define socklen_t int + + struct tm *localtime_r(const time_t *timep, struct tm *result); + char * strptime(const char *buf, const char *fmt, struct tm *tm); + char * strsep(char **stringp, const char *delim); + char * getpass(const char *prefix); + int flock(int fd, int option); + char * strndup(const char *s, size_t n); + int gettimeofday(struct timeval *ptv, void *pTimeZone); + + // for send function in tsocket.c + #define MSG_NOSIGNAL 0 + #define SO_NO_CHECK 0x1234 + #define SOL_TCP 0x1234 + + #ifndef TCP_KEEPCNT + #define TCP_KEEPCNT 0x1234 + #endif + + #ifndef TCP_KEEPIDLE + #define TCP_KEEPIDLE 0x1234 + #endif + + #ifndef TCP_KEEPINTVL + #define TCP_KEEPINTVL 0x1234 + #endif + + #define SHUT_RDWR SD_BOTH + #define SHUT_RD SD_RECEIVE + #define SHUT_WR SD_SEND + + #define LOCK_EX 1 + #define LOCK_NB 2 + #define LOCK_UN 3 + + #ifndef PATH_MAX + #define PATH_MAX 256 + #endif + + typedef struct { + int we_wordc; + char *we_wordv[1]; + int we_offs; + char wordPos[1025]; + } wordexp_t; + int wordexp(char *words, wordexp_t *pwordexp, int flags); + void wordfree(wordexp_t *pwordexp); + + #define openlog(a, b, c) + #define closelog() + #define LOG_ERR 0 + #define LOG_INFO 1 + void syslog(int unused, const char *format, ...); +#endif + #ifndef WINDOWS #ifndef O_BINARY #define O_BINARY 0 #endif #endif -#define FD_VALID(x) ((x) > STDERR_FILENO) -#define FD_INITIALIZER ((int32_t)-1) - -// #define WCHAR wchar_t - #define POINTER_SHIFT(p, b) ((void *)((char *)(p) + (b))) #define POINTER_DISTANCE(p1, p2) ((char *)(p1) - (char *)(p2)) @@ -113,6 +205,12 @@ extern "C" { #define threadlocal __declspec( thread ) #endif +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + #define PRIzu "ld" +#else + #define PRIzu "zu" +#endif + #ifdef __cplusplus } #endif diff --git a/src/os/inc/osDir.h b/src/os/inc/osDir.h index 540efc310c..bdc65e4520 100644 --- a/src/os/inc/osDir.h +++ b/src/os/inc/osDir.h @@ -20,13 +20,10 @@ extern "C" { #endif -#include - -// TAOS_OS_FUNC_DIR -void taosRemoveDir(char *rootDir); -int taosMkDir(const char *pathname, mode_t mode); -void taosRemoveOldLogFiles(char *rootDir, int32_t keepDays); -int32_t taosRename(char* oldName, char *newName); +void taosRemoveDir(char *rootDir); +int32_t taosMkDir(const char *pathname, mode_t mode); +void taosRemoveOldLogFiles(char *rootDir, int32_t keepDays); +int32_t taosRename(char *oldName, char *newName); int32_t taosCompressFile(char *srcFileName, char *destFileName); #ifdef __cplusplus diff --git a/src/os/inc/eok.h b/src/os/inc/osEok.h similarity index 95% rename from src/os/inc/eok.h rename to src/os/inc/osEok.h index 0874ca975b..3ca476f840 100644 --- a/src/os/inc/eok.h +++ b/src/os/inc/osEok.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef _eok_h_fd274616_996c_400e_9023_ae70be881fa3_ -#define _eok_h_fd274616_996c_400e_9023_ae70be881fa3_ +#ifndef TDENGINE_OS_EOK_H +#define TDENGINE_OS_EOK_H #include diff --git a/src/os/inc/osFile.h b/src/os/inc/osFile.h index c117ae4039..262f19ad22 100644 --- a/src/os/inc/osFile.h +++ b/src/os/inc/osFile.h @@ -22,50 +22,39 @@ extern "C" { #include "osSocket.h" -int64_t taosReadImp(int32_t fd, void *buf, int64_t count); -int64_t taosWriteImp(int32_t fd, void *buf, int64_t count); -int64_t taosLSeekImp(int32_t fd, int64_t offset, int32_t whence); -int32_t taosRenameFile(char *fullPath, char *suffix, char delimiter, char **dstPath); +#define FD_VALID(x) ((x) > STDERR_FILENO) +#define FD_INITIALIZER ((int32_t)-1) + +#ifndef PATH_MAX + #define PATH_MAX 256 +#endif + +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) +typedef int32_t FileFd; +typedef SOCKET SocketFd; +#else +typedef int32_t FileFd; +typedef int32_t SocketFd; +#endif + +int64_t taosRead(FileFd fd, void *buf, int64_t count); +int64_t taosWrite(FileFd fd, void *buf, int64_t count); + +int64_t taosLSeek(FileFd fd, int64_t offset, int32_t whence); +int32_t taosFtruncate(FileFd fd, int64_t length); +int32_t taosFsync(FileFd fd); + +int32_t taosRename(char* oldName, char *newName); int64_t taosCopy(char *from, char *to); -#define taosRead(fd, buf, count) taosReadImp(fd, buf, count) -#define taosWrite(fd, buf, count) taosWriteImp(fd, buf, count) -#define taosLSeek(fd, offset, whence) taosLSeekImp(fd, offset, whence) -#define taosClose(fd) \ - { \ - if (FD_VALID(fd)) { \ - close(fd); \ - fd = FD_INITIALIZER; \ - } \ - } - -// TAOS_OS_FUNC_FILE_SENDIFLE -int64_t taosSendFile(SOCKET dfd, int32_t sfd, int64_t *offset, int64_t size); +int64_t taosSendFile(SocketFd dfd, FileFd sfd, int64_t *offset, int64_t size); int64_t taosFSendFile(FILE *outfile, FILE *infile, int64_t *offset, int64_t size); -#ifdef TAOS_RANDOM_FILE_FAIL - void taosSetRandomFileFailFactor(int32_t factor); - void taosSetRandomFileFailOutput(const char *path); - #ifdef TAOS_RANDOM_FILE_FAIL_TEST - int64_t taosReadFileRandomFail(int32_t fd, void *buf, int32_t count, const char *file, uint32_t line); - int64_t taosWriteFileRandomFail(int32_t fd, void *buf, int32_t count, const char *file, uint32_t line); - int64_t taosLSeekRandomFail(int32_t fd, int64_t offset, int32_t whence, const char *file, uint32_t line); - #undef taosRead - #undef taosWrite - #undef taosLSeek - #define taosRead(fd, buf, count) taosReadFileRandomFail(fd, buf, count, __FILE__, __LINE__) - #define taosWrite(fd, buf, count) taosWriteFileRandomFail(fd, buf, count, __FILE__, __LINE__) - #define taosLSeek(fd, offset, whence) taosLSeekRandomFail(fd, offset, whence, __FILE__, __LINE__) - #endif -#endif - -// TAOS_OS_FUNC_FILE_GETTMPFILEPATH void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath); +void taosClose(FileFd fd); -// TAOS_OS_FUNC_FILE_FTRUNCATE -int32_t taosFtruncate(int32_t fd, int64_t length); #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/src/os/inc/osInc.h b/src/os/inc/osInc.h new file mode 100644 index 0000000000..6a3c754dcc --- /dev/null +++ b/src/os/inc/osInc.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef TDENGINE_OS_INC_H +#define TDENGINE_OS_INC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_TD_LINUX_64) || defined(_TD_LINUX_32) || defined(_TD_MIPS_64) || defined(_TD_ARM_32) || defined(_TD_ARM_64) || defined(_TD_DARWIN_64) + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #if defined(_TD_DARWIN_64) + #include + #include "osEok.h" + #else + #include + #include + #include + #include + #include + #include + #include + #include + + #if !(defined(_ALPINE)) + #include + #endif + #endif +#endif + +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + #include + #include + #include "winsock2.h" + #include + #include + #include + #include + #include + #include "msvcProcess.h" + #include "msvcDirect.h" + #include "msvcFcntl.h" + #include "msvcLibgen.h" + #include "msvcStdio.h" + #include "msvcUnistd.h" + #include "msvcLibgen.h" + #include "sys/msvcStat.h" + #include "sys/msvcTypes.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/os/inc/osLinux32.h b/src/os/inc/osLinux32.h deleted file mode 100644 index eee4999399..0000000000 --- a/src/os/inc/osLinux32.h +++ /dev/null @@ -1,92 +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_OS_LINUX32_H -#define TDENGINE_OS_LINUX32_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TAOS_OS_FUNC_LZ4 -#define BUILDIN_CLZL(val) __builtin_clzll(val) -#define BUILDIN_CTZL(val) __builtin_ctzll(val) -#define BUILDIN_CLZ(val) __builtin_clz(val) -#define BUILDIN_CTZ(val) __builtin_ctz(val) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/os/inc/osLinux64.h b/src/os/inc/osLinux64.h deleted file mode 100644 index 0dfc819da3..0000000000 --- a/src/os/inc/osLinux64.h +++ /dev/null @@ -1,89 +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_OS_LINUX64_H -#define TDENGINE_OS_LINUX64_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _ALPINE -#include -#endif -#include -#include - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/os/inc/osLz4.h b/src/os/inc/osLz4.h index a944892c48..8363861e03 100644 --- a/src/os/inc/osLz4.h +++ b/src/os/inc/osLz4.h @@ -20,7 +20,22 @@ extern "C" { #endif -#ifndef TAOS_OS_FUNC_LZ4 +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + int32_t BUILDIN_CLZL(uint64_t val); + int32_t BUILDIN_CLZ(uint32_t val); + int32_t BUILDIN_CTZL(uint64_t val); + int32_t BUILDIN_CTZ(uint32_t val); +#elif defined (_TD_LINUX_32) + #define BUILDIN_CLZL(val) __builtin_clzll(val) + #define BUILDIN_CTZL(val) __builtin_ctzll(val) + #define BUILDIN_CLZ(val) __builtin_clz(val) + #define BUILDIN_CTZ(val) __builtin_ctz(val) +#elif defined (_TD_ARM_32) + #define BUILDIN_CLZL(val) __builtin_clzll(val) + #define BUILDIN_CTZL(val) __builtin_ctzll(val) + #define BUILDIN_CLZ(val) __builtin_clz(val) + #define BUILDIN_CTZ(val) __builtin_ctz(val) +#else #define BUILDIN_CLZL(val) __builtin_clzl(val) #define BUILDIN_CTZL(val) __builtin_ctzl(val) #define BUILDIN_CLZ(val) __builtin_clz(val) diff --git a/src/os/inc/osMath.h b/src/os/inc/osMath.h index 9935f94d39..65e8a1f6fe 100644 --- a/src/os/inc/osMath.h +++ b/src/os/inc/osMath.h @@ -23,26 +23,38 @@ extern "C" { #define POW2(x) ((x) * (x)) #define ABS(x) ((x) > 0 ? (x) : -(x)) -#ifndef TAOS_OS_FUNC_MATH - #define SWAP(a, b, c) \ - do { \ - typeof(a) __tmp = (a); \ - (a) = (b); \ - (b) = __tmp; \ +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + + #define SWAP(a, b, c) \ + do { \ + c __tmp = (c)(a); \ + (a) = (c)(b); \ + (b) = __tmp; \ + } while (0) + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#else + + #define SWAP(a, b, c) \ + do { \ + typeof(a) __tmp = (a); \ + (a) = (b); \ + (b) = __tmp; \ } while (0) - #define MAX(a, b) \ - ({ \ - typeof(a) __a = (a); \ - typeof(b) __b = (b); \ - (__a > __b) ? __a : __b; \ + #define MAX(a, b) \ + ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + (__a > __b) ? __a : __b; \ }) - #define MIN(a, b) \ - ({ \ - typeof(a) __a = (a); \ - typeof(b) __b = (b); \ - (__a < __b) ? __a : __b; \ + #define MIN(a, b) \ + ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + (__a < __b) ? __a : __b; \ }) #endif diff --git a/src/os/inc/osMemory.h b/src/os/inc/osMemory.h index 2cf7e14d2f..27efd9f505 100644 --- a/src/os/inc/osMemory.h +++ b/src/os/inc/osMemory.h @@ -43,9 +43,6 @@ void taosTMemset(void *ptr, int c); #define tmalloc(size) malloc(size) #define tcalloc(num, size) calloc(num, size) #define trealloc(ptr, size) realloc(ptr, size) -#define tstrdup(str) taosStrdupImp(str) -#define tstrndup(str, size) taosStrndupImp(str, size) -#define tgetline(lineptr, n, stream) taosGetlineImp(lineptr, n, stream) #define tfree(x) \ do { \ if (x) { \ @@ -71,15 +68,8 @@ void taosTMemset(void *ptr, int c); #define tcalloc(num, size) taosCallocMem(num, size, __FILE__, __LINE__) #define trealloc(ptr, size) taosReallocMem(ptr, size, __FILE__, __LINE__) #define tfree(ptr) taosFreeMem(ptr, __FILE__, __LINE__) - - // #undef tstrdup - // #undef tstrndup - // #undef tgetline - // #define taosStrdup(str) taos_strdup(str, __FILE__, __LINE__) - // #define taosStrndup(str, size) taos_strndup(str, size, __FILE__, __LINE__) - // #define tgetline(lineptr, n, stream) taos_getline(lineptr, n, stream, __FILE__, __LINE__) #endif -#endif +#endif #ifdef __cplusplus } diff --git a/src/os/inc/osMips64.h b/src/os/inc/osMips64.h deleted file mode 100644 index ed7b08a311..0000000000 --- a/src/os/inc/osMips64.h +++ /dev/null @@ -1,87 +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_OS_MIPS64_H -#define TDENGINE_OS_MIPS64_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/os/inc/osNingsi.h b/src/os/inc/osNingsi.h deleted file mode 100644 index d88d279745..0000000000 --- a/src/os/inc/osNingsi.h +++ /dev/null @@ -1,136 +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_OS_NINGSI_H -#define TDENGINE_OS_NINGSI_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define TAOS_OS_FUNC_ATOMIC -/* - * type __sync_fetch_and_add (type *ptr, type value); - * type __sync_fetch_and_sub (type *ptr, type value); - * type __sync_fetch_and_or (type *ptr, type value); - * type __sync_fetch_and_and (type *ptr, type value); - * type __sync_fetch_and_xor (type *ptr, type value); - * type __sync_fetch_and_nand (type *ptr, type value); - * type __sync_add_and_fetch (type *ptr, type value); - * type __sync_sub_and_fetch (type *ptr, type value); - * type __sync_or_and_fetch (type *ptr, type value); - * type __sync_and_and_fetch (type *ptr, type value); - * type __sync_xor_and_fetch (type *ptr, type value); - * type __sync_nand_and_fetch (type *ptr, type value); - * - * bool __sync_bool_compare_and_swap (type*ptr, type oldval, type newval, ...) - * type __sync_val_compare_and_swap (type *ptr, type oldval, ?type newval, ...) - * */ - -#define atomic_load_8(ptr) __sync_fetch_and_add((ptr), 0) -#define atomic_load_16(ptr) __sync_fetch_and_add((ptr), 0) -#define atomic_load_32(ptr) __sync_fetch_and_add((ptr), 0) -#define atomic_load_64(ptr) __sync_fetch_and_add((ptr), 0) -#define atomic_load_ptr(ptr) __sync_fetch_and_add((ptr), 0) - -#define atomic_store_8(ptr, val) (*(ptr)=(val)) -#define atomic_store_16(ptr, val) (*(ptr)=(val)) -#define atomic_store_32(ptr, val) (*(ptr)=(val)) -#define atomic_store_64(ptr, val) (*(ptr)=(val)) -#define atomic_store_ptr(ptr, val) (*(ptr)=(val)) - -int8_t atomic_exchange_8_impl(int8_t* ptr, int8_t val ); -int16_t atomic_exchange_16_impl(int16_t* ptr, int16_t val ); -int32_t atomic_exchange_32_impl(int32_t* ptr, int32_t val ); -int64_t atomic_exchange_64_impl(int64_t* ptr, int64_t val ); -void* atomic_exchange_ptr_impl( void **ptr, void *val ); - -#define atomic_exchange_8(ptr, val) atomic_exchange_8_impl((int8_t*)ptr, (int8_t)val) -#define atomic_exchange_16(ptr, val) atomic_exchange_16_impl((int16_t*)ptr, (int16_t)val) -#define atomic_exchange_32(ptr, val) atomic_exchange_32_impl((int32_t*)ptr, (int32_t)val) -#define atomic_exchange_64(ptr, val) atomic_exchange_64_impl((int64_t*)ptr, (int64_t)val) -#define atomic_exchange_ptr(ptr, val) atomic_exchange_ptr_impl((void **)ptr, (void*)val) - -#define atomic_val_compare_exchange_8 __sync_val_compare_and_swap -#define atomic_val_compare_exchange_16 __sync_val_compare_and_swap -#define atomic_val_compare_exchange_32 __sync_val_compare_and_swap -#define atomic_val_compare_exchange_64 __sync_val_compare_and_swap -#define atomic_val_compare_exchange_ptr __sync_val_compare_and_swap - -#define atomic_add_fetch_8(ptr, val) __sync_add_and_fetch((ptr), (val)) -#define atomic_add_fetch_16(ptr, val) __sync_add_and_fetch((ptr), (val)) -#define atomic_add_fetch_32(ptr, val) __sync_add_and_fetch((ptr), (val)) -#define atomic_add_fetch_64(ptr, val) __sync_add_and_fetch((ptr), (val)) -#define atomic_add_fetch_ptr(ptr, val) __sync_add_and_fetch((ptr), (val)) - -#define atomic_fetch_add_8(ptr, val) __sync_fetch_and_add((ptr), (val)) -#define atomic_fetch_add_16(ptr, val) __sync_fetch_and_add((ptr), (val)) -#define atomic_fetch_add_32(ptr, val) __sync_fetch_and_add((ptr), (val)) -#define atomic_fetch_add_64(ptr, val) __sync_fetch_and_add((ptr), (val)) -#define atomic_fetch_add_ptr(ptr, val) __sync_fetch_and_add((ptr), (val)) - -#define atomic_sub_fetch_8(ptr, val) __sync_sub_and_fetch((ptr), (val)) -#define atomic_sub_fetch_16(ptr, val) __sync_sub_and_fetch((ptr), (val)) -#define atomic_sub_fetch_32(ptr, val) __sync_sub_and_fetch((ptr), (val)) -#define atomic_sub_fetch_64(ptr, val) __sync_sub_and_fetch((ptr), (val)) -#define atomic_sub_fetch_ptr(ptr, val) __sync_sub_and_fetch((ptr), (val)) - -#define atomic_fetch_sub_8(ptr, val) __sync_fetch_and_sub((ptr), (val)) -#define atomic_fetch_sub_16(ptr, val) __sync_fetch_and_sub((ptr), (val)) -#define atomic_fetch_sub_32(ptr, val) __sync_fetch_and_sub((ptr), (val)) -#define atomic_fetch_sub_64(ptr, val) __sync_fetch_and_sub((ptr), (val)) -#define atomic_fetch_sub_ptr(ptr, val) __sync_fetch_and_sub((ptr), (val)) - -#define atomic_and_fetch_8(ptr, val) __sync_and_and_fetch((ptr), (val)) -#define atomic_and_fetch_16(ptr, val) __sync_and_and_fetch((ptr), (val)) -#define atomic_and_fetch_32(ptr, val) __sync_and_and_fetch((ptr), (val)) -#define atomic_and_fetch_64(ptr, val) __sync_and_and_fetch((ptr), (val)) -#define atomic_and_fetch_ptr(ptr, val) __sync_and_and_fetch((ptr), (val)) - -#define atomic_fetch_and_8(ptr, val) __sync_fetch_and_and((ptr), (val)) -#define atomic_fetch_and_16(ptr, val) __sync_fetch_and_and((ptr), (val)) -#define atomic_fetch_and_32(ptr, val) __sync_fetch_and_and((ptr), (val)) -#define atomic_fetch_and_64(ptr, val) __sync_fetch_and_and((ptr), (val)) -#define atomic_fetch_and_ptr(ptr, val) __sync_fetch_and_and((ptr), (val)) - -#define atomic_or_fetch_8(ptr, val) __sync_or_and_fetch((ptr), (val)) -#define atomic_or_fetch_16(ptr, val) __sync_or_and_fetch((ptr), (val)) -#define atomic_or_fetch_32(ptr, val) __sync_or_and_fetch((ptr), (val)) -#define atomic_or_fetch_64(ptr, val) __sync_or_and_fetch((ptr), (val)) -#define atomic_or_fetch_ptr(ptr, val) __sync_or_and_fetch((ptr), (val)) - -#define atomic_fetch_or_8(ptr, val) __sync_fetch_and_or((ptr), (val)) -#define atomic_fetch_or_16(ptr, val) __sync_fetch_and_or((ptr), (val)) -#define atomic_fetch_or_32(ptr, val) __sync_fetch_and_or((ptr), (val)) -#define atomic_fetch_or_64(ptr, val) __sync_fetch_and_or((ptr), (val)) -#define atomic_fetch_or_ptr(ptr, val) __sync_fetch_and_or((ptr), (val)) - -#define atomic_xor_fetch_8(ptr, val) __sync_xor_and_fetch((ptr), (val)) -#define atomic_xor_fetch_16(ptr, val) __sync_xor_and_fetch((ptr), (val)) -#define atomic_xor_fetch_32(ptr, val) __sync_xor_and_fetch((ptr), (val)) -#define atomic_xor_fetch_64(ptr, val) __sync_xor_and_fetch((ptr), (val)) -#define atomic_xor_fetch_ptr(ptr, val) __sync_xor_and_fetch((ptr), (val)) - -#define atomic_fetch_xor_8(ptr, val) __sync_fetch_and_xor((ptr), (val)) -#define atomic_fetch_xor_16(ptr, val) __sync_fetch_and_xor((ptr), (val)) -#define atomic_fetch_xor_32(ptr, val) __sync_fetch_and_xor((ptr), (val)) -#define atomic_fetch_xor_64(ptr, val) __sync_fetch_and_xor((ptr), (val)) -#define atomic_fetch_xor_ptr(ptr, val) __sync_fetch_and_xor((ptr), (val)) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/os/inc/osRand.h b/src/os/inc/osRand.h index 803c0688bb..e08768c2cc 100644 --- a/src/os/inc/osRand.h +++ b/src/os/inc/osRand.h @@ -20,9 +20,8 @@ extern "C" { #endif -// TAOS_OS_FUNC_RAND uint32_t taosRand(void); -void taosRandStr(char* str, int32_t size); +void taosRandStr(char* str, int32_t size); uint32_t taosSafeRand(void); #ifdef __cplusplus diff --git a/src/os/inc/osSemphone.h b/src/os/inc/osSemphone.h index 3332a9234b..fe59095205 100644 --- a/src/os/inc/osSemphone.h +++ b/src/os/inc/osSemphone.h @@ -20,7 +20,13 @@ extern "C" { #endif -#ifndef TAOS_OS_FUNC_SEMPHONE +#if defined (_TD_DARWIN_64) + typedef struct tsem_s *tsem_t; + int tsem_init(tsem_t *sem, int pshared, unsigned int value); + int tsem_wait(tsem_t *sem); + int tsem_post(tsem_t *sem); + int tsem_destroy(tsem_t *sem); +#else #define tsem_t sem_t #define tsem_init sem_init int tsem_wait(tsem_t* sem); @@ -28,7 +34,7 @@ extern "C" { #define tsem_destroy sem_destroy #endif -#ifdef TAOS_OS_FUNC_PTHREAD_RWLOCK +#if defined (_TD_DARWIN_64) #define pthread_rwlock_t pthread_mutex_t #define pthread_rwlock_init(lock, NULL) pthread_mutex_init(lock, NULL) #define pthread_rwlock_destroy(lock) pthread_mutex_destroy(lock) @@ -43,7 +49,6 @@ extern "C" { #define pthread_spin_unlock(lock) pthread_mutex_unlock(lock) #endif -// TAOS_OS_FUNC_SEMPHONE_PTHREAD bool taosCheckPthreadValid(pthread_t thread); int64_t taosGetSelfPthreadId(); int64_t taosGetPthreadId(pthread_t thread); diff --git a/src/os/inc/osSignal.h b/src/os/inc/osSignal.h index c13cd83178..eca1d3b3f6 100644 --- a/src/os/inc/osSignal.h +++ b/src/os/inc/osSignal.h @@ -20,8 +20,6 @@ extern "C" { #endif -#include "os.h" -#include "taosdef.h" #include #ifndef SIGALRM @@ -57,4 +55,4 @@ void taosDflSignal(int32_t signum); } #endif -#endif // TDENGINE_TTIME_H +#endif // TDENGINE_OS_SIGNAL_H diff --git a/src/os/inc/osCommon.h b/src/os/inc/osSleep.h similarity index 85% rename from src/os/inc/osCommon.h rename to src/os/inc/osSleep.h index 70d2b2c0c2..e42da8d5a6 100644 --- a/src/os/inc/osCommon.h +++ b/src/os/inc/osSleep.h @@ -13,19 +13,17 @@ * along with this program. If not, see . */ -#ifndef TDENGINE_OS_COMMON_H -#define TDENGINE_OS_COMMON_H +#ifndef TDENGINE_OS_SLEEP_H +#define TDENGINE_OS_SLEEP_H #ifdef __cplusplus extern "C" { #endif -#ifndef TAOS_OS_DEF_ZU - #define PRIzu "zu" -#endif +void taosMsleep(int32_t ms); #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/src/os/inc/osSocket.h b/src/os/inc/osSocket.h index cf75b74a9a..a172c0bf34 100644 --- a/src/os/inc/osSocket.h +++ b/src/os/inc/osSocket.h @@ -20,7 +20,14 @@ extern "C" { #endif -#ifndef TAOS_OS_FUNC_SOCKET_OP +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + #define taosSend(sockfd, buf, len, flags) send((SOCKET)sockfd, buf, len, flags) + #define taosSendto(sockfd, buf, len, flags, dest_addr, addrlen) sendto((SOCKET)sockfd, buf, len, flags, dest_addr, addrlen) + #define taosWriteSocket(fd, buf, len) send((SOCKET)fd, buf, len, 0) + #define taosReadSocket(fd, buf, len) recv((SOCKET)fd, buf, len, 0) + #define taosCloseSocketNoCheck(fd) closesocket((SOCKET)fd) + #define taosCloseSocket(fd) closesocket((SOCKET)fd) +#else #define taosSend(sockfd, buf, len, flags) send(sockfd, buf, len, flags) #define taosSendto(sockfd, buf, len, flags, dest_addr, addrlen) sendto(sockfd, buf, len, flags, dest_addr, addrlen) #define taosReadSocket(fd, buf, len) read(fd, buf, len) @@ -35,7 +42,21 @@ extern "C" { } #endif -#ifndef TAOS_OS_DEF_EPOLL +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + #define TAOS_EPOLL_WAIT_TIME 100 + typedef SOCKET eventfd_t; + #define eventfd(a, b) -1 + typedef SOCKET EpollFd; + #define EpollClose(pollFd) epoll_close(pollFd) + #ifndef EPOLLWAKEUP + #define EPOLLWAKEUP (1u << 29) + #endif +#elif defined(_TD_DARWIN_64) + #define TAOS_EPOLL_WAIT_TIME 500 + typedef int32_t SOCKET; + typedef SOCKET EpollFd; + #define EpollClose(pollFd) epoll_close(pollFd) +#else #define TAOS_EPOLL_WAIT_TIME 500 typedef int32_t SOCKET; typedef SOCKET EpollFd; @@ -59,21 +80,27 @@ extern "C" { #endif #endif -// TAOS_OS_FUNC_SOCKET int32_t taosSetNonblocking(SOCKET sock, int32_t on); void taosIgnSIGPIPE(); void taosBlockSIGPIPE(); void taosSetMaskSIGPIPE(); - -// TAOS_OS_FUNC_SOCKET_SETSOCKETOPT int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t optlen); - int32_t taosGetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t* optlen); -// TAOS_OS_FUNC_SOCKET_INET uint32_t taosInetAddr(char *ipAddr); const char *taosInetNtoa(struct in_addr ipInt); +#if (defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)) + #define htobe64 htonll + #if defined(_TD_GO_DLL_) + uint64_t htonll(uint64_t val); + #endif +#endif + +#if defined(_TD_DARWIN_64) + #define htobe64 htonll +#endif + #ifdef __cplusplus } #endif diff --git a/src/os/inc/osString.h b/src/os/inc/osString.h index 97966ed412..33f858485c 100644 --- a/src/os/inc/osString.h +++ b/src/os/inc/osString.h @@ -20,35 +20,30 @@ extern "C" { #endif -#ifndef TAOS_OS_FUNC_STRING_STRDUP - #define taosStrdupImp(str) strdup(str) - #define taosStrndupImp(str, size) strndup(str, size) -#endif - -#ifndef TAOS_OS_FUNC_STRING_GETLINE - #define taosGetlineImp(lineptr, n, stream) getline(lineptr, n , stream) -#else - int taosGetlineImp(char **lineptr, size_t *n, FILE *stream); -#endif - -#ifndef TAOS_OS_FUNC_STRING_WCHAR +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + #define tstrdup(str) _strdup(str) + #define tstrndup(str, size) _strndup(str, size) + int32_t tgetline(char **lineptr, size_t *n, FILE *stream); + int32_t twcslen(const wchar_t *wcs); +#else + #define tstrdup(str) strdup(str) + #define tstrndup(str, size) strndup(str, size) + #define tgetline(lineptr, n, stream) getline(lineptr, n, stream) #define twcslen wcslen -#endif +#endif -#define tstrncpy(dst, src, size) \ - do { \ - strncpy((dst), (src), (size)); \ - (dst)[(size)-1] = 0; \ +#define tstrncpy(dst, src, size) \ + do { \ + strncpy((dst), (src), (size)); \ + (dst)[(size)-1] = 0; \ } while (0) -#ifndef TAOS_OS_FUNC_STRING_STR2INT64 - int64_t tsosStr2int64(char *str); -#endif +int64_t taosStr2int64(char *str); // USE_LIBICONV int32_t taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs); -bool taosMbsToUcs4(char *mbs, size_t mbs_len, char *ucs4, int32_t ucs4_max_len, int *len); -int tasoUcs4Compare(void *f1_ucs4, void *f2_ucs4, int bytes); +bool taosMbsToUcs4(char *mbs, size_t mbs_len, char *ucs4, int32_t ucs4_max_len, int32_t *len); +int32_t tasoUcs4Compare(void *f1_ucs4, void *f2_ucs4, int32_t bytes); bool taosValidateEncodec(const char *encodec); char * taosCharsetReplace(char *charsetstr); diff --git a/src/os/inc/osSysinfo.h b/src/os/inc/osSysinfo.h index 895b5dd499..d136f9664c 100644 --- a/src/os/inc/osSysinfo.h +++ b/src/os/inc/osSysinfo.h @@ -20,7 +20,6 @@ extern "C" { #endif -// TAOS_OS_FUNC_SYSINFO typedef struct { int64_t tsize; int64_t used; @@ -28,20 +27,19 @@ typedef struct { } SysDiskSize; int32_t taosGetDiskSize(char *dataDir, SysDiskSize *diskSize); -void taosGetSystemInfo(); -bool taosGetProcIO(float *readKB, float *writeKB); -bool taosGetBandSpeed(float *bandSpeedKb); -void taosGetDisk(); -bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) ; -bool taosGetProcMemory(float *memoryUsedMB) ; -bool taosGetSysMemory(float *memoryUsedMB); -void taosPrintOsInfo(); -int taosSystem(const char * cmd) ; -void taosKillSystem(); -bool taosGetSystemUid(char *uid); -char *taosGetCmdlineByPID(int pid); +void taosGetSystemInfo(); +bool taosGetProcIO(float *readKB, float *writeKB); +bool taosGetBandSpeed(float *bandSpeedKb); +void taosGetDisk(); +bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage); +bool taosGetProcMemory(float *memoryUsedMB); +bool taosGetSysMemory(float *memoryUsedMB); +void taosPrintOsInfo(); +int taosSystem(const char *cmd); +void taosKillSystem(); +bool taosGetSystemUid(char *uid); +char * taosGetCmdlineByPID(int pid); -// TAOS_OS_FUNC_SYSINFO_CORE void taosSetCoreDump(); #ifdef __cplusplus diff --git a/src/os/inc/osTime.h b/src/os/inc/osTime.h index 2c50e7eeab..4743a8c160 100644 --- a/src/os/inc/osTime.h +++ b/src/os/inc/osTime.h @@ -23,9 +23,16 @@ extern "C" { #include "os.h" #include "taosdef.h" -#ifndef TAOS_OS_FUNC_TIME_DEF +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + #ifdef _TD_GO_DLL_ + #define MILLISECOND_PER_SECOND (1000LL) + #else + #define MILLISECOND_PER_SECOND (1000i64) + #endif +#else #define MILLISECOND_PER_SECOND ((int64_t)1000L) #endif + #define MILLISECOND_PER_MINUTE (MILLISECOND_PER_SECOND * 60) #define MILLISECOND_PER_HOUR (MILLISECOND_PER_MINUTE * 60) #define MILLISECOND_PER_DAY (MILLISECOND_PER_HOUR * 24) @@ -85,7 +92,7 @@ int32_t parseAbsoluteDuration(char* token, int32_t tokenlen, int64_t* ts); int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* duration, char* unit); int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t dayligth); -void deltaToUtcInitOnce(); +void deltaToUtcInitOnce(); #ifdef __cplusplus } diff --git a/src/os/inc/osTimer.h b/src/os/inc/osTimer.h index d6deae2a6d..72da19cd89 100644 --- a/src/os/inc/osTimer.h +++ b/src/os/inc/osTimer.h @@ -20,8 +20,6 @@ extern "C" { #endif -// TAOS_OS_FUNC_TIMER -void taosMsleep(int mseconds); int taosInitTimer(void (*callback)(int), int ms); void taosUninitTimer(); diff --git a/src/os/inc/osWindows.h b/src/os/inc/osWindows.h deleted file mode 100644 index a058f2cc99..0000000000 --- a/src/os/inc/osWindows.h +++ /dev/null @@ -1,352 +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_OS_WINDOWS_H -#define TDENGINE_OS_WINDOWS_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "winsock2.h" -#include -#include -#include -#include -#include -#include -#include -#include "msvcProcess.h" -#include "msvcDirect.h" -#include "msvcFcntl.h" -#include "msvcLibgen.h" -#include "msvcStdio.h" -#include "msvcUnistd.h" -#include "msvcLibgen.h" -#include "sys/msvcStat.h" -#include "sys/msvcTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define TAOS_OS_FUNC_LZ4 - int32_t BUILDIN_CLZL(uint64_t val); - int32_t BUILDIN_CLZ(uint32_t val); - int32_t BUILDIN_CTZL(uint64_t val); - int32_t BUILDIN_CTZ(uint32_t val); - -#define TAOS_OS_FUNC_FILE -#define TAOS_OS_FUNC_FILE_ISREG -#define TAOS_OS_FUNC_FILE_ISDIR -#define TAOS_OS_FUNC_FILE_ISLNK -#define TAOS_OS_FUNC_FILE_SENDIFLE -#define TAOS_OS_FUNC_FILE_GETTMPFILEPATH -#define TAOS_OS_FUNC_FILE_FTRUNCATE - -#define TAOS_OS_FUNC_DIR - -#define TAOS_OS_FUNC_MATH - #define SWAP(a, b, c) \ - do { \ - c __tmp = (c)(a); \ - (a) = (c)(b); \ - (b) = __tmp; \ - } while (0) - #define MAX(a,b) (((a)>(b))?(a):(b)) - #define MIN(a,b) (((a)<(b))?(a):(b)) - -#define TAOS_OS_FUNC_SEMPHONE_PTHREAD - -#define TAOS_OS_FUNC_SOCKET -#define TAOS_OS_FUNC_SOCKET_SETSOCKETOPT -#define TAOS_OS_FUNC_SOCKET_OP - #define taosSend(sockfd, buf, len, flags) send((SOCKET)sockfd, buf, len, flags) - #define taosSendto(sockfd, buf, len, flags, dest_addr, addrlen) sendto((SOCKET)sockfd, buf, len, flags, dest_addr, addrlen) - #define taosWriteSocket(fd, buf, len) send((SOCKET)fd, buf, len, 0) - #define taosReadSocket(fd, buf, len) recv((SOCKET)fd, buf, len, 0) - #define taosCloseSocketNoCheck(fd) closesocket((SOCKET)fd) - #define taosCloseSocket(fd) closesocket((SOCKET)fd) -typedef SOCKET eventfd_t; -#define eventfd(a, b) -1 - -#define TAOS_OS_DEF_EPOLL - #define TAOS_EPOLL_WAIT_TIME 100 - typedef SOCKET EpollFd; - #define EpollClose(pollFd) epoll_close(pollFd) - -#ifndef EPOLLWAKEUP - #define EPOLLWAKEUP (1u << 29) -#endif - -#define TAOS_OS_DEF_ZU - #define PRIzu "ld" - -#define TAOS_OS_FUNC_STRING_WCHAR - int twcslen(const wchar_t *wcs); -#define TAOS_OS_FUNC_STRING_GETLINE -#define TAOS_OS_FUNC_STRING_STR2INT64 - #ifdef _TD_GO_DLL_ - int64_t tsosStr2int64(char *str); - uint64_t htonll(uint64_t val); - #else - #define tsosStr2int64 _atoi64 - #endif -#define TAOS_OS_FUNC_STRING_STRDUP - #define taosStrdupImp(str) _strdup(str) - #define taosStrndupImp(str, size) _strndup(str, size) - -char *stpcpy (char *dest, const char *src); -char *stpncpy (char *dest, const char *src, size_t n); - -#define TAOS_OS_FUNC_SYSINFO - -#define TAOS_OS_FUNC_TIME_DEF - #ifdef _TD_GO_DLL_ - #define MILLISECOND_PER_SECOND (1000LL) - #else - #define MILLISECOND_PER_SECOND (1000i64) - #endif - -#define TAOS_OS_FUNC_TIMER_SLEEP -#define TAOS_OS_FUNC_TIMER - -// specific -typedef int (*__compar_fn_t)(const void *, const void *); -#define ssize_t int -#define bzero(ptr, size) memset((ptr), 0, (size)) -#define strcasecmp _stricmp -#define strncasecmp _strnicmp -#define wcsncasecmp _wcsnicmp -#define strtok_r strtok_s -#define snprintf _snprintf -#define in_addr_t unsigned long -#define socklen_t int -#define htobe64 htonll - -struct tm *localtime_r(const time_t *timep, struct tm *result); -char * strptime(const char *buf, const char *fmt, struct tm *tm); -char * strsep(char **stringp, const char *delim); -char * getpass(const char *prefix); -int flock(int fd, int option); -int fsync(int filedes); -char * strndup(const char *s, size_t n); -int gettimeofday(struct timeval *ptv, void *pTimeZone); - -// for send function in tsocket.c -#define MSG_NOSIGNAL 0 -#define SO_NO_CHECK 0x1234 -#define SOL_TCP 0x1234 - -#ifndef TCP_KEEPCNT - #define TCP_KEEPCNT 0x1234 -#endif - -#ifndef TCP_KEEPIDLE - #define TCP_KEEPIDLE 0x1234 -#endif - -#ifndef TCP_KEEPINTVL - #define TCP_KEEPINTVL 0x1234 -#endif - -#ifdef _MSC_VER -//#if _MSC_VER >= 1900 - #define TAOS_OS_FUNC_SOCKET_INET -//#endif -#endif - -#define SHUT_RDWR SD_BOTH -#define SHUT_RD SD_RECEIVE -#define SHUT_WR SD_SEND - -#define LOCK_EX 1 -#define LOCK_NB 2 -#define LOCK_UN 3 - -#ifndef PATH_MAX - #define PATH_MAX 256 -#endif - -#define TAOS_OS_FUNC_SIGNAL - -typedef struct { - int we_wordc; - char *we_wordv[1]; - int we_offs; - char wordPos[1025]; -} wordexp_t; -int wordexp(char *words, wordexp_t *pwordexp, int flags); -void wordfree(wordexp_t *pwordexp); - -#define openlog(a, b, c) -#define closelog() -#define LOG_ERR 0 -#define LOG_INFO 1 -void syslog(int unused, const char *format, ...); - -#define TAOS_OS_FUNC_ATOMIC - #define atomic_load_8(ptr) (*(char volatile*)(ptr)) - #define atomic_load_16(ptr) (*(short volatile*)(ptr)) - #define atomic_load_32(ptr) (*(long volatile*)(ptr)) - #define atomic_load_64(ptr) (*(__int64 volatile*)(ptr)) - #define atomic_load_ptr(ptr) (*(void* volatile*)(ptr)) - - #define atomic_store_8(ptr, val) ((*(char volatile*)(ptr)) = (char)(val)) - #define atomic_store_16(ptr, val) ((*(short volatile*)(ptr)) = (short)(val)) - #define atomic_store_32(ptr, val) ((*(long volatile*)(ptr)) = (long)(val)) - #define atomic_store_64(ptr, val) ((*(__int64 volatile*)(ptr)) = (__int64)(val)) - #define atomic_store_ptr(ptr, val) ((*(void* volatile*)(ptr)) = (void*)(val)) - - #define atomic_exchange_8(ptr, val) _InterlockedExchange8((char volatile*)(ptr), (char)(val)) - #define atomic_exchange_16(ptr, val) _InterlockedExchange16((short volatile*)(ptr), (short)(val)) - #define atomic_exchange_32(ptr, val) _InterlockedExchange((long volatile*)(ptr), (long)(val)) - #define atomic_exchange_64(ptr, val) _InterlockedExchange64((__int64 volatile*)(ptr), (__int64)(val)) - #ifdef _WIN64 - #define atomic_exchange_ptr(ptr, val) _InterlockedExchangePointer((void* volatile*)(ptr), (void*)(val)) - #else - #define atomic_exchange_ptr(ptr, val) _InlineInterlockedExchangePointer((void* volatile*)(ptr), (void*)(val)) - #endif - - #ifdef _TD_GO_DLL_ - #define atomic_val_compare_exchange_8 __sync_val_compare_and_swap - #else - #define atomic_val_compare_exchange_8(ptr, oldval, newval) _InterlockedCompareExchange8((char volatile*)(ptr), (char)(newval), (char)(oldval)) - #endif - #define atomic_val_compare_exchange_16(ptr, oldval, newval) _InterlockedCompareExchange16((short volatile*)(ptr), (short)(newval), (short)(oldval)) - #define atomic_val_compare_exchange_32(ptr, oldval, newval) _InterlockedCompareExchange((long volatile*)(ptr), (long)(newval), (long)(oldval)) - #define atomic_val_compare_exchange_64(ptr, oldval, newval) _InterlockedCompareExchange64((__int64 volatile*)(ptr), (__int64)(newval), (__int64)(oldval)) - #define atomic_val_compare_exchange_ptr(ptr, oldval, newval) _InterlockedCompareExchangePointer((void* volatile*)(ptr), (void*)(newval), (void*)(oldval)) - - char interlocked_add_fetch_8(char volatile *ptr, char val); - short interlocked_add_fetch_16(short volatile *ptr, short val); - long interlocked_add_fetch_32(long volatile *ptr, long val); - __int64 interlocked_add_fetch_64(__int64 volatile *ptr, __int64 val); - - char interlocked_and_fetch_8(char volatile* ptr, char val); - short interlocked_and_fetch_16(short volatile* ptr, short val); - long interlocked_and_fetch_32(long volatile* ptr, long val); - __int64 interlocked_and_fetch_64(__int64 volatile* ptr, __int64 val); - - __int64 interlocked_fetch_and_64(__int64 volatile* ptr, __int64 val); - - char interlocked_or_fetch_8(char volatile* ptr, char val); - short interlocked_or_fetch_16(short volatile* ptr, short val); - long interlocked_or_fetch_32(long volatile* ptr, long val); - __int64 interlocked_or_fetch_64(__int64 volatile* ptr, __int64 val); - - char interlocked_xor_fetch_8(char volatile* ptr, char val); - short interlocked_xor_fetch_16(short volatile* ptr, short val); - long interlocked_xor_fetch_32(long volatile* ptr, long val); - __int64 interlocked_xor_fetch_64(__int64 volatile* ptr, __int64 val); - - __int64 interlocked_fetch_xor_64(__int64 volatile* ptr, __int64 val); - - #define atomic_add_fetch_8(ptr, val) interlocked_add_fetch_8((char volatile*)(ptr), (char)(val)) - #define atomic_add_fetch_16(ptr, val) interlocked_add_fetch_16((short volatile*)(ptr), (short)(val)) - #define atomic_add_fetch_32(ptr, val) interlocked_add_fetch_32((long volatile*)(ptr), (long)(val)) - #define atomic_add_fetch_64(ptr, val) interlocked_add_fetch_64((__int64 volatile*)(ptr), (__int64)(val)) - #ifdef _TD_GO_DLL_ - #define atomic_fetch_add_8 __sync_fetch_and_ad - #define atomic_fetch_add_16 __sync_fetch_and_add - #else - #define atomic_fetch_add_8(ptr, val) _InterlockedExchangeAdd8((char volatile*)(ptr), (char)(val)) - #define atomic_fetch_add_16(ptr, val) _InterlockedExchangeAdd16((short volatile*)(ptr), (short)(val)) - #endif - #define atomic_fetch_add_8(ptr, val) _InterlockedExchangeAdd8((char volatile*)(ptr), (char)(val)) - #define atomic_fetch_add_16(ptr, val) _InterlockedExchangeAdd16((short volatile*)(ptr), (short)(val)) - #define atomic_fetch_add_32(ptr, val) _InterlockedExchangeAdd((long volatile*)(ptr), (long)(val)) - #define atomic_fetch_add_64(ptr, val) _InterlockedExchangeAdd64((__int64 volatile*)(ptr), (__int64)(val)) - - #define atomic_sub_fetch_8(ptr, val) interlocked_add_fetch_8((char volatile*)(ptr), -(char)(val)) - #define atomic_sub_fetch_16(ptr, val) interlocked_add_fetch_16((short volatile*)(ptr), -(short)(val)) - #define atomic_sub_fetch_32(ptr, val) interlocked_add_fetch_32((long volatile*)(ptr), -(long)(val)) - #define atomic_sub_fetch_64(ptr, val) interlocked_add_fetch_64((__int64 volatile*)(ptr), -(__int64)(val)) - - #define atomic_fetch_sub_8(ptr, val) _InterlockedExchangeAdd8((char volatile*)(ptr), -(char)(val)) - #define atomic_fetch_sub_16(ptr, val) _InterlockedExchangeAdd16((short volatile*)(ptr), -(short)(val)) - #define atomic_fetch_sub_32(ptr, val) _InterlockedExchangeAdd((long volatile*)(ptr), -(long)(val)) - #define atomic_fetch_sub_64(ptr, val) _InterlockedExchangeAdd64((__int64 volatile*)(ptr), -(__int64)(val)) - - #define atomic_and_fetch_8(ptr, val) interlocked_and_fetch_8((char volatile*)(ptr), (char)(val)) - #define atomic_and_fetch_16(ptr, val) interlocked_and_fetch_16((short volatile*)(ptr), (short)(val)) - #define atomic_and_fetch_32(ptr, val) interlocked_and_fetch_32((long volatile*)(ptr), (long)(val)) - #define atomic_and_fetch_64(ptr, val) interlocked_and_fetch_64((__int64 volatile*)(ptr), (__int64)(val)) - - #define atomic_fetch_and_8(ptr, val) _InterlockedAnd8((char volatile*)(ptr), (char)(val)) - #define atomic_fetch_and_16(ptr, val) _InterlockedAnd16((short volatile*)(ptr), (short)(val)) - #define atomic_fetch_and_32(ptr, val) _InterlockedAnd((long volatile*)(ptr), (long)(val)) - #define atomic_fetch_and_64(ptr, val) interlocked_fetch_and_64((__int64 volatile*)(ptr), (__int64)(val)) - - #define atomic_or_fetch_8(ptr, val) interlocked_or_fetch_8((char volatile*)(ptr), (char)(val)) - #define atomic_or_fetch_16(ptr, val) interlocked_or_fetch_16((short volatile*)(ptr), (short)(val)) - #define atomic_or_fetch_32(ptr, val) interlocked_or_fetch_32((long volatile*)(ptr), (long)(val)) - #define atomic_or_fetch_64(ptr, val) interlocked_or_fetch_64((__int64 volatile*)(ptr), (__int64)(val)) - - #define atomic_fetch_or_8(ptr, val) _InterlockedOr8((char volatile*)(ptr), (char)(val)) - #define atomic_fetch_or_16(ptr, val) _InterlockedOr16((short volatile*)(ptr), (short)(val)) - #define atomic_fetch_or_32(ptr, val) _InterlockedOr((long volatile*)(ptr), (long)(val)) - #define atomic_fetch_or_64(ptr, val) interlocked_fetch_or_64((__int64 volatile*)(ptr), (__int64)(val)) - - #define atomic_xor_fetch_8(ptr, val) interlocked_xor_fetch_8((char volatile*)(ptr), (char)(val)) - #define atomic_xor_fetch_16(ptr, val) interlocked_xor_fetch_16((short volatile*)(ptr), (short)(val)) - #define atomic_xor_fetch_32(ptr, val) interlocked_xor_fetch_32((long volatile*)(ptr), (long)(val)) - #define atomic_xor_fetch_64(ptr, val) interlocked_xor_fetch_64((__int64 volatile*)(ptr), (__int64)(val)) - - #define atomic_fetch_xor_8(ptr, val) _InterlockedXor8((char volatile*)(ptr), (char)(val)) - #define atomic_fetch_xor_16(ptr, val) _InterlockedXor16((short volatile*)(ptr), (short)(val)) - #define atomic_fetch_xor_32(ptr, val) _InterlockedXor((long volatile*)(ptr), (long)(val)) - #define atomic_fetch_xor_64(ptr, val) interlocked_fetch_xor_64((__int64 volatile*)(ptr), (__int64)(val)) - - #ifdef _WIN64 - #define atomic_add_fetch_ptr atomic_add_fetch_64 - #define atomic_fetch_add_ptr atomic_fetch_add_64 - #define atomic_sub_fetch_ptr atomic_sub_fetch_64 - #define atomic_fetch_sub_ptr atomic_fetch_sub_64 - #define atomic_and_fetch_ptr atomic_and_fetch_64 - #define atomic_fetch_and_ptr atomic_fetch_and_64 - #define atomic_or_fetch_ptr atomic_or_fetch_64 - #define atomic_fetch_or_ptr atomic_fetch_or_64 - #define atomic_xor_fetch_ptr atomic_xor_fetch_64 - #define atomic_fetch_xor_ptr atomic_fetch_xor_64 - #else - #define atomic_add_fetch_ptr atomic_add_fetch_32 - #define atomic_fetch_add_ptr atomic_fetch_add_32 - #define atomic_sub_fetch_ptr atomic_sub_fetch_32 - #define atomic_fetch_sub_ptr atomic_fetch_sub_32 - #define atomic_and_fetch_ptr atomic_and_fetch_32 - #define atomic_fetch_and_ptr atomic_fetch_and_32 - #define atomic_or_fetch_ptr atomic_or_fetch_32 - #define atomic_fetch_or_ptr atomic_fetch_or_32 - #define atomic_xor_fetch_ptr atomic_xor_fetch_32 - #define atomic_fetch_xor_ptr atomic_fetch_xor_32 - #endif -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/os/src/alpine/CMakeLists.txt b/src/os/src/alpine/CMakeLists.txt deleted file mode 100644 index b5e739c24c..0000000000 --- a/src/os/src/alpine/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) -PROJECT(TDengine) - -AUX_SOURCE_DIRECTORY(. SRC) -ADD_LIBRARY(os ${SRC}) -TARGET_LINK_LIBRARIES(os m rt) - diff --git a/src/os/src/alpine/alpineEnv.c b/src/os/src/alpine/alpineEnv.c deleted file mode 100644 index 811d98ad7f..0000000000 --- a/src/os/src/alpine/alpineEnv.c +++ /dev/null @@ -1,32 +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 . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "tglobal.h" - -void osInit() { - if (configDir[0] == 0) { - strcpy(configDir, "/etc/taos"); - } - - strcpy(tsVnodeDir, ""); - strcpy(tsDnodeDir, ""); - strcpy(tsMnodeDir, ""); - strcpy(tsDataDir, "/var/lib/taos"); - strcpy(tsLogDir, "/var/log/taos"); - strcpy(tsScriptDir, "/etc/taos"); - strcpy(tsOsName, "Linux"); -} \ No newline at end of file diff --git a/src/os/src/darwin/CMakeLists.txt b/src/os/src/darwin/CMakeLists.txt index c4cb28aa05..259e1a7a0b 100644 --- a/src/os/src/darwin/CMakeLists.txt +++ b/src/os/src/darwin/CMakeLists.txt @@ -2,4 +2,4 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(TDengine) AUX_SOURCE_DIRECTORY(. SRC) -ADD_LIBRARY(os ${SRC}) +ADD_LIBRARY(osdarwin ${SRC}) diff --git a/src/os/src/darwin/darwinFile.c b/src/os/src/darwin/darwinFile.c deleted file mode 100644 index 4236ea1c5f..0000000000 --- a/src/os/src/darwin/darwinFile.c +++ /dev/null @@ -1,65 +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 . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "tulog.h" - -int64_t taosFSendFile(FILE *out_file, FILE *in_file, int64_t *offset, int64_t count) { - int r = 0; - if (offset) { - r = fseek(in_file, *offset, SEEK_SET); - if (r==-1) return -1; - } - off_t len = count; - while (len>0) { - char buf[1024*16]; - off_t n = sizeof(buf); - if (len0) { - char buf[1024*16]; - off_t n = sizeof(buf); - if (len @@ -415,8 +415,6 @@ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) { static struct timespec do_timespec_diff(struct timespec *from, struct timespec *to); int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) { - taos_block_sigalrm(); - int e = 0; if (!events) { errno = EINVAL; diff --git a/src/os/src/darwin/darwinSemphone.c b/src/os/src/darwin/dwSemphone.c similarity index 99% rename from src/os/src/darwin/darwinSemphone.c rename to src/os/src/darwin/dwSemphone.c index 5bb926732a..898410647a 100644 --- a/src/os/src/darwin/darwinSemphone.c +++ b/src/os/src/darwin/dwSemphone.c @@ -20,7 +20,6 @@ #define _DEFAULT_SOURCE #include "os.h" - #include // #define SEM_USE_PTHREAD diff --git a/src/os/src/darwin/darwinSocket.c b/src/os/src/darwin/dwSocket.c similarity index 100% rename from src/os/src/darwin/darwinSocket.c rename to src/os/src/darwin/dwSocket.c diff --git a/src/os/src/darwin/darwinSysInfo.c b/src/os/src/darwin/dwSysInfo.c similarity index 99% rename from src/os/src/darwin/darwinSysInfo.c rename to src/os/src/darwin/dwSysInfo.c index 6e70043779..b3c9bd528e 100644 --- a/src/os/src/darwin/darwinSysInfo.c +++ b/src/os/src/darwin/dwSysInfo.c @@ -22,7 +22,6 @@ #include #include - static void taosGetSystemTimezone() { SGlobalCfg *cfg_timezone = taosGetConfigOption("timezone"); if (cfg_timezone == NULL) return; diff --git a/src/os/src/darwin/darwinTimer.c b/src/os/src/darwin/dwTimer.c similarity index 100% rename from src/os/src/darwin/darwinTimer.c rename to src/os/src/darwin/dwTimer.c diff --git a/src/os/src/detail/CMakeLists.txt b/src/os/src/detail/CMakeLists.txt index facfbd23af..5c49df24c1 100644 --- a/src/os/src/detail/CMakeLists.txt +++ b/src/os/src/detail/CMakeLists.txt @@ -7,10 +7,15 @@ AUX_SOURCE_DIRECTORY(. SRC) SET_SOURCE_FILES_PROPERTIES(osSysinfo.c PROPERTIES COMPILE_FLAGS -w) SET_SOURCE_FILES_PROPERTIES(osCoredump.c PROPERTIES COMPILE_FLAGS -w) -ADD_LIBRARY(osdetail ${SRC}) -TARGET_LINK_LIBRARIES(osdetail os) +ADD_LIBRARY(os ${SRC}) -IF (TD_ARM_32 OR TD_LINUX_32) - TARGET_LINK_LIBRARIES(osdetail atomic) +IF (TD_LINUX) + TARGET_LINK_LIBRARIES(os oslinux) + IF (TD_ARM_32 OR TD_LINUX_32) + TARGET_LINK_LIBRARIES(os atomic) + ENDIF () +ELSEIF (TD_DARWIN) + TARGET_LINK_LIBRARIES(os osdarwin) +ELSEIF (TD_WINDOWS) + TARGET_LINK_LIBRARIES(os oswindows) ENDIF () - diff --git a/src/os/src/linux/ningsi.c b/src/os/src/detail/osAtomic.c similarity index 99% rename from src/os/src/linux/ningsi.c rename to src/os/src/detail/osAtomic.c index 2514c38ece..ecda573528 100644 --- a/src/os/src/linux/ningsi.c +++ b/src/os/src/detail/osAtomic.c @@ -53,4 +53,3 @@ int64_t atomic_exchange_64_impl(int64_t* ptr, int64_t val ) { return old; } #endif - diff --git a/src/os/src/detail/osDir.c b/src/os/src/detail/osDir.c index 144c59fa2d..2a2e2519b5 100644 --- a/src/os/src/detail/osDir.c +++ b/src/os/src/detail/osDir.c @@ -28,7 +28,7 @@ void taosRemoveDir(char *rootDir) { struct dirent *de = NULL; while ((de = readdir(dir)) != NULL) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; - + char filename[1024]; snprintf(filename, 1023, "%s/%s", rootDir, de->d_name); if (de->d_type & DT_DIR) { @@ -51,27 +51,11 @@ int taosMkDir(const char *path, mode_t mode) { return code; } - -#ifndef TAOS_OS_FUNC_DIR - -int32_t taosRename(char* oldName, char *newName) { - int32_t code = rename(oldName, newName); - if (code < 0) { - uError("failed to rename file %s to %s, reason:%s", oldName, newName, strerror(errno)); - } else { - uTrace("successfully to rename file %s to %s", oldName, newName); - } - - return code; -} - -#endif - void taosRemoveOldLogFiles(char *rootDir, int32_t keepDays) { DIR *dir = opendir(rootDir); if (dir == NULL) return; - int64_t sec = taosGetTimestampSec(); + int64_t sec = taosGetTimestampSec(); struct dirent *de = NULL; while ((de = readdir(dir)) != NULL) { diff --git a/src/os/src/detail/osFile.c b/src/os/src/detail/osFile.c index 538ed37879..cc12968c72 100644 --- a/src/os/src/detail/osFile.c +++ b/src/os/src/detail/osFile.c @@ -16,19 +16,50 @@ #define _DEFAULT_SOURCE #include "os.h" #include "tglobal.h" +#include "tulog.h" -#ifndef TAOS_OS_FUNC_FILE_GETTMPFILEPATH +void taosClose(FileFd fd) { + close(fd); + fd = FD_INITIALIZER; +} + +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + +void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) { + const char *tdengineTmpFileNamePrefix = "tdengine-"; + char tmpPath[PATH_MAX]; + + int32_t len = (int32_t)strlen(tsTempDir); + memcpy(tmpPath, tsTempDir, len); + + if (tmpPath[len - 1] != '/' && tmpPath[len - 1] != '\\') { + tmpPath[len++] = '\\'; + } + + strcpy(tmpPath + len, tdengineTmpFileNamePrefix); + strcat(tmpPath, tdengineTmpFileNamePrefix); + if (strlen(tmpPath) + strlen(fileNamePrefix) + strlen("-%d-%s") < PATH_MAX) { + strcat(tmpPath, fileNamePrefix); + strcat(tmpPath, "-%d-%s"); + } + + char rand[8] = {0}; + taosRandStr(rand, tListLen(rand) - 1); + snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand); +} + +#else void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) { const char *tdengineTmpFileNamePrefix = "tdengine-"; - char tmpPath[PATH_MAX]; + char tmpPath[PATH_MAX]; int32_t len = strlen(tsTempDir); memcpy(tmpPath, tsTempDir, len); static uint64_t seqId = 0; - + if (tmpPath[len - 1] != '/') { - tmpPath[len++] = '/'; + tmpPath[len++] = '/'; } strcpy(tmpPath + len, tdengineTmpFileNamePrefix); @@ -38,43 +69,15 @@ void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) { } char rand[32] = {0}; - - sprintf(rand, "%"PRIu64, atomic_add_fetch_64(&seqId, 1)); - + + sprintf(rand, "%" PRIu64, atomic_add_fetch_64(&seqId, 1)); + snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand); } #endif -int32_t taosRenameFile(char *fullPath, char *suffix, char delimiter, char **dstPath) { - int32_t ts = taosGetTimestampSec(); - - char fname[PATH_MAX] = {0}; // max file name length must be less than 255 - - char *delimiterPos = strrchr(fullPath, delimiter); - if (delimiterPos == NULL) return -1; - - int32_t fileNameLen = 0; - if (suffix) { - fileNameLen = snprintf(fname, PATH_MAX, "%s.%d.%s", delimiterPos + 1, ts, suffix); - } else { - fileNameLen = snprintf(fname, PATH_MAX, "%s.%d", delimiterPos + 1, ts); - } - - int32_t len = (int32_t)((delimiterPos - fullPath) + fileNameLen + 1); - if (*dstPath == NULL) { - *dstPath = calloc(1, len + 1); - if (*dstPath == NULL) return -1; - } - - strncpy(*dstPath, fullPath, (size_t)(delimiterPos - fullPath + 1)); - strncat(*dstPath, fname, (size_t)fileNameLen); - (*dstPath)[len] = 0; - - return rename(fullPath, *dstPath); -} - -int64_t taosReadImp(int32_t fd, void *buf, int64_t count) { +int64_t taosRead(FileFd fd, void *buf, int64_t count) { int64_t leftbytes = count; int64_t readbytes; char * tbuf = (char *)buf; @@ -98,7 +101,7 @@ int64_t taosReadImp(int32_t fd, void *buf, int64_t count) { return count; } -int64_t taosWriteImp(int32_t fd, void *buf, int64_t n) { +int64_t taosWrite(FileFd fd, void *buf, int64_t n) { int64_t nleft = n; int64_t nwritten = 0; char * tbuf = (char *)buf; @@ -118,9 +121,7 @@ int64_t taosWriteImp(int32_t fd, void *buf, int64_t n) { return n; } -int64_t taosLSeekImp(int32_t fd, int64_t offset, int32_t whence) { - return (int64_t)lseek(fd, (long)offset, whence); -} +int64_t taosLSeek(FileFd fd, int64_t offset, int32_t whence) { return (int64_t)lseek(fd, (long)offset, whence); } int64_t taosCopy(char *from, char *to) { char buffer[4096]; @@ -145,22 +146,139 @@ int64_t taosCopy(char *from, char *to) { if (bytes < sizeof(buffer)) break; } - fsync(fidto); + taosFsync(fidto); - close(fidfrom); - close(fidto); + taosClose(fidfrom); + taosClose(fidto); return size; _err: - if (fidfrom >= 0) close(fidfrom); - if (fidto >= 0) close(fidto); + if (fidfrom >= 0) taosClose(fidfrom); + if (fidto >= 0) taosClose(fidto); remove(to); return -1; } -#ifndef TAOS_OS_FUNC_FILE_SENDIFLE +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) -int64_t taosSendFile(SOCKET dfd, int32_t sfd, int64_t *offset, int64_t size) { +#define _SEND_FILE_STEP_ 1000 + +int64_t taosFSendFile(FILE *out_file, FILE *in_file, int64_t *offset, int64_t count) { + fseek(in_file, (int32_t)(*offset), 0); + int64_t writeLen = 0; + uint8_t buffer[_SEND_FILE_STEP_] = {0}; + + for (int64_t len = 0; len < (count - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) { + size_t rlen = fread(buffer, 1, _SEND_FILE_STEP_, in_file); + if (rlen <= 0) { + return writeLen; + } else if (rlen < _SEND_FILE_STEP_) { + fwrite(buffer, 1, rlen, out_file); + return (int64_t)(writeLen + rlen); + } else { + fwrite(buffer, 1, _SEND_FILE_STEP_, in_file); + writeLen += _SEND_FILE_STEP_; + } + } + + int64_t remain = count - writeLen; + if (remain > 0) { + size_t rlen = fread(buffer, 1, (size_t)remain, in_file); + if (rlen <= 0) { + return writeLen; + } else { + fwrite(buffer, 1, (size_t)remain, out_file); + writeLen += remain; + } + } + + return writeLen; +} + +int64_t taosSendFile(SocketFd dfd, FileFd sfd, int64_t *offset, int64_t count) { + if (offset != NULL) lseek(sfd, (int32_t)(*offset), 0); + + int64_t writeLen = 0; + uint8_t buffer[_SEND_FILE_STEP_] = {0}; + + for (int64_t len = 0; len < (count - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) { + int32_t rlen = (int32_t)read(sfd, buffer, _SEND_FILE_STEP_); + if (rlen <= 0) { + return writeLen; + } else if (rlen < _SEND_FILE_STEP_) { + taosWriteSocket(dfd, buffer, rlen); + return (int64_t)(writeLen + rlen); + } else { + taosWriteSocket(dfd, buffer, _SEND_FILE_STEP_); + writeLen += _SEND_FILE_STEP_; + } + } + + int64_t remain = count - writeLen; + if (remain > 0) { + int32_t rlen = read(sfd, buffer, (int32_t)remain); + if (rlen <= 0) { + return writeLen; + } else { + taosWriteSocket(sfd, buffer, (int32_t)remain); + writeLen += remain; + } + } + + return writeLen; +} + +#elif defined(_TD_DARWIN_64) + +int64_t taosFSendFile(FILE *out_file, FILE *in_file, int64_t *offset, int64_t count) { + int r = 0; + if (offset) { + r = fseek(in_file, *offset, SEEK_SET); + if (r == -1) return -1; + } + off_t len = count; + while (len > 0) { + char buf[1024 * 16]; + off_t n = sizeof(buf); + if (len < n) n = len; + size_t m = fread(buf, 1, n, in_file); + if (m < n) { + int e = ferror(in_file); + if (e) return -1; + } + if (m == 0) break; + if (m != fwrite(buf, 1, m, out_file)) { + return -1; + } + len -= m; + } + return count - len; +} + +int64_t taosSendFile(SocketFd dfd, FileFd sfd, int64_t *offset, int64_t count) { + int r = 0; + if (offset) { + r = lseek(sfd, *offset, SEEK_SET); + if (r == -1) return -1; + } + off_t len = count; + while (len > 0) { + char buf[1024 * 16]; + off_t n = sizeof(buf); + if (len < n) n = len; + size_t m = read(sfd, buf, n); + if (m == -1) return -1; + if (m == 0) break; + size_t l = write(dfd, buf, m); + if (l == -1) return -1; + len -= l; + } + return count - len; +} + +#else + +int64_t taosSendFile(SocketFd dfd, FileFd sfd, int64_t *offset, int64_t size) { int64_t leftbytes = size; int64_t sentbytes; @@ -188,10 +306,96 @@ int64_t taosFSendFile(FILE *outfile, FILE *infile, int64_t *offset, int64_t size #endif -#ifndef TAOS_OS_FUNC_FILE_FTRUNCATE +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) -int32_t taosFtruncate(int32_t fd, int64_t length) { - return ftruncate(fd, length); +int32_t taosFtruncate(int32_t fd, int64_t l_size) { + if (fd < 0) { + errno = EBADF; + uError("%s\n", "fd arg was negative"); + return -1; + } + + HANDLE h = (HANDLE)_get_osfhandle(fd); + + LARGE_INTEGER li_0; + li_0.QuadPart = (int64_t)0; + BOOL cur = SetFilePointerEx(h, li_0, NULL, FILE_CURRENT); + if (!cur) { + uError("SetFilePointerEx Error getting current position in file.\n"); + return -1; + } + + LARGE_INTEGER li_size; + li_size.QuadPart = l_size; + BOOL cur2 = SetFilePointerEx(h, li_size, NULL, FILE_BEGIN); + if (cur2 == 0) { + int error = GetLastError(); + uError("SetFilePointerEx GetLastError is: %d\n", error); + switch (error) { + case ERROR_INVALID_HANDLE: + errno = EBADF; + break; + default: + errno = EIO; + break; + } + return -1; + } + + if (!SetEndOfFile(h)) { + int error = GetLastError(); + uError("SetEndOfFile GetLastError is:%d", error); + switch (error) { + case ERROR_INVALID_HANDLE: + errno = EBADF; + break; + default: + errno = EIO; + break; + } + return -1; + } + + return 0; } -#endif \ No newline at end of file +int32_t taosFsync(FileFd fd) { + if (fd < 0) { + errno = EBADF; + uError("%s\n", "fd arg was negative"); + return -1; + } + + HANDLE h = (HANDLE)_get_osfhandle(fd); + + return FlushFileBuffers(h); +} + +int32_t taosRename(char *oldName, char *newName) { + int32_t code = MoveFileEx(oldName, newName, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED); + if (code < 0) { + uError("failed to rename file %s to %s, reason:%s", oldName, newName, strerror(errno)); + } else { + uTrace("successfully to rename file %s to %s", oldName, newName); + } + + return code; +} + +#else + +int32_t taosFtruncate(FileFd fd, int64_t length) { return ftruncate(fd, length); } +int32_t taosFsync(FileFd fd) { return fsync(fd); } + +int32_t taosRename(char *oldName, char *newName) { + int32_t code = rename(oldName, newName); + if (code < 0) { + uError("failed to rename file %s to %s, reason:%s", oldName, newName, strerror(errno)); + } else { + uTrace("successfully to rename file %s to %s", oldName, newName); + } + + return code; +} + +#endif diff --git a/src/os/src/detail/osRand.c b/src/os/src/detail/osRand.c index b322a88684..0dda908bb3 100644 --- a/src/os/src/detail/osRand.c +++ b/src/os/src/detail/osRand.c @@ -16,8 +16,6 @@ #define _DEFAULT_SOURCE #include "os.h" -#ifndef TAOS_OS_FUNC_RAND - uint32_t taosRand(void) { return rand(); } uint32_t taosSafeRand(void) { @@ -38,8 +36,6 @@ uint32_t taosSafeRand(void) { return (uint32_t)seed; } -#endif - void taosRandStr(char* str, int32_t size) { const char* set = "abcdefghijklmnopqrstuvwxyz0123456789-_."; int32_t len = 39; diff --git a/src/os/src/detail/osSemphone.c b/src/os/src/detail/osSemphone.c index 2bf2f24487..06907d5258 100644 --- a/src/os/src/detail/osSemphone.c +++ b/src/os/src/detail/osSemphone.c @@ -16,9 +16,9 @@ #define _DEFAULT_SOURCE #include "os.h" -#ifndef TAOS_OS_FUNC_SEMPHONE +#if !defined (_TD_DARWIN_64) -int tsem_wait(tsem_t* sem) { +int32_t tsem_wait(tsem_t* sem) { int ret = 0; do { ret = sem_wait(sem); @@ -28,9 +28,9 @@ int tsem_wait(tsem_t* sem) { #endif -#ifndef TAOS_OS_FUNC_SEMPHONE_PTHREAD +#if !(defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) || defined (_TD_DARWIN_64)) -bool taosCheckPthreadValid(pthread_t thread) { return thread != 0; } +bool taosCheckPthreadValid(pthread_t thread) { return thread != 0; } int64_t taosGetSelfPthreadId() { static __thread int id = 0; diff --git a/src/os/src/detail/osSignal.c b/src/os/src/detail/osSignal.c index e1a0e84e7f..4467a607b2 100644 --- a/src/os/src/detail/osSignal.c +++ b/src/os/src/detail/osSignal.c @@ -15,11 +15,13 @@ #define _DEFAULT_SOURCE #include "os.h" +#include "taosdef.h" #include "tconfig.h" #include "tglobal.h" #include "tulog.h" -#ifndef TAOS_OS_FUNC_SIGNAL +#if !(defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)) + typedef void (*FLinuxSignalHandler)(int32_t signum, siginfo_t *sigInfo, void *context); void taosSetSignal(int32_t signum, FSignalHandler sigfp) { diff --git a/src/os/src/detail/osSleep.c b/src/os/src/detail/osSleep.c new file mode 100644 index 0000000000..9c3231fd13 --- /dev/null +++ b/src/os/src/detail/osSleep.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#define _DEFAULT_SOURCE +#include "os.h" + +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + +void taosMsleep(int32_t ms) { Sleep(ms); } + +#else + +/* + to make taosMsleep work, + signal SIGALRM shall be blocked in the calling thread, + + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGALRM); + pthread_sigmask(SIG_BLOCK, &set, NULL); +*/ +void taosMsleep(int32_t mseconds) { +#if 1 + usleep(mseconds * 1000); +#else + struct timeval timeout; + int32_t seconds, useconds; + + seconds = mseconds / 1000; + useconds = (mseconds % 1000) * 1000; + timeout.tv_sec = seconds; + timeout.tv_usec = useconds; + + /* sigset_t set; */ + /* sigemptyset(&set); */ + /* sigaddset(&set, SIGALRM); */ + /* pthread_sigmask(SIG_BLOCK, &set, NULL); */ + + select(0, NULL, NULL, NULL, &timeout); + +/* pthread_sigmask(SIG_UNBLOCK, &set, NULL); */ +#endif +} + +#endif diff --git a/src/os/src/detail/osSocket.c b/src/os/src/detail/osSocket.c index db976acccd..7ce9d6eb06 100644 --- a/src/os/src/detail/osSocket.c +++ b/src/os/src/detail/osSocket.c @@ -17,7 +17,7 @@ #include "os.h" #include "tulog.h" -#ifndef TAOS_OS_FUNC_SOCKET +#if !(defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)) int32_t taosSetNonblocking(SOCKET sock, int32_t on) { int32_t flags = 0; @@ -65,7 +65,7 @@ void taosSetMaskSIGPIPE() { #endif -#ifndef TAOS_OS_FUNC_SOCKET_SETSOCKETOPT +#if !(defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) || defined(_TD_DARWIN_32)) int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t optlen) { return setsockopt(socketfd, level, optname, optval, (socklen_t)optlen); @@ -74,9 +74,10 @@ int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *op int32_t taosGetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t* optlen) { return getsockopt(socketfd, level, optname, optval, (socklen_t *)optlen); } + #endif -#ifndef TAOS_OS_FUNC_SOCKET_INET +#if !( (defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)) && defined(_MSC_VER) ) uint32_t taosInetAddr(char *ipAddr) { return inet_addr(ipAddr); diff --git a/src/os/src/detail/osString.c b/src/os/src/detail/osString.c index 59f47b4815..2c49797d83 100644 --- a/src/os/src/detail/osString.c +++ b/src/os/src/detail/osString.c @@ -17,17 +17,17 @@ #include "os.h" #include "tglobal.h" -#ifndef TAOS_OS_FUNC_STRING_STR2INT64 -int64_t tsosStr2int64(char *str) { +int64_t taosStr2int64(char *str) { char *endptr = NULL; return strtoll(str, &endptr, 10); } -#endif -#ifndef TAOS_OS_FUNC_STRING_WCHAR -int tasoUcs4Compare(void *f1_ucs4, void *f2_ucs4, int bytes) { +#if !(defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32)) + +int32_t tasoUcs4Compare(void *f1_ucs4, void *f2_ucs4, int32_t bytes) { return wcsncmp((wchar_t *)f1_ucs4, (wchar_t *)f2_ucs4, bytes / TSDB_NCHAR_SIZE); } + #endif #ifdef USE_LIBICONV diff --git a/src/os/src/detail/osSysinfo.c b/src/os/src/detail/osSysinfo.c index bbda08aa25..d0b284e1ca 100644 --- a/src/os/src/detail/osSysinfo.c +++ b/src/os/src/detail/osSysinfo.c @@ -20,7 +20,7 @@ #include "tulog.h" #include "taoserror.h" -#ifndef TAOS_OS_FUNC_SYSINFO +#if !(defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) || defined (_TD_DARWIN_64)) #define PROCESS_ITEM 12 diff --git a/src/os/src/detail/osTimer.c b/src/os/src/detail/osTimer.c index c1135ce292..b054f08c78 100644 --- a/src/os/src/detail/osTimer.c +++ b/src/os/src/detail/osTimer.c @@ -18,7 +18,7 @@ #include "ttimer.h" #include "tulog.h" -#ifndef TAOS_OS_FUNC_TIMER +#if !(defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) || defined(_TD_DARWIN_64)) static void taosDeleteTimer(void *tharg) { timer_t *pTimer = tharg; @@ -104,42 +104,3 @@ void taosUninitTimer() { } #endif - -#ifndef TAOS_OS_FUNC_TIMER_SLEEP -/* - to make taosMsleep work, - signal SIGALRM shall be blocked in the calling thread, - - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGALRM); - pthread_sigmask(SIG_BLOCK, &set, NULL); -*/ -void taosMsleep(int mseconds) { -#ifdef __APPLE__ - taos_block_sigalrm(); -#endif // __APPLE__ -#if 1 - usleep(mseconds * 1000); -#else - struct timeval timeout; - int seconds, useconds; - - seconds = mseconds / 1000; - useconds = (mseconds % 1000) * 1000; - timeout.tv_sec = seconds; - timeout.tv_usec = useconds; - - /* sigset_t set; */ - /* sigemptyset(&set); */ - /* sigaddset(&set, SIGALRM); */ - /* pthread_sigmask(SIG_BLOCK, &set, NULL); */ - - select(0, NULL, NULL, NULL, &timeout); - -/* pthread_sigmask(SIG_UNBLOCK, &set, NULL); */ -#endif - -} - -#endif diff --git a/src/os/src/linux/CMakeLists.txt b/src/os/src/linux/CMakeLists.txt index b1a7ebf54e..08b696ba1a 100644 --- a/src/os/src/linux/CMakeLists.txt +++ b/src/os/src/linux/CMakeLists.txt @@ -2,6 +2,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(TDengine) AUX_SOURCE_DIRECTORY(. SRC) +ADD_LIBRARY(oslinux ${SRC}) -ADD_LIBRARY(os ${SRC}) -TARGET_LINK_LIBRARIES(os m rt z) +TARGET_LINK_LIBRARIES(oslinux m rt z) \ No newline at end of file diff --git a/src/os/src/linux/linuxEnv.c b/src/os/src/linux/linuxEnv.c index e3eadbc94b..417513314c 100644 --- a/src/os/src/linux/linuxEnv.c +++ b/src/os/src/linux/linuxEnv.c @@ -40,9 +40,8 @@ void osInit() { strcpy(tsOsName, "Linux"); } -char cmdline[1024]; - char* taosGetCmdlineByPID(int pid) { + static char cmdline[1024]; sprintf(cmdline, "/proc/%d/cmdline", pid); FILE* f = fopen(cmdline, "r"); if (f) { diff --git a/src/os/src/windows/CMakeLists.txt b/src/os/src/windows/CMakeLists.txt index 9dcc9e7e6d..e5472e1abd 100644 --- a/src/os/src/windows/CMakeLists.txt +++ b/src/os/src/windows/CMakeLists.txt @@ -2,6 +2,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(TDengine) AUX_SOURCE_DIRECTORY(. SRC) -ADD_LIBRARY(os ${SRC}) +ADD_LIBRARY(oswindows ${SRC}) -TARGET_LINK_LIBRARIES(os winmm IPHLPAPI ws2_32 MsvcLibXw) +TARGET_LINK_LIBRARIES(oswindows winmm IPHLPAPI ws2_32 MsvcLibXw) \ No newline at end of file diff --git a/src/os/src/windows/wFile.c b/src/os/src/windows/wFile.c deleted file mode 100644 index 3bfe1c1b5d..0000000000 --- a/src/os/src/windows/wFile.c +++ /dev/null @@ -1,184 +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 . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "osSocket.h" -#include "tglobal.h" -#include "tulog.h" - -void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) { - const char *tdengineTmpFileNamePrefix = "tdengine-"; - char tmpPath[PATH_MAX]; - - int32_t len = (int32_t)strlen(tsTempDir); - memcpy(tmpPath, tsTempDir, len); - - if (tmpPath[len - 1] != '/' && tmpPath[len - 1] != '\\') { - tmpPath[len++] = '\\'; - } - - strcpy(tmpPath + len, tdengineTmpFileNamePrefix); - strcat(tmpPath, tdengineTmpFileNamePrefix); - if (strlen(tmpPath) + strlen(fileNamePrefix) + strlen("-%d-%s") < PATH_MAX) { - strcat(tmpPath, fileNamePrefix); - strcat(tmpPath, "-%d-%s"); - } - - char rand[8] = {0}; - taosRandStr(rand, tListLen(rand) - 1); - snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand); -} - -#define _SEND_FILE_STEP_ 1000 - -int64_t taosFSendFile(FILE *out_file, FILE *in_file, int64_t *offset, int64_t count) { - fseek(in_file, (int32_t)(*offset), 0); - int64_t writeLen = 0; - uint8_t buffer[_SEND_FILE_STEP_] = {0}; - - for (int64_t len = 0; len < (count - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) { - size_t rlen = fread(buffer, 1, _SEND_FILE_STEP_, in_file); - if (rlen <= 0) { - return writeLen; - } else if (rlen < _SEND_FILE_STEP_) { - fwrite(buffer, 1, rlen, out_file); - return (int64_t)(writeLen + rlen); - } else { - fwrite(buffer, 1, _SEND_FILE_STEP_, in_file); - writeLen += _SEND_FILE_STEP_; - } - } - - int64_t remain = count - writeLen; - if (remain > 0) { - size_t rlen = fread(buffer, 1, (size_t)remain, in_file); - if (rlen <= 0) { - return writeLen; - } else { - fwrite(buffer, 1, (size_t)remain, out_file); - writeLen += remain; - } - } - - return writeLen; -} - -int64_t taosSendFile(SOCKET dfd, int32_t sfd, int64_t *offset, int64_t count) { - if (offset != NULL) lseek(sfd, (int32_t)(*offset), 0); - - int64_t writeLen = 0; - uint8_t buffer[_SEND_FILE_STEP_] = {0}; - - for (int64_t len = 0; len < (count - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) { - int32_t rlen = (int32_t)read(sfd, buffer, _SEND_FILE_STEP_); - if (rlen <= 0) { - return writeLen; - } else if (rlen < _SEND_FILE_STEP_) { - taosWriteSocket(dfd, buffer, rlen); - return (int64_t)(writeLen + rlen); - } else { - taosWriteSocket(dfd, buffer, _SEND_FILE_STEP_); - writeLen += _SEND_FILE_STEP_; - } - } - - int64_t remain = count - writeLen; - if (remain > 0) { - int32_t rlen = read(sfd, buffer, (int32_t)remain); - if (rlen <= 0) { - return writeLen; - } else { - taosWriteSocket(sfd, buffer, (int32_t)remain); - writeLen += remain; - } - } - - return writeLen; -} - -int32_t taosFtruncate(int32_t fd, int64_t l_size) { - if (fd < 0) { - errno = EBADF; - uError("%s\n", "fd arg was negative"); - return -1; - } - - HANDLE h = (HANDLE)_get_osfhandle(fd); - - LARGE_INTEGER li_0; - li_0.QuadPart = (int64_t)0; - BOOL cur = SetFilePointerEx(h, li_0, NULL, FILE_CURRENT); - if (!cur) { - uError("SetFilePointerEx Error getting current position in file.\n"); - return -1; - } - - LARGE_INTEGER li_size; - li_size.QuadPart = l_size; - BOOL cur2 = SetFilePointerEx(h, li_size, NULL, FILE_BEGIN); - if (cur2 == 0) { - int error = GetLastError(); - uError("SetFilePointerEx GetLastError is: %d\n", error); - switch (error) { - case ERROR_INVALID_HANDLE: - errno = EBADF; - break; - default: - errno = EIO; - break; - } - return -1; - } - - if (!SetEndOfFile(h)) { - int error = GetLastError(); - uError("SetEndOfFile GetLastError is:%d", error); - switch (error) { - case ERROR_INVALID_HANDLE: - errno = EBADF; - break; - default: - errno = EIO; - break; - } - return -1; - } - - return 0; -} - -int fsync(int filedes) { - if (filedes < 0) { - errno = EBADF; - uError("%s\n", "fd arg was negative"); - return -1; - } - - HANDLE h = (HANDLE)_get_osfhandle(filedes); - - return FlushFileBuffers(h); -} - -int32_t taosRename(char* oldName, char *newName) { - int32_t code = MoveFileEx(oldName, newName, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED); - if (code < 0) { - uError("failed to rename file %s to %s, reason:%s", oldName, newName, strerror(errno)); - } else { - uTrace("successfully to rename file %s to %s", oldName, newName); - } - - return code; -} \ No newline at end of file diff --git a/src/os/src/windows/wGetline.c b/src/os/src/windows/wGetline.c index 3e8701e19b..553aecaf0a 100644 --- a/src/os/src/windows/wGetline.c +++ b/src/os/src/windows/wGetline.c @@ -22,6 +22,7 @@ General Public License for more details. */ #include #include #include +#include #if STDC_HEADERS #include @@ -40,10 +41,10 @@ null terminator), or -1 on error or EOF. On a -1 return, the caller should check feof(), if not then errno has been set to indicate the error. */ -int getstr(char **lineptr, size_t *n, FILE *stream, char terminator, int offset) { - int nchars_avail; /* Allocated but unused chars in *LINEPTR. */ - char *read_pos; /* Where we're reading into *LINEPTR. */ - int ret; +int32_t getstr(char **lineptr, size_t *n, FILE *stream, char terminator, int32_t offset) { + int32_t nchars_avail; /* Allocated but unused chars in *LINEPTR. */ + char * read_pos; /* Where we're reading into *LINEPTR. */ + int32_t ret; if (!lineptr || !n || !stream) { errno = EINVAL; @@ -59,12 +60,12 @@ int getstr(char **lineptr, size_t *n, FILE *stream, char terminator, int offset) } } - nchars_avail = (int)(*n - offset); + nchars_avail = (int32_t)(*n - offset); read_pos = *lineptr + offset; for (;;) { - int save_errno; - register int c = getc(stream); + int32_t save_errno; + register int32_t c = getc(stream); save_errno = errno; @@ -79,7 +80,7 @@ int getstr(char **lineptr, size_t *n, FILE *stream, char terminator, int offset) else *n += MIN_CHUNK; - nchars_avail = (int)(*n + *lineptr - read_pos); + nchars_avail = (int32_t)(*n + *lineptr - read_pos); *lineptr = realloc(*lineptr, *n); if (!*lineptr) { errno = ENOMEM; @@ -115,10 +116,8 @@ int getstr(char **lineptr, size_t *n, FILE *stream, char terminator, int offset) /* Done - NUL terminate and return the number of chars read. */ *read_pos = '\0'; - ret = (int)(read_pos - (*lineptr + offset)); + ret = (int32_t)(read_pos - (*lineptr + offset)); return ret; } -int taosGetlineImp(char **lineptr, size_t *n, FILE *stream) { - return getstr(lineptr, n, stream, '\n', 0); -} \ No newline at end of file +int32_t tgetline(char **lineptr, size_t *n, FILE *stream) { return getstr(lineptr, n, stream, '\n', 0); } \ No newline at end of file diff --git a/src/os/src/windows/wGodll.c b/src/os/src/windows/wGodll.c deleted file mode 100644 index b270dab2f4..0000000000 --- a/src/os/src/windows/wGodll.c +++ /dev/null @@ -1,33 +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 . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "taosdef.h" -#include "tglobal.h" -#include "ttimer.h" -#include "tulog.h" -#include "tutil.h" - -#ifdef _TD_GO_DLL_ -int64_t tsosStr2int64(char *str) { - char *endptr = NULL; - return strtoll(str, &endptr, 10); -} - -uint64_t htonll(uint64_t val) { - return (((uint64_t) htonl(val)) << 32) + htonl(val >> 32); -} -#endif diff --git a/src/os/src/windows/wSocket.c b/src/os/src/windows/wSocket.c index 4e6ee15e77..ad0d87418d 100644 --- a/src/os/src/windows/wSocket.c +++ b/src/os/src/windows/wSocket.c @@ -70,7 +70,8 @@ int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *op return setsockopt(socketfd, level, optname, optval, optlen); } -#ifdef TAOS_OS_FUNC_SOCKET_INET +#ifdef _MSC_VER +//#if _MSC_VER >= 1900 uint32_t taosInetAddr(char *ipAddr) { uint32_t value; @@ -88,4 +89,11 @@ const char *taosInetNtoa(struct in_addr ipInt) { return inet_ntop(AF_INET, &ipInt, tmpDstStr, INET6_ADDRSTRLEN); } -#endif \ No newline at end of file +//#endif +#endif + +#if defined(_TD_GO_DLL_) + +uint64_t htonll(uint64_t val) { return (((uint64_t)htonl(val)) << 32) + htonl(val >> 32); } + +#endif diff --git a/src/os/src/windows/wString.c b/src/os/src/windows/wString.c index 67237e655c..96a604ae6e 100644 --- a/src/os/src/windows/wString.c +++ b/src/os/src/windows/wString.c @@ -33,9 +33,9 @@ * If *stringp is NULL, strsep returns NULL. */ char *strsep(char **stringp, const char *delim) { - char *s; + char * s; const char *spanp; - int c, sc; + int32_t c, sc; char *tok; if ((s = *stringp) == NULL) return (NULL); @@ -75,13 +75,13 @@ char *getpass(const char *prefix) { return passwd; } -int twcslen(const wchar_t *wcs) { - int *wstr = (int *)wcs; +int32_t twcslen(const wchar_t *wcs) { + int32_t *wstr = (int32_t *)wcs; if (NULL == wstr) { return 0; } - int n = 0; + int32_t n = 0; while (1) { if (0 == *wstr++) { break; @@ -92,8 +92,8 @@ int twcslen(const wchar_t *wcs) { return n; } -int tasoUcs4Compare(void *f1_ucs4, void *f2_ucs4, int bytes) { - for (int i = 0; i < bytes; ++i) { +int32_t tasoUcs4Compare(void *f1_ucs4, void *f2_ucs4, int32_t bytes) { + for (int32_t i = 0; i < bytes; ++i) { int32_t f1 = *(int32_t *)((char *)f1_ucs4 + i * 4); int32_t f2 = *(int32_t *)((char *)f2_ucs4 + i * 4); @@ -127,7 +127,6 @@ int tasoUcs4Compare(void *f1_ucs4, void *f2_ucs4, int bytes) { #endif } - /* Copy memory to memory until the specified number of bytes has been copied, return pointer to following byte. Overlap is NOT handled correctly. */ diff --git a/src/os/src/windows/wTimer.c b/src/os/src/windows/wTimer.c index 32e04746f1..c5984f915a 100644 --- a/src/os/src/windows/wTimer.c +++ b/src/os/src/windows/wTimer.c @@ -43,7 +43,3 @@ int taosInitTimer(win_timer_f callback, int ms) { void taosUninitTimer() { timeKillEvent(timerId); } - -void taosMsleep(int mseconds) { - Sleep(mseconds); -} diff --git a/src/os/tests/CMakeLists.txt b/src/os/tests/CMakeLists.txt index 1a18a72b40..b87e3d2a62 100644 --- a/src/os/tests/CMakeLists.txt +++ b/src/os/tests/CMakeLists.txt @@ -11,5 +11,5 @@ IF (HEADER_GTEST_INCLUDE_DIR AND LIB_GTEST_STATIC_DIR) AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) ADD_EXECUTABLE(osTest ${SOURCE_LIST}) - TARGET_LINK_LIBRARIES(osTest taos osdetail tutil common gtest pthread) + TARGET_LINK_LIBRARIES(osTest taos os tutil common gtest pthread) ENDIF() \ No newline at end of file diff --git a/src/os/tests/test.cpp b/src/os/tests/test.cpp index 600e5d71a7..12e9546ff1 100644 --- a/src/os/tests/test.cpp +++ b/src/os/tests/test.cpp @@ -18,7 +18,7 @@ TEST(testCase, parse_time) { deltaToUtcInitOnce(); // window: 1500000001000, 1500002000000 - // pQuery->interval: interval: 86400000, sliding:3600000 + // pQueryAttr->interval: interval: 86400000, sliding:3600000 int64_t key = 1500000001000; SInterval interval = {0}; interval.interval = 86400000; diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index c59067c4b3..bdccd4eb3c 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -122,7 +122,7 @@ enum { #define QUERY_IS_FREE_RESOURCE(type) (((type)&TSDB_QUERY_TYPE_FREE_RESOURCE) != 0) typedef struct SArithmeticSupport { - SExprInfo *pArithExpr; + SExprInfo *pExprInfo; int32_t numOfCols; SColumnInfo *colList; void *exprList; // client side used @@ -210,9 +210,6 @@ typedef struct SAggFunctionInfo { void (*xFunction)(SQLFunctionCtx *pCtx); // blocks version function void (*xFunctionF)(SQLFunctionCtx *pCtx, int32_t position); // single-row function version, todo merge with blockwise function - // some sql function require scan data twice or more, e.g.,stddev, percentile - void (*xNextStep)(SQLFunctionCtx *pCtx); - // finalizer must be called after all xFunction has been executed to generated final result. void (*xFinalize)(SQLFunctionCtx *pCtx); void (*mergeFunc)(SQLFunctionCtx *pCtx); diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index 31ac70d6cd..b9361650e9 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -86,7 +86,7 @@ typedef struct SResultRow { bool closed; // this result status: closed or opened uint32_t numOfRows; // number of rows of current time window SResultRowCellInfo* pCellInfo; // For each result column, there is a resultInfo - STimeWindow win; + STimeWindow win; char* key; // start key of current result row } SResultRow; @@ -178,8 +178,11 @@ typedef struct SSDataBlock { SDataBlockInfo info; } SSDataBlock; -typedef struct SQuery { +// The basic query information extracted from the SQueryInfo tree to support the +// execution of query in a data node. +typedef struct SQueryAttr { SLimitVal limit; + SLimitVal slimit; bool stableQuery; // super table query or not bool topBotQuery; // TODO used bitwise flag @@ -188,6 +191,11 @@ typedef struct SQuery { bool timeWindowInterpo;// if the time window start/end required interpolation bool queryBlockDist; // if query data block distribution bool stabledev; // super table stddev query + bool tsCompQuery; // is tscomp query + bool simpleAgg; + bool pointInterpQuery; // point interpolation query + bool needReverseScan; // need reverse scan + bool distinctTag; // distinct tag query int32_t interBufSize; // intermediate buffer sizse int32_t havingNum; // having expr number @@ -202,39 +210,41 @@ typedef struct SQuery { int16_t precision; int16_t numOfOutput; int16_t fillType; - int16_t checkResultBuf; // check if the buffer is full during scan each block int32_t srcRowSize; // todo extract struct int32_t resultRowSize; int32_t intermediateResultRowSize; // intermediate result row size, in case of top-k query. - int32_t maxSrcColumnSize; + int32_t maxTableColumnWidth; int32_t tagLen; // tag value length of current query SSqlGroupbyExpr* pGroupbyExpr; + SExprInfo* pExpr1; SExprInfo* pExpr2; int32_t numOfExpr2; - SColumnInfo* colList; + SExprInfo* pExpr3; + int32_t numOfExpr3; + + SColumnInfo* tableCols; SColumnInfo* tagColList; int32_t numOfFilterCols; int64_t* fillVal; SOrderedPrjQueryInfo prjInfo; // limit value for each vgroup, only available in global order projection query. SSingleColumnFilterInfo* pFilterInfo; - STableQueryInfo* current; void* tsdb; SMemRef memRef; STableGroupInfo tableGroupInfo; // table list SArray int32_t vgId; -} SQuery; +} SQueryAttr; -typedef SSDataBlock* (*__operator_fn_t)(void* param); +typedef SSDataBlock* (*__operator_fn_t)(void* param, bool* newgroup); typedef void (*__optr_cleanup_fn_t)(void* param, int32_t num); struct SOperatorInfo; typedef struct SQueryRuntimeEnv { jmp_buf env; - SQuery* pQuery; + SQueryAttr* pQueryAttr; uint32_t status; // query status void* qinfo; uint8_t scanFlag; // denotes reversed scan of data or not @@ -257,10 +267,10 @@ typedef struct SQueryRuntimeEnv { SSDataBlock *outputBuf; STableGroupInfo tableqinfoGroupInfo; // this is a group array list, including SArray structure struct SOperatorInfo *proot; - struct SOperatorInfo *pTableScanner; // table scan operator SGroupResInfo groupResInfo; int64_t currentOffset; // dynamic offset value + STableQueryInfo *current; SRspResultInfo resultInfo; SHashObj *pTableRetrieveTsMap; } SQueryRuntimeEnv; @@ -281,13 +291,17 @@ enum OPERATOR_TYPE_E { OP_Arithmetic = 7, OP_Groupby = 8, OP_Limit = 9, - OP_Offset = 10, + OP_SLimit = 10, OP_TimeWindow = 11, OP_SessionWindow = 12, OP_Fill = 13, OP_MultiTableAggregate = 14, OP_MultiTableTimeInterval = 15, - OP_Having = 16, + OP_DummyInput = 16, //TODO remove it after fully refactor. + OP_MultiwayMergeSort = 17, // multi-way data merge into one input stream. + OP_GlobalAggregate = 18, // global merge for the multi-way data sources. + OP_Filter = 19, + OP_Distinct = 20, }; typedef struct SOperatorInfo { @@ -310,6 +324,12 @@ enum { QUERY_RESULT_READY = 2, }; +typedef struct { + int32_t numOfTags; + int32_t numOfCols; + SColumnInfo *colList; +} SQueriedTableInfo; + typedef struct SQInfo { void* signature; uint64_t qId; @@ -317,7 +337,7 @@ typedef struct SQInfo { int64_t owner; // if it is in execution SQueryRuntimeEnv runtimeEnv; - SQuery query; + SQueryAttr query; void* pBuf; // allocated buffer for STableQueryInfo, sizeof(STableQueryInfo)*numOfTables; pthread_mutex_t lock; // used to synchronize the rsp/query threads @@ -335,14 +355,16 @@ typedef struct SQueryParam { char *tbnameCond; char *prevResult; SArray *pTableIdList; - SSqlFuncMsg **pExprMsg; - SSqlFuncMsg **pSecExprMsg; + SSqlExpr **pExpr; + SSqlExpr **pSecExpr; SExprInfo *pExprs; SExprInfo *pSecExprs; SColIndex *pGroupColIndex; SColumnInfo *pTagColumnInfo; SSqlGroupbyExpr *pGroupbyExpr; + int32_t tableScanOperator; + SArray *pOperator; } SQueryParam; typedef struct STableScanInfo { @@ -394,26 +416,39 @@ typedef struct SArithOperatorInfo { SOptrBasicInfo binfo; int32_t bufCapacity; uint32_t seed; + + SSDataBlock *existDataBlock; } SArithOperatorInfo; typedef struct SLimitOperatorInfo { - int64_t limit; - int64_t total; + int64_t limit; + int64_t total; } SLimitOperatorInfo; -typedef struct SOffsetOperatorInfo { - int64_t offset; -} SOffsetOperatorInfo; +typedef struct SSLimitOperatorInfo { + int64_t groupTotal; + int64_t currentGroupOffset; -typedef struct SHavingOperatorInfo { - SArray* fp; -} SHavingOperatorInfo; + int64_t rowsTotal; + int64_t currentOffset; + SLimitVal limit; + SLimitVal slimit; + char **prevRow; + SArray *orderColumnList; +} SSLimitOperatorInfo; + +typedef struct SFilterOperatorInfo { + SSingleColumnFilterInfo *pFilterInfo; + int32_t numOfFilterCols; +} SFilterOperatorInfo; typedef struct SFillOperatorInfo { SFillInfo *pFillInfo; SSDataBlock *pRes; int64_t totalInputRows; + + SSDataBlock *existNewGroupBlock; } SFillOperatorInfo; typedef struct SGroupbyOperatorInfo { @@ -430,25 +465,95 @@ typedef struct SSWindowOperatorInfo { int32_t start; // start row index } SSWindowOperatorInfo; +typedef struct SDistinctOperatorInfo { + SHashObj *pSet; + SSDataBlock *pRes; + bool recordNullVal; //has already record the null value, no need to try again + int64_t threshold; + int64_t outputCapacity; +} SDistinctOperatorInfo; + +struct SLocalMerger; + +typedef struct SMultiwayMergeInfo { + struct SLocalMerger *pMerge; + SOptrBasicInfo binfo; + int32_t bufCapacity; + int64_t seed; + char **prevRow; + SArray *orderColumnList; + int32_t resultRowFactor; + + bool hasGroupColData; + char **currentGroupColData; + SArray *groupColumnList; + bool hasDataBlockForNewGroup; + SSDataBlock *pExistBlock; + + bool hasPrev; + bool groupMix; +} SMultiwayMergeInfo; + +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); + +SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream); +SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); +SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, + int32_t numOfRows, void* merger, bool groupMix); +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); + +SSDataBlock* doGlobalAggregate(void* param, bool* newgroup); +SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup); +SSDataBlock* doSLimit(void* param, bool* newgroup); + +SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows); +void* destroyOutputBuf(SSDataBlock* pBlock); + +void setInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order); +int32_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput); +void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset); +void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOfInputRows); + void freeParam(SQueryParam *param); int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param); -int32_t createQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, SSqlFuncMsg **pExprMsg, - SColumnInfo* pTagCols); +int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo, + SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg); + int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, - SSqlFuncMsg **pExprMsg, SExprInfo *prevExpr); + SSqlExpr **pExpr, SExprInfo *prevExpr); SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code); SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs, - SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, bool stableQuery, char* sql, uint64_t *qId); -int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *pQInfo, SQueryParam* param, bool isSTable); + 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); + void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters); +STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf); +int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, void *pQueryMsg); + bool isQueryKilled(SQInfo *pQInfo); int32_t checkForQueryBuf(size_t numOfTables); bool doBuildResCheck(SQInfo* pQInfo); void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status); -bool onlyQueryTags(SQuery* pQuery); +bool onlyQueryTags(SQueryAttr* pQueryAttr); bool isValidQInfo(void *param); int32_t doDumpQueryResult(SQInfo *pQInfo, char *data); @@ -457,6 +562,7 @@ size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows); void setQueryKilled(SQInfo *pQInfo); void queryCostStatis(SQInfo *pQInfo); void freeQInfo(SQInfo *pQInfo); +void freeQueryAttr(SQueryAttr *pQuery); int32_t getMaximumIdleDurationSec(); diff --git a/src/query/inc/qExtbuffer.h b/src/query/inc/qExtbuffer.h index df6e64ddd8..b851fbb3e0 100644 --- a/src/query/inc/qExtbuffer.h +++ b/src/query/inc/qExtbuffer.h @@ -237,6 +237,11 @@ int32_t compare_a(tOrderDescriptor *, int32_t numOfRow1, int32_t s1, char *data1 int32_t compare_d(tOrderDescriptor *, int32_t numOfRow1, int32_t s1, char *data1, int32_t numOfRow2, int32_t s2, char *data2); +struct SSDataBlock; +int32_t compare_aRv(struct SSDataBlock* pBlock, SArray* colIndex, int32_t numOfCols, int32_t rowIndex, char** buffer, int32_t order); + +int32_t columnValueAscendingComparator(char *f1, char *f2, int32_t type, int32_t bytes); + #ifdef __cplusplus } #endif diff --git a/src/os/src/darwin/darwinString.c b/src/query/inc/qPlan.h similarity index 70% rename from src/os/src/darwin/darwinString.c rename to src/query/inc/qPlan.h index 3042e78666..8f35565e4b 100644 --- a/src/os/src/darwin/darwinString.c +++ b/src/query/inc/qPlan.h @@ -13,10 +13,12 @@ * along with this program. If not, see . */ -#define _DEFAULT_SOURCE -#include "os.h" +#ifndef TDENGINE_QPLAN_H +#define TDENGINE_QPLAN_H -int64_t tsosStr2int64(char *str) { - char *endptr = NULL; - return strtoll(str, &endptr, 10); -} +//TODO refactor +SArray* createTableScanPlan(SQueryAttr* pQueryAttr); +SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr); +SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr); + +#endif // TDENGINE_QPLAN_H diff --git a/src/query/inc/qSqlparser.h b/src/query/inc/qSqlparser.h index 0a0587f701..85cba06b3e 100644 --- a/src/query/inc/qSqlparser.h +++ b/src/query/inc/qSqlparser.h @@ -40,8 +40,8 @@ enum SQL_NODE_TYPE { }; enum SQL_NODE_FROM_TYPE { - SQL_NODE_FROM_SUBQUERY = 1, - SQL_NODE_FROM_NAMELIST = 2, + SQL_NODE_FROM_SUBQUERY = 1, + SQL_NODE_FROM_TABLELIST = 2, }; enum SQL_EXPR_FLAG { @@ -89,11 +89,11 @@ typedef struct SSessionWindowVal { SStrToken gap; } SSessionWindowVal; -struct SFromInfo; +struct SRelationInfo; -typedef struct SQuerySqlNode { - struct SArray *pSelectList; // select clause - struct SFromInfo *from; // from clause SArray +typedef struct SSqlNode { + struct SArray *pSelNodeList; // select clause + struct SRelationInfo *from; // from clause SArray struct tSqlExpr *pWhere; // where clause [optional] SArray *pGroupby; // groupby clause, only for tags[optional], SArray SArray *pSortOrder; // orderby [optional], SArray @@ -105,25 +105,17 @@ typedef struct SQuerySqlNode { SLimitVal slimit; // group limit offset [optional] SStrToken sqlstr; // sql string in select clause struct tSqlExpr *pHaving; // having clause [optional] -} SQuerySqlNode; +} SSqlNode; typedef struct STableNamePair { SStrToken name; SStrToken aliasName; } STableNamePair; -typedef struct SSubclauseInfo { // "UNION" multiple select sub-clause - SQuerySqlNode **pClause; - int32_t numOfClause; -} SSubclauseInfo; - -typedef struct SFromInfo { - int32_t type; // nested query|table name list - union { - SSubclauseInfo *pNode; - SArray *tableList; // SArray - }; -} SFromInfo; +typedef struct SRelationInfo { + int32_t type; // nested query|table name list + SArray *list; // SArray|SArray +} SRelationInfo; typedef struct SCreatedTableInfo { SStrToken name; // table name token @@ -146,7 +138,7 @@ typedef struct SCreateTableSql { } colInfo; SArray *childTableInfo; // SArray - SQuerySqlNode *pSelect; + SSqlNode *pSelect; } SCreateTableSql; typedef struct SAlterTableInfo { @@ -223,7 +215,7 @@ typedef struct SMiscInfo { typedef struct SSqlInfo { int32_t type; bool valid; - SSubclauseInfo subclauseInfo; + SArray *list; // todo refactor char msg[256]; union { SCreateTableSql *pCreateTableInfo; @@ -261,14 +253,9 @@ SArray *tVariantListAppend(SArray *pList, tVariant *pVar, uint8_t sortOrder); SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int32_t index); SArray *tVariantListAppendToken(SArray *pList, SStrToken *pAliasToken, uint8_t sortOrder); -tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType); - -int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right); - -tSqlExpr *tSqlExprClone(tSqlExpr *pSrc); -SFromInfo *setTableNameList(SFromInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias); -SFromInfo *setSubquery(SFromInfo* pFromInfo, SQuerySqlNode *pSqlNode); -void *destroyFromInfo(SFromInfo* pFromInfo); +SRelationInfo *setTableNameList(SRelationInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias); +SRelationInfo *setSubquery(SRelationInfo* pFromInfo, SArray* pSqlNode); +void *destroyRelationInfo(SRelationInfo* pFromInfo); // sql expr leaf node tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType); @@ -283,23 +270,23 @@ void tSqlExprDestroy(tSqlExpr *pExpr); SArray *tSqlExprListAppend(SArray *pList, tSqlExpr *pNode, SStrToken *pDistinct, SStrToken *pToken); void tSqlExprListDestroy(SArray *pList); -SQuerySqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelectList, SFromInfo *pFrom, tSqlExpr *pWhere, +SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere, SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving); +int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right); -SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SQuerySqlNode *pSelect, int32_t type); +SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SSqlNode *pSelect, int32_t type); SAlterTableInfo *tSetAlterTableInfo(SStrToken *pTableName, SArray *pCols, SArray *pVals, int32_t type, int16_t tableTable); SCreatedTableInfo createNewChildTableInfo(SStrToken *pTableName, SArray *pTagNames, SArray *pTagVals, SStrToken *pToken, SStrToken* igExists); -void destroyAllSelectClause(SSubclauseInfo *pSql); -void destroyQuerySqlNode(SQuerySqlNode *pSql); +void destroyAllSqlNode(SArray *pSqlNode); +void destroySqlNode(SSqlNode *pSql); void freeCreateTableInfo(void* p); -SSqlInfo *setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SStrToken *pTableName, int32_t type); -SSubclauseInfo *setSubclause(SSubclauseInfo *pClause, void *pSqlExprInfo); - -SSubclauseInfo *appendSelectClause(SSubclauseInfo *pInfo, void *pSubclause); +SSqlInfo *setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SStrToken *pTableName, int32_t type); +SArray *setSubclause(SArray *pList, void *pSqlNode); +SArray *appendSelectClause(SArray *pList, void *pSubclause); void setCreatedTableName(SSqlInfo *pInfo, SStrToken *pTableNameToken, SStrToken *pIfNotExists); diff --git a/src/query/inc/qUtil.h b/src/query/inc/qUtil.h index cb8c9679ec..3ca6d96746 100644 --- a/src/query/inc/qUtil.h +++ b/src/query/inc/qUtil.h @@ -28,9 +28,9 @@ #define GET_QID(_r) (((SQInfo*)((_r)->qinfo))->qId) #define curTimeWindowIndex(_winres) ((_winres)->curIndex) -#define GET_ROW_PARAM_FOR_MULTIOUTPUT(_q, tbq, sq) (((tbq) && (!(sq)))? (_q)->pExpr1[1].base.arg->argValue.i64:1) +#define GET_ROW_PARAM_FOR_MULTIOUTPUT(_q, tbq, sq) (((tbq) && (!(sq)))? (_q)->pExpr1[1].base.param[0].i64:1) -int32_t getOutputInterResultBufSize(SQuery* pQuery); +int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr); size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv); int32_t initResultRowInfo(SResultRowInfo* pResultRowInfo, int32_t size, int16_t type); @@ -52,20 +52,11 @@ static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int return pResultRowInfo->pResult[slot]; } -static FORCE_INLINE char* getPosInResultPage(SQueryRuntimeEnv* pRuntimeEnv, tFilePage* page, int32_t rowOffset, - int16_t offset, int32_t size) { - assert(rowOffset >= 0 && pRuntimeEnv != NULL); +static FORCE_INLINE char *getPosInResultPage(SQueryAttr *pQueryAttr, tFilePage* page, int32_t rowOffset, int16_t offset) { + assert(rowOffset >= 0 && pQueryAttr != NULL); - SQuery* pQuery = pRuntimeEnv->pQuery; - int64_t pageSize = pRuntimeEnv->pResultBuf->pageSize; - - int32_t numOfRows = (int32_t)GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pQuery->topBotQuery, pQuery->stableQuery); - - // buffer overflow check - int64_t bufEnd = (rowOffset + offset * numOfRows + size); - assert(page->num <= pageSize && bufEnd <= page->num); - - return ((char*)page->data) + rowOffset + offset * numOfRows; + int32_t numOfRows = (int32_t)GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery); + return ((char *)page->data) + rowOffset + offset * numOfRows; } bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type); diff --git a/src/query/inc/sql.y b/src/query/inc/sql.y index 5a42b3a631..fd922240c2 100644 --- a/src/query/inc/sql.y +++ b/src/query/inc/sql.y @@ -450,16 +450,16 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). { } //////////////////////// The SELECT statement ///////////////////////////////// -%type select {SQuerySqlNode*} -%destructor select {destroyQuerySqlNode($$);} +%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) ::= LP select(B) RP. {A = B;} -%type union {SSubclauseInfo*} -%destructor union {destroyAllSelectClause($$);} +%type union {SArray*} +%destructor union {destroyAllSqlNode($$);} union(Y) ::= select(X). { Y = setSubclause(NULL, X); } union(Y) ::= union(Z) UNION ALL select(X). { Y = appendSelectClause(Z, X); } @@ -505,35 +505,30 @@ distinct(X) ::= DISTINCT(Y). { X = Y; } distinct(X) ::= . { X.n = 0;} // A complete FROM clause. -%type from {SFromInfo*} +%type from {SRelationInfo*} +%destructor from {destroyRelationInfo($$);} from(A) ::= FROM tablelist(X). {A = X;} -from(A) ::= FROM LP union(Y) RP. {A = Y;} +from(A) ::= FROM LP union(Y) RP. {A = setSubquery(NULL, Y);} -%type tablelist {SArray*} +%type tablelist {SRelationInfo*} +%destructor tablelist {destroyRelationInfo($$);} tablelist(A) ::= ids(X) cpxName(Y). { - toTSDBType(X.type); X.n += Y.n; A = setTableNameList(NULL, &X, NULL); } tablelist(A) ::= ids(X) cpxName(Y) ids(Z). { - toTSDBType(X.type); - toTSDBType(Z.type); X.n += Y.n; A = setTableNameList(NULL, &X, &Z); } tablelist(A) ::= tablelist(Y) COMMA ids(X) cpxName(Z). { - toTSDBType(X.type); X.n += Z.n; A = setTableNameList(Y, &X, NULL); } tablelist(A) ::= tablelist(Y) COMMA ids(X) cpxName(Z) ids(F). { - toTSDBType(X.type); - toTSDBType(F.type); X.n += Z.n; - A = setTableNameList(Y, &X, &F); } diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index f312b4ab64..3b1ffa46d9 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -375,12 +375,6 @@ int32_t isValidFunction(const char* name, int32_t len) { return -1; } -// set the query flag to denote that query is completed -static void no_next_step(SQLFunctionCtx *pCtx) { - SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); - pResInfo->complete = true; -} - static bool function_setup(SQLFunctionCtx *pCtx) { SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); if (pResInfo->initialized) { @@ -1540,7 +1534,7 @@ static void stddev_function_f(SQLFunctionCtx *pCtx, int32_t index) { } } -static void stddev_next_step(SQLFunctionCtx *pCtx) { +static UNUSED_FUNC void stddev_next_step(SQLFunctionCtx *pCtx) { /* * the stddevInfo and the average info struct share the same buffer area * And the position of each element in their struct is exactly the same matched @@ -2921,7 +2915,7 @@ static void percentile_finalizer(SQLFunctionCtx *pCtx) { doFinalizer(pCtx); } -static void percentile_next_step(SQLFunctionCtx *pCtx) { +static UNUSED_FUNC void percentile_next_step(SQLFunctionCtx *pCtx) { SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); @@ -3026,7 +3020,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) { pInput->pHisto = (SHistogramInfo*) ((char *)pInput + sizeof(SAPercentileInfo)); pInput->pHisto->elems = (SHistBin*) ((char *)pInput->pHisto + sizeof(SHistogramInfo)); - + if (pInput->pHisto->numOfElems <= 0) { return; } @@ -3045,7 +3039,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) { pHisto->elems = (SHistBin*) ((char *)pHisto + sizeof(SHistogramInfo)); tHistogramDestroy(&pRes); } - + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); pResInfo->hasResult = DATA_SET_FLAG; SET_VAL(pCtx, 1, 1); @@ -3056,7 +3050,7 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) { SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); SAPercentileInfo *pOutput = GET_ROWCELL_INTERBUF(pResInfo); - + if (pCtx->currentStage == MERGE_STAGE) { if (pResInfo->hasResult == DATA_SET_FLAG) { // check for null assert(pOutput->pHisto->numOfElems > 0); @@ -3332,8 +3326,6 @@ static void col_project_function_f(SQLFunctionCtx *pCtx, int32_t index) { INC_INIT_VAL(pCtx, 1); char *pData = GET_INPUT_DATA(pCtx, index); memcpy(pCtx->pOutput, pData, pCtx->inputBytes); - - pCtx->pOutput += pCtx->inputBytes; } /** @@ -3371,9 +3363,15 @@ static void tag_project_function_f(SQLFunctionCtx *pCtx, int32_t index) { * @param pCtx * @return */ +static void copy_function(SQLFunctionCtx *pCtx); + static void tag_function(SQLFunctionCtx *pCtx) { SET_VAL(pCtx, 1, 1); - tVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->outputType, true); + if (pCtx->currentStage == MERGE_STAGE) { + copy_function(pCtx); + } else { + tVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->outputType, true); + } } static void tag_function_f(SQLFunctionCtx *pCtx, int32_t index) { @@ -3710,7 +3708,7 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) { GET_RES_INFO(pCtx)->numOfRes += pCtx->size; SArithmeticSupport *sas = (SArithmeticSupport *)pCtx->param[1].pz; - arithmeticTreeTraverse(sas->pArithExpr->pExpr, pCtx->size, pCtx->pOutput, sas, pCtx->order, getArithColumnData); + arithmeticTreeTraverse(sas->pExprInfo->pExpr, pCtx->size, pCtx->pOutput, sas, pCtx->order, getArithColumnData); } static void arithmetic_function_f(SQLFunctionCtx *pCtx, int32_t index) { @@ -3718,7 +3716,7 @@ static void arithmetic_function_f(SQLFunctionCtx *pCtx, int32_t index) { SArithmeticSupport *sas = (SArithmeticSupport *)pCtx->param[1].pz; sas->offset = index; - arithmeticTreeTraverse(sas->pArithExpr->pExpr, 1, pCtx->pOutput, sas, pCtx->order, getArithColumnData); + arithmeticTreeTraverse(sas->pExprInfo->pExpr, 1, pCtx->pOutput, sas, pCtx->order, getArithColumnData); pCtx->pOutput += pCtx->outputBytes; } @@ -4907,7 +4905,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, count_function, count_function_f, - no_next_step, doFinalizer, count_func_merge, countRequired, @@ -4921,7 +4918,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, sum_function, sum_function_f, - no_next_step, function_finalizer, sum_func_merge, statisRequired, @@ -4935,7 +4931,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, avg_function, avg_function_f, - no_next_step, avg_finalizer, avg_func_merge, statisRequired, @@ -4949,7 +4944,6 @@ SAggFunctionInfo aAggs[] = {{ min_func_setup, min_function, min_function_f, - no_next_step, function_finalizer, min_func_merge, statisRequired, @@ -4963,7 +4957,6 @@ SAggFunctionInfo aAggs[] = {{ max_func_setup, max_function, max_function_f, - no_next_step, function_finalizer, max_func_merge, statisRequired, @@ -4977,7 +4970,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, stddev_function, stddev_function_f, - stddev_next_step, stddev_finalizer, noop1, dataBlockRequired, @@ -4991,7 +4983,6 @@ SAggFunctionInfo aAggs[] = {{ percentile_function_setup, percentile_function, percentile_function_f, - percentile_next_step, percentile_finalizer, noop1, dataBlockRequired, @@ -5005,7 +4996,6 @@ SAggFunctionInfo aAggs[] = {{ apercentile_function_setup, apercentile_function, apercentile_function_f, - no_next_step, apercentile_finalizer, apercentile_func_merge, dataBlockRequired, @@ -5019,7 +5009,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, first_function, first_function_f, - no_next_step, function_finalizer, noop1, firstFuncRequired, @@ -5033,7 +5022,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, last_function, last_function_f, - no_next_step, function_finalizer, noop1, lastFuncRequired, @@ -5048,7 +5036,6 @@ SAggFunctionInfo aAggs[] = {{ first_last_function_setup, last_row_function, noop2, - no_next_step, last_row_finalizer, last_dist_func_merge, dataBlockRequired, @@ -5063,7 +5050,6 @@ SAggFunctionInfo aAggs[] = {{ top_bottom_function_setup, top_function, top_function_f, - no_next_step, top_bottom_func_finalizer, top_func_merge, dataBlockRequired, @@ -5078,7 +5064,6 @@ SAggFunctionInfo aAggs[] = {{ top_bottom_function_setup, bottom_function, bottom_function_f, - no_next_step, top_bottom_func_finalizer, bottom_func_merge, dataBlockRequired, @@ -5092,7 +5077,6 @@ SAggFunctionInfo aAggs[] = {{ spread_function_setup, spread_function, spread_function_f, - no_next_step, spread_function_finalizer, spread_func_merge, countRequired, @@ -5106,7 +5090,6 @@ SAggFunctionInfo aAggs[] = {{ twa_function_setup, twa_function, twa_function_f, - no_next_step, twa_function_finalizer, twa_function_copy, dataBlockRequired, @@ -5120,7 +5103,6 @@ SAggFunctionInfo aAggs[] = {{ leastsquares_function_setup, leastsquares_function, leastsquares_function_f, - no_next_step, leastsquares_finalizer, noop1, dataBlockRequired, @@ -5134,35 +5116,32 @@ SAggFunctionInfo aAggs[] = {{ function_setup, date_col_output_function, date_col_output_function_f, - no_next_step, doFinalizer, copy_function, noDataRequired, }, { // 17 - "ts", + "ts_dummy", TSDB_FUNC_TS_DUMMY, TSDB_FUNC_TS_DUMMY, TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_NEED_TS, function_setup, noop1, noop2, - no_next_step, doFinalizer, copy_function, dataBlockRequired, }, { // 18 - "tag", + "tag_dummy", TSDB_FUNC_TAG_DUMMY, TSDB_FUNC_TAG_DUMMY, TSDB_BASE_FUNC_SO, function_setup, tag_function, noop2, - no_next_step, doFinalizer, copy_function, noDataRequired, @@ -5176,7 +5155,6 @@ SAggFunctionInfo aAggs[] = {{ ts_comp_function_setup, ts_comp_function, ts_comp_function_f, - no_next_step, ts_comp_finalize, copy_function, dataBlockRequired, @@ -5190,7 +5168,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, tag_function, tag_function_f, - no_next_step, doFinalizer, copy_function, noDataRequired, @@ -5204,7 +5181,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, col_project_function, col_project_function_f, - no_next_step, doFinalizer, copy_function, dataBlockRequired, @@ -5218,7 +5194,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, tag_project_function, tag_project_function_f, - no_next_step, doFinalizer, copy_function, noDataRequired, @@ -5232,7 +5207,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, arithmetic_function, arithmetic_function_f, - no_next_step, doFinalizer, copy_function, dataBlockRequired, @@ -5246,7 +5220,6 @@ SAggFunctionInfo aAggs[] = {{ diff_function_setup, diff_function, diff_function_f, - no_next_step, doFinalizer, noop1, dataBlockRequired, @@ -5261,7 +5234,6 @@ SAggFunctionInfo aAggs[] = {{ first_last_function_setup, first_dist_function, first_dist_function_f, - no_next_step, function_finalizer, first_dist_func_merge, firstDistFuncRequired, @@ -5275,7 +5247,6 @@ SAggFunctionInfo aAggs[] = {{ first_last_function_setup, last_dist_function, last_dist_function_f, - no_next_step, function_finalizer, last_dist_func_merge, lastDistFuncRequired, @@ -5289,7 +5260,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, stddev_dst_function, stddev_dst_function_f, - no_next_step, stddev_dst_finalizer, stddev_dst_merge, dataBlockRequired, @@ -5303,7 +5273,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, interp_function, do_sum_f, // todo filter handle - no_next_step, doFinalizer, copy_function, dataBlockRequired, @@ -5317,7 +5286,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, rate_function, rate_function_f, - no_next_step, rate_finalizer, rate_func_copy, dataBlockRequired, @@ -5331,7 +5299,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, irate_function, irate_function_f, - no_next_step, rate_finalizer, rate_func_copy, dataBlockRequired, @@ -5345,7 +5312,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, rate_function, rate_function_f, - no_next_step, sumrate_finalizer, sumrate_func_merge, dataBlockRequired, @@ -5359,7 +5325,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, irate_function, irate_function_f, - no_next_step, sumrate_finalizer, sumrate_func_merge, dataBlockRequired, @@ -5373,7 +5338,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, rate_function, rate_function_f, - no_next_step, sumrate_finalizer, sumrate_func_merge, dataBlockRequired, @@ -5387,7 +5351,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, irate_function, irate_function_f, - no_next_step, sumrate_finalizer, sumrate_func_merge, dataBlockRequired, @@ -5401,7 +5364,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, noop1, noop2, - no_next_step, noop1, noop1, dataBlockRequired, @@ -5415,7 +5377,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, blockInfo_func, noop2, - no_next_step, blockinfo_func_finalizer, block_func_merge, dataBlockRequired, diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 4cf6d6072e..feaa205c3e 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -35,13 +35,6 @@ #define SWITCH_ORDER(n) (((n) = ((n) == TSDB_ORDER_ASC) ? TSDB_ORDER_DESC : TSDB_ORDER_ASC)) -#define CHECK_IF_QUERY_KILLED(_q) \ - do { \ - if (isQueryKilled((_q)->qinfo)) { \ - longjmp((_q)->env, TSDB_CODE_TSC_QUERY_CANCELLED); \ - } \ - } while (0) - #define SDATA_BLOCK_INITIALIZER (SDataBlockInfo) {{0}, 0} #define TIME_WINDOW_COPY(_dst, _src) do {\ @@ -98,28 +91,26 @@ static UNUSED_FUNC void* u_realloc(void* p, size_t __size) { #define GET_NUM_OF_TABLEGROUP(q) taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList) #define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0) - uint64_t queryHandleId = 0; int32_t getMaximumIdleDurationSec() { return tsShellActivityTimer * 2; } - int64_t genQueryId(void) { int64_t uid = 0; int64_t did = tsDnodeId; - + uid = did << 54; - + int64_t pid = ((int64_t)taosGetPId()) & 0x3FF; uid |= pid << 44; - + int64_t ts = taosGetTimestampMs() & 0x1FFFFFFFF; uid |= ts << 11; - + int64_t sid = atomic_add_fetch_64(&queryHandleId, 1) & 0x7FF; uid |= sid; @@ -127,21 +118,19 @@ int64_t genQueryId(void) { return uid; } - - -static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) { - int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); - if (pQuery->interval.intervalUnit != 'n' && pQuery->interval.intervalUnit != 'y') { - tw->skey += pQuery->interval.sliding * factor; - tw->ekey = tw->skey + pQuery->interval.interval - 1; +static void getNextTimeWindow(SQueryAttr* pQueryAttr, STimeWindow* tw) { + int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); + if (pQueryAttr->interval.intervalUnit != 'n' && pQueryAttr->interval.intervalUnit != 'y') { + tw->skey += pQueryAttr->interval.sliding * factor; + tw->ekey = tw->skey + pQueryAttr->interval.interval - 1; return; } - int64_t key = tw->skey / 1000, interval = pQuery->interval.interval; - if (pQuery->precision == TSDB_TIME_PRECISION_MICRO) { + int64_t key = tw->skey / 1000, interval = pQueryAttr->interval.interval; + if (pQueryAttr->precision == TSDB_TIME_PRECISION_MICRO) { key /= 1000; } - if (pQuery->interval.intervalUnit == 'y') { + if (pQueryAttr->interval.intervalUnit == 'y') { interval *= 12; } @@ -159,7 +148,7 @@ static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) { tm.tm_mon = mon % 12; tw->ekey = mktime(&tm) * 1000L; - if (pQuery->precision == TSDB_TIME_PRECISION_MICRO) { + if (pQueryAttr->precision == TSDB_TIME_PRECISION_MICRO) { tw->skey *= 1000L; tw->ekey *= 1000L; } @@ -167,8 +156,8 @@ static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) { } static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type, int16_t bytes); -static void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, - int32_t numOfCols, int32_t* rowCellInfoOffset); +static void setResultOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResult, SQLFunctionCtx* pCtx, + int32_t numOfCols, int32_t* rowCellInfoOffset); void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset); static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t functionId); @@ -176,36 +165,20 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx static void setBlockStatisInfo(SQLFunctionCtx *pCtx, SSDataBlock* pSDataBlock, SColIndex* pColIndex); static void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo); -static bool hasMainOutput(SQuery *pQuery); +static bool hasMainOutput(SQueryAttr *pQueryAttr); 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); -static STsdbQueryCond createTsdbQueryCond(SQuery* pQuery, STimeWindow* win); +static STsdbQueryCond createTsdbQueryCond(SQueryAttr* pQueryAttr, STimeWindow* win); 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(SQuery* pQuery); -static bool isFixedOutputQuery(SQuery* pQuery); - -static SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime); -static SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime); -static SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); - -static SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream); -static SOperatorInfo* createOffsetOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream); -static SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); -static SOperatorInfo* createHavingOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +static int32_t getNumOfScanTimes(SQueryAttr* pQueryAttr); static void destroyBasicOperatorInfo(void* param, int32_t numOfOutput); static void destroySFillOperatorInfo(void* param, int32_t numOfOutput); @@ -220,9 +193,8 @@ static int32_t getGroupbyColumnIndex(SSqlGroupbyExpr *pGroupbyExpr, SSDataBlock* static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOperatorInfo *pInfo, 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(SQuery *pQuery, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win); -static bool isPointInterpoQuery(SQuery *pQuery); -static void setResultBufSize(SQuery* pQuery, SRspResultInfo* pResultInfo); +static void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win); +static void setResultBufSize(SQueryAttr* pQueryAttr, SRspResultInfo* pResultInfo); static void setCtxTagForJoin(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable); static void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr); static void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr, char* val, int16_t bytes); @@ -231,7 +203,7 @@ static void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowIn int32_t groupIndex); // setup the output buffer for each operator -static SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows) { +SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows) { const static int32_t minSize = 8; SSDataBlock *res = calloc(1, sizeof(SSDataBlock)); @@ -240,18 +212,19 @@ static SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32 res->pDataBlock = taosArrayInit(numOfOutput, sizeof(SColumnInfoData)); for (int32_t i = 0; i < numOfOutput; ++i) { SColumnInfoData idata = {{0}}; - idata.info.type = pExpr[i].type; - idata.info.bytes = pExpr[i].bytes; + idata.info.type = pExpr[i].base.resType; + idata.info.bytes = pExpr[i].base.resBytes; idata.info.colId = pExpr[i].base.resColId; - idata.pData = calloc(1, MAX(idata.info.bytes * numOfRows, minSize)); // at least to hold a pointer on x64 platform + int32_t size = MAX(idata.info.bytes * numOfRows, minSize); + idata.pData = calloc(1, size); // at least to hold a pointer on x64 platform taosArrayPush(res->pDataBlock, &idata); } return res; } -static void* destroyOutputBuf(SSDataBlock* pBlock) { +void* destroyOutputBuf(SSDataBlock* pBlock) { if (pBlock == NULL) { return NULL; } @@ -269,8 +242,8 @@ static void* destroyOutputBuf(SSDataBlock* pBlock) { } int32_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput) { - SQuery *pQuery = pRuntimeEnv->pQuery; - bool hasMainFunction = hasMainOutput(pQuery); + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + bool hasMainFunction = hasMainOutput(pQueryAttr); int32_t maxOutput = 0; for (int32_t j = 0; j < numOfOutput; ++j) { @@ -301,37 +274,6 @@ static void clearNumOfRes(SQLFunctionCtx* pCtx, int32_t numOfOutput) { } } -static bool isGroupbyColumn(SSqlGroupbyExpr *pGroupbyExpr) { - if (pGroupbyExpr == NULL || pGroupbyExpr->numOfGroupCols == 0) { - return false; - } - - for (int32_t i = 0; i < pGroupbyExpr->numOfGroupCols; ++i) { - SColIndex *pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, i); - if (TSDB_COL_IS_NORMAL_COL(pColIndex->flag)) { - //make sure the normal column locates at the second position if tbname exists in group by clause - if (pGroupbyExpr->numOfGroupCols > 1) { - assert(pColIndex->colIndex > 0); - } - - return true; - } - } - - return false; -} - -static bool isStabledev(SQuery* pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functId = pQuery->pExpr1[i].base.functionId; - if (functId == TSDB_FUNC_STDDEV_DST) { - return true; - } - } - - return false; -} - static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput) { bool hasTags = false; int32_t numOfSelectivity = 0; @@ -351,9 +293,9 @@ static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput return (numOfSelectivity > 0 && hasTags); } -static bool isProjQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functId = pQuery->pExpr1[i].base.functionId; +static bool isProjQuery(SQueryAttr *pQueryAttr) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functId = pQueryAttr->pExpr1[i].base.functionId; if (functId != TSDB_FUNC_PRJ && functId != TSDB_FUNC_TAGPRJ) { return false; } @@ -362,52 +304,6 @@ static bool isProjQuery(SQuery *pQuery) { return true; } -static bool isTsCompQuery(SQuery *pQuery) { return pQuery->pExpr1[0].base.functionId == TSDB_FUNC_TS_COMP; } - -static bool isTopBottomQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; - if (functionId == TSDB_FUNC_TS) { - continue; - } - - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { - return true; - } - } - - return false; -} - -static bool timeWindowInterpoRequired(SQuery *pQuery) { - for(int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; - if (functionId == TSDB_FUNC_TWA || functionId == TSDB_FUNC_INTERP) { - return true; - } - } - - return false; -} - -static bool hasTagValOutput(SQuery* pQuery) { - SExprInfo *pExprInfo = &pQuery->pExpr1[0]; - if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP) { - return true; - } else { // set tag value, by which the results are aggregated. - for (int32_t idx = 0; idx < pQuery->numOfOutput; ++idx) { - SExprInfo *pLocalExprInfo = &pQuery->pExpr1[idx]; - - // ts_comp column required the tag value for join filter - if (TSDB_COL_IS_TAG(pLocalExprInfo->base.colInfo.flag)) { - return true; - } - } - } - - return false; -} - static bool hasNullRv(SColIndex* pColIndex, SDataStatis *pStatis) { if (TSDB_COL_IS_TAG(pColIndex->flag) || TSDB_COL_IS_UD_COL(pColIndex->flag) || pColIndex->colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { return false; @@ -455,7 +351,7 @@ static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SRes (SResultRow **)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes)); // in case of repeat scan/reverse scan, no new time window added. - if (QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQuery)) { + if (QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQueryAttr)) { if (!masterscan) { // the *p1 may be NULL in case of sliding+offset exists. return (p1 != NULL)? *p1:NULL; } @@ -479,7 +375,6 @@ static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SRes prepareResultListBuffer(pResultRowInfo, pRuntimeEnv); SResultRow *pResult = NULL; - if (p1 == NULL) { pResult = getNewResultRow(pRuntimeEnv->pool); int32_t ret = initResultRow(pResult); @@ -505,19 +400,19 @@ static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SRes return getResultRow(pResultRowInfo, pResultRowInfo->curIndex); } -static void getInitialStartTimeWindow(SQuery* pQuery, TSKEY ts, STimeWindow* w) { - if (QUERY_IS_ASC_QUERY(pQuery)) { - getAlignQueryTimeWindow(pQuery, ts, ts, pQuery->window.ekey, w); +static void getInitialStartTimeWindow(SQueryAttr* pQueryAttr, TSKEY ts, STimeWindow* w) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { + getAlignQueryTimeWindow(pQueryAttr, ts, ts, pQueryAttr->window.ekey, w); } else { // the start position of the first time window in the endpoint that spreads beyond the queried last timestamp - getAlignQueryTimeWindow(pQuery, ts, pQuery->window.ekey, ts, w); + getAlignQueryTimeWindow(pQueryAttr, ts, pQueryAttr->window.ekey, ts, w); int64_t key = w->skey; while(key < ts) { // moving towards end - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - key = taosTimeAdd(key, pQuery->interval.sliding, pQuery->interval.slidingUnit, pQuery->precision); + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + key = taosTimeAdd(key, pQueryAttr->interval.sliding, pQueryAttr->interval.slidingUnit, pQueryAttr->precision); } else { - key += pQuery->interval.sliding; + key += pQueryAttr->interval.sliding; } if (key >= ts) { @@ -530,21 +425,21 @@ static void getInitialStartTimeWindow(SQuery* pQuery, TSKEY ts, STimeWindow* w) } // get the correct time window according to the handled timestamp -static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t ts, SQuery *pQuery) { +static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t ts, SQueryAttr *pQueryAttr) { STimeWindow w = {0}; if (pResultRowInfo->curIndex == -1) { // the first window, from the previous stored value if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) { - getInitialStartTimeWindow(pQuery, ts, &w); + getInitialStartTimeWindow(pQueryAttr, ts, &w); pResultRowInfo->prevSKey = w.skey; } else { w.skey = pResultRowInfo->prevSKey; } - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - w.ekey = taosTimeAdd(w.skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + w.ekey = taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { - w.ekey = w.skey + pQuery->interval.interval - 1; + w.ekey = w.skey + pQueryAttr->interval.interval - 1; } } else { int32_t slot = curTimeWindowIndex(pResultRowInfo); @@ -553,23 +448,23 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t } if (w.skey > ts || w.ekey < ts) { - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - w.skey = taosTimeTruncate(ts, &pQuery->interval, pQuery->precision); - w.ekey = taosTimeAdd(w.skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + w.skey = taosTimeTruncate(ts, &pQueryAttr->interval, pQueryAttr->precision); + w.ekey = taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { int64_t st = w.skey; if (st > ts) { - st -= ((st - ts + pQuery->interval.sliding - 1) / pQuery->interval.sliding) * pQuery->interval.sliding; + st -= ((st - ts + pQueryAttr->interval.sliding - 1) / pQueryAttr->interval.sliding) * pQueryAttr->interval.sliding; } - int64_t et = st + pQuery->interval.interval - 1; + int64_t et = st + pQueryAttr->interval.interval - 1; if (et < ts) { - st += ((ts - et + pQuery->interval.sliding - 1) / pQuery->interval.sliding) * pQuery->interval.sliding; + st += ((ts - et + pQueryAttr->interval.sliding - 1) / pQueryAttr->interval.sliding) * pQueryAttr->interval.sliding; } w.skey = st; - w.ekey = w.skey + pQuery->interval.interval - 1; + w.ekey = w.skey + pQueryAttr->interval.interval - 1; } } @@ -577,8 +472,8 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t * query border check, skey should not be bounded by the query time range, since the value skey will * be used as the time window index value. So we only change ekey of time window accordingly. */ - if (w.ekey > pQuery->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) { - w.ekey = pQuery->window.ekey; + if (w.ekey > pQueryAttr->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) { + w.ekey = pQueryAttr->window.ekey; } return w; @@ -643,7 +538,7 @@ static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRow // not assign result buffer yet, add new result buffer if (pResultRow->pageId == -1) { - int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, (int32_t) groupId, pRuntimeEnv->pQuery->intermediateResultRowSize); + int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, (int32_t) groupId, pRuntimeEnv->pQueryAttr->intermediateResultRowSize); if (ret != TSDB_CODE_SUCCESS) { return -1; } @@ -754,28 +649,28 @@ static void doUpdateResultRowIndex(SResultRowInfo*pResultRowInfo, TSKEY lastKey, } } -static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, SQuery* pQuery, TSKEY lastKey) { - bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); - if ((lastKey > pQuery->window.ekey && ascQuery) || (lastKey < pQuery->window.ekey && (!ascQuery))) { +static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, SQueryAttr* pQueryAttr, TSKEY lastKey) { + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); + if ((lastKey > pQueryAttr->window.ekey && ascQuery) || (lastKey < pQueryAttr->window.ekey && (!ascQuery))) { closeAllResultRows(pResultRowInfo); pResultRowInfo->curIndex = pResultRowInfo->size - 1; } else { int32_t step = ascQuery ? 1 : -1; - doUpdateResultRowIndex(pResultRowInfo, lastKey - step, ascQuery, pQuery->timeWindowInterpo); + doUpdateResultRowIndex(pResultRowInfo, lastKey - step, ascQuery, pQueryAttr->timeWindowInterpo); } } -static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlockInfo, TSKEY *pPrimaryColumn, +static int32_t getNumOfRowsInTimeWindow(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo *pDataBlockInfo, TSKEY *pPrimaryColumn, int32_t startPos, TSKEY ekey, __block_search_fn_t searchFn, bool updateLastKey) { assert(startPos >= 0 && startPos < pDataBlockInfo->rows); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STableQueryInfo* item = pRuntimeEnv->current; int32_t num = -1; - int32_t order = pQuery->order.order; + int32_t order = pQueryAttr->order.order; int32_t step = GET_FORWARD_DIRECTION_FACTOR(order); - STableQueryInfo* item = pQuery->current; - - if (QUERY_IS_ASC_QUERY(pQuery)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { if (ekey < pDataBlockInfo->window.ekey) { num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn); if (updateLastKey) { // update the last key @@ -807,7 +702,7 @@ static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlo static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset, int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput) { - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; bool hasPrev = pCtx[0].preAggVals.isSet; for (int32_t k = 0; k < numOfOutput; ++k) { @@ -816,7 +711,7 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx char* start = pCtx[k].pInput; - int32_t pos = (QUERY_IS_ASC_QUERY(pQuery)) ? offset : offset - (forwardStep - 1); + int32_t pos = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? offset : offset - (forwardStep - 1); if (pCtx[k].pInput != NULL) { pCtx[k].pInput = (char *)pCtx[k].pInput + pos * pCtx[k].inputBytes; } @@ -844,42 +739,42 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx } -static int32_t getNextQualifiedWindow(SQuery* pQuery, STimeWindow *pNext, SDataBlockInfo *pDataBlockInfo, +static int32_t getNextQualifiedWindow(SQueryAttr* pQueryAttr, STimeWindow *pNext, SDataBlockInfo *pDataBlockInfo, TSKEY *primaryKeys, __block_search_fn_t searchFn, int32_t prevPosition) { - getNextTimeWindow(pQuery, pNext); + getNextTimeWindow(pQueryAttr, pNext); // next time window is not in current block - if ((pNext->skey > pDataBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) || - (pNext->ekey < pDataBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQuery))) { + if ((pNext->skey > pDataBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) || + (pNext->ekey < pDataBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) { return -1; } TSKEY startKey = -1; - if (QUERY_IS_ASC_QUERY(pQuery)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { startKey = pNext->skey; - if (startKey < pQuery->window.skey) { - startKey = pQuery->window.skey; + if (startKey < pQueryAttr->window.skey) { + startKey = pQueryAttr->window.skey; } } else { startKey = pNext->ekey; - if (startKey > pQuery->window.skey) { - startKey = pQuery->window.skey; + if (startKey > pQueryAttr->window.skey) { + startKey = pQueryAttr->window.skey; } } int32_t startPos = 0; // tumbling time window query, a special case of sliding time window query - if (pQuery->interval.sliding == pQuery->interval.interval && prevPosition != -1) { - int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + if (pQueryAttr->interval.sliding == pQueryAttr->interval.interval && prevPosition != -1) { + int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); startPos = prevPosition + factor; } else { - if (startKey <= pDataBlockInfo->window.skey && QUERY_IS_ASC_QUERY(pQuery)) { + if (startKey <= pDataBlockInfo->window.skey && QUERY_IS_ASC_QUERY(pQueryAttr)) { startPos = 0; - } else if (startKey >= pDataBlockInfo->window.ekey && !QUERY_IS_ASC_QUERY(pQuery)) { + } else if (startKey >= pDataBlockInfo->window.ekey && !QUERY_IS_ASC_QUERY(pQueryAttr)) { startPos = pDataBlockInfo->rows - 1; } else { - startPos = searchFn((char *)primaryKeys, pDataBlockInfo->rows, startKey, pQuery->order.order); + startPos = searchFn((char *)primaryKeys, pDataBlockInfo->rows, startKey, pQueryAttr->order.order); } } @@ -888,29 +783,29 @@ static int32_t getNextQualifiedWindow(SQuery* pQuery, STimeWindow *pNext, SDataB * this case may happen when the time window is too small */ if (primaryKeys == NULL) { - if (QUERY_IS_ASC_QUERY(pQuery)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { assert(pDataBlockInfo->window.skey <= pNext->ekey); } else { assert(pDataBlockInfo->window.ekey >= pNext->skey); } } else { - if (QUERY_IS_ASC_QUERY(pQuery) && primaryKeys[startPos] > pNext->ekey) { + if (QUERY_IS_ASC_QUERY(pQueryAttr) && primaryKeys[startPos] > pNext->ekey) { TSKEY next = primaryKeys[startPos]; - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - pNext->skey = taosTimeTruncate(next, &pQuery->interval, pQuery->precision); - pNext->ekey = taosTimeAdd(pNext->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + pNext->skey = taosTimeTruncate(next, &pQueryAttr->interval, pQueryAttr->precision); + pNext->ekey = taosTimeAdd(pNext->skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { - pNext->ekey += ((next - pNext->ekey + pQuery->interval.sliding - 1)/pQuery->interval.sliding) * pQuery->interval.sliding; - pNext->skey = pNext->ekey - pQuery->interval.interval + 1; + pNext->ekey += ((next - pNext->ekey + pQueryAttr->interval.sliding - 1)/pQueryAttr->interval.sliding) * pQueryAttr->interval.sliding; + pNext->skey = pNext->ekey - pQueryAttr->interval.interval + 1; } - } else if ((!QUERY_IS_ASC_QUERY(pQuery)) && primaryKeys[startPos] < pNext->skey) { + } else if ((!QUERY_IS_ASC_QUERY(pQueryAttr)) && primaryKeys[startPos] < pNext->skey) { TSKEY next = primaryKeys[startPos]; - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - pNext->skey = taosTimeTruncate(next, &pQuery->interval, pQuery->precision); - pNext->ekey = taosTimeAdd(pNext->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + pNext->skey = taosTimeTruncate(next, &pQueryAttr->interval, pQueryAttr->precision); + pNext->ekey = taosTimeAdd(pNext->skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { - pNext->skey -= ((pNext->skey - next + pQuery->interval.sliding - 1) / pQuery->interval.sliding) * pQuery->interval.sliding; - pNext->ekey = pNext->skey + pQuery->interval.interval - 1; + pNext->skey -= ((pNext->skey - next + pQueryAttr->interval.sliding - 1) / pQueryAttr->interval.sliding) * pQueryAttr->interval.sliding; + pNext->ekey = pNext->skey + pQueryAttr->interval.interval - 1; } } } @@ -918,17 +813,17 @@ static int32_t getNextQualifiedWindow(SQuery* pQuery, STimeWindow *pNext, SDataB return startPos; } -static FORCE_INLINE TSKEY reviseWindowEkey(SQuery *pQuery, STimeWindow *pWindow) { +static FORCE_INLINE TSKEY reviseWindowEkey(SQueryAttr *pQueryAttr, STimeWindow *pWindow) { TSKEY ekey = -1; - if (QUERY_IS_ASC_QUERY(pQuery)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { ekey = pWindow->ekey; - if (ekey > pQuery->window.ekey) { - ekey = pQuery->window.ekey; + if (ekey > pQueryAttr->window.ekey) { + ekey = pQueryAttr->window.ekey; } } else { ekey = pWindow->skey; - if (ekey < pQuery->window.ekey) { - ekey = pQuery->window.ekey; + if (ekey < pQueryAttr->window.ekey) { + ekey = pQueryAttr->window.ekey; } } @@ -956,17 +851,17 @@ static void saveDataBlockLastRow(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* return; } - SQuery* pQuery = pRuntimeEnv->pQuery; - for (int32_t k = 0; k < pQuery->numOfCols; ++k) { + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + for (int32_t k = 0; k < pQueryAttr->numOfCols; ++k) { SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, k); memcpy(pRuntimeEnv->prevRow[k], ((char*)pColInfo->pData) + (pColInfo->info.bytes * rowIndex), pColInfo->info.bytes); } } -static TSKEY getStartTsKey(SQuery* pQuery, STimeWindow* win, const TSKEY* tsCols, int32_t rows) { +static TSKEY getStartTsKey(SQueryAttr* pQueryAttr, STimeWindow* win, const TSKEY* tsCols, int32_t rows) { TSKEY ts = TSKEY_INITIAL_VAL; - bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); if (tsCols == NULL) { ts = ascQuery? win->skey : win->ekey; } else { @@ -979,7 +874,7 @@ static TSKEY getStartTsKey(SQuery* pQuery, STimeWindow* win, const TSKEY* tsCols static void setArithParams(SArithmeticSupport* sas, SExprInfo *pExprInfo, SSDataBlock* pSDataBlock) { sas->numOfCols = (int32_t) pSDataBlock->info.numOfCols; - sas->pArithExpr = pExprInfo; + sas->pExprInfo = pExprInfo; sas->colList = calloc(1, pSDataBlock->info.numOfCols*sizeof(SColumnInfo)); for(int32_t i = 0; i < sas->numOfCols; ++i) { @@ -1007,7 +902,7 @@ static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SQLFunctionCtx* pC } } -static void setInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order) { +void setInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order) { if (pCtx[0].functionId == TSDB_FUNC_ARITHM) { SArithmeticSupport* pSupport = (SArithmeticSupport*) pCtx[0].param[1].pz; if (pSupport->colList == NULL) { @@ -1036,19 +931,30 @@ 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) || (pCol->colId == TSDB_BLOCK_DIST_COLUMN_INDEX) || + (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); // in case of the block distribution query, the inputBytes is not a constant value. pCtx[i].pInput = p->pData; - assert(p->info.colId == pColIndex->colId && pCtx[i].inputType == p->info.type);// && pCtx[i].inputBytes == p->info.bytes); + assert(p->info.colId == pColIndex->colId && pCtx[i].inputType == p->info.type); 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; } + } else if (TSDB_COL_IS_UD_COL(pCol->flag) && (pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)) { + SColIndex* pColIndex = &pOperator->pExpr[i].base.colInfo; + SColumnInfoData* p = taosArrayGet(pBlock->pDataBlock, pColIndex->colIndex); + + pCtx[i].pInput = p->pData; + assert(p->info.colId == pColIndex->colId && pCtx[i].inputType == p->info.type); + for(int32_t j = 0; j < pBlock->info.rows; ++j) { + char* dst = p->pData + j * p->info.bytes; + tVariantDump(&pOperator->pExpr[i].base.param[1], dst, p->info.type, true); + } } } } @@ -1067,10 +973,16 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction } static void arithmeticApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t numOfOutput) { - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; for (int32_t k = 0; k < numOfOutput; ++k) { - pCtx[k].startTs = pQuery->window.skey; + pCtx[k].startTs = pQueryAttr->window.skey; + + // Always set the asc order for merge stage process + if (pCtx[k].currentStage == MERGE_STAGE) { + pCtx[k].order = TSDB_ORDER_ASC; + } + aAggs[pCtx[k].functionId].xFunction(&pCtx[k]); } } @@ -1133,9 +1045,9 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SQLFunctionCtx* pCtx, int32_t pos, int32_t numOfRows, SArray* pDataBlock, const TSKEY* tsCols, STimeWindow* win) { SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); TSKEY curTs = tsCols[pos]; TSKEY lastTs = *(TSKEY *) pRuntimeEnv->prevRow[0]; @@ -1153,7 +1065,7 @@ static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SQLF return true; } - int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); TSKEY prevTs = ((pos == 0 && ascQuery) || (pos == (numOfRows - 1) && !ascQuery))? lastTs:tsCols[pos - step]; doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, prevTs, pos - step, curTs, pos, @@ -1164,15 +1076,15 @@ static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SQLF static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SQLFunctionCtx* pCtx, int32_t endRowIndex, SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey, STimeWindow* win) { SQueryRuntimeEnv *pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfOutput = pOperatorInfo->numOfOutput; TSKEY actualEndKey = tsCols[endRowIndex]; - TSKEY key = QUERY_IS_ASC_QUERY(pQuery)? win->ekey:win->skey; + TSKEY key = QUERY_IS_ASC_QUERY(pQueryAttr)? win->ekey:win->skey; // not ended in current data block, do not invoke interpolation - if ((key > blockEkey && QUERY_IS_ASC_QUERY(pQuery)) || (key < blockEkey && !QUERY_IS_ASC_QUERY(pQuery))) { + if ((key > blockEkey && QUERY_IS_ASC_QUERY(pQueryAttr)) || (key < blockEkey && !QUERY_IS_ASC_QUERY(pQueryAttr))) { setNotInterpoWindowKey(pCtx, numOfOutput, RESULT_ROW_END_INTERP); return false; } @@ -1183,7 +1095,7 @@ static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SQLFun return true; } - int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); int32_t nextRowIndex = endRowIndex + step; assert(nextRowIndex >= 0); @@ -1196,13 +1108,13 @@ static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SQLFun static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlock, SQLFunctionCtx* pCtx, SResultRow* pResult, STimeWindow* win, int32_t startPos, int32_t forwardStep) { SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; - if (!pQuery->timeWindowInterpo) { + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + if (!pQueryAttr->timeWindowInterpo) { return; } assert(pBlock != NULL); - int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, 0); @@ -1216,11 +1128,11 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc setResultRowInterpo(pResult, RESULT_ROW_START_INTERP); } } else { - setNotInterpoWindowKey(pCtx, pQuery->numOfOutput, RESULT_ROW_START_INTERP); + setNotInterpoWindowKey(pCtx, pQueryAttr->numOfOutput, RESULT_ROW_START_INTERP); } // point interpolation does not require the end key time window interpolation. - if (isPointInterpoQuery(pQuery)) { + if (pQueryAttr->pointInterpQuery) { return; } @@ -1229,13 +1141,13 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc if (!done) { int32_t endRowIndex = startPos + (forwardStep - 1) * step; - TSKEY endKey = QUERY_IS_ASC_QUERY(pQuery)? pBlock->info.window.ekey:pBlock->info.window.skey; + TSKEY endKey = QUERY_IS_ASC_QUERY(pQueryAttr)? pBlock->info.window.ekey:pBlock->info.window.skey; bool interp = setTimeWindowInterpolationEndTs(pOperatorInfo, pCtx, endRowIndex, pBlock->pDataBlock, tsCols, endKey, win); if (interp) { setResultRowInterpo(pResult, RESULT_ROW_END_INTERP); } } else { - setNotInterpoWindowKey(pCtx, pQuery->numOfOutput, RESULT_ROW_END_INTERP); + setNotInterpoWindowKey(pCtx, pQueryAttr->numOfOutput, RESULT_ROW_END_INTERP); } } @@ -1244,10 +1156,10 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; int32_t numOfOutput = pOperatorInfo->numOfOutput; - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); - bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); int32_t prevIndex = curTimeWindowIndex(pResultRowInfo); @@ -1260,9 +1172,9 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul } int32_t startPos = ascQuery? 0 : (pSDataBlock->info.rows - 1); - TSKEY ts = getStartTsKey(pQuery, &pSDataBlock->info.window, tsCols, pSDataBlock->info.rows); + TSKEY ts = getStartTsKey(pQueryAttr, &pSDataBlock->info.window, tsCols, pSDataBlock->info.rows); - STimeWindow win = getActiveTimeWindow(pResultRowInfo, ts, pQuery); + STimeWindow win = getActiveTimeWindow(pResultRowInfo, ts, pQueryAttr); bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); SResultRow* pResult = NULL; @@ -1273,13 +1185,13 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul } int32_t forwardStep = 0; - TSKEY ekey = reviseWindowEkey(pQuery, &win); + TSKEY ekey = reviseWindowEkey(pQueryAttr, &win); forwardStep = - getNumOfRowsInTimeWindow(pQuery, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true); + getNumOfRowsInTimeWindow(pRuntimeEnv, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true); // prev time window not interpolation yet. int32_t curIndex = curTimeWindowIndex(pResultRowInfo); - if (prevIndex != -1 && prevIndex < curIndex && pQuery->timeWindowInterpo) { + if (prevIndex != -1 && prevIndex < curIndex && pQueryAttr->timeWindowInterpo) { for (int32_t j = prevIndex; j < curIndex; ++j) { // previous time window may be all closed already. SResultRow* pRes = pResultRowInfo->pResult[j]; if (pRes->closed) { @@ -1301,7 +1213,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul -1, tsCols[startPos], startPos, w.ekey, RESULT_ROW_END_INTERP); setResultRowInterpo(pResult, RESULT_ROW_END_INTERP); - setNotInterpoWindowKey(pInfo->pCtx, pQuery->numOfOutput, RESULT_ROW_START_INTERP); + setNotInterpoWindowKey(pInfo->pCtx, pQueryAttr->numOfOutput, RESULT_ROW_START_INTERP); doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &w, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput); } @@ -1321,7 +1233,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul STimeWindow nextWin = win; while (1) { int32_t prevEndPos = (forwardStep - 1) * step + startPos; - startPos = getNextQualifiedWindow(pQuery, &nextWin, &pSDataBlock->info, tsCols, binarySearchForKey, prevEndPos); + startPos = getNextQualifiedWindow(pQueryAttr, &nextWin, &pSDataBlock->info, tsCols, binarySearchForKey, prevEndPos); if (startPos < 0) { break; } @@ -1333,30 +1245,31 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } - ekey = reviseWindowEkey(pQuery, &nextWin); - forwardStep = getNumOfRowsInTimeWindow(pQuery, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true); + ekey = reviseWindowEkey(pQueryAttr, &nextWin); + forwardStep = getNumOfRowsInTimeWindow(pRuntimeEnv, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true); // window start(end) key interpolation doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->pCtx, pResult, &nextWin, startPos, forwardStep); doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &nextWin, startPos, forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput); } - if (pQuery->timeWindowInterpo) { + if (pQueryAttr->timeWindowInterpo) { int32_t rowIndex = ascQuery? (pSDataBlock->info.rows-1):0; saveDataBlockLastRow(pRuntimeEnv, &pSDataBlock->info, pSDataBlock->pDataBlock, rowIndex); } - updateResultRowInfoActiveIndex(pResultRowInfo, pQuery, pQuery->current->lastKey); + updateResultRowInfoActiveIndex(pResultRowInfo, pQueryAttr, pRuntimeEnv->current->lastKey); } static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - STableQueryInfo* item = pRuntimeEnv->pQuery->current; + STableQueryInfo* item = pRuntimeEnv->current; SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, pInfo->colIndex); - int16_t bytes = pColInfoData->info.bytes; - int16_t type = pColInfoData->info.type; - SQuery *pQuery = pRuntimeEnv->pQuery; + + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int16_t bytes = pColInfoData->info.bytes; + int16_t type = pColInfoData->info.type; if (type == TSDB_DATA_TYPE_FLOAT || type == TSDB_DATA_TYPE_DOUBLE) { qError("QInfo:0x%"PRIx64" group by not supported on double/float columns, abort", GET_QID(pRuntimeEnv)); @@ -1377,7 +1290,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn memcpy(pInfo->prevData, val, bytes); - if (pQuery->stableQuery && pQuery->stabledev && (pRuntimeEnv->prevResult != NULL)) { + if (pQueryAttr->stableQuery && pQueryAttr->stabledev && (pRuntimeEnv->prevResult != NULL)) { setParamForStableStddevByColData(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, pOperator->pExpr, val, bytes); } @@ -1400,7 +1313,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - STableQueryInfo* item = pRuntimeEnv->pQuery->current; + STableQueryInfo* item = pRuntimeEnv->current; // primary timestamp column SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, 0); @@ -1408,7 +1321,7 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInf bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); SOptrBasicInfo* pBInfo = &pInfo->binfo; - int64_t gap = pOperator->pRuntimeEnv->pQuery->sw.gap; + int64_t gap = pOperator->pRuntimeEnv->pQueryAttr->sw.gap; pInfo->numOfRows = 0; TSKEY* tsList = (TSKEY*)pColInfoData->pData; @@ -1494,7 +1407,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOp setResultRowKey(pResultRow, pData, type); if (pResultRow->pageId == -1) { - int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, groupIndex, pRuntimeEnv->pQuery->resultRowSize); + int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, groupIndex, pRuntimeEnv->pQueryAttr->resultRowSize); if (ret != 0) { return -1; } @@ -1528,7 +1441,7 @@ static int32_t getGroupbyColumnIndex(SSqlGroupbyExpr *pGroupbyExpr, SSDataBlock* static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t functionId) { SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; // in case of timestamp column, always generated results. if (functionId == TSDB_FUNC_TS) { @@ -1540,12 +1453,12 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx } if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_FIRST) { - return QUERY_IS_ASC_QUERY(pQuery); + return QUERY_IS_ASC_QUERY(pQueryAttr); } // denote the order type if ((functionId == TSDB_FUNC_LAST_DST || functionId == TSDB_FUNC_LAST)) { - return pCtx->param[0].i64 == pQuery->order.order; + return pCtx->param[0].i64 == pQueryAttr->order.order; } // in the reverse table scan, only the following functions need to be executed @@ -1624,7 +1537,7 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, int32_t** rowCellInfoOffset) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; SQLFunctionCtx * pFuncCtx = (SQLFunctionCtx *)calloc(numOfOutput, sizeof(SQLFunctionCtx)); if (pFuncCtx == NULL) { @@ -1638,10 +1551,10 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr } for (int32_t i = 0; i < numOfOutput; ++i) { - SSqlFuncMsg *pSqlFuncMsg = &pExpr[i].base; + SSqlExpr *pSqlExpr = &pExpr[i].base; SQLFunctionCtx* pCtx = &pFuncCtx[i]; - SColIndex *pIndex = &pSqlFuncMsg->colInfo; + SColIndex *pIndex = &pSqlExpr->colInfo; if (TSDB_COL_REQ_NULL(pIndex->flag)) { pCtx->requireNull = true; @@ -1650,33 +1563,33 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr pCtx->requireNull = false; } - pCtx->inputBytes = pSqlFuncMsg->colBytes; - pCtx->inputType = pSqlFuncMsg->colType; + pCtx->inputBytes = pSqlExpr->colBytes; + pCtx->inputType = pSqlExpr->colType; pCtx->ptsOutputBuf = NULL; - pCtx->outputBytes = pExpr[i].bytes; - pCtx->outputType = pExpr[i].type; + pCtx->outputBytes = pSqlExpr->resBytes; + pCtx->outputType = pSqlExpr->resType; - pCtx->order = pQuery->order.order; - pCtx->functionId = pSqlFuncMsg->functionId; - pCtx->stableQuery = pQuery->stableQuery; - pCtx->interBufBytes = pExpr[i].interBytes; + pCtx->order = pQueryAttr->order.order; + pCtx->functionId = pSqlExpr->functionId; + pCtx->stableQuery = pQueryAttr->stableQuery; + pCtx->interBufBytes = pSqlExpr->interBytes; pCtx->start.key = INT64_MIN; pCtx->end.key = INT64_MIN; - pCtx->numOfParams = pSqlFuncMsg->numOfParams; + pCtx->numOfParams = pSqlExpr->numOfParams; for (int32_t j = 0; j < pCtx->numOfParams; ++j) { - int16_t type = pSqlFuncMsg->arg[j].argType; - int16_t bytes = pSqlFuncMsg->arg[j].argBytes; - if (pSqlFuncMsg->functionId == TSDB_FUNC_STDDEV_DST) { + int16_t type = pSqlExpr->param[j].nType; + int16_t bytes = pSqlExpr->param[j].nLen; + if (pSqlExpr->functionId == TSDB_FUNC_STDDEV_DST) { continue; } if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { - tVariantCreateFromBinary(&pCtx->param[j], pSqlFuncMsg->arg[j].argValue.pz, bytes, type); + tVariantCreateFromBinary(&pCtx->param[j], pSqlExpr->param[j].pz, bytes, type); } else { - tVariantCreateFromBinary(&pCtx->param[j], (char *)&pSqlFuncMsg->arg[j].argValue.i64, bytes, type); + tVariantCreateFromBinary(&pCtx->param[j], (char *)&pSqlExpr->param[j].i64, bytes, type); } } @@ -1687,30 +1600,30 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr int32_t f = pExpr[0].base.functionId; assert(f == TSDB_FUNC_TS || f == TSDB_FUNC_TS_DUMMY); - pCtx->param[2].i64 = pQuery->order.order; + pCtx->param[2].i64 = pQueryAttr->order.order; pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT; pCtx->param[3].i64 = functionId; pCtx->param[3].nType = TSDB_DATA_TYPE_BIGINT; - pCtx->param[1].i64 = pQuery->order.orderColId; + pCtx->param[1].i64 = pQueryAttr->order.orderColId; } else if (functionId == TSDB_FUNC_INTERP) { - pCtx->param[2].i64 = (int8_t)pQuery->fillType; - if (pQuery->fillVal != NULL) { - if (isNull((const char *)&pQuery->fillVal[i], pCtx->inputType)) { + pCtx->param[2].i64 = (int8_t)pQueryAttr->fillType; + if (pQueryAttr->fillVal != NULL) { + if (isNull((const char *)&pQueryAttr->fillVal[i], pCtx->inputType)) { pCtx->param[1].nType = TSDB_DATA_TYPE_NULL; } else { // todo refactor, tVariantCreateFromBinary should handle the NULL value if (pCtx->inputType != TSDB_DATA_TYPE_BINARY && pCtx->inputType != TSDB_DATA_TYPE_NCHAR) { - tVariantCreateFromBinary(&pCtx->param[1], (char *)&pQuery->fillVal[i], pCtx->inputBytes, pCtx->inputType); + tVariantCreateFromBinary(&pCtx->param[1], (char *)&pQueryAttr->fillVal[i], pCtx->inputBytes, pCtx->inputType); } } } } else if (functionId == TSDB_FUNC_TS_COMP) { - pCtx->param[0].i64 = pQuery->vgId; //TODO this should be the parameter from client + pCtx->param[0].i64 = pQueryAttr->vgId; //TODO this should be the parameter from client pCtx->param[0].nType = TSDB_DATA_TYPE_BIGINT; } else if (functionId == TSDB_FUNC_TWA) { - pCtx->param[1].i64 = pQuery->window.skey; + pCtx->param[1].i64 = pQueryAttr->window.skey; pCtx->param[1].nType = TSDB_DATA_TYPE_BIGINT; - pCtx->param[2].i64 = pQuery->window.ekey; + pCtx->param[2].i64 = pQueryAttr->window.ekey; pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT; } else if (functionId == TSDB_FUNC_ARITHM) { pCtx->param[1].pz = (char*) &pRuntimeEnv->sasArray[i]; @@ -1719,7 +1632,7 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr for(int32_t i = 1; i < numOfOutput; ++i) { (*rowCellInfoOffset)[i] = (int32_t)((*rowCellInfoOffset)[i - 1] + sizeof(SResultRowCellInfo) + - pExpr[i - 1].interBytes * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pQuery->topBotQuery, pQuery->stableQuery)); + pExpr[i - 1].base.interBytes * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); } setCtxTagColumnInfo(pFuncCtx, numOfOutput); @@ -1745,35 +1658,35 @@ static void* destroySQLFunctionCtx(SQLFunctionCtx* pCtx, int32_t numOfOutput) { return NULL; } -static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfTables) { +static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfTables, SArray* pOperator, void* merger) { qDebug("QInfo:0x%"PRIx64" setup runtime env", GET_QID(pRuntimeEnv)); - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; pRuntimeEnv->prevGroupId = INT32_MIN; - pRuntimeEnv->pQuery = pQuery; + pRuntimeEnv->pQueryAttr = pQueryAttr; pRuntimeEnv->pResultRowHashTable = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); - pRuntimeEnv->keyBuf = malloc(pQuery->maxSrcColumnSize + sizeof(int64_t)); + pRuntimeEnv->keyBuf = malloc(pQueryAttr->maxTableColumnWidth + sizeof(int64_t)); pRuntimeEnv->pool = initResultRowPool(getResultRowSize(pRuntimeEnv)); - pRuntimeEnv->prevRow = malloc(POINTER_BYTES * pQuery->numOfCols + pQuery->srcRowSize); - pRuntimeEnv->tagVal = malloc(pQuery->tagLen); - pRuntimeEnv->currentOffset = pQuery->limit.offset; + pRuntimeEnv->prevRow = malloc(POINTER_BYTES * pQueryAttr->numOfCols + pQueryAttr->srcRowSize); + pRuntimeEnv->tagVal = malloc(pQueryAttr->tagLen); + pRuntimeEnv->currentOffset = pQueryAttr->limit.offset; // NOTE: pTableCheckInfo need to update the query time range and the lastKey info pRuntimeEnv->pTableRetrieveTsMap = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK); - pRuntimeEnv->sasArray = calloc(pQuery->numOfOutput, sizeof(SArithmeticSupport)); + pRuntimeEnv->sasArray = calloc(pQueryAttr->numOfOutput, sizeof(SArithmeticSupport)); if (pRuntimeEnv->sasArray == NULL || pRuntimeEnv->pResultRowHashTable == NULL || pRuntimeEnv->keyBuf == NULL || pRuntimeEnv->prevRow == NULL || pRuntimeEnv->tagVal == NULL) { goto _clean; } - if (pQuery->numOfCols) { - char* start = POINTER_BYTES * pQuery->numOfCols + (char*) pRuntimeEnv->prevRow; + if (pQueryAttr->numOfCols) { + char* start = POINTER_BYTES * pQueryAttr->numOfCols + (char*) pRuntimeEnv->prevRow; pRuntimeEnv->prevRow[0] = start; - for(int32_t i = 1; i < pQuery->numOfCols; ++i) { - pRuntimeEnv->prevRow[i] = pRuntimeEnv->prevRow[i - 1] + pQuery->colList[i-1].bytes; + for(int32_t i = 1; i < pQueryAttr->numOfCols; ++i) { + pRuntimeEnv->prevRow[i] = pRuntimeEnv->prevRow[i - 1] + pQueryAttr->tableCols[i-1].bytes; } *(int64_t*) pRuntimeEnv->prevRow[0] = INT64_MIN; @@ -1783,77 +1696,121 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf // group by normal column, sliding window query, interval query are handled by interval query processor // interval (down sampling operation) - if (onlyQueryTags(pQuery)) { // do nothing for tags query + int32_t numOfOperator = (int32_t) taosArrayGetSize(pOperator); + for(int32_t i = 0; i < numOfOperator; ++i) { + int32_t* op = taosArrayGet(pOperator, i); - } else if (QUERY_IS_INTERVAL_QUERY(pQuery)) { - if (pQuery->stableQuery) { - pRuntimeEnv->proot = createMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, - pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - } else { - pRuntimeEnv->proot = - createTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - - if (pQuery->pExpr2 != NULL) { + switch (*op) { + case OP_TagScan: { + pRuntimeEnv->proot = createTagScanOperatorInfo(pRuntimeEnv, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + break; + } + case OP_MultiTableTimeInterval: { pRuntimeEnv->proot = - createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2); + createMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + break; + } + case OP_TimeWindow: { + pRuntimeEnv->proot = + createTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + break; + } + case OP_Groupby: { + pRuntimeEnv->proot = + createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + break; + } + case OP_SessionWindow: { + pRuntimeEnv->proot = + createSWindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + break; + } + case OP_MultiTableAggregate: { + pRuntimeEnv->proot = + createMultiTableAggOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->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); + } + break; } - if (pQuery->fillType != TSDB_FILL_NONE && !isPointInterpoQuery(pQuery)) { + case OP_Arithmetic: { // TODO refactor to remove arith operator. + 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 + setTableScanFilterOperatorInfo(prev->info, pRuntimeEnv->proot); + } + } else { + prev = pRuntimeEnv->proot; + assert(pQueryAttr->pExpr2 != NULL); + pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, prev, pQueryAttr->pExpr2, pQueryAttr->numOfExpr2); + } + break; + } + + case OP_Limit: { + pRuntimeEnv->proot = createLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot); + break; + } + + 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); + } + break; + } + + case OP_Fill: { SOperatorInfo* pInfo = pRuntimeEnv->proot; pRuntimeEnv->proot = createFillOperatorInfo(pRuntimeEnv, pInfo, pInfo->pExpr, pInfo->numOfOutput); + break; + } + + case OP_MultiwayMergeSort: { + bool groupMix = true; + if(pQueryAttr->slimit.offset != 0 || pQueryAttr->slimit.limit != -1) { + groupMix = false; + } + pRuntimeEnv->proot = createMultiwaySortOperatorInfo(pRuntimeEnv, pQueryAttr->pExpr1, pQueryAttr->numOfOutput, + 4096, merger, groupMix); // TODO hack it + break; + } + + case OP_GlobalAggregate: { + pRuntimeEnv->proot = createGlobalAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3, + pQueryAttr->numOfExpr3, merger); + break; + } + + case OP_SLimit: { + pRuntimeEnv->proot = createSLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3, + pQueryAttr->numOfExpr3, merger); + break; + } + + case OP_Distinct: { + pRuntimeEnv->proot = createDistinctOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + break; + } + + default: { + assert(0); } } - - } else if (pQuery->groupbyColumn) { - pRuntimeEnv->proot = - createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - - if (pQuery->pExpr2 != NULL) { - pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2); - } - } else if (pQuery->sw.gap > 0) { - pRuntimeEnv->proot = createSWindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - - if (pQuery->pExpr2 != NULL) { - pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2); - } - } else if (isFixedOutputQuery(pQuery)) { - if (pQuery->stableQuery && !isTsCompQuery(pQuery)) { - pRuntimeEnv->proot = - createMultiTableAggOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - } else { - pRuntimeEnv->proot = - createAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - } - - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - - if (pQuery->pExpr2 != NULL) { - pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2); - } - } else { // diff/add/multiply/subtract/division - assert(pQuery->checkResultBuf == 1); - if (!onlyQueryTags(pQuery)) { - pRuntimeEnv->proot = - createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - } - } - - if (pQuery->havingNum > 0) { - pRuntimeEnv->proot = createHavingOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr1, pQuery->numOfOutput); - } - - if (pQuery->limit.offset > 0) { - pRuntimeEnv->proot = createOffsetOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot); - } - - if (pQuery->limit.limit > 0) { - pRuntimeEnv->proot = createLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot); } return TSDB_CODE_SUCCESS; @@ -1869,17 +1826,17 @@ _clean: } static void doFreeQueryHandle(SQueryRuntimeEnv* pRuntimeEnv) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; tsdbCleanupQueryHandle(pRuntimeEnv->pQueryHandle); pRuntimeEnv->pQueryHandle = NULL; - SMemRef* pMemRef = &pQuery->memRef; + SMemRef* pMemRef = &pQueryAttr->memRef; assert(pMemRef->ref == 0 && pMemRef->snapshot.imem == NULL && pMemRef->snapshot.mem == NULL); } -static void destroyTsComp(SQueryRuntimeEnv *pRuntimeEnv, SQuery *pQuery) { - if (isTsCompQuery(pQuery) && pRuntimeEnv->outputBuf && pRuntimeEnv->outputBuf->pDataBlock && taosArrayGetSize(pRuntimeEnv->outputBuf->pDataBlock) > 0) { +static void destroyTsComp(SQueryRuntimeEnv *pRuntimeEnv, SQueryAttr *pQueryAttr) { + if (pQueryAttr->tsCompQuery && pRuntimeEnv->outputBuf && pRuntimeEnv->outputBuf->pDataBlock && taosArrayGetSize(pRuntimeEnv->outputBuf->pDataBlock) > 0) { SColumnInfoData* pColInfoData = taosArrayGet(pRuntimeEnv->outputBuf->pDataBlock, 0); if (pColInfoData) { FILE *f = *(FILE **)pColInfoData->pData; // TODO refactor @@ -1892,13 +1849,13 @@ static void destroyTsComp(SQueryRuntimeEnv *pRuntimeEnv, SQuery *pQuery) { } static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SQInfo* pQInfo = (SQInfo*) pRuntimeEnv->qinfo; qDebug("QInfo:0x%"PRIx64" teardown runtime env", pQInfo->qId); if (pRuntimeEnv->sasArray != NULL) { - for(int32_t i = 0; i < pQuery->numOfOutput; ++i) { + for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { tfree(pRuntimeEnv->sasArray[i].data); tfree(pRuntimeEnv->sasArray[i].colList); } @@ -1909,8 +1866,8 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { destroyResultBuf(pRuntimeEnv->pResultBuf); doFreeQueryHandle(pRuntimeEnv); - destroyTsComp(pRuntimeEnv, pQuery); - + destroyTsComp(pRuntimeEnv, pQueryAttr); + pRuntimeEnv->pTsBuf = tsBufDestroy(pRuntimeEnv->pTsBuf); tfree(pRuntimeEnv->keyBuf); @@ -1928,7 +1885,6 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { pRuntimeEnv->pool = destroyResultRowPool(pRuntimeEnv->pool); taosArrayDestroyEx(pRuntimeEnv->prevResult, freeInterResult); pRuntimeEnv->prevResult = NULL; - } static bool needBuildResAfterQueryComplete(SQInfo* pQInfo) { @@ -1956,53 +1912,47 @@ bool isQueryKilled(SQInfo *pQInfo) { void setQueryKilled(SQInfo *pQInfo) { pQInfo->code = TSDB_CODE_TSC_QUERY_CANCELLED;} -static bool isFixedOutputQuery(SQuery* pQuery) { - if (QUERY_IS_INTERVAL_QUERY(pQuery)) { - return false; - } - - // Note:top/bottom query is fixed output query - if (pQuery->topBotQuery || pQuery->groupbyColumn || isTsCompQuery(pQuery)) { - return true; - } - - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - SSqlFuncMsg *pExprMsg = &pQuery->pExpr1[i].base; - - // ignore the ts_comp function - if (i == 0 && pExprMsg->functionId == TSDB_FUNC_PRJ && pExprMsg->numOfParams == 1 && - pExprMsg->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { - continue; - } - - if (pExprMsg->functionId == TSDB_FUNC_TS || pExprMsg->functionId == TSDB_FUNC_TS_DUMMY) { - continue; - } - - if (!IS_MULTIOUTPUT(aAggs[pExprMsg->functionId].status)) { - return true; - } - } - - return false; -} +//static bool isFixedOutputQuery(SQueryAttr* pQueryAttr) { +// if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { +// return false; +// } +// +// // Note:top/bottom query is fixed output query +// if (pQueryAttr->topBotQuery || pQueryAttr->groupbyColumn || pQueryAttr->tsCompQuery) { +// return true; +// } +// +// for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { +// SSqlExpr *pExpr = &pQueryAttr->pExpr1[i].base; +// +// if (pExpr->functionId == TSDB_FUNC_TS || pExpr->functionId == TSDB_FUNC_TS_DUMMY) { +// continue; +// } +// +// if (!IS_MULTIOUTPUT(aAggs[pExpr->functionId].status)) { +// return true; +// } +// } +// +// return false; +//} // todo refactor with isLastRowQuery -bool isPointInterpoQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; - if (functionId == TSDB_FUNC_INTERP) { - return true; - } - } - - return false; -} +//bool isPointInterpoQuery(SQueryAttr *pQueryAttr) { +// for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { +// int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; +// if (functionId == TSDB_FUNC_INTERP) { +// return true; +// } +// } +// +// return false; +//} // TODO REFACTOR:MERGE WITH CLIENT-SIDE FUNCTION -static UNUSED_FUNC bool isSumAvgRateQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; +static UNUSED_FUNC bool isSumAvgRateQuery(SQueryAttr *pQueryAttr) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; if (functionId == TSDB_FUNC_TS) { continue; } @@ -2016,9 +1966,9 @@ static UNUSED_FUNC bool isSumAvgRateQuery(SQuery *pQuery) { return false; } -static bool isFirstLastRowQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionID = pQuery->pExpr1[i].base.functionId; +static bool isFirstLastRowQuery(SQueryAttr *pQueryAttr) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionID = pQueryAttr->pExpr1[i].base.functionId; if (functionID == TSDB_FUNC_LAST_ROW) { return true; } @@ -2027,36 +1977,13 @@ static bool isFirstLastRowQuery(SQuery *pQuery) { return false; } -static bool needReverseScan(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; - if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG) { - continue; - } - - if ((functionId == TSDB_FUNC_FIRST || functionId == TSDB_FUNC_FIRST_DST) && !QUERY_IS_ASC_QUERY(pQuery)) { - return true; - } - - if (functionId == TSDB_FUNC_LAST || functionId == TSDB_FUNC_LAST_DST) { - // the scan order to acquire the last result of the specified column - int32_t order = (int32_t)pQuery->pExpr1[i].base.arg->argValue.i64; - if (order != pQuery->order.order) { - return true; - } - } - } - - return false; -} - /** * 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 */ -bool onlyQueryTags(SQuery* pQuery) { - for(int32_t i = 0; i < pQuery->numOfOutput; ++i) { - SExprInfo* pExprInfo = &pQuery->pExpr1[i]; +bool onlyQueryTags(SQueryAttr* pQueryAttr) { + for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + SExprInfo* pExprInfo = &pQueryAttr->pExpr1[i]; int32_t functionId = pExprInfo->base.functionId; @@ -2073,54 +2000,31 @@ bool onlyQueryTags(SQuery* pQuery) { ///////////////////////////////////////////////////////////////////////////////////////////// -void getAlignQueryTimeWindow(SQuery *pQuery, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win) { - assert(key >= keyFirst && key <= keyLast && pQuery->interval.sliding <= pQuery->interval.interval); - win->skey = taosTimeTruncate(key, &pQuery->interval, pQuery->precision); +void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win) { + assert(key >= keyFirst && key <= keyLast && pQueryAttr->interval.sliding <= pQueryAttr->interval.interval); + win->skey = taosTimeTruncate(key, &pQueryAttr->interval, pQueryAttr->precision); /* - * if the realSkey > INT64_MAX - pQuery->interval.interval, the query duration between + * if the realSkey > INT64_MAX - pQueryAttr->interval.interval, the query duration between * realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges. */ - if (keyFirst > (INT64_MAX - pQuery->interval.interval)) { - assert(keyLast - keyFirst < pQuery->interval.interval); + if (keyFirst > (INT64_MAX - pQueryAttr->interval.interval)) { + assert(keyLast - keyFirst < pQueryAttr->interval.interval); win->ekey = INT64_MAX; - } else if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - win->ekey = taosTimeAdd(win->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + } else if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + win->ekey = taosTimeAdd(win->skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { - win->ekey = win->skey + pQuery->interval.interval - 1; - } -} - -static void setScanLimitationByResultBuffer(SQuery *pQuery) { - if (isTopBottomQuery(pQuery)) { - pQuery->checkResultBuf = 0; - } else if (isGroupbyColumn(pQuery->pGroupbyExpr)) { - pQuery->checkResultBuf = 0; - } else { - bool hasMultioutput = false; - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - SSqlFuncMsg *pExprMsg = &pQuery->pExpr1[i].base; - if (pExprMsg->functionId == TSDB_FUNC_TS || pExprMsg->functionId == TSDB_FUNC_TS_DUMMY) { - continue; - } - - hasMultioutput = IS_MULTIOUTPUT(aAggs[pExprMsg->functionId].status); - if (!hasMultioutput) { - break; - } - } - - pQuery->checkResultBuf = hasMultioutput ? 1 : 0; + win->ekey = win->skey + pQueryAttr->interval.interval - 1; } } /* * todo add more parameters to check soon.. */ -bool colIdCheck(SQuery *pQuery, uint64_t qId) { +bool colIdCheck(SQueryAttr *pQueryAttr, uint64_t qId) { // load data column information is incorrect - for (int32_t i = 0; i < pQuery->numOfCols - 1; ++i) { - if (pQuery->colList[i].colId == pQuery->colList[i + 1].colId) { + for (int32_t i = 0; i < pQueryAttr->numOfCols - 1; ++i) { + if (pQueryAttr->tableCols[i].colId == pQueryAttr->tableCols[i + 1].colId) { qError("QInfo:0x%"PRIx64" invalid data load column for query", qId); return false; } @@ -2131,9 +2035,9 @@ bool colIdCheck(SQuery *pQuery, uint64_t qId) { // todo ignore the avg/sum/min/max/count/stddev/top/bottom functions, of which // the scan order is not matter -static bool onlyOneQueryType(SQuery *pQuery, int32_t functId, int32_t functIdDst) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; +static bool onlyOneQueryType(SQueryAttr *pQueryAttr, int32_t functId, int32_t functIdDst) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAG_DUMMY) { @@ -2148,11 +2052,11 @@ static bool onlyOneQueryType(SQuery *pQuery, int32_t functId, int32_t functIdDst return true; } -static bool onlyFirstQuery(SQuery *pQuery) { return onlyOneQueryType(pQuery, TSDB_FUNC_FIRST, TSDB_FUNC_FIRST_DST); } +static bool onlyFirstQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, TSDB_FUNC_FIRST, TSDB_FUNC_FIRST_DST); } -static bool onlyLastQuery(SQuery *pQuery) { return onlyOneQueryType(pQuery, TSDB_FUNC_LAST, TSDB_FUNC_LAST_DST); } +static bool onlyLastQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, TSDB_FUNC_LAST, TSDB_FUNC_LAST_DST); } -static int32_t updateBlockLoadStatus(SQuery *pQuery, int32_t status) { +static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { bool hasFirstLastFunc = false; bool hasOtherFunc = false; @@ -2187,10 +2091,10 @@ static int32_t updateBlockLoadStatus(SQuery *pQuery, int32_t status) { } static void doExchangeTimeWindow(SQInfo* pQInfo, STimeWindow* win) { - SQuery* pQuery = &pQInfo->query; - size_t t = taosArrayGetSize(pQuery->tableGroupInfo.pGroupList); + SQueryAttr* pQueryAttr = &pQInfo->query; + size_t t = taosArrayGetSize(pQueryAttr->tableGroupInfo.pGroupList); for(int32_t i = 0; i < t; ++i) { - SArray* p1 = taosArrayGetP(pQuery->tableGroupInfo.pGroupList, i); + SArray* p1 = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); size_t len = taosArrayGetSize(p1); for(int32_t j = 0; j < len; ++j) { @@ -2205,7 +2109,7 @@ static void doExchangeTimeWindow(SQInfo* pQInfo, STimeWindow* win) { } static void changeExecuteScanOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bool stableQuery) { - SQuery* pQuery = pQInfo->runtimeEnv.pQuery; + SQueryAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; // in case of point-interpolation query, use asc order scan char msg[] = "QInfo:0x%"PRIx64" scan order changed for %s query, old:%d, new:%d, qrange exchanged, old qrange:%" PRId64 @@ -2213,92 +2117,92 @@ static void changeExecuteScanOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bo // todo handle the case the the order irrelevant query type mixed up with order critical query type // descending order query for last_row query - if (isFirstLastRowQuery(pQuery)) { - qDebug("QInfo:0x%"PRIx64" scan order changed for last_row query, old:%d, new:%d", pQInfo->qId, pQuery->order.order, TSDB_ORDER_ASC); + if (isFirstLastRowQuery(pQueryAttr)) { + qDebug("QInfo:0x%"PRIx64" scan order changed for last_row query, old:%d, new:%d", pQInfo->qId, pQueryAttr->order.order, TSDB_ORDER_ASC); - pQuery->order.order = TSDB_ORDER_ASC; - if (pQuery->window.skey > pQuery->window.ekey) { - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); + pQueryAttr->order.order = TSDB_ORDER_ASC; + if (pQueryAttr->window.skey > pQueryAttr->window.ekey) { + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); } return; } - if (isGroupbyColumn(pQuery->pGroupbyExpr) && pQuery->order.order == TSDB_ORDER_DESC) { - pQuery->order.order = TSDB_ORDER_ASC; - if (pQuery->window.skey > pQuery->window.ekey) { - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); + if (pQueryAttr->groupbyColumn && pQueryAttr->order.order == TSDB_ORDER_DESC) { + pQueryAttr->order.order = TSDB_ORDER_ASC; + if (pQueryAttr->window.skey > pQueryAttr->window.ekey) { + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); } - doExchangeTimeWindow(pQInfo, &pQuery->window); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); return; } - if (isPointInterpoQuery(pQuery) && pQuery->interval.interval == 0) { - if (!QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "interp", pQuery->order.order, TSDB_ORDER_ASC, pQuery->window.skey, pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); + if (pQueryAttr->pointInterpQuery && pQueryAttr->interval.interval == 0) { + if (!QUERY_IS_ASC_QUERY(pQueryAttr)) { + qDebug(msg, pQInfo, "interp", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); } - pQuery->order.order = TSDB_ORDER_ASC; + pQueryAttr->order.order = TSDB_ORDER_ASC; return; } - if (pQuery->interval.interval == 0) { - if (onlyFirstQuery(pQuery)) { - if (!QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "only-first", pQuery->order.order, TSDB_ORDER_ASC, pQuery->window.skey, - pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); + if (pQueryAttr->interval.interval == 0) { + if (onlyFirstQuery(pQueryAttr)) { + if (!QUERY_IS_ASC_QUERY(pQueryAttr)) { + qDebug(msg, pQInfo, "only-first", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey, + pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); - doExchangeTimeWindow(pQInfo, &pQuery->window); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); } - pQuery->order.order = TSDB_ORDER_ASC; - } else if (onlyLastQuery(pQuery)) { - if (QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "only-last", pQuery->order.order, TSDB_ORDER_DESC, pQuery->window.skey, - pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); + pQueryAttr->order.order = TSDB_ORDER_ASC; + } else if (onlyLastQuery(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); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); - doExchangeTimeWindow(pQInfo, &pQuery->window); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); } - pQuery->order.order = TSDB_ORDER_DESC; + pQueryAttr->order.order = TSDB_ORDER_DESC; } } else { // interval query if (stableQuery) { - if (onlyFirstQuery(pQuery)) { - if (!QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "only-first stable", pQuery->order.order, TSDB_ORDER_ASC, - pQuery->window.skey, pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); + if (onlyFirstQuery(pQueryAttr)) { + if (!QUERY_IS_ASC_QUERY(pQueryAttr)) { + qDebug(msg, pQInfo, "only-first stable", pQueryAttr->order.order, TSDB_ORDER_ASC, + pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); - doExchangeTimeWindow(pQInfo, &pQuery->window); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); } - pQuery->order.order = TSDB_ORDER_ASC; - } else if (onlyLastQuery(pQuery)) { - if (QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "only-last stable", pQuery->order.order, TSDB_ORDER_DESC, - pQuery->window.skey, pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); + pQueryAttr->order.order = TSDB_ORDER_ASC; + } else if (onlyLastQuery(pQueryAttr)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { + qDebug(msg, pQInfo, "only-last stable", pQueryAttr->order.order, TSDB_ORDER_DESC, + pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); - doExchangeTimeWindow(pQInfo, &pQuery->window); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); } - pQuery->order.order = TSDB_ORDER_DESC; + pQueryAttr->order.order = TSDB_ORDER_DESC; } } } } static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t MIN_ROWS_PER_PAGE = 4; - *rowsize = (int32_t)(pQuery->resultRowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pQuery->topBotQuery, pQuery->stableQuery)); + *rowsize = (int32_t)(pQueryAttr->resultRowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); int32_t overhead = sizeof(tFilePage); // one page contains at least two rows @@ -2314,17 +2218,17 @@ static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, i #define IS_PREFILTER_TYPE(_t) ((_t) != TSDB_DATA_TYPE_BINARY && (_t) != TSDB_DATA_TYPE_NCHAR) static bool doFilterByBlockStatistics(SQueryRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis, SQLFunctionCtx *pCtx, int32_t numOfRows) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - if (pDataStatis == NULL || pQuery->numOfFilterCols == 0) { + if (pDataStatis == NULL || pQueryAttr->numOfFilterCols == 0) { return true; } - for (int32_t k = 0; k < pQuery->numOfFilterCols; ++k) { - SSingleColumnFilterInfo *pFilterInfo = &pQuery->pFilterInfo[k]; + for (int32_t k = 0; k < pQueryAttr->numOfFilterCols; ++k) { + SSingleColumnFilterInfo *pFilterInfo = &pQueryAttr->pFilterInfo[k]; int32_t index = -1; - for(int32_t i = 0; i < pQuery->numOfCols; ++i) { + for(int32_t i = 0; i < pQueryAttr->numOfCols; ++i) { if (pDataStatis[i].colId == pFilterInfo->info.colId) { index = i; break; @@ -2378,14 +2282,14 @@ static bool doFilterByBlockStatistics(SQueryRuntimeEnv* pRuntimeEnv, SDataStatis return false; } -static bool overlapWithTimeWindow(SQuery* pQuery, SDataBlockInfo* pBlockInfo) { +static bool overlapWithTimeWindow(SQueryAttr* pQueryAttr, SDataBlockInfo* pBlockInfo) { STimeWindow w = {0}; - TSKEY sk = MIN(pQuery->window.skey, pQuery->window.ekey); - TSKEY ek = MAX(pQuery->window.skey, pQuery->window.ekey); + TSKEY sk = MIN(pQueryAttr->window.skey, pQueryAttr->window.ekey); + TSKEY ek = MAX(pQueryAttr->window.skey, pQueryAttr->window.ekey); - if (QUERY_IS_ASC_QUERY(pQuery)) { - getAlignQueryTimeWindow(pQuery, pBlockInfo->window.skey, sk, ek, &w); + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { + getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.skey, sk, ek, &w); assert(w.ekey >= pBlockInfo->window.skey); if (w.ekey < pBlockInfo->window.ekey) { @@ -2393,7 +2297,7 @@ static bool overlapWithTimeWindow(SQuery* pQuery, SDataBlockInfo* pBlockInfo) { } while(1) { - getNextTimeWindow(pQuery, &w); + getNextTimeWindow(pQueryAttr, &w); if (w.skey > pBlockInfo->window.ekey) { break; } @@ -2404,7 +2308,7 @@ static bool overlapWithTimeWindow(SQuery* pQuery, SDataBlockInfo* pBlockInfo) { } } } else { - getAlignQueryTimeWindow(pQuery, pBlockInfo->window.ekey, sk, ek, &w); + getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w); assert(w.skey <= pBlockInfo->window.ekey); if (w.skey > pBlockInfo->window.skey) { @@ -2412,7 +2316,7 @@ static bool overlapWithTimeWindow(SQuery* pQuery, SDataBlockInfo* pBlockInfo) { } while(1) { - getNextTimeWindow(pQuery, &w); + getNextTimeWindow(pQueryAttr, &w); if (w.ekey < pBlockInfo->window.skey) { break; } @@ -2432,7 +2336,7 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key, bool asc #if defined(_DEBUG_VIEW) printf("elem in comp ts file:%" PRId64 ", key:%" PRId64 ", tag:%"PRIu64", query order:%d, ts order:%d, traverse:%d, index:%d\n", - elem.ts, key, elem.tag.i64, pQuery->order.order, pRuntimeEnv->pTsBuf->tsOrder, + elem.ts, key, elem.tag.i64, pQueryAttr->order.order, pRuntimeEnv->pTsBuf->tsOrder, pRuntimeEnv->pTsBuf->cur.order, pRuntimeEnv->pTsBuf->cur.tsIndex); #endif @@ -2454,7 +2358,7 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key, bool asc } void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, - SSDataBlock* pBlock, bool ascQuery) { + SSDataBlock* pBlock, bool ascQuery) { int32_t numOfRows = pBlock->info.rows; int8_t *p = calloc(numOfRows, sizeof(int8_t)); @@ -2483,7 +2387,7 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf } // save the cursor status - pRuntimeEnv->pQuery->current->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf); + pRuntimeEnv->current->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf); } else { for (int32_t i = 0; i < numOfRows; ++i) { bool qualified = false; @@ -2570,11 +2474,11 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf if (start > 0) { SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, 0); - assert(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)); + 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)); + } } } @@ -2603,18 +2507,18 @@ static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSData return status; } -static void doSetFilterColumnInfo(SQuery* pQuery, SSDataBlock* pBlock) { - if (pQuery->numOfFilterCols > 0 && pQuery->pFilterInfo[0].pData != NULL) { +static void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock) { + if (numOfFilterCols > 0 && pFilterInfo[0].pData != NULL) { return; } // set the initial static data value filter expression - for (int32_t i = 0; i < pQuery->numOfFilterCols; ++i) { + for (int32_t i = 0; i < numOfFilterCols; ++i) { for (int32_t j = 0; j < pBlock->info.numOfCols; ++j) { SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, j); - if (pQuery->pFilterInfo[i].info.colId == pColInfo->info.colId) { - pQuery->pFilterInfo[i].pData = pColInfo->pData; + if (pFilterInfo[i].info.colId == pColInfo->info.colId) { + pFilterInfo[i].pData = pColInfo->pData; break; } } @@ -2627,26 +2531,25 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa pBlock->pDataBlock = NULL; pBlock->pBlockStatis = NULL; - SQInfo* pQInfo = pRuntimeEnv->qinfo; - SQuery* pQuery = pRuntimeEnv->pQuery; - - int64_t groupId = pQuery->current->groupIndex; - bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int64_t groupId = pRuntimeEnv->current->groupIndex; + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); + SQInfo* pQInfo = pRuntimeEnv->qinfo; SQueryCostInfo* pCost = &pQInfo->summary; if (pRuntimeEnv->pTsBuf != NULL) { (*status) = BLK_DATA_ALL_NEEDED; - if (pQuery->stableQuery) { // todo refactor + if (pQueryAttr->stableQuery) { // todo refactor SExprInfo* pExprInfo = &pTableScanInfo->pExpr[0]; - int16_t tagId = (int16_t)pExprInfo->base.arg->argValue.i64; - SColumnInfo* pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagId); + int16_t tagId = (int16_t)pExprInfo->base.param[0].i64; + SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagId); // compare tag first tVariant t = {0}; - doSetTagValueInParam(pQuery->current->pTable, tagId, &t, pColInfo->type, pColInfo->bytes); - setTimestampListJoinInfo(pRuntimeEnv, &t, pQuery->current); + doSetTagValueInParam(pRuntimeEnv->current->pTable, tagId, &t, pColInfo->type, pColInfo->bytes); + setTimestampListJoinInfo(pRuntimeEnv, &t, pRuntimeEnv->current); STSElem elem = tsBufGetElem(pRuntimeEnv->pTsBuf); if (!tsBufIsValidElem(&elem) || (tsBufIsValidElem(&elem) && (tVariantCompare(&t, elem.tag) != 0))) { @@ -2658,8 +2561,8 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa // Calculate all time windows that are overlapping or contain current data block. // If current data block is contained by all possible time window, do not load current data block. - if (pQuery->numOfFilterCols > 0 || pQuery->groupbyColumn || pQuery->sw.gap > 0 || - (QUERY_IS_INTERVAL_QUERY(pQuery) && overlapWithTimeWindow(pQuery, &pBlock->info))) { + if (pQueryAttr->numOfFilterCols > 0 || pQueryAttr->groupbyColumn || pQueryAttr->sw.gap > 0 || + (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pQueryAttr, &pBlock->info))) { (*status) = BLK_DATA_ALL_NEEDED; } @@ -2667,29 +2570,29 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa if ((*status) != BLK_DATA_ALL_NEEDED) { // the pCtx[i] result is belonged to previous time window since the outputBuf has not been set yet, // the filter result may be incorrect. So in case of interval query, we need to set the correct time output buffer - if (QUERY_IS_INTERVAL_QUERY(pQuery)) { + if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { SResultRow* pResult = NULL; bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey; - STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQuery); + STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr); if (setWindowOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, &win, masterScan, &pResult, groupId, pTableScanInfo->pCtx, pTableScanInfo->numOfOutput, pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) { longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } - } else if (pQuery->stableQuery && (!isTsCompQuery(pQuery))) { // stable aggregate, not interval aggregate or normal column aggregate + } else if (pQueryAttr->stableQuery && (!pQueryAttr->tsCompQuery)) { // stable aggregate, not interval aggregate or normal column aggregate doSetTableGroupOutputBuf(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx, pTableScanInfo->rowCellInfoOffset, pTableScanInfo->numOfOutput, - pQuery->current->groupIndex); + pRuntimeEnv->current->groupIndex); } (*status) = doFilterByBlockTimeWindow(pTableScanInfo, pBlock); } SDataBlockInfo* pBlockInfo = &pBlock->info; - *status = updateBlockLoadStatus(pRuntimeEnv->pQuery, *status); + *status = updateBlockLoadStatus(pRuntimeEnv->pQueryAttr, *status); if ((*status) == BLK_DATA_NO_NEEDED || (*status) == BLK_DATA_DISCARD) { qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey, @@ -2711,15 +2614,15 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa pCost->loadBlockStatis += 1; tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pQueryHandle, &pBlock->pBlockStatis); - if (pQuery->topBotQuery && pBlock->pBlockStatis != NULL) { + if (pQueryAttr->topBotQuery && pBlock->pBlockStatis != NULL) { { // set previous window - if (QUERY_IS_INTERVAL_QUERY(pQuery)) { + if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { SResultRow* pResult = NULL; bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey; - STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQuery); + STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr); if (setWindowOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, &win, masterScan, &pResult, groupId, pTableScanInfo->pCtx, pTableScanInfo->numOfOutput, pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) { @@ -2728,7 +2631,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa } } bool load = false; - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { int32_t functionId = pTableScanInfo->pCtx[i].functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { load = topbot_datablock_filter(&pTableScanInfo->pCtx[i], (char*)&(pBlock->pBlockStatis[i].min), @@ -2760,9 +2663,9 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa return terrno; } - doSetFilterColumnInfo(pQuery, pBlock); - if (pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL) { - filterRowsInDataBlock(pRuntimeEnv, pQuery->pFilterInfo, pQuery->numOfFilterCols, pBlock, ascQuery); + doSetFilterColumnInfo(pQueryAttr->pFilterInfo, pQueryAttr->numOfFilterCols, pBlock); + if (pQueryAttr->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL) { + filterRowsInDataBlock(pRuntimeEnv, pQueryAttr->pFilterInfo, pQueryAttr->numOfFilterCols, pBlock, ascQuery); } } @@ -2877,22 +2780,22 @@ static SColumnInfo* doGetTagColumnInfoById(SColumnInfo* pTagColList, int32_t num void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCtx, int32_t numOfOutput) { SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SExprInfo *pExpr = pOperatorInfo->pExpr; - SQuery *pQuery = pRuntimeEnv->pQuery; + SExprInfo *pExpr = pOperatorInfo->pExpr; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SExprInfo* pExprInfo = &pExpr[0]; - if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP && pQuery->stableQuery) { + if (pQueryAttr->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP && pQueryAttr->stableQuery) { assert(pExprInfo->base.numOfParams == 1); - int16_t tagColId = (int16_t)pExprInfo->base.arg->argValue.i64; - SColumnInfo* pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagColId); + int16_t tagColId = (int16_t)pExprInfo->base.param[0].i64; + SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId); doSetTagValueInParam(pTable, tagColId, &pCtx[0].tag, pColInfo->type, pColInfo->bytes); return; } else { // set tag value, by which the results are aggregated. int32_t offset = 0; - memset(pRuntimeEnv->tagVal, 0, pQuery->tagLen); + memset(pRuntimeEnv->tagVal, 0, pQueryAttr->tagLen); for (int32_t idx = 0; idx < numOfOutput; ++idx) { SExprInfo* pLocalExprInfo = &pExpr[idx]; @@ -2903,20 +2806,20 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt } // todo use tag column index to optimize performance - doSetTagValueInParam(pTable, pLocalExprInfo->base.colInfo.colId, &pCtx[idx].tag, pLocalExprInfo->type, - pLocalExprInfo->bytes); + doSetTagValueInParam(pTable, pLocalExprInfo->base.colInfo.colId, &pCtx[idx].tag, pLocalExprInfo->base.resType, + pLocalExprInfo->base.resBytes); - if (IS_NUMERIC_TYPE(pLocalExprInfo->type) || pLocalExprInfo->type == TSDB_DATA_TYPE_BOOL) { - memcpy(pRuntimeEnv->tagVal + offset, &pCtx[idx].tag.i64, pLocalExprInfo->bytes); + if (IS_NUMERIC_TYPE(pLocalExprInfo->base.resType) || pLocalExprInfo->base.resType == TSDB_DATA_TYPE_BOOL) { + memcpy(pRuntimeEnv->tagVal + offset, &pCtx[idx].tag.i64, pLocalExprInfo->base.resBytes); } else { memcpy(pRuntimeEnv->tagVal + offset, pCtx[idx].tag.pz, pCtx[idx].tag.nLen); } - offset += pLocalExprInfo->bytes; + offset += pLocalExprInfo->base.resBytes; } //todo : use index to avoid iterator all possible output columns - if (pQuery->stableQuery && pQuery->stabledev && (pRuntimeEnv->prevResult != NULL)) { + if (pQueryAttr->stableQuery && pQueryAttr->stabledev && (pRuntimeEnv->prevResult != NULL)) { setParamForStableStddev(pRuntimeEnv, pCtx, numOfOutput, pExprInfo); } } @@ -2997,32 +2900,32 @@ static UNUSED_FUNC void printBinaryData(int32_t functionId, char *data, int32_t } void UNUSED_FUNC displayInterResult(tFilePage **pdata, SQueryRuntimeEnv* pRuntimeEnv, int32_t numOfRows) { - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t numOfCols = pQuery->numOfOutput; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t numOfCols = pQueryAttr->numOfOutput; printf("super table query intermediate result, total:%d\n", numOfRows); for (int32_t j = 0; j < numOfRows; ++j) { for (int32_t i = 0; i < numOfCols; ++i) { - switch (pQuery->pExpr1[i].type) { + switch (pQueryAttr->pExpr1[i].base.resType) { case TSDB_DATA_TYPE_BINARY: { - int32_t type = pQuery->pExpr1[i].type; - printBinaryData(pQuery->pExpr1[i].base.functionId, pdata[i]->data + pQuery->pExpr1[i].bytes * j, + int32_t type = pQueryAttr->pExpr1[i].base.resType; + printBinaryData(pQueryAttr->pExpr1[i].base.functionId, pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j, type); break; } case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_BIGINT: - printf("%" PRId64 "\t", *(int64_t *)(pdata[i]->data + pQuery->pExpr1[i].bytes * j)); + printf("%" PRId64 "\t", *(int64_t *)(pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j)); break; case TSDB_DATA_TYPE_INT: - printf("%d\t", *(int32_t *)(pdata[i]->data + pQuery->pExpr1[i].bytes * j)); + printf("%d\t", *(int32_t *)(pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j)); break; case TSDB_DATA_TYPE_FLOAT: - printf("%f\t", *(float *)(pdata[i]->data + pQuery->pExpr1[i].bytes * j)); + printf("%f\t", *(float *)(pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j)); break; case TSDB_DATA_TYPE_DOUBLE: - printf("%lf\t", *(double *)(pdata[i]->data + pQuery->pExpr1[i].bytes * j)); + printf("%lf\t", *(double *)(pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j)); break; } } @@ -3062,7 +2965,7 @@ void copyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, int32_t threshold, SSDataBl } -static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo *pTableQueryInfo) { +static void updateTableQueryInfoForReverseScan(SQueryAttr *pQueryAttr, STableQueryInfo *pTableQueryInfo) { if (pTableQueryInfo == NULL) { return; } @@ -3078,17 +2981,17 @@ static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo * } static void setupQueryRangeForReverseScan(SQueryRuntimeEnv* pRuntimeEnv) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfGroups = (int32_t)(GET_NUM_OF_TABLEGROUP(pRuntimeEnv)); for(int32_t i = 0; i < numOfGroups; ++i) { SArray *group = GET_TABLEGROUP(pRuntimeEnv, i); - SArray *tableKeyGroup = taosArrayGetP(pQuery->tableGroupInfo.pGroupList, i); + SArray *tableKeyGroup = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); size_t t = taosArrayGetSize(group); for (int32_t j = 0; j < t; ++j) { STableQueryInfo *pCheckInfo = taosArrayGetP(group, j); - updateTableQueryInfoForReverseScan(pQuery, pCheckInfo); + updateTableQueryInfoForReverseScan(pQueryAttr, pCheckInfo); // update the last key in tableKeyInfo list, the tableKeyInfo is used to build the tsdbQueryHandle and decide // the start check timestamp of tsdbQueryHandle @@ -3121,7 +3024,7 @@ int32_t initResultRow(SResultRow *pResultRow) { * +------------+-------------------------------------------+-------------------------------------------+ * offset[0] offset[1] */ -void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, int64_t uid) { +void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, int64_t uid, int32_t stage) { SQLFunctionCtx* pCtx = pInfo->pCtx; SSDataBlock* pDataBlock = pInfo->pRes; int32_t* rowCellInfoOffset = pInfo->rowCellInfoOffset; @@ -3140,8 +3043,9 @@ void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, i SResultRowCellInfo* pCellInfo = getResultCell(pRow, i, rowCellInfoOffset); RESET_RESULT_INFO(pCellInfo); - pCtx[i].resultInfo = pCellInfo; - pCtx[i].pOutput = pData->pData; + pCtx[i].resultInfo = pCellInfo; + pCtx[i].pOutput = pData->pData; + pCtx[i].currentStage = stage; assert(pCtx[i].pOutput != NULL); // set the timestamp output buffer for top/bottom/diff query @@ -3154,21 +3058,21 @@ void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, i initCtxOutputBuffer(pCtx, pDataBlock->info.numOfCols); } -void updateOutputBuf(SArithOperatorInfo* pInfo, int32_t numOfInputRows) { - SOptrBasicInfo* pBInfo = &pInfo->binfo; +void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOfInputRows) { SSDataBlock* pDataBlock = pBInfo->pRes; - int32_t newSize = pDataBlock->info.rows + numOfInputRows; - if (pInfo->bufCapacity < newSize) { + int32_t newSize = pDataBlock->info.rows + numOfInputRows + 5; // extra output buffer + if ((*bufCapacity) < newSize) { for(int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) { SColumnInfoData *pColInfo = taosArrayGet(pDataBlock->pDataBlock, i); + char* p = realloc(pColInfo->pData, newSize * pColInfo->info.bytes); if (p != NULL) { pColInfo->pData = p; // it starts from the tail of the previously generated results. pBInfo->pCtx[i].pOutput = pColInfo->pData; - pInfo->bufCapacity = newSize; + (*bufCapacity) = newSize; } else { // longjmp } @@ -3209,7 +3113,7 @@ void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status) { } static void setupEnvForReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, SQLFunctionCtx* pCtx, int32_t numOfOutput) { - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; if (pRuntimeEnv->pTsBuf) { SWITCH_ORDER(pRuntimeEnv->pTsBuf->cur.order); @@ -3218,25 +3122,25 @@ static void setupEnvForReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo } // reverse order time range - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); SET_REVERSE_SCAN_FLAG(pRuntimeEnv); setQueryStatus(pRuntimeEnv, QUERY_NOT_COMPLETED); switchCtxOrder(pCtx, numOfOutput); - SWITCH_ORDER(pQuery->order.order); + SWITCH_ORDER(pQueryAttr->order.order); setupQueryRangeForReverseScan(pRuntimeEnv); } void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfOutput = pOperator->numOfOutput; - if (pQuery->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQuery) || pQuery->sw.gap > 0) { + if (pQueryAttr->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQueryAttr) || pQueryAttr->sw.gap > 0) { // for each group result, call the finalize function for each column - if (pQuery->groupbyColumn) { + if (pQueryAttr->groupbyColumn) { closeAllResultRows(pResultRowInfo); } @@ -3266,9 +3170,9 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult } } -static bool hasMainOutput(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; +static bool hasMainOutput(SQueryAttr *pQueryAttr) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; if (functionId != TSDB_FUNC_TS && functionId != TSDB_FUNC_TAG && functionId != TSDB_FUNC_TAGPRJ) { return true; @@ -3278,7 +3182,7 @@ static bool hasMainOutput(SQuery *pQuery) { return false; } -static STableQueryInfo *createTableQueryInfo(SQuery* pQuery, void* pTable, bool groupbyColumn, STimeWindow win, void* buf) { +STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf) { STableQueryInfo *pTableQueryInfo = buf; pTableQueryInfo->win = win; @@ -3288,7 +3192,7 @@ static STableQueryInfo *createTableQueryInfo(SQuery* pQuery, void* pTable, bool pTableQueryInfo->cur.vgroupIndex = -1; // set more initial size of interval/groupby query - if (QUERY_IS_INTERVAL_QUERY(pQuery) || groupbyColumn) { + if (QUERY_IS_INTERVAL_QUERY(pQueryAttr) || groupbyColumn) { int32_t initialSize = 128; int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize, TSDB_DATA_TYPE_INT); if (code != TSDB_CODE_SUCCESS) { @@ -3324,7 +3228,7 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe continue; } - pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv, bufPage, pResult->offset, offset, pCtx[i].outputBytes); + pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv->pQueryAttr, bufPage, pResult->offset, offset); offset += pCtx[i].outputBytes; int32_t functionId = pCtx[i].functionId; @@ -3350,7 +3254,7 @@ void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pRe * all group belong to one result set, and each group result has different group id so set the id to be one */ if (pResultRow->pageId == -1) { - int32_t ret = addNewWindowResultBuf(pResultRow, pRuntimeEnv->pResultBuf, groupIndex, pRuntimeEnv->pQuery->resultRowSize); + int32_t ret = addNewWindowResultBuf(pResultRow, pRuntimeEnv->pResultBuf, groupIndex, pRuntimeEnv->pQueryAttr->resultRowSize); if (ret != TSDB_CODE_SUCCESS) { return; } @@ -3361,7 +3265,7 @@ void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pRe void setExecutionContext(SQueryRuntimeEnv* pRuntimeEnv, SOptrBasicInfo* pInfo, int32_t numOfOutput, int32_t groupIndex, TSKEY nextKey) { - STableQueryInfo *pTableQueryInfo = pRuntimeEnv->pQuery->current; + STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current; // lastKey needs to be updated pTableQueryInfo->lastKey = nextKey; @@ -3382,7 +3286,7 @@ void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLF int16_t offset = 0; for (int32_t i = 0; i < numOfCols; ++i) { - pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv, page, pResult->offset, offset, pCtx[i].outputBytes); + pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, pResult->offset, offset); offset += pCtx[i].outputBytes; int32_t functionId = pCtx[i].functionId; @@ -3399,32 +3303,32 @@ void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLF } void setCtxTagForJoin(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - SSqlFuncMsg* pFuncMsg = &pExprInfo->base; - if (pQuery->stableQuery && (pRuntimeEnv->pTsBuf != NULL) && - (pFuncMsg->functionId == TSDB_FUNC_TS || pFuncMsg->functionId == TSDB_FUNC_PRJ) && - (pFuncMsg->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { - assert(pFuncMsg->numOfParams == 1); + SSqlExpr* pExpr = &pExprInfo->base; + if (pQueryAttr->stableQuery && (pRuntimeEnv->pTsBuf != NULL) && + (pExpr->functionId == TSDB_FUNC_TS || pExpr->functionId == TSDB_FUNC_PRJ) && + (pExpr->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { + assert(pExpr->numOfParams == 1); - int16_t tagColId = (int16_t)pExprInfo->base.arg->argValue.i64; - SColumnInfo* pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagColId); + int16_t tagColId = (int16_t)pExprInfo->base.param[0].i64; + SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId); doSetTagValueInParam(pTable, tagColId, &pCtx->tag, pColInfo->type, pColInfo->bytes); int16_t tagType = pCtx[0].tag.nType; if (tagType == TSDB_DATA_TYPE_BINARY || tagType == TSDB_DATA_TYPE_NCHAR) { qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%s", GET_QID(pRuntimeEnv), - pExprInfo->base.arg->argValue.i64, pCtx[0].tag.pz); + pExprInfo->base.param[0].i64, pCtx[0].tag.pz); } else { qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%" PRId64, GET_QID(pRuntimeEnv), - pExprInfo->base.arg->argValue.i64, pCtx[0].tag.i64); + pExprInfo->base.param[0].i64, pCtx[0].tag.i64); } } } int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, STableQueryInfo *pTableQueryInfo) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; assert(pRuntimeEnv->pTsBuf != NULL); @@ -3432,7 +3336,7 @@ int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, if (pTableQueryInfo->cur.vgroupIndex == -1) { tVariantAssign(&pTableQueryInfo->tag, pTag); - STSElem elem = tsBufGetElemStartPos(pRuntimeEnv->pTsBuf, pQuery->vgId, &pTableQueryInfo->tag); + STSElem elem = tsBufGetElemStartPos(pRuntimeEnv->pTsBuf, pQueryAttr->vgId, &pTableQueryInfo->tag); // failed to find data with the specified tag value and vnodeId if (!tsBufIsValidElem(&elem)) { @@ -3465,17 +3369,17 @@ int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, return 0; } -void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr) { - SQuery* pQuery = pRuntimeEnv->pQuery; +void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExprInfo) { + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - int32_t numOfExprs = pQuery->numOfOutput; + int32_t numOfExprs = pQueryAttr->numOfOutput; for(int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExprInfo = &(pExpr[i]); - if (pExprInfo->base.functionId != TSDB_FUNC_STDDEV_DST) { + SExprInfo* pExprInfo1 = &(pExprInfo[i]); + if (pExprInfo1->base.functionId != TSDB_FUNC_STDDEV_DST) { continue; } - SSqlFuncMsg* pFuncMsg = &pExprInfo->base; + SSqlExpr* pExpr = &pExprInfo1->base; pCtx[i].param[0].arr = NULL; pCtx[i].param[0].nType = TSDB_DATA_TYPE_INT; // avoid freeing the memory by setting the type to be int @@ -3484,11 +3388,11 @@ void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx int32_t numOfGroup = (int32_t)taosArrayGetSize(pRuntimeEnv->prevResult); for (int32_t j = 0; j < numOfGroup; ++j) { SInterResult* p = taosArrayGet(pRuntimeEnv->prevResult, j); - if (pQuery->tagLen == 0 || memcmp(p->tags, pRuntimeEnv->tagVal, pQuery->tagLen) == 0) { + if (pQueryAttr->tagLen == 0 || memcmp(p->tags, pRuntimeEnv->tagVal, pQueryAttr->tagLen) == 0) { int32_t numOfCols = (int32_t)taosArrayGetSize(p->pResult); for (int32_t k = 0; k < numOfCols; ++k) { SStddevInterResult* pres = taosArrayGet(p->pResult, k); - if (pres->colId == pFuncMsg->colInfo.colId) { + if (pres->colId == pExpr->colInfo.colId) { pCtx[i].param[0].arr = pres->pResult; break; } @@ -3500,17 +3404,15 @@ void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx } void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr, char* val, int16_t bytes) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - int32_t numOfExprs = pQuery->numOfOutput; + int32_t numOfExprs = pQueryAttr->numOfOutput; for(int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExprInfo = &(pExpr[i]); - if (pExprInfo->base.functionId != TSDB_FUNC_STDDEV_DST) { + SSqlExpr* pExpr1 = &pExpr[i].base; + if (pExpr1->functionId != TSDB_FUNC_STDDEV_DST) { continue; } - SSqlFuncMsg* pFuncMsg = &pExprInfo->base; - pCtx[i].param[0].arr = NULL; pCtx[i].param[0].nType = TSDB_DATA_TYPE_INT; // avoid freeing the memory by setting the type to be int @@ -3522,7 +3424,7 @@ void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunction int32_t numOfCols = (int32_t)taosArrayGetSize(p->pResult); for (int32_t k = 0; k < numOfCols; ++k) { SStddevInterResult* pres = taosArrayGet(p->pResult, k); - if (pres->colId == pFuncMsg->colInfo.colId) { + if (pres->colId == pExpr1->colInfo.colId) { pCtx[i].param[0].arr = pres->pResult; break; } @@ -3530,23 +3432,20 @@ void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunction } } } - } - - /* * There are two cases to handle: * - * 1. Query range is not set yet (queryRangeSet = 0). we need to set the query range info, including pQuery->lastKey, - * pQuery->window.skey, and pQuery->eKey. + * 1. Query range is not set yet (queryRangeSet = 0). we need to set the query range info, including pQueryAttr->lastKey, + * pQueryAttr->window.skey, and pQueryAttr->eKey. * 2. Query range is set and query is in progress. There may be another result with the same query ranges to be * merged during merge stage. In this case, we need the pTableQueryInfo->lastResRows to decide if there * is a previous result generated or not. */ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { - SQuery *pQuery = pRuntimeEnv->pQuery; - STableQueryInfo *pTableQueryInfo = pQuery->current; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current; SResultRowInfo *pWindowResInfo = &pTableQueryInfo->resInfo; if (pWindowResInfo->prevSKey != TSKEY_INITIAL_VAL) { @@ -3554,7 +3453,7 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { } pTableQueryInfo->win.skey = key; - STimeWindow win = {.skey = key, .ekey = pQuery->window.ekey}; + STimeWindow win = {.skey = key, .ekey = pQueryAttr->window.ekey}; /** * In handling the both ascending and descending order super table query, we need to find the first qualified @@ -3566,11 +3465,11 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { TSKEY sk = MIN(win.skey, win.ekey); TSKEY ek = MAX(win.skey, win.ekey); - getAlignQueryTimeWindow(pQuery, win.skey, sk, ek, &w); + getAlignQueryTimeWindow(pQueryAttr, win.skey, sk, ek, &w); if (pWindowResInfo->prevSKey == TSKEY_INITIAL_VAL) { - if (!QUERY_IS_ASC_QUERY(pQuery)) { - assert(win.ekey == pQuery->window.ekey); + if (!QUERY_IS_ASC_QUERY(pQueryAttr)) { + assert(win.ekey == pQueryAttr->window.ekey); } pWindowResInfo->prevSKey = w.skey; @@ -3590,6 +3489,8 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { */ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock) { + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); int32_t numOfResult = pBlock->info.rows; // there are already exists result rows @@ -3624,7 +3525,7 @@ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* int32_t bytes = pColInfoData->info.bytes; char *out = pColInfoData->pData + numOfResult * bytes; - char *in = getPosInResultPage(pRuntimeEnv, page, pRow->offset, offset, bytes); + char *in = getPosInResultPage(pQueryAttr, page, pRow->offset, offset); memcpy(out, in, bytes * numOfRowsToCopy); offset += bytes; @@ -3649,10 +3550,11 @@ static void toSSDataBlock(SGroupResInfo *pGroupResInfo, SQueryRuntimeEnv* pRunti return; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t orderType = (pQuery->pGroupbyExpr != NULL) ? pQuery->pGroupbyExpr->orderType : TSDB_ORDER_ASC; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t orderType = (pQueryAttr->pGroupbyExpr != NULL) ? pQueryAttr->pGroupbyExpr->orderType : TSDB_ORDER_ASC; doCopyToSDataBlock(pRuntimeEnv, pGroupResInfo, orderType, pBlock); + // refactor : extract method SColumnInfoData* pInfoData = taosArrayGet(pBlock->pDataBlock, 0); if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP) { @@ -3662,12 +3564,12 @@ static void toSSDataBlock(SGroupResInfo *pGroupResInfo, SQueryRuntimeEnv* pRunti } } -static void updateNumOfRowsInResultRows(SQueryRuntimeEnv *pRuntimeEnv, - SQLFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { - SQuery *pQuery = pRuntimeEnv->pQuery; +static void updateNumOfRowsInResultRows(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, + SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; // update the number of result for each, only update the number of rows for the corresponding window result. - if (QUERY_IS_INTERVAL_QUERY(pQuery)) { + if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { return; } @@ -3688,18 +3590,18 @@ static void updateNumOfRowsInResultRows(SQueryRuntimeEnv *pRuntimeEnv, static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data) { SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SSDataBlock* pRes = pRuntimeEnv->outputBuf; - if (pQuery->pExpr2 == NULL) { - for (int32_t col = 0; col < pQuery->numOfOutput; ++col) { + if (pQueryAttr->pExpr2 == NULL) { + for (int32_t col = 0; col < pQueryAttr->numOfOutput; ++col) { SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, col); memmove(data, pColRes->pData, pColRes->info.bytes * pRes->info.rows); data += pColRes->info.bytes * pRes->info.rows; } } else { - for (int32_t col = 0; col < pQuery->numOfExpr2; ++col) { + for (int32_t col = 0; col < pQueryAttr->numOfExpr2; ++col) { SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, col); memmove(data, pColRes->pData, pColRes->info.bytes * numOfRows); data += pColRes->info.bytes * numOfRows; @@ -3775,34 +3677,34 @@ void queryCostStatis(SQInfo *pQInfo) { } //static void updateOffsetVal(SQueryRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) { -// SQuery *pQuery = pRuntimeEnv->pQuery; -// STableQueryInfo* pTableQueryInfo = pQuery->current; +// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; // -// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); +// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); // -// if (pQuery->limit.offset == pBlockInfo->rows) { // current block will ignore completed -// pTableQueryInfo->lastKey = QUERY_IS_ASC_QUERY(pQuery) ? pBlockInfo->window.ekey + step : pBlockInfo->window.skey + step; -// pQuery->limit.offset = 0; +// if (pQueryAttr->limit.offset == pBlockInfo->rows) { // current block will ignore completed +// pTableQueryInfo->lastKey = QUERY_IS_ASC_QUERY(pQueryAttr) ? pBlockInfo->window.ekey + step : pBlockInfo->window.skey + step; +// pQueryAttr->limit.offset = 0; // return; // } // -// if (QUERY_IS_ASC_QUERY(pQuery)) { -// pQuery->pos = (int32_t)pQuery->limit.offset; +// if (QUERY_IS_ASC_QUERY(pQueryAttr)) { +// pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset; // } else { -// pQuery->pos = pBlockInfo->rows - (int32_t)pQuery->limit.offset - 1; +// pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1; // } // -// assert(pQuery->pos >= 0 && pQuery->pos <= pBlockInfo->rows - 1); +// assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1); // // SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pQueryHandle, NULL); // SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0); // -// // update the pQuery->limit.offset value, and pQuery->pos value +// // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value // TSKEY *keys = (TSKEY *) pColInfoData->pData; // // // update the offset value -// pTableQueryInfo->lastKey = keys[pQuery->pos]; -// pQuery->limit.offset = 0; +// pTableQueryInfo->lastKey = keys[pQueryAttr->pos]; +// pQueryAttr->limit.offset = 0; // // int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock); // @@ -3811,16 +3713,16 @@ void queryCostStatis(SQInfo *pQInfo) { //} //void skipBlocks(SQueryRuntimeEnv *pRuntimeEnv) { -// SQuery *pQuery = pRuntimeEnv->pQuery; +// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // -// if (pQuery->limit.offset <= 0 || pQuery->numOfFilterCols > 0) { +// if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) { // return; // } // -// pQuery->pos = 0; -// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); +// pQueryAttr->pos = 0; +// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); // -// STableQueryInfo* pTableQueryInfo = pQuery->current; +// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; // TsdbQueryHandleT pQueryHandle = pRuntimeEnv->pQueryHandle; // // SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER; @@ -3831,9 +3733,9 @@ void queryCostStatis(SQInfo *pQInfo) { // // tsdbRetrieveDataBlockInfo(pQueryHandle, &blockInfo); // -// if (pQuery->limit.offset > blockInfo.rows) { -// pQuery->limit.offset -= blockInfo.rows; -// pTableQueryInfo->lastKey = (QUERY_IS_ASC_QUERY(pQuery)) ? blockInfo.window.ekey : blockInfo.window.skey; +// if (pQueryAttr->limit.offset > blockInfo.rows) { +// pQueryAttr->limit.offset -= blockInfo.rows; +// pTableQueryInfo->lastKey = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? blockInfo.window.ekey : blockInfo.window.skey; // pTableQueryInfo->lastKey += step; // // qDebug("QInfo:0x%"PRIx64" skip rows:%d, offset:%" PRId64, GET_QID(pRuntimeEnv), blockInfo.rows, @@ -3850,15 +3752,15 @@ void queryCostStatis(SQInfo *pQInfo) { //} //static TSKEY doSkipIntervalProcess(SQueryRuntimeEnv* pRuntimeEnv, STimeWindow* win, SDataBlockInfo* pBlockInfo, STableQueryInfo* pTableQueryInfo) { -// SQuery *pQuery = pRuntimeEnv->pQuery; +// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo; // -// assert(pQuery->limit.offset == 0); +// assert(pQueryAttr->limit.offset == 0); // STimeWindow tw = *win; -// getNextTimeWindow(pQuery, &tw); +// getNextTimeWindow(pQueryAttr, &tw); // -// if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) || -// (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQuery))) { +// if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) || +// (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) { // // // load the data block and check data remaining in current data block // // TODO optimize performance @@ -3867,15 +3769,15 @@ void queryCostStatis(SQInfo *pQInfo) { // // tw = *win; // int32_t startPos = -// getNextQualifiedWindow(pQuery, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1); +// getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1); // assert(startPos >= 0); // // // set the abort info -// pQuery->pos = startPos; +// pQueryAttr->pos = startPos; // // // reset the query start timestamp // pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos]; -// pQuery->window.skey = pTableQueryInfo->win.skey; +// pQueryAttr->window.skey = pTableQueryInfo->win.skey; // TSKEY key = pTableQueryInfo->win.skey; // // pWindowResInfo->prevSKey = tw.skey; @@ -3886,11 +3788,11 @@ void queryCostStatis(SQInfo *pQInfo) { // // qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%" PRId64, // GET_QID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, -// pQuery->current->lastKey); +// pQueryAttr->current->lastKey); // // return key; // } else { // do nothing -// pQuery->window.skey = tw.skey; +// pQueryAttr->window.skey = tw.skey; // pWindowResInfo->prevSKey = tw.skey; // pTableQueryInfo->lastKey = tw.skey; // @@ -3901,53 +3803,53 @@ void queryCostStatis(SQInfo *pQInfo) { //} //static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) { -// SQuery *pQuery = pRuntimeEnv->pQuery; -// if (QUERY_IS_ASC_QUERY(pQuery)) { -// assert(*start <= pQuery->current->lastKey); +// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +// if (QUERY_IS_ASC_QUERY(pQueryAttr)) { +// assert(*start <= pRuntimeEnv->current->lastKey); // } else { -// assert(*start >= pQuery->current->lastKey); +// assert(*start >= pRuntimeEnv->current->lastKey); // } // // // if queried with value filter, do NOT forward query start position -// if (pQuery->limit.offset <= 0 || pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL || pRuntimeEnv->pFillInfo != NULL) { +// if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL || pRuntimeEnv->pFillInfo != NULL) { // return true; // } // // /* -// * 1. for interval without interpolation query we forward pQuery->interval.interval at a time for -// * pQuery->limit.offset times. Since hole exists, pQuery->interval.interval*pQuery->limit.offset value is -// * not valid. otherwise, we only forward pQuery->limit.offset number of points +// * 1. for interval without interpolation query we forward pQueryAttr->interval.interval at a time for +// * pQueryAttr->limit.offset times. Since hole exists, pQueryAttr->interval.interval*pQueryAttr->limit.offset value is +// * not valid. otherwise, we only forward pQueryAttr->limit.offset number of points // */ // assert(pRuntimeEnv->resultRowInfo.prevSKey == TSKEY_INITIAL_VAL); // // STimeWindow w = TSWINDOW_INITIALIZER; -// bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); +// bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); // // SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo; -// STableQueryInfo *pTableQueryInfo = pQuery->current; +// STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current; // // SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER; // while (tsdbNextDataBlock(pRuntimeEnv->pQueryHandle)) { // tsdbRetrieveDataBlockInfo(pRuntimeEnv->pQueryHandle, &blockInfo); // -// if (QUERY_IS_ASC_QUERY(pQuery)) { +// if (QUERY_IS_ASC_QUERY(pQueryAttr)) { // if (pWindowResInfo->prevSKey == TSKEY_INITIAL_VAL) { -// getAlignQueryTimeWindow(pQuery, blockInfo.window.skey, blockInfo.window.skey, pQuery->window.ekey, &w); +// getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.skey, blockInfo.window.skey, pQueryAttr->window.ekey, &w); // pWindowResInfo->prevSKey = w.skey; // } // } else { -// getAlignQueryTimeWindow(pQuery, blockInfo.window.ekey, pQuery->window.ekey, blockInfo.window.ekey, &w); +// getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.ekey, pQueryAttr->window.ekey, blockInfo.window.ekey, &w); // pWindowResInfo->prevSKey = w.skey; // } // // // the first time window -// STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQuery); +// STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr); // -// while (pQuery->limit.offset > 0) { +// while (pQueryAttr->limit.offset > 0) { // STimeWindow tw = win; // // if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) { -// pQuery->limit.offset -= 1; +// pQueryAttr->limit.offset -= 1; // pWindowResInfo->prevSKey = win.skey; // // // current time window is aligned with blockInfo.window.ekey @@ -3957,13 +3859,13 @@ void queryCostStatis(SQInfo *pQInfo) { // } // } // -// if (pQuery->limit.offset == 0) { +// if (pQueryAttr->limit.offset == 0) { // *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo); // return true; // } // // // current window does not ended in current data block, try next data block -// getNextTimeWindow(pQuery, &tw); +// getNextTimeWindow(pQueryAttr, &tw); // // /* // * If the next time window still starts from current data block, @@ -3978,20 +3880,20 @@ void queryCostStatis(SQInfo *pQInfo) { // SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0); // // if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) { -// pQuery->limit.offset -= 1; +// pQueryAttr->limit.offset -= 1; // } // -// if (pQuery->limit.offset == 0) { +// if (pQueryAttr->limit.offset == 0) { // *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo); // return true; // } else { // tw = win; // int32_t startPos = -// getNextQualifiedWindow(pQuery, &tw, &blockInfo, pColInfoData->pData, binarySearchForKey, -1); +// getNextQualifiedWindow(pQueryAttr, &tw, &blockInfo, pColInfoData->pData, binarySearchForKey, -1); // assert(startPos >= 0); // // // set the abort info -// pQuery->pos = startPos; +// pQueryAttr->pos = startPos; // pTableQueryInfo->lastKey = ((TSKEY *)pColInfoData->pData)[startPos]; // pWindowResInfo->prevSKey = tw.skey; // win = tw; @@ -4012,26 +3914,25 @@ void queryCostStatis(SQInfo *pQInfo) { static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo); -static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) { - SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; +static int32_t setupQueryHandle(void* tsdb, SQueryRuntimeEnv* pRuntimeEnv, int64_t qId, bool isSTableQuery) { + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // TODO set the tags scan handle - if (onlyQueryTags(pQuery)) { + if (onlyQueryTags(pQueryAttr)) { return TSDB_CODE_SUCCESS; } - STsdbQueryCond cond = createTsdbQueryCond(pQuery, &pQuery->window); - if (isTsCompQuery(pQuery) || isPointInterpoQuery(pQuery)) { + STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window); + if (pQueryAttr->tsCompQuery || pQueryAttr->pointInterpQuery) { cond.type = BLOCK_LOAD_TABLE_SEQ_ORDER; } if (!isSTableQuery && (pRuntimeEnv->tableqinfoGroupInfo.numOfTables == 1) && (cond.order == TSDB_ORDER_ASC) - && (!QUERY_IS_INTERVAL_QUERY(pQuery)) - && (!isGroupbyColumn(pQuery->pGroupbyExpr)) - && (!isFixedOutputQuery(pQuery)) + && (!QUERY_IS_INTERVAL_QUERY(pQueryAttr)) + && (!pQueryAttr->groupbyColumn) + && (!pQueryAttr->simpleAgg) ) { SArray* pa = GET_TABLEGROUP(pRuntimeEnv, 0); STableQueryInfo* pCheckInfo = taosArrayGetP(pa, 0); @@ -4039,12 +3940,12 @@ static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) } terrno = TSDB_CODE_SUCCESS; - if (isFirstLastRowQuery(pQuery)) { - pRuntimeEnv->pQueryHandle = tsdbQueryLastRow(tsdb, &cond, &pQuery->tableGroupInfo, pQInfo->qId, &pQuery->memRef); + if (isFirstLastRowQuery(pQueryAttr)) { + pRuntimeEnv->pQueryHandle = tsdbQueryLastRow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef); // update the query time window - pQuery->window = cond.twindow; - if (pQuery->tableGroupInfo.numOfTables == 0) { + pQueryAttr->window = cond.twindow; + if (pQueryAttr->tableGroupInfo.numOfTables == 0) { pRuntimeEnv->tableqinfoGroupInfo.numOfTables = 0; } else { size_t numOfGroups = GET_NUM_OF_TABLEGROUP(pRuntimeEnv); @@ -4055,15 +3956,15 @@ static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) for (int32_t j = 0; j < t; ++j) { STableQueryInfo *pCheckInfo = taosArrayGetP(group, j); - pCheckInfo->win = pQuery->window; + pCheckInfo->win = pQueryAttr->window; pCheckInfo->lastKey = pCheckInfo->win.skey; } } } - } else if (isPointInterpoQuery(pQuery)) { - pRuntimeEnv->pQueryHandle = tsdbQueryRowsInExternalWindow(tsdb, &cond, &pQuery->tableGroupInfo, pQInfo->qId, &pQuery->memRef); + } else if (pQueryAttr->pointInterpQuery) { + pRuntimeEnv->pQueryHandle = tsdbQueryRowsInExternalWindow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef); } else { - pRuntimeEnv->pQueryHandle = tsdbQueryTables(tsdb, &cond, &pQuery->tableGroupInfo, pQInfo->qId, &pQuery->memRef); + pRuntimeEnv->pQueryHandle = tsdbQueryTables(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef); } return terrno; @@ -4080,82 +3981,92 @@ static SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, in for(int32_t i = 0; i < numOfOutput; ++i) { SExprInfo* pExprInfo = &pExpr[i]; - pFillCol[i].col.bytes = pExprInfo->bytes; - pFillCol[i].col.type = (int8_t)pExprInfo->type; + pFillCol[i].col.bytes = pExprInfo->base.resBytes; + pFillCol[i].col.type = (int8_t)pExprInfo->base.resType; pFillCol[i].col.offset = offset; + pFillCol[i].col.colId = pExprInfo->base.resColId; pFillCol[i].tagIndex = -2; - pFillCol[i].flag = TSDB_COL_NORMAL; // always be ta normal column for table query + pFillCol[i].flag = pExprInfo->base.colInfo.flag; // always be the normal column for table query pFillCol[i].functionId = pExprInfo->base.functionId; pFillCol[i].fillVal.i = fillVal[i]; - offset += pExprInfo->bytes; + offset += pExprInfo->base.resBytes; } return pFillCol; } -int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bool isSTableQuery) { +int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, SArray* prevResult, void* tsdb, void* sourceOptr, int32_t tbScanner, + SArray* pOperator, void* param) { SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; - pQuery->tsdb = tsdb; + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; + pQueryAttr->tsdb = tsdb; - pQuery->topBotQuery = isTopBottomQuery(pQuery); - pQuery->hasTagResults = hasTagValOutput(pQuery); - pQuery->timeWindowInterpo = timeWindowInterpoRequired(pQuery); - pQuery->stabledev = isStabledev(pQuery); + pRuntimeEnv->prevResult = prevResult; - setScanLimitationByResultBuffer(pQuery); - - int32_t code = setupQueryHandle(tsdb, pQInfo, isSTableQuery); - if (code != TSDB_CODE_SUCCESS) { - return code; + if (tsdb != NULL) { + int32_t code = setupQueryHandle(tsdb, pRuntimeEnv, pQInfo->qId, pQueryAttr->stableQuery); + if (code != TSDB_CODE_SUCCESS) { + return code; + } } - pQuery->tsdb = tsdb; - pQuery->vgId = vgId; - pQuery->stableQuery = isSTableQuery; - pQuery->groupbyColumn = isGroupbyColumn(pQuery->pGroupbyExpr); - pQuery->interBufSize = getOutputInterResultBufSize(pQuery); + pQueryAttr->interBufSize = getOutputInterResultBufSize(pQueryAttr); - pRuntimeEnv->groupResInfo.totalGroup = (int32_t) (isSTableQuery? GET_NUM_OF_TABLEGROUP(pRuntimeEnv):0); + pRuntimeEnv->groupResInfo.totalGroup = (int32_t) (pQueryAttr->stableQuery? GET_NUM_OF_TABLEGROUP(pRuntimeEnv):0); - pRuntimeEnv->pQuery = pQuery; + pRuntimeEnv->pQueryAttr = pQueryAttr; pRuntimeEnv->pTsBuf = pTsBuf; pRuntimeEnv->cur.vgroupIndex = -1; - setResultBufSize(pQuery, &pRuntimeEnv->resultInfo); + setResultBufSize(pQueryAttr, &pRuntimeEnv->resultInfo); - if (onlyQueryTags(pQuery)) { - pRuntimeEnv->resultInfo.capacity = 4096; - pRuntimeEnv->proot = createTagScanOperatorInfo(pRuntimeEnv, pQuery->pExpr1, pQuery->numOfOutput); - } else if (pQuery->queryBlockDist) { - pRuntimeEnv->pTableScanner = createTableBlockInfoScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv); - } else if (isTsCompQuery(pQuery) || isPointInterpoQuery(pQuery)) { - pRuntimeEnv->pTableScanner = createTableSeqScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv); - } else if (needReverseScan(pQuery)) { - pRuntimeEnv->pTableScanner = createDataBlocksOptScanInfo(pRuntimeEnv->pQueryHandle, pRuntimeEnv, getNumOfScanTimes(pQuery), 1); - } else { - pRuntimeEnv->pTableScanner = createTableScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv, getNumOfScanTimes(pQuery)); + switch(tbScanner) { + case OP_TableBlockInfoScan: { + pRuntimeEnv->proot = createTableBlockInfoScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv); + break; + } + case OP_TableSeqScan: { + pRuntimeEnv->proot = createTableSeqScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv); + break; + } + case OP_DataBlocksOptScan: { + pRuntimeEnv->proot = createDataBlocksOptScanInfo(pRuntimeEnv->pQueryHandle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr), 1); + break; + } + case OP_TableScan: { + pRuntimeEnv->proot = createTableScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr)); + break; + } + default: { // do nothing + break; + } + } + + if (sourceOptr != NULL) { + assert(pRuntimeEnv->proot == NULL); + pRuntimeEnv->proot = sourceOptr; } if (pTsBuf != NULL) { - int16_t order = (pQuery->order.order == pRuntimeEnv->pTsBuf->tsOrder) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; + int16_t order = (pQueryAttr->order.order == pRuntimeEnv->pTsBuf->tsOrder) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; tsBufSetTraverseOrder(pRuntimeEnv->pTsBuf, order); } int32_t ps = DEFAULT_PAGE_SIZE; - getIntermediateBufInfo(pRuntimeEnv, &ps, &pQuery->intermediateResultRowSize); + getIntermediateBufInfo(pRuntimeEnv, &ps, &pQueryAttr->intermediateResultRowSize); int32_t TENMB = 1024*1024*10; - code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, ps, TENMB, pQInfo->qId); + int32_t code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, ps, TENMB, pQInfo->qId); if (code != TSDB_CODE_SUCCESS) { return code; } // create runtime environment - int32_t numOfTables = (int32_t)pQuery->tableGroupInfo.numOfTables; + int32_t numOfTables = (int32_t)pQueryAttr->tableGroupInfo.numOfTables; pQInfo->summary.tableInfoSize += (numOfTables * sizeof(STableQueryInfo)); - code = setupQueryRuntimeEnv(pRuntimeEnv, (int32_t) pQuery->tableGroupInfo.numOfTables); + + code = setupQueryRuntimeEnv(pRuntimeEnv, (int32_t) pQueryAttr->tableGroupInfo.numOfTables, pOperator, param); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -4164,25 +4075,25 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo return TSDB_CODE_SUCCESS; } -static void doTableQueryInfoTimeWindowCheck(SQuery* pQuery, STableQueryInfo* pTableQueryInfo) { - if (QUERY_IS_ASC_QUERY(pQuery)) { +static void doTableQueryInfoTimeWindowCheck(SQueryAttr* pQueryAttr, STableQueryInfo* pTableQueryInfo) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { assert( (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) && (pTableQueryInfo->lastKey >= pTableQueryInfo->win.skey) && - (pTableQueryInfo->win.skey >= pQuery->window.skey && pTableQueryInfo->win.ekey <= pQuery->window.ekey)); + (pTableQueryInfo->win.skey >= pQueryAttr->window.skey && pTableQueryInfo->win.ekey <= pQueryAttr->window.ekey)); } else { assert( (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) && (pTableQueryInfo->lastKey <= pTableQueryInfo->win.skey) && - (pTableQueryInfo->win.skey <= pQuery->window.skey && pTableQueryInfo->win.ekey >= pQuery->window.ekey)); + (pTableQueryInfo->win.skey <= pQueryAttr->window.skey && pTableQueryInfo->win.ekey >= pQueryAttr->window.ekey)); } } -STsdbQueryCond createTsdbQueryCond(SQuery* pQuery, STimeWindow* win) { +STsdbQueryCond createTsdbQueryCond(SQueryAttr* pQueryAttr, STimeWindow* win) { STsdbQueryCond cond = { - .colList = pQuery->colList, - .order = pQuery->order.order, - .numOfCols = pQuery->numOfCols, + .colList = pQueryAttr->tableCols, + .order = pQueryAttr->order.order, + .numOfCols = pQueryAttr->numOfCols, .type = BLOCK_LOAD_OFFSET_SEQ_ORDER, .loadExternalRows = false, }; @@ -4229,13 +4140,16 @@ static void doCloseAllTimeWindow(SQueryRuntimeEnv* pRuntimeEnv) { } } -static SSDataBlock* doTableScanImpl(void* param) { +static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; STableScanInfo* pTableScanInfo = pOperator->info; - SSDataBlock* pBlock = &pTableScanInfo->block; - SQuery* pQuery = pOperator->pRuntimeEnv->pQuery; - STableGroupInfo* pTableGroupInfo = &pOperator->pRuntimeEnv->tableqinfoGroupInfo; + SSDataBlock* pBlock = &pTableScanInfo->block; + SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STableGroupInfo *pTableGroupInfo = &pOperator->pRuntimeEnv->tableqinfoGroupInfo; + + *newgroup = false; while (tsdbNextDataBlock(pTableScanInfo->pQueryHandle)) { if (isQueryKilled(pOperator->pRuntimeEnv->qinfo)) { @@ -4246,15 +4160,15 @@ static SSDataBlock* doTableScanImpl(void* param) { tsdbRetrieveDataBlockInfo(pTableScanInfo->pQueryHandle, &pBlock->info); // todo opt - if (pTableGroupInfo->numOfTables > 1 || (pQuery->current == NULL && pTableGroupInfo->numOfTables == 1)) { + if (pTableGroupInfo->numOfTables > 1 || (pRuntimeEnv->current == NULL && pTableGroupInfo->numOfTables == 1)) { STableQueryInfo** pTableQueryInfo = (STableQueryInfo**)taosHashGet(pTableGroupInfo->map, &pBlock->info.tid, sizeof(pBlock->info.tid)); if (pTableQueryInfo == NULL) { break; } - pQuery->current = *pTableQueryInfo; - doTableQueryInfoTimeWindowCheck(pQuery, *pTableQueryInfo); + pRuntimeEnv->current = *pTableQueryInfo; + doTableQueryInfoTimeWindowCheck(pQueryAttr, *pTableQueryInfo); } // this function never returns error? @@ -4275,17 +4189,18 @@ static SSDataBlock* doTableScanImpl(void* param) { return NULL; } -static SSDataBlock* doTableScan(void* param) { +static SSDataBlock* doTableScan(void* param, bool *newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; STableScanInfo *pTableScanInfo = pOperator->info; SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SResultRowInfo* pResultRowInfo = pTableScanInfo->pResultRowInfo; + *newgroup = false; while (pTableScanInfo->current < pTableScanInfo->times) { - SSDataBlock* p = doTableScanImpl(pOperator); + SSDataBlock* p = doTableScanImpl(pOperator, newgroup); if (p != NULL) { return p; } @@ -4299,7 +4214,7 @@ static SSDataBlock* doTableScan(void* param) { } // do prepare for the next round table scan operation - STsdbQueryCond cond = createTsdbQueryCond(pQuery, &pQuery->window); + STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window); tsdbResetQueryHandle(pTableScanInfo->pQueryHandle, &cond); setQueryStatus(pRuntimeEnv, QUERY_NOT_COMPLETED); @@ -4319,10 +4234,11 @@ static SSDataBlock* doTableScan(void* param) { GET_QID(pRuntimeEnv), cond.twindow.skey, cond.twindow.ekey); } + SSDataBlock *p = NULL; if (pTableScanInfo->reverseTimes > 0) { setupEnvForReverseScan(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx, pTableScanInfo->numOfOutput); - STsdbQueryCond cond = createTsdbQueryCond(pQuery, &pQuery->window); + STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window); tsdbResetQueryHandle(pTableScanInfo->pQueryHandle, &cond); qDebug("QInfo:0x%"PRIx64" start to reverse scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64, @@ -4340,22 +4256,20 @@ static SSDataBlock* doTableScan(void* param) { pResultRowInfo->prevSKey = pResultRowInfo->pResult[pResultRowInfo->size-1]->win.skey; } - SSDataBlock* p = doTableScanImpl(pOperator); - if (p != NULL) { - return p; - } + p = doTableScanImpl(pOperator, newgroup); } - return NULL; + return p; } -static SSDataBlock* doBlockInfoScan(void* param) { +static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) { SOperatorInfo *pOperator = (SOperatorInfo*)param; if (pOperator->status == OP_EXEC_DONE) { return NULL; } STableScanInfo *pTableScanInfo = pOperator->info; + *newgroup = false; STableBlockDist tableBlockDist = {0}; tableBlockDist.numOfTables = (int32_t)pOperator->pRuntimeEnv->tableqinfoGroupInfo.numOfTables; @@ -4381,7 +4295,7 @@ static SSDataBlock* doBlockInfoScan(void* param) { tbufCloseWriter(&bw); SArray* g = GET_TABLEGROUP(pOperator->pRuntimeEnv, 0); - pOperator->pRuntimeEnv->pQuery->current = taosArrayGetP(g, 0); + pOperator->pRuntimeEnv->current = taosArrayGetP(g, 0); pOperator->status = OP_EXEC_DONE; return pBlock; @@ -4394,15 +4308,16 @@ SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pInfo->pQueryHandle = pTsdbQueryHandle; pInfo->times = repeatTime; pInfo->reverseTimes = 0; - pInfo->order = pRuntimeEnv->pQuery->order.order; + pInfo->order = pRuntimeEnv->pQueryAttr->order.order; pInfo->current = 0; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableScanOperator"; + pOperator->operatorType = OP_TableScan; pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; - pOperator->numOfOutput = pRuntimeEnv->pQuery->numOfCols; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doTableScan; @@ -4415,7 +4330,7 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeE pInfo->pQueryHandle = pTsdbQueryHandle; pInfo->times = 1; pInfo->reverseTimes = 0; - pInfo->order = pRuntimeEnv->pQuery->order.order; + pInfo->order = pRuntimeEnv->pQueryAttr->order.order; pInfo->current = 0; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); @@ -4424,7 +4339,7 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeE pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; - pOperator->numOfOutput = pRuntimeEnv->pQuery->numOfCols; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doTableScanImpl; @@ -4450,7 +4365,7 @@ SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRu pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->numOfOutput = pRuntimeEnv->pQuery->numOfCols; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; pOperator->exec = doBlockInfoScan; return pOperator; @@ -4506,7 +4421,7 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf } } -static SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime) { +SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime) { assert(repeatTime > 0); STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); @@ -4514,7 +4429,7 @@ static SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQuery pInfo->times = repeatTime; pInfo->reverseTimes = reverseTime; pInfo->current = 0; - pInfo->order = pRuntimeEnv->pQuery->order.order; + pInfo->order = pRuntimeEnv->pQueryAttr->order.order; SOperatorInfo* pOptr = calloc(1, sizeof(SOperatorInfo)); pOptr->name = "DataBlocksOptimizedScanOperator"; @@ -4527,12 +4442,211 @@ static SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQuery return pOptr; } +SArray* getOrderCheckColumns(SQueryAttr* pQuery) { + int32_t numOfCols = pQuery->pGroupbyExpr->numOfGroupCols; + + SArray* pOrderColumns = NULL; + if (numOfCols > 0) { + pOrderColumns = taosArrayDup(pQuery->pGroupbyExpr->columnInfo); + } else { + pOrderColumns = taosArrayInit(4, sizeof(SColIndex)); + } + + if (pQuery->interval.interval > 0) { + if (pOrderColumns == NULL) { + pOrderColumns = taosArrayInit(1, sizeof(SColIndex)); + } + + SColIndex colIndex = {.colIndex = 0, .colId = 0, .flag = TSDB_COL_NORMAL}; + taosArrayPush(pOrderColumns, &colIndex); + } + + { + numOfCols = (int32_t) taosArrayGetSize(pOrderColumns); + for(int32_t i = 0; i < numOfCols; ++i) { + SColIndex* index = taosArrayGet(pOrderColumns, i); + for(int32_t j = 0; j < pQuery->numOfOutput; ++j) { + SSqlExpr* pExpr = &pQuery->pExpr1[j].base; + int32_t functionId = pExpr->functionId; + + if (index->colId == pExpr->colInfo.colId && + (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS)) { + index->colIndex = j; + index->colId = pExpr->resColId; + } + } + } + } + + return pOrderColumns; +} + +SArray* getResultGroupCheckColumns(SQueryAttr* pQuery) { + int32_t numOfCols = pQuery->pGroupbyExpr->numOfGroupCols; + + SArray* pOrderColumns = NULL; + if (numOfCols > 0) { + pOrderColumns = taosArrayDup(pQuery->pGroupbyExpr->columnInfo); + } else { + pOrderColumns = taosArrayInit(4, sizeof(SColIndex)); + } + + for(int32_t i = 0; i < numOfCols; ++i) { + SColIndex* index = taosArrayGet(pOrderColumns, i); + + bool found = false; + for(int32_t j = 0; j < pQuery->numOfOutput; ++j) { + SSqlExpr* pExpr = &pQuery->pExpr1[j].base; + + // TSDB_FUNC_TAG_DUMMY function needs to be ignored + if (index->colId == pExpr->colInfo.colId && + ((TSDB_COL_IS_TAG(pExpr->colInfo.flag) && pExpr->functionId == TSDB_FUNC_TAG) || + (TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && pExpr->functionId == TSDB_FUNC_PRJ))) { + index->colIndex = j; + index->colId = pExpr->resColId; + found = true; + break; + } + } + + assert(found && index->colIndex >= 0 && index->colIndex < pQuery->numOfOutput); + } + + return pOrderColumns; +} + +static void destroyGlobalAggOperatorInfo(void* param, int32_t numOfOutput) { + SMultiwayMergeInfo *pInfo = (SMultiwayMergeInfo*) param; + destroyBasicOperatorInfo(&pInfo->binfo, numOfOutput); + + taosArrayDestroy(pInfo->orderColumnList); + taosArrayDestroy(pInfo->groupColumnList); + tfree(pInfo->prevRow); + tfree(pInfo->currentGroupColData); +} + +static void destroySlimitOperatorInfo(void* param, int32_t numOfOutput) { + SSLimitOperatorInfo *pInfo = (SSLimitOperatorInfo*) param; + taosArrayDestroy(pInfo->orderColumnList); + tfree(pInfo->prevRow); +} + +SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, + SExprInfo* pExpr, int32_t numOfOutput, void* param) { + SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo)); + + pInfo->resultRowFactor = + (int32_t)(GET_ROW_PARAM_FOR_MULTIOUTPUT(pRuntimeEnv->pQueryAttr, pRuntimeEnv->pQueryAttr->topBotQuery, + false)); + + pRuntimeEnv->scanFlag = MERGE_STAGE; // TODO init when creating pCtx + + pInfo->pMerge = param; + pInfo->bufCapacity = 4096; + + pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pInfo->bufCapacity * pInfo->resultRowFactor); + pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); + + pInfo->orderColumnList = getOrderCheckColumns(pRuntimeEnv->pQueryAttr); + pInfo->groupColumnList = getResultGroupCheckColumns(pRuntimeEnv->pQueryAttr); + + // TODO refactor + int32_t len = 0; + for(int32_t i = 0; i < numOfOutput; ++i) { + len += pExpr[i].base.colBytes; + } + + int32_t numOfCols = (pInfo->orderColumnList != NULL)? (int32_t) taosArrayGetSize(pInfo->orderColumnList):0; + pInfo->prevRow = calloc(1, (POINTER_BYTES * numOfCols + len)); + int32_t offset = POINTER_BYTES * numOfCols; + + for(int32_t i = 0; i < numOfCols; ++i) { + pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; + + SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[index->colIndex].base.resBytes; + } + + numOfCols = (pInfo->groupColumnList != NULL)? (int32_t)taosArrayGetSize(pInfo->groupColumnList):0; + pInfo->currentGroupColData = calloc(1, (POINTER_BYTES * numOfCols + len)); + offset = POINTER_BYTES * numOfCols; + + for(int32_t i = 0; i < numOfCols; ++i) { + pInfo->currentGroupColData[i] = (char*)pInfo->currentGroupColData + offset; + + SColIndex* index = taosArrayGet(pInfo->groupColumnList, i); + offset += pExpr[index->colIndex].base.resBytes; + } + + initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); + + pInfo->seed = rand(); + setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MERGE_STAGE); + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + pOperator->name = "GlobalAggregate"; + pOperator->operatorType = OP_GlobalAggregate; + 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; + return pOperator; +} + +SOperatorInfo *createMultiwaySortOperatorInfo(SQueryRuntimeEnv *pRuntimeEnv, SExprInfo *pExpr, int32_t numOfOutput, + int32_t numOfRows, void *merger, bool groupMix) { + SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo)); + + pInfo->pMerge = merger; + pInfo->groupMix = groupMix; + pInfo->bufCapacity = numOfRows; + + pInfo->orderColumnList = getResultGroupCheckColumns(pRuntimeEnv->pQueryAttr); + pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, numOfRows); + + { + int32_t len = 0; + for(int32_t i = 0; i < numOfOutput; ++i) { + len += pExpr[i].base.colBytes; + } + + int32_t numOfCols = (pInfo->orderColumnList != NULL)? (int32_t) taosArrayGetSize(pInfo->orderColumnList):0; + pInfo->prevRow = calloc(1, (POINTER_BYTES * numOfCols + len)); + int32_t offset = POINTER_BYTES * numOfCols; + + for(int32_t i = 0; i < numOfCols; ++i) { + pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; + + SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[index->colIndex].base.colBytes; + } + } + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + pOperator->name = "MultiwaySortOperator"; + pOperator->operatorType = OP_MultiwayMergeSort; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; + pOperator->exec = doMultiwayMergeSort; + pOperator->cleanup = destroyGlobalAggOperatorInfo; + return pOperator; +} + static int32_t getTableScanOrder(STableScanInfo* pTableScanInfo) { return pTableScanInfo->order; } // this is a blocking operator -static SSDataBlock* doAggregate(void* param) { +static SSDataBlock* doAggregate(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -4543,18 +4657,20 @@ static SSDataBlock* doAggregate(void* param) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } - setTagValue(pOperator, pQuery->current->pTable, pInfo->pCtx, pOperator->numOfOutput); + if (pRuntimeEnv->current != NULL) { + setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput); + } if (upstream->operatorType == OP_DataBlocksOptScan) { STableScanInfo* pScanInfo = upstream->info; @@ -4563,7 +4679,7 @@ static SSDataBlock* doAggregate(void* param) { // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); - doAggregateImpl(pOperator, pQuery->window.skey, pInfo->pCtx, pBlock); + doAggregateImpl(pOperator, pQueryAttr->window.skey, pInfo->pCtx, pBlock); } pOperator->status = OP_EXEC_DONE; @@ -4575,7 +4691,7 @@ static SSDataBlock* doAggregate(void* param) { return pInfo->pRes; } -static SSDataBlock* doSTableAggregate(void* param) { +static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -4596,18 +4712,18 @@ static SSDataBlock* doSTableAggregate(void* param) { return pInfo->pRes; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } - setTagValue(pOperator, pRuntimeEnv->pQuery->current->pTable, pInfo->pCtx, pOperator->numOfOutput); + setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput); if (upstream->operatorType == OP_DataBlocksOptScan) { STableScanInfo* pScanInfo = upstream->info; @@ -4617,9 +4733,9 @@ static SSDataBlock* doSTableAggregate(void* param) { // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); - TSKEY key = QUERY_IS_ASC_QUERY(pQuery)? pBlock->info.window.ekey + 1:pBlock->info.window.skey-1; - setExecutionContext(pRuntimeEnv, pInfo, pOperator->numOfOutput, pQuery->current->groupIndex, key); - doAggregateImpl(pOperator, pQuery->window.skey, pInfo->pCtx, pBlock); + TSKEY key = QUERY_IS_ASC_QUERY(pQueryAttr)? pBlock->info.window.ekey + 1:pBlock->info.window.skey-1; + setExecutionContext(pRuntimeEnv, pInfo, pOperator->numOfOutput, pRuntimeEnv->current->groupIndex, key); + doAggregateImpl(pOperator, pQueryAttr->window.skey, pInfo->pCtx, pBlock); } pOperator->status = OP_RES_TO_RETURN; @@ -4638,7 +4754,7 @@ static SSDataBlock* doSTableAggregate(void* param) { return pInfo->pRes; } -static SSDataBlock* doArithmeticOperation(void* param) { +static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; SArithOperatorInfo* pArithInfo = pOperator->info; @@ -4646,28 +4762,75 @@ static SSDataBlock* doArithmeticOperation(void* param) { SOptrBasicInfo *pInfo = &pArithInfo->binfo; SSDataBlock* pRes = pInfo->pRes; - int32_t order = pRuntimeEnv->pQuery->order.order; + int32_t order = pRuntimeEnv->pQueryAttr->order.order; pRes->info.rows = 0; + if (pArithInfo->existDataBlock) { // TODO refactor + STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; + + SSDataBlock* pBlock = pArithInfo->existDataBlock; + pArithInfo->existDataBlock = NULL; + *newgroup = true; + + // todo dynamic set tags + if (pTableQueryInfo != NULL) { + setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput); + } + + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); + updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows); + + arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); + + if (pTableQueryInfo != NULL) { // TODO refactor + updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order); + } + + pRes->info.rows = getNumOfResult(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); + if (pRes->info.rows >= pRuntimeEnv->resultInfo.threshold) { + clearNumOfRes(pInfo->pCtx, pOperator->numOfOutput); + return pRes; + } + } + while(1) { - SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream); + 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); if (pBlock == NULL) { + assert(*newgroup == false); + + *newgroup = prevVal; setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); break; } - STableQueryInfo* pTableQueryInfo = pRuntimeEnv->pQuery->current; + // Return result of the previous group in the firstly. + if (*newgroup && pRes->info.rows > 0) { + pArithInfo->existDataBlock = pBlock; + clearNumOfRes(pInfo->pCtx, pOperator->numOfOutput); + return pInfo->pRes; + } + + STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; // todo dynamic set tags - setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput); + if (pTableQueryInfo != NULL) { + setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput); + } // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); - updateOutputBuf(pArithInfo, pBlock->info.rows); + updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows); arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); - updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order); + + if (pTableQueryInfo != NULL) { // TODO refactor + updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order); + } pRes->info.rows = getNumOfResult(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); if (pRes->info.rows >= pRuntimeEnv->resultInfo.threshold) { @@ -4679,24 +4842,46 @@ static SSDataBlock* doArithmeticOperation(void* param) { return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; } -static SSDataBlock* doLimit(void* param) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doLimit(void* param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*)param; if (pOperator->status == OP_EXEC_DONE) { return NULL; } SLimitOperatorInfo* pInfo = pOperator->info; + SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream); - if (pBlock == NULL) { - setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); - pOperator->status = OP_EXEC_DONE; - return NULL; + SSDataBlock* pBlock = NULL; + while (1) { + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + if (pRuntimeEnv->currentOffset == 0) { + break; + } else if (pRuntimeEnv->currentOffset >= pBlock->info.rows) { + pRuntimeEnv->currentOffset -= pBlock->info.rows; + } else { + int32_t remain = (int32_t)(pBlock->info.rows - pRuntimeEnv->currentOffset); + pBlock->info.rows = remain; + + for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); + + int16_t bytes = pColInfoData->info.bytes; + memmove(pColInfoData->pData, pColInfoData->pData + bytes * pRuntimeEnv->currentOffset, remain * bytes); + } + + pRuntimeEnv->currentOffset = 0; + break; + } } if (pInfo->total + pBlock->info.rows >= pInfo->limit) { - pBlock->info.rows = (int32_t) (pInfo->limit - pInfo->total); - + pBlock->info.rows = (int32_t)(pInfo->limit - pInfo->total); pInfo->total = pInfo->limit; setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); @@ -4708,44 +4893,6 @@ static SSDataBlock* doLimit(void* param) { return pBlock; } -// TODO add log -static SSDataBlock* doOffset(void* param) { - SOperatorInfo *pOperator = (SOperatorInfo *)param; - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } - - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - - while (1) { - SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream); - if (pBlock == NULL) { - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); - pOperator->status = OP_EXEC_DONE; - return NULL; - } - - if (pRuntimeEnv->currentOffset == 0) { - return pBlock; - } else if (pRuntimeEnv->currentOffset >= pBlock->info.rows) { - pRuntimeEnv->currentOffset -= pBlock->info.rows; - } else { - int32_t remain = (int32_t)(pBlock->info.rows - pRuntimeEnv->currentOffset); - pBlock->info.rows = remain; - - for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { - SColumnInfoData *pColInfoData = taosArrayGet(pBlock->pDataBlock, i); - - int16_t bytes = pColInfoData->info.bytes; - memmove(pColInfoData->pData, pColInfoData->pData + bytes * pRuntimeEnv->currentOffset, remain * bytes); - } - - pRuntimeEnv->currentOffset = 0; - return pBlock; - } - } -} - bool doFilterData(SColumnInfoData* p, int32_t rid, SColumnFilterElem *filterElem, __filter_func_t fp) { char* input = p->pData + p->info.bytes * rid; @@ -4759,7 +4906,7 @@ bool doFilterData(SColumnInfoData* p, int32_t rid, SColumnFilterElem *filterElem return false; } } - + if (fp(filterElem, input, input, p->info.type)) { return true; } @@ -4767,91 +4914,36 @@ bool doFilterData(SColumnInfoData* p, int32_t rid, SColumnFilterElem *filterElem return false; } - -void doHavingImpl(SOperatorInfo *pOperator, SSDataBlock *pBlock) { - SHavingOperatorInfo* pInfo = pOperator->info; - int32_t f = 0; - int32_t allQualified = 1; - int32_t exprQualified = 0; - - for (int32_t r = 0; r < pBlock->info.rows; ++r) { - allQualified = 1; - - for (int32_t i = 0; i < pOperator->numOfOutput; ++i) { - SExprInfo* pExprInfo = &(pOperator->pExpr[i]); - if (pExprInfo->pFilter == NULL) { - continue; - } - - SArray* es = taosArrayGetP(pInfo->fp, i); - assert(es); - - size_t fpNum = taosArrayGetSize(es); - - exprQualified = 0; - for (int32_t m = 0; m < fpNum; ++m) { - __filter_func_t fp = taosArrayGetP(es, m); - - assert(fp); - - //SColIndex* colIdx = &pExprInfo->base.colInfo; - SColumnInfoData* p = taosArrayGet(pBlock->pDataBlock, i); - - SColumnFilterElem filterElem = {.filterInfo = pExprInfo->pFilter[m]}; - - if (doFilterData(p, r, &filterElem, fp)) { - exprQualified = 1; - break; - } - } - - if (exprQualified == 0) { - allQualified = 0; - break; - } - } - - if (allQualified == 0) { - continue; - } - - for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { - SColumnInfoData *pColInfoData = taosArrayGet(pBlock->pDataBlock, i); - - int16_t bytes = pColInfoData->info.bytes; - memmove(pColInfoData->pData + f * bytes, pColInfoData->pData + bytes * r, bytes); - } - - ++f; - } - - pBlock->info.rows = f; -} - -static SSDataBlock* doHaving(void* param) { +static SSDataBlock* doFilter(void* param, bool* newgroup) { SOperatorInfo *pOperator = (SOperatorInfo *)param; if (pOperator->status == OP_EXEC_DONE) { return NULL; } + SFilterOperatorInfo* pCondInfo = pOperator->info; SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; while (1) { - SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream); + SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); if (pBlock == NULL) { - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); - pOperator->status = OP_EXEC_DONE; - return NULL; + break; } - - doHavingImpl(pOperator, pBlock); - return pBlock; + doSetFilterColumnInfo(pCondInfo->pFilterInfo, pCondInfo->numOfFilterCols, pBlock); + assert(pRuntimeEnv->pTsBuf == NULL); + filterRowsInDataBlock(pRuntimeEnv, pCondInfo->pFilterInfo, pCondInfo->numOfFilterCols, pBlock, true); + + if (pBlock->info.rows > 0) { + return pBlock; + } } + + setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; } - -static SSDataBlock* doIntervalAgg(void* param) { +static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -4870,26 +4962,26 @@ static SSDataBlock* doIntervalAgg(void* param) { return pIntervalInfo->pRes; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; - STimeWindow win = pQuery->window; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; + STimeWindow win = pQueryAttr->window; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQuery->order.order); + setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQueryAttr->order.order); hashIntervalAgg(pOperator, &pIntervalInfo->resultRowInfo, pBlock, 0); } // restore the value - pQuery->order.order = order; - pQuery->window = win; + pQueryAttr->order.order = order; + pQueryAttr->window = win; pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pIntervalInfo->resultRowInfo); @@ -4906,7 +4998,7 @@ static SSDataBlock* doIntervalAgg(void* param) { return pIntervalInfo->pRes->info.rows == 0? NULL:pIntervalInfo->pRes; } -static SSDataBlock* doSTableIntervalAgg(void* param) { +static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -4924,29 +5016,29 @@ static SSDataBlock* doSTableIntervalAgg(void* param) { return pIntervalInfo->pRes; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } // the pDataBlock are always the same one, no need to call this again - STableQueryInfo* pTableQueryInfo = pRuntimeEnv->pQuery->current; + STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; setTagValue(pOperator, pTableQueryInfo->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput); - setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQuery->order.order); + setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQueryAttr->order.order); setIntervalQueryRange(pRuntimeEnv, pBlock->info.window.skey); hashIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pTableQueryInfo->groupIndex); } pOperator->status = OP_RES_TO_RETURN; - pQuery->order.order = order; // TODO : restore the order + pQueryAttr->order.order = order; // TODO : restore the order doCloseAllTimeWindow(pRuntimeEnv); setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); @@ -4958,7 +5050,7 @@ static SSDataBlock* doSTableIntervalAgg(void* param) { return pIntervalInfo->pRes; } -static SSDataBlock* doSessionWindowAgg(void* param) { +static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -4978,26 +5070,26 @@ static SSDataBlock* doSessionWindowAgg(void* param) { return pBInfo->pRes; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; - STimeWindow win = pQuery->window; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; + STimeWindow win = pQueryAttr->window; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, pQuery->order.order); + setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, pQueryAttr->order.order); doSessionWindowAggImpl(pOperator, pWindowInfo, pBlock); } // restore the value - pQuery->order.order = order; - pQuery->window = win; + pQueryAttr->order.order = order; + pQueryAttr->window = win; pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pBInfo->resultRowInfo); @@ -5014,7 +5106,7 @@ static SSDataBlock* doSessionWindowAgg(void* param) { return pBInfo->pRes->info.rows == 0? NULL:pBInfo->pRes; } -static SSDataBlock* hashGroupbyAggregate(void* param) { +static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -5036,16 +5128,16 @@ static SSDataBlock* hashGroupbyAggregate(void* param) { SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, pRuntimeEnv->pQuery->order.order); - setTagValue(pOperator, pRuntimeEnv->pQuery->current->pTable, pInfo->binfo.pCtx, pOperator->numOfOutput); + setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, pRuntimeEnv->pQueryAttr->order.order); + setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->binfo.pCtx, pOperator->numOfOutput); if (pInfo->colIndex == -1) { - pInfo->colIndex = getGroupbyColumnIndex(pRuntimeEnv->pQuery->pGroupbyExpr, pBlock); + pInfo->colIndex = getGroupbyColumnIndex(pRuntimeEnv->pQueryAttr->pGroupbyExpr, pBlock); } doHashGroupbyAgg(pOperator, pInfo, pBlock); @@ -5055,7 +5147,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param) { closeAllResultRows(&pInfo->binfo.resultRowInfo); setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); - if (!pRuntimeEnv->pQuery->stableQuery) { // finalize include the update of result rows + if (!pRuntimeEnv->pQueryAttr->stableQuery) { // finalize include the update of result rows finalizeQueryResult(pOperator, pInfo->binfo.pCtx, &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset); } else { updateNumOfRowsInResultRows(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset); @@ -5071,47 +5163,96 @@ static SSDataBlock* hashGroupbyAggregate(void* param) { return pInfo->binfo.pRes; } -static SSDataBlock* doFill(void* param) { +static SSDataBlock* doFill(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; } SFillOperatorInfo *pInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; if (taosFillHasMoreResults(pInfo->pFillInfo)) { + *newgroup = false; doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pRuntimeEnv->resultInfo.capacity); return pInfo->pRes; } + // handle the cached new group data block + if (pInfo->existNewGroupBlock) { + pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows; + int64_t ekey = Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED)?pRuntimeEnv->pQueryAttr->window.ekey:pInfo->existNewGroupBlock->info.window.ekey; + taosResetFillInfo(pInfo->pFillInfo, pInfo->pFillInfo->start); + + taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey); + taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock); + + doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pRuntimeEnv->resultInfo.capacity); + pInfo->existNewGroupBlock = NULL; + *newgroup = true; + return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; + } + while(1) { - SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream); - if (pBlock == NULL) { - if (pInfo->totalInputRows == 0) { - pOperator->status = OP_EXEC_DONE; - return NULL; - } + SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (*newgroup) { + assert(pBlock != NULL); + } - taosFillSetStartInfo(pInfo->pFillInfo, 0, pRuntimeEnv->pQuery->window.ekey); + if (*newgroup && pInfo->totalInputRows > 0) { // there are already processed current group data block + pInfo->existNewGroupBlock = pBlock; + *newgroup = false; + + // fill the previous group data block + // before handle a new data block, close the fill operation for previous group data block + taosFillSetStartInfo(pInfo->pFillInfo, 0, pRuntimeEnv->pQueryAttr->window.ekey); } else { - pInfo->totalInputRows += pBlock->info.rows; + if (pBlock == NULL) { + if (pInfo->totalInputRows == 0) { + pOperator->status = OP_EXEC_DONE; + return NULL; + } - int64_t ekey = Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED)?pRuntimeEnv->pQuery->window.ekey:pBlock->info.window.ekey; + taosFillSetStartInfo(pInfo->pFillInfo, 0, pRuntimeEnv->pQueryAttr->window.ekey); + } else { + pInfo->totalInputRows += pBlock->info.rows; - taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, ekey); - taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock); + int64_t ekey = /*Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED) ? pRuntimeEnv->pQueryAttr->window.ekey + : */pBlock->info.window.ekey; + + taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, ekey); + taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock); + } } doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pRuntimeEnv->resultInfo.capacity); - return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; + if (pInfo->pRes->info.rows > 0) { // current group has no more result to return + return pInfo->pRes; + } else if (pInfo->existNewGroupBlock) { // try next group + pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows; + int64_t ekey = /*Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED) ? pRuntimeEnv->pQueryAttr->window.ekey + :*/ pInfo->existNewGroupBlock->info.window.ekey; + taosResetFillInfo(pInfo->pFillInfo, pInfo->pFillInfo->start); + + taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey); + taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock); + + doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pRuntimeEnv->resultInfo.capacity); + pInfo->existNewGroupBlock = NULL; + *newgroup = true; + + return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL; + } else { + return NULL; + } + // return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; } } // todo set the attribute of query scan count -static int32_t getNumOfScanTimes(SQuery* pQuery) { - for(int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; +static int32_t getNumOfScanTimes(SQueryAttr* pQueryAttr) { + for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; if (functionId == TSDB_FUNC_STDDEV || functionId == TSDB_FUNC_PERCT) { return 2; } @@ -5134,11 +5275,11 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) { tfree(pOperator); } -static SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo)); - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t numOfRows = (int32_t)(GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pQuery->topBotQuery, pQuery->stableQuery)); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t numOfRows = (int32_t)(GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, numOfRows); pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); @@ -5146,7 +5287,7 @@ static SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); pInfo->seed = rand(); - setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed); + setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MASTER_SCAN); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableAggregate"; @@ -5201,11 +5342,15 @@ static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput) { pInfo->pRes = destroyOutputBuf(pInfo->pRes); } -static void destroyHavingOperatorInfo(void* param, int32_t numOfOutput) { - SHavingOperatorInfo* pInfo = (SHavingOperatorInfo*) param; - if (pInfo->fp) { - taosArrayDestroy(pInfo->fp); - } +static void destroyConditionOperatorInfo(void* param, int32_t numOfOutput) { + SFilterOperatorInfo* pInfo = (SFilterOperatorInfo*) param; + doDestroyFilterInfo(pInfo->pFilterInfo, pInfo->numOfFilterCols); +} + +static void destroyDistinctOperatorInfo(void* param, int32_t numOfOutput) { + SDistinctOperatorInfo* pInfo = (SDistinctOperatorInfo*) param; + taosHashCleanup(pInfo->pSet); + pInfo->pRes = destroyOutputBuf(pInfo->pRes); } SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { @@ -5245,7 +5390,7 @@ SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI pBInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pBInfo->rowCellInfoOffset); initResultRowInfo(&pBInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT); - setDefaultOutputBuf(pRuntimeEnv, pBInfo, pInfo->seed); + setDefaultOutputBuf(pRuntimeEnv, pBInfo, pInfo->seed, MASTER_SCAN); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "ArithmeticOperator"; @@ -5264,86 +5409,59 @@ SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI return pOperator; } +SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, + int32_t numOfOutput) { + SFilterOperatorInfo* pInfo = calloc(1, sizeof(SFilterOperatorInfo)); -int32_t initFilterFp(SExprInfo* pExpr, int32_t numOfOutput, SArray** fps) { - __filter_func_t fp = NULL; + { + SColumnInfo* pCols = calloc(numOfOutput, sizeof(SColumnInfo)); - *fps = taosArrayInit(numOfOutput, sizeof(SArray*)); - if (*fps == NULL) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - - for (int32_t i = 0; i < numOfOutput; ++i) { - SExprInfo* pExprInfo = &(pExpr[i]); - SColIndex* colIdx = &pExprInfo->base.colInfo; - - if (pExprInfo->pFilter == NULL || !TSDB_COL_IS_NORMAL_COL(colIdx->flag)) { - taosArrayPush(*fps, &fp); - - continue; - } - - int32_t filterNum = pExprInfo->base.filterNum; - SColumnFilterInfo *filterInfo = pExprInfo->pFilter; - - SArray* es = taosArrayInit(filterNum, sizeof(__filter_func_t)); - - for (int32_t j = 0; j < filterNum; ++j) { - int32_t lower = filterInfo->lowerRelOptr; - int32_t upper = filterInfo->upperRelOptr; - if (lower == TSDB_RELATION_INVALID && upper == TSDB_RELATION_INVALID) { - qError("invalid rel optr"); - taosArrayDestroy(es); - return TSDB_CODE_QRY_APP_ERROR; + int32_t numOfFilter = 0; + for(int32_t i = 0; i < numOfOutput; ++i) { + if (pExpr[i].base.flist.numOfFilters > 0) { + numOfFilter += 1; } - __filter_func_t ffp = getFilterOperator(lower, upper); - if (ffp == NULL) { - qError("invalid filter info"); - taosArrayDestroy(es); - return TSDB_CODE_QRY_APP_ERROR; - } - - taosArrayPush(es, &ffp); - - filterInfo += 1; + 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)); } - taosArrayPush(*fps, &es); + assert(numOfFilter > 0); + doCreateFilterInfo(pCols, numOfOutput, numOfFilter, &pInfo->pFilterInfo, 0); + pInfo->numOfFilterCols = numOfFilter; + + for(int32_t i = 0; i < numOfOutput; ++i) { + tfree(pCols[i].flist.filterInfo); + } + + tfree(pCols); } - return TSDB_CODE_SUCCESS; -} - -SOperatorInfo* createHavingOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { - SHavingOperatorInfo* pInfo = calloc(1, sizeof(SHavingOperatorInfo)); - - initFilterFp(pExpr, numOfOutput, &pInfo->fp); - - assert(pInfo->fp); - SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "HavingOperator"; - pOperator->operatorType = OP_Having; + pOperator->name = "ConditionOperator"; + pOperator->operatorType = OP_Filter; pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->numOfOutput = numOfOutput; pOperator->pExpr = pExpr; pOperator->upstream = upstream; - pOperator->exec = doHaving; + pOperator->exec = doFilter; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->cleanup = destroyHavingOperatorInfo; + pOperator->cleanup = destroyConditionOperatorInfo; return pOperator; } - - SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream) { SLimitOperatorInfo* pInfo = calloc(1, sizeof(SLimitOperatorInfo)); - pInfo->limit = pRuntimeEnv->pQuery->limit.limit; + pInfo->limit = pRuntimeEnv->pQueryAttr->limit.limit; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); @@ -5359,24 +5477,6 @@ SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI return pOperator; } -SOperatorInfo* createOffsetOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream) { - SOffsetOperatorInfo* pInfo = calloc(1, sizeof(SOffsetOperatorInfo)); - - pInfo->offset = pRuntimeEnv->pQuery->limit.offset; - SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - - pOperator->name = "OffsetOperator"; - pOperator->operatorType = OP_Offset; - pOperator->blockingOptr = false; - pOperator->status = OP_IN_EXECUTING; - pOperator->upstream = upstream; - pOperator->exec = doOffset; - pOperator->info = pInfo; - pOperator->pRuntimeEnv = pRuntimeEnv; - - return pOperator; -} - SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); @@ -5480,17 +5580,18 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); { - SQuery* pQuery = pRuntimeEnv->pQuery; - SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfOutput, pQuery->fillVal); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfOutput, pQueryAttr->fillVal); STimeWindow w = TSWINDOW_INITIALIZER; - TSKEY sk = MIN(pQuery->window.skey, pQuery->window.ekey); - TSKEY ek = MAX(pQuery->window.skey, pQuery->window.ekey); - getAlignQueryTimeWindow(pQuery, pQuery->window.skey, sk, ek, &w); + TSKEY sk = MIN(pQueryAttr->window.skey, pQueryAttr->window.ekey); + TSKEY ek = MAX(pQueryAttr->window.skey, pQueryAttr->window.ekey); + getAlignQueryTimeWindow(pQueryAttr, pQueryAttr->window.skey, sk, ek, &w); - pInfo->pFillInfo = taosCreateFillInfo(pQuery->order.order, w.skey, 0, (int32_t)pRuntimeEnv->resultInfo.capacity, numOfOutput, - pQuery->interval.sliding, pQuery->interval.slidingUnit, (int8_t)pQuery->precision, - pQuery->fillType, pColInfo, pRuntimeEnv->qinfo); + pInfo->pFillInfo = + taosCreateFillInfo(pQueryAttr->order.order, w.skey, 0, (int32_t)pRuntimeEnv->resultInfo.capacity, numOfOutput, + pQueryAttr->interval.sliding, pQueryAttr->interval.slidingUnit, + (int8_t)pQueryAttr->precision, pQueryAttr->fillType, pColInfo, pRuntimeEnv->qinfo); } SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); @@ -5512,7 +5613,50 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn return pOperator; } -static SSDataBlock* doTagScan(void* param) { +SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* pMerger) { + SSLimitOperatorInfo* pInfo = calloc(1, sizeof(SSLimitOperatorInfo)); + + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + + pInfo->orderColumnList = getResultGroupCheckColumns(pQueryAttr); + pInfo->slimit = pQueryAttr->slimit; + pInfo->limit = pQueryAttr->limit; + + pInfo->currentGroupOffset = pQueryAttr->slimit.offset; + pInfo->currentOffset = pQueryAttr->limit.offset; + + // TODO refactor + int32_t len = 0; + for(int32_t i = 0; i < numOfOutput; ++i) { + len += pExpr[i].base.resBytes; + } + + int32_t numOfCols = pInfo->orderColumnList != NULL? (int32_t) taosArrayGetSize(pInfo->orderColumnList):0; + pInfo->prevRow = calloc(1, (POINTER_BYTES * numOfCols + len)); + int32_t offset = POINTER_BYTES * numOfCols; + + for(int32_t i = 0; i < numOfCols; ++i) { + pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; + + SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[index->colIndex].base.resBytes; + } + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + + pOperator->name = "SLimitOperator"; + 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; + return pOperator; +} + +static SSDataBlock* doTagScan(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -5524,27 +5668,28 @@ static SSDataBlock* doTagScan(void* param) { STagScanInfo *pInfo = pOperator->info; SSDataBlock *pRes = pInfo->pRes; + *newgroup = false; int32_t count = 0; SArray* pa = GET_TABLEGROUP(pRuntimeEnv, 0); int32_t functionId = pOperator->pExpr[0].base.functionId; if (functionId == TSDB_FUNC_TID_TAG) { // return the tags & table Id - SQuery* pQuery = pRuntimeEnv->pQuery; - assert(pQuery->numOfOutput == 1); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + assert(pQueryAttr->numOfOutput == 1); SExprInfo* pExprInfo = &pOperator->pExpr[0]; - int32_t rsize = pExprInfo->bytes; + int32_t rsize = pExprInfo->base.resBytes; count = 0; - int16_t bytes = pExprInfo->bytes; - int16_t type = pExprInfo->type; + int16_t bytes = pExprInfo->base.resBytes; + int16_t type = pExprInfo->base.resType; - for(int32_t i = 0; i < pQuery->numOfTags; ++i) { - if (pQuery->tagColList[i].colId == pExprInfo->base.colInfo.colId) { - bytes = pQuery->tagColList[i].bytes; - type = pQuery->tagColList[i].type; + for(int32_t i = 0; i < pQueryAttr->numOfTags; ++i) { + if (pQueryAttr->tagColList[i].colId == pExprInfo->base.colInfo.colId) { + bytes = pQueryAttr->tagColList[i].bytes; + type = pQueryAttr->tagColList[i].type; break; } } @@ -5570,8 +5715,8 @@ static SSDataBlock* doTagScan(void* param) { *(int32_t *)output = id->tid; output += sizeof(id->tid); - *(int32_t *)output = pQuery->vgId; - output += sizeof(pQuery->vgId); + *(int32_t *)output = pQueryAttr->vgId; + output += sizeof(pQueryAttr->vgId); char* data = NULL; if (pExprInfo->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { @@ -5610,8 +5755,8 @@ static SSDataBlock* doTagScan(void* param) { } SColumnInfoData* pColInfo = taosArrayGet(pRes->pDataBlock, j); - type = pExprInfo[j].type; - bytes = pExprInfo[j].bytes; + type = pExprInfo[j].base.resType; + bytes = pExprInfo[j].base.resBytes; if (pExprInfo[j].base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { data = tsdbGetTableName(item->pTable); @@ -5619,7 +5764,7 @@ static SSDataBlock* doTagScan(void* param) { data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.colInfo.colId, type, bytes); } - dst = pColInfo->pData + count * pExprInfo[j].bytes; + dst = pColInfo->pData + count * pExprInfo[j].base.resBytes; doSetTagValueToResultBuf(dst, data, type, bytes); } @@ -5662,30 +5807,112 @@ SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInf return pOperator; } -static int32_t getColumnIndexInSource(SQueryTableMsg *pQueryMsg, SSqlFuncMsg *pExprMsg, SColumnInfo* pTagCols) { +static SSDataBlock* hashDistinct(void* param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*) param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SDistinctOperatorInfo* pInfo = pOperator->info; + SSDataBlock* pRes = pInfo->pRes; + + pRes->info.rows = 0; + SSDataBlock* pBlock = NULL; + while(1) { + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + assert(pBlock->info.numOfCols == 1); + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0); + + int16_t bytes = pColInfoData->info.bytes; + int16_t type = pColInfoData->info.type; + + // ensure the output buffer size + SColumnInfoData* pResultColInfoData = taosArrayGet(pRes->pDataBlock, 0); + if (pRes->info.rows + pBlock->info.rows > pInfo->outputCapacity) { + int32_t newSize = pRes->info.rows + pBlock->info.rows; + char* tmp = realloc(pResultColInfoData->pData, newSize * bytes); + if (tmp == NULL) { + return NULL; + } else { + pResultColInfoData->pData = tmp; + pInfo->outputCapacity = newSize; + } + } + + for(int32_t i = 0; i < pBlock->info.rows; ++i) { + char* val = ((char*)pColInfoData->pData) + bytes * i; + if (isNull(val, type)) { + continue; + } + + void* res = taosHashGet(pInfo->pSet, val, bytes); + if (res == NULL) { + taosHashPut(pInfo->pSet, val, bytes, NULL, 0); + char* start = pResultColInfoData->pData + bytes * pInfo->pRes->info.rows; + memcpy(start, val, bytes); + pRes->info.rows += 1; + } + } + + if (pRes->info.rows >= pInfo->threshold) { + break; + } + } + + return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; +} + +SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { + SDistinctOperatorInfo* pInfo = calloc(1, sizeof(SDistinctOperatorInfo)); + + pInfo->outputCapacity = 4096; + pInfo->pSet = taosHashInit(64, taosGetDefaultHashFunction(pExpr->base.colType), false, HASH_NO_LOCK); + pInfo->pRes = createOutputBuf(pExpr, numOfOutput, (int32_t) pInfo->outputCapacity); + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + pOperator->name = "DistinctOperator"; + 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; + return pOperator; +} + +static int32_t getColumnIndexInSource(SQueriedTableInfo *pTableInfo, SSqlExpr *pExpr, SColumnInfo* pTagCols) { int32_t j = 0; - if (TSDB_COL_IS_TAG(pExprMsg->colInfo.flag)) { - if (pExprMsg->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { + if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { + if (pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { return TSDB_TBNAME_COLUMN_INDEX; - } else if (pExprMsg->colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { + } else if (pExpr->colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { return TSDB_BLOCK_DIST_COLUMN_INDEX; } - while(j < pQueryMsg->numOfTags) { - if (pExprMsg->colInfo.colId == pTagCols[j].colId) { + while(j < pTableInfo->numOfTags) { + if (pExpr->colInfo.colId == pTagCols[j].colId) { return j; } j += 1; } - } else if (TSDB_COL_IS_UD_COL(pExprMsg->colInfo.flag)) { // user specified column data + } else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) { // user specified column data return TSDB_UD_COLUMN_INDEX; } else { - while (j < pQueryMsg->numOfCols) { - if (pExprMsg->colInfo.colId == pQueryMsg->colList[j].colId) { + while (j < pTableInfo->numOfCols) { + if (pExpr->colInfo.colId == pTableInfo->colList[j].colId) { return j; } @@ -5696,8 +5923,8 @@ static int32_t getColumnIndexInSource(SQueryTableMsg *pQueryMsg, SSqlFuncMsg *pE return INT32_MIN; // return a less than TSDB_TBNAME_COLUMN_INDEX value } -bool validateExprColumnInfo(SQueryTableMsg *pQueryMsg, SSqlFuncMsg *pExprMsg, SColumnInfo* pTagCols) { - int32_t j = getColumnIndexInSource(pQueryMsg, pExprMsg, pTagCols); +bool validateExprColumnInfo(SQueriedTableInfo *pTableInfo, SSqlExpr *pExpr, SColumnInfo* pTagCols) { + int32_t j = getColumnIndexInSource(pTableInfo, pExpr, pTagCols); return j != INT32_MIN; } @@ -5736,21 +5963,21 @@ static bool validateQueryMsg(SQueryTableMsg *pQueryMsg) { return true; } -static bool validateQuerySourceCols(SQueryTableMsg *pQueryMsg, SSqlFuncMsg** pExprMsg, SColumnInfo* pTagCols) { - int32_t numOfTotal = pQueryMsg->numOfCols + pQueryMsg->numOfTags; - if (pQueryMsg->numOfCols < 0 || pQueryMsg->numOfTags < 0 || numOfTotal > TSDB_MAX_COLUMNS) { - qError("qmsg:%p illegal value of numOfCols %d numOfTags:%d", pQueryMsg, pQueryMsg->numOfCols, pQueryMsg->numOfTags); +static UNUSED_FUNC bool validateQueryTableCols(SQueriedTableInfo* pTableInfo, SSqlExpr** pExpr, int32_t numOfOutput, + SColumnInfo* pTagCols, void* pMsg) { + int32_t numOfTotal = pTableInfo->numOfCols + pTableInfo->numOfTags; + if (pTableInfo->numOfCols < 0 || pTableInfo->numOfTags < 0 || numOfTotal > TSDB_MAX_COLUMNS) { + qError("qmsg:%p illegal value of numOfCols %d numOfTags:%d", pMsg, pTableInfo->numOfCols, pTableInfo->numOfTags); return false; } - if (numOfTotal == 0) { - for(int32_t i = 0; i < pQueryMsg->numOfOutput; ++i) { - SSqlFuncMsg* pFuncMsg = pExprMsg[i]; - - if ((pFuncMsg->functionId == TSDB_FUNC_TAGPRJ) || - (pFuncMsg->functionId == TSDB_FUNC_TID_TAG && pFuncMsg->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) || - (pFuncMsg->functionId == TSDB_FUNC_COUNT && pFuncMsg->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) || - (pFuncMsg->functionId == TSDB_FUNC_BLKINFO)) { + if (numOfTotal == 0) { // table total columns are not required. + for(int32_t i = 0; i < numOfOutput; ++i) { + SSqlExpr* p = pExpr[i]; + if ((p->functionId == TSDB_FUNC_TAGPRJ) || + (p->functionId == TSDB_FUNC_TID_TAG && p->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) || + (p->functionId == TSDB_FUNC_COUNT && p->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) || + (p->functionId == TSDB_FUNC_BLKINFO)) { continue; } @@ -5758,8 +5985,8 @@ static bool validateQuerySourceCols(SQueryTableMsg *pQueryMsg, SSqlFuncMsg** pEx } } - for(int32_t i = 0; i < pQueryMsg->numOfOutput; ++i) { - if (!validateExprColumnInfo(pQueryMsg, pExprMsg[i], pTagCols)) { + for(int32_t i = 0; i < numOfOutput; ++i) { + if (!validateExprColumnInfo(pTableInfo, pExpr[i], pTagCols)) { return TSDB_CODE_QRY_INVALID_MSG; } } @@ -5786,6 +6013,37 @@ static char *createTableIdList(SQueryTableMsg *pQueryMsg, char *pMsg, SArray **p return pMsg; } +static int32_t deserializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t numOfFilters, char** pMsg) { + for (int32_t f = 0; f < numOfFilters; ++f) { + SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)(*pMsg); + + SColumnFilterInfo *pColFilter = &pColFilters[f]; + pColFilter->filterstr = htons(pFilterMsg->filterstr); + + (*pMsg) += sizeof(SColumnFilterInfo); + + if (pColFilter->filterstr) { + pColFilter->len = htobe64(pFilterMsg->len); + + pColFilter->pz = (int64_t)calloc(1, (size_t)(pColFilter->len + 1 * TSDB_NCHAR_SIZE)); // note: null-terminator + if (pColFilter->pz == 0) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + memcpy((void *)pColFilter->pz, (*pMsg), (size_t)pColFilter->len); + (*pMsg) += (pColFilter->len + 1); + } else { + pColFilter->lowerBndi = htobe64(pFilterMsg->lowerBndi); + pColFilter->upperBndi = htobe64(pFilterMsg->upperBndi); + } + + pColFilter->lowerRelOptr = htons(pFilterMsg->lowerRelOptr); + pColFilter->upperRelOptr = htons(pFilterMsg->upperRelOptr); + } + + return TSDB_CODE_SUCCESS; +} + /** * pQueryMsg->head has been converted before this function is called. * @@ -5802,7 +6060,6 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { } pQueryMsg->numOfTables = htonl(pQueryMsg->numOfTables); - pQueryMsg->window.skey = htobe64(pQueryMsg->window.skey); pQueryMsg->window.ekey = htobe64(pQueryMsg->window.ekey); pQueryMsg->interval.interval = htobe64(pQueryMsg->interval.interval); @@ -5821,10 +6078,10 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pQueryMsg->numOfOutput = htons(pQueryMsg->numOfOutput); pQueryMsg->numOfGroupCols = htons(pQueryMsg->numOfGroupCols); pQueryMsg->tagCondLen = htons(pQueryMsg->tagCondLen); - pQueryMsg->tsOffset = htonl(pQueryMsg->tsOffset); - pQueryMsg->tsLen = htonl(pQueryMsg->tsLen); - pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks); - pQueryMsg->tsOrder = htonl(pQueryMsg->tsOrder); + pQueryMsg->tsBuf.tsOffset = htonl(pQueryMsg->tsBuf.tsOffset); + pQueryMsg->tsBuf.tsLen = htonl(pQueryMsg->tsBuf.tsLen); + pQueryMsg->tsBuf.tsNumOfBlocks = htonl(pQueryMsg->tsBuf.tsNumOfBlocks); + pQueryMsg->tsBuf.tsOrder = htonl(pQueryMsg->tsBuf.tsOrder); pQueryMsg->numOfTags = htonl(pQueryMsg->numOfTags); pQueryMsg->tbnameCondLen = htonl(pQueryMsg->tbnameCondLen); pQueryMsg->secondStageOutput = htonl(pQueryMsg->secondStageOutput); @@ -5832,6 +6089,8 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pQueryMsg->prevResultLen = htonl(pQueryMsg->prevResultLen); pQueryMsg->sw.gap = htobe64(pQueryMsg->sw.gap); pQueryMsg->sw.primaryColId = htonl(pQueryMsg->sw.primaryColId); + pQueryMsg->tableScanOperator = htonl(pQueryMsg->tableScanOperator); + pQueryMsg->numOfOperator = htonl(pQueryMsg->numOfOperator); // query msg safety check if (!validateQueryMsg(pQueryMsg)) { @@ -5839,14 +6098,14 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { goto _cleanup; } - char *pMsg = (char *)(pQueryMsg->colList) + sizeof(SColumnInfo) * pQueryMsg->numOfCols; + char *pMsg = (char *)(pQueryMsg->tableCols) + sizeof(SColumnInfo) * pQueryMsg->numOfCols; for (int32_t col = 0; col < pQueryMsg->numOfCols; ++col) { - SColumnInfo *pColInfo = &pQueryMsg->colList[col]; + SColumnInfo *pColInfo = &pQueryMsg->tableCols[col]; pColInfo->colId = htons(pColInfo->colId); pColInfo->type = htons(pColInfo->type); pColInfo->bytes = htons(pColInfo->bytes); - pColInfo->numOfFilters = htons(pColInfo->numOfFilters); + pColInfo->flist.numOfFilters = htons(pColInfo->flist.numOfFilters); if (!isValidDataType(pColInfo->type)) { qDebug("qmsg:%p, invalid data type in source column, index:%d, type:%d", pQueryMsg, col, pColInfo->type); @@ -5854,102 +6113,57 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { goto _cleanup; } - int32_t numOfFilters = pColInfo->numOfFilters; + int32_t numOfFilters = pColInfo->flist.numOfFilters; if (numOfFilters > 0) { - pColInfo->filters = calloc(numOfFilters, sizeof(SColumnFilterInfo)); - if (pColInfo->filters == NULL) { + pColInfo->flist.filterInfo = calloc(numOfFilters, sizeof(SColumnFilterInfo)); + if (pColInfo->flist.filterInfo == NULL) { code = TSDB_CODE_QRY_OUT_OF_MEMORY; goto _cleanup; } } - for (int32_t f = 0; f < numOfFilters; ++f) { - SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)pMsg; - - SColumnFilterInfo *pColFilter = &pColInfo->filters[f]; - pColFilter->filterstr = htons(pFilterMsg->filterstr); - - pMsg += sizeof(SColumnFilterInfo); - - if (pColFilter->filterstr) { - pColFilter->len = htobe64(pFilterMsg->len); - - pColFilter->pz = (int64_t)calloc(1, (size_t)(pColFilter->len + 1 * TSDB_NCHAR_SIZE)); // note: null-terminator - if (pColFilter->pz == 0) { - code = TSDB_CODE_QRY_OUT_OF_MEMORY; - goto _cleanup; - } - - memcpy((void *)pColFilter->pz, pMsg, (size_t)pColFilter->len); - pMsg += (pColFilter->len + 1); - } else { - pColFilter->lowerBndi = htobe64(pFilterMsg->lowerBndi); - pColFilter->upperBndi = htobe64(pFilterMsg->upperBndi); - } - - pColFilter->lowerRelOptr = htons(pFilterMsg->lowerRelOptr); - pColFilter->upperRelOptr = htons(pFilterMsg->upperRelOptr); + code = deserializeColFilterInfo(pColInfo->flist.filterInfo, numOfFilters, &pMsg); + if (code != TSDB_CODE_SUCCESS) { + goto _cleanup; } } - param->pExprMsg = calloc(pQueryMsg->numOfOutput, POINTER_BYTES); - if (param->pExprMsg == NULL) { + param->tableScanOperator = pQueryMsg->tableScanOperator; + param->pExpr = calloc(pQueryMsg->numOfOutput, POINTER_BYTES); + if (param->pExpr == NULL) { code = TSDB_CODE_QRY_OUT_OF_MEMORY; goto _cleanup; } - SSqlFuncMsg *pExprMsg = (SSqlFuncMsg *)pMsg; + SSqlExpr *pExprMsg = (SSqlExpr *)pMsg; for (int32_t i = 0; i < pQueryMsg->numOfOutput; ++i) { - param->pExprMsg[i] = pExprMsg; + param->pExpr[i] = pExprMsg; pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex); pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId); pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag); - pExprMsg->colType = htons(pExprMsg->colType); pExprMsg->colBytes = htons(pExprMsg->colBytes); + pExprMsg->colType = htons(pExprMsg->colType); + + pExprMsg->resType = htons(pExprMsg->resType); + pExprMsg->resBytes = htons(pExprMsg->resBytes); pExprMsg->functionId = htons(pExprMsg->functionId); pExprMsg->numOfParams = htons(pExprMsg->numOfParams); pExprMsg->resColId = htons(pExprMsg->resColId); - pExprMsg->filterNum = htonl(pExprMsg->filterNum); - - pMsg += sizeof(SSqlFuncMsg); - - SColumnFilterInfo* pExprFilterInfo = pExprMsg->filterInfo; - - pMsg += sizeof(SColumnFilterInfo) * pExprMsg->filterNum; - - for (int32_t f = 0; f < pExprMsg->filterNum; ++f) { - SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)pExprFilterInfo; - - pFilterMsg->filterstr = htons(pFilterMsg->filterstr); - - if (pFilterMsg->filterstr) { - pFilterMsg->len = htobe64(pFilterMsg->len); - - pFilterMsg->pz = (int64_t)pMsg; - pMsg += (pFilterMsg->len + 1); - } else { - pFilterMsg->lowerBndi = htobe64(pFilterMsg->lowerBndi); - pFilterMsg->upperBndi = htobe64(pFilterMsg->upperBndi); - } - - pFilterMsg->lowerRelOptr = htons(pFilterMsg->lowerRelOptr); - pFilterMsg->upperRelOptr = htons(pFilterMsg->upperRelOptr); - - pExprFilterInfo++; - } + pExprMsg->flist.numOfFilters = htons(pExprMsg->flist.numOfFilters); + pMsg += sizeof(SSqlExpr); for (int32_t j = 0; j < pExprMsg->numOfParams; ++j) { - pExprMsg->arg[j].argType = htons(pExprMsg->arg[j].argType); - pExprMsg->arg[j].argBytes = htons(pExprMsg->arg[j].argBytes); + pExprMsg->param[j].nType = htons(pExprMsg->param[j].nType); + pExprMsg->param[j].nLen = htons(pExprMsg->param[j].nLen); - if (pExprMsg->arg[j].argType == TSDB_DATA_TYPE_BINARY) { - pExprMsg->arg[j].argValue.pz = pMsg; - pMsg += pExprMsg->arg[j].argBytes; // one more for the string terminated char. + if (pExprMsg->param[j].nType == TSDB_DATA_TYPE_BINARY) { + pExprMsg->param[j].pz = pMsg; + pMsg += pExprMsg->param[j].nLen; // one more for the string terminated char. } else { - pExprMsg->arg[j].argValue.i64 = htobe64(pExprMsg->arg[j].argValue.i64); + pExprMsg->param[j].i64 = htobe64(pExprMsg->param[j].i64); } } @@ -5961,36 +6175,43 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { } } - pExprMsg = (SSqlFuncMsg *)pMsg; + if (pExprMsg->flist.numOfFilters > 0) { + pExprMsg->flist.filterInfo = calloc(pExprMsg->flist.numOfFilters, sizeof(SColumnFilterInfo)); + } + + deserializeColFilterInfo(pExprMsg->flist.filterInfo, pExprMsg->flist.numOfFilters, &pMsg); + pExprMsg = (SSqlExpr *)pMsg; } if (pQueryMsg->secondStageOutput) { - pExprMsg = (SSqlFuncMsg *)pMsg; - param->pSecExprMsg = calloc(pQueryMsg->secondStageOutput, POINTER_BYTES); + pExprMsg = (SSqlExpr *)pMsg; + param->pSecExpr = calloc(pQueryMsg->secondStageOutput, POINTER_BYTES); for (int32_t i = 0; i < pQueryMsg->secondStageOutput; ++i) { - param->pSecExprMsg[i] = pExprMsg; + param->pSecExpr[i] = pExprMsg; pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex); pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId); pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag); - pExprMsg->colType = htons(pExprMsg->colType); + pExprMsg->resType = htons(pExprMsg->resType); + pExprMsg->resBytes = htons(pExprMsg->resBytes); pExprMsg->colBytes = htons(pExprMsg->colBytes); + pExprMsg->colType = htons(pExprMsg->colType); pExprMsg->functionId = htons(pExprMsg->functionId); pExprMsg->numOfParams = htons(pExprMsg->numOfParams); - pMsg += sizeof(SSqlFuncMsg); + pMsg += sizeof(SSqlExpr); for (int32_t j = 0; j < pExprMsg->numOfParams; ++j) { - pExprMsg->arg[j].argType = htons(pExprMsg->arg[j].argType); - pExprMsg->arg[j].argBytes = htons(pExprMsg->arg[j].argBytes); + pExprMsg->param[j].nType = htons(pExprMsg->param[j].nType); + pExprMsg->param[j].nLen = htons(pExprMsg->param[j].nLen); - if (pExprMsg->arg[j].argType == TSDB_DATA_TYPE_BINARY) { - pExprMsg->arg[j].argValue.pz = pMsg; - pMsg += pExprMsg->arg[j].argBytes; // one more for the string terminated char. + if (pExprMsg->param[j].nType == TSDB_DATA_TYPE_BINARY) { + pExprMsg->param[j].pz = pMsg; + pMsg += pExprMsg->param[j].nLen; // one more for the string terminated char. } else { - pExprMsg->arg[j].argValue.i64 = htobe64(pExprMsg->arg[j].argValue.i64); + pExprMsg->param[j].i64 = htobe64(pExprMsg->param[j].i64); } } @@ -6002,7 +6223,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { } } - pExprMsg = (SSqlFuncMsg *)pMsg; + pExprMsg = (SSqlExpr *)pMsg; } } @@ -6058,7 +6279,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pTagCol->colId = htons(pTagCol->colId); pTagCol->bytes = htons(pTagCol->bytes); pTagCol->type = htons(pTagCol->type); - pTagCol->numOfFilters = 0; + pTagCol->flist.numOfFilters = 0; param->pTagColumnInfo[i] = *pTagCol; pMsg += sizeof(SColumnInfo); @@ -6100,13 +6321,22 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { } //skip ts buf - if ((pQueryMsg->tsOffset + pQueryMsg->tsLen) > 0) { - pMsg = (char *)pQueryMsg + pQueryMsg->tsOffset + pQueryMsg->tsLen; + if ((pQueryMsg->tsBuf.tsOffset + pQueryMsg->tsBuf.tsLen) > 0) { + pMsg = (char *)pQueryMsg + pQueryMsg->tsBuf.tsOffset + pQueryMsg->tsBuf.tsLen; + } + + param->pOperator = taosArrayInit(pQueryMsg->numOfOperator, sizeof(int32_t)); + for(int32_t i = 0; i < pQueryMsg->numOfOperator; ++i) { + int32_t op = htonl(*(int32_t*)pMsg); + taosArrayPush(param->pOperator, &op); + + pMsg += sizeof(int32_t); } param->sql = strndup(pMsg, pQueryMsg->sqlstrLen); - if (!validateQuerySourceCols(pQueryMsg, param->pExprMsg, param->pTagColumnInfo)) { + SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols}; + if (!validateQueryTableCols(&info, param->pExpr, pQueryMsg->numOfOutput, param->pTagColumnInfo, pQueryMsg)) { code = TSDB_CODE_QRY_INVALID_MSG; goto _cleanup; } @@ -6115,7 +6345,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { "outputCols:%d, numOfCols:%d, interval:%" PRId64 ", fillType:%d, comptsLen:%d, compNumOfBlocks:%d, limit:%" PRId64 ", offset:%" PRId64, pQueryMsg, pQueryMsg->numOfTables, pQueryMsg->queryType, pQueryMsg->window.skey, pQueryMsg->window.ekey, pQueryMsg->numOfGroupCols, pQueryMsg->order, pQueryMsg->numOfOutput, pQueryMsg->numOfCols, pQueryMsg->interval.interval, - pQueryMsg->fillType, pQueryMsg->tsLen, pQueryMsg->tsNumOfBlocks, pQueryMsg->limit, pQueryMsg->offset); + pQueryMsg->fillType, pQueryMsg->tsBuf.tsLen, pQueryMsg->tsBuf.tsNumOfBlocks, pQueryMsg->limit, pQueryMsg->offset); qDebug("qmsg:%p, sql:%s", pQueryMsg, param->sql); return TSDB_CODE_SUCCESS; @@ -6125,75 +6355,75 @@ _cleanup: return code; } -int32_t cloneExprFilterInfo(SColumnFilterInfo **dst, SColumnFilterInfo* src, int32_t filterNum) { - if (filterNum <= 0) { + int32_t cloneExprFilterInfo(SColumnFilterInfo **dst, SColumnFilterInfo* src, int32_t filterNum) { + if (filterNum <= 0) { + return TSDB_CODE_SUCCESS; + } + + *dst = calloc(filterNum, sizeof(*src)); + if (*dst == NULL) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + memcpy(*dst, src, sizeof(*src) * filterNum); + + for (int32_t i = 0; i < filterNum; i++) { + if ((*dst)[i].filterstr && dst[i]->len > 0) { + void *pz = calloc(1, (size_t)(*dst)[i].len + 1); + + if (pz == NULL) { + if (i == 0) { + free(*dst); + } else { + freeColumnFilterInfo(*dst, i); + } + + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + memcpy(pz, (void *)src->pz, (size_t)src->len + 1); + + (*dst)[i].pz = (int64_t)pz; + } + } + return TSDB_CODE_SUCCESS; } - *dst = calloc(filterNum, sizeof(*src)); - if (*dst == NULL) { - return TSDB_CODE_QRY_OUT_OF_MEMORY; - } - - memcpy(*dst, src, sizeof(*src) * filterNum); - - for (int32_t i = 0; i < filterNum; i++) { - if ((*dst)[i].filterstr && dst[i]->len > 0) { - void *pz = calloc(1, (size_t)(*dst)[i].len + 1); - - if (pz == NULL) { - if (i == 0) { - free(*dst); - } else { - freeColumnFilterInfo(*dst, i); - } - - return TSDB_CODE_QRY_OUT_OF_MEMORY; - } - - memcpy(pz, (void *)src->pz, (size_t)src->len + 1); - - (*dst)[i].pz = (int64_t)pz; - } - } - - return TSDB_CODE_SUCCESS; -} - - -static int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, SQueryTableMsg *pQueryMsg) { +int32_t buildArithmeticExprFromMsg(SExprInfo *pExprInfo, void *pQueryMsg) { qDebug("qmsg:%p create arithmetic expr from binary", pQueryMsg); tExprNode* pExprNode = NULL; TRY(TSDB_MAX_TAG_CONDITIONS) { - pExprNode = exprTreeFromBinary(pArithExprInfo->base.arg[0].argValue.pz, pArithExprInfo->base.arg[0].argBytes); + pExprNode = exprTreeFromBinary(pExprInfo->base.param[0].pz, pExprInfo->base.param[0].nLen); } CATCH( code ) { CLEANUP_EXECUTE(); - qError("qmsg:%p failed to create arithmetic expression string from:%s, reason: %s", pQueryMsg, pArithExprInfo->base.arg[0].argValue.pz, tstrerror(code)); + qError("qmsg:%p failed to create arithmetic expression string from:%s, reason: %s", pQueryMsg, pExprInfo->base.param[0].pz, tstrerror(code)); return code; } END_TRY if (pExprNode == NULL) { - qError("qmsg:%p failed to create arithmetic expression string from:%s", pQueryMsg, pArithExprInfo->base.arg[0].argValue.pz); + qError("qmsg:%p failed to create arithmetic expression string from:%s", pQueryMsg, pExprInfo->base.param[0].pz); return TSDB_CODE_QRY_APP_ERROR; } - pArithExprInfo->pExpr = pExprNode; + pExprInfo->pExpr = pExprNode; return TSDB_CODE_SUCCESS; } -static int32_t updateOutputBufForTopBotQuery(SQueryTableMsg* pQueryMsg, SColumnInfo* pTagCols, SExprInfo* pExprs, int32_t numOfOutput, int32_t tagLen, bool superTable) { + +static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SColumnInfo* pTagCols, SExprInfo* pExprs, int32_t numOfOutput, int32_t tagLen, bool superTable) { for (int32_t i = 0; i < numOfOutput; ++i) { int16_t functId = pExprs[i].base.functionId; if (functId == TSDB_FUNC_TOP || functId == TSDB_FUNC_BOTTOM) { - int32_t j = getColumnIndexInSource(pQueryMsg, &pExprs[i].base, pTagCols); - if (j < 0 || j >= pQueryMsg->numOfCols) { + int32_t j = getColumnIndexInSource(pTableInfo, &pExprs[i].base, pTagCols); + if (j < 0 || j >= pTableInfo->numOfCols) { return TSDB_CODE_QRY_INVALID_MSG; } else { - SColumnInfo* pCol = &pQueryMsg->colList[j]; - int32_t ret = getResultDataInfo(pCol->type, pCol->bytes, functId, (int32_t)pExprs[i].base.arg[0].argValue.i64, - &pExprs[i].type, &pExprs[i].bytes, &pExprs[i].interBytes, tagLen, superTable); + SColumnInfo* pCol = &pTableInfo->colList[j]; + int32_t ret = getResultDataInfo(pCol->type, pCol->bytes, functId, (int32_t)pExprs[i].base.param[0].i64, + &pExprs[i].base.resType, &pExprs[i].base.resBytes, &pExprs[i].base.interBytes, tagLen, superTable); assert(ret == TSDB_CODE_SUCCESS); } } @@ -6203,29 +6433,33 @@ static int32_t updateOutputBufForTopBotQuery(SQueryTableMsg* pQueryMsg, SColumnI } // TODO tag length should be passed from client -int32_t createQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutput, SExprInfo** pExprInfo, - SSqlFuncMsg** pExprMsg, SColumnInfo* pTagCols) { +int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo, + SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg) { *pExprInfo = NULL; int32_t code = TSDB_CODE_SUCCESS; - SExprInfo *pExprs = (SExprInfo *)calloc(pQueryMsg->numOfOutput, sizeof(SExprInfo)); + SExprInfo *pExprs = (SExprInfo *)calloc(numOfOutput, sizeof(SExprInfo)); if (pExprs == NULL) { return TSDB_CODE_QRY_OUT_OF_MEMORY; } - bool isSuperTable = QUERY_IS_STABLE_QUERY(pQueryMsg->queryType); + bool isSuperTable = QUERY_IS_STABLE_QUERY(queryType); int16_t tagLen = 0; for (int32_t i = 0; i < numOfOutput; ++i) { pExprs[i].base = *pExprMsg[i]; - pExprs[i].bytes = 0; + memset(pExprs[i].base.param, 0, sizeof(tVariant) * tListLen(pExprs[i].base.param)); + + for (int32_t j = 0; j < pExprMsg[i]->numOfParams; ++j) { + tVariantAssign(&pExprs[i].base.param[j], &pExprMsg[i]->param[j]); + } int16_t type = 0; int16_t bytes = 0; // parse the arithmetic expression if (pExprs[i].base.functionId == TSDB_FUNC_ARITHM) { - code = buildArithmeticExprFromMsg(&pExprs[i], pQueryMsg); + code = buildArithmeticExprFromMsg(&pExprs[i], pMsg); if (code != TSDB_CODE_SUCCESS) { tfree(pExprs); @@ -6242,30 +6476,29 @@ int32_t createQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutpu SSchema s = tGetBlockDistColumnSchema(); type = s.type; bytes = s.bytes; - } else if (pExprs[i].base.colInfo.colId <= TSDB_UD_COLUMN_INDEX) { + } 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); - type = pExprs[i].base.arg[1].argType; - bytes = pExprs[i].base.arg[1].argBytes; - + type = pExprs[i].base.param[1].nType; + bytes = pExprs[i].base.param[1].nLen; if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { bytes += VARSTR_HEADER_SIZE; } } else { - int32_t j = getColumnIndexInSource(pQueryMsg, &pExprs[i].base, pTagCols); + 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 >= pQueryMsg->numOfTags) { + if (j < TSDB_BLOCK_DIST_COLUMN_INDEX || j >= pTableInfo->numOfTags) { return TSDB_CODE_QRY_INVALID_MSG; } } else { - if (j < PRIMARYKEY_TIMESTAMP_COL_INDEX || j >= pQueryMsg->numOfCols) { + if (j < PRIMARYKEY_TIMESTAMP_COL_INDEX || j >= pTableInfo->numOfCols) { return TSDB_CODE_QRY_INVALID_MSG; } } if (pExprs[i].base.colInfo.colId != TSDB_TBNAME_COLUMN_INDEX && j >= 0) { - SColumnInfo* pCol = (TSDB_COL_IS_TAG(pExprs[i].base.colInfo.flag))? &pTagCols[j]:&pQueryMsg->colList[j]; + SColumnInfo* pCol = (TSDB_COL_IS_TAG(pExprs[i].base.colInfo.flag))? &pTagCols[j]:&pTableInfo->colList[j]; type = pCol->type; bytes = pCol->bytes; } else { @@ -6275,43 +6508,45 @@ int32_t createQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutpu bytes = s->bytes; } - if (pExprs[i].base.filterNum > 0) { - int32_t ret = cloneExprFilterInfo(&pExprs[i].pFilter, pExprMsg[i]->filterInfo, pExprMsg[i]->filterNum); + if (pExprs[i].base.flist.numOfFilters > 0) { + int32_t ret = cloneExprFilterInfo(&pExprs[i].base.flist.filterInfo, pExprMsg[i]->flist.filterInfo, + pExprMsg[i]->flist.numOfFilters); if (ret) { return ret; } } } - int32_t param = (int32_t)pExprs[i].base.arg[0].argValue.i64; + int32_t param = (int32_t)pExprs[i].base.param[0].i64; if (pExprs[i].base.functionId != TSDB_FUNC_ARITHM && (type != pExprs[i].base.colType || bytes != pExprs[i].base.colBytes)) { tfree(pExprs); return TSDB_CODE_QRY_INVALID_MSG; } - if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].type, &pExprs[i].bytes, - &pExprs[i].interBytes, 0, isSuperTable) != TSDB_CODE_SUCCESS) { + if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes, + &pExprs[i].base.interBytes, 0, isSuperTable) != TSDB_CODE_SUCCESS) { tfree(pExprs); return TSDB_CODE_QRY_INVALID_MSG; } if (pExprs[i].base.functionId == TSDB_FUNC_TAG_DUMMY || pExprs[i].base.functionId == TSDB_FUNC_TS_DUMMY) { - tagLen += pExprs[i].bytes; + tagLen += pExprs[i].base.resBytes; } - assert(isValidDataType(pExprs[i].type)); + assert(isValidDataType(pExprs[i].base.resType)); } // the tag length is affected by other tag columns, so this should be update. - updateOutputBufForTopBotQuery(pQueryMsg, pTagCols, pExprs, numOfOutput, tagLen, isSuperTable); + updateOutputBufForTopBotQuery(pTableInfo, pTagCols, pExprs, numOfOutput, tagLen, isSuperTable); *pExprInfo = pExprs; return TSDB_CODE_SUCCESS; } -int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, - SSqlFuncMsg **pExprMsg, SExprInfo *prevExpr) { +// todo refactor +int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutput, SExprInfo** pExprInfo, + SSqlExpr** pExpr, SExprInfo* prevExpr) { *pExprInfo = NULL; int32_t code = TSDB_CODE_SUCCESS; @@ -6323,8 +6558,14 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t nu bool isSuperTable = QUERY_IS_STABLE_QUERY(pQueryMsg->queryType); for (int32_t i = 0; i < numOfOutput; ++i) { - pExprs[i].base = *pExprMsg[i]; - pExprs[i].bytes = 0; + pExprs[i].base = *pExpr[i]; + memset(pExprs[i].base.param, 0, sizeof(tVariant) * tListLen(pExprs[i].base.param)); + + for (int32_t j = 0; j < pExpr[i]->numOfParams; ++j) { + tVariantAssign(&pExprs[i].base.param[j], &pExpr[i]->param[j]); + } + + pExprs[i].base.resType = 0; int16_t type = 0; int16_t bytes = 0; @@ -6344,18 +6585,18 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t nu int32_t index = pExprs[i].base.colInfo.colIndex; assert(prevExpr[index].base.resColId == pExprs[i].base.colInfo.colId); - type = prevExpr[index].type; - bytes = prevExpr[index].bytes; + type = prevExpr[index].base.resType; + bytes = prevExpr[index].base.resBytes; } - int32_t param = (int32_t)pExprs[i].base.arg[0].argValue.i64; - if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].type, &pExprs[i].bytes, - &pExprs[i].interBytes, 0, isSuperTable) != TSDB_CODE_SUCCESS) { + int32_t param = (int32_t)pExprs[i].base.param[0].i64; + if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes, + &pExprs[i].base.interBytes, 0, isSuperTable) != TSDB_CODE_SUCCESS) { tfree(pExprs); return TSDB_CODE_QRY_INVALID_MSG; } - assert(isValidDataType(pExprs[i].type)); + assert(isValidDataType(pExprs[i].base.resType)); } *pExprInfo = pExprs; @@ -6386,38 +6627,29 @@ SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex * return pGroupbyExpr; } -static int32_t createFilterInfo(SQuery *pQuery, uint64_t qId) { - for (int32_t i = 0; i < pQuery->numOfCols; ++i) { - if (pQuery->colList[i].numOfFilters > 0) { - pQuery->numOfFilterCols++; - } - } - - if (pQuery->numOfFilterCols == 0) { - return TSDB_CODE_SUCCESS; - } - - pQuery->pFilterInfo = calloc(1, sizeof(SSingleColumnFilterInfo) * pQuery->numOfFilterCols); - if (pQuery->pFilterInfo == NULL) { +static 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; } - for (int32_t i = 0, j = 0; i < pQuery->numOfCols; ++i) { - if (pQuery->colList[i].numOfFilters > 0) { - SSingleColumnFilterInfo *pFilterInfo = &pQuery->pFilterInfo[j]; + for (int32_t i = 0, j = 0; i < numOfCols; ++i) { + if (pCols[i].flist.numOfFilters > 0) { + SSingleColumnFilterInfo* pFilter = &((*pFilterInfo)[j]); - memcpy(&pFilterInfo->info, &pQuery->colList[i], sizeof(SColumnInfo)); - pFilterInfo->info = pQuery->colList[i]; + memcpy(&pFilter->info, &pCols[i], sizeof(SColumnInfo)); + pFilter->info = pCols[i]; - pFilterInfo->numOfFilters = pQuery->colList[i].numOfFilters; - pFilterInfo->pFilters = calloc(pFilterInfo->numOfFilters, sizeof(SColumnFilterElem)); - if (pFilterInfo->pFilters == NULL) { + pFilter->numOfFilters = pCols[i].flist.numOfFilters; + pFilter->pFilters = calloc(pFilter->numOfFilters, sizeof(SColumnFilterElem)); + if (pFilter->pFilters == NULL) { return TSDB_CODE_QRY_OUT_OF_MEMORY; } - for (int32_t f = 0; f < pFilterInfo->numOfFilters; ++f) { - SColumnFilterElem *pSingleColFilter = &pFilterInfo->pFilters[f]; - pSingleColFilter->filterInfo = pQuery->colList[i].filters[f]; + for (int32_t f = 0; f < pFilter->numOfFilters; ++f) { + SColumnFilterElem* pSingleColFilter = &pFilter->pFilters[f]; + pSingleColFilter->filterInfo = pCols[i].flist.filterInfo[f]; int32_t lower = pSingleColFilter->filterInfo.lowerRelOptr; int32_t upper = pSingleColFilter->filterInfo.upperRelOptr; @@ -6432,7 +6664,7 @@ static int32_t createFilterInfo(SQuery *pQuery, uint64_t qId) { return TSDB_CODE_QRY_INVALID_MSG; } - pSingleColFilter->bytes = pQuery->colList[i].bytes; + pSingleColFilter->bytes = pCols[i].bytes; } j++; @@ -6442,11 +6674,39 @@ static int32_t createFilterInfo(SQuery *pQuery, uint64_t qId) { return TSDB_CODE_SUCCESS; } -static void doUpdateExprColumnIndex(SQuery *pQuery) { - assert(pQuery->pExpr1 != NULL && pQuery != NULL); +void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols) { + for (int32_t i = 0; i < numOfFilterCols; ++i) { + if (pFilterInfo[i].numOfFilters > 0) { + tfree(pFilterInfo[i].pFilters); + } + } - for (int32_t k = 0; k < pQuery->numOfOutput; ++k) { - SSqlFuncMsg *pSqlExprMsg = &pQuery->pExpr1[k].base; + tfree(pFilterInfo); + return NULL; +} + +static 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++; + } + } + + if (pQueryAttr->numOfFilterCols == 0) { + return TSDB_CODE_SUCCESS; + } + + doCreateFilterInfo(pQueryAttr->tableCols, pQueryAttr->numOfCols, pQueryAttr->numOfFilterCols, + &pQueryAttr->pFilterInfo, qId); + + return TSDB_CODE_SUCCESS; +} + +static void doUpdateExprColumnIndex(SQueryAttr *pQueryAttr) { + assert(pQueryAttr->pExpr1 != NULL && pQueryAttr != NULL); + + for (int32_t k = 0; k < pQueryAttr->numOfOutput; ++k) { + SSqlExpr *pSqlExprMsg = &pQueryAttr->pExpr1[k].base; if (pSqlExprMsg->functionId == TSDB_FUNC_ARITHM) { continue; } @@ -6455,34 +6715,34 @@ static void doUpdateExprColumnIndex(SQuery *pQuery) { SColIndex *pColIndex = &pSqlExprMsg->colInfo; if (TSDB_COL_IS_NORMAL_COL(pColIndex->flag)) { int32_t f = 0; - for (f = 0; f < pQuery->numOfCols; ++f) { - if (pColIndex->colId == pQuery->colList[f].colId) { + for (f = 0; f < pQueryAttr->numOfCols; ++f) { + if (pColIndex->colId == pQueryAttr->tableCols[f].colId) { pColIndex->colIndex = f; break; } } - assert(f < pQuery->numOfCols); + 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(pQuery->numOfOutput == 1); + assert(pQueryAttr->numOfOutput == 1); } else { int32_t f = 0; - for (f = 0; f < pQuery->numOfTags; ++f) { - if (pColIndex->colId == pQuery->tagColList[f].colId) { + for (f = 0; f < pQueryAttr->numOfTags; ++f) { + if (pColIndex->colId == pQueryAttr->tagColList[f].colId) { pColIndex->colIndex = f; break; } } - assert(f < pQuery->numOfTags || pColIndex->colId == TSDB_TBNAME_COLUMN_INDEX || pColIndex->colId == TSDB_BLOCK_DIST_COLUMN_INDEX); + assert(f < pQueryAttr->numOfTags || pColIndex->colId == TSDB_TBNAME_COLUMN_INDEX || pColIndex->colId == TSDB_BLOCK_DIST_COLUMN_INDEX); } } } -void setResultBufSize(SQuery* pQuery, SRspResultInfo* pResultInfo) { +void setResultBufSize(SQueryAttr* pQueryAttr, SRspResultInfo* pResultInfo) { const int32_t DEFAULT_RESULT_MSG_SIZE = 1024 * (1024 + 512); // the minimum number of rows for projection query @@ -6491,8 +6751,8 @@ void setResultBufSize(SQuery* pQuery, SRspResultInfo* pResultInfo) { const float THRESHOLD_RATIO = 0.85f; - if (isProjQuery(pQuery)) { - int32_t numOfRes = DEFAULT_RESULT_MSG_SIZE / pQuery->resultRowSize; + if (isProjQuery(pQueryAttr)) { + int32_t numOfRes = DEFAULT_RESULT_MSG_SIZE / pQueryAttr->resultRowSize; if (numOfRes < MIN_ROWS_FOR_PRJ_QUERY) { numOfRes = MIN_ROWS_FOR_PRJ_QUERY; } @@ -6511,7 +6771,7 @@ FORCE_INLINE bool checkQIdEqual(void *qHandle, uint64_t qId) { } SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs, - SExprInfo* pSecExprs, STableGroupInfo* pTableGroupInfo, SColumnInfo* pTagCols, bool stableQuery, + SExprInfo* pSecExprs, STableGroupInfo* pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId, char* sql, uint64_t *qId) { int16_t numOfCols = pQueryMsg->numOfCols; int16_t numOfOutput = pQueryMsg->numOfOutput; @@ -6525,73 +6785,87 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr // to make sure third party won't overwrite this structure pQInfo->signature = pQInfo; - SQuery* pQuery = &pQInfo->query; - pQInfo->runtimeEnv.pQuery = pQuery; + SQueryAttr* pQueryAttr = &pQInfo->query; + pQInfo->runtimeEnv.pQueryAttr = pQueryAttr; - pQuery->tableGroupInfo = *pTableGroupInfo; - pQuery->numOfCols = numOfCols; - pQuery->numOfOutput = numOfOutput; - pQuery->limit.limit = pQueryMsg->limit; - pQuery->limit.offset = pQueryMsg->offset; - pQuery->order.order = pQueryMsg->order; - pQuery->order.orderColId = pQueryMsg->orderColId; - pQuery->pExpr1 = pExprs; - pQuery->pExpr2 = pSecExprs; - pQuery->numOfExpr2 = pQueryMsg->secondStageOutput; - pQuery->pGroupbyExpr = pGroupbyExpr; - memcpy(&pQuery->interval, &pQueryMsg->interval, sizeof(pQuery->interval)); - pQuery->fillType = pQueryMsg->fillType; - pQuery->numOfTags = pQueryMsg->numOfTags; - pQuery->tagColList = pTagCols; - pQuery->prjInfo.vgroupLimit = pQueryMsg->vgroupLimit; - pQuery->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX; - pQuery->sw = pQueryMsg->sw; - pQuery->colList = calloc(numOfCols, sizeof(SSingleColumnFilterInfo)); - if (pQuery->colList == NULL) { + pQueryAttr->tableGroupInfo = *pTableGroupInfo; + pQueryAttr->numOfCols = numOfCols; + pQueryAttr->numOfOutput = numOfOutput; + pQueryAttr->limit.limit = pQueryMsg->limit; + pQueryAttr->limit.offset = pQueryMsg->offset; + pQueryAttr->order.order = pQueryMsg->order; + pQueryAttr->order.orderColId = pQueryMsg->orderColId; + pQueryAttr->pExpr1 = pExprs; + pQueryAttr->pExpr2 = pSecExprs; + pQueryAttr->numOfExpr2 = pQueryMsg->secondStageOutput; + pQueryAttr->pGroupbyExpr = pGroupbyExpr; + memcpy(&pQueryAttr->interval, &pQueryMsg->interval, sizeof(pQueryAttr->interval)); + pQueryAttr->fillType = pQueryMsg->fillType; + pQueryAttr->numOfTags = pQueryMsg->numOfTags; + pQueryAttr->tagColList = pTagCols; + pQueryAttr->prjInfo.vgroupLimit = pQueryMsg->vgroupLimit; + pQueryAttr->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX; + pQueryAttr->sw = pQueryMsg->sw; + + pQueryAttr->stableQuery = pQueryMsg->stableQuery; + pQueryAttr->topBotQuery = pQueryMsg->topBotQuery; + pQueryAttr->groupbyColumn = pQueryMsg->groupbyColumn; + pQueryAttr->hasTagResults = pQueryMsg->hasTagResults; + pQueryAttr->timeWindowInterpo = pQueryMsg->timeWindowInterpo; + pQueryAttr->queryBlockDist = pQueryMsg->queryBlockDist; + pQueryAttr->stabledev = pQueryMsg->stabledev; + pQueryAttr->tsCompQuery = pQueryMsg->tsCompQuery; + pQueryAttr->simpleAgg = pQueryMsg->simpleAgg; + pQueryAttr->pointInterpQuery = pQueryMsg->pointInterpQuery; + pQueryAttr->needReverseScan = pQueryMsg->needReverseScan; + pQueryAttr->vgId = vgId; + + pQueryAttr->tableCols = calloc(numOfCols, sizeof(SSingleColumnFilterInfo)); + if (pQueryAttr->tableCols == NULL) { goto _cleanup; } - pQuery->srcRowSize = 0; - pQuery->maxSrcColumnSize = 0; + pQueryAttr->srcRowSize = 0; + pQueryAttr->maxTableColumnWidth = 0; for (int16_t i = 0; i < numOfCols; ++i) { - pQuery->colList[i] = pQueryMsg->colList[i]; - pQuery->colList[i].filters = tFilterInfoDup(pQueryMsg->colList[i].filters, pQuery->colList[i].numOfFilters); + pQueryAttr->tableCols[i] = pQueryMsg->tableCols[i]; + pQueryAttr->tableCols[i].flist.filterInfo = tFilterInfoDup(pQueryMsg->tableCols[i].flist.filterInfo, pQueryAttr->tableCols[i].flist.numOfFilters); - pQuery->srcRowSize += pQuery->colList[i].bytes; - if (pQuery->maxSrcColumnSize < pQuery->colList[i].bytes) { - pQuery->maxSrcColumnSize = pQuery->colList[i].bytes; + pQueryAttr->srcRowSize += pQueryAttr->tableCols[i].bytes; + if (pQueryAttr->maxTableColumnWidth < pQueryAttr->tableCols[i].bytes) { + pQueryAttr->maxTableColumnWidth = pQueryAttr->tableCols[i].bytes; } } // calculate the result row size for (int16_t col = 0; col < numOfOutput; ++col) { - assert(pExprs[col].bytes > 0); - pQuery->resultRowSize += pExprs[col].bytes; + assert(pExprs[col].base.resBytes > 0); + pQueryAttr->resultRowSize += pExprs[col].base.resBytes; // keep the tag length if (TSDB_COL_IS_TAG(pExprs[col].base.colInfo.flag)) { - pQuery->tagLen += pExprs[col].bytes; + pQueryAttr->tagLen += pExprs[col].base.resBytes; } - if (pExprs[col].pFilter) { - ++pQuery->havingNum; + if (pExprs[col].base.flist.filterInfo) { + ++pQueryAttr->havingNum; } } - doUpdateExprColumnIndex(pQuery); - int32_t ret = createFilterInfo(pQuery, pQInfo->qId); + doUpdateExprColumnIndex(pQueryAttr); + int32_t ret = createFilterInfo(pQueryAttr, pQInfo->qId); if (ret != TSDB_CODE_SUCCESS) { goto _cleanup; } - if (pQuery->fillType != TSDB_FILL_NONE) { - pQuery->fillVal = malloc(sizeof(int64_t) * pQuery->numOfOutput); - if (pQuery->fillVal == NULL) { + if (pQueryAttr->fillType != TSDB_FILL_NONE) { + pQueryAttr->fillVal = malloc(sizeof(int64_t) * pQueryAttr->numOfOutput); + if (pQueryAttr->fillVal == NULL) { goto _cleanup; } // the first column is the timestamp - memcpy(pQuery->fillVal, (char *)pQueryMsg->fillVal, pQuery->numOfOutput * sizeof(int64_t)); + memcpy(pQueryAttr->fillVal, (char *)pQueryMsg->fillVal, pQueryAttr->numOfOutput * sizeof(int64_t)); } size_t numOfGroups = 0; @@ -6615,17 +6889,15 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr pthread_mutex_init(&pQInfo->lock, NULL); tsem_init(&pQInfo->ready, 0, 0); - pQuery->window = pQueryMsg->window; - changeExecuteScanOrder(pQInfo, pQueryMsg, stableQuery); + pQueryAttr->window = pQueryMsg->window; + changeExecuteScanOrder(pQInfo, pQueryMsg, pQueryAttr->stableQuery); SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - bool groupByCol = isGroupbyColumn(pQuery->pGroupbyExpr); - - STimeWindow window = pQuery->window; + STimeWindow window = pQueryAttr->window; int32_t index = 0; for(int32_t i = 0; i < numOfGroups; ++i) { - SArray* pa = taosArrayGetP(pQuery->tableGroupInfo.pGroupList, i); + SArray* pa = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); size_t s = taosArrayGetSize(pa); SArray* p1 = taosArrayInit(s, POINTER_BYTES); @@ -6640,7 +6912,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr window.skey = info->lastKey; void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo); - STableQueryInfo* item = createTableQueryInfo(pQuery, info->pTable, groupByCol, window, buf); + STableQueryInfo* item = createTableQueryInfo(pQueryAttr, info->pTable, pQueryAttr->groupbyColumn, window, buf); if (item == NULL) { goto _cleanup; } @@ -6654,7 +6926,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr } } - colIdCheck(pQuery, pQInfo->qId); + colIdCheck(pQueryAttr, pQInfo->qId); // todo refactor pQInfo->query.queryBlockDist = (numOfOutput == 1 && pExprs[0].base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX); @@ -6678,8 +6950,8 @@ _cleanup_qinfo: pExprInfo->pExpr = NULL; } - if (pExprInfo->pFilter) { - freeColumnFilterInfo(pExprInfo->pFilter, pExprInfo->base.filterNum); + if (pExprInfo->base.flist.filterInfo) { + freeColumnFilterInfo(pExprInfo->base.flist.filterInfo, pExprInfo->base.flist.numOfFilters); } } @@ -6704,38 +6976,39 @@ bool isValidQInfo(void *param) { return (sig == (uint64_t)pQInfo); } -int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *pQInfo, SQueryParam* param, bool isSTable) { +int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start, + int32_t prevResultLen, void* merger) { int32_t code = TSDB_CODE_SUCCESS; SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; pRuntimeEnv->qinfo = pQInfo; - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; STSBuf *pTsBuf = NULL; - if (pQueryMsg->tsLen > 0) { // open new file to save the result - char *tsBlock = (char *) pQueryMsg + pQueryMsg->tsOffset; - pTsBuf = tsBufCreateFromCompBlocks(tsBlock, pQueryMsg->tsNumOfBlocks, pQueryMsg->tsLen, pQueryMsg->tsOrder, vgId); + if (pTsBufInfo->tsLen > 0) { // open new file to save the result + char *tsBlock = start + pTsBufInfo->tsOffset; + pTsBuf = tsBufCreateFromCompBlocks(tsBlock, pTsBufInfo->tsNumOfBlocks, pTsBufInfo->tsLen, pTsBufInfo->tsOrder, + pQueryAttr->vgId); tsBufResetPos(pTsBuf); bool ret = tsBufNextPos(pTsBuf); - UNUSED(ret); } SArray* prevResult = NULL; - if (pQueryMsg->prevResultLen > 0) { - prevResult = interResFromBinary(param->prevResult, pQueryMsg->prevResultLen); - - pRuntimeEnv->prevResult = prevResult; + if (prevResultLen > 0) { + prevResult = interResFromBinary(param->prevResult, prevResultLen); } - pQuery->precision = tsdbGetCfg(tsdb)->precision; + if (tsdb != NULL) { + pQueryAttr->precision = tsdbGetCfg(tsdb)->precision; + } - if ((QUERY_IS_ASC_QUERY(pQuery) && (pQuery->window.skey > pQuery->window.ekey)) || - (!QUERY_IS_ASC_QUERY(pQuery) && (pQuery->window.ekey > pQuery->window.skey))) { - qDebug("QInfo:0x%"PRIx64" no result in time range %" PRId64 "-%" PRId64 ", order %d", pQInfo->qId, pQuery->window.skey, - pQuery->window.ekey, pQuery->order.order); + if ((QUERY_IS_ASC_QUERY(pQueryAttr) && (pQueryAttr->window.skey > pQueryAttr->window.ekey)) || + (!QUERY_IS_ASC_QUERY(pQueryAttr) && (pQueryAttr->window.ekey > pQueryAttr->window.skey))) { + qDebug("QInfo:0x%"PRIx64" no result in time range %" PRId64 "-%" PRId64 ", order %d", pQInfo->qId, pQueryAttr->window.skey, + pQueryAttr->window.ekey, pQueryAttr->order.order); setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); pRuntimeEnv->tableqinfoGroupInfo.numOfTables = 0; // todo free memory @@ -6749,7 +7022,7 @@ int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *p } // filter the qualified - if ((code = doInitQInfo(pQInfo, pTsBuf, tsdb, vgId, isSTable)) != TSDB_CODE_SUCCESS) { + if ((code = doInitQInfo(pQInfo, pTsBuf, prevResult, tsdb, sourceOptr, param->tableScanOperator, param->pOperator, merger)) != TSDB_CODE_SUCCESS) { goto _error; } @@ -6761,6 +7034,7 @@ _error: return code; } +//TODO refactor void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) { if (pFilter == NULL || numOfFilters == 0) { return; @@ -6810,8 +7084,12 @@ static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) { tExprTreeDestroy(pExprInfo[i].pExpr, NULL); } - if (pExprInfo[i].pFilter) { - freeColumnFilterInfo(pExprInfo[i].pFilter, pExprInfo[i].base.filterNum); + if (pExprInfo[i].base.flist.filterInfo) { + freeColumnFilterInfo(pExprInfo[i].base.flist.filterInfo, pExprInfo[i].base.flist.numOfFilters); + } + + for(int32_t j = 0; j < pExprInfo[i].base.numOfParams; ++j) { + tVariantDestroy(&pExprInfo[i].base.param[j]); } } @@ -6830,48 +7108,16 @@ void freeQInfo(SQInfo *pQInfo) { releaseQueryBuf(pRuntimeEnv->tableqinfoGroupInfo.numOfTables); doDestroyTableQueryInfo(&pRuntimeEnv->tableqinfoGroupInfo); - teardownQueryRuntimeEnv(&pQInfo->runtimeEnv); - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; - if (pQuery != NULL) { - if (pQuery->fillVal != NULL) { - tfree(pQuery->fillVal); - } - - for (int32_t i = 0; i < pQuery->numOfFilterCols; ++i) { - SSingleColumnFilterInfo *pColFilter = &pQuery->pFilterInfo[i]; - if (pColFilter->numOfFilters > 0) { - tfree(pColFilter->pFilters); - } - } - - pQuery->pExpr1 = destroyQueryFuncExpr(pQuery->pExpr1, pQuery->numOfOutput); - pQuery->pExpr2 = destroyQueryFuncExpr(pQuery->pExpr2, pQuery->numOfExpr2); - - tfree(pQuery->tagColList); - tfree(pQuery->pFilterInfo); - - if (pQuery->colList != NULL) { - for (int32_t i = 0; i < pQuery->numOfCols; i++) { - SColumnInfo *column = pQuery->colList + i; - freeColumnFilterInfo(column->filters, column->numOfFilters); - } - tfree(pQuery->colList); - } - - if (pQuery->pGroupbyExpr != NULL) { - taosArrayDestroy(pQuery->pGroupbyExpr->columnInfo); - tfree(pQuery->pGroupbyExpr); - } - } + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; + freeQueryAttr(pQueryAttr); + tsdbDestroyTableGroup(&pQueryAttr->tableGroupInfo); tfree(pQInfo->pBuf); tfree(pQInfo->sql); - tsdbDestroyTableGroup(&pQuery->tableGroupInfo); - taosArrayDestroy(pRuntimeEnv->groupResInfo.pRows); pQInfo->signature = 0; @@ -6883,10 +7129,10 @@ void freeQInfo(SQInfo *pQInfo) { int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { // the remained number of retrieved rows, not the interpolated result SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; // load data from file to msg buffer - if (isTsCompQuery(pQuery)) { + if (pQueryAttr->tsCompQuery) { SColumnInfoData* pColInfoData = taosArrayGet(pRuntimeEnv->outputBuf->pDataBlock, 0); FILE *f = *(FILE **)pColInfoData->pData; // TODO refactor @@ -6930,8 +7176,8 @@ int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { qDebug("QInfo:0x%"PRIx64" current numOfRes rows:%d, total:%" PRId64, pQInfo->qId, pRuntimeEnv->outputBuf->info.rows, pRuntimeEnv->resultInfo.total); - if (pQuery->limit.limit > 0 && pQuery->limit.limit == pRuntimeEnv->resultInfo.total) { - qDebug("QInfo:0x%"PRIx64" results limitation reached, limitation:%"PRId64, pQInfo->qId, pQuery->limit.limit); + if (pQueryAttr->limit.limit > 0 && pQueryAttr->limit.limit == pRuntimeEnv->resultInfo.total) { + qDebug("QInfo:0x%"PRIx64" results limitation reached, limitation:%"PRId64, pQInfo->qId, pQueryAttr->limit.limit); setQueryStatus(pRuntimeEnv, QUERY_OVER); } @@ -7019,3 +7265,34 @@ void releaseQueryBuf(size_t numOfTables) { // restore value is not enough buffer available atomic_add_fetch_64(&tsQueryBufferSizeBytes, t); } + +void freeQueryAttr(SQueryAttr* pQueryAttr) { + if (pQueryAttr != NULL) { + if (pQueryAttr->fillVal != NULL) { + tfree(pQueryAttr->fillVal); + } + + pQueryAttr->pFilterInfo = doDestroyFilterInfo(pQueryAttr->pFilterInfo, pQueryAttr->numOfFilterCols); + + pQueryAttr->pExpr1 = destroyQueryFuncExpr(pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + pQueryAttr->pExpr2 = destroyQueryFuncExpr(pQueryAttr->pExpr2, pQueryAttr->numOfExpr2); + pQueryAttr->pExpr3 = destroyQueryFuncExpr(pQueryAttr->pExpr3, pQueryAttr->numOfExpr3); + + 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); + } + + if (pQueryAttr->pGroupbyExpr != NULL) { + taosArrayDestroy(pQueryAttr->pGroupbyExpr->columnInfo); + tfree(pQueryAttr->pGroupbyExpr); + } + } +} + diff --git a/src/query/src/qExtbuffer.c b/src/query/src/qExtbuffer.c index 90734e2e0e..1fe2819ea2 100644 --- a/src/query/src/qExtbuffer.c +++ b/src/query/src/qExtbuffer.c @@ -20,6 +20,7 @@ #include "taosdef.h" #include "taosmsg.h" #include "tulog.h" +#include "qExecutor.h" #define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \ (data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes) @@ -352,7 +353,19 @@ static FORCE_INLINE int32_t primaryKeyComparator(int64_t f1, int64_t f2, int32_t } } -static FORCE_INLINE int32_t columnValueAscendingComparator(char *f1, char *f2, int32_t type, int32_t bytes) { +static int32_t tsCompareFunc(TSKEY k1, TSKEY k2, int32_t order) { + if (k1 == k2) { + return 0; + } + + if (order == TSDB_ORDER_DESC) { + return (k1 < k2)? 1:-1; + } else { + return (k1 < k2)? -1:1; + } +} + +int32_t columnValueAscendingComparator(char *f1, char *f2, int32_t type, int32_t bytes) { switch (type) { case TSDB_DATA_TYPE_INT: DEFAULT_COMP(GET_INT32_VAL(f1), GET_INT32_VAL(f2)); case TSDB_DATA_TYPE_DOUBLE: DEFAULT_DOUBLE_COMP(GET_DOUBLE_VAL(f1), GET_DOUBLE_VAL(f2)); @@ -425,6 +438,35 @@ int32_t compare_a(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1, return 0; } +int32_t compare_aRv(SSDataBlock* pBlock, SArray* colIndex, int32_t numOfCols, int32_t rowIndex, char** buffer, int32_t order) { + for (int32_t i = 0; i < numOfCols; ++i) { + SColIndex* pColIndex = taosArrayGet(colIndex, i); + int32_t index = pColIndex->colIndex; + + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, index); + assert(pColIndex->colId == pColInfo->info.colId); + + char* data = pColInfo->pData + rowIndex * pColInfo->info.bytes; + if (pColInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP) { + int32_t ret = tsCompareFunc(GET_INT64_VAL(data), GET_INT64_VAL(buffer[i]), order); + if (ret == 0) { + continue; // The timestamps are identical + } else { + return ret; + } + } else { + int32_t ret = columnValueAscendingComparator(data, buffer[i], pColInfo->info.type, pColInfo->info.bytes); + if (ret == 0) { + continue; + } else { + return ret; + } + } + } + + return 0; +} + int32_t compare_d(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1, char *data1, int32_t numOfRows2, int32_t s2, char *data2) { assert(numOfRows1 == numOfRows2); diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index 2de1029396..fa572029fc 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -31,7 +31,7 @@ static void setTagsValue(SFillInfo* pFillInfo, void** data, int32_t genRows) { for(int32_t j = 0; j < pFillInfo->numOfCols; ++j) { SFillColInfo* pCol = &pFillInfo->pFillCol[j]; - if (TSDB_COL_IS_NORMAL_COL(pCol->flag)) { + if (TSDB_COL_IS_NORMAL_COL(pCol->flag) || TSDB_COL_IS_UD_COL(pCol->flag)) { continue; } @@ -126,10 +126,10 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData } else { setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, index); } - } else { /* fill the default value */ + } else { // fill the default value */ for (int32_t i = 1; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; - if (TSDB_COL_IS_TAG(pCol->flag)) { + if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { continue; } @@ -210,7 +210,7 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, void** data, int32_t outputR // assign rows to dst buffer for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; - if (TSDB_COL_IS_TAG(pCol->flag)) { + if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { continue; } @@ -275,13 +275,16 @@ static int64_t appendFilledResult(SFillInfo* pFillInfo, void** output, int64_t r // there are no duplicated tags in the SFillTagColInfo list static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t capacity) { int32_t rowsize = 0; + int32_t numOfTags = 0; int32_t k = 0; for (int32_t i = 0; i < numOfCols; ++i) { SFillColInfo* pColInfo = &pFillInfo->pFillCol[i]; pFillInfo->pData[i] = NULL; - if (TSDB_COL_IS_TAG(pColInfo->flag)) { + if (TSDB_COL_IS_TAG(pColInfo->flag) || pColInfo->col.type == TSDB_DATA_TYPE_BINARY) { + numOfTags += 1; + bool exists = false; int32_t index = -1; for (int32_t j = 0; j < k; ++j) { @@ -310,6 +313,8 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t rowsize += pColInfo->col.bytes; } + pFillInfo->numOfTags = numOfTags; + assert(k <= pFillInfo->numOfTags); return rowsize; } @@ -347,12 +352,13 @@ SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int3 pFillInfo->interval.slidingUnit = slidingUnit; pFillInfo->pData = malloc(POINTER_BYTES * numOfCols); - if (numOfTags > 0) { - pFillInfo->pTags = calloc(pFillInfo->numOfTags, sizeof(SFillTagColInfo)); - for (int32_t i = 0; i < numOfTags; ++i) { + +// if (numOfTags > 0) { + pFillInfo->pTags = calloc(numOfCols, sizeof(SFillTagColInfo)); + for (int32_t i = 0; i < numOfCols; ++i) { pFillInfo->pTags[i].col.colId = -2; // TODO } - } +// } pFillInfo->rowSize = setTagColumnInfo(pFillInfo, pFillInfo->numOfCols, pFillInfo->alloc); assert(pFillInfo->rowSize > 0); @@ -367,6 +373,7 @@ SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int3 void taosResetFillInfo(SFillInfo* pFillInfo, TSKEY startTimestamp) { pFillInfo->start = startTimestamp; pFillInfo->currentKey = startTimestamp; + pFillInfo->end = startTimestamp; pFillInfo->index = -1; pFillInfo->numOfRows = 0; pFillInfo->numOfCurrent = 0; @@ -425,6 +432,8 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey) void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) { for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { + SFillColInfo* pCol = &pFillInfo->pFillCol[i]; + SColumnInfoData* pColData = taosArrayGet(pInput->pDataBlock, i); // pFillInfo->pData[i] = pColData->pData; if (pInput->info.rows > pFillInfo->alloc) { @@ -436,6 +445,12 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) } memcpy(pFillInfo->pData[i], pColData->pData, pColData->info.bytes * pInput->info.rows); + + 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, pColData->pData, pCol->col.bytes); // TODO not memcpy?? + } } } @@ -456,7 +471,7 @@ void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* memcpy(pFillInfo->pData[i], data, (size_t)(pCol->col.bytes * pInput->num)); - if (TSDB_COL_IS_TAG(pCol->flag)) { // copy the tag value to tag value buffer + 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?? @@ -465,7 +480,17 @@ void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* } bool taosFillHasMoreResults(SFillInfo* pFillInfo) { - return taosNumOfRemainRows(pFillInfo) > 0; + int32_t remain = taosNumOfRemainRows(pFillInfo); + if (remain > 0) { + return true; + } + + if (pFillInfo->numOfTotal > 0 && (((pFillInfo->end > pFillInfo->start) && FILL_IS_ASC_FILL(pFillInfo)) || + (pFillInfo->end < pFillInfo->start && !FILL_IS_ASC_FILL(pFillInfo)))) { + return getNumOfResultsAfterFillGap(pFillInfo, pFillInfo->end, 4096) > 0; + } + + return false; } int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t maxNumOfRows) { diff --git a/src/query/src/qPlan.c b/src/query/src/qPlan.c new file mode 100644 index 0000000000..0554a887ec --- /dev/null +++ b/src/query/src/qPlan.c @@ -0,0 +1,195 @@ +#include "os.h" +#include "tsclient.h" +#include "qUtil.h" +#include "texpr.h" + +#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; +} + +char* queryPlanToString() { + return NULL; +} + +SQueryNode* queryPlanFromString() { + return NULL; +} + +SArray* createTableScanPlan(SQueryAttr* pQueryAttr) { + SArray* plan = taosArrayInit(4, sizeof(int32_t)); + + int32_t op = 0; + if (onlyQueryTags(pQueryAttr)) { +// op = OP_TagScan; + } else { + if (pQueryAttr->queryBlockDist) { + op = OP_TableBlockInfoScan; + } else if (pQueryAttr->tsCompQuery || pQueryAttr->pointInterpQuery) { + op = OP_TableSeqScan; + } else if (pQueryAttr->needReverseScan) { + op = OP_DataBlocksOptScan; + } else { + op = OP_TableScan; + } + + taosArrayPush(plan, &op); + } + + return plan; +} + +SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) { + SArray* plan = taosArrayInit(4, sizeof(int32_t)); + int32_t op = 0; + + if (onlyQueryTags(pQueryAttr)) { // do nothing for tags query + op = OP_TagScan; + taosArrayPush(plan, &op); + if (pQueryAttr->distinctTag) { + op = OP_Distinct; + taosArrayPush(plan, &op); + } + } else if (pQueryAttr->interval.interval > 0) { + if (pQueryAttr->stableQuery) { + op = OP_MultiTableTimeInterval; + taosArrayPush(plan, &op); + } else { + op = OP_TimeWindow; + taosArrayPush(plan, &op); + + if (pQueryAttr->pExpr2 != NULL) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->fillType != TSDB_FILL_NONE && (!pQueryAttr->pointInterpQuery)) { + op = OP_Fill; + taosArrayPush(plan, &op); + } + } + + } else if (pQueryAttr->groupbyColumn) { + op = OP_Groupby; + taosArrayPush(plan, &op); + + if (!pQueryAttr->stableQuery && pQueryAttr->havingNum > 0) { + op = OP_Filter; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->pExpr2 != NULL) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + } else if (pQueryAttr->sw.gap > 0) { + op = OP_SessionWindow; + taosArrayPush(plan, &op); + + if (pQueryAttr->pExpr2 != NULL) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + } else if (pQueryAttr->simpleAgg) { + if (pQueryAttr->stableQuery && !pQueryAttr->tsCompQuery) { + op = OP_MultiTableAggregate; + } else { + op = OP_Aggregate; + } + + taosArrayPush(plan, &op); + + if (!pQueryAttr->stableQuery && pQueryAttr->havingNum > 0) { + op = OP_Filter; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->pExpr2 != NULL && !pQueryAttr->stableQuery) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + } else { // diff/add/multiply/subtract/division + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->limit.limit > 0 || pQueryAttr->limit.offset > 0) { + op = OP_Limit; + taosArrayPush(plan, &op); + } + + return plan; +} + +SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr) { + SArray* plan = taosArrayInit(4, sizeof(int32_t)); + + if (!pQueryAttr->stableQuery) { + return plan; + } + + int32_t op = OP_MultiwayMergeSort; + taosArrayPush(plan, &op); + + if (pQueryAttr->distinctTag) { + op = OP_Distinct; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->simpleAgg || (pQueryAttr->interval.interval > 0 || pQueryAttr->sw.gap > 0)) { + op = OP_GlobalAggregate; + taosArrayPush(plan, &op); + + if (pQueryAttr->havingNum > 0) { + op = OP_Filter; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->pExpr2 != NULL) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + } + + // fill operator + if (pQueryAttr->fillType != TSDB_FILL_NONE && (!pQueryAttr->pointInterpQuery)) { + op = OP_Fill; + taosArrayPush(plan, &op); + } + + // limit/offset operator + if (pQueryAttr->limit.limit > 0 || pQueryAttr->limit.offset > 0 || + pQueryAttr->slimit.limit > 0 || pQueryAttr->slimit.offset > 0) { + op = OP_SLimit; + taosArrayPush(plan, &op); + } + + return plan; +} diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index 6b38536b15..fb8f164ed3 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -330,7 +330,7 @@ int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) { if ((left == NULL && right) || (left && right == NULL)) { return 1; } - + if (left->type != right->type) { return 1; } @@ -343,11 +343,11 @@ int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) { return 1; } - if ((left->pLeft && right->pLeft == NULL) + if ((left->pLeft && right->pLeft == NULL) || (left->pLeft == NULL && right->pLeft) - || (left->pRight && right->pRight == NULL) + || (left->pRight && right->pRight == NULL) || (left->pRight == NULL && right->pRight) - || (left->pParam && right->pParam == NULL) + || (left->pParam && right->pParam == NULL) || (left->pParam == NULL && right->pParam)) { return 1; } @@ -360,19 +360,18 @@ int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) { return 1; } - if (right->pParam && left->pParam) { size_t size = taosArrayGetSize(right->pParam); if (left->pParam && taosArrayGetSize(left->pParam) != size) { return 1; } - for (int32_t i = 0; i < size; i++) { + for (int32_t i = 0; i < size; i++) { tSqlExprItem* pLeftElem = taosArrayGet(left->pParam, i); tSqlExpr* pSubLeft = pLeftElem->pNode; - tSqlExprItem* pRightElem = taosArrayGet(left->pParam, i); + tSqlExprItem* pRightElem = taosArrayGet(right->pParam, i); tSqlExpr* pSubRight = pRightElem->pNode; - + if (tSqlExprCompare(pSubLeft, pSubRight)) { return 1; } @@ -534,13 +533,13 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int return pList; } -SFromInfo *setTableNameList(SFromInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias) { - if (pFromInfo == NULL) { - pFromInfo = calloc(1, sizeof(SFromInfo)); - pFromInfo->tableList = taosArrayInit(4, sizeof(STableNamePair)); +SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, SStrToken* pAlias) { + if (pRelationInfo == NULL) { + pRelationInfo = calloc(1, sizeof(SRelationInfo)); + pRelationInfo->list = taosArrayInit(4, sizeof(STableNamePair)); } - pFromInfo->type = SQL_NODE_FROM_NAMELIST; + pRelationInfo->type = SQL_NODE_FROM_TABLELIST; STableNamePair p = {.name = *pName}; if (pAlias != NULL) { p.aliasName = *pAlias; @@ -548,34 +547,39 @@ SFromInfo *setTableNameList(SFromInfo* pFromInfo, SStrToken *pName, SStrToken* p TPARSER_SET_NONE_TOKEN(p.aliasName); } - taosArrayPush(pFromInfo->tableList, &p); - - return pFromInfo; + taosArrayPush(pRelationInfo->list, &p); + return pRelationInfo; } -SFromInfo *setSubquery(SFromInfo* pFromInfo, SQuerySqlNode* pSqlNode) { - if (pFromInfo == NULL) { - pFromInfo = calloc(1, sizeof(SFromInfo)); +SRelationInfo* setSubquery(SRelationInfo* pRelationInfo, SArray* pList) { + if (pRelationInfo == NULL) { + pRelationInfo = calloc(1, sizeof(SRelationInfo)); + pRelationInfo->list = taosArrayInit(4, POINTER_BYTES); } - pFromInfo->type = SQL_NODE_FROM_SUBQUERY; - pFromInfo->pNode->pClause[pFromInfo->pNode->numOfClause - 1] = pSqlNode; + pRelationInfo->type = SQL_NODE_FROM_SUBQUERY; + taosArrayPush(pRelationInfo->list, &pList); - return pFromInfo; + return pRelationInfo; } -void* destroyFromInfo(SFromInfo* pFromInfo) { - if (pFromInfo == NULL) { +void* destroyRelationInfo(SRelationInfo* pRelationInfo) { + if (pRelationInfo == NULL) { return NULL; } - if (pFromInfo->type == SQL_NODE_FROM_NAMELIST) { - taosArrayDestroy(pFromInfo->tableList); + if (pRelationInfo->type == SQL_NODE_FROM_TABLELIST) { + taosArrayDestroy(pRelationInfo->list); } else { - destroyAllSelectClause(pFromInfo->pNode); + size_t size = taosArrayGetSize(pRelationInfo->list); + for(int32_t i = 0; i < size; ++i) { + SArray* pa = taosArrayGetP(pRelationInfo->list, 0); + destroyAllSqlNode(pa); + } + taosArrayDestroy(pRelationInfo->list); } - tfree(pFromInfo); + tfree(pRelationInfo); return NULL; } @@ -719,19 +723,19 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) { /* * extract the select info out of sql string */ -SQuerySqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelectList, SFromInfo *pFrom, tSqlExpr *pWhere, +SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere, SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *pSession, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *psLimit, tSqlExpr *pHaving) { - assert(pSelectList != NULL); + assert(pSelNodeList != NULL); - SQuerySqlNode *pSqlNode = calloc(1, sizeof(SQuerySqlNode)); + SSqlNode *pSqlNode = calloc(1, sizeof(SSqlNode)); // all later sql string are belonged to the stream sql pSqlNode->sqlstr = *pSelectToken; pSqlNode->sqlstr.n = (uint32_t)strlen(pSqlNode->sqlstr.z); - pSqlNode->pSelectList = pSelectList; + pSqlNode->pSelNodeList = pSelNodeList; pSqlNode->from = pFrom; pSqlNode->pGroupby = pGroupby; pSqlNode->pSortOrder = pSortOrder; @@ -789,49 +793,47 @@ void freeCreateTableInfo(void* p) { tfree(pInfo->tagdata.data); } -void destroyQuerySqlNode(SQuerySqlNode *pQuerySql) { - if (pQuerySql == NULL) { +void destroySqlNode(SSqlNode *pSqlNode) { + if (pSqlNode == NULL) { return; } - tSqlExprListDestroy(pQuerySql->pSelectList); + tSqlExprListDestroy(pSqlNode->pSelNodeList); + pSqlNode->pSelNodeList = NULL; + + tSqlExprDestroy(pSqlNode->pWhere); + pSqlNode->pWhere = NULL; - pQuerySql->pSelectList = NULL; + taosArrayDestroyEx(pSqlNode->pSortOrder, freeVariant); + pSqlNode->pSortOrder = NULL; - tSqlExprDestroy(pQuerySql->pWhere); - pQuerySql->pWhere = NULL; + taosArrayDestroyEx(pSqlNode->pGroupby, freeVariant); + pSqlNode->pGroupby = NULL; - tSqlExprDestroy(pQuerySql->pHaving); - pQuerySql->pHaving = NULL; - - taosArrayDestroyEx(pQuerySql->pSortOrder, freeVariant); - pQuerySql->pSortOrder = NULL; + pSqlNode->from = destroyRelationInfo(pSqlNode->from); - taosArrayDestroyEx(pQuerySql->pGroupby, freeVariant); - pQuerySql->pGroupby = NULL; + taosArrayDestroyEx(pSqlNode->fillType, freeVariant); + pSqlNode->fillType = NULL; - pQuerySql->from = destroyFromInfo(pQuerySql->from); - - taosArrayDestroyEx(pQuerySql->fillType, freeVariant); - pQuerySql->fillType = NULL; - - free(pQuerySql); + tSqlExprDestroy(pSqlNode->pHaving); + free(pSqlNode); } -void destroyAllSelectClause(SSubclauseInfo *pClause) { - if (pClause == NULL || pClause->numOfClause == 0) { +void destroyAllSqlNode(SArray *pList) { + if (pList == NULL) { return; } - for(int32_t i = 0; i < pClause->numOfClause; ++i) { - SQuerySqlNode *pQuerySql = pClause->pClause[i]; - destroyQuerySqlNode(pQuerySql); + size_t size = taosArrayGetSize(pList); + for(int32_t i = 0; i < size; ++i) { + SSqlNode *pNode = taosArrayGetP(pList, i); + destroySqlNode(pNode); } - - tfree(pClause->pClause); + + taosArrayDestroy(pList); } -SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SQuerySqlNode *pSelect, int32_t type) { +SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SSqlNode *pSelect, int32_t type) { SCreateTableSql *pCreate = calloc(1, sizeof(SCreateTableSql)); switch (type) { @@ -899,7 +901,7 @@ SAlterTableInfo *tSetAlterTableInfo(SStrToken *pTableName, SArray *pCols, SArray } void* destroyCreateTableSql(SCreateTableSql* pCreate) { - destroyQuerySqlNode(pCreate->pSelect); + destroySqlNode(pCreate->pSelect); taosArrayDestroy(pCreate->colInfo.pColumns); taosArrayDestroy(pCreate->colInfo.pTagColumns); @@ -914,7 +916,7 @@ void SqlInfoDestroy(SSqlInfo *pInfo) { if (pInfo == NULL) return; if (pInfo->type == TSDB_SQL_SELECT) { - destroyAllSelectClause(&pInfo->subclauseInfo); + destroyAllSqlNode(pInfo->list); } else if (pInfo->type == TSDB_SQL_CREATE_TABLE) { pInfo->pCreateTableInfo = destroyCreateTableSql(pInfo->pCreateTableInfo); } else if (pInfo->type == TSDB_SQL_ALTER_TABLE) { @@ -935,31 +937,20 @@ void SqlInfoDestroy(SSqlInfo *pInfo) { } } -SSubclauseInfo* setSubclause(SSubclauseInfo* pSubclause, void *pSqlExprInfo) { - if (pSubclause == NULL) { - pSubclause = calloc(1, sizeof(SSubclauseInfo)); +SArray* setSubclause(SArray* pList, void *pSqlNode) { + if (pList == NULL) { + pList = taosArrayInit(1, POINTER_BYTES); } - int32_t newSize = pSubclause->numOfClause + 1; - char* tmp = realloc(pSubclause->pClause, newSize * POINTER_BYTES); - if (tmp == NULL) { - return pSubclause; - } - - pSubclause->pClause = (SQuerySqlNode**) tmp; - - pSubclause->pClause[newSize - 1] = pSqlExprInfo; - pSubclause->numOfClause++; - - return pSubclause; + taosArrayPush(pList, &pSqlNode); + return pList; } SSqlInfo* setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SStrToken *pTableName, int32_t type) { pInfo->type = type; if (type == TSDB_SQL_SELECT) { - pInfo->subclauseInfo = *(SSubclauseInfo*) pSqlExprInfo; - free(pSqlExprInfo); + pInfo->list = (SArray*) pSqlExprInfo; } else { pInfo->pCreateTableInfo = pSqlExprInfo; } @@ -971,16 +962,9 @@ SSqlInfo* setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SStrToken *pTableName, return pInfo; } -SSubclauseInfo* appendSelectClause(SSubclauseInfo *pQueryInfo, void *pSubclause) { - char* tmp = realloc(pQueryInfo->pClause, (pQueryInfo->numOfClause + 1) * POINTER_BYTES); - if (tmp == NULL) { // out of memory - return pQueryInfo; - } - - pQueryInfo->pClause = (SQuerySqlNode**) tmp; - pQueryInfo->pClause[pQueryInfo->numOfClause++] = pSubclause; - - return pQueryInfo; +SArray* appendSelectClause(SArray *pList, void *pSubclause) { + taosArrayPush(pList, &pSubclause); + return pList; } void setCreatedTableName(SSqlInfo *pInfo, SStrToken *pTableNameToken, SStrToken *pIfNotExists) { diff --git a/src/query/src/qTsbuf.c b/src/query/src/qTsbuf.c index 1f43c5b33c..5d599ff08a 100644 --- a/src/query/src/qTsbuf.c +++ b/src/query/src/qTsbuf.c @@ -484,7 +484,7 @@ void tsBufFlush(STSBuf* pTSBuf) { .magic = TS_COMP_FILE_MAGIC, .numOfGroup = pTSBuf->numOfGroups, .tsOrder = pTSBuf->tsOrder}; STSBufUpdateHeader(pTSBuf, &header); - fsync(fileno(pTSBuf->f)); + taosFsync(fileno(pTSBuf->f)); } static int32_t tsBufFindGroupById(STSGroupBlockInfoEx* pGroupInfoEx, int32_t numOfGroups, int32_t id) { @@ -868,7 +868,7 @@ STSBuf* tsBufCreateFromCompBlocks(const char* pData, int32_t numOfBlocks, int32_ .magic = TS_COMP_FILE_MAGIC, .numOfGroup = pTSBuf->numOfGroups, .tsOrder = pTSBuf->tsOrder}; STSBufUpdateHeader(pTSBuf, &header); - fsync(fileno(pTSBuf->f)); + taosFsync(fileno(pTSBuf->f)); return pTSBuf; } diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index aa793add84..7ff2d16962 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -30,11 +30,11 @@ typedef struct SCompSupporter { int32_t order; } SCompSupporter; -int32_t getOutputInterResultBufSize(SQuery* pQuery) { +int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr) { int32_t size = 0; - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - size += pQuery->pExpr1[i].interBytes; + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + size += pQueryAttr->pExpr1[i].base.interBytes; } assert(size >= 0); @@ -136,11 +136,11 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16 tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResultRow->pageId); int16_t offset = 0; - for (int32_t i = 0; i < pRuntimeEnv->pQuery->numOfOutput; ++i) { + for (int32_t i = 0; i < pRuntimeEnv->pQueryAttr->numOfOutput; ++i) { SResultRowCellInfo *pResultInfo = &pResultRow->pCellInfo[i]; - int16_t size = pRuntimeEnv->pQuery->pExpr1[i].bytes; - char * s = getPosInResultPage(pRuntimeEnv, page, pResultRow->offset, offset, size); + int16_t size = pRuntimeEnv->pQueryAttr->pExpr1[i].base.resType; + char * s = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, pResultRow->offset, offset); memset(s, 0, size); offset += size; @@ -164,8 +164,8 @@ SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t } size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv) { - SQuery* pQuery = pRuntimeEnv->pQuery; - return (pQuery->numOfOutput * sizeof(SResultRowCellInfo)) + pQuery->interBufSize + sizeof(SResultRow); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + return (pQueryAttr->numOfOutput * sizeof(SResultRowCellInfo)) + pQueryAttr->interBufSize + sizeof(SResultRow); } SResultRowPool* initResultRowPool(size_t size) { @@ -382,10 +382,10 @@ int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo) { } static int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow *pResultRow, int32_t* rowCellInfoOffset) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - for (int32_t j = 0; j < pQuery->numOfOutput; ++j) { - int32_t functionId = pQuery->pExpr1[j].base.functionId; + for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) { + int32_t functionId = pQueryAttr->pExpr1[j].base.functionId; /* * ts, tag, tagprj function can not decide the output number of current query @@ -448,7 +448,7 @@ static int32_t tableResultComparFn(const void *pLeft, const void *pRight, void * static int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEnv, SGroupResInfo* pGroupResInfo, SArray *pTableList, int32_t* rowCellInfoOffset) { - bool ascQuery = QUERY_IS_ASC_QUERY(pRuntimeEnv->pQuery); + bool ascQuery = QUERY_IS_ASC_QUERY(pRuntimeEnv->pQueryAttr); int32_t code = TSDB_CODE_SUCCESS; @@ -484,7 +484,7 @@ static int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEnv, SGroupRes goto _end; } - SCompSupporter cs = {pTableQueryInfoList, posList, pRuntimeEnv->pQuery->order.order}; + SCompSupporter cs = {pTableQueryInfoList, posList, pRuntimeEnv->pQueryAttr->order.order}; int32_t ret = tLoserTreeCreate(&pTree, numOfTables, &cs, tableResultComparFn); if (ret != TSDB_CODE_SUCCESS) { @@ -537,7 +537,7 @@ static int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEnv, SGroupRes int64_t endt = taosGetTimestampMs(); - qDebug("QInfo:%"PRIu64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_QID(pRuntimeEnv), + qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_QID(pRuntimeEnv), pGroupResInfo->currentGroup, endt - startt); _end: diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index bfe6aee4f6..f00d5ceb41 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -14,7 +14,6 @@ */ #include "os.h" -#include "qFill.h" #include "taosmsg.h" #include "tcache.h" #include "tglobal.h" @@ -23,13 +22,11 @@ #include "hash.h" #include "texpr.h" #include "qExecutor.h" -#include "qResultbuf.h" #include "qUtil.h" #include "query.h" #include "queryLog.h" #include "tlosertree.h" #include "ttype.h" -#include "tcompare.h" typedef struct SQueryMgmt { pthread_mutex_t lock; @@ -58,10 +55,13 @@ void freeParam(SQueryParam *param) { tfree(param->tagCond); tfree(param->tbnameCond); tfree(param->pTableIdList); - tfree(param->pExprMsg); - tfree(param->pSecExprMsg); + taosArrayDestroy(param->pOperator); tfree(param->pExprs); tfree(param->pSecExprs); + + tfree(param->pExpr); + tfree(param->pSecExpr); + tfree(param->pGroupColIndex); tfree(param->pTagColumnInfo); tfree(param->pGroupbyExpr); @@ -91,12 +91,14 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi goto _over; } - if ((code = createQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->numOfOutput, ¶m.pExprs, param.pExprMsg, param.pTagColumnInfo)) != TSDB_CODE_SUCCESS) { + SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols}; + if ((code = createQueryFunc(&info, pQueryMsg->numOfOutput, ¶m.pExprs, param.pExpr, param.pTagColumnInfo, + pQueryMsg->queryType, pQueryMsg)) != TSDB_CODE_SUCCESS) { goto _over; } - if (param.pSecExprMsg != NULL) { - if ((code = createIndirectQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, ¶m.pSecExprs, param.pSecExprMsg, param.pExprs)) != TSDB_CODE_SUCCESS) { + if (param.pSecExpr != NULL) { + if ((code = createIndirectQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, ¶m.pSecExprs, param.pSecExpr, param.pExprs)) != TSDB_CODE_SUCCESS) { goto _over; } } @@ -158,7 +160,9 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi goto _over; } - (*pQInfo) = createQInfoImpl(pQueryMsg, param.pGroupbyExpr, param.pExprs, param.pSecExprs, &tableGroupInfo, param.pTagColumnInfo, isSTableQuery, param.sql, qId); + assert(pQueryMsg->stableQuery == isSTableQuery); + (*pQInfo) = createQInfoImpl(pQueryMsg, param.pGroupbyExpr, param.pExprs, param.pSecExprs, &tableGroupInfo, + param.pTagColumnInfo, vgId, param.sql, qId); param.sql = NULL; param.pExprs = NULL; @@ -171,7 +175,7 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi goto _over; } - code = initQInfo(pQueryMsg, tsdb, vgId, *pQInfo, ¶m, isSTableQuery); + code = initQInfo(&pQueryMsg->tsBuf, tsdb, NULL, *pQInfo, ¶m, (char*)pQueryMsg, pQueryMsg->prevResultLen, NULL); _over: if (param.pGroupbyExpr != NULL) { @@ -184,8 +188,8 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi freeParam(¶m); for (int32_t i = 0; i < pQueryMsg->numOfCols; i++) { - SColumnInfo* column = pQueryMsg->colList + i; - freeColumnFilterInfo(column->filters, column->numOfFilters); + SColumnInfo* column = pQueryMsg->tableCols + i; + freeColumnFilterInfo(column->flist.filterInfo, column->flist.numOfFilters); } //pQInfo already freed in initQInfo, but *pQInfo may not pointer to null; @@ -210,7 +214,6 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { return false; } - *qId = pQInfo->qId; pQInfo->startExecTs = taosGetTimestampSec(); @@ -236,7 +239,8 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { qDebug("QInfo:0x%"PRIx64" query task is launched", pQInfo->qId); - pRuntimeEnv->outputBuf = pRuntimeEnv->proot->exec(pRuntimeEnv->proot); + bool newgroup = false; + pRuntimeEnv->outputBuf = pRuntimeEnv->proot->exec(pRuntimeEnv->proot, &newgroup); if (isQueryKilled(pQInfo)) { qDebug("QInfo:0x%"PRIx64" query is killed", pQInfo->qId); @@ -274,14 +278,14 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex code = pQInfo->code; } else { SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; pthread_mutex_lock(&pQInfo->lock); assert(pQInfo->rspContext == NULL); if (pQInfo->dataReady == QUERY_RESULT_READY) { *buildRes = true; - qDebug("QInfo:0x%"PRIx64" retrieve result info, rowsize:%d, rows:%d, code:%s", pQInfo->qId, pQuery->resultRowSize, + qDebug("QInfo:0x%"PRIx64" retrieve result info, rowsize:%d, rows:%d, code:%s", pQInfo->qId, pQueryAttr->resultRowSize, GET_NUM_OF_RESULTS(pRuntimeEnv), tstrerror(pQInfo->code)); } else { *buildRes = false; @@ -304,11 +308,11 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co return TSDB_CODE_QRY_INVALID_QHANDLE; } - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; int32_t s = GET_NUM_OF_RESULTS(pRuntimeEnv); - size_t size = pQuery->resultRowSize * s; + size_t size = pQueryAttr->resultRowSize * s; size += sizeof(int32_t); size += sizeof(STableIdInfo) * taosHashGetSize(pRuntimeEnv->pTableRetrieveTsMap); @@ -330,7 +334,7 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co (*pRsp)->useconds = htobe64(pQInfo->summary.elapsedTime); } - (*pRsp)->precision = htons(pQuery->precision); + (*pRsp)->precision = htons(pQueryAttr->precision); if (GET_NUM_OF_RESULTS(&(pQInfo->runtimeEnv)) > 0 && pQInfo->code == TSDB_CODE_SUCCESS) { doDumpQueryResult(pQInfo, (*pRsp)->data); } else { diff --git a/src/query/src/sql.c b/src/query/src/sql.c index 96d33a8ed6..f3929da022 100644 --- a/src/query/src/sql.c +++ b/src/query/src/sql.c @@ -23,7 +23,6 @@ ** input grammar file: */ #include -#include /************ Begin %include sections from the grammar ************************/ #include @@ -77,10 +76,8 @@ ** zero the stack is dynamically sized using realloc() ** ParseARG_SDECL A static variable declaration for the %extra_argument ** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_PARAM Code to pass %extra_argument as a subroutine parameter ** ParseARG_STORE Code to store %extra_argument into yypParser ** ParseARG_FETCH Code to extract %extra_argument from yypParser -** ParseCTX_* As ParseARG_ except for %extra_context ** YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. ** YYNSTATE the combined number of states. @@ -100,46 +97,38 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 262 +#define YYNOCODE 264 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SStrToken typedef union { int yyinit; ParseTOKENTYPE yy0; - SLimitVal yy18; - SFromInfo* yy70; - SSessionWindowVal yy87; - SCreateDbInfo yy94; - int yy116; - SSubclauseInfo* yy141; - tSqlExpr* yy170; - SCreateTableSql* yy194; - tVariant yy218; - SIntervalVal yy220; - SCreatedTableInfo yy252; - SQuerySqlNode* yy254; - SCreateAcctInfo yy419; - SArray* yy429; - TAOS_FIELD yy451; - int64_t yy481; + 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; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #endif #define ParseARG_SDECL SSqlInfo* pInfo; #define ParseARG_PDECL ,SSqlInfo* pInfo -#define ParseARG_PARAM ,pInfo -#define ParseARG_FETCH SSqlInfo* pInfo=yypParser->pInfo; -#define ParseARG_STORE yypParser->pInfo=pInfo; -#define ParseCTX_SDECL -#define ParseCTX_PDECL -#define ParseCTX_PARAM -#define ParseCTX_FETCH -#define ParseCTX_STORE +#define ParseARG_FETCH SSqlInfo* pInfo = yypParser->pInfo +#define ParseARG_STORE yypParser->pInfo = pInfo #define YYFALLBACK 1 #define YYNSTATE 315 #define YYNRULE 269 -#define YYNRULE_WITH_ACTION 269 #define YYNTOKEN 187 #define YY_MAX_SHIFT 314 #define YY_MIN_SHIFTREDUCE 508 @@ -150,7 +139,6 @@ typedef union { #define YY_MIN_REDUCE 780 #define YY_MAX_REDUCE 1048 /************* End control #defines *******************************************/ -#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. @@ -215,224 +203,226 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (672) +#define YY_ACTTAB_COUNT (683) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 133, 555, 204, 312, 208, 140, 947, 17, 85, 556, - /* 10 */ 778, 314, 179, 47, 48, 140, 51, 52, 30, 181, + /* 0 */ 133, 555, 204, 312, 208, 140, 947, 226, 140, 556, + /* 10 */ 778, 314, 17, 47, 48, 140, 51, 52, 30, 181, /* 20 */ 214, 41, 181, 50, 262, 55, 53, 57, 54, 1029, - /* 30 */ 926, 211, 1030, 46, 45, 185, 181, 44, 43, 42, - /* 40 */ 47, 48, 914, 51, 52, 210, 1030, 214, 41, 555, - /* 50 */ 50, 262, 55, 53, 57, 54, 938, 556, 1026, 205, + /* 30 */ 926, 211, 1030, 46, 45, 179, 181, 44, 43, 42, + /* 40 */ 47, 48, 924, 51, 52, 210, 1030, 214, 41, 555, + /* 50 */ 50, 262, 55, 53, 57, 54, 938, 556, 185, 205, /* 60 */ 46, 45, 923, 247, 44, 43, 42, 48, 944, 51, - /* 70 */ 52, 242, 978, 214, 41, 555, 50, 262, 55, 53, - /* 80 */ 57, 54, 979, 556, 257, 278, 46, 45, 298, 225, + /* 70 */ 52, 242, 978, 214, 41, 79, 50, 262, 55, 53, + /* 80 */ 57, 54, 979, 634, 257, 30, 46, 45, 278, 225, /* 90 */ 44, 43, 42, 509, 510, 511, 512, 513, 514, 515, - /* 100 */ 516, 517, 518, 519, 520, 521, 313, 634, 1025, 231, - /* 110 */ 70, 555, 30, 47, 48, 1024, 51, 52, 825, 556, - /* 120 */ 214, 41, 166, 50, 262, 55, 53, 57, 54, 44, - /* 130 */ 43, 42, 720, 46, 45, 288, 287, 44, 43, 42, - /* 140 */ 47, 49, 834, 51, 52, 198, 166, 214, 41, 234, - /* 150 */ 50, 262, 55, 53, 57, 54, 922, 238, 237, 227, + /* 100 */ 516, 517, 518, 519, 520, 521, 313, 555, 85, 231, + /* 110 */ 70, 288, 287, 47, 48, 556, 51, 52, 298, 219, + /* 120 */ 214, 41, 555, 50, 262, 55, 53, 57, 54, 922, + /* 130 */ 556, 105, 720, 46, 45, 1026, 298, 44, 43, 42, + /* 140 */ 47, 49, 914, 51, 52, 926, 140, 214, 41, 234, + /* 150 */ 50, 262, 55, 53, 57, 54, 1025, 238, 237, 227, /* 160 */ 46, 45, 285, 284, 44, 43, 42, 23, 276, 307, /* 170 */ 306, 275, 274, 273, 305, 272, 304, 303, 302, 271, - /* 180 */ 301, 300, 886, 140, 874, 875, 876, 877, 878, 879, + /* 180 */ 301, 300, 886, 30, 874, 875, 876, 877, 878, 879, /* 190 */ 880, 881, 882, 883, 884, 885, 887, 888, 51, 52, - /* 200 */ 826, 219, 214, 41, 166, 50, 262, 55, 53, 57, - /* 210 */ 54, 223, 18, 82, 25, 46, 45, 1, 154, 44, - /* 220 */ 43, 42, 213, 735, 938, 722, 724, 926, 727, 190, - /* 230 */ 730, 226, 213, 735, 140, 191, 724, 912, 727, 206, - /* 240 */ 730, 118, 117, 189, 909, 910, 29, 913, 259, 74, - /* 250 */ 78, 726, 30, 729, 200, 201, 221, 36, 261, 199, - /* 260 */ 23, 723, 307, 306, 200, 201, 924, 305, 30, 304, - /* 270 */ 303, 302, 74, 301, 300, 894, 183, 308, 892, 893, - /* 280 */ 36, 224, 926, 895, 280, 897, 898, 896, 184, 899, - /* 290 */ 900, 920, 658, 217, 69, 655, 923, 656, 725, 657, - /* 300 */ 728, 79, 241, 926, 68, 55, 53, 57, 54, 218, - /* 310 */ 197, 212, 923, 46, 45, 30, 278, 44, 43, 42, - /* 320 */ 673, 103, 108, 228, 229, 56, 911, 97, 107, 113, - /* 330 */ 116, 106, 736, 220, 263, 56, 186, 110, 732, 30, - /* 340 */ 180, 30, 736, 5, 156, 30, 3, 167, 732, 33, - /* 350 */ 155, 92, 87, 91, 731, 6, 281, 701, 702, 923, - /* 360 */ 174, 170, 28, 733, 731, 268, 172, 169, 121, 120, - /* 370 */ 119, 46, 45, 105, 80, 44, 43, 42, 298, 662, - /* 380 */ 282, 663, 286, 923, 670, 923, 290, 71, 12, 923, - /* 390 */ 187, 24, 84, 188, 81, 311, 310, 126, 677, 243, - /* 400 */ 680, 659, 660, 31, 661, 686, 1040, 692, 245, 135, - /* 410 */ 734, 60, 693, 756, 737, 61, 20, 19, 19, 64, - /* 420 */ 644, 265, 646, 267, 31, 31, 60, 83, 645, 67, - /* 430 */ 739, 633, 60, 925, 96, 95, 194, 62, 195, 65, - /* 440 */ 193, 14, 13, 102, 101, 115, 114, 131, 129, 16, - /* 450 */ 15, 178, 192, 182, 989, 988, 215, 239, 985, 132, - /* 460 */ 984, 216, 289, 946, 39, 971, 954, 956, 134, 138, - /* 470 */ 970, 939, 246, 130, 921, 151, 919, 150, 152, 153, - /* 480 */ 248, 837, 270, 685, 890, 299, 104, 291, 148, 37, - /* 490 */ 145, 176, 936, 141, 34, 58, 207, 250, 255, 66, - /* 500 */ 63, 142, 279, 833, 1045, 260, 143, 258, 144, 256, - /* 510 */ 93, 1044, 1042, 254, 157, 146, 283, 1039, 99, 1038, - /* 520 */ 1036, 252, 158, 855, 35, 32, 38, 177, 249, 822, - /* 530 */ 109, 820, 111, 112, 818, 817, 230, 168, 815, 814, - /* 540 */ 813, 812, 811, 810, 171, 173, 807, 805, 803, 801, - /* 550 */ 799, 175, 40, 244, 72, 75, 251, 292, 972, 293, - /* 560 */ 294, 296, 295, 297, 309, 776, 202, 222, 269, 232, - /* 570 */ 233, 203, 775, 235, 88, 89, 236, 196, 774, 762, - /* 580 */ 761, 240, 245, 8, 73, 264, 209, 665, 687, 816, - /* 590 */ 165, 856, 161, 159, 160, 122, 162, 163, 123, 164, - /* 600 */ 809, 2, 76, 124, 125, 808, 800, 136, 137, 4, - /* 610 */ 690, 149, 147, 77, 253, 26, 694, 139, 902, 9, + /* 200 */ 825, 1024, 214, 41, 166, 50, 262, 55, 53, 57, + /* 210 */ 54, 259, 18, 78, 82, 46, 45, 61, 223, 44, + /* 220 */ 43, 42, 213, 735, 217, 25, 724, 923, 727, 190, + /* 230 */ 730, 221, 213, 735, 198, 191, 724, 912, 727, 62, + /* 240 */ 730, 118, 117, 189, 69, 909, 910, 29, 913, 44, + /* 250 */ 43, 42, 30, 74, 200, 201, 308, 926, 261, 30, + /* 260 */ 23, 36, 307, 306, 200, 201, 938, 305, 30, 304, + /* 270 */ 303, 302, 74, 301, 300, 894, 911, 199, 892, 893, + /* 280 */ 36, 206, 926, 895, 920, 897, 898, 896, 224, 899, + /* 290 */ 900, 280, 658, 218, 834, 655, 923, 656, 166, 657, + /* 300 */ 281, 673, 241, 923, 68, 55, 53, 57, 54, 282, + /* 310 */ 197, 263, 923, 46, 45, 30, 278, 44, 43, 42, + /* 320 */ 80, 103, 108, 228, 229, 56, 220, 97, 107, 113, + /* 330 */ 116, 106, 736, 71, 726, 56, 729, 110, 732, 30, + /* 340 */ 1, 154, 736, 5, 156, 725, 183, 728, 732, 33, + /* 350 */ 155, 92, 87, 91, 731, 680, 286, 184, 826, 923, + /* 360 */ 174, 170, 166, 245, 731, 212, 172, 169, 121, 120, + /* 370 */ 119, 46, 45, 3, 167, 44, 43, 42, 12, 677, + /* 380 */ 290, 722, 84, 923, 81, 670, 311, 310, 126, 701, + /* 390 */ 702, 243, 24, 686, 692, 31, 693, 135, 60, 756, + /* 400 */ 20, 659, 737, 19, 64, 186, 19, 739, 644, 6, + /* 410 */ 180, 265, 31, 187, 646, 31, 267, 723, 60, 645, + /* 420 */ 83, 188, 28, 60, 65, 268, 662, 67, 663, 633, + /* 430 */ 96, 95, 660, 194, 661, 115, 114, 14, 13, 102, + /* 440 */ 101, 195, 16, 15, 131, 129, 733, 193, 178, 192, + /* 450 */ 182, 1040, 925, 989, 988, 215, 985, 734, 239, 984, + /* 460 */ 216, 289, 132, 946, 39, 971, 954, 970, 956, 939, + /* 470 */ 246, 130, 248, 134, 138, 921, 150, 244, 151, 207, + /* 480 */ 250, 299, 685, 149, 919, 255, 142, 936, 143, 141, + /* 490 */ 144, 152, 256, 153, 260, 258, 66, 145, 837, 270, + /* 500 */ 63, 37, 58, 176, 34, 254, 279, 833, 1045, 252, + /* 510 */ 93, 1044, 1042, 249, 147, 157, 283, 1039, 99, 1038, + /* 520 */ 146, 1036, 158, 855, 35, 32, 38, 177, 822, 40, + /* 530 */ 109, 104, 820, 111, 112, 818, 817, 230, 168, 815, + /* 540 */ 814, 813, 812, 811, 810, 171, 173, 807, 805, 803, + /* 550 */ 291, 801, 799, 175, 292, 72, 75, 293, 251, 972, + /* 560 */ 294, 295, 296, 297, 309, 776, 202, 232, 222, 269, + /* 570 */ 233, 775, 236, 235, 774, 761, 203, 762, 88, 196, + /* 580 */ 89, 240, 245, 264, 8, 73, 76, 665, 687, 690, + /* 590 */ 816, 161, 136, 122, 856, 159, 164, 160, 162, 163, + /* 600 */ 165, 123, 809, 2, 890, 124, 808, 4, 125, 800, + /* 610 */ 137, 209, 77, 148, 253, 26, 694, 139, 9, 902, /* 620 */ 10, 27, 738, 7, 11, 740, 21, 22, 266, 86, /* 630 */ 597, 593, 84, 591, 590, 589, 586, 559, 277, 90, - /* 640 */ 94, 31, 636, 59, 635, 632, 581, 579, 571, 577, - /* 650 */ 573, 575, 569, 567, 98, 100, 600, 599, 598, 596, + /* 640 */ 31, 94, 98, 59, 100, 636, 635, 632, 581, 579, + /* 650 */ 571, 577, 573, 575, 569, 567, 600, 599, 598, 596, /* 660 */ 595, 594, 592, 588, 587, 60, 557, 525, 523, 780, - /* 670 */ 127, 128, + /* 670 */ 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, + /* 680 */ 779, 127, 128, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 190, 1, 189, 190, 209, 190, 190, 251, 196, 9, - /* 10 */ 187, 188, 251, 13, 14, 190, 16, 17, 190, 251, - /* 20 */ 20, 21, 251, 23, 24, 25, 26, 27, 28, 261, - /* 30 */ 235, 260, 261, 33, 34, 251, 251, 37, 38, 39, - /* 40 */ 13, 14, 230, 16, 17, 260, 261, 20, 21, 1, - /* 50 */ 23, 24, 25, 26, 27, 28, 233, 9, 251, 231, - /* 60 */ 33, 34, 234, 253, 37, 38, 39, 14, 252, 16, - /* 70 */ 17, 248, 257, 20, 21, 1, 23, 24, 25, 26, - /* 80 */ 27, 28, 257, 9, 259, 79, 33, 34, 81, 67, + /* 0 */ 191, 1, 190, 191, 210, 191, 191, 191, 191, 9, + /* 10 */ 188, 189, 252, 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, 226, 16, 17, 261, 262, 20, 21, 1, + /* 50 */ 23, 24, 25, 26, 27, 28, 234, 9, 252, 232, + /* 60 */ 33, 34, 235, 254, 37, 38, 39, 14, 253, 16, + /* 70 */ 17, 249, 258, 20, 21, 258, 23, 24, 25, 26, + /* 80 */ 27, 28, 258, 5, 260, 191, 33, 34, 79, 67, /* 90 */ 37, 38, 39, 45, 46, 47, 48, 49, 50, 51, - /* 100 */ 52, 53, 54, 55, 56, 57, 58, 5, 251, 61, - /* 110 */ 110, 1, 190, 13, 14, 251, 16, 17, 195, 9, - /* 120 */ 20, 21, 199, 23, 24, 25, 26, 27, 28, 37, - /* 130 */ 38, 39, 105, 33, 34, 33, 34, 37, 38, 39, - /* 140 */ 13, 14, 195, 16, 17, 251, 199, 20, 21, 135, - /* 150 */ 23, 24, 25, 26, 27, 28, 234, 143, 144, 137, + /* 100 */ 52, 53, 54, 55, 56, 57, 58, 1, 197, 61, + /* 110 */ 110, 33, 34, 13, 14, 9, 16, 17, 81, 210, + /* 120 */ 20, 21, 1, 23, 24, 25, 26, 27, 28, 235, + /* 130 */ 9, 76, 105, 33, 34, 252, 81, 37, 38, 39, + /* 140 */ 13, 14, 231, 16, 17, 236, 191, 20, 21, 135, + /* 150 */ 23, 24, 25, 26, 27, 28, 252, 143, 144, 137, /* 160 */ 33, 34, 140, 141, 37, 38, 39, 88, 89, 90, /* 170 */ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - /* 180 */ 101, 102, 208, 190, 210, 211, 212, 213, 214, 215, - /* 190 */ 216, 217, 218, 219, 220, 221, 222, 223, 16, 17, - /* 200 */ 195, 209, 20, 21, 199, 23, 24, 25, 26, 27, - /* 210 */ 28, 67, 44, 196, 104, 33, 34, 197, 198, 37, - /* 220 */ 38, 39, 1, 2, 233, 1, 5, 235, 7, 61, - /* 230 */ 9, 190, 1, 2, 190, 67, 5, 0, 7, 248, - /* 240 */ 9, 73, 74, 75, 227, 228, 229, 230, 255, 104, - /* 250 */ 257, 5, 190, 7, 33, 34, 209, 112, 37, 251, - /* 260 */ 88, 37, 90, 91, 33, 34, 225, 95, 190, 97, - /* 270 */ 98, 99, 104, 101, 102, 208, 251, 209, 211, 212, - /* 280 */ 112, 137, 235, 216, 140, 218, 219, 220, 251, 222, - /* 290 */ 223, 190, 2, 231, 196, 5, 234, 7, 5, 9, - /* 300 */ 7, 257, 134, 235, 136, 25, 26, 27, 28, 231, - /* 310 */ 142, 60, 234, 33, 34, 190, 79, 37, 38, 39, - /* 320 */ 37, 62, 63, 33, 34, 104, 228, 68, 69, 70, - /* 330 */ 71, 72, 111, 232, 15, 104, 251, 78, 117, 190, - /* 340 */ 251, 190, 111, 62, 63, 190, 193, 194, 117, 68, - /* 350 */ 69, 70, 71, 72, 133, 104, 231, 124, 125, 234, - /* 360 */ 62, 63, 104, 117, 133, 107, 68, 69, 70, 71, - /* 370 */ 72, 33, 34, 76, 236, 37, 38, 39, 81, 5, - /* 380 */ 231, 7, 231, 234, 109, 234, 231, 249, 104, 234, - /* 390 */ 251, 116, 108, 251, 110, 64, 65, 66, 115, 105, - /* 400 */ 105, 111, 5, 109, 7, 105, 235, 105, 113, 109, - /* 410 */ 117, 109, 105, 105, 105, 109, 109, 109, 109, 109, - /* 420 */ 105, 105, 105, 105, 109, 109, 109, 109, 105, 104, - /* 430 */ 111, 106, 109, 235, 138, 139, 251, 131, 251, 129, - /* 440 */ 251, 138, 139, 138, 139, 76, 77, 62, 63, 138, - /* 450 */ 139, 251, 251, 251, 226, 226, 226, 190, 226, 190, - /* 460 */ 226, 226, 226, 190, 250, 258, 190, 190, 190, 190, - /* 470 */ 258, 233, 233, 60, 233, 190, 190, 237, 190, 190, - /* 480 */ 254, 190, 190, 117, 224, 103, 87, 86, 239, 190, - /* 490 */ 242, 190, 247, 246, 190, 127, 254, 254, 254, 128, - /* 500 */ 130, 245, 190, 190, 190, 122, 244, 126, 243, 121, - /* 510 */ 190, 190, 190, 120, 190, 241, 190, 190, 190, 190, - /* 520 */ 190, 119, 190, 190, 190, 190, 190, 190, 118, 190, - /* 530 */ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - /* 540 */ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - /* 550 */ 190, 190, 132, 191, 191, 191, 191, 50, 191, 83, - /* 560 */ 85, 84, 54, 82, 79, 5, 191, 191, 191, 145, - /* 570 */ 5, 191, 5, 145, 196, 196, 5, 191, 5, 90, - /* 580 */ 89, 135, 113, 104, 114, 107, 1, 105, 105, 191, - /* 590 */ 200, 207, 201, 206, 205, 192, 204, 202, 192, 203, - /* 600 */ 191, 197, 109, 192, 192, 191, 191, 104, 109, 193, - /* 610 */ 105, 238, 240, 104, 104, 109, 105, 104, 224, 123, + /* 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, 197, 33, 34, 109, 67, 37, + /* 220 */ 38, 39, 1, 2, 232, 104, 5, 235, 7, 61, + /* 230 */ 9, 210, 1, 2, 252, 67, 5, 0, 7, 131, + /* 240 */ 9, 73, 74, 75, 197, 228, 229, 230, 231, 37, + /* 250 */ 38, 39, 191, 104, 33, 34, 210, 236, 37, 191, + /* 260 */ 88, 112, 90, 91, 33, 34, 234, 95, 191, 97, + /* 270 */ 98, 99, 104, 101, 102, 209, 229, 252, 212, 213, + /* 280 */ 112, 249, 236, 217, 191, 219, 220, 221, 137, 223, + /* 290 */ 224, 140, 2, 232, 196, 5, 235, 7, 200, 9, + /* 300 */ 232, 37, 134, 235, 136, 25, 26, 27, 28, 232, + /* 310 */ 142, 15, 235, 33, 34, 191, 79, 37, 38, 39, + /* 320 */ 237, 62, 63, 33, 34, 104, 233, 68, 69, 70, + /* 330 */ 71, 72, 111, 250, 5, 104, 7, 78, 117, 191, + /* 340 */ 198, 199, 111, 62, 63, 5, 252, 7, 117, 68, + /* 350 */ 69, 70, 71, 72, 133, 105, 232, 252, 196, 235, + /* 360 */ 62, 63, 200, 113, 133, 60, 68, 69, 70, 71, + /* 370 */ 72, 33, 34, 194, 195, 37, 38, 39, 104, 115, + /* 380 */ 232, 1, 108, 235, 110, 109, 64, 65, 66, 124, + /* 390 */ 125, 105, 116, 105, 105, 109, 105, 109, 109, 105, + /* 400 */ 109, 111, 105, 109, 109, 252, 109, 111, 105, 104, + /* 410 */ 252, 105, 109, 252, 105, 109, 105, 37, 109, 105, + /* 420 */ 109, 252, 104, 109, 129, 107, 5, 104, 7, 106, + /* 430 */ 138, 139, 5, 252, 7, 76, 77, 138, 139, 138, + /* 440 */ 139, 252, 138, 139, 62, 63, 117, 252, 252, 252, + /* 450 */ 252, 236, 236, 227, 227, 227, 227, 117, 191, 227, + /* 460 */ 227, 227, 191, 191, 251, 259, 191, 259, 191, 234, + /* 470 */ 234, 60, 255, 191, 191, 234, 238, 192, 191, 255, + /* 480 */ 255, 103, 117, 239, 191, 255, 246, 248, 245, 247, + /* 490 */ 244, 191, 121, 191, 122, 126, 128, 243, 191, 191, + /* 500 */ 130, 191, 127, 191, 191, 120, 191, 191, 191, 119, + /* 510 */ 191, 191, 191, 118, 241, 191, 191, 191, 191, 191, + /* 520 */ 242, 191, 191, 191, 191, 191, 191, 191, 191, 132, + /* 530 */ 191, 87, 191, 191, 191, 191, 191, 191, 191, 191, + /* 540 */ 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + /* 550 */ 86, 191, 191, 191, 50, 192, 192, 83, 192, 192, + /* 560 */ 85, 54, 84, 82, 79, 5, 192, 145, 192, 192, + /* 570 */ 5, 5, 5, 145, 5, 89, 192, 90, 197, 192, + /* 580 */ 197, 135, 113, 107, 104, 114, 109, 105, 105, 105, + /* 590 */ 192, 202, 104, 193, 208, 207, 204, 206, 205, 203, + /* 600 */ 201, 193, 192, 198, 225, 193, 192, 194, 193, 192, + /* 610 */ 109, 1, 104, 240, 104, 109, 105, 104, 123, 225, /* 620 */ 123, 109, 105, 104, 104, 111, 104, 104, 107, 76, /* 630 */ 9, 5, 108, 5, 5, 5, 5, 80, 15, 76, - /* 640 */ 139, 109, 5, 16, 5, 105, 5, 5, 5, 5, - /* 650 */ 5, 5, 5, 5, 139, 139, 5, 5, 5, 5, + /* 640 */ 109, 139, 139, 16, 139, 5, 5, 105, 5, 5, + /* 650 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /* 660 */ 5, 5, 5, 5, 5, 109, 80, 60, 59, 0, - /* 670 */ 21, 21, 262, 262, 262, 262, 262, 262, 262, 262, - /* 680 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 690 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 700 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 710 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 720 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 730 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 740 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 750 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 760 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 770 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 780 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 790 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 800 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 810 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 820 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 830 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 840 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, - /* 850 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 670 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + /* 680 */ 263, 21, 21, 263, 263, 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, }; #define YY_SHIFT_COUNT (314) #define YY_SHIFT_MIN (0) #define YY_SHIFT_MAX (669) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 168, 79, 79, 172, 172, 6, 221, 231, 74, 74, - /* 10 */ 74, 74, 74, 74, 74, 74, 74, 0, 48, 231, - /* 20 */ 290, 290, 290, 290, 110, 145, 74, 74, 74, 237, - /* 30 */ 74, 74, 297, 6, 7, 7, 672, 672, 672, 231, + /* 0 */ 168, 79, 79, 172, 172, 9, 221, 231, 106, 106, + /* 10 */ 106, 106, 106, 106, 106, 106, 106, 0, 48, 231, + /* 20 */ 290, 290, 290, 290, 121, 149, 106, 106, 106, 237, + /* 30 */ 106, 106, 55, 9, 37, 37, 683, 683, 683, 231, /* 40 */ 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, /* 50 */ 231, 231, 231, 231, 231, 231, 231, 231, 231, 290, - /* 60 */ 290, 102, 102, 102, 102, 102, 102, 102, 74, 74, - /* 70 */ 74, 283, 74, 145, 145, 74, 74, 74, 233, 233, - /* 80 */ 275, 145, 74, 74, 74, 74, 74, 74, 74, 74, - /* 90 */ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - /* 100 */ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - /* 110 */ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - /* 120 */ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - /* 130 */ 74, 74, 413, 413, 413, 366, 366, 366, 413, 366, - /* 140 */ 413, 371, 370, 368, 383, 381, 388, 393, 402, 410, - /* 150 */ 420, 413, 413, 413, 382, 6, 6, 413, 413, 399, - /* 160 */ 401, 507, 476, 475, 508, 477, 481, 382, 413, 485, - /* 170 */ 485, 413, 485, 413, 485, 413, 672, 672, 27, 100, + /* 60 */ 290, 78, 78, 78, 78, 78, 78, 78, 106, 106, + /* 70 */ 106, 264, 106, 149, 149, 106, 106, 106, 265, 265, + /* 80 */ 276, 149, 106, 106, 106, 106, 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, 411, 411, 411, 365, 365, 365, 411, 365, + /* 140 */ 411, 368, 370, 375, 372, 369, 371, 385, 390, 395, + /* 150 */ 397, 411, 411, 411, 378, 9, 9, 411, 411, 444, + /* 160 */ 464, 504, 474, 475, 507, 478, 481, 378, 411, 485, + /* 170 */ 485, 411, 485, 411, 485, 411, 683, 683, 27, 100, /* 180 */ 127, 100, 100, 53, 182, 280, 280, 280, 280, 259, - /* 190 */ 281, 298, 338, 338, 338, 338, 22, 14, 92, 92, - /* 200 */ 246, 293, 284, 144, 331, 294, 295, 300, 302, 307, - /* 210 */ 308, 309, 224, 251, 319, 306, 310, 315, 316, 317, - /* 220 */ 318, 323, 258, 296, 303, 305, 325, 311, 374, 397, - /* 230 */ 369, 385, 560, 424, 565, 567, 428, 571, 573, 489, - /* 240 */ 491, 446, 469, 478, 479, 470, 482, 493, 483, 503, - /* 250 */ 505, 499, 509, 585, 510, 511, 513, 506, 496, 512, - /* 260 */ 497, 517, 519, 514, 520, 478, 522, 521, 523, 524, + /* 190 */ 281, 298, 338, 338, 338, 338, 22, 14, 212, 212, + /* 200 */ 329, 340, 274, 151, 322, 286, 250, 288, 289, 291, + /* 210 */ 294, 297, 380, 305, 296, 108, 295, 303, 306, 309, + /* 220 */ 311, 314, 318, 292, 299, 301, 323, 304, 421, 427, + /* 230 */ 359, 382, 560, 422, 565, 566, 428, 567, 569, 487, + /* 240 */ 486, 446, 469, 476, 480, 471, 482, 477, 483, 488, + /* 250 */ 484, 501, 508, 610, 510, 511, 513, 506, 495, 512, + /* 260 */ 497, 517, 519, 514, 520, 476, 522, 521, 523, 524, /* 270 */ 553, 621, 626, 628, 629, 630, 631, 557, 623, 563, - /* 280 */ 501, 532, 532, 627, 515, 516, 532, 637, 639, 540, - /* 290 */ 532, 641, 642, 643, 644, 645, 646, 647, 648, 651, + /* 280 */ 502, 531, 531, 627, 503, 505, 531, 640, 641, 542, + /* 290 */ 531, 643, 644, 645, 646, 647, 648, 649, 650, 651, /* 300 */ 652, 653, 654, 655, 656, 657, 658, 659, 556, 586, - /* 310 */ 649, 650, 607, 609, 669, + /* 310 */ 660, 661, 607, 609, 669, }; #define YY_REDUCE_COUNT (177) -#define YY_REDUCE_MIN (-244) -#define YY_REDUCE_MAX (416) +#define YY_REDUCE_MIN (-240) +#define YY_REDUCE_MAX (417) static const short yy_reduce_ofst[] = { - /* 0 */ -177, -26, -26, 67, 67, 17, -229, -215, -172, -175, - /* 10 */ -7, 62, 78, 125, 149, 151, 155, -184, -187, -232, - /* 20 */ -205, -8, 47, 68, -190, -9, -185, 44, 101, -188, - /* 30 */ 41, -78, -77, 98, -53, 5, 138, 20, 153, -244, - /* 40 */ -239, -216, -193, -143, -136, -106, 8, 25, 37, 85, - /* 50 */ 89, 139, 142, 185, 187, 189, 200, 201, 202, 171, - /* 60 */ 198, 228, 229, 230, 232, 234, 235, 236, 267, 269, - /* 70 */ 273, 214, 276, 238, 239, 277, 278, 279, 207, 212, - /* 80 */ 240, 241, 285, 286, 288, 289, 291, 292, 299, 301, - /* 90 */ 304, 312, 313, 314, 320, 321, 322, 324, 326, 327, - /* 100 */ 328, 329, 330, 332, 333, 334, 335, 336, 337, 339, - /* 110 */ 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - /* 120 */ 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, - /* 130 */ 360, 361, 362, 363, 364, 226, 242, 243, 365, 244, - /* 140 */ 367, 245, 247, 256, 262, 265, 248, 274, 372, 249, - /* 150 */ 373, 375, 376, 377, 260, 378, 379, 380, 386, 384, - /* 160 */ 387, 389, 391, 392, 395, 396, 390, 394, 398, 403, - /* 170 */ 406, 409, 411, 414, 412, 415, 404, 416, + /* 0 */ -178, -27, -27, 66, 66, 17, -230, -216, -173, -176, + /* 10 */ -45, -8, 61, 68, 77, 124, 148, -185, -188, -233, + /* 20 */ -206, -91, 21, 46, -191, 32, -186, -183, 93, -89, + /* 30 */ -184, -106, 4, 47, 98, 162, 83, 142, 179, -240, + /* 40 */ -217, -194, -117, -96, -51, -18, 25, 94, 105, 153, + /* 50 */ 158, 161, 169, 181, 189, 195, 196, 197, 198, 215, + /* 60 */ 216, 226, 227, 228, 229, 232, 233, 234, 267, 271, + /* 70 */ 272, 213, 275, 235, 236, 277, 282, 283, 206, 208, + /* 80 */ 238, 241, 287, 293, 300, 302, 307, 308, 310, 312, + /* 90 */ 313, 315, 316, 317, 319, 320, 321, 324, 325, 326, + /* 100 */ 327, 328, 330, 331, 332, 333, 334, 335, 336, 337, + /* 110 */ 339, 341, 342, 343, 344, 345, 346, 347, 348, 349, + /* 120 */ 350, 351, 352, 353, 354, 355, 356, 357, 358, 360, + /* 130 */ 361, 362, 285, 363, 364, 217, 224, 225, 366, 230, + /* 140 */ 367, 239, 242, 240, 243, 246, 254, 278, 273, 373, + /* 150 */ 244, 374, 376, 377, 379, 381, 383, 384, 387, 386, + /* 160 */ 388, 391, 389, 393, 396, 392, 399, 394, 398, 400, + /* 170 */ 408, 410, 412, 414, 415, 417, 405, 413, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 777, 889, 835, 901, 823, 832, 1032, 1032, 777, 777, @@ -712,7 +702,6 @@ struct yyParser { int yyerrcnt; /* Shifts left before out of the error */ #endif ParseARG_SDECL /* A place to hold %extra_argument */ - ParseCTX_SDECL /* A place to hold %extra_context */ #if YYSTACKDEPTH<=0 int yystksz; /* Current side of the stack */ yyStackEntry *yystack; /* The parser's stack */ @@ -947,81 +936,82 @@ static const char *const yyTokenName[] = { /* 184 */ "INSERT", /* 185 */ "INTO", /* 186 */ "VALUES", - /* 187 */ "program", - /* 188 */ "cmd", - /* 189 */ "dbPrefix", - /* 190 */ "ids", - /* 191 */ "cpxName", - /* 192 */ "ifexists", - /* 193 */ "alter_db_optr", - /* 194 */ "alter_topic_optr", - /* 195 */ "acct_optr", - /* 196 */ "ifnotexists", - /* 197 */ "db_optr", - /* 198 */ "topic_optr", - /* 199 */ "pps", - /* 200 */ "tseries", - /* 201 */ "dbs", - /* 202 */ "streams", - /* 203 */ "storage", - /* 204 */ "qtime", - /* 205 */ "users", - /* 206 */ "conns", - /* 207 */ "state", - /* 208 */ "keep", - /* 209 */ "tagitemlist", - /* 210 */ "cache", - /* 211 */ "replica", - /* 212 */ "quorum", - /* 213 */ "days", - /* 214 */ "minrows", - /* 215 */ "maxrows", - /* 216 */ "blocks", - /* 217 */ "ctime", - /* 218 */ "wal", - /* 219 */ "fsync", - /* 220 */ "comp", - /* 221 */ "prec", - /* 222 */ "update", - /* 223 */ "cachelast", - /* 224 */ "partitions", - /* 225 */ "typename", - /* 226 */ "signed", - /* 227 */ "create_table_args", - /* 228 */ "create_stable_args", - /* 229 */ "create_table_list", - /* 230 */ "create_from_stable", - /* 231 */ "columnlist", - /* 232 */ "tagNamelist", - /* 233 */ "select", - /* 234 */ "column", - /* 235 */ "tagitem", - /* 236 */ "selcollist", - /* 237 */ "from", - /* 238 */ "where_opt", - /* 239 */ "interval_opt", - /* 240 */ "session_option", - /* 241 */ "fill_opt", - /* 242 */ "sliding_opt", - /* 243 */ "groupby_opt", - /* 244 */ "orderby_opt", - /* 245 */ "having_opt", - /* 246 */ "slimit_opt", - /* 247 */ "limit_opt", - /* 248 */ "union", - /* 249 */ "sclp", - /* 250 */ "distinct", - /* 251 */ "expr", - /* 252 */ "as", - /* 253 */ "tablelist", - /* 254 */ "tmvar", - /* 255 */ "sortlist", - /* 256 */ "sortitem", - /* 257 */ "item", - /* 258 */ "sortorder", - /* 259 */ "grouplist", - /* 260 */ "exprlist", - /* 261 */ "expritem", + /* 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", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -1346,29 +1336,28 @@ static int yyGrowStack(yyParser *p){ /* Initialize a new parser that has already been allocated. */ -void ParseInit(void *yypRawParser ParseCTX_PDECL){ - yyParser *yypParser = (yyParser*)yypRawParser; - ParseCTX_STORE +void ParseInit(void *yypParser){ + yyParser *pParser = (yyParser*)yypParser; #ifdef YYTRACKMAXSTACKDEPTH - yypParser->yyhwm = 0; + pParser->yyhwm = 0; #endif #if YYSTACKDEPTH<=0 - yypParser->yytos = NULL; - yypParser->yystack = NULL; - yypParser->yystksz = 0; - if( yyGrowStack(yypParser) ){ - yypParser->yystack = &yypParser->yystk0; - yypParser->yystksz = 1; + pParser->yytos = NULL; + pParser->yystack = NULL; + pParser->yystksz = 0; + if( yyGrowStack(pParser) ){ + pParser->yystack = &pParser->yystk0; + pParser->yystksz = 1; } #endif #ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; + pParser->yyerrcnt = -1; #endif - yypParser->yytos = yypParser->yystack; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; + pParser->yytos = pParser->yystack; + pParser->yystack[0].stateno = 0; + pParser->yystack[0].major = 0; #if YYSTACKDEPTH>0 - yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; + pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1]; #endif } @@ -1385,14 +1374,11 @@ void ParseInit(void *yypRawParser ParseCTX_PDECL){ ** A pointer to a parser. This pointer is used in subsequent calls ** to Parse and ParseFree. */ -void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) ParseCTX_PDECL){ - yyParser *yypParser; - yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); - if( yypParser ){ - ParseCTX_STORE - ParseInit(yypParser ParseCTX_PARAM); - } - return (void*)yypParser; +void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ + yyParser *pParser; + pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); + if( pParser ) ParseInit(pParser); + return pParser; } #endif /* Parse_ENGINEALWAYSONSTACK */ @@ -1409,8 +1395,7 @@ static void yy_destructor( YYCODETYPE yymajor, /* Type code for object to destroy */ YYMINORTYPE *yypminor /* The object to be destroyed */ ){ - ParseARG_FETCH - ParseCTX_FETCH + ParseARG_FETCH; switch( yymajor ){ /* Here is inserted the actions which take place when a ** terminal or non-terminal is destroyed. This can happen @@ -1423,52 +1408,58 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 208: /* keep */ - case 209: /* tagitemlist */ - case 231: /* columnlist */ - case 232: /* tagNamelist */ - case 241: /* fill_opt */ - case 243: /* groupby_opt */ - case 244: /* orderby_opt */ - case 255: /* sortlist */ - case 259: /* grouplist */ + 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 */ { -taosArrayDestroy((yypminor->yy429)); +taosArrayDestroy((yypminor->yy159)); } break; - case 229: /* create_table_list */ + case 230: /* create_table_list */ { -destroyCreateTableSql((yypminor->yy194)); +destroyCreateTableSql((yypminor->yy14)); } break; - case 233: /* select */ + case 234: /* select */ { -destroyQuerySqlNode((yypminor->yy254)); +destroySqlNode((yypminor->yy116)); } break; - case 236: /* selcollist */ - case 249: /* sclp */ - case 260: /* exprlist */ + case 237: /* selcollist */ + case 250: /* sclp */ + case 261: /* exprlist */ { -tSqlExprListDestroy((yypminor->yy429)); +tSqlExprListDestroy((yypminor->yy159)); } break; - case 238: /* where_opt */ - case 245: /* having_opt */ - case 251: /* expr */ - case 261: /* expritem */ + case 238: /* from */ + case 254: /* tablelist */ { -tSqlExprDestroy((yypminor->yy170)); +destroyRelationInfo((yypminor->yy236)); } break; - case 248: /* union */ + case 239: /* where_opt */ + case 246: /* having_opt */ + case 252: /* expr */ + case 262: /* expritem */ { -destroyAllSelectClause((yypminor->yy141)); +tSqlExprDestroy((yypminor->yy118)); } break; - case 256: /* sortitem */ + case 249: /* union */ { -tVariantDestroy(&(yypminor->yy218)); +destroyAllSqlNode((yypminor->yy159)); +} + break; + case 257: /* sortitem */ +{ +tVariantDestroy(&(yypminor->yy488)); } break; /********* End destructor definitions *****************************************/ @@ -1580,12 +1571,13 @@ int ParseCoverage(FILE *out){ ** Find the appropriate action for a parser given the terminal ** look-ahead token iLookAhead. */ -static YYACTIONTYPE yy_find_shift_action( - YYCODETYPE iLookAhead, /* The look-ahead token */ - YYACTIONTYPE stateno /* Current state number */ +static unsigned int yy_find_shift_action( + yyParser *pParser, /* The parser */ + YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; - + int stateno = pParser->yytos->stateno; + if( stateno>YY_MAX_SHIFT ) return stateno; assert( stateno <= YY_SHIFT_COUNT ); #if defined(YYCOVERAGE) @@ -1593,19 +1585,15 @@ static YYACTIONTYPE yy_find_shift_action( #endif do{ i = yy_shift_ofst[stateno]; - assert( i>=0 ); - assert( i<=YY_ACTTAB_COUNT ); - assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); + assert( i>=0 && i+YYNTOKEN<=sizeof(yy_lookahead)/sizeof(yy_lookahead[0]) ); assert( iLookAhead!=YYNOCODE ); assert( iLookAhead < YYNTOKEN ); i += iLookAhead; - assert( i<(int)YY_NLOOKAHEAD ); if( yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ - assert( iLookAhead %s\n", @@ -1620,8 +1608,15 @@ static YYACTIONTYPE yy_find_shift_action( #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD; - assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) ); - if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){ + if( +#if YY_SHIFT_MIN+YYWILDCARD<0 + j>=0 && +#endif +#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT + j0 + ){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", @@ -1635,7 +1630,6 @@ static YYACTIONTYPE yy_find_shift_action( #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ - assert( i>=0 && iyytos; - yytos->stateno = yyNewState; - yytos->major = yyMajor; + yytos->stateno = (YYACTIONTYPE)yyNewState; + yytos->major = (YYCODETYPE)yyMajor; yytos->minor.yy0 = yyMinor; yyTraceShift(yypParser, yyNewState, "Shift"); } -/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side -** of that rule */ -static const YYCODETYPE yyRuleInfoLhs[] = { - 187, /* (0) program ::= cmd */ - 188, /* (1) cmd ::= SHOW DATABASES */ - 188, /* (2) cmd ::= SHOW TOPICS */ - 188, /* (3) cmd ::= SHOW MNODES */ - 188, /* (4) cmd ::= SHOW DNODES */ - 188, /* (5) cmd ::= SHOW ACCOUNTS */ - 188, /* (6) cmd ::= SHOW USERS */ - 188, /* (7) cmd ::= SHOW MODULES */ - 188, /* (8) cmd ::= SHOW QUERIES */ - 188, /* (9) cmd ::= SHOW CONNECTIONS */ - 188, /* (10) cmd ::= SHOW STREAMS */ - 188, /* (11) cmd ::= SHOW VARIABLES */ - 188, /* (12) cmd ::= SHOW SCORES */ - 188, /* (13) cmd ::= SHOW GRANTS */ - 188, /* (14) cmd ::= SHOW VNODES */ - 188, /* (15) cmd ::= SHOW VNODES IPTOKEN */ - 189, /* (16) dbPrefix ::= */ - 189, /* (17) dbPrefix ::= ids DOT */ - 191, /* (18) cpxName ::= */ - 191, /* (19) cpxName ::= DOT ids */ - 188, /* (20) cmd ::= SHOW CREATE TABLE ids cpxName */ - 188, /* (21) cmd ::= SHOW CREATE DATABASE ids */ - 188, /* (22) cmd ::= SHOW dbPrefix TABLES */ - 188, /* (23) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - 188, /* (24) cmd ::= SHOW dbPrefix STABLES */ - 188, /* (25) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - 188, /* (26) cmd ::= SHOW dbPrefix VGROUPS */ - 188, /* (27) cmd ::= SHOW dbPrefix VGROUPS ids */ - 188, /* (28) cmd ::= DROP TABLE ifexists ids cpxName */ - 188, /* (29) cmd ::= DROP STABLE ifexists ids cpxName */ - 188, /* (30) cmd ::= DROP DATABASE ifexists ids */ - 188, /* (31) cmd ::= DROP TOPIC ifexists ids */ - 188, /* (32) cmd ::= DROP DNODE ids */ - 188, /* (33) cmd ::= DROP USER ids */ - 188, /* (34) cmd ::= DROP ACCOUNT ids */ - 188, /* (35) cmd ::= USE ids */ - 188, /* (36) cmd ::= DESCRIBE ids cpxName */ - 188, /* (37) cmd ::= ALTER USER ids PASS ids */ - 188, /* (38) cmd ::= ALTER USER ids PRIVILEGE ids */ - 188, /* (39) cmd ::= ALTER DNODE ids ids */ - 188, /* (40) cmd ::= ALTER DNODE ids ids ids */ - 188, /* (41) cmd ::= ALTER LOCAL ids */ - 188, /* (42) cmd ::= ALTER LOCAL ids ids */ - 188, /* (43) cmd ::= ALTER DATABASE ids alter_db_optr */ - 188, /* (44) cmd ::= ALTER TOPIC ids alter_topic_optr */ - 188, /* (45) cmd ::= ALTER ACCOUNT ids acct_optr */ - 188, /* (46) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - 190, /* (47) ids ::= ID */ - 190, /* (48) ids ::= STRING */ - 192, /* (49) ifexists ::= IF EXISTS */ - 192, /* (50) ifexists ::= */ - 196, /* (51) ifnotexists ::= IF NOT EXISTS */ - 196, /* (52) ifnotexists ::= */ - 188, /* (53) cmd ::= CREATE DNODE ids */ - 188, /* (54) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - 188, /* (55) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - 188, /* (56) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - 188, /* (57) cmd ::= CREATE USER ids PASS ids */ - 199, /* (58) pps ::= */ - 199, /* (59) pps ::= PPS INTEGER */ - 200, /* (60) tseries ::= */ - 200, /* (61) tseries ::= TSERIES INTEGER */ - 201, /* (62) dbs ::= */ - 201, /* (63) dbs ::= DBS INTEGER */ - 202, /* (64) streams ::= */ - 202, /* (65) streams ::= STREAMS INTEGER */ - 203, /* (66) storage ::= */ - 203, /* (67) storage ::= STORAGE INTEGER */ - 204, /* (68) qtime ::= */ - 204, /* (69) qtime ::= QTIME INTEGER */ - 205, /* (70) users ::= */ - 205, /* (71) users ::= USERS INTEGER */ - 206, /* (72) conns ::= */ - 206, /* (73) conns ::= CONNS INTEGER */ - 207, /* (74) state ::= */ - 207, /* (75) state ::= STATE ids */ - 195, /* (76) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - 208, /* (77) keep ::= KEEP tagitemlist */ - 210, /* (78) cache ::= CACHE INTEGER */ - 211, /* (79) replica ::= REPLICA INTEGER */ - 212, /* (80) quorum ::= QUORUM INTEGER */ - 213, /* (81) days ::= DAYS INTEGER */ - 214, /* (82) minrows ::= MINROWS INTEGER */ - 215, /* (83) maxrows ::= MAXROWS INTEGER */ - 216, /* (84) blocks ::= BLOCKS INTEGER */ - 217, /* (85) ctime ::= CTIME INTEGER */ - 218, /* (86) wal ::= WAL INTEGER */ - 219, /* (87) fsync ::= FSYNC INTEGER */ - 220, /* (88) comp ::= COMP INTEGER */ - 221, /* (89) prec ::= PRECISION STRING */ - 222, /* (90) update ::= UPDATE INTEGER */ - 223, /* (91) cachelast ::= CACHELAST INTEGER */ - 224, /* (92) partitions ::= PARTITIONS INTEGER */ - 197, /* (93) db_optr ::= */ - 197, /* (94) db_optr ::= db_optr cache */ - 197, /* (95) db_optr ::= db_optr replica */ - 197, /* (96) db_optr ::= db_optr quorum */ - 197, /* (97) db_optr ::= db_optr days */ - 197, /* (98) db_optr ::= db_optr minrows */ - 197, /* (99) db_optr ::= db_optr maxrows */ - 197, /* (100) db_optr ::= db_optr blocks */ - 197, /* (101) db_optr ::= db_optr ctime */ - 197, /* (102) db_optr ::= db_optr wal */ - 197, /* (103) db_optr ::= db_optr fsync */ - 197, /* (104) db_optr ::= db_optr comp */ - 197, /* (105) db_optr ::= db_optr prec */ - 197, /* (106) db_optr ::= db_optr keep */ - 197, /* (107) db_optr ::= db_optr update */ - 197, /* (108) db_optr ::= db_optr cachelast */ - 198, /* (109) topic_optr ::= db_optr */ - 198, /* (110) topic_optr ::= topic_optr partitions */ - 193, /* (111) alter_db_optr ::= */ - 193, /* (112) alter_db_optr ::= alter_db_optr replica */ - 193, /* (113) alter_db_optr ::= alter_db_optr quorum */ - 193, /* (114) alter_db_optr ::= alter_db_optr keep */ - 193, /* (115) alter_db_optr ::= alter_db_optr blocks */ - 193, /* (116) alter_db_optr ::= alter_db_optr comp */ - 193, /* (117) alter_db_optr ::= alter_db_optr wal */ - 193, /* (118) alter_db_optr ::= alter_db_optr fsync */ - 193, /* (119) alter_db_optr ::= alter_db_optr update */ - 193, /* (120) alter_db_optr ::= alter_db_optr cachelast */ - 194, /* (121) alter_topic_optr ::= alter_db_optr */ - 194, /* (122) alter_topic_optr ::= alter_topic_optr partitions */ - 225, /* (123) typename ::= ids */ - 225, /* (124) typename ::= ids LP signed RP */ - 225, /* (125) typename ::= ids UNSIGNED */ - 226, /* (126) signed ::= INTEGER */ - 226, /* (127) signed ::= PLUS INTEGER */ - 226, /* (128) signed ::= MINUS INTEGER */ - 188, /* (129) cmd ::= CREATE TABLE create_table_args */ - 188, /* (130) cmd ::= CREATE TABLE create_stable_args */ - 188, /* (131) cmd ::= CREATE STABLE create_stable_args */ - 188, /* (132) cmd ::= CREATE TABLE create_table_list */ - 229, /* (133) create_table_list ::= create_from_stable */ - 229, /* (134) create_table_list ::= create_table_list create_from_stable */ - 227, /* (135) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - 228, /* (136) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - 230, /* (137) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - 230, /* (138) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - 232, /* (139) tagNamelist ::= tagNamelist COMMA ids */ - 232, /* (140) tagNamelist ::= ids */ - 227, /* (141) create_table_args ::= ifnotexists ids cpxName AS select */ - 231, /* (142) columnlist ::= columnlist COMMA column */ - 231, /* (143) columnlist ::= column */ - 234, /* (144) column ::= ids typename */ - 209, /* (145) tagitemlist ::= tagitemlist COMMA tagitem */ - 209, /* (146) tagitemlist ::= tagitem */ - 235, /* (147) tagitem ::= INTEGER */ - 235, /* (148) tagitem ::= FLOAT */ - 235, /* (149) tagitem ::= STRING */ - 235, /* (150) tagitem ::= BOOL */ - 235, /* (151) tagitem ::= NULL */ - 235, /* (152) tagitem ::= MINUS INTEGER */ - 235, /* (153) tagitem ::= MINUS FLOAT */ - 235, /* (154) tagitem ::= PLUS INTEGER */ - 235, /* (155) tagitem ::= PLUS FLOAT */ - 233, /* (156) select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ - 233, /* (157) select ::= LP select RP */ - 248, /* (158) union ::= select */ - 248, /* (159) union ::= union UNION ALL select */ - 188, /* (160) cmd ::= union */ - 233, /* (161) select ::= SELECT selcollist */ - 249, /* (162) sclp ::= selcollist COMMA */ - 249, /* (163) sclp ::= */ - 236, /* (164) selcollist ::= sclp distinct expr as */ - 236, /* (165) selcollist ::= sclp STAR */ - 252, /* (166) as ::= AS ids */ - 252, /* (167) as ::= ids */ - 252, /* (168) as ::= */ - 250, /* (169) distinct ::= DISTINCT */ - 250, /* (170) distinct ::= */ - 237, /* (171) from ::= FROM tablelist */ - 237, /* (172) from ::= FROM LP union RP */ - 253, /* (173) tablelist ::= ids cpxName */ - 253, /* (174) tablelist ::= ids cpxName ids */ - 253, /* (175) tablelist ::= tablelist COMMA ids cpxName */ - 253, /* (176) tablelist ::= tablelist COMMA ids cpxName ids */ - 254, /* (177) tmvar ::= VARIABLE */ - 239, /* (178) interval_opt ::= INTERVAL LP tmvar RP */ - 239, /* (179) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ - 239, /* (180) interval_opt ::= */ - 240, /* (181) session_option ::= */ - 240, /* (182) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - 241, /* (183) fill_opt ::= */ - 241, /* (184) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - 241, /* (185) fill_opt ::= FILL LP ID RP */ - 242, /* (186) sliding_opt ::= SLIDING LP tmvar RP */ - 242, /* (187) sliding_opt ::= */ - 244, /* (188) orderby_opt ::= */ - 244, /* (189) orderby_opt ::= ORDER BY sortlist */ - 255, /* (190) sortlist ::= sortlist COMMA item sortorder */ - 255, /* (191) sortlist ::= item sortorder */ - 257, /* (192) item ::= ids cpxName */ - 258, /* (193) sortorder ::= ASC */ - 258, /* (194) sortorder ::= DESC */ - 258, /* (195) sortorder ::= */ - 243, /* (196) groupby_opt ::= */ - 243, /* (197) groupby_opt ::= GROUP BY grouplist */ - 259, /* (198) grouplist ::= grouplist COMMA item */ - 259, /* (199) grouplist ::= item */ - 245, /* (200) having_opt ::= */ - 245, /* (201) having_opt ::= HAVING expr */ - 247, /* (202) limit_opt ::= */ - 247, /* (203) limit_opt ::= LIMIT signed */ - 247, /* (204) limit_opt ::= LIMIT signed OFFSET signed */ - 247, /* (205) limit_opt ::= LIMIT signed COMMA signed */ - 246, /* (206) slimit_opt ::= */ - 246, /* (207) slimit_opt ::= SLIMIT signed */ - 246, /* (208) slimit_opt ::= SLIMIT signed SOFFSET signed */ - 246, /* (209) slimit_opt ::= SLIMIT signed COMMA signed */ - 238, /* (210) where_opt ::= */ - 238, /* (211) where_opt ::= WHERE expr */ - 251, /* (212) expr ::= LP expr RP */ - 251, /* (213) expr ::= ID */ - 251, /* (214) expr ::= ID DOT ID */ - 251, /* (215) expr ::= ID DOT STAR */ - 251, /* (216) expr ::= INTEGER */ - 251, /* (217) expr ::= MINUS INTEGER */ - 251, /* (218) expr ::= PLUS INTEGER */ - 251, /* (219) expr ::= FLOAT */ - 251, /* (220) expr ::= MINUS FLOAT */ - 251, /* (221) expr ::= PLUS FLOAT */ - 251, /* (222) expr ::= STRING */ - 251, /* (223) expr ::= NOW */ - 251, /* (224) expr ::= VARIABLE */ - 251, /* (225) expr ::= PLUS VARIABLE */ - 251, /* (226) expr ::= MINUS VARIABLE */ - 251, /* (227) expr ::= BOOL */ - 251, /* (228) expr ::= NULL */ - 251, /* (229) expr ::= ID LP exprlist RP */ - 251, /* (230) expr ::= ID LP STAR RP */ - 251, /* (231) expr ::= expr IS NULL */ - 251, /* (232) expr ::= expr IS NOT NULL */ - 251, /* (233) expr ::= expr LT expr */ - 251, /* (234) expr ::= expr GT expr */ - 251, /* (235) expr ::= expr LE expr */ - 251, /* (236) expr ::= expr GE expr */ - 251, /* (237) expr ::= expr NE expr */ - 251, /* (238) expr ::= expr EQ expr */ - 251, /* (239) expr ::= expr BETWEEN expr AND expr */ - 251, /* (240) expr ::= expr AND expr */ - 251, /* (241) expr ::= expr OR expr */ - 251, /* (242) expr ::= expr PLUS expr */ - 251, /* (243) expr ::= expr MINUS expr */ - 251, /* (244) expr ::= expr STAR expr */ - 251, /* (245) expr ::= expr SLASH expr */ - 251, /* (246) expr ::= expr REM expr */ - 251, /* (247) expr ::= expr LIKE expr */ - 251, /* (248) expr ::= expr IN LP exprlist RP */ - 260, /* (249) exprlist ::= exprlist COMMA expritem */ - 260, /* (250) exprlist ::= expritem */ - 261, /* (251) expritem ::= expr */ - 261, /* (252) expritem ::= */ - 188, /* (253) cmd ::= RESET QUERY CACHE */ - 188, /* (254) cmd ::= SYNCDB ids REPLICA */ - 188, /* (255) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - 188, /* (256) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - 188, /* (257) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - 188, /* (258) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - 188, /* (259) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - 188, /* (260) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - 188, /* (261) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - 188, /* (262) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - 188, /* (263) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - 188, /* (264) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - 188, /* (265) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - 188, /* (266) cmd ::= KILL CONNECTION INTEGER */ - 188, /* (267) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - 188, /* (268) cmd ::= KILL QUERY INTEGER COLON INTEGER */ -}; - -/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number -** of symbols on the right-hand side of that rule. */ -static const signed char yyRuleInfoNRhs[] = { - -1, /* (0) program ::= cmd */ - -2, /* (1) cmd ::= SHOW DATABASES */ - -2, /* (2) cmd ::= SHOW TOPICS */ - -2, /* (3) cmd ::= SHOW MNODES */ - -2, /* (4) cmd ::= SHOW DNODES */ - -2, /* (5) cmd ::= SHOW ACCOUNTS */ - -2, /* (6) cmd ::= SHOW USERS */ - -2, /* (7) cmd ::= SHOW MODULES */ - -2, /* (8) cmd ::= SHOW QUERIES */ - -2, /* (9) cmd ::= SHOW CONNECTIONS */ - -2, /* (10) cmd ::= SHOW STREAMS */ - -2, /* (11) cmd ::= SHOW VARIABLES */ - -2, /* (12) cmd ::= SHOW SCORES */ - -2, /* (13) cmd ::= SHOW GRANTS */ - -2, /* (14) cmd ::= SHOW VNODES */ - -3, /* (15) cmd ::= SHOW VNODES IPTOKEN */ - 0, /* (16) dbPrefix ::= */ - -2, /* (17) dbPrefix ::= ids DOT */ - 0, /* (18) cpxName ::= */ - -2, /* (19) cpxName ::= DOT ids */ - -5, /* (20) cmd ::= SHOW CREATE TABLE ids cpxName */ - -4, /* (21) cmd ::= SHOW CREATE DATABASE ids */ - -3, /* (22) cmd ::= SHOW dbPrefix TABLES */ - -5, /* (23) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - -3, /* (24) cmd ::= SHOW dbPrefix STABLES */ - -5, /* (25) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - -3, /* (26) cmd ::= SHOW dbPrefix VGROUPS */ - -4, /* (27) cmd ::= SHOW dbPrefix VGROUPS ids */ - -5, /* (28) cmd ::= DROP TABLE ifexists ids cpxName */ - -5, /* (29) cmd ::= DROP STABLE ifexists ids cpxName */ - -4, /* (30) cmd ::= DROP DATABASE ifexists ids */ - -4, /* (31) cmd ::= DROP TOPIC ifexists ids */ - -3, /* (32) cmd ::= DROP DNODE ids */ - -3, /* (33) cmd ::= DROP USER ids */ - -3, /* (34) cmd ::= DROP ACCOUNT ids */ - -2, /* (35) cmd ::= USE ids */ - -3, /* (36) cmd ::= DESCRIBE ids cpxName */ - -5, /* (37) cmd ::= ALTER USER ids PASS ids */ - -5, /* (38) cmd ::= ALTER USER ids PRIVILEGE ids */ - -4, /* (39) cmd ::= ALTER DNODE ids ids */ - -5, /* (40) cmd ::= ALTER DNODE ids ids ids */ - -3, /* (41) cmd ::= ALTER LOCAL ids */ - -4, /* (42) cmd ::= ALTER LOCAL ids ids */ - -4, /* (43) cmd ::= ALTER DATABASE ids alter_db_optr */ - -4, /* (44) cmd ::= ALTER TOPIC ids alter_topic_optr */ - -4, /* (45) cmd ::= ALTER ACCOUNT ids acct_optr */ - -6, /* (46) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - -1, /* (47) ids ::= ID */ - -1, /* (48) ids ::= STRING */ - -2, /* (49) ifexists ::= IF EXISTS */ - 0, /* (50) ifexists ::= */ - -3, /* (51) ifnotexists ::= IF NOT EXISTS */ - 0, /* (52) ifnotexists ::= */ - -3, /* (53) cmd ::= CREATE DNODE ids */ - -6, /* (54) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - -5, /* (55) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - -5, /* (56) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - -5, /* (57) cmd ::= CREATE USER ids PASS ids */ - 0, /* (58) pps ::= */ - -2, /* (59) pps ::= PPS INTEGER */ - 0, /* (60) tseries ::= */ - -2, /* (61) tseries ::= TSERIES INTEGER */ - 0, /* (62) dbs ::= */ - -2, /* (63) dbs ::= DBS INTEGER */ - 0, /* (64) streams ::= */ - -2, /* (65) streams ::= STREAMS INTEGER */ - 0, /* (66) storage ::= */ - -2, /* (67) storage ::= STORAGE INTEGER */ - 0, /* (68) qtime ::= */ - -2, /* (69) qtime ::= QTIME INTEGER */ - 0, /* (70) users ::= */ - -2, /* (71) users ::= USERS INTEGER */ - 0, /* (72) conns ::= */ - -2, /* (73) conns ::= CONNS INTEGER */ - 0, /* (74) state ::= */ - -2, /* (75) state ::= STATE ids */ - -9, /* (76) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - -2, /* (77) keep ::= KEEP tagitemlist */ - -2, /* (78) cache ::= CACHE INTEGER */ - -2, /* (79) replica ::= REPLICA INTEGER */ - -2, /* (80) quorum ::= QUORUM INTEGER */ - -2, /* (81) days ::= DAYS INTEGER */ - -2, /* (82) minrows ::= MINROWS INTEGER */ - -2, /* (83) maxrows ::= MAXROWS INTEGER */ - -2, /* (84) blocks ::= BLOCKS INTEGER */ - -2, /* (85) ctime ::= CTIME INTEGER */ - -2, /* (86) wal ::= WAL INTEGER */ - -2, /* (87) fsync ::= FSYNC INTEGER */ - -2, /* (88) comp ::= COMP INTEGER */ - -2, /* (89) prec ::= PRECISION STRING */ - -2, /* (90) update ::= UPDATE INTEGER */ - -2, /* (91) cachelast ::= CACHELAST INTEGER */ - -2, /* (92) partitions ::= PARTITIONS INTEGER */ - 0, /* (93) db_optr ::= */ - -2, /* (94) db_optr ::= db_optr cache */ - -2, /* (95) db_optr ::= db_optr replica */ - -2, /* (96) db_optr ::= db_optr quorum */ - -2, /* (97) db_optr ::= db_optr days */ - -2, /* (98) db_optr ::= db_optr minrows */ - -2, /* (99) db_optr ::= db_optr maxrows */ - -2, /* (100) db_optr ::= db_optr blocks */ - -2, /* (101) db_optr ::= db_optr ctime */ - -2, /* (102) db_optr ::= db_optr wal */ - -2, /* (103) db_optr ::= db_optr fsync */ - -2, /* (104) db_optr ::= db_optr comp */ - -2, /* (105) db_optr ::= db_optr prec */ - -2, /* (106) db_optr ::= db_optr keep */ - -2, /* (107) db_optr ::= db_optr update */ - -2, /* (108) db_optr ::= db_optr cachelast */ - -1, /* (109) topic_optr ::= db_optr */ - -2, /* (110) topic_optr ::= topic_optr partitions */ - 0, /* (111) alter_db_optr ::= */ - -2, /* (112) alter_db_optr ::= alter_db_optr replica */ - -2, /* (113) alter_db_optr ::= alter_db_optr quorum */ - -2, /* (114) alter_db_optr ::= alter_db_optr keep */ - -2, /* (115) alter_db_optr ::= alter_db_optr blocks */ - -2, /* (116) alter_db_optr ::= alter_db_optr comp */ - -2, /* (117) alter_db_optr ::= alter_db_optr wal */ - -2, /* (118) alter_db_optr ::= alter_db_optr fsync */ - -2, /* (119) alter_db_optr ::= alter_db_optr update */ - -2, /* (120) alter_db_optr ::= alter_db_optr cachelast */ - -1, /* (121) alter_topic_optr ::= alter_db_optr */ - -2, /* (122) alter_topic_optr ::= alter_topic_optr partitions */ - -1, /* (123) typename ::= ids */ - -4, /* (124) typename ::= ids LP signed RP */ - -2, /* (125) typename ::= ids UNSIGNED */ - -1, /* (126) signed ::= INTEGER */ - -2, /* (127) signed ::= PLUS INTEGER */ - -2, /* (128) signed ::= MINUS INTEGER */ - -3, /* (129) cmd ::= CREATE TABLE create_table_args */ - -3, /* (130) cmd ::= CREATE TABLE create_stable_args */ - -3, /* (131) cmd ::= CREATE STABLE create_stable_args */ - -3, /* (132) cmd ::= CREATE TABLE create_table_list */ - -1, /* (133) create_table_list ::= create_from_stable */ - -2, /* (134) create_table_list ::= create_table_list create_from_stable */ - -6, /* (135) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - -10, /* (136) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - -10, /* (137) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - -13, /* (138) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - -3, /* (139) tagNamelist ::= tagNamelist COMMA ids */ - -1, /* (140) tagNamelist ::= ids */ - -5, /* (141) create_table_args ::= ifnotexists ids cpxName AS select */ - -3, /* (142) columnlist ::= columnlist COMMA column */ - -1, /* (143) columnlist ::= column */ - -2, /* (144) column ::= ids typename */ - -3, /* (145) tagitemlist ::= tagitemlist COMMA tagitem */ - -1, /* (146) tagitemlist ::= tagitem */ - -1, /* (147) tagitem ::= INTEGER */ - -1, /* (148) tagitem ::= FLOAT */ - -1, /* (149) tagitem ::= STRING */ - -1, /* (150) tagitem ::= BOOL */ - -1, /* (151) tagitem ::= NULL */ - -2, /* (152) tagitem ::= MINUS INTEGER */ - -2, /* (153) tagitem ::= MINUS FLOAT */ - -2, /* (154) tagitem ::= PLUS INTEGER */ - -2, /* (155) tagitem ::= PLUS FLOAT */ - -13, /* (156) select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ - -3, /* (157) select ::= LP select RP */ - -1, /* (158) union ::= select */ - -4, /* (159) union ::= union UNION ALL select */ - -1, /* (160) cmd ::= union */ - -2, /* (161) select ::= SELECT selcollist */ - -2, /* (162) sclp ::= selcollist COMMA */ - 0, /* (163) sclp ::= */ - -4, /* (164) selcollist ::= sclp distinct expr as */ - -2, /* (165) selcollist ::= sclp STAR */ - -2, /* (166) as ::= AS ids */ - -1, /* (167) as ::= ids */ - 0, /* (168) as ::= */ - -1, /* (169) distinct ::= DISTINCT */ - 0, /* (170) distinct ::= */ - -2, /* (171) from ::= FROM tablelist */ - -4, /* (172) from ::= FROM LP union RP */ - -2, /* (173) tablelist ::= ids cpxName */ - -3, /* (174) tablelist ::= ids cpxName ids */ - -4, /* (175) tablelist ::= tablelist COMMA ids cpxName */ - -5, /* (176) tablelist ::= tablelist COMMA ids cpxName ids */ - -1, /* (177) tmvar ::= VARIABLE */ - -4, /* (178) interval_opt ::= INTERVAL LP tmvar RP */ - -6, /* (179) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ - 0, /* (180) interval_opt ::= */ - 0, /* (181) session_option ::= */ - -7, /* (182) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - 0, /* (183) fill_opt ::= */ - -6, /* (184) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - -4, /* (185) fill_opt ::= FILL LP ID RP */ - -4, /* (186) sliding_opt ::= SLIDING LP tmvar RP */ - 0, /* (187) sliding_opt ::= */ - 0, /* (188) orderby_opt ::= */ - -3, /* (189) orderby_opt ::= ORDER BY sortlist */ - -4, /* (190) sortlist ::= sortlist COMMA item sortorder */ - -2, /* (191) sortlist ::= item sortorder */ - -2, /* (192) item ::= ids cpxName */ - -1, /* (193) sortorder ::= ASC */ - -1, /* (194) sortorder ::= DESC */ - 0, /* (195) sortorder ::= */ - 0, /* (196) groupby_opt ::= */ - -3, /* (197) groupby_opt ::= GROUP BY grouplist */ - -3, /* (198) grouplist ::= grouplist COMMA item */ - -1, /* (199) grouplist ::= item */ - 0, /* (200) having_opt ::= */ - -2, /* (201) having_opt ::= HAVING expr */ - 0, /* (202) limit_opt ::= */ - -2, /* (203) limit_opt ::= LIMIT signed */ - -4, /* (204) limit_opt ::= LIMIT signed OFFSET signed */ - -4, /* (205) limit_opt ::= LIMIT signed COMMA signed */ - 0, /* (206) slimit_opt ::= */ - -2, /* (207) slimit_opt ::= SLIMIT signed */ - -4, /* (208) slimit_opt ::= SLIMIT signed SOFFSET signed */ - -4, /* (209) slimit_opt ::= SLIMIT signed COMMA signed */ - 0, /* (210) where_opt ::= */ - -2, /* (211) where_opt ::= WHERE expr */ - -3, /* (212) expr ::= LP expr RP */ - -1, /* (213) expr ::= ID */ - -3, /* (214) expr ::= ID DOT ID */ - -3, /* (215) expr ::= ID DOT STAR */ - -1, /* (216) expr ::= INTEGER */ - -2, /* (217) expr ::= MINUS INTEGER */ - -2, /* (218) expr ::= PLUS INTEGER */ - -1, /* (219) expr ::= FLOAT */ - -2, /* (220) expr ::= MINUS FLOAT */ - -2, /* (221) expr ::= PLUS FLOAT */ - -1, /* (222) expr ::= STRING */ - -1, /* (223) expr ::= NOW */ - -1, /* (224) expr ::= VARIABLE */ - -2, /* (225) expr ::= PLUS VARIABLE */ - -2, /* (226) expr ::= MINUS VARIABLE */ - -1, /* (227) expr ::= BOOL */ - -1, /* (228) expr ::= NULL */ - -4, /* (229) expr ::= ID LP exprlist RP */ - -4, /* (230) expr ::= ID LP STAR RP */ - -3, /* (231) expr ::= expr IS NULL */ - -4, /* (232) expr ::= expr IS NOT NULL */ - -3, /* (233) expr ::= expr LT expr */ - -3, /* (234) expr ::= expr GT expr */ - -3, /* (235) expr ::= expr LE expr */ - -3, /* (236) expr ::= expr GE expr */ - -3, /* (237) expr ::= expr NE expr */ - -3, /* (238) expr ::= expr EQ expr */ - -5, /* (239) expr ::= expr BETWEEN expr AND expr */ - -3, /* (240) expr ::= expr AND expr */ - -3, /* (241) expr ::= expr OR expr */ - -3, /* (242) expr ::= expr PLUS expr */ - -3, /* (243) expr ::= expr MINUS expr */ - -3, /* (244) expr ::= expr STAR expr */ - -3, /* (245) expr ::= expr SLASH expr */ - -3, /* (246) expr ::= expr REM expr */ - -3, /* (247) expr ::= expr LIKE expr */ - -5, /* (248) expr ::= expr IN LP exprlist RP */ - -3, /* (249) exprlist ::= exprlist COMMA expritem */ - -1, /* (250) exprlist ::= expritem */ - -1, /* (251) expritem ::= expr */ - 0, /* (252) expritem ::= */ - -3, /* (253) cmd ::= RESET QUERY CACHE */ - -3, /* (254) cmd ::= SYNCDB ids REPLICA */ - -7, /* (255) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (256) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - -7, /* (257) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - -7, /* (258) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - -8, /* (259) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - -9, /* (260) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - -7, /* (261) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (262) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - -7, /* (263) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - -7, /* (264) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - -8, /* (265) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - -3, /* (266) cmd ::= KILL CONNECTION INTEGER */ - -5, /* (267) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - -5, /* (268) cmd ::= KILL QUERY INTEGER COLON INTEGER */ +/* The following table contains information about every rule that +** is used during the reduce. +*/ +static const struct { + YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ + signed char nrhs; /* Negative of the number of RHS symbols in the rule */ +} 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, -4 }, /* (21) cmd ::= SHOW CREATE DATABASE ids */ + { 189, -3 }, /* (22) cmd ::= SHOW dbPrefix TABLES */ + { 189, -5 }, /* (23) cmd ::= SHOW dbPrefix TABLES LIKE ids */ + { 189, -3 }, /* (24) cmd ::= SHOW dbPrefix STABLES */ + { 189, -5 }, /* (25) cmd ::= SHOW dbPrefix STABLES LIKE ids */ + { 189, -3 }, /* (26) cmd ::= SHOW dbPrefix VGROUPS */ + { 189, -4 }, /* (27) cmd ::= SHOW dbPrefix VGROUPS ids */ + { 189, -5 }, /* (28) cmd ::= DROP TABLE ifexists ids cpxName */ + { 189, -5 }, /* (29) cmd ::= DROP STABLE ifexists ids cpxName */ + { 189, -4 }, /* (30) cmd ::= DROP DATABASE ifexists ids */ + { 189, -4 }, /* (31) cmd ::= DROP TOPIC ifexists ids */ + { 189, -3 }, /* (32) cmd ::= DROP DNODE ids */ + { 189, -3 }, /* (33) cmd ::= DROP USER ids */ + { 189, -3 }, /* (34) cmd ::= DROP ACCOUNT ids */ + { 189, -2 }, /* (35) cmd ::= USE ids */ + { 189, -3 }, /* (36) cmd ::= DESCRIBE ids cpxName */ + { 189, -5 }, /* (37) cmd ::= ALTER USER ids PASS ids */ + { 189, -5 }, /* (38) cmd ::= ALTER USER ids PRIVILEGE ids */ + { 189, -4 }, /* (39) cmd ::= ALTER DNODE ids ids */ + { 189, -5 }, /* (40) cmd ::= ALTER DNODE ids ids ids */ + { 189, -3 }, /* (41) cmd ::= ALTER LOCAL ids */ + { 189, -4 }, /* (42) cmd ::= ALTER LOCAL ids ids */ + { 189, -4 }, /* (43) cmd ::= ALTER DATABASE ids alter_db_optr */ + { 189, -4 }, /* (44) cmd ::= ALTER TOPIC ids alter_topic_optr */ + { 189, -4 }, /* (45) cmd ::= ALTER ACCOUNT ids acct_optr */ + { 189, -6 }, /* (46) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ + { 191, -1 }, /* (47) ids ::= ID */ + { 191, -1 }, /* (48) ids ::= STRING */ + { 193, -2 }, /* (49) ifexists ::= IF EXISTS */ + { 193, 0 }, /* (50) ifexists ::= */ + { 197, -3 }, /* (51) ifnotexists ::= IF NOT EXISTS */ + { 197, 0 }, /* (52) ifnotexists ::= */ + { 189, -3 }, /* (53) cmd ::= CREATE DNODE ids */ + { 189, -6 }, /* (54) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ + { 189, -5 }, /* (55) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ + { 189, -5 }, /* (56) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ + { 189, -5 }, /* (57) cmd ::= CREATE USER ids PASS ids */ + { 200, 0 }, /* (58) pps ::= */ + { 200, -2 }, /* (59) pps ::= PPS INTEGER */ + { 201, 0 }, /* (60) tseries ::= */ + { 201, -2 }, /* (61) tseries ::= TSERIES INTEGER */ + { 202, 0 }, /* (62) dbs ::= */ + { 202, -2 }, /* (63) dbs ::= DBS INTEGER */ + { 203, 0 }, /* (64) streams ::= */ + { 203, -2 }, /* (65) streams ::= STREAMS INTEGER */ + { 204, 0 }, /* (66) storage ::= */ + { 204, -2 }, /* (67) storage ::= STORAGE INTEGER */ + { 205, 0 }, /* (68) qtime ::= */ + { 205, -2 }, /* (69) qtime ::= QTIME INTEGER */ + { 206, 0 }, /* (70) users ::= */ + { 206, -2 }, /* (71) users ::= USERS INTEGER */ + { 207, 0 }, /* (72) conns ::= */ + { 207, -2 }, /* (73) conns ::= CONNS INTEGER */ + { 208, 0 }, /* (74) state ::= */ + { 208, -2 }, /* (75) state ::= STATE ids */ + { 196, -9 }, /* (76) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ + { 209, -2 }, /* (77) keep ::= KEEP tagitemlist */ + { 211, -2 }, /* (78) cache ::= CACHE INTEGER */ + { 212, -2 }, /* (79) replica ::= REPLICA INTEGER */ + { 213, -2 }, /* (80) quorum ::= QUORUM INTEGER */ + { 214, -2 }, /* (81) days ::= DAYS INTEGER */ + { 215, -2 }, /* (82) minrows ::= MINROWS INTEGER */ + { 216, -2 }, /* (83) maxrows ::= MAXROWS INTEGER */ + { 217, -2 }, /* (84) blocks ::= BLOCKS INTEGER */ + { 218, -2 }, /* (85) ctime ::= CTIME INTEGER */ + { 219, -2 }, /* (86) wal ::= WAL INTEGER */ + { 220, -2 }, /* (87) fsync ::= FSYNC INTEGER */ + { 221, -2 }, /* (88) comp ::= COMP INTEGER */ + { 222, -2 }, /* (89) prec ::= PRECISION STRING */ + { 223, -2 }, /* (90) update ::= UPDATE INTEGER */ + { 224, -2 }, /* (91) cachelast ::= CACHELAST INTEGER */ + { 225, -2 }, /* (92) partitions ::= PARTITIONS INTEGER */ + { 198, 0 }, /* (93) db_optr ::= */ + { 198, -2 }, /* (94) db_optr ::= db_optr cache */ + { 198, -2 }, /* (95) db_optr ::= db_optr replica */ + { 198, -2 }, /* (96) db_optr ::= db_optr quorum */ + { 198, -2 }, /* (97) db_optr ::= db_optr days */ + { 198, -2 }, /* (98) db_optr ::= db_optr minrows */ + { 198, -2 }, /* (99) db_optr ::= db_optr maxrows */ + { 198, -2 }, /* (100) db_optr ::= db_optr blocks */ + { 198, -2 }, /* (101) db_optr ::= db_optr ctime */ + { 198, -2 }, /* (102) db_optr ::= db_optr wal */ + { 198, -2 }, /* (103) db_optr ::= db_optr fsync */ + { 198, -2 }, /* (104) db_optr ::= db_optr comp */ + { 198, -2 }, /* (105) db_optr ::= db_optr prec */ + { 198, -2 }, /* (106) db_optr ::= db_optr keep */ + { 198, -2 }, /* (107) db_optr ::= db_optr update */ + { 198, -2 }, /* (108) db_optr ::= db_optr cachelast */ + { 199, -1 }, /* (109) topic_optr ::= db_optr */ + { 199, -2 }, /* (110) topic_optr ::= topic_optr partitions */ + { 194, 0 }, /* (111) alter_db_optr ::= */ + { 194, -2 }, /* (112) alter_db_optr ::= alter_db_optr replica */ + { 194, -2 }, /* (113) alter_db_optr ::= alter_db_optr quorum */ + { 194, -2 }, /* (114) alter_db_optr ::= alter_db_optr keep */ + { 194, -2 }, /* (115) alter_db_optr ::= alter_db_optr blocks */ + { 194, -2 }, /* (116) alter_db_optr ::= alter_db_optr comp */ + { 194, -2 }, /* (117) alter_db_optr ::= alter_db_optr wal */ + { 194, -2 }, /* (118) alter_db_optr ::= alter_db_optr fsync */ + { 194, -2 }, /* (119) alter_db_optr ::= alter_db_optr update */ + { 194, -2 }, /* (120) alter_db_optr ::= alter_db_optr cachelast */ + { 195, -1 }, /* (121) alter_topic_optr ::= alter_db_optr */ + { 195, -2 }, /* (122) alter_topic_optr ::= alter_topic_optr partitions */ + { 226, -1 }, /* (123) typename ::= ids */ + { 226, -4 }, /* (124) typename ::= ids LP signed RP */ + { 226, -2 }, /* (125) typename ::= ids UNSIGNED */ + { 227, -1 }, /* (126) signed ::= INTEGER */ + { 227, -2 }, /* (127) signed ::= PLUS INTEGER */ + { 227, -2 }, /* (128) signed ::= MINUS INTEGER */ + { 189, -3 }, /* (129) cmd ::= CREATE TABLE create_table_args */ + { 189, -3 }, /* (130) cmd ::= CREATE TABLE create_stable_args */ + { 189, -3 }, /* (131) cmd ::= CREATE STABLE create_stable_args */ + { 189, -3 }, /* (132) cmd ::= CREATE TABLE create_table_list */ + { 230, -1 }, /* (133) create_table_list ::= create_from_stable */ + { 230, -2 }, /* (134) create_table_list ::= create_table_list create_from_stable */ + { 228, -6 }, /* (135) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ + { 229, -10 }, /* (136) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ + { 231, -10 }, /* (137) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ + { 231, -13 }, /* (138) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ + { 233, -3 }, /* (139) tagNamelist ::= tagNamelist COMMA ids */ + { 233, -1 }, /* (140) tagNamelist ::= ids */ + { 228, -5 }, /* (141) create_table_args ::= ifnotexists ids cpxName AS select */ + { 232, -3 }, /* (142) columnlist ::= columnlist COMMA column */ + { 232, -1 }, /* (143) columnlist ::= column */ + { 235, -2 }, /* (144) column ::= ids typename */ + { 210, -3 }, /* (145) tagitemlist ::= tagitemlist COMMA tagitem */ + { 210, -1 }, /* (146) tagitemlist ::= tagitem */ + { 236, -1 }, /* (147) tagitem ::= INTEGER */ + { 236, -1 }, /* (148) tagitem ::= FLOAT */ + { 236, -1 }, /* (149) tagitem ::= STRING */ + { 236, -1 }, /* (150) tagitem ::= BOOL */ + { 236, -1 }, /* (151) tagitem ::= NULL */ + { 236, -2 }, /* (152) tagitem ::= MINUS INTEGER */ + { 236, -2 }, /* (153) tagitem ::= MINUS FLOAT */ + { 236, -2 }, /* (154) tagitem ::= PLUS INTEGER */ + { 236, -2 }, /* (155) tagitem ::= PLUS FLOAT */ + { 234, -13 }, /* (156) 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 }, /* (157) select ::= LP select RP */ + { 249, -1 }, /* (158) union ::= select */ + { 249, -4 }, /* (159) union ::= union UNION ALL select */ + { 189, -1 }, /* (160) cmd ::= union */ + { 234, -2 }, /* (161) select ::= SELECT selcollist */ + { 250, -2 }, /* (162) sclp ::= selcollist COMMA */ + { 250, 0 }, /* (163) sclp ::= */ + { 237, -4 }, /* (164) selcollist ::= sclp distinct expr as */ + { 237, -2 }, /* (165) selcollist ::= sclp STAR */ + { 253, -2 }, /* (166) as ::= AS ids */ + { 253, -1 }, /* (167) as ::= ids */ + { 253, 0 }, /* (168) as ::= */ + { 251, -1 }, /* (169) distinct ::= DISTINCT */ + { 251, 0 }, /* (170) distinct ::= */ + { 238, -2 }, /* (171) from ::= FROM tablelist */ + { 238, -4 }, /* (172) from ::= FROM LP union RP */ + { 254, -2 }, /* (173) tablelist ::= ids cpxName */ + { 254, -3 }, /* (174) tablelist ::= ids cpxName ids */ + { 254, -4 }, /* (175) tablelist ::= tablelist COMMA ids cpxName */ + { 254, -5 }, /* (176) tablelist ::= tablelist COMMA ids cpxName ids */ + { 255, -1 }, /* (177) tmvar ::= VARIABLE */ + { 240, -4 }, /* (178) interval_opt ::= INTERVAL LP tmvar RP */ + { 240, -6 }, /* (179) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ + { 240, 0 }, /* (180) interval_opt ::= */ + { 241, 0 }, /* (181) session_option ::= */ + { 241, -7 }, /* (182) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ + { 242, 0 }, /* (183) fill_opt ::= */ + { 242, -6 }, /* (184) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ + { 242, -4 }, /* (185) fill_opt ::= FILL LP ID RP */ + { 243, -4 }, /* (186) sliding_opt ::= SLIDING LP tmvar RP */ + { 243, 0 }, /* (187) sliding_opt ::= */ + { 245, 0 }, /* (188) orderby_opt ::= */ + { 245, -3 }, /* (189) orderby_opt ::= ORDER BY sortlist */ + { 256, -4 }, /* (190) sortlist ::= sortlist COMMA item sortorder */ + { 256, -2 }, /* (191) sortlist ::= item sortorder */ + { 258, -2 }, /* (192) item ::= ids cpxName */ + { 259, -1 }, /* (193) sortorder ::= ASC */ + { 259, -1 }, /* (194) sortorder ::= DESC */ + { 259, 0 }, /* (195) sortorder ::= */ + { 244, 0 }, /* (196) groupby_opt ::= */ + { 244, -3 }, /* (197) groupby_opt ::= GROUP BY grouplist */ + { 260, -3 }, /* (198) grouplist ::= grouplist COMMA item */ + { 260, -1 }, /* (199) grouplist ::= item */ + { 246, 0 }, /* (200) having_opt ::= */ + { 246, -2 }, /* (201) having_opt ::= HAVING expr */ + { 248, 0 }, /* (202) limit_opt ::= */ + { 248, -2 }, /* (203) limit_opt ::= LIMIT signed */ + { 248, -4 }, /* (204) limit_opt ::= LIMIT signed OFFSET signed */ + { 248, -4 }, /* (205) limit_opt ::= LIMIT signed COMMA signed */ + { 247, 0 }, /* (206) slimit_opt ::= */ + { 247, -2 }, /* (207) slimit_opt ::= SLIMIT signed */ + { 247, -4 }, /* (208) slimit_opt ::= SLIMIT signed SOFFSET signed */ + { 247, -4 }, /* (209) slimit_opt ::= SLIMIT signed COMMA signed */ + { 239, 0 }, /* (210) where_opt ::= */ + { 239, -2 }, /* (211) where_opt ::= WHERE expr */ + { 252, -3 }, /* (212) expr ::= LP expr RP */ + { 252, -1 }, /* (213) expr ::= ID */ + { 252, -3 }, /* (214) expr ::= ID DOT ID */ + { 252, -3 }, /* (215) expr ::= ID DOT STAR */ + { 252, -1 }, /* (216) expr ::= INTEGER */ + { 252, -2 }, /* (217) expr ::= MINUS INTEGER */ + { 252, -2 }, /* (218) expr ::= PLUS INTEGER */ + { 252, -1 }, /* (219) expr ::= FLOAT */ + { 252, -2 }, /* (220) expr ::= MINUS FLOAT */ + { 252, -2 }, /* (221) expr ::= PLUS FLOAT */ + { 252, -1 }, /* (222) expr ::= STRING */ + { 252, -1 }, /* (223) expr ::= NOW */ + { 252, -1 }, /* (224) expr ::= VARIABLE */ + { 252, -2 }, /* (225) expr ::= PLUS VARIABLE */ + { 252, -2 }, /* (226) expr ::= MINUS VARIABLE */ + { 252, -1 }, /* (227) expr ::= BOOL */ + { 252, -1 }, /* (228) expr ::= NULL */ + { 252, -4 }, /* (229) expr ::= ID LP exprlist RP */ + { 252, -4 }, /* (230) expr ::= ID LP STAR RP */ + { 252, -3 }, /* (231) expr ::= expr IS NULL */ + { 252, -4 }, /* (232) expr ::= expr IS NOT NULL */ + { 252, -3 }, /* (233) expr ::= expr LT expr */ + { 252, -3 }, /* (234) expr ::= expr GT expr */ + { 252, -3 }, /* (235) expr ::= expr LE expr */ + { 252, -3 }, /* (236) expr ::= expr GE expr */ + { 252, -3 }, /* (237) expr ::= expr NE expr */ + { 252, -3 }, /* (238) expr ::= expr EQ expr */ + { 252, -5 }, /* (239) expr ::= expr BETWEEN expr AND expr */ + { 252, -3 }, /* (240) expr ::= expr AND expr */ + { 252, -3 }, /* (241) expr ::= expr OR expr */ + { 252, -3 }, /* (242) expr ::= expr PLUS expr */ + { 252, -3 }, /* (243) expr ::= expr MINUS expr */ + { 252, -3 }, /* (244) expr ::= expr STAR expr */ + { 252, -3 }, /* (245) expr ::= expr SLASH expr */ + { 252, -3 }, /* (246) expr ::= expr REM expr */ + { 252, -3 }, /* (247) expr ::= expr LIKE expr */ + { 252, -5 }, /* (248) expr ::= expr IN LP exprlist RP */ + { 261, -3 }, /* (249) exprlist ::= exprlist COMMA expritem */ + { 261, -1 }, /* (250) exprlist ::= expritem */ + { 262, -1 }, /* (251) expritem ::= expr */ + { 262, 0 }, /* (252) expritem ::= */ + { 189, -3 }, /* (253) cmd ::= RESET QUERY CACHE */ + { 189, -3 }, /* (254) cmd ::= SYNCDB ids REPLICA */ + { 189, -7 }, /* (255) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + { 189, -7 }, /* (256) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + { 189, -7 }, /* (257) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + { 189, -7 }, /* (258) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + { 189, -8 }, /* (259) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + { 189, -9 }, /* (260) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + { 189, -7 }, /* (261) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + { 189, -7 }, /* (262) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + { 189, -7 }, /* (263) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + { 189, -7 }, /* (264) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + { 189, -8 }, /* (265) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + { 189, -3 }, /* (266) cmd ::= KILL CONNECTION INTEGER */ + { 189, -5 }, /* (267) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + { 189, -5 }, /* (268) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -2314,34 +2036,30 @@ static void yy_accept(yyParser*); /* Forward Declaration */ ** only called from one place, optimizing compilers will in-line it, which ** means that the extra parameters have no performance impact. */ -static YYACTIONTYPE yy_reduce( +static void yy_reduce( yyParser *yypParser, /* The parser */ unsigned int yyruleno, /* Number of the rule by which to reduce */ int yyLookahead, /* Lookahead token, or YYNOCODE if none */ ParseTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ - ParseCTX_PDECL /* %extra_context */ ){ int yygoto; /* The next state */ - YYACTIONTYPE yyact; /* The next action */ + int yyact; /* The next action */ yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ - ParseARG_FETCH + ParseARG_FETCH; (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; #ifndef NDEBUG if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfoNRhs[yyruleno]; + yysize = yyRuleInfo[yyruleno].nrhs; if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ yypParser->yyhwm++; @@ -2359,19 +2077,13 @@ static YYACTIONTYPE yy_reduce( #if YYSTACKDEPTH>0 if( yypParser->yytos>=yypParser->yystackEnd ){ yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; + return; } #else if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; + return; } yymsp = yypParser->yytos; } @@ -2556,13 +2268,13 @@ static YYACTIONTYPE yy_reduce( break; case 43: /* cmd ::= ALTER DATABASE ids alter_db_optr */ case 44: /* cmd ::= ALTER TOPIC ids alter_topic_optr */ yytestcase(yyruleno==44); -{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy94, &t);} +{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy322, &t);} break; case 45: /* cmd ::= ALTER ACCOUNT ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy419);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy351);} break; case 46: /* 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.yy419);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy351);} break; case 47: /* ids ::= ID */ case 48: /* ids ::= STRING */ yytestcase(yyruleno==48); @@ -2584,11 +2296,11 @@ static YYACTIONTYPE yy_reduce( { setDCLSqlElems(pInfo, TSDB_SQL_CREATE_DNODE, 1, &yymsp[0].minor.yy0);} break; case 54: /* 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.yy419);} +{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy351);} break; case 55: /* cmd ::= CREATE DATABASE ifnotexists ids db_optr */ case 56: /* cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ yytestcase(yyruleno==56); -{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy94, &yymsp[-2].minor.yy0);} +{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy322, &yymsp[-2].minor.yy0);} break; case 57: /* cmd ::= CREATE USER ids PASS ids */ { setCreateUserSql(pInfo, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);} @@ -2617,20 +2329,20 @@ static YYACTIONTYPE yy_reduce( break; case 76: /* acct_optr ::= pps tseries storage streams qtime dbs users conns state */ { - yylhsminor.yy419.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; - yylhsminor.yy419.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; - yylhsminor.yy419.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; - yylhsminor.yy419.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; - yylhsminor.yy419.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; - yylhsminor.yy419.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy419.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy419.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; - yylhsminor.yy419.stat = yymsp[0].minor.yy0; + 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.yy419 = yylhsminor.yy419; + yymsp[-8].minor.yy351 = yylhsminor.yy351; break; case 77: /* keep ::= KEEP tagitemlist */ -{ yymsp[-1].minor.yy429 = yymsp[0].minor.yy429; } +{ yymsp[-1].minor.yy159 = yymsp[0].minor.yy159; } break; case 78: /* cache ::= CACHE INTEGER */ case 79: /* replica ::= REPLICA INTEGER */ yytestcase(yyruleno==79); @@ -2650,234 +2362,234 @@ static YYACTIONTYPE yy_reduce( { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } break; case 93: /* db_optr ::= */ -{setDefaultCreateDbOption(&yymsp[1].minor.yy94); yymsp[1].minor.yy94.dbType = TSDB_DB_TYPE_DEFAULT;} +{setDefaultCreateDbOption(&yymsp[1].minor.yy322); yymsp[1].minor.yy322.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 94: /* db_optr ::= db_optr cache */ -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 95: /* db_optr ::= db_optr replica */ case 112: /* alter_db_optr ::= alter_db_optr replica */ yytestcase(yyruleno==112); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 96: /* db_optr ::= db_optr quorum */ case 113: /* alter_db_optr ::= alter_db_optr quorum */ yytestcase(yyruleno==113); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 97: /* db_optr ::= db_optr days */ -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 98: /* db_optr ::= db_optr minrows */ -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 99: /* db_optr ::= db_optr maxrows */ -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 100: /* db_optr ::= db_optr blocks */ case 115: /* alter_db_optr ::= alter_db_optr blocks */ yytestcase(yyruleno==115); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 101: /* db_optr ::= db_optr ctime */ -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 102: /* db_optr ::= db_optr wal */ case 117: /* alter_db_optr ::= alter_db_optr wal */ yytestcase(yyruleno==117); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 103: /* db_optr ::= db_optr fsync */ case 118: /* alter_db_optr ::= alter_db_optr fsync */ yytestcase(yyruleno==118); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 104: /* db_optr ::= db_optr comp */ case 116: /* alter_db_optr ::= alter_db_optr comp */ yytestcase(yyruleno==116); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 105: /* db_optr ::= db_optr prec */ -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.precision = yymsp[0].minor.yy0; } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.precision = yymsp[0].minor.yy0; } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 106: /* db_optr ::= db_optr keep */ case 114: /* alter_db_optr ::= alter_db_optr keep */ yytestcase(yyruleno==114); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.keep = yymsp[0].minor.yy429; } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.keep = yymsp[0].minor.yy159; } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 107: /* db_optr ::= db_optr update */ case 119: /* alter_db_optr ::= alter_db_optr update */ yytestcase(yyruleno==119); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 108: /* db_optr ::= db_optr cachelast */ case 120: /* alter_db_optr ::= alter_db_optr cachelast */ yytestcase(yyruleno==120); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 109: /* topic_optr ::= db_optr */ case 121: /* alter_topic_optr ::= alter_db_optr */ yytestcase(yyruleno==121); -{ yylhsminor.yy94 = yymsp[0].minor.yy94; yylhsminor.yy94.dbType = TSDB_DB_TYPE_TOPIC; } - yymsp[0].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[0].minor.yy322; yylhsminor.yy322.dbType = TSDB_DB_TYPE_TOPIC; } + yymsp[0].minor.yy322 = yylhsminor.yy322; break; case 110: /* topic_optr ::= topic_optr partitions */ case 122: /* alter_topic_optr ::= alter_topic_optr partitions */ yytestcase(yyruleno==122); -{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy94 = yylhsminor.yy94; +{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy322 = yylhsminor.yy322; break; case 111: /* alter_db_optr ::= */ -{ setDefaultCreateDbOption(&yymsp[1].minor.yy94); yymsp[1].minor.yy94.dbType = TSDB_DB_TYPE_DEFAULT;} +{ setDefaultCreateDbOption(&yymsp[1].minor.yy322); yymsp[1].minor.yy322.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 123: /* typename ::= ids */ { yymsp[0].minor.yy0.type = 0; - tSetColumnType (&yylhsminor.yy451, &yymsp[0].minor.yy0); + tSetColumnType (&yylhsminor.yy407, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy451 = yylhsminor.yy451; + yymsp[0].minor.yy407 = yylhsminor.yy407; break; case 124: /* typename ::= ids LP signed RP */ { - if (yymsp[-1].minor.yy481 <= 0) { + if (yymsp[-1].minor.yy317 <= 0) { yymsp[-3].minor.yy0.type = 0; - tSetColumnType(&yylhsminor.yy451, &yymsp[-3].minor.yy0); + tSetColumnType(&yylhsminor.yy407, &yymsp[-3].minor.yy0); } else { - yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy481; // negative value of name length - tSetColumnType(&yylhsminor.yy451, &yymsp[-3].minor.yy0); + yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy317; // negative value of name length + tSetColumnType(&yylhsminor.yy407, &yymsp[-3].minor.yy0); } } - yymsp[-3].minor.yy451 = yylhsminor.yy451; + yymsp[-3].minor.yy407 = yylhsminor.yy407; break; case 125: /* 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.yy451, &yymsp[-1].minor.yy0); + tSetColumnType (&yylhsminor.yy407, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy451 = yylhsminor.yy451; + yymsp[-1].minor.yy407 = yylhsminor.yy407; break; case 126: /* signed ::= INTEGER */ -{ yylhsminor.yy481 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[0].minor.yy481 = yylhsminor.yy481; +{ yylhsminor.yy317 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[0].minor.yy317 = yylhsminor.yy317; break; case 127: /* signed ::= PLUS INTEGER */ -{ yymsp[-1].minor.yy481 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +{ yymsp[-1].minor.yy317 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 128: /* signed ::= MINUS INTEGER */ -{ yymsp[-1].minor.yy481 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} +{ yymsp[-1].minor.yy317 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} break; case 132: /* cmd ::= CREATE TABLE create_table_list */ -{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy194;} +{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy14;} break; case 133: /* create_table_list ::= create_from_stable */ { SCreateTableSql* pCreateTable = calloc(1, sizeof(SCreateTableSql)); pCreateTable->childTableInfo = taosArrayInit(4, sizeof(SCreatedTableInfo)); - taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy252); + taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy206); pCreateTable->type = TSQL_CREATE_TABLE_FROM_STABLE; - yylhsminor.yy194 = pCreateTable; + yylhsminor.yy14 = pCreateTable; } - yymsp[0].minor.yy194 = yylhsminor.yy194; + yymsp[0].minor.yy14 = yylhsminor.yy14; break; case 134: /* create_table_list ::= create_table_list create_from_stable */ { - taosArrayPush(yymsp[-1].minor.yy194->childTableInfo, &yymsp[0].minor.yy252); - yylhsminor.yy194 = yymsp[-1].minor.yy194; + taosArrayPush(yymsp[-1].minor.yy14->childTableInfo, &yymsp[0].minor.yy206); + yylhsminor.yy14 = yymsp[-1].minor.yy14; } - yymsp[-1].minor.yy194 = yylhsminor.yy194; + yymsp[-1].minor.yy14 = yylhsminor.yy14; break; case 135: /* create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ { - yylhsminor.yy194 = tSetCreateTableInfo(yymsp[-1].minor.yy429, NULL, NULL, TSQL_CREATE_TABLE); - setSqlInfo(pInfo, yylhsminor.yy194, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy14 = tSetCreateTableInfo(yymsp[-1].minor.yy159, NULL, NULL, TSQL_CREATE_TABLE); + setSqlInfo(pInfo, yylhsminor.yy14, 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.yy194 = yylhsminor.yy194; + yymsp[-5].minor.yy14 = yylhsminor.yy14; break; case 136: /* create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ { - yylhsminor.yy194 = tSetCreateTableInfo(yymsp[-5].minor.yy429, yymsp[-1].minor.yy429, NULL, TSQL_CREATE_STABLE); - setSqlInfo(pInfo, yylhsminor.yy194, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy14 = tSetCreateTableInfo(yymsp[-5].minor.yy159, yymsp[-1].minor.yy159, NULL, TSQL_CREATE_STABLE); + setSqlInfo(pInfo, yylhsminor.yy14, 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.yy194 = yylhsminor.yy194; + yymsp[-9].minor.yy14 = yylhsminor.yy14; break; case 137: /* 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.yy252 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy429, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); + yylhsminor.yy206 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy159, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy252 = yylhsminor.yy252; + yymsp[-9].minor.yy206 = yylhsminor.yy206; break; case 138: /* 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.yy252 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy429, yymsp[-1].minor.yy429, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); + yylhsminor.yy206 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy159, yymsp[-1].minor.yy159, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); } - yymsp[-12].minor.yy252 = yylhsminor.yy252; + yymsp[-12].minor.yy206 = yylhsminor.yy206; break; case 139: /* tagNamelist ::= tagNamelist COMMA ids */ -{taosArrayPush(yymsp[-2].minor.yy429, &yymsp[0].minor.yy0); yylhsminor.yy429 = yymsp[-2].minor.yy429; } - yymsp[-2].minor.yy429 = yylhsminor.yy429; +{taosArrayPush(yymsp[-2].minor.yy159, &yymsp[0].minor.yy0); yylhsminor.yy159 = yymsp[-2].minor.yy159; } + yymsp[-2].minor.yy159 = yylhsminor.yy159; break; case 140: /* tagNamelist ::= ids */ -{yylhsminor.yy429 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy429, &yymsp[0].minor.yy0);} - yymsp[0].minor.yy429 = yylhsminor.yy429; +{yylhsminor.yy159 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy159, &yymsp[0].minor.yy0);} + yymsp[0].minor.yy159 = yylhsminor.yy159; break; case 141: /* create_table_args ::= ifnotexists ids cpxName AS select */ { - yylhsminor.yy194 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy254, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, yylhsminor.yy194, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy14 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy116, TSQL_CREATE_STREAM); + setSqlInfo(pInfo, yylhsminor.yy14, 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.yy194 = yylhsminor.yy194; + yymsp[-4].minor.yy14 = yylhsminor.yy14; break; case 142: /* columnlist ::= columnlist COMMA column */ -{taosArrayPush(yymsp[-2].minor.yy429, &yymsp[0].minor.yy451); yylhsminor.yy429 = yymsp[-2].minor.yy429; } - yymsp[-2].minor.yy429 = yylhsminor.yy429; +{taosArrayPush(yymsp[-2].minor.yy159, &yymsp[0].minor.yy407); yylhsminor.yy159 = yymsp[-2].minor.yy159; } + yymsp[-2].minor.yy159 = yylhsminor.yy159; break; case 143: /* columnlist ::= column */ -{yylhsminor.yy429 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy429, &yymsp[0].minor.yy451);} - yymsp[0].minor.yy429 = yylhsminor.yy429; +{yylhsminor.yy159 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy159, &yymsp[0].minor.yy407);} + yymsp[0].minor.yy159 = yylhsminor.yy159; break; case 144: /* column ::= ids typename */ { - tSetColumnInfo(&yylhsminor.yy451, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy451); + tSetColumnInfo(&yylhsminor.yy407, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy407); } - yymsp[-1].minor.yy451 = yylhsminor.yy451; + yymsp[-1].minor.yy407 = yylhsminor.yy407; break; case 145: /* tagitemlist ::= tagitemlist COMMA tagitem */ -{ yylhsminor.yy429 = tVariantListAppend(yymsp[-2].minor.yy429, &yymsp[0].minor.yy218, -1); } - yymsp[-2].minor.yy429 = yylhsminor.yy429; +{ yylhsminor.yy159 = tVariantListAppend(yymsp[-2].minor.yy159, &yymsp[0].minor.yy488, -1); } + yymsp[-2].minor.yy159 = yylhsminor.yy159; break; case 146: /* tagitemlist ::= tagitem */ -{ yylhsminor.yy429 = tVariantListAppend(NULL, &yymsp[0].minor.yy218, -1); } - yymsp[0].minor.yy429 = yylhsminor.yy429; +{ yylhsminor.yy159 = tVariantListAppend(NULL, &yymsp[0].minor.yy488, -1); } + yymsp[0].minor.yy159 = yylhsminor.yy159; break; case 147: /* tagitem ::= INTEGER */ case 148: /* tagitem ::= FLOAT */ yytestcase(yyruleno==148); case 149: /* tagitem ::= STRING */ yytestcase(yyruleno==149); case 150: /* tagitem ::= BOOL */ yytestcase(yyruleno==150); -{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy218, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy218 = yylhsminor.yy218; +{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy488, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy488 = yylhsminor.yy488; break; case 151: /* tagitem ::= NULL */ -{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy218, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy218 = yylhsminor.yy218; +{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy488, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy488 = yylhsminor.yy488; break; case 152: /* tagitem ::= MINUS INTEGER */ case 153: /* tagitem ::= MINUS FLOAT */ yytestcase(yyruleno==153); @@ -2887,56 +2599,56 @@ static YYACTIONTYPE 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.yy218, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy488, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy218 = yylhsminor.yy218; + yymsp[-1].minor.yy488 = yylhsminor.yy488; break; case 156: /* select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ { - yylhsminor.yy254 = tSetQuerySqlNode(&yymsp[-12].minor.yy0, yymsp[-11].minor.yy429, yymsp[-10].minor.yy70, yymsp[-9].minor.yy170, yymsp[-4].minor.yy429, yymsp[-3].minor.yy429, &yymsp[-8].minor.yy220, &yymsp[-7].minor.yy87, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy429, &yymsp[0].minor.yy18, &yymsp[-1].minor.yy18, yymsp[-2].minor.yy170); + 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); } - yymsp[-12].minor.yy254 = yylhsminor.yy254; + yymsp[-12].minor.yy116 = yylhsminor.yy116; break; case 157: /* select ::= LP select RP */ -{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} +{yymsp[-2].minor.yy116 = yymsp[-1].minor.yy116;} break; case 158: /* union ::= select */ -{ yylhsminor.yy141 = setSubclause(NULL, yymsp[0].minor.yy254); } - yymsp[0].minor.yy141 = yylhsminor.yy141; +{ yylhsminor.yy159 = setSubclause(NULL, yymsp[0].minor.yy116); } + yymsp[0].minor.yy159 = yylhsminor.yy159; break; case 159: /* union ::= union UNION ALL select */ -{ yylhsminor.yy141 = appendSelectClause(yymsp[-3].minor.yy141, yymsp[0].minor.yy254); } - yymsp[-3].minor.yy141 = yylhsminor.yy141; +{ yylhsminor.yy159 = appendSelectClause(yymsp[-3].minor.yy159, yymsp[0].minor.yy116); } + yymsp[-3].minor.yy159 = yylhsminor.yy159; break; case 160: /* cmd ::= union */ -{ setSqlInfo(pInfo, yymsp[0].minor.yy141, NULL, TSDB_SQL_SELECT); } +{ setSqlInfo(pInfo, yymsp[0].minor.yy159, NULL, TSDB_SQL_SELECT); } break; case 161: /* select ::= SELECT selcollist */ { - yylhsminor.yy254 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy429, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + yylhsminor.yy116 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy159, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } - yymsp[-1].minor.yy254 = yylhsminor.yy254; + yymsp[-1].minor.yy116 = yylhsminor.yy116; break; case 162: /* sclp ::= selcollist COMMA */ -{yylhsminor.yy429 = yymsp[-1].minor.yy429;} - yymsp[-1].minor.yy429 = yylhsminor.yy429; +{yylhsminor.yy159 = yymsp[-1].minor.yy159;} + yymsp[-1].minor.yy159 = yylhsminor.yy159; break; case 163: /* sclp ::= */ case 188: /* orderby_opt ::= */ yytestcase(yyruleno==188); -{yymsp[1].minor.yy429 = 0;} +{yymsp[1].minor.yy159 = 0;} break; case 164: /* selcollist ::= sclp distinct expr as */ { - yylhsminor.yy429 = tSqlExprListAppend(yymsp[-3].minor.yy429, yymsp[-1].minor.yy170, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); + 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); } - yymsp[-3].minor.yy429 = yylhsminor.yy429; + yymsp[-3].minor.yy159 = yylhsminor.yy159; break; case 165: /* selcollist ::= sclp STAR */ { tSqlExpr *pNode = tSqlExprCreateIdValue(NULL, TK_ALL); - yylhsminor.yy429 = tSqlExprListAppend(yymsp[-1].minor.yy429, pNode, 0, 0); + yylhsminor.yy159 = tSqlExprListAppend(yymsp[-1].minor.yy159, pNode, 0, 0); } - yymsp[-1].minor.yy429 = yylhsminor.yy429; + yymsp[-1].minor.yy159 = yylhsminor.yy159; break; case 166: /* as ::= AS ids */ { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } @@ -2953,71 +2665,64 @@ static YYACTIONTYPE yy_reduce( yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 171: /* from ::= FROM tablelist */ -{yymsp[-1].minor.yy70 = yymsp[0].minor.yy429;} +{yymsp[-1].minor.yy236 = yymsp[0].minor.yy236;} break; case 172: /* from ::= FROM LP union RP */ -{yymsp[-3].minor.yy70 = yymsp[-1].minor.yy141;} +{yymsp[-3].minor.yy236 = setSubquery(NULL, yymsp[-1].minor.yy159);} break; case 173: /* tablelist ::= ids cpxName */ { - toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy429 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy236 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); } - yymsp[-1].minor.yy429 = yylhsminor.yy429; + yymsp[-1].minor.yy236 = yylhsminor.yy236; break; case 174: /* tablelist ::= ids cpxName ids */ { - toTSDBType(yymsp[-2].minor.yy0.type); - toTSDBType(yymsp[0].minor.yy0.type); yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy429 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy236 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy429 = yylhsminor.yy429; + yymsp[-2].minor.yy236 = yylhsminor.yy236; break; case 175: /* tablelist ::= tablelist COMMA ids cpxName */ { - toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy429 = setTableNameList(yymsp[-3].minor.yy429, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy236 = setTableNameList(yymsp[-3].minor.yy236, &yymsp[-1].minor.yy0, NULL); } - yymsp[-3].minor.yy429 = yylhsminor.yy429; + yymsp[-3].minor.yy236 = yylhsminor.yy236; break; case 176: /* tablelist ::= tablelist COMMA ids cpxName ids */ { - toTSDBType(yymsp[-2].minor.yy0.type); - toTSDBType(yymsp[0].minor.yy0.type); yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - - yylhsminor.yy429 = setTableNameList(yymsp[-4].minor.yy429, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy236 = setTableNameList(yymsp[-4].minor.yy236, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-4].minor.yy429 = yylhsminor.yy429; + yymsp[-4].minor.yy236 = yylhsminor.yy236; break; case 177: /* tmvar ::= VARIABLE */ {yylhsminor.yy0 = yymsp[0].minor.yy0;} yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 178: /* interval_opt ::= INTERVAL LP tmvar RP */ -{yymsp[-3].minor.yy220.interval = yymsp[-1].minor.yy0; yymsp[-3].minor.yy220.offset.n = 0;} +{yymsp[-3].minor.yy184.interval = yymsp[-1].minor.yy0; yymsp[-3].minor.yy184.offset.n = 0;} break; case 179: /* interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ -{yymsp[-5].minor.yy220.interval = yymsp[-3].minor.yy0; yymsp[-5].minor.yy220.offset = yymsp[-1].minor.yy0;} +{yymsp[-5].minor.yy184.interval = yymsp[-3].minor.yy0; yymsp[-5].minor.yy184.offset = yymsp[-1].minor.yy0;} break; case 180: /* interval_opt ::= */ -{memset(&yymsp[1].minor.yy220, 0, sizeof(yymsp[1].minor.yy220));} +{memset(&yymsp[1].minor.yy184, 0, sizeof(yymsp[1].minor.yy184));} break; case 181: /* session_option ::= */ -{yymsp[1].minor.yy87.col.n = 0; yymsp[1].minor.yy87.gap.n = 0;} +{yymsp[1].minor.yy249.col.n = 0; yymsp[1].minor.yy249.gap.n = 0;} break; case 182: /* session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - yymsp[-6].minor.yy87.col = yymsp[-4].minor.yy0; - yymsp[-6].minor.yy87.gap = yymsp[-1].minor.yy0; + yymsp[-6].minor.yy249.col = yymsp[-4].minor.yy0; + yymsp[-6].minor.yy249.gap = yymsp[-1].minor.yy0; } break; case 183: /* fill_opt ::= */ -{ yymsp[1].minor.yy429 = 0; } +{ yymsp[1].minor.yy159 = 0; } break; case 184: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */ { @@ -3025,14 +2730,14 @@ static YYACTIONTYPE yy_reduce( toTSDBType(yymsp[-3].minor.yy0.type); tVariantCreate(&A, &yymsp[-3].minor.yy0); - tVariantListInsert(yymsp[-1].minor.yy429, &A, -1, 0); - yymsp[-5].minor.yy429 = yymsp[-1].minor.yy429; + tVariantListInsert(yymsp[-1].minor.yy159, &A, -1, 0); + yymsp[-5].minor.yy159 = yymsp[-1].minor.yy159; } break; case 185: /* fill_opt ::= FILL LP ID RP */ { toTSDBType(yymsp[-1].minor.yy0.type); - yymsp[-3].minor.yy429 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); + yymsp[-3].minor.yy159 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); } break; case 186: /* sliding_opt ::= SLIDING LP tmvar RP */ @@ -3042,235 +2747,235 @@ static YYACTIONTYPE yy_reduce( {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = NULL; yymsp[1].minor.yy0.type = 0; } break; case 189: /* orderby_opt ::= ORDER BY sortlist */ -{yymsp[-2].minor.yy429 = yymsp[0].minor.yy429;} +{yymsp[-2].minor.yy159 = yymsp[0].minor.yy159;} break; case 190: /* sortlist ::= sortlist COMMA item sortorder */ { - yylhsminor.yy429 = tVariantListAppend(yymsp[-3].minor.yy429, &yymsp[-1].minor.yy218, yymsp[0].minor.yy116); + yylhsminor.yy159 = tVariantListAppend(yymsp[-3].minor.yy159, &yymsp[-1].minor.yy488, yymsp[0].minor.yy20); } - yymsp[-3].minor.yy429 = yylhsminor.yy429; + yymsp[-3].minor.yy159 = yylhsminor.yy159; break; case 191: /* sortlist ::= item sortorder */ { - yylhsminor.yy429 = tVariantListAppend(NULL, &yymsp[-1].minor.yy218, yymsp[0].minor.yy116); + yylhsminor.yy159 = tVariantListAppend(NULL, &yymsp[-1].minor.yy488, yymsp[0].minor.yy20); } - yymsp[-1].minor.yy429 = yylhsminor.yy429; + yymsp[-1].minor.yy159 = yylhsminor.yy159; break; case 192: /* item ::= ids cpxName */ { toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - tVariantCreate(&yylhsminor.yy218, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy488, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy218 = yylhsminor.yy218; + yymsp[-1].minor.yy488 = yylhsminor.yy488; break; case 193: /* sortorder ::= ASC */ -{ yymsp[0].minor.yy116 = TSDB_ORDER_ASC; } +{ yymsp[0].minor.yy20 = TSDB_ORDER_ASC; } break; case 194: /* sortorder ::= DESC */ -{ yymsp[0].minor.yy116 = TSDB_ORDER_DESC;} +{ yymsp[0].minor.yy20 = TSDB_ORDER_DESC;} break; case 195: /* sortorder ::= */ -{ yymsp[1].minor.yy116 = TSDB_ORDER_ASC; } +{ yymsp[1].minor.yy20 = TSDB_ORDER_ASC; } break; case 196: /* groupby_opt ::= */ -{ yymsp[1].minor.yy429 = 0;} +{ yymsp[1].minor.yy159 = 0;} break; case 197: /* groupby_opt ::= GROUP BY grouplist */ -{ yymsp[-2].minor.yy429 = yymsp[0].minor.yy429;} +{ yymsp[-2].minor.yy159 = yymsp[0].minor.yy159;} break; case 198: /* grouplist ::= grouplist COMMA item */ { - yylhsminor.yy429 = tVariantListAppend(yymsp[-2].minor.yy429, &yymsp[0].minor.yy218, -1); + yylhsminor.yy159 = tVariantListAppend(yymsp[-2].minor.yy159, &yymsp[0].minor.yy488, -1); } - yymsp[-2].minor.yy429 = yylhsminor.yy429; + yymsp[-2].minor.yy159 = yylhsminor.yy159; break; case 199: /* grouplist ::= item */ { - yylhsminor.yy429 = tVariantListAppend(NULL, &yymsp[0].minor.yy218, -1); + yylhsminor.yy159 = tVariantListAppend(NULL, &yymsp[0].minor.yy488, -1); } - yymsp[0].minor.yy429 = yylhsminor.yy429; + yymsp[0].minor.yy159 = yylhsminor.yy159; break; case 200: /* having_opt ::= */ case 210: /* where_opt ::= */ yytestcase(yyruleno==210); case 252: /* expritem ::= */ yytestcase(yyruleno==252); -{yymsp[1].minor.yy170 = 0;} +{yymsp[1].minor.yy118 = 0;} break; case 201: /* having_opt ::= HAVING expr */ case 211: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==211); -{yymsp[-1].minor.yy170 = yymsp[0].minor.yy170;} +{yymsp[-1].minor.yy118 = yymsp[0].minor.yy118;} break; case 202: /* limit_opt ::= */ case 206: /* slimit_opt ::= */ yytestcase(yyruleno==206); -{yymsp[1].minor.yy18.limit = -1; yymsp[1].minor.yy18.offset = 0;} +{yymsp[1].minor.yy440.limit = -1; yymsp[1].minor.yy440.offset = 0;} break; case 203: /* limit_opt ::= LIMIT signed */ case 207: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==207); -{yymsp[-1].minor.yy18.limit = yymsp[0].minor.yy481; yymsp[-1].minor.yy18.offset = 0;} +{yymsp[-1].minor.yy440.limit = yymsp[0].minor.yy317; yymsp[-1].minor.yy440.offset = 0;} break; case 204: /* limit_opt ::= LIMIT signed OFFSET signed */ -{ yymsp[-3].minor.yy18.limit = yymsp[-2].minor.yy481; yymsp[-3].minor.yy18.offset = yymsp[0].minor.yy481;} +{ yymsp[-3].minor.yy440.limit = yymsp[-2].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[0].minor.yy317;} break; case 205: /* limit_opt ::= LIMIT signed COMMA signed */ -{ yymsp[-3].minor.yy18.limit = yymsp[0].minor.yy481; yymsp[-3].minor.yy18.offset = yymsp[-2].minor.yy481;} +{ yymsp[-3].minor.yy440.limit = yymsp[0].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[-2].minor.yy317;} break; case 208: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ -{yymsp[-3].minor.yy18.limit = yymsp[-2].minor.yy481; yymsp[-3].minor.yy18.offset = yymsp[0].minor.yy481;} +{yymsp[-3].minor.yy440.limit = yymsp[-2].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[0].minor.yy317;} break; case 209: /* slimit_opt ::= SLIMIT signed COMMA signed */ -{yymsp[-3].minor.yy18.limit = yymsp[0].minor.yy481; yymsp[-3].minor.yy18.offset = yymsp[-2].minor.yy481;} +{yymsp[-3].minor.yy440.limit = yymsp[0].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[-2].minor.yy317;} break; case 212: /* expr ::= LP expr RP */ -{yylhsminor.yy170 = yymsp[-1].minor.yy170; yylhsminor.yy170->token.z = yymsp[-2].minor.yy0.z; yylhsminor.yy170->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{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; break; case 213: /* expr ::= ID */ -{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} - yymsp[0].minor.yy170 = yylhsminor.yy170; +{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} + yymsp[0].minor.yy118 = yylhsminor.yy118; break; case 214: /* expr ::= ID DOT ID */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{ 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; break; case 215: /* expr ::= ID DOT STAR */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{ 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; break; case 216: /* expr ::= INTEGER */ -{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} - yymsp[0].minor.yy170 = yylhsminor.yy170; +{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} + yymsp[0].minor.yy118 = yylhsminor.yy118; break; case 217: /* expr ::= MINUS INTEGER */ case 218: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==218); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} - yymsp[-1].minor.yy170 = yylhsminor.yy170; +{ 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; break; case 219: /* expr ::= FLOAT */ -{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} - yymsp[0].minor.yy170 = yylhsminor.yy170; +{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} + yymsp[0].minor.yy118 = yylhsminor.yy118; break; case 220: /* expr ::= MINUS FLOAT */ case 221: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==221); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} - yymsp[-1].minor.yy170 = yylhsminor.yy170; +{ 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; break; case 222: /* expr ::= STRING */ -{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} - yymsp[0].minor.yy170 = yylhsminor.yy170; +{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} + yymsp[0].minor.yy118 = yylhsminor.yy118; break; case 223: /* expr ::= NOW */ -{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } - yymsp[0].minor.yy170 = yylhsminor.yy170; +{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } + yymsp[0].minor.yy118 = yylhsminor.yy118; break; case 224: /* expr ::= VARIABLE */ -{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} - yymsp[0].minor.yy170 = yylhsminor.yy170; +{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} + yymsp[0].minor.yy118 = yylhsminor.yy118; break; case 225: /* expr ::= PLUS VARIABLE */ case 226: /* expr ::= MINUS VARIABLE */ yytestcase(yyruleno==226); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_VARIABLE; yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_VARIABLE);} - yymsp[-1].minor.yy170 = yylhsminor.yy170; +{ 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; break; case 227: /* expr ::= BOOL */ -{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} - yymsp[0].minor.yy170 = yylhsminor.yy170; +{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} + yymsp[0].minor.yy118 = yylhsminor.yy118; break; case 228: /* expr ::= NULL */ -{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} - yymsp[0].minor.yy170 = yylhsminor.yy170; +{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} + yymsp[0].minor.yy118 = yylhsminor.yy118; break; case 229: /* expr ::= ID LP exprlist RP */ -{ yylhsminor.yy170 = tSqlExprCreateFunction(yymsp[-1].minor.yy429, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy170 = yylhsminor.yy170; +{ 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; break; case 230: /* expr ::= ID LP STAR RP */ -{ yylhsminor.yy170 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy170 = yylhsminor.yy170; +{ yylhsminor.yy118 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy118 = yylhsminor.yy118; break; case 231: /* expr ::= expr IS NULL */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, NULL, TK_ISNULL);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, NULL, TK_ISNULL);} + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 232: /* expr ::= expr IS NOT NULL */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-3].minor.yy170, NULL, TK_NOTNULL);} - yymsp[-3].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-3].minor.yy118, NULL, TK_NOTNULL);} + yymsp[-3].minor.yy118 = yylhsminor.yy118; break; case 233: /* expr ::= expr LT expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_LT);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_LT);} + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 234: /* expr ::= expr GT expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_GT);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_GT);} + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 235: /* expr ::= expr LE expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_LE);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_LE);} + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 236: /* expr ::= expr GE expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_GE);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_GE);} + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 237: /* expr ::= expr NE expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_NE);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_NE);} + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 238: /* expr ::= expr EQ expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_EQ);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_EQ);} + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 239: /* expr ::= expr BETWEEN expr AND expr */ -{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy170); yylhsminor.yy170 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy170, yymsp[-2].minor.yy170, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy170, TK_LE), TK_AND);} - yymsp[-4].minor.yy170 = yylhsminor.yy170; +{ 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; break; case 240: /* expr ::= expr AND expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_AND);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_AND);} + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 241: /* expr ::= expr OR expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_OR); } - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_OR); } + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 242: /* expr ::= expr PLUS expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_PLUS); } - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_PLUS); } + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 243: /* expr ::= expr MINUS expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_MINUS); } - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_MINUS); } + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 244: /* expr ::= expr STAR expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_STAR); } - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_STAR); } + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 245: /* expr ::= expr SLASH expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_DIVIDE);} - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_DIVIDE);} + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 246: /* expr ::= expr REM expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_REM); } - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_REM); } + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 247: /* expr ::= expr LIKE expr */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_LIKE); } - yymsp[-2].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_LIKE); } + yymsp[-2].minor.yy118 = yylhsminor.yy118; break; case 248: /* expr ::= expr IN LP exprlist RP */ -{yylhsminor.yy170 = tSqlExprCreate(yymsp[-4].minor.yy170, (tSqlExpr*)yymsp[-1].minor.yy429, TK_IN); } - yymsp[-4].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = tSqlExprCreate(yymsp[-4].minor.yy118, (tSqlExpr*)yymsp[-1].minor.yy159, TK_IN); } + yymsp[-4].minor.yy118 = yylhsminor.yy118; break; case 249: /* exprlist ::= exprlist COMMA expritem */ -{yylhsminor.yy429 = tSqlExprListAppend(yymsp[-2].minor.yy429,yymsp[0].minor.yy170,0, 0);} - yymsp[-2].minor.yy429 = yylhsminor.yy429; +{yylhsminor.yy159 = tSqlExprListAppend(yymsp[-2].minor.yy159,yymsp[0].minor.yy118,0, 0);} + yymsp[-2].minor.yy159 = yylhsminor.yy159; break; case 250: /* exprlist ::= expritem */ -{yylhsminor.yy429 = tSqlExprListAppend(0,yymsp[0].minor.yy170,0, 0);} - yymsp[0].minor.yy429 = yylhsminor.yy429; +{yylhsminor.yy159 = tSqlExprListAppend(0,yymsp[0].minor.yy118,0, 0);} + yymsp[0].minor.yy159 = yylhsminor.yy159; break; case 251: /* expritem ::= expr */ -{yylhsminor.yy170 = yymsp[0].minor.yy170;} - yymsp[0].minor.yy170 = yylhsminor.yy170; +{yylhsminor.yy118 = yymsp[0].minor.yy118;} + yymsp[0].minor.yy118 = yylhsminor.yy118; break; case 253: /* cmd ::= RESET QUERY CACHE */ { setDCLSqlElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} @@ -3281,7 +2986,7 @@ static YYACTIONTYPE yy_reduce( case 255: /* 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.yy429, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy159, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; @@ -3299,7 +3004,7 @@ static YYACTIONTYPE yy_reduce( case 257: /* 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.yy429, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy159, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; @@ -3334,7 +3039,7 @@ static YYACTIONTYPE yy_reduce( toTSDBType(yymsp[-2].minor.yy0.type); SArray* A = tVariantListAppendToken(NULL, &yymsp[-2].minor.yy0, -1); - A = tVariantListAppend(A, &yymsp[0].minor.yy218, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy488, -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); @@ -3343,7 +3048,7 @@ static YYACTIONTYPE yy_reduce( case 261: /* 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.yy429, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy159, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; @@ -3361,7 +3066,7 @@ static YYACTIONTYPE yy_reduce( case 263: /* 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.yy429, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy159, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; @@ -3403,9 +3108,9 @@ static YYACTIONTYPE yy_reduce( break; /********** End reduce actions ************************************************/ }; - assert( yyrulenostateno = (YYACTIONTYPE)yyact; yymsp->major = (YYCODETYPE)yygoto; yyTraceShift(yypParser, yyact, "... then shift"); - return yyact; } /* @@ -3430,8 +3134,7 @@ static YYACTIONTYPE yy_reduce( static void yy_parse_failed( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH - ParseCTX_FETCH + ParseARG_FETCH; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); @@ -3442,8 +3145,7 @@ static void yy_parse_failed( ** parser fails */ /************ Begin %parse_failure code ***************************************/ /************ End %parse_failure code *****************************************/ - ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ - ParseCTX_STORE + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } #endif /* YYNOERRORRECOVERY */ @@ -3455,8 +3157,7 @@ static void yy_syntax_error( int yymajor, /* The major type of the error token */ ParseTOKENTYPE yyminor /* The minor type of the error token */ ){ - ParseARG_FETCH - ParseCTX_FETCH + ParseARG_FETCH; #define TOKEN yyminor /************ Begin %syntax_error code ****************************************/ @@ -3482,8 +3183,7 @@ static void yy_syntax_error( assert(len <= outputBufLen); /************ End %syntax_error code ******************************************/ - ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ - ParseCTX_STORE + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } /* @@ -3492,8 +3192,7 @@ static void yy_syntax_error( static void yy_accept( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH - ParseCTX_FETCH + ParseARG_FETCH; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); @@ -3508,8 +3207,7 @@ static void yy_accept( /*********** Begin %parse_accept code *****************************************/ /*********** End %parse_accept code *******************************************/ - ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ - ParseCTX_STORE + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } /* The main parser program. @@ -3538,47 +3236,45 @@ void Parse( ParseARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; - YYACTIONTYPE yyact; /* The parser action. */ + unsigned int yyact; /* The parser action. */ #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) int yyendofinput; /* True if we are at the end of input */ #endif #ifdef YYERRORSYMBOL int yyerrorhit = 0; /* True if yymajor has invoked an error */ #endif - yyParser *yypParser = (yyParser*)yyp; /* The parser */ - ParseCTX_FETCH - ParseARG_STORE + yyParser *yypParser; /* The parser */ + yypParser = (yyParser*)yyp; assert( yypParser->yytos!=0 ); #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) yyendofinput = (yymajor==0); #endif + ParseARG_STORE; - yyact = yypParser->yytos->stateno; #ifndef NDEBUG if( yyTraceFILE ){ - if( yyact < YY_MIN_REDUCE ){ + int stateno = yypParser->yytos->stateno; + if( stateno < YY_MIN_REDUCE ){ fprintf(yyTraceFILE,"%sInput '%s' in state %d\n", - yyTracePrompt,yyTokenName[yymajor],yyact); + yyTracePrompt,yyTokenName[yymajor],stateno); }else{ fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n", - yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE); + yyTracePrompt,yyTokenName[yymajor],stateno-YY_MIN_REDUCE); } } #endif do{ - assert( yyact==yypParser->yytos->stateno ); - yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); + yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); if( yyact >= YY_MIN_REDUCE ){ - yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, - yyminor ParseCTX_PARAM); + yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,yyminor); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ - yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); + yy_shift(yypParser,yyact,yymajor,yyminor); #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt--; #endif - break; + yymajor = YYNOCODE; }else if( yyact==YY_ACCEPT_ACTION ){ yypParser->yytos--; yy_accept(yypParser); @@ -3629,9 +3325,10 @@ void Parse( yymajor = YYNOCODE; }else{ while( yypParser->yytos >= yypParser->yystack + && yymx != YYERRORSYMBOL && (yyact = yy_find_reduce_action( yypParser->yytos->stateno, - YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE + YYERRORSYMBOL)) >= YY_MIN_REDUCE ){ yy_pop_parser_stack(yypParser); } @@ -3648,8 +3345,6 @@ void Parse( } yypParser->yyerrcnt = 3; yyerrorhit = 1; - if( yymajor==YYNOCODE ) break; - yyact = yypParser->yytos->stateno; #elif defined(YYNOERRORRECOVERY) /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to ** do any kind of error recovery. Instead, simply invoke the syntax @@ -3660,7 +3355,8 @@ void Parse( */ yy_syntax_error(yypParser,yymajor, yyminor); yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - break; + yymajor = YYNOCODE; + #else /* YYERRORSYMBOL is not defined */ /* This is what we do if the grammar does not define ERROR: ** @@ -3682,10 +3378,10 @@ void Parse( yypParser->yyerrcnt = -1; #endif } - break; + yymajor = YYNOCODE; #endif } - }while( yypParser->yytos>yypParser->yystack ); + }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack ); #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; @@ -3700,17 +3396,3 @@ void Parse( #endif return; } - -/* -** Return the fallback token corresponding to canonical token iToken, or -** 0 if iToken has no fallback. -*/ -int ParseFallback(int iToken){ -#ifdef YYFALLBACK - assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ); - return yyFallback[iToken]; -#else - (void)iToken; - return 0; -#endif -} diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 2ec508f050..08e7551a2e 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -399,7 +399,7 @@ void rpcSendRequest(void *shandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64 pContext->oldInUse = pEpSet->inUse; pContext->connType = RPC_CONN_UDPC; - if (contLen > tsRpcMaxUdpSize) pContext->connType = RPC_CONN_TCPC; + if (contLen > tsRpcMaxUdpSize || tsRpcForceTcp ) pContext->connType = RPC_CONN_TCPC; // connection type is application specific. // for TDengine, all the query, show commands shall have TCP connection @@ -409,7 +409,7 @@ void rpcSendRequest(void *shandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64 || type == TSDB_MSG_TYPE_CM_TABLES_META || type == TSDB_MSG_TYPE_CM_TABLE_META || type == TSDB_MSG_TYPE_CM_SHOW || type == TSDB_MSG_TYPE_DM_STATUS) pContext->connType = RPC_CONN_TCPC; - + pContext->rid = taosAddRef(tsRpcRefId, pContext); if (pRid) *pRid = pContext->rid; diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index 3162ab2e4c..09857610d2 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -529,9 +529,6 @@ static void *taosProcessTcpData(void *param) { struct epoll_event events[maxEvents]; SRecvInfo recvInfo; -#ifdef __APPLE__ - taos_block_sigalrm(); -#endif // __APPLE__ while (1) { int fdNum = epoll_wait(pThreadObj->pollFd, events, maxEvents, TAOS_EPOLL_WAIT_TIME); if (pThreadObj->stop) { diff --git a/src/rpc/test/rserver.c b/src/rpc/test/rserver.c index 44c5cd6ab4..64960db044 100644 --- a/src/rpc/test/rserver.c +++ b/src/rpc/test/rserver.c @@ -52,7 +52,7 @@ void processShellMsg() { if (commit >=2) { num += numOfMsgs; - if ( fsync(dataFd) < 0 ) { + if ( taosFsync(dataFd) < 0 ) { tInfo("failed to flush data to file, reason:%s", strerror(errno)); } diff --git a/src/sync/CMakeLists.txt b/src/sync/CMakeLists.txt index 82d0bbf520..521f51ceb7 100644 --- a/src/sync/CMakeLists.txt +++ b/src/sync/CMakeLists.txt @@ -11,6 +11,6 @@ TARGET_LINK_LIBRARIES(sync tutil pthread common) LIST(APPEND BIN_SRC src/syncArbitrator.c) LIST(APPEND BIN_SRC src/syncTcp.c) ADD_EXECUTABLE(tarbitrator ${BIN_SRC}) -TARGET_LINK_LIBRARIES(tarbitrator sync common osdetail tutil) +TARGET_LINK_LIBRARIES(tarbitrator sync common os tutil) #ADD_SUBDIRECTORY(test) diff --git a/src/tsdb/inc/tsdbFile.h b/src/tsdb/inc/tsdbFile.h index 792efcdb2e..dcb5eadfab 100644 --- a/src/tsdb/inc/tsdbFile.h +++ b/src/tsdb/inc/tsdbFile.h @@ -32,7 +32,7 @@ #define TSDB_FILE_SET_CLOSED(f) (TSDB_FILE_FD(f) = -1) #define TSDB_FILE_LEVEL(tf) TFILE_LEVEL(TSDB_FILE_F(tf)) #define TSDB_FILE_ID(tf) TFILE_ID(TSDB_FILE_F(tf)) -#define TSDB_FILE_FSYNC(tf) fsync(TSDB_FILE_FD(tf)) +#define TSDB_FILE_FSYNC(tf) taosFsync(TSDB_FILE_FD(tf)) #define TSDB_FILE_STATE(tf) ((tf)->state) #define TSDB_FILE_SET_STATE(tf, s) ((tf)->state = (s)) #define TSDB_FILE_IS_OK(tf) (TSDB_FILE_STATE(tf) == TSDB_FILE_STATE_OK) diff --git a/src/tsdb/src/tsdbFS.c b/src/tsdb/src/tsdbFS.c index c9f087a5cf..f6e721e3d3 100644 --- a/src/tsdb/src/tsdbFS.c +++ b/src/tsdb/src/tsdbFS.c @@ -390,7 +390,7 @@ static int tsdbSaveFSStatus(SFSStatus *pStatus, int vid) { } // fsync, close and rename - if (fsync(fd) < 0) { + if (taosFsync(fd) < 0) { terrno = TAOS_SYSTEM_ERROR(errno); close(fd); remove(tfname); diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 1b24405952..9df25409de 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -123,7 +123,7 @@ typedef struct STsdbQueryHandle { SMemRef *pMemRef; SArray *defaultLoadColumn;// default load column SDataBlockLoadInfo dataBlockLoadInfo; /* record current block load information */ - SLoadCompBlockInfo compBlockLoadInfo; /* record current compblock information in SQuery */ + SLoadCompBlockInfo compBlockLoadInfo; /* record current compblock information in SQueryAttr */ SArray *prev; // previous row which is before than time window SArray *next; // next row which is after the query time window @@ -3413,14 +3413,16 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList) { size_t numOfTables = taosArrayGetSize(p); for(int32_t j = 0; j < numOfTables; ++j) { STable* pTable = taosArrayGetP(p, j); - assert(pTable != NULL); - - tsdbUnRefTable(pTable); + if (pTable != NULL) { // in case of handling retrieve data from tsdb + tsdbUnRefTable(pTable); + } + //assert(pTable != NULL); } taosArrayDestroy(p); } + taosHashCleanup(pGroupList->map); taosArrayDestroy(pGroupList->pGroupList); pGroupList->numOfTables = 0; } @@ -3431,7 +3433,7 @@ static void applyFilterToSkipListNode(SSkipList *pSkipList, tExprNode *pExpr, SA // Scan each node in the skiplist by using iterator while (tSkipListIterNext(iter)) { SSkipListNode *pNode = tSkipListIterGet(iter); - if (exprTreeApplayFilter(pExpr, pNode, param)) { + if (exprTreeApplyFilter(pExpr, pNode, param)) { taosArrayPush(pResult, &(SL_GET_NODE_DATA(pNode))); } } diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index a7f4f59e07..e8a1d61ee5 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/sync/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/rmonotonic/inc) AUX_SOURCE_DIRECTORY(src SRC) ADD_LIBRARY(tutil ${SRC}) -TARGET_LINK_LIBRARIES(tutil pthread osdetail lz4 z rmonotonic) +TARGET_LINK_LIBRARIES(tutil pthread os lz4 z rmonotonic) IF (TD_LINUX) TARGET_LINK_LIBRARIES(tutil m rt) diff --git a/src/util/src/exception.c b/src/util/src/exception.c index 0b716b6aba..9740b9031b 100644 --- a/src/util/src/exception.c +++ b/src/util/src/exception.c @@ -1,7 +1,21 @@ +/* + * 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 "exception.h" - static threadlocal SExceptionNode* expList; void exceptionPushNode( SExceptionNode* node ) { diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c index 4dde5dbba2..f4587b33e7 100644 --- a/src/util/src/tarray.c +++ b/src/util/src/tarray.c @@ -13,6 +13,7 @@ * along with this program. If not, see . */ +#include "os.h" #include "tarray.h" void* taosArrayInit(size_t size, size_t elemSize) { diff --git a/src/util/src/tbase64.c b/src/util/src/tbase64.c index 937adfde5c..1b1f53df17 100644 --- a/src/util/src/tbase64.c +++ b/src/util/src/tbase64.c @@ -1,23 +1,19 @@ -/** - * Copyright (c) 2006-2008 Apple Inc. All rights reserved. +/* + * Copyright (c) 2019 TAOS Data, Inc. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ -#include -#include -#include -#include +#include "os.h" // deprecated this file for bug prone // base64 encode diff --git a/src/util/src/tbuffer.c b/src/util/src/tbuffer.c index a2cb32c1f4..abfa35f42c 100644 --- a/src/util/src/tbuffer.c +++ b/src/util/src/tbuffer.c @@ -14,12 +14,9 @@ */ #include "os.h" -#include -#include -#include #include "tbuffer.h" #include "exception.h" -#include +#include "taoserror.h" //////////////////////////////////////////////////////////////////////////////// // reader functions diff --git a/src/util/src/tcache.c b/src/util/src/tcache.c index c0cc8ce339..57d45cc8c0 100644 --- a/src/util/src/tcache.c +++ b/src/util/src/tcache.c @@ -661,11 +661,7 @@ void* taosCacheTimedRefresh(void *handle) { int64_t count = 0; while(1) { -#if defined LINUX - usleep(500*1000); -#else taosMsleep(500); -#endif // check if current cache object will be deleted every 500ms. if (pCacheObj->deleting) { diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 354e7899c2..09199eaee3 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -1,3 +1,19 @@ +/* + * 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 "ttype.h" #include "tcompare.h" #include "tarray.h" diff --git a/src/util/src/tcompression.c b/src/util/src/tcompression.c index 1a5d28625f..1de6e76f71 100644 --- a/src/util/src/tcompression.c +++ b/src/util/src/tcompression.c @@ -47,8 +47,8 @@ * */ -#include "lz4.h" #include "os.h" +#include "lz4.h" #include "taosdef.h" #include "tscompression.h" #include "tulog.h" diff --git a/src/util/src/tcrc32c.c b/src/util/src/tcrc32c.c index 054b8f8171..4009973a9f 100644 --- a/src/util/src/tcrc32c.c +++ b/src/util/src/tcrc32c.c @@ -17,6 +17,7 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ + #ifndef _TD_ARM_ #include #endif diff --git a/src/util/src/tdes.c b/src/util/src/tdes.c index 871ae15a8a..6e003756a3 100644 --- a/src/util/src/tdes.c +++ b/src/util/src/tdes.c @@ -1,3 +1,17 @@ +/* + * 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 "tkey.h" diff --git a/src/util/src/terror.c b/src/util/src/terror.c index fc24b28dc3..d88393777c 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 TAOS Data, Inc. + * 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 @@ -13,10 +13,7 @@ * along with this program. If not, see . */ -#include -#include -#include -#include +#include "os.h" #define TAOS_ERROR_C diff --git a/src/util/src/tfile.c b/src/util/src/tfile.c index dd621b3199..455c885e75 100644 --- a/src/util/src/tfile.c +++ b/src/util/src/tfile.c @@ -98,7 +98,7 @@ int32_t tfFsync(int64_t tfd) { if (p == NULL) return -1; int32_t fd = (int32_t)(uintptr_t)p; - int32_t code = fsync(fd); + int32_t code = taosFsync(fd); taosReleaseRef(tsFileRsetId, tfd); return code; diff --git a/src/util/src/thashutil.c b/src/util/src/thashutil.c index 681d73db3d..3634dca4c0 100644 --- a/src/util/src/thashutil.c +++ b/src/util/src/thashutil.c @@ -1,12 +1,19 @@ -/** - * MurmurHash3 by Austin Appleby - * @ref - * https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp +/* + * Copyright (c) 2019 TAOS Data, Inc. * - * Plese refers to the link above for the complete implementation of - * MurmurHash algorithm + * 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 "hashfunc.h" #include "tutil.h" diff --git a/src/util/src/tidpool.c b/src/util/src/tidpool.c index bd3f774543..61cecf54c0 100644 --- a/src/util/src/tidpool.c +++ b/src/util/src/tidpool.c @@ -15,7 +15,6 @@ #include "os.h" #include "tulog.h" -#include typedef struct { int maxId; diff --git a/src/util/src/tlist.c b/src/util/src/tlist.c index 2f52551e2a..c5b4dbad10 100644 --- a/src/util/src/tlist.c +++ b/src/util/src/tlist.c @@ -12,9 +12,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#include -#include +#include "os.h" #include "tlist.h" SList *tdListNew(int eleSize) { diff --git a/src/util/src/tlockfree.c b/src/util/src/tlockfree.c index 3161518a36..f54206f5cb 100644 --- a/src/util/src/tlockfree.c +++ b/src/util/src/tlockfree.c @@ -12,9 +12,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -// #define _GNU_SOURCE -// #include +#include "os.h" #include "tlockfree.h" #define TD_RWLATCH_WRITE_FLAG 0x40000000 diff --git a/src/util/src/tlosertree.c b/src/util/src/tlosertree.c index fa7e4fc340..e793548407 100644 --- a/src/util/src/tlosertree.c +++ b/src/util/src/tlosertree.c @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#include "tlosertree.h" #include "os.h" +#include "tlosertree.h" #include "taosmsg.h" #include "tulog.h" diff --git a/src/util/src/tmd5.c b/src/util/src/tmd5.c index 4971ed7a12..a1fdcc6a05 100644 --- a/src/util/src/tmd5.c +++ b/src/util/src/tmd5.c @@ -33,10 +33,8 @@ *********************************************************************** */ +#include "os.h" #include "tmd5.h" -#include -#include -#include #include "taosdef.h" /* forward declaration */ diff --git a/src/util/tests/CMakeLists.txt b/src/util/tests/CMakeLists.txt index 0c96ed2a2f..ee99348cd9 100644 --- a/src/util/tests/CMakeLists.txt +++ b/src/util/tests/CMakeLists.txt @@ -12,7 +12,7 @@ IF (HEADER_GTEST_INCLUDE_DIR AND LIB_GTEST_STATIC_DIR) LIST(REMOVE_ITEM SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/trefTest.c) ADD_EXECUTABLE(utilTest ${SOURCE_LIST}) - TARGET_LINK_LIBRARIES(utilTest tutil common osdetail gtest pthread gcov) + TARGET_LINK_LIBRARIES(utilTest tutil common os gtest pthread gcov) LIST(APPEND BIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/trefTest.c) ADD_EXECUTABLE(trefTest ${BIN_SRC}) diff --git a/src/vnode/src/vnodeCfg.c b/src/vnode/src/vnodeCfg.c index c9cd366c64..2e1d761fcf 100644 --- a/src/vnode/src/vnodeCfg.c +++ b/src/vnode/src/vnodeCfg.c @@ -362,7 +362,7 @@ int32_t vnodeWriteCfg(SCreateVnodeMsg *pMsg) { len += snprintf(content + len, maxLen - len, "}\n"); fwrite(content, 1, len, fp); - fsync(fileno(fp)); + taosFsync(fileno(fp)); fclose(fp); free(content); terrno = 0; diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c index 8ec66316e3..0e47996c6f 100644 --- a/src/vnode/src/vnodeMain.c +++ b/src/vnode/src/vnodeMain.c @@ -232,9 +232,28 @@ int32_t vnodeAlter(void *vparam, SCreateVnodeMsg *pVnodeCfg) { return code; } +static void vnodeFindWalRootDir(int32_t vgId, char *walRootDir) { + char vnodeDir[TSDB_FILENAME_LEN] = "\0"; + snprintf(vnodeDir, TSDB_FILENAME_LEN, "/vnode/vnode%d/wal", vgId); + + TDIR *tdir = tfsOpendir(vnodeDir); + if (!tdir) return; + + const TFILE *tfile = tfsReaddir(tdir); + if (!tfile) { + tfsClosedir(tdir); + return; + } + + sprintf(walRootDir, "%s/vnode/vnode%d", TFS_DISK_PATH(tfile->level, tfile->id), vgId); + + tfsClosedir(tdir); +} + int32_t vnodeOpen(int32_t vgId) { char temp[TSDB_FILENAME_LEN * 3]; char rootDir[TSDB_FILENAME_LEN * 2]; + char walRootDir[TSDB_FILENAME_LEN * 2] = {0}; snprintf(rootDir, TSDB_FILENAME_LEN * 2, "%s/vnode%d", tsVnodeDir, vgId); SVnodeObj *pVnode = calloc(sizeof(SVnodeObj), 1); @@ -321,7 +340,21 @@ int32_t vnodeOpen(int32_t vgId) { } } - sprintf(temp, "%s/wal", rootDir); + // walRootDir for wal & syncInfo.path (not empty dir of /vnode/vnode{pVnode->vgId}/wal) + vnodeFindWalRootDir(pVnode->vgId, walRootDir); + if (walRootDir[0] == 0) { + int level = -1, id = -1; + + tfsAllocDisk(TFS_PRIMARY_LEVEL, &level, &id); + if (level < 0 || id < 0) { + vnodeCleanUp(pVnode); + return terrno; + } + + sprintf(walRootDir, "%s/vnode/vnode%d", TFS_DISK_PATH(level, id), vgId); + } + + sprintf(temp, "%s/wal", walRootDir); pVnode->walCfg.vgId = pVnode->vgId; pVnode->wal = walOpen(temp, &pVnode->walCfg); if (pVnode->wal == NULL) { @@ -353,7 +386,7 @@ int32_t vnodeOpen(int32_t vgId) { pVnode->events = NULL; - vDebug("vgId:%d, vnode is opened in %s, pVnode:%p", pVnode->vgId, rootDir, pVnode); + vDebug("vgId:%d, vnode is opened in %s - %s, pVnode:%p", pVnode->vgId, rootDir, walRootDir, pVnode); vnodeAddIntoHash(pVnode); @@ -361,7 +394,7 @@ int32_t vnodeOpen(int32_t vgId) { syncInfo.vgId = pVnode->vgId; syncInfo.version = pVnode->version; syncInfo.syncCfg = pVnode->syncCfg; - tstrncpy(syncInfo.path, rootDir, TSDB_FILENAME_LEN); + tstrncpy(syncInfo.path, walRootDir, TSDB_FILENAME_LEN); syncInfo.getWalInfoFp = vnodeGetWalInfo; syncInfo.writeToCacheFp = vnodeWriteToCache; syncInfo.confirmForward = vnodeConfirmForard; diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index b60fc5a8cd..b28bdbf130 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -232,7 +232,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { SQueryTableRsp *pRsp = (SQueryTableRsp *)rpcMallocCont(sizeof(SQueryTableRsp)); pRsp->code = code; - pRsp->qhandle = 0; + pRsp->qId = 0; pRet->len = sizeof(SQueryTableRsp); pRet->rsp = pRsp; @@ -250,7 +250,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { return pRsp->code; } else { assert(*handle == pQInfo); - pRsp->qhandle = htobe64(qId); + pRsp->qId = htobe64(qId); } if (handle != NULL && @@ -324,8 +324,8 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { } static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { - void * pCont = pRead->pCont; - SRspRet *pRet = &pRead->rspRet; + void *pCont = pRead->pCont; + SRspRet *pRet = &pRead->rspRet; SRetrieveTableMsg *pRetrieve = pCont; pRetrieve->free = htons(pRetrieve->free); @@ -383,7 +383,7 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp)); freeHandle = true; } else { // result is not ready, return immediately - // Only effects in the non-blocking model + // Only affects the non-blocking model if (!tsRetrieveBlockingModel) { if (!buildRes) { assert(pRead->rpcHandle != NULL); diff --git a/src/vnode/src/vnodeVersion.c b/src/vnode/src/vnodeVersion.c index d22bc17cbe..d1aee5a3d3 100644 --- a/src/vnode/src/vnodeVersion.c +++ b/src/vnode/src/vnodeVersion.c @@ -90,7 +90,7 @@ int32_t vnodeSaveVersion(SVnodeObj *pVnode) { len += snprintf(content + len, maxLen - len, "}\n"); fwrite(content, 1, len, fp); - fsync(fileno(fp)); + taosFsync(fileno(fp)); fclose(fp); free(content); terrno = 0; diff --git a/src/wal/test/CMakeLists.txt b/src/wal/test/CMakeLists.txt index f20a57899e..071ff6fdba 100644 --- a/src/wal/test/CMakeLists.txt +++ b/src/wal/test/CMakeLists.txt @@ -6,7 +6,7 @@ IF (TD_LINUX) LIST(APPEND WALTEST_SRC ./waltest.c) ADD_EXECUTABLE(waltest ${WALTEST_SRC}) - TARGET_LINK_LIBRARIES(waltest twal osdetail tutil) + TARGET_LINK_LIBRARIES(waltest twal os tutil) ENDIF () @@ -15,7 +15,7 @@ IF (TD_DARWIN) LIST(APPEND WALTEST_SRC ./waltest.c) ADD_EXECUTABLE(waltest ${WALTEST_SRC}) - TARGET_LINK_LIBRARIES(waltest twal osdetail tutil) + TARGET_LINK_LIBRARIES(waltest twal os tutil) ENDIF () diff --git a/tests/Jenkinsfile b/tests/Jenkinsfile index 64a71ef8f9..93db09ad6c 100644 --- a/tests/Jenkinsfile +++ b/tests/Jenkinsfile @@ -228,11 +228,11 @@ pipeline { } } - post { + post { success { emailext ( - subject: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", - body: ''' + subject: "PR-result: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' SUCCESS", + body: """ @@ -248,29 +248,29 @@ pipeline {
    -
  • 构建名称>>分支:${PROJECT_NAME}
  • +
  • 构建名称>>分支:${env.BRANCH_NAME}
  • 构建结果: Successful
  • 构建编号:${BUILD_NUMBER}
  • -
  • 触发用户:${CAUSE}
  • -
  • 变更概要:${CHANGES}
  • +
  • 触发用户:${env.CHANGE_AUTHOR}
  • +
  • 提交信息:${env.CHANGE_TITLE}
  • 构建地址:${BUILD_URL}
  • 构建日志:${BUILD_URL}console
  • -
  • 变更集:${JELLY_SCRIPT}
  • +
- ''', + """, to: "yqliu@taosdata.com,pxiao@taosdata.com", from: "support@taosdata.com" ) } failure { emailext ( - subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", - body: ''' + subject: "PR-result: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' FAIL", + body: """ @@ -286,21 +286,21 @@ pipeline {
    -
  • 构建名称>>分支:${PROJECT_NAME}
  • -
  • 构建结果: Successful
  • +
  • 构建名称>>分支:${env.BRANCH_NAME}
  • +
  • 构建结果: Failure
  • 构建编号:${BUILD_NUMBER}
  • -
  • 触发用户:${CAUSE}
  • -
  • 变更概要:${CHANGES}
  • +
  • 触发用户:${env.CHANGE_AUTHOR}
  • +
  • 提交信息:${env.CHANGE_TITLE}
  • 构建地址:${BUILD_URL}
  • 构建日志:${BUILD_URL}console
  • -
  • 变更集:${JELLY_SCRIPT}
  • +
- ''', + """, to: "yqliu@taosdata.com,pxiao@taosdata.com", from: "support@taosdata.com" ) diff --git a/tests/comparisonTest/cassandra/cassandratest/pom.xml b/tests/comparisonTest/cassandra/cassandratest/pom.xml index 01667ff53a..8eeb5c3aa0 100644 --- a/tests/comparisonTest/cassandra/cassandratest/pom.xml +++ b/tests/comparisonTest/cassandra/cassandratest/pom.xml @@ -100,7 +100,7 @@ commons-io commons-io - 2.4 + 2.7 diff --git a/tests/comparisonTest/opentsdb/opentsdbtest/pom.xml b/tests/comparisonTest/opentsdb/opentsdbtest/pom.xml index ae288ae294..0af7491128 100644 --- a/tests/comparisonTest/opentsdb/opentsdbtest/pom.xml +++ b/tests/comparisonTest/opentsdb/opentsdbtest/pom.xml @@ -198,7 +198,7 @@ commons-io commons-io - 2.4 + 2.7 diff --git a/tests/examples/C#/taosdemo/TDengineDriver.cs b/tests/examples/C#/taosdemo/TDengineDriver.cs index 205269501d..2c150341f6 100644 --- a/tests/examples/C#/taosdemo/TDengineDriver.cs +++ b/tests/examples/C#/taosdemo/TDengineDriver.cs @@ -31,7 +31,11 @@ namespace TDengineDriver TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes TSDB_DATA_TYPE_BINARY = 8, // string TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes - TSDB_DATA_TYPE_NCHAR = 10 // unicode string + TSDB_DATA_TYPE_NCHAR = 10, // unicode string + TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte + TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes + TSDB_DATA_TYPE_UINT = 13, // 4 bytes + TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes } enum TDengineInitOption @@ -53,15 +57,23 @@ namespace TDengineDriver switch ((TDengineDataType)type) { case TDengineDataType.TSDB_DATA_TYPE_BOOL: - return "BOOLEAN"; + return "BOOL"; case TDengineDataType.TSDB_DATA_TYPE_TINYINT: - return "BYTE"; + return "TINYINT"; case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: - return "SHORT"; + return "SMALLINT"; case TDengineDataType.TSDB_DATA_TYPE_INT: return "INT"; case TDengineDataType.TSDB_DATA_TYPE_BIGINT: - return "LONG"; + return "BIGINT"; + case TDengineDataType.TSDB_DATA_TYPE_UTINYINT: + return "TINYINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_USMALLINT: + return "SMALLINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_UINT: + return "INT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_UBIGINT: + return "BIGINT UNSIGNED"; case TDengineDataType.TSDB_DATA_TYPE_FLOAT: return "FLOAT"; case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: diff --git a/tests/examples/C#/taosdemo/taosdemo.cs b/tests/examples/C#/taosdemo/taosdemo.cs index 02e843b380..e092c48f15 100644 --- a/tests/examples/C#/taosdemo/taosdemo.cs +++ b/tests/examples/C#/taosdemo/taosdemo.cs @@ -63,7 +63,7 @@ namespace TDengineDriver static void HelpPrint(string arg, string desc) { string indent = " "; - Console.WriteLine("{0}{1}", indent, arg.PadRight(25)+desc); + Console.WriteLine("{0}{1}", indent, arg.PadRight(25) + desc); } static void PrintHelp(String[] argv) @@ -142,33 +142,33 @@ namespace TDengineDriver verbose = this.GetArgumentAsFlag(argv, "-v", true); debug = this.GetArgumentAsFlag(argv, "-g", true); - VerbosePrint ("###################################################################\n"); - VerbosePrintFormat ("# Server IP: {0}\n", host); - VerbosePrintFormat ("# User: {0}\n", user); - VerbosePrintFormat ("# Password: {0}\n", password); - VerbosePrintFormat ("# Number of Columns per record: {0}\n", colsPerRecord); - VerbosePrintFormat ("# Number of Threads: {0}\n", numOfThreads); - VerbosePrintFormat ("# Number of Tables: {0}\n", numOfTables); - VerbosePrintFormat ("# Number of records per Table: {0}\n", recordsPerTable); - VerbosePrintFormat ("# Records/Request: {0}\n", recordsPerRequest); - VerbosePrintFormat ("# Database name: {0}\n", dbName); - VerbosePrintFormat ("# Replica: {0}\n", replica); - VerbosePrintFormat ("# Use STable: {0}\n", useStable); - VerbosePrintFormat ("# Table prefix: {0}\n", tablePrefix); + VerbosePrint("###################################################################\n"); + VerbosePrintFormat("# Server IP: {0}\n", host); + VerbosePrintFormat("# User: {0}\n", user); + VerbosePrintFormat("# Password: {0}\n", password); + VerbosePrintFormat("# Number of Columns per record: {0}\n", colsPerRecord); + VerbosePrintFormat("# Number of Threads: {0}\n", numOfThreads); + VerbosePrintFormat("# Number of Tables: {0}\n", numOfTables); + VerbosePrintFormat("# Number of records per Table: {0}\n", recordsPerTable); + VerbosePrintFormat("# Records/Request: {0}\n", recordsPerRequest); + VerbosePrintFormat("# Database name: {0}\n", dbName); + VerbosePrintFormat("# Replica: {0}\n", replica); + VerbosePrintFormat("# Use STable: {0}\n", useStable); + VerbosePrintFormat("# Table prefix: {0}\n", tablePrefix); if (useStable == true) { VerbosePrintFormat("# STable prefix: {0}\n", stablePrefix); } - VerbosePrintFormat ("# Data order: {0}\n", order); - VerbosePrintFormat ("# Data out of order rate: {0}\n", rateOfOutorder); - VerbosePrintFormat ("# Delete method: {0}\n", methodOfDelete); - VerbosePrintFormat ("# Query command: {0}\n", query); - VerbosePrintFormat ("# Query Mode: {0}\n", queryMode); - VerbosePrintFormat ("# Insert Only: {0}\n", isInsertOnly); - VerbosePrintFormat ("# Verbose output {0}\n", verbose); - VerbosePrintFormat ("# Test time: {0}\n", DateTime.Now.ToString("h:mm:ss tt")); + VerbosePrintFormat("# Data order: {0}\n", order); + VerbosePrintFormat("# Data out of order rate: {0}\n", rateOfOutorder); + VerbosePrintFormat("# Delete method: {0}\n", methodOfDelete); + VerbosePrintFormat("# Query command: {0}\n", query); + VerbosePrintFormat("# Query Mode: {0}\n", queryMode); + VerbosePrintFormat("# Insert Only: {0}\n", isInsertOnly); + VerbosePrintFormat("# Verbose output {0}\n", verbose); + VerbosePrintFormat("# Test time: {0}\n", DateTime.Now.ToString("h:mm:ss tt")); - VerbosePrint ("###################################################################\n"); + VerbosePrint("###################################################################\n"); if (skipReadKey == false) { @@ -388,7 +388,7 @@ namespace TDengineDriver public void CreateDb() { StringBuilder sql = new StringBuilder(); - sql.Append("CREATE DATABASE IF NOT EXISTS ").Append(this.dbName).Append(" replica ").Append(this.replica); + sql.Append("CREATE DATABASE IF NOT EXISTS ").Append(this.dbName).Append(" replica ").Append(this.replica).Append(" keep 36500"); IntPtr res = TDengine.Query(this.conn, sql.ToString()); if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { @@ -413,7 +413,7 @@ namespace TDengineDriver sql.Clear(); sql.Append("CREATE TABLE IF NOT EXISTS "). Append(this.dbName).Append(".").Append(this.stablePrefix). - Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10)) tags(t1 int)"); + Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10), v10 tinyint unsigned, v11 smallint unsigned, v12 int unsigned, v13 bigint unsigned) tags(t1 int)"); IntPtr res = TDengine.Query(this.conn, sql.ToString()); if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { @@ -538,7 +538,7 @@ namespace TDengineDriver int offset = IntPtr.Size * fields; IntPtr data = Marshal.ReadIntPtr(rowdata, offset); - builder.Append("---"); + builder.Append(" | "); if (data == IntPtr.Zero) { @@ -553,7 +553,7 @@ namespace TDengineDriver builder.Append(v1); break; case TDengineDataType.TSDB_DATA_TYPE_TINYINT: - byte v2 = Marshal.ReadByte(data); + sbyte v2 = (sbyte)Marshal.ReadByte(data); builder.Append(v2); break; case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: @@ -588,9 +588,25 @@ namespace TDengineDriver string v10 = Marshal.PtrToStringAnsi(data); builder.Append(v10); break; + case TDengineDataType.TSDB_DATA_TYPE_UTINYINT: + byte v11 = Marshal.ReadByte(data); + builder.Append(v11); + break; + case TDengineDataType.TSDB_DATA_TYPE_USMALLINT: + ushort v12 = (ushort)Marshal.ReadInt16(data); + builder.Append(v12); + break; + case TDengineDataType.TSDB_DATA_TYPE_UINT: + uint v13 = (uint)Marshal.ReadInt32(data); + builder.Append(v13); + break; + case TDengineDataType.TSDB_DATA_TYPE_UBIGINT: + ulong v14 = (ulong)Marshal.ReadInt64(data); + builder.Append(v14); + break; } } - builder.Append("---"); + builder.Append(" | "); VerbosePrint(builder.ToString() + "\n"); builder.Clear(); @@ -657,8 +673,8 @@ namespace TDengineDriver tester.ExecuteQuery(); watch.Stop(); elapsedMs = watch.Elapsed.TotalMilliseconds; - Console.WriteLine("C# taosdemo: Spent {0} seconds to query {1} records.\n", - elapsedMs/1000, + Console.WriteLine("C# taosdemo: Spent {0} seconds to query {1} records.\n", + elapsedMs / 1000, tester.recordsPerTable * tester.numOfTables ); } @@ -727,9 +743,9 @@ namespace TDengineDriver int m = now.Minute; int s = now.Second; - long baseTimestamp = 1609430400000; // 2021/01/01 0:0:0 + long baseTimestamp = -16094340000; // 1969-06-29 01:21:00 VerbosePrintFormat("beginTime is {0} + {1}h:{2}m:{3}s\n", baseTimestamp, h, m, s); - long beginTimestamp = baseTimestamp + ((h*60 + m) * 60 + s) * 1000; + long beginTimestamp = baseTimestamp + ((h * 60 + m) * 60 + s) * 1000; Random random = new Random(); long rowsInserted = 0; @@ -770,11 +786,16 @@ namespace TDengineDriver sql.Append("(") .Append(writeTimeStamp) - .Append(", 1, 2, 3,") - .Append(i + batch) - .Append(", 5, 6, 7, 'abc', 'def')"); + .Append(", 1, -2, -3,") + .Append(i + batch - 127) + .Append(", -5, -6, -7, 'abc', 'def', 254, 65534,") + .Append(4294967294 - (uint)i - (uint)batch) + .Append(",") + .Append(18446744073709551614 - (ulong)i - (ulong)batch) + .Append(")"); } + VerbosePrint(sql.ToString() + "\n"); IntPtr res = TDengine.Query(this.conn, sql.ToString()); if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { @@ -856,7 +877,7 @@ namespace TDengineDriver } else { - sql = sql.Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10))"); + sql = sql.Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10), v10 tinyint unsigned, v11 smallint unsigned, v12 int unsigned, v13 bigint unsigned)"); } IntPtr res = TDengine.Query(this.conn, sql.ToString()); if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) diff --git a/tests/examples/JDBC/springbootdemo/pom.xml b/tests/examples/JDBC/springbootdemo/pom.xml index bd5f7efbc0..6c83718896 100644 --- a/tests/examples/JDBC/springbootdemo/pom.xml +++ b/tests/examples/JDBC/springbootdemo/pom.xml @@ -63,9 +63,9 @@ com.taosdata.jdbc taos-jdbcdriver - 2.0.20 + 2.0.28 - + diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java index 8f30c29946..fa10f3b092 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java @@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @MapperScan(basePackages = {"com.taosdata.example.springbootdemo.dao"}) @SpringBootApplication public class SpringbootdemoApplication { + public static void main(String[] args) { SpringApplication.run(SpringbootdemoApplication.class, args); } diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java index c153e27701..cf14f5d84a 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java @@ -45,7 +45,7 @@ public class WeatherController { * @return */ @PostMapping("/{temperature}/{humidity}") - public int saveWeather(@PathVariable float temperature, @PathVariable int humidity) { + public int saveWeather(@PathVariable float temperature, @PathVariable float humidity) { return weatherService.save(temperature, humidity); } diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java index 255b2cdca9..c11b9a6f50 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java @@ -8,8 +8,8 @@ public class Weather { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8") private Timestamp ts; - private float temperature; - private float humidity; + private Float temperature; + private Float humidity; private String location; private int groupId; @@ -30,19 +30,19 @@ public class Weather { this.ts = ts; } - public float getTemperature() { + public Float getTemperature() { return temperature; } - public void setTemperature(float temperature) { + public void setTemperature(Float temperature) { this.temperature = temperature; } - public float getHumidity() { + public Float getHumidity() { return humidity; } - public void setHumidity(float humidity) { + public void setHumidity(Float humidity) { this.humidity = humidity; } diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java index 0aef828e1c..26d09c7d12 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java @@ -39,7 +39,7 @@ public class WeatherService { return weatherMapper.select(limit, offset); } - public int save(float temperature, int humidity) { + public int save(float temperature, float humidity) { Weather weather = new Weather(); weather.setTemperature(temperature); weather.setHumidity(humidity); diff --git a/tests/examples/c/epoll.c b/tests/examples/c/epoll.c index de7c5989d1..284268ac43 100644 --- a/tests/examples/c/epoll.c +++ b/tests/examples/c/epoll.c @@ -20,7 +20,7 @@ // monitor and compare : glances #ifdef __APPLE__ -#include "eok.h" +#include "osEok.h" #else // __APPLE__ #include #endif // __APPLE__ diff --git a/tests/pytest/import_merge/importDataLastS.py b/tests/pytest/import_merge/importDataLastS.py index 2c1559d290..4e5701deb1 100644 --- a/tests/pytest/import_merge/importDataLastS.py +++ b/tests/pytest/import_merge/importDataLastS.py @@ -54,8 +54,8 @@ class TDTestCase: tdSql.execute(" ".join(sqlcmd)) tdLog.info("================= step3") - tdSql.query('select * from tb1') - tdSql.checkRows(205) + tdSql.query('select count(*) from tb1') + tdSql.checkData(0, 0, 205) tdLog.info("================= step4") tdDnodes.stop(1) @@ -71,8 +71,8 @@ class TDTestCase: tdSql.execute(" ".join(sqlcmd)) tdLog.info("================= step6") - tdSql.query('select * from tb1') - tdSql.checkRows(250) + tdSql.query('select count(*) from tb1') + tdSql.checkData(0, 0, 250) def stop(self): tdSql.close() diff --git a/tests/pytest/insert/boundary2.py b/tests/pytest/insert/boundary2.py index 99784b7cd9..8a6fd1e6a1 100644 --- a/tests/pytest/insert/boundary2.py +++ b/tests/pytest/insert/boundary2.py @@ -50,14 +50,16 @@ class TDTestCase: sql += "'%s')" % self.get_random_string(22) tdSql.execute(sql % (self.ts + i)) - tdSql.query("select * from stb") - tdSql.checkRows(4096) + time.sleep(10) + tdSql.query("select count(*) from stb") + tdSql.checkData(0, 0, 4096) tdDnodes.stop(1) tdDnodes.start(1) - - tdSql.query("select * from stb") - tdSql.checkRows(4096) + + time.sleep(1) + tdSql.query("select count(*) from stb") + tdSql.checkData(0, 0, 4096) endTime = time.time() diff --git a/tests/script/general/parser/alter1.sim b/tests/script/general/parser/alter1.sim index a52202fc1a..3b6b0d9465 100644 --- a/tests/script/general/parser/alter1.sim +++ b/tests/script/general/parser/alter1.sim @@ -129,8 +129,8 @@ if $rows != 3 then return -1 endi -sql drop database $db -sql show databases -if $rows != 0 then - return -1 -endi +#sql drop database $db +#sql show databases +#if $rows != 0 then +# return -1 +#endi diff --git a/tests/script/general/parser/col_arithmetic_query.sim b/tests/script/general/parser/col_arithmetic_query.sim index 2c56c6445f..191f56fcfb 100644 --- a/tests/script/general/parser/col_arithmetic_query.sim +++ b/tests/script/general/parser/col_arithmetic_query.sim @@ -414,6 +414,7 @@ if $rows != 1 then endi if $data00 != 0.204545455 then + print expect 0.204545455, actual: $data00 return -1 endi diff --git a/tests/script/general/parser/having.sim b/tests/script/general/parser/having.sim index 2e95664d31..ddafdd7329 100644 --- a/tests/script/general/parser/having.sim +++ b/tests/script/general/parser/having.sim @@ -141,9 +141,7 @@ if $data30 != 4 then endi sql_error select top(f1,2) from st2 group by f1 having count(f2) > 0; - sql_error select top(f1,2) from st2 group by f1 having count(f2) > 0; - sql_error select top(f1,2) from st2 group by f1 having avg(f1) > 0; sql select avg(f1),count(f1) from st2 group by f1 having avg(f1) > 2; diff --git a/tests/script/general/parser/having_child.sim b/tests/script/general/parser/having_child.sim index 1f29a63b91..a38db3fe44 100644 --- a/tests/script/general/parser/having_child.sim +++ b/tests/script/general/parser/having_child.sim @@ -1,6 +1,6 @@ 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 walLevel -v 1 system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2 system sh/exec.sh -n dnode1 -s start @@ -1460,8 +1460,7 @@ if $data03 != 0.000000000 then return -1 endi -sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having avg(f1) < 0 and avg(f1) = 3; - +#sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having avg(f1) < 0 and avg(f1) = 3; sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by id1 having avg(f1) < 2; sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f1 > 0 group by f1 having avg(f1) > 0; diff --git a/tests/script/general/parser/join_multivnode.sim b/tests/script/general/parser/join_multivnode.sim index 2322496a94..c72b2c5b3e 100644 --- a/tests/script/general/parser/join_multivnode.sim +++ b/tests/script/general/parser/join_multivnode.sim @@ -142,7 +142,7 @@ if $rows != 300 then endi if $data00 != @70-01-01 08:01:40.990@ then - print expect 0, actual: $data00 + print expect 70-01-01 08:01:40.990, actual: $data00 return -1 endi diff --git a/tests/script/general/parser/limit2_query.sim b/tests/script/general/parser/limit2_query.sim index 9fe287960d..c35fd369ca 100644 --- a/tests/script/general/parser/limit2_query.sim +++ b/tests/script/general/parser/limit2_query.sim @@ -148,6 +148,9 @@ if $rows != 8200 then return -1 endi +sql select max(c1) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 interval(5m) fill(value, -1000) limit 100000; + + sql select max(c1) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 interval(5m) fill(value, -1000, -2) limit 10 offset 8190; if $rows != 10 then return -1 diff --git a/tests/script/general/parser/select_with_tags.sim b/tests/script/general/parser/select_with_tags.sim index 9f445649e1..7e5f31f759 100644 --- a/tests/script/general/parser/select_with_tags.sim +++ b/tests/script/general/parser/select_with_tags.sim @@ -26,7 +26,7 @@ sql drop database if exists $db -x step1 step1: sql create database if not exists $db keep 36500 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, t2 binary(12)) +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, t2 binary(12), t3 int) $i = 0 $j = 1 @@ -36,7 +36,7 @@ while $i < $tbNum $tg2 = ' . abc $tg2 = $tg2 . $i $tg2 = $tg2 . ' - sql create table $tb using $mt tags( $i , $tg2 ) + sql create table $tb using $mt tags( $i , $tg2 , 123 ) $x = 0 while $x < $rowNum @@ -85,6 +85,7 @@ if $data00 != @70-01-01 08:01:40.000@ then endi if $data01 != @select_tags_tb0@ then + print expect: select_tags_tb0, actual: $data01 return -1 endi @@ -813,7 +814,46 @@ if $row != 1 then return -1 endi -print ======= selectivity + tags+ group by + tags + filter + interval + join=========== +print TODO ======= selectivity + tags+ group by + tags + filter + interval + join=========== + +print ==========================mix tag columns and group by columns====================== +sql select top(c1, 100), tbname from select_tags_mt0 where tbname in ('select_tags_tb0', 'select_tags_tb1') group by t3 +if $rows != 100 then + return -1 +endi + +if $data00 != @70-01-01 08:01:40.094@ then + print expect: 70-01-01 08:01:40.094, actual: $data00 + return -1 +endi + +if $data01 != 94 then + return -1 +endi + +if $data02 != @select_tags_tb0@ then + return -1 +endi + +if $data03 != 123 then + return -1 +endi + +if $data10 != @70-01-01 08:01:40.095@ then + return -1 +endi + +if $data11 != 95 then + return -1 +endi + +if $data12 != @select_tags_tb0@ then + return -1 +endi + +if $data13 != 123 then + return -1 +endi print ======error sql============================================= diff --git a/tests/script/general/parser/subInfrom.sim b/tests/script/general/parser/subInfrom.sim new file mode 100644 index 0000000000..e47831ee87 --- /dev/null +++ b/tests/script/general/parser/subInfrom.sim @@ -0,0 +1,147 @@ +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 +sleep 100 + +print ========== sub_in_from.sim +$i = 0 + +$dbPrefix = subdb +$tbPrefix = sub_tb +$stbPrefix = sub_stb +$tbNum = 10 +$rowNum = 1000 +$totalNum = $tbNum * $rowNum +$loops = 200000 +$log = 10000 +$ts0 = 1537146000000 +$delta = 600000 +$i = 0 +$db = $dbPrefix . $i +$stb = $stbPrefix . $i + +sql drop database $db -x step1 +step1: +sql create database $db cache 16 maxrows 4096 keep 36500 +print ====== create tables +sql use $db +sql create table $stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 smallint, c6 tinyint, c7 bool, c8 binary(10), c9 nchar(10)) tags(t1 int) + +$i = 0 +$ts = $ts0 +$halfNum = $tbNum / 2 +while $i < $halfNum + $tbId = $i + $halfNum + $tb = $tbPrefix . $i + $tb1 = $tbPrefix . $tbId + sql create table $tb using $stb tags( $i ) + sql create table $tb1 using $stb tags( $tbId ) + + $x = 0 + while $x < $rowNum + $xs = $x * $delta + $ts = $ts0 + $xs + $c = $x / 10 + $c = $c * 10 + $c = $x - $c + $binary = 'binary . $c + $binary = $binary . ' + $nchar = 'nchar . $c + $nchar = $nchar . ' + sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) + sql insert into $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) + $x = $x + 1 + endw + + $i = $i + 1 +endw +print ====== tables created + +sql_error select count(*) from (select count(*) from abc.sub_stb0) +sql_error select val + 20 from (select count(*) from sub_stb0 interval(10h)) +sql_error select abc+20 from (select count(*) from sub_stb0 interval(1s)) + +sql select count(*) from (select count(*) from sub_stb0 interval(10h)) +if $rows != 1 then + return -1 +endi + +if $data00 != 18 then + print expect 18, actual: $data00 + return -1 +endi + +sql select ts from (select count(*) from sub_stb0 interval(10h)) +if $rows != 18 then + return -1 +endi + +if $data00 != @18-09-17 04:00:00.000@ then + return -1 +endi + +if $data01 != @18-09-17 14:00:00.000@ then + return -1 +endi + +sql select val + 20, val from (select count(*) as val from sub_stb0 interval(10h)) +if $rows != 18 then + return -1 +endi + +if $data00 != 320.000000 then + return -1 +endi + +if $data01 != 300 then + return -1 +endi + +if $data10 != 620 then + return -1 +endi + +if $data11 != 600 then + return -1 +endi + +if $data20 != 620 then + return -1 +endi + +if $data21 != 600 then + return -1 +endi + +sql select max(val), min(val), max(val) - min(val) from (select count(*) val from sub_stb0 interval(10h)) +if $rows != 1 then + return -1 +endi + +if $data00 != 600 then + return -1 +endi + +if $data01 != 100 then + return -1 +endi + +if $data02 != 500.000000 then + return -1 +endi + +sql select first(ts,val),last(ts,val) from (select count(*) val from sub_stb0 interval(10h)) +sql select top(val, 5) from (select count(*) val from sub_stb0 interval(10h)) +sql select diff(val) from (select count(*) val from sub_stb0 interval(10h)) +sql select apercentile(val, 50) from (select count(*) val from sub_stb0 interval(10h)) + +# not support yet +sql select percentile(val, 50) from (select count(*) val from sub_stb0 interval(10h)) +sql select stddev(val) from (select count(*) val from sub_stb0 interval(10h)) + +print ====================>complex query + diff --git a/tests/script/general/parser/testSuite.sim b/tests/script/general/parser/testSuite.sim index f05474d158..62af4818e5 100644 --- a/tests/script/general/parser/testSuite.sim +++ b/tests/script/general/parser/testSuite.sim @@ -17,7 +17,7 @@ run general/parser/first_last.sim run general/parser/import_commit1.sim run general/parser/import_commit2.sim run general/parser/import_commit3.sim -#run general/parser/import_file.sim +run general/parser/import_file.sim run general/parser/insert_tb.sim run general/parser/tags_dynamically_specifiy.sim run general/parser/interp.sim @@ -38,12 +38,12 @@ run general/parser/slimit.sim run general/parser/slimit1.sim run general/parser/slimit_alter_tags.sim run general/parser/tbnameIn.sim -run general/parser/slimit_alter_tags.sim # persistent failed run general/parser/join.sim run general/parser/join_multivnode.sim run general/parser/join_manyblocks.sim run general/parser/projection_limit_offset.sim run general/parser/select_with_tags.sim +run general/parser/select_distinct_tag.sim run general/parser/groupby.sim run general/parser/tags_filter.sim run general/parser/topbot.sim @@ -54,5 +54,5 @@ run general/parser/timestamp.sim run general/parser/sliding.sim run general/parser/function.sim run general/parser/stableOp.sim -run general/parser/slimit_alter_tags.sim - +run general/parser/having.sim +run general/parser/having_child.sim \ No newline at end of file diff --git a/tests/script/test.sh b/tests/script/test.sh index 1c7a7527ab..a092a38a2d 100755 --- a/tests/script/test.sh +++ b/tests/script/test.sh @@ -132,6 +132,7 @@ if [ -n "$FILE_NAME" ]; then else echo "ExcuteCmd:" $PROGRAM -c $CFG_DIR -f $FILE_NAME $PROGRAM -c $CFG_DIR -f $FILE_NAME +# valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes --log-file=${CODE_DIR}/../script/valgrind.log $PROGRAM -c $CFG_DIR -f $FILE_NAME fi else echo "ExcuteCmd:" $PROGRAM -c $CFG_DIR -f basicSuite.sim diff --git a/tests/tsim/src/simSystem.c b/tests/tsim/src/simSystem.c index dda1e133de..0879e371ef 100644 --- a/tests/tsim/src/simSystem.c +++ b/tests/tsim/src/simSystem.c @@ -166,7 +166,7 @@ void *simExecuteScript(void *inputScript) { if (script->killed || script->linePos >= script->numOfLines) { script = simProcessCallOver(script); if (script == NULL) { - printf("abort now!\n"); + simDebug("sim test abort now!"); break; } } else {