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