diff --git a/.travis.yml b/.travis.yml
index d814a465e67468fc05c2d03b62c092a9c5130e22..0617d759768251fcf09aa2316f3556f20c1718d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -171,6 +171,8 @@ matrix:
- build-essential
- cmake
- binutils-2.26
+ - unixodbc
+ - unixodbc-dev
env:
- DESC="trusty/gcc-4.8/bintuils-2.26 build"
@@ -198,6 +200,8 @@ matrix:
packages:
- build-essential
- cmake
+ - unixodbc
+ - unixodbc-dev
before_script:
- export TZ=Asia/Harbin
@@ -252,6 +256,8 @@ matrix:
packages:
- build-essential
- cmake
+ - unixodbc
+ - unixodbc-dev
env:
- DESC="arm64 xenial build"
@@ -280,6 +286,7 @@ matrix:
addons:
homebrew:
- cmake
+ - unixodbc
script:
- cd ${TRAVIS_BUILD_DIR}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7bb36fe1b001473cf5641ad195959581affeb2cb..be97e679d1c2ca6229013a96e8946d6a18068ed3 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,7 @@ SET(TD_GRANT FALSE)
SET(TD_MQTT FALSE)
SET(TD_TSDB_PLUGINS FALSE)
SET(TD_STORAGE FALSE)
+SET(TD_TOPIC FALSE)
SET(TD_COVER FALSE)
SET(TD_MEM_CHECK FALSE)
diff --git a/README-CN.md b/README-CN.md
new file mode 100644
index 0000000000000000000000000000000000000000..9601cde3af526800a407c8bf9af8694e01e5641e
--- /dev/null
+++ b/README-CN.md
@@ -0,0 +1,267 @@
+[![Build Status](https://travis-ci.org/taosdata/TDengine.svg?branch=master)](https://travis-ci.org/taosdata/TDengine)
+[![Build status](https://ci.appveyor.com/api/projects/status/kf3pwh2or5afsgl9/branch/master?svg=true)](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master)
+[![Coverage Status](https://coveralls.io/repos/github/taosdata/TDengine/badge.svg?branch=develop)](https://coveralls.io/github/taosdata/TDengine?branch=develop)
+[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4201/badge)](https://bestpractices.coreinfrastructure.org/projects/4201)
+[![tdengine](https://snapcraft.io//tdengine/badge.svg)](https://snapcraft.io/tdengine)
+
+[![TDengine](TDenginelogo.png)](https://www.taosdata.com)
+
+简体中文 | [English](./README.md)
+
+# TDengine 简介
+
+TDengine是涛思数据专为物联网、车联网、工业互联网、IT运维等设计和优化的大数据平台。除核心的快10倍以上的时序数据库功能外,还提供缓存、数据订阅、流式计算等功能,最大程度减少研发和运维的复杂度,且核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。
+
+- 10 倍以上性能提升。定义了创新的数据存储结构,单核每秒就能处理至少2万次请求,插入数百万个数据点,读出一千万以上数据点,比现有通用数据库快了十倍以上。
+- 硬件或云服务成本降至1/5。由于超强性能,计算资源不到通用大数据方案的1/5;通过列式存储和先进的压缩算法,存储空间不到通用数据库的1/10。
+- 全栈时序数据处理引擎。将数据库、消息队列、缓存、流式计算等功能融合一起,应用无需再集成Kafka/Redis/HBase/Spark等软件,大幅降低应用开发和维护成本。
+- 强大的分析功能。无论是十年前还是一秒钟前的数据,指定时间范围即可查询。数据可在时间轴上或多个设备上进行聚合。即席查询可通过Shell/Python/R/Matlab随时进行。
+- 与第三方工具无缝连接。不用一行代码,即可与Telegraf, Grafana, EMQ X, Prometheus, Matlab, R集成。后续还将支持MQTT, OPC, Hadoop,Spark等, BI工具也将无缝连接。
+- 零运维成本、零学习成本。安装、集群一秒搞定,无需分库分表,实时备份。标准SQL,支持JDBC,RESTful,支持Python/Java/C/C++/Go/Node.JS, 与MySQL相似,零学习成本。
+
+# 文档
+
+TDengine是一个高效的存储、查询、分析时序大数据的平台,专为物联网、车联网、工业互联网、运维监测等优化而设计。您可以像使用关系型数据库MySQL一样来使用它,但建议您在使用前仔细阅读一遍下面的文档,特别是 [数据模型](https://www.taosdata.com/cn/documentation/architecture) 与 [数据建模](https://www.taosdata.com/cn/documentation/model)。除本文档之外,欢迎 [下载产品白皮书](https://www.taosdata.com/downloads/TDengine%20White%20Paper.pdf)。
+
+# 生成
+
+TDengine目前2.0版服务器仅能在Linux系统上安装和运行,后续会支持Windows、macOS等系统。客户端可以在Windows或Linux上安装和运行。任何OS的应用也可以选择RESTful接口连接服务器taosd。CPU支持X64/ARM64/MIPS64/Alpha64,后续会支持ARM32、RISC-V等CPU架构。用户可根据需求选择通过[源码](https://www.taosdata.com/cn/getting-started/#通过源码安装)或者[安装包](https://www.taosdata.com/cn/getting-started/#通过安装包安装)来安装。本快速指南仅适用于通过源码安装。
+
+## 安装工具
+
+### Ubuntu 16.04 及以上版本 & Debian:
+
+```bash
+sudo apt-get install -y gcc cmake build-essential git
+```
+
+### Ubuntu 14.04:
+
+```bash
+sudo apt-get install -y gcc cmake3 build-essential git binutils-2.26
+export PATH=/usr/lib/binutils-2.26/bin:$PATH
+```
+
+编译或打包 JDBC 驱动源码,需安装 Java JDK 8 或以上版本和 Apache Maven 2.7 或以上版本。
+
+安装 OpenJDK 8:
+
+```bash
+sudo apt-get install -y openjdk-8-jdk
+```
+
+安装 Apache Maven:
+
+```bash
+sudo apt-get install -y maven
+```
+
+### CentOS 7:
+
+```bash
+sudo yum install -y gcc gcc-c++ make cmake git
+```
+
+安装 OpenJDK 8:
+
+```bash
+sudo yum install -y java-1.8.0-openjdk
+```
+
+安装 Apache Maven:
+
+```bash
+sudo yum install -y maven
+```
+
+### CentOS 8 & Fedora:
+
+```bash
+sudo dnf install -y gcc gcc-c++ make cmake epel-release git
+```
+
+安装 OpenJDK 8:
+
+```bash
+sudo dnf install -y java-1.8.0-openjdk
+```
+
+安装 Apache Maven:
+
+```bash
+sudo dnf install -y maven
+```
+
+## 获取源码
+
+首先,你需要从 GitHub 克隆源码:
+
+```bash
+git clone https://github.com/taosdata/TDengine.git
+cd TDengine
+```
+
+Go 连接器和 Grafana 插件在其他独立仓库,如果安装它们的话,需要在 TDengine 目录下通过此命令安装:
+
+```bash
+git submodule update --init --recursive
+```
+
+## 生成 TDengine
+
+### Linux 系统
+
+```bash
+mkdir debug && cd debug
+cmake .. && cmake --build .
+```
+
+在X86-64、X86、arm64 和 arm32 平台上,TDengine 生成脚本可以自动检测机器架构。也可以手动配置 CPUTYPE 参数来指定 CPU 类型,如 aarch64 或 aarch32 等。
+
+aarch64:
+
+```bash
+cmake .. -DCPUTYPE=aarch64 && cmake --build .
+```
+
+aarch32:
+
+```bash
+cmake .. -DCPUTYPE=aarch32 && cmake --build .
+```
+
+### Windows 系统
+
+如果你使用的是 Visual Studio 2013 版本:
+
+打开 cmd.exe,执行 vcvarsall.bat 时,为 64 位操作系统指定“x86_amd64”,为 32 位操作系统指定“x86”。
+
+```bash
+mkdir debug && cd debug
+"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" < x86_amd64 | x86 >
+cmake .. -G "NMake Makefiles"
+nmake
+```
+
+如果你使用的是 Visual Studio 2019 或 2017 版本:
+
+打开cmd.exe,执行 vcvarsall.bat 时,为 64 位操作系统指定“x64”,为 32 位操作系统指定“x86”。
+
+```bash
+mkdir debug && cd debug
+"c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" < x64 | x86 >
+cmake .. -G "NMake Makefiles"
+nmake
+```
+
+你也可以从开始菜单中找到"Visual Studio < 2019 | 2017 >"菜单项,根据你的系统选择"x64 Native Tools Command Prompt for VS < 2019 | 2017 >"或"x86 Native Tools Command Prompt for VS < 2019 | 2017 >",打开命令行窗口,执行:
+
+```bash
+mkdir debug && cd debug
+cmake .. -G "NMake Makefiles"
+nmake
+```
+
+### Mac OS X 系统
+
+安装 Xcode 命令行工具和 cmake. 在 Catalina 和 Big Sur 操作系统上,需要安装 XCode 11.4+ 版本。
+
+```bash
+mkdir debug && cd debug
+cmake .. && cmake --build .
+```
+
+# 安装
+
+如果你不想安装,可以直接在shell中运行。生成完成后,安装 TDengine:
+```bash
+make install
+```
+
+用户可以在[文件目录结构](https://www.taosdata.com/cn/documentation/administrator#directories)中了解更多在操作系统中生成的目录或文件。
+
+安装成功后,在终端中启动 TDengine 服务:
+
+```bash
+taosd
+```
+
+用户可以使用 TDengine Shell 来连接 TDengine 服务,在终端中,输入:
+
+```bash
+taos
+```
+
+如果 TDengine Shell 连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印出错误消息。
+
+## 快速运行
+
+TDengine 生成后,在终端执行以下命令:
+
+```bash
+./build/bin/taosd -c test/cfg
+```
+
+在另一个终端,使用 TDengine shell 连接服务器:
+
+```bash
+./build/bin/taos -c test/cfg
+```
+
+"-c test/cfg"指定系统配置文件所在目录。
+
+# 体验 TDengine
+
+在TDengine终端中,用户可以通过SQL命令来创建/删除数据库、表等,并进行插入查询操作。
+
+```bash
+create database demo;
+use demo;
+create table t (ts timestamp, speed int);
+insert into t values ('2019-07-15 00:00:00', 10);
+insert into t values ('2019-07-15 01:00:00', 20);
+select * from t;
+ ts | speed |
+===================================
+ 19-07-15 00:00:00.000| 10|
+ 19-07-15 01:00:00.000| 20|
+Query OK, 2 row(s) in set (0.001700s)
+```
+
+# 应用开发
+
+## 官方连接器
+
+TDengine 提供了丰富的应用程序开发接口,其中包括C/C++、Java、Python、Go、Node.js、C# 、RESTful 等,便于用户快速开发应用:
+
+- Java
+
+- C/C++
+
+- Python
+
+- Go
+
+- RESTful API
+
+- Node.js
+
+## 第三方连接器
+
+TDengine 社区生态中也有一些非常友好的第三方连接器,可以通过以下链接访问它们的源码。
+
+- [Rust Connector](https://github.com/taosdata/TDengine/tree/master/tests/examples/rust)
+- [.Net Core Connector](https://github.com/maikebing/Maikebing.EntityFrameworkCore.Taos)
+- [Lua Connector](https://github.com/taosdata/TDengine/tree/develop/tests/examples/lua)
+
+# 运行和添加测试例
+
+TDengine 的测试框架和所有测试例全部开源。
+
+点击[这里](tests/How-To-Run-Test-And-How-To-Add-New-Test-Case.md),了解如何运行测试例和添加新的测试例。
+
+# 成为社区贡献者
+点击[这里](https://www.taosdata.com/cn/contributor/),了解如何成为 TDengine 的贡献者。
+
+#加入技术交流群
+TDengine官方社群「物联网大数据群」对外开放,欢迎您加入讨论。搜索微信号 "tdengine",加小T为好友,即可入群。
diff --git a/README.md b/README.md
index 489b6d0a4e12db06c9f2c1274e7a87f22cf76655..79c140c741c1164633e5a2953db9c2d86569e01f 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,8 @@
[![TDengine](TDenginelogo.png)](https://www.taosdata.com)
+English | [简体中文](./README-CN.md)
+
# What is TDengine?
TDengine is an open-sourced big data platform under [GNU AGPL v3.0](http://www.gnu.org/licenses/agpl-3.0.html), designed and optimized for the Internet of Things (IoT), Connected Cars, Industrial IoT, and IT Infrastructure and Application Monitoring. Besides the 10x faster time-series database, it provides caching, stream computing, message queuing and other functionalities to reduce the complexity and cost of development and operation.
@@ -29,7 +31,7 @@ For user manual, system design and architecture, engineering blogs, refer to [TD
# Building
At the moment, TDengine only supports building and running on Linux systems. You can choose to [install from packages](https://www.taosdata.com/en/getting-started/#Install-from-Package) or from the source code. This quick guide is for installation from the source only.
-To build TDengine, use [CMake](https://cmake.org/) 3.5 or higher versions in the project directory.
+To build TDengine, use [CMake](https://cmake.org/) 2.8.12.x or higher versions in the project directory.
## Install tools
@@ -160,39 +162,42 @@ mkdir debug && cd debug
cmake .. && cmake --build .
```
-# Quick Run
-
-# Quick Run
-To quickly start a TDengine server after building, run the command below in terminal:
-```bash
-./build/bin/taosd -c test/cfg
-```
-In another terminal, use the TDengine shell to connect the server:
-```bash
-./build/bin/taos -c test/cfg
-```
-option "-c test/cfg" specifies the system configuration file directory.
-
# Installing
+
After building successfully, TDengine can be installed by:
```bash
-make install
+sudo make install
```
-Users can find more information about directories installed on the system in the [directory and files](https://www.taosdata.com/en/documentation/administrator/#Directory-and-Files) section. It should be noted that installing from source code does not configure service management for TDengine.
+
+Users can find more information about directories installed on the system in the [directory and files](https://www.taosdata.com/en/documentation/administrator/#Directory-and-Files) section. Since version 2.0, installing from source code will also configure service management for TDengine.
Users can also choose to [install from packages](https://www.taosdata.com/en/getting-started/#Install-from-Package) for it.
To start the service after installation, in a terminal, use:
-```cmd
-taosd
+```bash
+sudo systemctl start taosd
```
Then users can use the [TDengine shell](https://www.taosdata.com/en/getting-started/#TDengine-Shell) to connect the TDengine server. In a terminal, use:
-```cmd
+```bash
taos
```
If TDengine shell connects the server successfully, welcome messages and version info are printed. Otherwise, an error message is shown.
+## Quick Run
+
+If you don't want to run TDengine as a service, you can run it in current shell. For example, to quickly start a TDengine server after building, run the command below in terminal:
+```bash
+./build/bin/taosd -c test/cfg
+```
+
+In another terminal, use the TDengine shell to connect the server:
+```bash
+./build/bin/taos -c test/cfg
+```
+
+option "-c test/cfg" specifies the system configuration file directory.
+
# Try TDengine
It is easy to run SQL commands from TDengine shell which is the same as other SQL databases.
```sql
diff --git a/cmake/define.inc b/cmake/define.inc
index ae90410f2d6873b60ee0e355f18462983e615545..ff4583d02bd924f59701a8302a2e9d8dbb32a14f 100755
--- a/cmake/define.inc
+++ b/cmake/define.inc
@@ -25,6 +25,10 @@ IF (TD_STORAGE)
ADD_DEFINITIONS(-D_STORAGE)
ENDIF ()
+IF (TD_TOPIC)
+ ADD_DEFINITIONS(-D_TOPIC)
+ENDIF ()
+
IF (TD_GODLL)
ADD_DEFINITIONS(-D_TD_GO_DLL_)
ENDIF ()
diff --git a/cmake/input.inc b/cmake/input.inc
index e8324887a051ae6ac27eff6b748c824d1f0a3fa5..b1a993c996724d6f8948d98de3600db856a09c86 100755
--- a/cmake/input.inc
+++ b/cmake/input.inc
@@ -9,6 +9,14 @@ ELSEIF (${ACCOUNT} MATCHES "false")
MESSAGE(STATUS "Build without account plugins")
ENDIF ()
+IF (${TOPIC} MATCHES "true")
+ SET(TD_TOPIC TRUE)
+ MESSAGE(STATUS "Build with topic plugins")
+ELSEIF (${TOPIC} MATCHES "false")
+ SET(TD_TOPIC FALSE)
+ MESSAGE(STATUS "Build without topic plugins")
+ENDIF ()
+
IF (${COVER} MATCHES "true")
SET(TD_COVER TRUE)
MESSAGE(STATUS "Build with test coverage")
diff --git a/cmake/install.inc b/cmake/install.inc
index 0ea79589caef1bf3ec72f4234f99e87328759c33..1d50ca292d902461e0f77732da83076954224f06 100755
--- a/cmake/install.inc
+++ b/cmake/install.inc
@@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS)
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
IF (TD_MVN_INSTALLED)
- INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.21-dist.jar DESTINATION connector/jdbc)
+ INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.22-dist.jar DESTINATION connector/jdbc)
ENDIF ()
ELSEIF (TD_DARWIN)
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
diff --git a/cmake/version.inc b/cmake/version.inc
index 05fbef5b87a85168f43f3445acc3e5567c92fbd9..b1e09c9532ef8193b32c99180d35946cc6ef5c7e 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.17.0")
+ SET(TD_VER_NUMBER "2.0.18.0")
ENDIF ()
IF (DEFINED VERCOMPATIBLE)
diff --git a/documentation20/cn/03.architecture/docs.md b/documentation20/cn/03.architecture/docs.md
index 26d8bc55c29d283511080f420663c5fa32bf43fe..87553fa8ad9760ecdb6d1667823d336189542331 100644
--- a/documentation20/cn/03.architecture/docs.md
+++ b/documentation20/cn/03.architecture/docs.md
@@ -145,7 +145,7 @@ TDengine 建议用数据采集点的名字(如上表中的D1001)来做表名。
在TDengine的设计里,**表用来代表一个具体的数据采集点,超级表用来代表一组相同类型的数据采集点集合**。当为某个具体数据采集点创建表时,用户使用超级表的定义做模板,同时指定该具体采集点(表)的标签值。与传统的关系型数据库相比,表(一个数据采集点)是带有静态标签的,而且这些标签可以事后增加、删除、修改。**一张超级表包含有多张表,这些表具有相同的时序数据schema,但带有不同的标签值**。
-当对多个具有相同数据类型的数据采集点进行聚合操作时,TDengine将先把满足标签过滤条件的表从超级表的中查找出来,然后再扫描这些表的时序数据,进行聚合操作,这样能将需要扫描的数据集大幅减少,从而大幅提高聚合计算的性能。
+当对多个具有相同数据类型的数据采集点进行聚合操作时,TDengine会先把满足标签过滤条件的表从超级表中找出来,然后再扫描这些表的时序数据,进行聚合操作,这样需要扫描的数据集会大幅减少,从而显著提高聚合计算的性能。
## 集群与基本逻辑单元
diff --git a/documentation20/cn/08.connector/01.java/docs.md b/documentation20/cn/08.connector/01.java/docs.md
index c39f6ffb4c98e97c21369b5767eff38f0fa9fe3c..3ed7343579ef7dc9c774367a8d9b41e2dabb7561 100644
--- a/documentation20/cn/08.connector/01.java/docs.md
+++ b/documentation20/cn/08.connector/01.java/docs.md
@@ -451,7 +451,8 @@ Query OK, 1 row(s) in set (0.000141s)
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
| -------------------- | ----------------- | -------- |
-| 2.0.12 及以上 | 2.0.8.0 及以上 | 1.8.x |
+| 2.0.22 | 2.0.18.0 及以上 | 1.8.x |
+| 2.0.12 - 2.0.21 | 2.0.8.0 - 2.0.17.0 | 1.8.x |
| 2.0.4 - 2.0.11 | 2.0.0.0 - 2.0.7.x | 1.8.x |
| 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
| 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md
index 52a0da6551a332b9b578d3830d1bb8135eb30692..027828d9033c138a727d5f0e9056118681484b10 100644
--- a/documentation20/cn/11.administrator/docs.md
+++ b/documentation20/cn/11.administrator/docs.md
@@ -14,6 +14,8 @@ Memory Size = maxVgroupsPerDb * (blocks * cache + 10MB) + numOfTables * (tagSize
示例:假设是 4 核机器,cache 是缺省大小 16M, blocks 是缺省值 6,假设有 10 万张表,标签总长度是 256 字节,则总的内存需求为:4 \* (16 \* 6 + 10) + 100000 \* (0.25 + 0.5) / 1000 = 499M。
+注意:从这个公式计算得到的内存容量,应理解为系统的“必要需求”,而不是“内存总数”。在实际运行的生产系统中,由于操作系统缓存、资源管理调度等方面的需要,内存规划应当在计算结果的基础上保留一定冗余,以维持系统状态和系统性能的稳定性。
+
实际运行的系统往往会根据数据特点的不同,将数据存放在不同的 DB 里。因此做规划时,也需要考虑。
如果内存充裕,可以加大 Blocks 的配置,这样更多数据将保存在内存里,提高查询速度。
diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md
index c89dbda7a02c243e62d6bd81b6c0d78b14f67d2c..b4fa2b160aa8ec04ba3a45db0fbbca17022cbd23 100644
--- a/documentation20/cn/12.taos-sql/docs.md
+++ b/documentation20/cn/12.taos-sql/docs.md
@@ -125,7 +125,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```mysql
ALTER DATABASE db_name CACHELAST 0;
```
- CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11 版本开始支持)
+ CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11 版本开始支持,修改后需要重启服务器生效。)
**Tips**: 以上所有参数修改后都可以用show databases来确认是否修改成功。
@@ -249,7 +249,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
3) TAGS 列名不能为预留关键字;
- 4) TAGS 最多允许128个,至少1个,总长度不超过16k个字符。
+ 4) TAGS 最多允许 128 个,至少 1 个,总长度不超过 16 KB。
- **删除超级表**
@@ -331,7 +331,8 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```mysql
INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...) ...;
```
- 向表tb_name中插入多条记录
+ 向表tb_name中插入多条记录
+ **注意**:在使用“插入多条记录”方式写入数据时,不能把第一列的时间戳取值都设为now,否则会导致语句中的多条记录使用相同的时间戳,于是就可能出现相互覆盖以致这些数据行无法全部被正确保存。
- **按指定的列插入多条记录**
```mysql
diff --git a/documentation20/cn/13.faq/docs.md b/documentation20/cn/13.faq/docs.md
index d3169d507ac69d6d40eec698edf76a69a929bda2..e2285b29e244641566661cf102c7b17616a6780a 100644
--- a/documentation20/cn/13.faq/docs.md
+++ b/documentation20/cn/13.faq/docs.md
@@ -16,13 +16,13 @@
## 1. TDengine2.0之前的版本升级到2.0及以上的版本应该注意什么?☆☆☆
-2.0版本在之前版本的基础上,进行了完全的重构,配置文件和数据文件是不兼容的。在升级之前务必进行如下操作:
+2.0版在之前版本的基础上,进行了完全的重构,配置文件和数据文件是不兼容的。在升级之前务必进行如下操作:
-1. 删除配置文件,执行 sudo rm -rf /etc/taos/taos.cfg
-2. 删除日志文件,执行 sudo rm -rf /var/log/taos/
-3. 确保数据已经不再需要的前提下,删除数据文件,执行 sudo rm -rf /var/lib/taos/
-4. 安装最新稳定版本的TDengine
-5. 如果数据需要迁移数据或者数据文件损坏,请联系涛思数据官方技术支持团队,进行协助解决
+1. 删除配置文件,执行 `sudo rm -rf /etc/taos/taos.cfg`
+2. 删除日志文件,执行 `sudo rm -rf /var/log/taos/`
+3. 确保数据已经不再需要的前提下,删除数据文件,执行 `sudo rm -rf /var/lib/taos/`
+4. 安装最新稳定版本的 TDengine
+5. 如果需要迁移数据或者数据文件损坏,请联系涛思数据官方技术支持团队,进行协助解决
## 2. Windows平台下JDBCDriver找不到动态链接库,怎么办?
diff --git a/packaging/tools/remove.sh b/packaging/tools/remove.sh
index 2f2660d44635c86df3b51d2b86e37b3399869a88..e63889aff1a6eceebfc9624576270200f6e79fa7 100755
--- a/packaging/tools/remove.sh
+++ b/packaging/tools/remove.sh
@@ -213,10 +213,10 @@ fi
if echo $osinfo | grep -qwi "ubuntu" ; then
# echo "this is ubuntu system"
- ${csudo} rm -f /var/lib/dpkg/info/tdengine* || :
+ ${csudo} dpkg --force-all -P tdengine || :
elif echo $osinfo | grep -qwi "debian" ; then
# echo "this is debian system"
- ${csudo} rm -f /var/lib/dpkg/info/tdengine* || :
+ ${csudo} dpkg --force-all -P tdengine || :
elif echo $osinfo | grep -qwi "centos" ; then
# echo "this is centos system"
${csudo} rpm -e --noscripts tdengine || :
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index c7ed621815c6f4ba5553210ccac18929fb550631..88628b4db6cfafa2a9815489313ced1345f2b600 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -1,6 +1,6 @@
name: tdengine
base: core18
-version: '2.0.17.0'
+version: '2.0.18.0'
icon: snap/gui/t-dengine.svg
summary: an open-source big data platform designed and optimized for IoT.
description: |
@@ -72,7 +72,7 @@ parts:
- usr/bin/taosd
- usr/bin/taos
- usr/bin/taosdemo
- - usr/lib/libtaos.so.2.0.17.0
+ - usr/lib/libtaos.so.2.0.18.0
- usr/lib/libtaos.so.1
- usr/lib/libtaos.so
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b0f2cc0a48f906b40d7be5185ae5f081c2ed4418..8cc5cee3b51675b2d42ad62c442b2b030e802cbb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -19,6 +19,6 @@ ADD_SUBDIRECTORY(tsdb)
ADD_SUBDIRECTORY(wal)
ADD_SUBDIRECTORY(cq)
ADD_SUBDIRECTORY(dnode)
-#ADD_SUBDIRECTORY(connector/odbc)
+ADD_SUBDIRECTORY(connector/odbc)
ADD_SUBDIRECTORY(connector/jdbc)
diff --git a/src/balance/src/bnMain.c b/src/balance/src/bnMain.c
index 236b22afafb9ed6ee13acfaf6b831520f2b4d2f6..3055f77e81021c4877d97147033fc34f4c525df9 100644
--- a/src/balance/src/bnMain.c
+++ b/src/balance/src/bnMain.c
@@ -425,7 +425,7 @@ static bool bnMonitorVgroups() {
while (1) {
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
- if (pVgroup == NULL) break;
+ if (pVgroup == NULL || pVgroup->pDb == NULL) break;
int32_t dbReplica = pVgroup->pDb->cfg.replications;
int32_t vgReplica = pVgroup->numOfVnodes;
@@ -721,4 +721,4 @@ int32_t bnAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t dnode
mnodeDecDnodeRef(pDestDnode);
return code;
-}
\ No newline at end of file
+}
diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h
index 502d044d7540169497b682df96424ca3304f4668..f69ee23222119b3bc9b983c8fb24b067f11ff996 100644
--- a/src/client/inc/tscUtil.h
+++ b/src/client/inc/tscUtil.h
@@ -123,6 +123,7 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo);
+bool tscGroupbyColumn(SQueryInfo* pQueryInfo);
bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex);
bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
@@ -133,6 +134,7 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo);
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
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,
SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType);
@@ -152,7 +154,6 @@ SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_F
SInternalField* tscFieldInfoGetInternalField(SFieldInfo* pFieldInfo, int32_t index);
TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index);
-void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo);
void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo);
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index);
diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h
index 0bfbf3f946a4a1428549a493ab990a2be2173266..1740266518dd2c736feb47a5e9baa98cb66cbd94 100644
--- a/src/client/inc/tsclient.h
+++ b/src/client/inc/tsclient.h
@@ -198,9 +198,10 @@ typedef struct STableDataBlocks {
typedef struct SQueryInfo {
int16_t command; // the command may be different for each subclause, so keep it seperately.
uint32_t type; // query/insert type
+ STimeWindow window; // the whole query time window
- STimeWindow window; // query time window
- SInterval interval;
+ SInterval interval; // tumble time window
+ SSessionWindow sessionWindow; // session time window
SSqlGroupbyExpr groupbyExpr; // group by tags info
SArray * colList; // SArray
@@ -232,6 +233,7 @@ typedef struct SQueryInfo {
typedef struct {
int command;
uint8_t msgType;
+ char reserve1[3]; // fix bus error on arm32
bool autoCreated; // create table if it is not existed during retrieve table meta in mnode
union {
@@ -244,8 +246,10 @@ typedef struct {
char * curSql; // current sql, resume position of sql after parsing paused
int8_t parseFinished;
+ char reserve2[3]; // fix bus error on arm32
int16_t numOfCols;
+ char reserve3[2]; // fix bus error on arm32
uint32_t allocSize;
char * payload;
int32_t payloadLen;
@@ -255,7 +259,9 @@ typedef struct {
int32_t numOfParams;
int8_t dataSourceType; // load data from file or not
+ char reserve4[3]; // fix bus error on arm32
int8_t submitSchema; // submit block is built with table schema
+ char reserve5[3]; // fix bus error on arm32
STagData tagData; // NOTE: pTagData->data is used as a variant length array
SName **pTableNameList; // all involved tableMeta list of current insert sql statement.
@@ -397,7 +403,6 @@ typedef struct SSqlStream {
void tscSetStreamDestTable(SSqlStream* pStream, const char* dstTable);
-
int tscAcquireRpc(const char *key, const char *user, const char *secret,void **pRpcObj);
void tscReleaseRpc(void *param);
void tscInitMsgsFp();
diff --git a/src/client/src/TSDBJNIConnector.c b/src/client/src/TSDBJNIConnector.c
index a8829499a324605036beefad62d83eccf4d1c65b..56e155311e60dd0a30d3f6b5dce99c9d4c76ec7f 100644
--- a/src/client/src/TSDBJNIConnector.c
+++ b/src/client/src/TSDBJNIConnector.c
@@ -481,15 +481,19 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
case TSDB_DATA_TYPE_BOOL:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetBooleanFp, i, (jboolean)(*((char *)row[i]) == 1));
break;
+ case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_TINYINT:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetByteFp, i, (jbyte) * ((int8_t *)row[i]));
break;
+ case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_SMALLINT:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetShortFp, i, (jshort) * ((int16_t *)row[i]));
break;
+ case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_INT:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetIntFp, i, (jint) * (int32_t *)row[i]);
break;
+ case TSDB_DATA_TYPE_UBIGINT:
case TSDB_DATA_TYPE_BIGINT:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetLongFp, i, (jlong) * ((int64_t *)row[i]));
break;
diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c
index 5cba897b3028a2d6301e9363ca6180f6b41022f8..87f6058cecefbfc1bb45fd4ccff584d8d0c10aba 100644
--- a/src/client/src/tscAsync.c
+++ b/src/client/src/tscAsync.c
@@ -281,7 +281,7 @@ void tscQueueAsyncError(void(*fp), void *param, int32_t code) {
}
static void tscAsyncResultCallback(SSchedMsg *pMsg) {
- SSqlObj* pSql = pMsg->ahandle;
+ SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pMsg->ahandle);
if (pSql == NULL || pSql->signature != pSql) {
tscDebug("%p SqlObj is freed, not add into queue async res", pSql);
return;
@@ -292,23 +292,26 @@ static void tscAsyncResultCallback(SSchedMsg *pMsg) {
SSqlRes *pRes = &pSql->res;
if (pSql->fp == NULL || pSql->fetchFp == NULL){
+ taosReleaseRef(tscObjRef, pSql->self);
return;
}
pSql->fp = pSql->fetchFp;
(*pSql->fp)(pSql->param, pSql, pRes->code);
+ taosReleaseRef(tscObjRef, pSql->self);
}
void tscAsyncResultOnError(SSqlObj* pSql) {
SSchedMsg schedMsg = {0};
schedMsg.fp = tscAsyncResultCallback;
- schedMsg.ahandle = pSql;
+ schedMsg.ahandle = (void *)pSql->self;
schedMsg.thandle = (void *)1;
schedMsg.msg = 0;
taosScheduleTask(tscQhandle, &schedMsg);
}
+
int tscSendMsgToServer(SSqlObj *pSql);
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c
index 23fb0ab67cded77ff737fac4246343486e80eb95..a44b0c46ba7920c2483c4baa3b34bc37f06bdee7 100644
--- a/src/client/src/tscLocalMerge.c
+++ b/src/client/src/tscLocalMerge.c
@@ -100,6 +100,10 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalMerger *pReducer, tOrderDescr
} else if (functionId == TSDB_FUNC_APERCT) {
pCtx->param[0].i64 = pExpr->param[0].i64;
pCtx->param[0].nType = pExpr->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->interBufBytes = pExpr->interBytes;
@@ -951,10 +955,10 @@ static void doFillResult(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool doneOutp
// todo extract function
int64_t actualETime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.ekey: pQueryInfo->window.skey;
- tFilePage **pResPages = malloc(POINTER_BYTES * pQueryInfo->fieldsInfo.numOfOutput);
+ 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, sizeof(tFilePage) + pField->bytes * pLocalMerge->resColModel->capacity);
+ pResPages[i] = calloc(1, pField->bytes * pLocalMerge->resColModel->capacity);
}
while (1) {
@@ -966,7 +970,7 @@ static void doFillResult(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool doneOutp
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]->data, pResPages[i]->data + pField->bytes * pQueryInfo->limit.offset,
+ memmove(pResPages[i], ((char*)pResPages[i]) + pField->bytes * pQueryInfo->limit.offset,
(size_t)(newRows * pField->bytes));
}
}
@@ -1010,7 +1014,7 @@ static void doFillResult(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool doneOutp
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]->data, (size_t)(pField->bytes * pRes->numOfRows));
+ memcpy(pRes->data + offset * pRes->numOfRows, pResPages[i], (size_t)(pField->bytes * pRes->numOfRows));
offset += pField->bytes;
}
diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c
index a5906f5539a8d40b055f580933feb4b1184331f1..2b962333d588117ba54f363b7da586b6f04e3d47 100644
--- a/src/client/src/tscParseInsert.c
+++ b/src/client/src/tscParseInsert.c
@@ -307,7 +307,8 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SStrToken *pToken, char *payload,
return tscInvalidSQLErrMsg(msg, "illegal float data", pToken->z);
}
- *((float *)payload) = (float)dv;
+// *((float *)payload) = (float)dv;
+ SET_FLOAT_VAL(payload, dv);
}
break;
@@ -393,7 +394,7 @@ static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start
TSKEY k = *(TSKEY *)start;
- if (k == 0) {
+ if (k == INT64_MIN) {
if (pDataBlocks->tsSource == TSDB_USE_CLI_TS) {
return -1;
} else if (pDataBlocks->tsSource == -1) {
@@ -1359,7 +1360,7 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
}
}
} else {
- SSqlInfo SQLInfo = qSQLParse(pSql->sqlstr);
+ SSqlInfo SQLInfo = qSqlParse(pSql->sqlstr);
ret = tscToSQLCmd(pSql, &SQLInfo);
if (ret == TSDB_CODE_TSC_INVALID_SQL && pSql->parseRetry == 0 && SQLInfo.type == TSDB_SQL_NULL) {
tscResetSqlCmd(pCmd, true);
diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c
index c5f06a52f342b5726321925c1864d58c41afbeb4..0669d6aeb095e2410e48b86b10c724a38a5728fa 100644
--- a/src/client/src/tscPrepare.c
+++ b/src/client/src/tscPrepare.c
@@ -261,7 +261,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
return TSDB_CODE_SUCCESS;
}
- if (1) {
+ if (0) {
// allow user bind param data with different type
union {
int8_t v1;
@@ -1057,14 +1057,28 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
}
if (pStmt->isInsert) {
- SSqlObj* pSql = pStmt->pSql;
- SSqlCmd *pCmd = &pSql->cmd;
- STableDataBlocks* pBlock = taosArrayGetP(pCmd->pDataBlocks, 0);
+ SSqlCmd* pCmd = &pStmt->pSql->cmd;
+ STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
+ STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
+ if (pCmd->pTableBlockHashList == NULL) {
+ pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
+ }
+
+ STableDataBlocks* pBlock = NULL;
- assert(pCmd->numOfParams == pBlock->numOfParams);
- if (idx < 0 || idx >= pBlock->numOfParams) return -1;
+ int32_t ret =
+ tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
+ pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
+ if (ret != 0) {
+ // todo handle error
+ }
+
+ if (idx<0 || idx>=pBlock->numOfParams) {
+ tscError("param %d: out of range", idx);
+ abort();
+ }
- SParamInfo* param = pBlock->params + idx;
+ SParamInfo* param = &pBlock->params[idx];
if (type) *type = param->type;
if (bytes) *bytes = param->bytes;
diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c
index d5f8f420bf76d9a0b361480fa3255d49ecd9cf52..402770391d7ae1304da8b543e13eb58dd01886d2 100644
--- a/src/client/src/tscSQLParser.c
+++ b/src/client/src/tscSQLParser.c
@@ -75,32 +75,31 @@ static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int3
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
int8_t type, char* fieldName, SSqlExpr* pSqlExpr);
-static int32_t convertFunctionId(int32_t optr, int16_t* functionId);
static uint8_t convertOptr(SStrToken *pToken);
-static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool intervalQuery);
+static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectList, 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 intervalQuery);
+static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool twQuery);
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd);
-static int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
-static int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
-static int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
+static int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode);
+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, SQuerySQL* pQuerySQL);
-static int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema);
+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 tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
static int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
static int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
-static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type);
+static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type);
static int32_t validateEp(char* ep);
static int32_t validateDNodeConfig(SMiscInfo* pOptions);
static int32_t validateLocalConfig(SMiscInfo* pOptions);
@@ -111,15 +110,14 @@ 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, SQuerySQL* pQuerySql, SSqlObj* pSql);
+static int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t index, SQuerySqlNode* pQuerySqlNode, 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 optrToString(tSQLExpr* pExpr, char** exprString);
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, SQuerySQL* pQuerySql);
+static int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode);
static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate);
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex);
@@ -127,9 +125,13 @@ static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t column
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 doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index);
-static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid);
-static bool validateDebugFlag(int32_t flag);
+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 bool validateDebugFlag(int32_t v);
+
+static bool isTimeWindowQuery(SQueryInfo* pQueryInfo) {
+ return pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0;
+}
int16_t getNewResColId(SQueryInfo* pQueryInfo) {
return pQueryInfo->resColumnId--;
@@ -176,11 +178,11 @@ static uint8_t convertOptr(SStrToken *pToken) {
static bool validateDebugFlag(int32_t v) {
const static int validFlag[] = {131, 135, 143};
-
+
for (int i = 0; i < tListLen(validFlag); i++) {
if (v == validFlag[i]) {
return true;
- }
+ }
}
return false;
}
@@ -584,12 +586,12 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
SStrToken* t1 = taosArrayGet(pMiscInfo->a, 1);
pCmd->payload[t->n] = ' '; // add sep
strncpy(&pCmd->payload[t->n + 1], t1->z, t1->n);
- }
- return TSDB_CODE_SUCCESS;
+ }
+ return TSDB_CODE_SUCCESS;
}
case TSDB_SQL_CREATE_TABLE: {
- SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
+ SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo;
if (pCreateTable->type == TSQL_CREATE_TABLE || pCreateTable->type == TSQL_CREATE_STABLE) {
if ((code = doCheckForCreateTable(pSql, 0, pInfo)) != TSDB_CODE_SUCCESS) {
@@ -624,9 +626,9 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
assert(pCmd->numOfClause == pInfo->subclauseInfo.numOfClause);
for (int32_t i = pCmd->clauseIndex; i < pInfo->subclauseInfo.numOfClause; ++i) {
- SQuerySQL* pQuerySql = pInfo->subclauseInfo.pClause[i];
+ SQuerySqlNode* pQuerySqlNode = pInfo->subclauseInfo.pClause[i];
tscTrace("%p start to parse %dth subclause, total:%d", pSql, i, pInfo->subclauseInfo.numOfClause);
- if ((code = doCheckForQuery(pSql, pQuerySql, i)) != TSDB_CODE_SUCCESS) {
+ if ((code = doValidateSqlNode(pSql, pQuerySqlNode, i)) != TSDB_CODE_SUCCESS) {
return code;
}
@@ -702,21 +704,86 @@ static bool isTopBottomQuery(SQueryInfo* pQueryInfo) {
return false;
}
-int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
+// 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;
+
+ int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
+ for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
+ STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
+ if (pTableMetaInfo->pTableMeta->id.uid == uid) {
+ tableIndex = i;
+ break;
+ }
+ }
+
+ if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
+ return TSDB_CODE_TSC_INVALID_SQL;
+ }
+
+ SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
+ tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
+
+ SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
+ tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL);
+ return TSDB_CODE_SUCCESS;
+}
+
+static int32_t checkInvalidExprForTimeWindow(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
const char* msg1 = "invalid query expression";
+ const char* msg2 = "top/bottom query does not support order by value in time window query";
+
+ // for top/bottom + interval query, we do not add additional timestamp column in the front
+ if (isTopBottomQuery(pQueryInfo)) {
+
+ // invalid sql:
+ // top(col, k) from table_name [interval(1d)|session(ts, 1d)] order by k asc
+ // order by normal column is not supported
+ int32_t colId = pQueryInfo->order.orderColId;
+ if (isTimeWindowQuery(pQueryInfo) && colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
+ }
+
+ return TSDB_CODE_SUCCESS;
+ }
+
+ /*
+ * invalid sql:
+ * select count(tbname)/count(tag1)/count(tag2) from super_table_name [interval(1d)|session(ts, 1d)];
+ */
+ 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)) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
+ }
+ }
+
+ /*
+ * invalid sql:
+ * select tbname, tags_fields from super_table_name [interval(1s)|session(ts,1s)]
+ */
+ if (tscQueryTags(pQueryInfo) && isTimeWindowQuery(pQueryInfo)) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
+ }
+
+ return addPrimaryTsColumnForTimeWindowQuery(pQueryInfo);
+}
+
+int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode) {
const char* msg2 = "interval cannot be less than 10 ms";
const char* msg3 = "sliding cannot be used without interval";
- const char* msg4 = "top/bottom query does not support order by value in interval query";
SSqlCmd* pCmd = &pSql->cmd;
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
- if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
- if (pQuerySql->sliding.n > 0) {
+ if (!TPARSER_HAS_TOKEN(pQuerySqlNode->interval.interval)) {
+ if (TPARSER_HAS_TOKEN(pQuerySqlNode->sliding)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
+
return TSDB_CODE_SUCCESS;
}
@@ -726,7 +793,7 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQ
}
// interval is not null
- SStrToken* t = &pQuerySql->interval;
+ SStrToken *t = &pQuerySqlNode->interval.interval;
if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.interval, &pQueryInfo->interval.intervalUnit) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -743,78 +810,64 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQ
}
}
- // for top/bottom + interval query, we do not add additional timestamp column in the front
- if (isTopBottomQuery(pQueryInfo)) {
- if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
+ if (parseIntervalOffset(pCmd, pQueryInfo, &pQuerySqlNode->interval.offset) != TSDB_CODE_SUCCESS) {
+ return TSDB_CODE_TSC_INVALID_SQL;
+ }
- if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
+ if (parseSlidingClause(pCmd, pQueryInfo, &pQuerySqlNode->sliding) != TSDB_CODE_SUCCESS) {
+ return TSDB_CODE_TSC_INVALID_SQL;
+ }
- int32_t colId = pQueryInfo->order.orderColId;
- if (pQueryInfo->interval.interval > 0 && colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
- return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
- }
+ // The following part is used to check for the invalid query expression.
+ return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
+}
+
+int32_t parseSessionClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode * pQuerySqlNode) {
+ 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)) {
return TSDB_CODE_SUCCESS;
}
- /*
- * check invalid SQL:
- * select count(tbname)/count(tag1)/count(tag2) from super_table_name interval(1d);
- */
- 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)) {
- return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
- }
+ SStrToken* col = &pQuerySqlNode->sessionVal.col;
+ SStrToken* gap = &pQuerySqlNode->sessionVal.gap;
+
+ char timeUnit = 0;
+ if (parseNatualDuration(gap->z, gap->n, &pQueryInfo->sessionWindow.gap, &timeUnit) != TSDB_CODE_SUCCESS) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
- /*
- * check invalid SQL:
- * select tbname, tags_fields from super_table_name interval(1s)
- */
- if (tscQueryTags(pQueryInfo) && pQueryInfo->interval.interval > 0) {
+ if (timeUnit == 'y' || timeUnit == 'n') {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
- // need to add timestamp column in result set, if interval is existed
- uint64_t uid = tscSqlExprGet(pQueryInfo, 0)->uid;
-
- int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
- for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
- pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
- if (pTableMetaInfo->pTableMeta->id.uid == uid) {
- tableIndex = i;
- break;
- }
+ // if the unit of time window value is millisecond, change the value from microsecond
+ STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
+ STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
+ if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
+ pQueryInfo->sessionWindow.gap = pQueryInfo->sessionWindow.gap / 1000;
}
- if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
- return TSDB_CODE_TSC_INVALID_SQL;
+ if (pQueryInfo->sessionWindow.gap != 0 && pQueryInfo->interval.interval != 0) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
- tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
-
- SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
- tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL);
-
- if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
+ SColumnIndex index = COLUMN_INDEX_INITIALIZER;
+ if (getColumnIndexByName(pCmd, col, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
- if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
+ pQueryInfo->sessionWindow.primaryColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
- return TSDB_CODE_SUCCESS;
+ // The following part is used to check for the invalid query expression.
+ return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
}
-int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
+int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* offsetToken) {
const char* msg1 = "interval offset cannot be negative";
const char* msg2 = "interval offset should be shorter than interval";
const char* msg3 = "cannot use 'year' as offset when interval is 'month'";
@@ -822,7 +875,7 @@ int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQue
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
- SStrToken* t = &pQuerySql->offset;
+ SStrToken* t = offsetToken;
if (t->n == 0) {
pQueryInfo->interval.offsetUnit = pQueryInfo->interval.intervalUnit;
pQueryInfo->interval.offset = 0;
@@ -865,20 +918,17 @@ int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQue
return TSDB_CODE_SUCCESS;
}
-int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
+int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSliding) {
const char* msg0 = "sliding value too small";
const char* msg1 = "sliding value no larger than the interval value";
const char* msg2 = "sliding value can not less than 1% of interval value";
const char* msg3 = "does not support sliding when interval is natural month/year";
-// const char* msg4 = "sliding not support yet in ordinary query";
const static int32_t INTERVAL_SLIDING_FACTOR = 100;
- SSqlCmd* pCmd = &pSql->cmd;
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
- SStrToken* pSliding = &pQuerySql->sliding;
if (pSliding->n == 0) {
pQueryInfo->interval.slidingUnit = pQueryInfo->interval.intervalUnit;
pQueryInfo->interval.sliding = pQueryInfo->interval.interval;
@@ -970,7 +1020,7 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) {
const char* msg1 = "first column must be timestamp";
const char* msg2 = "row length exceeds max length";
const char* msg3 = "duplicated column names";
- const char* msg4 = "invalid data types";
+ const char* msg4 = "invalid data type";
const char* msg5 = "invalid binary/nchar column length";
const char* msg6 = "invalid column name";
@@ -991,14 +1041,13 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) {
int32_t nLen = 0;
for (int32_t i = 0; i < numOfCols; ++i) {
pField = taosArrayGet(pFieldList, i);
-
- if (pField->bytes == 0) {
- invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
+ if (!isValidDataType(pField->type)) {
+ invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
return false;
}
- if (!isValidDataType(pField->type)) {
- invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
+ if (pField->bytes == 0) {
+ invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
return false;
}
@@ -1191,7 +1240,7 @@ bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
const char* msg1 = "too many columns";
const char* msg2 = "duplicated column names";
const char* msg3 = "column length too long";
- const char* msg4 = "invalid data types";
+ const char* msg4 = "invalid data type";
const char* msg5 = "invalid column name";
const char* msg6 = "invalid column length";
@@ -1537,10 +1586,11 @@ bool isValidDistinctSql(SQueryInfo* pQueryInfo) {
}
return false;
}
-int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool intervalQuery) {
- assert(pSelection != NULL && pCmd != NULL);
- const char* msg2 = "functions can not be mixed up";
+int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectList, bool isSTable, bool joinQuery, bool timeWindowQuery) {
+ assert(pSelectList != NULL && pCmd != NULL);
+
+ const char* msg2 = "functions or others can not be mixed up";
const char* msg3 = "not support query expression";
const char* msg5 = "invalid function name";
const char* msg6 = "only support distinct one tag";
@@ -1550,34 +1600,35 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
if (pQueryInfo->colList == NULL) {
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
}
+
bool hasDistinct = false;
- for (int32_t i = 0; i < pSelection->nExpr; ++i) {
+ size_t numOfExpr = taosArrayGetSize(pSelectList);
+ for (int32_t i = 0; i < numOfExpr; ++i) {
int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
- tSqlExprItem* pItem = &pSelection->a[i];
+ tSqlExprItem* pItem = taosArrayGet(pSelectList, i);
if (hasDistinct == false) {
hasDistinct = (pItem->distinct == true);
}
- // project on all fields
- int32_t optr = pItem->pNode->nSQLOptr;
- if (optr == TK_ALL || optr == TK_ID || optr == TK_STRING || optr == TK_INTEGER || optr == TK_FLOAT) {
- // it is actually a function, but the function name is invalid
- if (pItem->pNode->nSQLOptr == TK_ID && (pItem->pNode->colInfo.z == NULL && pItem->pNode->colInfo.n == 0)) {
+ int32_t type = pItem->pNode->type;
+ if (type == SQL_NODE_SQLFUNCTION) {
+ pItem->pNode->functionId = isValidFunction(pItem->pNode->operand.z, pItem->pNode->operand.n);
+ if (pItem->pNode->functionId < 0) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
- // select table_name1.field_name1, table_name2.field_name2 from table_name1, table_name2
- if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
- } else if (pItem->pNode->nSQLOptr >= TK_COUNT && pItem->pNode->nSQLOptr <= TK_TBID) {
// sql function in selection clause, append sql function info in pSqlCmd structure sequentially
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
-
- } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
+ } else if (type == SQL_NODE_TABLE_COLUMN || type == SQL_NODE_VALUE) {
+ // use the dynamic array list to decide if the function is valid or not
+ // select table_name1.field_name1, table_name2.field_name2 from table_name1, table_name2
+ if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
+ return TSDB_CODE_TSC_INVALID_SQL;
+ }
+ } else if (type == SQL_NODE_EXPR) {
int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
if (code != TSDB_CODE_SUCCESS) {
return code;
@@ -1600,11 +1651,11 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
// there is only one user-defined column in the final result field, add the timestamp column.
size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
- if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo)) {
+ if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) {
addPrimaryTsColIntoResult(pQueryInfo);
}
- if (!functionCompatibleCheck(pQueryInfo, joinQuery, intervalQuery)) {
+ if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
@@ -1727,7 +1778,7 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
const char* msg1 = "tag for normal table query is not allowed";
int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
- int32_t optr = pItem->pNode->nSQLOptr;
+ int32_t optr = pItem->pNode->tokenId;
if (optr == TK_ALL) { // project on all fields
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY);
@@ -1757,13 +1808,13 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
index.columnIndex = (pQueryInfo->udColumnId--);
index.tableIndex = 0;
- SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->val, &pItem->pNode->token, pItem->aliasName);
+ SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->value, &pItem->pNode->token, pItem->aliasName);
SSqlExpr* 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->val);
+ tVariantAssign(&pExpr->param[1], &pItem->pNode->value);
} else if (optr == TK_ID) {
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
@@ -1872,9 +1923,25 @@ void setResultColName(char* name, tSqlExprItem* pItem, int32_t functionId, SStrT
}
}
+static void updateLastScanOrderIfNeeded(SQueryInfo* pQueryInfo) {
+ if (pQueryInfo->sessionWindow.gap > 0 || tscGroupbyColumn(pQueryInfo)) {
+ size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo);
+ 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) {
+ continue;
+ }
+
+ pExpr->numOfParams = 1;
+ pExpr->param->i64 = TSDB_ORDER_ASC;
+ pExpr->param->nType = TSDB_DATA_TYPE_INT;
+ }
+ }
+}
+
int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult) {
STableMetaInfo* pTableMetaInfo = NULL;
- int32_t optr = pItem->pNode->nSQLOptr;
+ int32_t functionId = pItem->pNode->functionId;
const char* msg1 = "not support column types";
const char* msg2 = "invalid parameters";
@@ -1884,28 +1951,22 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
const char* msg6 = "function applied to tags not allowed";
const char* msg7 = "normal table can not apply this function";
const char* msg8 = "multi-columns selection does not support alias column name";
- const char* msg9 = "invalid function";
- const char* msg10 = "diff can no be applied to unsigned numeric type";
+ const char* msg9 = "diff can no be applied to unsigned numeric type";
- switch (optr) {
- case TK_COUNT: {
+ switch (functionId) {
+ case TSDB_FUNC_COUNT: {
/* more than one parameter for count() function */
- if (pItem->pNode->pParam != NULL && pItem->pNode->pParam->nExpr != 1) {
+ if (pItem->pNode->pParam != NULL && taosArrayGetSize(pItem->pNode->pParam) != 1) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- int16_t functionID = 0;
- if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
-
SSqlExpr* pExpr = NULL;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (pItem->pNode->pParam != NULL) {
- tSqlExprItem* pParamElem = &pItem->pNode->pParam->a[0];
+ tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->pParam, 0);
SStrToken* pToken = &pParamElem->pNode->colInfo;
- int16_t sqlOptr = pParamElem->pNode->nSQLOptr;
+ int16_t sqlOptr = pParamElem->pNode->tokenId;
if ((pToken->z == NULL || pToken->n == 0)
&& (TK_INTEGER != sqlOptr)) /*select count(1) from table*/ {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
@@ -1921,11 +1982,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
- pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false);
+ pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false);
} else if (sqlOptr == TK_INTEGER) { // select count(1) from table1
char buf[8] = {0};
int64_t val = -1;
- tVariant* pVariant = &pParamElem->pNode->val;
+ tVariant* pVariant = &pParamElem->pNode->value;
if (pVariant->nType == TSDB_DATA_TYPE_BIGINT) {
tVariantDump(pVariant, buf, TSDB_DATA_TYPE_BIGINT, true);
val = GET_INT64_VAL(buf);
@@ -1933,7 +1994,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
if (val == 1) {
index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
- pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false);
+ pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false);
} else {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
@@ -1953,12 +2014,12 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
}
int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
- pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, isTag);
+ pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, isTag);
}
} else { // count(*) is equalled to count(primary_timestamp_key)
index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
- pExpr = tscSqlExprAppend(pQueryInfo, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false);
+ pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(pQueryInfo), size, false);
}
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
@@ -1983,29 +2044,29 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
return TSDB_CODE_SUCCESS;
}
- case TK_SUM:
- case TK_AVG:
- case TK_RATE:
- case TK_IRATE:
- case TK_SUM_RATE:
- case TK_SUM_IRATE:
- case TK_AVG_RATE:
- case TK_AVG_IRATE:
- case TK_TWA:
- case TK_MIN:
- case TK_MAX:
- case TK_DIFF:
- case TK_STDDEV:
- case TK_LEASTSQUARES: {
+ case TSDB_FUNC_SUM:
+ case TSDB_FUNC_AVG:
+ case TSDB_FUNC_RATE:
+ case TSDB_FUNC_IRATE:
+ case TSDB_FUNC_SUM_RATE:
+ case TSDB_FUNC_SUM_IRATE:
+ case TSDB_FUNC_AVG_RATE:
+ case TSDB_FUNC_AVG_IRATE:
+ case TSDB_FUNC_TWA:
+ case TSDB_FUNC_MIN:
+ case TSDB_FUNC_MAX:
+ case TSDB_FUNC_DIFF:
+ case TSDB_FUNC_STDDEV:
+ case TSDB_FUNC_LEASTSQR: {
// 1. valid the number of parameters
- if (pItem->pNode->pParam == NULL || (optr != TK_LEASTSQUARES && pItem->pNode->pParam->nExpr != 1) ||
- (optr == TK_LEASTSQUARES && pItem->pNode->pParam->nExpr != 3)) {
+ if (pItem->pNode->pParam == NULL || (functionId != TSDB_FUNC_LEASTSQR && taosArrayGetSize(pItem->pNode->pParam) != 1) ||
+ (functionId == TSDB_FUNC_LEASTSQR && taosArrayGetSize(pItem->pNode->pParam) != 3)) {
/* no parameters or more than one parameter for function */
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- tSqlExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
- if (pParamElem->pNode->nSQLOptr != TK_ALL && pParamElem->pNode->nSQLOptr != TK_ID) {
+ tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->pParam, 0);
+ if (pParamElem->pNode->tokenId != TK_ALL && pParamElem->pNode->tokenId != TK_ID) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
@@ -2025,26 +2086,21 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
if (!IS_NUMERIC_TYPE(colType)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
- } else if (IS_UNSIGNED_NUMERIC_TYPE(colType) && optr == TK_DIFF) {
- return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
+ } else if (IS_UNSIGNED_NUMERIC_TYPE(colType) && functionId == TSDB_FUNC_DIFF) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
}
int16_t resultType = 0;
int16_t resultSize = 0;
int32_t intermediateResSize = 0;
- int16_t functionID = 0;
- if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
-
- if (getResultDataInfo(pSchema->type, pSchema->bytes, functionID, 0, &resultType, &resultSize,
+ if (getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize,
&intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
// set the first column ts for diff query
- if (optr == TK_DIFF) {
+ 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,
@@ -2059,19 +2115,19 @@ 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);
+ SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false);
- if (optr == TK_LEASTSQUARES) {
+ if (functionId == TSDB_FUNC_LEASTSQR) {
/* set the leastsquares parameters */
char val[8] = {0};
- if (tVariantDump(&pParamElem[1].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
+ if (tVariantDump(&pParamElem[1].pNode->value, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
return TSDB_CODE_TSC_INVALID_SQL;
}
addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES);
memset(val, 0, tListLen(val));
- if (tVariantDump(&pParamElem[2].pNode->val, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
+ if (tVariantDump(&pParamElem[2].pNode->value, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -2097,43 +2153,38 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
tscInsertPrimaryTsSourceColumn(pQueryInfo, &index);
return TSDB_CODE_SUCCESS;
}
- case TK_FIRST:
- case TK_LAST:
- case TK_SPREAD:
- case TK_LAST_ROW:
- case TK_INTERP: {
+ case TSDB_FUNC_FIRST:
+ case TSDB_FUNC_LAST:
+ case TSDB_FUNC_SPREAD:
+ case TSDB_FUNC_LAST_ROW:
+ case TSDB_FUNC_INTERP: {
bool requireAllFields = (pItem->pNode->pParam == NULL);
- int16_t functionID = 0;
- if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
- return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
- }
-
// NOTE: has time range condition or normal column filter condition, the last_row query will be transferred to last query
- SConvertFunc cvtFunc = {.originFuncId = functionID, .execFuncId = functionID};
- if (functionID == TSDB_FUNC_LAST_ROW && ((!TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER)) || (hasNormalColumnFilter(pQueryInfo)))) {
+ SConvertFunc cvtFunc = {.originFuncId = functionId, .execFuncId = functionId};
+ if (functionId == TSDB_FUNC_LAST_ROW && ((!TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER)) || (hasNormalColumnFilter(pQueryInfo)))) {
cvtFunc.execFuncId = TSDB_FUNC_LAST;
}
if (!requireAllFields) {
- if (pItem->pNode->pParam->nExpr < 1) {
+ if (taosArrayGetSize(pItem->pNode->pParam) < 1) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
- if (pItem->pNode->pParam->nExpr > 1 && (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0)) {
+ if (taosArrayGetSize(pItem->pNode->pParam) > 1 && (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
}
/* in first/last function, multiple columns can be add to resultset */
- for (int32_t i = 0; i < pItem->pNode->pParam->nExpr; ++i) {
- tSqlExprItem* pParamElem = &(pItem->pNode->pParam->a[i]);
- if (pParamElem->pNode->nSQLOptr != TK_ALL && pParamElem->pNode->nSQLOptr != TK_ID) {
+ for (int32_t i = 0; i < taosArrayGetSize(pItem->pNode->pParam); ++i) {
+ tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->pParam, i);
+ if (pParamElem->pNode->tokenId != TK_ALL && pParamElem->pNode->tokenId != TK_ID) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
- if (pParamElem->pNode->nSQLOptr == TK_ALL) { // select table.*
+ if (pParamElem->pNode->tokenId == TK_ALL) { // select table.*
SStrToken tmpToken = pParamElem->pNode->colInfo;
if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
@@ -2167,31 +2218,14 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
}
char name[TSDB_COL_NAME_LEN] = {0};
-
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
- bool multiColOutput = pItem->pNode->pParam->nExpr > 1;
+ bool multiColOutput = taosArrayGetSize(pItem->pNode->pParam) > 1;
setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->colInfo, multiColOutput);
- if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex + i, &index, finalResult) != 0) {
+ if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex++, &index, finalResult) != 0) {
return TSDB_CODE_TSC_INVALID_SQL;
}
-
- if (optr == TK_LAST) { // todo refactor
- SSqlGroupbyExpr* pGroupBy = &pQueryInfo->groupbyExpr;
- if (pGroupBy->numOfGroupCols > 0) {
- for(int32_t k = 0; k < pGroupBy->numOfGroupCols; ++k) {
- SColIndex* pIndex = taosArrayGet(pGroupBy->columnInfo, k);
- if (!TSDB_COL_IS_TAG(pIndex->flag) && pIndex->colIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { // group by normal columns
- SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, colIndex + i);
- pExpr->numOfParams = 1;
- pExpr->param->i64 = TSDB_ORDER_ASC;
-
- break;
- }
- }
- }
- }
}
}
@@ -2218,29 +2252,28 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult) != 0) {
return TSDB_CODE_TSC_INVALID_SQL;
}
-
colIndex++;
}
numOfFields += tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
}
-
return TSDB_CODE_SUCCESS;
}
}
- case TK_TOP:
- case TK_BOTTOM:
- case TK_PERCENTILE:
- case TK_APERCENTILE: {
+
+ case TSDB_FUNC_TOP:
+ case TSDB_FUNC_BOTTOM:
+ case TSDB_FUNC_PERCT:
+ case TSDB_FUNC_APERCT: {
// 1. valid the number of parameters
- if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 2) {
+ if (pItem->pNode->pParam == NULL || taosArrayGetSize(pItem->pNode->pParam) != 2) {
/* no parameters or more than one parameter for function */
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- tSqlExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
- if (pParamElem->pNode->nSQLOptr != TK_ID) {
+ tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->pParam, 0);
+ if (pParamElem->pNode->tokenId != TK_ID) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
@@ -2268,11 +2301,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
}
// 3. valid the parameters
- if (pParamElem[1].pNode->nSQLOptr == TK_ID) {
+ if (pParamElem[1].pNode->tokenId == TK_ID) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- tVariant* pVariant = &pParamElem[1].pNode->val;
+ tVariant* pVariant = &pParamElem[1].pNode->value;
int8_t resultType = pSchema[index.columnIndex].type;
int16_t resultSize = pSchema[index.columnIndex].bytes;
@@ -2280,7 +2313,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
char val[8] = {0};
SSqlExpr* pExpr = NULL;
- if (optr == TK_PERCENTILE || optr == TK_APERCENTILE) {
+ if (functionId == TSDB_FUNC_PERCT || functionId == TSDB_FUNC_APERCT) {
tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
double dp = GET_DOUBLE_VAL(val);
@@ -2296,10 +2329,6 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
* for dp = 0, it is actually min,
* for dp = 100, it is max,
*/
- int16_t functionId = 0;
- if (convertFunctionId(optr, &functionId) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
tscInsertPrimaryTsSourceColumn(pQueryInfo, &index);
colIndex += 1; // the first column is ts
@@ -2313,20 +2342,15 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
- int16_t functionId = 0;
- if (convertFunctionId(optr, &functionId) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
-
// todo REFACTOR
// set the first column ts for top/bottom query
- SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
+ 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));
const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
- SColumnList ids = getColumnList(1, 0, TS_COLUMN_INDEX);
+ SColumnList ids = getColumnList(1, index.tableIndex, TS_COLUMN_INDEX);
insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
aAggs[TSDB_FUNC_TS].name, pExpr);
@@ -2339,7 +2363,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
- SColumnList ids = getColumnList(1, 0, index.columnIndex);
+ SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex);
if (finalResult) {
insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
} else {
@@ -2351,19 +2375,20 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
return TSDB_CODE_SUCCESS;
};
- case TK_TBID: {
+ case TSDB_FUNC_TID_TAG: {
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
}
// no parameters or more than one parameter for function
- if (pItem->pNode->pParam == NULL || pItem->pNode->pParam->nExpr != 1) {
+ if (pItem->pNode->pParam == NULL || taosArrayGetSize(pItem->pNode->pParam) != 1) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- tSQLExpr* pParam = pItem->pNode->pParam->a[0].pNode;
-
+ tSqlExprItem* pParamItem = taosArrayGet(pItem->pNode->pParam, 0);
+ tSqlExpr* pParam = pParamItem->pNode;
+
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(pCmd, &pParam->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
@@ -2419,7 +2444,31 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
return TSDB_CODE_SUCCESS;
}
-
+ case TSDB_FUNC_BLKINFO: {
+ // no parameters or more than one parameter for function
+ if (pItem->pNode->pParam != NULL && taosArrayGetSize(pItem->pNode->pParam) != 0) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
+ }
+
+ SColumnIndex index = {.tableIndex = 0, .columnIndex = TSDB_BLOCK_DIST_COLUMN_INDEX,};
+ pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
+
+ SSchema s = {.name = "block_dist", .type = TSDB_DATA_TYPE_BINARY};
+ int32_t inter = 0;
+ int16_t resType = 0;
+ int16_t bytes = 0;
+ getResultDataInfo(TSDB_DATA_TYPE_INT, 4, TSDB_FUNC_BLKINFO, 0, &resType, &bytes, &inter, 0, 0);
+
+ s.bytes = bytes;
+ s.type = (uint8_t)resType;
+ 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;
+
+ return TSDB_CODE_SUCCESS;
+ }
+
default:
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -2444,8 +2493,8 @@ void getColumnName(tSqlExprItem* pItem, char* resultFieldName, int32_t nameLengt
if (pItem->aliasName != NULL) {
strncpy(resultFieldName, pItem->aliasName, nameLength);
} else {
- int32_t len = ((int32_t)pItem->pNode->operand.n < nameLength) ? (int32_t)pItem->pNode->operand.n : nameLength;
- strncpy(resultFieldName, pItem->pNode->operand.z, len);
+ int32_t len = ((int32_t)pItem->pNode->token.n < nameLength) ? (int32_t)pItem->pNode->token.n : nameLength;
+ strncpy(resultFieldName, pItem->pNode->token.z, len);
}
}
@@ -2585,87 +2634,6 @@ int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo*
return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
}
-int32_t convertFunctionId(int32_t optr, int16_t* functionId) {
- switch (optr) {
- case TK_COUNT:
- *functionId = TSDB_FUNC_COUNT;
- break;
- case TK_SUM:
- *functionId = TSDB_FUNC_SUM;
- break;
- case TK_AVG:
- *functionId = TSDB_FUNC_AVG;
- break;
- case TK_RATE:
- *functionId = TSDB_FUNC_RATE;
- break;
- case TK_IRATE:
- *functionId = TSDB_FUNC_IRATE;
- break;
- case TK_SUM_RATE:
- *functionId = TSDB_FUNC_SUM_RATE;
- break;
- case TK_SUM_IRATE:
- *functionId = TSDB_FUNC_SUM_IRATE;
- break;
- case TK_AVG_RATE:
- *functionId = TSDB_FUNC_AVG_RATE;
- break;
- case TK_AVG_IRATE:
- *functionId = TSDB_FUNC_AVG_IRATE;
- break;
- case TK_MIN:
- *functionId = TSDB_FUNC_MIN;
- break;
- case TK_MAX:
- *functionId = TSDB_FUNC_MAX;
- break;
- case TK_STDDEV:
- *functionId = TSDB_FUNC_STDDEV;
- break;
- case TK_PERCENTILE:
- *functionId = TSDB_FUNC_PERCT;
- break;
- case TK_APERCENTILE:
- *functionId = TSDB_FUNC_APERCT;
- break;
- case TK_FIRST:
- *functionId = TSDB_FUNC_FIRST;
- break;
- case TK_LAST:
- *functionId = TSDB_FUNC_LAST;
- break;
- case TK_LEASTSQUARES:
- *functionId = TSDB_FUNC_LEASTSQR;
- break;
- case TK_TOP:
- *functionId = TSDB_FUNC_TOP;
- break;
- case TK_BOTTOM:
- *functionId = TSDB_FUNC_BOTTOM;
- break;
- case TK_DIFF:
- *functionId = TSDB_FUNC_DIFF;
- break;
- case TK_SPREAD:
- *functionId = TSDB_FUNC_SPREAD;
- break;
- case TK_TWA:
- *functionId = TSDB_FUNC_TWA;
- break;
- case TK_INTERP:
- *functionId = TSDB_FUNC_INTERP;
- break;
- case TK_LAST_ROW:
- *functionId = TSDB_FUNC_LAST_ROW;
- break;
- default:
- return -1;
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
SSqlCmd* pCmd = &pSql->cmd;
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
@@ -2902,23 +2870,40 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
return false;
}
-static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool intervalQuery) {
+static bool groupbyTagsOrNull(SQueryInfo* pQueryInfo) {
+ if (pQueryInfo->groupbyExpr.columnInfo == NULL ||
+ taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo) == 0) {
+ return true;
+ }
+
+ size_t s = taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo);
+ for (int32_t i = 0; i < s; i++) {
+ SColIndex* colIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
+ if (colIndex->flag != TSDB_COL_TAG) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool twQuery) {
int32_t startIdx = 0;
size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo);
assert(numOfExpr > 0);
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
- int32_t functionID = pExpr->functionId;
// ts function can be simultaneously used with any other functions.
+ int32_t functionID = pExpr->functionId;
if (functionID == TSDB_FUNC_TS || functionID == TSDB_FUNC_TS_DUMMY) {
startIdx++;
}
int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
- if (tscSqlExprGet(pQueryInfo, 0)->functionId == TSDB_FUNC_LAST_ROW && (joinQuery || intervalQuery)) {
+ if (tscSqlExprGet(pQueryInfo, 0)->functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) {
return false;
}
@@ -2946,7 +2931,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool
}
}
- if (functionId == TSDB_FUNC_LAST_ROW && (joinQuery || intervalQuery)) {
+ if (functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) {
return false;
}
}
@@ -3086,10 +3071,10 @@ static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
}
static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SColumnFilterInfo* pColumnFilter,
- SColumnIndex* columnIndex, tSQLExpr* pExpr) {
+ SColumnIndex* columnIndex, tSqlExpr* pExpr) {
const char* msg = "not supported filter condition";
- tSQLExpr* pRight = pExpr->pRight;
+ tSqlExpr* pRight = pExpr->pRight;
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, columnIndex->tableIndex);
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex->columnIndex);
@@ -3099,39 +3084,47 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
colType = TSDB_DATA_TYPE_BIGINT;
} else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
colType = TSDB_DATA_TYPE_DOUBLE;
- } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->val.nType)) {
- int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->val);
+ } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BINARY == pRight->value.nType)) {
+ int retVal = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, &pRight->value);
if (TSDB_CODE_SUCCESS != retVal) {
return retVal;
}
}
int32_t retVal = TSDB_CODE_SUCCESS;
- if (pExpr->nSQLOptr == TK_LE || pExpr->nSQLOptr == TK_LT) {
- retVal = tVariantDump(&pRight->val, (char*)&pColumnFilter->upperBndd, colType, false);
+
+ int32_t bufLen = 0;
+ if (IS_NUMERIC_TYPE(pRight->value.nType)) {
+ bufLen = 60;
+ } else {
+ bufLen = pRight->value.nLen + 1;
+ }
+
+ if (pExpr->tokenId == TK_LE || pExpr->tokenId == TK_LT) {
+ retVal = tVariantDump(&pRight->value, (char*)&pColumnFilter->upperBndd, colType, false);
// TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
} else if (colType == TSDB_DATA_TYPE_BINARY) {
- pColumnFilter->pz = (int64_t)calloc(1, pRight->val.nLen + TSDB_NCHAR_SIZE);
- pColumnFilter->len = pRight->val.nLen;
- retVal = tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
+ pColumnFilter->pz = (int64_t)calloc(1, bufLen * TSDB_NCHAR_SIZE);
+ pColumnFilter->len = pRight->value.nLen;
+ retVal = tVariantDump(&pRight->value, (char*)pColumnFilter->pz, colType, false);
} else if (colType == TSDB_DATA_TYPE_NCHAR) {
- // pRight->val.nLen + 1 is larger than the actual nchar string length
- pColumnFilter->pz = (int64_t)calloc(1, (pRight->val.nLen + 1) * TSDB_NCHAR_SIZE);
- retVal = tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
+ // pRight->value.nLen + 1 is larger than the actual nchar string length
+ pColumnFilter->pz = (int64_t)calloc(1, bufLen * TSDB_NCHAR_SIZE);
+ retVal = tVariantDump(&pRight->value, (char*)pColumnFilter->pz, colType, false);
size_t len = twcslen((wchar_t*)pColumnFilter->pz);
pColumnFilter->len = len * TSDB_NCHAR_SIZE;
} else {
- retVal = tVariantDump(&pRight->val, (char*)&pColumnFilter->lowerBndd, colType, false);
+ retVal = tVariantDump(&pRight->value, (char*)&pColumnFilter->lowerBndd, colType, false);
}
if (retVal != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
}
- switch (pExpr->nSQLOptr) {
+ switch (pExpr->tokenId) {
case TK_LE:
pColumnFilter->upperRelOptr = TSDB_RELATION_LESS_EQUAL;
break;
@@ -3167,162 +3160,45 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
}
typedef struct SCondExpr {
- tSQLExpr* pTagCond;
- tSQLExpr* pTimewindow;
+ tSqlExpr* pTagCond;
+ tSqlExpr* pTimewindow;
- tSQLExpr* pColumnCond;
+ tSqlExpr* pColumnCond;
- tSQLExpr* pTableCond;
+ tSqlExpr* pTableCond;
int16_t relType; // relation between table name in expression and other tag
// filter condition expression, TK_AND or TK_OR
int16_t tableCondIndex;
- tSQLExpr* pJoinExpr; // join condition
+ tSqlExpr* pJoinExpr; // join condition
bool tsJoin;
} SCondExpr;
-static int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision);
-
-static int32_t tSQLExprNodeToString(tSQLExpr* pExpr, char** str) {
- if (pExpr->nSQLOptr == TK_ID) { // column name
- strncpy(*str, pExpr->colInfo.z, pExpr->colInfo.n);
- *str += pExpr->colInfo.n;
-
- } else if (pExpr->nSQLOptr >= TK_BOOL && pExpr->nSQLOptr <= TK_STRING) { // value
- *str += tVariantToString(&pExpr->val, *str);
-
- } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
- /*
- * arithmetic expression of aggregation, such as count(ts) + count(ts) *2
- */
- strncpy(*str, pExpr->operand.z, pExpr->operand.n);
- *str += pExpr->operand.n;
- } else { // not supported operation
- assert(false);
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-// pExpr->nSQLOptr == 0 while handling "is null" query
-static bool isExprLeafNode(tSQLExpr* pExpr) {
- return (pExpr->pRight == NULL && pExpr->pLeft == NULL) &&
- (pExpr->nSQLOptr == 0 || pExpr->nSQLOptr == TK_ID || (pExpr->nSQLOptr >= TK_BOOL && pExpr->nSQLOptr <= TK_NCHAR) || pExpr->nSQLOptr == TK_SET);
-}
-
-static bool isExprDirectParentOfLeafNode(tSQLExpr* pExpr) {
- return (pExpr->pLeft != NULL && pExpr->pRight != NULL) &&
- (isExprLeafNode(pExpr->pLeft) && isExprLeafNode(pExpr->pRight));
-}
-
-static int32_t tSQLExprLeafToString(tSQLExpr* pExpr, bool addParentheses, char** output) {
- if (!isExprDirectParentOfLeafNode(pExpr)) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
-
- tSQLExpr* pLeft = pExpr->pLeft;
- tSQLExpr* pRight = pExpr->pRight;
-
- if (addParentheses) {
- *(*output) = '(';
- *output += 1;
- }
-
- tSQLExprNodeToString(pLeft, output);
- if (optrToString(pExpr, output) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_TSC_INVALID_SQL;
- }
-
- tSQLExprNodeToString(pRight, output);
-
- if (addParentheses) {
- *(*output) = ')';
- *output += 1;
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t optrToString(tSQLExpr* pExpr, char** exprString) {
- const char* le = "<=";
- const char* ge = ">=";
- const char* ne = "<>";
- const char* likeOptr = "LIKE";
-
- switch (pExpr->nSQLOptr) {
- case TK_LE: {
- *(int16_t*)(*exprString) = *(int16_t*)le;
- *exprString += 1;
- break;
- }
- case TK_GE: {
- *(int16_t*)(*exprString) = *(int16_t*)ge;
- *exprString += 1;
- break;
- }
- case TK_NE: {
- *(int16_t*)(*exprString) = *(int16_t*)ne;
- *exprString += 1;
- break;
- }
+static int32_t getTimeRange(STimeWindow* win, tSqlExpr* pRight, int32_t optr, int16_t timePrecision);
- case TK_LT:
- *(*exprString) = '<';
- break;
- case TK_GT:
- *(*exprString) = '>';
- break;
- case TK_EQ:
- *(*exprString) = '=';
- break;
- case TK_PLUS:
- *(*exprString) = '+';
- break;
- case TK_MINUS:
- *(*exprString) = '-';
- break;
- case TK_STAR:
- *(*exprString) = '*';
- break;
- case TK_DIVIDE:
- *(*exprString) = '/';
- break;
- case TK_REM:
- *(*exprString) = '%';
- break;
- case TK_LIKE: {
- int32_t len = sprintf(*exprString, " %s ", likeOptr);
- *exprString += (len - 1);
- break;
- }
- default:
- return TSDB_CODE_TSC_INVALID_SQL;
- }
-
- *exprString += 1;
-
- return TSDB_CODE_SUCCESS;
-}
+static int32_t tablenameListToString(tSqlExpr* pExpr, SStringBuilder* sb) {
+ SArray* pList = pExpr->pParam;
-static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
- tSQLExprList* pList = pExpr->pParam;
- if (pList->nExpr <= 0) {
+ int32_t size = (int32_t) taosArrayGetSize(pList);
+ if (size <= 0) {
return TSDB_CODE_TSC_INVALID_SQL;
}
- if (pList->nExpr > 0) {
+ if (size > 0) {
taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
}
- for (int32_t i = 0; i < pList->nExpr; ++i) {
- tSQLExpr* pSub = pList->a[i].pNode;
- taosStringBuilderAppendStringLen(sb, pSub->val.pz, pSub->val.nLen);
+ for (int32_t i = 0; i < size; ++i) {
+ tSqlExprItem* pSub = taosArrayGet(pList, i);
+ tVariant* pVar = &pSub->pNode->value;
+
+ taosStringBuilderAppendStringLen(sb, pVar->pz, pVar->nLen);
- if (i < pList->nExpr - 1) {
+ if (i < size - 1) {
taosStringBuilderAppendString(sb, TBNAME_LIST_SEP);
}
- if (pSub->val.nLen <= 0 || !tscValidateTableNameLength(pSub->val.nLen)) {
+ if (pVar->nLen <= 0 || !tscValidateTableNameLength(pVar->nLen)) {
return TSDB_CODE_TSC_INVALID_SQL;
}
}
@@ -3330,9 +3206,9 @@ static int32_t tablenameListToString(tSQLExpr* pExpr, SStringBuilder* sb) {
return TSDB_CODE_SUCCESS;
}
-static int32_t tablenameCondToString(tSQLExpr* pExpr, SStringBuilder* sb) {
+static int32_t tablenameCondToString(tSqlExpr* pExpr, SStringBuilder* sb) {
taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
- taosStringBuilderAppendString(sb, pExpr->val.pz);
+ taosStringBuilderAppendString(sb, pExpr->value.pz);
return TSDB_CODE_SUCCESS;
}
@@ -3344,7 +3220,7 @@ enum {
TSQL_EXPR_TBNAME = 3,
};
-static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SColumnIndex* pIndex, tSQLExpr* pExpr, int32_t sqlOptr) {
+static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SColumnIndex* pIndex, tSqlExpr* pExpr, int32_t sqlOptr) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
@@ -3386,21 +3262,21 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC
((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);
if (pColFilter->filterstr) {
- if (pExpr->nSQLOptr != TK_EQ
- && pExpr->nSQLOptr != TK_NE
- && pExpr->nSQLOptr != TK_ISNULL
- && pExpr->nSQLOptr != TK_NOTNULL
- && pExpr->nSQLOptr != TK_LIKE
+ if (pExpr->tokenId != TK_EQ
+ && pExpr->tokenId != TK_NE
+ && pExpr->tokenId != TK_ISNULL
+ && pExpr->tokenId != TK_NOTNULL
+ && pExpr->tokenId != TK_LIKE
) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
} else {
- if (pExpr->nSQLOptr == TK_LIKE) {
+ if (pExpr->tokenId == TK_LIKE) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
- if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
+ if (pExpr->tokenId != TK_EQ && pExpr->tokenId != TK_NE) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
}
@@ -3410,51 +3286,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC
return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
}
-static void relToString(tSQLExpr* pExpr, char** str) {
- assert(pExpr->nSQLOptr == TK_AND || pExpr->nSQLOptr == TK_OR);
-
- const char* or = "OR";
- const char*and = "AND";
-
- // if (pQueryInfo->tagCond.relType == TSQL_STABLE_QTYPE_COND) {
- if (pExpr->nSQLOptr == TK_AND) {
- strcpy(*str, and);
- *str += strlen(and);
- } else {
- strcpy(*str, or);
- *str += strlen(or);
- }
-}
-
-UNUSED_FUNC
-static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
- if (pExpr == NULL) {
- return TSDB_CODE_SUCCESS;
- }
-
- if (!isExprDirectParentOfLeafNode(pExpr)) {
- *(*str) = '(';
- *str += 1;
-
- int32_t ret = getTagCondString(pExpr->pLeft, str);
- if (ret != TSDB_CODE_SUCCESS) {
- return ret;
- }
-
- relToString(pExpr, str);
-
- ret = getTagCondString(pExpr->pRight, str);
-
- *(*str) = ')';
- *str += 1;
-
- return ret;
- }
-
- return tSQLExprLeafToString(pExpr, true, str);
-}
-
-static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pTableCond, SStringBuilder* sb) {
+static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pTableCond, SStringBuilder* sb) {
const char* msg0 = "invalid table name list";
const char* msg1 = "not string following like";
@@ -3462,8 +3294,8 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
return TSDB_CODE_SUCCESS;
}
- tSQLExpr* pLeft = pTableCond->pLeft;
- tSQLExpr* pRight = pTableCond->pRight;
+ tSqlExpr* pLeft = pTableCond->pLeft;
+ tSqlExpr* pRight = pTableCond->pRight;
if (!isTablenameToken(&pLeft->colInfo)) {
return TSDB_CODE_TSC_INVALID_SQL;
@@ -3471,10 +3303,10 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
int32_t ret = TSDB_CODE_SUCCESS;
- if (pTableCond->nSQLOptr == TK_IN) {
+ if (pTableCond->tokenId == TK_IN) {
ret = tablenameListToString(pRight, sb);
- } else if (pTableCond->nSQLOptr == TK_LIKE) {
- if (pRight->nSQLOptr != TK_STRING) {
+ } else if (pTableCond->tokenId == TK_LIKE) {
+ if (pRight->tokenId != TK_STRING) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
@@ -3488,18 +3320,18 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
return ret;
}
-static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t relOptr) {
+static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, int32_t relOptr) {
if (pExpr == NULL) {
return TSDB_CODE_SUCCESS;
}
- if (!isExprDirectParentOfLeafNode(pExpr)) { // internal node
- int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->nSQLOptr);
+ if (!tSqlExprIsParentOfLeaf(pExpr)) { // internal node
+ int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->tokenId);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
- return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->nSQLOptr);
+ return getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->tokenId);
} else { // handle leaf node
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(pCmd, &pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
@@ -3510,7 +3342,7 @@ static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQ
}
}
-static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
+static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) {
const char* msg1 = "invalid join query condition";
const char* msg2 = "invalid table name in join query";
const char* msg3 = "type of join columns must be identical";
@@ -3520,7 +3352,7 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
return TSDB_CODE_SUCCESS;
}
- if (!isExprDirectParentOfLeafNode(pExpr)) {
+ if (!tSqlExprIsParentOfLeaf(pExpr)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
@@ -3568,9 +3400,9 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
return TSDB_CODE_SUCCESS;
}
-static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList,
- int32_t* type, uint64_t* uid) {
- if (pExpr->nSQLOptr == TK_ID) {
+static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList,
+ int32_t* type, uint64_t* uid) {
+ if (pExpr->type == SQL_NODE_TABLE_COLUMN) {
if (*type == NON_ARITHMEIC_EXPR) {
*type = NORMAL_ARITHMETIC;
} else if (*type == AGG_ARIGHTMEIC) {
@@ -3592,9 +3424,9 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQuer
}
pList->ids[pList->num++] = index;
- } else if (pExpr->nSQLOptr == TK_FLOAT && (isnan(pExpr->val.dKey) || isinf(pExpr->val.dKey))) {
+ } else if (pExpr->tokenId == TK_FLOAT && (isnan(pExpr->value.dKey) || isinf(pExpr->value.dKey))) {
return TSDB_CODE_TSC_INVALID_SQL;
- } else if (pExpr->nSQLOptr >= TK_COUNT && pExpr->nSQLOptr <= TK_AVG_IRATE) {
+ } else if (pExpr->type == SQL_NODE_SQLFUNCTION) {
if (*type == NON_ARITHMEIC_EXPR) {
*type = AGG_ARIGHTMEIC;
} else if (*type == NORMAL_ARITHMETIC) {
@@ -3607,6 +3439,11 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQuer
// sql function list in selection clause.
// Append the sqlExpr into exprList of pQueryInfo structure sequentially
+ pExpr->functionId = isValidFunction(pExpr->operand.z, pExpr->operand.n);
+ if (pExpr->functionId < 0) {
+ return TSDB_CODE_TSC_INVALID_SQL;
+ }
+
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, false) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -3639,16 +3476,16 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQuer
return TSDB_CODE_SUCCESS;
}
-static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
+static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
if (pExpr == NULL) {
return TSDB_CODE_SUCCESS;
}
- tSQLExpr* pLeft = pExpr->pLeft;
+ tSqlExpr* pLeft = pExpr->pLeft;
uint64_t uidLeft = 0;
uint64_t uidRight = 0;
- if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
+ if (pLeft->type == SQL_NODE_EXPR) {
int32_t ret = validateArithmeticSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
@@ -3660,8 +3497,8 @@ static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryI
}
}
- tSQLExpr* pRight = pExpr->pRight;
- if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
+ tSqlExpr* pRight = pExpr->pRight;
+ if (pRight->type == SQL_NODE_EXPR) {
int32_t ret = validateArithmeticSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
@@ -3681,7 +3518,7 @@ static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryI
return TSDB_CODE_SUCCESS;
}
-static bool isValidExpr(tSQLExpr* pLeft, tSQLExpr* pRight, int32_t optr) {
+static bool isValidExpr(tSqlExpr* pLeft, tSqlExpr* pRight, int32_t optr) {
if (pLeft == NULL || (pRight == NULL && optr != TK_IN)) {
return false;
}
@@ -3694,34 +3531,27 @@ static bool isValidExpr(tSQLExpr* pLeft, tSQLExpr* pRight, int32_t optr) {
*
* However, columnA < 4+12 is valid
*/
- if (pLeft->nSQLOptr >= TK_COUNT && pLeft->nSQLOptr <= TK_AVG_IRATE) {
+ if (pLeft->type == SQL_NODE_SQLFUNCTION) {
return false;
}
if (pRight == NULL) {
return true;
}
-
- if (pRight->nSQLOptr >= TK_COUNT && pRight->nSQLOptr <= TK_AVG_IRATE) {
- return false;
- }
- if (pLeft->nSQLOptr >= TK_BOOL
- && pLeft->nSQLOptr <= TK_BINARY
- && pRight->nSQLOptr >= TK_BOOL
- && pRight->nSQLOptr <= TK_BINARY) {
+ if (pLeft->tokenId >= TK_BOOL && pLeft->tokenId <= TK_BINARY && pRight->tokenId >= TK_BOOL && pRight->tokenId <= TK_BINARY) {
return false;
}
return true;
}
-static void exchangeExpr(tSQLExpr* pExpr) {
- tSQLExpr* pLeft = pExpr->pLeft;
- tSQLExpr* pRight = pExpr->pRight;
+static void exchangeExpr(tSqlExpr* pExpr) {
+ tSqlExpr* pLeft = pExpr->pLeft;
+ tSqlExpr* pRight = pExpr->pRight;
- if (pRight->nSQLOptr == TK_ID && (pLeft->nSQLOptr == TK_INTEGER || pLeft->nSQLOptr == TK_FLOAT ||
- pLeft->nSQLOptr == TK_STRING || pLeft->nSQLOptr == TK_BOOL)) {
+ if (pRight->tokenId == TK_ID && (pLeft->tokenId == TK_INTEGER || pLeft->tokenId == TK_FLOAT ||
+ pLeft->tokenId == TK_STRING || pLeft->tokenId == TK_BOOL)) {
/*
* exchange value of the left handside and the value of the right-handside
* to make sure that the value of filter expression always locates in
@@ -3729,7 +3559,7 @@ static void exchangeExpr(tSQLExpr* pExpr) {
* the column-id is at the left handside.
*/
uint32_t optr = 0;
- switch (pExpr->nSQLOptr) {
+ switch (pExpr->tokenId) {
case TK_LE:
optr = TK_GE;
break;
@@ -3743,28 +3573,28 @@ static void exchangeExpr(tSQLExpr* pExpr) {
optr = TK_LE;
break;
default:
- optr = pExpr->nSQLOptr;
+ optr = pExpr->tokenId;
}
- pExpr->nSQLOptr = optr;
+ pExpr->tokenId = optr;
SWAP(pExpr->pLeft, pExpr->pRight, void*);
}
}
-static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
+static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SColumnIndex* pLeftIndex) {
const char* msg1 = "illegal column name";
const char* msg2 = "= is expected in join expression";
const char* msg3 = "join column must have same type";
const char* msg4 = "self join is not allowed";
const char* msg5 = "join table must be the same type(table to table, super table to super table)";
- tSQLExpr* pRight = pExpr->pRight;
+ tSqlExpr* pRight = pExpr->pRight;
- if (pRight->nSQLOptr != TK_ID) {
+ if (pRight->tokenId != TK_ID) {
return true;
}
- if (pExpr->nSQLOptr != TK_EQ) {
+ if (pExpr->tokenId != TK_EQ) {
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
return false;
}
@@ -3802,11 +3632,11 @@ static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr
return true;
}
-static bool validTableNameOptr(tSQLExpr* pExpr) {
+static bool validTableNameOptr(tSqlExpr* pExpr) {
const char nameFilterOptr[] = {TK_IN, TK_LIKE};
for (int32_t i = 0; i < tListLen(nameFilterOptr); ++i) {
- if (pExpr->nSQLOptr == nameFilterOptr[i]) {
+ if (pExpr->tokenId == nameFilterOptr[i]) {
return true;
}
}
@@ -3814,7 +3644,7 @@ static bool validTableNameOptr(tSQLExpr* pExpr) {
return false;
}
-static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
+static int32_t setExprToCond(tSqlExpr** parent, tSqlExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
if (*parent != NULL) {
if (parentOptr == TK_OR && msg != NULL) {
return invalidSqlErrMsg(msgBuf, msg);
@@ -3828,7 +3658,7 @@ static int32_t setExprToCond(tSQLExpr** parent, tSQLExpr* pExpr, const char* msg
return TSDB_CODE_SUCCESS;
}
-static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
+static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr,
int32_t* type, int32_t parentOptr) {
const char* msg1 = "table query cannot use tags filter";
const char* msg2 = "illegal column name";
@@ -3839,8 +3669,8 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQL
const char* msg7 = "only in/like allowed in filter table name";
const char* msg8 = "wildcard string should be less than 20 characters";
- tSQLExpr* pLeft = (*pExpr)->pLeft;
- tSQLExpr* pRight = (*pExpr)->pRight;
+ tSqlExpr* pLeft = (*pExpr)->pLeft;
+ tSqlExpr* pRight = (*pExpr)->pRight;
int32_t ret = TSDB_CODE_SUCCESS;
@@ -3849,7 +3679,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQL
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- assert(isExprDirectParentOfLeafNode(*pExpr));
+ assert(tSqlExprIsParentOfLeaf(*pExpr));
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
@@ -3860,7 +3690,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQL
}
// set join query condition
- if (pRight->nSQLOptr == TK_ID) { // no need to keep the timestamp join condition
+ if (pRight->tokenId == TK_ID) { // no need to keep the timestamp join condition
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY);
pCondExpr->tsJoin = true;
@@ -3882,8 +3712,8 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQL
}
// check for like expression
- if ((*pExpr)->nSQLOptr == TK_LIKE) {
- if (pRight->val.nLen > TSDB_PATTERN_STRING_MAX_LEN) {
+ if ((*pExpr)->tokenId == TK_LIKE) {
+ if (pRight->value.nLen > TSDB_PATTERN_STRING_MAX_LEN) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
}
@@ -3916,7 +3746,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQL
*type = TSQL_EXPR_TBNAME;
*pExpr = NULL;
} else {
- if (pRight != NULL && pRight->nSQLOptr == TK_ID) { // join on tag columns for stable query
+ if (pRight != NULL && pRight->tokenId == TK_ID) { // join on tag columns for stable query
if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -3940,7 +3770,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQL
} else { // query on other columns
*type = TSQL_EXPR_COLUMN;
- if (pRight->nSQLOptr == TK_ID) { // other column cannot be served as the join column
+ if (pRight->tokenId == TK_ID) { // other column cannot be served as the join column
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
@@ -3951,7 +3781,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQL
return ret;
}
-int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SCondExpr* pCondExpr,
+int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr,
int32_t* type, int32_t parentOptr) {
if (pExpr == NULL) {
return TSDB_CODE_SUCCESS;
@@ -3959,23 +3789,23 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr
const char* msg1 = "query condition between different columns must use 'AND'";
- tSQLExpr* pLeft = (*pExpr)->pLeft;
- tSQLExpr* pRight = (*pExpr)->pRight;
+ tSqlExpr* pLeft = (*pExpr)->pLeft;
+ tSqlExpr* pRight = (*pExpr)->pRight;
- if (!isValidExpr(pLeft, pRight, (*pExpr)->nSQLOptr)) {
+ if (!isValidExpr(pLeft, pRight, (*pExpr)->tokenId)) {
return TSDB_CODE_TSC_INVALID_SQL;
}
int32_t leftType = -1;
int32_t rightType = -1;
- if (!isExprDirectParentOfLeafNode(*pExpr)) {
- int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->nSQLOptr);
+ if (!tSqlExprIsParentOfLeaf(*pExpr)) {
+ int32_t ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, &leftType, (*pExpr)->tokenId);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
- ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->nSQLOptr);
+ ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, &rightType, (*pExpr)->tokenId);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
@@ -3985,7 +3815,7 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr
* expression is not valid for parent node, it must be TK_AND operator.
*/
if (leftType != rightType) {
- if ((*pExpr)->nSQLOptr == TK_OR && (leftType + rightType != TSQL_EXPR_TBNAME + TSQL_EXPR_TAG)) {
+ if ((*pExpr)->tokenId == TK_OR && (leftType + rightType != TSQL_EXPR_TBNAME + TSQL_EXPR_TAG)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
}
@@ -3999,40 +3829,9 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr
return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr);
}
-static void doCompactQueryExpr(tSQLExpr** pExpr) {
- if (*pExpr == NULL || isExprDirectParentOfLeafNode(*pExpr)) {
- return;
- }
-
- if ((*pExpr)->pLeft) {
- doCompactQueryExpr(&(*pExpr)->pLeft);
- }
-
- if ((*pExpr)->pRight) {
- doCompactQueryExpr(&(*pExpr)->pRight);
- }
-
- if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight == NULL &&
- ((*pExpr)->nSQLOptr == TK_OR || (*pExpr)->nSQLOptr == TK_AND)) {
- tSqlExprNodeDestroy(*pExpr);
- *pExpr = NULL;
-
- } else if ((*pExpr)->pLeft == NULL && (*pExpr)->pRight != NULL) {
- tSQLExpr* tmpPtr = (*pExpr)->pRight;
- tSqlExprNodeDestroy(*pExpr);
-
- (*pExpr) = tmpPtr;
- } else if ((*pExpr)->pRight == NULL && (*pExpr)->pLeft != NULL) {
- tSQLExpr* tmpPtr = (*pExpr)->pLeft;
- tSqlExprNodeDestroy(*pExpr);
-
- (*pExpr) = tmpPtr;
- }
-}
-
-static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, tSQLExpr** pOut, int32_t tableIndex) {
- if (isExprDirectParentOfLeafNode(*pExpr)) {
- tSQLExpr* pLeft = (*pExpr)->pLeft;
+static void doExtractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* pQueryInfo, tSqlExpr** pOut, int32_t tableIndex) {
+ if (tSqlExprIsParentOfLeaf(*pExpr)) {
+ tSqlExpr* pLeft = (*pExpr)->pLeft;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(pCmd, &pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
@@ -4047,19 +3846,19 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo*
(*pExpr) = NULL;
} else {
- *pOut = tSqlExprCreate(NULL, NULL, (*pExpr)->nSQLOptr);
+ *pOut = tSqlExprCreate(NULL, NULL, (*pExpr)->tokenId);
doExtractExprForSTable(pCmd, &(*pExpr)->pLeft, pQueryInfo, &((*pOut)->pLeft), tableIndex);
doExtractExprForSTable(pCmd, &(*pExpr)->pRight, pQueryInfo, &((*pOut)->pRight), tableIndex);
}
}
-static tSQLExpr* extractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* pQueryInfo, int32_t tableIndex) {
- tSQLExpr* pResExpr = NULL;
+static tSqlExpr* extractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* pQueryInfo, int32_t tableIndex) {
+ tSqlExpr* pResExpr = NULL;
if (*pExpr != NULL) {
doExtractExprForSTable(pCmd, pExpr, pQueryInfo, &pResExpr, tableIndex);
- doCompactQueryExpr(&pResExpr);
+ tSqlExprCompact(&pResExpr);
}
return pResExpr;
@@ -4079,7 +3878,7 @@ int tableNameCompar(const void* lhs, const void* rhs) {
}
static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, const char* account,
- tSQLExpr* pExpr, int16_t tableCondIndex, SStringBuilder* sb) {
+ tSqlExpr* pExpr, int16_t tableCondIndex, SStringBuilder* sb) {
const char* msg = "table name too long";
if (pExpr == NULL) {
@@ -4091,9 +3890,9 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
STagCond* pTagCond = &pQueryInfo->tagCond;
pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
- assert(pExpr->nSQLOptr == TK_LIKE || pExpr->nSQLOptr == TK_IN);
+ assert(pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_IN);
- if (pExpr->nSQLOptr == TK_LIKE) {
+ if (pExpr->tokenId == TK_LIKE) {
char* str = taosStringBuilderGetResult(sb, NULL);
pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
pQueryInfo->tagCond.tbnameCond.len = (int32_t) strlen(str);
@@ -4180,7 +3979,7 @@ static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
return true;
}
-static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
+static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) {
const char* msg0 = "invalid timestamp";
const char* msg1 = "only one time stamp window allowed";
@@ -4188,8 +3987,8 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLE
return TSDB_CODE_SUCCESS;
}
- if (!isExprDirectParentOfLeafNode(pExpr)) {
- if (pExpr->nSQLOptr == TK_OR) {
+ if (!tSqlExprIsParentOfLeaf(pExpr)) {
+ if (pExpr->tokenId == TK_OR) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
@@ -4205,10 +4004,10 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLE
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
- tSQLExpr* pRight = pExpr->pRight;
+ tSqlExpr* pRight = pExpr->pRight;
STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
- if (getTimeRange(&win, pRight, pExpr->nSQLOptr, tinfo.precision) != TSDB_CODE_SUCCESS) {
+ if (getTimeRange(&win, pRight, pExpr->tokenId, tinfo.precision) != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
}
@@ -4347,13 +4146,21 @@ static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) {
}
int32_t retVal = TSDB_CODE_SUCCESS;
+
+ int32_t bufLen = 0;
+ if (IS_NUMERIC_TYPE(vVariant->nType)) {
+ bufLen = 60; // The maximum length of string that a number is converted to.
+ } else {
+ bufLen = vVariant->nLen + 1;
+ }
+
if (schemaType == TSDB_DATA_TYPE_BINARY) {
- char *tmp = calloc(1, vVariant->nLen + TSDB_NCHAR_SIZE);
+ char *tmp = calloc(1, bufLen * TSDB_NCHAR_SIZE);
retVal = tVariantDump(vVariant, tmp, schemaType, false);
free(tmp);
} else if (schemaType == TSDB_DATA_TYPE_NCHAR) {
- // pRight->val.nLen + 1 is larger than the actual nchar string length
- char *tmp = calloc(1, (vVariant->nLen + 1) * TSDB_NCHAR_SIZE);
+ // pRight->value.nLen + 1 is larger than the actual nchar string length
+ char *tmp = calloc(1, bufLen * TSDB_NCHAR_SIZE);
retVal = tVariantDump(vVariant, tmp, schemaType, false);
free(tmp);
} else {
@@ -4364,12 +4171,12 @@ static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) {
if (retVal != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- }while (0);
+ } while (0);
return TSDB_CODE_SUCCESS;
}
-static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr, tSQLExpr** pExpr) {
+static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr, tSqlExpr** pExpr) {
int32_t ret = TSDB_CODE_SUCCESS;
if (pCondExpr->pTagCond == NULL) {
@@ -4377,7 +4184,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
}
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
- tSQLExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
+ tSqlExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
if (p1 == NULL) { // no query condition on this table
continue;
}
@@ -4409,7 +4216,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
}
tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
- doCompactQueryExpr(pExpr);
+ tSqlExprCompact(pExpr);
if (ret == TSDB_CODE_SUCCESS) {
ret = validateTagCondExpr(pCmd, p);
@@ -4432,7 +4239,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
return ret;
}
-int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
+int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) {
if (pExpr == NULL) {
return TSDB_CODE_SUCCESS;
}
@@ -4451,11 +4258,11 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql
}
int32_t type = 0;
- if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->nSQLOptr)) != TSDB_CODE_SUCCESS) {
+ if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, &type, (*pExpr)->tokenId)) != TSDB_CODE_SUCCESS) {
return ret;
}
- doCompactQueryExpr(pExpr);
+ tSqlExprCompact(pExpr);
// after expression compact, the expression tree is only include tag query condition
condExpr.pTagCond = (*pExpr);
@@ -4506,9 +4313,9 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql
return ret;
}
-int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t timePrecision) {
+int32_t getTimeRange(STimeWindow* win, tSqlExpr* pRight, int32_t optr, int16_t timePrecision) {
// this is join condition, do nothing
- if (pRight->nSQLOptr == TK_ID) {
+ if (pRight->tokenId == TK_ID) {
return TSDB_CODE_SUCCESS;
}
@@ -4516,42 +4323,42 @@ int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t t
* filter primary ts filter expression like:
* where ts in ('2015-12-12 4:8:12')
*/
- if (pRight->nSQLOptr == TK_SET || optr == TK_IN) {
+ if (pRight->tokenId == TK_SET || optr == TK_IN) {
return TSDB_CODE_TSC_INVALID_SQL;
}
int64_t val = 0;
bool parsed = false;
- if (pRight->val.nType == TSDB_DATA_TYPE_BINARY) {
- pRight->val.nLen = strdequote(pRight->val.pz);
+ if (pRight->value.nType == TSDB_DATA_TYPE_BINARY) {
+ pRight->value.nLen = strdequote(pRight->value.pz);
- char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false);
+ char* seg = strnchr(pRight->value.pz, '-', pRight->value.nLen, false);
if (seg != NULL) {
- if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
+ if (taosParseTime(pRight->value.pz, &val, pRight->value.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) {
parsed = true;
} else {
return TSDB_CODE_TSC_INVALID_SQL;
}
} else {
- SStrToken token = {.z = pRight->val.pz, .n = pRight->val.nLen, .type = TK_ID};
- int32_t len = tSQLGetToken(pRight->val.pz, &token.type);
+ SStrToken token = {.z = pRight->value.pz, .n = pRight->value.nLen, .type = TK_ID};
+ int32_t len = tSQLGetToken(pRight->value.pz, &token.type);
- if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->val.nLen) {
+ if ((token.type != TK_INTEGER && token.type != TK_FLOAT) || len != pRight->value.nLen) {
return TSDB_CODE_TSC_INVALID_SQL;
}
}
- } else if (pRight->nSQLOptr == TK_INTEGER && timePrecision == TSDB_TIME_PRECISION_MILLI) {
+ } else if (pRight->tokenId == TK_INTEGER && timePrecision == TSDB_TIME_PRECISION_MILLI) {
/*
- * if the pRight->nSQLOptr == TK_INTEGER/TK_FLOAT, the value is adaptive, we
+ * if the pRight->tokenId == TK_INTEGER/TK_FLOAT, the value is adaptive, we
* need the time precision in metermeta to transfer the value in MICROSECOND
*
* Additional check to avoid data overflow
*/
- if (pRight->val.i64 <= INT64_MAX / 1000) {
- pRight->val.i64 *= 1000;
+ if (pRight->value.i64 <= INT64_MAX / 1000) {
+ pRight->value.i64 *= 1000;
}
- } else if (pRight->nSQLOptr == TK_FLOAT && timePrecision == TSDB_TIME_PRECISION_MILLI) {
- pRight->val.dKey *= 1000;
+ } else if (pRight->tokenId == TK_FLOAT && timePrecision == TSDB_TIME_PRECISION_MILLI) {
+ pRight->value.dKey *= 1000;
}
if (!parsed) {
@@ -4559,7 +4366,7 @@ int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t t
* failed to parse timestamp in regular formation, try next
* it may be a epoch time in string format
*/
- tVariantDump(&pRight->val, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
+ tVariantDump(&pRight->value, (char*)&val, TSDB_DATA_TYPE_BIGINT, true);
/*
* transfer it into MICROSECOND format if it is a string, since for
@@ -4567,7 +4374,7 @@ int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t t
*
* additional check to avoid data overflow
*/
- if (pRight->nSQLOptr == TK_STRING && timePrecision == TSDB_TIME_PRECISION_MILLI) {
+ if (pRight->tokenId == TK_STRING && timePrecision == TSDB_TIME_PRECISION_MILLI) {
if (val <= INT64_MAX / 1000) {
val *= 1000;
}
@@ -4626,7 +4433,7 @@ int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
return TSDB_CODE_SUCCESS;
}
-int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
+int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySQL) {
SArray* pFillToken = pQuerySQL->fillType;
tVariantListItem* pItem = taosArrayGet(pFillToken, 0);
@@ -4748,7 +4555,7 @@ static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
}
}
-int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
+int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode, 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";
@@ -4763,11 +4570,11 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu
pQueryInfo->order.orderColId = 0;
return TSDB_CODE_SUCCESS;
}
- if (pQuerySql->pSortOrder == NULL) {
+ if (pQuerySqlNode->pSortOrder == NULL) {
return TSDB_CODE_SUCCESS;
}
- SArray* pSortorder = pQuerySql->pSortOrder;
+ SArray* pSortorder = pQuerySqlNode->pSortOrder;
/*
* for table query, there is only one or none order option is allowed, which is the
@@ -4835,7 +4642,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu
if (orderByTags) {
pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
- tVariantListItem* p1 = taosArrayGet(pQuerySql->pSortOrder, 0);
+ tVariantListItem* p1 = taosArrayGet(pQuerySqlNode->pSortOrder, 0);
pQueryInfo->groupbyExpr.orderType = p1->sortOrder;
} else if (isTopBottomQuery(pQueryInfo)) {
/* order of top/bottom query in interval is not valid */
@@ -4847,12 +4654,12 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- tVariantListItem* p1 = taosArrayGet(pQuerySql->pSortOrder, 0);
+ tVariantListItem* p1 = taosArrayGet(pQuerySqlNode->pSortOrder, 0);
pQueryInfo->order.order = p1->sortOrder;
pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
return TSDB_CODE_SUCCESS;
} else {
- tVariantListItem* p1 = taosArrayGet(pQuerySql->pSortOrder, 0);
+ tVariantListItem* p1 = taosArrayGet(pQuerySqlNode->pSortOrder, 0);
pQueryInfo->order.order = p1->sortOrder;
pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
@@ -4865,7 +4672,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu
}
if (s == 2) {
- tVariantListItem *pItem = taosArrayGet(pQuerySql->pSortOrder, 0);
+ tVariantListItem *pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 0);
if (orderByTags) {
pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
pQueryInfo->groupbyExpr.orderType = pItem->sortOrder;
@@ -4874,7 +4681,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu
pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
}
- pItem = taosArrayGet(pQuerySql->pSortOrder, 1);
+ pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 1);
tVariant* pVar2 = &pItem->pVar;
SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
@@ -4909,13 +4716,13 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- tVariantListItem* pItem = taosArrayGet(pQuerySql->pSortOrder, 0);
+ tVariantListItem* pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 0);
pQueryInfo->order.order = pItem->sortOrder;
pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
return TSDB_CODE_SUCCESS;
}
- tVariantListItem* pItem = taosArrayGet(pQuerySql->pSortOrder, 0);
+ tVariantListItem* pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 0);
pQueryInfo->order.order = pItem->sortOrder;
}
@@ -5378,7 +5185,7 @@ int32_t validateLocalConfig(SMiscInfo* pOptions) {
// reset log does not need value
for (int32_t i = 0; i < 1; ++i) {
SDNodeDynConfOption* pOption = &LOCAL_DYNAMIC_CFG_OPTIONS[i];
- if ((pOption->len == pOptionToken->n) &&
+ if ((pOption->len == pOptionToken->n) &&
(strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0)) {
return TSDB_CODE_SUCCESS;
}
@@ -5393,7 +5200,7 @@ int32_t validateLocalConfig(SMiscInfo* pOptions) {
for (int32_t i = 1; i < tListLen(LOCAL_DYNAMIC_CFG_OPTIONS); ++i) {
SDNodeDynConfOption* pOption = &LOCAL_DYNAMIC_CFG_OPTIONS[i];
- if ((pOption->len == pOptionToken->n)
+ if ((pOption->len == pOptionToken->n)
&& (strncasecmp(pOption->name, pOptionToken->z, pOptionToken->n) == 0)) {
return TSDB_CODE_SUCCESS;
}
@@ -5443,7 +5250,7 @@ bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0);
}
-int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL* pQuerySql, SSqlObj* pSql) {
+int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySqlNode* pQuerySqlNode, SSqlObj* pSql) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
const char* msg0 = "soffset/offset can not be less than 0";
@@ -5451,9 +5258,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 = pQuerySql->limit;
+ pQueryInfo->limit = pQuerySqlNode->limit;
pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
- pQueryInfo->slimit = pQuerySql->slimit;
+ pQueryInfo->slimit = pQuerySqlNode->slimit;
tscDebug("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
@@ -5614,6 +5421,8 @@ static void setCreateDBOption(SCreateDbMsg* pMsg, SCreateDbInfo* pCreateDb) {
pMsg->ignoreExist = pCreateDb->ignoreExists;
pMsg->update = pCreateDb->update;
pMsg->cacheLastRow = pCreateDb->cachelast;
+ pMsg->dbType = pCreateDb->dbType;
+ pMsg->partitions = htons(pCreateDb->partitions);
}
int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDbInfo* pCreateDbSql) {
@@ -5976,8 +5785,8 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo
SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
} else {
- // if this query is "group by" normal column, interval is not allowed
- if (pQueryInfo->interval.interval > 0) {
+ // if this query is "group by" normal column, time window query is not allowed
+ if (isTimeWindowQuery(pQueryInfo)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
@@ -6039,7 +5848,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
- if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->interval.interval > 0) {
+ if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || isTimeWindowQuery(pQueryInfo)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
} else {
return TSDB_CODE_SUCCESS;
@@ -6110,17 +5919,20 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
return checkUpdateTagPrjFunctions(pQueryInfo, pCmd);
}
}
-int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
+int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode) {
const char* msg1 = "only one expression allowed";
const char* msg2 = "invalid expression in select clause";
const char* msg3 = "invalid function";
- tSQLExprList* pExprList = pQuerySql->pSelection;
- if (pExprList->nExpr != 1) {
+ SArray* pExprList = pQuerySqlNode->pSelectList;
+ size_t size = taosArrayGetSize(pExprList);
+ if (size != 1) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
+
bool server_status = false;
- tSQLExpr* pExpr = pExprList->a[0].pNode;
+ tSqlExprItem* pExprItem = taosArrayGet(pExprList, 0);
+ tSqlExpr* pExpr = pExprItem->pNode;
if (pExpr->operand.z == NULL) {
//handle 'select 1'
if (pExpr->token.n == 1 && 0 == strncasecmp(pExpr->token.z, "1", 1)) {
@@ -6141,8 +5953,8 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQ
index = 2;
} else {
for (int32_t i = 0; i < tListLen(functionsInfo); ++i) {
- if (strncasecmp(functionsInfo[i].name, pExpr->operand.z, functionsInfo[i].len) == 0 &&
- functionsInfo[i].len == pExpr->operand.n) {
+ if (strncasecmp(functionsInfo[i].name, pExpr->token.z, functionsInfo[i].len) == 0 &&
+ functionsInfo[i].len == pExpr->token.n) {
index = i;
break;
}
@@ -6166,8 +5978,9 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQ
SColumnIndex ind = {0};
SSqlExpr* 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);
-
- const char* name = (pExprList->a[0].aliasName != NULL)? pExprList->a[0].aliasName:functionsInfo[index].name;
+
+ tSqlExprItem* item = taosArrayGet(pExprList, 0);
+ const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[index].name;
tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName));
return TSDB_CODE_SUCCESS;
@@ -6244,6 +6057,15 @@ int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
}
+ val = (int16_t)htons(pCreate->partitions);
+ if (val != -1 &&
+ (val < TSDB_MIN_DB_PARTITON_OPTION || val > TSDB_MAX_DB_PARTITON_OPTION)) {
+ snprintf(msg, tListLen(msg), "invalid topic option partition: %d valid range: [%d, %d]", val,
+ TSDB_MIN_DB_PARTITON_OPTION, TSDB_MAX_DB_PARTITON_OPTION);
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
+ }
+
+
return TSDB_CODE_SUCCESS;
}
@@ -6293,7 +6115,7 @@ int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* p
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex);
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
- SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
+ SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo;
SArray* pFieldList = pCreateTable->colInfo.pColumns;
SArray* pTagList = pCreateTable->colInfo.pTagColumns;
@@ -6348,7 +6170,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
SSqlCmd* pCmd = &pSql->cmd;
- SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
+ SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo;
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
// two table: the first one is for current table, and the secondary is for the super table.
@@ -6428,12 +6250,12 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
tVariantListItem* pItem = taosArrayGet(pValList, i);
findColumnIndex = false;
-
+
// todo speedup by using hash list
for (int32_t t = 0; t < schemaSize; ++t) {
if (strncmp(sToken->z, pTagSchema[t].name, sToken->n) == 0 && strlen(pTagSchema[t].name) == sToken->n) {
SSchema* pSchema = &pTagSchema[t];
-
+
char tagVal[TSDB_MAX_TAGS_LEN];
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
if (pItem->pVar.nLen > pSchema->bytes) {
@@ -6441,9 +6263,9 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
}
-
+
ret = tVariantDump(&(pItem->pVar), tagVal, pSchema->type, true);
-
+
// check again after the convert since it may be converted from binary to nchar.
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
int16_t len = varDataTLen(tagVal);
@@ -6452,12 +6274,12 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
}
-
+
if (ret != TSDB_CODE_SUCCESS) {
tdDestroyKVRowBuilder(&kvRowBuilder);
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
-
+
tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
findColumnIndex = true;
@@ -6468,7 +6290,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
if (!findColumnIndex) {
tdDestroyKVRowBuilder(&kvRowBuilder);
return tscInvalidSQLErrMsg(pCmd->payload, "invalid tag name", sToken->z);
- }
+ }
}
} else {
if (schemaSize != valSize) {
@@ -6479,7 +6301,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
for (int32_t i = 0; i < valSize; ++i) {
SSchema* pSchema = &pTagSchema[i];
tVariantListItem* pItem = taosArrayGet(pValList, i);
-
+
char tagVal[TSDB_MAX_TAGS_LEN];
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
if (pItem->pVar.nLen > pSchema->bytes) {
@@ -6487,9 +6309,9 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
}
-
+
ret = tVariantDump(&(pItem->pVar), tagVal, pSchema->type, true);
-
+
// check again after the convert since it may be converted from binary to nchar.
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
int16_t len = varDataTLen(tagVal);
@@ -6498,12 +6320,12 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
}
-
+
if (ret != TSDB_CODE_SUCCESS) {
tdDestroyKVRowBuilder(&kvRowBuilder);
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
-
+
tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
}
}
@@ -6557,24 +6379,24 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
assert(pQueryInfo->numOfTables == 1);
- SCreateTableSQL* pCreateTable = pInfo->pCreateTableInfo;
+ SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo;
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
// if sql specifies db, use it, otherwise use default db
SStrToken* pName = &(pCreateTable->name);
- SQuerySQL* pQuerySql = pCreateTable->pSelect;
+ SQuerySqlNode* pQuerySqlNode = pCreateTable->pSelect;
if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
- SArray* pSrcMeterName = pInfo->pCreateTableInfo->pSelect->from;
- if (pSrcMeterName == NULL || taosArrayGetSize(pSrcMeterName) == 0) {
+ SFromInfo* pFromInfo = pInfo->pCreateTableInfo->pSelect->from;
+ if (pFromInfo == NULL || taosArrayGetSize(pFromInfo->tableList) == 0) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
}
- tVariantListItem* p1 = taosArrayGet(pSrcMeterName, 0);
- SStrToken srcToken = {.z = p1->pVar.pz, .n = p1->pVar.nLen, .type = TK_STRING};
+ STableNamePair* p1 = taosArrayGet(pFromInfo->tableList, 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);
}
@@ -6590,23 +6412,22 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
}
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
- if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false, false) != TSDB_CODE_SUCCESS) {
+ if (parseSelectClause(&pSql->cmd, 0, pQuerySqlNode->pSelectList, isSTable, false, false) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
- if (pQuerySql->pWhere != NULL) { // query condition in stream computing
- if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
+ if (pQuerySqlNode->pWhere != NULL) { // query condition in stream computing
+ if (parseWhereClause(pQueryInfo, &pQuerySqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
}
// set interval value
- if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
+ if (parseIntervalClause(pSql, pQueryInfo, pQuerySqlNode) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
- if ((pQueryInfo->interval.interval > 0) &&
- (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
+ if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
@@ -6620,7 +6441,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
return code;
}
- if (pQuerySql->selectToken.n > TSDB_MAX_SAVED_SQL_LEN) {
+ if (pQuerySqlNode->sqlstr.n > TSDB_MAX_SAVED_SQL_LEN) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
@@ -6638,12 +6459,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 (pQuerySql->fillType != NULL) {
+ if (pQuerySqlNode->fillType != NULL) {
if (pQueryInfo->interval.interval == 0) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
- tVariantListItem* pItem = taosArrayGet(pQuerySql->fillType, 0);
+ tVariantListItem* pItem = taosArrayGet(pQuerySqlNode->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))) {
@@ -6692,10 +6513,10 @@ static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
return TSDB_CODE_SUCCESS;
}
-int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
- assert(pQuerySql != NULL && (pQuerySql->from == NULL || taosArrayGetSize(pQuerySql->from) > 0));
+int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t index) {
+ assert(pQuerySqlNode != NULL && (pQuerySqlNode->from == NULL || taosArrayGetSize(pQuerySqlNode->from->tableList) > 0));
- const char* msg0 = "invalid table name";
+ 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* msg3 = "start(end) time of query range required or time range too large";
@@ -6703,6 +6524,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
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;
@@ -6717,7 +6539,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
assert(pCmd->clauseIndex == index);
// too many result columns not support order by in query
- if (pQuerySql->pSelection->nExpr > TSDB_MAX_COLUMNS) {
+ if (taosArrayGetSize(pQuerySqlNode->pSelectList) > TSDB_MAX_COLUMNS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
@@ -6728,77 +6550,77 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
* select client_version();
* select server_state();
*/
- if (pQuerySql->from == NULL) {
- assert(pQuerySql->fillType == NULL && pQuerySql->pGroupby == NULL && pQuerySql->pWhere == NULL &&
- pQuerySql->pSortOrder == NULL);
- return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
+ if (pQuerySqlNode->from == NULL) {
+ assert(pQuerySqlNode->fillType == NULL && pQuerySqlNode->pGroupby == NULL && pQuerySqlNode->pWhere == NULL &&
+ pQuerySqlNode->pSortOrder == NULL);
+ return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySqlNode);
}
- size_t fromSize = taosArrayGetSize(pQuerySql->from);
- if (fromSize > TSDB_MAX_JOIN_TABLE_NUM * 2) {
+ size_t fromSize = taosArrayGetSize(pQuerySqlNode->from->tableList);
+ if (fromSize > TSDB_MAX_JOIN_TABLE_NUM) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
pQueryInfo->command = TSDB_SQL_SELECT;
-
- if (fromSize > 4) {
+ if (fromSize > 2) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
}
// set all query tables, which are maybe more than one.
- for (int32_t i = 0; i < fromSize; ) {
- tVariantListItem* item = taosArrayGet(pQuerySql->from, i);
- tVariant* pTableItem = &item->pVar;
+ for (int32_t i = 0; i < fromSize; ++i) {
+ STableNamePair* item = taosArrayGet(pQuerySqlNode->from->tableList, i);
+ SStrToken* pTableItem = &item->name;
- if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
+ if (pTableItem->type != TSDB_DATA_TYPE_BINARY) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
}
- pTableItem->nLen = strdequote(pTableItem->pz);
+ tscDequoteAndTrimToken(pTableItem);
- SStrToken tableName = {.z = pTableItem->pz, .n = pTableItem->nLen, .type = TK_STRING};
+ 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/2) { // more than one table
+ if (pQueryInfo->numOfTables <= i) { // more than one table
tscAddEmptyMetaInfo(pQueryInfo);
}
- STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i/2);
-
- SStrToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
- code = tscSetTableFullName(pTableMetaInfo1, &t, pSql);
+ STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i);
+ code = tscSetTableFullName(pTableMetaInfo1, pTableItem, pSql);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
- tVariantListItem* p1 = taosArrayGet(pQuerySql->from, i + 1);
- if (p1->pVar.nType != TSDB_DATA_TYPE_BINARY) {
- return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
- }
+ SStrToken* aliasName = &item->aliasName;
+ if (TPARSER_HAS_TOKEN(*aliasName)) {
+ if (aliasName->type != TSDB_DATA_TYPE_BINARY) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
+ }
- SStrToken aliasName = {.z = p1->pVar.pz, .n = p1->pVar.nLen, .type = TK_STRING};
- if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
- return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
- }
+ tscDequoteAndTrimToken(aliasName);
- // has no table alias name
- if (memcmp(pTableItem->pz, p1->pVar.pz, p1->pVar.nLen) == 0) {
- strncpy(pTableMetaInfo1->aliasName, tNameGetTableName(&pTableMetaInfo1->name), tListLen(pTableMetaInfo->aliasName));
+ SStrToken aliasName1 = {.z = aliasName->z, .n = aliasName->n, .type = TK_STRING};
+ if (tscValidateName(&aliasName1) != TSDB_CODE_SUCCESS) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
+ }
+
+ if (aliasName1.n >= TSDB_TABLE_NAME_LEN) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
+ }
+
+ strncpy(pTableMetaInfo1->aliasName, aliasName1.z, aliasName1.n);
} else {
- tstrncpy(pTableMetaInfo1->aliasName, p1->pVar.pz, sizeof(pTableMetaInfo1->aliasName));
+ strncpy(pTableMetaInfo1->aliasName, tNameGetTableName(&pTableMetaInfo1->name), tListLen(pTableMetaInfo1->aliasName));
}
code = tscGetTableMeta(pSql, pTableMetaInfo1);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
-
- i += 2;
}
- assert(pQueryInfo->numOfTables == taosArrayGetSize(pQuerySql->from) / 2);
+ assert(pQueryInfo->numOfTables == taosArrayGetSize(pQuerySqlNode->from->tableList));
bool isSTable = false;
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
@@ -6814,52 +6636,56 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
}
// parse the group by clause in the first place
- if (parseGroupbyClause(pQueryInfo, pQuerySql->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
+ if (parseGroupbyClause(pQueryInfo, pQuerySqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
// set where info
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
- if (pQuerySql->pWhere != NULL) {
- if (parseWhereClause(pQueryInfo, &pQuerySql->pWhere, pSql) != TSDB_CODE_SUCCESS) {
+ if (pQuerySqlNode->pWhere != NULL) {
+ if (parseWhereClause(pQueryInfo, &pQuerySqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
- pQuerySql->pWhere = NULL;
+ 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(pQuerySql->from) > 2) { // it is a join query, no wher clause is not allowed.
+ 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 = (pQuerySql->from != NULL && taosArrayGetSize(pQuerySql->from) > 2);
+ 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));
- int32_t intervalQuery = !(pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0);
-
- if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery, intervalQuery) != TSDB_CODE_SUCCESS) {
+ 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, pQuerySql, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
+ if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
// set interval value
- if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
+ if (parseIntervalClause(pSql, pQueryInfo, pQuerySqlNode) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
} else {
- if ((pQueryInfo->interval.interval > 0) &&
+ if (isTimeWindowQuery(pQueryInfo) &&
(validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
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;
@@ -6873,13 +6699,12 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
// 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, pQuerySql, pSql)) != TSDB_CODE_SUCCESS) {
+ if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySqlNode, pSql)) != TSDB_CODE_SUCCESS) {
return code;
}
@@ -6887,9 +6712,10 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
return code;
}
+ updateLastScanOrderIfNeeded(pQueryInfo);
tscFieldInfoUpdateOffset(pQueryInfo);
- if (pQuerySql->fillType != NULL) {
+ if (pQuerySqlNode->fillType != NULL) {
if (pQueryInfo->interval.interval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
@@ -6902,7 +6728,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
return code;
}
- if ((code = parseFillClause(pCmd, pQueryInfo, pQuerySql)) != TSDB_CODE_SUCCESS) {
+ if ((code = parseFillClause(pCmd, pQueryInfo, pQuerySqlNode)) != TSDB_CODE_SUCCESS) {
return code;
}
}
@@ -6910,7 +6736,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
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, int64_t *uid) {
tExprNode* pLeft = NULL;
tExprNode* pRight= NULL;
@@ -6928,25 +6754,25 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
}
}
- if (pSqlExpr->pLeft == NULL && pSqlExpr->pRight == NULL && pSqlExpr->nSQLOptr == 0) {
+ if (pSqlExpr->pLeft == NULL && pSqlExpr->pRight == NULL && pSqlExpr->tokenId == 0) {
*pExpr = calloc(1, sizeof(tExprNode));
return TSDB_CODE_SUCCESS;
}
if (pSqlExpr->pLeft == NULL) {
- if (pSqlExpr->nSQLOptr >= TK_BOOL && pSqlExpr->nSQLOptr <= TK_STRING) {
+ if (pSqlExpr->type == SQL_NODE_VALUE) {
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_VALUE;
(*pExpr)->pVal = calloc(1, sizeof(tVariant));
- tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
+ tVariantAssign((*pExpr)->pVal, &pSqlExpr->value);
return TSDB_CODE_SUCCESS;
- } else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
+ } else if (pSqlExpr->type == SQL_NODE_SQLFUNCTION) {
// arithmetic expression on the results of aggregation functions
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_COL;
(*pExpr)->pSchema = calloc(1, sizeof(SSchema));
- strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
+ strncpy((*pExpr)->pSchema->name, pSqlExpr->token.z, pSqlExpr->token.n);
// set the input column data byte and type.
size_t size = taosArrayGetSize(pQueryInfo->exprList);
@@ -6966,7 +6792,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
break;
}
}
- } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
+ } else if (pSqlExpr->type == SQL_NODE_TABLE_COLUMN) { // column name, normal column arithmetic expression
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
if (ret != TSDB_CODE_SUCCESS) {
@@ -7006,7 +6832,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
(*pExpr)->_node.pLeft = pLeft;
(*pExpr)->_node.pRight = pRight;
- SStrToken t = {.type = pSqlExpr->nSQLOptr};
+ SStrToken t = {.type = pSqlExpr->tokenId};
(*pExpr)->_node.optr = convertOptr(&t);
assert((*pExpr)->_node.optr != 0);
diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c
index d005eaf75cb7544d9ab51cd313a542cf04da53e3..45ca470ce69bda06484feea2af2a9dec004e815f 100644
--- a/src/client/src/tscServer.c
+++ b/src/client/src/tscServer.c
@@ -497,8 +497,6 @@ int tscProcessSql(SSqlObj *pSql) {
return pSql->res.code;
}
} else if (pCmd->command >= TSDB_SQL_LOCAL) {
- //pSql->epSet = tscMgmtEpSet;
-// } else { // local handler
return (*tscProcessMsgRsp[pCmd->command])(pSql);
}
@@ -522,7 +520,7 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
assert(pVgroupInfo->vgroups[vgIndex].vgId > 0 && vgIndex < pTableMetaInfo->vgroupList->numOfVgroups);
pRetrieveMsg->header.vgId = htonl(pVgroupInfo->vgroups[vgIndex].vgId);
- tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d", pSql, pVgroupInfo->vgroups[vgIndex].vgId, vgIndex);
+ tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qhandle:%" PRIX64, pSql, pVgroupInfo->vgroups[vgIndex].vgId, vgIndex, pSql->res.qhandle);
} else {
int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
assert(vgIndex >= 0 && vgIndex < numOfVgroups);
@@ -530,12 +528,12 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, vgIndex);
pRetrieveMsg->header.vgId = htonl(pTableIdList->vgInfo.vgId);
- tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d", pSql, pTableIdList->vgInfo.vgId, vgIndex);
+ tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qhandle:%" PRIX64, pSql, pTableIdList->vgInfo.vgId, vgIndex, pSql->res.qhandle);
}
} else {
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
pRetrieveMsg->header.vgId = htonl(pTableMeta->vgId);
- tscDebug("%p build fetch msg from only one vgroup, vgId:%d", pSql, pTableMeta->vgId);
+ tscDebug("%p build fetch msg from only one vgroup, vgId:%d, qhandle:%" PRIX64, pSql, pTableMeta->vgId, pSql->res.qhandle);
}
pSql->cmd.payloadLen = sizeof(SRetrieveTableMsg);
@@ -645,7 +643,6 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
}
pSql->epSet.inUse = rand()%pSql->epSet.numOfEps;
-
pQueryMsg->head.vgId = htonl(vgId);
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
@@ -660,8 +657,6 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
assert(index >= 0 && index < numOfVgroups);
- tscDebug("%p query on stable, vgIndex:%d, numOfVgroups:%d", pSql, index, numOfVgroups);
-
SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, index);
// set the vgroup info
@@ -670,7 +665,10 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
int32_t numOfTables = (int32_t)taosArrayGetSize(pTableIdList->itemList);
pQueryMsg->numOfTables = htonl(numOfTables); // set the number of tables
-
+
+ tscDebug("%p query on stable, vgId:%d, numOfTables:%d, vgIndex:%d, numOfVgroups:%d", pSql,
+ pTableIdList->vgInfo.vgId, numOfTables, index, numOfVgroups);
+
// serialize each table id info
for(int32_t i = 0; i < numOfTables; ++i) {
STableIdInfo* pItem = taosArrayGet(pTableIdList->itemList, i);
@@ -705,7 +703,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
- if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo)) {
+ if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) {
tscError("%p illegal value of numOfCols in query msg: %" PRIu64 ", table cols:%d", pSql, (uint64_t)numOfSrcCols,
tscGetNumOfColumns(pTableMeta));
@@ -756,6 +754,8 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
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
@@ -835,13 +835,31 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
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);
pMsg += sizeof(SSqlFuncMsg);
- for (int32_t j = 0; j < pExpr->numOfParams; ++j) {
- // todo add log
+ 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);
@@ -866,6 +884,8 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
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
@@ -879,33 +899,31 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
return TSDB_CODE_TSC_INVALID_SQL;
}
- pSqlFuncExpr1->colInfo.colId = htons(pExpr->colInfo.colId);
- pSqlFuncExpr1->colInfo.colIndex = htons(pExpr->colInfo.colIndex);
- pSqlFuncExpr1->colInfo.flag = htons(pExpr->colInfo.flag);
-
- pSqlFuncExpr1->functionId = htons(pExpr->functionId);
- pSqlFuncExpr1->numOfParams = htons(pExpr->numOfParams);
- pMsg += sizeof(SSqlFuncMsg);
-
- for (int32_t j = 0; j < pExpr->numOfParams; ++j) {
- // todo add log
- pSqlFuncExpr1->arg[j].argType = htons((uint16_t)pExpr->param[j].nType);
- pSqlFuncExpr1->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 {
- pSqlFuncExpr1->arg[j].argValue.i64 = htobe64(pExpr->param[j].i64);
+ 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->colInfo.colId = htons(pExprInfo->base.colInfo.colId);
pSqlFuncExpr1->functionId = htons(pExprInfo->base.functionId);
pSqlFuncExpr1->numOfParams = htons(pExprInfo->base.numOfParams);
pMsg += sizeof(SSqlFuncMsg);
@@ -1055,7 +1073,8 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SCreateDbMsg);
- pCmd->msgType = TSDB_MSG_TYPE_CM_CREATE_DB;
+
+ pCmd->msgType = (pInfo->pMiscInfo->dbOpt.dbType == TSDB_DB_TYPE_DEFAULT) ? TSDB_MSG_TYPE_CM_CREATE_DB : TSDB_MSG_TYPE_CM_CREATE_TP;
SCreateDbMsg *pCreateDbMsg = (SCreateDbMsg *)pCmd->payload;
@@ -1187,7 +1206,7 @@ int32_t tscBuildDropDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pDropDbMsg->ignoreNotExists = pInfo->pMiscInfo->existsCheck ? 1 : 0;
- pCmd->msgType = TSDB_MSG_TYPE_CM_DROP_DB;
+ pCmd->msgType = (pInfo->pMiscInfo->dbType == TSDB_DB_TYPE_DEFAULT) ? TSDB_MSG_TYPE_CM_DROP_DB : TSDB_MSG_TYPE_CM_DROP_TP;
return TSDB_CODE_SUCCESS;
}
@@ -1331,7 +1350,7 @@ int tscEstimateCreateTableMsgLength(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &(pSql->cmd);
int32_t size = minMsgSize() + sizeof(SCMCreateTableMsg) + sizeof(SCreateTableMsg);
- SCreateTableSQL *pCreateTableInfo = pInfo->pCreateTableInfo;
+ SCreateTableSql *pCreateTableInfo = pInfo->pCreateTableInfo;
if (pCreateTableInfo->type == TSQL_CREATE_TABLE_FROM_STABLE) {
int32_t numOfTables = (int32_t)taosArrayGetSize(pInfo->pCreateTableInfo->childTableInfo);
size += numOfTables * (sizeof(SCreateTableMsg) + TSDB_MAX_TAGS_LEN);
@@ -1340,7 +1359,7 @@ int tscEstimateCreateTableMsgLength(SSqlObj *pSql, SSqlInfo *pInfo) {
}
if (pCreateTableInfo->pSelect != NULL) {
- size += (pCreateTableInfo->pSelect->selectToken.n + 1);
+ size += (pCreateTableInfo->pSelect->sqlstr.n + 1);
}
return size + TSDB_EXTRA_PAYLOAD_SIZE;
@@ -1398,7 +1417,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pCreateMsg->tableName);
assert(code == 0);
- SCreateTableSQL *pCreateTable = pInfo->pCreateTableInfo;
+ SCreateTableSql *pCreateTable = pInfo->pCreateTableInfo;
pCreateMsg->igExists = pCreateTable->existCheck ? 1 : 0;
pCreateMsg->numOfColumns = htons(pCmd->numOfCols);
@@ -1421,11 +1440,11 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pMsg = (char *)pSchema;
if (type == TSQL_CREATE_STREAM) { // check if it is a stream sql
- SQuerySQL *pQuerySql = pInfo->pCreateTableInfo->pSelect;
+ SQuerySqlNode *pQuerySql = pInfo->pCreateTableInfo->pSelect;
- strncpy(pMsg, pQuerySql->selectToken.z, pQuerySql->selectToken.n + 1);
- pCreateMsg->sqlLen = htons(pQuerySql->selectToken.n + 1);
- pMsg += pQuerySql->selectToken.n + 1;
+ strncpy(pMsg, pQuerySql->sqlstr.z, pQuerySql->sqlstr.n + 1);
+ pCreateMsg->sqlLen = htons(pQuerySql->sqlstr.n + 1);
+ pMsg += pQuerySql->sqlstr.n + 1;
}
}
@@ -1514,9 +1533,11 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
int tscAlterDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SAlterDbMsg);
- pCmd->msgType = TSDB_MSG_TYPE_CM_ALTER_DB;
+ pCmd->msgType = (pInfo->pMiscInfo->dbOpt.dbType == TSDB_DB_TYPE_DEFAULT) ? TSDB_MSG_TYPE_CM_ALTER_DB : TSDB_MSG_TYPE_CM_ALTER_TP;
SAlterDbMsg *pAlterDbMsg = (SAlterDbMsg* )pCmd->payload;
+ pAlterDbMsg->dbType = -1;
+
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
tNameExtractFullName(&pTableMetaInfo->name, pAlterDbMsg->db);
diff --git a/src/client/src/tscSub.c b/src/client/src/tscSub.c
index f3d7ef28c05fc3128622f8217341d52327d79ec0..32257f5a7c723d04ec0f8200c889a68d78cf7824 100644
--- a/src/client/src/tscSub.c
+++ b/src/client/src/tscSub.c
@@ -503,9 +503,19 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
SSqlCmd *pCmd = &pSql->cmd;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
- if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single tabel subscription
- pQueryInfo->window.skey = ((SSubscriptionProgress*)taosArrayGet(pSub->progress, 0))->key;
- tscDebug("subscribe:%s set subscribe skey:%"PRId64, pSub->topic, pQueryInfo->window.skey);
+ if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single table subscription
+
+ size_t size = taosArrayGetSize(pSub->progress);
+ TSKEY s = INT64_MAX;
+ for(int32_t i = 0; i < size; ++i) {
+ TSKEY k = ((SSubscriptionProgress*)taosArrayGet(pSub->progress, i))->key;
+ if (s > k) {
+ s = k;
+ }
+ }
+
+ pQueryInfo->window.skey = s;
+ tscDebug("subscribe:%s set next round subscribe skey:%"PRId64, pSub->topic, pQueryInfo->window.skey);
}
if (pSub->pTimer == NULL) {
diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c
index 78e9c6829081cb61f5fa8e2ed55397242ba357a4..22cb5809510e0863c8aaeb71e0072a3146b31610 100644
--- a/src/client/src/tscSubquery.c
+++ b/src/client/src/tscSubquery.c
@@ -74,14 +74,14 @@ static bool allSubqueryDone(SSqlObj *pParentSql) {
SSubqueryState *subState = &pParentSql->subState;
//lock in caller
-
+ tscDebug("%p total subqueries: %d", pParentSql, subState->numOfSub);
for (int i = 0; i < subState->numOfSub; i++) {
if (0 == subState->states[i]) {
- tscDebug("%p subquery:%p,%d is NOT finished, total:%d", pParentSql, pParentSql->pSubs[i], i, subState->numOfSub);
+ tscDebug("%p subquery:%p, index: %d NOT finished, abort query completion check", pParentSql, pParentSql->pSubs[i], i);
done = false;
break;
} else {
- tscDebug("%p subquery:%p,%d is finished, total:%d", pParentSql, pParentSql->pSubs[i], i, subState->numOfSub);
+ tscDebug("%p subquery:%p, index: %d finished", pParentSql, pParentSql->pSubs[i], i);
}
}
@@ -453,7 +453,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
pSubQueryInfo->tsBuf = NULL;
// free result for async object will also free sqlObj
- assert(tscSqlExprNumOfExprs(pSubQueryInfo) == 1); // ts_comp query only requires one resutl columns
+ assert(tscSqlExprNumOfExprs(pSubQueryInfo) == 1); // ts_comp query only requires one result columns
taos_free_result(pPrevSub);
SSqlObj *pNew = createSubqueryObj(pSql, (int16_t) i, tscJoinQueryCallback, pSupporter, TSDB_SQL_SELECT, NULL);
@@ -507,6 +507,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0);
int16_t funcId = pExpr->functionId;
+ // add the invisible timestamp column
if ((pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) ||
(funcId != TSDB_FUNC_TS && funcId != TSDB_FUNC_TS_DUMMY && funcId != TSDB_FUNC_PRJ)) {
@@ -847,6 +848,8 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
SSqlRes* pRes = &pSql->res;
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(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));
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
@@ -1059,7 +1062,6 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
tscError("%p invalid ts comp file from vnode, abort subquery, file size:%d", pSql, numOfRows);
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
-
if (quitAllSubquery(pSql, pParentSql, pSupporter)){
return;
}
@@ -1880,6 +1882,13 @@ void doAppendData(SInterResult* pInterResult, TAOS_ROW row, int32_t numOfCols, S
}
}
+ if (p && taosArrayGetSize(p) > 0) {
+ SResPair *l = taosArrayGetLast(p);
+ if (l->key == key && key == INT64_MIN) {
+ continue;
+ }
+ }
+
//append a new column
if (p == NULL) {
SStddevInterResult t = {.colId = id, .pResult = taosArrayInit(10, sizeof(SResPair)),};
@@ -1941,7 +1950,11 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
// tag or group by column
if (TSDB_COL_IS_TAG(pExpr->colInfo.flag) || pExpr->functionId == TSDB_FUNC_PRJ) {
- memcpy(p + offset, row[i], length[i]);
+ if (row[i] == NULL) {
+ setNull(p + offset, pExpr->resType, pExpr->resBytes);
+ } else {
+ memcpy(p + offset, row[i], length[i]);
+ }
offset += pExpr->resBytes;
}
}
@@ -2639,12 +2652,17 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0);
pQueryInfo->type |= TSDB_QUERY_TYPE_STABLE_SUBQUERY;
+
+ // clear the limit/offset info, since it should not be sent to vnode to be executed.
+ pQueryInfo->limit.limit = -1;
+ pQueryInfo->limit.offset = 0;
+
assert(pQueryInfo->numOfTables == 1 && pNew->cmd.numOfClause == 1 && trsupport->subqueryIndex < pSql->subState.numOfSub);
// launch subquery for each vnode, so the subquery index equals to the vgroupIndex.
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, table_index);
pTableMetaInfo->vgroupIndex = trsupport->subqueryIndex;
-
+
pSql->pSubs[trsupport->subqueryIndex] = pNew;
}
@@ -3098,30 +3116,6 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
}
}
-static UNUSED_FUNC void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pField) {
- SSqlRes *pRes = &pSql->res;
-
- if (pRes->tsrow[columnIndex] != NULL && pField->type == TSDB_DATA_TYPE_NCHAR) {
- // convert unicode to native code in a temporary buffer extra one byte for terminated symbol
- if (pRes->buffer[columnIndex] == NULL) {
- pRes->buffer[columnIndex] = malloc(pField->bytes + TSDB_NCHAR_SIZE);
- }
-
- /* string terminated char for binary data*/
- memset(pRes->buffer[columnIndex], 0, pField->bytes + TSDB_NCHAR_SIZE);
-
- int32_t length = taosUcs4ToMbs(pRes->tsrow[columnIndex], pRes->length[columnIndex], pRes->buffer[columnIndex]);
- if ( length >= 0 ) {
- pRes->tsrow[columnIndex] = (unsigned char*)pRes->buffer[columnIndex];
- pRes->length[columnIndex] = length;
- } else {
- tscError("%p charset:%s to %s. val:%s convert failed.", pSql, DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)pRes->tsrow[columnIndex]);
- pRes->tsrow[columnIndex] = NULL;
- pRes->length[columnIndex] = 0;
- }
- }
-}
-
char *getArithmeticInputSrc(void *param, const char *name, int32_t colId) {
SArithmeticSupport *pSupport = (SArithmeticSupport *) param;
diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c
index 578a7df1493b23792791a29bf0acf43c6e38b719..e8994502610653c01b9a6f93247f9ab4b42792af 100644
--- a/src/client/src/tscUtil.c
+++ b/src/client/src/tscUtil.c
@@ -97,6 +97,22 @@ bool tscQueryTags(SQueryInfo* pQueryInfo) {
return true;
}
+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;
+
+ // "select count(tbname)" query
+ if (functId == TSDB_FUNC_BLKINFO) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex) {
if (pQueryInfo == NULL) {
return false;
@@ -223,6 +239,21 @@ bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo) {
return false;
}
+bool tscGroupbyColumn(SQueryInfo* pQueryInfo) {
+ STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
+ int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
+
+ SSqlGroupbyExpr* pGroupbyExpr = &pQueryInfo->groupbyExpr;
+ for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols; ++k) {
+ SColIndex* pIndex = taosArrayGet(pGroupbyExpr->columnInfo, k);
+ if (!TSDB_COL_IS_TAG(pIndex->flag) && pIndex->colIndex < numOfCols) { // group by normal columns
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool tscIsTWAQuery(SQueryInfo* pQueryInfo) {
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
for (int32_t i = 0; i < numOfExprs; ++i) {
@@ -1128,7 +1159,7 @@ SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functi
}
SSqlExpr* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
- int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) {
+ int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) {
SSqlExpr* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol);
taosArrayPush(pQueryInfo->exprList, &pExpr);
return pExpr;
@@ -1722,10 +1753,15 @@ 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->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;
}
int32_t tscAddSubqueryInfo(SSqlCmd* pCmd) {
diff --git a/src/common/inc/tdataformat.h b/src/common/inc/tdataformat.h
index 959654d1585b13c31e96ab7972d0aa2782a51901..e8c076099759ffe683c78b55a54848cf765daada 100644
--- a/src/common/inc/tdataformat.h
+++ b/src/common/inc/tdataformat.h
@@ -283,12 +283,37 @@ typedef struct {
#define keyCol(pCols) (&((pCols)->cols[0])) // Key column
#define dataColsTKeyAt(pCols, idx) ((TKEY *)(keyCol(pCols)->pData))[(idx)]
#define dataColsKeyAt(pCols, idx) tdGetKey(dataColsTKeyAt(pCols, idx))
-#define dataColsTKeyFirst(pCols) (((pCols)->numOfRows == 0) ? TKEY_INVALID : dataColsTKeyAt(pCols, 0))
-#define dataColsKeyFirst(pCols) (((pCols)->numOfRows == 0) ? TSDB_DATA_TIMESTAMP_NULL : dataColsKeyAt(pCols, 0))
-#define dataColsTKeyLast(pCols) \
- (((pCols)->numOfRows == 0) ? TKEY_INVALID : dataColsTKeyAt(pCols, (pCols)->numOfRows - 1))
-#define dataColsKeyLast(pCols) \
- (((pCols)->numOfRows == 0) ? TSDB_DATA_TIMESTAMP_NULL : dataColsKeyAt(pCols, (pCols)->numOfRows - 1))
+static FORCE_INLINE TKEY dataColsTKeyFirst(SDataCols *pCols) {
+ if (pCols->numOfRows) {
+ return dataColsTKeyAt(pCols, 0);
+ } else {
+ return TKEY_INVALID;
+ }
+}
+
+static FORCE_INLINE TSKEY dataColsKeyFirst(SDataCols *pCols) {
+ if (pCols->numOfRows) {
+ return dataColsKeyAt(pCols, 0);
+ } else {
+ return TSDB_DATA_TIMESTAMP_NULL;
+ }
+}
+
+static FORCE_INLINE TKEY dataColsTKeyLast(SDataCols *pCols) {
+ if (pCols->numOfRows) {
+ return dataColsTKeyAt(pCols, pCols->numOfRows - 1);
+ } else {
+ return TKEY_INVALID;
+ }
+}
+
+static FORCE_INLINE TSKEY dataColsKeyLast(SDataCols *pCols) {
+ if (pCols->numOfRows) {
+ return dataColsKeyAt(pCols, pCols->numOfRows - 1);
+ } else {
+ return TSDB_DATA_TIMESTAMP_NULL;
+ }
+}
SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows);
void tdResetDataCols(SDataCols *pCols);
diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h
index c6d0226244b9b64d21fcc6c7939d61fa27a55525..3f96466cc00fc3250860e79bc3dd85e6fd0368d7 100644
--- a/src/common/inc/tglobal.h
+++ b/src/common/inc/tglobal.h
@@ -95,6 +95,7 @@ extern int8_t tsCompression;
extern int8_t tsWAL;
extern int32_t tsFsyncPeriod;
extern int32_t tsReplications;
+extern int16_t tsPartitons;
extern int32_t tsQuorum;
extern int8_t tsUpdate;
extern int8_t tsCacheLastRow;
@@ -162,6 +163,7 @@ extern float tsTotalDataDirGB;
extern float tsAvailLogDirGB;
extern float tsAvailTmpDirectorySpace;
extern float tsAvailDataDirGB;
+extern float tsUsedDataDirGB;
extern float tsMinimalLogDirGB;
extern float tsReservedTmpDirectorySpace;
extern float tsMinimalDataDirGB;
diff --git a/src/common/inc/tname.h b/src/common/inc/tname.h
index b651913d7384bac75eea7c9644b501b781c47e33..465b298973cbccdf380150bdce46a09b56594801 100644
--- a/src/common/inc/tname.h
+++ b/src/common/inc/tname.h
@@ -33,7 +33,7 @@ typedef struct SDataStatis {
typedef struct SColumnInfoData {
SColumnInfo info;
- void* pData; // the corresponding block data in memory
+ char* pData; // the corresponding block data in memory
} SColumnInfoData;
typedef struct SResPair {
diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c
index f50b829baa7c6dadea99bd81874cef57140f4fc0..1008c4cf8f77ca77f59a57aea189cdebef9c9129 100644
--- a/src/common/src/texpr.c
+++ b/src/common/src/texpr.c
@@ -41,41 +41,46 @@ static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, co
static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
switch(type) {
- case TSDB_DATA_TYPE_TINYINT: {
+ case TSDB_DATA_TYPE_TINYINT:
+ case TSDB_DATA_TYPE_UTINYINT:{
int8_t* p = (int8_t*) dest;
int8_t* pSrc = (int8_t*) src;
for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1];
}
- break;
+ return;
}
- case TSDB_DATA_TYPE_SMALLINT: {
+
+ case TSDB_DATA_TYPE_SMALLINT:
+ case TSDB_DATA_TYPE_USMALLINT:{
int16_t* p = (int16_t*) dest;
int16_t* pSrc = (int16_t*) src;
for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1];
}
- break;
+ return;
}
- case TSDB_DATA_TYPE_INT: {
+ case TSDB_DATA_TYPE_INT:
+ case TSDB_DATA_TYPE_UINT: {
int32_t* p = (int32_t*) dest;
int32_t* pSrc = (int32_t*) src;
for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1];
}
- break;
+ return;
}
- case TSDB_DATA_TYPE_BIGINT: {
+ case TSDB_DATA_TYPE_BIGINT:
+ case TSDB_DATA_TYPE_UBIGINT: {
int64_t* p = (int64_t*) dest;
int64_t* pSrc = (int64_t*) src;
for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1];
}
- break;
+ return;
}
case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) dest;
@@ -84,7 +89,7 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf
for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1];
}
- break;
+ return;
}
case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) dest;
@@ -93,7 +98,7 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf
for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1];
}
- break;
+ return;
}
default: assert(0);
}
diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c
index 4ed4e0473bdf3c11c2838842b24c15d886a02f2e..4a5df9361b7a9bb8d6fe852db273f53cab6bf879 100644
--- a/src/common/src/tglobal.c
+++ b/src/common/src/tglobal.c
@@ -126,8 +126,9 @@ int8_t tsWAL = TSDB_DEFAULT_WAL_LEVEL;
int32_t tsFsyncPeriod = TSDB_DEFAULT_FSYNC_PERIOD;
int32_t tsReplications = TSDB_DEFAULT_DB_REPLICA_OPTION;
int32_t tsQuorum = TSDB_DEFAULT_DB_QUORUM_OPTION;
+int16_t tsPartitons = TSDB_DEFAULT_DB_PARTITON_OPTION;
int8_t tsUpdate = TSDB_DEFAULT_DB_UPDATE_OPTION;
-int8_t tsCacheLastRow = TSDB_DEFAULT_CACHE_BLOCK_SIZE;
+int8_t tsCacheLastRow = TSDB_DEFAULT_CACHE_LAST_ROW;
int32_t tsMaxVgroupsPerDb = 0;
int32_t tsMinTablePerVnode = TSDB_TABLES_STEP;
int32_t tsMaxTablePerVnode = TSDB_DEFAULT_TABLES;
@@ -209,6 +210,7 @@ float tsTotalTmpDirGB = 0;
float tsTotalDataDirGB = 0;
float tsAvailTmpDirectorySpace = 0;
float tsAvailDataDirGB = 0;
+float tsUsedDataDirGB = 0;
float tsReservedTmpDirectorySpace = 1.0f;
float tsMinimalDataDirGB = 1.0f;
int32_t tsTotalMemoryMB = 0;
@@ -853,6 +855,16 @@ static void doInitGlobalConfig(void) {
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
+ cfg.option = "partitions";
+ cfg.ptr = &tsPartitons;
+ cfg.valType = TAOS_CFG_VTYPE_INT16;
+ cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
+ cfg.minValue = TSDB_MIN_DB_PARTITON_OPTION;
+ cfg.maxValue = TSDB_MAX_DB_PARTITON_OPTION;
+ cfg.ptrLength = 0;
+ cfg.unitType = TAOS_CFG_UTYPE_NONE;
+ taosInitConfigOption(cfg);
+
cfg.option = "quorum";
cfg.ptr = &tsQuorum;
cfg.valType = TAOS_CFG_VTYPE_INT32;
diff --git a/src/connector/jdbc/CMakeLists.txt b/src/connector/jdbc/CMakeLists.txt
index 3c50ac566b5fe49a619a50c9eac446285a2b431c..86ddfcb022f4467f7378b85dda5760b66366bbbc 100644
--- a/src/connector/jdbc/CMakeLists.txt
+++ b/src/connector/jdbc/CMakeLists.txt
@@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED)
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
POST_BUILD
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.21-dist.jar ${LIBRARY_OUTPUT_PATH}
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.22-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMENT "build jdbc driver")
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
diff --git a/src/connector/jdbc/deploy-pom.xml b/src/connector/jdbc/deploy-pom.xml
index 1c24b621efe52e152ac8ea70ef3c2afdbc72d5b0..fe93e54c69e969cd8f54b41b6275423157f56197 100755
--- a/src/connector/jdbc/deploy-pom.xml
+++ b/src/connector/jdbc/deploy-pom.xml
@@ -5,7 +5,7 @@
com.taosdata.jdbctaos-jdbcdriver
- 2.0.21
+ 2.0.22jarJDBCDriver
diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml
index f1e013e864f4617e04be0c8c5b892c4396c66e79..51cb0b380822c81137c1a5514c898b51ae0d85be 100755
--- a/src/connector/jdbc/pom.xml
+++ b/src/connector/jdbc/pom.xml
@@ -3,7 +3,7 @@
4.0.0com.taosdata.jdbctaos-jdbcdriver
- 2.0.21
+ 2.0.22jarJDBCDriverhttps://github.com/taosdata/TDengine/tree/master/src/connector/jdbc
@@ -102,6 +102,8 @@
**/*Test.java
+ **/TSDBJNIConnectorTest.java
+ **/UnsignedNumberJniTest.java**/DatetimeBefore1970Test.java**/AppMemoryLeakTest.java**/AuthenticationTest.java
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDriver.java
index c4785127fdbfaad3b67c2aa513bc874d7dd3fd9a..5eaac1cd3ba7283b019a1d294c1a33334a3d9fa7 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDriver.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDriver.java
@@ -1,80 +1,18 @@
package com.taosdata.jdbc;
-import java.io.*;
import java.sql.Driver;
import java.sql.DriverPropertyInfo;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
public abstract class AbstractDriver implements Driver {
- private static final String TAOS_CFG_FILENAME = "taos.cfg";
-
- /**
- * @param cfgDirPath
- * @return return the config dir
- **/
- protected File loadConfigDir(String cfgDirPath) {
- if (cfgDirPath == null)
- return loadDefaultConfigDir();
- File cfgDir = new File(cfgDirPath);
- if (!cfgDir.exists())
- return loadDefaultConfigDir();
- return cfgDir;
- }
-
- /**
- * @return search the default config dir, if the config dir is not exist will return null
- */
- protected File loadDefaultConfigDir() {
- File cfgDir;
- File cfgDir_linux = new File("/etc/taos");
- cfgDir = cfgDir_linux.exists() ? cfgDir_linux : null;
- File cfgDir_windows = new File("C:\\TDengine\\cfg");
- cfgDir = (cfgDir == null && cfgDir_windows.exists()) ? cfgDir_windows : cfgDir;
- return cfgDir;
- }
-
- protected List loadConfigEndpoints(File cfgFile) {
- List endpoints = new ArrayList<>();
- try (BufferedReader reader = new BufferedReader(new FileReader(cfgFile))) {
- String line = null;
- while ((line = reader.readLine()) != null) {
- if (line.trim().startsWith("firstEp") || line.trim().startsWith("secondEp")) {
- endpoints.add(line.substring(line.indexOf('p') + 1).trim());
- }
- if (endpoints.size() > 1)
- break;
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return endpoints;
- }
-
- protected void loadTaosConfig(Properties info) {
- if ((info.getProperty(TSDBDriver.PROPERTY_KEY_HOST) == null || info.getProperty(TSDBDriver.PROPERTY_KEY_HOST).isEmpty()) && (
- info.getProperty(TSDBDriver.PROPERTY_KEY_PORT) == null || info.getProperty(TSDBDriver.PROPERTY_KEY_PORT).isEmpty())) {
- File cfgDir = loadConfigDir(info.getProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR));
- File cfgFile = cfgDir.listFiles((dir, name) -> TAOS_CFG_FILENAME.equalsIgnoreCase(name))[0];
- List endpoints = loadConfigEndpoints(cfgFile);
- if (!endpoints.isEmpty()) {
- info.setProperty(TSDBDriver.PROPERTY_KEY_HOST, endpoints.get(0).split(":")[0]);
- info.setProperty(TSDBDriver.PROPERTY_KEY_PORT, endpoints.get(0).split(":")[1]);
- }
- }
- }
-
protected DriverPropertyInfo[] getPropertyInfo(Properties info) {
DriverPropertyInfo hostProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_HOST, info.getProperty(TSDBDriver.PROPERTY_KEY_HOST));
hostProp.required = false;
hostProp.description = "Hostname";
- DriverPropertyInfo portProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_PORT, info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT));
+ DriverPropertyInfo portProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_PORT, info.getProperty(TSDBDriver.PROPERTY_KEY_PORT));
portProp.required = false;
portProp.description = "Port";
@@ -102,11 +40,11 @@ public abstract class AbstractDriver implements Driver {
protected Properties parseURL(String url, Properties defaults) {
Properties urlProps = (defaults != null) ? defaults : new Properties();
- // parse properties
+ // parse properties in url
int beginningOfSlashes = url.indexOf("//");
int index = url.indexOf("?");
if (index != -1) {
- String paramString = url.substring(index + 1, url.length());
+ String paramString = url.substring(index + 1);
url = url.substring(0, index);
StringTokenizer queryParams = new StringTokenizer(paramString, "&");
while (queryParams.hasMoreElements()) {
@@ -130,6 +68,7 @@ public abstract class AbstractDriver implements Driver {
String dbProductName = url.substring(0, beginningOfSlashes);
dbProductName = dbProductName.substring(dbProductName.indexOf(":") + 1);
dbProductName = dbProductName.substring(0, dbProductName.indexOf(":"));
+ urlProps.setProperty(TSDBDriver.PROPERTY_KEY_PRODUCT_NAME,dbProductName);
// parse dbname
url = url.substring(beginningOfSlashes + 2);
int indexOfSlash = url.indexOf("/");
@@ -154,6 +93,4 @@ public abstract class AbstractDriver implements Driver {
return urlProps;
}
-
-
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java
index 14bd2929f17e344381510897528bc479c50a4d36..238d18039de8ca6bf2f178263827bc4f1d6634f2 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java
@@ -29,12 +29,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
public abstract boolean getBoolean(int columnIndex) throws SQLException;
@Override
- public byte getByte(int columnIndex) throws SQLException {
- if (isClosed())
- throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
-
- throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
- }
+ public abstract byte getByte(int columnIndex) throws SQLException;
@Override
public abstract short getShort(int columnIndex) throws SQLException;
@@ -1205,6 +1200,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
public T getObject(String columnLabel, Class type) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
- throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); }
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java
index fe16aa653546f4033bd944f0b6c72aec1863ab8a..14e75f0e09e3403e703658fb503019fefbb6156d 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java
@@ -52,4 +52,14 @@ public class ColumnMetaData {
public void setColIndex(int colIndex) {
this.colIndex = colIndex;
}
+
+ @Override
+ public String toString() {
+ return "ColumnMetaData{" +
+ "colType=" + colType +
+ ", colName='" + colName + '\'' +
+ ", colSize=" + colSize +
+ ", colIndex=" + colIndex +
+ '}';
+ }
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SavedPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SavedPreparedStatement.java
index a0aa7ec584ee351185d10b023e5142d00d60d66b..512fcd26b8ce01b9e673fd7ed9a266ed0372ba52 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SavedPreparedStatement.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SavedPreparedStatement.java
@@ -122,8 +122,7 @@ public class SavedPreparedStatement {
initPreparedParam = initDefaultParam(tableName, middleParamSize, valueListSize);
} else {
- // not match
- throw new SQLException(TSDBConstants.WrapErrMsg("the sql is not complete!"));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL);
}
}
@@ -189,7 +188,7 @@ public class SavedPreparedStatement {
String errorMsg = String.format("the parameterIndex %s out of the range [1, %s]", parameterIndex, paramSize);
if (parameterIndex < 1 || parameterIndex > paramSize) {
- throw new SQLException(TSDBConstants.WrapErrMsg(errorMsg));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE,errorMsg);
}
this.isAddBatch = false; //set isAddBatch to false
@@ -212,7 +211,7 @@ public class SavedPreparedStatement {
return;
}
- throw new SQLException(TSDBConstants.WrapErrMsg(errorMsg));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE,errorMsg);
}
public void addBatch() {
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java
index 8d947b9411eb91eded49b3c7b1f12586682346ff..a8653eb1729dffa83fb556e1f7a1772257018699 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java
@@ -87,11 +87,10 @@ public class TSDBConnection extends AbstractConnection {
}
public void close() throws SQLException {
- if (isClosed()) {
- throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
- }
- this.isClosed = true;
+ if (isClosed)
+ return;
this.connector.closeConnection();
+ this.isClosed = true;
}
public boolean isClosed() throws SQLException {
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
index 6179b47da1041a3461f1be43625f8c7d4e284e64..37073e243fef99176c6d3d16d87d7cdaabb0e1b4 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
@@ -16,16 +16,11 @@ package com.taosdata.jdbc;
import java.sql.SQLException;
import java.sql.Types;
-import java.util.HashMap;
-import java.util.Map;
public abstract class TSDBConstants {
- public static final String DEFAULT_PORT = "6200";
- public static Map DATATYPE_MAP = null;
-
public static final long JNI_NULL_POINTER = 0L;
-
+ // JNI_ERROR_NUMBER
public static final int JNI_SUCCESS = 0;
public static final int JNI_TDENGINE_ERROR = -1;
public static final int JNI_CONNECTION_NULL = -2;
@@ -34,8 +29,7 @@ public abstract class TSDBConstants {
public static final int JNI_SQL_NULL = -5;
public static final int JNI_FETCH_END = -6;
public static final int JNI_OUT_OF_MEMORY = -7;
-
- public static final int TSDB_DATA_TYPE_NULL = 0;
+ // TSDB Data Types
public static final int TSDB_DATA_TYPE_BOOL = 1;
public static final int TSDB_DATA_TYPE_TINYINT = 2;
public static final int TSDB_DATA_TYPE_SMALLINT = 3;
@@ -46,46 +40,36 @@ public abstract class TSDBConstants {
public static final int TSDB_DATA_TYPE_BINARY = 8;
public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
public static final int TSDB_DATA_TYPE_NCHAR = 10;
-
- // nchar field's max length
+ /*
+ 系统增加新的无符号数据类型,分别是:
+ unsigned tinyint, 数值范围:0-254, NULL 为255
+ unsigned smallint,数值范围: 0-65534, NULL 为65535
+ unsigned int,数值范围:0-4294967294,NULL 为4294967295u
+ unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。
+ example:
+ create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned);
+ */
+ public static final int TSDB_DATA_TYPE_UTINYINT = 11; //unsigned tinyint
+ public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint
+ public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int
+ public static final int TSDB_DATA_TYPE_UBIGINT = 14; //unsigned bigint
+ // nchar column max length
public static final int maxFieldSize = 16 * 1024;
- public static String WrapErrMsg(String msg) {
- return "TDengine Error: " + msg;
- }
-
- public static String FixErrMsg(int code) {
- switch (code) {
- case JNI_TDENGINE_ERROR:
- return WrapErrMsg("internal error of database!");
- case JNI_CONNECTION_NULL:
- return WrapErrMsg("invalid tdengine connection!");
- case JNI_RESULT_SET_NULL:
- return WrapErrMsg("invalid resultset pointer!");
- case JNI_NUM_OF_FIELDS_0:
- return WrapErrMsg("invalid num of fields!");
- case JNI_SQL_NULL:
- return WrapErrMsg("can't execute empty sql!");
- case JNI_FETCH_END:
- return WrapErrMsg("fetch to the end of resultset");
- default:
- break;
- }
- return WrapErrMsg("unkown error!");
- }
-
public static int taosType2JdbcType(int taosType) throws SQLException {
switch (taosType) {
- case TSDBConstants.TSDB_DATA_TYPE_NULL:
- return Types.NULL;
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Types.BOOLEAN;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
+ case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
return Types.TINYINT;
+ case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return Types.SMALLINT;
+ case TSDBConstants.TSDB_DATA_TYPE_UINT:
case TSDBConstants.TSDB_DATA_TYPE_INT:
return Types.INTEGER;
+ case TSDBConstants.TSDB_DATA_TYPE_UBIGINT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return Types.BIGINT;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
@@ -99,13 +83,42 @@ public abstract class TSDBConstants {
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return Types.NCHAR;
}
- throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE);
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
+ }
+
+ public static String taosType2JdbcTypeName(int taosType) throws SQLException {
+ switch (taosType){
+ case TSDBConstants.TSDB_DATA_TYPE_BOOL:
+ return "BOOL";
+ case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
+ case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
+ return "TINYINT";
+ case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
+ case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
+ return "SMALLINT";
+ case TSDBConstants.TSDB_DATA_TYPE_UINT:
+ case TSDBConstants.TSDB_DATA_TYPE_INT:
+ return "INT";
+ case TSDBConstants.TSDB_DATA_TYPE_UBIGINT:
+ case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
+ return "BIGINT";
+ case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
+ return "FLOAT";
+ case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
+ return "DOUBLE";
+ case TSDBConstants.TSDB_DATA_TYPE_BINARY:
+ return "BINARY";
+ case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
+ return "TIMESTAMP";
+ case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
+ return "NCHAR";
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
+ }
}
public static int jdbcType2TaosType(int jdbcType) throws SQLException {
switch (jdbcType){
- case Types.NULL:
- return TSDBConstants.TSDB_DATA_TYPE_NULL;
case Types.BOOLEAN:
return TSDBConstants.TSDB_DATA_TYPE_BOOL;
case Types.TINYINT:
@@ -130,22 +143,31 @@ public abstract class TSDBConstants {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE);
}
- static {
- DATATYPE_MAP = new HashMap<>();
- DATATYPE_MAP.put(0, "NULL");
- DATATYPE_MAP.put(1, "BOOL");
- DATATYPE_MAP.put(2, "TINYINT");
- DATATYPE_MAP.put(3, "SMALLINT");
- DATATYPE_MAP.put(4, "INT");
- DATATYPE_MAP.put(5, "BIGINT");
- DATATYPE_MAP.put(6, "FLOAT");
- DATATYPE_MAP.put(7, "DOUBLE");
- DATATYPE_MAP.put(8, "BINARY");
- DATATYPE_MAP.put(9, "TIMESTAMP");
- DATATYPE_MAP.put(10, "NCHAR");
+ public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException {
+ switch (jdbcType){
+ case Types.BOOLEAN:
+ return "BOOL";
+ case Types.TINYINT:
+ return "TINYINT";
+ case Types.SMALLINT:
+ return "SMALLINT";
+ case Types.INTEGER:
+ return "INT";
+ case Types.BIGINT:
+ return "BIGINT";
+ case Types.FLOAT:
+ return "FLOAT";
+ case Types.DOUBLE:
+ return "DOUBLE";
+ case Types.BINARY:
+ return "BINARY";
+ case Types.TIMESTAMP:
+ return "TIMESTAMP";
+ case Types.NCHAR:
+ return "NCHAR";
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE);
+ }
}
- public static String jdbcType2TaosTypeName(int type) throws SQLException {
- return DATATYPE_MAP.get(jdbcType2TaosType(type));
- }
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java
index 2b87b72fef0f2b621536c5a11aba69975aa86434..5f599df1300b3d6959e9a7b58c00a720d722e07b 100755
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java
@@ -44,6 +44,10 @@ public class TSDBDriver extends AbstractDriver {
private static final String URL_PREFIX = "jdbc:TAOS://";
+ /**
+ * PRODUCT_NAME
+ */
+ public static final String PROPERTY_KEY_PRODUCT_NAME = "productName";
/**
* Key used to retrieve the host value from the properties instance passed to
* the driver.
@@ -96,40 +100,34 @@ public class TSDBDriver extends AbstractDriver {
static {
try {
java.sql.DriverManager.registerDriver(new TSDBDriver());
- } catch (SQLException E) {
- throw new RuntimeException(TSDBConstants.WrapErrMsg("can't register tdengine jdbc driver!"));
+ } catch (SQLException e) {
+ throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_CANNOT_REGISTER_JNI_DRIVER, e);
}
}
public Connection connect(String url, Properties info) throws SQLException {
if (url == null)
- throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!"));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_URL_NOT_SET);
if (!acceptsURL(url))
return null;
- Properties props = null;
- if ((props = parseURL(url, info)) == null) {
+ Properties props = parseURL(url, info);
+ if (props == null) {
return null;
}
- //load taos.cfg start
- loadTaosConfig(info);
try {
TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE),
(String) props.get(PROPERTY_KEY_CHARSET), (String) props.get(PROPERTY_KEY_TIME_ZONE));
- Connection newConn = new TSDBConnection(props, this.dbMetaData);
- return newConn;
+ return new TSDBConnection(props, this.dbMetaData);
} catch (SQLWarning sqlWarning) {
sqlWarning.printStackTrace();
- Connection newConn = new TSDBConnection(props, this.dbMetaData);
- return newConn;
+ return new TSDBConnection(props, this.dbMetaData);
} catch (SQLException sqlEx) {
throw sqlEx;
} catch (Exception ex) {
- SQLException sqlEx = new SQLException("SQLException:" + ex.toString());
- sqlEx.initCause(ex);
- throw sqlEx;
+ throw new SQLException("SQLException:" + ex.toString(), ex);
}
}
@@ -141,8 +139,8 @@ public class TSDBDriver extends AbstractDriver {
*/
public boolean acceptsURL(String url) throws SQLException {
if (url == null)
- throw new SQLException(TSDBConstants.WrapErrMsg("url is null"));
- return (url != null && url.length() > 0 && url.trim().length() > 0) && (url.startsWith(URL_PREFIX) || url.startsWith(URL_PREFIX1));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_URL_NOT_SET);
+ return url.length() > 0 && url.trim().length() > 0 && (url.startsWith(URL_PREFIX) || url.startsWith(URL_PREFIX1));
}
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java
index c7717e331b39247542d1a022cafd1cab2ac65627..90967b3620fdaccf69f253c8f8927c067b6221fd 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java
@@ -3,6 +3,7 @@ package com.taosdata.jdbc;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLWarning;
import java.util.HashMap;
import java.util.Map;
@@ -18,18 +19,25 @@ public class TSDBError {
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_BATCH_IS_EMPTY, "Batch is empty!");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY, "Can not issue data manipulation statements with executeQuery()");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE, "Can not issue SELECT via executeUpdate()");
- TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: (?)");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "invalid sql for executeQuery: (?)");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE, "Database not specified or available");
- TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: (?)");
- TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE, "not a valid sql for execute: (?)");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "invalid sql for executeUpdate: (?)");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE, "invalid sql for execute: (?)");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "parameter index out of range");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED, "connection already closed");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE, "unknown sql type in tdengine");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_CANNOT_REGISTER_JNI_DRIVER, "can't register JDBC-JNI driver");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_CANNOT_REGISTER_RESTFUL_DRIVER, "can't register JDBC-RESTful driver");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_URL_NOT_SET, "url is not set");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_SQL, "invalid sql");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE, "numeric value out of range");
+ TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE, "unknown taos type in tdengine");
+
/**************************************************/
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error");
/**************************************************/
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SUBSCRIBE_FAILED, "failed to create subscription");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING, "Unsupported encoding");
-
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_TDENGINE_ERROR, "internal error of database");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL, "JNI connection is NULL");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL, "JNI result set is NULL");
@@ -65,4 +73,12 @@ public class TSDBError {
return new SQLException("TDengine ERROR (" + Integer.toHexString(errorCode) + "): " + message, "", errorCode);
}
-}
+ public static RuntimeException createRuntimeException(int errorCode, Throwable t) {
+ String message = TSDBErrorMap.get(errorCode);
+ return new RuntimeException("ERROR (" + Integer.toHexString(errorCode) + "): " + message, t);
+ }
+
+ public static SQLWarning createSQLWarning(String message) {
+ return new SQLWarning(message);
+ }
+}
\ No newline at end of file
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java
index 78e7aec79c252a2e6b2eeafcba37ab1c66f8674d..c978bb3a2e4a1b9dbd264268f057f2b6c735250a 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java
@@ -16,15 +16,20 @@ public class TSDBErrorNumbers {
public static final int ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE = 0x230a; //Database not specified or available
public static final int ERROR_INVALID_FOR_EXECUTE_UPDATE = 0x230b; //not a valid sql for executeUpdate: (SQL)
public static final int ERROR_INVALID_FOR_EXECUTE = 0x230c; //not a valid sql for execute: (SQL)
- public static final int ERROR_PARAMETER_INDEX_OUT_RANGE = 0x230d; // parameter index out of range
+ public static final int ERROR_PARAMETER_INDEX_OUT_RANGE = 0x230d; // parameter index out of range
public static final int ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED = 0x230e; // connection already closed
public static final int ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE = 0x230f; //unknown sql type in tdengine
+ public static final int ERROR_CANNOT_REGISTER_JNI_DRIVER = 0x2310; // can't register JDBC-JNI driver
+ public static final int ERROR_CANNOT_REGISTER_RESTFUL_DRIVER = 0x2311; // can't register JDBC-RESTful driver
+ public static final int ERROR_URL_NOT_SET = 0x2312; // url is not set
+ public static final int ERROR_INVALID_SQL = 0x2313; // invalid sql
+ public static final int ERROR_NUMERIC_VALUE_OUT_OF_RANGE = 0x2314; // numeric value out of range
+ public static final int ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE = 0x2315; //unknown taos type in tdengine
public static final int ERROR_UNKNOWN = 0x2350; //unknown error
public static final int ERROR_SUBSCRIBE_FAILED = 0x2351; // failed to create subscription
public static final int ERROR_UNSUPPORTED_ENCODING = 0x2352; // Unsupported encoding
-
public static final int ERROR_JNI_TDENGINE_ERROR = 0x2353; // internal error of database
public static final int ERROR_JNI_CONNECTION_NULL = 0x2354; // JNI connection is NULL
public static final int ERROR_JNI_RESULT_SET_NULL = 0x2355; // invalid JNI result set
@@ -51,11 +56,16 @@ public class TSDBErrorNumbers {
errorNumbers.add(ERROR_PARAMETER_INDEX_OUT_RANGE);
errorNumbers.add(ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
errorNumbers.add(ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE);
+ errorNumbers.add(ERROR_CANNOT_REGISTER_JNI_DRIVER);
+ errorNumbers.add(ERROR_CANNOT_REGISTER_RESTFUL_DRIVER);
+ errorNumbers.add(ERROR_URL_NOT_SET);
+ errorNumbers.add(ERROR_INVALID_SQL);
+ errorNumbers.add(ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
+ errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
/*****************************************************/
errorNumbers.add(ERROR_SUBSCRIBE_FAILED);
errorNumbers.add(ERROR_UNSUPPORTED_ENCODING);
-
errorNumbers.add(ERROR_JNI_TDENGINE_ERROR);
errorNumbers.add(ERROR_JNI_CONNECTION_NULL);
errorNumbers.add(ERROR_JNI_RESULT_SET_NULL);
@@ -63,7 +73,6 @@ public class TSDBErrorNumbers {
errorNumbers.add(ERROR_JNI_SQL_NULL);
errorNumbers.add(ERROR_JNI_FETCH_END);
errorNumbers.add(ERROR_JNI_OUT_OF_MEMORY);
-
}
private TSDBErrorNumbers() {
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
index f3c4e025798e8e3fd8db0e5c1a1b25aa6fea3dc7..7d3741917cb9166a5b29e69ad2b4d3f5023bd43d 100755
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
@@ -1,17 +1,19 @@
-/***************************************************************************
+/**
+ * *************************************************************************
* Copyright (c) 2019 TAOS Data, Inc.
- *
+ *
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
- *
+ *
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
- *****************************************************************************/
+ * ***************************************************************************
+ */
package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.TaosInfo;
@@ -20,6 +22,9 @@ import java.sql.SQLException;
import java.sql.SQLWarning;
import java.util.List;
+/**
+ * JNI connector
+ */
public class TSDBJNIConnector {
private static volatile Boolean isInitialized = false;
@@ -68,13 +73,13 @@ public class TSDBJNIConnector {
if (!isInitialized) {
initImp(configDir);
if (setOptions(0, locale) < 0) {
- throw new SQLWarning(TSDBConstants.WrapErrMsg("Failed to set locale: " + locale + ". System default will be used."));
+ throw TSDBError.createSQLWarning("Failed to set locale: " + locale + ". System default will be used.");
}
if (setOptions(1, charset) < 0) {
- throw new SQLWarning(TSDBConstants.WrapErrMsg("Failed to set charset: " + charset + ". System default will be used."));
+ throw TSDBError.createSQLWarning("Failed to set charset: " + charset + ". System default will be used.");
}
if (setOptions(2, timezone) < 0) {
- throw new SQLWarning(TSDBConstants.WrapErrMsg("Failed to set timezone: " + timezone + ". System default will be used."));
+ throw TSDBError.createSQLWarning("Failed to set timezone: " + timezone + ". System default will be used.");
}
isInitialized = true;
TaosGlobalConfig.setCharset(getTsCharset());
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java
index 80ff49253016c632b6bf85f4756fe2d702a9bffc..7c2940fdc2c1a0cb15a5a0f1557598cb5b062e61 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java
@@ -20,18 +20,16 @@ import java.util.ArrayList;
import java.util.List;
public class TSDBResultSet extends AbstractResultSet implements ResultSet {
- private TSDBJNIConnector jniConnector;
-
+ private final TSDBJNIConnector jniConnector;
private final TSDBStatement statement;
- private long resultSetPointer = 0L;
+ private final long resultSetPointer;
private List columnMetaDataList = new ArrayList<>();
+ private final TSDBResultSetRowData rowData;
+ private final TSDBResultSetBlockData blockData;
- private TSDBResultSetRowData rowData;
- private TSDBResultSetBlockData blockData;
-
- private boolean batchFetch = false;
- private boolean lastWasNull = false;
- private final int COLUMN_INDEX_START_VALUE = 1;
+ private boolean batchFetch;
+ private boolean lastWasNull;
+ private boolean isClosed;
public void setBatchFetch(boolean batchFetch) {
this.batchFetch = batchFetch;
@@ -56,13 +54,13 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
int code = this.jniConnector.getSchemaMetaData(this.resultSetPointer, this.columnMetaDataList);
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
}
if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL);
}
if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0);
}
this.rowData = new TSDBResultSetRowData(this.columnMetaDataList.size());
this.blockData = new TSDBResultSetBlockData(this.columnMetaDataList, this.columnMetaDataList.size());
@@ -78,28 +76,23 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
this.blockData.reset();
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL);
} else if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0));
- } else if (code == TSDBConstants.JNI_FETCH_END) {
- return false;
- }
-
- return true;
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0);
+ } else return code != TSDBConstants.JNI_FETCH_END;
} else {
if (rowData != null) {
this.rowData.clear();
}
-
int code = this.jniConnector.fetchRow(this.resultSetPointer, this.rowData);
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL);
} else if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0);
} else if (code == TSDBConstants.JNI_FETCH_END) {
return false;
} else {
@@ -109,14 +102,17 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
}
public void close() throws SQLException {
+ if (isClosed)
+ return;
if (this.jniConnector != null) {
int code = this.jniConnector.freeResultSet(this.resultSetPointer);
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
- throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL));
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL);
}
}
+ isClosed = true;
}
public boolean wasNull() throws SQLException {
@@ -127,30 +123,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
String res = null;
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- if (!lastWasNull) {
- res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType());
- }
- return res;
- } else {
+ if (this.getBatchFetch())
return this.blockData.getString(colIndex);
+
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ if (!lastWasNull) {
+ res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
+ return res;
}
public boolean getBoolean(int columnIndex) throws SQLException {
boolean res = false;
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- if (!lastWasNull) {
- res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType());
- }
- } else {
+ if (this.getBatchFetch())
return this.blockData.getBoolean(colIndex);
- }
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ if (!lastWasNull) {
+ res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType());
+ }
return res;
}
@@ -158,91 +151,84 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
byte res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- if (!lastWasNull) {
- res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
- }
- return res;
- } else {
+ if (this.getBatchFetch())
return (byte) this.blockData.getInt(colIndex);
+
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ if (!lastWasNull) {
+ res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
+ return res;
}
public short getShort(int columnIndex) throws SQLException {
short res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- if (!lastWasNull) {
- res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
- }
- return res;
- } else {
+ if (this.getBatchFetch())
return (short) this.blockData.getInt(colIndex);
+
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ if (!lastWasNull) {
+ res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
+ return res;
}
public int getInt(int columnIndex) throws SQLException {
int res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- if (!lastWasNull) {
- res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
- }
- return res;
- } else {
+ if (this.getBatchFetch())
return this.blockData.getInt(colIndex);
- }
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ if (!lastWasNull) {
+ res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
+ }
+ return res;
}
public long getLong(int columnIndex) throws SQLException {
long res = 0L;
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- if (!lastWasNull) {
- res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType());
- }
- return res;
- } else {
+ if (this.getBatchFetch())
return this.blockData.getLong(colIndex);
+
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ if (!lastWasNull) {
+ res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
+ return res;
}
public float getFloat(int columnIndex) throws SQLException {
float res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- if (!lastWasNull) {
- res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType());
- }
- return res;
- } else {
+ if (this.getBatchFetch())
return (float) this.blockData.getDouble(colIndex);
- }
+
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ if (!lastWasNull)
+ res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType());
+
+ return res;
}
public double getDouble(int columnIndex) throws SQLException {
double res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- if (!lastWasNull) {
- res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType());
- }
- return res;
- } else {
+ if (this.getBatchFetch())
return this.blockData.getDouble(colIndex);
+
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ if (!lastWasNull) {
+ res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
+ return res;
}
@Deprecated
@@ -258,15 +244,14 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
Timestamp res = null;
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- if (!lastWasNull) {
- res = this.rowData.getTimestamp(colIndex);
- }
- return res;
- } else {
+ if (this.getBatchFetch())
return this.blockData.getTimestamp(columnIndex);
+
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ if (!lastWasNull) {
+ res = this.rowData.getTimestamp(colIndex);
}
+ return res;
}
public ResultSetMetaData getMetaData() throws SQLException {
@@ -277,12 +262,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
public Object getObject(int columnIndex) throws SQLException {
int colIndex = getTrueColumnIndex(columnIndex);
- if (!this.getBatchFetch()) {
- this.lastWasNull = this.rowData.wasNull(colIndex);
- return this.rowData.get(colIndex);
- } else {
+ if (this.getBatchFetch())
return this.blockData.get(colIndex);
- }
+
+ this.lastWasNull = this.rowData.wasNull(colIndex);
+ return this.rowData.get(colIndex);
}
@Override
@@ -415,8 +399,8 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
}
public boolean isClosed() throws SQLException {
- //TODO: check if need release resources
- boolean isClosed = true;
+ if (isClosed)
+ return true;
if (jniConnector != null) {
isClosed = jniConnector.isResultsetClosed();
}
@@ -429,14 +413,12 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
}
private int getTrueColumnIndex(int columnIndex) throws SQLException {
- if (columnIndex < this.COLUMN_INDEX_START_VALUE) {
- throw new SQLException("Column Index out of range, " + columnIndex + " < " + this.COLUMN_INDEX_START_VALUE);
- }
+ if (columnIndex < 1)
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "columnIndex(" + columnIndex + "): < 1");
int numOfCols = this.columnMetaDataList.size();
- if (columnIndex > numOfCols) {
- throw new SQLException("Column Index out of range, " + columnIndex + " > " + numOfCols);
- }
+ if (columnIndex > numOfCols)
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "columnIndex: " + columnIndex);
return columnIndex - 1;
}
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java
index 9352cf525350ff57525680f405d61c6b00c0cf55..ce5290de6616dfcc367434cc2e24899e992ddd63 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java
@@ -30,468 +30,472 @@ import java.util.Collections;
import java.util.List;
public class TSDBResultSetBlockData {
- private int numOfRows = 0;
- private int rowIndex = 0;
-
- private List columnMetaDataList;
- private ArrayList